diff --git a/public/app/themes/clarity/inc/admin/plugins/wp-document-revisions.php b/public/app/themes/clarity/inc/admin/plugins/wp-document-revisions.php index 3503ab41b..bfb6be294 100644 --- a/public/app/themes/clarity/inc/admin/plugins/wp-document-revisions.php +++ b/public/app/themes/clarity/inc/admin/plugins/wp-document-revisions.php @@ -20,6 +20,7 @@ class WPDocumentRevisions private $home_url = ''; private $site_url = ''; + private $wp_document_revisions = null; public function __construct() { @@ -36,6 +37,8 @@ public function hooks(): void add_filter('document_permalink', [$this, 'filterPermalink'], 10, 2); // Filter using gzip, always return false, let nginx handle gzipping where necessary. add_filter('document_serve_use_gzip', '__return_false', null, 2); + // Filter to retry missing files. + add_filter('get_attached_file', [$this, 'retryFilesNotFound'], 15, 2); } /** @@ -46,7 +49,6 @@ public function hooks(): void * * @return string The filtered permalink. */ - public function filterPermalink(string $link, null|object|array $document) { // Do nothing if the document is published. @@ -57,4 +59,88 @@ public function filterPermalink(string $link, null|object|array $document) // Remove unnecessary `/wp` from the link. return str_replace($this->site_url, $this->home_url, $link); } + + /** + * Extract the date from the file path. + * + * @param string $file The file path. + * @return string|null The date. + */ + private function getDateFromFile(string $file): ?string + { + $matches = []; + preg_match('/\/media\/(\d{4}\/\d{2})\//', $file, $matches); + return $matches[1] ?? null; + } + + /** + * Extract the date from the URL (guid). + * + * @param string $url The URL. + * @return string|null The date. + */ + private function getDateFromUrl(string $url): ?string + { + $matches = []; + preg_match('/\/documents\/(\d{4}\/\d{2})\//', $url, $matches); + return $matches[1] ?? null; + } + + /** + * Retry missing document/file, with date from attachment guid. + * + * This function has been added because files are not being served correctly + * when the published date has been updated. In the function, we check if the + * file exists, if it doesn't the we extract the date from the attachment's + * guid and replace the date in the file path. + * + * @param string $file The file path. + * @param int $attachment_id The attachment ID. + * @return string The file path. + */ + public function retryFilesNotFound($file, $attachment_id) + { + if (!$file) { + return $file; + } + + if (!$this->wp_document_revisions) { + // Make sure we are dealing with a document. + $this->wp_document_revisions = new \WP_Document_Revisions(); + } + + if (!$this->wp_document_revisions->verify_post_type($attachment_id)) { + return $file; + } + + if (is_file($file)) { + return $file; + } + + $attachment = get_post($attachment_id); + + if (!$attachment) { + return $file; + } + + $dates = [ + 'file' => $this->getDateFromFile($file), + 'guid' => $this->getDateFromUrl($attachment->guid), + ]; + + if ($dates['file'] === $dates['guid'] || $dates['file'] === null || $dates['guid'] === null) { + return $file; + } + + // Let's replace the date with the one from the attachment's guid. + $new_file = str_replace($dates['file'], $dates['guid'], $file); + + // If the new file exists, return it. + if (is_file($new_file)) { + return $new_file; + } + + // If the file still doesn't exist, return the original file. + return $file; + } }