PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.4.0
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.4.0
3.7.5 3.7.4 3.7.3 3.7.2 1-final 3.7.1 3.7.0 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.10 All 111 releases
templately / includes / Core / Importer / Utils / GutenbergHelper.php

GutenbergHelper.php in Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! 3.4.0, at includes/Core/Importer/Utils/GutenbergHelper.php

408 lines 12.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Templately\Core\Importer\Utils;
4
5 use Templately\Core\Importer\WPImport;
6 use Templately\Utils\Helper;
7
8 class GutenbergHelper extends ImportHelper {
9 const IMAGE_URL_PATTERN = '/(http(s?):)([\/|.|\w|\s|-])*\.(?:jpg|gif|png)/';
10
11 private $template_settings = [];
12 private $forms = [];
13 /**
14 * @var WPImport
15 */
16 private $wp_importer;
17
18 public $shouldLog = true; // This is the class property to check
19
20 protected $content;
21
22 protected $post_id;
23
24 protected static $attachment_ids = [];
25
26
27 /**
28 * @param $template_json
29 * @param $template_settings
30 * @param $extra_content
31 *
32 * @return GutenbergHelper
33 */
34 public function prepare( $template_json, $template_settings, $extra_content = [], $request_params = [] ) {
35 $this->template_settings = $template_settings;
36 $this->post_id = $this->map_post_ids[ $template_settings['post_id'] ];
37 $this->wp_importer = new WPImport( null, [
38 'session_id' => $this->session_id,
39 'fetch_attachments' => true,
40 ] );
41
42 $parsed_blocks = parse_blocks( $template_json['content'] );
43 if ( ! empty( $extra_content ) ) {
44 $this->prepare_form_data( $extra_content, $template_settings );
45 }
46 if ( isset($this->template_settings['__attachments']) ) {
47 $this->process_images();
48 // Make sure we do the longest urls first, in case one is a substring of another.
49 }
50 if(!empty($this->wp_importer->url_remap)){
51 uksort( $this->wp_importer->url_remap, function ( $a, $b ) {
52 // Return the difference in length between two strings.
53 return strlen( $b ) - strlen( $a );
54 } );
55 }
56 $this->replace( $parsed_blocks, $request_params );
57 $this->content = wp_slash( serialize_blocks( $parsed_blocks ) );
58
59 return $this;
60 }
61
62 public function update() {
63 $this->sse_log('update', 'Updating prepared data, just a moment...', 1, 'eventLog');
64 wp_update_post( [
65 'ID' => $this->post_id,
66 'post_content' => $this->content
67 ] );
68 }
69
70 private function prepare_form_data( $extra_content, $template_settings ) {
71 foreach ( $extra_content as $type => $content ) {
72 foreach ( $content as $block_id => $value ) {
73 foreach ( $template_settings['data']['form'][ $type ] as $setting ) {
74 if ( isset( $setting['id'] ) && $setting['id'] === $block_id ) {
75 $this->forms[ $block_id ] = [
76 'value' => $value,
77 'attr' => $setting['identifier']
78 ];
79 }
80 }
81
82 }
83 }
84 }
85
86 private function replace( &$blocks, $request_params = [] ) {
87 foreach ( $blocks as &$block ) {
88 $this->sse_log('prepare', 'Preparing output for finalize, just a moment...', 1, 'eventLog');
89 if ( $block['blockName'] === 'core/navigation' ) {
90 if ( ! empty( $block['attrs']['ref'] ) && array_key_exists( $block['attrs']['ref'], $this->map_post_ids ) ) {
91 $block['attrs']['ref'] = $this->map_post_ids[ $block['attrs']['ref'] ];
92 $this->replace_archive_id( $block['attrs']['ref'] );
93 }
94 }
95 if ( isset( $block['attrs']['blockId'] ) && array_key_exists( $block['attrs']['blockId'], $this->forms ) ) {
96 $blockId = $block['attrs']['blockId'];
97 $form = $this->forms[$blockId];
98 $attr = $form['attr'];
99 $value = (string) $form['value'];
100
101 $block['attrs'][$attr] = $value;
102 }
103
104 if ( ! empty( $block['attrs']['queryData'] ) ) {
105 $this->replace_query_data( $block );
106 }
107
108 if ( isset($this->template_settings['__attachments']) ) {
109 $block = $this->replace_attachment_url( $block );
110 }
111
112 if ( ! empty( $block['innerBlocks'] ) ) {
113 $this->replace( $block['innerBlocks'], $request_params );
114 }
115 else if(!empty($request_params['logo']['id']) && isset($request_params['logo_size']) && $request_params['logo_size'] && $block['blockName'] === "essential-blocks/advanced-image" && $block["attrs"]["imgSource"] === "site-logo"){
116 $block["attrs"]["widthRange"] = $request_params['logo_size'];
117 unset($block["attrs"]["widthUnit"]);
118 if (isset($block['attrs']['blockMeta']['desktop']) && is_string($block['attrs']['blockMeta']['desktop'])) {
119 $meta = $block['attrs']['blockMeta']['desktop'];
120 $regex = '/\.image-wrapper\s*{\s*width:\s*(\d+)px;/';
121
122 if (preg_match($regex, $meta, $matches)) {
123 $replaced = preg_replace($regex, '.image-wrapper { width:' . $request_params['logo_size'] . 'px;', $meta);
124
125 if ($replaced) {
126 $block['attrs']['blockMeta']['desktop'] = $replaced;
127 }
128 }
129 }
130
131 $this->sse_log('prepare', 'Updated Site Logo', 1, 'eventLog');
132 }
133 }
134 }
135
136 private function replace_archive_id( $menu_id ) {
137 if ( ! empty( $this->imported_data['archive_settings'] ) ) {
138 $post = get_post( $menu_id );
139 $blocks = parse_blocks( $post->post_content );
140 $changed = false;
141 foreach ( $blocks as &$block ) {
142 $this->sse_log('query', 'Finalizing archive settings, just a moment...', 1, 'eventLog');
143
144 if (isset($block['attrs']['id'])) {
145 $blockId = $block['attrs']['id'];
146 $archiveSettings = $this->imported_data['archive_settings'];
147
148 $archiveIds = $archiveSettings[$blockId] ?? false;
149
150 if ($archiveIds) {
151 $block['attrs']['id'] = $archiveIds['page_id'];
152 $block['attrs']['url'] = get_the_permalink($archiveIds['page_id']);
153 $changed = true;
154 }
155 }
156 }
157 if ( $changed ) {
158 wp_update_post( [
159 'ID' => $menu_id,
160 'post_content' => wp_slash( serialize_blocks( $blocks ) )
161 ] );
162 }
163 }
164 }
165
166 /**
167 * @param $block
168 *
169 * @return void
170 */
171 private function replace_query_data( &$block ) {
172 if ( ! empty( $block['attrs']['queryData']['taxonomies'] ) ) {
173 foreach ( $block['attrs']['queryData']['taxonomies'] as &$tax ) {
174 $this->sse_log('query', 'Finalizing query data, just a moment...', 1, 'eventLog');
175 $tax['value'] = json_decode( $tax['value'], true );
176 if ( ! empty( $tax['value'] ) ) {
177 foreach ( $tax['value'] as &$val ) {
178 if ( array_key_exists( $val['value'], $this->map_term_ids ) ) {
179 $val['value'] = $this->map_term_ids[ $val['value'] ];
180 }
181 }
182 }
183 $tax['value'] = json_encode( $tax['value'] );
184 }
185 }
186 $this->replace_raw_taxonomies($block);
187 if(!empty( $block['attrs']['queryData']['author'])){
188 $user = wp_get_current_user();
189 $block['attrs']['queryData']['author'] = json_encode([['label' => $user->display_name, 'value' => $user->ID]]);
190 }
191 }
192
193 /**
194 * @param $block
195 *
196 * @return void
197 */
198 private function replace_raw_taxonomies( &$block ) {
199 $types = ['category', 'tag'];
200 foreach ( $types as $type){
201 if(!empty($block['attrs']['queryData'][$type])){
202 $block['attrs']['queryData'][$type] = json_decode($block['attrs']['queryData'][$type], true);
203 foreach ($block['attrs']['queryData'][$type] as &$term){
204 $this->sse_log('prepare', 'Finalizing taxonomies, just a moment...', 1, 'eventLog');
205 if ( isset($term['value']) && array_key_exists( $term['value'], $this->map_term_ids ) ) {
206 $term['value'] = $this->map_term_ids[ $term['value'] ];
207 }
208 }
209 $block['attrs']['queryData'][$type] = json_encode($block['attrs']['queryData'][$type]);
210 }
211 }
212 }
213
214 public function replace_attachment_url($attrs) {
215 if ( !empty($attrs['blockName'] ) ) {
216 $attrs = $this->replace_attachment_ids($attrs);
217 }
218
219 if (is_string($attrs)) {
220 foreach ($this->wp_importer->url_remap as $old_url => $new_url) {
221 if (strpos($attrs, $old_url) !== false) {
222 $attrs = str_replace($old_url, $new_url, $attrs);
223 }
224 }
225 }
226 else if (is_array($attrs)) {
227 foreach ($attrs as $key => $attr) {
228 $attrs[$key] = $this->replace_attachment_url($attr);
229 }
230 }
231
232 return $attrs;
233 }
234
235 protected function replace_attachment_ids($attrs){
236 switch ($attrs['blockName']) {
237 case 'essential-blocks/slider':
238 $attrs = $this->processImages($attrs, 'images', 'imageId', 'url');
239 break;
240 case 'essential-blocks/advanced-image':
241 $attrs = $this->processSingleImage($attrs, 'image');
242 break;
243 case 'essential-blocks/parallax-slider':
244 $attrs = $this->processImages($attrs, 'sliderData', 'id', 'src');
245 break;
246 case 'essential-blocks/image-gallery':
247 $attrs = $this->processImages($attrs, 'images', 'id', 'url');
248 $attrs = $this->processImages($attrs, 'sources', 'id', 'url');
249 break;
250 case 'core/image':
251 $attrs = $this->processCoreImage($attrs, 'id');
252 break;
253 case 'core/media-text':
254 $attrs = $this->processCoreImage($attrs, 'mediaId');
255 break;
256 case 'core/cover':
257 $attrs = $this->processSingleImage($attrs, 'url');
258 break;
259 }
260 return $attrs;
261 }
262
263 private function processImages($attrs, $imageKey, $idKey, $urlKey) {
264 if (!empty($attrs['attrs'][$imageKey])) {
265 foreach ($attrs['attrs'][$imageKey] as $key => &$image) {
266 $imageUrl = $image[$urlKey];
267 if (!empty(self::$attachment_ids[$imageUrl])) {
268 $oldId = $image[$idKey];
269 $newId = (int) self::$attachment_ids[$imageUrl];
270 $image[$idKey] = $newId;
271
272 // Update innerHTML and innerContent for 'essential-blocks/slider'
273 if ($attrs['blockName'] === 'essential-blocks/slider') {
274 $attrs = $this->updateInnerHTMLAndContent($attrs, "imageId&quot;:$oldId,&quot;", "imageId&quot;:$newId,&quot;");
275 }
276 }
277 }
278 }
279 return $attrs;
280 }
281
282 private function processSingleImage($attrs, $imageKey) {
283 if (!empty(self::$attachment_ids[$attrs['attrs'][$imageKey]['url']])) {
284 $attrs['attrs'][$imageKey]['id'] = (int) self::$attachment_ids[$attrs['attrs'][$imageKey]['url']];
285 }
286 return $attrs;
287 }
288
289 private function processCoreImage($attrs, $idKey) {
290 preg_match(self::IMAGE_URL_PATTERN, $attrs['innerHTML'], $matches);
291 if (!empty($matches[0])) {
292 $url = $matches[0];
293 if (!empty(self::$attachment_ids[$url])) {
294 $oldId = $attrs['attrs'][$idKey];
295 $newId = (int) self::$attachment_ids[$url];
296 $attrs['attrs'][$idKey] = $newId;
297
298 // Replace old ID with new ID in innerHTML and innerContent
299 $attrs = $this->updateInnerHTMLAndContent($attrs, "wp-image-$oldId", "wp-image-$newId");
300 }
301 }
302 return $attrs;
303 }
304
305 private function updateInnerHTMLAndContent($attrs, $oldValue, $newValue) {
306 $attrs['innerHTML'] = str_replace($oldValue, $newValue, $attrs['innerHTML']);
307 if (is_array($attrs['innerContent'])) {
308 foreach ($attrs['innerContent'] as $i => $content) {
309 $attrs['innerContent'][$i] = str_replace($oldValue, $newValue, $content);
310 }
311 } else {
312 $attrs['innerContent'] = str_replace($oldValue, $newValue, $attrs['innerContent']);
313 }
314 return $attrs;
315 }
316
317 /**
318 * Parses the images from the post content, processes them as attachments, and updates the post with the new attachment URL.
319 * @todo: Parse using parse_blocks instead of regex
320 *
321 * @param int $post_id The ID of the post.
322 * @param string $post_content The content of the post.
323 */
324 public function parse_images($post_content) {
325 // Find all image URLs in the post content
326 preg_match_all(self::IMAGE_URL_PATTERN, $post_content, $matches);
327
328 $urls = $matches[0];
329 $organizedUrls = [];
330
331 foreach ($urls as $url) {
332 // Remove the size suffix from the URL
333 $base_url = preg_replace('/-\d+x\d+(?=\.[a-zA-Z]+$)/', '', $url);
334
335 // Check if the URL already exists in the array
336 if (!isset($organizedUrls[$base_url]) || !in_array($url, $organizedUrls[$base_url])) {
337 // Add the URL to the array under the base URL key
338 $organizedUrls[$base_url][] = $url;
339 }
340 }
341
342 return $organizedUrls;
343 }
344
345 public function process_images(){
346 // Time to run the import!
347 set_time_limit( 0 );
348
349 $organizedUrls = $this->template_settings['__attachments'];
350 // For each base image URL...
351 foreach ($organizedUrls as $base_url => $sizes) {
352 // Prepare the post data for the attachment
353 $post_data = $this->prepare_post_data($this->post_id, $base_url);
354
355 // If prepare_post_data returned null, skip this iteration
356 if ($post_data === null) {
357 continue;
358 }
359
360 foreach ($sizes as $key => $size) {
361 if ($base_url == $size) {
362 unset($sizes[$key]);
363 continue;
364 }
365
366 // $size url string; get width height from the image url
367 preg_match('/-(\d+)x(\d+)\.[a-zA-Z]+$/', $size, $matches);
368 if (isset($matches[1]) && isset($matches[2])) {
369 $sizes[$key] = [
370 'file' => basename($size),
371 'width' => $matches[1],
372 'height' => $matches[2]
373 ];
374 } else {
375 unset($sizes[$key]);
376 }
377 }
378
379 // Check if the attachment already exists
380 $attachment_id = $this->wp_importer->process_attachment($post_data, $base_url, $sizes);
381 // If there was an error, handle it here
382 if (is_wp_error($attachment_id)) {
383 $this->sse_log('error', $attachment_id->get_error_message(), -1, 'eventLog');
384 } else {
385 $this->sse_log('success', "Imported attachment: $attachment_id", -1, 'eventLog');
386 self::$attachment_ids[$base_url] = $attachment_id;
387 }
388 }
389 }
390
391 private function prepare_post_data($post_id, $image_url) {
392 return Utils::prepare_post_data($image_url, $post_id, [$this, 'sse_log']);
393 }
394
395 public function sse_log( $type, $message, $progress = 1, $action = 'updateLog', $status = null ) {
396 if ($this->shouldLog) {
397 parent::sse_log($type, $message, $progress, $action, $status);
398 }
399 else{
400 Helper::log(func_get_args());
401 }
402 }
403
404 public function get_content(){
405 return $this->content;
406 }
407
408 }