PluginProbe
Passster – Password Protect Pages and Content / 4.3.16
Passster – Password Protect Pages and Content v4.3.16
4.3.16 4.3.15 4.3.14 4.3.12 4.3.13 4.3.11 4.3.10 4.3.9 4.3.8 4.3.7 4.3.6 4.3.5 trunk 3.5.4 3.5.5.2 3.5.5.8 3.5.5.9 4.0 4.1.4 4.2.10 4.2.11 4.2.12 4.2.13 4.2.14 4.2.15 All 48 releases
← All changes | inc/class-ps-block-editor.php +238 -53 4.1.44.3.16 View file →
@@ -1,46 +1,72 @@
1 1 <?php
2 2
3 3 namespace passster;
4 4
5 -class PS_Block_Editor
6 -{
5 +class PS_Block_Editor {
7 6 /**
8 7 * Contains instance or null
9 8 *
10 9 * @var object|null
11 10 */
12 - private static $instance = null ;
11 + private static $instance = null;
12 +
13 13 /**
14 14 * Returns instance of PS_Block_Editor.
15 15 *
16 16 * @return object
17 17 */
18 - public static function get_instance()
19 - {
18 + public static function get_instance() {
20 19 if ( null === self::$instance ) {
21 20 self::$instance = new self();
22 21 }
23 22 return self::$instance;
24 23 }
25 -
24 +
26 25 /**
27 26 * Constructor for PS_Block_Editor
28 27 */
29 - public function __construct()
30 - {
31 - add_action( 'wp_enqueue_scripts', array( $this, 'register_block_scripts' ) );
32 - add_action( 'enqueue_block_editor_assets', array( $this, 'add_block_editor_assets' ) );
33 - add_action( 'init', array( $this, 'register_area_block' ) );
28 + public function __construct() {
29 + add_action( 'wp_enqueue_scripts', array($this, 'register_block_scripts') );
30 + add_action( 'enqueue_block_editor_assets', array($this, 'add_block_editor_assets') );
31 + add_action( 'init', array($this, 'register_area_block') );
32 + add_action( 'init', array($this, 'register_protected_content_block') );
33 + add_action(
34 + 'save_post',
35 + array($this, 'sync_protected_content_blocks'),
36 + 10,
37 + 2
38 + );
39 + add_filter(
40 + 'block_categories_all',
41 + array($this, 'register_block_category'),
42 + 10,
43 + 2
44 + );
34 45 }
35 -
46 +
36 47 /**
48 + * Register Passster block category.
49 + *
50 + * @param array $categories Block categories.
51 + * @param WP_Block_Editor_Context $context Block editor context.
52 + *
53 + * @return array Modified categories.
54 + */
55 + public function register_block_category( $categories, $context ) {
56 + return array_merge( array(array(
57 + 'slug' => 'passster',
58 + 'title' => __( 'Passster', 'content-protector' ),
59 + 'icon' => 'lock',
60 + )), $categories );
61 + }
62 +
63 + /**
37 64 * Enqueue scripts for blocks.
38 65 *
39 66 * @return void
40 67 */
41 - public function register_block_scripts()
42 - {
68 + public function register_block_scripts() {
43 69 $area_asset_file = (include PASSSTER_PATH . '/build/area/index.asset.php');
44 70 wp_register_script(
45 71 'area-script',
46 72 PASSSTER_URL . '/build/area/index.js',
@@ -47,16 +73,16 @@
47 73 $area_asset_file['dependencies'],
48 74 $area_asset_file['version']
49 75 );
50 76 }
51 -
77 +
52 78 /**
53 79 * Add block editor scripts and styles.
54 80 *
55 81 * @return void
56 82 */
57 - public function add_block_editor_assets()
58 - {
83 + public function add_block_editor_assets() {
84 + // Area block.
59 85 $area_asset_file = (include PASSSTER_PATH . '/build/area/index.asset.php');
60 86 wp_enqueue_script(
61 87 'area-script',
62 88 PASSSTER_URL . '/build/area/index.js',
@@ -68,46 +94,73 @@
68 94 'create_area_url' => admin_url( 'post-new.php?post_type=protected_areas' ),
69 95 'options' => get_option( 'passster' ),
70 96 ) );
71 97 wp_enqueue_style( 'area-style', PASSSTER_URL . '/build/area/index.css' );
98 + // Protected Content block.
99 + $protected_content_asset = PASSSTER_PATH . '/build/blocks/protected-content/index.asset.php';
100 + if ( file_exists( $protected_content_asset ) ) {
101 + $protected_content_asset_file = (include $protected_content_asset);
102 + wp_enqueue_script(
103 + 'passster-protected-content-script',
104 + PASSSTER_URL . '/build/blocks/protected-content/index.js',
105 + $protected_content_asset_file['dependencies'],
106 + $protected_content_asset_file['version']
107 + );
108 + wp_localize_script( 'passster-protected-content-script', 'passster_block_data', array(
109 + 'is_pro' => \passster_fs()->is_plan_or_trial__premium_only( 'pro' ),
110 + 'options' => get_option( 'passster' ),
111 + 'date_format' => get_option( 'date_format' ),
112 + 'time_format' => get_option( 'time_format' ),
113 + 'timezone' => wp_timezone_string(),
114 + 'now' => current_time( 'c' ),
115 + ) );
116 + wp_enqueue_style(
117 + 'passster-protected-content-style',
118 + PASSSTER_URL . '/build/blocks/protected-content/index.css',
119 + array(),
120 + $protected_content_asset_file['version']
121 + );
122 + if ( function_exists( 'wp_set_script_translations' ) ) {
123 + wp_set_script_translations( 'passster-protected-content-script', 'content-protector', PASSSTER_PATH . '/languages' );
124 + }
125 + }
72 126 // Make the blocks translatable.
73 127 if ( function_exists( 'wp_set_script_translations' ) ) {
74 128 wp_set_script_translations( 'area-script', 'content-protector', PASSSTER_PATH . '/languages' );
75 129 }
76 130 }
77 -
131 +
78 132 /**
79 133 * Register area block in WordPress.
80 134 *
81 135 * @return void
82 136 */
83 - public function register_area_block()
84 - {
137 + public function register_area_block() {
85 138 $options = get_option( 'passster' );
86 139 $settings = array(
87 - 'render_callback' => array( $this, 'render_area_block' ),
140 + 'render_callback' => array($this, 'render_area_block'),
88 141 'attributes' => array(
89 - 'area_id' => array(
90 - 'type' => 'string',
91 - 'default' => 0,
92 - ),
93 - 'headline' => array(
94 - 'type' => 'string',
95 - 'default' => esc_html( $options['headline'] ),
96 - ),
97 - 'instruction' => array(
98 - 'type' => 'string',
99 - 'default' => wp_kses_post( $options['instruction'] ),
100 - ),
101 - 'buttonLabel' => array(
102 - 'type' => 'string',
103 - 'default' => esc_html( $options['button_label'] ),
104 - ),
105 - 'placeholder' => array(
106 - 'type' => 'string',
107 - 'default' => esc_html( $options['placeholder'] ),
108 - ),
109 - ),
142 + 'area_id' => array(
143 + 'type' => 'string',
144 + 'default' => 0,
145 + ),
146 + 'headline' => array(
147 + 'type' => 'string',
148 + 'default' => esc_html( $options['headline'] ),
149 + ),
150 + 'instruction' => array(
151 + 'type' => 'string',
152 + 'default' => wp_kses_post( $options['instruction'] ),
153 + ),
154 + 'buttonLabel' => array(
155 + 'type' => 'string',
156 + 'default' => esc_html( $options['button_label'] ),
157 + ),
158 + 'placeholder' => array(
159 + 'type' => 'string',
160 + 'default' => esc_html( $options['placeholder'] ),
161 + ),
162 + ),
110 163 );
111 164 register_block_type( 'content-protector/area', array_merge( array(
112 165 'editor_script' => 'area-script',
113 166 'editor_style' => 'area-style',
@@ -112,9 +165,9 @@
112 165 'editor_script' => 'area-script',
113 166 'editor_style' => 'area-style',
114 167 ), $settings ) );
115 168 }
116 -
169 +
117 170 /**
118 171 * Returns the shortcode for an area based on block attributes.
119 172 *
120 173 * @param array $attributes the list attributes from the block.
@@ -120,10 +173,9 @@
120 173 * @param array $attributes the list attributes from the block.
121 174 *
122 175 * @return string
123 176 */
124 - public function render_area_block( array $attributes )
125 - {
177 + public function render_area_block( array $attributes ) {
126 178 $area_id = esc_attr( $attributes['area_id'] );
127 179 $area = get_post( $area_id );
128 180 if ( !$area ) {
129 181 return '';
@@ -143,24 +195,24 @@
143 195 $password = get_post_meta( $area_id, 'passster_password', true );
144 196 $atts['password'] = $password;
145 197 $shortcode = '[passster password="' . $password . '" area="' . $area_id . '" ';
146 198 // Building the actual shortcode.
147 - if ( !empty($redirection) ) {
199 + if ( !empty( $redirection ) ) {
148 200 $shortcode .= 'redirect="' . $redirection . '" ';
149 201 }
150 - if ( !empty($headline) ) {
202 + if ( !empty( $headline ) ) {
151 203 $shortcode .= 'headline="' . $headline . '" ';
152 204 }
153 - if ( !empty($instruction) ) {
154 - $shortcode .= 'instruction="' . $instruction . '" ';
205 + if ( !empty( $instruction ) ) {
206 + $shortcode .= 'instruction="' . base64_encode( $instruction ) . '" ';
155 207 }
156 - if ( !empty($placeholder) ) {
208 + if ( !empty( $placeholder ) ) {
157 209 $shortcode .= 'placeholder="' . $placeholder . '" ';
158 210 }
159 - if ( !empty($button) ) {
211 + if ( !empty( $button ) ) {
160 212 $shortcode .= 'button="' . $button . '" ';
161 213 }
162 - if ( !empty($id) ) {
214 + if ( !empty( $id ) ) {
163 215 $shortcode .= 'id="' . $id . '" ';
164 216 }
165 217 $shortcode = rtrim( $shortcode );
166 218 $shortcode .= ']';
@@ -171,5 +223,138 @@
171 223 }
172 224 return do_shortcode( $shortcode );
173 225 }
174 226
175 -}
227 + /**
228 + * Register protected content block.
229 + *
230 + * @return void
231 + */
232 + public function register_protected_content_block() {
233 + // Check if build files exist.
234 + $block_path = PASSSTER_PATH . '/build/blocks/protected-content';
235 + if ( !file_exists( $block_path . '/block.json' ) ) {
236 + return;
237 + }
238 + register_block_type( $block_path );
239 + }
240 +
241 + /**
242 + * Sync protected content blocks with Protected Areas CPT.
243 + *
244 + * @param int $post_id Post ID being saved.
245 + * @param WP_Post $post Post object.
246 + *
247 + * @return void
248 + */
249 + public function sync_protected_content_blocks( $post_id, $post ) {
250 + // Skip auto-saves and revisions.
251 + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
252 + return;
253 + }
254 + if ( wp_is_post_revision( $post_id ) ) {
255 + return;
256 + }
257 + // Skip protected areas CPT to avoid loops.
258 + if ( 'protected_areas' === $post->post_type ) {
259 + return;
260 + }
261 + // Parse blocks from content.
262 + $blocks = parse_blocks( $post->post_content );
263 + $protected_blocks = $this->find_protected_content_blocks( $blocks );
264 + // Get existing synced areas for this post.
265 + $existing_areas = get_posts( array(
266 + 'post_type' => 'protected_areas',
267 + 'posts_per_page' => -1,
268 + 'meta_query' => array(array(
269 + 'key' => '_passster_source',
270 + 'value' => 'block',
271 + ), array(
272 + 'key' => '_passster_source_post_id',
273 + 'value' => $post_id,
274 + )),
275 + ) );
276 + $existing_block_ids = array();
277 + foreach ( $existing_areas as $area ) {
278 + $block_id = get_post_meta( $area->ID, '_passster_block_id', true );
279 + $existing_block_ids[$block_id] = $area->ID;
280 + }
281 + $synced_block_ids = array();
282 + // Sync each protected block.
283 + foreach ( $protected_blocks as $block ) {
284 + $attrs = $block['attrs'];
285 + $block_id = ( !empty( $attrs['blockId'] ) ? $attrs['blockId'] : '' );
286 + if ( empty( $block_id ) ) {
287 + continue;
288 + }
289 + $synced_block_ids[] = $block_id;
290 + // Prepare area data.
291 + $area_title = ( !empty( $attrs['areaTitle'] ) ? $attrs['areaTitle'] : sprintf(
292 + /* translators: %s: Post title */
293 + __( 'Protected block in %s', 'content-protector' ),
294 + $post->post_title
295 + ) );
296 + $area_data = array(
297 + 'post_title' => $area_title,
298 + 'post_type' => 'protected_areas',
299 + 'post_status' => 'publish',
300 + );
301 + // Check if area already exists.
302 + if ( isset( $existing_block_ids[$block_id] ) ) {
303 + $area_data['ID'] = $existing_block_ids[$block_id];
304 + $area_id = wp_update_post( $area_data );
305 + } else {
306 + $area_id = wp_insert_post( $area_data );
307 + }
308 + if ( !$area_id || is_wp_error( $area_id ) ) {
309 + continue;
310 + }
311 + // Save source meta.
312 + update_post_meta( $area_id, '_passster_source', 'block' );
313 + update_post_meta( $area_id, '_passster_source_post_id', $post_id );
314 + update_post_meta( $area_id, '_passster_block_id', $block_id );
315 + // Save protection settings.
316 + $protection_type = ( !empty( $attrs['protectionType'] ) ? $attrs['protectionType'] : 'password' );
317 + update_post_meta( $area_id, 'passster_activate_protection', true );
318 + update_post_meta( $area_id, 'passster_protection_type', $protection_type );
319 + switch ( $protection_type ) {
320 + case 'password':
321 + update_post_meta( $area_id, 'passster_password', ( !empty( $attrs['password'] ) ? $attrs['password'] : '' ) );
322 + break;
323 + case 'passwords':
324 + update_post_meta( $area_id, 'passster_passwords', ( !empty( $attrs['passwords'] ) ? $attrs['passwords'] : '' ) );
325 + break;
326 + case 'password_list':
327 + update_post_meta( $area_id, 'passster_password_list', ( !empty( $attrs['passwordList'] ) ? absint( $attrs['passwordList'] ) : 0 ) );
328 + break;
329 + }
330 + }
331 + // Delete areas for blocks that no longer exist.
332 + foreach ( $existing_block_ids as $block_id => $area_id ) {
333 + if ( !in_array( $block_id, $synced_block_ids, true ) ) {
334 + wp_delete_post( $area_id, true );
335 + }
336 + }
337 + }
338 +
339 + /**
340 + * Recursively find protected content blocks.
341 + *
342 + * @param array $blocks Parsed blocks.
343 + *
344 + * @return array Protected content blocks.
345 + */
346 + private function find_protected_content_blocks( $blocks ) {
347 + $found = array();
348 + foreach ( $blocks as $block ) {
349 + if ( 'passster/content-lock' === $block['blockName'] ) {
350 + $found[] = $block;
351 + }
352 + // Check inner blocks recursively.
353 + if ( !empty( $block['innerBlocks'] ) ) {
354 + $found = array_merge( $found, $this->find_protected_content_blocks( $block['innerBlocks'] ) );
355 + }
356 + }
357 + return $found;
358 + }
359 +
360 +}