PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.3.0
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.3.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.3.0, at includes/Core/Importer/Utils/GutenbergHelper.php

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