Commit graph

175 commits

Author SHA1 Message Date
Mike Colagrosso
03ed3c2257 Add Ebook::DownloadUrl for web and feed downloads
This commit adds a rewrite rule for ebook downloads of the form:

```
/ebooks/some-author/some-book/downloads/some-filename.epub
```

to `www/ebooks/download.php`. That file handles the logic of whether to
show a thank you page before beginning the download.

Download URLs in RSS, Atom, and OPDS feeds follow the same pattern, but
they have a query string parameter `?source=feed` to always skip the
thank you page.
2025-04-25 14:31:44 -05:00
Alex Cabal
fbcafb8f1d Improve type hints 2025-03-27 16:46:05 -05:00
Mike Colagrosso
9202717a6b Add a special case for hyphens: Replace with space
See #484 for details. By adding a special case for hyphens, users can
search for these terms:

`beta` to match `Alpha-Beta`
`queen` to match `Haycraft-Queen`

These searches also work as expected:

`Alpha-Beta`
`Alpha`
`Haycraft-Queen`
`Haycraft`

I don't think these queries should work, and they do not:

`AlphaBeta`
`HaycraftQueen`

This commit changes `IndexableText`, `IndexableAuthors`, and
`IndexableCollections`, so existing DBs need an update. This will update
all published books:

```
cd /standardebooks.org/ebooks
for BOOK in $(find /standardebooks.org/ebooks -maxdepth 1 -type d)
do
  tsp nice /standardebooks.org/web/scripts/deploy-ebook-to-www --verbose --no-build --no-images --no-recompose --no-epubcheck --no-feeds --no-bulk-downloads "$BOOK"
done
```

And this PHP code will update placeholders:

```
<?
require_once('/standardebooks.org/web/lib/Core.php');

$ebooks = Ebook::GetAll();

foreach($ebooks as $ebook){
        if($ebook->IsPlaceholder()){
                print('Saving ' . $ebook->Identifier . "\n");

                // Need to force `Ebook::GetAllContributors()` to be called before `Ebook::Save()`. Otherwise, authors and translators will be deleted.
                $ebook->Authors;

                $ebook->Save();
        }
}
```
2025-03-25 13:16:25 -05:00
Mike Colagrosso
8a4da08a66 Remove non-alphanumerics (except quotes) from search query
That is, don't replace non-alphanumerics with a space. This matches the
behavior of Formatter::RemoveDiacriticsAndNonalphanumerics(), which
would be used here except that function would also remove quotes.  We
actually discussed not introducing spaces previously, but I made a
mistake and didn't apply the same change to the user's search query:

https://github.com/standardebooks/web/pull/470#discussion_r1929591492

This change fixes queries with compound words like:

`Haycraft-Queen`

and also fixes queries for authors with apostrophes:

`O'Neill`

