| @@ -1,17 +1,10 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | /** |
| 3 | 3 | * Block Registry |
| 4 | 4 | * |
| 5 | - * Which block types the email renderer knows. | |
| 5 | + * Central registry for email editor blocks with Free/Pro availability. | |
| 6 | 6 | * |
| 7 | - * Up to Core 5.7 this class also decided, by licence, which blocks and how | |
| 8 | - * many templates were allowed. Core on wordpress.org may not lock | |
| 9 | - * functionality behind a licence (plugin guideline 5), and editing | |
| 10 | - * templates is the email editor add-on's feature anyway; since 5.8 nothing | |
| 11 | - * here depends on a licence. The methods the add-on up to 1.0.5 calls are | |
| 12 | - * kept so an older add-on keeps working, but they no longer restrict. | |
| 13 | - * | |
| 14 | 7 | * @package Forge12\DoubleOptIn\EmailTemplates |
| 15 | 8 | * @since 4.2.0 |
| 16 | 9 | */ |
| 17 | 10 | |
| @@ -22,13 +15,15 @@ | ||
| 22 | 15 | } |
| 23 | 16 | |
| 24 | 17 | /** |
| 25 | 18 | * Class BlockRegistry |
| 19 | + * | |
| 20 | + * Manages block availability based on Free/Pro status. | |
| 26 | 21 | */ |
| 27 | 22 | class BlockRegistry { |
| 28 | 23 | |
| 29 | 24 | /** |
| 30 | - * Basic blocks. | |
| 25 | + * Blocks available in the Free version. | |
| 31 | 26 | * |
| 32 | 27 | * @var string[] |
| 33 | 28 | */ |
| 34 | 29 | const FREE_BLOCKS = array( |
| @@ -48,10 +43,9 @@ | ||
| 48 | 43 | 'placeholder-custom', |
| 49 | 44 | ); |
| 50 | 45 | |
| 51 | 46 | /** |
| 52 | - * Blocks the editor add-on labels as Pro. The renderer handles them | |
| 53 | - * like any other block. | |
| 47 | + * Blocks that require the Pro version. | |
| 54 | 48 | * |
| 55 | 49 | * @var string[] |
| 56 | 50 | */ |
| 57 | 51 | const PRO_BLOCKS = array( |
| @@ -65,34 +59,42 @@ | ||
| 65 | 59 | 'conditional-content', |
| 66 | 60 | ); |
| 67 | 61 | |
| 68 | 62 | /** |
| 69 | - * Maximum number of published templates: no limit. | |
| 63 | + * Get the template limit based on Pro status. | |
| 70 | 64 | * |
| 71 | - * @deprecated 5.8.0 Kept for the email editor add-on up to 1.0.5. | |
| 65 | + * @return int Maximum number of published templates allowed. | |
| 72 | 66 | */ |
| 73 | 67 | public function getTemplateLimit(): int { |
| 74 | - return PHP_INT_MAX; | |
| 68 | + return $this->isProActive() ? PHP_INT_MAX : 1; | |
| 75 | 69 | } |
| 76 | 70 | |
| 77 | 71 | /** |
| 78 | - * Always true: Core no longer checks licences here. | |
| 72 | + * Check if Pro is active. | |
| 79 | 73 | * |
| 80 | - * @deprecated 5.8.0 Kept for the email editor add-on up to 1.0.5, which | |
| 81 | - * only runs with a licence anyway. | |
| 74 | + * @return bool | |
| 82 | 75 | */ |
| 83 | 76 | public function isProActive(): bool { |
| 84 | - return true; | |
| 77 | + /** | |
| 78 | + * Filter to check if the Pro version is active and licensed. | |
| 79 | + * | |
| 80 | + * @param bool $isActive Whether Pro is active. Default false. | |
| 81 | + * | |
| 82 | + * @since 4.2.0 | |
| 83 | + */ | |
| 84 | + return (bool) apply_filters( 'f12_doi_is_pro_active', false ); | |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | 87 | /** |
| 88 | - * Every known block, all available. | |
| 88 | + * Get block availability for all blocks. | |
| 89 | 89 | * |
| 90 | - * @deprecated 5.8.0 Kept for the email editor add-on up to 1.0.5. | |
| 90 | + * Returns an associative array where each key is a block type | |
| 91 | + * and the value indicates its availability status. | |
| 91 | 92 | * |
| 92 | - * @return array<string, array{type: string, available: bool, requiresPro: bool}> | |
| 93 | + * @return array | |
| 93 | 94 | */ |
| 94 | 95 | public function getBlockAvailability(): array { |
| 96 | + $isProActive = $this->isProActive(); | |
| 95 | 97 | $availability = array(); |
| 96 | 98 | |
| 97 | 99 | foreach ( self::FREE_BLOCKS as $blockType ) { |
| 98 | 100 | $availability[ $blockType ] = array( |
| @@ -104,35 +106,78 @@ | ||
| 104 | 106 | |
| 105 | 107 | foreach ( self::PRO_BLOCKS as $blockType ) { |
| 106 | 108 | $availability[ $blockType ] = array( |
| 107 | 109 | 'type' => $blockType, |
| 108 | - 'available' => true, | |
| 110 | + 'available' => $isProActive, | |
| 109 | 111 | 'requiresPro' => true, |
| 110 | 112 | ); |
| 111 | 113 | } |
| 112 | 114 | |
| 113 | - return $availability; | |
| 115 | + /** | |
| 116 | + * Filter block availability. | |
| 117 | + * | |
| 118 | + * Allows extensions to modify block availability. | |
| 119 | + * | |
| 120 | + * @param array $availability The block availability array. | |
| 121 | + * @param bool $isProActive Whether Pro is active. | |
| 122 | + * | |
| 123 | + * @since 4.2.0 | |
| 124 | + */ | |
| 125 | + return apply_filters( 'f12_doi_block_availability', $availability, $isProActive ); | |
| 114 | 126 | } |
| 115 | 127 | |
| 116 | 128 | /** |
| 117 | - * Every block type is available. | |
| 129 | + * Check if a specific block type is available. | |
| 118 | 130 | * |
| 119 | - * @deprecated 5.8.0 | |
| 131 | + * @param string $blockType The block type to check. | |
| 120 | 132 | * |
| 121 | - * @param string $blockType The block type to check. | |
| 133 | + * @return bool True if the block is available. | |
| 122 | 134 | */ |
| 123 | 135 | public function isBlockAvailable( string $blockType ): bool { |
| 136 | + if ( in_array( $blockType, self::FREE_BLOCKS, true ) ) { | |
| 137 | + return true; | |
| 138 | + } | |
| 139 | + | |
| 140 | + if ( in_array( $blockType, self::PRO_BLOCKS, true ) ) { | |
| 141 | + return $this->isProActive(); | |
| 142 | + } | |
| 143 | + | |
| 144 | + // Unknown block types are allowed by default | |
| 124 | 145 | return true; |
| 125 | 146 | } |
| 126 | 147 | |
| 127 | 148 | /** |
| 128 | - * No block is refused. | |
| 149 | + * Validate blocks recursively, checking that no Pro blocks are used without a license. | |
| 129 | 150 | * |
| 130 | - * @deprecated 5.8.0 | |
| 151 | + * @param array $blocks The blocks array to validate. | |
| 131 | 152 | * |
| 132 | - * @param array $blocks The blocks array. | |
| 133 | - * @return array Always empty. | |
| 153 | + * @return array Array of invalid block types found. Empty if all valid. | |
| 134 | 154 | */ |
| 135 | 155 | public function validateBlocks( array $blocks ): array { |
| 136 | - return array(); | |
| 156 | + $invalidBlocks = array(); | |
| 157 | + $this->validateBlocksRecursive( $blocks, $invalidBlocks ); | |
| 158 | + | |
| 159 | + return $invalidBlocks; | |
| 160 | + } | |
| 161 | + | |
| 162 | + /** | |
| 163 | + * Recursively validate blocks. | |
| 164 | + * | |
| 165 | + * @param array $blocks The blocks to validate. | |
| 166 | + * @param array $invalidBlocks Reference to collect invalid block types. | |
| 167 | + * | |
| 168 | + * @return void | |
| 169 | + */ | |
| 170 | + private function validateBlocksRecursive( array $blocks, array &$invalidBlocks ): void { | |
| 171 | + foreach ( $blocks as $block ) { | |
| 172 | + $type = $block['type'] ?? ''; | |
| 173 | + | |
| 174 | + if ( ! empty( $type ) && ! $this->isBlockAvailable( $type ) ) { | |
| 175 | + $invalidBlocks[] = $type; | |
| 176 | + } | |
| 177 | + | |
| 178 | + if ( ! empty( $block['children'] ) && is_array( $block['children'] ) ) { | |
| 179 | + $this->validateBlocksRecursive( $block['children'], $invalidBlocks ); | |
| 180 | + } | |
| 181 | + } | |
| 137 | 182 | } |
| 138 | 183 | } |