diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bc6627..d2320c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,323 +1,324 @@ # Changelog -## v3.8.7 +## [v3.9.0] - 2026-07-07 + +- Feat: add related items filtering on type tax when setting enabled +- Fix: tests + +## [v3.8.7] - 2026-06-10 - Fix: add psr/container -## v3.8.6 +## [v3.8.6] - 2026-06-10 - Chore: use 10up/elasticpress -## v3.8.5 +## [v3.8.5] - 2026-06-10 - Fix: Restore default expiration dates feature -## v3.8.4 +## [v3.8.4] - 2026-06-02 - Chore: update cmb2, move to wp-packages over wp-packagist -## v3.8.3 - -- Fix: Restore default expiration dates feature - -## v3.8.3 +## [v3.8.3] - 2026-03-19 - Chore: Revert to wp-packagist version of 10up/elasticpress due to psr/container conflicts -## v3.8.2 +## [v3.8.2] - 2026-03-19 - Fix: Add php version constraints -## v3.8.1 +## [v3.8.1] - 2026-03-17 - Chore: Remove plugin repositories in favour of direct composer support -## v3.8.0 +## [v3.8.0] - 2026-01-13 - Feat: add filter dropdown for easy filtering of target website @rmpel (#45) -## v3.7.7 +## [v3.7.7] - 2025-08-15 - Feat: add query parameters for taxonomies added through apply_filter -## v3.7.6 +## [v3.7.6] - 2025-07-17 - Feat: add taxonomies to API added through apply_filter -## v3.7.5 +## [v3.7.5] - 2025-07-16 - Feat: add author id in API response of items endpoint -## v3.7.4 +## [v3.7.4] - 2025-07-03 - Feat: apply filter before registering extended taxonomies -## v3.7.3 +## [v3.7.3] - 2025-03-28 - Feat: getShowOnPortalURL(): add filter and sorting for portalUrls by numeric blogId with taxonomy 'openpub-show-on' -## v3.7.2 +## [v3.7.2] - 2025-03-28 - Refactor: register rest routes in correct order -## v3.7.1 +## [v3.7.1] - 2025-03-25 - Fix: autoloader -## v3.7.0 +## [v3.7.0] - 2025-03-20 - Feat: update extended-cpts to v5 -## v3.6.1 +## [v3.6.1] - 2025-03-18 - Feat: use the correct portal URL if the Show On functionality is used. (Partly copied from PDC Base) @richardkorthuis (#37) -## v3.6.0 +## [v3.6.0] - 2025-03-13 - Feat: added wp_reset_postdata() @eyal (#34) - Feat: setup global postdata for OpenPub item @eyal (#34) - Feat: update SettingsController.php @eyal (#35) -## v3.5.3 +## [v3.5.3] - 2025-03-11 - Fix: translations just in time error -## v3.5.2 +## [v3.5.2] - 2025-02-10 - Feat: add settings API endpoint. @richardkorthuis (#31) -## v3.5.1 +## [v3.5.1] - 2024-10-30 - Refactor: Remove optional params from fillPostName called by 'wp_insert_post_data' hook -## v3.5.0 +## [v3.5.0] - 2024-10-23 - Feat: add filter for altering the post types config -## v3.4.8 +## [v3.4.8] - 2024-09-20 - Fix: Fix composer.lock on PHP 7.4 rather than PHP 8.1 -## v3.4.7 +## [v3.4.7] - 2024-06-26 - Refactor: openpub-show-on taxonomy capabilities to 'manage_options' -## v3.4.6 +## [v3.4.6] - 2024-06-21 - Refactor: enable openpub-show-on taxonomy in REST -## v3.4.5 +## [v3.4.5] - 2024-06-17 - Chore: Updated elasticpress to v5 -## v3.4.4 +## [v3.4.4] - 2024-04-26 - Refactor: CMB2 'show on' taxonomy field type from 'select_advanced' to 'taxonomy_multicheck' -## v3.4.3 +## [v3.4.3] - 2024-04-05 - Chore: Updated CMB2 to version 2.11.0 -## v3.4.2 +## [v3.4.2] - 2024-01-02 - Fix: Ensure that only authenticated users can access draft preview items in the API response -## v3.4.1 +## [v3.4.1] - 2023-11-07 - Feat: Enable filtering on taxonomy 'openpub-audience' - Feat: Add 'date_modified_gmt' to the API response - Feat: Add translation for 'Author' -## v3.4.0 +## [v3.4.0] - 2023-09-27 - Feat: Support for multiple type params in tax query used in API responses -## v3.3.3 +## [v3.3.3] - 2023-09-14 - Feat: DateTime modifier could also be a negative integer inside Item repository class. -## v3.3.2 +## [v3.3.2] - 2023-09-13 - Fix: Expiration Parameters because the CMB2 field type 'text_datetime_timestamp' is not working correctly. -## v3.3.1 +## [v3.3.1] - 2023-09-11 - Fix: Comparing expiration date with 'now' is done wrongly by comparing different timezones. -## v3.3.0 +## [v3.3.0] - 2023-08-22 - Feat: Add 'date_modified' to theme endpoints. - Feat: Add 'yoast' to theme endpoints. -## v3.2.0 +## [v3.2.0] - 2023-08-01 - Feat: Add endpoint to search for themes by their slug. -## v3.1.3 +## [v3.1.3] - 2023-07-19 - Fix: Duplicated post_names when multiple items had the same post_title. -## v3.1.2 +## [v3.1.2] - 2023-07-17 - Fix: Restore some of the documented actions and filters. -## v3.1.1 +## [v3.1.1] - 2023-07-06 - Feat: Always fill the post_name when an openpub-item is saved, is required for previewing openpub-items. -## v3.1.0 +## [v3.1.0] - 2023-06-20 - Feat: Fill the post_name when an openpub-item is not published, is required for previewing openpub-items. - Feat: Upgrade admin notices. -## v3.0.2 +## [v3.0.2] - 2023-05-26 - Feat: Always return date_modified in API. -## v3.0.1 +## [v3.0.1] - 2023-04-21 - Feat: Add future post status when retrieving item for draft preview. -## v3.0.0 +## [v3.0.0] - 2023-03-31 - Feat: Implement CMB2 metabox plugin. - Chore: Clean-up/refactoring. -## v2.3.3 +## [v2.3.3] - 2023-03-28 - Feat: Related items type taxonomy args. -## v2.3.2 +## [v2.3.2] - 2023-03-21 - Feat: Added the 'johnbillion/extended-cpts' package as dependency to composer.json. - Chore: Update dependencies. - Chore: Directory name of plugin in README.md. -## v2.3.1 +## [v2.3.1] - 2023-03-21 - Fix: checkForUpdate() inside Plugin class should not run when class is being extended. -## v2.3.0 +## [v2.3.0] - 2023-03-06 - Feat: Updates can now be provided through the Admin interface. -## v2.2.2 +## [v2.2.2] - 2023-02-14 - Chore: Change the settings page identifier to prevent collision with OpenPDC. -## v2.2.1 +## [v2.2.1] - 2023-02-09 - Feat: Filter items, in API, on type taxonomy slug when param is set. -## v2.2.0 +## [v2.2.0] - 2022-12-19 - Feat: Support PHP 8 - Chore: Update dependencies. -## v2.1.1 +## [v2.1.1] - 2022-11-01 - Feat: Remove Elasticpress settings when plugin yard-elasticsearch is active -## v2.1.0 +## [v2.1.0] - 2022-11-30 - Feat: Include SEO meta fields, provided by multiple plugins, in API. -## v2.0.20 +## [v2.0.20] - 2022-11-16 - Chore: Taxonomy openpub-show-on change capabilities from manage_options to manage_categories. -## v2.0.19 +## [v2.0.19] - 2022-10-07 - Chore: Update dependencies. -## v2.0.18 +## [v2.0.18] - 2022-02-18 - Feat: Generating portal URL. -### Fix +### [Fix] - Fix: Return value in filter 'post_type_link' registered in '\OWC\OpenPub\Base\Admin\AdminServiceProvider::class. -## v2.0.17 +## [v2.0.17] - 2022-01-28 - Feat: Set argument public to false for the CPT's 'openpub-theme', 'openpub-subtheme' and 'openpub-location' so ElasticPress does not include them in the sync. -## v2.0.16 +## [v2.0.16] - 2021-12-10 - Feat: Add featured image field to related items -## v2.0.15 +## [v2.0.15] - 2021-11-12 - Feat: Change 'preview' parameter into 'draft-preview' -## v2.0.14 +## [v2.0.14] - 2021-10-19 - Fix: Append id for pdc draft previews -## v2.0.13 +## [v2.0.13] - 2021-10-22 - Fix: Elasticpress indexables posttypes and statuses hooks was not correctly returned. -## v2.0.12 +## [v2.0.12] - 2021-10-08 - Feat: Existing OpenPub items without an expiration date will be assigned a value of the published date plus the value given in days. - Feat: New OpenPub items will have a value of the current date plus the value given in days. -## v2.0.11 +## [v2.0.11] - 2021-07-15 - Fix: Meta-query with multiple arguments not working correctly. -## v2.0.10 +## [v2.0.10] - 2021-07-12 - Feat: Add preview parameter for retrieving drafts - Feat: Purge Varnish on save_post - Fix: Add addHighlightedParameters to active items -## v2.0.9 +## [v2.0.9] - 2021-07-09 - Feat: Add author column for openpub items -## v2.0.8 +## [v2.0.8] - 2021-06-02 - Feat: Add explanation to 'show on' taxonomy form. - Feat: Only use 'show on' filtering in endpoints when setting is active. - Feat: Filter related items on source slug when param is set. -## v2.0.7 +## [v2.0.7] - 2021-05-27 - Feat: Add filtering on 'show on' to active items endpoint. - Feat: 'show on' taxonomy is only allowed to be managed by administrators. -## v2.0.6 +## [v2.0.6] - 2021-05-27 - Refactor: Filtering on 'show on' in items endpoint from string to numeric value. -## v2.0.5 +## [v2.0.5] - 2021-05-10 - Feat: Add 'show on' setting to openpub-settings. - Feat: Add 'show on' setting in editor of openpub-item. - Feat: Add filtering on 'show on' to items endpoint. -## v2.0.4 +## [v2.0.4] - 2021-04-06 - Feat: Add escape element setting to openpub-settings. - Feat: Add escape element setting in editor of openpub-item. -## v2.0.3 +## [v2.0.3] - 2021-03-12 - Fix: Filter inactive items -## v2.0.2 +## [v2.0.2] - 2021-02-26 - Feat: Add slug to related item in API. - Feat: Add multiple unit tests. -## v2.0.1 +## [v2.0.1] - 2021-01-08 - Feat: Add full image size to attachment meta - Feat: Add expiration parameters to related items -## v2.0.0 +## [v2.0.0] - 2020-11-25 - Chore: Clean-up for version 1.0. - Feat: Add settings on settings page. @@ -326,95 +327,95 @@ - Feat: Add date_modified to API output on conditional. - Fix: Base settings on settings page. -## v1.2.0 +## [v1.2.0] - 2020-11-10 - Feat: Comments to items. -## v1.1.9 +## [v1.1.9] - 2020-10-30 - Feat: Highlighted parameter on rest endpoint. -## v1.1.8 +## [v1.1.8] - 2020-07-29 - Feat: Add correct mappings for ElasticSearch. -## v1.1.7 +## [v1.1.7] - 2020-07-21 - Feat: Add openpub rest route route on slug. -## v1.1.6 +## [v1.1.6] - 2020-07-17 - Feat: Add add thumnbail url to related posts. -## v1.1.5 +## [v1.1.5] - 2020-05-27 - Fix: Standardize expired date for better compatibility. -## v1.1.4 +## [v1.1.4] - 2020-03-05 - Feat: Add make posttypes and taxonomies available in REST API. -## v1.1.3 +## [v1.1.3] - 2020-01-28 - Feat: Add make taxonomy "openpub-type" available in REST API. -## v1.1.2 +## [v1.1.2] - 2020-01-17 - Feat: Add endpoint for active items only: `wp-json/owc/openpub/v1/items/active`. -## v1.1.1 +## [v1.1.1] - 2019-10-25 - Fix: Remove unwanted redirect. -## v1.1.0 +## [v1.1.0] - 2019-09-07 - Fix: Remove unwanted exit. - Fix: Related items of theme REST API. -## v1.0.9 +## [v1.0.9] - 2019-09-03 - Chore: Remove Hooks class. -## v1.0.8 +## [v1.0.8] - 2019-08-02 - Feat: Add query args for REST API. - Update: PHPunit 8. -## v1.0.7 +## [v1.0.7] - 2019-05-02 - Fix: Check if required file for `is_plugin_active` is already loaded, otherwise load it. _Props @Jasper Heidebrink_ -## v1.0.6 +## [v1.0.6] - 2019-01-31 - Feat: Add openpub endpoint description for documentation. -## v1.0.5 +## [v1.0.5] - 2018-12-05 - Feat: Add default order of published date. -## v1.0.4 +## [v1.0.4] - 2018-11-22 - Feat: Add filter options to REST API. -## v1.0.3 +## [v1.0.3] - 2018-11-15 - Update: Languages - Feat: Add highlighted item to API. -## v1.0.2 +## [v1.0.2] - 2018-11-01 - Update: Languages - Change: Format of REST API to follow WP_Post for elasticsearch - Chore: Remove unused setting tab -## v1.0.1 +## [v1.0.1] - 2018-10-30 - Feat: Add docs. - Feat: Add PHP style linter. - Change: Add REST API output to follow WP_Post. -## v1.0.0 +## [v1.0.0] - 2018-06-28 - Initial release. - The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), diff --git a/config/api.php b/config/api.php index d9a8cde..26b55cb 100644 --- a/config/api.php +++ b/config/api.php @@ -12,7 +12,7 @@ */ 'item' => [ 'fields' => [ - 'author_id' => OWC\OpenPub\Base\RestAPI\ItemFields\AuthorField::class, + 'author_id' => OWC\OpenPub\Base\RestAPI\ItemFields\AuthorField::class, 'comments' => OWC\OpenPub\Base\RestAPI\ItemFields\CommentField::class, 'connected' => OWC\OpenPub\Base\RestAPI\ItemFields\ConnectedField::class, 'portal_url' => OWC\OpenPub\Base\RestAPI\ItemFields\PortalURL::class, diff --git a/config/cmb2_settings_pages.php b/config/cmb2_settings_pages.php index e77eb7a..be17d75 100644 --- a/config/cmb2_settings_pages.php +++ b/config/cmb2_settings_pages.php @@ -41,6 +41,12 @@ 'id' => 'setting_openpub_enable_show_on', 'type' => 'checkbox' ], + 'openpub_related_items_own_type' => [ + 'name' => __('Related items type', 'openpub-base'), + 'desc' => __('Scope related items to the type(s) of the current item when no explicit type is requested.', 'openpub-base'), + 'id' => 'setting_openpub_related_items_own_type', + 'type' => 'checkbox' + ], 'openpub_expired_heading' => [ 'type' => 'heading', 'name' => __('Expired', 'openpub-base'), diff --git a/languages/openpub-base-nl_NL.mo b/languages/openpub-base-nl_NL.mo index cbc889b..9d91eeb 100644 Binary files a/languages/openpub-base-nl_NL.mo and b/languages/openpub-base-nl_NL.mo differ diff --git a/languages/openpub-base-nl_NL.po b/languages/openpub-base-nl_NL.po index 85a4e4a..c088b0b 100644 --- a/languages/openpub-base-nl_NL.po +++ b/languages/openpub-base-nl_NL.po @@ -169,7 +169,7 @@ msgctxt "Admin Filter definition" msgid "Usage" msgstr "Toepassing" -#: config/cmb2_settings_pages.php:46 +#: config/cmb2_settings_pages.php:52 #: config/posttypes.php:39 #: config/posttypes.php:47 msgid "Expired" @@ -432,23 +432,31 @@ msgstr "Gebruik een element waarmee de website verlaten kan worden zonder dat er msgid "Used for configuring on which websites an OpenPub item should be displayed on." msgstr "Wordt gebruikt voor het instellen van de websites waarop een OpenPub item weergegeven moet worden." -#: config/cmb2_settings_pages.php:47 +#: config/cmb2_settings_pages.php:45 +msgid "Related items type" +msgstr "Type gerelateerde items" + +#: config/cmb2_settings_pages.php:46 +msgid "Scope related items to the type(s) of the current item when no explicit type is requested." +msgstr "Beperk gerelateerde items tot het type/de typen van het huidige item wanneer er geen expliciet type is opgegeven." + +#: config/cmb2_settings_pages.php:53 msgid "OpenPub items without an expiration date expire automatically when the field below has a value bigger than 0. Existing OpenPub items without an expiration date will be assigned a value of the published date plus the value given in days. New OpenPub items will have a value of the current date plus the value given in days." msgstr "Items zonder een einddatum verlopen automatisch als het veld hieronder een waarde heeft die groter is dan 0. Bestaande OpenPub items zonder een einddatum krijgen een waarde toegewezen van de publicatie datum plus de waarde die is opgegeven in dagen. Nieuwe OpenPub items krijgen een waarde van de huidige datum plus de waarde die is opgegeven in dagen." -#: config/cmb2_settings_pages.php:50 +#: config/cmb2_settings_pages.php:56 msgid "Days to expire" msgstr "Dagen tot verlopen" -#: config/cmb2_settings_pages.php:51 +#: config/cmb2_settings_pages.php:57 msgid "After how many days should an item expire?" msgstr "Na hoeveel dagen moet een item verlopen?" -#: config/cmb2_settings_pages.php:56 +#: config/cmb2_settings_pages.php:62 msgid "Admin notices" msgstr "Administratieve mededelingen" -#: config/cmb2_settings_pages.php:57 +#: config/cmb2_settings_pages.php:63 msgid "Disable upgrade admin notices." msgstr "Schakel administratieve mededelingen over upgraden uit." diff --git a/languages/openpub-base.pot b/languages/openpub-base.pot index c83e262..2ba34ed 100644 --- a/languages/openpub-base.pot +++ b/languages/openpub-base.pot @@ -177,29 +177,37 @@ msgstr "" msgid "Used for configuring on which websites an OpenPub item should be displayed on." msgstr "" +#: config/cmb2_settings_pages.php:45 +msgid "Related items type" +msgstr "" + #: config/cmb2_settings_pages.php:46 +msgid "Scope related items to the type(s) of the current item when no explicit type is requested." +msgstr "" + +#: config/cmb2_settings_pages.php:52 #: config/posttypes.php:39 #: config/posttypes.php:47 msgid "Expired" msgstr "" -#: config/cmb2_settings_pages.php:47 +#: config/cmb2_settings_pages.php:53 msgid "OpenPub items without an expiration date expire automatically when the field below has a value bigger than 0. Existing OpenPub items without an expiration date will be assigned a value of the published date plus the value given in days. New OpenPub items will have a value of the current date plus the value given in days." msgstr "" -#: config/cmb2_settings_pages.php:50 +#: config/cmb2_settings_pages.php:56 msgid "Days to expire" msgstr "" -#: config/cmb2_settings_pages.php:51 +#: config/cmb2_settings_pages.php:57 msgid "After how many days should an item expire?" msgstr "" -#: config/cmb2_settings_pages.php:56 +#: config/cmb2_settings_pages.php:62 msgid "Admin notices" msgstr "" -#: config/cmb2_settings_pages.php:57 +#: config/cmb2_settings_pages.php:63 msgid "Disable upgrade admin notices." msgstr "" diff --git a/openpub-base.php b/openpub-base.php index 4307d16..0c3ab87 100644 --- a/openpub-base.php +++ b/openpub-base.php @@ -4,7 +4,7 @@ * Plugin Name: Yard | OpenPub Base * Plugin URI: https://www.openwebconcept.nl/ * Description: Acts as foundation for other OpenPub related content plugins. This plugin implements actions to allow for other plugins to add and/or change Custom Posttypes, Metaboxes, Taxonomies, en Posts 2 posts relations. - * Version: 3.8.7 + * Version: 3.9.0 * Author: Yard | Digital Agency * Author URI: https://www.yard.nl/ * License: GPL-3.0 diff --git a/src/Base/ElasticPress/ElasticPress.php b/src/Base/ElasticPress/ElasticPress.php index 52ecc80..71d772a 100644 --- a/src/Base/ElasticPress/ElasticPress.php +++ b/src/Base/ElasticPress/ElasticPress.php @@ -305,7 +305,7 @@ public function setIndexNameByEnvironment($indexName, $siteID) protected function getEnvironmentVariable(): string { - return $_ENV['environment'] ?? ''; + return getenv('environment') ?: ''; } /** diff --git a/src/Base/Foundation/Plugin.php b/src/Base/Foundation/Plugin.php index 0a8b5e9..9995f13 100644 --- a/src/Base/Foundation/Plugin.php +++ b/src/Base/Foundation/Plugin.php @@ -8,7 +8,7 @@ class Plugin { public const NAME = 'openpub-base'; - public const VERSION = '3.8.7'; + public const VERSION = '3.9.0'; protected string $rootPath; public Config $config; diff --git a/src/Base/Metabox/MetaboxServiceProvider.php b/src/Base/Metabox/MetaboxServiceProvider.php index 5236c14..46a4f43 100644 --- a/src/Base/Metabox/MetaboxServiceProvider.php +++ b/src/Base/Metabox/MetaboxServiceProvider.php @@ -94,13 +94,13 @@ protected function registerMetaboxFields(CMB2 $metabox, array $fields): void protected function addExpirationDefaultValue(array $configMetaboxes): array { - $configMetaboxes['base']['fields']['general']['expiration']['default_cb'] = function( $field_args, $field ) { - $post = get_post( $field->object_id ); - if ( ! $post || $post->post_status !== 'auto-draft' ) { - return ''; - } - return strtotime( 'midnight', strtotime( '+' . $this->plugin->settings->expireAfter() . ' days' ) ); - }; + $configMetaboxes['base']['fields']['general']['expiration']['default_cb'] = function ($field_args, $field) { + $post = get_post($field->object_id); + if (! $post || $post->post_status !== 'auto-draft') { + return ''; + } + return strtotime('midnight', strtotime('+' . $this->plugin->settings->expireAfter() . ' days')); + }; return $configMetaboxes; } diff --git a/src/Base/Models/PortalLinkGenerator.php b/src/Base/Models/PortalLinkGenerator.php index 726595e..0cc4ca6 100644 --- a/src/Base/Models/PortalLinkGenerator.php +++ b/src/Base/Models/PortalLinkGenerator.php @@ -65,15 +65,15 @@ private function getShowOnPortalURL(): string return ''; } - // Filter out terms where slug is not numeric - $terms = array_filter($terms, function($term) { - return is_numeric($term->slug); - }); - - // Sort terms by slug (blog ID) - usort($terms, function($a, $b) { - return intval($a->slug) <=> intval($b->slug); - }); + // Filter out terms where slug is not numeric + $terms = array_filter($terms, function ($term) { + return is_numeric($term->slug); + }); + + // Sort terms by slug (blog ID) + usort($terms, function ($a, $b) { + return intval($a->slug) <=> intval($b->slug); + }); $portalURL = reset($terms); diff --git a/src/Base/PostType/PostTypeServiceProvider.php b/src/Base/PostType/PostTypeServiceProvider.php index 1f55eda..987cc1b 100644 --- a/src/Base/PostType/PostTypeServiceProvider.php +++ b/src/Base/PostType/PostTypeServiceProvider.php @@ -45,16 +45,16 @@ public function orderByPublishedDate(WP_Query $query): void */ public function registerPostTypes(): void { - if (! function_exists('register_extended_post_type')) { - return; - } + if (! function_exists('register_extended_post_type')) { + return; + } - $this->configPostTypes = apply_filters('owc/openpub-base/before-register-posttypes', $this->plugin->config->get('posttypes')); + $this->configPostTypes = apply_filters('owc/openpub-base/before-register-posttypes', $this->plugin->config->get('posttypes')); - foreach ($this->configPostTypes as $postTypeName => $postType) { - // Examples of registering post types: http://johnbillion.com/extended-cpts/ - register_extended_post_type($postTypeName, $postType['args'], $postType['names']); - } + foreach ($this->configPostTypes as $postTypeName => $postType) { + // Examples of registering post types: http://johnbillion.com/extended-cpts/ + register_extended_post_type($postTypeName, $postType['args'], $postType['names']); + } } /** diff --git a/src/Base/RestAPI/Controllers/ItemController.php b/src/Base/RestAPI/Controllers/ItemController.php index 2d31361..3529d1d 100644 --- a/src/Base/RestAPI/Controllers/ItemController.php +++ b/src/Base/RestAPI/Controllers/ItemController.php @@ -55,7 +55,7 @@ protected function itemQueryBuilder(WP_REST_Request $request = null): Item $items->query(Item::addAudienceParameters($this->getAudienceParam($request))); } - return apply_filters('owc/openpub/rest-api/items/query/parameters', $items, $request); + return apply_filters('owc/openpub/rest-api/items/query/parameters', $items, $request); } /** @@ -131,11 +131,18 @@ protected function addRelated(array $item, WP_REST_Request $request): array 'posts_per_page' => 10, 'post_status' => 'publish', 'post_type' => 'openpub-item', + 'no_found_rows' => true, ]) ->query(Item::addExpirationParameters()); - if ($this->getTypeParam($request)) { - $items->query(Item::addTypeParameter($this->getTypeParam($request))); + $type = $this->getTypeParam($request); + + if (! $type && $this->plugin->settings->useRelatedItemsOwnType()) { + $type = $this->getItemTypeSlugs($item); + } + + if ($type) { + $items->query(Item::addTypeParameter($type)); } if ($this->showOnParamIsValid($request) && $this->plugin->settings->useShowOn()) { @@ -146,7 +153,7 @@ protected function addRelated(array $item, WP_REST_Request $request): array $items->query(Item::addAudienceParameters($this->getAudienceParam($request))); } - $items = apply_filters('owc/openpub/rest-api/items/query/parameters', $items, $request); + $items = apply_filters('owc/openpub/rest-api/items/query/parameters', $items, $request); $query = new WP_Query($items->getQueryArgs()); return array_map([$this, 'transform'], $query->posts); @@ -194,6 +201,22 @@ protected function hasHighlightedParam(WP_REST_Request $request): bool return true; } + /** + * Get the type slugs already attached to an item, comma-separated. + * + * @since 3.9.0 + */ + protected function getItemTypeSlugs(array $item): string + { + $types = $item['taxonomies']['openpub-type'] ?? []; + + if (! is_array($types) || [] === $types) { + return ''; + } + + return implode(',', array_column($types, 'slug')); + } + protected function getTypeParam(WP_REST_Request $request): string { $typeParam = $request->get_param('type'); diff --git a/src/Base/RestAPI/ItemFields/TaxonomyField.php b/src/Base/RestAPI/ItemFields/TaxonomyField.php index 59dc8c4..6182bb9 100644 --- a/src/Base/RestAPI/ItemFields/TaxonomyField.php +++ b/src/Base/RestAPI/ItemFields/TaxonomyField.php @@ -12,15 +12,15 @@ class TaxonomyField extends CreatesFields */ public function create(WP_Post $post): array { - $result = []; + $result = []; - $taxonomies = apply_filters('owc/openpub-base/before-register-extended-taxonomies', $this->plugin->config->get('taxonomies')); + $taxonomies = apply_filters('owc/openpub-base/before-register-extended-taxonomies', $this->plugin->config->get('taxonomies')); if (! is_array($taxonomies) || 1 > count($taxonomies)) { - return $result; - } + return $result; + } - $taxonomiesKeys = array_unique(array_keys($taxonomies)); + $taxonomiesKeys = array_unique(array_keys($taxonomies)); foreach ($taxonomiesKeys as $taxonomy) { $result[$taxonomy] = $this->getTerms($post->ID, $taxonomy); diff --git a/src/Base/RestAPI/RestAPIServiceProvider.php b/src/Base/RestAPI/RestAPIServiceProvider.php index d1080d4..c9c1d74 100644 --- a/src/Base/RestAPI/RestAPIServiceProvider.php +++ b/src/Base/RestAPI/RestAPIServiceProvider.php @@ -63,11 +63,11 @@ public function registerRoutes(): void 'permission_callback' => '__return_true', ]); - register_rest_route($this->namespace, 'items/active', [ - 'methods' => WP_REST_Server::READABLE, - 'callback' => [new ItemController($this->plugin), 'getActiveItems'], - 'permission_callback' => '__return_true', - ]); + register_rest_route($this->namespace, 'items/active', [ + 'methods' => WP_REST_Server::READABLE, + 'callback' => [new ItemController($this->plugin), 'getActiveItems'], + 'permission_callback' => '__return_true', + ]); register_rest_route($this->namespace, 'items/(?P\d+)', [ 'methods' => WP_REST_Server::READABLE, diff --git a/src/Base/Settings/SettingsPageOptions.php b/src/Base/Settings/SettingsPageOptions.php index 7e9e404..2d07b86 100644 --- a/src/Base/Settings/SettingsPageOptions.php +++ b/src/Base/Settings/SettingsPageOptions.php @@ -55,6 +55,16 @@ public function useShowOn(): bool return filter_var($setting, FILTER_VALIDATE_BOOLEAN); } + /** + * @since 3.9.0 + */ + public function useRelatedItemsOwnType(): bool + { + $setting = $this->settings['_owc_setting_openpub_related_items_own_type'] ?? false; + + return filter_var($setting, FILTER_VALIDATE_BOOLEAN); + } + public function expireAfter(): int { return $this->settings['_owc_setting_openpub_expired_auto_after_days'] ?? 0; @@ -75,6 +85,7 @@ public static function make(): self '_owc_setting_use_portal_url' => 0, '_owc_setting_use_escape_element' => 0, '_owc_setting_openpub_enable_show_on' => 0, + '_owc_setting_openpub_related_items_own_type' => 0, '_owc_setting_openpub_expired_auto_after_days' => 0, '_owc_setting_openpub_disable_upgrade_admin_notice' => 0 ]; diff --git a/tests/Stubs/WordPress/CMB2.php b/tests/Stubs/WordPress/CMB2.php new file mode 100644 index 0000000..636e932 --- /dev/null +++ b/tests/Stubs/WordPress/CMB2.php @@ -0,0 +1,18 @@ +args = $args; + } + + public function add_field(array $field) + { + $this->fields[] = $field; + } +} diff --git a/tests/Unit/Base/Metabox/MetaboxServiceProviderTest.php b/tests/Unit/Base/Metabox/MetaboxServiceProviderTest.php index e208f29..b77488f 100644 --- a/tests/Unit/Base/Metabox/MetaboxServiceProviderTest.php +++ b/tests/Unit/Base/Metabox/MetaboxServiceProviderTest.php @@ -2,10 +2,12 @@ namespace OWC\OpenPub\Tests\Base\Metabox; +use CMB2; use Mockery as m; use OWC\OpenPub\Base\Foundation\Config; use OWC\OpenPub\Base\Foundation\Loader; use OWC\OpenPub\Base\Foundation\Plugin; +use OWC\OpenPub\Base\Metabox\AdminNotice; use OWC\OpenPub\Base\Metabox\MetaboxServiceProvider; use OWC\OpenPub\Tests\TestCase; use WP_Mock; @@ -42,6 +44,7 @@ protected function setUp(): void protected function tearDown(): void { WP_Mock::tearDown(); + m::close(); } /** @test */ @@ -55,16 +58,25 @@ public function check_registration_of_metaboxes() $service = new MetaboxServiceProvider($plugin); - $plugin->loader->shouldReceive('addFilter')->withArgs([ - 'rwmb_meta_boxes', + $plugin->loader->shouldReceive('addAction')->withArgs([ + 'cmb2_admin_init', $service, 'registerMetaboxes', 10, - 1 + 0 ])->once(); + $plugin->loader->shouldReceive('addAction')->withArgs(function ($hook, $notice, $method, $priority, $args) { + return 'admin_notices' === $hook + && $notice instanceof AdminNotice + && 'upgradeAdminNotice' === $method + && 10 === $priority + && 0 === $args; + })->once(); + $service->register(); + // Setting '_owc_setting_use_escape_element' is enabled, so the escape element metabox is merged in. $configMetaboxes = [ 'base' => [ 'id' => 'metadata', @@ -73,26 +85,20 @@ public function check_registration_of_metaboxes() 'testfield_noid' => [ 'type' => 'heading' ], - 'testfield1' => [ + 'testfield1' => [ 'id' => 'metabox_id1' - ], - 'testfield2' => [ - 'id' => 'metabox_id2' ] ] ] - ], + ] + ]; + + $escapeElementMetabox = [ 'escape_element' => [ 'id' => 'escape_element', 'fields' => [ 'general' => [ - 'testfield_noid' => [ - 'type' => 'heading' - ], - 'testfield1' => [ - 'id' => 'metabox_id1' - ], - 'testfield2' => [ + 'testfield2' => [ 'id' => 'metabox_id2' ] ] @@ -100,113 +106,34 @@ public function check_registration_of_metaboxes() ] ]; - $prefix = MetaboxServiceProvider::PREFIX; + $config->shouldReceive('get')->with('cmb2_metaboxes')->once()->andReturn($configMetaboxes); + $config->shouldReceive('get')->with('escape_element_metabox')->once()->andReturn($escapeElementMetabox); - $expectedMetaboxes = [ - 0 => [ - 'id' => 'metadata', - 'fields' => [ - [ - 'type' => 'heading' - ], - [ - 'id' => $prefix . 'metabox_id1' - ], - [ - 'id' => $prefix . 'metabox_id2' - ] - ] - ], - 1 => [ - 'id' => 'escape_element', - 'fields' => [ - [ - 'type' => 'heading' - ], - [ - 'id' => $prefix . 'metabox_id1' - ], - [ - 'id' => $prefix . 'metabox_id2' - ] - ] - ] - ]; + $createdBoxes = []; - $config->shouldReceive('get')->with('metaboxes')->once()->andReturn($configMetaboxes); - $config->shouldReceive('get')->with('escape_element_metabox')->once()->andReturn($configMetaboxes); + \WP_Mock::userFunction('new_cmb2_box')->andReturnUsing(function (array $args) use (&$createdBoxes) { + $box = new CMB2($args); + $createdBoxes[] = $box; - //test for filter being called - \WP_Mock::expectFilter('owc/openpub/base/before-register-metaboxes', $expectedMetaboxes); + return $box; + }); - $this->assertEquals($expectedMetaboxes, $service->registerMetaboxes([])); + $service->registerMetaboxes(); - $existingMetaboxes = [ - 0 => [ - 'id' => 'existing_metadata', - 'fields' => [ - [ - 'type' => 'existing_heading' - ], - [ - 'id' => $prefix . 'existing_metabox_id1' - ], - [ - 'id' => $prefix . 'existing_metabox_id2' - ] - ] - ] - ]; - - $expectedMetaboxesAfterMerge = [ - - 0 => [ - 'id' => 'existing_metadata', - 'fields' => [ - [ - 'type' => 'existing_heading' - ], - [ - 'id' => $prefix . 'existing_metabox_id1' - ], - [ - 'id' => $prefix . 'existing_metabox_id2' - ] - ] - ], - 1 => [ - 'id' => 'metadata', - 'fields' => [ - [ - 'type' => 'heading' - ], - [ - 'id' => $prefix . 'metabox_id1' - ], - [ - 'id' => $prefix . 'metabox_id2' - ] - ] - ], - 2 => [ - 'id' => 'escape_element', - 'fields' => [ - [ - 'type' => 'heading' - ], - [ - 'id' => $prefix . 'metabox_id1' - ], - [ - 'id' => $prefix . 'metabox_id2' - ] - ] - ] - ]; + $this->assertCount(2, $createdBoxes); - $config->shouldReceive('get')->with('metaboxes')->once()->andReturn($configMetaboxes); - $config->shouldReceive('get')->with('escape_element_metabox')->once()->andReturn($configMetaboxes); + $metadataBox = $createdBoxes[0]; + $this->assertSame('metadata', $metadataBox->args['id']); + $this->assertArrayNotHasKey('fields', $metadataBox->args); + $this->assertEquals([ + ['type' => 'heading'], + ['id' => MetaboxServiceProvider::PREFIX . 'metabox_id1'] + ], $metadataBox->fields); - $this->assertEquals($expectedMetaboxesAfterMerge, $service->registerMetaboxes($existingMetaboxes)); + $escapeElementBox = $createdBoxes[1]; + $this->assertSame('escape_element', $escapeElementBox->args['id']); + $this->assertEquals([ + ['id' => MetaboxServiceProvider::PREFIX . 'metabox_id2'] + ], $escapeElementBox->fields); } } diff --git a/tests/Unit/Base/PostType/PostTypeServiceProviderTest.php b/tests/Unit/Base/PostType/PostTypeServiceProviderTest.php index 0e26ad0..a88ca93 100644 --- a/tests/Unit/Base/PostType/PostTypeServiceProviderTest.php +++ b/tests/Unit/Base/PostType/PostTypeServiceProviderTest.php @@ -67,6 +67,14 @@ public function check_registration_of_posttypes() 'orderByPublishedDate', ])->once(); + $plugin->loader->shouldReceive('addAction')->withArgs([ + 'wp_insert_post_data', + $service, + 'fillPostName', + 10, + 4 + ])->once(); + /** * Examples of registering post types: http://johnbillion.com/extended-cpts/ */ diff --git a/tests/Unit/Base/RestAPI/ItemFields/ExpiredFieldTest.php b/tests/Unit/Base/RestAPI/ItemFields/ExpiredFieldTest.php index dbfeb4a..bf0ce29 100644 --- a/tests/Unit/Base/RestAPI/ItemFields/ExpiredFieldTest.php +++ b/tests/Unit/Base/RestAPI/ItemFields/ExpiredFieldTest.php @@ -80,6 +80,7 @@ public function return_expired_status_when_date_is_in_future() { $futureDate = \DateTime::createFromFormat(self::DATETIMEFORMAT, $this->now, $this->dateTime); $futureDate->modify("+1 day"); + $timestamp = $futureDate->getTimestamp(); WP_Mock::userFunction('get_post_meta', [ 'args' => [ @@ -88,7 +89,7 @@ public function return_expired_status_when_date_is_in_future() 'true' ], 'times' => 1, - 'return' => $futureDate->format(self::DATETIMEFORMAT) + 'return' => $timestamp ]); $expiredField = new ExpiredField($this->plugin); @@ -97,7 +98,7 @@ public function return_expired_status_when_date_is_in_future() $this->assertEquals([ 'message' => '', 'status' => false, - 'on' => $futureDate + 'on' => date(self::DATETIMEFORMAT, $timestamp) ], $status); } @@ -106,6 +107,7 @@ public function return_expired_status_when_date_has_no_time() { $futureDate = \DateTime::createFromFormat(self::DATETIMEFORMAT, $this->now, $this->dateTime); $futureDate->modify("midnight +1 day"); + $timestamp = $futureDate->getTimestamp(); WP_Mock::userFunction('get_post_meta', [ 'args' => [ @@ -114,7 +116,7 @@ public function return_expired_status_when_date_has_no_time() 'true' ], 'times' => 1, - 'return' => $futureDate->format(self::DATEFORMAT) + 'return' => $timestamp ]); $expiredField = new ExpiredField($this->plugin); @@ -123,7 +125,7 @@ public function return_expired_status_when_date_has_no_time() $this->assertEquals([ 'message' => '', 'status' => false, - 'on' => $futureDate + 'on' => date(self::DATETIMEFORMAT, $timestamp) ], $status); } @@ -132,6 +134,7 @@ public function return_expired_status_when_date_is_in_past() { $pastDate = \DateTime::createFromFormat(self::DATETIMEFORMAT, $this->now, $this->dateTime); $pastDate->modify("-1 day"); + $timestamp = $pastDate->getTimestamp(); WP_Mock::userFunction('get_post_meta', [ 'args' => [ @@ -140,7 +143,7 @@ public function return_expired_status_when_date_is_in_past() 'true' ], 'times' => 1, - 'return' => $pastDate->format(self::DATETIMEFORMAT) + 'return' => $timestamp ]); $expiredField = new ExpiredField($this->plugin); @@ -149,7 +152,7 @@ public function return_expired_status_when_date_is_in_past() $this->assertEquals([ 'message' => 'Item is expired', 'status' => true, - 'on' => $pastDate + 'on' => date(self::DATETIMEFORMAT, $timestamp) ], $status); } } diff --git a/tests/Unit/Base/RestAPI/RestAPIServiceProviderTest.php b/tests/Unit/Base/RestAPI/RestAPIServiceProviderTest.php index dfc872e..f75aa84 100644 --- a/tests/Unit/Base/RestAPI/RestAPIServiceProviderTest.php +++ b/tests/Unit/Base/RestAPI/RestAPIServiceProviderTest.php @@ -3,7 +3,7 @@ namespace OWC\OpenPub\Tests\Base\RestAPI; use Mockery as m; -use OWC\OpenPub\Base\Config; +use OWC\OpenPub\Base\Foundation\Config; use OWC\OpenPub\Base\Foundation\Loader; use OWC\OpenPub\Base\Foundation\Plugin; use OWC\OpenPub\Base\RestAPI\RestAPIServiceProvider; diff --git a/tests/Unit/Base/Settings/SettingsServiceProviderTest.php b/tests/Unit/Base/Settings/SettingsServiceProviderTest.php index d5bca20..91f47bf 100644 --- a/tests/Unit/Base/Settings/SettingsServiceProviderTest.php +++ b/tests/Unit/Base/Settings/SettingsServiceProviderTest.php @@ -2,6 +2,7 @@ namespace OWC\OpenPub\Tests\Base\Settings; +use CMB2; use Mockery as m; use OWC\OpenPub\Base\Foundation\Config; use OWC\OpenPub\Base\Foundation\Loader; @@ -42,6 +43,7 @@ public function setUp(): void public function tearDown(): void { \WP_Mock::tearDown(); + m::close(); } /** @test */ @@ -55,157 +57,62 @@ public function check_registration_of_settings_metaboxes() $service = new SettingsServiceProvider($plugin); - $plugin->loader->shouldReceive('addFilter')->withArgs([ - 'mb_settings_pages', + $plugin->loader->shouldReceive('addAction')->withArgs([ + 'cmb2_render_number', $service, - 'registerSettingsPage', + 'registerMissingNumberField', 10, - 1 + 5 ])->once(); - $plugin->loader->shouldReceive('addFilter')->withArgs([ - 'rwmb_meta_boxes', + $plugin->loader->shouldReceive('addAction')->withArgs([ + 'cmb2_admin_init', $service, - 'registerSettings', + 'registerSettingsPages', 10, - 1 + 0 ])->once(); $service->register(); - $configSettingsPage = [ - 'base' => [ - 'id' => '_owc_openpub_base_settings', - 'option_name' => '_owc_openpub_base_settings' - ] - ]; - - $config->shouldReceive('get')->with('settings_pages')->once()->andReturn($configSettingsPage); - - $this->assertEquals($configSettingsPage, $service->registerSettingsPage([])); - - $existingSettingsPage = [ - 0 => [ - 'id' => 'existing_settings_page', - 'option_name' => 'existing_settings_page' - ] - ]; - - $existingSettingsPageAfterMerge = [ + $prefix = SettingsServiceProvider::PREFIX; - 0 => [ - 'id' => 'existing_settings_page', - 'option_name' => 'existing_settings_page' - ], + $configSettingsPages = [ 'base' => [ 'id' => '_owc_openpub_base_settings', - 'option_name' => '_owc_openpub_base_settings' - ] - ]; - - $config->shouldReceive('get')->with('settings_pages')->once()->andReturn($configSettingsPage); - - $this->assertEquals($existingSettingsPageAfterMerge, $service->registerSettingsPage($existingSettingsPage)); - - $configMetaboxes = [ - 'base' => [ - 'id' => 'metadata', - 'settings_pages' => 'base_settings_page', - 'fields' => [ - 'general' => [ - 'testfield_noid' => [ - 'type' => 'heading' - ], - 'testfield1' => [ - 'id' => 'metabox_id1' - ], - 'testfield2' => [ - 'id' => 'metabox_id2' - ] - ] - ] - ] - ]; - - $prefix = SettingsServiceProvider::PREFIX; - - $expectedMetaboxes = [ - 0 => [ - 'id' => 'metadata', - 'settings_pages' => 'base_settings_page', - 'fields' => [ - [ + 'option_name' => '_owc_openpub_base_settings', + 'fields' => [ + 'testfield_noid' => [ 'type' => 'heading' ], - [ - 'id' => $prefix . 'metabox_id1' - ], - [ - 'id' => $prefix . 'metabox_id2' + 'testfield1' => [ + 'id' => 'metabox_id1' ] ] ] ]; - $config->shouldReceive('get')->with('settings')->once()->andReturn($configMetaboxes); + $config->shouldReceive('get')->with('cmb2_settings_pages')->once()->andReturn($configSettingsPages); - //test for filter being called - \WP_Mock::expectFilter('owc/openpub/base/before-register-settings', $expectedMetaboxes); + $createdBoxes = []; - $this->assertEquals($expectedMetaboxes, $service->registerSettings([])); + \WP_Mock::userFunction('new_cmb2_box')->andReturnUsing(function (array $args) use (&$createdBoxes) { + $box = new CMB2($args); + $createdBoxes[] = $box; - $existingMetaboxes = [ - 0 => [ - 'id' => 'existing_metadata', - 'fields' => [ - [ - 'type' => 'existing_heading' - ], - [ - 'id' => $prefix . 'existing_metabox_id1' - ], - [ - 'id' => $prefix . 'existing_metabox_id2' - ] - ] - ] - ]; + return $box; + }); - $expectedMetaboxesAfterMerge = [ - - 0 => [ - 'id' => 'existing_metadata', - 'fields' => [ - [ - 'type' => 'existing_heading' - ], - [ - 'id' => $prefix . 'existing_metabox_id1' - ], - [ - 'id' => $prefix . 'existing_metabox_id2' - ] - ] - ], - 1 => [ - 'id' => 'metadata', - 'settings_pages' => 'base_settings_page', - 'fields' => [ - [ - 'type' => 'heading' - ], - [ - 'id' => $prefix . 'metabox_id1' - ], - [ - 'id' => $prefix . 'metabox_id2' - ] - ] - ] - ]; + $service->registerSettingsPages(); - $config->shouldReceive('get')->with('settings')->once()->andReturn($configMetaboxes); + $this->assertCount(1, $createdBoxes); - $this->assertEquals($expectedMetaboxesAfterMerge, $service->registerSettings($existingMetaboxes)); + $optionsPage = $createdBoxes[0]; + $this->assertSame('_owc_openpub_base_settings', $optionsPage->args['id']); + $this->assertArrayNotHasKey('fields', $optionsPage->args); + $this->assertEquals([ + ['type' => 'heading'], + ['id' => $prefix . 'metabox_id1'] + ], $optionsPage->fields); } }