No changes to existing DBs are necessary because they already have terms
like `haycraftqueen` and `oneill` stored in `IndexableCollections` and
`IndexableAuthors`.
2025-03-25 13:16:25 -05:00
Alex Cabal
dc84ff3fa9 Style tweaks 2025-03-10 14:38:54 -05:00
Mike Colagrosso
af956b2714
Replace EbookUrl with EbookId in Artworks (#482)
* Replace `EbookUrl` with `EbookId` in `Artworks`

* Add a `FullUrl` member to `Ebook`

Add documentation about when to use it versus Url.

The full URL is also being used as an ID in RSS feeds, so use `FullUrl` there.

* Store an `EbookId` in `Artworks`
2025-03-10 14:33:20 -05:00
Alex Cabal
5066252355 Use 'insert ... returning' instead of 'Db::GetLastInsertedId()' 2025-03-10 13:03:31 -05:00
Alex Cabal
7f5ffb4aea Use shorthand assignment for basic getters 2025-02-27 16:03:26 -06:00
Alex Cabal
a5a19f947f More type fixes 2025-02-26 14:32:04 -06:00
Alex Cabal
9d1b66d19e Update PHPStan and Safe PHP, and review codebase for further type correctness 2025-02-25 22:41:18 -06:00
Alex Cabal
831c1531d8 Minor refactor 2025-02-15 11:44:18 -06:00
Alex Cabal
388dbab1f1 Change indexable properties to private class properties instead of public getters/setters 2025-02-13 22:52:12 -06:00
Mike Colagrosso
d05f0ea3c7 Remove blank line 2025-02-13 13:48:39 -06:00
Mike Colagrosso
804b786065 Keep IndexableText null if it's an empty string
The `Validate()` method is correctly setting it to null, but then the
`UPDATE` SQL statement is triggering another call to
`GetIndexableText()`. Without this change, empty strings are being
written to the `IndexableText` column.
2025-02-13 13:48:39 -06:00
Mike Colagrosso
55e0428006 Add a Default EbookSortType
This allows the user to run a keyword search and then change the sort
order. `Default` is interpreted as `Relevance` if a query is present,
`Newest` if not.
2025-02-13 13:48:39 -06:00
Mike Colagrosso
a3ce3f1ec1 Make IndexableText optional
Placeholders do not have FullTitle, AlternateTitle, Tags, LocSubjects,
or TocEntries.
2025-02-13 13:48:39 -06:00
Mike Colagrosso
1629d3a1a1 Remove RelevanceScore from the SELECT fields
Having it in the SELECT fields was causing warnings like this:

```
NOTICE: PHP message: PHP Deprecated:  Creation of dynamic property Ebook::$RelevanceScore is deprecated in /standardebooks.org/web/lib/Traits/Accessor.php
```
2025-02-13 13:48:39 -06:00
Mike Colagrosso
61bbf8f071 Add idxSearchCombined to match multiple fields
The data in these fields are separate:

* `IndexableText`
* `Title`
* `IndexableAuthors`
* `IndexableCollections`

There are also on indices on each of these fields so that they can have
separate weight in the relevance scoring.
2025-02-13 13:48:39 -06:00
Mike Colagrosso
fd3abb568c Remove title, authors, and collections from IndexableText
Those properties are indexed separately. `FullTitle` and
`AlternateTitle` are still indexed here.
2025-02-13 13:48:39 -06:00
Mike Colagrosso
660f8b5e3e RelevanceScore not relevance_score 2025-02-13 13:48:39 -06:00
Mike Colagrosso
0c87f1f262 Remove unnecessary check ?? '' from non-null 2025-02-13 13:48:39 -06:00
Mike Colagrosso
1a71913794 Add a Relevance sort order and improve search
Here's what's in `IndexableText` right now:

1. Title
2. Collections
3. Authors
4. Tags
5. LocSubjects
6. TocEntries

Here is the proposed new ranking:

```
10 * Title +
8 * Authors +
3 * Collections +
IndexableText
```

New indices for existing DBs:

```
ALTER TABLE `Ebooks` ADD COLUMN `IndexableAuthors` text NOT NULL;
ALTER TABLE `Ebooks` ADD COLUMN `IndexableCollections` text NULL;
ALTER TABLE `Ebooks` ADD FULLTEXT `indexSearchTitle` (`Title`);
ALTER TABLE `Ebooks` ADD FULLTEXT `idxSearchAuthors` (`IndexableAuthors`);
ALTER TABLE `Ebooks` ADD FULLTEXT `idxSearchCollections` (`IndexableCollections`);
```
2025-02-13 13:48:39 -06:00
Alex Cabal
6378d687d8 Add 'awaiting review' and 'reviewed' project statuses that update from GitHub; allow project owners to update their project statuses 2025-01-27 15:52:21 -06:00
Mike Colagrosso
38f4e34a11 Match Contributor UrlName to Identifier
Fixes #459
2025-01-15 15:47:04 -06:00
Alex Cabal
c36d1ac3d3 Rename exception for consistency 2025-01-09 14:08:54 -06:00
Alex Cabal
94d62fdcdf Fix exception for duplicate ebook placeholder on save 2025-01-09 14:07:40 -06:00
Alex Cabal
87620287f1 Don't check max string length for ebook description 2025-01-07 10:12:04 -06:00
Mike Colagrosso
0e7bff5d82 Rewrite MultiTableSelect queries with ON
Instead of `USING(EbookId)`, it would be easier to handle
`MultiTableSelect` queries in `FromMultiTableRow()` if the queries used

`ON Projects.EbookId = Ebooks.Ebooks`

This is because `USING` will return only one `EbookId` column, but `ON`
will return all columns from both tables.
2025-01-02 09:57:45 -06:00
Alex Cabal
9abae874f6 Fix sort order of collection placeholders with no sequence 2024-12-31 14:21:59 -06:00
Alex Cabal
b8c4de4b20 Change order of collection sorting 2024-12-31 10:32:57 -06:00
Alex Cabal
53fe66a364 Initialize empty values for some image URLs 2024-12-29 15:10:41 -06:00
Alex Cabal
c43c4fa2dd Tweak wanted list appearance 2024-12-28 19:14:04 -06:00
Mike Colagrosso
2d5cba0aaa Rename function to Ebook::GetByIsWantedAndDifficulty() 2024-12-28 14:18:08 -06:00
Mike Colagrosso
5b605a00b7 Populate the wanted list from DB placeholders 2024-12-28 14:18:08 -06:00
Mike Colagrosso
d6dd10be9c Clean up unused Tags, LocSubjects, and Collections
On `Ebook::Save()` and `Ebook::Delete()`, remove any unreferenced `Tag`,
`LocSubject`, and `Collection` records. These are analogous to these lines in
`Ebook::Create()`:

```
$this->CreateTags();
$this->CreateLocSubjects();
$this->CreateCollections();
```

`EbookPlaceholder`s can't have `Tags` or `LocSubjects` at the moment, but other
mistakes in production that are later corrected could leave unused `Tags` and
`LocSubjects`.

Context: https://github.com/standardebooks/web/pull/447#issuecomment-2555734692
2024-12-26 12:10:13 -06:00
Alex Cabal
8e8cbb0c5e Move delete form and more multi select fixes 2024-12-19 14:40:38 -06:00
Mike Colagrosso
d0d79d637c Add form to delete placeholders 2024-12-19 14:21:25 -06:00
Alex Cabal
378555d131 Show improved project details on placeholder page 2024-12-18 15:54:06 -06:00
Alex Cabal
7a6a743295 Some type check fixes 2024-12-18 15:03:44 -06:00
Alex Cabal
a1da50fc1a Sort projects by ebook title 2024-12-18 14:28:07 -06:00
Alex Cabal
b2191d1219 Allow editing of projects 2024-12-18 14:20:28 -06:00
Mike Colagrosso
f449c024ea Add /edit endpoint to update placeholders 2024-12-18 12:58:18 -06:00
Alex Cabal
c7a4e34e31 Add projects index page, and more detail on placeholder pages 2024-12-14 21:12:00 -06:00
Alex Cabal
adfe07aad9 Add beginning of a project management system to placeholders 2024-12-14 19:13:03 -06:00
Alex Cabal
e56de4b19d Switch from EbookPlaceholder.Status to EbookPlaceholder.IsInProgress, and some type tweaks 2024-12-14 13:39:28 -06:00
Alex Cabal
1a742baa51 Add CanEditEbooks benefit and clean up some PHPStan errors 2024-12-14 11:50:16 -06:00
Alex Cabal
23b5c8ef31 Allow admin to view collection metadata 2024-12-14 11:32:02 -06:00
Alex Cabal
79fdc8c20f Some type check fixes 2024-12-13 23:21:04 -06:00
Alex Cabal
89d0b2ea46 Replace ' with ’ in placeholder titles 2024-12-13 12:24:29 -06:00
Mike Colagrosso
1ab95df084 Add placeholders for ebooks 2024-12-13 11:46:36 -06:00