AutoPurge.php
4 months ago
BeaverBuilder.php
4 months ago
CPTOptimization.php
1 month ago
CacheWarmup.php
1 month ago
CartCache.php
4 months ago
Components.php
1 month ago
EditorClearCache.php
1 month ago
GeneratePreview.php
7 months ago
HTMLCompression.php
3 months ago
Logger.php
4 months ago
OptimizationLevel.php
1 month ago
Optimizations.php
1 month ago
PurgeCache.php
1 month ago
Shortcodes.php
4 months ago
StockRefresh.php
2 months ago
Subscription.php
4 months ago
SystemReport.php
4 months ago
TestMode.php
1 month ago
CPTOptimization.php
260 lines
| 1 | <?php |
| 2 | |
| 3 | namespace NitroPack\WordPress\Settings; |
| 4 | use NitroPack\WordPress\NitroPack; |
| 5 | |
| 6 | defined( 'ABSPATH' ) || die( 'No script kiddies please!' ); |
| 7 | /** |
| 8 | * Class CPTOptimization |
| 9 | * |
| 10 | * This class manages the optimization settings for Custom Post Types (CPTs) and taxonomies (called Page Optimization) in NitroPack. |
| 11 | * |
| 12 | * @package NitroPack\WordPress\Settings |
| 13 | */ |
| 14 | class CPTOptimization { |
| 15 | public static $instance = null; |
| 16 | public static function getInstance() { |
| 17 | static $instance = null; |
| 18 | if ( null === $instance ) { |
| 19 | $instance = new self(); |
| 20 | } |
| 21 | return $instance; |
| 22 | } |
| 23 | public function __construct() { |
| 24 | add_action( 'admin_init', [ $this, 'autooptimize_new_post_types_and_taxonomies' ] ); |
| 25 | add_action( 'wp_ajax_nitropack_set_cacheable_post_types', [ $this, 'nitropack_set_cacheable_post_types' ] ); |
| 26 | } |
| 27 | |
| 28 | /** |
| 29 | * Retrievs all CPTs eligable for optimization and checking if they are optimized |
| 30 | */ |
| 31 | public function nitropack_get_CPTs_with_optimization_status() { |
| 32 | |
| 33 | $cacheableObjectTypes = $this->nitropack_get_cacheable_object_types(); |
| 34 | $objectTypes = $this->nitropack_get_object_types(); |
| 35 | |
| 36 | $result = [ |
| 37 | "home" => [ |
| 38 | 'name' => 'Home', |
| 39 | 'isOptimized' => in_array( 'home', $cacheableObjectTypes ) ? 1 : 0, |
| 40 | ], |
| 41 | "archive" => [ |
| 42 | 'name' => 'Archive', |
| 43 | 'isOptimized' => in_array( 'archive', $cacheableObjectTypes ) ? 1 : 0, |
| 44 | ] |
| 45 | ]; |
| 46 | |
| 47 | // Determine new object types by comparing current with stored |
| 48 | foreach ( $objectTypes as $slug => $objectType ) { |
| 49 | $isOptimized = in_array( $objectType->name, $cacheableObjectTypes ); |
| 50 | $taxonomies = []; |
| 51 | |
| 52 | if ( ! empty( $objectType->taxonomies ) ) { |
| 53 | foreach ( $objectType->taxonomies as $tax ) { |
| 54 | $taxName = $tax->name; |
| 55 | $taxonomies[ $taxName ] = [ |
| 56 | 'isOptimized' => in_array( $taxName, $cacheableObjectTypes ) ? 1 : 0, |
| 57 | 'name' => $tax->labels->name |
| 58 | ]; |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | $result[ $slug ] = [ |
| 63 | 'isOptimized' => $isOptimized ? 1 : 0, |
| 64 | 'name' => $objectType->labels->name, |
| 65 | 'taxonomies' => $taxonomies |
| 66 | ]; |
| 67 | } |
| 68 | |
| 69 | return $result; |
| 70 | } |
| 71 | /** |
| 72 | * Filters the CPTs which are not optimized. |
| 73 | * Show it only once. |
| 74 | */ |
| 75 | public function nitropack_filter_non_optimized() { |
| 76 | $filteredArr = []; |
| 77 | $objectTypes = $this->nitropack_get_CPTs_with_optimization_status(); |
| 78 | foreach ( $objectTypes as $slug => $objectType ) { |
| 79 | $includeObjectType = ! $objectType['isOptimized']; |
| 80 | $filteredTaxonomies = []; |
| 81 | if ( isset( $objectType['taxonomies'] ) ) { |
| 82 | foreach ( $objectType['taxonomies'] as $taxSlug => $taxonomy ) { |
| 83 | if ( ! $taxonomy['isOptimized'] ) { |
| 84 | $filteredTaxonomies[ $taxSlug ] = $taxonomy; |
| 85 | $includeObjectType = true; // Include CPT if it has any non-optimized taxonomy |
| 86 | } |
| 87 | } |
| 88 | } |
| 89 | if ( $includeObjectType ) { |
| 90 | $filteredArr[ $slug ] = [ |
| 91 | 'isOptimized' => $objectType['isOptimized'], |
| 92 | 'name' => $objectType['name'], |
| 93 | 'taxonomies' => $filteredTaxonomies |
| 94 | ]; |
| 95 | } |
| 96 | } |
| 97 | return $filteredArr; |
| 98 | } |
| 99 | /** |
| 100 | * Retrieve the list of optimized Custom Post Types (CPTs). |
| 101 | * |
| 102 | * This public function fetches the CPTs with their optimization status and returns an array of CPT keys |
| 103 | * that are marked as optimized. It excludes 'home' and 'archive' as they are not valid CPTs. |
| 104 | * |
| 105 | * @return array An array of optimized CPT keys. |
| 106 | */ |
| 107 | public function nitropack_get_optimized_CPTs() { |
| 108 | $get_CPTs_with_optimization_status = $this->nitropack_get_CPTs_with_optimization_status(); |
| 109 | |
| 110 | $optimizedKeys = []; |
| 111 | |
| 112 | foreach ( $get_CPTs_with_optimization_status as $key => $value ) { |
| 113 | |
| 114 | if ( $key === 'home' || $key === 'archive' ) |
| 115 | continue; //not valid CPTs |
| 116 | |
| 117 | if ( isset( $value['isOptimized'] ) && $value['isOptimized'] === 1 ) { |
| 118 | $optimizedKeys[] = $key; |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | return $optimizedKeys; |
| 123 | } |
| 124 | |
| 125 | public function autooptimize_new_post_types_and_taxonomies() { |
| 126 | //start optimizing after the notice is shown |
| 127 | $notices = get_option( 'nitropack-dismissed-notices', [] ); |
| 128 | if ( ! $notices || ! in_array( 'OptimizeCPT', $notices ) ) |
| 129 | return; |
| 130 | //check if the non-optimized CPTs are stored, if not store them |
| 131 | $nonCacheableObjectTypes = get_option( 'nitropack-nonCacheableObjectTypes' ); |
| 132 | if ( ! $nonCacheableObjectTypes ) { |
| 133 | $notOptimizedCPTs = $this->nitropack_filter_non_optimized(); |
| 134 | $nonCacheableObjectTypes = []; |
| 135 | foreach ( $notOptimizedCPTs as $slug => $objectType ) { |
| 136 | if ( ! $objectType['isOptimized'] ) { |
| 137 | $nonCacheableObjectTypes[] = $slug; |
| 138 | } |
| 139 | foreach ( $objectType['taxonomies'] as $taxSlug => $taxonomy ) { |
| 140 | if ( ! $taxonomy['isOptimized'] ) { |
| 141 | $nonCacheableObjectTypes[] = $taxSlug; |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | update_option( 'nitropack-nonCacheableObjectTypes', $nonCacheableObjectTypes ); |
| 146 | } |
| 147 | |
| 148 | $postTypes = get_post_types( array( 'public' => true ), 'objects' ); |
| 149 | $cacheableObjectTypes = $this->nitropack_get_cacheable_object_types(); |
| 150 | foreach ( $postTypes as $slug => $postType ) { |
| 151 | if ( $postType->public ) { |
| 152 | // Check and add post type to cacheable object types |
| 153 | if ( ! in_array( $slug, $nonCacheableObjectTypes ) && ! in_array( $slug, $cacheableObjectTypes ) ) { |
| 154 | $cacheableObjectTypes[] = $slug; |
| 155 | } |
| 156 | |
| 157 | // Fetch and add connected taxonomies |
| 158 | $taxonomies = get_object_taxonomies( $slug, 'names' ); |
| 159 | foreach ( $taxonomies as $taxonomy ) { |
| 160 | if ( ! in_array( $taxonomy, $nonCacheableObjectTypes ) && ! in_array( $taxonomy, $cacheableObjectTypes ) ) { |
| 161 | $cacheableObjectTypes[] = $taxonomy; |
| 162 | } |
| 163 | } |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | update_option( 'nitropack-cacheableObjectTypes', $cacheableObjectTypes ); |
| 168 | } |
| 169 | /** |
| 170 | * Gets the cachable post types and taxonomies. |
| 171 | * Allows to filter and modify them via 'nitropack_cacheable_post_types' filter. |
| 172 | * @return array |
| 173 | */ |
| 174 | public function nitropack_get_cacheable_object_types() { |
| 175 | return apply_filters( "nitropack_cacheable_post_types", get_option( "nitropack-cacheableObjectTypes", $this->nitropack_get_default_cacheable_object_types() ) ); |
| 176 | } |
| 177 | |
| 178 | /** |
| 179 | * Gets the default cacheable post types and taxonomies. |
| 180 | * @return array |
| 181 | */ |
| 182 | public function nitropack_get_default_cacheable_object_types() { |
| 183 | $result = array( "home", "archive" ); |
| 184 | $postTypes = get_post_types( array( 'public' => true ), 'names' ); |
| 185 | $result = array_merge( $result, $postTypes ); |
| 186 | foreach ( $postTypes as $postType ) { |
| 187 | $result = array_merge( $result, get_taxonomies( array( 'object_type' => array( $postType ), 'public' => true ), 'names' ) ); |
| 188 | } |
| 189 | return $result; |
| 190 | } |
| 191 | /** |
| 192 | * Gets all public post types and taxonomies from WP. |
| 193 | * @return array |
| 194 | */ |
| 195 | public function nitropack_get_object_types() { |
| 196 | $objectTypes = get_post_types( array( 'public' => true ), 'objects' ); |
| 197 | $taxonomies = get_taxonomies( array( 'public' => true ), 'objects' ); |
| 198 | |
| 199 | foreach ( $objectTypes as &$objectType ) { |
| 200 | $objectType->taxonomies = []; |
| 201 | foreach ( $taxonomies as $tax ) { |
| 202 | if ( in_array( $objectType->name, $tax->object_type ) ) { |
| 203 | $objectType->taxonomies[] = $tax; |
| 204 | } |
| 205 | } |
| 206 | } |
| 207 | |
| 208 | return $objectTypes; |
| 209 | } |
| 210 | |
| 211 | /** |
| 212 | * AJAX handler when saving the cachable post types and taxonomies. |
| 213 | * Used when saving CPTs in the modal for Page Optimization in the Dashboard |
| 214 | * @return void |
| 215 | */ |
| 216 | public function nitropack_set_cacheable_post_types() { |
| 217 | nitropack_verify_ajax_nonce( $_REQUEST ); |
| 218 | $currentCacheableObjectTypes = $this->nitropack_get_cacheable_object_types(); |
| 219 | $cacheableObjectTypes = ! empty( $_POST["cacheableObjectTypes"] ) ? $_POST["cacheableObjectTypes"] : array(); |
| 220 | $noncacheableObjectTypes = ! empty( $_POST["noncacheableObjectTypes"] ) ? $_POST["noncacheableObjectTypes"] : array(); |
| 221 | |
| 222 | /* Used for non optimized CPT modal which is shown only once */ |
| 223 | if ( isset( $_POST["append"] ) && $_POST["append"] === "yes" ) { |
| 224 | $cacheableObjectTypes = array_merge( $currentCacheableObjectTypes, $cacheableObjectTypes ); |
| 225 | } |
| 226 | |
| 227 | update_option( "nitropack-cacheableObjectTypes", $cacheableObjectTypes ); |
| 228 | update_option( "nitropack-nonCacheableObjectTypes", $noncacheableObjectTypes ); |
| 229 | |
| 230 | foreach ( $currentCacheableObjectTypes as $objectType ) { |
| 231 | if ( ! in_array( $objectType, $cacheableObjectTypes ) ) { |
| 232 | nitropack_purge( NULL, "pageType:" . $objectType, "Optimizing '$objectType' pages was manually disabled" ); |
| 233 | } |
| 234 | } |
| 235 | |
| 236 | NitroPack::getInstance()->getLogger()->notice( "Optimized CPTs: " . implode( ", ", $cacheableObjectTypes ) ); |
| 237 | NitroPack::getInstance()->getLogger()->notice( "Non-optimized CPTs: " . ( ! empty( $noncacheableObjectTypes ) && is_array( $noncacheableObjectTypes ) ? implode( ", ", $noncacheableObjectTypes ) : 'N/A' ) ); |
| 238 | |
| 239 | nitropack_json_and_exit( array( |
| 240 | "type" => "success", |
| 241 | "message" => nitropack_admin_toast_msgs( 'success' ) |
| 242 | ) ); |
| 243 | } |
| 244 | public function render() { |
| 245 | ?> |
| 246 | <div class="nitro-option" id="page-optimization-widget"> |
| 247 | <div class="nitro-option-main"> |
| 248 | <div class="text-box"> |
| 249 | <h6><?php esc_html_e( 'Page optimization', 'nitropack' ); ?></h6> |
| 250 | <p><?php esc_html_e( 'Select what post/page types get optimized', 'nitropack' ); ?></p> |
| 251 | </div> |
| 252 | <a data-modal-target="modal-posttypes" data-modal-toggle="modal-posttypes" class="btn btn-secondary btn-icon"> |
| 253 | <img src="<?php echo plugin_dir_url( NITROPACK_FILE ); ?>assets/img/setting-icon.svg" alt="" class="icon"> |
| 254 | </a> |
| 255 | </div> |
| 256 | <?php require_once NITROPACK_PLUGIN_DIR . 'view/modals/modal-posttypes.php'; ?> |
| 257 | </div> |
| 258 | <?php |
| 259 | } |
| 260 | } |