PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.3
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.3
3.4.3 3.4.2 3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 2.3.1 All 196 releases
convertkit / includes / blocks / helpers / class-convertkit-block-post-helper.php

class-convertkit-block-post-helper.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 3.4.3, at includes/blocks/helpers/class-convertkit-block-post-helper.php

311 lines 7.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ConvertKit Block Post Helper class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * Helper methods to find, insert, update and delete blocks within a WordPress Post's content.
11 *
12 * @package ConvertKit
13 * @author ConvertKit
14 */
15 class ConvertKit_Block_Post_Helper {
16
17 /**
18 * Finds all blocks matching the given block name in a Post's content.
19 *
20 * @since 3.4.0
21 *
22 * @param int $post_id Post ID.
23 * @param string $block_name Programmatic Block Name.
24 * @return WP_Error|array
25 */
26 public static function find( $post_id, $block_name ) {
27
28 // Get post.
29 $post = get_post( $post_id );
30 if ( ! $post ) {
31 return new WP_Error(
32 'convertkit_block_post_helper_post_not_found',
33 /* translators: %d: post ID */
34 sprintf( __( 'No post exists with ID %d.', 'convertkit' ), $post_id )
35 );
36 }
37
38 // Parse blocks.
39 $blocks = parse_blocks( $post->post_content );
40 $found = array();
41
42 $occurrence_index = 0;
43
44 foreach ( $blocks as $block ) {
45 if ( ! isset( $block['blockName'] ) || $block['blockName'] !== $block_name ) {
46 continue;
47 }
48
49 $found[] = array(
50 'occurrence_index' => (int) $occurrence_index,
51 'attrs' => $block['attrs'],
52 );
53
54 ++$occurrence_index;
55 }
56
57 return $found;
58
59 }
60
61 /**
62 * Inserts a new block into the Post's content at the specified position.
63 *
64 * @since 3.4.0
65 *
66 * @param int $post_id Post ID.
67 * @param string $block_name Programmatic Block Name.
68 * @param array $attrs Block Attributes.
69 * @param string $position One of 'prepend', 'append', 'index'.
70 * @param int $index Zero-based top-level block index; only used when $position is 'index'.
71 * @return WP_Error|array
72 */
73 public static function insert( $post_id, $block_name, $attrs, $position = 'append', $index = 0 ) {
74
75 // If the index is negative, bail.
76 if ( $position === 'index' && (int) $index < 0 ) {
77 return new WP_Error(
78 'convertkit_block_post_helper_invalid_index',
79 sprintf(
80 /* translators: %d: index */
81 __( 'The supplied index (%d) must be zero or a positive integer.', 'convertkit' ),
82 (int) $index
83 )
84 );
85 }
86
87 // Get Post.
88 $post = get_post( $post_id );
89 if ( ! $post ) {
90 return new WP_Error(
91 'convertkit_block_post_helper_insert_block_post_not_found',
92 /* translators: %d: Post ID */
93 sprintf( __( 'No Post exists with ID %d.', 'convertkit' ), $post_id )
94 );
95 }
96
97 // Parse blocks.
98 $blocks = parse_blocks( $post->post_content );
99
100 // Build the new block to insert.
101 $new_block = array(
102 'blockName' => $block_name,
103 'attrs' => (array) $attrs,
104 'innerBlocks' => array(),
105 'innerHTML' => '',
106 'innerContent' => array(),
107 );
108
109 // Resolve $position into a concrete zero-based splice point in the
110 // top-level block array.
111 switch ( $position ) {
112 case 'prepend':
113 $insert_at = 0;
114 break;
115
116 case 'index':
117 $insert_at = max( 0, min( (int) $index, count( $blocks ) ) );
118 break;
119
120 case 'append':
121 default:
122 $insert_at = count( $blocks );
123 break;
124 }
125
126 // Splice in the new block.
127 array_splice( $blocks, $insert_at, 0, array( $new_block ) );
128
129 // Determine the occurrence index of the newly inserted block, by
130 // counting how many blocks of the same name precede it.
131 $occurrence_index = 0;
132 for ( $i = 0; $i < $insert_at; $i++ ) {
133 if ( isset( $blocks[ $i ]['blockName'] ) && $blocks[ $i ]['blockName'] === $block_name ) {
134 ++$occurrence_index;
135 }
136 }
137
138 // Update Post.
139 $result = wp_update_post(
140 array(
141 'ID' => $post_id,
142 'post_content' => serialize_blocks( $blocks ),
143 ),
144 true
145 );
146
147 // Bail if the update failed.
148 if ( is_wp_error( $result ) ) {
149 return $result;
150 }
151
152 // Return the occurrence index of the newly inserted block.
153 return array(
154 'post_id' => $post_id,
155 'occurrence_index' => $occurrence_index,
156 );
157
158 }
159
160 /**
161 * Updates the attributes of an existing block in the Post's content.
162 *
163 * @since 3.4.0
164 *
165 * @param int $post_id Post ID.
166 * @param string $block_name Programmatic Block Name.
167 * @param int $occurrence_index Position to update block.
168 * @param array $attrs Block Attributes.
169 * @return WP_Error|array
170 */
171 public static function update( $post_id, $block_name, $occurrence_index, $attrs ) {
172
173 // Get Post.
174 $post = get_post( $post_id );
175 if ( ! $post ) {
176 return new WP_Error(
177 'convertkit_block_post_helper_update_block_post_not_found',
178 /* translators: %d: post ID */
179 sprintf( __( 'No Post exists with ID %d.', 'convertkit' ), $post_id )
180 );
181 }
182
183 // Parse blocks.
184 $blocks = parse_blocks( $post->post_content );
185 $block_index = 0;
186 $matched = false;
187
188 foreach ( $blocks as $key => $block ) {
189 // Skip if the block name does not match.
190 if ( ! isset( $block['blockName'] ) || $block['blockName'] !== $block_name ) {
191 continue;
192 }
193
194 // Update the block if the occurrence index matches.
195 if ( $block_index === (int) $occurrence_index ) {
196 $blocks[ $key ]['attrs'] = array_merge( (array) $block['attrs'], (array) $attrs );
197 $matched = true;
198 break;
199 }
200
201 ++$block_index;
202 }
203
204 // Bail if the block was not found.
205 if ( ! $matched ) {
206 return new WP_Error(
207 'convertkit_block_post_helper_occurrence_not_found',
208 /* translators: 1: block name, 2: occurrence index, 3: post ID */
209 sprintf( __( 'No occurrence #%2$d of block %1$s found in post %3$d.', 'convertkit' ), $block_name, (int) $occurrence_index, $post_id )
210 );
211 }
212
213 // Update Post.
214 $result = wp_update_post(
215 array(
216 'ID' => $post_id,
217 'post_content' => serialize_blocks( $blocks ),
218 ),
219 true
220 );
221
222 // Bail if the update failed.
223 if ( is_wp_error( $result ) ) {
224 return $result;
225 }
226
227 // Return the occurrence index of the block that was updated.
228 return array(
229 'post_id' => $post_id,
230 'occurrence_index' => (int) $occurrence_index,
231 );
232
233 }
234
235 /**
236 * Deletes a specific block from the Post's content.
237 *
238 * @since 3.4.0
239 *
240 * @param int $post_id Post ID.
241 * @param string $block_name Programmatic Block Name.
242 * @param int $occurrence_index Zero-based index among this block's occurrences in the post.
243 * @return WP_Error|array
244 */
245 public static function delete( $post_id, $block_name, $occurrence_index ) {
246
247 // Get Post.
248 $post = get_post( $post_id );
249 if ( ! $post ) {
250 return new WP_Error(
251 'convertkit_block_post_helper_update_block_post_not_found',
252 /* translators: %d: post ID */
253 sprintf( __( 'No Post exists with ID %d.', 'convertkit' ), $post_id )
254 );
255 }
256
257 // Parse blocks.
258 $blocks = parse_blocks( $post->post_content );
259 $block_index = 0;
260 $matched = false;
261
262 foreach ( $blocks as $key => $block ) {
263 // Skip if the block name does not match.
264 if ( ! isset( $block['blockName'] ) || $block['blockName'] !== $block_name ) {
265 continue;
266 }
267
268 // Delete the block if the occurrence index matches.
269 if ( $block_index === (int) $occurrence_index ) {
270 unset( $blocks[ $key ] );
271 $blocks = array_values( $blocks );
272 $matched = true;
273 break;
274 }
275
276 ++$block_index;
277 }
278
279 // Bail if the block was not found.
280 if ( ! $matched ) {
281 return new WP_Error(
282 'convertkit_block_post_helper_occurrence_not_found',
283 /* translators: 1: block name, 2: occurrence index, 3: post ID */
284 sprintf( __( 'No occurrence #%2$d of block %1$s found in post %3$d.', 'convertkit' ), $block_name, (int) $occurrence_index, $post_id )
285 );
286 }
287
288 // Update Post.
289 $result = wp_update_post(
290 array(
291 'ID' => $post_id,
292 'post_content' => serialize_blocks( $blocks ),
293 ),
294 true
295 );
296
297 // Bail if the update failed.
298 if ( is_wp_error( $result ) ) {
299 return $result;
300 }
301
302 // Return the occurrence index of the block that was deleted.
303 return array(
304 'post_id' => $post_id,
305 'occurrence_index' => (int) $occurrence_index,
306 );
307
308 }
309
310 }
311