mirror of
https://github.com/standardebooks/web.git
synced 2025-07-16 03:16:36 -04:00
Comment formatting
This commit is contained in:
parent
8e2bb6edb0
commit
8546039b97
17 changed files with 37 additions and 52 deletions
|
@ -31,9 +31,9 @@ class RssFeed extends Feed{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SaveIfChanged(): bool{
|
public function SaveIfChanged(): bool{
|
||||||
// Did we actually update the feed? If so, write to file and update the index
|
// Did we actually update the feed? If so, write to file and update the index.
|
||||||
if($this->HasChanged($this->Path)){
|
if($this->HasChanged($this->Path)){
|
||||||
// Files don't match, save the file
|
// Files don't match, save the file.
|
||||||
$this->Save();
|
$this->Save();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -42,11 +42,7 @@ class RssFeed extends Feed{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function HasChanged(string $path): bool{
|
protected function HasChanged(string $path): bool{
|
||||||
// RSS doesn't have information about when an item was updated,
|
// RSS doesn't have information about when an item was updated, only when it was first published. So, we approximate on whether the feed has changed by looking at the length of the enclosed file. This can sometimes be the same even if the file has changed, but most of the time it also changes.
|
||||||
// only when it was first published. So, we approximate on whether the feed
|
|
||||||
// has changed by looking at the length of the enclosed file.
|
|
||||||
// This can sometimes be the same even if the file has changed, but most of the time
|
|
||||||
// it also changes.
|
|
||||||
|
|
||||||
if(!is_file($path)){
|
if(!is_file($path)){
|
||||||
return true;
|
return true;
|
||||||
|
@ -75,7 +71,7 @@ class RssFeed extends Feed{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception){
|
catch(Exception){
|
||||||
// Invalid XML
|
// Invalid XML.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
$patronsCircle = [];
|
$patronsCircle = [];
|
||||||
$anonymousPatronCount = 0;
|
$anonymousPatronCount = 0;
|
||||||
|
|
||||||
// Get the Patrons Circle and try to sort by last name ascending
|
// Get the Patrons Circle and try to sort by last name ascending.
|
||||||
// See <https://mariadb.com/kb/en/pcre/#unicode-character-properties> for Unicode character properties
|
// See <https://mariadb.com/kb/en/pcre/#unicode-character-properties> for Unicode character properties.
|
||||||
|
|
||||||
$patronsCircle = Db::Query('
|
$patronsCircle = Db::Query('
|
||||||
SELECT if(p.AlternateName is not null, p.AlternateName, u.Name) as SortedName
|
SELECT if(p.AlternateName is not null, p.AlternateName, u.Name) as SortedName
|
||||||
|
|
|
@ -21,7 +21,7 @@ try{
|
||||||
throw new Exceptions\InvalidPermissionsException();
|
throw new Exceptions\InvalidPermissionsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We got here because an artwork update had errors and the user has to try again
|
// We got here because an artwork update had errors and the user has to try again.
|
||||||
if($exception){
|
if($exception){
|
||||||
http_response_code(422);
|
http_response_code(422);
|
||||||
session_unset();
|
session_unset();
|
||||||
|
@ -34,7 +34,7 @@ catch(Exceptions\LoginRequiredException){
|
||||||
Template::RedirectToLogin();
|
Template::RedirectToLogin();
|
||||||
}
|
}
|
||||||
catch(Exceptions\InvalidPermissionsException){
|
catch(Exceptions\InvalidPermissionsException){
|
||||||
Template::Emit403(); // No permissions to edit artwork
|
Template::Emit403(); // No permissions to edit artwork.
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -40,18 +40,16 @@ try{
|
||||||
throw new Exceptions\InvalidPermissionsException();
|
throw new Exceptions\InvalidPermissionsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We got here because an artwork was successfully submitted
|
// We got here because an artwork was successfully submitted.
|
||||||
if($isSaved){
|
if($isSaved){
|
||||||
session_unset();
|
session_unset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We got here because an artwork PATCH operation had errors and the user has to try again
|
// We got here because an artwork PATCH operation had errors and the user has to try again.
|
||||||
if($exception){
|
if($exception){
|
||||||
http_response_code(422);
|
http_response_code(422);
|
||||||
|
|
||||||
// Before we overwrite the original artwork with our new one, restore the old status,
|
// Before we overwrite the original artwork with our new one, restore the old status, because if the new status is 'approved' then it will hide the status form entirely, which will be confusing.
|
||||||
// because if the new status is 'approved' then it will hide the status form entirely,
|
|
||||||
// which will be confusing.
|
|
||||||
$oldStatus = $artwork->Status;
|
$oldStatus = $artwork->Status;
|
||||||
/** @var Artwork $artwork */
|
/** @var Artwork $artwork */
|
||||||
$artwork = $_SESSION['artwork'] ?? $artwork;
|
$artwork = $_SESSION['artwork'] ?? $artwork;
|
||||||
|
|
|
@ -24,8 +24,7 @@ try{
|
||||||
$perPage = ARTWORK_PER_PAGE;
|
$perPage = ARTWORK_PER_PAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're passed string values that are the same as the defaults,
|
// If we're passed string values that are the same as the defaults, set them to null so that we can have cleaner query strings in the navigation footer.
|
||||||
// set them to null so that we can have cleaner query strings in the navigation footer
|
|
||||||
if($sort == Enums\ArtworkSortType::CreatedNewest){
|
if($sort == Enums\ArtworkSortType::CreatedNewest){
|
||||||
$sort = null;
|
$sort = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,14 +18,14 @@ try{
|
||||||
throw new Exceptions\InvalidPermissionsException();
|
throw new Exceptions\InvalidPermissionsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We got here because an artwork was successfully submitted
|
// We got here because an artwork was successfully submitted.
|
||||||
if($isCreated){
|
if($isCreated){
|
||||||
http_response_code(201);
|
http_response_code(201);
|
||||||
$artwork = null;
|
$artwork = null;
|
||||||
session_unset();
|
session_unset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We got here because an artwork submission had errors and the user has to try again
|
// We got here because an artwork submission had errors and the user has to try again.
|
||||||
if($exception){
|
if($exception){
|
||||||
http_response_code(422);
|
http_response_code(422);
|
||||||
session_unset();
|
session_unset();
|
||||||
|
@ -44,7 +44,7 @@ catch(Exceptions\LoginRequiredException){
|
||||||
Template::RedirectToLogin();
|
Template::RedirectToLogin();
|
||||||
}
|
}
|
||||||
catch(Exceptions\InvalidPermissionsException){
|
catch(Exceptions\InvalidPermissionsException){
|
||||||
Template::Emit403(); // No permissions to submit artwork
|
Template::Emit403(); // No permissions to submit artwork.
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -13,7 +13,7 @@ try{
|
||||||
throw new Exceptions\LoginRequiredException();
|
throw new Exceptions\LoginRequiredException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// POSTing a new artwork
|
// POSTing a new artwork.
|
||||||
if($httpMethod == Enums\HttpMethod::Post){
|
if($httpMethod == Enums\HttpMethod::Post){
|
||||||
if(!Session::$User->Benefits->CanUploadArtwork){
|
if(!Session::$User->Benefits->CanUploadArtwork){
|
||||||
throw new Exceptions\InvalidPermissionsException();
|
throw new Exceptions\InvalidPermissionsException();
|
||||||
|
@ -44,7 +44,7 @@ try{
|
||||||
header('Location: /artworks/new');
|
header('Location: /artworks/new');
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUTing an artwork
|
// PUTing an artwork.
|
||||||
if($httpMethod == Enums\HttpMethod::Put){
|
if($httpMethod == Enums\HttpMethod::Put){
|
||||||
$originalArtwork = Artwork::GetByUrl(HttpInput::Str(GET, 'artist-url-name'), HttpInput::Str(GET, 'artwork-url-name'));
|
$originalArtwork = Artwork::GetByUrl(HttpInput::Str(GET, 'artist-url-name'), HttpInput::Str(GET, 'artwork-url-name'));
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ try{
|
||||||
header('Location: ' . $artwork->Url);
|
header('Location: ' . $artwork->Url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PATCHing an artwork
|
// PATCHing an artwork.
|
||||||
if($httpMethod == Enums\HttpMethod::Patch){
|
if($httpMethod == Enums\HttpMethod::Patch){
|
||||||
$artwork = Artwork::GetByUrl(HttpInput::Str(GET, 'artist-url-name'), HttpInput::Str(GET, 'artwork-url-name'));
|
$artwork = Artwork::GetByUrl(HttpInput::Str(GET, 'artist-url-name'), HttpInput::Str(GET, 'artwork-url-name'));
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,11 @@ $author = '';
|
||||||
$authorUrl = '';
|
$authorUrl = '';
|
||||||
|
|
||||||
try{
|
try{
|
||||||
$urlPath = trim(str_replace('.', '', HttpInput::Str(GET, 'url-path') ?? ''), '/'); // Contains the portion of the URL (without query string) that comes after https://standardebooks.org/ebooks/
|
$urlPath = trim(str_replace('.', '', HttpInput::Str(GET, 'url-path') ?? ''), '/'); // Contains the portion of the URL (without query string) that comes after `https://standardebooks.org/ebooks/`.
|
||||||
$wwwFilesystemPath = EBOOKS_DIST_PATH . $urlPath; // Path to the deployed WWW files for this ebook
|
$wwwFilesystemPath = EBOOKS_DIST_PATH . $urlPath; // Path to the deployed www files for this ebook.
|
||||||
|
|
||||||
if($urlPath == '' || mb_stripos($wwwFilesystemPath, EBOOKS_DIST_PATH) !== 0 || !is_dir($wwwFilesystemPath)){
|
if($urlPath == '' || mb_stripos($wwwFilesystemPath, EBOOKS_DIST_PATH) !== 0 || !is_dir($wwwFilesystemPath)){
|
||||||
// Ensure the path exists and that the root is in our www directory
|
// Ensure the path exists and that the root is in our www directory.
|
||||||
throw new Exceptions\AuthorNotFoundException();
|
throw new Exceptions\AuthorNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ try{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything OK, serve the file using Apache.
|
// Everything OK, serve the file using Apache.
|
||||||
// The xsendfile Apache module tells Apache to serve the file, including not-modified or etag headers.
|
// The `xsendfile` Apache module tells Apache to serve the file, including `not-modified` or `etag` headers.
|
||||||
// Much more efficient than reading it in PHP and outputting it that way.
|
// Much more efficient than reading it in PHP and outputting it that way.
|
||||||
header('X-Sendfile: ' . WEB_ROOT . $path);
|
header('X-Sendfile: ' . WEB_ROOT . $path);
|
||||||
header('Content-Type: application/zip');
|
header('Content-Type: application/zip');
|
||||||
|
@ -37,8 +37,7 @@ catch(Exceptions\LoginRequiredException){
|
||||||
else{
|
else{
|
||||||
preg_match('|(^/bulk-downloads/[^/]+?)/|ius', $path, $matches);
|
preg_match('|(^/bulk-downloads/[^/]+?)/|ius', $path, $matches);
|
||||||
if(sizeof($matches) == 2){
|
if(sizeof($matches) == 2){
|
||||||
// If we arrived from the bulk-downloads page,
|
// If we arrived from the bulk-downloads page make the login form redirect to the bulk download root, instead of refreshing directly into a download.
|
||||||
// Make the login form redirect to the bulk download root, instead of refreshing directly into a download
|
|
||||||
Template::RedirectToLogin(true, $matches[1]);
|
Template::RedirectToLogin(true, $matches[1]);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
|
@ -15,7 +15,7 @@ try{
|
||||||
if($collectionUrlName !== null){
|
if($collectionUrlName !== null){
|
||||||
$collections = [];
|
$collections = [];
|
||||||
|
|
||||||
// Get all collections and then find the specific one we're looking for
|
// Get all collections and then find the specific one we're looking for.
|
||||||
try{
|
try{
|
||||||
/** @var array<stdClass> $collections */
|
/** @var array<stdClass> $collections */
|
||||||
$collections = apcu_fetch('bulk-downloads-collections');
|
$collections = apcu_fetch('bulk-downloads-collections');
|
||||||
|
@ -42,7 +42,7 @@ try{
|
||||||
if($authorUrlName !== null){
|
if($authorUrlName !== null){
|
||||||
$authors = [];
|
$authors = [];
|
||||||
|
|
||||||
// Get all authors and then find the specific one we're looking for
|
// Get all authors and then find the specific one we're looking for.
|
||||||
try{
|
try{
|
||||||
/** @var array<stdClass> $collections */
|
/** @var array<stdClass> $collections */
|
||||||
$collections = apcu_fetch('bulk-downloads-authors');
|
$collections = apcu_fetch('bulk-downloads-authors');
|
||||||
|
|
|
@ -8,7 +8,7 @@ try{
|
||||||
$collectionType = '';
|
$collectionType = '';
|
||||||
|
|
||||||
$ebooks = Ebook::GetAllByCollection($collection);
|
$ebooks = Ebook::GetAllByCollection($collection);
|
||||||
// Get the *actual* name of the collection, in case there are accent marks (like "Arsène Lupin")
|
// Get the *actual* name of the collection, in case there are accent marks (like `Arsène Lupin`).
|
||||||
if(sizeof($ebooks) > 0){
|
if(sizeof($ebooks) > 0){
|
||||||
foreach($ebooks[0]->CollectionMemberships as $cm){
|
foreach($ebooks[0]->CollectionMemberships as $cm){
|
||||||
$c = $cm->Collection;
|
$c = $cm->Collection;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?
|
<?
|
||||||
use Safe\DateTimeImmutable;
|
use Safe\DateTimeImmutable;
|
||||||
|
|
||||||
// If the user is not logged in, or has less than some amount of downloads, show a thank-you page
|
// If the user is not logged in, or has less than some amount of downloads, show a thank-you page.
|
||||||
|
|
||||||
$ebook = null;
|
$ebook = null;
|
||||||
$downloadCount = $_COOKIE['download-count'] ?? 0;
|
$downloadCount = $_COOKIE['download-count'] ?? 0;
|
||||||
|
@ -34,7 +34,7 @@ try{
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$showThankYouPage){
|
if(!$showThankYouPage){
|
||||||
// Download the file directly, without showing the thank you page
|
// Download the file directly, without showing the thank you page.
|
||||||
$downloadPath = WEB_ROOT . $downloadUrl;
|
$downloadPath = WEB_ROOT . $downloadUrl;
|
||||||
|
|
||||||
if(!is_file($downloadPath)){
|
if(!is_file($downloadPath)){
|
||||||
|
@ -42,7 +42,7 @@ try{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything OK, serve the file using Apache.
|
// Everything OK, serve the file using Apache.
|
||||||
// The xsendfile Apache module tells Apache to serve the file, including not-modified or etag headers.
|
// The `xsendfile` Apache module tells Apache to serve the file, including `not-modified` or `etag` headers.
|
||||||
// Much more efficient than reading it in PHP and outputting it that way.
|
// Much more efficient than reading it in PHP and outputting it that way.
|
||||||
header('X-Sendfile: ' . $downloadPath);
|
header('X-Sendfile: ' . $downloadPath);
|
||||||
header('Content-Type: ' . $format->GetMimeType());
|
header('Content-Type: ' . $format->GetMimeType());
|
||||||
|
@ -50,7 +50,7 @@ try{
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increment local download count, expires in 2 weeks
|
// Increment local download count, expires in 2 weeks.
|
||||||
$downloadCount++;
|
$downloadCount++;
|
||||||
setcookie('download-count', (string)$downloadCount, ['expires' => intval((new DateTimeImmutable('+2 week'))->format(Enums\DateTimeFormat::UnixTimestamp->value)), 'path' => '/', 'domain' => SITE_DOMAIN, 'secure' => true, 'httponly' => false, 'samesite' => 'Lax']);
|
setcookie('download-count', (string)$downloadCount, ['expires' => intval((new DateTimeImmutable('+2 week'))->format(Enums\DateTimeFormat::UnixTimestamp->value)), 'path' => '/', 'domain' => SITE_DOMAIN, 'secure' => true, 'httponly' => false, 'samesite' => 'Lax']);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,7 @@ try{
|
||||||
$perPage = EBOOKS_PER_PAGE;
|
$perPage = EBOOKS_PER_PAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're passed string values that are the same as the defaults,
|
// If we're passed string values that are the same as the defaults, set them to null so that we can have cleaner query strings in the navigation footer.
|
||||||
// set them to null so that we can have cleaner query strings in the navigation footer
|
|
||||||
if($view === Enums\ViewType::Grid){
|
if($view === Enums\ViewType::Grid){
|
||||||
$view = null;
|
$view = null;
|
||||||
}
|
}
|
||||||
|
@ -99,8 +98,8 @@ catch(Exceptions\PageOutOfBoundsException){
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
catch(Exceptions\AppException $ex){
|
catch(Exceptions\AppException $ex){
|
||||||
// Something very unexpected happened, log and emit 500
|
// Something very unexpected happened, log and emit 500.
|
||||||
http_response_code(500); // Internal server error
|
http_response_code(500); // Internal server error.
|
||||||
Log::WriteErrorLogEntry($ex);
|
Log::WriteErrorLogEntry($ex);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
<?
|
<?
|
||||||
use Safe\DateTimeImmutable;
|
|
||||||
|
|
||||||
$ebooks = [];
|
$ebooks = [];
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use function Safe\preg_match;
|
use function Safe\preg_match;
|
||||||
|
|
||||||
// This page is blocked by HTTP Basic auth.
|
// This page is blocked by HTTP Basic auth.
|
||||||
// Basic authorization is handled in Core.php. By the time we get here, a valid user has a session.
|
// Basic authorization is handled in `Core.php`. By the time we get here, a valid user has a session.
|
||||||
|
|
||||||
$path = HttpInput::Str(GET, 'path') ?? '';
|
$path = HttpInput::Str(GET, 'path') ?? '';
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ try{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything OK, serve the file using Apache.
|
// Everything OK, serve the file using Apache.
|
||||||
// The xsendfile Apache module tells Apache to serve the file, including not-modified or etag headers.
|
// The `xsendfile` Apache module tells Apache to serve the file, including `not-modified` or `etag` headers.
|
||||||
// Much more efficient than reading it in PHP and outputting it that way.
|
// Much more efficient than reading it in PHP and outputting it that way.
|
||||||
header('X-Sendfile: ' . WEB_ROOT . $path);
|
header('X-Sendfile: ' . WEB_ROOT . $path);
|
||||||
|
|
||||||
|
@ -56,8 +56,8 @@ try{
|
||||||
$mime = 'application/xml';
|
$mime = 'application/xml';
|
||||||
|
|
||||||
// Decide on what content-type to serve via HTTP content negotation.
|
// Decide on what content-type to serve via HTTP content negotation.
|
||||||
// If the feed is viewed from a web browser, we will usuall serve application/xml as that's typically what's in the browser's Accept header.
|
// If the feed is viewed from a web browser, we will usuall serve application/xml as that's typically what's in the browser's `Accept` header.
|
||||||
// If the Accept header has application/rss+xml or application/atom+xml then serve that instead, as those are the "technically correct" content types that may be requested by RSS readers.
|
// If the `Accept` header is `application/rss+xml` or `application/atom+xml` then serve that instead, as those are the "technically correct" content types that may be requested by RSS readers.
|
||||||
if(preg_match('/^\/feeds\/opds/', $path)){
|
if(preg_match('/^\/feeds\/opds/', $path)){
|
||||||
$contentType = [
|
$contentType = [
|
||||||
'application/atom+xml',
|
'application/atom+xml',
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
<?
|
<?
|
||||||
use Safe\DateTimeImmutable;
|
|
||||||
|
|
||||||
$ebooks = [];
|
$ebooks = [];
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
<?
|
<?
|
||||||
use Safe\DateTimeImmutable;
|
|
||||||
|
|
||||||
$ebooks = [];
|
$ebooks = [];
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue