PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 1.25.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v1.25.0
2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.10.0 All 48 releases
thinkrank / includes / seo / class-global-seo-post-types.php

class-global-seo-post-types.php in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 1.25.0, at includes/seo/class-global-seo-post-types.php

73 lines 2.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Global SEO Post Type Policy
4 *
5 * Single source of truth for which post types are valid Global SEO targets,
6 * shared by the admin post-type discovery (which populates the UI), the REST
7 * validator, and the MCP ability validator so all three agree. Previously the
8 * UI hid ineligible types while the write paths accepted any public type,
9 * letting direct REST/ability calls persist settings for types the UI
10 * classifies as unsuitable.
11 *
12 * @package ThinkRank
13 * @subpackage SEO
14 * @since 1.20.1
15 */
16
17 declare(strict_types=1);
18
19 namespace ThinkRank\SEO;
20
21 // Prevent direct access.
22 if (!defined('ABSPATH')) {
23 exit;
24 }
25
26 /**
27 * Global SEO post-type eligibility policy.
28 *
29 * @since 1.20.1
30 */
31 class Global_SEO_Post_Types {
32
33 /**
34 * Whether a post type may receive Global SEO settings.
35 *
36 * Policy: the type must be public; a non-built-in type must also be
37 * front-end viewable (excludes builder/utility CPTs that register
38 * `public => true` only for previews); and it must not be on the filterable
39 * `thinkrank_global_seo_excluded_post_types` deny list.
40 *
41 * @param \WP_Post_Type|string $post_type Post type object or name.
42 * @return bool
43 */
44 public static function is_allowed($post_type): bool {
45 $object = is_string($post_type) ? get_post_type_object($post_type) : $post_type;
46
47 if (!$object instanceof \WP_Post_Type || empty($object->public)) {
48 return false;
49 }
50
51 // Builder/utility CPTs that register public => true for preview purposes
52 // but aren't front-end viewable content (e.g. Elementor's "Floating
53 // Elements"). Built-in types (post/page/attachment) are always kept.
54 if ($object->_builtin === false && !is_post_type_viewable($object)) {
55 return false;
56 }
57
58 // Named deny list for viewable-but-unsuitable builder/utility CPTs.
59 // Filterable so integrators can tune it without patching core. The
60 // post-type object is passed as the second argument (matches the admin
61 // discovery filter usage).
62 $excluded = apply_filters('thinkrank_global_seo_excluded_post_types', [
63 'elementor_library', 'oceanwp_library', 'ae_global_templates',
64 'e-floating-buttons', 'elementor_component',
65 // Divi: the library plus every Theme Builder template type.
66 'et_pb_layout', 'et_theme_builder', 'et_template',
67 'et_header_layout', 'et_body_layout', 'et_footer_layout',
68 ], $object);
69
70 return !in_array($object->name, (array) $excluded, true);
71 }
72 }
73