From 76aced90ac9af69691791d033e3f40f8a622d921 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sun, 16 May 2021 14:48:04 +0100 Subject: [PATCH 01/29] Add Composer autoloading #248 --- book-database.php | 68 +-- composer.json | 17 + composer.lock | 20 + includes/analytics/analytics-functions.php | 6 +- .../class-analytics.php => src/Analytics.php | 6 +- .../Analytics/Bar_Graph.php | 4 +- .../Analytics/Dataset.php | 4 +- .../Average_Days_Acquired_to_Read.php | 8 +- .../Datasets/Average_Days_Finish_Book.php | 7 +- .../Analytics/Datasets/Average_Rating.php | 7 +- .../Analytics/Datasets/Books_Per_Year.php | 8 +- .../Datasets/Books_Read_Over_Time.php | 8 +- .../Books_Read_by_Publication_Year.php | 8 +- .../Datasets/Edition_Format_Breakdown.php | 8 +- .../Datasets/Edition_Genre_Breakdown.php | 8 +- .../Datasets/Edition_Source_Breakdown.php | 8 +- .../Analytics/Datasets/Editions_Over_Time.php | 8 +- .../Analytics/Datasets/Format_Breakdown.php | 8 +- .../Datasets/Highest_Rated_Books.php | 7 +- .../Datasets/Library_Book_Releases.php | 8 +- .../Datasets/Library_Genre_Breakdown.php | 8 +- .../Analytics/Datasets/Longest_Book_Read.php | 8 +- .../Analytics/Datasets/Lowest_Rated_Books.php | 7 +- .../Analytics/Datasets/Most_Read_Genres.php | 7 +- .../Analytics/Datasets/Number_Books_Added.php | 7 +- .../Number_Different_Authors_Read.php | 7 +- .../Datasets/Number_Different_Series_Read.php | 8 +- .../Number_Distinct_Authors_Added.php | 7 +- .../Analytics/Datasets/Number_Editions.php | 7 +- .../Datasets/Number_Reviews_Written.php | 7 +- .../Datasets/Number_Series_Books_Added.php | 7 +- .../Datasets/Number_Signed_Editions.php | 7 +- .../Datasets/Number_Standalones_Added.php | 7 +- .../Datasets/Number_Standalones_Read.php | 8 +- .../Analytics/Datasets/Pages_Breakdown.php | 8 +- .../Analytics/Datasets/Pages_Read.php | 7 +- .../Analytics/Datasets/Ratings_Breakdown.php | 8 +- .../Analytics/Datasets/Reading_Overview.php | 7 +- .../Analytics/Datasets/Reading_Track.php | 7 +- .../Analytics/Datasets/Reviews_Over_Time.php | 8 +- .../Analytics/Datasets/Reviews_Written.php | 7 +- .../Analytics/Datasets/Shortest_Book_Read.php | 7 +- .../Analytics/Datasets/Terms_Breakdown.php | 7 +- .../Analytics/Graph.php | 4 +- .../Analytics/Horizontal_Bar_Graph.php | 0 .../Analytics/Pie_Chart.php | 0 .../Analytics/Scatter_Chart.php | 0 .../class-author.php => src/Author.php | 4 +- .../Base_Object.php | 4 +- includes/books/class-book.php => src/Book.php | 4 +- .../Book_Author_Relationship.php | 4 +- .../Book_Grid_Query.php | 4 +- .../Book_Layout.php | 4 +- .../class-book-link.php => src/Book_Link.php | 4 +- .../Book_Reviews_Query.php | 4 +- .../Book_Taxonomy.php | 4 +- .../class-book-term.php => src/Book_Term.php | 4 +- .../Book_Term_Relationship.php | 4 +- includes/class-cli.php => src/CLI.php | 4 +- src/Deprecated/class-names.php | 47 ++ .../class-edition.php => src/Edition.php | 4 +- .../class-exception.php => src/Exception.php | 4 +- includes/class-html.php => src/HTML.php | 4 +- .../class-rest-api.php => src/REST_API.php | 4 +- .../REST_API/Controller.php | 4 +- .../REST_API/v1/Analytics.php | 6 +- .../REST_API/v1/Author.php | 4 +- .../REST_API/v1/Book.php | 2 +- .../REST_API/v1/Book_Link.php | 4 +- .../REST_API/v1/Book_Term.php | 4 +- .../REST_API/v1/Edition.php | 4 +- .../REST_API/v1/Reading_Log.php | 4 +- .../REST_API/v1/Retailer.php | 4 +- .../REST_API/v1/Review.php | 4 +- .../REST_API/v1/Series.php | 4 +- .../REST_API/v1/Taxonomy.php | 4 +- .../REST_API/v1/Utility.php | 4 +- .../class-rating.php => src/Rating.php | 4 +- .../Reading_Log.php | 4 +- .../class-retailer.php => src/Retailer.php | 4 +- .../class-review.php => src/Review.php | 4 +- .../series/class-series.php => src/Series.php | 4 +- .../widgets => src/Widgets}/Reading_Log.php | 4 +- {includes/widgets => src/Widgets}/Reviews.php | 4 +- vendor/autoload.php | 7 + vendor/composer/ClassLoader.php | 479 ++++++++++++++++++ vendor/composer/InstalledVersions.php | 283 +++++++++++ vendor/composer/LICENSE | 21 + vendor/composer/autoload_classmap.php | 10 + vendor/composer/autoload_files.php | 10 + vendor/composer/autoload_namespaces.php | 9 + vendor/composer/autoload_psr4.php | 10 + vendor/composer/autoload_real.php | 75 +++ vendor/composer/autoload_static.php | 40 ++ vendor/composer/installed.json | 5 + vendor/composer/installed.php | 24 + vendor/composer/platform_check.php | 26 + 97 files changed, 1326 insertions(+), 262 deletions(-) create mode 100644 composer.json create mode 100644 composer.lock rename includes/class-analytics.php => src/Analytics.php (99%) rename includes/analytics/graphs/class-bar-graph.php => src/Analytics/Bar_Graph.php (88%) rename includes/analytics/abstract-class-dataset.php => src/Analytics/Dataset.php (98%) rename includes/analytics/datasets/class-average-days-acquired-to-read.php => src/Analytics/Datasets/Average_Days_Acquired_to_Read.php (87%) rename includes/analytics/datasets/class-average-days-finish-book.php => src/Analytics/Datasets/Average_Days_Finish_Book.php (85%) rename includes/analytics/datasets/class-average-rating.php => src/Analytics/Datasets/Average_Rating.php (86%) rename includes/analytics/datasets/class-books-per-year.php => src/Analytics/Datasets/Books_Per_Year.php (94%) rename includes/analytics/datasets/class-books-read-over-time.php => src/Analytics/Datasets/Books_Read_Over_Time.php (95%) rename includes/analytics/datasets/class-books-read-by-publication-year.php => src/Analytics/Datasets/Books_Read_by_Publication_Year.php (93%) rename includes/analytics/datasets/class-edition-format-breakdown.php => src/Analytics/Datasets/Edition_Format_Breakdown.php (90%) rename includes/analytics/datasets/class-edition-genre-breakdown.php => src/Analytics/Datasets/Edition_Genre_Breakdown.php (90%) rename includes/analytics/datasets/class-edition-source-breakdown.php => src/Analytics/Datasets/Edition_Source_Breakdown.php (89%) rename includes/analytics/datasets/class-editions-over-time.php => src/Analytics/Datasets/Editions_Over_Time.php (94%) rename includes/analytics/datasets/class-format-breakdown.php => src/Analytics/Datasets/Format_Breakdown.php (91%) rename includes/analytics/datasets/class-highest-rated-books.php => src/Analytics/Datasets/Highest_Rated_Books.php (91%) rename includes/analytics/datasets/class-library-book-releases.php => src/Analytics/Datasets/Library_Book_Releases.php (90%) rename includes/analytics/datasets/class-library-genre-breakdown.php => src/Analytics/Datasets/Library_Genre_Breakdown.php (90%) rename includes/analytics/datasets/class-longest-book-read.php => src/Analytics/Datasets/Longest_Book_Read.php (62%) rename includes/analytics/datasets/class-lowest-rated-books.php => src/Analytics/Datasets/Lowest_Rated_Books.php (92%) rename includes/analytics/datasets/class-most-read-genres.php => src/Analytics/Datasets/Most_Read_Genres.php (94%) rename includes/analytics/datasets/class-number-books-added.php => src/Analytics/Datasets/Number_Books_Added.php (82%) rename includes/analytics/datasets/class-number-different-authors-read.php => src/Analytics/Datasets/Number_Different_Authors_Read.php (88%) rename includes/analytics/datasets/class-number-different-series-read.php => src/Analytics/Datasets/Number_Different_Series_Read.php (88%) rename includes/analytics/datasets/class-number-distinct-authors-added.php => src/Analytics/Datasets/Number_Distinct_Authors_Added.php (86%) rename includes/analytics/datasets/class-number-editions.php => src/Analytics/Datasets/Number_Editions.php (84%) rename includes/analytics/datasets/class-number-reviews-written.php => src/Analytics/Datasets/Number_Reviews_Written.php (85%) rename includes/analytics/datasets/class-number-series-books-added.php => src/Analytics/Datasets/Number_Series_Books_Added.php (83%) rename includes/analytics/datasets/class-number-signed-editions.php => src/Analytics/Datasets/Number_Signed_Editions.php (85%) rename includes/analytics/datasets/class-number-standalones-added.php => src/Analytics/Datasets/Number_Standalones_Added.php (83%) rename includes/analytics/datasets/class-number-standalones-read.php => src/Analytics/Datasets/Number_Standalones_Read.php (87%) rename includes/analytics/datasets/class-pages-breakdown.php => src/Analytics/Datasets/Pages_Breakdown.php (90%) rename includes/analytics/datasets/class-pages-read.php => src/Analytics/Datasets/Pages_Read.php (87%) rename includes/analytics/datasets/class-ratings-breakdown.php => src/Analytics/Datasets/Ratings_Breakdown.php (90%) rename includes/analytics/datasets/class-reading-overview.php => src/Analytics/Datasets/Reading_Overview.php (95%) rename includes/analytics/datasets/class-reading-track.php => src/Analytics/Datasets/Reading_Track.php (91%) rename includes/analytics/datasets/class-reviews-over-time.php => src/Analytics/Datasets/Reviews_Over_Time.php (94%) rename includes/analytics/datasets/class-reviews-written.php => src/Analytics/Datasets/Reviews_Written.php (94%) rename includes/analytics/datasets/class-shortest-book-read.php => src/Analytics/Datasets/Shortest_Book_Read.php (92%) rename includes/analytics/datasets/class-terms-breakdown.php => src/Analytics/Datasets/Terms_Breakdown.php (92%) rename includes/analytics/graphs/class-graph.php => src/Analytics/Graph.php (99%) rename includes/analytics/graphs/class-horizontal-bar-graph.php => src/Analytics/Horizontal_Bar_Graph.php (100%) rename includes/analytics/graphs/class-pie-chart.php => src/Analytics/Pie_Chart.php (100%) rename includes/analytics/graphs/class-scatter-chart.php => src/Analytics/Scatter_Chart.php (100%) rename includes/authors/class-author.php => src/Author.php (97%) rename includes/abstract-class-base-object.php => src/Base_Object.php (97%) rename includes/books/class-book.php => src/Book.php (99%) rename includes/book-author-relationships/class-book-author-relationship.php => src/Book_Author_Relationship.php (91%) rename includes/class-book-grid-query.php => src/Book_Grid_Query.php (98%) rename includes/books/class-book-layout.php => src/Book_Layout.php (99%) rename includes/book-links/class-book-link.php => src/Book_Link.php (96%) rename includes/class-book-reviews-query.php => src/Book_Reviews_Query.php (99%) rename includes/book-taxonomies/class-book-taxonomy.php => src/Book_Taxonomy.php (92%) rename includes/book-terms/class-book-term.php => src/Book_Term.php (96%) rename includes/book-term-relationships/class-book-term-relationship.php => src/Book_Term_Relationship.php (91%) rename includes/class-cli.php => src/CLI.php (98%) create mode 100644 src/Deprecated/class-names.php rename includes/editions/class-edition.php => src/Edition.php (97%) rename includes/class-exception.php => src/Exception.php (94%) rename includes/class-html.php => src/HTML.php (98%) rename includes/rest-api/class-rest-api.php => src/REST_API.php (95%) rename includes/rest-api/abstract-class-controller.php => src/REST_API/Controller.php (94%) rename includes/rest-api/v1/class-analytics-controller.php => src/REST_API/v1/Analytics.php (97%) rename includes/rest-api/v1/class-author-controller.php => src/REST_API/v1/Author.php (97%) rename includes/rest-api/v1/class-book-controller.php => src/REST_API/v1/Book.php (99%) rename includes/rest-api/v1/class-book-link-controller.php => src/REST_API/v1/Book_Link.php (99%) rename includes/rest-api/v1/class-book-term-controller.php => src/REST_API/v1/Book_Term.php (97%) rename includes/rest-api/v1/class-edition-controller.php => src/REST_API/v1/Edition.php (99%) rename includes/rest-api/v1/class-reading-log-controller.php => src/REST_API/v1/Reading_Log.php (99%) rename includes/rest-api/v1/class-retailer-controller.php => src/REST_API/v1/Retailer.php (99%) rename includes/rest-api/v1/class-review-controller.php => src/REST_API/v1/Review.php (99%) rename includes/rest-api/v1/class-series-controller.php => src/REST_API/v1/Series.php (99%) rename includes/rest-api/v1/class-taxonomy-controller.php => src/REST_API/v1/Taxonomy.php (98%) rename includes/rest-api/v1/class-utility-controller.php => src/REST_API/v1/Utility.php (96%) rename includes/ratings/class-rating.php => src/Rating.php (99%) rename includes/reading-logs/class-reading-log.php => src/Reading_Log.php (98%) rename includes/retailers/class-retailer.php => src/Retailer.php (95%) rename includes/reviews/class-review.php => src/Review.php (99%) rename includes/series/class-series.php => src/Series.php (98%) rename {includes/widgets => src/Widgets}/Reading_Log.php (99%) rename {includes/widgets => src/Widgets}/Reviews.php (99%) create mode 100644 vendor/autoload.php create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/InstalledVersions.php create mode 100644 vendor/composer/LICENSE create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_files.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/autoload_static.php create mode 100644 vendor/composer/installed.json create mode 100644 vendor/composer/installed.php create mode 100644 vendor/composer/platform_check.php diff --git a/book-database.php b/book-database.php index 5e1f66ab..c4086b43 100644 --- a/book-database.php +++ b/book-database.php @@ -151,9 +151,7 @@ private function setup_files() { * Include global files */ private function include_files() { - - require_once BDB_DIR . 'includes/abstract-class-base-object.php'; - require_once BDB_DIR . 'includes/class-exception.php'; + require_once BDB_DIR . 'vendor/autoload.php'; // Database engine require_once BDB_DIR . 'includes/database/engine/base.php'; @@ -237,127 +235,63 @@ private function include_files() { require_once BDB_DIR . 'includes/database/series/class-series-query.php'; // Analytics - require_once BDB_DIR . 'includes/analytics/abstract-class-dataset.php'; require_once BDB_DIR . 'includes/analytics/analytics-functions.php'; - require_once BDB_DIR . 'includes/analytics/graphs/class-graph.php'; - require_once BDB_DIR . 'includes/analytics/graphs/class-bar-graph.php'; - require_once BDB_DIR . 'includes/analytics/graphs/class-horizontal-bar-graph.php'; - require_once BDB_DIR . 'includes/analytics/graphs/class-pie-chart.php'; - require_once BDB_DIR . 'includes/analytics/graphs/class-scatter-chart.php'; - $datasets = array( - 'reading-overview', 'number-different-series-read', 'number-standalones-read', 'pages-read', - 'number-different-authors-read', 'number-reviews-written', 'average-rating', 'reading-track', - 'books-per-year', 'most-read-genres', 'pages-breakdown', 'ratings-breakdown', 'highest-rated-books', - 'lowest-rated-books', 'format-breakdown', 'average-days-finish-book', 'shortest-book-read', 'longest-book-read', - 'number-editions', 'edition-format-breakdown', 'editions-over-time', 'reviews-over-time', 'reviews-written', - 'books-read-over-time', 'terms-breakdown', 'number-signed-editions', 'edition-genre-breakdown', - 'edition-source-breakdown', 'average-days-acquired-to-read', 'number-books-added', 'number-series-books-added', - 'number-standalones-added', 'number-distinct-authors-added', 'library-genre-breakdown', 'library-book-releases', - 'books-read-by-publication-year', - ); - foreach ( $datasets as $dataset ) { - if ( file_exists( BDB_DIR . 'includes/analytics/datasets/class-' . $dataset . '.php' ) ) { - require_once BDB_DIR . 'includes/analytics/datasets/class-' . $dataset . '.php'; - } - } // Authors - require_once BDB_DIR . 'includes/authors/class-author.php'; require_once BDB_DIR . 'includes/authors/author-functions.php'; // Blocks require_once BDB_DIR . 'includes/blocks.php'; // Book Author Relationships - require_once BDB_DIR . 'includes/book-author-relationships/class-book-author-relationship.php'; require_once BDB_DIR . 'includes/book-author-relationships/book-author-relationship-actions.php'; require_once BDB_DIR . 'includes/book-author-relationships/book-author-relationship-functions.php'; // Books - require_once BDB_DIR . 'includes/books/class-book.php'; - require_once BDB_DIR . 'includes/books/class-book-layout.php'; require_once BDB_DIR . 'includes/books/book-functions.php'; require_once BDB_DIR . 'includes/books/book-layout-functions.php'; require_once BDB_DIR . 'includes/books/book-meta.php'; // Book Links - require_once BDB_DIR . 'includes/book-links/class-book-link.php'; require_once BDB_DIR . 'includes/book-links/book-link-functions.php'; // Book Taxonomies - require_once BDB_DIR . 'includes/book-taxonomies/class-book-taxonomy.php'; require_once BDB_DIR . 'includes/book-taxonomies/book-taxonomy-functions.php'; // Book Term Relationships - require_once BDB_DIR . 'includes/book-term-relationships/class-book-term-relationship.php'; require_once BDB_DIR . 'includes/book-term-relationships/book-term-relationship-actions.php'; require_once BDB_DIR . 'includes/book-term-relationships/book-term-relationship-functions.php'; // Book Terms - require_once BDB_DIR . 'includes/book-terms/class-book-term.php'; require_once BDB_DIR . 'includes/book-terms/book-term-functions.php'; // Editions - require_once BDB_DIR . 'includes/editions/class-edition.php'; require_once BDB_DIR . 'includes/editions/edition-functions.php'; // Ratings - require_once BDB_DIR . 'includes/ratings/class-rating.php'; require_once BDB_DIR . 'includes/ratings/rating-functions.php'; // Reading Logs - require_once BDB_DIR . 'includes/reading-logs/class-reading-log.php'; require_once BDB_DIR . 'includes/reading-logs/reading-log-functions.php'; // Retailers - require_once BDB_DIR . 'includes/retailers/class-retailer.php'; require_once BDB_DIR . 'includes/retailers/retailer-functions.php'; // Reviews - require_once BDB_DIR . 'includes/reviews/class-review.php'; require_once BDB_DIR . 'includes/reviews/review-actions.php'; require_once BDB_DIR . 'includes/reviews/review-functions.php'; require_once BDB_DIR . 'includes/reviews/review-meta.php'; // Series - require_once BDB_DIR . 'includes/series/class-series.php'; require_once BDB_DIR . 'includes/series/series-functions.php'; - // REST API - require_once BDB_DIR . 'includes/rest-api/class-rest-api.php'; - require_once BDB_DIR . 'includes/rest-api/abstract-class-controller.php'; - require_once BDB_DIR . 'includes/rest-api/v1/class-analytics-controller.php'; - require_once BDB_DIR . 'includes/rest-api/v1/class-author-controller.php'; - require_once BDB_DIR . 'includes/rest-api/v1/class-book-controller.php'; - require_once BDB_DIR . 'includes/rest-api/v1/class-book-link-controller.php'; - require_once BDB_DIR . 'includes/rest-api/v1/class-book-term-controller.php'; - require_once BDB_DIR . 'includes/rest-api/v1/class-edition-controller.php'; - require_once BDB_DIR . 'includes/rest-api/v1/class-reading-log-controller.php'; - require_once BDB_DIR . 'includes/rest-api/v1/class-retailer-controller.php'; - require_once BDB_DIR . 'includes/rest-api/v1/class-review-controller.php'; - require_once BDB_DIR . 'includes/rest-api/v1/class-series-controller.php'; - require_once BDB_DIR . 'includes/rest-api/v1/class-taxonomy-controller.php'; - require_once BDB_DIR . 'includes/rest-api/v1/class-utility-controller.php'; - - // Widgets - require_once BDB_DIR . 'includes/widgets/Reading_Log.php'; - require_once BDB_DIR . 'includes/widgets/Reviews.php'; - // Misc. require_once BDB_DIR . 'includes/capabilities.php'; - require_once BDB_DIR . 'includes/class-analytics.php'; - require_once BDB_DIR . 'includes/class-book-reviews-query.php'; - require_once BDB_DIR . 'includes/class-book-grid-query.php'; - require_once BDB_DIR . 'includes/class-html.php'; require_once BDB_DIR . 'includes/misc-functions.php'; require_once BDB_DIR . 'includes/rewrites.php'; require_once BDB_DIR . 'includes/shortcodes.php'; require_once BDB_DIR . 'includes/template-functions.php'; - if ( defined( 'WP_CLI' ) && WP_CLI ) { - require_once BDB_DIR . 'includes/class-cli.php'; - } - } /** diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..7672405a --- /dev/null +++ b/composer.json @@ -0,0 +1,17 @@ +{ + "name": "ashleyfae/book-database", + "type": "wordpress-plugin", + "license": "GPL-2.0-or-later", + "description": "Maintain a database of books and reviews.", + "autoload": { + "files": [ + "src/Deprecated/class-names.php" + ], + "psr-4": { + "Book_Database\\": "src/" + } + }, + "require": { + "php": "^7.0|^8.0" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..81965b6d --- /dev/null +++ b/composer.lock @@ -0,0 +1,20 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "532d26738cf17785a60bfdb5d3697811", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^7.0|^8.0" + }, + "platform-dev": [], + "plugin-api-version": "2.0.0" +} diff --git a/includes/analytics/analytics-functions.php b/includes/analytics/analytics-functions.php index 2d167ce7..3f422cba 100644 --- a/includes/analytics/analytics-functions.php +++ b/includes/analytics/analytics-functions.php @@ -169,8 +169,7 @@ function get_date_filter_range( $option = '', $format = 'Y-m-d H:i:s' ) { * @throws Exception */ function get_dataset_value( $dataset, $args = array() ) { - - $class_name = __NAMESPACE__ . '\\' . $dataset; + $class_name = __NAMESPACE__ . '\\Datasets\\' . $dataset; if ( class_exists( $class_name ) ) { $dataset = new $class_name( $args ); @@ -182,5 +181,4 @@ function get_dataset_value( $dataset, $args = array() ) { } throw new Exception( 'invalid-dataset', __( 'Invalid dataset.', 'book-database' ), 404 ); - -} \ No newline at end of file +} diff --git a/includes/class-analytics.php b/src/Analytics.php similarity index 99% rename from includes/class-analytics.php rename to src/Analytics.php index 2af7d44c..fc8efdea 100644 --- a/includes/class-analytics.php +++ b/src/Analytics.php @@ -3,7 +3,7 @@ * Reading & Review Analytics * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -254,7 +254,7 @@ public function get_number_rereads() { /** * Get the number of pages read * - * @see Analytics\Pages_Read + * @see \Book_Database\Analytics\Datasets\Pages_Read * * @return int */ @@ -682,4 +682,4 @@ public function get_read_not_reviewed() { } -} \ No newline at end of file +} diff --git a/includes/analytics/graphs/class-bar-graph.php b/src/Analytics/Bar_Graph.php similarity index 88% rename from includes/analytics/graphs/class-bar-graph.php rename to src/Analytics/Bar_Graph.php index a682e940..f4c02219 100644 --- a/includes/analytics/graphs/class-bar-graph.php +++ b/src/Analytics/Bar_Graph.php @@ -3,7 +3,7 @@ * Bar Graph * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -26,4 +26,4 @@ class Bar_Graph extends Graph { */ protected $series_type = 'ColumnSeries'; -} \ No newline at end of file +} diff --git a/includes/analytics/abstract-class-dataset.php b/src/Analytics/Dataset.php similarity index 98% rename from includes/analytics/abstract-class-dataset.php rename to src/Analytics/Dataset.php index 088a2a4c..cfe13070 100644 --- a/includes/analytics/abstract-class-dataset.php +++ b/src/Analytics/Dataset.php @@ -3,7 +3,7 @@ * Base Dataset Class * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -155,4 +155,4 @@ protected function log( $message, $method ) { } } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-average-days-acquired-to-read.php b/src/Analytics/Datasets/Average_Days_Acquired_to_Read.php similarity index 87% rename from includes/analytics/datasets/class-average-days-acquired-to-read.php rename to src/Analytics/Datasets/Average_Days_Acquired_to_Read.php index 15f11d80..35b0227a 100644 --- a/includes/analytics/datasets/class-average-days-acquired-to-read.php +++ b/src/Analytics/Datasets/Average_Days_Acquired_to_Read.php @@ -3,12 +3,14 @@ * Dataset: Average number of days between acquiring a book and starting to read a book * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; +use function absint; use function Book_Database\book_database; /** @@ -44,4 +46,4 @@ protected function _get_dataset() { return is_null( $days ) ? '–' : absint( $days ); } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-average-days-finish-book.php b/src/Analytics/Datasets/Average_Days_Finish_Book.php similarity index 85% rename from includes/analytics/datasets/class-average-days-finish-book.php rename to src/Analytics/Datasets/Average_Days_Finish_Book.php index 25ff9b8d..bea0fba6 100644 --- a/includes/analytics/datasets/class-average-days-finish-book.php +++ b/src/Analytics/Datasets/Average_Days_Finish_Book.php @@ -3,12 +3,13 @@ * Dataset: Average number of days to finish a book * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -34,4 +35,4 @@ protected function _get_dataset() { return $this->get_db()->get_var( $query ); } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-average-rating.php b/src/Analytics/Datasets/Average_Rating.php similarity index 86% rename from includes/analytics/datasets/class-average-rating.php rename to src/Analytics/Datasets/Average_Rating.php index 66613393..348a2ff3 100644 --- a/includes/analytics/datasets/class-average-rating.php +++ b/src/Analytics/Datasets/Average_Rating.php @@ -3,12 +3,13 @@ * class-average-rating.php * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -45,4 +46,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-books-per-year.php b/src/Analytics/Datasets/Books_Per_Year.php similarity index 94% rename from includes/analytics/datasets/class-books-per-year.php rename to src/Analytics/Datasets/Books_Per_Year.php index 5b6d621a..24212a13 100644 --- a/includes/analytics/datasets/class-books-per-year.php +++ b/src/Analytics/Datasets/Books_Per_Year.php @@ -3,12 +3,14 @@ * class-books-per-year.php * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Bar_Graph; +use Book_Database\Analytics\Dataset; use DateInterval; use DatePeriod; use DateTime; @@ -121,4 +123,4 @@ protected function _get_dataset() { return $graph->get_args(); } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-books-read-over-time.php b/src/Analytics/Datasets/Books_Read_Over_Time.php similarity index 95% rename from includes/analytics/datasets/class-books-read-over-time.php rename to src/Analytics/Datasets/Books_Read_Over_Time.php index 7c0db776..3f372b23 100644 --- a/includes/analytics/datasets/class-books-read-over-time.php +++ b/src/Analytics/Datasets/Books_Read_Over_Time.php @@ -3,12 +3,14 @@ * Dataset: Books Read Over Time * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Bar_Graph; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -137,4 +139,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-books-read-by-publication-year.php b/src/Analytics/Datasets/Books_Read_by_Publication_Year.php similarity index 93% rename from includes/analytics/datasets/class-books-read-by-publication-year.php rename to src/Analytics/Datasets/Books_Read_by_Publication_Year.php index 55897436..4e25f3c7 100644 --- a/includes/analytics/datasets/class-books-read-by-publication-year.php +++ b/src/Analytics/Datasets/Books_Read_by_Publication_Year.php @@ -3,12 +3,14 @@ * Dataset: Books Read by Publication Year * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; +use Book_Database\Analytics\Scatter_Chart; use function Book_Database\book_database; /** @@ -110,4 +112,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-edition-format-breakdown.php b/src/Analytics/Datasets/Edition_Format_Breakdown.php similarity index 90% rename from includes/analytics/datasets/class-edition-format-breakdown.php rename to src/Analytics/Datasets/Edition_Format_Breakdown.php index 7b17dd85..612e5612 100644 --- a/includes/analytics/datasets/class-edition-format-breakdown.php +++ b/src/Analytics/Datasets/Edition_Format_Breakdown.php @@ -3,12 +3,14 @@ * Dataset: Edition Format Breakdown * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; +use Book_Database\Analytics\Pie_Chart; use function Book_Database\book_database; use function Book_Database\get_book_formats; @@ -78,4 +80,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-edition-genre-breakdown.php b/src/Analytics/Datasets/Edition_Genre_Breakdown.php similarity index 90% rename from includes/analytics/datasets/class-edition-genre-breakdown.php rename to src/Analytics/Datasets/Edition_Genre_Breakdown.php index d2c6a610..01f15989 100644 --- a/includes/analytics/datasets/class-edition-genre-breakdown.php +++ b/src/Analytics/Datasets/Edition_Genre_Breakdown.php @@ -3,12 +3,14 @@ * Dataset: Edition Genre Breakdown * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; +use Book_Database\Analytics\Pie_Chart; use function Book_Database\book_database; /** @@ -68,4 +70,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-edition-source-breakdown.php b/src/Analytics/Datasets/Edition_Source_Breakdown.php similarity index 89% rename from includes/analytics/datasets/class-edition-source-breakdown.php rename to src/Analytics/Datasets/Edition_Source_Breakdown.php index 43d62aca..bacd96ca 100644 --- a/includes/analytics/datasets/class-edition-source-breakdown.php +++ b/src/Analytics/Datasets/Edition_Source_Breakdown.php @@ -3,12 +3,14 @@ * Dataset: Edition Source Breakdown * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; +use Book_Database\Analytics\Pie_Chart; use function Book_Database\book_database; /** @@ -63,4 +65,4 @@ protected function _get_dataset() { return $chart->get_args(); } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-editions-over-time.php b/src/Analytics/Datasets/Editions_Over_Time.php similarity index 94% rename from includes/analytics/datasets/class-editions-over-time.php rename to src/Analytics/Datasets/Editions_Over_Time.php index 50074927..492229bd 100644 --- a/includes/analytics/datasets/class-editions-over-time.php +++ b/src/Analytics/Datasets/Editions_Over_Time.php @@ -3,12 +3,14 @@ * Dataset: Editions Acquired Over Time * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Bar_Graph; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -130,4 +132,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-format-breakdown.php b/src/Analytics/Datasets/Format_Breakdown.php similarity index 91% rename from includes/analytics/datasets/class-format-breakdown.php rename to src/Analytics/Datasets/Format_Breakdown.php index 7ef3db3a..dc8fd6b8 100644 --- a/includes/analytics/datasets/class-format-breakdown.php +++ b/src/Analytics/Datasets/Format_Breakdown.php @@ -3,12 +3,14 @@ * Dataset: Format Breakdown * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; +use Book_Database\Analytics\Pie_Chart; use function Book_Database\book_database; use function Book_Database\get_book_formats; @@ -82,4 +84,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-highest-rated-books.php b/src/Analytics/Datasets/Highest_Rated_Books.php similarity index 91% rename from includes/analytics/datasets/class-highest-rated-books.php rename to src/Analytics/Datasets/Highest_Rated_Books.php index f668d5a4..32d54e5d 100644 --- a/includes/analytics/datasets/class-highest-rated-books.php +++ b/src/Analytics/Datasets/Highest_Rated_Books.php @@ -3,12 +3,13 @@ * Dataset: Highest Rated Books * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use Book_Database\Rating; use function Book_Database\book_database; use function Book_Database\format_date; @@ -53,4 +54,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-library-book-releases.php b/src/Analytics/Datasets/Library_Book_Releases.php similarity index 90% rename from includes/analytics/datasets/class-library-book-releases.php rename to src/Analytics/Datasets/Library_Book_Releases.php index 7e6e78ef..4f101373 100644 --- a/includes/analytics/datasets/class-library-book-releases.php +++ b/src/Analytics/Datasets/Library_Book_Releases.php @@ -3,14 +3,16 @@ * Dataset: Books Releasing During This Period * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; use function Book_Database\format_date; +use function wp_get_attachment_image_url; /** * Class Library_Book_Releases @@ -55,4 +57,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-library-genre-breakdown.php b/src/Analytics/Datasets/Library_Genre_Breakdown.php similarity index 90% rename from includes/analytics/datasets/class-library-genre-breakdown.php rename to src/Analytics/Datasets/Library_Genre_Breakdown.php index 50cedc1f..4edf8395 100644 --- a/includes/analytics/datasets/class-library-genre-breakdown.php +++ b/src/Analytics/Datasets/Library_Genre_Breakdown.php @@ -3,12 +3,14 @@ * Dataset: Library Genre Breakdown * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; +use Book_Database\Analytics\Pie_Chart; use function Book_Database\book_database; /** @@ -67,4 +69,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-longest-book-read.php b/src/Analytics/Datasets/Longest_Book_Read.php similarity index 62% rename from includes/analytics/datasets/class-longest-book-read.php rename to src/Analytics/Datasets/Longest_Book_Read.php index c65cc6d0..2a3af60b 100644 --- a/includes/analytics/datasets/class-longest-book-read.php +++ b/src/Analytics/Datasets/Longest_Book_Read.php @@ -3,11 +3,13 @@ * Dataset: Longest book read * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; + +use Book_Database\Analytics\Datasets\Shortest_Book_Read; /** * Class Longest_Book_Read @@ -18,4 +20,4 @@ class Longest_Book_Read extends Shortest_Book_Read { protected $orderby = 'DESC'; -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-lowest-rated-books.php b/src/Analytics/Datasets/Lowest_Rated_Books.php similarity index 92% rename from includes/analytics/datasets/class-lowest-rated-books.php rename to src/Analytics/Datasets/Lowest_Rated_Books.php index 4e0425c8..fff57b78 100644 --- a/includes/analytics/datasets/class-lowest-rated-books.php +++ b/src/Analytics/Datasets/Lowest_Rated_Books.php @@ -3,12 +3,13 @@ * Dataset: Lowest Rated Books * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use Book_Database\Rating; use function Book_Database\book_database; use function Book_Database\format_date; @@ -64,4 +65,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-most-read-genres.php b/src/Analytics/Datasets/Most_Read_Genres.php similarity index 94% rename from includes/analytics/datasets/class-most-read-genres.php rename to src/Analytics/Datasets/Most_Read_Genres.php index b17b14cb..18489759 100644 --- a/includes/analytics/datasets/class-most-read-genres.php +++ b/src/Analytics/Datasets/Most_Read_Genres.php @@ -3,12 +3,13 @@ * Dataset: Most Read Genres * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -78,4 +79,4 @@ protected function _get_dataset() { return $results; } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-number-books-added.php b/src/Analytics/Datasets/Number_Books_Added.php similarity index 82% rename from includes/analytics/datasets/class-number-books-added.php rename to src/Analytics/Datasets/Number_Books_Added.php index e8668316..43c0fe7d 100644 --- a/includes/analytics/datasets/class-number-books-added.php +++ b/src/Analytics/Datasets/Number_Books_Added.php @@ -3,12 +3,13 @@ * Dataset: Number of Books Added * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -36,4 +37,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-number-different-authors-read.php b/src/Analytics/Datasets/Number_Different_Authors_Read.php similarity index 88% rename from includes/analytics/datasets/class-number-different-authors-read.php rename to src/Analytics/Datasets/Number_Different_Authors_Read.php index df4851da..0d12a028 100644 --- a/includes/analytics/datasets/class-number-different-authors-read.php +++ b/src/Analytics/Datasets/Number_Different_Authors_Read.php @@ -3,12 +3,13 @@ * Dataset: Number of Different Authors * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -42,4 +43,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-number-different-series-read.php b/src/Analytics/Datasets/Number_Different_Series_Read.php similarity index 88% rename from includes/analytics/datasets/class-number-different-series-read.php rename to src/Analytics/Datasets/Number_Different_Series_Read.php index c8e80dd5..9504340e 100644 --- a/includes/analytics/datasets/class-number-different-series-read.php +++ b/src/Analytics/Datasets/Number_Different_Series_Read.php @@ -3,13 +3,13 @@ * Dataset: Number of Different Series Read * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; - +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -44,4 +44,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-number-distinct-authors-added.php b/src/Analytics/Datasets/Number_Distinct_Authors_Added.php similarity index 86% rename from includes/analytics/datasets/class-number-distinct-authors-added.php rename to src/Analytics/Datasets/Number_Distinct_Authors_Added.php index 28af2e7e..dd24f67d 100644 --- a/includes/analytics/datasets/class-number-distinct-authors-added.php +++ b/src/Analytics/Datasets/Number_Distinct_Authors_Added.php @@ -3,12 +3,13 @@ * Dataset: Number of Distinct Authors Added * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -38,4 +39,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-number-editions.php b/src/Analytics/Datasets/Number_Editions.php similarity index 84% rename from includes/analytics/datasets/class-number-editions.php rename to src/Analytics/Datasets/Number_Editions.php index a43e3e13..2abb1de5 100644 --- a/includes/analytics/datasets/class-number-editions.php +++ b/src/Analytics/Datasets/Number_Editions.php @@ -3,12 +3,13 @@ * Dataset: Number Editions Added * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -40,4 +41,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-number-reviews-written.php b/src/Analytics/Datasets/Number_Reviews_Written.php similarity index 85% rename from includes/analytics/datasets/class-number-reviews-written.php rename to src/Analytics/Datasets/Number_Reviews_Written.php index b06f7ed4..94f3bbb0 100644 --- a/includes/analytics/datasets/class-number-reviews-written.php +++ b/src/Analytics/Datasets/Number_Reviews_Written.php @@ -3,12 +3,13 @@ * Dataset: Number of Reviews Written * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -40,4 +41,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-number-series-books-added.php b/src/Analytics/Datasets/Number_Series_Books_Added.php similarity index 83% rename from includes/analytics/datasets/class-number-series-books-added.php rename to src/Analytics/Datasets/Number_Series_Books_Added.php index aaea82ef..25602d14 100644 --- a/includes/analytics/datasets/class-number-series-books-added.php +++ b/src/Analytics/Datasets/Number_Series_Books_Added.php @@ -3,12 +3,13 @@ * Dataset: Number of Series Books Added * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -36,4 +37,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-number-signed-editions.php b/src/Analytics/Datasets/Number_Signed_Editions.php similarity index 85% rename from includes/analytics/datasets/class-number-signed-editions.php rename to src/Analytics/Datasets/Number_Signed_Editions.php index 7c5fa881..f80fdbb1 100644 --- a/includes/analytics/datasets/class-number-signed-editions.php +++ b/src/Analytics/Datasets/Number_Signed_Editions.php @@ -3,12 +3,13 @@ * Dataset: Number Signed Editions Added * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -41,4 +42,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-number-standalones-added.php b/src/Analytics/Datasets/Number_Standalones_Added.php similarity index 83% rename from includes/analytics/datasets/class-number-standalones-added.php rename to src/Analytics/Datasets/Number_Standalones_Added.php index d629b776..e8fac498 100644 --- a/includes/analytics/datasets/class-number-standalones-added.php +++ b/src/Analytics/Datasets/Number_Standalones_Added.php @@ -3,12 +3,13 @@ * Dataset: Number of Standalones Added * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -36,4 +37,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-number-standalones-read.php b/src/Analytics/Datasets/Number_Standalones_Read.php similarity index 87% rename from includes/analytics/datasets/class-number-standalones-read.php rename to src/Analytics/Datasets/Number_Standalones_Read.php index 8fb549fb..531dcacd 100644 --- a/includes/analytics/datasets/class-number-standalones-read.php +++ b/src/Analytics/Datasets/Number_Standalones_Read.php @@ -3,13 +3,13 @@ * Dataset: Number of Standalones Read * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; - +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -44,4 +44,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-pages-breakdown.php b/src/Analytics/Datasets/Pages_Breakdown.php similarity index 90% rename from includes/analytics/datasets/class-pages-breakdown.php rename to src/Analytics/Datasets/Pages_Breakdown.php index af63d805..4b51e692 100644 --- a/includes/analytics/datasets/class-pages-breakdown.php +++ b/src/Analytics/Datasets/Pages_Breakdown.php @@ -3,12 +3,14 @@ * Dataset: Pages Breakdown * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; +use Book_Database\Analytics\Pie_Chart; use function Book_Database\book_database; /** @@ -73,4 +75,4 @@ protected function _get_dataset() { return $chart->get_args(); } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-pages-read.php b/src/Analytics/Datasets/Pages_Read.php similarity index 87% rename from includes/analytics/datasets/class-pages-read.php rename to src/Analytics/Datasets/Pages_Read.php index c35dcb38..359e3e8d 100644 --- a/includes/analytics/datasets/class-pages-read.php +++ b/src/Analytics/Datasets/Pages_Read.php @@ -3,12 +3,13 @@ * Number of Pages Read * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -41,4 +42,4 @@ protected function _get_dataset() { return round( absint( $result ) ); } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-ratings-breakdown.php b/src/Analytics/Datasets/Ratings_Breakdown.php similarity index 90% rename from includes/analytics/datasets/class-ratings-breakdown.php rename to src/Analytics/Datasets/Ratings_Breakdown.php index 4f9c60c1..22b386fe 100644 --- a/includes/analytics/datasets/class-ratings-breakdown.php +++ b/src/Analytics/Datasets/Ratings_Breakdown.php @@ -3,12 +3,14 @@ * Dataset: Ratings Breakdown * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; +use Book_Database\Analytics\Pie_Chart; use function Book_Database\book_database; /** @@ -69,4 +71,4 @@ protected function _get_dataset() { return $chart->get_args(); } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-reading-overview.php b/src/Analytics/Datasets/Reading_Overview.php similarity index 95% rename from includes/analytics/datasets/class-reading-overview.php rename to src/Analytics/Datasets/Reading_Overview.php index 396ed212..7b983066 100644 --- a/includes/analytics/datasets/class-reading-overview.php +++ b/src/Analytics/Datasets/Reading_Overview.php @@ -3,12 +3,13 @@ * Dataset: Reading Overview * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -112,4 +113,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-reading-track.php b/src/Analytics/Datasets/Reading_Track.php similarity index 91% rename from includes/analytics/datasets/class-reading-track.php rename to src/Analytics/Datasets/Reading_Track.php index a6ae900b..521d001f 100644 --- a/includes/analytics/datasets/class-reading-track.php +++ b/src/Analytics/Datasets/Reading_Track.php @@ -3,12 +3,13 @@ * Dataset: Reading Track * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -61,4 +62,4 @@ protected function _get_dataset() { } } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-reviews-over-time.php b/src/Analytics/Datasets/Reviews_Over_Time.php similarity index 94% rename from includes/analytics/datasets/class-reviews-over-time.php rename to src/Analytics/Datasets/Reviews_Over_Time.php index a5c22b48..1c8ecc05 100644 --- a/includes/analytics/datasets/class-reviews-over-time.php +++ b/src/Analytics/Datasets/Reviews_Over_Time.php @@ -3,12 +3,14 @@ * Dataset: Reviews Written Over Time * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Bar_Graph; +use Book_Database\Analytics\Dataset; use function Book_Database\book_database; /** @@ -130,4 +132,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-reviews-written.php b/src/Analytics/Datasets/Reviews_Written.php similarity index 94% rename from includes/analytics/datasets/class-reviews-written.php rename to src/Analytics/Datasets/Reviews_Written.php index 8d1da2d3..220e39dc 100644 --- a/includes/analytics/datasets/class-reviews-written.php +++ b/src/Analytics/Datasets/Reviews_Written.php @@ -3,12 +3,13 @@ * Dataset: Reviews Written * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use Book_Database\Rating; use function Book_Database\book_database; use function Book_Database\format_date; @@ -65,4 +66,4 @@ protected function _get_dataset() { } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-shortest-book-read.php b/src/Analytics/Datasets/Shortest_Book_Read.php similarity index 92% rename from includes/analytics/datasets/class-shortest-book-read.php rename to src/Analytics/Datasets/Shortest_Book_Read.php index f75a77de..0ef97887 100644 --- a/includes/analytics/datasets/class-shortest-book-read.php +++ b/src/Analytics/Datasets/Shortest_Book_Read.php @@ -3,12 +3,13 @@ * Dataset: Shortest book read * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use Book_Database\Book; use function Book_Database\book_database; use function Book_Database\get_book; @@ -65,4 +66,4 @@ protected function _get_dataset() { return $book_link; } -} \ No newline at end of file +} diff --git a/includes/analytics/datasets/class-terms-breakdown.php b/src/Analytics/Datasets/Terms_Breakdown.php similarity index 92% rename from includes/analytics/datasets/class-terms-breakdown.php rename to src/Analytics/Datasets/Terms_Breakdown.php index bb4db468..98fd7ef1 100644 --- a/includes/analytics/datasets/class-terms-breakdown.php +++ b/src/Analytics/Datasets/Terms_Breakdown.php @@ -3,12 +3,13 @@ * class-terms-breakdown.php * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ -namespace Book_Database\Analytics; +namespace Book_Database\Analytics\Datasets; +use Book_Database\Analytics\Dataset; use Book_Database\Rating; use function Book_Database\book_database; @@ -59,4 +60,4 @@ protected function _get_dataset() { return $results; } -} \ No newline at end of file +} diff --git a/includes/analytics/graphs/class-graph.php b/src/Analytics/Graph.php similarity index 99% rename from includes/analytics/graphs/class-graph.php rename to src/Analytics/Graph.php index 742e1ed4..1a630e2b 100644 --- a/includes/analytics/graphs/class-graph.php +++ b/src/Analytics/Graph.php @@ -3,7 +3,7 @@ * Graph * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -240,4 +240,4 @@ public function get_args() { return $this->args; } -} \ No newline at end of file +} diff --git a/includes/analytics/graphs/class-horizontal-bar-graph.php b/src/Analytics/Horizontal_Bar_Graph.php similarity index 100% rename from includes/analytics/graphs/class-horizontal-bar-graph.php rename to src/Analytics/Horizontal_Bar_Graph.php diff --git a/includes/analytics/graphs/class-pie-chart.php b/src/Analytics/Pie_Chart.php similarity index 100% rename from includes/analytics/graphs/class-pie-chart.php rename to src/Analytics/Pie_Chart.php diff --git a/includes/analytics/graphs/class-scatter-chart.php b/src/Analytics/Scatter_Chart.php similarity index 100% rename from includes/analytics/graphs/class-scatter-chart.php rename to src/Analytics/Scatter_Chart.php diff --git a/includes/authors/class-author.php b/src/Author.php similarity index 97% rename from includes/authors/class-author.php rename to src/Author.php index 6727dc35..80e60481 100644 --- a/includes/authors/class-author.php +++ b/src/Author.php @@ -3,7 +3,7 @@ * Author Object * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -122,4 +122,4 @@ public function get_book_count() { return absint( $this->book_count ); } -} \ No newline at end of file +} diff --git a/includes/abstract-class-base-object.php b/src/Base_Object.php similarity index 97% rename from includes/abstract-class-base-object.php rename to src/Base_Object.php index 799d0e2a..b1c3cca1 100644 --- a/includes/abstract-class-base-object.php +++ b/src/Base_Object.php @@ -5,7 +5,7 @@ * Extended by core objects. * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -101,4 +101,4 @@ public function export_vars() { return get_object_vars( $this ); } -} \ No newline at end of file +} diff --git a/includes/books/class-book.php b/src/Book.php similarity index 99% rename from includes/books/class-book.php rename to src/Book.php index de530aed..c4b546f6 100644 --- a/includes/books/class-book.php +++ b/src/Book.php @@ -3,7 +3,7 @@ * Book * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -348,4 +348,4 @@ public function get_data() { } -} \ No newline at end of file +} diff --git a/includes/book-author-relationships/class-book-author-relationship.php b/src/Book_Author_Relationship.php similarity index 91% rename from includes/book-author-relationships/class-book-author-relationship.php rename to src/Book_Author_Relationship.php index 5649839b..0ace2938 100644 --- a/includes/book-author-relationships/class-book-author-relationship.php +++ b/src/Book_Author_Relationship.php @@ -3,7 +3,7 @@ * Book Author Relationship Object * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -37,4 +37,4 @@ public function get_book_id() { return absint( $this->book_id ); } -} \ No newline at end of file +} diff --git a/includes/class-book-grid-query.php b/src/Book_Grid_Query.php similarity index 98% rename from includes/class-book-grid-query.php rename to src/Book_Grid_Query.php index ef39baf7..33051473 100644 --- a/includes/class-book-grid-query.php +++ b/src/Book_Grid_Query.php @@ -5,7 +5,7 @@ * Used in the `[book-grid]` shortcode. * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -166,4 +166,4 @@ public function get_results() { } -} \ No newline at end of file +} diff --git a/includes/books/class-book-layout.php b/src/Book_Layout.php similarity index 99% rename from includes/books/class-book-layout.php rename to src/Book_Layout.php index fa9c28ea..303644e0 100644 --- a/includes/books/class-book-layout.php +++ b/src/Book_Layout.php @@ -3,7 +3,7 @@ * Book Layout * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -462,4 +462,4 @@ public function get_schema_markup() { return ob_get_clean(); } -} \ No newline at end of file +} diff --git a/includes/book-links/class-book-link.php b/src/Book_Link.php similarity index 96% rename from includes/book-links/class-book-link.php rename to src/Book_Link.php index 61d60e68..a8dff5b5 100644 --- a/includes/book-links/class-book-link.php +++ b/src/Book_Link.php @@ -3,7 +3,7 @@ * Book Link Object * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -83,4 +83,4 @@ public function format() { } -} \ No newline at end of file +} diff --git a/includes/class-book-reviews-query.php b/src/Book_Reviews_Query.php similarity index 99% rename from includes/class-book-reviews-query.php rename to src/Book_Reviews_Query.php index d4962026..7abed04e 100644 --- a/includes/class-book-reviews-query.php +++ b/src/Book_Reviews_Query.php @@ -5,7 +5,7 @@ * Used in the `[book-reviews]` shortcode. * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -234,4 +234,4 @@ public function get_pagination() { ) ); } -} \ No newline at end of file +} diff --git a/includes/book-taxonomies/class-book-taxonomy.php b/src/Book_Taxonomy.php similarity index 92% rename from includes/book-taxonomies/class-book-taxonomy.php rename to src/Book_Taxonomy.php index 348ea64e..5c01d8b6 100644 --- a/includes/book-taxonomies/class-book-taxonomy.php +++ b/src/Book_Taxonomy.php @@ -3,7 +3,7 @@ * Book Taxonomy Object * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -48,4 +48,4 @@ public function get_format() { return $this->format; } -} \ No newline at end of file +} diff --git a/includes/book-terms/class-book-term.php b/src/Book_Term.php similarity index 96% rename from includes/book-terms/class-book-term.php rename to src/Book_Term.php index 5399c29d..4f4ec6d3 100644 --- a/includes/book-terms/class-book-term.php +++ b/src/Book_Term.php @@ -3,7 +3,7 @@ * Book Term * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -92,4 +92,4 @@ public function get_book_count() { return absint( $this->book_count ); } -} \ No newline at end of file +} diff --git a/includes/book-term-relationships/class-book-term-relationship.php b/src/Book_Term_Relationship.php similarity index 91% rename from includes/book-term-relationships/class-book-term-relationship.php rename to src/Book_Term_Relationship.php index 40474d69..8e3109dc 100644 --- a/includes/book-term-relationships/class-book-term-relationship.php +++ b/src/Book_Term_Relationship.php @@ -3,7 +3,7 @@ * Book Term Relationship Object * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -37,4 +37,4 @@ public function get_book_id() { return absint( $this->book_id ); } -} \ No newline at end of file +} diff --git a/includes/class-cli.php b/src/CLI.php similarity index 98% rename from includes/class-cli.php rename to src/CLI.php index 7d518cfd..d696a8fc 100644 --- a/includes/class-cli.php +++ b/src/CLI.php @@ -3,7 +3,7 @@ * WP-CLI * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -15,7 +15,7 @@ use WP_CLI; -WP_CLI::add_command( 'bdb', '\Book_Database\CLI' ); +WP_CLI::add_command( 'bdb', '\\Book_Database\\CLI' ); class CLI extends \WP_CLI_Command { diff --git a/src/Deprecated/class-names.php b/src/Deprecated/class-names.php new file mode 100644 index 00000000..27100f21 --- /dev/null +++ b/src/Deprecated/class-names.php @@ -0,0 +1,47 @@ +error_type; } -} \ No newline at end of file +} diff --git a/includes/class-html.php b/src/HTML.php similarity index 98% rename from includes/class-html.php rename to src/HTML.php index 4208d728..5971a278 100644 --- a/includes/class-html.php +++ b/src/HTML.php @@ -3,7 +3,7 @@ * HTML Helper Class * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -124,4 +124,4 @@ public function taxonomy_field( $taxonomy, $args = array() ) { } -} \ No newline at end of file +} diff --git a/includes/rest-api/class-rest-api.php b/src/REST_API.php similarity index 95% rename from includes/rest-api/class-rest-api.php rename to src/REST_API.php index 9dc8f908..d8054c68 100644 --- a/includes/rest-api/class-rest-api.php +++ b/src/REST_API.php @@ -3,7 +3,7 @@ * REST API Setup * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -52,4 +52,4 @@ public function register_routes() { } } -} \ No newline at end of file +} diff --git a/includes/rest-api/abstract-class-controller.php b/src/REST_API/Controller.php similarity index 94% rename from includes/rest-api/abstract-class-controller.php rename to src/REST_API/Controller.php index 9d023859..3e95bb38 100644 --- a/includes/rest-api/abstract-class-controller.php +++ b/src/REST_API/Controller.php @@ -3,7 +3,7 @@ * REST API Base Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -52,4 +52,4 @@ public function can_edit( $request ) { return user_can_edit_books(); } -} \ No newline at end of file +} diff --git a/includes/rest-api/v1/class-analytics-controller.php b/src/REST_API/v1/Analytics.php similarity index 97% rename from includes/rest-api/v1/class-analytics-controller.php rename to src/REST_API/v1/Analytics.php index 4135ebe5..6eaeb497 100644 --- a/includes/rest-api/v1/class-analytics-controller.php +++ b/src/REST_API/v1/Analytics.php @@ -3,7 +3,7 @@ * Analytics Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -79,7 +79,7 @@ public function register_routes() { 'dataset' => array( 'required' => true, 'validate_callback' => function ( $param, $request, $key ) { - return class_exists( '\\Book_Database\\Analytics\\' . $param ); + return class_exists( '\\Book_Database\\Analytics\\Datasets\\' . $param ); } ), 'date_option' => array() @@ -194,4 +194,4 @@ public function set_dates( $request ) { } -} \ No newline at end of file +} diff --git a/includes/rest-api/v1/class-author-controller.php b/src/REST_API/v1/Author.php similarity index 97% rename from includes/rest-api/v1/class-author-controller.php rename to src/REST_API/v1/Author.php index 341c2ba9..ea728fc1 100644 --- a/includes/rest-api/v1/class-author-controller.php +++ b/src/REST_API/v1/Author.php @@ -3,7 +3,7 @@ * Author Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -78,4 +78,4 @@ public function suggest( $request ) { } -} \ No newline at end of file +} diff --git a/includes/rest-api/v1/class-book-controller.php b/src/REST_API/v1/Book.php similarity index 99% rename from includes/rest-api/v1/class-book-controller.php rename to src/REST_API/v1/Book.php index 127e8296..8b15061b 100644 --- a/includes/rest-api/v1/class-book-controller.php +++ b/src/REST_API/v1/Book.php @@ -3,7 +3,7 @@ * Book Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ diff --git a/includes/rest-api/v1/class-book-link-controller.php b/src/REST_API/v1/Book_Link.php similarity index 99% rename from includes/rest-api/v1/class-book-link-controller.php rename to src/REST_API/v1/Book_Link.php index 702e61ad..87844f96 100644 --- a/includes/rest-api/v1/class-book-link-controller.php +++ b/src/REST_API/v1/Book_Link.php @@ -3,7 +3,7 @@ * Book Link Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -289,4 +289,4 @@ public function delete_item( $request ) { } -} \ No newline at end of file +} diff --git a/includes/rest-api/v1/class-book-term-controller.php b/src/REST_API/v1/Book_Term.php similarity index 97% rename from includes/rest-api/v1/class-book-term-controller.php rename to src/REST_API/v1/Book_Term.php index 6148d5c0..797df0f9 100644 --- a/includes/rest-api/v1/class-book-term-controller.php +++ b/src/REST_API/v1/Book_Term.php @@ -3,7 +3,7 @@ * Book Term Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -87,4 +87,4 @@ public function suggest( $request ) { } -} \ No newline at end of file +} diff --git a/includes/rest-api/v1/class-edition-controller.php b/src/REST_API/v1/Edition.php similarity index 99% rename from includes/rest-api/v1/class-edition-controller.php rename to src/REST_API/v1/Edition.php index 2355d449..dcfc2fd4 100644 --- a/includes/rest-api/v1/class-edition-controller.php +++ b/src/REST_API/v1/Edition.php @@ -3,7 +3,7 @@ * Book Edition Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -434,4 +434,4 @@ public function delete_edition( $request ) { } -} \ No newline at end of file +} diff --git a/includes/rest-api/v1/class-reading-log-controller.php b/src/REST_API/v1/Reading_Log.php similarity index 99% rename from includes/rest-api/v1/class-reading-log-controller.php rename to src/REST_API/v1/Reading_Log.php index 351b3d87..270483db 100644 --- a/includes/rest-api/v1/class-reading-log-controller.php +++ b/src/REST_API/v1/Reading_Log.php @@ -3,7 +3,7 @@ * Reading Log Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -413,4 +413,4 @@ public function delete_reading_log( $request ) { } -} \ No newline at end of file +} diff --git a/includes/rest-api/v1/class-retailer-controller.php b/src/REST_API/v1/Retailer.php similarity index 99% rename from includes/rest-api/v1/class-retailer-controller.php rename to src/REST_API/v1/Retailer.php index aa587027..84b2fec3 100644 --- a/includes/rest-api/v1/class-retailer-controller.php +++ b/src/REST_API/v1/Retailer.php @@ -3,7 +3,7 @@ * Retailer Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -256,4 +256,4 @@ public function delete_retailer( $request ) { } -} \ No newline at end of file +} diff --git a/includes/rest-api/v1/class-review-controller.php b/src/REST_API/v1/Review.php similarity index 99% rename from includes/rest-api/v1/class-review-controller.php rename to src/REST_API/v1/Review.php index 92187589..0d515914 100644 --- a/includes/rest-api/v1/class-review-controller.php +++ b/src/REST_API/v1/Review.php @@ -3,7 +3,7 @@ * Review Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -265,4 +265,4 @@ public function delete_review( $request ) { } -} \ No newline at end of file +} diff --git a/includes/rest-api/v1/class-series-controller.php b/src/REST_API/v1/Series.php similarity index 99% rename from includes/rest-api/v1/class-series-controller.php rename to src/REST_API/v1/Series.php index c48f4651..486a036f 100644 --- a/includes/rest-api/v1/class-series-controller.php +++ b/src/REST_API/v1/Series.php @@ -3,7 +3,7 @@ * Series Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -309,4 +309,4 @@ public function suggest( $request ) { } -} \ No newline at end of file +} diff --git a/includes/rest-api/v1/class-taxonomy-controller.php b/src/REST_API/v1/Taxonomy.php similarity index 98% rename from includes/rest-api/v1/class-taxonomy-controller.php rename to src/REST_API/v1/Taxonomy.php index 53c2fcc2..64f00ed6 100644 --- a/includes/rest-api/v1/class-taxonomy-controller.php +++ b/src/REST_API/v1/Taxonomy.php @@ -3,7 +3,7 @@ * Taxonomy Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -183,4 +183,4 @@ public function delete_taxonomy( $request ) { } -} \ No newline at end of file +} diff --git a/includes/rest-api/v1/class-utility-controller.php b/src/REST_API/v1/Utility.php similarity index 96% rename from includes/rest-api/v1/class-utility-controller.php rename to src/REST_API/v1/Utility.php index 830e1e7c..d9c45ff5 100644 --- a/includes/rest-api/v1/class-utility-controller.php +++ b/src/REST_API/v1/Utility.php @@ -3,7 +3,7 @@ * Utility Controller * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -66,4 +66,4 @@ public function convert_date( $request ) { } -} \ No newline at end of file +} diff --git a/includes/ratings/class-rating.php b/src/Rating.php similarity index 99% rename from includes/ratings/class-rating.php rename to src/Rating.php index 729bb1db..e2132e1a 100644 --- a/includes/ratings/class-rating.php +++ b/src/Rating.php @@ -3,7 +3,7 @@ * Rating Object * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -283,4 +283,4 @@ public function repeat( $full_star, $half_star = '', $empty_star = '' ) { } -} \ No newline at end of file +} diff --git a/includes/reading-logs/class-reading-log.php b/src/Reading_Log.php similarity index 98% rename from includes/reading-logs/class-reading-log.php rename to src/Reading_Log.php index 2d1aaa01..56b2a2af 100644 --- a/includes/reading-logs/class-reading-log.php +++ b/src/Reading_Log.php @@ -3,7 +3,7 @@ * Reading Log Object * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -163,4 +163,4 @@ public function export_vars() { } -} \ No newline at end of file +} diff --git a/includes/retailers/class-retailer.php b/src/Retailer.php similarity index 95% rename from includes/retailers/class-retailer.php rename to src/Retailer.php index 6c700288..ecd25365 100644 --- a/includes/retailers/class-retailer.php +++ b/src/Retailer.php @@ -3,7 +3,7 @@ * Retailer Object * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -64,4 +64,4 @@ public function build_link( $url ) { } -} \ No newline at end of file +} diff --git a/includes/reviews/class-review.php b/src/Review.php similarity index 99% rename from includes/reviews/class-review.php rename to src/Review.php index d5f42f1d..7d9410e7 100644 --- a/includes/reviews/class-review.php +++ b/src/Review.php @@ -3,7 +3,7 @@ * Review Object * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -214,4 +214,4 @@ public function is_published() { } -} \ No newline at end of file +} diff --git a/includes/series/class-series.php b/src/Series.php similarity index 98% rename from includes/series/class-series.php rename to src/Series.php index b846c2d9..ad7211a0 100644 --- a/includes/series/class-series.php +++ b/src/Series.php @@ -3,7 +3,7 @@ * Series Object * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -135,4 +135,4 @@ public function get_average_rating() { } -} \ No newline at end of file +} diff --git a/includes/widgets/Reading_Log.php b/src/Widgets/Reading_Log.php similarity index 99% rename from includes/widgets/Reading_Log.php rename to src/Widgets/Reading_Log.php index d6c1dc1c..77c88bf4 100644 --- a/includes/widgets/Reading_Log.php +++ b/src/Widgets/Reading_Log.php @@ -3,7 +3,7 @@ * Reading Log Widget * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ * @since 1.1 */ @@ -325,4 +325,4 @@ public function update( $new_instance, $old_instance ) { */ add_action( 'widgets_init', function () { register_widget( '\\Book_Database\\Widgets\\Reading_log' ); -} ); \ No newline at end of file +} ); diff --git a/includes/widgets/Reviews.php b/src/Widgets/Reviews.php similarity index 99% rename from includes/widgets/Reviews.php rename to src/Widgets/Reviews.php index 00d7c76a..99e1814a 100644 --- a/includes/widgets/Reviews.php +++ b/src/Widgets/Reviews.php @@ -3,7 +3,7 @@ * Reviews Widget * * @package book-database - * @copyright Copyright (c) 2020, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ * @since 1.1 */ @@ -324,4 +324,4 @@ public function update( $new_instance, $old_instance ) { */ add_action( 'widgets_init', function () { register_widget( '\\Book_Database\\Widgets\\Reviews' ); -} ); \ No newline at end of file +} ); diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 00000000..afcb3464 --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + private $vendorDir; + + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + private static $registeredLoaders = array(); + + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + } + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders indexed by their corresponding vendor directories. + * + * @return self[] + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 00000000..11cf07bc --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,283 @@ + + array ( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'aliases' => + array ( + ), + 'reference' => '85e967e3f9245f57621d659fac0f148adffabd43', + 'name' => 'ashleyfae/book-database', + ), + 'versions' => + array ( + 'ashleyfae/book-database' => + array ( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'aliases' => + array ( + ), + 'reference' => '85e967e3f9245f57621d659fac0f148adffabd43', + ), + ), +); +private static $canGetVendors; +private static $installedByVendor = array(); + + + + + + + +public static function getInstalledPackages() +{ +$packages = array(); +foreach (self::getInstalled() as $installed) { +$packages[] = array_keys($installed['versions']); +} + + +if (1 === \count($packages)) { +return $packages[0]; +} + +return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); +} + + + + + + + + + +public static function isInstalled($packageName) +{ +foreach (self::getInstalled() as $installed) { +if (isset($installed['versions'][$packageName])) { +return true; +} +} + +return false; +} + + + + + + + + + + + + + + +public static function satisfies(VersionParser $parser, $packageName, $constraint) +{ +$constraint = $parser->parseConstraints($constraint); +$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + +return $provided->matches($constraint); +} + + + + + + + + + + +public static function getVersionRanges($packageName) +{ +foreach (self::getInstalled() as $installed) { +if (!isset($installed['versions'][$packageName])) { +continue; +} + +$ranges = array(); +if (isset($installed['versions'][$packageName]['pretty_version'])) { +$ranges[] = $installed['versions'][$packageName]['pretty_version']; +} +if (array_key_exists('aliases', $installed['versions'][$packageName])) { +$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); +} +if (array_key_exists('replaced', $installed['versions'][$packageName])) { +$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); +} +if (array_key_exists('provided', $installed['versions'][$packageName])) { +$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); +} + +return implode(' || ', $ranges); +} + +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + + + + + +public static function getVersion($packageName) +{ +foreach (self::getInstalled() as $installed) { +if (!isset($installed['versions'][$packageName])) { +continue; +} + +if (!isset($installed['versions'][$packageName]['version'])) { +return null; +} + +return $installed['versions'][$packageName]['version']; +} + +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + + + + + +public static function getPrettyVersion($packageName) +{ +foreach (self::getInstalled() as $installed) { +if (!isset($installed['versions'][$packageName])) { +continue; +} + +if (!isset($installed['versions'][$packageName]['pretty_version'])) { +return null; +} + +return $installed['versions'][$packageName]['pretty_version']; +} + +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + + + + + +public static function getReference($packageName) +{ +foreach (self::getInstalled() as $installed) { +if (!isset($installed['versions'][$packageName])) { +continue; +} + +if (!isset($installed['versions'][$packageName]['reference'])) { +return null; +} + +return $installed['versions'][$packageName]['reference']; +} + +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + + + + + +public static function getRootPackage() +{ +$installed = self::getInstalled(); + +return $installed[0]['root']; +} + + + + + + + +public static function getRawData() +{ +return self::$installed; +} + + + + + + + + + + + + + + + + + + + +public static function reload($data) +{ +self::$installed = $data; +self::$installedByVendor = array(); +} + + + + +private static function getInstalled() +{ +if (null === self::$canGetVendors) { +self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); +} + +$installed = array(); + +if (self::$canGetVendors) { +foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { +if (isset(self::$installedByVendor[$vendorDir])) { +$installed[] = self::$installedByVendor[$vendorDir]; +} elseif (is_file($vendorDir.'/composer/installed.php')) { +$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; +} +} +} + +$installed[] = self::$installed; + +return $installed; +} +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 00000000..f27399a0 --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 00000000..b26f1b13 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,10 @@ + $vendorDir . '/composer/InstalledVersions.php', +); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php new file mode 100644 index 00000000..1285eeff --- /dev/null +++ b/vendor/composer/autoload_files.php @@ -0,0 +1,10 @@ + $baseDir . '/src/Deprecated/class-names.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 00000000..b7fc0125 --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($baseDir . '/src'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 00000000..2945552c --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,75 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit5df8d9708ce95e08fc9df27c2e81f1c1::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInit5df8d9708ce95e08fc9df27c2e81f1c1::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequire5df8d9708ce95e08fc9df27c2e81f1c1($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequire5df8d9708ce95e08fc9df27c2e81f1c1($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 00000000..91400457 --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,40 @@ + __DIR__ . '/../..' . '/src/Deprecated/class-names.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'B' => + array ( + 'Book_Database\\' => 14, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Book_Database\\' => + array ( + 0 => __DIR__ . '/../..' . '/src', + ), + ); + + public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit5df8d9708ce95e08fc9df27c2e81f1c1::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit5df8d9708ce95e08fc9df27c2e81f1c1::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit5df8d9708ce95e08fc9df27c2e81f1c1::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 00000000..87fda747 --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,5 @@ +{ + "packages": [], + "dev": true, + "dev-package-names": [] +} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 00000000..3e67a393 --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,24 @@ + + array ( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'aliases' => + array ( + ), + 'reference' => '85e967e3f9245f57621d659fac0f148adffabd43', + 'name' => 'ashleyfae/book-database', + ), + 'versions' => + array ( + 'ashleyfae/book-database' => + array ( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'aliases' => + array ( + ), + 'reference' => '85e967e3f9245f57621d659fac0f148adffabd43', + ), + ), +); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php new file mode 100644 index 00000000..f79e574b --- /dev/null +++ b/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70000)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.0.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} From 0bfc171d7c412f847a8275685c8a6e911e154d57 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Thu, 20 May 2021 10:26:02 +0100 Subject: [PATCH 02/29] Remove use for absint --- src/Analytics/Datasets/Average_Days_Acquired_to_Read.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Analytics/Datasets/Average_Days_Acquired_to_Read.php b/src/Analytics/Datasets/Average_Days_Acquired_to_Read.php index 35b0227a..5c50b91d 100644 --- a/src/Analytics/Datasets/Average_Days_Acquired_to_Read.php +++ b/src/Analytics/Datasets/Average_Days_Acquired_to_Read.php @@ -10,7 +10,6 @@ namespace Book_Database\Analytics\Datasets; use Book_Database\Analytics\Dataset; -use function absint; use function Book_Database\book_database; /** From 2f04ad4083a25bd42766da471a3bd1406a872f94 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 20 Nov 2021 13:33:18 +0000 Subject: [PATCH 03/29] Delete vendor files. #248 --- .../class-edd-sl-plugin-updater.php | 0 vendor/autoload.php | 7 - vendor/composer/ClassLoader.php | 479 ------------------ vendor/composer/InstalledVersions.php | 283 ----------- vendor/composer/LICENSE | 21 - vendor/composer/autoload_classmap.php | 10 - vendor/composer/autoload_files.php | 10 - vendor/composer/autoload_namespaces.php | 9 - vendor/composer/autoload_psr4.php | 10 - vendor/composer/autoload_real.php | 75 --- vendor/composer/autoload_static.php | 40 -- vendor/composer/installed.json | 5 - vendor/composer/installed.php | 24 - vendor/composer/platform_check.php | 26 - 14 files changed, 999 deletions(-) rename {vendor => includes}/class-edd-sl-plugin-updater.php (100%) delete mode 100644 vendor/autoload.php delete mode 100644 vendor/composer/ClassLoader.php delete mode 100644 vendor/composer/InstalledVersions.php delete mode 100644 vendor/composer/LICENSE delete mode 100644 vendor/composer/autoload_classmap.php delete mode 100644 vendor/composer/autoload_files.php delete mode 100644 vendor/composer/autoload_namespaces.php delete mode 100644 vendor/composer/autoload_psr4.php delete mode 100644 vendor/composer/autoload_real.php delete mode 100644 vendor/composer/autoload_static.php delete mode 100644 vendor/composer/installed.json delete mode 100644 vendor/composer/installed.php delete mode 100644 vendor/composer/platform_check.php diff --git a/vendor/class-edd-sl-plugin-updater.php b/includes/class-edd-sl-plugin-updater.php similarity index 100% rename from vendor/class-edd-sl-plugin-updater.php rename to includes/class-edd-sl-plugin-updater.php diff --git a/vendor/autoload.php b/vendor/autoload.php deleted file mode 100644 index afcb3464..00000000 --- a/vendor/autoload.php +++ /dev/null @@ -1,7 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Autoload; - -/** - * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. - * - * $loader = new \Composer\Autoload\ClassLoader(); - * - * // register classes with namespaces - * $loader->add('Symfony\Component', __DIR__.'/component'); - * $loader->add('Symfony', __DIR__.'/framework'); - * - * // activate the autoloader - * $loader->register(); - * - * // to enable searching the include path (eg. for PEAR packages) - * $loader->setUseIncludePath(true); - * - * In this example, if you try to use a class in the Symfony\Component - * namespace or one of its children (Symfony\Component\Console for instance), - * the autoloader will first look for the class under the component/ - * directory, and it will then fallback to the framework/ directory if not - * found before giving up. - * - * This class is loosely based on the Symfony UniversalClassLoader. - * - * @author Fabien Potencier - * @author Jordi Boggiano - * @see https://www.php-fig.org/psr/psr-0/ - * @see https://www.php-fig.org/psr/psr-4/ - */ -class ClassLoader -{ - private $vendorDir; - - // PSR-4 - private $prefixLengthsPsr4 = array(); - private $prefixDirsPsr4 = array(); - private $fallbackDirsPsr4 = array(); - - // PSR-0 - private $prefixesPsr0 = array(); - private $fallbackDirsPsr0 = array(); - - private $useIncludePath = false; - private $classMap = array(); - private $classMapAuthoritative = false; - private $missingClasses = array(); - private $apcuPrefix; - - private static $registeredLoaders = array(); - - public function __construct($vendorDir = null) - { - $this->vendorDir = $vendorDir; - } - - public function getPrefixes() - { - if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); - } - - return array(); - } - - public function getPrefixesPsr4() - { - return $this->prefixDirsPsr4; - } - - public function getFallbackDirs() - { - return $this->fallbackDirsPsr0; - } - - public function getFallbackDirsPsr4() - { - return $this->fallbackDirsPsr4; - } - - public function getClassMap() - { - return $this->classMap; - } - - /** - * @param array $classMap Class to filename map - */ - public function addClassMap(array $classMap) - { - if ($this->classMap) { - $this->classMap = array_merge($this->classMap, $classMap); - } else { - $this->classMap = $classMap; - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, either - * appending or prepending to the ones previously set for this prefix. - * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories - */ - public function add($prefix, $paths, $prepend = false) - { - if (!$prefix) { - if ($prepend) { - $this->fallbackDirsPsr0 = array_merge( - (array) $paths, - $this->fallbackDirsPsr0 - ); - } else { - $this->fallbackDirsPsr0 = array_merge( - $this->fallbackDirsPsr0, - (array) $paths - ); - } - - return; - } - - $first = $prefix[0]; - if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; - - return; - } - if ($prepend) { - $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, - $this->prefixesPsr0[$first][$prefix] - ); - } else { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $this->prefixesPsr0[$first][$prefix], - (array) $paths - ); - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, either - * appending or prepending to the ones previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories - * - * @throws \InvalidArgumentException - */ - public function addPsr4($prefix, $paths, $prepend = false) - { - if (!$prefix) { - // Register directories for the root namespace. - if ($prepend) { - $this->fallbackDirsPsr4 = array_merge( - (array) $paths, - $this->fallbackDirsPsr4 - ); - } else { - $this->fallbackDirsPsr4 = array_merge( - $this->fallbackDirsPsr4, - (array) $paths - ); - } - } elseif (!isset($this->prefixDirsPsr4[$prefix])) { - // Register directories for a new namespace. - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } elseif ($prepend) { - // Prepend directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, - $this->prefixDirsPsr4[$prefix] - ); - } else { - // Append directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $this->prefixDirsPsr4[$prefix], - (array) $paths - ); - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, - * replacing any others previously set for this prefix. - * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories - */ - public function set($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr0 = (array) $paths; - } else { - $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, - * replacing any others previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * - * @throws \InvalidArgumentException - */ - public function setPsr4($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr4 = (array) $paths; - } else { - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } - } - - /** - * Turns on searching the include path for class files. - * - * @param bool $useIncludePath - */ - public function setUseIncludePath($useIncludePath) - { - $this->useIncludePath = $useIncludePath; - } - - /** - * Can be used to check if the autoloader uses the include path to check - * for classes. - * - * @return bool - */ - public function getUseIncludePath() - { - return $this->useIncludePath; - } - - /** - * Turns off searching the prefix and fallback directories for classes - * that have not been registered with the class map. - * - * @param bool $classMapAuthoritative - */ - public function setClassMapAuthoritative($classMapAuthoritative) - { - $this->classMapAuthoritative = $classMapAuthoritative; - } - - /** - * Should class lookup fail if not found in the current class map? - * - * @return bool - */ - public function isClassMapAuthoritative() - { - return $this->classMapAuthoritative; - } - - /** - * APCu prefix to use to cache found/not-found classes, if the extension is enabled. - * - * @param string|null $apcuPrefix - */ - public function setApcuPrefix($apcuPrefix) - { - $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; - } - - /** - * The APCu prefix in use, or null if APCu caching is not enabled. - * - * @return string|null - */ - public function getApcuPrefix() - { - return $this->apcuPrefix; - } - - /** - * Registers this instance as an autoloader. - * - * @param bool $prepend Whether to prepend the autoloader or not - */ - public function register($prepend = false) - { - spl_autoload_register(array($this, 'loadClass'), true, $prepend); - - if (null === $this->vendorDir) { - return; - } - - if ($prepend) { - self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; - } else { - unset(self::$registeredLoaders[$this->vendorDir]); - self::$registeredLoaders[$this->vendorDir] = $this; - } - } - - /** - * Unregisters this instance as an autoloader. - */ - public function unregister() - { - spl_autoload_unregister(array($this, 'loadClass')); - - if (null !== $this->vendorDir) { - unset(self::$registeredLoaders[$this->vendorDir]); - } - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - includeFile($file); - - return true; - } - } - - /** - * Finds the path to the file where the class is defined. - * - * @param string $class The name of the class - * - * @return string|false The path if found, false otherwise - */ - public function findFile($class) - { - // class map lookup - if (isset($this->classMap[$class])) { - return $this->classMap[$class]; - } - if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { - return false; - } - if (null !== $this->apcuPrefix) { - $file = apcu_fetch($this->apcuPrefix.$class, $hit); - if ($hit) { - return $file; - } - } - - $file = $this->findFileWithExtension($class, '.php'); - - // Search for Hack files if we are running on HHVM - if (false === $file && defined('HHVM_VERSION')) { - $file = $this->findFileWithExtension($class, '.hh'); - } - - if (null !== $this->apcuPrefix) { - apcu_add($this->apcuPrefix.$class, $file); - } - - if (false === $file) { - // Remember that this class does not exist. - $this->missingClasses[$class] = true; - } - - return $file; - } - - /** - * Returns the currently registered loaders indexed by their corresponding vendor directories. - * - * @return self[] - */ - public static function getRegisteredLoaders() - { - return self::$registeredLoaders; - } - - private function findFileWithExtension($class, $ext) - { - // PSR-4 lookup - $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; - - $first = $class[0]; - if (isset($this->prefixLengthsPsr4[$first])) { - $subPath = $class; - while (false !== $lastPos = strrpos($subPath, '\\')) { - $subPath = substr($subPath, 0, $lastPos); - $search = $subPath . '\\'; - if (isset($this->prefixDirsPsr4[$search])) { - $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); - foreach ($this->prefixDirsPsr4[$search] as $dir) { - if (file_exists($file = $dir . $pathEnd)) { - return $file; - } - } - } - } - } - - // PSR-4 fallback dirs - foreach ($this->fallbackDirsPsr4 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { - return $file; - } - } - - // PSR-0 lookup - if (false !== $pos = strrpos($class, '\\')) { - // namespaced class name - $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) - . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); - } else { - // PEAR-like class name - $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; - } - - if (isset($this->prefixesPsr0[$first])) { - foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { - if (0 === strpos($class, $prefix)) { - foreach ($dirs as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - } - } - } - - // PSR-0 fallback dirs - foreach ($this->fallbackDirsPsr0 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - - // PSR-0 include paths. - if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { - return $file; - } - - return false; - } -} - -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; -} diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php deleted file mode 100644 index 11cf07bc..00000000 --- a/vendor/composer/InstalledVersions.php +++ /dev/null @@ -1,283 +0,0 @@ - - array ( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'aliases' => - array ( - ), - 'reference' => '85e967e3f9245f57621d659fac0f148adffabd43', - 'name' => 'ashleyfae/book-database', - ), - 'versions' => - array ( - 'ashleyfae/book-database' => - array ( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'aliases' => - array ( - ), - 'reference' => '85e967e3f9245f57621d659fac0f148adffabd43', - ), - ), -); -private static $canGetVendors; -private static $installedByVendor = array(); - - - - - - - -public static function getInstalledPackages() -{ -$packages = array(); -foreach (self::getInstalled() as $installed) { -$packages[] = array_keys($installed['versions']); -} - - -if (1 === \count($packages)) { -return $packages[0]; -} - -return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); -} - - - - - - - - - -public static function isInstalled($packageName) -{ -foreach (self::getInstalled() as $installed) { -if (isset($installed['versions'][$packageName])) { -return true; -} -} - -return false; -} - - - - - - - - - - - - - - -public static function satisfies(VersionParser $parser, $packageName, $constraint) -{ -$constraint = $parser->parseConstraints($constraint); -$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); - -return $provided->matches($constraint); -} - - - - - - - - - - -public static function getVersionRanges($packageName) -{ -foreach (self::getInstalled() as $installed) { -if (!isset($installed['versions'][$packageName])) { -continue; -} - -$ranges = array(); -if (isset($installed['versions'][$packageName]['pretty_version'])) { -$ranges[] = $installed['versions'][$packageName]['pretty_version']; -} -if (array_key_exists('aliases', $installed['versions'][$packageName])) { -$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); -} -if (array_key_exists('replaced', $installed['versions'][$packageName])) { -$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); -} -if (array_key_exists('provided', $installed['versions'][$packageName])) { -$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); -} - -return implode(' || ', $ranges); -} - -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - - - - - -public static function getVersion($packageName) -{ -foreach (self::getInstalled() as $installed) { -if (!isset($installed['versions'][$packageName])) { -continue; -} - -if (!isset($installed['versions'][$packageName]['version'])) { -return null; -} - -return $installed['versions'][$packageName]['version']; -} - -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - - - - - -public static function getPrettyVersion($packageName) -{ -foreach (self::getInstalled() as $installed) { -if (!isset($installed['versions'][$packageName])) { -continue; -} - -if (!isset($installed['versions'][$packageName]['pretty_version'])) { -return null; -} - -return $installed['versions'][$packageName]['pretty_version']; -} - -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - - - - - -public static function getReference($packageName) -{ -foreach (self::getInstalled() as $installed) { -if (!isset($installed['versions'][$packageName])) { -continue; -} - -if (!isset($installed['versions'][$packageName]['reference'])) { -return null; -} - -return $installed['versions'][$packageName]['reference']; -} - -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - - - - - -public static function getRootPackage() -{ -$installed = self::getInstalled(); - -return $installed[0]['root']; -} - - - - - - - -public static function getRawData() -{ -return self::$installed; -} - - - - - - - - - - - - - - - - - - - -public static function reload($data) -{ -self::$installed = $data; -self::$installedByVendor = array(); -} - - - - -private static function getInstalled() -{ -if (null === self::$canGetVendors) { -self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); -} - -$installed = array(); - -if (self::$canGetVendors) { -foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { -if (isset(self::$installedByVendor[$vendorDir])) { -$installed[] = self::$installedByVendor[$vendorDir]; -} elseif (is_file($vendorDir.'/composer/installed.php')) { -$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; -} -} -} - -$installed[] = self::$installed; - -return $installed; -} -} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE deleted file mode 100644 index f27399a0..00000000 --- a/vendor/composer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - -Copyright (c) Nils Adermann, Jordi Boggiano - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php deleted file mode 100644 index b26f1b13..00000000 --- a/vendor/composer/autoload_classmap.php +++ /dev/null @@ -1,10 +0,0 @@ - $vendorDir . '/composer/InstalledVersions.php', -); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php deleted file mode 100644 index 1285eeff..00000000 --- a/vendor/composer/autoload_files.php +++ /dev/null @@ -1,10 +0,0 @@ - $baseDir . '/src/Deprecated/class-names.php', -); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php deleted file mode 100644 index b7fc0125..00000000 --- a/vendor/composer/autoload_namespaces.php +++ /dev/null @@ -1,9 +0,0 @@ - array($baseDir . '/src'), -); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php deleted file mode 100644 index 2945552c..00000000 --- a/vendor/composer/autoload_real.php +++ /dev/null @@ -1,75 +0,0 @@ -= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require __DIR__ . '/autoload_static.php'; - - call_user_func(\Composer\Autoload\ComposerStaticInit5df8d9708ce95e08fc9df27c2e81f1c1::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } - - $loader->register(true); - - if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit5df8d9708ce95e08fc9df27c2e81f1c1::$files; - } else { - $includeFiles = require __DIR__ . '/autoload_files.php'; - } - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire5df8d9708ce95e08fc9df27c2e81f1c1($fileIdentifier, $file); - } - - return $loader; - } -} - -function composerRequire5df8d9708ce95e08fc9df27c2e81f1c1($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - require $file; - - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - } -} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php deleted file mode 100644 index 91400457..00000000 --- a/vendor/composer/autoload_static.php +++ /dev/null @@ -1,40 +0,0 @@ - __DIR__ . '/../..' . '/src/Deprecated/class-names.php', - ); - - public static $prefixLengthsPsr4 = array ( - 'B' => - array ( - 'Book_Database\\' => 14, - ), - ); - - public static $prefixDirsPsr4 = array ( - 'Book_Database\\' => - array ( - 0 => __DIR__ . '/../..' . '/src', - ), - ); - - public static $classMap = array ( - 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', - ); - - public static function getInitializer(ClassLoader $loader) - { - return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit5df8d9708ce95e08fc9df27c2e81f1c1::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit5df8d9708ce95e08fc9df27c2e81f1c1::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit5df8d9708ce95e08fc9df27c2e81f1c1::$classMap; - - }, null, ClassLoader::class); - } -} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json deleted file mode 100644 index 87fda747..00000000 --- a/vendor/composer/installed.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "packages": [], - "dev": true, - "dev-package-names": [] -} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php deleted file mode 100644 index 3e67a393..00000000 --- a/vendor/composer/installed.php +++ /dev/null @@ -1,24 +0,0 @@ - - array ( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'aliases' => - array ( - ), - 'reference' => '85e967e3f9245f57621d659fac0f148adffabd43', - 'name' => 'ashleyfae/book-database', - ), - 'versions' => - array ( - 'ashleyfae/book-database' => - array ( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'aliases' => - array ( - ), - 'reference' => '85e967e3f9245f57621d659fac0f148adffabd43', - ), - ), -); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php deleted file mode 100644 index f79e574b..00000000 --- a/vendor/composer/platform_check.php +++ /dev/null @@ -1,26 +0,0 @@ -= 70000)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 7.0.0". You are running ' . PHP_VERSION . '.'; -} - -if ($issues) { - if (!headers_sent()) { - header('HTTP/1.1 500 Internal Server Error'); - } - if (!ini_get('display_errors')) { - if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { - fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); - } elseif (!headers_sent()) { - echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; - } - } - trigger_error( - 'Composer detected issues in your platform: ' . implode(' ', $issues), - E_USER_ERROR - ); -} From 343a306f76cef74d586af543ac1b70560f50b9bb Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 20 Nov 2021 13:33:34 +0000 Subject: [PATCH 04/29] Add vendor to gitignore #248 --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a80335fa..c6284b0e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ npm-debug.log *.sass.map *.scss.map /node_modules/ +/vendor/ # amcharts spam assets/js/build/vendors~canvg.min.js From 5b28df3f5b0b455b9a574a4c904159c39e7d1b2f Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 20 Nov 2021 13:34:05 +0000 Subject: [PATCH 05/29] Change plugin updater path. #248 --- book-database.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book-database.php b/book-database.php index c4086b43..963db1bb 100644 --- a/book-database.php +++ b/book-database.php @@ -338,7 +338,7 @@ private function include_admin() { require_once BDB_DIR . 'includes/admin/editions/edition-actions.php'; // Licensing - require_once BDB_DIR . 'vendor/class-edd-sl-plugin-updater.php'; + require_once BDB_DIR . 'includes/class-edd-sl-plugin-updater.php'; require_once BDB_DIR . 'includes/admin/licensing/class-license-key.php'; require_once BDB_DIR . 'includes/admin/licensing/license-actions.php'; From a6da6bf1706b2e76d7a4e9fc4cf5f5f9edad6e28 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 20 Nov 2021 14:25:36 +0000 Subject: [PATCH 06/29] Set up container, service providers #248 --- .phpstorm.meta.php | 11 + book-database.php | 555 +------- src/Container/Container.php | 1242 +++++++++++++++++ .../Exceptions/BindingResolutionException.php | 16 + src/Plugin.php | 300 ++++ .../LegacyServiceProvider.php | 267 ++++ src/ServiceProviders/ServiceProvider.php | 35 + 7 files changed, 1920 insertions(+), 506 deletions(-) create mode 100644 .phpstorm.meta.php create mode 100644 src/Container/Container.php create mode 100644 src/Container/Exceptions/BindingResolutionException.php create mode 100644 src/Plugin.php create mode 100644 src/ServiceProviders/LegacyServiceProvider.php create mode 100644 src/ServiceProviders/ServiceProvider.php diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php new file mode 100644 index 00000000..960c4604 --- /dev/null +++ b/.phpstorm.meta.php @@ -0,0 +1,11 @@ + '@', + '' => '@Class', + ] ) + ); +} diff --git a/book-database.php b/book-database.php index 963db1bb..321594fe 100644 --- a/book-database.php +++ b/book-database.php @@ -31,539 +31,82 @@ namespace Book_Database; -if ( ! defined( 'ABSPATH' ) ) { - exit; +if (! defined('BDB_VERSION')) { + define('BDB_VERSION', '1.2'); } - -if ( ! defined( 'BDB_VERSION' ) ) { - define( 'BDB_VERSION', '1.2' ); -} -if ( ! defined( 'BDB_DIR' ) ) { - define( 'BDB_DIR', plugin_dir_path( __FILE__ ) ); +if (! defined('BDB_DIR')) { + define('BDB_DIR', plugin_dir_path(__FILE__)); } -if ( ! defined( 'BDB_URL' ) ) { - define( 'BDB_URL', plugin_dir_url( __FILE__ ) ); +if (! defined('BDB_URL')) { + define('BDB_URL', plugin_dir_url(__FILE__)); } -if ( ! defined( 'BDB_FILE' ) ) { - define( 'BDB_FILE', __FILE__ ); +if (! defined('BDB_FILE')) { + define('BDB_FILE', __FILE__); } -if ( ! defined( 'NOSE_GRAZE_STORE_URL' ) ) { - define( 'NOSE_GRAZE_STORE_URL', 'https://shop.nosegraze.com' ); -} - -/** - * Class Book_Database - * - * @package Book_Database - */ -final class Book_Database { - - /** - * Instance of the Book_Database class. - * - * @var Book_Database - */ - private static $instance; - - /** - * Array of custom table objects - * - * @var array - */ - private $tables = array(); - - /** - * @var REST_API - */ - private $rest_api; - - /** - * @var HTML - */ - private $html; - - /** - * Book_Database instance. - * - * @return Book_Database Instance of Book_Database class - */ - public static function instance() { - - // Return if already instantiated - if ( self::is_instantiated() ) { - return self::$instance; - } - - // Set up the singleton. - self::setup_instance(); - - // Bootstrap - self::$instance->setup_files(); - self::$instance->setup_application(); - - add_action( 'admin_init', array( self::$instance, 'install' ), 11 ); - - return self::$instance; - - } - - /** - * Whether the main class has been instantiated or not. - * - * @return bool - */ - private static function is_instantiated() { - - // Return true if instance is correct class - if ( ! empty( self::$instance ) && ( self::$instance instanceof Book_Database ) ) { - return true; - } - - // Return false if not instantiated correctly - return false; - - } - - /** - * Set up the singleton instance - */ - private static function setup_instance() { - self::$instance = new Book_Database(); - } - - /** - * Include required files. - * - * @return void - */ - private function setup_files() { - $this->include_files(); - - // Admin - if ( is_admin() || ( defined( 'WP_CLI' ) && WP_CLI ) ) { - $this->include_admin(); - } else { - $this->include_frontend(); - } - } - - /** - * Include global files - */ - private function include_files() { - require_once BDB_DIR . 'vendor/autoload.php'; - - // Database engine - require_once BDB_DIR . 'includes/database/engine/base.php'; - require_once BDB_DIR . 'includes/database/engine/table.php'; - require_once BDB_DIR . 'includes/database/engine/query.php'; - require_once BDB_DIR . 'includes/database/engine/column.php'; - require_once BDB_DIR . 'includes/database/engine/row.php'; - require_once BDB_DIR . 'includes/database/engine/schema.php'; - require_once BDB_DIR . 'includes/database/engine/compare.php'; - require_once BDB_DIR . 'includes/database/engine/date.php'; - require_once BDB_DIR . 'includes/database/engine/series.php'; - require_once BDB_DIR . 'includes/database/engine/tax.php'; - require_once BDB_DIR . 'includes/database/engine/author.php'; - require_once BDB_DIR . 'includes/database/engine/join.php'; - require_once BDB_DIR . 'includes/database/engine/book.php'; - require_once BDB_DIR . 'includes/database/engine/edition.php'; - require_once BDB_DIR . 'includes/database/engine/reading-log.php'; - require_once BDB_DIR . 'includes/database/engine/class-where-clause.php'; - require_once BDB_DIR . 'includes/database/sanitization.php'; - - // Database - authors - require_once BDB_DIR . 'includes/database/authors/class-authors-table.php'; - require_once BDB_DIR . 'includes/database/authors/class-authors-schema.php'; - require_once BDB_DIR . 'includes/database/authors/class-authors-query.php'; - - // Database - book_author_relationships - require_once BDB_DIR . 'includes/database/book-author-relationships/class-book-author-relationships-table.php'; - require_once BDB_DIR . 'includes/database/book-author-relationships/class-book-author-relationships-schema.php'; - require_once BDB_DIR . 'includes/database/book-author-relationships/class-book-author-relationships-query.php'; - - // Database - books - require_once BDB_DIR . 'includes/database/books/class-books-table.php'; - require_once BDB_DIR . 'includes/database/books/class-books-schema.php'; - require_once BDB_DIR . 'includes/database/books/class-books-query.php'; - require_once BDB_DIR . 'includes/database/books/class-book-meta-table.php'; - - // Database - book_links - require_once BDB_DIR . 'includes/database/book-links/class-book-links-table.php'; - require_once BDB_DIR . 'includes/database/book-links/class-book-links-schema.php'; - require_once BDB_DIR . 'includes/database/book-links/class-book-links-query.php'; - - // Database - book_taxonomies - require_once BDB_DIR . 'includes/database/book-taxonomies/class-book-taxonomies-table.php'; - require_once BDB_DIR . 'includes/database/book-taxonomies/class-book-taxonomies-schema.php'; - require_once BDB_DIR . 'includes/database/book-taxonomies/class-book-taxonomies-query.php'; - - // Database - book_term_relationships - require_once BDB_DIR . 'includes/database/book-term-relationships/class-book-term-relationships-table.php'; - require_once BDB_DIR . 'includes/database/book-term-relationships/class-book-term-relationships-schema.php'; - require_once BDB_DIR . 'includes/database/book-term-relationships/class-book-term-relationships-query.php'; - - // Database - book_terms - require_once BDB_DIR . 'includes/database/book-terms/class-book-terms-table.php'; - require_once BDB_DIR . 'includes/database/book-terms/class-book-terms-schema.php'; - require_once BDB_DIR . 'includes/database/book-terms/class-book-terms-query.php'; - - // Database - owned_editions - require_once BDB_DIR . 'includes/database/editions/class-editions-table.php'; - require_once BDB_DIR . 'includes/database/editions/class-editions-schema.php'; - require_once BDB_DIR . 'includes/database/editions/class-editions-query.php'; - - // Database - reading_log - require_once BDB_DIR . 'includes/database/reading-logs/class-reading-logs-table.php'; - require_once BDB_DIR . 'includes/database/reading-logs/class-reading-logs-schema.php'; - require_once BDB_DIR . 'includes/database/reading-logs/class-reading-logs-query.php'; - - // Database - retailers - require_once BDB_DIR . 'includes/database/retailers/class-retailers-table.php'; - require_once BDB_DIR . 'includes/database/retailers/class-retailers-schema.php'; - require_once BDB_DIR . 'includes/database/retailers/class-retailers-query.php'; - - // Database - reviews - require_once BDB_DIR . 'includes/database/reviews/class-reviews-table.php'; - require_once BDB_DIR . 'includes/database/reviews/class-reviews-schema.php'; - require_once BDB_DIR . 'includes/database/reviews/class-reviews-query.php'; - require_once BDB_DIR . 'includes/database/reviews/class-review-meta-table.php'; - - // Database - series - require_once BDB_DIR . 'includes/database/series/class-series-table.php'; - require_once BDB_DIR . 'includes/database/series/class-series-schema.php'; - require_once BDB_DIR . 'includes/database/series/class-series-query.php'; - - // Analytics - require_once BDB_DIR . 'includes/analytics/analytics-functions.php'; - - // Authors - require_once BDB_DIR . 'includes/authors/author-functions.php'; - - // Blocks - require_once BDB_DIR . 'includes/blocks.php'; - - // Book Author Relationships - require_once BDB_DIR . 'includes/book-author-relationships/book-author-relationship-actions.php'; - require_once BDB_DIR . 'includes/book-author-relationships/book-author-relationship-functions.php'; - - // Books - require_once BDB_DIR . 'includes/books/book-functions.php'; - require_once BDB_DIR . 'includes/books/book-layout-functions.php'; - require_once BDB_DIR . 'includes/books/book-meta.php'; - - // Book Links - require_once BDB_DIR . 'includes/book-links/book-link-functions.php'; - - // Book Taxonomies - require_once BDB_DIR . 'includes/book-taxonomies/book-taxonomy-functions.php'; - - // Book Term Relationships - require_once BDB_DIR . 'includes/book-term-relationships/book-term-relationship-actions.php'; - require_once BDB_DIR . 'includes/book-term-relationships/book-term-relationship-functions.php'; - - // Book Terms - require_once BDB_DIR . 'includes/book-terms/book-term-functions.php'; - - // Editions - require_once BDB_DIR . 'includes/editions/edition-functions.php'; - - // Ratings - require_once BDB_DIR . 'includes/ratings/rating-functions.php'; - - // Reading Logs - require_once BDB_DIR . 'includes/reading-logs/reading-log-functions.php'; - - // Retailers - require_once BDB_DIR . 'includes/retailers/retailer-functions.php'; - - // Reviews - require_once BDB_DIR . 'includes/reviews/review-actions.php'; - require_once BDB_DIR . 'includes/reviews/review-functions.php'; - require_once BDB_DIR . 'includes/reviews/review-meta.php'; - - // Series - require_once BDB_DIR . 'includes/series/series-functions.php'; - - // Misc. - require_once BDB_DIR . 'includes/capabilities.php'; - require_once BDB_DIR . 'includes/misc-functions.php'; - require_once BDB_DIR . 'includes/rewrites.php'; - require_once BDB_DIR . 'includes/shortcodes.php'; - require_once BDB_DIR . 'includes/template-functions.php'; - - } - - /** - * Include admin files - */ - private function include_admin() { - - require_once BDB_DIR . 'includes/admin/abstract-class-list-table.php'; - require_once BDB_DIR . 'includes/admin/admin-assets.php'; - require_once BDB_DIR . 'includes/admin/admin-bar.php'; - require_once BDB_DIR . 'includes/admin/admin-notices.php'; - require_once BDB_DIR . 'includes/admin/admin-pages.php'; - - // Analytics - require_once BDB_DIR . 'includes/admin/analytics/analytics-page.php'; - require_once BDB_DIR . 'includes/admin/analytics/tabs/overview.php'; - require_once BDB_DIR . 'includes/admin/analytics/tabs/library.php'; - require_once BDB_DIR . 'includes/admin/analytics/tabs/reading.php'; - require_once BDB_DIR . 'includes/admin/analytics/tabs/ratings.php'; - require_once BDB_DIR . 'includes/admin/analytics/tabs/editions.php'; - require_once BDB_DIR . 'includes/admin/analytics/tabs/reviews.php'; - require_once BDB_DIR . 'includes/admin/analytics/tabs/terms.php'; - - // Authors - require_once BDB_DIR . 'includes/admin/authors/author-actions.php'; - require_once BDB_DIR . 'includes/admin/authors/author-functions.php'; - require_once BDB_DIR . 'includes/admin/authors/authors-page.php'; - - // Book Terms - require_once BDB_DIR . 'includes/admin/book-terms/book-term-actions.php'; - require_once BDB_DIR . 'includes/admin/book-terms/book-term-functions.php'; - require_once BDB_DIR . 'includes/admin/book-terms/book-terms-page.php'; - - // Books - require_once BDB_DIR . 'includes/admin/books/book-actions.php'; - require_once BDB_DIR . 'includes/admin/books/book-functions.php'; - require_once BDB_DIR . 'includes/admin/books/books-page.php'; - require_once BDB_DIR . 'includes/admin/books/edit-book-fields.php'; - - // Dashboard - require_once BDB_DIR . 'includes/admin/dashboard/widgets.php'; - - // Editions - require_once BDB_DIR . 'includes/admin/editions/edition-actions.php'; - - // Licensing - require_once BDB_DIR . 'includes/class-edd-sl-plugin-updater.php'; - require_once BDB_DIR . 'includes/admin/licensing/class-license-key.php'; - require_once BDB_DIR . 'includes/admin/licensing/license-actions.php'; - - // Posts - require_once BDB_DIR . 'includes/admin/posts/post-actions.php'; - - // Reading Logs - require_once BDB_DIR . 'includes/admin/reading-logs/reading-log-actions.php'; - - // Reviews - require_once BDB_DIR . 'includes/admin/reviews/review-actions.php'; - require_once BDB_DIR . 'includes/admin/reviews/review-fields.php'; - require_once BDB_DIR . 'includes/admin/reviews/review-functions.php'; - require_once BDB_DIR . 'includes/admin/reviews/reviews-page.php'; - - // Series - require_once BDB_DIR . 'includes/admin/series/series-actions.php'; - require_once BDB_DIR . 'includes/admin/series/series-functions.php'; - require_once BDB_DIR . 'includes/admin/series/series-page.php'; - - // Settings - require_once BDB_DIR . 'includes/admin/settings/book-layout-functions.php'; - require_once BDB_DIR . 'includes/admin/settings/register-settings.php'; - require_once BDB_DIR . 'includes/admin/settings/display-settings.php'; - - } - - /** - * Include front-end files - */ - private function include_frontend() { - require_once BDB_DIR . 'includes/assets.php'; - } - - /** - * Set up custom database tables - */ - private function setup_application() { - - self::$instance->tables = array( - 'authors' => new Authors_Table(), - 'book_author_relationships' => new Book_Author_Relationships_Table(), - 'book_links' => new Book_Links_Table(), - 'book_taxonomies' => new Book_Taxonomies_Table(), - 'book_term_relationships' => new Book_Term_Relationships_Table(), - 'book_terms' => new Book_Terms_Table(), - 'books' => new Books_Table(), - 'book_meta' => new Book_Meta_Table(), - 'editions' => new Editions_Table(), - 'reading_log' => new Reading_Logs_Table(), - 'retailers' => new Retailers_Table(), - 'reviews' => new Reviews_Table(), - 'review_meta' => new Review_Meta_Table(), - 'series' => new Series_Table(), - ); - - self::$instance->rest_api = new REST_API(); - self::$instance->html = new HTML(); - - } - - /** - * Get a table object by its key - * - * @param string $table_key Table key. One of: - * 'authors', - * 'book_author_relationships', - * 'book_links', - * 'book_taxonomies', - * 'book_term_relationships', - * 'book_terms' - * 'books' - * 'book_meta', - * 'editions' - * 'reading_log' - * 'retailers', - * 'reviews', - * 'review_meta', - * 'series' - * - * @return BerlinDB\Database\Table|false - */ - public function get_table( $table_key ) { - return array_key_exists( $table_key, self::$instance->tables ) ? self::$instance->tables[ $table_key ] : false; - } - - /** - * Returns an array of all registered tables - * - * @return BerlinDB\Database\Table[] - */ - public function get_tables() { - return self::$instance->tables; - } - - /** - * Get the HTML helper class - * - * @return HTML - */ - public function get_html() { - return $this->html; - } - - /** - * Run installation - * - * - Install default taxonomies. - * - Add rewrite tags/rules and flush - */ - public function install() { - - if ( ! get_option( 'bdb_run_activation' ) ) { - return; - } - - /** - * Add default taxonomies. - */ - if ( ! $this->get_table( 'book_taxonomies' )->exists() ) { - $this->get_table( 'book_taxonomies' )->install(); - } - - $default_taxonomies = array( - 'publisher' => array( - 'slug' => 'publisher', - 'name' => esc_html__( 'Publisher', 'book-database' ), - 'format' => 'text' // text, checkbox - ), - 'genre' => array( - 'slug' => 'genre', - 'name' => esc_html__( 'Genre', 'book-database' ), - 'format' => 'text' - ), - 'source' => array( - 'slug' => 'source', - 'name' => esc_html__( 'Source', 'book-database' ), - 'format' => 'checkbox' - ) - ); - - foreach ( $default_taxonomies as $taxonomy ) { - if ( get_book_taxonomy_by( 'slug', $taxonomy['slug'] ) ) { - continue; - } - - try { - add_book_taxonomy( $taxonomy ); - } catch ( Exception $e ) { - - } - } - - /** - * Add rewrite tags/rules and flush - */ - add_rewrite_tags(); - add_rewrite_rules(); - flush_rewrite_rules( true ); - - /** - * Add capabilities - */ - $role = get_role( 'administrator' ); - - foreach ( get_book_capabilities() as $capability ) { - $role->add_cap( $capability, true ); - } - - /** - * Set version number - */ - update_option( 'bdb_version', BDB_VERSION ); - - if ( ! get_option( 'bdb_install_date' ) ) { - update_option( 'bdb_install_date', date( 'Y-m-d H:i:s' ), false ); - } - - delete_option( 'bdb_run_activation' ); - - } - +if (! defined('NOSE_GRAZE_STORE_URL')) { + define('NOSE_GRAZE_STORE_URL', 'https://shop.nosegraze.com'); } - /** - * Require PHP 5.6+ + * Require PHP 7.1+ */ /** * Insufficient PHP version notice. * * @return void */ -function insufficient_php_version() { - ?> -
-

-
- +
+

+ +

+
+ =' ) ) { - return Book_Database::instance(); - } else { - add_action( 'admin_notices', __NAMESPACE__ . '\insufficient_php_version' ); - } +function book_database($abstract = null) +{ + $instance = Plugin::instance(); + + if ($abstract !== null) { + return $instance->make($abstract); + } + + return $instance; } -add_action( 'plugins_loaded', __NAMESPACE__ . '\book_database', 4 ); +if (version_compare(PHP_VERSION, '7.1', '>=')) { + require_once BDB_DIR.'vendor/autoload.php'; + book_database(); +} else { + add_action('admin_notices', __NAMESPACE__.'\insufficient_php_version'); +} /** * On activation, create an option. We'll use this as a flag to actually run our activation later. * - * @see Book_Database::install() + * @see Plugin::install() * * @since 1.0 */ -function activate() { - add_option( 'bdb_run_activation', date( 'Y-m-d H:i:s' ) ); +function activate() +{ + add_option('bdb_run_activation', date('Y-m-d H:i:s')); } -register_activation_hook( __FILE__, __NAMESPACE__ . '\activate' ); +register_activation_hook(__FILE__, __NAMESPACE__.'\activate'); diff --git a/src/Container/Container.php b/src/Container/Container.php new file mode 100644 index 00000000..8a9a86f5 --- /dev/null +++ b/src/Container/Container.php @@ -0,0 +1,1242 @@ +bindings[$abstract]) || + isset($this->instances[$abstract]) || + $this->isAlias($abstract); + } + + /** + * Returns true if the container can return an entry for the given identifier. + * Returns false otherwise. + * + * `has($id)` returning true does not mean that `get($id)` will not throw an exception. + * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`. + * + * @param string $id Identifier of the entry to look for. + * + * @return bool + */ + public function has($id) + { + return $this->bound($id); + } + + /** + * Determine if the given abstract type has been resolved. + * + * @param string $abstract + * + * @return bool + */ + public function resolved($abstract) + { + if ($this->isAlias($abstract)) { + $abstract = $this->getAlias($abstract); + } + + return isset($this->resolved[$abstract]) || + isset($this->instances[$abstract]); + } + + /** + * Determine if a given type is shared. + * + * @param string $abstract + * + * @return bool + */ + public function isShared($abstract) + { + return isset($this->instances[$abstract]) || + (isset($this->bindings[$abstract]['shared']) && + $this->bindings[$abstract]['shared'] === true); + } + + /** + * Determine if a given string is an alias. + * + * @param string $name + * + * @return bool + */ + public function isAlias($name) + { + return isset($this->aliases[$name]); + } + + /** + * Register a binding with the container. + * + * @param string $abstract + * @param Closure|string|null $concrete + * @param bool $shared + * + * @return void + */ + public function bind($abstract, $concrete = null, $shared = false) + { + $this->dropStaleInstances($abstract); + + // If no concrete type was given, we will simply set the concrete type to the + // abstract type. After that, the concrete type to be registered as shared + // without being forced to state their classes in both of the parameters. + if (is_null($concrete)) { + $concrete = $abstract; + } + + // If the factory is not a Closure, it means it is just a class name which is + // bound into this container to the abstract type and we will just wrap it + // up inside its own Closure to give us more convenience when extending. + if (! $concrete instanceof Closure) { + $concrete = $this->getClosure($abstract, $concrete); + } + + $this->bindings[$abstract] = compact('concrete', 'shared'); + + // If the abstract type was already resolved in this container we'll fire the + // rebound listener so that any objects which have already gotten resolved + // can have their copy of the object updated via the listener callbacks. + if ($this->resolved($abstract)) { + $this->rebound($abstract); + } + } + + /** + * Get the Closure to be used when building a type. + * + * @param string $abstract + * @param string $concrete + * + * @return Closure + */ + protected function getClosure($abstract, $concrete) + { + return function ($container, $parameters = []) use ($abstract, $concrete) { + if ($abstract == $concrete) { + return $container->build($concrete); + } + + return $container->resolve( + $concrete, + $parameters, + $raiseEvents = false + ); + }; + } + + /** + * Determine if the container has a method binding. + * + * @param string $method + * + * @return bool + */ + public function hasMethodBinding($method) + { + return isset($this->methodBindings[$method]); + } + + /** + * Bind a callback to resolve with Container::call. + * + * @param array|string $method + * @param Closure $callback + * + * @return void + */ + public function bindMethod($method, $callback) + { + $this->methodBindings[$this->parseBindMethod($method)] = $callback; + } + + /** + * Get the method to be bound in class@method format. + * + * @param array|string $method + * + * @return string + */ + protected function parseBindMethod($method) + { + if (is_array($method)) { + return $method[0].'@'.$method[1]; + } + + return $method; + } + + /** + * Get the method binding for the given method. + * + * @param string $method + * @param mixed $instance + * + * @return mixed + */ + public function callMethodBinding($method, $instance) + { + return call_user_func($this->methodBindings[$method], $instance, $this); + } + + /** + * Register a binding if it hasn't already been registered. + * + * @param string $abstract + * @param Closure|string|null $concrete + * @param bool $shared + * + * @return void + */ + public function bindIf($abstract, $concrete = null, $shared = false) + { + if (! $this->bound($abstract)) { + $this->bind($abstract, $concrete, $shared); + } + } + + /** + * Register a shared binding in the container. + * + * @param string $abstract + * @param Closure|string|null $concrete + * + * @return void + */ + public function singleton($abstract, $concrete = null) + { + $this->bind($abstract, $concrete, true); + } + + /** + * Register a shared binding if it hasn't already been registered. + * + * @param string $abstract + * @param Closure|string|null $concrete + * + * @return void + */ + public function singletonIf($abstract, $concrete = null) + { + if (! $this->bound($abstract)) { + $this->singleton($abstract, $concrete); + } + } + + /** + * "Extend" an abstract type in the container. + * + * @param string $abstract + * @param Closure $closure + * + * @return void + * + * @throws \InvalidArgumentException + */ + public function extend($abstract, Closure $closure) + { + $abstract = $this->getAlias($abstract); + + if (isset($this->instances[$abstract])) { + $this->instances[$abstract] = $closure($this->instances[$abstract], $this); + + $this->rebound($abstract); + } else { + $this->extenders[$abstract][] = $closure; + + if ($this->resolved($abstract)) { + $this->rebound($abstract); + } + } + } + + /** + * Register an existing instance as shared in the container. + * + * @param string $abstract + * @param mixed $instance + * + * @return mixed + */ + public function instance($abstract, $instance) + { + $this->removeAbstractAlias($abstract); + + $isBound = $this->bound($abstract); + + unset($this->aliases[$abstract]); + + // We'll check to determine if this type has been bound before, and if it has + // we will fire the rebound callbacks registered with the container and it + // can be updated with consuming classes that have gotten resolved here. + $this->instances[$abstract] = $instance; + + if ($isBound) { + $this->rebound($abstract); + } + + return $instance; + } + + /** + * Remove an alias from the contextual binding alias cache. + * + * @param string $searched + * + * @return void + */ + protected function removeAbstractAlias($searched) + { + if (! isset($this->aliases[$searched])) { + return; + } + + foreach ($this->abstractAliases as $abstract => $aliases) { + foreach ($aliases as $index => $alias) { + if ($alias == $searched) { + unset($this->abstractAliases[$abstract][$index]); + } + } + } + } + + /** + * Assign a set of tags to a given binding. + * + * @param array|string $abstracts + * @param array|mixed ...$tags + * + * @return void + */ + public function tag($abstracts, $tags) + { + $tags = is_array($tags) ? $tags : array_slice(func_get_args(), 1); + + foreach ($tags as $tag) { + if (! isset($this->tags[$tag])) { + $this->tags[$tag] = []; + } + + foreach ((array) $abstracts as $abstract) { + $this->tags[$tag][] = $abstract; + } + } + } + + /** + * Alias a type to a different name. + * + * @param string $abstract + * @param string $alias + * + * @return void + * + * @throws LogicException + */ + public function alias($abstract, $alias) + { + if ($alias === $abstract) { + throw new LogicException("[{$abstract}] is aliased to itself."); + } + + $this->aliases[$alias] = $abstract; + + $this->abstractAliases[$abstract][] = $alias; + } + + /** + * Bind a new callback to an abstract's rebind event. + * + * @param string $abstract + * @param Closure $callback + * + * @return mixed + */ + public function rebinding($abstract, Closure $callback) + { + $this->reboundCallbacks[$abstract = $this->getAlias($abstract)][] = $callback; + + if ($this->bound($abstract)) { + return $this->make($abstract); + } + + return null; + } + + /** + * Refresh an instance on the given target and method. + * + * @param string $abstract + * @param mixed $target + * @param string $method + * + * @return mixed + */ + public function refresh($abstract, $target, $method) + { + return $this->rebinding( + $abstract, + function ($app, $instance) use ($target, $method) { + $target->{$method}($instance); + } + ); + } + + /** + * Fire the "rebound" callbacks for the given abstract type. + * + * @param string $abstract + * + * @return void + */ + protected function rebound($abstract) + { + $instance = $this->make($abstract); + + foreach ($this->getReboundCallbacks($abstract) as $callback) { + $callback($this, $instance); + } + } + + /** + * Get the rebound callbacks for a given type. + * + * @param string $abstract + * + * @return array + */ + protected function getReboundCallbacks($abstract) + { + return isset($this->reboundCallbacks[$abstract]) ? $this->reboundCallbacks[$abstract] : []; + } + + /** + * Get a closure to resolve the given type from the container. + * + * @param string $abstract + * + * @return Closure + */ + public function factory($abstract) + { + return function () use ($abstract) { + return $this->make($abstract); + }; + } + + /** + * Resolve the given type from the container. + * + * @param string $abstract + * @param array $parameters + * + * @return mixed + * @throws BindingResolutionException + */ + public function make($abstract, array $parameters = []) + { + return $this->resolve($abstract, $parameters); + } + + /** + * Finds an entry of the container by its identifier and returns it. + * + * @param string $id Identifier of the entry to look for. + * + * @return mixed Entry. + * @throws InvalidArgumentException|BindingResolutionException + */ + public function get($id) + { + try { + return $this->resolve($id); + } catch (Exception $e) { + if ($this->has($id)) { + throw $e; + } + + throw new InvalidArgumentException($id, $e->getCode(), $e); + } + } + + /** + * Resolve the given type from the container. + * + * @param string $abstract + * @param array $parameters + * @param bool $raiseEvents + * + * @return mixed + * @throws BindingResolutionException + * @throws ReflectionException + */ + protected function resolve($abstract, $parameters = [], $raiseEvents = true) + { + $abstract = $this->getAlias($abstract); + + $concrete = null; + + // If an instance of the type is currently being managed as a singleton we'll + // just return an existing instance instead of instantiating new instances + // so the developer can keep using the same objects instance every time. + if (isset($this->instances[$abstract])) { + return $this->instances[$abstract]; + } + + $this->with[] = $parameters; + + if (is_null($concrete)) { + $concrete = $this->getConcrete($abstract); + } + + // We're ready to instantiate an instance of the concrete type registered for + // the binding. This will instantiate the types, as well as resolve any of + // its "nested" dependencies recursively until all have gotten resolved. + if ($this->isBuildable($concrete, $abstract)) { + $object = $this->build($concrete); + } else { + $object = $this->make($concrete); + } + + // If we defined any extenders for this type, we'll need to spin through them + // and apply them to the object being built. This allows for the extension + // of services, such as changing configuration or decorating the object. + foreach ($this->getExtenders($abstract) as $extender) { + $object = $extender($object, $this); + } + + // If the requested type is registered as a singleton we'll want to cache off + // the instances in "memory" so we can return it later without creating an + // entirely new instance of an object on each subsequent request for it. + if ($this->isShared($abstract)) { + $this->instances[$abstract] = $object; + } + + if ($raiseEvents) { + $this->fireResolvingCallbacks($abstract, $object); + } + + // Before returning, we will also set the resolved flag to "true" and pop off + // the parameter overrides for this build. After those two things are done + // we will be ready to return back the fully constructed class instance. + $this->resolved[$abstract] = true; + + array_pop($this->with); + + return $object; + } + + /** + * Get the concrete type for a given abstract. + * + * @param string $abstract + * + * @return mixed + */ + protected function getConcrete($abstract) + { + // If we don't have a registered resolver or concrete for the type, we'll just + // assume each type is a concrete name and will attempt to resolve it as is + // since the container should be able to resolve concretes automatically. + if (isset($this->bindings[$abstract])) { + return $this->bindings[$abstract]['concrete']; + } + + return $abstract; + } + + /** + * Determine if the given concrete is buildable. + * + * @param mixed $concrete + * @param string $abstract + * + * @return bool + */ + protected function isBuildable($concrete, $abstract) + { + return $concrete === $abstract || $concrete instanceof Closure; + } + + /** + * Instantiate a concrete instance of the given type. + * + * @param Closure|string $concrete + * + * @return mixed + * @throws BindingResolutionException + * @throws ReflectionException + */ + public function build($concrete) + { + // If the concrete type is actually a Closure, we will just execute it and + // hand back the results of the functions, which allows functions to be + // used as resolvers for more fine-tuned resolution of these objects. + if ($concrete instanceof Closure) { + return $concrete($this, $this->getLastParameterOverride()); + } + + try { + $reflector = new ReflectionClass($concrete); + } catch (ReflectionException $e) { + throw new InvalidArgumentException("Target class [$concrete] does not exist.", 0, $e); + } + + // If the type is not instantiable, the developer is attempting to resolve + // an abstract type such as an Interface or Abstract Class and there is + // no binding registered for the abstractions so we need to bail out. + if (! $reflector->isInstantiable()) { + $this->notInstantiable($concrete); + } + + $this->buildStack[] = $concrete; + + $constructor = $reflector->getConstructor(); + + // If there are no constructors, that means there are no dependencies then + // we can just resolve the instances of the objects right away, without + // resolving any other types or dependencies out of these containers. + if (is_null($constructor)) { + array_pop($this->buildStack); + + return new $concrete; + } + + $dependencies = $constructor->getParameters(); + + // Once we have all the constructor's parameters we can create each of the + // dependency instances and then use the reflection instances to make a + // new instance of this class, injecting the created dependencies in. + try { + $instances = $this->resolveDependencies($dependencies); + } catch (BindingResolutionException $e) { + array_pop($this->buildStack); + + throw $e; + } + + array_pop($this->buildStack); + + return $reflector->newInstanceArgs($instances); + } + + /** + * Resolve all of the dependencies from the ReflectionParameters. + * + * @param array $dependencies + * + * @return array + * @throws BindingResolutionException + * @throws ReflectionException + */ + protected function resolveDependencies(array $dependencies) + { + $results = []; + + foreach ($dependencies as $dependency) { + // If this dependency has a override for this particular build we will use + // that instead as the value. Otherwise, we will continue with this run + // of resolutions and let reflection attempt to determine the result. + if ($this->hasParameterOverride($dependency)) { + $results[] = $this->getParameterOverride($dependency); + + continue; + } + + + // @note: ReflectionParameter::getClass() is deprecated since PHP 8 + // @note: ReflectionParameter::getType() is not supported before PHP7 + $name = version_compare(PHP_VERSION, '8.0', '<') + ? $dependency->getClass() + : $dependency->getType()->getName(); + + // If the class is null, it means the dependency is a string or some other + // primitive type which we can not resolve since it is not a class and + // we will just bomb out with an error since we have no-where to go. + $result = is_null($name) + ? $this->resolvePrimitive($dependency) + : $this->resolveClass($dependency); + + if ($dependency->isVariadic()) { + array_push($results, ...$result); + } else { + $results[] = $result; + } + } + + return $results; + } + + /** + * Determine if the given dependency has a parameter override. + * + * @param ReflectionParameter $dependency + * + * @return bool + */ + protected function hasParameterOverride($dependency) + { + return array_key_exists( + $dependency->name, + $this->getLastParameterOverride() + ); + } + + /** + * Get a parameter override for a dependency. + * + * @param ReflectionParameter $dependency + * + * @return mixed + */ + protected function getParameterOverride($dependency) + { + return $this->getLastParameterOverride()[$dependency->name]; + } + + /** + * Get the last parameter override. + * + * @return array + */ + protected function getLastParameterOverride() + { + return count($this->with) ? end($this->with) : []; + } + + /** + * Resolve a non-class hinted primitive dependency. + * + * @param ReflectionParameter $parameter + * + * @return mixed + * @throws BindingResolutionException + */ + protected function resolvePrimitive(ReflectionParameter $parameter) + { + if ($parameter->isDefaultValueAvailable()) { + return $parameter->getDefaultValue(); + } + + $this->unresolvablePrimitive($parameter); + + return null; + } + + /** + * Resolve a class based dependency from the container. + * + * @param ReflectionParameter $parameter + * + * @return mixed + * @throws BindingResolutionException + * @throws ReflectionException + */ + protected function resolveClass(ReflectionParameter $parameter) + { + try { + // @note: ReflectionParameter::getClass() is deprecated since PHP 8 + // @note: ReflectionParameter::getType() is not supported before PHP7 + return version_compare(PHP_VERSION, '8.0', '<') + ? $this->make($parameter->getClass()->name) + : $this->make($parameter->getType()->getName()); + } + + // If we can not resolve the class instance, we will check to see if the value + // is optional, and if it is we will return the optional parameter value as + // the value of the dependency, similarly to how we do this with scalars. + catch (BindingResolutionException $e) { + if ($parameter->isDefaultValueAvailable()) { + return $parameter->getDefaultValue(); + } + + if ($parameter->isVariadic()) { + return []; + } + + throw $e; + } + } + + /** + * Throw an exception that the concrete is not instantiable. + * + * @param string $concrete + * + * @return void + * @throws BindingResolutionException + */ + protected function notInstantiable($concrete) + { + if (! empty($this->buildStack)) { + $previous = implode(', ', $this->buildStack); + + $message = "Target [$concrete] is not instantiable while building [$previous]."; + } else { + $message = "Target [$concrete] is not instantiable."; + } + + throw new BindingResolutionException($message); + } + + /** + * Throw an exception for an unresolvable primitive. + * + * @param ReflectionParameter $parameter + * + * @return void + * @throws BindingResolutionException + */ + protected function unresolvablePrimitive(ReflectionParameter $parameter) + { + $message = "Unresolvable dependency resolving [$parameter] in class {$parameter->getDeclaringClass()->getName()}"; + + throw new BindingResolutionException($message); + } + + /** + * Register a new resolving callback. + * + * @param Closure|string $abstract + * @param Closure|null $callback + * + * @return void + */ + public function resolving($abstract, Closure $callback = null) + { + if (is_string($abstract)) { + $abstract = $this->getAlias($abstract); + } + + if (is_null($callback) && $abstract instanceof Closure) { + $this->globalResolvingCallbacks[] = $abstract; + } else { + $this->resolvingCallbacks[$abstract][] = $callback; + } + } + + /** + * Register a new after resolving callback for all types. + * + * @param Closure|string $abstract + * @param Closure|null $callback + * + * @return void + */ + public function afterResolving($abstract, Closure $callback = null) + { + if (is_string($abstract)) { + $abstract = $this->getAlias($abstract); + } + + if ($abstract instanceof Closure && is_null($callback)) { + $this->globalAfterResolvingCallbacks[] = $abstract; + } else { + $this->afterResolvingCallbacks[$abstract][] = $callback; + } + } + + /** + * Fire all of the resolving callbacks. + * + * @param string $abstract + * @param mixed $object + * + * @return void + */ + protected function fireResolvingCallbacks($abstract, $object) + { + $this->fireCallbackArray($object, $this->globalResolvingCallbacks); + + $this->fireCallbackArray( + $object, + $this->getCallbacksForType($abstract, $object, $this->resolvingCallbacks) + ); + + $this->fireAfterResolvingCallbacks($abstract, $object); + } + + /** + * Fire all of the after resolving callbacks. + * + * @param string $abstract + * @param mixed $object + * + * @return void + */ + protected function fireAfterResolvingCallbacks($abstract, $object) + { + $this->fireCallbackArray($object, $this->globalAfterResolvingCallbacks); + + $this->fireCallbackArray( + $object, + $this->getCallbacksForType($abstract, $object, $this->afterResolvingCallbacks) + ); + } + + /** + * Get all callbacks for a given type. + * + * @param string $abstract + * @param object $object + * @param array $callbacksPerType + * + * @return array + */ + protected function getCallbacksForType($abstract, $object, array $callbacksPerType) + { + $results = []; + + foreach ($callbacksPerType as $type => $callbacks) { + if ($type === $abstract || $object instanceof $type) { + array_push($results, ...$callbacks); + } + } + + return $results; + } + + /** + * Fire an array of callbacks with an object. + * + * @param mixed $object + * @param array $callbacks + * + * @return void + */ + protected function fireCallbackArray($object, array $callbacks) + { + foreach ($callbacks as $callback) { + $callback($object, $this); + } + } + + /** + * Get the container's bindings. + * + * @return array + */ + public function getBindings() + { + return $this->bindings; + } + + /** + * Get the alias for an abstract if available. + * + * @param string $abstract + * + * @return string + */ + public function getAlias($abstract) + { + if (! isset($this->aliases[$abstract])) { + return $abstract; + } + + return $this->getAlias($this->aliases[$abstract]); + } + + /** + * Get the extender callbacks for a given type. + * + * @param string $abstract + * + * @return array + */ + protected function getExtenders($abstract) + { + $abstract = $this->getAlias($abstract); + + return isset($this->extenders[$abstract]) ? $this->extenders[$abstract] : []; + } + + /** + * Remove all of the extender callbacks for a given type. + * + * @param string $abstract + * + * @return void + */ + public function forgetExtenders($abstract) + { + unset($this->extenders[$this->getAlias($abstract)]); + } + + /** + * Drop all of the stale instances and aliases. + * + * @param string $abstract + * + * @return void + */ + protected function dropStaleInstances($abstract) + { + unset($this->instances[$abstract], $this->aliases[$abstract]); + } + + /** + * Remove a resolved instance from the instance cache. + * + * @param string $abstract + * + * @return void + */ + public function forgetInstance($abstract) + { + unset($this->instances[$abstract]); + } + + /** + * Clear all of the instances from the container. + * + * @return void + */ + public function forgetInstances() + { + $this->instances = []; + } + + /** + * Flush the container of all bindings and resolved instances. + * + * @return void + */ + public function flush() + { + $this->aliases = []; + $this->resolved = []; + $this->bindings = []; + $this->instances = []; + $this->abstractAliases = []; + } + + /** + * Determine if a given offset exists. + * + * @param string $key + * + * @return bool + */ + public function offsetExists($key) + { + return $this->bound($key); + } + + /** + * Get the value at a given offset. + * + * @param string $key + * + * @return mixed + * @throws BindingResolutionException + */ + public function offsetGet($key) + { + return $this->make($key); + } + + /** + * Set the value at a given offset. + * + * @param string $key + * @param mixed $value + * + * @return void + */ + public function offsetSet($key, $value) + { + $this->bind( + $key, + $value instanceof Closure ? $value : function () use ($value) { + return $value; + } + ); + } + + /** + * Unset the value at a given offset. + * + * @param string $key + * + * @return void + */ + public function offsetUnset($key) + { + unset($this->bindings[$key], $this->instances[$key], $this->resolved[$key]); + } + + /** + * Dynamically access container services. + * + * @param string $key + * + * @return mixed + */ + public function __get($key) + { + return $this[$key]; + } + + /** + * Dynamically set container services. + * + * @param string $key + * @param mixed $value + * + * @return void + */ + public function __set($key, $value) + { + $this[$key] = $value; + } + + /** + * Checks to see if the key exists. + * + * @param $key + * + * @return bool + */ + public function __isset($key) + { + return isset($this[$key]); + } + +} diff --git a/src/Container/Exceptions/BindingResolutionException.php b/src/Container/Exceptions/BindingResolutionException.php new file mode 100644 index 00000000..d9063169 --- /dev/null +++ b/src/Container/Exceptions/BindingResolutionException.php @@ -0,0 +1,16 @@ +container = new Container(); + } + + /** + * Plugin instance. + * + * @return Plugin Instance of Plugin class + */ + public static function instance(): Plugin + { + // Return if already instantiated + if (self::isInstantiated()) { + return self::$instance; + } + + // Set up the singleton. + self::$instance = new Plugin(); + + // Bootstrap + self::$instance->setup_application(); + + add_action('admin_init', array(self::$instance, 'install'), 11); + + return self::$instance; + } + + /** + * Magic methods are passed to the service container. + * + * @since 1.3 + * + * @param string $name + * @param mixed $arguments + * + * @return mixed + */ + public function __call($name, $arguments) + { + return call_user_func_array([$this->container, $name], $arguments); + } + + /** + * Properties are passed to the service container. + * + * @since 1.3 + * + * @param string $propertyName + * + * @return mixed|object + * @throws BindingResolutionException + */ + public function __get($propertyName) + { + return $this->container->get($propertyName); + } + + /** + * Whether the main class has been instantiated or not. + * + * @return bool + */ + private static function isInstantiated(): bool + { + return ! empty(self::$instance) && self::$instance instanceof Plugin; + } + + /** + * Set up custom database tables + */ + private function setup_application() + { + self::$instance->loadServiceProviders(); + + self::$instance->tables = array( + 'authors' => new Authors_Table(), + 'book_author_relationships' => new Book_Author_Relationships_Table(), + 'book_links' => new Book_Links_Table(), + 'book_taxonomies' => new Book_Taxonomies_Table(), + 'book_term_relationships' => new Book_Term_Relationships_Table(), + 'book_terms' => new Book_Terms_Table(), + 'books' => new Books_Table(), + 'book_meta' => new Book_Meta_Table(), + 'editions' => new Editions_Table(), + 'reading_log' => new Reading_Logs_Table(), + 'retailers' => new Retailers_Table(), + 'reviews' => new Reviews_Table(), + 'review_meta' => new Review_Meta_Table(), + 'series' => new Series_Table(), + ); + + } + + private function loadServiceProviders(): void + { + if ($this->serviceProvidersLoaded) { + return; + } + + $providers = []; + + foreach ($this->serviceProviders as $serviceProvider) { + if (! is_subclass_of($serviceProvider, ServiceProvider::class)) { + throw new \InvalidArgumentException(sprintf( + '%s class must implement the %s interface.', + $serviceProvider, + ServiceProvider::class + )); + } + + /** @var ServiceProvider $serviceProvider */ + $serviceProvider = new $serviceProvider; + $serviceProvider->register(); + $providers[] = $serviceProvider; + } + + foreach ($providers as $serviceProvider) { + $serviceProvider->boot(); + } + + $this->serviceProvidersLoaded = true; + } + + /** + * Get a table object by its key + * + * @param string $table_key Table key. One of: + * 'authors', + * 'book_author_relationships', + * 'book_links', + * 'book_taxonomies', + * 'book_term_relationships', + * 'book_terms' + * 'books' + * 'book_meta', + * 'editions' + * 'reading_log' + * 'retailers', + * 'reviews', + * 'review_meta', + * 'series' + * + * @return BerlinDB\Database\Table|false + */ + public function get_table(string $table_key) + { + return array_key_exists($table_key, self::$instance->tables) ? self::$instance->tables[$table_key] : false; + } + + /** + * Returns an array of all registered tables + * + * @return BerlinDB\Database\Table[] + */ + public function get_tables(): array + { + return self::$instance->tables; + } + + /** + * Get the HTML helper class + * + * @return HTML + */ + public function get_html(): HTML + { + return $this->html; + } + + /** + * Run installation + * + * - Install default taxonomies. + * - Add rewrite tags/rules and flush + */ + public function install(): void + { + if (! get_option('bdb_run_activation')) { + return; + } + + /** + * Add default taxonomies. + */ + if (! $this->get_table('book_taxonomies')->exists()) { + $this->get_table('book_taxonomies')->install(); + } + + $default_taxonomies = array( + 'publisher' => array( + 'slug' => 'publisher', + 'name' => esc_html__('Publisher', 'book-database'), + 'format' => 'text' // text, checkbox + ), + 'genre' => array( + 'slug' => 'genre', + 'name' => esc_html__('Genre', 'book-database'), + 'format' => 'text' + ), + 'source' => array( + 'slug' => 'source', + 'name' => esc_html__('Source', 'book-database'), + 'format' => 'checkbox' + ) + ); + + foreach ($default_taxonomies as $taxonomy) { + if (get_book_taxonomy_by('slug', $taxonomy['slug'])) { + continue; + } + + try { + add_book_taxonomy($taxonomy); + } catch (Exception $e) { + + } + } + + /** + * Add rewrite tags/rules and flush + */ + add_rewrite_tags(); + add_rewrite_rules(); + flush_rewrite_rules(true); + + /** + * Add capabilities + */ + $role = get_role('administrator'); + + foreach (get_book_capabilities() as $capability) { + $role->add_cap($capability, true); + } + + /** + * Set version number + */ + update_option('bdb_version', BDB_VERSION); + + if (! get_option('bdb_install_date')) { + update_option('bdb_install_date', date('Y-m-d H:i:s'), false); + } + + delete_option('bdb_run_activation'); + } + +} diff --git a/src/ServiceProviders/LegacyServiceProvider.php b/src/ServiceProviders/LegacyServiceProvider.php new file mode 100644 index 00000000..df7f7425 --- /dev/null +++ b/src/ServiceProviders/LegacyServiceProvider.php @@ -0,0 +1,267 @@ +includeLegacyFiles(); + + if (is_admin() || (defined('WP_CLI') && WP_CLI)) { + $this->includeAdminFiles(); + } else { + $this->includeFrontendFiles(); + } + + $this->registerClassAliases(); + $this->bindClasses(); + } + + public function boot(): void + { + + } + + private function includeLegacyFiles(): void + { + // Database engine + require_once BDB_DIR.'includes/database/engine/base.php'; + require_once BDB_DIR.'includes/database/engine/table.php'; + require_once BDB_DIR.'includes/database/engine/query.php'; + require_once BDB_DIR.'includes/database/engine/column.php'; + require_once BDB_DIR.'includes/database/engine/row.php'; + require_once BDB_DIR.'includes/database/engine/schema.php'; + require_once BDB_DIR.'includes/database/engine/compare.php'; + require_once BDB_DIR.'includes/database/engine/date.php'; + require_once BDB_DIR.'includes/database/engine/series.php'; + require_once BDB_DIR.'includes/database/engine/tax.php'; + require_once BDB_DIR.'includes/database/engine/author.php'; + require_once BDB_DIR.'includes/database/engine/join.php'; + require_once BDB_DIR.'includes/database/engine/book.php'; + require_once BDB_DIR.'includes/database/engine/edition.php'; + require_once BDB_DIR.'includes/database/engine/reading-log.php'; + require_once BDB_DIR.'includes/database/engine/class-where-clause.php'; + require_once BDB_DIR.'includes/database/sanitization.php'; + + // Database - authors + require_once BDB_DIR.'includes/database/authors/class-authors-table.php'; + require_once BDB_DIR.'includes/database/authors/class-authors-schema.php'; + require_once BDB_DIR.'includes/database/authors/class-authors-query.php'; + + // Database - book_author_relationships + require_once BDB_DIR.'includes/database/book-author-relationships/class-book-author-relationships-table.php'; + require_once BDB_DIR.'includes/database/book-author-relationships/class-book-author-relationships-schema.php'; + require_once BDB_DIR.'includes/database/book-author-relationships/class-book-author-relationships-query.php'; + + // Database - books + require_once BDB_DIR.'includes/database/books/class-books-table.php'; + require_once BDB_DIR.'includes/database/books/class-books-schema.php'; + require_once BDB_DIR.'includes/database/books/class-books-query.php'; + require_once BDB_DIR.'includes/database/books/class-book-meta-table.php'; + + // Database - book_links + require_once BDB_DIR.'includes/database/book-links/class-book-links-table.php'; + require_once BDB_DIR.'includes/database/book-links/class-book-links-schema.php'; + require_once BDB_DIR.'includes/database/book-links/class-book-links-query.php'; + + // Database - book_taxonomies + require_once BDB_DIR.'includes/database/book-taxonomies/class-book-taxonomies-table.php'; + require_once BDB_DIR.'includes/database/book-taxonomies/class-book-taxonomies-schema.php'; + require_once BDB_DIR.'includes/database/book-taxonomies/class-book-taxonomies-query.php'; + + // Database - book_term_relationships + require_once BDB_DIR.'includes/database/book-term-relationships/class-book-term-relationships-table.php'; + require_once BDB_DIR.'includes/database/book-term-relationships/class-book-term-relationships-schema.php'; + require_once BDB_DIR.'includes/database/book-term-relationships/class-book-term-relationships-query.php'; + + // Database - book_terms + require_once BDB_DIR.'includes/database/book-terms/class-book-terms-table.php'; + require_once BDB_DIR.'includes/database/book-terms/class-book-terms-schema.php'; + require_once BDB_DIR.'includes/database/book-terms/class-book-terms-query.php'; + + // Database - owned_editions + require_once BDB_DIR.'includes/database/editions/class-editions-table.php'; + require_once BDB_DIR.'includes/database/editions/class-editions-schema.php'; + require_once BDB_DIR.'includes/database/editions/class-editions-query.php'; + + // Database - reading_log + require_once BDB_DIR.'includes/database/reading-logs/class-reading-logs-table.php'; + require_once BDB_DIR.'includes/database/reading-logs/class-reading-logs-schema.php'; + require_once BDB_DIR.'includes/database/reading-logs/class-reading-logs-query.php'; + + // Database - retailers + require_once BDB_DIR.'includes/database/retailers/class-retailers-table.php'; + require_once BDB_DIR.'includes/database/retailers/class-retailers-schema.php'; + require_once BDB_DIR.'includes/database/retailers/class-retailers-query.php'; + + // Database - reviews + require_once BDB_DIR.'includes/database/reviews/class-reviews-table.php'; + require_once BDB_DIR.'includes/database/reviews/class-reviews-schema.php'; + require_once BDB_DIR.'includes/database/reviews/class-reviews-query.php'; + require_once BDB_DIR.'includes/database/reviews/class-review-meta-table.php'; + + // Database - series + require_once BDB_DIR.'includes/database/series/class-series-table.php'; + require_once BDB_DIR.'includes/database/series/class-series-schema.php'; + require_once BDB_DIR.'includes/database/series/class-series-query.php'; + + // Analytics + require_once BDB_DIR.'includes/analytics/analytics-functions.php'; + + // Authors + require_once BDB_DIR.'includes/authors/author-functions.php'; + + // Blocks + require_once BDB_DIR.'includes/blocks.php'; + + // Book Author Relationships + require_once BDB_DIR.'includes/book-author-relationships/book-author-relationship-actions.php'; + require_once BDB_DIR.'includes/book-author-relationships/book-author-relationship-functions.php'; + + // Books + require_once BDB_DIR.'includes/books/book-functions.php'; + require_once BDB_DIR.'includes/books/book-layout-functions.php'; + require_once BDB_DIR.'includes/books/book-meta.php'; + + // Book Links + require_once BDB_DIR.'includes/book-links/book-link-functions.php'; + + // Book Taxonomies + require_once BDB_DIR.'includes/book-taxonomies/book-taxonomy-functions.php'; + + // Book Term Relationships + require_once BDB_DIR.'includes/book-term-relationships/book-term-relationship-actions.php'; + require_once BDB_DIR.'includes/book-term-relationships/book-term-relationship-functions.php'; + + // Book Terms + require_once BDB_DIR.'includes/book-terms/book-term-functions.php'; + + // Editions + require_once BDB_DIR.'includes/editions/edition-functions.php'; + + // Ratings + require_once BDB_DIR.'includes/ratings/rating-functions.php'; + + // Reading Logs + require_once BDB_DIR.'includes/reading-logs/reading-log-functions.php'; + + // Retailers + require_once BDB_DIR.'includes/retailers/retailer-functions.php'; + + // Reviews + require_once BDB_DIR.'includes/reviews/review-actions.php'; + require_once BDB_DIR.'includes/reviews/review-functions.php'; + require_once BDB_DIR.'includes/reviews/review-meta.php'; + + // Series + require_once BDB_DIR.'includes/series/series-functions.php'; + + // Misc. + require_once BDB_DIR.'includes/capabilities.php'; + require_once BDB_DIR.'includes/misc-functions.php'; + require_once BDB_DIR.'includes/rewrites.php'; + require_once BDB_DIR.'includes/shortcodes.php'; + require_once BDB_DIR.'includes/template-functions.php'; + } + + private function includeAdminFiles(): void + { + require_once BDB_DIR.'includes/admin/abstract-class-list-table.php'; + require_once BDB_DIR.'includes/admin/admin-assets.php'; + require_once BDB_DIR.'includes/admin/admin-bar.php'; + require_once BDB_DIR.'includes/admin/admin-notices.php'; + require_once BDB_DIR.'includes/admin/admin-pages.php'; + + // Analytics + require_once BDB_DIR.'includes/admin/analytics/analytics-page.php'; + require_once BDB_DIR.'includes/admin/analytics/tabs/overview.php'; + require_once BDB_DIR.'includes/admin/analytics/tabs/library.php'; + require_once BDB_DIR.'includes/admin/analytics/tabs/reading.php'; + require_once BDB_DIR.'includes/admin/analytics/tabs/ratings.php'; + require_once BDB_DIR.'includes/admin/analytics/tabs/editions.php'; + require_once BDB_DIR.'includes/admin/analytics/tabs/reviews.php'; + require_once BDB_DIR.'includes/admin/analytics/tabs/terms.php'; + + // Authors + require_once BDB_DIR.'includes/admin/authors/author-actions.php'; + require_once BDB_DIR.'includes/admin/authors/author-functions.php'; + require_once BDB_DIR.'includes/admin/authors/authors-page.php'; + + // Book Terms + require_once BDB_DIR.'includes/admin/book-terms/book-term-actions.php'; + require_once BDB_DIR.'includes/admin/book-terms/book-term-functions.php'; + require_once BDB_DIR.'includes/admin/book-terms/book-terms-page.php'; + + // Books + require_once BDB_DIR.'includes/admin/books/book-actions.php'; + require_once BDB_DIR.'includes/admin/books/book-functions.php'; + require_once BDB_DIR.'includes/admin/books/books-page.php'; + require_once BDB_DIR.'includes/admin/books/edit-book-fields.php'; + + // Dashboard + require_once BDB_DIR.'includes/admin/dashboard/widgets.php'; + + // Editions + require_once BDB_DIR.'includes/admin/editions/edition-actions.php'; + + // Licensing + require_once BDB_DIR.'includes/class-edd-sl-plugin-updater.php'; + require_once BDB_DIR.'includes/admin/licensing/class-license-key.php'; + require_once BDB_DIR.'includes/admin/licensing/license-actions.php'; + + // Posts + require_once BDB_DIR.'includes/admin/posts/post-actions.php'; + + // Reading Logs + require_once BDB_DIR.'includes/admin/reading-logs/reading-log-actions.php'; + + // Reviews + require_once BDB_DIR.'includes/admin/reviews/review-actions.php'; + require_once BDB_DIR.'includes/admin/reviews/review-fields.php'; + require_once BDB_DIR.'includes/admin/reviews/review-functions.php'; + require_once BDB_DIR.'includes/admin/reviews/reviews-page.php'; + + // Series + require_once BDB_DIR.'includes/admin/series/series-actions.php'; + require_once BDB_DIR.'includes/admin/series/series-functions.php'; + require_once BDB_DIR.'includes/admin/series/series-page.php'; + + // Settings + require_once BDB_DIR.'includes/admin/settings/book-layout-functions.php'; + require_once BDB_DIR.'includes/admin/settings/register-settings.php'; + require_once BDB_DIR.'includes/admin/settings/display-settings.php'; + } + + private function includeFrontendFiles(): void + { + require_once BDB_DIR.'includes/assets.php'; + } + + private function registerClassAliases(): void + { + class_alias(Plugin::class, 'Book_Database\\Book_Database'); + } + + private function bindClasses(): void + { + book_database()->bind(REST_API::class); + book_database()->alias(REST_API::class, 'rest_api'); + + book_database()->bind(HTML::class); + book_database()->alias(HTML::class, 'html'); + } +} diff --git a/src/ServiceProviders/ServiceProvider.php b/src/ServiceProviders/ServiceProvider.php new file mode 100644 index 00000000..04b8d409 --- /dev/null +++ b/src/ServiceProviders/ServiceProvider.php @@ -0,0 +1,35 @@ + Date: Sat, 20 Nov 2021 14:57:05 +0000 Subject: [PATCH 07/29] Start renaming old classes. #248 --- .../admin/books/class-books-list-table.php | 7 +- includes/authors/author-functions.php | 18 +- .../book-author-relationship-functions.php | 14 +- includes/book-links/book-link-functions.php | 18 +- .../book-taxonomy-functions.php | 18 +- .../book-term-relationship-functions.php | 14 +- includes/book-terms/book-term-functions.php | 18 +- includes/books/book-functions.php | 21 +- .../database/authors/class-authors-query.php | 76 ----- .../database/authors/class-authors-schema.php | 113 ------- .../database/authors/class-authors-table.php | 58 ---- .../class-book-author-relationships-query.php | 76 ----- ...class-book-author-relationships-schema.php | 77 ----- .../class-book-author-relationships-table.php | 54 --- .../book-links/class-book-links-query.php | 76 ----- .../book-links/class-book-links-schema.php | 87 ----- .../book-links/class-book-links-table.php | 54 --- .../class-book-taxonomies-query.php | 76 ----- .../class-book-taxonomies-schema.php | 88 ----- .../class-book-taxonomies-table.php | 54 --- .../class-book-term-relationships-query.php | 76 ----- .../class-book-term-relationships-schema.php | 77 ----- .../class-book-term-relationships-table.php | 131 -------- .../book-terms/class-book-terms-query.php | 76 ----- .../book-terms/class-book-terms-schema.php | 122 ------- .../book-terms/class-book-terms-table.php | 208 ------------ .../database/books/class-book-meta-table.php | 54 --- includes/database/books/class-books-query.php | 302 ----------------- .../database/books/class-books-schema.php | 148 -------- includes/database/books/class-books-table.php | 190 ----------- .../editions/class-editions-query.php | 76 ----- .../editions/class-editions-schema.php | 119 ------- .../editions/class-editions-table.php | 182 ---------- .../database/reviews/class-reviews-query.php | 11 +- includes/editions/edition-functions.php | 18 +- src/Book_Grid_Query.php | 5 +- src/Database/Authors/AuthorsQuery.php | 83 +++++ src/Database/Authors/AuthorsSchema.php | 117 +++++++ src/Database/Authors/AuthorsTable.php | 64 ++++ src/Database/BookAuthor/BookAuthorQuery.php | 83 +++++ src/Database/BookAuthor/BookAuthorSchema.php | 81 +++++ src/Database/BookAuthor/BookAuthorTable.php | 60 ++++ src/Database/BookLinks/BookLinksQuery.php | 83 +++++ src/Database/BookLinks/BookLinksSchema.php | 91 +++++ src/Database/BookLinks/BookLinksTable.php | 60 ++++ .../BookTaxonomies/BookTaxonomiesQuery.php | 84 +++++ .../BookTaxonomies/BookTaxonomiesSchema.php | 92 +++++ .../BookTaxonomies/BookTaxonomiesTable.php | 60 ++++ .../BookTerm/BookTermRelationshipQuery.php | 83 +++++ .../BookTerm/BookTermRelationshipsSchema.php | 81 +++++ .../BookTerm/BookTermRelationshipsTable.php | 141 ++++++++ src/Database/BookTerms/BookTermsQuery.php | 83 +++++ src/Database/BookTerms/BookTermsSchema.php | 126 +++++++ src/Database/BookTerms/BookTermsTable.php | 220 ++++++++++++ src/Database/Books/BookMetaTable.php | 60 ++++ src/Database/Books/BooksQuery.php | 316 ++++++++++++++++++ src/Database/Books/BooksSchema.php | 152 +++++++++ src/Database/Books/BooksTable.php | 203 +++++++++++ src/Database/Editions/EditionsQuery.php | 83 +++++ src/Database/Editions/EditionsSchema.php | 123 +++++++ src/Database/Editions/EditionsTable.php | 193 +++++++++++ src/Plugin.php | 27 +- src/REST_API/v1/Book.php | 4 +- .../LegacyServiceProvider.php | 100 +++--- 64 files changed, 2995 insertions(+), 2770 deletions(-) delete mode 100644 includes/database/authors/class-authors-query.php delete mode 100644 includes/database/authors/class-authors-schema.php delete mode 100644 includes/database/authors/class-authors-table.php delete mode 100644 includes/database/book-author-relationships/class-book-author-relationships-query.php delete mode 100644 includes/database/book-author-relationships/class-book-author-relationships-schema.php delete mode 100644 includes/database/book-author-relationships/class-book-author-relationships-table.php delete mode 100644 includes/database/book-links/class-book-links-query.php delete mode 100644 includes/database/book-links/class-book-links-schema.php delete mode 100644 includes/database/book-links/class-book-links-table.php delete mode 100644 includes/database/book-taxonomies/class-book-taxonomies-query.php delete mode 100644 includes/database/book-taxonomies/class-book-taxonomies-schema.php delete mode 100644 includes/database/book-taxonomies/class-book-taxonomies-table.php delete mode 100644 includes/database/book-term-relationships/class-book-term-relationships-query.php delete mode 100644 includes/database/book-term-relationships/class-book-term-relationships-schema.php delete mode 100644 includes/database/book-term-relationships/class-book-term-relationships-table.php delete mode 100644 includes/database/book-terms/class-book-terms-query.php delete mode 100644 includes/database/book-terms/class-book-terms-schema.php delete mode 100644 includes/database/book-terms/class-book-terms-table.php delete mode 100644 includes/database/books/class-book-meta-table.php delete mode 100644 includes/database/books/class-books-query.php delete mode 100644 includes/database/books/class-books-schema.php delete mode 100644 includes/database/books/class-books-table.php delete mode 100644 includes/database/editions/class-editions-query.php delete mode 100644 includes/database/editions/class-editions-schema.php delete mode 100644 includes/database/editions/class-editions-table.php create mode 100644 src/Database/Authors/AuthorsQuery.php create mode 100644 src/Database/Authors/AuthorsSchema.php create mode 100644 src/Database/Authors/AuthorsTable.php create mode 100644 src/Database/BookAuthor/BookAuthorQuery.php create mode 100644 src/Database/BookAuthor/BookAuthorSchema.php create mode 100644 src/Database/BookAuthor/BookAuthorTable.php create mode 100644 src/Database/BookLinks/BookLinksQuery.php create mode 100644 src/Database/BookLinks/BookLinksSchema.php create mode 100644 src/Database/BookLinks/BookLinksTable.php create mode 100644 src/Database/BookTaxonomies/BookTaxonomiesQuery.php create mode 100644 src/Database/BookTaxonomies/BookTaxonomiesSchema.php create mode 100644 src/Database/BookTaxonomies/BookTaxonomiesTable.php create mode 100644 src/Database/BookTerm/BookTermRelationshipQuery.php create mode 100644 src/Database/BookTerm/BookTermRelationshipsSchema.php create mode 100644 src/Database/BookTerm/BookTermRelationshipsTable.php create mode 100644 src/Database/BookTerms/BookTermsQuery.php create mode 100644 src/Database/BookTerms/BookTermsSchema.php create mode 100644 src/Database/BookTerms/BookTermsTable.php create mode 100644 src/Database/Books/BookMetaTable.php create mode 100644 src/Database/Books/BooksQuery.php create mode 100644 src/Database/Books/BooksSchema.php create mode 100644 src/Database/Books/BooksTable.php create mode 100644 src/Database/Editions/EditionsQuery.php create mode 100644 src/Database/Editions/EditionsSchema.php create mode 100644 src/Database/Editions/EditionsTable.php diff --git a/includes/admin/books/class-books-list-table.php b/includes/admin/books/class-books-list-table.php index fcd501be..af394104 100644 --- a/includes/admin/books/class-books-list-table.php +++ b/includes/admin/books/class-books-list-table.php @@ -9,8 +9,11 @@ namespace Book_Database; +use Book_Database\Database\Books\BooksQuery; + /** * Class Books_List_Table + * * @package Book_Database */ class Books_List_Table extends List_Table { @@ -456,7 +459,7 @@ protected function get_query_args( $count = false ) { */ public function get_object_data( $count = false ) { - $query = new Books_Query(); + $query = new BooksQuery(); return $query->get_books( $this->get_query_args( $count ) ); @@ -665,4 +668,4 @@ public function view_switcher( $current_mode = '' ) { } -} \ No newline at end of file +} diff --git a/includes/authors/author-functions.php b/includes/authors/author-functions.php index 91722405..87502ceb 100644 --- a/includes/authors/author-functions.php +++ b/includes/authors/author-functions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Database\Authors\AuthorsQuery; + /** * Get a single author by its ID * @@ -18,7 +20,7 @@ */ function get_book_author( $author_id ) { - $query = new Authors_Query(); + $query = new AuthorsQuery(); return $query->get_item( $author_id ); @@ -34,7 +36,7 @@ function get_book_author( $author_id ) { */ function get_book_author_by( $column_name, $column_value ) { - $query = new Authors_Query(); + $query = new AuthorsQuery(); return $query->get_item_by( $column_name, $column_value ); @@ -80,7 +82,7 @@ function get_book_authors( $args = array() ) { 'number' => 20 ) ); - $query = new Authors_Query(); + $query = new AuthorsQuery(); return $query->query( $args ); @@ -101,7 +103,7 @@ function count_book_authors( $args = array() ) { 'count' => true ) ); - $query = new Authors_Query( $args ); + $query = new AuthorsQuery( $args ); return absint( $query->found_items ); @@ -141,7 +143,7 @@ function add_book_author( $args = array() ) { // Generate a slug. $args['slug'] = ! empty( $args['slug'] ) ? unique_book_slug( $args['slug'], 'book_taxonomy' ) : unique_book_slug( sanitize_title( $args['name'] ), 'author' ); - $query = new Authors_Query(); + $query = new AuthorsQuery(); $author_id = $query->add_item( $args ); if ( empty( $author_id ) ) { @@ -174,7 +176,7 @@ function update_book_author( $author_id, $args = array() ) { $args['slug'] = unique_book_slug( $args['slug'], 'author' ); } - $query = new Authors_Query(); + $query = new AuthorsQuery(); $updated = $query->update_item( $author_id, $args ); if ( ! $updated ) { @@ -195,7 +197,7 @@ function update_book_author( $author_id, $args = array() ) { */ function delete_book_author( $author_id ) { - $query = new Authors_Query(); + $query = new AuthorsQuery(); $deleted = $query->delete_item( $author_id ); if ( ! $deleted ) { @@ -262,4 +264,4 @@ function get_authors_admin_page_url( $args = array() ) { return add_query_arg( $sanitized_args, admin_url( 'admin.php?page=bdb-authors' ) ); -} \ No newline at end of file +} diff --git a/includes/book-author-relationships/book-author-relationship-functions.php b/includes/book-author-relationships/book-author-relationship-functions.php index e6eb599b..044acd17 100644 --- a/includes/book-author-relationships/book-author-relationship-functions.php +++ b/includes/book-author-relationships/book-author-relationship-functions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Database\BookAuthor\BookAuthorQuery; + /** * Get a single book-author-relationship by its ID * @@ -18,7 +20,7 @@ */ function get_book_author_relationship( $relationship_id ) { - $query = new Book_Author_Relationships_Query(); + $query = new BookAuthorQuery(); return $query->get_item( $relationship_id ); @@ -87,7 +89,7 @@ function get_book_author_relationships( $args = array() ) { 'number' => 20 ) ); - $query = new Book_Author_Relationships_Query(); + $query = new BookAuthorQuery(); return $query->query( $args ); @@ -108,7 +110,7 @@ function count_book_author_relationships( $args = array() ) { 'count' => true ) ); - $query = new Book_Author_Relationships_Query( $args ); + $query = new BookAuthorQuery( $args ); return absint( $query->found_items ); @@ -141,7 +143,7 @@ function add_book_author_relationship( $args ) { throw new Exception( 'missing_required_parameter', __( 'A book ID is required.', 'book-database' ), 400 ); } - $query = new Book_Author_Relationships_Query(); + $query = new BookAuthorQuery(); $relationship_id = $query->add_item( $args ); if ( empty( $relationship_id ) ) { @@ -179,7 +181,7 @@ function delete_book_author_relationship( $relationship_id ) { return true; } - $query = new Book_Author_Relationships_Query(); + $query = new BookAuthorQuery(); $deleted = $query->delete_item( $relationship_id ); if ( ! $deleted ) { @@ -382,4 +384,4 @@ function set_book_authors( $book_id, $authors, $append = false ) { } -} \ No newline at end of file +} diff --git a/includes/book-links/book-link-functions.php b/includes/book-links/book-link-functions.php index c8a48dfa..e8959114 100644 --- a/includes/book-links/book-link-functions.php +++ b/includes/book-links/book-link-functions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Database\BookLinks\BookLinksQuery; + /** * Get a single link by its ID * @@ -18,7 +20,7 @@ */ function get_book_link( $link_id ) { - $query = new Book_Links_Query(); + $query = new BookLinksQuery(); return $query->get_item( $link_id ); @@ -34,7 +36,7 @@ function get_book_link( $link_id ) { */ function get_book_link_by( $column_name, $column_value ) { - $query = new Book_Links_Query(); + $query = new BookLinksQuery(); return $query->get_item_by( $column_name, $column_value ); @@ -76,7 +78,7 @@ function get_book_links( $args = array() ) { 'number' => 20 ) ); - $query = new Book_Links_Query(); + $query = new BookLinksQuery(); return $query->query( $args ); @@ -97,7 +99,7 @@ function count_book_links( $args = array() ) { 'count' => true ) ); - $query = new Book_Links_Query( $args ); + $query = new BookLinksQuery( $args ); return absint( $query->found_items ); @@ -134,7 +136,7 @@ function add_book_link( $args = array() ) { throw new Exception( 'missing_required_parameter', __( 'A url is required.', 'book-database' ), 400 ); } - $query = new Book_Links_Query(); + $query = new BookLinksQuery(); $link_id = $query->add_item( $args ); if ( empty( $link_id ) ) { @@ -156,7 +158,7 @@ function add_book_link( $args = array() ) { */ function update_book_link( $link_id, $args = array() ) { - $query = new Book_Links_Query(); + $query = new BookLinksQuery(); $updated = $query->update_item( $link_id, $args ); if ( ! $updated ) { @@ -177,7 +179,7 @@ function update_book_link( $link_id, $args = array() ) { */ function delete_book_link( $link_id ) { - $query = new Book_Links_Query(); + $query = new BookLinksQuery(); $deleted = $query->delete_item( $link_id ); if ( ! $deleted ) { @@ -186,4 +188,4 @@ function delete_book_link( $link_id ) { return true; -} \ No newline at end of file +} diff --git a/includes/book-taxonomies/book-taxonomy-functions.php b/includes/book-taxonomies/book-taxonomy-functions.php index 80e0cb7c..855571a0 100644 --- a/includes/book-taxonomies/book-taxonomy-functions.php +++ b/includes/book-taxonomies/book-taxonomy-functions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Database\BookTaxonomies\BookTaxonomiesQuery; + /** * Get a single taxonomy by its ID * @@ -18,7 +20,7 @@ */ function get_book_taxonomy( $taxonomy_id ) { - $query = new Book_Taxonomies_Query(); + $query = new BookTaxonomiesQuery(); return $query->get_item( $taxonomy_id ); @@ -34,7 +36,7 @@ function get_book_taxonomy( $taxonomy_id ) { */ function get_book_taxonomy_by( $column_name, $column_value ) { - $query = new Book_Taxonomies_Query(); + $query = new BookTaxonomiesQuery(); return $query->get_item_by( $column_name, $column_value ); @@ -80,7 +82,7 @@ function get_book_taxonomies( $args = array() ) { 'number' => 20 ) ); - $query = new Book_Taxonomies_Query(); + $query = new BookTaxonomiesQuery(); return $query->query( $args ); @@ -101,7 +103,7 @@ function count_book_taxonomies( $args = array() ) { 'count' => true ) ); - $query = new Book_Taxonomies_Query( $args ); + $query = new BookTaxonomiesQuery( $args ); return absint( $query->found_items ); @@ -139,7 +141,7 @@ function add_book_taxonomy( $args ) { $args['slug'] = sanitize_key( $args['slug'] ); $args['display'] = sanitize_text_field( wp_strip_all_tags( $args['display'] ) ); - $query = new Book_Taxonomies_Query(); + $query = new BookTaxonomiesQuery(); $taxonomy_id = $query->add_item( $args ); if ( empty( $taxonomy_id ) ) { @@ -166,7 +168,7 @@ function update_book_taxonomy( $taxonomy_id, $args = array() ) { throw new Exception( 'invalid_parameter', __( 'Taxonomy slugs cannot be changed.', 'book-database' ), 400 ); } - $query = new Book_Taxonomies_Query(); + $query = new BookTaxonomiesQuery(); $updated = $query->update_item( $taxonomy_id, $args ); if ( ! $updated ) { @@ -205,7 +207,7 @@ function delete_book_taxonomy( $taxonomy_id ) { throw new Exception( 'protected_taxonomy', sprintf( __( 'The %s taxonomy cannot be deleted.', 'book-database' ), $taxonomy->get_slug() ), 400 ); } - $query = new Book_Taxonomies_Query(); + $query = new BookTaxonomiesQuery(); $deleted = $query->delete_item( $taxonomy_id ); if ( ! $deleted ) { @@ -214,4 +216,4 @@ function delete_book_taxonomy( $taxonomy_id ) { return true; -} \ No newline at end of file +} diff --git a/includes/book-term-relationships/book-term-relationship-functions.php b/includes/book-term-relationships/book-term-relationship-functions.php index 7c4bc490..cbc621a1 100644 --- a/includes/book-term-relationships/book-term-relationship-functions.php +++ b/includes/book-term-relationships/book-term-relationship-functions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Database\BookTerm\BookTermRelationshipQuery; + /** * Get a single book-term-relationship by its ID * @@ -18,7 +20,7 @@ */ function get_book_term_relationship( $relationship_id ) { - $query = new Book_Term_Relationships_Query(); + $query = new BookTermRelationshipQuery(); return $query->get_item( $relationship_id ); @@ -87,7 +89,7 @@ function get_book_term_relationships( $args = array() ) { 'number' => 20 ) ); - $query = new Book_Term_Relationships_Query(); + $query = new BookTermRelationshipQuery(); return $query->query( $args ); @@ -108,7 +110,7 @@ function count_book_term_relationships( $args = array() ) { 'count' => true ) ); - $query = new Book_Term_Relationships_Query( $args ); + $query = new BookTermRelationshipQuery( $args ); return absint( $query->found_items ); @@ -141,7 +143,7 @@ function add_book_term_relationship( $args ) { throw new Exception( 'missing_required_parameter', __( 'A book ID is required.', 'book-database' ), 400 ); } - $query = new Book_Term_Relationships_Query(); + $query = new BookTermRelationshipQuery(); $relationship_id = $query->add_item( $args ); if ( empty( $relationship_id ) ) { @@ -179,7 +181,7 @@ function delete_book_term_relationship( $relationship_id ) { return true; } - $query = new Book_Term_Relationships_Query(); + $query = new BookTermRelationshipQuery(); $deleted = $query->delete_item( $relationship_id ); if ( ! $deleted ) { @@ -378,4 +380,4 @@ function set_book_terms( $book_id, $terms, $taxonomy, $append = false ) { } -} \ No newline at end of file +} diff --git a/includes/book-terms/book-term-functions.php b/includes/book-terms/book-term-functions.php index 2a7e1afa..379aa03f 100644 --- a/includes/book-terms/book-term-functions.php +++ b/includes/book-terms/book-term-functions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Database\BookTerms\BookTermsQuery; + /** * Get a single book term by its ID * @@ -18,7 +20,7 @@ */ function get_book_term( $term_id ) { - $query = new Book_Terms_Query(); + $query = new BookTermsQuery(); return $query->get_item( $term_id ); @@ -34,7 +36,7 @@ function get_book_term( $term_id ) { */ function get_book_term_by( $column_name, $column_value ) { - $query = new Book_Terms_Query(); + $query = new BookTermsQuery(); return $query->get_item_by( $column_name, $column_value ); @@ -107,7 +109,7 @@ function get_book_terms( $args = array() ) { 'number' => 20 ) ); - $query = new Book_Terms_Query(); + $query = new BookTermsQuery(); return $query->query( $args ); @@ -128,7 +130,7 @@ function count_book_terms( $args = array() ) { 'count' => true ) ); - $query = new Book_Terms_Query( $args ); + $query = new BookTermsQuery( $args ); return absint( $query->found_items ); @@ -175,7 +177,7 @@ function add_book_term( $args ) { // Generate a slug. $args['slug'] = ! empty( $args['slug'] ) ? unique_book_slug( $args['slug'], $args['taxonomy'] ) : unique_book_slug( sanitize_title( $args['name'], $args['taxonomy'] ) ); - $query = new Book_Terms_Query(); + $query = new BookTermsQuery(); $term_id = $query->add_item( $args ); if ( empty( $term_id ) ) { @@ -210,7 +212,7 @@ function update_book_term( $term_id, $args = array() ) { $args['slug'] = unique_book_slug( $args['slug'], $term->get_taxonomy() ); } - $query = new Book_Terms_Query(); + $query = new BookTermsQuery(); $updated = $query->update_item( $term_id, $args ); if ( ! $updated ) { @@ -233,7 +235,7 @@ function update_book_term( $term_id, $args = array() ) { */ function delete_book_term( $term_id ) { - $query = new Book_Terms_Query(); + $query = new BookTermsQuery(); $deleted = $query->delete_item( $term_id ); if ( ! $deleted ) { @@ -300,4 +302,4 @@ function get_book_terms_admin_page_url( $args = array() ) { return add_query_arg( $sanitized_args, admin_url( 'admin.php?page=bdb-terms' ) ); -} \ No newline at end of file +} diff --git a/includes/books/book-functions.php b/includes/books/book-functions.php index c0a33dff..fc1cf7eb 100644 --- a/includes/books/book-functions.php +++ b/includes/books/book-functions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Database\Books\BooksQuery; + /** * Get a single book by its ID * @@ -18,7 +20,7 @@ */ function get_book( $book_id ) { - $query = new Books_Query(); + $query = new BooksQuery(); return $query->get_item( $book_id ); @@ -34,7 +36,7 @@ function get_book( $book_id ) { */ function get_book_by( $column_name, $column_value ) { - $query = new Books_Query(); + $query = new BooksQuery(); return $query->get_item_by( $column_name, $column_value ); @@ -44,7 +46,8 @@ function get_book_by( $column_name, $column_value ) { * Query for books * * Note: An alternative to this function is Books_Query::get_books(). - * @see Books_Query::get_books() + * + * @see BooksQuery::get_books() * * Here's how they differ: * @@ -112,7 +115,7 @@ function get_books( $args = array() ) { 'number' => 20 ) ); - $query = new Books_Query(); + $query = new BooksQuery(); return $query->query( $args ); @@ -133,7 +136,7 @@ function count_books( $args = array() ) { 'count' => true ) ); - $query = new Books_Query( $args ); + $query = new BooksQuery( $args ); return absint( $query->found_items ); @@ -181,7 +184,7 @@ function add_book( $args = array() ) { throw new Exception( 'missing_parameter', __( 'Book title is required.', 'book-database' ), 400 ); } - $query = new Books_Query(); + $query = new BooksQuery(); $book_id = $query->add_item( $args ); if ( empty( $book_id ) ) { @@ -213,7 +216,7 @@ function add_book( $args = array() ) { */ function update_book( $book_id, $args = array() ) { - $query = new Books_Query(); + $query = new BooksQuery(); $updated = $query->update_item( $book_id, $args ); if ( ! $updated ) { @@ -239,7 +242,7 @@ function delete_book( $book_id ) { global $wpdb; - $query = new Books_Query(); + $query = new BooksQuery(); $deleted = $query->delete_item( $book_id ); if ( ! $deleted ) { @@ -329,4 +332,4 @@ function generate_book_index_title( $original_title ) { */ return apply_filters( 'book-database/book/generate-index-title', $index_title, $original_title ); -} \ No newline at end of file +} diff --git a/includes/database/authors/class-authors-query.php b/includes/database/authors/class-authors-query.php deleted file mode 100644 index 1ab5b227..00000000 --- a/includes/database/authors/class-authors-query.php +++ /dev/null @@ -1,76 +0,0 @@ - 'id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'extra' => 'auto_increment', - 'primary' => true, - 'sortable' => true - ), - - // name - array( - 'name' => 'name', - 'type' => 'varchar', - 'length' => '200', - 'sortable' => true, - 'searchable' => true, - 'validate' => 'sanitize_text_field' - ), - - // slug - array( - 'name' => 'slug', - 'type' => 'varchar', - 'length' => '200', - 'sortable' => true, - 'validate' => 'sanitize_key' - ), - - // description - array( - 'name' => 'description', - 'type' => 'longtext', - 'validate' => 'wp_kses_post' - ), - - // image_id - array( - 'name' => 'image_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'allow_null' => true, - 'default' => null, - 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' - ), - - // links - array( - 'name' => 'links', - 'type' => 'longtext', - ), - - // book_count - array( - 'name' => 'book_count', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'default' => 0 - ), - - // date_created - array( - 'name' => 'date_created', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'created' => true, - 'date_query' => true, - 'sortable' => true, - ), - - // date_modified - array( - 'name' => 'date_modified', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'modified' => true, - 'date_query' => true, - 'sortable' => true, - ), - - ); - -} \ No newline at end of file diff --git a/includes/database/authors/class-authors-table.php b/includes/database/authors/class-authors-table.php deleted file mode 100644 index 68886612..00000000 --- a/includes/database/authors/class-authors-table.php +++ /dev/null @@ -1,58 +0,0 @@ -schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - name varchar(200) NOT NULL DEFAULT '', - slug varchar(200) NOT NULL DEFAULT '', - description longtext NOT NULL DEFAULT '', - image_id bigint(20) UNSIGNED DEFAULT NULL, - links longtext NOT NULL DEFAULT '', - book_count bigint(20) UNSIGNED NOT NULL DEFAULT 0, - date_created datetime NOT NULL, - date_modified datetime NOT NULL, - INDEX name (name), - INDEX slug (slug)"; - } - -} \ No newline at end of file diff --git a/includes/database/book-author-relationships/class-book-author-relationships-query.php b/includes/database/book-author-relationships/class-book-author-relationships-query.php deleted file mode 100644 index 79528239..00000000 --- a/includes/database/book-author-relationships/class-book-author-relationships-query.php +++ /dev/null @@ -1,76 +0,0 @@ - 'id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'extra' => 'auto_increment', - 'primary' => true, - 'sortable' => true - ), - - // author_id - array( - 'name' => 'author_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true - ), - - // book_id - array( - 'name' => 'book_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true - ), - - // date_created - array( - 'name' => 'date_created', - 'type' => 'datetime', - 'default' => '', - 'created' => true, - 'date_query' => true, - 'sortable' => true, - ), - - // date_modified - array( - 'name' => 'date_modified', - 'type' => 'datetime', - 'default' => '', - 'modified' => true, - 'date_query' => true, - 'sortable' => true, - ), - - ); - -} \ No newline at end of file diff --git a/includes/database/book-author-relationships/class-book-author-relationships-table.php b/includes/database/book-author-relationships/class-book-author-relationships-table.php deleted file mode 100644 index 869ba31f..00000000 --- a/includes/database/book-author-relationships/class-book-author-relationships-table.php +++ /dev/null @@ -1,54 +0,0 @@ -schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - author_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, - book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, - date_created datetime NOT NULL, - date_modified datetime NOT NULL, - INDEX author_id (author_id), - INDEX book_id (book_id)"; - } - -} \ No newline at end of file diff --git a/includes/database/book-links/class-book-links-query.php b/includes/database/book-links/class-book-links-query.php deleted file mode 100644 index 9eb91bf7..00000000 --- a/includes/database/book-links/class-book-links-query.php +++ /dev/null @@ -1,76 +0,0 @@ - 'id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'extra' => 'auto_increment', - 'primary' => true, - 'sortable' => true - ), - - // book_id - array( - 'name' => 'book_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'validate' => 'absint' - ), - - // retailer_id - array( - 'name' => 'retailer_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'validate' => 'absint' - ), - - // url - array( - 'name' => 'url', - 'type' => 'text', - 'searchable' => true, - 'validate' => 'esc_url_raw' - ), - - // date_created - array( - 'name' => 'date_created', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'created' => true, - 'date_query' => true, - 'sortable' => true, - ), - - // date_modified - array( - 'name' => 'date_modified', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'modified' => true, - 'date_query' => true, - 'sortable' => true, - ), - - ); - -} \ No newline at end of file diff --git a/includes/database/book-links/class-book-links-table.php b/includes/database/book-links/class-book-links-table.php deleted file mode 100644 index c472f434..00000000 --- a/includes/database/book-links/class-book-links-table.php +++ /dev/null @@ -1,54 +0,0 @@ -schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - book_id bigint(20) UNSIGNED NOT NULL, - retailer_id bigint(20) UNSIGNED NOT NULL, - url text NOT NULL DEFAULT '', - date_created datetime NOT NULL, - date_modified datetime NOT NULL, - INDEX book_id (book_id)"; - } - -} \ No newline at end of file diff --git a/includes/database/book-taxonomies/class-book-taxonomies-query.php b/includes/database/book-taxonomies/class-book-taxonomies-query.php deleted file mode 100644 index 3943b4a5..00000000 --- a/includes/database/book-taxonomies/class-book-taxonomies-query.php +++ /dev/null @@ -1,76 +0,0 @@ - 'id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'extra' => 'auto_increment', - 'primary' => true, - 'sortable' => true - ), - - // name - array( - 'name' => 'name', - 'type' => 'varchar', - 'length' => '32', - 'sortable' => true, - 'searchable' => true, - 'validate' => 'sanitize_text_field' - ), - - // slug - array( - 'name' => 'slug', - 'type' => 'varchar', - 'length' => '32', - 'sortable' => true, - 'validate' => 'sanitize_key' - ), - - // format - array( - 'name' => 'format', - 'type' => 'varchar', - 'length' => '32', - 'sortable' => true, - 'default' => 'text', - 'validate' => 'sanitize_text_field' - ), - - // date_created - array( - 'name' => 'date_created', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'created' => true, - 'date_query' => true, - 'sortable' => true, - ), - - // date_modified - array( - 'name' => 'date_modified', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'modified' => true, - 'date_query' => true, - 'sortable' => true, - ), - - ); - -} \ No newline at end of file diff --git a/includes/database/book-taxonomies/class-book-taxonomies-table.php b/includes/database/book-taxonomies/class-book-taxonomies-table.php deleted file mode 100644 index 7f9312cc..00000000 --- a/includes/database/book-taxonomies/class-book-taxonomies-table.php +++ /dev/null @@ -1,54 +0,0 @@ -schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - name varchar(32) NOT NULL DEFAULT '', - slug varchar(32) NOT NULL DEFAULT '', - format varchar(32) NOT NULL DEFAULT 'text', - date_created datetime NOT NULL, - date_modified datetime NOT NULL, - INDEX slug( slug )"; - } - -} \ No newline at end of file diff --git a/includes/database/book-term-relationships/class-book-term-relationships-query.php b/includes/database/book-term-relationships/class-book-term-relationships-query.php deleted file mode 100644 index c5d96b61..00000000 --- a/includes/database/book-term-relationships/class-book-term-relationships-query.php +++ /dev/null @@ -1,76 +0,0 @@ - 'id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'extra' => 'auto_increment', - 'primary' => true, - 'sortable' => true - ), - - // term_id - array( - 'name' => 'term_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true - ), - - // book_id - array( - 'name' => 'book_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true - ), - - // date_created - array( - 'name' => 'date_created', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'created' => true, - 'date_query' => true, - 'sortable' => true, - ), - - // date_modified - array( - 'name' => 'date_modified', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'modified' => true, - 'date_query' => true, - 'sortable' => true, - ), - - ); - -} \ No newline at end of file diff --git a/includes/database/book-term-relationships/class-book-term-relationships-table.php b/includes/database/book-term-relationships/class-book-term-relationships-table.php deleted file mode 100644 index 25a0a5b7..00000000 --- a/includes/database/book-term-relationships/class-book-term-relationships-table.php +++ /dev/null @@ -1,131 +0,0 @@ - 201910122, - '201910123' => 201910123, - '201910124' => 201910124 - ); - - /** - * Book_Term_Relationships_Table constructor. - */ - public function __construct() { - parent::__construct(); - } - - /** - * Set up the database schema - */ - protected function set_schema() { - $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - term_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, - book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, - date_created datetime NOT NULL, - date_modified datetime NOT NULL, - INDEX book_id (book_id), - INDEX term_id (term_id)"; - } - - /** - * If the old `wp_bdb_book_term_relationships_db_version` option exists, copy that value to our new version key. - * This will ensure new upgrades are processed on old installs. - */ - public function maybe_upgrade() { - - $old_key = $this->get_db()->prefix . 'bdb_book_term_relationships_db_version'; - $old_version = get_option( $old_key ); - - if ( false !== $old_version ) { - update_option( $this->db_version_key, get_option( $old_key ) ); - - delete_option( $old_key ); - } - - return parent::maybe_upgrade(); - - } - - /** - * Upgrade to version 201910122 - * - Rename `ID` to `id` & add `unsigned` - * - * @return bool - */ - protected function __201910122() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `ID` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT" ); - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910123 - * - Add `unsigned` to `term_id` and `book_id` - * - * @return bool - */ - protected function __201910123() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} MODIFY term_id bigint(20) UNSIGNED NOT NULL DEFAULT 0" ); - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} MODIFY book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0" ); - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910124 - * - Add `date_created` column - * - Add `date_modified` column - * - * @return bool - */ - protected function __201910124() { - - $result = $this->column_exists( 'date_created' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - $result = $this->column_exists( 'date_modified' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - return $this->is_success( $result ); - - } - -} \ No newline at end of file diff --git a/includes/database/book-terms/class-book-terms-query.php b/includes/database/book-terms/class-book-terms-query.php deleted file mode 100644 index e9147084..00000000 --- a/includes/database/book-terms/class-book-terms-query.php +++ /dev/null @@ -1,76 +0,0 @@ - 'id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'extra' => 'auto_increment', - 'primary' => true, - 'sortable' => true - ), - - // taxonomy - array( - 'name' => 'taxonomy', - 'type' => 'varchar', - 'length' => '32', - 'sortable' => true, - 'validate' => 'sanitize_text_field' - ), - - // name - array( - 'name' => 'name', - 'type' => 'varchar', - 'length' => '200', - 'sortable' => true, - 'searchable' => true, - 'validate' => 'sanitize_text_field' - ), - - // slug - array( - 'name' => 'slug', - 'type' => 'varchar', - 'length' => '200', - 'sortable' => true, - 'searchable' => true, - 'validate' => 'sanitize_key' - ), - - // description - array( - 'name' => 'description', - 'type' => 'longtext', - 'validate' => 'wp_kses_post' - ), - - // image_id - array( - 'name' => 'image_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'allow_null' => true, - 'default' => null, - 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' - ), - - // links - array( - 'name' => 'links', - 'type' => 'longtext', - ), - - // book_count - array( - 'name' => 'book_count', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true - ), - - // date_created - array( - 'name' => 'date_created', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'created' => true, - 'date_query' => true, - 'sortable' => true, - ), - - // date_modified - array( - 'name' => 'date_modified', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'modified' => true, - 'date_query' => true, - 'sortable' => true, - ), - - ); - -} \ No newline at end of file diff --git a/includes/database/book-terms/class-book-terms-table.php b/includes/database/book-terms/class-book-terms-table.php deleted file mode 100644 index adf626e1..00000000 --- a/includes/database/book-terms/class-book-terms-table.php +++ /dev/null @@ -1,208 +0,0 @@ - 201910122, - '201910123' => 201910123, - '201910125' => 201910125, - '201910126' => 201910126, - '201910181' => 201910181 - ); - - /** - * Book_Terms_Table constructor. - */ - public function __construct() { - parent::__construct(); - } - - /** - * Set up the database schema - */ - protected function set_schema() { - $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - taxonomy varchar(32) NOT NULL DEFAULT '', - name varchar(200) NOT NULL DEFAULT '', - slug varchar(200) NOT NULL DEFAULT '', - description longtext NOT NULL DEFAULT '', - image_id bigint(20) UNSIGNED DEFAULT NULL, - links longtext NOT NULL DEFAULT '', - book_count bigint(20) UNSIGNED NOT NULL DEFAULT 0, - date_created datetime NOT NULL, - date_modified datetime NOT NULL, - INDEX id_taxonomy_name (id, taxonomy, name), - INDEX id_taxonomy_slug (id, taxonomy, slug), - INDEX taxonomy (taxonomy), - INDEX name (name)"; - } - - /** - * If the old `wp_bdb_book_terms_db_version` option exists, copy that value to our new version key. - * This will ensure new upgrades are processed on old installs. - */ - public function maybe_upgrade() { - - $old_key = $this->get_db()->prefix . 'bdb_book_terms_db_version'; - $old_version = get_option( $old_key ); - - if ( false !== $old_version ) { - update_option( $this->db_version_key, get_option( $old_key ) ); - - delete_option( $old_key ); - } - - return parent::maybe_upgrade(); - - } - - /** - * Upgrade to version 201910122 - * - Rename `term_id` to `id` & add `unsigned` - * - * @return bool - */ - protected function __201910122() { - - $result = true; - - // Drop keys involving `term_id` or `type`. - if ( $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'id_type_name'" ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} DROP INDEX id_type_name" ); - } - if ( $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'id_type_slug'" ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} DROP INDEX id_type_slug" ); - } - if ( $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'type'" ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} DROP INDEX type" ); - } - - if ( $result && $this->column_exists( 'term_id' ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `term_id` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT" ); - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910123 - * - Change `image` to `image_id` & add `unsigned` - * - * @return bool - */ - protected function __201910123() { - - if ( $this->column_exists( 'image' ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `image` `image_id` bigint(20) UNSIGNED NOT NULL DEFAULT 0" ); - } else { - $result = true; - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910125 - * - Add `date_created` column - * - Add `date_modified` column - * - * @return bool - */ - protected function __201910125() { - - $result = $this->column_exists( 'date_created' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - $result = $this->column_exists( 'date_modified' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910126 - * - Change `type` to `taxonomy` - * - Add new indexes - * - * @return bool - */ - protected function __201910126() { - - if ( $this->column_exists( 'type' ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `type` `taxonomy` varchar(32) NOT NULL DEFAULT ''" ); - } else { - $result = true; - } - - // Add new indexes. - if ( $result ) { - if ( ! $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'id_taxonomy_name'" ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD UNIQUE KEY id_taxonomy_name (id, taxonomy, name)" ); - } - if ( ! $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'id_taxonomy_slug'" ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD UNIQUE KEY id_taxonomy_slug (id, taxonomy, slug)" ); - } - if ( ! $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'taxonomy'" ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD KEY taxonomy (taxonomy)" ); - } - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910181 - * - Change `count` to `book_count` - * - * @return bool - */ - protected function __201910181() { - - if ( $this->column_exists( 'count' ) && ! $this->column_exists( 'book_count' ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `count` `book_count` bigint(20) UNSIGNED NOT NULL DEFAULT 0" ); - } else { - $result = true; - } - - return $this->is_success( $result ); - - } - -} diff --git a/includes/database/books/class-book-meta-table.php b/includes/database/books/class-book-meta-table.php deleted file mode 100644 index 18118375..00000000 --- a/includes/database/books/class-book-meta-table.php +++ /dev/null @@ -1,54 +0,0 @@ -schema = "meta_id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - bdb_book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, - meta_key varchar(255) DEFAULT NULL, - meta_value longtext DEFAULT NULL, - INDEX bdb_book_id (bdb_book_id), - INDEX meta_key (meta_key({$max_index_length}))"; - } - -} \ No newline at end of file diff --git a/includes/database/books/class-books-query.php b/includes/database/books/class-books-query.php deleted file mode 100644 index dc1654ac..00000000 --- a/includes/database/books/class-books-query.php +++ /dev/null @@ -1,302 +0,0 @@ - array(), - 'book_query' => array(), - 'series_query' => array(), - 'reading_log_query' => array(), - 'review_query' => array(), - 'edition_query' => array(), - 'tax_query' => array(), - 'unread' => false, - 'orderby' => 'book.id', - 'order' => 'DESC', - 'include_rating' => true, - 'include_review' => false, // Whether or not to always include review data. - 'number' => 20, - 'offset' => 0, - 'count' => false - ) ); - - $select = $join = $where = array(); - - $clause_engine = new Where_Clause(); - - $tbl_books = book_database()->get_table( 'books' )->get_table_name(); - $tbl_author = book_database()->get_table( 'authors' )->get_table_name(); - $tbl_author_r = book_database()->get_table( 'book_author_relationships' )->get_table_name(); - $tbl_ed = book_database()->get_table( 'editions' )->get_table_name(); - $tbl_log = book_database()->get_table( 'reading_log' )->get_table_name(); - $tbl_series = book_database()->get_table( 'series' )->get_table_name(); - $tbl_reviews = book_database()->get_table( 'reviews' )->get_table_name(); - - // Select - $select = array( - 'book.*', - "GROUP_CONCAT( DISTINCT author.id SEPARATOR ',' ) as author_id", - "GROUP_CONCAT( DISTINCT author.name SEPARATOR ',' ) as author_name", - 'series.id as series_id', - 'series.name as series_name' - ); - - // Author Join - $join['author_query'] = "LEFT JOIN {$tbl_author_r} AS ar ON book.id = ar.book_id LEFT JOIN {$tbl_author} AS author ON ar.author_id = author.id"; - - // Series Join - $join['series_query'] = "LEFT JOIN {$tbl_series} AS series ON book.series_id = series.id"; - - // Average Rating - if ( ! empty( $args['include_rating'] ) ) { - $join['average_rating_select'] = "LEFT JOIN {$tbl_log} AS avg_rating ON (book.id = avg_rating.book_id AND avg_rating.rating IS NOT NULL)"; - $select[] = 'ROUND( AVG( avg_rating.rating ), 2 ) as avg_rating'; - } - - /** - * Where - */ - - // Author query - if ( ! empty( $args['author_query'] ) ) { - $clause_engine->set_table_query( new Authors_Query() ); - $clause_engine->set_args( $args['author_query'] ); - $where = array_merge( $where, $clause_engine->get_clauses() ); - } - - // Book query - if ( ! empty( $args['book_query'] ) ) { - $clause_engine->set_table_query( $this ); - $clause_engine->set_args( $args['book_query'] ); - $where = array_merge( $where, $clause_engine->get_clauses() ); - } - - // Edition query - if ( ! empty( $args['edition_query'] ) ) { - $join['edition_query'] = "INNER JOIN {$tbl_ed} AS ed ON (book.id = ed.book_id)"; - $clause_engine->set_table_query( new Editions_Query() ); - $clause_engine->set_args( $args['edition_query'] ); - $where = array_merge( $where, $clause_engine->get_clauses() ); - } - - // Reading log query - if ( ! empty( $args['reading_log_query'] ) ) { - $join['reading_log_query'] = "INNER JOIN {$tbl_log} AS log ON (book.id = log.book_id)"; - $clause_engine->set_table_query( new Reading_Logs_Query() ); - $clause_engine->set_args( $args['reading_log_query'] ); - $where = array_merge( $where, $clause_engine->get_clauses() ); - $select[] = 'log.id AS log_id, log.user_id AS log_user_id, log.date_started AS date_started, log.date_finished AS date_finished, log.percentage_complete AS percentage_complete, log.rating AS rating'; - } - - // Review query - if ( ! empty( $args['review_query'] ) ) { - $join['review_query'] = "INNER JOIN {$tbl_reviews} AS review ON (book.id = review.book_id)"; - $clause_engine->set_table_query( new Reviews_Query() ); - $clause_engine->set_args( $args['review_query'] ); - $where = array_merge( $where, $clause_engine->get_clauses() ); - } elseif ( ! empty( $args['include_review'] ) ) { - // Include review data, but as a LEFT JOIN. - $join['review_query'] = "LEFT JOIN {$tbl_reviews} AS review ON (book.id = review.book_id)"; - } - - // Unread books only - // This is a bit "special" because we need a weird left join. - if ( ! empty( $args['unread'] ) ) { - $join['unread_query'] = "LEFT JOIN {$tbl_log} as ulog ON (book.id = ulog.book_id)"; - $where[] = 'ulog.book_id IS NULL'; - } - - // Series query - if ( ! empty( $args['series_query'] ) ) { - $clause_engine->set_table_query( new Series_Query() ); - $clause_engine->set_args( $args['series_query'] ); - $where = array_merge( $where, $clause_engine->get_clauses() ); - } - - // Tax query - if ( ! empty( $args['tax_query'] ) ) { - $tax_query = new Tax( $args['tax_query'] ); - $clauses = $tax_query->get_sql( $this->table_alias, 'id' ); - $join['tax_query'] = $clauses['join']; - $where['tax_query'] = preg_replace( '/^\s*AND\s*/', '', $clauses['where'] ); - } - - // Select review data if we have a review query. - if ( ( ! empty( $args['review_query'] ) || ! empty( $args['include_review'] ) ) && ! empty( $join['review_query'] ) ) { - $select[] = 'review.id AS review_id, review.user_id AS review_user_id, review.post_id AS review_post_id, review.url AS review_url, review.date_written AS review_date_written, review.date_published AS review_date_published'; - } - - /** - * Format and query - */ - $select = implode( ', ', $select ); - $join = implode( ' ', $join ); - $where = ! empty( $where ) ? 'WHERE ' . implode( ' AND ', $where ) : ''; - - /** - * Validate the orderby / order - */ - $orderby = $this->validate_orderby( $args['orderby'], $args ); - $order = 'ASC' === strtoupper( $args['order'] ) ? 'ASC' : 'DESC'; - - $group_by = 'GROUP BY book.id'; - - // Override select if we're counting. - if ( ! empty( $args['count'] ) ) { - $select = 'COUNT( DISTINCT book.id )'; - $group_by = ''; - } - - if ( ! empty( $args['count'] ) ) { - $query = "SELECT {$select} FROM {$tbl_books} AS book {$join} {$where}"; - - $books = $this->get_db()->get_var( $query ); - - return absint( $books ); - } - - $query = $this->get_db()->prepare( "SELECT {$select} FROM {$tbl_books} AS book {$join} {$where} {$group_by} ORDER BY $orderby $order LIMIT %d,%d;", absint( $args['offset'] ), absint( $args['number'] ) ); - - $books = $this->get_db()->get_results( $query ); - - return wp_unslash( $books ); - - } - - /** - * Validate the orderby - * - * @param string $orderby Desired orderby. - * @param array $args Query arguments. - * - * @return string - */ - protected function validate_orderby( $orderby, $args = array() ) { - - $valid_orderbys = array( - 'author.id', - 'author.name', - 'author.slug', - 'book.id', - 'book.title', - 'book.index_title', - 'book.series_id', - 'book.series_position', - 'book.pub_date', - 'book.pages', - 'book.date_created', - 'book.date_modified', - 'series.id', - 'series.name', - 'series.slug', - 'series.number_books', - 'series.date_created', - ); - if ( ! empty( $args['include_rating'] ) ) { - $valid_orderbys = $valid_orderbys + array( - 'avg_rating.id', - 'avg_rating.review_id', - 'avg_rating.user_id', - 'avg_rating.date_started', - 'avg_rating.date_finished', - 'avg_rating.percentage_complete', - 'avg_rating.rating' - ); - } - if ( ! empty( $args['reading_log_query'] ) ) { - $valid_orderbys = $valid_orderbys + array( - 'log.date_started', - 'log.date_finished', - 'log.percentage_complete' - ); - } - - return in_array( $orderby, $valid_orderbys ) ? $orderby : 'book.id'; - - } - -} \ No newline at end of file diff --git a/includes/database/books/class-books-schema.php b/includes/database/books/class-books-schema.php deleted file mode 100644 index f18c239b..00000000 --- a/includes/database/books/class-books-schema.php +++ /dev/null @@ -1,148 +0,0 @@ - 'id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'extra' => 'auto_increment', - 'primary' => true, - 'sortable' => true - ), - - // cover_id - array( - 'name' => 'cover_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'allow_null' => true, - 'default' => null, - 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' - ), - - // title - array( - 'name' => 'title', - 'type' => 'text', - 'sortable' => true, - 'searchable' => true, - 'default' => '', - 'validate' => 'sanitize_text_field' - ), - - // index_title - array( - 'name' => 'index_title', - 'type' => 'text', - 'sortable' => true, - 'searchable' => true, - 'default' => '', - 'validate' => 'sanitize_text_field' - ), - - // series_id - array( - 'name' => 'series_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'allow_null' => true, - 'default' => null, - 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' - ), - - // series_position - array( - 'name' => 'series_position', - 'type' => 'float', - 'sortable' => true, - 'allow_null' => true, - 'default' => null, - 'validate' => '\Book_Database\BerlinDB\Sanitization\floatval_int_allow_null' - ), - - // pub_date - array( - 'name' => 'pub_date', - 'type' => 'date', - 'sortable' => true, - 'date_query' => true, - 'validate' => '\Book_Database\BerlinDB\Sanitization\validate_date' - ), - - // pages - array( - 'name' => 'pages', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'allow_null' => true, - 'default' => null, - 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' - ), - - // synopsis - array( - 'name' => 'synopsis', - 'type' => 'longtext', - 'validate' => 'wp_kses_post' - ), - - // goodreads_url - array( - 'name' => 'goodreads_url', - 'type' => 'text', - 'validate' => 'sanitize_text_field' - ), - - // date_created - array( - 'name' => 'date_created', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'created' => true, - 'date_query' => true, - 'sortable' => true, - ), - - // date_modified - array( - 'name' => 'date_modified', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'modified' => true, - 'date_query' => true, - 'sortable' => true, - ), - - ); - -} \ No newline at end of file diff --git a/includes/database/books/class-books-table.php b/includes/database/books/class-books-table.php deleted file mode 100644 index d5d2304e..00000000 --- a/includes/database/books/class-books-table.php +++ /dev/null @@ -1,190 +0,0 @@ - 201910092, - '201910093' => 201910093, - '201910094' => 201910094, - '201910095' => 201910095, - '201910096' => 201910096, - '201910271' => 201910271 - ); - - /** - * Books_Table constructor. - */ - public function __construct() { - parent::__construct(); - } - - /** - * Set up the database schema - */ - protected function set_schema() { - $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - cover_id bigint(20) UNSIGNED DEFAULT NULL, - title text NOT NULL, - index_title text NOT NULL, - series_id bigint(20) UNSIGNED DEFAULT NULL, - series_position float DEFAULT NULL, - pub_date date DEFAULT NULL, - pages bigint(20) UNSIGNED DEFAULT NULL, - synopsis longtext NOT NULL, - goodreads_url text NOT NULL, - date_created datetime NOT NULL, - date_modified datetime NOT NULL, - INDEX title( title(64) ), - INDEX series_id ( series_id )"; - } - - /** - * If the old `wp_bdb_books_db_version` option exists, copy that value to our new version key. - * This will ensure new upgrades are processed on old installs. - */ - public function maybe_upgrade() { - - $old_key = $this->get_db()->prefix . 'bdb_books_db_version'; - $old_version = get_option( $old_key ); - - if ( false !== $old_version ) { - update_option( $this->db_version_key, get_option( $old_key ) ); - - delete_option( $old_key ); - } - - return parent::maybe_upgrade(); - } - - /** - * Upgrade to version 201910092 - * - Rename `ID` to `id` & add `unsigned` - * - * @return bool - */ - protected function __201910092() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `ID` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT" ); - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910093 - * - Rename `cover` to `cover_id` & add `unsigned` - * - * @return bool - */ - protected function __201910093() { - - if ( $this->column_exists( 'cover' ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `cover` `cover_id` bigint(20) UNSIGNED DEFAULT NULL" ); - } else { - $result = true; - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910094 - * - Add `unsigned` to `series_id` and `pages` - * - * @return bool - */ - protected function __201910094() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} MODIFY series_id bigint(20) UNSIGNED DEFAULT NULL" ); - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} MODIFY pages bigint(20) UNSIGNED DEFAULT NULL" ); - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910095 - * - Add `date_created` column - * - Add `date_modified` column - * - * @return bool - */ - protected function __201910095() { - - $result = $this->column_exists( 'date_created' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - $result = $this->column_exists( 'date_modified' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910096 - * - Add `title` index - * - * @return bool - */ - protected function __201910096() { - - if ( ! $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'title'" ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD INDEX title( title(64) )" ); - } else { - $result = true; - } - - return $result; - - } - - /** - * Upgrade to version 201910271 - * - Convert `pub_date` to a DATE field - * - * @return bool - */ - protected function __201910271() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} MODIFY pub_date date DEFAULT NULL" ); - - return $this->is_success( $result ); - - } - -} diff --git a/includes/database/editions/class-editions-query.php b/includes/database/editions/class-editions-query.php deleted file mode 100644 index 7b160c12..00000000 --- a/includes/database/editions/class-editions-query.php +++ /dev/null @@ -1,76 +0,0 @@ - 'id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'extra' => 'auto_increment', - 'primary' => true, - 'sortable' => true - ), - - // book_id - array( - 'name' => 'book_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true - ), - - // isbn - array( - 'name' => 'isbn', - 'type' => 'varchar', - 'length' => '13', - 'sortable' => true, - 'validate' => 'sanitize_text_field' - ), - - // format - array( - 'name' => 'format', - 'type' => 'varchar', - 'length' => '13', - 'validate' => 'sanitize_text_field' - ), - - // date_acquired - array( - 'name' => 'date_acquired', - 'type' => 'datetime', - 'default' => null, - 'allow_null' => true, - 'date_query' => true, - 'sortable' => true, - ), - - // source_id - array( - 'name' => 'source_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'default' => null, - 'allow_null' => true, - 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' - ), - - // signed - array( - 'name' => 'signed', - 'type' => 'int', - 'length' => '1', - 'unsigned' => true, - 'sortable' => true, - 'allow_null' => true, - 'default' => null, - 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' - ), - - // date_created - array( - 'name' => 'date_created', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'created' => true, - 'date_query' => true, - 'sortable' => true, - ), - - // date_modified - array( - 'name' => 'date_modified', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'modified' => true, - 'date_query' => true, - 'sortable' => true, - ), - - ); - -} \ No newline at end of file diff --git a/includes/database/editions/class-editions-table.php b/includes/database/editions/class-editions-table.php deleted file mode 100644 index 4952a042..00000000 --- a/includes/database/editions/class-editions-table.php +++ /dev/null @@ -1,182 +0,0 @@ - 201910132, - '201910133' => 201910133, - '201910134' => 201910134, - '201910135' => 201910135, - '201910141' => 201910141, - '202002231' => 202002231 - ); - - /** - * Owned_Editions_Table constructor. - */ - public function __construct() { - parent::__construct(); - } - - /** - * Set up the database schema - */ - protected function set_schema() { - $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, - isbn varchar(13) NOT NULL DEFAULT '', - format varchar(200) NOT NULL DEFAULT '', - date_acquired datetime DEFAULT NULL, - source_id bigint(20) UNSIGNED DEFAULT NULL, - signed int(1) UNSIGNED DEFAULT NULL, - date_created datetime NOT NULL, - date_modified datetime NOT NULL, - INDEX book_id (book_id), - INDEX isbn (isbn), - INDEX date_acquired (date_acquired)"; - } - - /** - * If the old `wp_bdb_owned_editions_db_version` option exists, copy that value to our new version key. - * This will ensure new upgrades are processed on old installs. - */ - public function maybe_upgrade() { - - $old_key = $this->get_db()->prefix . 'bdb_owned_editions_db_version'; - $old_version = get_option( $old_key ); - - if ( false !== $old_version ) { - update_option( $this->db_version_key, get_option( $old_key ) ); - - delete_option( $old_key ); - } - - return parent::maybe_upgrade(); - - } - - /** - * Upgrade to version 201910132 - * - Rename `ID` to `id` & add `unsigned` - * - * @return bool - */ - protected function __201910132() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `ID` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT" ); - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910133 - * - Rename `source` to `source_id` & add `unsigned` - * - * @return bool - */ - protected function __201910133() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `source` source_id bigint(20) UNSIGNED DEFAULT NULL" ); - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910134 - * - Add `date_created` column - * - Add `date_modified` column - * - * @return bool - */ - protected function __201910134() { - - $result = $this->column_exists( 'date_created' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - $result = $this->column_exists( 'date_modified' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - return $result; - - } - - /** - * Upgrade to version 201910135 - * - Add `isbn` index - * - * @return bool - */ - protected function __201910135() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD INDEX isbn (isbn)" ); - - return $result; - - } - - /** - * Upgrade to version 201910141 - * - Add `date_acquired` index - * - * @return bool - */ - protected function __201910141() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD INDEX date_acquired (date_acquired)" ); - - return $result; - - } - - /** - * Upgrade to version 202002231 - * - Allow `date_acquired` to be `null`. - * - * @return bool - */ - protected function __202002231() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} MODIFY date_acquired datetime DEFAULT NULL" ); - - return $this->is_success( $result ); - - } - -} \ No newline at end of file diff --git a/includes/database/reviews/class-reviews-query.php b/includes/database/reviews/class-reviews-query.php index 5f9159cc..beac7575 100644 --- a/includes/database/reviews/class-reviews-query.php +++ b/includes/database/reviews/class-reviews-query.php @@ -10,6 +10,9 @@ namespace Book_Database; use Book_Database\BerlinDB\Database\Queries\Tax; +use Book_Database\Database\Authors\AuthorsQuery; +use Book_Database\Database\Books\BooksQuery; +use Book_Database\Database\Editions\EditionsQuery; /** * Class Reviews_Query @@ -165,14 +168,14 @@ public function get_reviews( $args = array() ) { // Author query if ( ! empty( $args['author_query'] ) ) { - $clause_engine->set_table_query( new Authors_Query() ); + $clause_engine->set_table_query( new AuthorsQuery() ); $clause_engine->set_args( $args['author_query'] ); $where = array_merge( $where, $clause_engine->get_clauses() ); } // Book query if ( ! empty( $args['book_query'] ) ) { - $clause_engine->set_table_query( new Books_Query() ); + $clause_engine->set_table_query( new BooksQuery() ); $clause_engine->set_args( $args['book_query'] ); $where = array_merge( $where, $clause_engine->get_clauses() ); } @@ -180,7 +183,7 @@ public function get_reviews( $args = array() ) { // Edition query if ( ! empty( $args['edition_query'] ) ) { $join['edition_query'] = "INNER JOIN {$tbl_ed} AS ed ON (review.book_id = ed.book_id)"; - $clause_engine->set_table_query( new Editions_Query() ); + $clause_engine->set_table_query( new EditionsQuery() ); $clause_engine->set_args( $args['edition_query'] ); $where = array_merge( $where, $clause_engine->get_clauses() ); } @@ -300,4 +303,4 @@ protected function validate_orderby( $orderby, $args = array() ) { } -} \ No newline at end of file +} diff --git a/includes/editions/edition-functions.php b/includes/editions/edition-functions.php index 907b7ce8..70582d4b 100644 --- a/includes/editions/edition-functions.php +++ b/includes/editions/edition-functions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Database\Editions\EditionsQuery; + /** * Get a single edition by its ID * @@ -18,7 +20,7 @@ */ function get_edition( $edition_id ) { - $query = new Editions_Query(); + $query = new EditionsQuery(); return $query->get_item( $edition_id ); @@ -34,7 +36,7 @@ function get_edition( $edition_id ) { */ function get_edition_by( $column_name, $column_value ) { - $query = new Editions_Query(); + $query = new EditionsQuery(); return $query->get_item_by( $column_name, $column_value ); @@ -82,7 +84,7 @@ function get_editions( $args = array() ) { 'number' => 20 ) ); - $query = new Editions_Query(); + $query = new EditionsQuery(); return $query->query( $args ); @@ -103,7 +105,7 @@ function count_editions( $args = array() ) { 'count' => true ) ); - $query = new Editions_Query( $args ); + $query = new EditionsQuery( $args ); return absint( $query->found_items ); @@ -140,7 +142,7 @@ function add_edition( $args = array() ) { throw new Exception( 'missing_required_parameter', __( 'A book ID is required.', 'book-database' ), 400 ); } - $query = new Editions_Query(); + $query = new EditionsQuery(); $edition_id = $query->add_item( $args ); if ( empty( $edition_id ) ) { @@ -162,7 +164,7 @@ function add_edition( $args = array() ) { */ function update_edition( $edition_id, $args = array() ) { - $query = new Editions_Query(); + $query = new EditionsQuery(); $updated = $query->update_item( $edition_id, $args ); if ( ! $updated ) { @@ -183,7 +185,7 @@ function update_edition( $edition_id, $args = array() ) { */ function delete_edition( $edition_id ) { - $query = new Editions_Query(); + $query = new EditionsQuery(); $deleted = $query->delete_item( $edition_id ); if ( ! $deleted ) { @@ -229,4 +231,4 @@ function get_book_formats() { */ return apply_filters( 'book-database/book/formats', $formats ); -} \ No newline at end of file +} diff --git a/src/Book_Grid_Query.php b/src/Book_Grid_Query.php index 33051473..b7e23a90 100644 --- a/src/Book_Grid_Query.php +++ b/src/Book_Grid_Query.php @@ -11,8 +11,11 @@ namespace Book_Database; +use Book_Database\Database\Books\BooksQuery; + /** * Class Book_Grid_Query + * * @package Book_Database */ class Book_Grid_Query extends Book_Reviews_Query { @@ -155,7 +158,7 @@ protected function parse_args( $atts = array() ) { */ public function get_results() { - $query = new Books_Query(); + $query = new BooksQuery(); $results = $query->get_books( $this->args ); $count_args = $this->args; diff --git a/src/Database/Authors/AuthorsQuery.php b/src/Database/Authors/AuthorsQuery.php new file mode 100644 index 00000000..2d2228c6 --- /dev/null +++ b/src/Database/Authors/AuthorsQuery.php @@ -0,0 +1,83 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true + ), + + // name + array( + 'name' => 'name', + 'type' => 'varchar', + 'length' => '200', + 'sortable' => true, + 'searchable' => true, + 'validate' => 'sanitize_text_field' + ), + + // slug + array( + 'name' => 'slug', + 'type' => 'varchar', + 'length' => '200', + 'sortable' => true, + 'validate' => 'sanitize_key' + ), + + // description + array( + 'name' => 'description', + 'type' => 'longtext', + 'validate' => 'wp_kses_post' + ), + + // image_id + array( + 'name' => 'image_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'allow_null' => true, + 'default' => null, + 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' + ), + + // links + array( + 'name' => 'links', + 'type' => 'longtext', + ), + + // book_count + array( + 'name' => 'book_count', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'default' => 0 + ), + + // date_created + array( + 'name' => 'date_created', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ), + + // date_modified + array( + 'name' => 'date_modified', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'modified' => true, + 'date_query' => true, + 'sortable' => true, + ), + + ); + +} diff --git a/src/Database/Authors/AuthorsTable.php b/src/Database/Authors/AuthorsTable.php new file mode 100644 index 00000000..b56845bb --- /dev/null +++ b/src/Database/Authors/AuthorsTable.php @@ -0,0 +1,64 @@ +schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + name varchar(200) NOT NULL DEFAULT '', + slug varchar(200) NOT NULL DEFAULT '', + description longtext NOT NULL DEFAULT '', + image_id bigint(20) UNSIGNED DEFAULT NULL, + links longtext NOT NULL DEFAULT '', + book_count bigint(20) UNSIGNED NOT NULL DEFAULT 0, + date_created datetime NOT NULL, + date_modified datetime NOT NULL, + INDEX name (name), + INDEX slug (slug)"; + } + +} diff --git a/src/Database/BookAuthor/BookAuthorQuery.php b/src/Database/BookAuthor/BookAuthorQuery.php new file mode 100644 index 00000000..06cbb61c --- /dev/null +++ b/src/Database/BookAuthor/BookAuthorQuery.php @@ -0,0 +1,83 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true + ), + + // author_id + array( + 'name' => 'author_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true + ), + + // book_id + array( + 'name' => 'book_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true + ), + + // date_created + array( + 'name' => 'date_created', + 'type' => 'datetime', + 'default' => '', + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ), + + // date_modified + array( + 'name' => 'date_modified', + 'type' => 'datetime', + 'default' => '', + 'modified' => true, + 'date_query' => true, + 'sortable' => true, + ), + + ); + +} diff --git a/src/Database/BookAuthor/BookAuthorTable.php b/src/Database/BookAuthor/BookAuthorTable.php new file mode 100644 index 00000000..9c0d410e --- /dev/null +++ b/src/Database/BookAuthor/BookAuthorTable.php @@ -0,0 +1,60 @@ +schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + author_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, + book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, + date_created datetime NOT NULL, + date_modified datetime NOT NULL, + INDEX author_id (author_id), + INDEX book_id (book_id)"; + } + +} diff --git a/src/Database/BookLinks/BookLinksQuery.php b/src/Database/BookLinks/BookLinksQuery.php new file mode 100644 index 00000000..ce525194 --- /dev/null +++ b/src/Database/BookLinks/BookLinksQuery.php @@ -0,0 +1,83 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true + ), + + // book_id + array( + 'name' => 'book_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'validate' => 'absint' + ), + + // retailer_id + array( + 'name' => 'retailer_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'validate' => 'absint' + ), + + // url + array( + 'name' => 'url', + 'type' => 'text', + 'searchable' => true, + 'validate' => 'esc_url_raw' + ), + + // date_created + array( + 'name' => 'date_created', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ), + + // date_modified + array( + 'name' => 'date_modified', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'modified' => true, + 'date_query' => true, + 'sortable' => true, + ), + + ); + +} diff --git a/src/Database/BookLinks/BookLinksTable.php b/src/Database/BookLinks/BookLinksTable.php new file mode 100644 index 00000000..36098b1b --- /dev/null +++ b/src/Database/BookLinks/BookLinksTable.php @@ -0,0 +1,60 @@ +schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + book_id bigint(20) UNSIGNED NOT NULL, + retailer_id bigint(20) UNSIGNED NOT NULL, + url text NOT NULL DEFAULT '', + date_created datetime NOT NULL, + date_modified datetime NOT NULL, + INDEX book_id (book_id)"; + } + +} diff --git a/src/Database/BookTaxonomies/BookTaxonomiesQuery.php b/src/Database/BookTaxonomies/BookTaxonomiesQuery.php new file mode 100644 index 00000000..e21665da --- /dev/null +++ b/src/Database/BookTaxonomies/BookTaxonomiesQuery.php @@ -0,0 +1,84 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true + ), + + // name + array( + 'name' => 'name', + 'type' => 'varchar', + 'length' => '32', + 'sortable' => true, + 'searchable' => true, + 'validate' => 'sanitize_text_field' + ), + + // slug + array( + 'name' => 'slug', + 'type' => 'varchar', + 'length' => '32', + 'sortable' => true, + 'validate' => 'sanitize_key' + ), + + // format + array( + 'name' => 'format', + 'type' => 'varchar', + 'length' => '32', + 'sortable' => true, + 'default' => 'text', + 'validate' => 'sanitize_text_field' + ), + + // date_created + array( + 'name' => 'date_created', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ), + + // date_modified + array( + 'name' => 'date_modified', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'modified' => true, + 'date_query' => true, + 'sortable' => true, + ), + + ); + +} diff --git a/src/Database/BookTaxonomies/BookTaxonomiesTable.php b/src/Database/BookTaxonomies/BookTaxonomiesTable.php new file mode 100644 index 00000000..0a992878 --- /dev/null +++ b/src/Database/BookTaxonomies/BookTaxonomiesTable.php @@ -0,0 +1,60 @@ +schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + name varchar(32) NOT NULL DEFAULT '', + slug varchar(32) NOT NULL DEFAULT '', + format varchar(32) NOT NULL DEFAULT 'text', + date_created datetime NOT NULL, + date_modified datetime NOT NULL, + INDEX slug( slug )"; + } + +} diff --git a/src/Database/BookTerm/BookTermRelationshipQuery.php b/src/Database/BookTerm/BookTermRelationshipQuery.php new file mode 100644 index 00000000..b4725822 --- /dev/null +++ b/src/Database/BookTerm/BookTermRelationshipQuery.php @@ -0,0 +1,83 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true + ), + + // term_id + array( + 'name' => 'term_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true + ), + + // book_id + array( + 'name' => 'book_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true + ), + + // date_created + array( + 'name' => 'date_created', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ), + + // date_modified + array( + 'name' => 'date_modified', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'modified' => true, + 'date_query' => true, + 'sortable' => true, + ), + + ); + +} diff --git a/src/Database/BookTerm/BookTermRelationshipsTable.php b/src/Database/BookTerm/BookTermRelationshipsTable.php new file mode 100644 index 00000000..b9835461 --- /dev/null +++ b/src/Database/BookTerm/BookTermRelationshipsTable.php @@ -0,0 +1,141 @@ + 201910122, + '201910123' => 201910123, + '201910124' => 201910124 + ); + + /** + * Book_Term_Relationships_Table constructor. + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Set up the database schema + */ + protected function set_schema() + { + $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + term_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, + book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, + date_created datetime NOT NULL, + date_modified datetime NOT NULL, + INDEX book_id (book_id), + INDEX term_id (term_id)"; + } + + /** + * If the old `wp_bdb_book_term_relationships_db_version` option exists, copy that value to our new version key. + * This will ensure new upgrades are processed on old installs. + */ + public function maybe_upgrade() + { + + $old_key = $this->get_db()->prefix.'bdb_book_term_relationships_db_version'; + $old_version = get_option($old_key); + + if (false !== $old_version) { + update_option($this->db_version_key, get_option($old_key)); + + delete_option($old_key); + } + + parent::maybe_upgrade(); + + } + + /** + * Upgrade to version 201910122 + * - Rename `ID` to `id` & add `unsigned` + * + * @return bool + */ + protected function __201910122() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `ID` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT"); + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910123 + * - Add `unsigned` to `term_id` and `book_id` + * + * @return bool + */ + protected function __201910123() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} MODIFY term_id bigint(20) UNSIGNED NOT NULL DEFAULT 0"); + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} MODIFY book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0"); + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910124 + * - Add `date_created` column + * - Add `date_modified` column + * + * @return bool + */ + protected function __201910124() + { + + $result = $this->column_exists('date_created'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + $result = $this->column_exists('date_modified'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + return $this->is_success($result); + + } + +} diff --git a/src/Database/BookTerms/BookTermsQuery.php b/src/Database/BookTerms/BookTermsQuery.php new file mode 100644 index 00000000..2f375d34 --- /dev/null +++ b/src/Database/BookTerms/BookTermsQuery.php @@ -0,0 +1,83 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true + ), + + // taxonomy + array( + 'name' => 'taxonomy', + 'type' => 'varchar', + 'length' => '32', + 'sortable' => true, + 'validate' => 'sanitize_text_field' + ), + + // name + array( + 'name' => 'name', + 'type' => 'varchar', + 'length' => '200', + 'sortable' => true, + 'searchable' => true, + 'validate' => 'sanitize_text_field' + ), + + // slug + array( + 'name' => 'slug', + 'type' => 'varchar', + 'length' => '200', + 'sortable' => true, + 'searchable' => true, + 'validate' => 'sanitize_key' + ), + + // description + array( + 'name' => 'description', + 'type' => 'longtext', + 'validate' => 'wp_kses_post' + ), + + // image_id + array( + 'name' => 'image_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'allow_null' => true, + 'default' => null, + 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' + ), + + // links + array( + 'name' => 'links', + 'type' => 'longtext', + ), + + // book_count + array( + 'name' => 'book_count', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true + ), + + // date_created + array( + 'name' => 'date_created', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ), + + // date_modified + array( + 'name' => 'date_modified', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'modified' => true, + 'date_query' => true, + 'sortable' => true, + ), + + ); + +} diff --git a/src/Database/BookTerms/BookTermsTable.php b/src/Database/BookTerms/BookTermsTable.php new file mode 100644 index 00000000..6c235563 --- /dev/null +++ b/src/Database/BookTerms/BookTermsTable.php @@ -0,0 +1,220 @@ + 201910122, + '201910123' => 201910123, + '201910125' => 201910125, + '201910126' => 201910126, + '201910181' => 201910181 + ); + + /** + * Book_Terms_Table constructor. + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Set up the database schema + */ + protected function set_schema() + { + $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + taxonomy varchar(32) NOT NULL DEFAULT '', + name varchar(200) NOT NULL DEFAULT '', + slug varchar(200) NOT NULL DEFAULT '', + description longtext NOT NULL DEFAULT '', + image_id bigint(20) UNSIGNED DEFAULT NULL, + links longtext NOT NULL DEFAULT '', + book_count bigint(20) UNSIGNED NOT NULL DEFAULT 0, + date_created datetime NOT NULL, + date_modified datetime NOT NULL, + INDEX id_taxonomy_name (id, taxonomy, name), + INDEX id_taxonomy_slug (id, taxonomy, slug), + INDEX taxonomy (taxonomy), + INDEX name (name)"; + } + + /** + * If the old `wp_bdb_book_terms_db_version` option exists, copy that value to our new version key. + * This will ensure new upgrades are processed on old installs. + */ + public function maybe_upgrade() + { + + $old_key = $this->get_db()->prefix.'bdb_book_terms_db_version'; + $old_version = get_option($old_key); + + if (false !== $old_version) { + update_option($this->db_version_key, get_option($old_key)); + + delete_option($old_key); + } + + return parent::maybe_upgrade(); + + } + + /** + * Upgrade to version 201910122 + * - Rename `term_id` to `id` & add `unsigned` + * + * @return bool + */ + protected function __201910122() + { + + $result = true; + + // Drop keys involving `term_id` or `type`. + if ($this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'id_type_name'")) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} DROP INDEX id_type_name"); + } + if ($this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'id_type_slug'")) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} DROP INDEX id_type_slug"); + } + if ($this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'type'")) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} DROP INDEX type"); + } + + if ($result && $this->column_exists('term_id')) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `term_id` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT"); + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910123 + * - Change `image` to `image_id` & add `unsigned` + * + * @return bool + */ + protected function __201910123() + { + + if ($this->column_exists('image')) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `image` `image_id` bigint(20) UNSIGNED NOT NULL DEFAULT 0"); + } else { + $result = true; + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910125 + * - Add `date_created` column + * - Add `date_modified` column + * + * @return bool + */ + protected function __201910125() + { + + $result = $this->column_exists('date_created'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + $result = $this->column_exists('date_modified'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910126 + * - Change `type` to `taxonomy` + * - Add new indexes + * + * @return bool + */ + protected function __201910126() + { + + if ($this->column_exists('type')) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `type` `taxonomy` varchar(32) NOT NULL DEFAULT ''"); + } else { + $result = true; + } + + // Add new indexes. + if ($result) { + if (! $this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'id_taxonomy_name'")) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD UNIQUE KEY id_taxonomy_name (id, taxonomy, name)"); + } + if (! $this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'id_taxonomy_slug'")) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD UNIQUE KEY id_taxonomy_slug (id, taxonomy, slug)"); + } + if (! $this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'taxonomy'")) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD KEY taxonomy (taxonomy)"); + } + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910181 + * - Change `count` to `book_count` + * + * @return bool + */ + protected function __201910181() + { + + if ($this->column_exists('count') && ! $this->column_exists('book_count')) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `count` `book_count` bigint(20) UNSIGNED NOT NULL DEFAULT 0"); + } else { + $result = true; + } + + return $this->is_success($result); + + } + +} diff --git a/src/Database/Books/BookMetaTable.php b/src/Database/Books/BookMetaTable.php new file mode 100644 index 00000000..4abee45c --- /dev/null +++ b/src/Database/Books/BookMetaTable.php @@ -0,0 +1,60 @@ +schema = "meta_id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + bdb_book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, + meta_key varchar(255) DEFAULT NULL, + meta_value longtext DEFAULT NULL, + INDEX bdb_book_id (bdb_book_id), + INDEX meta_key (meta_key({$max_index_length}))"; + } + +} diff --git a/src/Database/Books/BooksQuery.php b/src/Database/Books/BooksQuery.php new file mode 100644 index 00000000..37bf047f --- /dev/null +++ b/src/Database/Books/BooksQuery.php @@ -0,0 +1,316 @@ + array(), + 'book_query' => array(), + 'series_query' => array(), + 'reading_log_query' => array(), + 'review_query' => array(), + 'edition_query' => array(), + 'tax_query' => array(), + 'unread' => false, + 'orderby' => 'book.id', + 'order' => 'DESC', + 'include_rating' => true, + 'include_review' => false, // Whether or not to always include review data. + 'number' => 20, + 'offset' => 0, + 'count' => false + )); + + $select = $join = $where = array(); + + $clause_engine = new Where_Clause(); + + $tbl_books = book_database()->get_table('books')->get_table_name(); + $tbl_author = book_database()->get_table('authors')->get_table_name(); + $tbl_author_r = book_database()->get_table('book_author_relationships')->get_table_name(); + $tbl_ed = book_database()->get_table('editions')->get_table_name(); + $tbl_log = book_database()->get_table('reading_log')->get_table_name(); + $tbl_series = book_database()->get_table('series')->get_table_name(); + $tbl_reviews = book_database()->get_table('reviews')->get_table_name(); + + // Select + $select = array( + 'book.*', + "GROUP_CONCAT( DISTINCT author.id SEPARATOR ',' ) as author_id", + "GROUP_CONCAT( DISTINCT author.name SEPARATOR ',' ) as author_name", + 'series.id as series_id', + 'series.name as series_name' + ); + + // Author Join + $join['author_query'] = "LEFT JOIN {$tbl_author_r} AS ar ON book.id = ar.book_id LEFT JOIN {$tbl_author} AS author ON ar.author_id = author.id"; + + // Series Join + $join['series_query'] = "LEFT JOIN {$tbl_series} AS series ON book.series_id = series.id"; + + // Average Rating + if (! empty($args['include_rating'])) { + $join['average_rating_select'] = "LEFT JOIN {$tbl_log} AS avg_rating ON (book.id = avg_rating.book_id AND avg_rating.rating IS NOT NULL)"; + $select[] = 'ROUND( AVG( avg_rating.rating ), 2 ) as avg_rating'; + } + + /** + * Where + */ + + // Author query + if (! empty($args['author_query'])) { + $clause_engine->set_table_query(new AuthorsQuery()); + $clause_engine->set_args($args['author_query']); + $where = array_merge($where, $clause_engine->get_clauses()); + } + + // Book query + if (! empty($args['book_query'])) { + $clause_engine->set_table_query($this); + $clause_engine->set_args($args['book_query']); + $where = array_merge($where, $clause_engine->get_clauses()); + } + + // Edition query + if (! empty($args['edition_query'])) { + $join['edition_query'] = "INNER JOIN {$tbl_ed} AS ed ON (book.id = ed.book_id)"; + $clause_engine->set_table_query(new EditionsQuery()); + $clause_engine->set_args($args['edition_query']); + $where = array_merge($where, $clause_engine->get_clauses()); + } + + // Reading log query + if (! empty($args['reading_log_query'])) { + $join['reading_log_query'] = "INNER JOIN {$tbl_log} AS log ON (book.id = log.book_id)"; + $clause_engine->set_table_query(new Reading_Logs_Query()); + $clause_engine->set_args($args['reading_log_query']); + $where = array_merge($where, $clause_engine->get_clauses()); + $select[] = 'log.id AS log_id, log.user_id AS log_user_id, log.date_started AS date_started, log.date_finished AS date_finished, log.percentage_complete AS percentage_complete, log.rating AS rating'; + } + + // Review query + if (! empty($args['review_query'])) { + $join['review_query'] = "INNER JOIN {$tbl_reviews} AS review ON (book.id = review.book_id)"; + $clause_engine->set_table_query(new Reviews_Query()); + $clause_engine->set_args($args['review_query']); + $where = array_merge($where, $clause_engine->get_clauses()); + } elseif (! empty($args['include_review'])) { + // Include review data, but as a LEFT JOIN. + $join['review_query'] = "LEFT JOIN {$tbl_reviews} AS review ON (book.id = review.book_id)"; + } + + // Unread books only + // This is a bit "special" because we need a weird left join. + if (! empty($args['unread'])) { + $join['unread_query'] = "LEFT JOIN {$tbl_log} as ulog ON (book.id = ulog.book_id)"; + $where[] = 'ulog.book_id IS NULL'; + } + + // Series query + if (! empty($args['series_query'])) { + $clause_engine->set_table_query(new Series_Query()); + $clause_engine->set_args($args['series_query']); + $where = array_merge($where, $clause_engine->get_clauses()); + } + + // Tax query + if (! empty($args['tax_query'])) { + $tax_query = new Tax($args['tax_query']); + $clauses = $tax_query->get_sql($this->table_alias, 'id'); + $join['tax_query'] = $clauses['join']; + $where['tax_query'] = preg_replace('/^\s*AND\s*/', '', $clauses['where']); + } + + // Select review data if we have a review query. + if ((! empty($args['review_query']) || ! empty($args['include_review'])) && ! empty($join['review_query'])) { + $select[] = 'review.id AS review_id, review.user_id AS review_user_id, review.post_id AS review_post_id, review.url AS review_url, review.date_written AS review_date_written, review.date_published AS review_date_published'; + } + + /** + * Format and query + */ + $select = implode(', ', $select); + $join = implode(' ', $join); + $where = ! empty($where) ? 'WHERE '.implode(' AND ', $where) : ''; + + /** + * Validate the orderby / order + */ + $orderby = $this->validate_orderby($args['orderby'], $args); + $order = 'ASC' === strtoupper($args['order']) ? 'ASC' : 'DESC'; + + $group_by = 'GROUP BY book.id'; + + // Override select if we're counting. + if (! empty($args['count'])) { + $select = 'COUNT( DISTINCT book.id )'; + $group_by = ''; + } + + if (! empty($args['count'])) { + $query = "SELECT {$select} FROM {$tbl_books} AS book {$join} {$where}"; + + $books = $this->get_db()->get_var($query); + + return absint($books); + } + + $query = $this->get_db()->prepare("SELECT {$select} FROM {$tbl_books} AS book {$join} {$where} {$group_by} ORDER BY $orderby $order LIMIT %d,%d;", + absint($args['offset']), absint($args['number'])); + + $books = $this->get_db()->get_results($query); + + return wp_unslash($books); + + } + + /** + * Validate the orderby + * + * @param string $orderby Desired orderby. + * @param array $args Query arguments. + * + * @return string + */ + protected function validate_orderby($orderby, $args = array()) + { + + $valid_orderbys = array( + 'author.id', + 'author.name', + 'author.slug', + 'book.id', + 'book.title', + 'book.index_title', + 'book.series_id', + 'book.series_position', + 'book.pub_date', + 'book.pages', + 'book.date_created', + 'book.date_modified', + 'series.id', + 'series.name', + 'series.slug', + 'series.number_books', + 'series.date_created', + ); + if (! empty($args['include_rating'])) { + $valid_orderbys = $valid_orderbys + array( + 'avg_rating.id', + 'avg_rating.review_id', + 'avg_rating.user_id', + 'avg_rating.date_started', + 'avg_rating.date_finished', + 'avg_rating.percentage_complete', + 'avg_rating.rating' + ); + } + if (! empty($args['reading_log_query'])) { + $valid_orderbys = $valid_orderbys + array( + 'log.date_started', + 'log.date_finished', + 'log.percentage_complete' + ); + } + + return in_array($orderby, $valid_orderbys) ? $orderby : 'book.id'; + + } + +} diff --git a/src/Database/Books/BooksSchema.php b/src/Database/Books/BooksSchema.php new file mode 100644 index 00000000..2f6337f2 --- /dev/null +++ b/src/Database/Books/BooksSchema.php @@ -0,0 +1,152 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true + ), + + // cover_id + array( + 'name' => 'cover_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'allow_null' => true, + 'default' => null, + 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' + ), + + // title + array( + 'name' => 'title', + 'type' => 'text', + 'sortable' => true, + 'searchable' => true, + 'default' => '', + 'validate' => 'sanitize_text_field' + ), + + // index_title + array( + 'name' => 'index_title', + 'type' => 'text', + 'sortable' => true, + 'searchable' => true, + 'default' => '', + 'validate' => 'sanitize_text_field' + ), + + // series_id + array( + 'name' => 'series_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'allow_null' => true, + 'default' => null, + 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' + ), + + // series_position + array( + 'name' => 'series_position', + 'type' => 'float', + 'sortable' => true, + 'allow_null' => true, + 'default' => null, + 'validate' => '\Book_Database\BerlinDB\Sanitization\floatval_int_allow_null' + ), + + // pub_date + array( + 'name' => 'pub_date', + 'type' => 'date', + 'sortable' => true, + 'date_query' => true, + 'validate' => '\Book_Database\BerlinDB\Sanitization\validate_date' + ), + + // pages + array( + 'name' => 'pages', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'allow_null' => true, + 'default' => null, + 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' + ), + + // synopsis + array( + 'name' => 'synopsis', + 'type' => 'longtext', + 'validate' => 'wp_kses_post' + ), + + // goodreads_url + array( + 'name' => 'goodreads_url', + 'type' => 'text', + 'validate' => 'sanitize_text_field' + ), + + // date_created + array( + 'name' => 'date_created', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ), + + // date_modified + array( + 'name' => 'date_modified', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'modified' => true, + 'date_query' => true, + 'sortable' => true, + ), + + ); + +} diff --git a/src/Database/Books/BooksTable.php b/src/Database/Books/BooksTable.php new file mode 100644 index 00000000..09bf9de8 --- /dev/null +++ b/src/Database/Books/BooksTable.php @@ -0,0 +1,203 @@ + 201910092, + '201910093' => 201910093, + '201910094' => 201910094, + '201910095' => 201910095, + '201910096' => 201910096, + '201910271' => 201910271 + ); + + /** + * Books_Table constructor. + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Set up the database schema + */ + protected function set_schema() + { + $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + cover_id bigint(20) UNSIGNED DEFAULT NULL, + title text NOT NULL, + index_title text NOT NULL, + series_id bigint(20) UNSIGNED DEFAULT NULL, + series_position float DEFAULT NULL, + pub_date date DEFAULT NULL, + pages bigint(20) UNSIGNED DEFAULT NULL, + synopsis longtext NOT NULL, + goodreads_url text NOT NULL, + date_created datetime NOT NULL, + date_modified datetime NOT NULL, + INDEX title( title(64) ), + INDEX series_id ( series_id )"; + } + + /** + * If the old `wp_bdb_books_db_version` option exists, copy that value to our new version key. + * This will ensure new upgrades are processed on old installs. + */ + public function maybe_upgrade() + { + + $old_key = $this->get_db()->prefix.'bdb_books_db_version'; + $old_version = get_option($old_key); + + if (false !== $old_version) { + update_option($this->db_version_key, get_option($old_key)); + + delete_option($old_key); + } + + parent::maybe_upgrade(); + } + + /** + * Upgrade to version 201910092 + * - Rename `ID` to `id` & add `unsigned` + * + * @return bool + */ + protected function __201910092() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `ID` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT"); + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910093 + * - Rename `cover` to `cover_id` & add `unsigned` + * + * @return bool + */ + protected function __201910093() + { + + if ($this->column_exists('cover')) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `cover` `cover_id` bigint(20) UNSIGNED DEFAULT NULL"); + } else { + $result = true; + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910094 + * - Add `unsigned` to `series_id` and `pages` + * + * @return bool + */ + protected function __201910094() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} MODIFY series_id bigint(20) UNSIGNED DEFAULT NULL"); + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} MODIFY pages bigint(20) UNSIGNED DEFAULT NULL"); + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910095 + * - Add `date_created` column + * - Add `date_modified` column + * + * @return bool + */ + protected function __201910095() + { + + $result = $this->column_exists('date_created'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + $result = $this->column_exists('date_modified'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910096 + * - Add `title` index + * + * @return bool + */ + protected function __201910096() + { + + if (! $this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'title'")) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD INDEX title( title(64) )"); + } else { + $result = true; + } + + return $result; + + } + + /** + * Upgrade to version 201910271 + * - Convert `pub_date` to a DATE field + * + * @return bool + */ + protected function __201910271() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} MODIFY pub_date date DEFAULT NULL"); + + return $this->is_success($result); + + } + +} diff --git a/src/Database/Editions/EditionsQuery.php b/src/Database/Editions/EditionsQuery.php new file mode 100644 index 00000000..d2f18bd0 --- /dev/null +++ b/src/Database/Editions/EditionsQuery.php @@ -0,0 +1,83 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true + ), + + // book_id + array( + 'name' => 'book_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true + ), + + // isbn + array( + 'name' => 'isbn', + 'type' => 'varchar', + 'length' => '13', + 'sortable' => true, + 'validate' => 'sanitize_text_field' + ), + + // format + array( + 'name' => 'format', + 'type' => 'varchar', + 'length' => '13', + 'validate' => 'sanitize_text_field' + ), + + // date_acquired + array( + 'name' => 'date_acquired', + 'type' => 'datetime', + 'default' => null, + 'allow_null' => true, + 'date_query' => true, + 'sortable' => true, + ), + + // source_id + array( + 'name' => 'source_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'default' => null, + 'allow_null' => true, + 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' + ), + + // signed + array( + 'name' => 'signed', + 'type' => 'int', + 'length' => '1', + 'unsigned' => true, + 'sortable' => true, + 'allow_null' => true, + 'default' => null, + 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' + ), + + // date_created + array( + 'name' => 'date_created', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ), + + // date_modified + array( + 'name' => 'date_modified', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'modified' => true, + 'date_query' => true, + 'sortable' => true, + ), + + ); + +} diff --git a/src/Database/Editions/EditionsTable.php b/src/Database/Editions/EditionsTable.php new file mode 100644 index 00000000..eea1fc9e --- /dev/null +++ b/src/Database/Editions/EditionsTable.php @@ -0,0 +1,193 @@ + 201910132, + '201910133' => 201910133, + '201910134' => 201910134, + '201910135' => 201910135, + '201910141' => 201910141, + '202002231' => 202002231 + ); + + /** + * Owned_Editions_Table constructor. + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Set up the database schema + */ + protected function set_schema() + { + $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, + isbn varchar(13) NOT NULL DEFAULT '', + format varchar(200) NOT NULL DEFAULT '', + date_acquired datetime DEFAULT NULL, + source_id bigint(20) UNSIGNED DEFAULT NULL, + signed int(1) UNSIGNED DEFAULT NULL, + date_created datetime NOT NULL, + date_modified datetime NOT NULL, + INDEX book_id (book_id), + INDEX isbn (isbn), + INDEX date_acquired (date_acquired)"; + } + + /** + * If the old `wp_bdb_owned_editions_db_version` option exists, copy that value to our new version key. + * This will ensure new upgrades are processed on old installs. + */ + public function maybe_upgrade() + { + $old_key = $this->get_db()->prefix.'bdb_owned_editions_db_version'; + $old_version = get_option($old_key); + + if (false !== $old_version) { + update_option($this->db_version_key, get_option($old_key)); + + delete_option($old_key); + } + + parent::maybe_upgrade(); + } + + /** + * Upgrade to version 201910132 + * - Rename `ID` to `id` & add `unsigned` + * + * @return bool + */ + protected function __201910132() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `ID` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT"); + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910133 + * - Rename `source` to `source_id` & add `unsigned` + * + * @return bool + */ + protected function __201910133() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `source` source_id bigint(20) UNSIGNED DEFAULT NULL"); + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910134 + * - Add `date_created` column + * - Add `date_modified` column + * + * @return bool + */ + protected function __201910134() + { + + $result = $this->column_exists('date_created'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + $result = $this->column_exists('date_modified'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + return $result; + + } + + /** + * Upgrade to version 201910135 + * - Add `isbn` index + * + * @return bool + */ + protected function __201910135() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD INDEX isbn (isbn)"); + + return $result; + + } + + /** + * Upgrade to version 201910141 + * - Add `date_acquired` index + * + * @return bool + */ + protected function __201910141() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD INDEX date_acquired (date_acquired)"); + + return $result; + + } + + /** + * Upgrade to version 202002231 + * - Allow `date_acquired` to be `null`. + * + * @return bool + */ + protected function __202002231() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} MODIFY date_acquired datetime DEFAULT NULL"); + + return $this->is_success($result); + + } + +} diff --git a/src/Plugin.php b/src/Plugin.php index 359aaf35..e4294aaf 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -12,6 +12,15 @@ use Book_Database\Container\Container; use Book_Database\Container\Exceptions\BindingResolutionException; +use Book_Database\Database\Authors\AuthorsTable; +use Book_Database\Database\BookAuthor\BookAuthorTable; +use Book_Database\Database\BookLinks\BookLinksTable; +use Book_Database\Database\Books\BookMetaTable; +use Book_Database\Database\Books\BooksTable; +use Book_Database\Database\BookTaxonomies\BookTaxonomiesTable; +use Book_Database\Database\BookTerm\BookTermRelationshipsTable; +use Book_Database\Database\BookTerms\BookTermsTable; +use Book_Database\Database\Editions\EditionsTable; use Book_Database\ServiceProviders\LegacyServiceProvider; use Book_Database\ServiceProviders\ServiceProvider; @@ -126,15 +135,15 @@ private function setup_application() self::$instance->loadServiceProviders(); self::$instance->tables = array( - 'authors' => new Authors_Table(), - 'book_author_relationships' => new Book_Author_Relationships_Table(), - 'book_links' => new Book_Links_Table(), - 'book_taxonomies' => new Book_Taxonomies_Table(), - 'book_term_relationships' => new Book_Term_Relationships_Table(), - 'book_terms' => new Book_Terms_Table(), - 'books' => new Books_Table(), - 'book_meta' => new Book_Meta_Table(), - 'editions' => new Editions_Table(), + 'authors' => new AuthorsTable(), + 'book_author_relationships' => new BookAuthorTable(), + 'book_links' => new BookLinksTable(), + 'book_taxonomies' => new BookTaxonomiesTable(), + 'book_term_relationships' => new BookTermRelationshipsTable(), + 'book_terms' => new BookTermsTable(), + 'books' => new BooksTable(), + 'book_meta' => new BookMetaTable(), + 'editions' => new EditionsTable(), 'reading_log' => new Reading_Logs_Table(), 'retailers' => new Retailers_Table(), 'reviews' => new Reviews_Table(), diff --git a/src/REST_API/v1/Book.php b/src/REST_API/v1/Book.php index 8b15061b..717ff294 100644 --- a/src/REST_API/v1/Book.php +++ b/src/REST_API/v1/Book.php @@ -9,7 +9,7 @@ namespace Book_Database\REST_API\v1; -use Book_Database\Books_Query; +use Book_Database\Database\Books\BooksQuery; use Book_Database\Exception; use Book_Database\REST_API\Controller; use function Book_Database\add_book; @@ -254,7 +254,7 @@ public function get_books( $request ) { 'order' => 'ASC' ) ); - $query = new Books_Query(); + $query = new BooksQuery(); $books = $query->get_books( $args ); foreach ( $books as $key => $book ) { diff --git a/src/ServiceProviders/LegacyServiceProvider.php b/src/ServiceProviders/LegacyServiceProvider.php index df7f7425..00e1b2c6 100644 --- a/src/ServiceProviders/LegacyServiceProvider.php +++ b/src/ServiceProviders/LegacyServiceProvider.php @@ -9,6 +9,31 @@ namespace Book_Database\ServiceProviders; +use Book_Database\Database\Authors\AuthorsQuery; +use Book_Database\Database\Authors\AuthorsSchema; +use Book_Database\Database\Authors\AuthorsTable; +use Book_Database\Database\BookAuthor\BookAuthorQuery; +use Book_Database\Database\BookAuthor\BookAuthorSchema; +use Book_Database\Database\BookAuthor\BookAuthorTable; +use Book_Database\Database\BookLinks\BookLinksQuery; +use Book_Database\Database\BookLinks\BookLinksSchema; +use Book_Database\Database\BookLinks\BookLinksTable; +use Book_Database\Database\Books\BookMetaTable; +use Book_Database\Database\Books\BooksQuery; +use Book_Database\Database\Books\BooksSchema; +use Book_Database\Database\Books\BooksTable; +use Book_Database\Database\BookTaxonomies\BookTaxonomiesQuery; +use Book_Database\Database\BookTaxonomies\BookTaxonomiesSchema; +use Book_Database\Database\BookTaxonomies\BookTaxonomiesTable; +use Book_Database\Database\BookTerm\BookTermRelationshipQuery; +use Book_Database\Database\BookTerm\BookTermRelationshipsSchema; +use Book_Database\Database\BookTerm\BookTermRelationshipsTable; +use Book_Database\Database\BookTerms\BookTermsQuery; +use Book_Database\Database\BookTerms\BookTermsSchema; +use Book_Database\Database\BookTerms\BookTermsTable; +use Book_Database\Database\Editions\EditionsQuery; +use Book_Database\Database\Editions\EditionsSchema; +use Book_Database\Database\Editions\EditionsTable; use Book_Database\HTML; use Book_Database\Plugin; use Book_Database\REST_API; @@ -57,47 +82,6 @@ private function includeLegacyFiles(): void require_once BDB_DIR.'includes/database/engine/class-where-clause.php'; require_once BDB_DIR.'includes/database/sanitization.php'; - // Database - authors - require_once BDB_DIR.'includes/database/authors/class-authors-table.php'; - require_once BDB_DIR.'includes/database/authors/class-authors-schema.php'; - require_once BDB_DIR.'includes/database/authors/class-authors-query.php'; - - // Database - book_author_relationships - require_once BDB_DIR.'includes/database/book-author-relationships/class-book-author-relationships-table.php'; - require_once BDB_DIR.'includes/database/book-author-relationships/class-book-author-relationships-schema.php'; - require_once BDB_DIR.'includes/database/book-author-relationships/class-book-author-relationships-query.php'; - - // Database - books - require_once BDB_DIR.'includes/database/books/class-books-table.php'; - require_once BDB_DIR.'includes/database/books/class-books-schema.php'; - require_once BDB_DIR.'includes/database/books/class-books-query.php'; - require_once BDB_DIR.'includes/database/books/class-book-meta-table.php'; - - // Database - book_links - require_once BDB_DIR.'includes/database/book-links/class-book-links-table.php'; - require_once BDB_DIR.'includes/database/book-links/class-book-links-schema.php'; - require_once BDB_DIR.'includes/database/book-links/class-book-links-query.php'; - - // Database - book_taxonomies - require_once BDB_DIR.'includes/database/book-taxonomies/class-book-taxonomies-table.php'; - require_once BDB_DIR.'includes/database/book-taxonomies/class-book-taxonomies-schema.php'; - require_once BDB_DIR.'includes/database/book-taxonomies/class-book-taxonomies-query.php'; - - // Database - book_term_relationships - require_once BDB_DIR.'includes/database/book-term-relationships/class-book-term-relationships-table.php'; - require_once BDB_DIR.'includes/database/book-term-relationships/class-book-term-relationships-schema.php'; - require_once BDB_DIR.'includes/database/book-term-relationships/class-book-term-relationships-query.php'; - - // Database - book_terms - require_once BDB_DIR.'includes/database/book-terms/class-book-terms-table.php'; - require_once BDB_DIR.'includes/database/book-terms/class-book-terms-schema.php'; - require_once BDB_DIR.'includes/database/book-terms/class-book-terms-query.php'; - - // Database - owned_editions - require_once BDB_DIR.'includes/database/editions/class-editions-table.php'; - require_once BDB_DIR.'includes/database/editions/class-editions-schema.php'; - require_once BDB_DIR.'includes/database/editions/class-editions-query.php'; - // Database - reading_log require_once BDB_DIR.'includes/database/reading-logs/class-reading-logs-table.php'; require_once BDB_DIR.'includes/database/reading-logs/class-reading-logs-schema.php'; @@ -254,6 +238,40 @@ private function includeFrontendFiles(): void private function registerClassAliases(): void { class_alias(Plugin::class, 'Book_Database\\Book_Database'); + + // Databases + class_alias(AuthorsTable::class, 'Book_Database\\Authors_Table'); + class_alias(AuthorsQuery::class, 'Book_Database\\Authors_Query'); + class_alias(AuthorsSchema::class, 'Book_Database\\Authors_Schema'); + + class_alias(BookAuthorQuery::class, 'Book_Database\\Book_Author_Relationships_Query'); + class_alias(BookAuthorSchema::class, 'Book_Database\\Book_Author_Relationships_Schema'); + class_alias(BookAuthorTable::class, 'Book_Database\\Book_Author_Relationships_Table'); + + class_alias(BookLinksQuery::class, 'Book_Database\\Book_Links_Query'); + class_alias(BookLinksSchema::class, 'Book_Database\\Book_Links_Schema'); + class_alias(BookLinksTable::class, 'Book_Database\\Book_Links_Table'); + + class_alias(BookTaxonomiesQuery::class, 'Book_Database\\Book_Taxonomies_Query'); + class_alias(BookTaxonomiesSchema::class, 'Book_Database\\Book_Taxonomies_Schema'); + class_alias(BookTaxonomiesTable::class, 'Book_Database\\Book_Taxonomies_Table'); + + class_alias(BookTermRelationshipQuery::class, 'Book_Database\\Book_Term_Relationships_Query'); + class_alias(BookTermRelationshipsSchema::class, 'Book_Database\\Book_Term_Relationships_Schema'); + class_alias(BookTermRelationshipsTable::class, 'Book_Database\\Book_Term_Relationships_Table'); + + class_alias(BookTermsQuery::class, 'Book_Database\\Book_Terms_Query'); + class_alias(BookTermsSchema::class, 'Book_Database\\Book_Terms_Schema'); + class_alias(BookTermsTable::class, 'Book_Database\\Book_Terms_Table'); + + class_alias(BookMetaTable::class, 'Book_Database\\Book_Meta_Table'); + class_alias(BooksQuery::class, 'Book_Database\\Books_Query'); + class_alias(BooksSchema::class, 'Book_Database\\Books_Schema'); + class_alias(BooksTable::class, 'Book_Database\\Books_Table'); + + class_alias(EditionsQuery::class, 'Book_Database\Editions_Query'); + class_alias(EditionsSchema::class, 'Book_Database\\Editions_Schema'); + class_alias(EditionsTable::class, 'Book_Database\\Editions_Table'); } private function bindClasses(): void From b7218537e9e3cd8652653077d661fc5be23469e3 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 20 Nov 2021 15:58:18 +0000 Subject: [PATCH 08/29] Finish refactoring DB classes. #248 --- .../reviews/class-reviews-list-table.php | 7 +- .../reading-logs/class-reading-logs-query.php | 76 ----- .../class-reading-logs-schema.php | 122 ------- .../reading-logs/class-reading-logs-table.php | 195 ----------- .../retailers/class-retailers-query.php | 76 ----- .../retailers/class-retailers-schema.php | 76 ----- .../retailers/class-retailers-table.php | 73 ---- .../reviews/class-review-meta-table.php | 130 ------- .../database/reviews/class-reviews-query.php | 306 ----------------- .../database/reviews/class-reviews-schema.php | 137 -------- .../database/reviews/class-reviews-table.php | 218 ------------ .../database/series/class-series-query.php | 76 ----- .../database/series/class-series-schema.php | 95 ------ .../database/series/class-series-table.php | 131 ------- .../reading-logs/reading-log-functions.php | 18 +- includes/retailers/retailer-functions.php | 18 +- includes/reviews/review-functions.php | 18 +- includes/series/series-functions.php | 16 +- src/Book_Reviews_Query.php | 5 +- src/Database/Books/BooksQuery.php | 12 +- src/Database/ReadingLogs/ReadingLogsQuery.php | 83 +++++ .../ReadingLogs/ReadingLogsSchema.php | 126 +++++++ src/Database/ReadingLogs/ReadingLogsTable.php | 207 +++++++++++ src/Database/Retailers/RetailersQuery.php | 83 +++++ src/Database/Retailers/RetailersSchema.php | 80 +++++ src/Database/Retailers/RetailersTable.php | 80 +++++ src/Database/Reviews/ReviewMetaTable.php | 140 ++++++++ src/Database/Reviews/ReviewsQuery.php | 321 ++++++++++++++++++ src/Database/Reviews/ReviewsSchema.php | 141 ++++++++ src/Database/Reviews/ReviewsTable.php | 232 +++++++++++++ src/Database/Series/SeriesQuery.php | 83 +++++ src/Database/Series/SeriesSchema.php | 99 ++++++ src/Database/Series/SeriesTable.php | 141 ++++++++ src/Plugin.php | 15 +- .../LegacyServiceProvider.php | 46 ++- src/Widgets/Reviews.php | 4 +- 36 files changed, 1912 insertions(+), 1774 deletions(-) delete mode 100644 includes/database/reading-logs/class-reading-logs-query.php delete mode 100644 includes/database/reading-logs/class-reading-logs-schema.php delete mode 100644 includes/database/reading-logs/class-reading-logs-table.php delete mode 100644 includes/database/retailers/class-retailers-query.php delete mode 100644 includes/database/retailers/class-retailers-schema.php delete mode 100644 includes/database/retailers/class-retailers-table.php delete mode 100644 includes/database/reviews/class-review-meta-table.php delete mode 100644 includes/database/reviews/class-reviews-query.php delete mode 100644 includes/database/reviews/class-reviews-schema.php delete mode 100644 includes/database/reviews/class-reviews-table.php delete mode 100644 includes/database/series/class-series-query.php delete mode 100644 includes/database/series/class-series-schema.php delete mode 100644 includes/database/series/class-series-table.php create mode 100644 src/Database/ReadingLogs/ReadingLogsQuery.php create mode 100644 src/Database/ReadingLogs/ReadingLogsSchema.php create mode 100644 src/Database/ReadingLogs/ReadingLogsTable.php create mode 100644 src/Database/Retailers/RetailersQuery.php create mode 100644 src/Database/Retailers/RetailersSchema.php create mode 100644 src/Database/Retailers/RetailersTable.php create mode 100644 src/Database/Reviews/ReviewMetaTable.php create mode 100644 src/Database/Reviews/ReviewsQuery.php create mode 100644 src/Database/Reviews/ReviewsSchema.php create mode 100644 src/Database/Reviews/ReviewsTable.php create mode 100644 src/Database/Series/SeriesQuery.php create mode 100644 src/Database/Series/SeriesSchema.php create mode 100644 src/Database/Series/SeriesTable.php diff --git a/includes/admin/reviews/class-reviews-list-table.php b/includes/admin/reviews/class-reviews-list-table.php index 88d92566..78ab871d 100644 --- a/includes/admin/reviews/class-reviews-list-table.php +++ b/includes/admin/reviews/class-reviews-list-table.php @@ -9,8 +9,11 @@ namespace Book_Database; +use Book_Database\Database\Reviews\ReviewsQuery; + /** * Class Reviews_List_Table + * * @package Book_Database */ class Reviews_List_Table extends List_Table { @@ -327,7 +330,7 @@ public function get_object_data( $count = false ) { ); } - $query = new Reviews_Query(); + $query = new ReviewsQuery(); return $query->get_reviews( $args ); @@ -503,4 +506,4 @@ protected function extra_tablenav( $which ) { } -} \ No newline at end of file +} diff --git a/includes/database/reading-logs/class-reading-logs-query.php b/includes/database/reading-logs/class-reading-logs-query.php deleted file mode 100644 index 62300bad..00000000 --- a/includes/database/reading-logs/class-reading-logs-query.php +++ /dev/null @@ -1,76 +0,0 @@ - 'id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'extra' => 'auto_increment', - 'primary' => true, - 'sortable' => true - ), - - // book_id - array( - 'name' => 'book_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'default' => 0 - ), - - // edition_id - array( - 'name' => 'edition_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'allow_null' => true, - 'default' => null, - 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' - ), - - // user_id - array( - 'name' => 'user_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'default' => 0 - ), - - // date_started - array( - 'name' => 'date_started', - 'type' => 'datetime', - 'sortable' => true, - 'date_query' => true, - 'allow_null' => true, - 'default' => null - ), - - // date_finished - array( - 'name' => 'date_finished', - 'type' => 'datetime', - 'sortable' => true, - 'date_query' => true, - 'allow_null' => true, - 'default' => null - ), - - // percentage_complete - array( - 'name' => 'percentage_complete', - 'type' => 'decimal', - 'length' => '5,4', - 'unsigned' => true, - 'sortable' => true, - 'default' => 0.00, - ), - - // rating - array( - 'name' => 'rating', - 'type' => 'decimal', - 'length' => '4,2', - 'unsigned' => true, - 'sortable' => true, - 'allow_null' => true, - 'default' => null - ), - - // date_modified - array( - 'name' => 'date_modified', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'modified' => true, - 'date_query' => true, - 'sortable' => true, - ), - - ); - -} \ No newline at end of file diff --git a/includes/database/reading-logs/class-reading-logs-table.php b/includes/database/reading-logs/class-reading-logs-table.php deleted file mode 100644 index cc620d83..00000000 --- a/includes/database/reading-logs/class-reading-logs-table.php +++ /dev/null @@ -1,195 +0,0 @@ - 201910132, - '201910133' => 201910133, - '201910141' => 201910141, - '201910142' => 201910142, - '202001281' => 202001281 - ); - - /** - * Books_Table constructor. - */ - public function __construct() { - parent::__construct(); - } - - /** - * Set up the database schema - */ - protected function set_schema() { - $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, - edition_id bigint(20) UNSIGNED DEFAULT NULL, - user_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, - date_started datetime DEFAULT NULL, - date_finished datetime DEFAULT NULL, - percentage_complete decimal(5,4) UNSIGNED NOT NULL DEFAULT 0.00, - rating decimal(4,2) DEFAULT NULL, - date_modified datetime NOT NULL, - INDEX book_id (book_id), - INDEX percentage_complete (percentage_complete), - INDEX date_finished_book_id (date_finished, book_id), - INDEX date_finished_percentage_complete (date_finished, percentage_complete), - INDEX date_finished_rating (date_finished, rating), - INDEX date_started (date_started), - INDEX rating_book_id (rating, book_id), - INDEX user_id (user_id)"; - } - - /** - * If the old `wp_bdb_reading_list_db_version` option exists, copy that value to our new version key. - * This will ensure new upgrades are processed on old installs. - */ - public function maybe_upgrade() { - - $old_key = $this->get_db()->prefix . 'bdb_reading_list_db_version'; - $old_version = get_option( $old_key ); - - if ( false !== $old_version ) { - update_option( $this->db_version_key, get_option( $old_key ) ); - - delete_option( $old_key ); - } - - return parent::maybe_upgrade(); - } - - /** - * Upgrade to version 201910132 - * - Rename `ID` to `id` & add `unsigned` - * - * @return bool - */ - protected function __201910132() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `ID` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT" ); - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910133 - * - Add `date_modified` column - * - * @return bool - */ - protected function __201910133() { - - $result = $this->column_exists( 'date_modified' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910141 - * - Change `complete` to `percentage_complete` - * - * @return bool - */ - protected function __201910141() { - - if ( $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'complete'" ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} DROP INDEX complete" ); - } else { - $result = true; - } - - if ( $result ) { - if ( ! $this->column_exists( 'percentage_complete' ) ) { - // First change to `float`. - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `complete` `percentage_complete` float UNSIGNED NOT NULL DEFAULT 0" ); - - if ( $result ) { - // Now change to divide by 100. - $result = $this->get_db()->query( "UPDATE {$this->table_name} SET percentage_complete = percentage_complete / 100 WHERE percentage_complete > 0" ); - - // Now change to decimal. - if ( $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} MODIFY `percentage_complete` decimal(5,4) UNSIGNED NOT NULL DEFAULT 0" ); - - // Now add an index. - if ( ! $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'percentage_complete'" ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD INDEX percentage_complete (percentage_complete)" ); - } - } - } - } - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910142 - * - Remove `dnf` rating values - * - Change `rating` to `decimal(4,2)` - * - * @return bool - */ - protected function __201910142() { - - $result = $this->get_db()->query( "UPDATE {$this->table_name} SET rating = NULL WHERE rating = 'dnf'" ); - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} MODIFY rating decimal(4,2) DEFAULT NULL" ); - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 202001281 - * - Add `edition_id` column - * - * @return bool - */ - protected function __202001281() { - - $result = $this->column_exists( 'edition_id' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN edition_id bigint(20) UNSIGNED DEFAULT NULL AFTER book_id" ); - } - - return $this->is_success( $result ); - - } - -} \ No newline at end of file diff --git a/includes/database/retailers/class-retailers-query.php b/includes/database/retailers/class-retailers-query.php deleted file mode 100644 index 706b7e83..00000000 --- a/includes/database/retailers/class-retailers-query.php +++ /dev/null @@ -1,76 +0,0 @@ - 'id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'extra' => 'auto_increment', - 'primary' => true, - 'sortable' => true - ), - - // name - array( - 'name' => 'name', - 'type' => 'varchar', - 'length' => '200', - 'sortable' => true, - 'searchable' => true, - 'validate' => 'sanitize_text_field' - ), - - // template - array( - 'name' => 'template', - 'type' => 'text', - 'validate' => 'wp_kses_post' - ), - - // date_created - array( - 'name' => 'date_created', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'created' => true, - 'date_query' => true, - 'sortable' => true, - ), - - // date_modified - array( - 'name' => 'date_modified', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'modified' => true, - 'date_query' => true, - 'sortable' => true, - ), - - ); - -} \ No newline at end of file diff --git a/includes/database/retailers/class-retailers-table.php b/includes/database/retailers/class-retailers-table.php deleted file mode 100644 index cb3838a2..00000000 --- a/includes/database/retailers/class-retailers-table.php +++ /dev/null @@ -1,73 +0,0 @@ - 201911021 - ); - - /** - * Book_Taxonomies_Table constructor. - */ - public function __construct() { - parent::__construct(); - } - - /** - * Set up the database schema - */ - protected function set_schema() { - $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - name varchar(200) NOT NULL DEFAULT '', - template text NOT NULL DEFAULT '', - date_created datetime NOT NULL, - date_modified datetime NOT NULL, - INDEX name (name)"; - } - - /** - * Upgrade to version 201911021 - * - add `template` column - * - * @return bool - */ - protected function __201911021() { - - $result = $this->column_exists( 'template' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN template text NOT NULL DEFAULT '' AFTER `name`" ); - } - - return $this->is_success( $result ); - - } - -} \ No newline at end of file diff --git a/includes/database/reviews/class-review-meta-table.php b/includes/database/reviews/class-review-meta-table.php deleted file mode 100644 index e18df4ca..00000000 --- a/includes/database/reviews/class-review-meta-table.php +++ /dev/null @@ -1,130 +0,0 @@ - 201910272, - '201910273' => 201910273, - '201910274' => 201910274 - ); - - /** - * Reviews_Table constructor. - */ - public function __construct() { - parent::__construct(); - } - - /** - * Set up the database schema - */ - protected function set_schema() { - $max_index_length = 191; - $this->schema = "meta_id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - bdb_review_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, - meta_key varchar(255) DEFAULT NULL, - meta_value longtext DEFAULT NULL, - INDEX bdb_review_id (bdb_review_id), - INDEX meta_key (meta_key({$max_index_length}))"; - } - - /** - * If the old `wp_bdb_reviewmeta_db_version` option exists, copy that value to our new version key. - * This will ensure new upgrades are processed on old installs. - */ - public function maybe_upgrade() { - - $old_key = $this->get_db()->prefix . 'bdb_reviewmeta_db_version'; - $old_version = get_option( $old_key ); - - if ( false !== $old_version ) { - update_option( $this->db_version_key, get_option( $old_key ) ); - - delete_option( $old_key ); - } - - return parent::maybe_upgrade(); - } - - /** - * Upgrade to version 201910272 - * - Drop the `review_id` index - * - * @return bool - */ - protected function __201910272() { - - if ( $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'review_id'" ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} DROP INDEX review_id" ); - } else { - $result = true; - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910273 - * - Rename `review_id` to `bdb_review_id` & add `unsigned` - * - * @return bool - */ - protected function __201910273() { - - if ( $this->column_exists( 'review_id' ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `review_id` `bdb_review_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0" ); - } else { - $result = true; - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910274 - * - Add a new `bdb_review_id` index - * - * @return bool - */ - protected function __201910274() { - - $result = $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'bdb_review_id'" ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD INDEX bdb_review_id (bdb_review_id)" ); - } - - return $this->is_success( $result ); - - } - -} \ No newline at end of file diff --git a/includes/database/reviews/class-reviews-query.php b/includes/database/reviews/class-reviews-query.php deleted file mode 100644 index beac7575..00000000 --- a/includes/database/reviews/class-reviews-query.php +++ /dev/null @@ -1,306 +0,0 @@ - array(), - 'book_query' => array(), - 'series_query' => array(), - 'reading_log_query' => array(), - 'review_query' => array(), - 'edition_query' => array(), - 'tax_query' => array(), - 'orderby' => 'review.id', - 'order' => 'DESC', - 'number' => 20, - 'offset' => 0, - 'count' => false - ) ); - - $select = $join = $where = array(); - - $clause_engine = new Where_Clause(); - - $tbl_books = book_database()->get_table( 'books' )->get_table_name(); - $tbl_author = book_database()->get_table( 'authors' )->get_table_name(); - $tbl_author_r = book_database()->get_table( 'book_author_relationships' )->get_table_name(); - $tbl_ed = book_database()->get_table( 'editions' )->get_table_name(); - $tbl_log = book_database()->get_table( 'reading_log' )->get_table_name(); - $tbl_reviews = book_database()->get_table( 'reviews' )->get_table_name(); - $tbl_series = book_database()->get_table( 'series' )->get_table_name(); - - // Select - $select = array( - 'review.*', - 'book.id as book_id', - 'book.cover_id as book_cover_id', - 'book.title as book_title', - 'book.pub_date as book_pub_date', - 'book.series_position as series_position', - "GROUP_CONCAT( DISTINCT author.id SEPARATOR ',' ) as author_id", - "GROUP_CONCAT( DISTINCT author.name SEPARATOR ',' ) as author_name", - 'series.id as series_id', - 'series.name as series_name', - 'log.date_started as date_started_reading', - 'log.date_finished as date_finished_reading', - 'log.percentage_complete as percentage_complete', - 'log.rating as rating', - ); - - // Book Join - $join['book_query'] = "LEFT JOIN {$tbl_books} AS book ON review.book_id = book.id"; - - // Author Join - $join['author_query'] = "LEFT JOIN {$tbl_author_r} AS ar ON review.book_id = ar.book_id LEFT JOIN {$tbl_author} AS author ON ar.author_id = author.id"; - - // Series Join - $join['series_query'] = "LEFT JOIN {$tbl_series} AS series ON book.series_id = series.id"; - - // Reading Log Join - $join['reading_log_query'] = "LEFT JOIN {$tbl_log} AS log ON log.id = review.reading_log_id"; - - /** - * Where - */ - - // Author query - if ( ! empty( $args['author_query'] ) ) { - $clause_engine->set_table_query( new AuthorsQuery() ); - $clause_engine->set_args( $args['author_query'] ); - $where = array_merge( $where, $clause_engine->get_clauses() ); - } - - // Book query - if ( ! empty( $args['book_query'] ) ) { - $clause_engine->set_table_query( new BooksQuery() ); - $clause_engine->set_args( $args['book_query'] ); - $where = array_merge( $where, $clause_engine->get_clauses() ); - } - - // Edition query - if ( ! empty( $args['edition_query'] ) ) { - $join['edition_query'] = "INNER JOIN {$tbl_ed} AS ed ON (review.book_id = ed.book_id)"; - $clause_engine->set_table_query( new EditionsQuery() ); - $clause_engine->set_args( $args['edition_query'] ); - $where = array_merge( $where, $clause_engine->get_clauses() ); - } - - // Reading log query - if ( ! empty( $args['reading_log_query'] ) ) { - $clause_engine->set_table_query( new Reading_Logs_Query() ); - $clause_engine->set_args( $args['reading_log_query'] ); - $where = array_merge( $where, $clause_engine->get_clauses() ); - } - - // Review query - if ( ! empty( $args['review_query'] ) ) { - $clause_engine->set_table_query( $this ); - $clause_engine->set_args( $args['review_query'] ); - $where = array_merge( $where, $clause_engine->get_clauses() ); - } - - // Series query - if ( ! empty( $args['series_query'] ) ) { - $clause_engine->set_table_query( new Series_Query() ); - $clause_engine->set_args( $args['series_query'] ); - $where = array_merge( $where, $clause_engine->get_clauses() ); - } - - // Tax query - if ( ! empty( $args['tax_query'] ) ) { - $tax_query = new Tax( $args['tax_query'] ); - $clauses = $tax_query->get_sql( $this->table_alias, 'book_id' ); - $join['tax_query'] = $clauses['join']; - $where['tax_query'] = preg_replace( '/^\s*AND\s*/', '', $clauses['where'] ); - } - - /** - * Format and query - */ - $select = implode( ', ', $select ); - $join = implode( ' ', $join ); - $where = ! empty( $where ) ? 'WHERE ' . implode( ' AND ', $where ) : ''; - - /** - * Validate the orderby / order - */ - $orderby = $this->validate_orderby( $args['orderby'], $args ); - $order = 'ASC' === strtoupper( $args['order'] ) ? 'ASC' : 'DESC'; - - $group_by = 'GROUP BY review.id'; - - // Override select if we're counting. - if ( ! empty( $args['count'] ) ) { - $select = 'COUNT( DISTINCT review.id )'; - $group_by = ''; - } - - if ( ! empty( $args['count'] ) ) { - $query = "SELECT {$select} FROM {$tbl_reviews} AS review {$join} {$where}"; - - $reviews = $this->get_db()->get_var( $query ); - - return absint( $reviews ); - } - - $query = $this->get_db()->prepare( "SELECT {$select} FROM {$tbl_reviews} AS review {$join} {$where} {$group_by} ORDER BY $orderby $order LIMIT %d,%d;", absint( $args['offset'] ), absint( $args['number'] ) ); - - $reviews = $this->get_db()->get_results( $query ); - - return wp_unslash( $reviews ); - - } - - /** - * Validate the orderby - * - * @param string $orderby Desired orderby. - * @param array $args Query arguments. - * - * @return string - */ - protected function validate_orderby( $orderby, $args = array() ) { - - $valid_orderbys = array( - 'review.id', - 'review.book_id', - 'review.reading_log_id', - 'review.user_id', - 'review.post_id', - 'review.date_written', - 'review.date_published', - 'review.date_created', - 'review.date_modified', - 'author.id', - 'author.name', - 'author.slug', - 'book.id', - 'book.title', - 'book.index_title', - 'book.series_id', - 'book.series_position', - 'book.pub_date', - 'book.pages', - 'book.date_created', - 'book.date_modified', - 'series.id', - 'series.name', - 'series.slug', - 'series.number_books', - 'series.date_created', - 'log.id', - 'log.user_id', - 'log.date_started', - 'log.date_finished', - 'log.percentage_complete', - 'log.rating' - ); - - return in_array( $orderby, $valid_orderbys ) ? $orderby : 'review.id'; - - } - -} diff --git a/includes/database/reviews/class-reviews-schema.php b/includes/database/reviews/class-reviews-schema.php deleted file mode 100644 index 34dc03ec..00000000 --- a/includes/database/reviews/class-reviews-schema.php +++ /dev/null @@ -1,137 +0,0 @@ - 'id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'extra' => 'auto_increment', - 'primary' => true, - 'sortable' => true - ), - - // book_id - array( - 'name' => 'book_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'validate' => 'absint' - ), - - // reading_log_id - array( - 'name' => 'reading_log_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'allow_null' => true, - 'default' => null, - 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' - ), - - // user_id - array( - 'name' => 'user_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'validate' => 'absint' - ), - - // post_id - array( - 'name' => 'post_id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true, - 'allow_null' => true, - 'default' => null, - 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' - ), - - // url - array( - 'name' => 'url', - 'type' => 'mediumtext', - 'default' => '', - 'validate' => 'sanitize_text_field' - ), - - // review - array( - 'name' => 'review', - 'type' => 'longtext', - 'validate' => 'wp_kses_post' - ), - - // date_written - array( - 'name' => 'date_written', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'sortable' => true, - 'date_query' => true - ), - - // date_published - array( - 'name' => 'date_published', - 'type' => 'datetime', - 'sortable' => true, - 'date_query' => true, - 'allow_null' => true, - 'default' => null, - ), - - // date_created - array( - 'name' => 'date_created', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'created' => true, - 'date_query' => true, - 'sortable' => true, - ), - - // date_modified - array( - 'name' => 'date_modified', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'modified' => true, - 'date_query' => true, - 'sortable' => true, - ), - - ); - -} \ No newline at end of file diff --git a/includes/database/reviews/class-reviews-table.php b/includes/database/reviews/class-reviews-table.php deleted file mode 100644 index 31c6902e..00000000 --- a/includes/database/reviews/class-reviews-table.php +++ /dev/null @@ -1,218 +0,0 @@ - 201910181, - '201910182' => 201910182, - '201910183' => 201910183, - '201910184' => 201910184, - '201910185' => 201910185, - '201910261' => 201910261, - '201910301' => 201910301 - ); - - /** - * Reviews_Table constructor. - */ - public function __construct() { - parent::__construct(); - } - - /** - * Set up the database schema - */ - protected function set_schema() { - $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, - reading_log_id bigint(20) UNSIGNED DEFAULT NULL, - user_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, - post_id bigint(20) UNSIGNED DEFAULT NULL, - url mediumtext NOT NULL DEFAULT '', - review longtext NOT NULL DEFAULT '', - date_written datetime NOT NULL, - date_published datetime DEFAULT NULL, - date_created datetime NOT NULL, - date_modified datetime NOT NULL, - INDEX book_id (book_id), - INDEX date_written_book_id (date_written, book_id), - INDEX date_written_id (date_written, id), - INDEX post_id (post_id), - INDEX user_id (user_id)"; - } - - /** - * If the old `wp_bdb_reviews_db_version` option exists, copy that value to our new version key. - * This will ensure new upgrades are processed on old installs. - */ - public function maybe_upgrade() { - - $old_key = $this->get_db()->prefix . 'bdb_reviews_db_version'; - $old_version = get_option( $old_key ); - - if ( false !== $old_version ) { - update_option( $this->db_version_key, get_option( $old_key ) ); - - delete_option( $old_key ); - } - - return parent::maybe_upgrade(); - } - - /** - * Upgrade to version 201910181 - * - Drop the `date_written_ID` index - * - * @return bool - */ - protected function __201910181() { - - if ( $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'date_written_ID'" ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} DROP INDEX date_written_ID" ); - } else { - $result = true; - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910182 - * - Rename `ID` to `id` & add `unsigned` - * - * @return bool - */ - protected function __201910182() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `ID` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT" ); - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910183 - * - Add a new `date_written_id` index - * - * @return bool - */ - protected function __201910183() { - - $result = $this->get_db()->query( "SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'date_written_id'" ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD INDEX date_written_id (date_written, id)" ); - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910184 - * - Add `date_created` column - * - Add `date_modified` column - * - * @return bool - */ - protected function __201910184() { - - $result = $this->column_exists( 'date_created' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - $result = $this->column_exists( 'date_modified' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910185 - * - Change `book_id` column - add `unsigned` - * - Change `post_id` column - add `unsigned` and allow null - * - Change `user_id` column - add `unsigned` - * - * @return bool - */ - protected function __201910185() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} MODIFY book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0" ); - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} MODIFY post_id bigint(20) UNSIGNED DEFAULT NULL" ); - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} MODIFY user_id bigint(20) UNSIGNED NOT NULL DEFAULT 0 AFTER book_id" ); - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910261 - * - Drop column `rating` - * - * @return bool - */ - protected function __201910261() { - - if ( $this->column_exists( 'rating' ) ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} DROP COLUMN `rating`" ); - } else { - $result = true; - } - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910301 - * - Add `reading_log_id` column - * - * @return bool - */ - protected function __201910301() { - - $result = $this->column_exists( 'reading_log_id' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN reading_log_id bigint(20) UNSIGNED DEFAULT NULL AFTER book_id" ); - } - - return $this->is_success( $result ); - - } - -} \ No newline at end of file diff --git a/includes/database/series/class-series-query.php b/includes/database/series/class-series-query.php deleted file mode 100644 index 99db9bfc..00000000 --- a/includes/database/series/class-series-query.php +++ /dev/null @@ -1,76 +0,0 @@ - 'id', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'extra' => 'auto_increment', - 'primary' => true, - 'sortable' => true - ), - - // name - array( - 'name' => 'name', - 'type' => 'varchar', - 'length' => '200', - 'sortable' => true, - 'searchable' => true, - 'validate' => 'sanitize_text_field' - ), - - // slug - array( - 'name' => 'slug', - 'type' => 'varchar', - 'length' => '200', - 'sortable' => true, - 'searchable' => true, - 'validate' => 'sanitize_key' - ), - - // description - array( - 'name' => 'description', - 'type' => 'longtext', - 'validate' => 'wp_kses_post' - ), - - // number_books - array( - 'name' => 'number_books', - 'type' => 'bigint', - 'length' => '20', - 'unsigned' => true, - 'sortable' => true - ), - - // date_created - array( - 'name' => 'date_created', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'created' => true, - 'date_query' => true, - 'sortable' => true, - ), - - // date_modified - array( - 'name' => 'date_modified', - 'type' => 'datetime', - 'default' => '', // True default is current time, set in query class - 'modified' => true, - 'date_query' => true, - 'sortable' => true, - ), - - ); - -} \ No newline at end of file diff --git a/includes/database/series/class-series-table.php b/includes/database/series/class-series-table.php deleted file mode 100644 index 8323f2ca..00000000 --- a/includes/database/series/class-series-table.php +++ /dev/null @@ -1,131 +0,0 @@ - 201910122, - '201910123' => 201910123, - '201910124' => 201910124 - ); - - /** - * Series_Table constructor. - */ - public function __construct() { - parent::__construct(); - } - - /** - * Set up the database schema - */ - protected function set_schema() { - $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - name varchar(200) NOT NULL DEFAULT '', - slug varchar(200) NOT NULL DEFAULT '', - description longtext NOT NULL DEFAULT '', - number_books bigint(20) UNSIGNED NOT NULL DEFAULT 0, - date_created datetime NOT NULL, - date_modified datetime NOT NULL, - INDEX name (name)"; - } - - /** - * If the old `wp_bdb_series_db_version` option exists, copy that value to our new version key. - * This will ensure new upgrades are processed on old installs. - */ - public function maybe_upgrade() { - - $old_key = $this->get_db()->prefix . 'bdb_series_db_version'; - $old_version = get_option( $old_key ); - - if ( false !== $old_version ) { - update_option( $this->db_version_key, get_option( $old_key ) ); - - delete_option( $old_key ); - } - - return parent::maybe_upgrade(); - - } - - /** - * Upgrade to version 201910122 - * - Rename `ID` to `id` & add `unsigned` - * - * @return bool - */ - protected function __201910122() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} CHANGE `ID` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT" ); - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910123 - * - Add `unsigned` to `number_books` - * - * @return bool - */ - protected function __201910123() { - - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} MODIFY number_books bigint(20) UNSIGNED NOT NULL DEFAULT 0" ); - - return $this->is_success( $result ); - - } - - /** - * Upgrade to version 201910124 - * - Add `date_created` column - * - Add `date_modified` column - * - * @return bool - */ - protected function __201910124() { - - $result = $this->column_exists( 'date_created' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - $result = $this->column_exists( 'date_modified' ); - - if ( ! $result ) { - $result = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'" ); - } - - return $result; - - } - -} \ No newline at end of file diff --git a/includes/reading-logs/reading-log-functions.php b/includes/reading-logs/reading-log-functions.php index 112b0d44..e8f9bbb8 100644 --- a/includes/reading-logs/reading-log-functions.php +++ b/includes/reading-logs/reading-log-functions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Database\ReadingLogs\ReadingLogsQuery; + /** * Get a single reading log entry by its ID * @@ -18,7 +20,7 @@ */ function get_reading_log( $log_id ) { - $query = new Reading_Logs_Query(); + $query = new ReadingLogsQuery(); return $query->get_item( $log_id ); @@ -34,7 +36,7 @@ function get_reading_log( $log_id ) { */ function get_reading_log_by( $column_name, $column_value ) { - $query = new Reading_Logs_Query(); + $query = new ReadingLogsQuery(); return $query->get_item_by( $column_name, $column_value ); @@ -84,7 +86,7 @@ function get_reading_logs( $args = array() ) { 'number' => 20 ) ); - $query = new Reading_Logs_Query(); + $query = new ReadingLogsQuery(); return $query->query( $args ); @@ -105,7 +107,7 @@ function count_reading_logs( $args = array() ) { 'count' => true ) ); - $query = new Reading_Logs_Query( $args ); + $query = new ReadingLogsQuery( $args ); return absint( $query->found_items ); @@ -148,7 +150,7 @@ function add_reading_log( $args = array() ) { throw new Exception( 'missing_required_parameter', __( 'A user ID is required.', 'book-database' ), 400 ); } - $query = new Reading_Logs_Query(); + $query = new ReadingLogsQuery(); $log_id = $query->add_item( $args ); if ( empty( $log_id ) ) { @@ -170,7 +172,7 @@ function add_reading_log( $args = array() ) { */ function update_reading_log( $log_id, $args = array() ) { - $query = new Reading_Logs_Query(); + $query = new ReadingLogsQuery(); $updated = $query->update_item( $log_id, $args ); if ( ! $updated ) { @@ -191,7 +193,7 @@ function update_reading_log( $log_id, $args = array() ) { */ function delete_reading_log( $log_id ) { - $query = new Reading_Logs_Query(); + $query = new ReadingLogsQuery(); $deleted = $query->delete_item( $log_id ); if ( ! $deleted ) { @@ -218,4 +220,4 @@ function delete_reading_log( $log_id ) { return true; -} \ No newline at end of file +} diff --git a/includes/retailers/retailer-functions.php b/includes/retailers/retailer-functions.php index 1d0af520..410afa78 100644 --- a/includes/retailers/retailer-functions.php +++ b/includes/retailers/retailer-functions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Database\Retailers\RetailersQuery; + /** * Get a single retailer by its ID * @@ -18,7 +20,7 @@ */ function get_retailer( $retailer_id ) { - $query = new Retailers_Query(); + $query = new RetailersQuery(); return $query->get_item( $retailer_id ); @@ -34,7 +36,7 @@ function get_retailer( $retailer_id ) { */ function get_retailer_by( $column_name, $column_value ) { - $query = new Retailers_Query(); + $query = new RetailersQuery(); return $query->get_item_by( $column_name, $column_value ); @@ -74,7 +76,7 @@ function get_retailers( $args = array() ) { 'number' => 20 ) ); - $query = new Retailers_Query(); + $query = new RetailersQuery(); return $query->query( $args ); @@ -95,7 +97,7 @@ function count_retailers( $args = array() ) { 'count' => true ) ); - $query = new Retailers_Query( $args ); + $query = new RetailersQuery( $args ); return absint( $query->found_items ); @@ -124,7 +126,7 @@ function add_retailer( $args = array() ) { throw new Exception( 'missing_required_parameter', __( 'An author name is required.', 'book-database' ), 400 ); } - $query = new Retailers_Query(); + $query = new RetailersQuery(); $retailer_id = $query->add_item( $args ); if ( empty( $retailer_id ) ) { @@ -146,7 +148,7 @@ function add_retailer( $args = array() ) { */ function update_retailer( $retailer_id, $args = array() ) { - $query = new Retailers_Query(); + $query = new RetailersQuery(); $updated = $query->update_item( $retailer_id, $args ); if ( ! $updated ) { @@ -169,7 +171,7 @@ function delete_retailer( $retailer_id ) { global $wpdb; - $query = new Retailers_Query(); + $query = new RetailersQuery(); $deleted = $query->delete_item( $retailer_id ); if ( ! $deleted ) { @@ -183,4 +185,4 @@ function delete_retailer( $retailer_id ) { return true; -} \ No newline at end of file +} diff --git a/includes/reviews/review-functions.php b/includes/reviews/review-functions.php index d6f188e9..dbc9b87e 100644 --- a/includes/reviews/review-functions.php +++ b/includes/reviews/review-functions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Database\Reviews\ReviewsQuery; + /** * Get a single review by its ID * @@ -18,7 +20,7 @@ */ function get_review( $review_id ) { - $query = new Reviews_Query(); + $query = new ReviewsQuery(); return $query->get_item( $review_id ); @@ -34,7 +36,7 @@ function get_review( $review_id ) { */ function get_review_by( $column_name, $column_value ) { - $query = new Reviews_Query(); + $query = new ReviewsQuery(); return $query->get_item_by( $column_name, $column_value ); @@ -64,7 +66,7 @@ function get_review_by( $column_name, $column_value ) { */ function get_reviews( $args = array() ) { - $query = new Reviews_Query(); + $query = new ReviewsQuery(); return $query->get_reviews( $args ); @@ -85,7 +87,7 @@ function count_reviews( $args = array() ) { 'count' => true ) ); - $query = new Reviews_Query( $args ); + $query = new ReviewsQuery( $args ); return absint( $query->found_items ); @@ -125,7 +127,7 @@ function add_review( $args = array() ) { throw new Exception( 'missing_parameter', __( 'Book ID is required.', 'book-database' ), 400 ); } - $query = new Reviews_Query(); + $query = new ReviewsQuery(); $review_id = $query->add_item( $args ); if ( empty( $review_id ) ) { @@ -147,7 +149,7 @@ function add_review( $args = array() ) { */ function update_review( $review_id, $args = array() ) { - $query = new Reviews_Query(); + $query = new ReviewsQuery(); $updated = $query->update_item( $review_id, $args ); if ( ! $updated ) { @@ -168,7 +170,7 @@ function update_review( $review_id, $args = array() ) { */ function delete_review( $review_id ) { - $query = new Reviews_Query(); + $query = new ReviewsQuery(); $deleted = $query->delete_item( $review_id ); if ( ! $deleted ) { @@ -251,4 +253,4 @@ function get_review_post_types() { $post_types = array( 'post' ); return apply_filters( 'book-database/review-post-types', $post_types ); -} \ No newline at end of file +} diff --git a/includes/series/series-functions.php b/includes/series/series-functions.php index 23a3e1c4..90466992 100644 --- a/includes/series/series-functions.php +++ b/includes/series/series-functions.php @@ -15,6 +15,8 @@ * for the plural version. To get a single series by ID, use `get_book_series_by( 'id', $id )` */ +use Book_Database\Database\Series\SeriesQuery; + /** * Get a single series by a column name/value combo * @@ -25,7 +27,7 @@ */ function get_book_series_by( $column_name, $column_value ) { - $query = new Series_Query(); + $query = new SeriesQuery(); return $query->get_item_by( $column_name, $column_value ); @@ -68,7 +70,7 @@ function get_book_series( $args = array() ) { 'number' => 20 ) ); - $query = new Series_Query(); + $query = new SeriesQuery(); return $query->query( $args ); @@ -89,7 +91,7 @@ function count_book_series( $args = array() ) { 'count' => true ) ); - $query = new Series_Query( $args ); + $query = new SeriesQuery( $args ); return absint( $query->found_items ); @@ -128,7 +130,7 @@ function add_book_series( $args ) { // Sanitize. $args['slug'] = sanitize_key( $args['slug'] ); - $query = new Series_Query(); + $query = new SeriesQuery(); $series_id = $query->add_item( $args ); if ( empty( $series_id ) ) { @@ -161,7 +163,7 @@ function update_book_series( $series_id, $args = array() ) { $args['slug'] = unique_book_slug( $args['slug'], 'series' ); } - $query = new Series_Query(); + $query = new SeriesQuery(); $updated = $query->update_item( $series_id, $args ); if ( ! $updated ) { @@ -184,7 +186,7 @@ function update_book_series( $series_id, $args = array() ) { */ function delete_book_series( $series_id ) { - $query = new Series_Query(); + $query = new SeriesQuery(); $deleted = $query->delete_item( $series_id ); if ( ! $deleted ) { @@ -232,4 +234,4 @@ function get_series_admin_page_url( $args = array() ) { return add_query_arg( $sanitized_args, admin_url( 'admin.php?page=bdb-series' ) ); -} \ No newline at end of file +} diff --git a/src/Book_Reviews_Query.php b/src/Book_Reviews_Query.php index 7abed04e..8f02d047 100644 --- a/src/Book_Reviews_Query.php +++ b/src/Book_Reviews_Query.php @@ -11,8 +11,11 @@ namespace Book_Database; +use Book_Database\Database\Reviews\ReviewsQuery; + /** * Class Book_Reviews_Query + * * @package Book_Database */ class Book_Reviews_Query { @@ -207,7 +210,7 @@ protected function parse_args( $args = array() ) { */ public function get_results() { - $query = new Reviews_Query(); + $query = new ReviewsQuery(); $reviews = $query->get_reviews( $this->args ); $count_args = $this->args; diff --git a/src/Database/Books/BooksQuery.php b/src/Database/Books/BooksQuery.php index 37bf047f..5331abe4 100644 --- a/src/Database/Books/BooksQuery.php +++ b/src/Database/Books/BooksQuery.php @@ -14,9 +14,9 @@ use Book_Database\Book; use Book_Database\Database\Authors\AuthorsQuery; use Book_Database\Database\Editions\EditionsQuery; -use Book_Database\Reading_Logs_Query; -use Book_Database\Reviews_Query; -use Book_Database\Series_Query; +use Book_Database\Database\ReadingLogs\ReadingLogsQuery; +use Book_Database\Database\Reviews\ReviewsQuery; +use Book_Database\Database\Series\SeriesQuery; use Book_Database\Where_Clause; use function Book_Database\book_database; @@ -178,7 +178,7 @@ public function get_books($args = array()) // Reading log query if (! empty($args['reading_log_query'])) { $join['reading_log_query'] = "INNER JOIN {$tbl_log} AS log ON (book.id = log.book_id)"; - $clause_engine->set_table_query(new Reading_Logs_Query()); + $clause_engine->set_table_query(new ReadingLogsQuery()); $clause_engine->set_args($args['reading_log_query']); $where = array_merge($where, $clause_engine->get_clauses()); $select[] = 'log.id AS log_id, log.user_id AS log_user_id, log.date_started AS date_started, log.date_finished AS date_finished, log.percentage_complete AS percentage_complete, log.rating AS rating'; @@ -187,7 +187,7 @@ public function get_books($args = array()) // Review query if (! empty($args['review_query'])) { $join['review_query'] = "INNER JOIN {$tbl_reviews} AS review ON (book.id = review.book_id)"; - $clause_engine->set_table_query(new Reviews_Query()); + $clause_engine->set_table_query(new ReviewsQuery()); $clause_engine->set_args($args['review_query']); $where = array_merge($where, $clause_engine->get_clauses()); } elseif (! empty($args['include_review'])) { @@ -204,7 +204,7 @@ public function get_books($args = array()) // Series query if (! empty($args['series_query'])) { - $clause_engine->set_table_query(new Series_Query()); + $clause_engine->set_table_query(new SeriesQuery()); $clause_engine->set_args($args['series_query']); $where = array_merge($where, $clause_engine->get_clauses()); } diff --git a/src/Database/ReadingLogs/ReadingLogsQuery.php b/src/Database/ReadingLogs/ReadingLogsQuery.php new file mode 100644 index 00000000..104221a0 --- /dev/null +++ b/src/Database/ReadingLogs/ReadingLogsQuery.php @@ -0,0 +1,83 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true + ), + + // book_id + array( + 'name' => 'book_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'default' => 0 + ), + + // edition_id + array( + 'name' => 'edition_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'allow_null' => true, + 'default' => null, + 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' + ), + + // user_id + array( + 'name' => 'user_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'default' => 0 + ), + + // date_started + array( + 'name' => 'date_started', + 'type' => 'datetime', + 'sortable' => true, + 'date_query' => true, + 'allow_null' => true, + 'default' => null + ), + + // date_finished + array( + 'name' => 'date_finished', + 'type' => 'datetime', + 'sortable' => true, + 'date_query' => true, + 'allow_null' => true, + 'default' => null + ), + + // percentage_complete + array( + 'name' => 'percentage_complete', + 'type' => 'decimal', + 'length' => '5,4', + 'unsigned' => true, + 'sortable' => true, + 'default' => 0.00, + ), + + // rating + array( + 'name' => 'rating', + 'type' => 'decimal', + 'length' => '4,2', + 'unsigned' => true, + 'sortable' => true, + 'allow_null' => true, + 'default' => null + ), + + // date_modified + array( + 'name' => 'date_modified', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'modified' => true, + 'date_query' => true, + 'sortable' => true, + ), + + ); + +} diff --git a/src/Database/ReadingLogs/ReadingLogsTable.php b/src/Database/ReadingLogs/ReadingLogsTable.php new file mode 100644 index 00000000..5541dcbe --- /dev/null +++ b/src/Database/ReadingLogs/ReadingLogsTable.php @@ -0,0 +1,207 @@ + 201910132, + '201910133' => 201910133, + '201910141' => 201910141, + '201910142' => 201910142, + '202001281' => 202001281 + ); + + /** + * Books_Table constructor. + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Set up the database schema + */ + protected function set_schema() + { + $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, + edition_id bigint(20) UNSIGNED DEFAULT NULL, + user_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, + date_started datetime DEFAULT NULL, + date_finished datetime DEFAULT NULL, + percentage_complete decimal(5,4) UNSIGNED NOT NULL DEFAULT 0.00, + rating decimal(4,2) DEFAULT NULL, + date_modified datetime NOT NULL, + INDEX book_id (book_id), + INDEX percentage_complete (percentage_complete), + INDEX date_finished_book_id (date_finished, book_id), + INDEX date_finished_percentage_complete (date_finished, percentage_complete), + INDEX date_finished_rating (date_finished, rating), + INDEX date_started (date_started), + INDEX rating_book_id (rating, book_id), + INDEX user_id (user_id)"; + } + + /** + * If the old `wp_bdb_reading_list_db_version` option exists, copy that value to our new version key. + * This will ensure new upgrades are processed on old installs. + */ + public function maybe_upgrade() + { + + $old_key = $this->get_db()->prefix.'bdb_reading_list_db_version'; + $old_version = get_option($old_key); + + if (false !== $old_version) { + update_option($this->db_version_key, get_option($old_key)); + + delete_option($old_key); + } + + parent::maybe_upgrade(); + } + + /** + * Upgrade to version 201910132 + * - Rename `ID` to `id` & add `unsigned` + * + * @return bool + */ + protected function __201910132() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `ID` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT"); + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910133 + * - Add `date_modified` column + * + * @return bool + */ + protected function __201910133() + { + + $result = $this->column_exists('date_modified'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910141 + * - Change `complete` to `percentage_complete` + * + * @return bool + */ + protected function __201910141() + { + + if ($this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'complete'")) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} DROP INDEX complete"); + } else { + $result = true; + } + + if ($result) { + if (! $this->column_exists('percentage_complete')) { + // First change to `float`. + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `complete` `percentage_complete` float UNSIGNED NOT NULL DEFAULT 0"); + + if ($result) { + // Now change to divide by 100. + $result = $this->get_db()->query("UPDATE {$this->table_name} SET percentage_complete = percentage_complete / 100 WHERE percentage_complete > 0"); + + // Now change to decimal. + if ($result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} MODIFY `percentage_complete` decimal(5,4) UNSIGNED NOT NULL DEFAULT 0"); + + // Now add an index. + if (! $this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'percentage_complete'")) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD INDEX percentage_complete (percentage_complete)"); + } + } + } + } + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910142 + * - Remove `dnf` rating values + * - Change `rating` to `decimal(4,2)` + * + * @return bool + */ + protected function __201910142() + { + + $result = $this->get_db()->query("UPDATE {$this->table_name} SET rating = NULL WHERE rating = 'dnf'"); + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} MODIFY rating decimal(4,2) DEFAULT NULL"); + + return $this->is_success($result); + + } + + /** + * Upgrade to version 202001281 + * - Add `edition_id` column + * + * @return bool + */ + protected function __202001281() + { + + $result = $this->column_exists('edition_id'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN edition_id bigint(20) UNSIGNED DEFAULT NULL AFTER book_id"); + } + + return $this->is_success($result); + + } + +} diff --git a/src/Database/Retailers/RetailersQuery.php b/src/Database/Retailers/RetailersQuery.php new file mode 100644 index 00000000..abe9fe52 --- /dev/null +++ b/src/Database/Retailers/RetailersQuery.php @@ -0,0 +1,83 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true + ), + + // name + array( + 'name' => 'name', + 'type' => 'varchar', + 'length' => '200', + 'sortable' => true, + 'searchable' => true, + 'validate' => 'sanitize_text_field' + ), + + // template + array( + 'name' => 'template', + 'type' => 'text', + 'validate' => 'wp_kses_post' + ), + + // date_created + array( + 'name' => 'date_created', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ), + + // date_modified + array( + 'name' => 'date_modified', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'modified' => true, + 'date_query' => true, + 'sortable' => true, + ), + + ); + +} diff --git a/src/Database/Retailers/RetailersTable.php b/src/Database/Retailers/RetailersTable.php new file mode 100644 index 00000000..47685981 --- /dev/null +++ b/src/Database/Retailers/RetailersTable.php @@ -0,0 +1,80 @@ + 201911021 + ); + + /** + * Book_Taxonomies_Table constructor. + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Set up the database schema + */ + protected function set_schema() + { + $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + name varchar(200) NOT NULL DEFAULT '', + template text NOT NULL DEFAULT '', + date_created datetime NOT NULL, + date_modified datetime NOT NULL, + INDEX name (name)"; + } + + /** + * Upgrade to version 201911021 + * - add `template` column + * + * @return bool + */ + protected function __201911021() + { + + $result = $this->column_exists('template'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN template text NOT NULL DEFAULT '' AFTER `name`"); + } + + return $this->is_success($result); + + } + +} diff --git a/src/Database/Reviews/ReviewMetaTable.php b/src/Database/Reviews/ReviewMetaTable.php new file mode 100644 index 00000000..dec15f6e --- /dev/null +++ b/src/Database/Reviews/ReviewMetaTable.php @@ -0,0 +1,140 @@ + 201910272, + '201910273' => 201910273, + '201910274' => 201910274 + ); + + /** + * Reviews_Table constructor. + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Set up the database schema + */ + protected function set_schema() + { + $max_index_length = 191; + $this->schema = "meta_id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + bdb_review_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, + meta_key varchar(255) DEFAULT NULL, + meta_value longtext DEFAULT NULL, + INDEX bdb_review_id (bdb_review_id), + INDEX meta_key (meta_key({$max_index_length}))"; + } + + /** + * If the old `wp_bdb_reviewmeta_db_version` option exists, copy that value to our new version key. + * This will ensure new upgrades are processed on old installs. + */ + public function maybe_upgrade() + { + + $old_key = $this->get_db()->prefix.'bdb_reviewmeta_db_version'; + $old_version = get_option($old_key); + + if (false !== $old_version) { + update_option($this->db_version_key, get_option($old_key)); + + delete_option($old_key); + } + + return parent::maybe_upgrade(); + } + + /** + * Upgrade to version 201910272 + * - Drop the `review_id` index + * + * @return bool + */ + protected function __201910272() + { + + if ($this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'review_id'")) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} DROP INDEX review_id"); + } else { + $result = true; + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910273 + * - Rename `review_id` to `bdb_review_id` & add `unsigned` + * + * @return bool + */ + protected function __201910273() + { + + if ($this->column_exists('review_id')) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `review_id` `bdb_review_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0"); + } else { + $result = true; + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910274 + * - Add a new `bdb_review_id` index + * + * @return bool + */ + protected function __201910274() + { + + $result = $this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'bdb_review_id'"); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD INDEX bdb_review_id (bdb_review_id)"); + } + + return $this->is_success($result); + + } + +} diff --git a/src/Database/Reviews/ReviewsQuery.php b/src/Database/Reviews/ReviewsQuery.php new file mode 100644 index 00000000..0aef6fe1 --- /dev/null +++ b/src/Database/Reviews/ReviewsQuery.php @@ -0,0 +1,321 @@ + array(), + 'book_query' => array(), + 'series_query' => array(), + 'reading_log_query' => array(), + 'review_query' => array(), + 'edition_query' => array(), + 'tax_query' => array(), + 'orderby' => 'review.id', + 'order' => 'DESC', + 'number' => 20, + 'offset' => 0, + 'count' => false + )); + + $select = $join = $where = array(); + + $clause_engine = new Where_Clause(); + + $tbl_books = book_database()->get_table('books')->get_table_name(); + $tbl_author = book_database()->get_table('authors')->get_table_name(); + $tbl_author_r = book_database()->get_table('book_author_relationships')->get_table_name(); + $tbl_ed = book_database()->get_table('editions')->get_table_name(); + $tbl_log = book_database()->get_table('reading_log')->get_table_name(); + $tbl_reviews = book_database()->get_table('reviews')->get_table_name(); + $tbl_series = book_database()->get_table('series')->get_table_name(); + + // Select + $select = array( + 'review.*', + 'book.id as book_id', + 'book.cover_id as book_cover_id', + 'book.title as book_title', + 'book.pub_date as book_pub_date', + 'book.series_position as series_position', + "GROUP_CONCAT( DISTINCT author.id SEPARATOR ',' ) as author_id", + "GROUP_CONCAT( DISTINCT author.name SEPARATOR ',' ) as author_name", + 'series.id as series_id', + 'series.name as series_name', + 'log.date_started as date_started_reading', + 'log.date_finished as date_finished_reading', + 'log.percentage_complete as percentage_complete', + 'log.rating as rating', + ); + + // Book Join + $join['book_query'] = "LEFT JOIN {$tbl_books} AS book ON review.book_id = book.id"; + + // Author Join + $join['author_query'] = "LEFT JOIN {$tbl_author_r} AS ar ON review.book_id = ar.book_id LEFT JOIN {$tbl_author} AS author ON ar.author_id = author.id"; + + // Series Join + $join['series_query'] = "LEFT JOIN {$tbl_series} AS series ON book.series_id = series.id"; + + // Reading Log Join + $join['reading_log_query'] = "LEFT JOIN {$tbl_log} AS log ON log.id = review.reading_log_id"; + + /** + * Where + */ + + // Author query + if (! empty($args['author_query'])) { + $clause_engine->set_table_query(new AuthorsQuery()); + $clause_engine->set_args($args['author_query']); + $where = array_merge($where, $clause_engine->get_clauses()); + } + + // Book query + if (! empty($args['book_query'])) { + $clause_engine->set_table_query(new BooksQuery()); + $clause_engine->set_args($args['book_query']); + $where = array_merge($where, $clause_engine->get_clauses()); + } + + // Edition query + if (! empty($args['edition_query'])) { + $join['edition_query'] = "INNER JOIN {$tbl_ed} AS ed ON (review.book_id = ed.book_id)"; + $clause_engine->set_table_query(new EditionsQuery()); + $clause_engine->set_args($args['edition_query']); + $where = array_merge($where, $clause_engine->get_clauses()); + } + + // Reading log query + if (! empty($args['reading_log_query'])) { + $clause_engine->set_table_query(new ReadingLogsQuery()); + $clause_engine->set_args($args['reading_log_query']); + $where = array_merge($where, $clause_engine->get_clauses()); + } + + // Review query + if (! empty($args['review_query'])) { + $clause_engine->set_table_query($this); + $clause_engine->set_args($args['review_query']); + $where = array_merge($where, $clause_engine->get_clauses()); + } + + // Series query + if (! empty($args['series_query'])) { + $clause_engine->set_table_query(new SeriesQuery()); + $clause_engine->set_args($args['series_query']); + $where = array_merge($where, $clause_engine->get_clauses()); + } + + // Tax query + if (! empty($args['tax_query'])) { + $tax_query = new Tax($args['tax_query']); + $clauses = $tax_query->get_sql($this->table_alias, 'book_id'); + $join['tax_query'] = $clauses['join']; + $where['tax_query'] = preg_replace('/^\s*AND\s*/', '', $clauses['where']); + } + + /** + * Format and query + */ + $select = implode(', ', $select); + $join = implode(' ', $join); + $where = ! empty($where) ? 'WHERE '.implode(' AND ', $where) : ''; + + /** + * Validate the orderby / order + */ + $orderby = $this->validate_orderby($args['orderby'], $args); + $order = 'ASC' === strtoupper($args['order']) ? 'ASC' : 'DESC'; + + $group_by = 'GROUP BY review.id'; + + // Override select if we're counting. + if (! empty($args['count'])) { + $select = 'COUNT( DISTINCT review.id )'; + $group_by = ''; + } + + if (! empty($args['count'])) { + $query = "SELECT {$select} FROM {$tbl_reviews} AS review {$join} {$where}"; + + $reviews = $this->get_db()->get_var($query); + + return absint($reviews); + } + + $query = $this->get_db()->prepare("SELECT {$select} FROM {$tbl_reviews} AS review {$join} {$where} {$group_by} ORDER BY $orderby $order LIMIT %d,%d;", + absint($args['offset']), absint($args['number'])); + + $reviews = $this->get_db()->get_results($query); + + return wp_unslash($reviews); + + } + + /** + * Validate the orderby + * + * @param string $orderby Desired orderby. + * @param array $args Query arguments. + * + * @return string + */ + protected function validate_orderby($orderby, $args = array()) + { + + $valid_orderbys = array( + 'review.id', + 'review.book_id', + 'review.reading_log_id', + 'review.user_id', + 'review.post_id', + 'review.date_written', + 'review.date_published', + 'review.date_created', + 'review.date_modified', + 'author.id', + 'author.name', + 'author.slug', + 'book.id', + 'book.title', + 'book.index_title', + 'book.series_id', + 'book.series_position', + 'book.pub_date', + 'book.pages', + 'book.date_created', + 'book.date_modified', + 'series.id', + 'series.name', + 'series.slug', + 'series.number_books', + 'series.date_created', + 'log.id', + 'log.user_id', + 'log.date_started', + 'log.date_finished', + 'log.percentage_complete', + 'log.rating' + ); + + return in_array($orderby, $valid_orderbys) ? $orderby : 'review.id'; + + } + +} diff --git a/src/Database/Reviews/ReviewsSchema.php b/src/Database/Reviews/ReviewsSchema.php new file mode 100644 index 00000000..f0bd4d72 --- /dev/null +++ b/src/Database/Reviews/ReviewsSchema.php @@ -0,0 +1,141 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true + ), + + // book_id + array( + 'name' => 'book_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'validate' => 'absint' + ), + + // reading_log_id + array( + 'name' => 'reading_log_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'allow_null' => true, + 'default' => null, + 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' + ), + + // user_id + array( + 'name' => 'user_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'validate' => 'absint' + ), + + // post_id + array( + 'name' => 'post_id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true, + 'allow_null' => true, + 'default' => null, + 'validate' => '\Book_Database\BerlinDB\Sanitization\absint_allow_null' + ), + + // url + array( + 'name' => 'url', + 'type' => 'mediumtext', + 'default' => '', + 'validate' => 'sanitize_text_field' + ), + + // review + array( + 'name' => 'review', + 'type' => 'longtext', + 'validate' => 'wp_kses_post' + ), + + // date_written + array( + 'name' => 'date_written', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'sortable' => true, + 'date_query' => true + ), + + // date_published + array( + 'name' => 'date_published', + 'type' => 'datetime', + 'sortable' => true, + 'date_query' => true, + 'allow_null' => true, + 'default' => null, + ), + + // date_created + array( + 'name' => 'date_created', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ), + + // date_modified + array( + 'name' => 'date_modified', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'modified' => true, + 'date_query' => true, + 'sortable' => true, + ), + + ); + +} diff --git a/src/Database/Reviews/ReviewsTable.php b/src/Database/Reviews/ReviewsTable.php new file mode 100644 index 00000000..e2d605a3 --- /dev/null +++ b/src/Database/Reviews/ReviewsTable.php @@ -0,0 +1,232 @@ + 201910181, + '201910182' => 201910182, + '201910183' => 201910183, + '201910184' => 201910184, + '201910185' => 201910185, + '201910261' => 201910261, + '201910301' => 201910301 + ); + + /** + * Reviews_Table constructor. + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Set up the database schema + */ + protected function set_schema() + { + $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, + reading_log_id bigint(20) UNSIGNED DEFAULT NULL, + user_id bigint(20) UNSIGNED NOT NULL DEFAULT 0, + post_id bigint(20) UNSIGNED DEFAULT NULL, + url mediumtext NOT NULL DEFAULT '', + review longtext NOT NULL DEFAULT '', + date_written datetime NOT NULL, + date_published datetime DEFAULT NULL, + date_created datetime NOT NULL, + date_modified datetime NOT NULL, + INDEX book_id (book_id), + INDEX date_written_book_id (date_written, book_id), + INDEX date_written_id (date_written, id), + INDEX post_id (post_id), + INDEX user_id (user_id)"; + } + + /** + * If the old `wp_bdb_reviews_db_version` option exists, copy that value to our new version key. + * This will ensure new upgrades are processed on old installs. + */ + public function maybe_upgrade() + { + + $old_key = $this->get_db()->prefix.'bdb_reviews_db_version'; + $old_version = get_option($old_key); + + if (false !== $old_version) { + update_option($this->db_version_key, get_option($old_key)); + + delete_option($old_key); + } + + return parent::maybe_upgrade(); + } + + /** + * Upgrade to version 201910181 + * - Drop the `date_written_ID` index + * + * @return bool + */ + protected function __201910181() + { + + if ($this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'date_written_ID'")) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} DROP INDEX date_written_ID"); + } else { + $result = true; + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910182 + * - Rename `ID` to `id` & add `unsigned` + * + * @return bool + */ + protected function __201910182() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `ID` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT"); + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910183 + * - Add a new `date_written_id` index + * + * @return bool + */ + protected function __201910183() + { + + $result = $this->get_db()->query("SHOW INDEX FROM {$this->table_name} WHERE Key_name = 'date_written_id'"); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD INDEX date_written_id (date_written, id)"); + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910184 + * - Add `date_created` column + * - Add `date_modified` column + * + * @return bool + */ + protected function __201910184() + { + + $result = $this->column_exists('date_created'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + $result = $this->column_exists('date_modified'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910185 + * - Change `book_id` column - add `unsigned` + * - Change `post_id` column - add `unsigned` and allow null + * - Change `user_id` column - add `unsigned` + * + * @return bool + */ + protected function __201910185() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} MODIFY book_id bigint(20) UNSIGNED NOT NULL DEFAULT 0"); + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} MODIFY post_id bigint(20) UNSIGNED DEFAULT NULL"); + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} MODIFY user_id bigint(20) UNSIGNED NOT NULL DEFAULT 0 AFTER book_id"); + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910261 + * - Drop column `rating` + * + * @return bool + */ + protected function __201910261() + { + + if ($this->column_exists('rating')) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} DROP COLUMN `rating`"); + } else { + $result = true; + } + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910301 + * - Add `reading_log_id` column + * + * @return bool + */ + protected function __201910301() + { + + $result = $this->column_exists('reading_log_id'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN reading_log_id bigint(20) UNSIGNED DEFAULT NULL AFTER book_id"); + } + + return $this->is_success($result); + + } + +} diff --git a/src/Database/Series/SeriesQuery.php b/src/Database/Series/SeriesQuery.php new file mode 100644 index 00000000..a159871a --- /dev/null +++ b/src/Database/Series/SeriesQuery.php @@ -0,0 +1,83 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true + ), + + // name + array( + 'name' => 'name', + 'type' => 'varchar', + 'length' => '200', + 'sortable' => true, + 'searchable' => true, + 'validate' => 'sanitize_text_field' + ), + + // slug + array( + 'name' => 'slug', + 'type' => 'varchar', + 'length' => '200', + 'sortable' => true, + 'searchable' => true, + 'validate' => 'sanitize_key' + ), + + // description + array( + 'name' => 'description', + 'type' => 'longtext', + 'validate' => 'wp_kses_post' + ), + + // number_books + array( + 'name' => 'number_books', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'sortable' => true + ), + + // date_created + array( + 'name' => 'date_created', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ), + + // date_modified + array( + 'name' => 'date_modified', + 'type' => 'datetime', + 'default' => '', // True default is current time, set in query class + 'modified' => true, + 'date_query' => true, + 'sortable' => true, + ), + + ); + +} diff --git a/src/Database/Series/SeriesTable.php b/src/Database/Series/SeriesTable.php new file mode 100644 index 00000000..34d1fdf1 --- /dev/null +++ b/src/Database/Series/SeriesTable.php @@ -0,0 +1,141 @@ + 201910122, + '201910123' => 201910123, + '201910124' => 201910124 + ); + + /** + * Series_Table constructor. + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Set up the database schema + */ + protected function set_schema() + { + $this->schema = "id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + name varchar(200) NOT NULL DEFAULT '', + slug varchar(200) NOT NULL DEFAULT '', + description longtext NOT NULL DEFAULT '', + number_books bigint(20) UNSIGNED NOT NULL DEFAULT 0, + date_created datetime NOT NULL, + date_modified datetime NOT NULL, + INDEX name (name)"; + } + + /** + * If the old `wp_bdb_series_db_version` option exists, copy that value to our new version key. + * This will ensure new upgrades are processed on old installs. + */ + public function maybe_upgrade() + { + + $old_key = $this->get_db()->prefix.'bdb_series_db_version'; + $old_version = get_option($old_key); + + if (false !== $old_version) { + update_option($this->db_version_key, get_option($old_key)); + + delete_option($old_key); + } + + return parent::maybe_upgrade(); + + } + + /** + * Upgrade to version 201910122 + * - Rename `ID` to `id` & add `unsigned` + * + * @return bool + */ + protected function __201910122() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} CHANGE `ID` `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT"); + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910123 + * - Add `unsigned` to `number_books` + * + * @return bool + */ + protected function __201910123() + { + + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} MODIFY number_books bigint(20) UNSIGNED NOT NULL DEFAULT 0"); + + return $this->is_success($result); + + } + + /** + * Upgrade to version 201910124 + * - Add `date_created` column + * - Add `date_modified` column + * + * @return bool + */ + protected function __201910124() + { + + $result = $this->column_exists('date_created'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + $result = $this->column_exists('date_modified'); + + if (! $result) { + $result = $this->get_db()->query("ALTER TABLE {$this->table_name} ADD COLUMN date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"); + } + + return $result; + + } + +} diff --git a/src/Plugin.php b/src/Plugin.php index e4294aaf..39a7acc2 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -21,6 +21,11 @@ use Book_Database\Database\BookTerm\BookTermRelationshipsTable; use Book_Database\Database\BookTerms\BookTermsTable; use Book_Database\Database\Editions\EditionsTable; +use Book_Database\Database\ReadingLogs\ReadingLogsTable; +use Book_Database\Database\Retailers\RetailersTable; +use Book_Database\Database\Reviews\ReviewMetaTable; +use Book_Database\Database\Reviews\ReviewsTable; +use Book_Database\Database\Series\SeriesTable; use Book_Database\ServiceProviders\LegacyServiceProvider; use Book_Database\ServiceProviders\ServiceProvider; @@ -144,11 +149,11 @@ private function setup_application() 'books' => new BooksTable(), 'book_meta' => new BookMetaTable(), 'editions' => new EditionsTable(), - 'reading_log' => new Reading_Logs_Table(), - 'retailers' => new Retailers_Table(), - 'reviews' => new Reviews_Table(), - 'review_meta' => new Review_Meta_Table(), - 'series' => new Series_Table(), + 'reading_log' => new ReadingLogsTable(), + 'retailers' => new RetailersTable(), + 'reviews' => new ReviewsTable(), + 'review_meta' => new ReviewMetaTable(), + 'series' => new SeriesTable(), ); } diff --git a/src/ServiceProviders/LegacyServiceProvider.php b/src/ServiceProviders/LegacyServiceProvider.php index 00e1b2c6..31e721c2 100644 --- a/src/ServiceProviders/LegacyServiceProvider.php +++ b/src/ServiceProviders/LegacyServiceProvider.php @@ -34,6 +34,19 @@ use Book_Database\Database\Editions\EditionsQuery; use Book_Database\Database\Editions\EditionsSchema; use Book_Database\Database\Editions\EditionsTable; +use Book_Database\Database\ReadingLogs\ReadingLogsQuery; +use Book_Database\Database\ReadingLogs\ReadingLogsSchema; +use Book_Database\Database\ReadingLogs\ReadingLogsTable; +use Book_Database\Database\Retailers\RetailersQuery; +use Book_Database\Database\Retailers\RetailersSchema; +use Book_Database\Database\Retailers\RetailersTable; +use Book_Database\Database\Reviews\ReviewMetaTable; +use Book_Database\Database\Reviews\ReviewsQuery; +use Book_Database\Database\Reviews\ReviewsSchema; +use Book_Database\Database\Reviews\ReviewsTable; +use Book_Database\Database\Series\SeriesQuery; +use Book_Database\Database\Series\SeriesSchema; +use Book_Database\Database\Series\SeriesTable; use Book_Database\HTML; use Book_Database\Plugin; use Book_Database\REST_API; @@ -82,22 +95,6 @@ private function includeLegacyFiles(): void require_once BDB_DIR.'includes/database/engine/class-where-clause.php'; require_once BDB_DIR.'includes/database/sanitization.php'; - // Database - reading_log - require_once BDB_DIR.'includes/database/reading-logs/class-reading-logs-table.php'; - require_once BDB_DIR.'includes/database/reading-logs/class-reading-logs-schema.php'; - require_once BDB_DIR.'includes/database/reading-logs/class-reading-logs-query.php'; - - // Database - retailers - require_once BDB_DIR.'includes/database/retailers/class-retailers-table.php'; - require_once BDB_DIR.'includes/database/retailers/class-retailers-schema.php'; - require_once BDB_DIR.'includes/database/retailers/class-retailers-query.php'; - - // Database - reviews - require_once BDB_DIR.'includes/database/reviews/class-reviews-table.php'; - require_once BDB_DIR.'includes/database/reviews/class-reviews-schema.php'; - require_once BDB_DIR.'includes/database/reviews/class-reviews-query.php'; - require_once BDB_DIR.'includes/database/reviews/class-review-meta-table.php'; - // Database - series require_once BDB_DIR.'includes/database/series/class-series-table.php'; require_once BDB_DIR.'includes/database/series/class-series-schema.php'; @@ -272,6 +269,23 @@ class_alias(BooksTable::class, 'Book_Database\\Books_Table'); class_alias(EditionsQuery::class, 'Book_Database\Editions_Query'); class_alias(EditionsSchema::class, 'Book_Database\\Editions_Schema'); class_alias(EditionsTable::class, 'Book_Database\\Editions_Table'); + + class_alias(ReadingLogsQuery::class, 'Book_Database\\Reading_Logs_Query'); + class_alias(ReadingLogsSchema::class, 'Book_Database\\Reading_Logs_Schema'); + class_alias(ReadingLogsTable::class, 'Book_Database\\Reading_Logs_Table'); + + class_alias(RetailersQuery::class, 'Book_Database\\Retailers_Query'); + class_alias(RetailersSchema::class, 'Book_Database\\Retailers_Schema'); + class_alias(RetailersTable::class, 'Book_Database\\Retailers_Table'); + + class_alias(ReviewMetaTable::class, 'Book_Database\\Review_Meta_Table'); + class_alias(ReviewsQuery::class, 'Book_Database\\Reviews_Query'); + class_alias(ReviewsSchema::class, 'Book_Database\\Reviews_Schema'); + class_alias(ReviewsTable::class, 'Book_Database\\Reviews_Table'); + + class_alias(SeriesQuery::class, 'Book_Database\\Series_Query'); + class_alias(SeriesSchema::class, 'Book_Database\\Series_Schema'); + class_alias(SeriesTable::class, 'Book_Database\\Series_Table'); } private function bindClasses(): void diff --git a/src/Widgets/Reviews.php b/src/Widgets/Reviews.php index 99e1814a..80f736bc 100644 --- a/src/Widgets/Reviews.php +++ b/src/Widgets/Reviews.php @@ -13,7 +13,7 @@ use Book_Database\Book; use Book_Database\Rating; use Book_Database\Review; -use Book_Database\Reviews_Query; +use Book_Database\Database\Reviews\ReviewsQuery; /** * Class Reviews @@ -105,7 +105,7 @@ protected function query_reviews( $args ) { ); } - $query = new Reviews_Query(); + $query = new ReviewsQuery(); return $query->get_reviews( $query_args ); From 33bc778629747d796c74164ce760bec229e8a3ce Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 20 Nov 2021 16:37:57 +0000 Subject: [PATCH 09/29] More file renaming. #248 --- composer.json | 5 +- includes/admin/abstract-class-list-table.php | 6 +- includes/admin/authors/author-actions.php | 4 +- .../authors/class-authors-list-table.php | 6 +- includes/admin/authors/edit-author.php | 4 +- .../admin/book-terms/book-term-actions.php | 4 +- .../class-book-terms-list-table.php | 13 +- includes/admin/books/book-actions.php | 5 +- .../admin/books/class-books-list-table.php | 2 + .../books/class-monthly-books-list-table.php | 5 +- includes/admin/books/edit-book-fields.php | 8 +- includes/admin/books/edit-book.php | 6 +- includes/admin/editions/edition-actions.php | 4 +- .../admin/licensing/class-license-key.php | 5 +- includes/admin/licensing/license-actions.php | 4 +- .../reading-logs/reading-log-actions.php | 4 +- .../reviews/class-reviews-list-table.php | 4 + includes/admin/reviews/edit-review.php | 6 +- includes/admin/reviews/review-actions.php | 4 +- includes/admin/reviews/review-fields.php | 8 +- .../admin/series/class-series-list-table.php | 6 +- includes/admin/series/edit-series.php | 4 +- includes/admin/series/series-actions.php | 4 +- includes/analytics/analytics-functions.php | 2 +- includes/authors/author-functions.php | 2 + .../book-author-relationship-functions.php | 11 +- includes/book-links/book-link-functions.php | 8 +- .../book-taxonomy-functions.php | 8 +- .../book-term-relationship-functions.php | 15 +- includes/book-terms/book-term-functions.php | 10 +- includes/books/book-functions.php | 2 + includes/editions/edition-functions.php | 2 + includes/misc-functions.php | 13 +- .../reading-logs/reading-log-functions.php | 8 +- includes/retailers/retailer-functions.php | 2 + includes/reviews/review-actions.php | 4 +- includes/reviews/review-functions.php | 2 + includes/series/series-functions.php | 2 + includes/shortcodes.php | 17 +- src/Analytics.php | 685 ------------------ src/Analytics/Analytics.php | 677 +++++++++++++++++ .../Datasets/Highest_Rated_Books.php | 2 +- src/Analytics/Datasets/Lowest_Rated_Books.php | 2 +- src/Analytics/Datasets/Reviews_Written.php | 2 +- src/Analytics/Datasets/Shortest_Book_Read.php | 2 +- src/Analytics/Datasets/Terms_Breakdown.php | 2 +- src/Author.php | 125 ---- src/Base_Object.php | 104 --- src/Book.php | 351 --------- src/Book_Author_Relationship.php | 40 - src/Book_Layout.php | 14 +- src/Book_Link.php | 86 --- src/Book_Taxonomy.php | 51 -- src/Book_Term.php | 95 --- src/Book_Term_Relationship.php | 40 - src/CLI.php | 4 + src/Database/Authors/AuthorsQuery.php | 2 +- src/Database/BookAuthor/BookAuthorQuery.php | 4 +- src/Database/BookLinks/BookLinksQuery.php | 4 +- .../BookTaxonomies/BookTaxonomiesQuery.php | 4 +- .../BookTerm/BookTermRelationshipQuery.php | 4 +- src/Database/BookTerms/BookTermsQuery.php | 4 +- src/Database/Books/BooksQuery.php | 2 +- src/Database/Editions/EditionsQuery.php | 2 +- src/Database/ReadingLogs/ReadingLogsQuery.php | 4 +- src/Database/Retailers/RetailersQuery.php | 2 +- src/Database/Reviews/ReviewsQuery.php | 2 +- src/Database/Series/SeriesQuery.php | 2 +- src/Deprecated/class-names.php | 47 -- src/Edition.php | 107 --- src/Exception.php | 45 -- src/Exceptions/Exception.php | 48 ++ src/HTML.php | 127 ---- src/Helpers/HTML.php | 141 ++++ src/Helpers/Hooks.php | 89 +++ src/Models/Author.php | 138 ++++ src/Models/Book.php | 375 ++++++++++ src/Models/BookAuthorRelationship.php | 45 ++ src/Models/BookLink.php | 94 +++ src/Models/BookTaxonomy.php | 57 ++ src/Models/BookTerm.php | 108 +++ src/Models/BookTermRelationship.php | 45 ++ src/Models/Edition.php | 123 ++++ src/Models/Model.php | 119 +++ src/Models/ReadingLog.php | 189 +++++ src/Models/Retailer.php | 75 ++ src/Models/Review.php | 233 ++++++ src/Models/Series.php | 146 ++++ src/Plugin.php | 4 + src/REST_API.php | 55 -- src/REST_API/RouteRegistration.php | 53 ++ src/REST_API/v1/Analytics.php | 4 +- src/REST_API/v1/Author.php | 2 +- src/REST_API/v1/Book.php | 2 +- src/REST_API/v1/Book_Link.php | 2 +- src/REST_API/v1/Book_Term.php | 2 +- src/REST_API/v1/Edition.php | 10 +- src/REST_API/v1/Reading_Log.php | 6 +- src/REST_API/v1/Retailer.php | 2 +- src/REST_API/v1/Review.php | 4 +- src/REST_API/v1/Series.php | 6 +- src/REST_API/v1/Taxonomy.php | 2 +- src/REST_API/v1/Utility.php | 2 +- src/Rating.php | 286 -------- src/Reading_Log.php | 166 ----- src/Retailer.php | 67 -- src/Review.php | 217 ------ src/Series.php | 138 ---- src/ServiceProviders/ApiServiceProvider.php | 27 + .../LegacyServiceProvider.php | 92 ++- src/ValueObjects/Rating.php | 289 ++++++++ src/Widgets/Reading_Log.php | 14 +- src/Widgets/Reviews.php | 6 +- templates/shortcode-book-grid-entry.php | 4 + templates/shortcode-book-reviews-entry.php | 7 +- tests/books/test-book-functions.php | 14 +- tests/books/test-book-object.php | 4 +- .../phpunit/factories/class-book-factory.php | 6 +- .../factories/class-series-factory.php | 6 +- tests/series/test-series-functions.php | 10 +- 120 files changed, 3418 insertions(+), 2989 deletions(-) delete mode 100644 src/Analytics.php create mode 100644 src/Analytics/Analytics.php delete mode 100644 src/Author.php delete mode 100644 src/Base_Object.php delete mode 100644 src/Book.php delete mode 100644 src/Book_Author_Relationship.php delete mode 100644 src/Book_Link.php delete mode 100644 src/Book_Taxonomy.php delete mode 100644 src/Book_Term.php delete mode 100644 src/Book_Term_Relationship.php delete mode 100644 src/Deprecated/class-names.php delete mode 100644 src/Edition.php delete mode 100644 src/Exception.php create mode 100644 src/Exceptions/Exception.php delete mode 100644 src/HTML.php create mode 100644 src/Helpers/HTML.php create mode 100644 src/Helpers/Hooks.php create mode 100644 src/Models/Author.php create mode 100644 src/Models/Book.php create mode 100644 src/Models/BookAuthorRelationship.php create mode 100644 src/Models/BookLink.php create mode 100644 src/Models/BookTaxonomy.php create mode 100644 src/Models/BookTerm.php create mode 100644 src/Models/BookTermRelationship.php create mode 100644 src/Models/Edition.php create mode 100644 src/Models/Model.php create mode 100644 src/Models/ReadingLog.php create mode 100644 src/Models/Retailer.php create mode 100644 src/Models/Review.php create mode 100644 src/Models/Series.php delete mode 100644 src/REST_API.php create mode 100644 src/REST_API/RouteRegistration.php delete mode 100644 src/Rating.php delete mode 100644 src/Reading_Log.php delete mode 100644 src/Retailer.php delete mode 100644 src/Review.php delete mode 100644 src/Series.php create mode 100644 src/ServiceProviders/ApiServiceProvider.php create mode 100644 src/ValueObjects/Rating.php diff --git a/composer.json b/composer.json index 7672405a..172cc046 100644 --- a/composer.json +++ b/composer.json @@ -4,14 +4,11 @@ "license": "GPL-2.0-or-later", "description": "Maintain a database of books and reviews.", "autoload": { - "files": [ - "src/Deprecated/class-names.php" - ], "psr-4": { "Book_Database\\": "src/" } }, "require": { - "php": "^7.0|^8.0" + "php": "^7.1|^8.0" } } diff --git a/includes/admin/abstract-class-list-table.php b/includes/admin/abstract-class-list-table.php index 1dd074e8..321600a0 100644 --- a/includes/admin/abstract-class-list-table.php +++ b/includes/admin/abstract-class-list-table.php @@ -10,6 +10,8 @@ namespace Book_Database; // Load WP_List_Table if not loaded +use Book_Database\Models\Model; + if ( ! class_exists( '\WP_List_Table' ) ) { require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; } @@ -258,7 +260,7 @@ public function get_views() { /** * Render the checkbox column. * - * @param Base_Object $object + * @param Model $object * * @return string */ @@ -327,4 +329,4 @@ public function prepare_items() { public function process_bulk_actions() { } -} \ No newline at end of file +} diff --git a/includes/admin/authors/author-actions.php b/includes/admin/authors/author-actions.php index cc806ef7..f7a8ef60 100644 --- a/includes/admin/authors/author-actions.php +++ b/includes/admin/authors/author-actions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Exceptions\Exception; + /** * Add a new author */ @@ -135,4 +137,4 @@ function process_delete_author() { } -add_action( 'admin_init', __NAMESPACE__ . '\process_delete_author' ); \ No newline at end of file +add_action( 'admin_init', __NAMESPACE__ . '\process_delete_author' ); diff --git a/includes/admin/authors/class-authors-list-table.php b/includes/admin/authors/class-authors-list-table.php index 8defdef2..7b1c15e7 100644 --- a/includes/admin/authors/class-authors-list-table.php +++ b/includes/admin/authors/class-authors-list-table.php @@ -9,8 +9,12 @@ namespace Book_Database; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\Author; + /** * Class Authors_List_Table + * * @package Book_Database */ class Authors_List_Table extends List_Table { @@ -271,4 +275,4 @@ private function show_admin_notice( $action, $number = 1, $class = 'success' ) { } -} \ No newline at end of file +} diff --git a/includes/admin/authors/edit-author.php b/includes/admin/authors/edit-author.php index dbd700b9..71b266ae 100644 --- a/includes/admin/authors/edit-author.php +++ b/includes/admin/authors/edit-author.php @@ -9,7 +9,9 @@ namespace Book_Database; -$author = ! empty( $_GET['author_id'] ) ? get_book_author( absint( $_GET['author_id'] ) ) : false; +use Book_Database\Models\Author; + +$author = ! empty($_GET['author_id'] ) ? get_book_author( absint($_GET['author_id'] ) ) : false; if ( ! empty( $_GET['view'] ) && 'edit' === $_GET['view'] && empty( $author ) ) { wp_die( __( 'Invalid author ID.', 'book-database' ) ); diff --git a/includes/admin/book-terms/book-term-actions.php b/includes/admin/book-terms/book-term-actions.php index a31ac02e..d810e1ca 100644 --- a/includes/admin/book-terms/book-term-actions.php +++ b/includes/admin/book-terms/book-term-actions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Exceptions\Exception; + /** * Add a new book_term */ @@ -137,4 +139,4 @@ function process_delete_book_term() { } -add_action( 'admin_init', __NAMESPACE__ . '\process_delete_book_term' ); \ No newline at end of file +add_action( 'admin_init', __NAMESPACE__ . '\process_delete_book_term' ); diff --git a/includes/admin/book-terms/class-book-terms-list-table.php b/includes/admin/book-terms/class-book-terms-list-table.php index d587ccf4..24ea75b2 100644 --- a/includes/admin/book-terms/class-book-terms-list-table.php +++ b/includes/admin/book-terms/class-book-terms-list-table.php @@ -9,8 +9,13 @@ namespace Book_Database; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\BookTaxonomy; +use Book_Database\Models\BookTerm; + /** * Class Book_Terms_List_Table + * * @package Book_Database */ class Book_Terms_List_Table extends List_Table { @@ -128,7 +133,7 @@ protected function get_primary_column_name() { /** * Render the "Name" column. * - * @param Book_Term $item + * @param BookTerm $item * * @return string */ @@ -156,7 +161,7 @@ public function column_name( $item ) { /** * Renders most of the columns in the list table * - * @param Book_Term $item + * @param BookTerm $item * @param string $column_name * * @return string Column value. @@ -340,7 +345,7 @@ public function get_views() { foreach ( $counts as $status => $count ) { $taxonomy = get_book_taxonomy_by( 'slug', $status ); - if ( ! $taxonomy instanceof Book_Taxonomy ) { + if ( ! $taxonomy instanceof BookTaxonomy ) { continue; } @@ -361,4 +366,4 @@ public function get_views() { return $views; } -} \ No newline at end of file +} diff --git a/includes/admin/books/book-actions.php b/includes/admin/books/book-actions.php index 5baac8a5..f4ea59cb 100644 --- a/includes/admin/books/book-actions.php +++ b/includes/admin/books/book-actions.php @@ -9,6 +9,9 @@ namespace Book_Database; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\Series; + /** * Add a new book */ @@ -253,4 +256,4 @@ function process_delete_book() { } -add_action( 'admin_init', __NAMESPACE__ . '\process_delete_book' ); \ No newline at end of file +add_action( 'admin_init', __NAMESPACE__ . '\process_delete_book' ); diff --git a/includes/admin/books/class-books-list-table.php b/includes/admin/books/class-books-list-table.php index af394104..6f0c1321 100644 --- a/includes/admin/books/class-books-list-table.php +++ b/includes/admin/books/class-books-list-table.php @@ -10,6 +10,8 @@ namespace Book_Database; use Book_Database\Database\Books\BooksQuery; +use Book_Database\Models\Book; +use Book_Database\ValueObjects\Rating; /** * Class Books_List_Table diff --git a/includes/admin/books/class-monthly-books-list-table.php b/includes/admin/books/class-monthly-books-list-table.php index d1aa3d97..86aed68b 100644 --- a/includes/admin/books/class-monthly-books-list-table.php +++ b/includes/admin/books/class-monthly-books-list-table.php @@ -9,8 +9,11 @@ namespace Book_Database; +use Book_Database\Models\Book; + /** * Class Monthly_Books_List_Table + * * @package Book_Database */ class Monthly_Books_List_Table extends Books_List_Table { @@ -747,4 +750,4 @@ protected function set_queried_item( $iterator = 1, $type = 'items', $item_id = public function no_items() { // Do nothing; calendars always have rows } -} \ No newline at end of file +} diff --git a/includes/admin/books/edit-book-fields.php b/includes/admin/books/edit-book-fields.php index b9205fe5..77a79ee3 100644 --- a/includes/admin/books/edit-book-fields.php +++ b/includes/admin/books/edit-book-fields.php @@ -9,9 +9,9 @@ namespace Book_Database\Admin\Fields; -use Book_Database\Book; -use Book_Database\Rating; -use Book_Database\Series; +use Book_Database\Models\Book; +use Book_Database\ValueObjects\Rating; +use Book_Database\Models\Series; use function Book_Database\book_database; use function Book_Database\count_books; use function Book_Database\generate_book_index_title; @@ -537,4 +537,4 @@ function books_in_series( $book ) { } -add_action( 'book-database/book-edit/after-save-box', __NAMESPACE__ . '\books_in_series' ); \ No newline at end of file +add_action( 'book-database/book-edit/after-save-box', __NAMESPACE__ . '\books_in_series' ); diff --git a/includes/admin/books/edit-book.php b/includes/admin/books/edit-book.php index 9e521c07..50db21ce 100644 --- a/includes/admin/books/edit-book.php +++ b/includes/admin/books/edit-book.php @@ -9,7 +9,9 @@ namespace Book_Database; -$book = ! empty( $_GET['book_id'] ) ? get_book( absint( $_GET['book_id'] ) ) : false; +use Book_Database\Models\Book; + +$book = ! empty($_GET['book_id'] ) ? get_book( absint($_GET['book_id'] ) ) : false; if ( ! empty( $_GET['view'] ) && 'edit' === $_GET['view'] && empty( $book ) ) { wp_die( __( 'Invalid book ID.', 'book-database' ) ); @@ -70,4 +72,4 @@ wp_nonce_field( 'bdb_add_book', 'bdb_add_book_nonce' ); } ?> - \ No newline at end of file + diff --git a/includes/admin/editions/edition-actions.php b/includes/admin/editions/edition-actions.php index 81df9bac..ea949d1a 100644 --- a/includes/admin/editions/edition-actions.php +++ b/includes/admin/editions/edition-actions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Models\Book; + /** * Add a table of editions to the Edit Book page * @@ -141,4 +143,4 @@ function load_edition_templates() { } -add_action( 'admin_footer', __NAMESPACE__ . '\load_edition_templates' ); \ No newline at end of file +add_action( 'admin_footer', __NAMESPACE__ . '\load_edition_templates' ); diff --git a/includes/admin/licensing/class-license-key.php b/includes/admin/licensing/class-license-key.php index 1f6705cd..5d6618ab 100644 --- a/includes/admin/licensing/class-license-key.php +++ b/includes/admin/licensing/class-license-key.php @@ -9,8 +9,11 @@ namespace Book_Database; +use Book_Database\Exceptions\Exception; + /** * Class License_Key + * * @package Book_Database */ class License_Key { @@ -432,4 +435,4 @@ public function get_renewal_url() { return add_query_arg( 'edd_license_key', urlencode( $this->get_key() ), trailingslashit( NOSE_GRAZE_STORE_URL ) . 'checkout/' ); } -} \ No newline at end of file +} diff --git a/includes/admin/licensing/license-actions.php b/includes/admin/licensing/license-actions.php index afad1423..c29c934d 100644 --- a/includes/admin/licensing/license-actions.php +++ b/includes/admin/licensing/license-actions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Exceptions\Exception; + /** * Initialize the updater */ @@ -135,4 +137,4 @@ function refresh_license_key() { } -add_action( 'wp_ajax_bdb_refresh_license_key', __NAMESPACE__ . '\refresh_license_key' ); \ No newline at end of file +add_action( 'wp_ajax_bdb_refresh_license_key', __NAMESPACE__ . '\refresh_license_key' ); diff --git a/includes/admin/reading-logs/reading-log-actions.php b/includes/admin/reading-logs/reading-log-actions.php index b2bb7a49..a8c1cecf 100644 --- a/includes/admin/reading-logs/reading-log-actions.php +++ b/includes/admin/reading-logs/reading-log-actions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Models\Book; + /** * Add a table of reading logs to the Edit Book page * @@ -145,4 +147,4 @@ function load_reading_log_templates() { } -add_action( 'admin_footer', __NAMESPACE__ . '\load_reading_log_templates' ); \ No newline at end of file +add_action( 'admin_footer', __NAMESPACE__ . '\load_reading_log_templates' ); diff --git a/includes/admin/reviews/class-reviews-list-table.php b/includes/admin/reviews/class-reviews-list-table.php index 78ab871d..d6ede120 100644 --- a/includes/admin/reviews/class-reviews-list-table.php +++ b/includes/admin/reviews/class-reviews-list-table.php @@ -10,6 +10,10 @@ namespace Book_Database; use Book_Database\Database\Reviews\ReviewsQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\Book; +use Book_Database\Models\Review; +use Book_Database\ValueObjects\Rating; /** * Class Reviews_List_Table diff --git a/includes/admin/reviews/edit-review.php b/includes/admin/reviews/edit-review.php index 6e535272..306eca24 100644 --- a/includes/admin/reviews/edit-review.php +++ b/includes/admin/reviews/edit-review.php @@ -9,7 +9,9 @@ namespace Book_Database; -$review = ! empty( $_GET['review_id'] ) ? get_review( absint( $_GET['review_id'] ) ) : false; +use Book_Database\Models\Review; + +$review = ! empty($_GET['review_id'] ) ? get_review( absint($_GET['review_id'] ) ) : false; if ( ! empty( $_GET['view'] ) && 'edit' === $_GET['view'] && empty( $review ) ) { wp_die( __( 'Invalid review ID.', 'book-database' ) ); @@ -75,4 +77,4 @@ wp_nonce_field( 'bdb_add_review', 'bdb_add_review_nonce' ); } ?> - \ No newline at end of file + diff --git a/includes/admin/reviews/review-actions.php b/includes/admin/reviews/review-actions.php index 32b63232..74883736 100644 --- a/includes/admin/reviews/review-actions.php +++ b/includes/admin/reviews/review-actions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Exceptions\Exception; + /** * Add a new review */ @@ -145,4 +147,4 @@ function process_delete_review() { } -add_action( 'admin_init', __NAMESPACE__ . '\process_delete_review' ); \ No newline at end of file +add_action( 'admin_init', __NAMESPACE__ . '\process_delete_review' ); diff --git a/includes/admin/reviews/review-fields.php b/includes/admin/reviews/review-fields.php index 955c7c02..86d1e7a1 100644 --- a/includes/admin/reviews/review-fields.php +++ b/includes/admin/reviews/review-fields.php @@ -10,9 +10,9 @@ namespace Book_Database\Admin\Reviews\Fields; use Book_Database\Book_Layout; -use Book_Database\Rating; -use Book_Database\Reading_Log; -use Book_Database\Review; +use Book_Database\ValueObjects\Rating; +use Book_Database\Models\ReadingLog; +use Book_Database\Models\Review; use function Book_Database\book_database; use function Book_Database\get_book; use function Book_Database\get_books_admin_page_url; @@ -287,4 +287,4 @@ function book_info( $review ) { } -add_action( 'book-database/review-edit/after-fields', __NAMESPACE__ . '\book_info' ); \ No newline at end of file +add_action( 'book-database/review-edit/after-fields', __NAMESPACE__ . '\book_info' ); diff --git a/includes/admin/series/class-series-list-table.php b/includes/admin/series/class-series-list-table.php index 869587fd..d820ae2b 100644 --- a/includes/admin/series/class-series-list-table.php +++ b/includes/admin/series/class-series-list-table.php @@ -9,8 +9,12 @@ namespace Book_Database; +use Book_Database\Models\Series; +use Book_Database\ValueObjects\Rating; + /** * Class Series_List_Table + * * @package Book_Database */ class Series_List_Table extends List_Table { @@ -284,4 +288,4 @@ private function show_admin_notice( $action, $number = 1, $class = 'success' ) { } -} \ No newline at end of file +} diff --git a/includes/admin/series/edit-series.php b/includes/admin/series/edit-series.php index 3b752f26..5f9fa832 100644 --- a/includes/admin/series/edit-series.php +++ b/includes/admin/series/edit-series.php @@ -9,7 +9,9 @@ namespace Book_Database; -$series = ! empty( $_GET['series_id'] ) ? get_book_series_by( 'id', absint( $_GET['series_id'] ) ) : false; +use Book_Database\Models\Series; + +$series = ! empty($_GET['series_id'] ) ? get_book_series_by( 'id', absint($_GET['series_id'] ) ) : false; if ( ! empty( $_GET['view'] ) && 'edit' === $_GET['view'] && empty( $series ) ) { wp_die( __( 'Invalid series ID.', 'book-database' ) ); diff --git a/includes/admin/series/series-actions.php b/includes/admin/series/series-actions.php index 2444d508..6ee74f72 100644 --- a/includes/admin/series/series-actions.php +++ b/includes/admin/series/series-actions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Exceptions\Exception; + /** * Add a new series */ @@ -135,4 +137,4 @@ function process_delete_series() { } -add_action( 'admin_init', __NAMESPACE__ . '\process_delete_series' ); \ No newline at end of file +add_action( 'admin_init', __NAMESPACE__ . '\process_delete_series' ); diff --git a/includes/analytics/analytics-functions.php b/includes/analytics/analytics-functions.php index 3f422cba..0fea188c 100644 --- a/includes/analytics/analytics-functions.php +++ b/includes/analytics/analytics-functions.php @@ -9,7 +9,7 @@ namespace Book_Database\Analytics; -use Book_Database\Exception; +use Book_Database\Exceptions\Exception; use function Book_Database\get_site_timezone; /** diff --git a/includes/authors/author-functions.php b/includes/authors/author-functions.php index 87502ceb..751bf7fc 100644 --- a/includes/authors/author-functions.php +++ b/includes/authors/author-functions.php @@ -10,6 +10,8 @@ namespace Book_Database; use Book_Database\Database\Authors\AuthorsQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\Author; /** * Get a single author by its ID diff --git a/includes/book-author-relationships/book-author-relationship-functions.php b/includes/book-author-relationships/book-author-relationship-functions.php index 044acd17..c64c703d 100644 --- a/includes/book-author-relationships/book-author-relationship-functions.php +++ b/includes/book-author-relationships/book-author-relationship-functions.php @@ -10,13 +10,16 @@ namespace Book_Database; use Book_Database\Database\BookAuthor\BookAuthorQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\Author; +use Book_Database\Models\BookAuthorRelationship; /** * Get a single book-author-relationship by its ID * * @param int $relationship_id * - * @return Book_Author_Relationship|false + * @return BookAuthorRelationship|false */ function get_book_author_relationship( $relationship_id ) { @@ -33,7 +36,7 @@ function get_book_author_relationship( $relationship_id ) { * @param int $author_id ID of the author. * @param array $args Query arguments to override the defaults. * - * @return Book_Author_Relationship|false|mixed + * @return BookAuthorRelationship|false|mixed */ function get_book_author_relationship_by_book_and_author( $book_id, $author_id, $args = array() ) { @@ -81,7 +84,7 @@ function get_book_author_relationship_by_book_and_author( $book_id, $author_id, * @type bool $update_cache Whether to prime the cache for found items. Default false. * } * - * @return Book_Author_Relationship[] Array of Book_Author_Relationship objects. + * @return BookAuthorRelationship[] Array of Book_Author_Relationship objects. */ function get_book_author_relationships( $args = array() ) { @@ -177,7 +180,7 @@ function delete_book_author_relationship( $relationship_id ) { $relationship = get_book_author_relationship( $relationship_id ); - if ( ! $relationship instanceof Book_Author_Relationship ) { + if ( ! $relationship instanceof BookAuthorRelationship ) { return true; } diff --git a/includes/book-links/book-link-functions.php b/includes/book-links/book-link-functions.php index e8959114..0bd2a5f8 100644 --- a/includes/book-links/book-link-functions.php +++ b/includes/book-links/book-link-functions.php @@ -10,13 +10,15 @@ namespace Book_Database; use Book_Database\Database\BookLinks\BookLinksQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\BookLink; /** * Get a single link by its ID * * @param int $link_id * - * @return Book_Link|false + * @return BookLink|false */ function get_book_link( $link_id ) { @@ -32,7 +34,7 @@ function get_book_link( $link_id ) { * @param string $column_name * @param mixed $column_value * - * @return Book_Link|false + * @return BookLink|false */ function get_book_link_by( $column_name, $column_value ) { @@ -70,7 +72,7 @@ function get_book_link_by( $column_name, $column_value ) { * @type bool $update_cache Whether to prime the cache for found items. Default false. * } * - * @return Book_Link[] Array of Book_Link objects. + * @return BookLink[] Array of Book_Link objects. */ function get_book_links( $args = array() ) { diff --git a/includes/book-taxonomies/book-taxonomy-functions.php b/includes/book-taxonomies/book-taxonomy-functions.php index 855571a0..b89b06ee 100644 --- a/includes/book-taxonomies/book-taxonomy-functions.php +++ b/includes/book-taxonomies/book-taxonomy-functions.php @@ -10,13 +10,15 @@ namespace Book_Database; use Book_Database\Database\BookTaxonomies\BookTaxonomiesQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\BookTaxonomy; /** * Get a single taxonomy by its ID * * @param int $taxonomy_id * - * @return Book_Taxonomy|false + * @return BookTaxonomy|false */ function get_book_taxonomy( $taxonomy_id ) { @@ -32,7 +34,7 @@ function get_book_taxonomy( $taxonomy_id ) { * @param string $column_name * @param mixed $column_value * - * @return Book_Taxonomy|false + * @return BookTaxonomy|false */ function get_book_taxonomy_by( $column_name, $column_value ) { @@ -74,7 +76,7 @@ function get_book_taxonomy_by( $column_name, $column_value ) { * @type bool $update_cache Whether to prime the cache for found items. Default false. * } * - * @return Book_Taxonomy[]|array Array of Book_Taxonomy objects. + * @return BookTaxonomy[]|array Array of Book_Taxonomy objects. */ function get_book_taxonomies( $args = array() ) { diff --git a/includes/book-term-relationships/book-term-relationship-functions.php b/includes/book-term-relationships/book-term-relationship-functions.php index cbc621a1..450f3848 100644 --- a/includes/book-term-relationships/book-term-relationship-functions.php +++ b/includes/book-term-relationships/book-term-relationship-functions.php @@ -10,13 +10,16 @@ namespace Book_Database; use Book_Database\Database\BookTerm\BookTermRelationshipQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\BookTerm; +use Book_Database\Models\BookTermRelationship; /** * Get a single book-term-relationship by its ID * * @param int $relationship_id * - * @return Book_Term_Relationship|false + * @return BookTermRelationship|false */ function get_book_term_relationship( $relationship_id ) { @@ -33,7 +36,7 @@ function get_book_term_relationship( $relationship_id ) { * @param int $term_id ID of the term. * @param array $args Query arguments to override the defaults. * - * @return Book_Term_Relationship|false|mixed + * @return BookTermRelationship|false|mixed */ function get_book_term_relationship_by_book_and_term( $book_id, $term_id, $args = array() ) { @@ -81,7 +84,7 @@ function get_book_term_relationship_by_book_and_term( $book_id, $term_id, $args * @type bool $update_cache Whether to prime the cache for found items. Default false. * } * - * @return Book_Term_Relationship[] Array of Book_Term_Relationship objects. + * @return BookTermRelationship[] Array of Book_Term_Relationship objects. */ function get_book_term_relationships( $args = array() ) { @@ -177,7 +180,7 @@ function delete_book_term_relationship( $relationship_id ) { $relationship = get_book_term_relationship( $relationship_id ); - if ( ! $relationship instanceof Book_Term_Relationship ) { + if ( ! $relationship instanceof BookTermRelationship ) { return true; } @@ -214,7 +217,7 @@ function delete_book_term_relationship( $relationship_id ) { * @type string $fields Column names to return. * } * - * @return Book_Term[]|array + * @return BookTerm[]|array */ function get_attached_book_terms( $book_id, $taxonomy, $args = array() ) { @@ -269,7 +272,7 @@ function get_attached_book_terms( $book_id, $taxonomy, $args = array() ) { if ( is_array( $objects ) ) { foreach ( $objects as $object ) { - $terms[] = new Book_Term( $object ); + $terms[] = new BookTerm( $object ); } } } elseif ( in_array( $args['fields'], array( 'id', 'ids', 'name', 'names' ) ) ) { diff --git a/includes/book-terms/book-term-functions.php b/includes/book-terms/book-term-functions.php index 379aa03f..fbeb65b4 100644 --- a/includes/book-terms/book-term-functions.php +++ b/includes/book-terms/book-term-functions.php @@ -10,13 +10,15 @@ namespace Book_Database; use Book_Database\Database\BookTerms\BookTermsQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\BookTerm; /** * Get a single book term by its ID * * @param int $term_id * - * @return Book_Term|false + * @return BookTerm|false */ function get_book_term( $term_id ) { @@ -32,7 +34,7 @@ function get_book_term( $term_id ) { * @param string $column_name * @param mixed $column_value * - * @return Book_Term|false + * @return BookTerm|false */ function get_book_term_by( $column_name, $column_value ) { @@ -48,7 +50,7 @@ function get_book_term_by( $column_name, $column_value ) { * @param string $term_name Term name. * @param string $taxonomy Taxonomy slug. * - * @return Book_Term|false + * @return BookTerm|false */ function get_book_term_by_name_and_taxonomy( $term_name, $taxonomy, $args = array() ) { @@ -101,7 +103,7 @@ function get_book_term_by_name_and_taxonomy( $term_name, $taxonomy, $args = arra * @type bool $update_cache Whether to prime the cache for found items. Default false. * } * - * @return Book_Term[] Array of Book_Term objects. + * @return BookTerm[] Array of Book_Term objects. */ function get_book_terms( $args = array() ) { diff --git a/includes/books/book-functions.php b/includes/books/book-functions.php index fc1cf7eb..65d4d199 100644 --- a/includes/books/book-functions.php +++ b/includes/books/book-functions.php @@ -10,6 +10,8 @@ namespace Book_Database; use Book_Database\Database\Books\BooksQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\Book; /** * Get a single book by its ID diff --git a/includes/editions/edition-functions.php b/includes/editions/edition-functions.php index 70582d4b..acf019b8 100644 --- a/includes/editions/edition-functions.php +++ b/includes/editions/edition-functions.php @@ -10,6 +10,8 @@ namespace Book_Database; use Book_Database\Database\Editions\EditionsQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\Edition; /** * Get a single edition by its ID diff --git a/includes/misc-functions.php b/includes/misc-functions.php index eff212a5..82c24a8c 100644 --- a/includes/misc-functions.php +++ b/includes/misc-functions.php @@ -9,6 +9,11 @@ namespace Book_Database; +use Book_Database\Models\Author; +use Book_Database\Models\BookTerm; +use Book_Database\Models\Series; +use Book_Database\ValueObjects\Rating; + /** * Get an array of all settings * @@ -148,7 +153,7 @@ function link_book_terms() { /** * Get the term archive link * - * @param Author|Book_Term|Series|Rating $term + * @param Author|BookTerm|Series|Rating $term * * @return bool */ @@ -163,7 +168,7 @@ function get_book_term_link( $term ) { if ( $term instanceof Author ) { $taxonomy = 'author'; - } elseif ( $term instanceof Book_Term ) { + } elseif ( $term instanceof BookTerm ) { $taxonomy = $term->get_taxonomy(); } elseif ( $term instanceof Series ) { $taxonomy = 'series'; @@ -185,7 +190,7 @@ function get_book_term_link( $term ) { * @param string $final_url Final archive URL. * @param string $slug Term slug. * @param string $taxonomy Term taxonomy / type. - * @param Author|Book_Term|Series|Rating $term Term object. + * @param Author|BookTerm|Series|Rating $term Term object. */ return apply_filters( 'book-database/term-archive-link', $final_url, $slug, $taxonomy, $term ); @@ -202,4 +207,4 @@ function get_site_timezone() { } else { return new \DateTimeZone( get_option( 'timezone_string' ) ); } -} \ No newline at end of file +} diff --git a/includes/reading-logs/reading-log-functions.php b/includes/reading-logs/reading-log-functions.php index e8f9bbb8..dc6d7a50 100644 --- a/includes/reading-logs/reading-log-functions.php +++ b/includes/reading-logs/reading-log-functions.php @@ -10,13 +10,15 @@ namespace Book_Database; use Book_Database\Database\ReadingLogs\ReadingLogsQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\ReadingLog; /** * Get a single reading log entry by its ID * * @param int $log_id * - * @return Reading_Log|false + * @return ReadingLog|false */ function get_reading_log( $log_id ) { @@ -32,7 +34,7 @@ function get_reading_log( $log_id ) { * @param string $column_name * @param mixed $column_value * - * @return Reading_Log|false + * @return ReadingLog|false */ function get_reading_log_by( $column_name, $column_value ) { @@ -78,7 +80,7 @@ function get_reading_log_by( $column_name, $column_value ) { * @type bool $update_cache Whether to prime the cache for found items. Default false. * } * - * @return Reading_Log[] Array of Reading_Log objects. + * @return ReadingLog[] Array of Reading_Log objects. */ function get_reading_logs( $args = array() ) { diff --git a/includes/retailers/retailer-functions.php b/includes/retailers/retailer-functions.php index 410afa78..b5f9adc2 100644 --- a/includes/retailers/retailer-functions.php +++ b/includes/retailers/retailer-functions.php @@ -10,6 +10,8 @@ namespace Book_Database; use Book_Database\Database\Retailers\RetailersQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\Retailer; /** * Get a single retailer by its ID diff --git a/includes/reviews/review-actions.php b/includes/reviews/review-actions.php index d669acf5..1b5e9808 100644 --- a/includes/reviews/review-actions.php +++ b/includes/reviews/review-actions.php @@ -9,6 +9,8 @@ namespace Book_Database; +use Book_Database\Exceptions\Exception; + /** * When a post is published or scheduled, sync associated reviews with the post's publication date. * @@ -56,4 +58,4 @@ function sync_review_publish_date( $new_status, $old_status, $post ) { } -add_action( 'transition_post_status', __NAMESPACE__ . '\sync_review_publish_date', 10, 3 ); \ No newline at end of file +add_action( 'transition_post_status', __NAMESPACE__ . '\sync_review_publish_date', 10, 3 ); diff --git a/includes/reviews/review-functions.php b/includes/reviews/review-functions.php index dbc9b87e..81f257f3 100644 --- a/includes/reviews/review-functions.php +++ b/includes/reviews/review-functions.php @@ -10,6 +10,8 @@ namespace Book_Database; use Book_Database\Database\Reviews\ReviewsQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\Review; /** * Get a single review by its ID diff --git a/includes/series/series-functions.php b/includes/series/series-functions.php index 90466992..7e45c7b0 100644 --- a/includes/series/series-functions.php +++ b/includes/series/series-functions.php @@ -16,6 +16,8 @@ */ use Book_Database\Database\Series\SeriesQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\Series; /** * Get a single series by a column name/value combo diff --git a/includes/shortcodes.php b/includes/shortcodes.php index 56851f46..be65b71d 100644 --- a/includes/shortcodes.php +++ b/includes/shortcodes.php @@ -9,6 +9,15 @@ namespace Book_Database; +use Book_Database\Models\Author; +use Book_Database\Models\Book; +use Book_Database\Models\BookTaxonomy; +use Book_Database\Models\BookTerm; +use Book_Database\Models\ReadingLog; +use Book_Database\Models\Review; +use Book_Database\Models\Series; +use Book_Database\ValueObjects\Rating; + /** * Book * @@ -195,7 +204,7 @@ function book_reviews_shortcode( $atts, $content = '' ) { default : $taxonomy = get_book_taxonomy_by( 'slug', $filter ); - if ( ! $taxonomy instanceof Book_Taxonomy ) { + if ( ! $taxonomy instanceof BookTaxonomy ) { break; } @@ -213,7 +222,7 @@ function book_reviews_shortcode( $atts, $content = '' ) { $slug = $wp_query->query_vars['book_term']; $term = get_book_term_by( 'slug', $slug ); - if ( $term instanceof Book_Term ) { + if ( $term instanceof BookTerm ) { $selected_term = $term->get_id(); } } @@ -254,7 +263,7 @@ function book_reviews_shortcode( $atts, $content = '' ) { 'pub_date' => $review_data->book_pub_date ?? '', 'series_position' => $review_data->series_position ?? '' ) ); - $reading_log = new Reading_Log( array( + $reading_log = new ReadingLog( array( 'date_started' => $review_data->date_started_reading ?? null, 'date_finished' => $review_data->date_finished_reading ?? null, 'percentage_complete' => $review_data->percentage_complete ?? null, @@ -398,4 +407,4 @@ function book_grid_shortcode( $atts, $content = '' ) { } -add_shortcode( 'book-grid', __NAMESPACE__ . '\book_grid_shortcode' ); \ No newline at end of file +add_shortcode( 'book-grid', __NAMESPACE__ . '\book_grid_shortcode' ); diff --git a/src/Analytics.php b/src/Analytics.php deleted file mode 100644 index fc8efdea..00000000 --- a/src/Analytics.php +++ /dev/null @@ -1,685 +0,0 @@ -start_date = $start_date; - $this->end_date = $end_date; - $this->args = wp_parse_args( $args, array( - 'rating_format' => null - ) ); - $this->wpdb = $wpdb; - $this->tables = array( - 'authors' => book_database()->get_table( 'authors' )->get_table_name(), - 'author_r' => book_database()->get_table( 'book_author_relationships' )->get_table_name(), - 'term_r' => book_database()->get_table( 'book_term_relationships' )->get_table_name(), - 'book_terms' => book_database()->get_table( 'book_terms' )->get_table_name(), - 'books' => book_database()->get_table( 'books' )->get_table_name(), - 'editions' => book_database()->get_table( 'editions' )->get_table_name(), - 'reading_log' => book_database()->get_table( 'reading_log' )->get_table_name(), - 'reviews' => book_database()->get_table( 'reviews' )->get_table_name(), - 'series' => book_database()->get_table( 'series' )->get_table_name(), - ); - - } - - /** - * Log the performed query - * - * This only actually logs if WP_DEBUG is enabled. - * - * @param string $query MySQL query. - * @param string $method Method name. - */ - protected function log( $query, $method ) { - if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { - error_log( sprintf( "%s:\n%s", $method, $query ) ); - } - } - - /** - * Get a breakdown of how books were read - * - * Returns an array of `finished`, `dnf`, `rereads`, and `new`. - * - * @see Analytics\Books_Finished_Count - * @see Analytics\Books_DNF_Count - * - * @return array - */ - public function get_number_books_read_breakdown() { - - if ( is_array( $this->number_books_read_breakdown ) ) { - return $this->number_books_read_breakdown; - } - - $counts = array( - 'finished' => 0, - 'dnf' => 0, - 'rereads' => 0, - 'new' => 0 - ); - - /** - * Number of books finished. - */ - $query = $this->wpdb->prepare( - "SELECT COUNT(*) FROM {$this->tables['reading_log']} - WHERE date_finished >= %s - AND date_finished <= %s - AND date_finished IS NOT NULL - AND percentage_complete >= 1", - $this->start_date, $this->end_date - ); - - $this->log( $query, __METHOD__ . '\finished' ); - - $counts['finished'] = absint( $this->wpdb->get_var( $query ) ); - - /** - * Number of books DNF - */ - $query = $this->wpdb->prepare( - "SELECT COUNT(*) - FROM {$this->tables['reading_log']} - WHERE date_started >= %s - AND date_finished <= %s - AND date_finished IS NOT NULL - AND percentage_complete < 1", - $this->start_date, - $this->end_date - ); - - $this->log( $query, __METHOD__ . '\dnf' ); - - $counts['dnf'] = absint( $this->wpdb->get_var( $query ) ); - - /** - * Count rereads - */ - $query = $this->wpdb->prepare( - "SELECT ( COUNT(*) - 1 ) AS count, GROUP_CONCAT( date_finished SEPARATOR ',' ) AS date_finished, book_id - FROM {$this->tables['reading_log']} AS log - INNER JOIN {$this->tables['books']} AS book ON book.id = log.book_id - WHERE `date_finished` < %s - AND `date_finished` IS NOT NULL - GROUP BY book_id", - $this->end_date - ); - - $this->log( $query, __METHOD__ . '\rereads' ); - - $books_read = $this->wpdb->get_results( $query ); - - if ( ! empty( $books_read ) ) { - foreach ( $books_read as $book_read ) { - if ( $book_read->count < 1 ) { - continue; - } - - $dates_finished = explode( ',', $book_read->date_finished ); - $this_book_rereads = 0; - - foreach ( $dates_finished as $date_finished ) { - if ( $date_finished >= $this->start_date && $date_finished <= $this->end_date ) { - $this_book_rereads ++; - } - - if ( $this_book_rereads >= $book_read->count ) { - break; - } - } - - $counts['rereads'] += $this_book_rereads; - } - } - - $counts['new'] = ( $counts['finished'] + $counts['dnf'] ) - $counts['rereads']; - - return $counts; - - } - - /** - * Returns the number of books that have been fully read/finished. - * - * @return int - */ - public function get_number_books_finished() { - - $breakdown = $this->get_number_books_read_breakdown(); - - return absint( $breakdown['finished'] ); - - } - - /** - * Returns the number of books that were marked as DNF - * - * @return int - */ - public function get_number_dnf() { - - $breakdown = $this->get_number_books_read_breakdown(); - - return absint( $breakdown['dnf'] ); - - } - - /** - * Get the number of new books that were read - * - * @return int - */ - public function get_number_new_books() { - - $breakdown = $this->get_number_books_read_breakdown(); - - return absint( $breakdown['new'] ); - - } - - /** - * Get the number of rereads - * - * @return int - */ - public function get_number_rereads() { - - $breakdown = $this->get_number_books_read_breakdown(); - - return absint( $breakdown['rereads'] ); - - } - - /** - * Get the number of pages read - * - * @see \Book_Database\Analytics\Datasets\Pages_Read - * - * @return int - */ - public function get_number_pages_read() { - - $query = $this->wpdb->prepare( - "SELECT SUM(pages * percentage_complete) as pages_read - FROM {$this->tables['books']} AS book - INNER JOIN {$this->tables['reading_log']} AS log ON( log.book_id = book.id ) - WHERE date_finished >= %s - AND date_finished <= %s - AND date_finished IS NOT NULL", - $this->start_date, $this->end_date - ); - - $this->log( $query, __METHOD__ ); - - $result = $this->wpdb->get_var( $query ); - - return round( absint( $result ) ); - - } - - /** - * Calculate the number of books on track to be read in a given period - * - * @return int - */ - public function get_reading_track() { - - try { - - $books_read = $this->get_number_books_finished(); - - // If end date is in the past, return books read. - if ( time() > strtotime( $this->end_date ) ) { - return $books_read; - } - - $now = new \DateTime(); - $start_date = new \DateTime( $this->start_date ); - $end_date = new \DateTime( $this->end_date ); - - // Calculate books read per day so far. - $days_in_period = $now->diff( $start_date )->days; - $books_per_day = ( $days_in_period > 0 ) ? $books_read / $days_in_period : 0; - - // Based on books per day, calculate how many we'll read in the remaining days. - $remaining_days = $end_date->diff( $now )->days; - $left_to_read = $books_per_day * $remaining_days; - - return round( $left_to_read + $books_read ); - - } catch ( \Exception $e ) { - return null; - } - - } - - /** - * Query for reviews written during this period - * - * @return object[] - */ - public function query_reviews() { - - if ( ! is_null( $this->reviews ) ) { - return $this->reviews; - } - - $query = $this->wpdb->prepare( - "SELECT DISTINCT review.id, review.date_written, log.rating AS rating, book.id AS book_id, book.title AS book_title, GROUP_CONCAT(author.name SEPARATOR ', ') AS author_name - FROM {$this->tables['reviews']} AS review - LEFT JOIN {$this->tables['reading_log']} AS log ON ( review.reading_log_id = log.id ) - INNER JOIN {$this->tables['books']} AS book ON ( review.book_id = book.id ) - LEFT JOIN {$this->tables['author_r']} AS ar ON ( book.id = ar.book_id ) - INNER JOIN {$this->tables['authors']} AS author ON ( ar.author_id = author.id ) - WHERE date_written >= %s - AND date_written <= %s - GROUP BY book.id - ORDER BY review.date_written DESC", - $this->start_date, - $this->end_date - ); - - $this->log( $query, __METHOD__ ); - - $this->reviews = $this->wpdb->get_results( $query ); - - return $this->reviews; - - } - - /** - * Get the number of reviews - * - * @return int - */ - public function get_number_reviews() { - - $reviews = $this->query_reviews(); - - return is_array( $reviews ) ? count( $reviews ) : 0; - - } - - /** - * Get the average star rating - * - * @return float|int - */ - public function get_avg_rating() { - - $query = $this->wpdb->prepare( - "SELECT ROUND( AVG( rating ), 2 ) - FROM {$this->tables['reading_log']} - WHERE rating IS NOT NULL - AND date_finished >= %s - AND date_finished <= %s - AND date_finished IS NOT NULL", - $this->start_date, - $this->end_date - ); - - $this->log( $query, __METHOD__ ); - - $average = $this->wpdb->get_var( $query ); - - return $average * 1; - - } - - /** - * Count the number of different series read - * - * @return int - */ - public function get_number_different_series() { - - $query = $this->wpdb->prepare( - "SELECT COUNT( DISTINCT series_id ) - FROM {$this->tables['reading_log']} AS log - INNER JOIN {$this->tables['books']} AS book ON ( book.id = log.book_id ) - WHERE date_finished >= %s - AND date_finished <= %s - AND date_finished IS NOT NULL - AND series_id IS NOT NULL", - $this->start_date, - $this->end_date - ); - - $this->log( $query, __METHOD__ ); - - $number = $this->wpdb->get_var( $query ); - - return absint( $number ); - - } - - /** - * Count the number of standalones read - * - * @return int - */ - public function get_number_standalones() { - - $query = $this->wpdb->prepare( - "SELECT COUNT(*) - FROM {$this->tables['reading_log']} AS log - INNER JOIN {$this->tables['books']} AS book ON ( book.id = log.book_id ) - WHERE date_finished >= %s - AND date_finished <= %s - AND date_finished IS NOT NULL - AND series_id IS NULL", - $this->start_date, - $this->end_date - ); - - $this->log( $query, __METHOD__ ); - - $number = $this->wpdb->get_var( $query ); - - return absint( $number ); - - } - - /** - * Get the number of different authors - * - * @return int - */ - public function get_number_authors() { - - $query = $this->wpdb->prepare( - "SELECT COUNT( DISTINCT ar.author_id ) - FROM {$this->tables['author_r']} AS ar - INNER JOIN {$this->tables['reading_log']} AS log ON ( ar.book_id = log.book_id ) - WHERE date_finished >= %s - AND date_finished <= %s - AND date_finished IS NOT NULL", - $this->start_date, - $this->end_date - ); - - $this->log( $query, __METHOD__ ); - - $number = $this->wpdb->get_var( $query ); - - return absint( $number ); - - } - - /** - * Get rating breakdown - * - * Returns an array of arrays, containing each available rating and the associated number of books. - */ - public function get_rating_breakdown() { - - $query = $this->wpdb->prepare( - "SELECT rating, COUNT( IFNULL( rating, 1 ) ) AS count - FROM {$this->tables['reading_log']} AS log - WHERE date_finished >= %s - AND date_finished <= %s - AND date_finished IS NOT NULL - GROUP BY rating - ORDER BY rating DESC", - $this->start_date, - $this->end_date - ); - - $this->log( $query, __METHOD__ ); - - $results = $this->wpdb->get_results( $query ); - $final_array = $temp_array = array(); - - foreach ( get_available_ratings() as $rating => $label ) { - $temp_array[ $rating ] = 0; - } - - if ( is_array( $results ) ) { - foreach ( $results as $result ) { - $key = ( null === $result->rating ) ? 'none' : (string) ( $result->rating * 1 ); - $temp_array[ $key ] = absint( $result->count ); - } - } - - foreach ( $temp_array as $key => $value ) { - $rating = new Rating( $key ); - $final_array[] = array( - 'rating' => 'none' === $key ? 'none' : $rating->format( $this->args['rating_format'] ), - 'number_books' => $value - ); - } - - return $final_array; - - } - - /** - * Get pages breakdown - * - * Returns a table containing page ranges, along with how many books fell into that range. - * Example: - * - * +------------+-----------------+ - * | page_range | number of books | - * +------------+-----------------+ - * | 0-199 | 2 | - * | 200-399 | 6 | - * | 400-599 | 1 | - * +------------+-----------------+ - * - * @param int $number_range Number of pages in each range. - * - * @return array - */ - public function get_pages_breakdown( $number_range = 200 ) { - - $query = $this->wpdb->prepare( - "SELECT CONCAT( %d * FLOOR( pages/%d ), '-', %d * FLOOR( pages/%d ) + %d ) AS page_range, COUNT(*) AS number_books - FROM {$this->tables['reading_log']} AS log - INNER JOIN {$this->tables['books']} AS book ON ( book.id = log.book_id ) - WHERE date_finished >= %s - AND date_finished <= %s - AND date_finished IS NOT NULL - AND book.pages IS NOT NULL - GROUP BY 1 - ORDER BY pages", - absint( $number_range ), - absint( $number_range ), - absint( $number_range ), - absint( $number_range ), - absint( $number_range - 1 ), - $this->start_date, - $this->end_date - ); - - $this->log( $query, __NAMESPACE__ ); - - $breakdown = $this->wpdb->get_results( $query, ARRAY_A ); - - if ( ! is_array( $breakdown ) ) { - $breakdown = array(); - } - - return $breakdown; - - } - - /** - * Get taxonomy breakdown - * - * For each term: number of books read, average rating, and term name. - * - * @param string $taxonomy Taxonomy slug - * - * @return array|object|null - */ - public function get_taxonomy_breakdown( $taxonomy ) { - - $query = $this->wpdb->prepare( - "SELECT COUNT( log.id ) AS number_books_read, ROUND( AVG( log.rating ), 2 ) AS average_rating, COUNT( review.id ) AS number_reviews, term.name AS term_name - FROM {$this->tables['reading_log']} AS log - LEFT JOIN {$this->tables['reviews']} AS review ON ( review.reading_log_id = log.id ) - INNER JOIN {$this->tables['term_r']} AS tr ON ( tr.book_id = log.book_id ) - INNER JOIN {$this->tables['book_terms']} AS term ON ( term.id = tr.term_id ) - WHERE date_finished >= %s - AND date_finished <= %s - AND date_finished IS NOT NULL - AND term.taxonomy = %s - GROUP BY term.taxonomy, term.name - ORDER BY term.name ASC", - $this->start_date, - $this->end_date, - $taxonomy - ); - - $this->log( $query, __NAMESPACE__ ); - - $results = $this->wpdb->get_results( $query ); - - // Format rating. - foreach ( $results as $key => $result ) { - $rating = new Rating( $result->average_rating ); - $results[ $key ]->average_rating = $rating->format( $this->args['rating_format'] ); - } - - return $results; - - } - - /** - * Get a list of reviews written - * - * Limited to 20 results. - * - * @return object[]|array - */ - public function get_reviews_written() { - - $reviews = $this->query_reviews(); - - if ( ! is_array( $reviews ) ) { - return null; - } - - // Limit results to 20. - if ( count( $reviews ) > 20 ) { - $reviews = array_slice( $reviews, 0, 20 ); - } - - foreach ( $reviews as $key => $review ) { - $rating = new Rating( $review->rating ); - $reviews[ $key ]->rating = $rating->format_html_stars(); - $reviews[ $key ]->rating_class = $rating->format_html_class(); - } - - return $reviews; - - } - - /** - * Get a list of books that have been read but not reviewed - * - * Limited to 20 results. - * - * @return object[]|array - */ - public function get_read_not_reviewed() { - - $query = $this->wpdb->prepare( - "SELECT DISTINCT log.id, log.date_started, log.date_finished, log.rating, log.percentage_complete, book.id AS book_id, book.title AS book_title, GROUP_CONCAT(author.name SEPARATOR ', ') AS author_name - FROM {$this->tables['reading_log']} AS log - INNER JOIN {$this->tables['books']} AS book ON ( log.book_id = book.id ) - LEFT JOIN {$this->tables['author_r']} AS ar ON ( log.book_id = ar.book_id ) - INNER JOIN {$this->tables['authors']} AS author ON ( ar.author_id = author.id ) - LEFT JOIN {$this->tables['reviews']} AS review ON ( book.id = review.book_id ) - WHERE date_finished >= %s - AND date_finished <= %s - AND date_finished IS NOT NULL - AND review.book_id IS NULL - GROUP BY book.id - ORDER BY log.date_finished DESC - LIMIT 20", - $this->start_date, - $this->end_date - ); - - $this->log( $query, __METHOD__ ); - - $books = $this->wpdb->get_results( $query ); - - if ( ! is_array( $books ) ) { - return null; - } - - foreach ( $books as $key => $book ) { - $rating = new Rating( $book->rating ); - $books[ $key ]->rating = $rating->format_html_stars(); - $books[ $key ]->rating_class = $rating->format_html_class(); - } - - return $books; - - } - -} diff --git a/src/Analytics/Analytics.php b/src/Analytics/Analytics.php new file mode 100644 index 00000000..c82f43ff --- /dev/null +++ b/src/Analytics/Analytics.php @@ -0,0 +1,677 @@ +start_date = $start_date; + $this->end_date = $end_date; + $this->args = wp_parse_args($args, array( + 'rating_format' => null + )); + $this->wpdb = $wpdb; + $this->tables = array( + 'authors' => book_database()->get_table('authors')->get_table_name(), + 'author_r' => book_database()->get_table('book_author_relationships')->get_table_name(), + 'term_r' => book_database()->get_table('book_term_relationships')->get_table_name(), + 'book_terms' => book_database()->get_table('book_terms')->get_table_name(), + 'books' => book_database()->get_table('books')->get_table_name(), + 'editions' => book_database()->get_table('editions')->get_table_name(), + 'reading_log' => book_database()->get_table('reading_log')->get_table_name(), + 'reviews' => book_database()->get_table('reviews')->get_table_name(), + 'series' => book_database()->get_table('series')->get_table_name(), + ); + + } + + /** + * Log the performed query + * + * This only actually logs if WP_DEBUG is enabled. + * + * @param string $query MySQL query. + * @param string $method Method name. + */ + protected function log($query, $method) + { + if (defined('WP_DEBUG') && WP_DEBUG) { + error_log(sprintf("%s:\n%s", $method, $query)); + } + } + + /** + * Get a breakdown of how books were read + * + * Returns an array of `finished`, `dnf`, `rereads`, and `new`. + * + * @see Books_Finished_Count + * @see Books_DNF_Count + * + * @return array + */ + public function get_number_books_read_breakdown(): array + { + if (is_array($this->number_books_read_breakdown)) { + return $this->number_books_read_breakdown; + } + + $counts = array( + 'finished' => 0, + 'dnf' => 0, + 'rereads' => 0, + 'new' => 0 + ); + + /** + * Number of books finished. + */ + $query = $this->wpdb->prepare( + "SELECT COUNT(*) FROM {$this->tables['reading_log']} + WHERE date_finished >= %s + AND date_finished <= %s + AND date_finished IS NOT NULL + AND percentage_complete >= 1", + $this->start_date, $this->end_date + ); + + $this->log($query, __METHOD__.'\finished'); + + $counts['finished'] = absint($this->wpdb->get_var($query)); + + /** + * Number of books DNF + */ + $query = $this->wpdb->prepare( + "SELECT COUNT(*) + FROM {$this->tables['reading_log']} + WHERE date_started >= %s + AND date_finished <= %s + AND date_finished IS NOT NULL + AND percentage_complete < 1", + $this->start_date, + $this->end_date + ); + + $this->log($query, __METHOD__.'\dnf'); + + $counts['dnf'] = absint($this->wpdb->get_var($query)); + + /** + * Count rereads + */ + $query = $this->wpdb->prepare( + "SELECT ( COUNT(*) - 1 ) AS count, GROUP_CONCAT( date_finished SEPARATOR ',' ) AS date_finished, book_id + FROM {$this->tables['reading_log']} AS log + INNER JOIN {$this->tables['books']} AS book ON book.id = log.book_id + WHERE `date_finished` < %s + AND `date_finished` IS NOT NULL + GROUP BY book_id", + $this->end_date + ); + + $this->log($query, __METHOD__.'\rereads'); + + $books_read = $this->wpdb->get_results($query); + + if (! empty($books_read)) { + foreach ($books_read as $book_read) { + if ($book_read->count < 1) { + continue; + } + + $dates_finished = explode(',', $book_read->date_finished); + $this_book_rereads = 0; + + foreach ($dates_finished as $date_finished) { + if ($date_finished >= $this->start_date && $date_finished <= $this->end_date) { + $this_book_rereads++; + } + + if ($this_book_rereads >= $book_read->count) { + break; + } + } + + $counts['rereads'] += $this_book_rereads; + } + } + + $counts['new'] = ($counts['finished'] + $counts['dnf']) - $counts['rereads']; + + return $counts; + } + + /** + * Returns the number of books that have been fully read/finished. + * + * @return int + */ + public function get_number_books_finished(): int + { + $breakdown = $this->get_number_books_read_breakdown(); + + return absint($breakdown['finished']); + } + + /** + * Returns the number of books that were marked as DNF + * + * @return int + */ + public function get_number_dnf(): int + { + $breakdown = $this->get_number_books_read_breakdown(); + + return absint($breakdown['dnf']); + } + + /** + * Get the number of new books that were read + * + * @return int + */ + public function get_number_new_books(): int + { + $breakdown = $this->get_number_books_read_breakdown(); + + return absint($breakdown['new']); + } + + /** + * Get the number of rereads + * + * @return int + */ + public function get_number_rereads(): int + { + $breakdown = $this->get_number_books_read_breakdown(); + + return absint($breakdown['rereads']); + } + + /** + * Get the number of pages read + * + * @see \Book_Database\Analytics\Datasets\Pages_Read + * + * @return int + */ + public function get_number_pages_read(): int + { + $query = $this->wpdb->prepare( + "SELECT SUM(pages * percentage_complete) as pages_read + FROM {$this->tables['books']} AS book + INNER JOIN {$this->tables['reading_log']} AS log ON( log.book_id = book.id ) + WHERE date_finished >= %s + AND date_finished <= %s + AND date_finished IS NOT NULL", + $this->start_date, $this->end_date + ); + + $this->log($query, __METHOD__); + + $result = $this->wpdb->get_var($query); + + return round(absint($result)); + } + + /** + * Calculate the number of books on track to be read in a given period + * + * @return int|null + */ + public function get_reading_track(): ?int + { + try { + + $books_read = $this->get_number_books_finished(); + + // If end date is in the past, return books read. + if (time() > strtotime($this->end_date)) { + return $books_read; + } + + $now = new \DateTime(); + $start_date = new \DateTime($this->start_date); + $end_date = new \DateTime($this->end_date); + + // Calculate books read per day so far. + $days_in_period = $now->diff($start_date)->days; + $books_per_day = ($days_in_period > 0) ? $books_read / $days_in_period : 0; + + // Based on books per day, calculate how many we'll read in the remaining days. + $remaining_days = $end_date->diff($now)->days; + $left_to_read = $books_per_day * $remaining_days; + + return round($left_to_read + $books_read); + + } catch (\Exception $e) { + return null; + } + } + + /** + * Query for reviews written during this period + * + * @return object[] + */ + public function query_reviews(): array + { + if (! is_null($this->reviews)) { + return $this->reviews; + } + + $query = $this->wpdb->prepare( + "SELECT DISTINCT review.id, review.date_written, log.rating AS rating, book.id AS book_id, book.title AS book_title, GROUP_CONCAT(author.name SEPARATOR ', ') AS author_name + FROM {$this->tables['reviews']} AS review + LEFT JOIN {$this->tables['reading_log']} AS log ON ( review.reading_log_id = log.id ) + INNER JOIN {$this->tables['books']} AS book ON ( review.book_id = book.id ) + LEFT JOIN {$this->tables['author_r']} AS ar ON ( book.id = ar.book_id ) + INNER JOIN {$this->tables['authors']} AS author ON ( ar.author_id = author.id ) + WHERE date_written >= %s + AND date_written <= %s + GROUP BY book.id + ORDER BY review.date_written DESC", + $this->start_date, + $this->end_date + ); + + $this->log($query, __METHOD__); + + $this->reviews = $this->wpdb->get_results($query); + + return $this->reviews; + } + + /** + * Get the number of reviews + * + * @return int + */ + public function get_number_reviews(): int + { + $reviews = $this->query_reviews(); + + return is_array($reviews) ? count($reviews) : 0; + } + + /** + * Get the average star rating + * + * @return float|int + */ + public function get_avg_rating() + { + $query = $this->wpdb->prepare( + "SELECT ROUND( AVG( rating ), 2 ) + FROM {$this->tables['reading_log']} + WHERE rating IS NOT NULL + AND date_finished >= %s + AND date_finished <= %s + AND date_finished IS NOT NULL", + $this->start_date, + $this->end_date + ); + + $this->log($query, __METHOD__); + + $average = $this->wpdb->get_var($query); + + return $average * 1; + } + + /** + * Count the number of different series read + * + * @return int + */ + public function get_number_different_series(): int + { + $query = $this->wpdb->prepare( + "SELECT COUNT( DISTINCT series_id ) + FROM {$this->tables['reading_log']} AS log + INNER JOIN {$this->tables['books']} AS book ON ( book.id = log.book_id ) + WHERE date_finished >= %s + AND date_finished <= %s + AND date_finished IS NOT NULL + AND series_id IS NOT NULL", + $this->start_date, + $this->end_date + ); + + $this->log($query, __METHOD__); + + $number = $this->wpdb->get_var($query); + + return absint($number); + } + + /** + * Count the number of standalones read + * + * @return int + */ + public function get_number_standalones(): int + { + $query = $this->wpdb->prepare( + "SELECT COUNT(*) + FROM {$this->tables['reading_log']} AS log + INNER JOIN {$this->tables['books']} AS book ON ( book.id = log.book_id ) + WHERE date_finished >= %s + AND date_finished <= %s + AND date_finished IS NOT NULL + AND series_id IS NULL", + $this->start_date, + $this->end_date + ); + + $this->log($query, __METHOD__); + + $number = $this->wpdb->get_var($query); + + return absint($number); + } + + /** + * Get the number of different authors + * + * @return int + */ + public function get_number_authors(): int + { + $query = $this->wpdb->prepare( + "SELECT COUNT( DISTINCT ar.author_id ) + FROM {$this->tables['author_r']} AS ar + INNER JOIN {$this->tables['reading_log']} AS log ON ( ar.book_id = log.book_id ) + WHERE date_finished >= %s + AND date_finished <= %s + AND date_finished IS NOT NULL", + $this->start_date, + $this->end_date + ); + + $this->log($query, __METHOD__); + + $number = $this->wpdb->get_var($query); + + return absint($number); + } + + /** + * Get rating breakdown + * + * Returns an array of arrays, containing each available rating and the associated number of books. + */ + public function get_rating_breakdown(): array + { + $query = $this->wpdb->prepare( + "SELECT rating, COUNT( IFNULL( rating, 1 ) ) AS count + FROM {$this->tables['reading_log']} AS log + WHERE date_finished >= %s + AND date_finished <= %s + AND date_finished IS NOT NULL + GROUP BY rating + ORDER BY rating DESC", + $this->start_date, + $this->end_date + ); + + $this->log($query, __METHOD__); + + $results = $this->wpdb->get_results($query); + $final_array = $temp_array = array(); + + foreach (get_available_ratings() as $rating => $label) { + $temp_array[$rating] = 0; + } + + if (is_array($results)) { + foreach ($results as $result) { + $key = (null === $result->rating) ? 'none' : (string) ($result->rating * 1); + $temp_array[$key] = absint($result->count); + } + } + + foreach ($temp_array as $key => $value) { + $rating = new Rating($key); + $final_array[] = array( + 'rating' => 'none' === $key ? 'none' : $rating->format($this->args['rating_format']), + 'number_books' => $value + ); + } + + return $final_array; + } + + /** + * Get pages breakdown + * + * Returns a table containing page ranges, along with how many books fell into that range. + * Example: + * + * +------------+-----------------+ + * | page_range | number of books | + * +------------+-----------------+ + * | 0-199 | 2 | + * | 200-399 | 6 | + * | 400-599 | 1 | + * +------------+-----------------+ + * + * @param int $number_range Number of pages in each range. + * + * @return array + */ + public function get_pages_breakdown(int $number_range = 200): array + { + $query = $this->wpdb->prepare( + "SELECT CONCAT( %d * FLOOR( pages/%d ), '-', %d * FLOOR( pages/%d ) + %d ) AS page_range, COUNT(*) AS number_books + FROM {$this->tables['reading_log']} AS log + INNER JOIN {$this->tables['books']} AS book ON ( book.id = log.book_id ) + WHERE date_finished >= %s + AND date_finished <= %s + AND date_finished IS NOT NULL + AND book.pages IS NOT NULL + GROUP BY 1 + ORDER BY pages", + absint($number_range), + absint($number_range), + absint($number_range), + absint($number_range), + absint($number_range - 1), + $this->start_date, + $this->end_date + ); + + $this->log($query, __NAMESPACE__); + + $breakdown = $this->wpdb->get_results($query, ARRAY_A); + + if (! is_array($breakdown)) { + $breakdown = array(); + } + + return $breakdown; + } + + /** + * Get taxonomy breakdown + * + * For each term: number of books read, average rating, and term name. + * + * @param string $taxonomy Taxonomy slug + * + * @return array|object|null + */ + public function get_taxonomy_breakdown(string $taxonomy) + { + $query = $this->wpdb->prepare( + "SELECT COUNT( log.id ) AS number_books_read, ROUND( AVG( log.rating ), 2 ) AS average_rating, COUNT( review.id ) AS number_reviews, term.name AS term_name + FROM {$this->tables['reading_log']} AS log + LEFT JOIN {$this->tables['reviews']} AS review ON ( review.reading_log_id = log.id ) + INNER JOIN {$this->tables['term_r']} AS tr ON ( tr.book_id = log.book_id ) + INNER JOIN {$this->tables['book_terms']} AS term ON ( term.id = tr.term_id ) + WHERE date_finished >= %s + AND date_finished <= %s + AND date_finished IS NOT NULL + AND term.taxonomy = %s + GROUP BY term.taxonomy, term.name + ORDER BY term.name ASC", + $this->start_date, + $this->end_date, + $taxonomy + ); + + $this->log($query, __NAMESPACE__); + + $results = $this->wpdb->get_results($query); + + // Format rating. + foreach ($results as $key => $result) { + $rating = new Rating($result->average_rating); + $results[$key]->average_rating = $rating->format($this->args['rating_format']); + } + + return $results; + } + + /** + * Get a list of reviews written + * + * Limited to 20 results. + * + * @return object[]|array|null + */ + public function get_reviews_written(): ?array + { + $reviews = $this->query_reviews(); + + if (! is_array($reviews)) { + return null; + } + + // Limit results to 20. + if (count($reviews) > 20) { + $reviews = array_slice($reviews, 0, 20); + } + + foreach ($reviews as $key => $review) { + $rating = new Rating($review->rating); + $reviews[$key]->rating = $rating->format_html_stars(); + $reviews[$key]->rating_class = $rating->format_html_class(); + } + + return $reviews; + } + + /** + * Get a list of books that have been read but not reviewed + * + * Limited to 20 results. + * + * @return object[]|array|null + */ + public function get_read_not_reviewed(): ?array + { + $query = $this->wpdb->prepare( + "SELECT DISTINCT log.id, log.date_started, log.date_finished, log.rating, log.percentage_complete, book.id AS book_id, book.title AS book_title, GROUP_CONCAT(author.name SEPARATOR ', ') AS author_name + FROM {$this->tables['reading_log']} AS log + INNER JOIN {$this->tables['books']} AS book ON ( log.book_id = book.id ) + LEFT JOIN {$this->tables['author_r']} AS ar ON ( log.book_id = ar.book_id ) + INNER JOIN {$this->tables['authors']} AS author ON ( ar.author_id = author.id ) + LEFT JOIN {$this->tables['reviews']} AS review ON ( book.id = review.book_id ) + WHERE date_finished >= %s + AND date_finished <= %s + AND date_finished IS NOT NULL + AND review.book_id IS NULL + GROUP BY book.id + ORDER BY log.date_finished DESC + LIMIT 20", + $this->start_date, + $this->end_date + ); + + $this->log($query, __METHOD__); + + $books = $this->wpdb->get_results($query); + + if (! is_array($books)) { + return null; + } + + foreach ($books as $key => $book) { + $rating = new Rating($book->rating); + $books[$key]->rating = $rating->format_html_stars(); + $books[$key]->rating_class = $rating->format_html_class(); + } + + return $books; + } + +} diff --git a/src/Analytics/Datasets/Highest_Rated_Books.php b/src/Analytics/Datasets/Highest_Rated_Books.php index 32d54e5d..d7d3aef7 100644 --- a/src/Analytics/Datasets/Highest_Rated_Books.php +++ b/src/Analytics/Datasets/Highest_Rated_Books.php @@ -10,7 +10,7 @@ namespace Book_Database\Analytics\Datasets; use Book_Database\Analytics\Dataset; -use Book_Database\Rating; +use Book_Database\ValueObjects\Rating; use function Book_Database\book_database; use function Book_Database\format_date; diff --git a/src/Analytics/Datasets/Lowest_Rated_Books.php b/src/Analytics/Datasets/Lowest_Rated_Books.php index fff57b78..5487de30 100644 --- a/src/Analytics/Datasets/Lowest_Rated_Books.php +++ b/src/Analytics/Datasets/Lowest_Rated_Books.php @@ -10,7 +10,7 @@ namespace Book_Database\Analytics\Datasets; use Book_Database\Analytics\Dataset; -use Book_Database\Rating; +use Book_Database\ValueObjects\Rating; use function Book_Database\book_database; use function Book_Database\format_date; diff --git a/src/Analytics/Datasets/Reviews_Written.php b/src/Analytics/Datasets/Reviews_Written.php index 220e39dc..436e66d9 100644 --- a/src/Analytics/Datasets/Reviews_Written.php +++ b/src/Analytics/Datasets/Reviews_Written.php @@ -10,7 +10,7 @@ namespace Book_Database\Analytics\Datasets; use Book_Database\Analytics\Dataset; -use Book_Database\Rating; +use Book_Database\ValueObjects\Rating; use function Book_Database\book_database; use function Book_Database\format_date; diff --git a/src/Analytics/Datasets/Shortest_Book_Read.php b/src/Analytics/Datasets/Shortest_Book_Read.php index 0ef97887..a853cc0a 100644 --- a/src/Analytics/Datasets/Shortest_Book_Read.php +++ b/src/Analytics/Datasets/Shortest_Book_Read.php @@ -10,7 +10,7 @@ namespace Book_Database\Analytics\Datasets; use Book_Database\Analytics\Dataset; -use Book_Database\Book; +use Book_Database\Models\Book; use function Book_Database\book_database; use function Book_Database\get_book; use function Book_Database\get_books_admin_page_url; diff --git a/src/Analytics/Datasets/Terms_Breakdown.php b/src/Analytics/Datasets/Terms_Breakdown.php index 98fd7ef1..b0490e95 100644 --- a/src/Analytics/Datasets/Terms_Breakdown.php +++ b/src/Analytics/Datasets/Terms_Breakdown.php @@ -10,7 +10,7 @@ namespace Book_Database\Analytics\Datasets; use Book_Database\Analytics\Dataset; -use Book_Database\Rating; +use Book_Database\ValueObjects\Rating; use function Book_Database\book_database; /** diff --git a/src/Author.php b/src/Author.php deleted file mode 100644 index 80e60481..00000000 --- a/src/Author.php +++ /dev/null @@ -1,125 +0,0 @@ -name; - } - - /** - * Get the author slug - * - * @return string - */ - public function get_slug() { - return $this->slug; - } - - /** - * Get the author description - * - * @return string - */ - public function get_description() { - return $this->description; - } - - /** - * Get the ID of the image attachment - * - * @return int - */ - public function get_image_id() { - return ! empty( $this->image_id ) ? absint( $this->image_id ) : 0; - } - - /** - * Get the author image URL - * - * @param string $size Desired image size. - * - * @return string - */ - public function get_image_url( $size = 'full' ) { - - $url = ''; - $image_id = $this->get_image_id(); - - if ( ! empty( $image_id ) ) { - $url = wp_get_attachment_image_url( $image_id, $size ); - } - - return apply_filters( 'book-database/author/get/image_url', $url, $image_id, $this ); - - } - - /** - * Get the author image HTML. - * - * @param string|array $size Desired image size. - * @param array $args Arguments to use in `wp_get_attachment_image()`. - * - * @return string - */ - public function get_image( $size = 'full', $args = array() ) { - - $image = ''; - $image_id = $this->get_image_id(); - - if ( $image_id ) { - $image = wp_get_attachment_image( absint( $image_id ), $size, false, $args ); - } - - return apply_filters( 'book-database/author/get/image', $image, $image_id, $this ); - - } - - /** - * Get an array of author links - * - * @return array() - */ - public function get_links() { - return $this->links; - } - - /** - * Get the number of books by this author - * - * @return int - */ - public function get_book_count() { - return absint( $this->book_count ); - } - -} diff --git a/src/Base_Object.php b/src/Base_Object.php deleted file mode 100644 index b1c3cca1..00000000 --- a/src/Base_Object.php +++ /dev/null @@ -1,104 +0,0 @@ -set_vars( $args ); - } - - /** - * Set class properties from arguments - * - * @param array $args - */ - protected function set_vars( $args = array() ) { - - // Bail if empty. - if ( empty( $args ) ) { - return; - } - - // Cast to an array. - if ( ! is_array( $args ) ) { - $args = (array) $args; - } - - foreach ( $args as $key => $value ) { - if ( '0000-00-00 00:00:00' === $value ) { - $value = null; - } - - $this->{$key} = $value; - } - - } - - /** - * Get the ID - * - * @return int - */ - public function get_id() { - return absint( $this->id ); - } - - /** - * Get the created date - * - * @param bool $formatted Whether or not to format the result for display. - * @param string $format Format to display in. Defaults to site format. - * - * @return string - */ - public function get_date_created( $formatted = false, $format = '' ) { - return ( ! empty( $this->date_created ) && $formatted ) ? format_date( $this->date_created, $format ) : $this->date_created; - } - - /** - * Get the modified date - * - * @param bool $formatted Whether or not to format the result for display. - * @param string $format Format to display in. Defaults to site format. - * - * @return string - */ - public function get_date_modified( $formatted = false, $format = '' ) { - return ( ! empty( $this->date_modified ) && $formatted ) ? format_date( $this->date_modified, $format ) : $this->date_modified; - } - - /** - * Get all object properties as an array - * - * @return array - */ - public function export_vars() { - return get_object_vars( $this ); - } - -} diff --git a/src/Book.php b/src/Book.php deleted file mode 100644 index c4b546f6..00000000 --- a/src/Book.php +++ /dev/null @@ -1,351 +0,0 @@ -cover_id ); - } - - /** - * Get the cover image URL - * - * @param string $size Desired image size. - * - * @return string - */ - public function get_cover_url( $size = 'full' ) { - - $url = ''; - $cover_id = $this->get_cover_id(); - - if ( ! empty( $cover_id ) ) { - $url = wp_get_attachment_image_url( $cover_id, $size ); - } - - return apply_filters( 'book-database/book/get/cover_url', $url, $cover_id, $this ); - - } - - /** - * Get the cover image HTML. - * - * @param string|array $size Desired image size. - * @param array $args Arguments to use in `wp_get_attachment_image()`. - * - * @return string - */ - public function get_cover( $size = 'full', $args = array() ) { - - $image = ''; - $cover_id = $this->get_cover_id(); - - if ( $cover_id ) { - $image = wp_get_attachment_image( absint( $cover_id ), $size, false, $args ); - } - - return apply_filters( 'book-database/book/get/cover', $image, $cover_id, $this ); - - } - - /** - * Get the title of the book - * - * @return string - */ - public function get_title() { - return $this->title; - } - - /** - * Get the index-friendly title - * - * This moves "The", "An", and "A" to the end of the title. Example: - * `Binding, The` - * - * @return string - */ - public function get_index_title() { - return $this->index_title; - } - - /** - * Get the authors of the book - * - * This returns an array of `Author` objects. - * - * @param array $args Query args to override the defaults. - * - * @return Author[]|array - */ - public function get_authors( $args = array() ) { - - if ( ! isset( $this->authors ) ) { - $this->authors = get_attached_book_authors( $this->get_id(), $args ); - } - - return $this->authors; - - } - - /** - * Get the author names - * - * @param bool $implode True to return a comma-separated list, false to return an array. - * - * @return array|string - */ - public function get_author_names( $implode = false ) { - - $author_names = array(); - $author_terms = $this->get_authors(); - - if ( $author_terms ) { - foreach ( $author_terms as $author_term ) { - $author_names[] = $author_term->get_name(); - } - } - - if ( $implode ) { - $author_names = implode( ', ', $author_names ); - } - - return $author_names; - - } - - /** - * Get the ID of the series this book is in - * - * @return int|null - */ - public function get_series_id() { - return ! empty( $this->series_id ) ? absint( $this->series_id ) : null; - } - - /** - * Get the position in the series - * - * @return int|float|null - */ - public function get_series_position() { - return $this->series_position ?? null; - } - - /** - * Get the name of the series - * - * @return string|false Series name on success, false on failure. - */ - public function get_series_name() { - - $series = get_book_series_by( 'id', $this->get_series_id() ); - - if ( $series instanceof Series ) { - return $series->get_name(); - } - - return false; - - } - - /** - * Get the book's publication date - * - * @param bool $formatted Whether or not to format the result for display. - * Unlike other dates, this DOES NOT convert the date - * to local time. We keep it in UTC always. - * @param string $format Format to display in. Defaults to site format. - * - * @return string - */ - public function get_pub_date( $formatted = false, $format = '' ) { - - if ( empty( $this->pub_date ) || ! $formatted ) { - return $this->pub_date; - } - - $format = ! empty( $format ) ? $format : get_option( 'date_format' ); - - return date( $format, strtotime( $this->pub_date ) ); - - } - - /** - * Get the number of pages in the book - * - * @return int - */ - public function get_pages() { - return ! empty( $this->pages ) ? absint( $this->pages ) : null; - } - - /** - * Get the synopsis - * - * @return string - */ - public function get_synopsis() { - return $this->synopsis; - } - - /** - * Get the Goodreads URL - * - * @return string - */ - public function get_goodreads_url() { - return $this->goodreads_url; - } - - /** - * Get the links associated with this book - * - * @return Book_Link[] - */ - public function get_links() { - - if ( ! isset( $this->links ) ) { - $this->links = get_book_links( array( - 'book_id' => $this->get_id(), - 'number' => 30 - ) ); - } - - return $this->links; - - } - - /** - * Get the average rating from all reading logs associated with this book - * - * @return int|float|null - */ - public function get_average_rating() { - - global $wpdb; - - $log_table = book_database()->get_table( 'reading_log' )->get_table_name(); - - $query = $wpdb->prepare( "SELECT ROUND( AVG( rating ), 2 ) FROM {$log_table} WHERE book_id = %d AND rating IS NOT NULL", $this->get_id() ); - $average = $wpdb->get_var( $query ); - - /** - * Filters the average rating for a book. - * - * @param int|float|null $average Average rating. - * @param int $book_id ID of the book. - * @param Book $this Book object. - */ - return apply_filters( 'book-database/book/get/average-rating', $average, $this->get_id(), $this ); - - } - - /** - * Whether or not the book has a term attached. - * - * @param string|int $term_name_or_id Term name or ID. - * @param string $taxonomy Taxonomy slug. - * - * @return bool - */ - public function has_term( $term_name_or_id, $taxonomy ) { - - $args = array(); - - if ( is_numeric( $term_name_or_id ) ) { - $args['fields'] = 'id'; - } else { - $args['fields'] = 'name'; - } - - $terms = get_attached_book_terms( $this->get_id(), $taxonomy, $args ); - - return in_array( $term_name_or_id, $terms ); - - } - - /** - * Returns all data associated with a book - * - * @return array - */ - public function get_data() { - - $data = array( - 'id' => $this->get_id(), - 'cover_id' => $this->get_cover_id(), - 'cover_url' => $this->get_cover_url( 'full' ), - 'title' => $this->get_title(), - 'index_title' => $this->get_index_title(), - 'authors' => $this->get_authors(), - 'series_id' => $this->get_series_id(), - 'series_name' => $this->get_series_name(), - 'series_position' => $this->get_series_position(), - 'pub_date' => $this->get_pub_date(), - 'pages' => $this->get_pages(), - 'synopsis' => $this->get_synopsis(), - 'goodreads_url' => $this->get_goodreads_url(), - 'links' => $this->get_links(), - 'terms' => array(), - 'date_created' => $this->get_date_created(), - 'date_modified' => $this->get_date_modified() - ); - - // Attach all terms. - foreach ( get_book_taxonomies( array( 'field' => 'slug' ) ) as $taxonomy ) { - $data['terms'][ $taxonomy ] = get_attached_book_terms( $this->get_id(), $taxonomy ); - } - - /** - * Filters the data. - * - * @param array $data - * @param int $book_id - * @param Book $this - */ - return apply_filters( 'book-database/book/get/data', $data, $this->get_id(), $this ); - - } - -} diff --git a/src/Book_Author_Relationship.php b/src/Book_Author_Relationship.php deleted file mode 100644 index 0ace2938..00000000 --- a/src/Book_Author_Relationship.php +++ /dev/null @@ -1,40 +0,0 @@ -author_id ); - } - - /** - * Get the book ID - * - * @return int - */ - public function get_book_id() { - return absint( $this->book_id ); - } - -} diff --git a/src/Book_Layout.php b/src/Book_Layout.php index 303644e0..2803b72d 100644 --- a/src/Book_Layout.php +++ b/src/Book_Layout.php @@ -9,8 +9,16 @@ namespace Book_Database; +use Book_Database\Models\Book; +use Book_Database\Models\BookLink; +use Book_Database\Models\BookTaxonomy; +use Book_Database\Models\Edition; +use Book_Database\Models\Series; +use Book_Database\ValueObjects\Rating; + /** * Class Book_Layout + * * @package Book_Database */ class Book_Layout { @@ -144,7 +152,7 @@ public function get_field_value( $field ) { } else { // Route all taxonomies not covered to `get_field_taxonomy`. $taxonomy = get_book_taxonomy_by( 'slug', $field ); - if ( $taxonomy instanceof Book_Taxonomy ) { + if ( $taxonomy instanceof BookTaxonomy ) { $value = call_user_func( array( $this, 'get_field_taxonomy' ), $taxonomy ); } } @@ -297,7 +305,7 @@ public function get_field_buy_link() { * Filters the buy link separator. * * @param string $link_separator Separator string between links. - * @param Book_Link[] $links Array of Book_Link objects. + * @param BookLink[] $links Array of Book_Link objects. * @param Book $book Book object. * @param Book_Layout $this Book layout object. * @@ -355,7 +363,7 @@ public function get_field_synopsis() { * * This covers the `source` taxonomy and all custom taxonomies. * - * @param Book_Taxonomy $taxonomy + * @param BookTaxonomy $taxonomy * * @return string */ diff --git a/src/Book_Link.php b/src/Book_Link.php deleted file mode 100644 index a8dff5b5..00000000 --- a/src/Book_Link.php +++ /dev/null @@ -1,86 +0,0 @@ -book_id ); - } - - /** - * Get the ID of the retailer - * - * @return int - */ - public function get_retailer_id() { - return absint( $this->retailer_id ); - } - - /** - * Get the URL - * - * @return string - */ - public function get_url() { - return $this->url; - } - - /** - * Format the book link - * - * @return string - */ - public function format() { - - $retailer = get_retailer( $this->get_retailer_id() ); - - if ( $retailer instanceof Retailer ) { - $html = $retailer->build_link( $this->get_url() ); - } else { - $html = make_clickable( $this->get_url() ); - } - - /** - * Filters the formatted book link - * - * @param string $html Final HTML to be displayed in the book layout. - * @param Retailer $retailer Retailer object. - * @param Book_Link $this Book link object. - */ - return apply_filters( 'book-database/book-link/format', $html, $retailer, $this ); - - } - -} diff --git a/src/Book_Taxonomy.php b/src/Book_Taxonomy.php deleted file mode 100644 index 5c01d8b6..00000000 --- a/src/Book_Taxonomy.php +++ /dev/null @@ -1,51 +0,0 @@ -name; - } - - /** - * Get the slug - * - * @return string - */ - public function get_slug() { - return $this->slug; - } - - /** - * Get the format - either `text` or `checkbox` - * - * @return string - */ - public function get_format() { - return $this->format; - } - -} diff --git a/src/Book_Term.php b/src/Book_Term.php deleted file mode 100644 index 4f4ec6d3..00000000 --- a/src/Book_Term.php +++ /dev/null @@ -1,95 +0,0 @@ -taxonomy; - } - - /** - * Get the name of the term - * - * @return string - */ - public function get_name() { - return $this->name; - } - - /** - * Get the term slug - * - * @return string - */ - public function get_slug() { - return $this->slug; - } - - /** - * Get the description - * - * @return string - */ - public function get_description() { - return $this->description; - } - - /** - * Get the ID of the image attachment - * - * @return int - */ - public function get_image_id() { - return absint( $this->image_id ); - } - - /** - * Get the term links - * - * @return string - */ - public function get_links() { - return $this->links; - } - - /** - * Get the number of books associated with this term - * - * @return int - */ - public function get_book_count() { - return absint( $this->book_count ); - } - -} diff --git a/src/Book_Term_Relationship.php b/src/Book_Term_Relationship.php deleted file mode 100644 index 8e3109dc..00000000 --- a/src/Book_Term_Relationship.php +++ /dev/null @@ -1,40 +0,0 @@ -term_id ); - } - - /** - * Get the book ID - * - * @return int - */ - public function get_book_id() { - return absint( $this->book_id ); - } - -} diff --git a/src/CLI.php b/src/CLI.php index d696a8fc..474ed6af 100644 --- a/src/CLI.php +++ b/src/CLI.php @@ -13,6 +13,10 @@ return; } +use Book_Database\Exceptions\Exception; +use Book_Database\Models\Author; +use Book_Database\Models\Retailer; +use Book_Database\Models\Review; use WP_CLI; WP_CLI::add_command( 'bdb', '\\Book_Database\\CLI' ); diff --git a/src/Database/Authors/AuthorsQuery.php b/src/Database/Authors/AuthorsQuery.php index 2d2228c6..91db7bbc 100644 --- a/src/Database/Authors/AuthorsQuery.php +++ b/src/Database/Authors/AuthorsQuery.php @@ -9,7 +9,7 @@ namespace Book_Database\Database\Authors; -use Book_Database\Author; +use Book_Database\Models\Author; use Book_Database\BerlinDB; /** diff --git a/src/Database/BookAuthor/BookAuthorQuery.php b/src/Database/BookAuthor/BookAuthorQuery.php index 06cbb61c..4145a3cf 100644 --- a/src/Database/BookAuthor/BookAuthorQuery.php +++ b/src/Database/BookAuthor/BookAuthorQuery.php @@ -10,7 +10,7 @@ namespace Book_Database\Database\BookAuthor; use Book_Database\BerlinDB; -use Book_Database\Book_Author_Relationship; +use Book_Database\Models\BookAuthorRelationship; /** * Class Book_Author_Relationships_Query @@ -61,7 +61,7 @@ class BookAuthorQuery extends BerlinDB\Database\Query * * @var string */ - protected $item_shape = Book_Author_Relationship::class; + protected $item_shape = BookAuthorRelationship::class; /** * Group to cache queries and queried items to diff --git a/src/Database/BookLinks/BookLinksQuery.php b/src/Database/BookLinks/BookLinksQuery.php index ce525194..9b2c70a8 100644 --- a/src/Database/BookLinks/BookLinksQuery.php +++ b/src/Database/BookLinks/BookLinksQuery.php @@ -10,7 +10,7 @@ namespace Book_Database\Database\BookLinks; use Book_Database\BerlinDB; -use Book_Database\Book_Link; +use Book_Database\Models\BookLink; /** * Class BookLinksQuery @@ -61,7 +61,7 @@ class BookLinksQuery extends BerlinDB\Database\Query * * @var string */ - protected $item_shape = Book_Link::class; + protected $item_shape = BookLink::class; /** * Group to cache queries and queried items to diff --git a/src/Database/BookTaxonomies/BookTaxonomiesQuery.php b/src/Database/BookTaxonomies/BookTaxonomiesQuery.php index e21665da..33723b6c 100644 --- a/src/Database/BookTaxonomies/BookTaxonomiesQuery.php +++ b/src/Database/BookTaxonomies/BookTaxonomiesQuery.php @@ -11,7 +11,7 @@ namespace Book_Database\Database\BookTaxonomies; use Book_Database\BerlinDB; -use Book_Database\Book_Taxonomy; +use Book_Database\Models\BookTaxonomy; /** * Class Book_Taxonomies_Query @@ -62,7 +62,7 @@ class BookTaxonomiesQuery extends BerlinDB\Database\Query * * @var string */ - protected $item_shape = Book_Taxonomy::class; + protected $item_shape = BookTaxonomy::class; /** * Group to cache queries and queried items to diff --git a/src/Database/BookTerm/BookTermRelationshipQuery.php b/src/Database/BookTerm/BookTermRelationshipQuery.php index b4725822..b44a06fb 100644 --- a/src/Database/BookTerm/BookTermRelationshipQuery.php +++ b/src/Database/BookTerm/BookTermRelationshipQuery.php @@ -10,7 +10,7 @@ namespace Book_Database\Database\BookTerm; use Book_Database\BerlinDB; -use Book_Database\Book_Term_Relationship; +use Book_Database\Models\BookTermRelationship; /** * Class BookTermRelationshipQuery @@ -61,7 +61,7 @@ class BookTermRelationshipQuery extends BerlinDB\Database\Query * * @var string */ - protected $item_shape = Book_Term_Relationship::class; + protected $item_shape = BookTermRelationship::class; /** * Group to cache queries and queried items to diff --git a/src/Database/BookTerms/BookTermsQuery.php b/src/Database/BookTerms/BookTermsQuery.php index 2f375d34..80028dc3 100644 --- a/src/Database/BookTerms/BookTermsQuery.php +++ b/src/Database/BookTerms/BookTermsQuery.php @@ -10,7 +10,7 @@ namespace Book_Database\Database\BookTerms; use Book_Database\BerlinDB; -use Book_Database\Book_Term; +use Book_Database\Models\BookTerm; /** * Class Book_Terms_Query @@ -61,7 +61,7 @@ class BookTermsQuery extends BerlinDB\Database\Query * * @var string */ - protected $item_shape = Book_Term::class; + protected $item_shape = BookTerm::class; /** * Group to cache queries and queried items to diff --git a/src/Database/Books/BooksQuery.php b/src/Database/Books/BooksQuery.php index 5331abe4..071582db 100644 --- a/src/Database/Books/BooksQuery.php +++ b/src/Database/Books/BooksQuery.php @@ -11,7 +11,7 @@ use Book_Database\BerlinDB; use Book_Database\BerlinDB\Database\Queries\Tax; -use Book_Database\Book; +use Book_Database\Models\Book; use Book_Database\Database\Authors\AuthorsQuery; use Book_Database\Database\Editions\EditionsQuery; use Book_Database\Database\ReadingLogs\ReadingLogsQuery; diff --git a/src/Database/Editions/EditionsQuery.php b/src/Database/Editions/EditionsQuery.php index d2f18bd0..7ef11ef4 100644 --- a/src/Database/Editions/EditionsQuery.php +++ b/src/Database/Editions/EditionsQuery.php @@ -10,7 +10,7 @@ namespace Book_Database\Database\Editions; use Book_Database\BerlinDB; -use Book_Database\Edition; +use Book_Database\Models\Edition; /** * Class EditionsQuery diff --git a/src/Database/ReadingLogs/ReadingLogsQuery.php b/src/Database/ReadingLogs/ReadingLogsQuery.php index 104221a0..d0ea9f23 100644 --- a/src/Database/ReadingLogs/ReadingLogsQuery.php +++ b/src/Database/ReadingLogs/ReadingLogsQuery.php @@ -10,7 +10,7 @@ namespace Book_Database\Database\ReadingLogs; use Book_Database\BerlinDB; -use Book_Database\Reading_Log; +use Book_Database\Models\ReadingLog; /** * Class ReadingLogsQuery @@ -61,7 +61,7 @@ class ReadingLogsQuery extends BerlinDB\Database\Query * * @var string */ - protected $item_shape = Reading_Log::class; + protected $item_shape = ReadingLog::class; /** * Group to cache queries and queried items to diff --git a/src/Database/Retailers/RetailersQuery.php b/src/Database/Retailers/RetailersQuery.php index abe9fe52..4c0292c4 100644 --- a/src/Database/Retailers/RetailersQuery.php +++ b/src/Database/Retailers/RetailersQuery.php @@ -10,7 +10,7 @@ namespace Book_Database\Database\Retailers; use Book_Database\BerlinDB; -use Book_Database\Retailer; +use Book_Database\Models\Retailer; /** * Class RetailersQuery diff --git a/src/Database/Reviews/ReviewsQuery.php b/src/Database/Reviews/ReviewsQuery.php index 0aef6fe1..620df6f8 100644 --- a/src/Database/Reviews/ReviewsQuery.php +++ b/src/Database/Reviews/ReviewsQuery.php @@ -15,7 +15,7 @@ use Book_Database\Database\Books\BooksQuery; use Book_Database\Database\Editions\EditionsQuery; use Book_Database\Database\ReadingLogs\ReadingLogsQuery; -use Book_Database\Review; +use Book_Database\Models\Review; use Book_Database\Database\Series\SeriesQuery; use Book_Database\Where_Clause; use function Book_Database\book_database; diff --git a/src/Database/Series/SeriesQuery.php b/src/Database/Series/SeriesQuery.php index a159871a..2a7a0f66 100644 --- a/src/Database/Series/SeriesQuery.php +++ b/src/Database/Series/SeriesQuery.php @@ -10,7 +10,7 @@ namespace Book_Database\Database\Series; use Book_Database\BerlinDB; -use Book_Database\Series; +use Book_Database\Models\Series; /** * Class SeriesQuery diff --git a/src/Deprecated/class-names.php b/src/Deprecated/class-names.php deleted file mode 100644 index 27100f21..00000000 --- a/src/Deprecated/class-names.php +++ /dev/null @@ -1,47 +0,0 @@ -book_id ); - } - - /** - * Get the ISBN - * - * @return string - */ - public function get_isbn() { - return $this->isbn; - } - - /** - * Get the format (ebook, hardback, etc.) - * - * @return string - */ - public function get_format() { - return $this->format; - } - - /** - * Get the date the book was acquired - * - * @param bool $formatted Whether or not to format the date for display. - * @param string $format Format to display the formatted date in. Default to site format. - * - * @return string|null - */ - public function get_date_acquired( $formatted = false, $format = '' ) { - return ( ! empty( $this->date_acquired ) && $formatted ) ? format_date( $this->date_acquired, $format ) : $this->date_acquired; - } - - /** - * Get the ID of the source term - * - * @return int|null - */ - public function get_source_id() { - return ! empty( $this->source_id ) ? absint( $this->source_id ) : null; - } - - /** - * Whether or not the book is signed - * - * @return bool - */ - public function is_signed() { - return ! empty( $this->signed ); - } - - /** - * Export properties - * - * @return array - */ - public function export_vars() { - $vars = parent::export_vars(); - $vars['format_name'] = get_book_formats()[ $this->get_format() ] ?? ''; - - if ( $this->get_source_id() ) { - $source = get_book_term( $this->get_source_id() ); - - if ( $source instanceof Book_Term ) { - $vars['source_name'] = $source->get_name(); - } - } - - return $vars; - } - -} diff --git a/src/Exception.php b/src/Exception.php deleted file mode 100644 index ad9f7224..00000000 --- a/src/Exception.php +++ /dev/null @@ -1,45 +0,0 @@ -error_type = $error_type; - - parent::__construct( $message, $code_number, $previous ); - - } - - /** - * Get the error type - * - * @return string - */ - public function get_error_type() { - return $this->error_type; - } - -} diff --git a/src/Exceptions/Exception.php b/src/Exceptions/Exception.php new file mode 100644 index 00000000..e2c97814 --- /dev/null +++ b/src/Exceptions/Exception.php @@ -0,0 +1,48 @@ +error_type = $error_type; + + parent::__construct($message, $code_number, $previous); + } + + /** + * Get the error type + * + * @return string + */ + public function get_error_type(): string + { + return $this->error_type; + } + +} diff --git a/src/HTML.php b/src/HTML.php deleted file mode 100644 index 5971a278..00000000 --- a/src/HTML.php +++ /dev/null @@ -1,127 +0,0 @@ - '', - 'field' => '', - 'id' => '' - ) ); - ?> -
- -
- -
-
- array(), - 'number' => 300, - 'id' => '' - ) ); - - if ( ! $taxonomy instanceof Book_Taxonomy ) { - $taxonomy = get_book_taxonomy_by( 'slug', $taxonomy ); - } - - if ( ! $taxonomy instanceof Book_Taxonomy ) { - return; - } - - if ( 'checkbox' === $taxonomy->get_format() ) { - - // "Categories" - - // Get all terms EXCEPT the ones already checked. - $all_terms = get_book_terms( array( - 'number' => 300, - 'taxonomy' => $taxonomy->get_slug(), - 'name__not_in' => $args['selected'], - 'fields' => 'name', - 'orderby' => 'name', - 'order' => 'ASC' - ) ); - - $final_terms = $args['selected'] + $all_terms; - ?> -
-
- - - -
-
- - - -
-
- -
-
-
- - -
-
-

- - - -

-
-
-
-
- '', + 'field' => '', + 'id' => '' + )); + ?> +
+ +
+ +
+
+ array(), + 'number' => 300, + 'id' => '' + )); + + if (! $taxonomy instanceof BookTaxonomy) { + $taxonomy = get_book_taxonomy_by('slug', $taxonomy); + } + + if (! $taxonomy instanceof BookTaxonomy) { + return; + } + + if ('checkbox' === $taxonomy->get_format()) { + + // "Categories" + + // Get all terms EXCEPT the ones already checked. + $all_terms = get_book_terms(array( + 'number' => 300, + 'taxonomy' => $taxonomy->get_slug(), + 'name__not_in' => $args['selected'], + 'fields' => 'name', + 'orderby' => 'name', + 'order' => 'ASC' + )); + + $final_terms = $args['selected'] + $all_terms; + ?> +
+
+ + + +
+
+ + + +
+
+ +
+
+
+ + +
+
+

+ + + +

+
+
+
+
+ name; + } + + /** + * Get the author slug + * + * @return string + */ + public function get_slug(): string + { + return $this->slug; + } + + /** + * Get the author description + * + * @return string + */ + public function get_description(): string + { + return $this->description; + } + + /** + * Get the ID of the image attachment + * + * @return int + */ + public function get_image_id(): int + { + return ! empty($this->image_id) ? absint($this->image_id) : 0; + } + + /** + * Get the author image URL + * + * @param string $size Desired image size. + * + * @return string + */ + public function get_image_url(string $size = 'full'): string + { + + $url = ''; + $image_id = $this->get_image_id(); + + if (! empty($image_id)) { + $url = wp_get_attachment_image_url($image_id, $size); + } + + return apply_filters('book-database/author/get/image_url', $url, $image_id, $this); + + } + + /** + * Get the author image HTML. + * + * @param string|array $size Desired image size. + * @param array $args Arguments to use in `wp_get_attachment_image()`. + * + * @return string + */ + public function get_image($size = 'full', array $args = array()): string + { + + $image = ''; + $image_id = $this->get_image_id(); + + if ($image_id) { + $image = wp_get_attachment_image(absint($image_id), $size, false, $args); + } + + return apply_filters('book-database/author/get/image', $image, $image_id, $this); + + } + + /** + * Get an array of author links + * + * @return array() + */ + public function get_links(): array + { + return $this->links; + } + + /** + * Get the number of books by this author + * + * @return int + */ + public function get_book_count(): int + { + return absint($this->book_count); + } + +} diff --git a/src/Models/Book.php b/src/Models/Book.php new file mode 100644 index 00000000..dd0257cb --- /dev/null +++ b/src/Models/Book.php @@ -0,0 +1,375 @@ +cover_id); + } + + /** + * Get the cover image URL + * + * @param string $size Desired image size. + * + * @return string + */ + public function get_cover_url(string $size = 'full'): string + { + + $url = ''; + $cover_id = $this->get_cover_id(); + + if (! empty($cover_id)) { + $url = wp_get_attachment_image_url($cover_id, $size); + } + + return apply_filters('book-database/book/get/cover_url', $url, $cover_id, $this); + + } + + /** + * Get the cover image HTML. + * + * @param string|array $size Desired image size. + * @param array $args Arguments to use in `wp_get_attachment_image()`. + * + * @return string + */ + public function get_cover($size = 'full', array $args = array()): string + { + + $image = ''; + $cover_id = $this->get_cover_id(); + + if ($cover_id) { + $image = wp_get_attachment_image(absint($cover_id), $size, false, $args); + } + + return apply_filters('book-database/book/get/cover', $image, $cover_id, $this); + + } + + /** + * Get the title of the book + * + * @return string + */ + public function get_title(): string + { + return $this->title; + } + + /** + * Get the index-friendly title + * + * This moves "The", "An", and "A" to the end of the title. Example: + * `Binding, The` + * + * @return string + */ + public function get_index_title(): string + { + return $this->index_title; + } + + /** + * Get the authors of the book + * + * This returns an array of `Author` objects. + * + * @param array $args Query args to override the defaults. + * + * @return Author[]|array + */ + public function get_authors(array $args = array()): array + { + + if (! isset($this->authors)) { + $this->authors = get_attached_book_authors($this->get_id(), $args); + } + + return $this->authors; + + } + + /** + * Get the author names + * + * @param bool $implode True to return a comma-separated list, false to return an array. + * + * @return array|string + */ + public function get_author_names(bool $implode = false) + { + + $author_names = array(); + $author_terms = $this->get_authors(); + + if ($author_terms) { + foreach ($author_terms as $author_term) { + $author_names[] = $author_term->get_name(); + } + } + + if ($implode) { + $author_names = implode(', ', $author_names); + } + + return $author_names; + + } + + /** + * Get the ID of the series this book is in + * + * @return int|null + */ + public function get_series_id(): ?int + { + return ! empty($this->series_id) ? absint($this->series_id) : null; + } + + /** + * Get the position in the series + * + * @return int|float|null + */ + public function get_series_position() + { + return $this->series_position ?? null; + } + + /** + * Get the name of the series + * + * @return string|false Series name on success, false on failure. + */ + public function get_series_name() + { + + $series = get_book_series_by('id', $this->get_series_id()); + + if ($series instanceof Series) { + return $series->get_name(); + } + + return false; + + } + + /** + * Get the book's publication date + * + * @param bool $formatted Whether or not to format the result for display. + * Unlike other dates, this DOES NOT convert the date + * to local time. We keep it in UTC always. + * @param string $format Format to display in. Defaults to site format. + * + * @return string + */ + public function get_pub_date(bool $formatted = false, string $format = ''): string + { + + if (empty($this->pub_date) || ! $formatted) { + return $this->pub_date; + } + + $format = ! empty($format) ? $format : get_option('date_format'); + + return date($format, strtotime($this->pub_date)); + + } + + /** + * Get the number of pages in the book + * + * @return int|null + */ + public function get_pages(): ?int + { + return ! empty($this->pages) ? absint($this->pages) : null; + } + + /** + * Get the synopsis + * + * @return string + */ + public function get_synopsis(): string + { + return $this->synopsis; + } + + /** + * Get the Goodreads URL + * + * @return string + */ + public function get_goodreads_url(): string + { + return $this->goodreads_url; + } + + /** + * Get the links associated with this book + * + * @return BookLink[] + */ + public function get_links(): array + { + + if (! isset($this->links)) { + $this->links = get_book_links(array( + 'book_id' => $this->get_id(), + 'number' => 30 + )); + } + + return $this->links; + + } + + /** + * Get the average rating from all reading logs associated with this book + * + * @return int|float|null + */ + public function get_average_rating() + { + global $wpdb; + + $log_table = book_database()->get_table('reading_log')->get_table_name(); + + $query = $wpdb->prepare("SELECT ROUND( AVG( rating ), 2 ) FROM {$log_table} WHERE book_id = %d AND rating IS NOT NULL", + $this->get_id()); + $average = $wpdb->get_var($query); + + /** + * Filters the average rating for a book. + * + * @param int|float|null $average Average rating. + * @param int $book_id ID of the book. + * @param Book $this Book object. + */ + return apply_filters('book-database/book/get/average-rating', $average, $this->get_id(), $this); + } + + /** + * Whether or not the book has a term attached. + * + * @param string|int $term_name_or_id Term name or ID. + * @param string $taxonomy Taxonomy slug. + * + * @return bool + */ + public function has_term($term_name_or_id, string $taxonomy): bool + { + $args = array(); + + if (is_numeric($term_name_or_id)) { + $args['fields'] = 'id'; + } else { + $args['fields'] = 'name'; + } + + $terms = get_attached_book_terms($this->get_id(), $taxonomy, $args); + + return in_array($term_name_or_id, $terms); + } + + /** + * Returns all data associated with a book + * + * @return array + */ + public function get_data(): array + { + $data = array( + 'id' => $this->get_id(), + 'cover_id' => $this->get_cover_id(), + 'cover_url' => $this->get_cover_url('full'), + 'title' => $this->get_title(), + 'index_title' => $this->get_index_title(), + 'authors' => $this->get_authors(), + 'series_id' => $this->get_series_id(), + 'series_name' => $this->get_series_name(), + 'series_position' => $this->get_series_position(), + 'pub_date' => $this->get_pub_date(), + 'pages' => $this->get_pages(), + 'synopsis' => $this->get_synopsis(), + 'goodreads_url' => $this->get_goodreads_url(), + 'links' => $this->get_links(), + 'terms' => array(), + 'date_created' => $this->get_date_created(), + 'date_modified' => $this->get_date_modified() + ); + + // Attach all terms. + foreach (get_book_taxonomies(array('field' => 'slug')) as $taxonomy) { + $data['terms'][$taxonomy] = get_attached_book_terms($this->get_id(), $taxonomy); + } + + /** + * Filters the data. + * + * @param array $data + * @param int $book_id + * @param Book $this + */ + return apply_filters('book-database/book/get/data', $data, $this->get_id(), $this); + } + +} diff --git a/src/Models/BookAuthorRelationship.php b/src/Models/BookAuthorRelationship.php new file mode 100644 index 00000000..f58f1d01 --- /dev/null +++ b/src/Models/BookAuthorRelationship.php @@ -0,0 +1,45 @@ +author_id); + } + + /** + * Get the book ID + * + * @return int + */ + public function get_book_id(): int + { + return absint($this->book_id); + } + +} diff --git a/src/Models/BookLink.php b/src/Models/BookLink.php new file mode 100644 index 00000000..94df846a --- /dev/null +++ b/src/Models/BookLink.php @@ -0,0 +1,94 @@ +book_id); + } + + /** + * Get the ID of the retailer + * + * @return int + */ + public function get_retailer_id(): int + { + return absint($this->retailer_id); + } + + /** + * Get the URL + * + * @return string + */ + public function get_url(): string + { + return $this->url; + } + + /** + * Format the book link + * + * @return string + */ + public function format(): string + { + $retailer = get_retailer($this->get_retailer_id()); + + if ($retailer instanceof Retailer) { + $html = $retailer->build_link($this->get_url()); + } else { + $html = make_clickable($this->get_url()); + } + + /** + * Filters the formatted book link + * + * @param string $html Final HTML to be displayed in the book layout. + * @param Retailer $retailer Retailer object. + * @param BookLink $this Book link object. + */ + return apply_filters('book-database/book-link/format', $html, $retailer, $this); + } + +} diff --git a/src/Models/BookTaxonomy.php b/src/Models/BookTaxonomy.php new file mode 100644 index 00000000..67d4358c --- /dev/null +++ b/src/Models/BookTaxonomy.php @@ -0,0 +1,57 @@ +name; + } + + /** + * Get the slug + * + * @return string + */ + public function get_slug(): string + { + return $this->slug; + } + + /** + * Get the format - either `text` or `checkbox` + * + * @return string + */ + public function get_format(): string + { + return $this->format; + } + +} diff --git a/src/Models/BookTerm.php b/src/Models/BookTerm.php new file mode 100644 index 00000000..e87b9fb1 --- /dev/null +++ b/src/Models/BookTerm.php @@ -0,0 +1,108 @@ +taxonomy; + } + + /** + * Get the name of the term + * + * @return string + */ + public function get_name(): string + { + return $this->name; + } + + /** + * Get the term slug + * + * @return string + */ + public function get_slug(): string + { + return $this->slug; + } + + /** + * Get the description + * + * @return string + */ + public function get_description(): string + { + return $this->description; + } + + /** + * Get the ID of the image attachment + * + * @return int + */ + public function get_image_id(): int + { + return absint($this->image_id); + } + + /** + * Get the term links + * + * @return string + */ + public function get_links(): array + { + return $this->links; + } + + /** + * Get the number of books associated with this term + * + * @return int + */ + public function get_book_count(): int + { + return absint($this->book_count); + } + +} diff --git a/src/Models/BookTermRelationship.php b/src/Models/BookTermRelationship.php new file mode 100644 index 00000000..e9429b9e --- /dev/null +++ b/src/Models/BookTermRelationship.php @@ -0,0 +1,45 @@ +term_id); + } + + /** + * Get the book ID + * + * @return int + */ + public function get_book_id(): int + { + return absint($this->book_id); + } + +} diff --git a/src/Models/Edition.php b/src/Models/Edition.php new file mode 100644 index 00000000..9c090dae --- /dev/null +++ b/src/Models/Edition.php @@ -0,0 +1,123 @@ +book_id); + } + + /** + * Get the ISBN + * + * @return string + */ + public function get_isbn(): string + { + return $this->isbn; + } + + /** + * Get the format (ebook, hardback, etc.) + * + * @return string + */ + public function get_format(): string + { + return $this->format; + } + + /** + * Get the date the book was acquired + * + * @param bool $formatted Whether or not to format the date for display. + * @param string $format Format to display the formatted date in. Default to site format. + * + * @return string|null + */ + public function get_date_acquired(bool $formatted = false, string $format = ''): ?string + { + return (! empty($this->date_acquired) && $formatted) + ? format_date($this->date_acquired, $format) + : $this->date_acquired; + } + + /** + * Get the ID of the source term + * + * @return int|null + */ + public function get_source_id(): ?int + { + return ! empty($this->source_id) ? absint($this->source_id) : null; + } + + /** + * Whether or not the book is signed + * + * @return bool + */ + public function is_signed(): bool + { + return ! empty($this->signed); + } + + /** + * Export properties + * + * @return array + */ + public function export_vars(): array + { + $vars = parent::export_vars(); + $vars['format_name'] = get_book_formats()[$this->get_format()] ?? ''; + + if ($this->get_source_id()) { + $source = get_book_term($this->get_source_id()); + + if ($source instanceof BookTerm) { + $vars['source_name'] = $source->get_name(); + } + } + + return $vars; + } + +} diff --git a/src/Models/Model.php b/src/Models/Model.php new file mode 100644 index 00000000..15b7eabb --- /dev/null +++ b/src/Models/Model.php @@ -0,0 +1,119 @@ +set_vars($args); + } + + /** + * Set class properties from arguments + * + * @param array $args + */ + protected function set_vars($args = array()) + { + + // Bail if empty. + if (empty($args)) { + return; + } + + // Cast to an array. + if (! is_array($args)) { + $args = (array) $args; + } + + foreach ($args as $key => $value) { + if ('0000-00-00 00:00:00' === $value) { + $value = null; + } + + $this->{$key} = $value; + } + + } + + /** + * Get the ID + * + * @return int + */ + public function get_id(): int + { + return absint($this->id); + } + + /** + * Get the created date + * + * @param bool $formatted Whether or not to format the result for display. + * @param string $format Format to display in. Defaults to site format. + * + * @return string + */ + public function get_date_created(bool $formatted, string $format = ''): string + { + return (! empty($this->date_created) && $formatted) + ? format_date($this->date_created, $format) + : $this->date_created; + } + + /** + * Get the modified date + * + * @param bool $formatted Whether or not to format the result for display. + * @param string $format Format to display in. Defaults to site format. + * + * @return string + */ + public function get_date_modified(bool $formatted = false, string $format = ''): string + { + return (! empty($this->date_modified) && $formatted) + ? format_date($this->date_modified, $format) + : $this->date_modified; + } + + /** + * Get all object properties as an array + * + * @return array + */ + public function export_vars(): array + { + return get_object_vars($this); + } + +} diff --git a/src/Models/ReadingLog.php b/src/Models/ReadingLog.php new file mode 100644 index 00000000..cbabbfa4 --- /dev/null +++ b/src/Models/ReadingLog.php @@ -0,0 +1,189 @@ +book_id); + } + + /** + * Get the ID of the associated edition + * + * @return int|null + */ + public function get_edition_id(): ?int + { + return ! empty($this->edition_id) ? absint($this->edition_id) : null; + } + + /** + * Get the ID of the user who made this entry + * + * @return int + */ + public function get_user_id(): int + { + return absint($this->user_id); + } + + /** + * Get the date the user started reading + * + * @param bool $formatted Whether or not to format the result for display. + * @param string $format Format to display in. Defaults to site format. + * + * @return string + */ + public function get_date_started(bool $formatted = false, string $format = ''): string + { + return (! empty($this->date_started) && $formatted) + ? format_date($this->date_started, $format) + : $this->date_started; + } + + /** + * Get the date the user finished reading + * + * @param bool $formatted Whether or not to format the result for display. + * @param string $format Format to display in. Defaults to site format. + * + * @return string + */ + public function get_date_finished(bool $formatted = false, string $format = ''): string + { + return (! empty($this->date_finished) && $formatted) + ? format_date($this->date_finished, $format) + : $this->date_finished; + } + + /** + * Get the percentage complete + * + * Note: This is the `percentage_complete` value multiplied by 100. + * + * @return float|int + */ + public function get_percentage_complete() + { + $percentage = floatval($this->percentage_complete); + + if ($percentage >= 1) { + $percentage = 1; + } elseif ($percentage <= 0) { + $percentage = 0; + } + + return round($percentage * 100, 2); + } + + /** + * Whether or not the book has been fully read + * + * @return bool + */ + public function is_complete(): bool + { + return $this->get_percentage_complete() >= 100; + } + + /** + * A book is "DNF" (didn't finish) if there's a finished date but the percentage is less than 100%. + * + * @return bool + */ + public function is_dnf(): bool + { + return ! empty($this->get_date_finished()) && ! $this->is_complete(); + } + + /** + * Get the rating + * + * @return float|null + */ + public function get_rating() + { + return $this->rating; + } + + /** + * Export vars + * + * @return array + */ + public function export_vars(): array + { + + $vars = parent::export_vars(); + + $vars['is_complete'] = $this->is_complete(); + $vars['is_dnf'] = $this->is_dnf(); + + // Get the edition. + $edition = $this->get_edition_id() ? get_edition($this->get_edition_id()) : null; + $vars['edition'] = $edition instanceof Edition ? $edition->export_vars() : null; + + // Get the review ID. + $review = get_review_by('reading_log_id', $this->get_id()); + if ($review instanceof Review) { + $vars['review_id'] = $review->get_id(); + } + + // Calculate the page number we're on. + $vars['page'] = 0; + $vars['max_pages'] = 0; + $book = get_book($this->get_book_id()); + if ($book instanceof Book) { + $percentage = $this->get_percentage_complete() / 100; + $vars['page'] = round($percentage * $book->get_pages()); + $vars['max_pages'] = $book->get_pages(); + } + + return $vars; + + } + +} diff --git a/src/Models/Retailer.php b/src/Models/Retailer.php new file mode 100644 index 00000000..2aa1fa17 --- /dev/null +++ b/src/Models/Retailer.php @@ -0,0 +1,75 @@ +name; + } + + /** + * Get the template + * + * @return string + */ + public function get_template(): string + { + return $this->template; + } + + /** + * Build a link + * + * This injects the provided URL into the template, replacing the `[url]` placeholder. + * + * @param string $url + * + * @return string + */ + public function build_link(string $url): string + { + + $template = $this->get_template(); + + if (empty($template)) { + $template = ''.esc_html($this->get_name()).''; + } + + return str_replace('[url]', esc_url($url), $template); + + } + +} diff --git a/src/Models/Review.php b/src/Models/Review.php new file mode 100644 index 00000000..1708dade --- /dev/null +++ b/src/Models/Review.php @@ -0,0 +1,233 @@ +book_id); + } + + /** + * Get the ID of the user who wrote the review + * + * @return int|null + */ + public function get_reading_log_id(): ?int + { + return is_null($this->reading_log_id) ? null : absint($this->reading_log_id); + } + + /** + * Get the ID of the user who wrote the review + * + * @return int + */ + public function get_user_id(): int + { + return absint($this->user_id); + } + + /** + * Get the ID of the corresponding post + * + * This is the post the review was published on. This will only be filled out if the + * review was published as a blog post on this site. + * + * @return int|null + */ + public function get_post_id(): ?int + { + return is_null($this->post_id) ? null : absint($this->post_id); + } + + /** + * Get the URL of the review + * + * This will only be filled out if the review is external. + * + * @return string + */ + public function get_url(): string + { + return $this->url; + } + + /** + * Whether or not this is an external review + * + * Will return true if `url` is filled out. + * + * @return bool + */ + public function is_external(): bool + { + return ! empty($this->get_url()); + } + + /** + * Get the review text + * + * @return string + */ + public function get_review(): string + { + return $this->review; + } + + /** + * Get the date the review was written + * + * @param bool $formatted Whether or not to format the result for display. + * @param string $format Format to display in. Defaults to site format. + * + * @return string + */ + public function get_date_written(bool $formatted = false, string $format = ''): string + { + return (! empty($this->date_written) && $formatted) + ? format_date($this->date_written, $format) + : $this->date_written; + } + + /** + * Get the date the review was (or will be) published + * + * @param bool $formatted Whether or not to format the result for display. + * @param string $format Format to display in. Defaults to site format. + * + * @return string|null + */ + public function get_date_published(bool $formatted = false, string $format = ''): ?string + { + return (! empty($this->date_published) && $formatted) + ? format_date($this->date_published, $format) + : $this->date_published; + } + + /** + * Get the review permalink + * + * Returns the URL to the external review if provided, otherwise the URL to the post where + * the review is located. Returns false if all else fails. + * + * @param bool $use_id Whether or not to build the URL with the post ID (ugly permalinks). + * @param bool $id_appended Whether or not to includle a "skip-to" the book ID. + * + * @return string|false + */ + public function get_permalink(bool $use_id = true, bool $id_appended = true) + { + $url = false; + + if ($this->is_external()) { + $url = $this->get_url(); + } elseif ($this->get_post_id() && $use_id) { + $url = add_query_arg(array('p' => urlencode($this->get_post_id())), home_url('/')); + } elseif ($this->get_post_id()) { + $url = get_permalink($this->get_post_id()); + } + + if ($id_appended && ! empty($url) && ! $this->is_external()) { + $url .= '#book-'.urlencode($this->get_book_id()); + } + + /** + * Filters the review permalink. + * + * @param string|false $url URL to the review. + * @param bool $use_id Whether or not to build the URL with the post ID (ugly permalinks). + * @param bool $id_appended Whether or not to includle a "skip-to" the book ID. + * @param Review $this Review object. + */ + return apply_filters('book-database/review/get/permalink', $url, $use_id, $id_appended, $this); + } + + /** + * Whether or not the review has been published + * + * Returns `true` if the review is external, or if the review published date is in the past. + * Returns `false` f the review is associated with a post and that post is not "published". + * + * @return bool + */ + public function is_published(): bool + { + if ($this->is_external()) { + return true; + } + + if ($this->get_post_id()) { + $post = get_post($this->get_post_id()); + + if ($post instanceof \WP_Post && 'publish' !== $post->post_status) { + return false; + } + } + + return ($this->get_date_published(true, 'U') <= current_time('timestamp')); + } + +} diff --git a/src/Models/Series.php b/src/Models/Series.php new file mode 100644 index 00000000..04dc7c50 --- /dev/null +++ b/src/Models/Series.php @@ -0,0 +1,146 @@ +name; + } + + /** + * Get the series slug + * + * @return string + */ + public function get_slug(): string + { + return $this->slug; + } + + /** + * Get the series description + * + * @return string + */ + public function get_description(): string + { + return $this->description; + } + + /** + * Get the number of books in the series + * + * Note: This is not the number of books present in the database with this series, but + * rather the number of books PLANNED to be in the series. So if the series is a trilogy + * but there's only one book in the database, this would return `3` because there are 3 + * books planned in the series. It's the length of the series. + * + * @return int + */ + public function get_number_books(): int + { + if (empty($this->number_books)) { + $this->number_books = count_books(array('series_id' => $this->get_id())); + } + + return absint($this->number_books); + } + + /** + * Get the number of books in this series that have been read + * + * @return int + */ + public function get_number_books_read(): int + { + global $wpdb; + + $log_table = book_database()->get_table('reading_log')->get_table_name(); + $book_table = book_database()->get_table('books')->get_table_name(); + + $query = $wpdb->prepare( + "SELECT COUNT( DISTINCT book_id ) + FROM {$log_table} log + INNER JOIN {$book_table} b ON log.book_id = b.id + WHERE series_id = %d + AND date_finished IS NOT NULL + AND user_id = %d", + $this->get_id(), + get_current_user_id() + ); + $number_read = $wpdb->get_var($query); + + return absint($number_read); + } + + /** + * Get the books in this series + * + * @param array $args + * + * @return Book[] + */ + public function get_books_in_series(array $args = array()): array + { + $args = wp_parse_args($args, array( + 'series_id' => $this->get_id(), + 'number' => 50, + 'orderby' => 'series_position', + 'order' => 'ASC' + )); + + return get_books($args); + } + + /** + * Get the average rating of all books in this series + */ + public function get_average_rating(): float + { + global $wpdb; + + $log_table = book_database()->get_table('reading_log')->get_table_name(); + $book_table = book_database()->get_table('books')->get_table_name(); + + $query = $wpdb->prepare( + "SELECT ROUND( AVG( rating ), 2 ) FROM {$log_table} log INNER JOIN {$book_table} b ON log.book_id = b.id WHERE series_id = %d AND rating IS NOT NULL", + $this->get_id() + ); + + return (float) $wpdb->get_var($query); + } + +} diff --git a/src/Plugin.php b/src/Plugin.php index 39a7acc2..d36f2f74 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -26,6 +26,9 @@ use Book_Database\Database\Reviews\ReviewMetaTable; use Book_Database\Database\Reviews\ReviewsTable; use Book_Database\Database\Series\SeriesTable; +use Book_Database\Exceptions\Exception; +use Book_Database\Helpers\HTML; +use Book_Database\ServiceProviders\ApiServiceProvider; use Book_Database\ServiceProviders\LegacyServiceProvider; use Book_Database\ServiceProviders\ServiceProvider; @@ -49,6 +52,7 @@ final class Plugin */ private $serviceProviders = [ LegacyServiceProvider::class, + ApiServiceProvider::class, ]; /** diff --git a/src/REST_API.php b/src/REST_API.php deleted file mode 100644 index d8054c68..00000000 --- a/src/REST_API.php +++ /dev/null @@ -1,55 +0,0 @@ -register_routes(); - } - } - -} diff --git a/src/REST_API/RouteRegistration.php b/src/REST_API/RouteRegistration.php new file mode 100644 index 00000000..7e3329ec --- /dev/null +++ b/src/REST_API/RouteRegistration.php @@ -0,0 +1,53 @@ +register_routes(); + } + } + +} diff --git a/src/REST_API/v1/Analytics.php b/src/REST_API/v1/Analytics.php index 6eaeb497..0c910aa8 100644 --- a/src/REST_API/v1/Analytics.php +++ b/src/REST_API/v1/Analytics.php @@ -9,7 +9,7 @@ namespace Book_Database\REST_API\v1; -use Book_Database\Exception; +use Book_Database\Exceptions\Exception; use Book_Database\REST_API\Controller; use function Book_Database\Analytics\get_dataset_value; use function Book_Database\Analytics\get_date_filter_range; @@ -129,7 +129,7 @@ public function get_analytics( $request ) { $stat_types = $request->get_param( 'stats' ); $stats = array(); - $analytics = new \Book_Database\Analytics( $request->get_param( 'start_date' ), $request->get_param( 'end_date' ), $request->get_param( 'args' ) ); + $analytics = new \Book_Database\Analytics\Analytics( $request->get_param( 'start_date' ), $request->get_param( 'end_date' ), $request->get_param( 'args' ) ); foreach ( $stat_types as $stat_type ) { $method = 'get_' . str_replace( '-', '_', $stat_type ); diff --git a/src/REST_API/v1/Author.php b/src/REST_API/v1/Author.php index ea728fc1..033395fb 100644 --- a/src/REST_API/v1/Author.php +++ b/src/REST_API/v1/Author.php @@ -9,7 +9,7 @@ namespace Book_Database\REST_API\v1; -use Book_Database\Exception; +use Book_Database\Exceptions\Exception; use Book_Database\REST_API\Controller; use function Book_Database\get_book_authors; diff --git a/src/REST_API/v1/Book.php b/src/REST_API/v1/Book.php index 717ff294..734b3376 100644 --- a/src/REST_API/v1/Book.php +++ b/src/REST_API/v1/Book.php @@ -10,7 +10,7 @@ namespace Book_Database\REST_API\v1; use Book_Database\Database\Books\BooksQuery; -use Book_Database\Exception; +use Book_Database\Exceptions\Exception; use Book_Database\REST_API\Controller; use function Book_Database\add_book; use function Book_Database\book_grid_shortcode; diff --git a/src/REST_API/v1/Book_Link.php b/src/REST_API/v1/Book_Link.php index 87844f96..7647c7dc 100644 --- a/src/REST_API/v1/Book_Link.php +++ b/src/REST_API/v1/Book_Link.php @@ -9,7 +9,7 @@ namespace Book_Database\REST_API\v1; -use Book_Database\Exception; +use Book_Database\Exceptions\Exception; use Book_Database\REST_API\Controller; use function Book_Database\add_book_link; use function Book_Database\delete_book_link; diff --git a/src/REST_API/v1/Book_Term.php b/src/REST_API/v1/Book_Term.php index 797df0f9..740e408b 100644 --- a/src/REST_API/v1/Book_Term.php +++ b/src/REST_API/v1/Book_Term.php @@ -9,7 +9,7 @@ namespace Book_Database\REST_API\v1; -use Book_Database\Exception; +use Book_Database\Exceptions\Exception; use Book_Database\REST_API\Controller; use function Book_Database\get_book_terms; diff --git a/src/REST_API/v1/Edition.php b/src/REST_API/v1/Edition.php index dcfc2fd4..afc21dc3 100644 --- a/src/REST_API/v1/Edition.php +++ b/src/REST_API/v1/Edition.php @@ -9,7 +9,7 @@ namespace Book_Database\REST_API\v1; -use Book_Database\Exception; +use Book_Database\Exceptions\Exception; use Book_Database\REST_API\Controller; use function Book_Database\add_book_term; use function Book_Database\add_edition; @@ -140,7 +140,7 @@ public function register_routes() { } if ( is_numeric( $param ) ) { - return get_book_term( $param ) instanceof \Book_Database\Book_Term; + return get_book_term( $param ) instanceof \Book_Database\Models\BookTerm; } return true; @@ -168,7 +168,7 @@ public function register_routes() { $source = get_book_term( $source_id ); } - if ( ! isset( $source ) || ! $source instanceof \Book_Database\Book_Term ) { + if ( ! isset( $source ) || ! $source instanceof \Book_Database\Models\BookTerm ) { throw new \Exception(); } @@ -239,7 +239,7 @@ public function register_routes() { } if ( is_numeric( $param ) ) { - return get_book_term( $param ) instanceof \Book_Database\Book_Term; + return get_book_term( $param ) instanceof \Book_Database\Models\BookTerm; } return true; @@ -267,7 +267,7 @@ public function register_routes() { $source = get_book_term( $source_id ); } - if ( ! isset( $source ) || ! $source instanceof \Book_Database\Book_Term ) { + if ( ! isset( $source ) || ! $source instanceof \Book_Database\Models\BookTerm ) { throw new \Exception(); } diff --git a/src/REST_API/v1/Reading_Log.php b/src/REST_API/v1/Reading_Log.php index 270483db..47756704 100644 --- a/src/REST_API/v1/Reading_Log.php +++ b/src/REST_API/v1/Reading_Log.php @@ -9,7 +9,7 @@ namespace Book_Database\REST_API\v1; -use Book_Database\Exception; +use Book_Database\Exceptions\Exception; use Book_Database\REST_API\Controller; use function Book_Database\add_reading_log; use function Book_Database\delete_reading_log; @@ -114,7 +114,7 @@ public function register_routes() { return false; } - return get_edition( absint( $param ) ) instanceof \Book_Database\Edition; + return get_edition( absint( $param ) ) instanceof \Book_Database\Models\Edition; }, 'sanitize_callback' => function ( $param, $request, $key ) { return ! empty( absint( $param ) ) ? absint( $param ) : null; @@ -207,7 +207,7 @@ public function register_routes() { return false; } - return get_edition( absint( $param ) ) instanceof \Book_Database\Edition; + return get_edition( absint( $param ) ) instanceof \Book_Database\Models\Edition; }, 'sanitize_callback' => function ( $param, $request, $key ) { return ! empty( absint( $param ) ) ? absint( $param ) : null; diff --git a/src/REST_API/v1/Retailer.php b/src/REST_API/v1/Retailer.php index 84b2fec3..a4187ec4 100644 --- a/src/REST_API/v1/Retailer.php +++ b/src/REST_API/v1/Retailer.php @@ -9,7 +9,7 @@ namespace Book_Database\REST_API\v1; -use Book_Database\Exception; +use Book_Database\Exceptions\Exception; use Book_Database\REST_API\Controller; use function Book_Database\add_retailer; use function Book_Database\delete_retailer; diff --git a/src/REST_API/v1/Review.php b/src/REST_API/v1/Review.php index 0d515914..ba6508ea 100644 --- a/src/REST_API/v1/Review.php +++ b/src/REST_API/v1/Review.php @@ -9,8 +9,8 @@ namespace Book_Database\REST_API\v1; -use Book_Database\Exception; -use Book_Database\Rating; +use Book_Database\Exceptions\Exception; +use Book_Database\ValueObjects\Rating; use Book_Database\REST_API\Controller; use function Book_Database\add_review; use function Book_Database\delete_review; diff --git a/src/REST_API/v1/Series.php b/src/REST_API/v1/Series.php index 486a036f..13c76c84 100644 --- a/src/REST_API/v1/Series.php +++ b/src/REST_API/v1/Series.php @@ -9,7 +9,7 @@ namespace Book_Database\REST_API\v1; -use Book_Database\Exception; +use Book_Database\Exceptions\Exception; use Book_Database\REST_API\Controller; use function Book_Database\add_book_series; use function Book_Database\delete_book_series; @@ -81,7 +81,7 @@ public function register_routes() { 'validate_callback' => function ( $param, $request, $key ) { $series = get_book_series_by( 'id', $param ); - return $series instanceof \Book_Database\Series; + return $series instanceof \Book_Database\Models\Series; }, 'sanitize_callback' => function ( $param, $request, $key ) { return absint( $param ); @@ -124,7 +124,7 @@ public function register_routes() { 'validate_callback' => function ( $param, $request, $key ) { $series = get_book_series_by( 'id', $param ); - return $series instanceof \Book_Database\Series; + return $series instanceof \Book_Database\Models\Series; }, 'sanitize_callback' => function ( $param, $request, $key ) { return absint( $param ); diff --git a/src/REST_API/v1/Taxonomy.php b/src/REST_API/v1/Taxonomy.php index 64f00ed6..3fec526d 100644 --- a/src/REST_API/v1/Taxonomy.php +++ b/src/REST_API/v1/Taxonomy.php @@ -10,7 +10,7 @@ namespace Book_Database\REST_API\v1; use \Book_Database\REST_API\Controller; -use \Book_Database\Exception; +use Book_Database\Exceptions\Exception; use function Book_Database\add_book_taxonomy; use function Book_Database\delete_book_taxonomy; use function Book_Database\get_book_taxonomies; diff --git a/src/REST_API/v1/Utility.php b/src/REST_API/v1/Utility.php index d9c45ff5..b010416b 100644 --- a/src/REST_API/v1/Utility.php +++ b/src/REST_API/v1/Utility.php @@ -9,7 +9,7 @@ namespace Book_Database\REST_API\v1; -use Book_Database\Exception; +use Book_Database\Exceptions\Exception; use Book_Database\REST_API\Controller; /** diff --git a/src/Rating.php b/src/Rating.php deleted file mode 100644 index e2132e1a..00000000 --- a/src/Rating.php +++ /dev/null @@ -1,286 +0,0 @@ -set_rating( $rating ); - $this->available_ratings = get_available_ratings(); - $this->max = max( array_keys( $this->available_ratings ) ); - } - - /** - * Set the rating - * - * @param null|float|int $rating Rating value to set. - */ - public function set_rating( $rating ) { - if ( is_null( $rating ) ) { - $this->rating = null; - } elseif ( is_numeric( $rating ) ) { - $this->rating = $rating + 0; - } else { - $this->rating = $rating; - } - } - - /** - * Get the raw rating - * - * @return float|int|null - */ - public function get_rating() { - return $this->rating; - } - - /** - * Get the highest possible rating - * - * @return float|int - */ - public function get_max_rating() { - return $this->max; - } - - /** - * Round the rating to the nearest half - * - * @return float|int|null - */ - public function round_rating() { - - $rating = $this->rating; - - if ( is_null( $rating ) || ! is_numeric( $rating ) ) { - return null; - } - - if ( ! array_key_exists( (string) $rating, $this->available_ratings ) ) { - $rating = round( $this->rating * 2 ) / 2; - } - - return $rating; - - } - - /** - * Format the rating - * - * @param string $format - * - * @return float|int|null - */ - public function format( $format = 'text' ) { - - $rating = $this->round_rating(); - - if ( is_null( $format ) || ! is_numeric( $rating ) ) { - return $rating; - } elseif ( method_exists( $this, 'format_' . $format ) ) { - return call_user_func( array( $this, 'format_' . $format ) ); - } else { - return $rating; - } - - } - - /** - * Format as text (with "Star(s)" appended) - * - * @return string - */ - public function format_text() { - - if ( null === $this->rating ) { - $text = '–'; - } elseif ( ! is_numeric( $this->rating ) ) { - return $this->rating; - } else { - $text = $this->rating * 1; - - if ( array_key_exists( (string) $text, $this->available_ratings ) ) { - $text = $this->available_ratings[ (string) $text ]; - } else { - $text = sprintf( _n( '%s Star', '%s Stars', $text, 'book-database' ), $text ); - } - } - - /** - * Filters the text display. - * - * @param string $text - * @param null|float|int $rating - * @param Rating $this - */ - return apply_filters( 'book-database/rating/format/text', $text, $this->rating, $this ); - - } - - /** - * Format with Font Awesome stars - * - * @return string - */ - public function format_font_awesome() { - - if ( ! is_numeric( $this->rating ) ) { - return $this->format_text(); - } - - $font_awesome_rating = $this->repeat( '', '', '' ); - - /** - * Filters the Font Awesome rating display. - * - * @param string $font_awesome_rating - * @param null|float|int $rating - * @param Rating $this - */ - return apply_filters( 'book-database/rating/format/font_awesome', $font_awesome_rating, $this->rating, $this ); - - } - - /** - * Format with HTML stars - * - * @return string - */ - public function format_html_stars() { - - if ( ! is_numeric( $this->rating ) ) { - return $this->format_text(); - } - - $html_stars = $this->repeat( '★', '½', '' ); - - /** - * Filters the HTML stars display. - * - * @param string $html_stars - * @param null|float|int $rating - * @param Rating $this - */ - return apply_filters( 'book-database/rating/format/html_stars', $html_stars, $this->rating, $this ); - - } - - /** - * Format as HTML class name - * - * @return string - */ - public function format_html_class() { - - $class = ''; - $rating = $this->round_rating(); - - switch ( $rating ) { - case '5' : - $class = 'five-stars'; - break; - case '4.5' : - $class = 'four-half-stars'; - break; - case '4' : - $class = 'four-stars'; - break; - case '3.5' : - $class = 'three-half-stars'; - break; - case '3' : - $class = 'three-stars'; - break; - case '2.5' : - $class = 'two-half-stars'; - break; - case '2' : - $class = 'two-stars'; - break; - case '1.5' : - $class = 'one-half-stars'; - break; - case '1' : - $class = 'one-star'; - break; - case '0.5' : - $class = 'half-star'; - break; - case '0' : - $class = 'zero-stars'; - break; - } - - /** - * Filters the HTML class display - * - * @param string $class - * @param null|float|int $rating - * @param Rating $this - */ - return apply_filters( 'book-database/rating/format/html_class', $class, $this->rating, $this ); - - } - - /** - * Repeat text/HTML for the number of stars - * - * @param string $full_star Text/HTML to use for full stars. - * @param string $half_star Text/HTML to use for half stars. - * @param string $empty_star Text/HTML to use for empty stars. - * - * @return string - */ - public function repeat( $full_star, $half_star = '', $empty_star = '' ) { - - $rating = $this->round_rating(); - $full_stars = floor( $rating ); - $half_stars = ceil( $rating - $full_stars ); - $empty_stars = $this->max - $full_stars - $half_stars; - - $output = str_repeat( $full_star, $full_stars ); - $output .= str_repeat( $half_star, $half_stars ); - $output .= str_repeat( $empty_star, $empty_stars ); - - return $output; - - } - -} diff --git a/src/Reading_Log.php b/src/Reading_Log.php deleted file mode 100644 index 56b2a2af..00000000 --- a/src/Reading_Log.php +++ /dev/null @@ -1,166 +0,0 @@ -book_id ); - } - - /** - * Get the ID of the associated edition - * - * @return int|null - */ - public function get_edition_id() { - return ! empty( $this->edition_id ) ? absint( $this->edition_id ) : null; - } - - /** - * Get the ID of the user who made this entry - * - * @return int - */ - public function get_user_id() { - return absint( $this->user_id ); - } - - /** - * Get the date the user started reading - * - * @param bool $formatted Whether or not to format the result for display. - * @param string $format Format to display in. Defaults to site format. - * - * @return string - */ - public function get_date_started( $formatted = false, $format = '' ) { - return ( ! empty( $this->date_started ) && $formatted ) ? format_date( $this->date_started, $format ) : $this->date_started; - } - - /** - * Get the date the user finished reading - * - * @param bool $formatted Whether or not to format the result for display. - * @param string $format Format to display in. Defaults to site format. - * - * @return string - */ - public function get_date_finished( $formatted = false, $format = '' ) { - return ( ! empty( $this->date_finished ) && $formatted ) ? format_date( $this->date_finished, $format ) : $this->date_finished; - } - - /** - * Get the percentage complete - * - * Note: This is the `percentage_complete` value multiplied by 100. - * - * @return float - */ - public function get_percentage_complete() { - $percentage = floatval( $this->percentage_complete ); - - if ( $percentage >= 1 ) { - $percentage = 1; - } elseif ( $percentage <= 0 ) { - $percentage = 0; - } - - return round( $percentage * 100, 2 ); - } - - /** - * Whether or not the book has been fully read - * - * @return bool - */ - public function is_complete() { - return $this->get_percentage_complete() >= 100; - } - - /** - * A book is "DNF" (didn't finish) if there's a finished date but the percentage is less than 100%. - * - * @return bool - */ - public function is_dnf() { - return ! empty( $this->get_date_finished() ) && ! $this->is_complete(); - } - - /** - * Get the rating - * - * @return float|null - */ - public function get_rating() { - return $this->rating; - } - - /** - * Export vars - * - * @return array - */ - public function export_vars() { - - $vars = parent::export_vars(); - - $vars['is_complete'] = $this->is_complete(); - $vars['is_dnf'] = $this->is_dnf(); - - // Get the edition. - $edition = $this->get_edition_id() ? get_edition( $this->get_edition_id() ) : null; - $vars['edition'] = $edition instanceof Edition ? $edition->export_vars() : null; - - // Get the review ID. - $review = get_review_by( 'reading_log_id', $this->get_id() ); - if ( $review instanceof Review ) { - $vars['review_id'] = $review->get_id(); - } - - // Calculate the page number we're on. - $vars['page'] = 0; - $vars['max_pages'] = 0; - $book = get_book( $this->get_book_id() ); - if ( $book instanceof Book ) { - $percentage = $this->get_percentage_complete() / 100; - $vars['page'] = round( $percentage * $book->get_pages() ); - $vars['max_pages'] = $book->get_pages(); - } - - return $vars; - - } - -} diff --git a/src/Retailer.php b/src/Retailer.php deleted file mode 100644 index ecd25365..00000000 --- a/src/Retailer.php +++ /dev/null @@ -1,67 +0,0 @@ -name; - } - - /** - * Get the template - * - * @return string - */ - public function get_template() { - return $this->template; - } - - /** - * Build a link - * - * This injects the provided URL into the template, replacing the `[url]` placeholder. - * - * @param string $url - * - * @return string - */ - public function build_link( $url ) { - - $template = $this->get_template(); - - if ( empty( $template ) ) { - $template = '' . esc_html( $this->get_name() ) . ''; - } - - return str_replace( '[url]', esc_url( $url ), $template ); - - } - -} diff --git a/src/Review.php b/src/Review.php deleted file mode 100644 index 7d9410e7..00000000 --- a/src/Review.php +++ /dev/null @@ -1,217 +0,0 @@ -book_id ); - } - - /** - * Get the ID of the user who wrote the review - * - * @return int - */ - public function get_reading_log_id() { - return is_null( $this->reading_log_id ) ? null : absint( $this->reading_log_id ); - } - - /** - * Get the ID of the user who wrote the review - * - * @return int - */ - public function get_user_id() { - return absint( $this->user_id ); - } - - /** - * Get the ID of the corresponding post - * - * This is the post the review was published on. This will only be filled out if the - * review was published as a blog post on this site. - * - * @return int|null - */ - public function get_post_id() { - return is_null( $this->post_id ) ? null : absint( $this->post_id ); - } - - /** - * Get the URL of the review - * - * This will only be filled out if the review is external. - * - * @return string - */ - public function get_url() { - return $this->url; - } - - /** - * Whether or not this is an external review - * - * Will return true if `url` is filled out. - * - * @return bool - */ - public function is_external() { - return ! empty( $this->get_url() ); - } - - /** - * Get the review text - * - * @return string - */ - public function get_review() { - return $this->review; - } - - /** - * Get the date the review was written - * - * @param bool $formatted Whether or not to format the result for display. - * @param string $format Format to display in. Defaults to site format. - * - * @return string - */ - public function get_date_written( $formatted = false, $format = '' ) { - return ( ! empty( $this->date_written ) && $formatted ) ? format_date( $this->date_written, $format ) : $this->date_written; - } - - /** - * Get the date the review was (or will be) published - * - * @param bool $formatted Whether or not to format the result for display. - * @param string $format Format to display in. Defaults to site format. - * - * @return string|null - */ - public function get_date_published( $formatted = false, $format = '' ) { - return ( ! empty( $this->date_published ) && $formatted ) ? format_date( $this->date_published, $format ) : $this->date_published; - } - - /** - * Get the review permalink - * - * Returns the URL to the external review if provided, otherwise the URL to the post where - * the review is located. Returns false if all else fails. - * - * @param bool $use_id Whether or not to build the URL with the post ID (ugly permalinks). - * @param bool $id_appended Whether or not to includle a "skip-to" the book ID. - * - * @return string|false - */ - public function get_permalink( $use_id = true, $id_appended = true ) { - - $url = false; - - if ( $this->is_external() ) { - $url = $this->get_url(); - } elseif ( $this->get_post_id() && $use_id ) { - $url = add_query_arg( array( 'p' => urlencode( $this->get_post_id() ) ), home_url( '/' ) ); - } elseif ( $this->get_post_id() ) { - $url = get_permalink( $this->get_post_id() ); - } - - if ( $id_appended && ! empty( $url ) && ! $this->is_external() ) { - $url .= '#book-' . urlencode( $this->get_book_id() ); - } - - /** - * Filters the review permalink. - * - * @param string|false $url URL to the review. - * @param bool $use_id Whether or not to build the URL with the post ID (ugly permalinks). - * @param bool $id_appended Whether or not to includle a "skip-to" the book ID. - * @param Review $this Review object. - */ - return apply_filters( 'book-database/review/get/permalink', $url, $use_id, $id_appended, $this ); - - } - - /** - * Whether or not the review has been published - * - * Returns `true` if the review is external, or if the review published date is in the past. - * Returns `false` f the review is associated with a post and that post is not "published". - * - * @return bool - */ - public function is_published() { - - if ( $this->is_external() ) { - return true; - } - - if ( $this->get_post_id() ) { - $post = get_post( $this->get_post_id() ); - - if ( $post instanceof \WP_Post && 'publish' !== $post->post_status ) { - return false; - } - } - - return ( $this->get_date_published( true, 'U' ) <= current_time( 'timestamp' ) ); - - } - -} diff --git a/src/Series.php b/src/Series.php deleted file mode 100644 index ad7211a0..00000000 --- a/src/Series.php +++ /dev/null @@ -1,138 +0,0 @@ -name; - } - - /** - * Get the series slug - * - * @return string - */ - public function get_slug() { - return $this->slug; - } - - /** - * Get the series description - * - * @return string - */ - public function get_description() { - return $this->description; - } - - /** - * Get the number of books in the series - * - * Note: This is not the number of books present in the database with this series, but - * rather the number of books PLANNED to be in the series. So if the series is a trilogy - * but there's only one book in the database, this would return `3` because there are 3 - * books planned in the series. It's the length of the series. - * - * @return int - */ - public function get_number_books() { - - if ( empty( $this->number_books ) ) { - $this->number_books = count_books( array( 'series_id' => $this->get_id() ) ); - } - - return absint( $this->number_books ); - - } - - /** - * Get the number of books in this series that have been read - * - * @return int - */ - public function get_number_books_read() { - - global $wpdb; - - $log_table = book_database()->get_table( 'reading_log' )->get_table_name(); - $book_table = book_database()->get_table( 'books' )->get_table_name(); - - $query = $wpdb->prepare( - "SELECT COUNT( DISTINCT book_id ) - FROM {$log_table} log - INNER JOIN {$book_table} b ON log.book_id = b.id - WHERE series_id = %d - AND date_finished IS NOT NULL - AND user_id = %d", - $this->get_id(), - get_current_user_id() - ); - $number_read = $wpdb->get_var( $query ); - - return absint( $number_read ); - - } - - /** - * Get the books in this series - * - * @param array $args - * - * @return Book[] - */ - public function get_books_in_series( $args = array() ) { - - $args = wp_parse_args( $args, array( - 'series_id' => $this->get_id(), - 'number' => 50, - 'orderby' => 'series_position', - 'order' => 'ASC' - ) ); - - return get_books( $args ); - - } - - /** - * Get the average rating of all books in this series - */ - public function get_average_rating() { - - global $wpdb; - - $log_table = book_database()->get_table( 'reading_log' )->get_table_name(); - $book_table = book_database()->get_table( 'books' )->get_table_name(); - - $query = $wpdb->prepare( "SELECT ROUND( AVG( rating ), 2 ) FROM {$log_table} log INNER JOIN {$book_table} b ON log.book_id = b.id WHERE series_id = %d AND rating IS NOT NULL", $this->get_id() ); - $average = $wpdb->get_var( $query ); - - return $average; - - } - -} diff --git a/src/ServiceProviders/ApiServiceProvider.php b/src/ServiceProviders/ApiServiceProvider.php new file mode 100644 index 00000000..33984b1c --- /dev/null +++ b/src/ServiceProviders/ApiServiceProvider.php @@ -0,0 +1,27 @@ +bind(REST_API::class); - book_database()->alias(REST_API::class, 'rest_api'); + book_database()->bind(RouteRegistration::class); + book_database()->alias(RouteRegistration::class, 'rest_api'); book_database()->bind(HTML::class); book_database()->alias(HTML::class, 'html'); diff --git a/src/ValueObjects/Rating.php b/src/ValueObjects/Rating.php new file mode 100644 index 00000000..46ced014 --- /dev/null +++ b/src/ValueObjects/Rating.php @@ -0,0 +1,289 @@ +set_rating($rating); + $this->available_ratings = get_available_ratings(); + $this->max = max(array_keys($this->available_ratings)); + } + + /** + * Set the rating + * + * @param null|float|int $rating Rating value to set. + */ + public function set_rating($rating): void + { + if (is_null($rating)) { + $this->rating = null; + } elseif (is_numeric($rating)) { + $this->rating = $rating + 0; + } else { + $this->rating = $rating; + } + } + + /** + * Get the raw rating + * + * @return float|int|null + */ + public function get_rating() + { + return $this->rating; + } + + /** + * Get the highest possible rating + * + * @return float|int + */ + public function get_max_rating() + { + return $this->max; + } + + /** + * Round the rating to the nearest half + * + * @return float|int|null + */ + public function round_rating() + { + $rating = $this->rating; + + if (! is_numeric($rating)) { + return null; + } + + if (! array_key_exists((string) $rating, $this->available_ratings)) { + $rating = round($this->rating * 2) / 2; + } + + return $rating; + } + + /** + * Format the rating + * + * @param string $format + * + * @return float|int|null + */ + public function format(string $format = 'text') + { + $rating = $this->round_rating(); + + if (is_null($format) || ! is_numeric($rating)) { + return $rating; + } elseif (method_exists($this, 'format_'.$format)) { + return call_user_func(array($this, 'format_'.$format)); + } else { + return $rating; + } + } + + /** + * Format as text (with "Star(s)" appended) + * + * @return string + */ + public function format_text(): string + { + if (null === $this->rating) { + $text = '–'; + } elseif (! is_numeric($this->rating)) { + return $this->rating; + } else { + $text = $this->rating * 1; + + if (array_key_exists((string) $text, $this->available_ratings)) { + $text = $this->available_ratings[(string) $text]; + } else { + $text = sprintf(_n('%s Star', '%s Stars', $text, 'book-database'), $text); + } + } + + /** + * Filters the text display. + * + * @param string $text + * @param null|float|int $rating + * @param Rating $this + */ + return apply_filters('book-database/rating/format/text', $text, $this->rating, $this); + } + + /** + * Format with Font Awesome stars + * + * @return string + */ + public function format_font_awesome(): string + { + if (! is_numeric($this->rating)) { + return $this->format_text(); + } + + $font_awesome_rating = $this->repeat('', '', + ''); + + /** + * Filters the Font Awesome rating display. + * + * @param string $font_awesome_rating + * @param null|float|int $rating + * @param Rating $this + */ + return apply_filters('book-database/rating/format/font_awesome', $font_awesome_rating, $this->rating, $this); + } + + /** + * Format with HTML stars + * + * @return string + */ + public function format_html_stars(): string + { + if (! is_numeric($this->rating)) { + return $this->format_text(); + } + + $html_stars = $this->repeat('★', '½', ''); + + /** + * Filters the HTML stars display. + * + * @param string $html_stars + * @param null|float|int $rating + * @param Rating $this + */ + return apply_filters('book-database/rating/format/html_stars', $html_stars, $this->rating, $this); + } + + /** + * Format as HTML class name + * + * @return string + */ + public function format_html_class(): string + { + $class = ''; + $rating = $this->round_rating(); + + switch ($rating) { + case '5' : + $class = 'five-stars'; + break; + case '4.5' : + $class = 'four-half-stars'; + break; + case '4' : + $class = 'four-stars'; + break; + case '3.5' : + $class = 'three-half-stars'; + break; + case '3' : + $class = 'three-stars'; + break; + case '2.5' : + $class = 'two-half-stars'; + break; + case '2' : + $class = 'two-stars'; + break; + case '1.5' : + $class = 'one-half-stars'; + break; + case '1' : + $class = 'one-star'; + break; + case '0.5' : + $class = 'half-star'; + break; + case '0' : + $class = 'zero-stars'; + break; + } + + /** + * Filters the HTML class display + * + * @param string $class + * @param null|float|int $rating + * @param Rating $this + */ + return apply_filters('book-database/rating/format/html_class', $class, $this->rating, $this); + } + + /** + * Repeat text/HTML for the number of stars + * + * @param string $full_star Text/HTML to use for full stars. + * @param string $half_star Text/HTML to use for half stars. + * @param string $empty_star Text/HTML to use for empty stars. + * + * @return string + */ + public function repeat(string $full_star, string $half_star = '', string $empty_star = ''): string + { + $rating = $this->round_rating(); + $full_stars = floor($rating); + $half_stars = ceil($rating - $full_stars); + $empty_stars = $this->max - $full_stars - $half_stars; + + $output = str_repeat($full_star, $full_stars); + $output .= str_repeat($half_star, $half_stars); + $output .= str_repeat($empty_star, $empty_stars); + + return $output; + } + +} diff --git a/src/Widgets/Reading_Log.php b/src/Widgets/Reading_Log.php index 77c88bf4..0f7c9c20 100644 --- a/src/Widgets/Reading_Log.php +++ b/src/Widgets/Reading_Log.php @@ -10,8 +10,8 @@ namespace Book_Database\Widgets; -use Book_Database\Book; -use Book_Database\Rating; +use Book_Database\Models\Book; +use Book_Database\ValueObjects\Rating; use function Book_Database\book_database; use function Book_Database\get_book; @@ -66,7 +66,7 @@ public function widget( $args, $instance ) { * * @param array $args * - * @return \Book_Database\Reading_Log[] + * @return \Book_Database\Models\ReadingLog[] */ protected function query_reading_logs( $args ) { @@ -97,7 +97,7 @@ protected function query_reading_logs( $args ) { if ( ! empty( $results ) ) { foreach ( $results as $key => $result ) { - $results[ $key ] = new \Book_Database\Reading_Log( $result ); + $results[ $key ] = new \Book_Database\Models\ReadingLog( $result ); } } @@ -108,7 +108,7 @@ protected function query_reading_logs( $args ) { /** * Displays results * - * @param \Book_Database\Reading_Log[] $logs + * @param \Book_Database\Models\ReadingLog[] $logs * @param array $args */ protected function display_books( $logs, $args ) { @@ -157,7 +157,7 @@ protected function display_books( $logs, $args ) { /** * Displays start and finish dates if enabled * - * @param \Book_Database\Reading_Log $log + * @param \Book_Database\Models\ReadingLog $log * @param array $args */ protected function maybe_show_dates( $log, $args ) { @@ -194,7 +194,7 @@ protected function maybe_show_dates( $log, $args ) { /** * Displays rating if enabled * - * @param \Book_Database\Reading_Log $log + * @param \Book_Database\Models\ReadingLog $log * @param array $args */ protected function maybe_show_rating( $log, $args ) { diff --git a/src/Widgets/Reviews.php b/src/Widgets/Reviews.php index 80f736bc..fe01b74b 100644 --- a/src/Widgets/Reviews.php +++ b/src/Widgets/Reviews.php @@ -10,9 +10,9 @@ namespace Book_Database\Widgets; -use Book_Database\Book; -use Book_Database\Rating; -use Book_Database\Review; +use Book_Database\Models\Book; +use Book_Database\ValueObjects\Rating; +use Book_Database\Models\Review; use Book_Database\Database\Reviews\ReviewsQuery; /** diff --git a/templates/shortcode-book-grid-entry.php b/templates/shortcode-book-grid-entry.php index 77ac93c0..6c9184c4 100644 --- a/templates/shortcode-book-grid-entry.php +++ b/templates/shortcode-book-grid-entry.php @@ -9,6 +9,10 @@ namespace Book_Database; +use Book_Database\Models\Book; +use Book_Database\Models\Review; +use Book_Database\ValueObjects\Rating; + /** * @var array $atts Shortcode attributes. * @var Book $book Book object. diff --git a/templates/shortcode-book-reviews-entry.php b/templates/shortcode-book-reviews-entry.php index 4fb94242..49f1026c 100644 --- a/templates/shortcode-book-reviews-entry.php +++ b/templates/shortcode-book-reviews-entry.php @@ -9,11 +9,16 @@ namespace Book_Database; +use Book_Database\Models\Book; +use Book_Database\Models\ReadingLog; +use Book_Database\Models\Review; +use Book_Database\ValueObjects\Rating; + /** * @var array $atts Shortcode attributes. * @var Book $book Book object. * @var Review $review Review object. - * @var Reading_Log $reading_log Reading log object. + * @var ReadingLog $reading_log Reading log object. * @var object $review_data Full object from the database. */ diff --git a/tests/books/test-book-functions.php b/tests/books/test-book-functions.php index 3080f8a5..7c2e6118 100644 --- a/tests/books/test-book-functions.php +++ b/tests/books/test-book-functions.php @@ -9,8 +9,8 @@ namespace Book_Database\Tests; -use Book_Database\Book; -use Book_Database\Exception; +use Book_Database\Models\Book; +use Book_Database\Exceptions\Exception; use function Book_Database\add_book; use function Book_Database\add_book_series; use function Book_Database\get_book; @@ -77,21 +77,21 @@ public function test_create_book_without_title_throws_exception() { * @covers ::get_book */ public function test_get_book() { - $this->assertInstanceOf( 'Book_Database\Book', get_book( self::$book_id ) ); + $this->assertInstanceOf( 'Book_Database\Models\Book', get_book( self::$book_id ) ); } /** * @covers ::get_book_by */ public function test_get_book_by_title() { - $this->assertInstanceOf( 'Book_Database\Book', get_book_by( 'title', 'The First Book' ) ); + $this->assertInstanceOf( 'Book_Database\Models\Book', get_book_by( 'title', 'The First Book' ) ); } /** * @covers ::get_book_by */ public function test_get_book_by_index_title() { - $this->assertInstanceOf( 'Book_Database\Book', get_book_by( 'index_title', 'First Book, The' ) ); + $this->assertInstanceOf( 'Book_Database\Models\Book', get_book_by( 'index_title', 'First Book, The' ) ); } /** @@ -100,7 +100,7 @@ public function test_get_book_by_index_title() { public function test_get_books_array_of_book_objects() { $books = get_books(); - $this->assertInstanceOf( 'Book_Database\Book', $books[0] ); + $this->assertInstanceOf( 'Book_Database\Models\Book', $books[0] ); } /** @@ -172,4 +172,4 @@ public function test_add_book_with_series_position_float() { $this->assertEquals( 1.5, $integer_book->get_series_position() ); } -} \ No newline at end of file +} diff --git a/tests/books/test-book-object.php b/tests/books/test-book-object.php index c02b27ee..f4ca07b3 100644 --- a/tests/books/test-book-object.php +++ b/tests/books/test-book-object.php @@ -9,7 +9,7 @@ namespace Book_Database\Tests; -use Book_Database\Book; +use Book_Database\Models\Book; use function Book_Database\add_book; use function Book_Database\add_book_series; use function Book_Database\get_book; @@ -104,4 +104,4 @@ public function test_pages() { $this->assertEquals( 123, self::$book->get_pages() ); } -} \ No newline at end of file +} diff --git a/tests/phpunit/factories/class-book-factory.php b/tests/phpunit/factories/class-book-factory.php index 5f4575d7..bac34734 100644 --- a/tests/phpunit/factories/class-book-factory.php +++ b/tests/phpunit/factories/class-book-factory.php @@ -9,8 +9,8 @@ namespace Book_Database\Tests\Factory; -use Book_Database\Book; -use Book_Database\Exception; +use Book_Database\Models\Book; +use Book_Database\Exceptions\Exception; use function Book_Database\add_book; use function Book_Database\get_book; use function Book_Database\update_book; @@ -89,4 +89,4 @@ public function get_object_by_id( $object_id ) { return get_book( $object_id ); } -} \ No newline at end of file +} diff --git a/tests/phpunit/factories/class-series-factory.php b/tests/phpunit/factories/class-series-factory.php index 4126284e..5cbce7dd 100644 --- a/tests/phpunit/factories/class-series-factory.php +++ b/tests/phpunit/factories/class-series-factory.php @@ -9,8 +9,8 @@ namespace Book_Database\Tests\Factory; -use Book_Database\Exception; -use Book_Database\Series; +use Book_Database\Exceptions\Exception; +use Book_Database\Models\Series; use function Book_Database\add_book_series; use function Book_Database\get_book_series_by; use function Book_Database\update_book_series; @@ -73,4 +73,4 @@ public function get_object_by_id( $object_id ) { return get_book_series_by( 'id', $object_id ); } -} \ No newline at end of file +} diff --git a/tests/series/test-series-functions.php b/tests/series/test-series-functions.php index 83a22bce..04ad7032 100644 --- a/tests/series/test-series-functions.php +++ b/tests/series/test-series-functions.php @@ -9,7 +9,7 @@ namespace Book_Database\Tests; -use Book_Database\Series; +use Book_Database\Models\Series; use function Book_Database\get_book_series_by; /** @@ -48,21 +48,21 @@ public function setUp() { * @covers ::\Book_Database\get_book_series_by() */ public function test_get_series_by_id() { - $this->assertInstanceOf( 'Book_Database\Series', get_book_series_by( 'id', self::$series[0] ) ); + $this->assertInstanceOf( 'Book_Database\Models\Series', get_book_series_by( 'id', self::$series[0] ) ); } /** * @covers ::\Book_Database\get_book_series_by() */ public function test_get_series_by_name() { - $this->assertInstanceOf( 'Book_Database\Series', get_book_series_by( 'name', 'My Trilogy' ) ); + $this->assertInstanceOf( 'Book_Database\Models\Series', get_book_series_by( 'name', 'My Trilogy' ) ); } /** * @covers ::\Book_Database\get_book_series_by() */ public function test_get_series_by_slug() { - $this->assertInstanceOf( 'Book_Database\Series', get_book_series_by( 'slug', 'my-trilogy' ) ); + $this->assertInstanceOf( 'Book_Database\Models\Series', get_book_series_by( 'slug', 'my-trilogy' ) ); } /** @@ -91,4 +91,4 @@ public function test_series_same_slug_should_append_number() { } -} \ No newline at end of file +} From 31f7d87983a60a8dfbd0d74a543f766fb45b1ed8 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 20 Nov 2021 16:39:43 +0000 Subject: [PATCH 10/29] Get unit test working with WP 5.9. --- composer.json | 4 + composer.lock | 2168 ++++++++++++++++++++++++++++++++++++++++++- tests/bootstrap.php | 4 +- 3 files changed, 2170 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 172cc046..8113b142 100644 --- a/composer.json +++ b/composer.json @@ -10,5 +10,9 @@ }, "require": { "php": "^7.1|^8.0" + }, + "require-dev": { + "phpunit/phpunit": "9.5.10", + "yoast/phpunit-polyfills": "1.x-dev" } } diff --git a/composer.lock b/composer.lock index 81965b6d..63ef3988 100644 --- a/composer.lock +++ b/composer.lock @@ -4,17 +4,2175 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "532d26738cf17785a60bfdb5d3697811", + "content-hash": "7fbaffb327dcba594fed03a0f2b1f502", "packages": [], - "packages-dev": [], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^8.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2020-11-10T18:47:58+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.10.2", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-11-13T09:40:50+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.13.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/63a79e8daa781cac14e5195e63ed8ae231dd10fd", + "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.1" + }, + "time": "2021-11-03T20:52:16+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "bae7c545bef187884426f042434e561ab1ddb182" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", + "reference": "bae7c545bef187884426f042434e561ab1ddb182", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.1.0" + }, + "time": "2021-02-23T14:00:09+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" + }, + "time": "2021-10-02T14:08:47+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.14.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.2", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0 || ^7.0", + "phpunit/phpunit": "^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/1.14.0" + }, + "time": "2021-09-10T09:02:12+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "f301eb1453c9e7a1bc912ee8b0ea9db22c60223b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f301eb1453c9e7a1bc912ee8b0ea9db22c60223b", + "reference": "f301eb1453c9e7a1bc912ee8b0ea9db22c60223b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.13.0", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.9" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-11-19T15:21:02+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", + "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:57:25+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.5.10", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.7", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^2.3.4", + "sebastian/version": "^3.0.2" + }, + "require-dev": { + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.5-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ], + "files": [ + "src/Framework/Assert/Functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" + }, + "funding": [ + { + "url": "https://phpunit.de/donate.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-09-25T07:38:51+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:49:45+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "388b6ced16caa751030f6a69e588299fa09200ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", + "reference": "388b6ced16caa751030f6a69e588299fa09200ac", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:52:38+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-11-11T14:18:36+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-06-11T13:31:12+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "2.3.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-06-15T12:49:02+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.23.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-19T12:13:01+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" + }, + { + "name": "yoast/phpunit-polyfills", + "version": "dev-develop", + "source": { + "type": "git", + "url": "https://github.com/Yoast/PHPUnit-Polyfills.git", + "reference": "0b45bcca2664c3d6a75f3e1343d4bbd630b2bb32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/0b45bcca2664c3d6a75f3e1343d4bbd630b2bb32", + "reference": "0b45bcca2664c3d6a75f3e1343d4bbd630b2bb32", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + }, + "require-dev": { + "yoast/yoastcs": "^2.2.0" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev", + "dev-develop": "1.x-dev" + } + }, + "autoload": { + "files": [ + "phpunitpolyfills-autoload.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Team Yoast", + "email": "support@yoast.com", + "homepage": "https://yoast.com" + }, + { + "name": "Contributors", + "homepage": "https://github.com/Yoast/PHPUnit-Polyfills/graphs/contributors" + } + ], + "description": "Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit cross-version compatible tests", + "homepage": "https://github.com/Yoast/PHPUnit-Polyfills", + "keywords": [ + "phpunit", + "polyfill", + "testing" + ], + "support": { + "issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues", + "source": "https://github.com/Yoast/PHPUnit-Polyfills" + }, + "time": "2021-11-18T17:12:39+00:00" + } + ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "yoast/phpunit-polyfills": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^7.0|^8.0" + "php": "^7.1|^8.0" }, "platform-dev": [], - "plugin-api-version": "2.0.0" + "plugin-api-version": "2.1.0" } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index c33f7282..5f8b4758 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -16,6 +16,8 @@ define( 'BDB_DOING_TESTS', true ); +require_once dirname( dirname( __FILE__ ) ) . '/vendor/autoload.php'; + $_tests_dir = getenv( 'WP_TESTS_DIR' ); if ( ! $_tests_dir ) $_tests_dir = '/tmp/wordpress-tests-lib'; @@ -54,4 +56,4 @@ function _manually_load_plugin() { update_option( 'bdb_run_activation', 1 ); book_database()->install(); -require_once 'phpunit/class-unittestcase.php'; \ No newline at end of file +require_once 'phpunit/class-unittestcase.php'; From b800a2e9cf8331392473eab7a1d5b1847f71d6b9 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 20 Nov 2021 17:06:59 +0000 Subject: [PATCH 11/29] Add query interface & update Series functions. #248 --- includes/database/engine/query.php | 4 +- includes/series/series-functions.php | 181 ++++++-------------- src/Exceptions/ModelNotFoundException.php | 16 ++ src/Models/Model.php | 4 +- src/Models/Series.php | 74 +++++++- src/Traits/HasQueryInterface.php | 199 ++++++++++++++++++++++ 6 files changed, 344 insertions(+), 134 deletions(-) create mode 100644 src/Exceptions/ModelNotFoundException.php create mode 100644 src/Traits/HasQueryInterface.php diff --git a/includes/database/engine/query.php b/includes/database/engine/query.php index d6a58e3d..27682a4a 100644 --- a/includes/database/engine/query.php +++ b/includes/database/engine/query.php @@ -1922,7 +1922,7 @@ public function get_item_by( $column_name = '', $column_value = '' ) { * @since 1.0.0 * * @param array $data - * @return bool + * @return int|false */ public function add_item( $data = array() ) { @@ -3167,4 +3167,4 @@ public function get_results( $cols = array(), $where_cols = array(), $limit = 25 // Return results. return $results; } -} \ No newline at end of file +} diff --git a/includes/series/series-functions.php b/includes/series/series-functions.php index 7e45c7b0..4186170c 100644 --- a/includes/series/series-functions.php +++ b/includes/series/series-functions.php @@ -3,7 +3,7 @@ * Series Functions * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -15,24 +15,24 @@ * for the plural version. To get a single series by ID, use `get_book_series_by( 'id', $id )` */ -use Book_Database\Database\Series\SeriesQuery; use Book_Database\Exceptions\Exception; use Book_Database\Models\Series; /** * Get a single series by a column name/value combo * - * @param string $column_name - * @param mixed $column_value + * @param string $column_name + * @param mixed $column_value * * @return Series|false */ -function get_book_series_by( $column_name, $column_value ) { - - $query = new SeriesQuery(); - - return $query->get_item_by( $column_name, $column_value ); - +function get_book_series_by(string $column_name, $column_value) +{ + try { + return Series::findBy($column_name, $column_value); + } catch (\Exception $e) { + return false; + } } /** @@ -66,114 +66,64 @@ function get_book_series_by( $column_name, $column_value ) { * * @return Series[] Array of Series objects. */ -function get_book_series( $args = array() ) { - - $args = wp_parse_args( $args, array( - 'number' => 20 - ) ); - - $query = new SeriesQuery(); - - return $query->query( $args ); - +function get_book_series(array $args = []): array +{ + try { + return Series::query($args); + } catch (\Exception $e) { + return []; + } } /** * Count the series * - * @param array $args + * @param array $args * * @see get_book_series() for accepted arguments. * * @return int */ -function count_book_series( $args = array() ) { - - $args = wp_parse_args( $args, array( - 'count' => true - ) ); - - $query = new SeriesQuery( $args ); - - return absint( $query->found_items ); - +function count_book_series(array $args = []): int +{ + try { + return Series::count($args); + } catch (\Exception $e) { + return 0; + } } /** * Add a new series * - * @param array $args { + * @param array $args { * - * @type string $name Name of the series. - * @type string $slug Series slug. Omit to auto generate. - * @type string $description Description of the series. - * @type int $number_books Number of books planned for the series. + * @type string $name Name of the series. + * @type string $slug Series slug. Omit to auto generate. + * @type string $description Description of the series. + * @type int $number_books Number of books planned for the series. * } * * @return int ID of the newly created taxonomy. - * @throws Exception + * @throws Exception|\Exception */ -function add_book_series( $args ) { - - $args = wp_parse_args( $args, array( - 'name' => '', - 'slug' => '', - 'description' => '', - 'number_books' => 1 - ) ); - - if ( empty( $args['name'] ) ) { - throw new Exception( 'missing_required_parameter', __( 'A taxonomy name is required.', 'book-database' ), 400 ); - } - - // Generate a slug. - $args['slug'] = ! empty( $args['slug'] ) ? unique_book_slug( $args['slug'], 'series' ) : unique_book_slug( sanitize_title( $args['name'] ), 'series' ); - - // Sanitize. - $args['slug'] = sanitize_key( $args['slug'] ); - - $query = new SeriesQuery(); - $series_id = $query->add_item( $args ); - - if ( empty( $series_id ) ) { - throw new Exception( 'database_error', __( 'Failed to insert new series into the database.', 'book-database' ), 500 ); - } - - return absint( $series_id ); - +function add_book_series(array $args): int +{ + return Series::create($args); } /** * Update an existing series * - * @param int $series_id ID of the series to update. - * @param array $args Arguments to change. + * @param int $series_id ID of the series to update. + * @param array $args Arguments to change. * * @return bool * @throws Exception */ -function update_book_series( $series_id, $args = array() ) { - - $series = get_book_series_by( 'id', $series_id ); - - if ( empty( $series ) ) { - throw new Exception( 'invalid_id', __( 'Invalid series ID.', 'book-database' ), 400 ); - } - - // If the slug is changing, let's re-generate it. - if ( isset( $args['slug'] ) && $args['slug'] != $series->get_slug() ) { - $args['slug'] = unique_book_slug( $args['slug'], 'series' ); - } - - $query = new SeriesQuery(); - $updated = $query->update_item( $series_id, $args ); - - if ( ! $updated ) { - throw new Exception( 'database_error', __( 'Failed to update the series.', 'book-database' ), 500 ); - } - - return true; - +function update_book_series(int $series_id, array $args = []): bool +{ + return Series::update($series_id, $args); } /** @@ -181,59 +131,32 @@ function update_book_series( $series_id, $args = array() ) { * * This also updates the records of each book in this series to wipe their series_id and series_position. * - * @param int $series_id ID of the book to delete. + * @param int $series_id ID of the book to delete. * * @return bool * @throws Exception */ -function delete_book_series( $series_id ) { - - $query = new SeriesQuery(); - $deleted = $query->delete_item( $series_id ); - - if ( ! $deleted ) { - throw new Exception( 'database_error', __( 'Failed to delete the series.', 'book-database' ), 500 ); - } - - // Get all the books in this series. - $books = get_books( array( - 'series_id' => absint( $series_id ), - 'number' => 9999, - 'fields' => 'id' - ) ); - - if ( $books ) { - /** - * @var int[] $books - */ - // Remove series_id and series_position from each book. - foreach ( $books as $book_id ) { - update_book( $book_id, array( - 'series_id' => 0, - 'series_position' => null - ) ); - } - } - - return true; +function delete_book_series(int $series_id): bool +{ + Series::delete($series_id); + return true; } /** * Get the series admin page URL. * - * @param array $args Query args to append to the URL. + * @param array $args Query args to append to the URL. * * @return string */ -function get_series_admin_page_url( $args = array() ) { - - $sanitized_args = array(); - - foreach ( $args as $key => $value ) { - $sanitized_args[ sanitize_key( $key ) ] = urlencode( $value ); - } +function get_series_admin_page_url(array $args = []): string +{ + $sanitized_args = array(); - return add_query_arg( $sanitized_args, admin_url( 'admin.php?page=bdb-series' ) ); + foreach ($args as $key => $value) { + $sanitized_args[sanitize_key($key)] = urlencode($value); + } + return add_query_arg($sanitized_args, admin_url('admin.php?page=bdb-series')); } diff --git a/src/Exceptions/ModelNotFoundException.php b/src/Exceptions/ModelNotFoundException.php new file mode 100644 index 00000000..8910b192 --- /dev/null +++ b/src/Exceptions/ModelNotFoundException.php @@ -0,0 +1,16 @@ +{$key} = $value; } - } /** diff --git a/src/Models/Series.php b/src/Models/Series.php index 04dc7c50..951d1032 100644 --- a/src/Models/Series.php +++ b/src/Models/Series.php @@ -9,9 +9,14 @@ namespace Book_Database\Models; +use Book_Database\Database\Series\SeriesQuery; +use Book_Database\Exceptions\Exception; +use Book_Database\Exceptions\ModelNotFoundException; use function Book_Database\book_database; use function Book_Database\count_books; use function Book_Database\get_books; +use function Book_Database\unique_book_slug; +use function Book_Database\update_book; /** * Class Series @@ -21,6 +26,7 @@ */ class Series extends Model { + protected static $queryInterfaceClass = SeriesQuery::class; protected $name = ''; @@ -30,6 +36,72 @@ class Series extends Model protected $number_books = 0; + public static function create(array $args): int + { + $args = wp_parse_args($args, array( + 'name' => '', + 'slug' => '', + 'description' => '', + 'number_books' => 1, + )); + + if (empty($args['name'])) { + throw new Exception('missing_required_parameter', __('A taxonomy name is required.', 'book-database'), 400); + } + + // Generate a slug. + $args['slug'] = ! empty($args['slug']) + ? unique_book_slug($args['slug'], 'series') + : unique_book_slug(sanitize_title($args['name']), 'series'); + + // Sanitize. + $args['slug'] = sanitize_key($args['slug']); + + return parent::create($args); + } + + public static function update(int $id, array $args): bool + { + try { + /** @var Series $series */ + $series = static::find($id); + } catch (ModelNotFoundException $e) { + throw new Exception('invalid_id', __('Invalid series ID.', 'book-database'), 400); + } + + // If the slug is changing, let's re-generate it. + if (isset($args['slug']) && $args['slug'] !== $series->get_slug()) { + $args['slug'] = unique_book_slug($args['slug'], 'series'); + } + + return parent::update($id, $args); + } + + public static function delete(int $id): void + { + parent::delete($id); + + // Get all the books in this series. + $books = get_books(array( + 'series_id' => absint($id), + 'number' => 9999, + 'fields' => 'id' + )); + + if ($books) { + /** + * @var int[] $books + */ + // Remove series_id and series_position from each book. + foreach ($books as $book_id) { + update_book($book_id, array( + 'series_id' => 0, + 'series_position' => null + )); + } + } + } + /** * Get the name of the series * @@ -135,7 +207,7 @@ public function get_average_rating(): float $log_table = book_database()->get_table('reading_log')->get_table_name(); $book_table = book_database()->get_table('books')->get_table_name(); - $query = $wpdb->prepare( + $query = $wpdb->prepare( "SELECT ROUND( AVG( rating ), 2 ) FROM {$log_table} log INNER JOIN {$book_table} b ON log.book_id = b.id WHERE series_id = %d AND rating IS NOT NULL", $this->get_id() ); diff --git a/src/Traits/HasQueryInterface.php b/src/Traits/HasQueryInterface.php new file mode 100644 index 00000000..e8a076e4 --- /dev/null +++ b/src/Traits/HasQueryInterface.php @@ -0,0 +1,199 @@ +add_item($args); + + if ($id) { + return (int) $id; + } + + throw new Exception( + 'database_error', + __('Failed to insert new model into the database.', 'book-database'), + 500 + ); + } + + /** + * Updates a model by its ID. + * + * @since 1.3 + * + * @param int $id + * @param array $args + * + * @return bool + * @throws \Exception + */ + public static function update(int $id, array $args): bool + { + return (bool) static::getQueryInterface()->update_item($id, $args); + } + + /** + * Deletes a model by its ID. + * + * @since 1.3 + * + * @param int $id + * + * @throws \Exception + */ + public static function delete(int $id): void + { + if (! static::getQueryInterface()->delete_item($id)) { + throw new \Exception('Failed to delete model.'); + } + } + + /** + * Retrieves a model by its ID. + * + * @since 1.3 + * + * @param int $id + * + * @return Model + * @throws ModelNotFoundException|\Exception + */ + public static function find(int $id): Model + { + $item = static::getQueryInterface()->get_item($id); + + if (! $item) { + throw new ModelNotFoundException(); + } + + return $item; + } + + /** + * Retrieves a model by a given column + value. + * + * @since 1.3 + * + * @param string $column + * @param mixed $value + * + * @return Model + * @throws ModelNotFoundException|\Exception + */ + public static function findBy(string $column, $value): Model + { + $item = static::getQueryInterface()->get_item_by($column, $value); + + if (! $item) { + throw new ModelNotFoundException(); + } + + return $item; + } + + /** + * Queries for models. + * + * @since 1.3 + * + * @param array $args + * + * @return Model[]|array + * @throws \Exception + */ + public static function query(array $args = []): array + { + return self::getQueryInterface()->query($args); + } + + /** + * Queries for all models. + * + * @since 1.3 + * + * @param array $args + * + * @return Model[]|array + * @throws \Exception + */ + public static function all(array $args = []): array + { + return self::query(wp_parse_args($args, ['number' => 9999])); + } + + /** + * Counts the number of models. + * + * @since 1.3 + * + * @param array $args + * + * @return int + * @throws \Exception + */ + public static function count(array $args = []): int + { + $args = wp_parse_args($args, ['count' => true]); + $query = static::getQueryInterface(); + $query->query($args); + + return absint($query->found_items); + } + +} From 43ebe7c8ff3da4ff014f7eac281b451ec2793359 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 20 Nov 2021 17:13:46 +0000 Subject: [PATCH 12/29] Update review functions. #248 --- includes/reviews/review-functions.php | 186 ++++++++++---------------- src/Models/Review.php | 39 ++++++ 2 files changed, 107 insertions(+), 118 deletions(-) diff --git a/includes/reviews/review-functions.php b/includes/reviews/review-functions.php index 81f257f3..60d0c30c 100644 --- a/includes/reviews/review-functions.php +++ b/includes/reviews/review-functions.php @@ -3,7 +3,7 @@ * Review Functions * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -16,32 +16,34 @@ /** * Get a single review by its ID * - * @param int $review_id + * @param int $review_id * * @return Review|false */ -function get_review( $review_id ) { - - $query = new ReviewsQuery(); - - return $query->get_item( $review_id ); - +function get_review($review_id) +{ + try { + return Review::find($review_id); + } catch (\Exception $e) { + return false; + } } /** * Get a single review by a column name/value combo * - * @param string $column_name - * @param mixed $column_value + * @param string $column_name + * @param mixed $column_value * * @return Review|false */ -function get_review_by( $column_name, $column_value ) { - - $query = new ReviewsQuery(); - - return $query->get_item_by( $column_name, $column_value ); - +function get_review_by(string $column_name, $column_value) +{ + try { + return Review::findBy($column_name, $column_value); + } catch (\Exception $e) { + return false; + } } /** @@ -66,12 +68,13 @@ function get_review_by( $column_name, $column_value ) { * * @return object[] Array of database objects. */ -function get_reviews( $args = array() ) { - - $query = new ReviewsQuery(); - - return $query->get_reviews( $args ); - +function get_reviews(array $args = []): array +{ + try { + return Review::query($args); + } catch (\Exception $e) { + return []; + } } /** @@ -83,16 +86,13 @@ function get_reviews( $args = array() ) { * * @return int */ -function count_reviews( $args = array() ) { - - $args = wp_parse_args( $args, array( - 'count' => true - ) ); - - $query = new ReviewsQuery( $args ); - - return absint( $query->found_items ); - +function count_reviews(array $args = []): int +{ + try { + return Review::count($args); + } catch (\Exception $e) { + return 0; + } } /** @@ -112,32 +112,9 @@ function count_reviews( $args = array() ) { * @return int ID of the newly created review. * @throws Exception */ -function add_review( $args = array() ) { - - $args = wp_parse_args( $args, array( - 'book_id' => 0, - 'reading_log_id' => null, - 'user_id' => get_current_user_id(), - 'post_id' => null, - 'url' => '', - 'review' => '', - 'date_written' => current_time( 'mysql', true ), - 'date_published' => null - ) ); - - if ( empty( $args['book_id'] ) ) { - throw new Exception( 'missing_parameter', __( 'Book ID is required.', 'book-database' ), 400 ); - } - - $query = new ReviewsQuery(); - $review_id = $query->add_item( $args ); - - if ( empty( $review_id ) ) { - throw new Exception( 'database_error', __( 'Failed to insert new review into the database.', 'book-database' ), 500 ); - } - - return absint( $review_id ); - +function add_review(array $args = []): int +{ + return Review::create($args); } /** @@ -149,63 +126,42 @@ function add_review( $args = array() ) { * @return bool * @throws Exception */ -function update_review( $review_id, $args = array() ) { - - $query = new ReviewsQuery(); - $updated = $query->update_item( $review_id, $args ); - - if ( ! $updated ) { - throw new Exception( 'database_error', __( 'Failed to update the review.', 'book-database' ), 500 ); - } - - return true; - +function update_review($review_id, array $args = []): bool +{ + return Review::update($review_id, $args); } /** * Delete a review * - * @param int $review_id ID of the review to delete. + * @param int $review_id ID of the review to delete. * * @return bool * @throws Exception */ -function delete_review( $review_id ) { - - $query = new ReviewsQuery(); - $deleted = $query->delete_item( $review_id ); - - if ( ! $deleted ) { - throw new Exception( 'database_error', __( 'Failed to delete the review.', 'book-database' ), 500 ); - } - - // Delete all review meta. - global $wpdb; - $tbl_meta = book_database()->get_table( 'review_meta' )->get_table_name(); - $query = $wpdb->prepare( "DELETE FROM {$tbl_meta} WHERE bdb_review_id = %d", $review_id ); - $wpdb->query( $query ); - - return true; +function delete_review($review_id): bool +{ + Review::delete($review_id); + return true; } /** * Get the reviews admin page URL. * - * @param array $args Query args to append to the URL. + * @param array $args Query args to append to the URL. * * @return string */ -function get_reviews_admin_page_url( $args = array() ) { +function get_reviews_admin_page_url(array $args = []): string +{ + $sanitized_args = array(); - $sanitized_args = array(); - - foreach ( $args as $key => $value ) { - $sanitized_args[ sanitize_key( $key ) ] = urlencode( $value ); - } - - return add_query_arg( $sanitized_args, admin_url( 'admin.php?page=bdb-reviews' ) ); + foreach ($args as $key => $value) { + $sanitized_args[sanitize_key($key)] = urlencode($value); + } + return add_query_arg($sanitized_args, admin_url('admin.php?page=bdb-reviews')); } /** @@ -213,37 +169,32 @@ function get_reviews_admin_page_url( $args = array() ) { * * @return array */ -function get_reviewer_user_ids() { - - global $wpdb; - - $review_table = book_database()->get_table( 'reviews' )->get_table_name(); +function get_reviewer_user_ids(): array +{ + global $wpdb; - $results = $wpdb->get_col( "SELECT DISTINCT user_id FROM {$review_table}" ); - - return $results; + $review_table = book_database()->get_table('reviews')->get_table_name(); + return $wpdb->get_col("SELECT DISTINCT user_id FROM {$review_table}"); } /** * Returns an array of all the years that reviews have been written/published in. * - * @param string $type Date type - either `written` or `published`. - * @param string $order Either ASC or DESC. + * @param string $type Date type - either `written` or `published`. + * @param string $order Either ASC or DESC. * * @return array */ -function get_review_years( $type = 'written', $order = 'DESC' ) { - - global $wpdb; +function get_review_years(string $type = 'written', string $order = 'DESC'): array +{ + global $wpdb; - $review_table = book_database()->get_table( 'reviews' )->get_table_name(); - $date_type = 'written' === $type ? 'date_written' : 'date_published'; - $order = 'DESC' === $order ? 'DESC' : 'ASC'; - $years = $wpdb->get_col( "SELECT DISTINCT YEAR( {$date_type} ) FROM {$review_table} WHERE {$date_type} IS NOT NULL ORDER BY {$date_type} {$order}" ); - - return $years; + $review_table = book_database()->get_table('reviews')->get_table_name(); + $date_type = 'written' === $type ? 'date_written' : 'date_published'; + $order = 'DESC' === $order ? 'DESC' : 'ASC'; + return $wpdb->get_col("SELECT DISTINCT YEAR( {$date_type} ) FROM {$review_table} WHERE {$date_type} IS NOT NULL ORDER BY {$date_type} {$order}"); } /** @@ -251,8 +202,7 @@ function get_review_years( $type = 'written', $order = 'DESC' ) { * * @return array */ -function get_review_post_types() { - $post_types = array( 'post' ); - - return apply_filters( 'book-database/review-post-types', $post_types ); +function get_review_post_types(): array +{ + return apply_filters('book-database/review-post-types', ['post']); } diff --git a/src/Models/Review.php b/src/Models/Review.php index 1708dade..fc0a7a95 100644 --- a/src/Models/Review.php +++ b/src/Models/Review.php @@ -9,6 +9,9 @@ namespace Book_Database\Models; +use Book_Database\Database\Reviews\ReviewsQuery; +use Book_Database\Exceptions\Exception; +use function Book_Database\book_database; use function Book_Database\format_date; /** @@ -19,6 +22,7 @@ */ class Review extends Model { + protected static $queryInterfaceClass = ReviewsQuery::class; /** * @var int ID of the associated book. @@ -60,6 +64,41 @@ class Review extends Model */ protected $date_published = null; + public static function create(array $args): int + { + $args = wp_parse_args($args, array( + 'book_id' => 0, + 'reading_log_id' => null, + 'user_id' => get_current_user_id(), + 'post_id' => null, + 'url' => '', + 'review' => '', + 'date_written' => current_time('mysql', true), + 'date_published' => null, + )); + + if (empty($args['book_id'])) { + throw new Exception( + 'missing_parameter', + __('Book ID is required.', 'book-database'), + 400 + ); + } + + return parent::create($args); + } + + public static function delete(int $id): void + { + parent::delete($id); + + // Delete all review meta. + global $wpdb; + $tbl_meta = book_database()->get_table( 'review_meta' )->get_table_name(); + $query = $wpdb->prepare( "DELETE FROM {$tbl_meta} WHERE bdb_review_id = %d", $id ); + $wpdb->query( $query ); + } + /** * Get the ID of the book * From fbae437e8e51669780f9d2cd39ae94d031a29a0b Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sun, 21 Nov 2021 13:28:12 +0000 Subject: [PATCH 13/29] Refactor shortcodes into classes #248 --- includes/capabilities.php | 135 +++--- includes/deprecated/deprecated-functions.php | 72 +++ includes/misc-functions.php | 240 +++++----- includes/shortcodes.php | 410 ------------------ src/Plugin.php | 2 + .../LegacyServiceProvider.php | 3 +- .../ShortcodeServiceProvider.php | 42 ++ src/Shortcodes/BookGridShortcode.php | 132 ++++++ src/Shortcodes/BookReviewsShortcode.php | 296 +++++++++++++ src/Shortcodes/BookShortcode.php | 57 +++ src/Shortcodes/Shortcode.php | 36 ++ 11 files changed, 825 insertions(+), 600 deletions(-) create mode 100644 includes/deprecated/deprecated-functions.php delete mode 100644 includes/shortcodes.php create mode 100644 src/ServiceProviders/ShortcodeServiceProvider.php create mode 100644 src/Shortcodes/BookGridShortcode.php create mode 100644 src/Shortcodes/BookReviewsShortcode.php create mode 100644 src/Shortcodes/BookShortcode.php create mode 100644 src/Shortcodes/Shortcode.php diff --git a/includes/capabilities.php b/includes/capabilities.php index 6ce8ea6f..893ad9bd 100644 --- a/includes/capabilities.php +++ b/includes/capabilities.php @@ -3,7 +3,7 @@ * Capabilities * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -15,7 +15,7 @@ * @since 1.0 * @return array */ -function get_book_capabilities() { +function get_book_capabilities(): array { return array( 'bdb_view_books', 'bdb_edit_books', @@ -26,89 +26,86 @@ function get_book_capabilities() { /** * Returns true if the user can view books in the admin area * - * @param int $user_id + * @param int $user_id * * @return bool */ -function user_can_view_books( $user_id = 0 ) { - - if ( empty( $user_id ) ) { - $user_id = get_current_user_id(); - } - - $can_view = user_can( $user_id, 'bdb_view_books' ); - - // Admins can always view. - if ( ! $can_view && user_can( $user_id, 'manage_options' ) ) { - $can_view = true; - } - - /** - * Filters whether or not a user is allowed to view books in the admin area. - * - * @param bool $can_view - * @param int $user_id - */ - return apply_filters( 'book-database/capabilities/view-books', $can_view, $user_id ); - +function user_can_view_books(int $user_id = 0): bool +{ + if (empty($user_id)) { + $user_id = get_current_user_id(); + } + + $can_view = user_can($user_id, 'bdb_view_books'); + + // Admins can always view. + if (! $can_view && user_can($user_id, 'manage_options')) { + $can_view = true; + } + + /** + * Filters whether or not a user is allowed to view books in the admin area. + * + * @param bool $can_view + * @param int $user_id + */ + return apply_filters('book-database/capabilities/view-books', $can_view, $user_id); } /** * Returns true if the user can edit books in the admin area * - * @param int $user_id + * @param int $user_id * * @return bool */ -function user_can_edit_books( $user_id = 0 ) { - - if ( empty( $user_id ) ) { - $user_id = get_current_user_id(); - } - - $can_edit = user_can( $user_id, 'bdb_edit_books' ); - - // Admins can always edit. - if ( ! $can_edit && user_can( $user_id, 'manage_options' ) ) { - $can_edit = true; - } - - /** - * Filters whether or not a user is allowed to edit books in the admin area. - * - * @param bool $can_view - * @param int $user_id - */ - return apply_filters( 'book-database/capabilities/edit-books', $can_edit, $user_id ); - +function user_can_edit_books(int $user_id = 0): bool +{ + if (empty($user_id)) { + $user_id = get_current_user_id(); + } + + $can_edit = user_can($user_id, 'bdb_edit_books'); + + // Admins can always edit. + if (! $can_edit && user_can($user_id, 'manage_options')) { + $can_edit = true; + } + + /** + * Filters whether or not a user is allowed to edit books in the admin area. + * + * @param bool $can_view + * @param int $user_id + */ + return apply_filters('book-database/capabilities/edit-books', $can_edit, $user_id); } /** * Returns true if the user can manage the BDB settings * - * @param int $user_id + * @param int $user_id * * @return bool */ -function user_can_manage_book_settings( $user_id = 0 ) { - - if ( empty( $user_id ) ) { - $user_id = get_current_user_id(); - } - - $can_manage = user_can( $user_id, 'bdb_manage_book_settings' ); - - // Admins can always edit. - if ( ! $can_manage && user_can( $user_id, 'manage_options' ) ) { - $can_manage = true; - } - - /** - * Filters whether or not a user is allowed to manage BDB settings. - * - * @param bool $can_view - * @param int $user_id - */ - return apply_filters( 'book-database/capabilities/manage-book-settings', $can_manage, $user_id ); - -} \ No newline at end of file +function user_can_manage_book_settings(int $user_id = 0): bool +{ + if (empty($user_id)) { + $user_id = get_current_user_id(); + } + + $can_manage = user_can($user_id, 'bdb_manage_book_settings'); + + // Admins can always edit. + if (! $can_manage && user_can($user_id, 'manage_options')) { + $can_manage = true; + } + + /** + * Filters whether or not a user is allowed to manage BDB settings. + * + * @param bool $can_view + * @param int $user_id + */ + return apply_filters('book-database/capabilities/manage-book-settings', $can_manage, $user_id); +} diff --git a/includes/deprecated/deprecated-functions.php b/includes/deprecated/deprecated-functions.php new file mode 100644 index 00000000..e6a671cd --- /dev/null +++ b/includes/deprecated/deprecated-functions.php @@ -0,0 +1,72 @@ +make($atts, $content); +} + +/** + * Book reviews + * + * Displays a list of book reviews with filters allowing users to change the parameters. + * + * @deprecated 1.3 + * + * @param array $atts Shortcode attributes. + * @param string $content Shortcode content. + * + * @return string + */ +function book_reviews_shortcode($atts, $content = '') +{ + _deprecated_function(__FUNCTION__, '1.3', BookReviewsShortcode::class); + + return book_database(BookReviewsShortcode::class)->make($atts, $content); +} + +/** + * Book grid + * + * Similar to `[book-reviews]` but filtering is done via shortcode attributes instead of + * a front-end form. It also focuses on books rather than reviews. + * + * @deprecated 1.3 + * + * @param array $atts Shortcode attributes. + * @param string $content Shortcode content. + * + * @return string + */ +function book_grid_shortcode($atts, $content = '') +{ + _deprecated_function(__FUNCTION__, '1.3', BookGridShortcode::class); + + return book_database(BookGridShortcode::class)->make($atts, $content); +} + diff --git a/includes/misc-functions.php b/includes/misc-functions.php index 82c24a8c..927ad4c1 100644 --- a/includes/misc-functions.php +++ b/includes/misc-functions.php @@ -3,7 +3,7 @@ * Misc. Functions * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2021, Ashley Gibson * @license GPL2+ */ @@ -19,41 +19,42 @@ * * @return array */ -function bdb_get_settings() { - return get_option( 'bdb_settings', array() ); +function bdb_get_settings(): array +{ + return (array) get_option('bdb_settings', array()); } /** * Get an option value * - * @param string $key - * @param bool $default + * @param string $key + * @param mixed $default * * @return mixed */ -function bdb_get_option( $key, $default = false ) { - - $settings = bdb_get_settings(); - - return isset( $settings[ $key ] ) ? $settings[ $key ] : $default; +function bdb_get_option($key, $default = false) +{ + $settings = bdb_get_settings(); + return $settings[$key] ?? $default; } /** * Update an option * - * @param string $key - * @param mixed $value + * @param string $key + * @param mixed $value * * @return bool */ -function bdb_update_option( $key, $value ) { +function bdb_update_option($key, $value) +{ - $settings = bdb_get_settings(); + $settings = bdb_get_settings(); - $settings[ $key ] = $value; + $settings[$key] = $value; - return update_option( 'bdb_settings', $settings ); + return update_option('bdb_settings', $settings); } @@ -62,18 +63,17 @@ function bdb_update_option( $key, $value ) { * * This converts a GMT date to local site time and formats it. * - * @param string $date Date string to format. - * @param string $format Date format. Default is the site's `date_format`. + * @param string $date Date string to format. + * @param string $format Date format. Default is the site's `date_format`. * * @return string */ -function format_date( $date, $format = '' ) { - - $format = ! empty( $format ) ? $format : get_option( 'date_format' ); - $local_date = get_date_from_gmt( $date, 'Y-m-d H:i:s' ); - - return date( $format, strtotime( $local_date ) ); +function format_date(string $date, string $format = ''): string +{ + $format = ! empty($format) ? $format : get_option('date_format'); + $local_date = get_date_from_gmt($date, 'Y-m-d H:i:s'); + return date($format, strtotime($local_date)); } /** @@ -84,58 +84,57 @@ function format_date( $date, $format = '' ) { * * @see wp_unique_post_slug() * - * @param string $slug Desired slug. - * @param string $taxonomy Accepts any taxonomy slug, `author`, `series`, or `book_taxonomy`. + * @param string $slug Desired slug. + * @param string $taxonomy Accepts any taxonomy slug, `author`, `series`, or `book_taxonomy`. * * @return string A unique slug. */ -function unique_book_slug( $slug, $taxonomy = 'author' ) { - - // Check if this slug already exists. - if ( 'series' === $taxonomy ) { - $terms = get_book_series_by( 'slug', $slug ); - } elseif ( 'book_taxonomy' === $taxonomy ) { - $terms = get_book_taxonomy_by( 'slug', $slug ); - } elseif ( 'author' == $taxonomy ) { - $terms = get_book_author_by( 'slug', $slug ); - } else { - $terms = count_book_terms( array( - 'taxonomy' => $taxonomy, - 'slug' => $slug - ) ); - } - - $new_slug = $slug; - - if ( $terms ) { - $suffix = 2; - - do { - - $alt_slug = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . '-' . $suffix; - - if ( 'series' === $taxonomy ) { - $terms = get_book_series_by( 'slug', $alt_slug ); - } elseif ( 'book_taxonomy' === $taxonomy ) { - $terms = get_book_taxonomy_by( 'slug', $alt_slug ); - } elseif ( 'author' === $taxonomy ) { - $terms = get_book_author_by( 'slug', $alt_slug ); - } else { - $terms = count_book_terms( array( - 'taxonomy' => $taxonomy, - 'slug' => $alt_slug - ) ); - } - - $suffix ++; - - } while ( $terms ); - - $new_slug = $alt_slug; - } - - return apply_filters( 'book-database/unique-slug', $new_slug, $slug, $taxonomy ); - +function unique_book_slug(string $slug, string $taxonomy = 'author'): string +{ + // Check if this slug already exists. + if ('series' === $taxonomy) { + $terms = get_book_series_by('slug', $slug); + } elseif ('book_taxonomy' === $taxonomy) { + $terms = get_book_taxonomy_by('slug', $slug); + } elseif ('author' == $taxonomy) { + $terms = get_book_author_by('slug', $slug); + } else { + $terms = count_book_terms(array( + 'taxonomy' => $taxonomy, + 'slug' => $slug + )); + } + + $new_slug = $slug; + + if ($terms) { + $suffix = 2; + + do { + + $alt_slug = _truncate_post_slug($slug, 200 - (strlen($suffix) + 1)).'-'.$suffix; + + if ('series' === $taxonomy) { + $terms = get_book_series_by('slug', $alt_slug); + } elseif ('book_taxonomy' === $taxonomy) { + $terms = get_book_taxonomy_by('slug', $alt_slug); + } elseif ('author' === $taxonomy) { + $terms = get_book_author_by('slug', $alt_slug); + } else { + $terms = count_book_terms(array( + 'taxonomy' => $taxonomy, + 'slug' => $alt_slug + )); + } + + $suffix++; + + } while ($terms); + + $new_slug = $alt_slug; + } + + return apply_filters('book-database/unique-slug', $new_slug, $slug, $taxonomy); } /** @@ -146,54 +145,54 @@ function unique_book_slug( $slug, $taxonomy = 'author' ) { * * @return bool */ -function link_book_terms() { - return apply_filters( 'book-database/link-terms', true ); +function link_book_terms(): bool +{ + return (bool) apply_filters('book-database/link-terms', true); } /** * Get the term archive link * - * @param Author|BookTerm|Series|Rating $term + * @param Author|BookTerm|Series|Rating $term * - * @return bool + * @return string|false */ -function get_book_term_link( $term ) { - - if ( ! is_object( $term ) ) { - return false; - } - - $slug = method_exists( $term, 'get_slug' ) ? $term->get_slug() : ''; - $taxonomy = ''; - - if ( $term instanceof Author ) { - $taxonomy = 'author'; - } elseif ( $term instanceof BookTerm ) { - $taxonomy = $term->get_taxonomy(); - } elseif ( $term instanceof Series ) { - $taxonomy = 'series'; - } elseif ( $term instanceof Rating ) { - $taxonomy = 'rating'; - $slug = $term->get_rating(); - } - - if ( empty( $taxonomy ) || empty( $slug ) ) { - return false; - } - - $base_url = untrailingslashit( get_reviews_page_url() ); - $final_url = sprintf( '%1$s/%2$s/%3$s/', $base_url, urlencode( $taxonomy ), urlencode( $slug ) ); - - /** - * Filters the term archive URL. - * - * @param string $final_url Final archive URL. - * @param string $slug Term slug. - * @param string $taxonomy Term taxonomy / type. - * @param Author|BookTerm|Series|Rating $term Term object. - */ - return apply_filters( 'book-database/term-archive-link', $final_url, $slug, $taxonomy, $term ); - +function get_book_term_link($term) +{ + if (! is_object($term)) { + return false; + } + + $slug = method_exists($term, 'get_slug') ? $term->get_slug() : ''; + $taxonomy = ''; + + if ($term instanceof Author) { + $taxonomy = 'author'; + } elseif ($term instanceof BookTerm) { + $taxonomy = $term->get_taxonomy(); + } elseif ($term instanceof Series) { + $taxonomy = 'series'; + } elseif ($term instanceof Rating) { + $taxonomy = 'rating'; + $slug = $term->get_rating(); + } + + if (empty($taxonomy) || empty($slug)) { + return false; + } + + $base_url = untrailingslashit(get_reviews_page_url()); + $final_url = sprintf('%1$s/%2$s/%3$s/', $base_url, urlencode($taxonomy), urlencode($slug)); + + /** + * Filters the term archive URL. + * + * @param string $final_url Final archive URL. + * @param string $slug Term slug. + * @param string $taxonomy Term taxonomy / type. + * @param Author|BookTerm|Series|Rating $term Term object. + */ + return apply_filters('book-database/term-archive-link', $final_url, $slug, $taxonomy, $term); } /** @@ -201,10 +200,11 @@ function get_book_term_link( $term ) { * * @return \DateTimeZone */ -function get_site_timezone() { - if ( function_exists( 'wp_timezone' ) ) { - return wp_timezone(); - } else { - return new \DateTimeZone( get_option( 'timezone_string' ) ); - } +function get_site_timezone(): \DateTimeZone +{ + if (function_exists('wp_timezone')) { + return wp_timezone(); + } else { + return new \DateTimeZone(get_option('timezone_string')); + } } diff --git a/includes/shortcodes.php b/includes/shortcodes.php deleted file mode 100644 index be65b71d..00000000 --- a/includes/shortcodes.php +++ /dev/null @@ -1,410 +0,0 @@ - 0, - 'rating' => null - ), $atts, 'book' ); - - if ( empty( $atts['id'] ) || ! is_numeric( $atts['id'] ) ) { - return sprintf( __( 'Invalid book: %s', 'book-database' ), $atts['id'] ); - } - - $book = get_book( absint( $atts['id'] ) ); - - if ( ! $book instanceof Book ) { - return sprintf( __( 'Invalid book: %s', 'book-database' ), $atts['id'] ); - } - - $layout = new Book_Layout( $book ); - $layout->set_rating( $atts['rating'] ); - - $html = $layout->get_html(); - - /** - * Filters the [book] shortcode HTML. - * - * @param string $html Formatted book layout. - * @param Book $book Book object. - * @param array $atts Shortcode attributes. - * @param string $content Shortcode content. - */ - return apply_filters( 'book-database/shortcodes/book/output', $html, $book, $atts, $content ); - -} - -add_shortcode( 'book', __NAMESPACE__ . '\book_shortcode' ); - -/** - * Book reviews - * - * Displays a list of book reviews with filters allowing users to change the parameters. - * - * @param array $atts Shortcode attributes. - * @param string $content Shortcode content. - * - * @return string - */ -function book_reviews_shortcode( $atts, $content = '' ) { - - global $wp_query; - - $atts = shortcode_atts( array( - 'hide-future' => true, - 'per-page' => 20, - 'filters' => 'book_title book_author book_series rating genre publisher review_year orderby order', - 'cover-size' => 'medium' - ), $atts, 'book-reviews' ); - - $atts['hide-future'] = filter_var( $atts['hide-future'], FILTER_VALIDATE_BOOLEAN ); - - $query = new Book_Reviews_Query( $atts ); - $filters = explode( ' ', $atts['filters'] ); - - ob_start(); - ?> -
-
- -
- - - - query_vars['book_tax'] ) && 'author' === $wp_query->query_vars['book_tax'] && ! empty( $wp_query->query_vars['book_term'] ) ) { - $slug = $wp_query->query_vars['book_term']; - $author = get_book_author_by( 'slug', $slug ); - $author = $author instanceof Author ? $author->get_name() : ''; - } - ?> - - - query_vars['book_tax'] ) && 'series' === $wp_query->query_vars['book_tax'] && ! empty( $wp_query->query_vars['book_term'] ) ) { - $slug = $wp_query->query_vars['book_term']; - $series = get_book_series_by( 'slug', $slug ); - $series = $series instanceof Series ? $series->get_name() : ''; - } - ?> - - - query_vars['book_tax'] ) && 'rating' === $wp_query->query_vars['book_tax'] && ! empty( $wp_query->query_vars['book_term'] ) ) { - $selected_rating = $wp_query->query_vars['book_term']; - } - ?> - - - - - - - - - - - - $taxonomy->get_slug(), - 'number' => 300, - 'orderby' => 'name', - 'order' => 'ASC' - ) ); - - $selected_term = 'any'; - if ( ! empty( $_GET[ $taxonomy->get_slug() ] ) ) { - $selected_term = wp_strip_all_tags( $_GET[ $taxonomy->get_slug() ] ); - } elseif ( ! empty( $wp_query->query_vars['book_tax'] ) && $taxonomy->get_slug() === $wp_query->query_vars['book_tax'] && ! empty( $wp_query->query_vars['book_term'] ) ) { - $slug = $wp_query->query_vars['book_term']; - $term = get_book_term_by( 'slug', $slug ); - - if ( $term instanceof BookTerm ) { - $selected_term = $term->get_id(); - } - } - ?> - - - -
- -
-
- - -
-
-
- get_results(); - $template = get_book_template_part( 'shortcode-book-reviews-entry', '', false ); - - if ( ! empty( $reviews ) ) { - echo '
' . sprintf( _n( '%s review found', '%s reviews found', $query->total_results, 'book-database' ), $query->total_results ) . '
'; - echo '
'; - foreach ( $reviews as $review_data ) { - $review = new Review( $review_data ); - $book = new Book( array( - 'id' => $review_data->book_id ?? 0, - 'cover_id' => $review_data->book_cover_id ?? null, - 'title' => $review_data->book_title ?? '', - 'pub_date' => $review_data->book_pub_date ?? '', - 'series_position' => $review_data->series_position ?? '' - ) ); - $reading_log = new ReadingLog( array( - 'date_started' => $review_data->date_started_reading ?? null, - 'date_finished' => $review_data->date_finished_reading ?? null, - 'percentage_complete' => $review_data->percentage_complete ?? null, - 'rating' => $review_data->rating ?? null - ) ); - include $template; - } - echo '
'; - } else { - ?> -

- total_results > count( $reviews ) ) { - ?> - - -
- '', - 'author' => '', - 'series' => '', - 'rating' => '', - 'pub-date-after' => '', - 'pub-date-before' => '', - 'pub-year' => '', - 'read-status' => '', - 'review-date-after' => '', - 'review-date-before' => '', - 'review-start-date' => '', // Deprecated - 'review-end-date' => '', // Deprecated - 'reviews-only' => false, - 'show-ratings' => false, - 'show-pub-date' => true, - 'show-goodreads-link' => false, - 'show-purchase-links' => false, - 'show-review-link' => false, - 'orderby' => 'book.id', - 'order' => 'DESC', - 'cover-size' => 'large', - 'per-page' => 20, - ); - - foreach ( get_book_taxonomies( array( 'fields' => 'slug' ) ) as $tax_slug ) { - $default_atts[ $tax_slug ] = ''; - } - - $atts = shortcode_atts( $default_atts, $atts, 'book-grid' ); - - // Validate booleans. - $booleans = array( 'reviews-only', 'show-ratings', 'show-pub-date', 'show-goodreads-link', 'show-purchase-links', 'show-review-link' ); - foreach ( $booleans as $boolean ) { - $atts[ $boolean ] = filter_var( $atts[ $boolean ], FILTER_VALIDATE_BOOLEAN ); - } - - // Replace "review-start-date" and "review-end-date". - if ( ! empty( $atts['review-start-date'] ) ) { - $atts['review-date-after'] = $atts['review-start-date']; - } - if ( ! empty( $atts['review-end-date'] ) ) { - $atts['review-date-before'] = $atts['review-end-date']; - } - - $query = new Book_Grid_Query( $atts ); - - ob_start(); - ?> -
- get_results(); - $template = get_book_template_part( 'shortcode-book-grid-entry', '', false ); - - if ( ! empty( $books ) ) { - echo '
' . sprintf( _n( '%s book found', '%s books found', $query->total_results, 'book-database' ), $query->total_results ) . '
'; - echo '
'; - foreach ( $books as $book_data ) { - $book = new Book( $book_data ); - $review = false; - - // Create a review object if we can. - if ( ! empty( $book_data->review_id ) ) { - $review_data = array( - 'id' => $book_data->review_id ?? 0, - 'book_id' => $book->get_id(), - 'reading_log_id' => $book_data->review_reading_log_id ?? null, - 'user_id' => $book_data->review_user_id ?? null, - 'post_id' => $book_data->review_post_id ?? null, - 'url' => $book_data->review_url ?? '', - 'review' => $book_data->review_review ?? '', - 'date_written' => $book_data->review_date_written ?? '', - 'date_published' => $book_data->review_date_published ?? null, - 'date_created' => $book_data->review_date_created ?? '', - 'date_modified' => $book_data->review_date_modified ?? '' - ); - - $review = new Review( $review_data ); - } - - include $template; - } - echo '
'; - } else { - ?> -

- total_results > count( $books ) ) { - ?> - - -
- shortcodes as $shortcode) { + if (is_subclass_of($shortcode, Shortcode::class)) { + /** @var Shortcode $shortcode */ + $shortcode = book_database()->make($shortcode); + add_shortcode($shortcode::tag(), [$shortcode, 'make']); + } + } + } +} diff --git a/src/Shortcodes/BookGridShortcode.php b/src/Shortcodes/BookGridShortcode.php new file mode 100644 index 00000000..7ec01857 --- /dev/null +++ b/src/Shortcodes/BookGridShortcode.php @@ -0,0 +1,132 @@ + '', + 'author' => '', + 'series' => '', + 'rating' => '', + 'pub-date-after' => '', + 'pub-date-before' => '', + 'pub-year' => '', + 'read-status' => '', + 'review-date-after' => '', + 'review-date-before' => '', + 'review-start-date' => '', // Deprecated + 'review-end-date' => '', // Deprecated + 'reviews-only' => false, + 'show-ratings' => false, + 'show-pub-date' => true, + 'show-goodreads-link' => false, + 'show-purchase-links' => false, + 'show-review-link' => false, + 'orderby' => 'book.id', + 'order' => 'DESC', + 'cover-size' => 'large', + 'per-page' => 20, + ); + + foreach (get_book_taxonomies(array('fields' => 'slug')) as $tax_slug) { + $default_atts[$tax_slug] = ''; + } + + $atts = shortcode_atts($default_atts, $atts, 'book-grid'); + + // Validate booleans. + $booleans = array( + 'reviews-only', 'show-ratings', 'show-pub-date', 'show-goodreads-link', 'show-purchase-links', + 'show-review-link' + ); + foreach ($booleans as $boolean) { + $atts[$boolean] = filter_var($atts[$boolean], FILTER_VALIDATE_BOOLEAN); + } + + // Replace "review-start-date" and "review-end-date". + if (! empty($atts['review-start-date'])) { + $atts['review-date-after'] = $atts['review-start-date']; + } + if (! empty($atts['review-end-date'])) { + $atts['review-date-before'] = $atts['review-end-date']; + } + + $query = new Book_Grid_Query($atts); + + ob_start(); + ?> +
+ get_results(); + $template = get_book_template_part('shortcode-book-grid-entry', '', false); + + if (! empty($books)) { + echo '
'.sprintf(_n('%s book found', + '%s books found', $query->total_results, 'book-database'), $query->total_results).'
'; + echo '
'; + foreach ($books as $book_data) { + $book = new Book($book_data); + $review = false; + + // Create a review object if we can. + if (! empty($book_data->review_id)) { + $review_data = array( + 'id' => $book_data->review_id ?? 0, + 'book_id' => $book->get_id(), + 'reading_log_id' => $book_data->review_reading_log_id ?? null, + 'user_id' => $book_data->review_user_id ?? null, + 'post_id' => $book_data->review_post_id ?? null, + 'url' => $book_data->review_url ?? '', + 'review' => $book_data->review_review ?? '', + 'date_written' => $book_data->review_date_written ?? '', + 'date_published' => $book_data->review_date_published ?? null, + 'date_created' => $book_data->review_date_created ?? '', + 'date_modified' => $book_data->review_date_modified ?? '' + ); + + $review = new Review($review_data); + } + + include $template; + } + echo '
'; + } else { + ?> +

+ total_results > count($books)) { + ?> + + +
+ true, + 'per-page' => 20, + 'filters' => 'book_title book_author book_series rating genre publisher review_year orderby order', + 'cover-size' => 'medium', + ), $atts, 'book-reviews'); + + $atts['hide-future'] = filter_var($atts['hide-future'], FILTER_VALIDATE_BOOLEAN); + + $query = new Book_Reviews_Query($atts); + $filters = explode(' ', $atts['filters']); + + ob_start(); + ?> +
+
+ +
+ + + + query_vars['book_tax']) && 'author' === $wp_query->query_vars['book_tax'] && ! empty($wp_query->query_vars['book_term'])) { + $slug = $wp_query->query_vars['book_term']; + $author = get_book_author_by('slug', $slug); + $author = $author instanceof Author ? $author->get_name() : ''; + } + ?> + + + query_vars['book_tax']) && 'series' === $wp_query->query_vars['book_tax'] && ! empty($wp_query->query_vars['book_term'])) { + $slug = $wp_query->query_vars['book_term']; + $series = get_book_series_by('slug', $slug); + $series = $series instanceof Series ? $series->get_name() : ''; + } + ?> + + + query_vars['book_tax']) && 'rating' === $wp_query->query_vars['book_tax'] && ! empty($wp_query->query_vars['book_term'])) { + $selected_rating = $wp_query->query_vars['book_term']; + } + ?> + + + + + + + + + + + + $taxonomy->get_slug(), + 'number' => 300, + 'orderby' => 'name', + 'order' => 'ASC' + )); + + $selected_term = 'any'; + if (! empty($_GET[$taxonomy->get_slug()])) { + $selected_term = wp_strip_all_tags($_GET[$taxonomy->get_slug()]); + } elseif (! empty($wp_query->query_vars['book_tax']) && $taxonomy->get_slug() === $wp_query->query_vars['book_tax'] && ! empty($wp_query->query_vars['book_term'])) { + $slug = $wp_query->query_vars['book_term']; + $term = get_book_term_by('slug', $slug); + + if ($term instanceof BookTerm) { + $selected_term = $term->get_id(); + } + } + ?> + + + +
+ +
+
+ + + + +
+
+
+ get_results(); + $template = get_book_template_part('shortcode-book-reviews-entry', '', false); + + if (! empty($reviews)) { + echo '
'.sprintf(_n('%s review found', + '%s reviews found', $query->total_results, 'book-database'), $query->total_results).'
'; + echo '
'; + foreach ($reviews as $review_data) { + $review = new Review($review_data); + $book = new Book(array( + 'id' => $review_data->book_id ?? 0, + 'cover_id' => $review_data->book_cover_id ?? null, + 'title' => $review_data->book_title ?? '', + 'pub_date' => $review_data->book_pub_date ?? '', + 'series_position' => $review_data->series_position ?? '' + )); + $reading_log = new ReadingLog(array( + 'date_started' => $review_data->date_started_reading ?? null, + 'date_finished' => $review_data->date_finished_reading ?? null, + 'percentage_complete' => $review_data->percentage_complete ?? null, + 'rating' => $review_data->rating ?? null + )); + include $template; + } + echo '
'; + } else { + ?> +

+ total_results > count($reviews)) { + ?> + + +
+ 0, + 'rating' => null, + ), $atts, 'book'); + + if (empty($atts['id']) || ! is_numeric($atts['id'])) { + return sprintf(__('Invalid book: %s', 'book-database'), $atts['id']); + } + + $book = get_book(absint($atts['id'])); + + if (! $book instanceof Book) { + return sprintf(__('Invalid book: %s', 'book-database'), $atts['id']); + } + + $layout = new Book_Layout($book); + $layout->set_rating($atts['rating']); + + $html = $layout->get_html(); + + /** + * Filters the [book] shortcode HTML. + * + * @param string $html Formatted book layout. + * @param Book $book Book object. + * @param array $atts Shortcode attributes. + * @param string $content Shortcode content. + */ + return apply_filters('book-database/shortcodes/book/output', $html, $book, $atts, $content); + } +} diff --git a/src/Shortcodes/Shortcode.php b/src/Shortcodes/Shortcode.php new file mode 100644 index 00000000..b9149910 --- /dev/null +++ b/src/Shortcodes/Shortcode.php @@ -0,0 +1,36 @@ + Date: Sat, 19 Mar 2022 13:13:26 +0000 Subject: [PATCH 14/29] Move admin ListTable abstract. --- includes/admin/authors/class-authors-list-table.php | 3 ++- .../admin/book-terms/class-book-terms-list-table.php | 3 ++- includes/admin/books/class-books-list-table.php | 3 ++- includes/admin/reviews/class-reviews-list-table.php | 3 ++- includes/admin/series/class-series-list-table.php | 3 ++- .../Admin/Utils/ListTable.php | 10 +++++----- src/ServiceProviders/LegacyServiceProvider.php | 4 +++- 7 files changed, 18 insertions(+), 11 deletions(-) rename includes/admin/abstract-class-list-table.php => src/Admin/Utils/ListTable.php (97%) diff --git a/includes/admin/authors/class-authors-list-table.php b/includes/admin/authors/class-authors-list-table.php index 7b1c15e7..3b5e3ee3 100644 --- a/includes/admin/authors/class-authors-list-table.php +++ b/includes/admin/authors/class-authors-list-table.php @@ -9,6 +9,7 @@ namespace Book_Database; +use Book_Database\Admin\Utils\ListTable; use Book_Database\Exceptions\Exception; use Book_Database\Models\Author; @@ -17,7 +18,7 @@ * * @package Book_Database */ -class Authors_List_Table extends List_Table { +class Authors_List_Table extends ListTable { /** * Authors_List_Table constructor. diff --git a/includes/admin/book-terms/class-book-terms-list-table.php b/includes/admin/book-terms/class-book-terms-list-table.php index 24ea75b2..a4743401 100644 --- a/includes/admin/book-terms/class-book-terms-list-table.php +++ b/includes/admin/book-terms/class-book-terms-list-table.php @@ -9,6 +9,7 @@ namespace Book_Database; +use Book_Database\Admin\Utils\ListTable; use Book_Database\Exceptions\Exception; use Book_Database\Models\BookTaxonomy; use Book_Database\Models\BookTerm; @@ -18,7 +19,7 @@ * * @package Book_Database */ -class Book_Terms_List_Table extends List_Table { +class Book_Terms_List_Table extends ListTable { protected $default_taxonomy; diff --git a/includes/admin/books/class-books-list-table.php b/includes/admin/books/class-books-list-table.php index 5f6c52e2..a1267d87 100644 --- a/includes/admin/books/class-books-list-table.php +++ b/includes/admin/books/class-books-list-table.php @@ -9,6 +9,7 @@ namespace Book_Database; +use Book_Database\Admin\Utils\ListTable; use Book_Database\Database\Books\BooksQuery; use Book_Database\Models\Book; use Book_Database\ValueObjects\Rating; @@ -18,7 +19,7 @@ * * @package Book_Database */ -class Books_List_Table extends List_Table { +class Books_List_Table extends ListTable { /** * Mode diff --git a/includes/admin/reviews/class-reviews-list-table.php b/includes/admin/reviews/class-reviews-list-table.php index d6ede120..a0986e54 100644 --- a/includes/admin/reviews/class-reviews-list-table.php +++ b/includes/admin/reviews/class-reviews-list-table.php @@ -9,6 +9,7 @@ namespace Book_Database; +use Book_Database\Admin\Utils\ListTable; use Book_Database\Database\Reviews\ReviewsQuery; use Book_Database\Exceptions\Exception; use Book_Database\Models\Book; @@ -20,7 +21,7 @@ * * @package Book_Database */ -class Reviews_List_Table extends List_Table { +class Reviews_List_Table extends ListTable { /** * Reviews_List_Table constructor. diff --git a/includes/admin/series/class-series-list-table.php b/includes/admin/series/class-series-list-table.php index d820ae2b..2bc80228 100644 --- a/includes/admin/series/class-series-list-table.php +++ b/includes/admin/series/class-series-list-table.php @@ -9,6 +9,7 @@ namespace Book_Database; +use Book_Database\Admin\Utils\ListTable; use Book_Database\Models\Series; use Book_Database\ValueObjects\Rating; @@ -17,7 +18,7 @@ * * @package Book_Database */ -class Series_List_Table extends List_Table { +class Series_List_Table extends ListTable { /** * Series_List_Table constructor. diff --git a/includes/admin/abstract-class-list-table.php b/src/Admin/Utils/ListTable.php similarity index 97% rename from includes/admin/abstract-class-list-table.php rename to src/Admin/Utils/ListTable.php index 321600a0..753d0dc5 100644 --- a/includes/admin/abstract-class-list-table.php +++ b/src/Admin/Utils/ListTable.php @@ -3,24 +3,24 @@ * Admin List Table Base Class * * @package book-database - * @copyright Copyright (c) 2019, Ashley Gibson + * @copyright Copyright (c) 2022, Ashley Gibson * @license GPL2+ */ -namespace Book_Database; +namespace Book_Database\Admin\Utils; -// Load WP_List_Table if not loaded use Book_Database\Models\Model; +// Load WP_List_Table if not loaded if ( ! class_exists( '\WP_List_Table' ) ) { require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; } /** - * Class List_Table + * Class ListTable * @package Book_Database */ -abstract class List_Table extends \WP_List_Table { +abstract class ListTable extends \WP_List_Table { /** * Number of items per page diff --git a/src/ServiceProviders/LegacyServiceProvider.php b/src/ServiceProviders/LegacyServiceProvider.php index 15b1dbfc..c2d9ef57 100644 --- a/src/ServiceProviders/LegacyServiceProvider.php +++ b/src/ServiceProviders/LegacyServiceProvider.php @@ -173,7 +173,6 @@ private function includeLegacyFiles(): void private function includeAdminFiles(): void { - require_once BDB_DIR.'includes/admin/abstract-class-list-table.php'; require_once BDB_DIR.'includes/admin/admin-assets.php'; require_once BDB_DIR.'includes/admin/admin-bar.php'; require_once BDB_DIR.'includes/admin/admin-notices.php'; @@ -361,6 +360,9 @@ class_alias( \Book_Database\Analytics\Datasets\Reviews_Over_Time::class, '\Book_ class_alias( \Book_Database\Analytics\Datasets\Reviews_Written::class, '\Book_Database\Analytics\Reviews_Written' ); class_alias( \Book_Database\Analytics\Datasets\Shortest_Book_Read::class, '\Book_Database\Analytics\Shortest_Book_Read' ); class_alias( \Book_Database\Analytics\Datasets\Terms_Breakdown::class, '\Book_Database\Analytics\Terms_Breakdown' ); + + // Admin + class_alias(\Book_Database\Admin\Utils\ListTable::class, '\Book_Database\List_Table'); } private function bindClasses(): void From 49145b0f66ed21f7c11f095c8bdd18242d130cd6 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 19 Mar 2022 13:13:34 +0000 Subject: [PATCH 15/29] Allow nullable return type. --- src/Models/Book.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Models/Book.php b/src/Models/Book.php index dd0257cb..a73228e7 100644 --- a/src/Models/Book.php +++ b/src/Models/Book.php @@ -218,9 +218,9 @@ public function get_series_name() * to local time. We keep it in UTC always. * @param string $format Format to display in. Defaults to site format. * - * @return string + * @return string|null */ - public function get_pub_date(bool $formatted = false, string $format = ''): string + public function get_pub_date(bool $formatted = false, string $format = ''): ?string { if (empty($this->pub_date) || ! $formatted) { From dfe2a7e7bdddfc81d4f5e55fac7da21d6c3567e1 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 19 Mar 2022 13:15:09 +0000 Subject: [PATCH 16/29] Allow null returns. --- src/Models/ReadingLog.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Models/ReadingLog.php b/src/Models/ReadingLog.php index cbabbfa4..737df9ae 100644 --- a/src/Models/ReadingLog.php +++ b/src/Models/ReadingLog.php @@ -90,9 +90,9 @@ public function get_date_started(bool $formatted = false, string $format = ''): * @param bool $formatted Whether or not to format the result for display. * @param string $format Format to display in. Defaults to site format. * - * @return string + * @return string|null */ - public function get_date_finished(bool $formatted = false, string $format = ''): string + public function get_date_finished(bool $formatted = false, string $format = ''): ?string { return (! empty($this->date_finished) && $formatted) ? format_date($this->date_finished, $format) From 0d4118b92629b66fade99ae628622418a60bd811 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 19 Mar 2022 13:23:56 +0000 Subject: [PATCH 17/29] Fix review queries. --- includes/reviews/review-functions.php | 2 +- src/Models/Model.php | 6 +++--- src/Models/Review.php | 17 +++++++++++++++++ src/REST_API/v1/Review.php | 2 +- src/Traits/HasQueryInterface.php | 4 ++-- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/includes/reviews/review-functions.php b/includes/reviews/review-functions.php index 60d0c30c..8580703b 100644 --- a/includes/reviews/review-functions.php +++ b/includes/reviews/review-functions.php @@ -66,7 +66,7 @@ function get_review_by(string $column_name, $column_value) * @type bool $count Whether or not to only return a count. Default false. * } * - * @return object[] Array of database objects. + * @return Review[] Array of database objects. */ function get_reviews(array $args = []): array { diff --git a/src/Models/Model.php b/src/Models/Model.php index 11e079a6..9db0254a 100644 --- a/src/Models/Model.php +++ b/src/Models/Model.php @@ -24,11 +24,11 @@ abstract class Model { use HasQueryInterface; - protected $id = 0; + public $id = 0; - protected $date_created = ''; + public $date_created = ''; - protected $date_modified = ''; + public $date_modified = ''; /** * Object constructor diff --git a/src/Models/Review.php b/src/Models/Review.php index fc0a7a95..60a8fe5f 100644 --- a/src/Models/Review.php +++ b/src/Models/Review.php @@ -17,6 +17,8 @@ /** * Class Review * + * @method static ReviewsQuery getQueryInterface() + * * @package Book_Database * @since 1.3 Namespace changed. */ @@ -269,4 +271,19 @@ public function is_published(): bool return ($this->get_date_published(true, 'U') <= current_time('timestamp')); } + /** + * Queries for reviews. + * + * @since 1.3 + * + * @param array $args + * + * @return Review[]|array + * @throws \Exception + */ + public static function query(array $args = []): array + { + return static::getQueryInterface()->get_reviews($args); + } + } diff --git a/src/REST_API/v1/Review.php b/src/REST_API/v1/Review.php index ba6508ea..d83fbf9b 100644 --- a/src/REST_API/v1/Review.php +++ b/src/REST_API/v1/Review.php @@ -178,7 +178,7 @@ public function get_reviews( $request ) { // Format ratings. if ( $request->get_param( 'rating_format' ) ) { foreach ( $reviews as $key => $review ) { - if ( is_null( $review->rating ) ) { + if ( is_null( $review->rating ?? null ) ) { continue; } diff --git a/src/Traits/HasQueryInterface.php b/src/Traits/HasQueryInterface.php index e8a076e4..ae2a8f91 100644 --- a/src/Traits/HasQueryInterface.php +++ b/src/Traits/HasQueryInterface.php @@ -159,7 +159,7 @@ public static function findBy(string $column, $value): Model */ public static function query(array $args = []): array { - return self::getQueryInterface()->query($args); + return static::getQueryInterface()->query($args); } /** @@ -174,7 +174,7 @@ public static function query(array $args = []): array */ public static function all(array $args = []): array { - return self::query(wp_parse_args($args, ['number' => 9999])); + return static::query(wp_parse_args($args, ['number' => 9999])); } /** From c1030acb53da9d12a5a0f17e733b692a8c845492 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 19 Mar 2022 13:27:40 +0000 Subject: [PATCH 18/29] Update block category filter. #261 --- includes/blocks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/blocks.php b/includes/blocks.php index 0e79d691..349794fc 100644 --- a/includes/blocks.php +++ b/includes/blocks.php @@ -28,7 +28,7 @@ function register_block_category( $categories, $post ) { return $categories; } -add_filter( 'block_categories', __NAMESPACE__ . '\register_block_category', 10, 2 ); +add_filter( 'block_categories_all', __NAMESPACE__ . '\register_block_category', 10, 2 ); /** * Register Gutenberg blocks From 7ee3d2d288610d690fd4135f815e8cfccf392f2c Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 19 Mar 2022 13:28:28 +0000 Subject: [PATCH 19/29] Add filter note. --- includes/blocks.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/includes/blocks.php b/includes/blocks.php index 349794fc..fa997b2a 100644 --- a/includes/blocks.php +++ b/includes/blocks.php @@ -12,6 +12,8 @@ /** * Adds a new block category for Book Database. * + * Note: This filter requires WP 5.8+ + * * @param array $categories * @param \WP_Post $post * From 958f28115fedf670a9225ade217f00313a668e53 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Sat, 19 Mar 2022 13:35:19 +0000 Subject: [PATCH 20/29] Add Alpine.js --- assets/js/build/alpine.min.js | 5 +++++ includes/admin/admin-assets.php | 16 ++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 assets/js/build/alpine.min.js diff --git a/assets/js/build/alpine.min.js b/assets/js/build/alpine.min.js new file mode 100644 index 00000000..69e438a6 --- /dev/null +++ b/assets/js/build/alpine.min.js @@ -0,0 +1,5 @@ +(()=>{var qe=!1,Ue=!1,F=[];function kt(e){tn(e)}function tn(e){F.includes(e)||F.push(e),rn()}function he(e){let t=F.indexOf(e);t!==-1&&F.splice(t,1)}function rn(){!Ue&&!qe&&(qe=!0,queueMicrotask(nn))}function nn(){qe=!1,Ue=!0;for(let e=0;ee.effect(t,{scheduler:r=>{Ge?kt(r):r()}}),We=e.raw}function Ye(e){K=e}function Dt(e){let t=()=>{};return[n=>{let i=K(n);e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),Y(i))}},()=>{t()}]}var $t=[],Lt=[],jt=[];function Ft(e){jt.push(e)}function _e(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,Lt.push(t))}function Kt(e){$t.push(e)}function Bt(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function Je(e,t){!e._x_attributeCleanups||Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}var Qe=new MutationObserver(Ze),Xe=!1;function et(){Qe.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),Xe=!0}function sn(){on(),Qe.disconnect(),Xe=!1}var te=[],tt=!1;function on(){te=te.concat(Qe.takeRecords()),te.length&&!tt&&(tt=!0,queueMicrotask(()=>{an(),tt=!1}))}function an(){Ze(te),te.length=0}function m(e){if(!Xe)return e();sn();let t=e();return et(),t}var rt=!1,ge=[];function zt(){rt=!0}function Vt(){rt=!1,Ze(ge),ge=[]}function Ze(e){if(rt){ge=ge.concat(e);return}let t=[],r=[],n=new Map,i=new Map;for(let o=0;os.nodeType===1&&t.push(s)),e[o].removedNodes.forEach(s=>s.nodeType===1&&r.push(s))),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{Je(s,o)}),n.forEach((o,s)=>{$t.forEach(a=>a(s,o))});for(let o of r)if(!t.includes(o)&&(Lt.forEach(s=>s(o)),o._x_cleanups))for(;o._x_cleanups.length;)o._x_cleanups.pop()();t.forEach(o=>{o._x_ignoreSelf=!0,o._x_ignore=!0});for(let o of t)r.includes(o)||!o.isConnected||(delete o._x_ignoreSelf,delete o._x_ignore,jt.forEach(s=>s(o)),o._x_ignore=!0,o._x_ignoreSelf=!0);t.forEach(o=>{delete o._x_ignoreSelf,delete o._x_ignore}),t=null,r=null,n=null,i=null}function xe(e){return I(k(e))}function T(e,t,r){return e._x_dataStack=[t,...k(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function nt(e,t){let r=e._x_dataStack[0];Object.entries(t).forEach(([n,i])=>{r[n]=i})}function k(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?k(e.host):e.parentNode?k(e.parentNode):[]}function I(e){let t=new Proxy({},{ownKeys:()=>Array.from(new Set(e.flatMap(r=>Object.keys(r)))),has:(r,n)=>e.some(i=>i.hasOwnProperty(n)),get:(r,n)=>(e.find(i=>{if(i.hasOwnProperty(n)){let o=Object.getOwnPropertyDescriptor(i,n);if(o.get&&o.get._x_alreadyBound||o.set&&o.set._x_alreadyBound)return!0;if((o.get||o.set)&&o.enumerable){let s=o.get,a=o.set,c=o;s=s&&s.bind(t),a=a&&a.bind(t),s&&(s._x_alreadyBound=!0),a&&(a._x_alreadyBound=!0),Object.defineProperty(i,n,{...c,get:s,set:a})}return!0}return!1})||{})[n],set:(r,n,i)=>{let o=e.find(s=>s.hasOwnProperty(n));return o?o[n]=i:e[e.length-1][n]=i,!0}});return t}function ye(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function be(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>cn(n,i),s=>it(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function cn(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function it(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),it(e[t[0]],t.slice(1),r)}}var Ht={};function y(e,t){Ht[e]=t}function re(e,t){return Object.entries(Ht).forEach(([r,n])=>{Object.defineProperty(e,`$${r}`,{get(){let[i,o]=ot(t);return i={interceptor:be,...i},_e(t,o),n(t,i)},enumerable:!1})}),e}function qt(e,t,r,...n){try{return r(...n)}catch(i){J(i,e,t)}}function J(e,t,r=void 0){Object.assign(e,{el:t,expression:r}),console.warn(`Alpine Expression Error: ${e.message} + +${r?'Expression: "'+r+`" + +`:""}`,t),setTimeout(()=>{throw e},0)}function N(e,t,r={}){let n;return g(e,t)(i=>n=i,r),n}function g(...e){return Ut(...e)}var Ut=st;function Wt(e){Ut=e}function st(e,t){let r={};re(r,e);let n=[r,...k(e)];if(typeof t=="function")return ln(n,t);let i=un(n,t,e);return qt.bind(null,e,t,i)}function ln(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(I([n,...e]),i);ve(r,o)}}var at={};function fn(e,t){if(at[e])return at[e];let r=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)\s/.test(e)?`(() => { ${e} })()`:e,o=(()=>{try{return new r(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`)}catch(s){return J(s,t,e),Promise.resolve()}})();return at[e]=o,o}function un(e,t,r){let n=fn(t,r);return(i=()=>{},{scope:o={},params:s=[]}={})=>{n.result=void 0,n.finished=!1;let a=I([o,...e]);if(typeof n=="function"){let c=n(n,a).catch(l=>J(l,r,t));n.finished?(ve(i,n.result,a,s,r),n.result=void 0):c.then(l=>{ve(i,l,a,s,r)}).catch(l=>J(l,r,t)).finally(()=>n.result=void 0)}}}function ve(e,t,r,n,i){if(typeof t=="function"){let o=t.apply(r,n);o instanceof Promise?o.then(s=>ve(e,s,r,n)).catch(s=>J(s,i,t)):e(o)}else e(t)}var ct="x-";function w(e=""){return ct+e}function Gt(e){ct=e}var Yt={};function p(e,t){Yt[e]=t}function ne(e,t,r){let n={};return Array.from(t).map(Jt((o,s)=>n[o]=s)).filter(Zt).map(pn(n,r)).sort(mn).map(o=>dn(e,o))}function Qt(e){return Array.from(e).map(Jt()).filter(t=>!Zt(t))}var lt=!1,ie=new Map,Xt=Symbol();function er(e){lt=!0;let t=Symbol();Xt=t,ie.set(t,[]);let r=()=>{for(;ie.get(t).length;)ie.get(t).shift()();ie.delete(t)},n=()=>{lt=!1,r()};e(r),n()}function ot(e){let t=[],r=a=>t.push(a),[n,i]=Dt(e);return t.push(i),[{Alpine:P,effect:n,cleanup:r,evaluateLater:g.bind(g,e),evaluate:N.bind(N,e)},()=>t.forEach(a=>a())]}function dn(e,t){let r=()=>{},n=Yt[t.type]||r,[i,o]=ot(e);Bt(e,t.original,o);let s=()=>{e._x_ignore||e._x_ignoreSelf||(n.inline&&n.inline(e,t,i),n=n.bind(n,e,t,i),lt?ie.get(Xt).push(n):n())};return s.runCleanups=o,s}var we=(e,t)=>({name:r,value:n})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:n}),Ee=e=>e;function Jt(e=()=>{}){return({name:t,value:r})=>{let{name:n,value:i}=tr.reduce((o,s)=>s(o),{name:t,value:r});return n!==t&&e(n,t),{name:n,value:i}}}var tr=[];function Z(e){tr.push(e)}function Zt({name:e}){return rr().test(e)}var rr=()=>new RegExp(`^${ct}([^:^.]+)\\b`);function pn(e,t){return({name:r,value:n})=>{let i=r.match(rr()),o=r.match(/:([a-zA-Z0-9\-:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var ut="DEFAULT",Se=["ignore","ref","data","id","bind","init","for","model","modelable","transition","show","if",ut,"teleport","element"];function mn(e,t){let r=Se.indexOf(e.type)===-1?ut:e.type,n=Se.indexOf(t.type)===-1?ut:t.type;return Se.indexOf(r)-Se.indexOf(n)}function B(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}var ft=[],dt=!1;function Oe(e){ft.push(e),queueMicrotask(()=>{dt||setTimeout(()=>{Ae()})})}function Ae(){for(dt=!1;ft.length;)ft.shift()()}function nr(){dt=!0}function C(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>C(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)C(n,t,!1),n=n.nextElementSibling}function z(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}function or(){document.body||z("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's `