PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.1.2
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.1.2
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
← All changes | includes/Core/Importer/Runners/Finalizer.php +27 -240 3.7.33.1.2 View file →
@@ -3,25 +3,21 @@
3 3 namespace Templately\Core\Importer\Runners;
4 4
5 5
6 6 use Exception;
7 -use Templately\Core\Importer\Utils\AIContentHelper;
8 -use Templately\Core\Importer\Utils\AIContentResolver;
9 7 use Templately\Core\Importer\Utils\Utils;
10 -use Templately\Utils\Helper;
11 8
12 9 class Finalizer extends BaseRunner {
13 - use AIContentHelper;
14 10 private $options = [];
15 11 private $type_to_check = [ 'templates', 'content' ];
16 12 private $imported_data;
17 13
18 - public $type = '';
19 - private $data = [];
20 - public $sub_type = '';
14 + private $type = '';
15 + private $sub_type = '';
21 16 private $extra_content;
22 17
23 18 private $total_counts = 0;
19 + private $processed_items = 0;
24 20
25 21 /**
26 22 * @var array|mixed
27 23 */
@@ -42,20 +38,18 @@
42 38 public function log_message(): string {
43 39 return __( 'Finalizing Your Imports', 'templately' );
44 40 }
45 41
46 - public function should_run( $param_data, $imported_data = [] ): bool {
42 + public function should_run( $data, $imported_data = [] ): bool {
47 43 $data = [];
48 44
49 45 foreach ( $this->type_to_check as $type ) {
50 46 $contents = ! empty ( $this->manifest[ $type ] ) ? $this->manifest[ $type ] : [];
51 47 if ( $type == 'templates' ) {
52 - // $imported_data["templates"]["__attachments"][691]
53 - $this->prepare( $data, $contents, $type, null, $imported_data );
48 + $this->prepare( $data, $contents, $type );
54 49 } else {
55 50 foreach ( $contents as $post_type => $templates ) {
56 - // $imported_data["content"]["__attachments"][$post_type][11]
57 - $this->prepare( $data, $templates, $type, $post_type, $imported_data );
51 + $this->prepare( $data, $templates, $type, $post_type );
58 52 }
59 53 }
60 54 }
61 55 $this->options = &$data;
@@ -62,36 +56,14 @@
62 56
63 57 return ! empty( $data ) || $this->platform == 'gutenberg';
64 58 }
65 59
66 - private function prepare( &$data, $templates, $type, $sub_type = null, $imported_data = [] ) {
60 + private function prepare( &$data, $templates, $type, $sub_type = null ) {
67 61 if ( empty( $templates ) || ! is_array( $templates ) ) {
68 62 return;
69 63 }
70 64 foreach ( $templates as $id => $template ) {
71 - // Check for __attachments in both template and imported_data
72 - $has_attachment = !empty($template['__attachments']);
73 -
74 - if (!$has_attachment && !empty($imported_data)) {
75 - if ($sub_type) {
76 - // $imported_data["content"]["__attachments"]["page"][11]
77 - $has_attachment = isset($imported_data[$type]['__attachments'][$sub_type][$id]);
78 - } else {
79 - // $imported_data["templates"]["__attachments"][691]
80 - $has_attachment = isset($imported_data[$type]['__attachments'][$id]);
81 - }
82 - }
83 -
84 - // Pick up docs the import runners flagged as carrying source-site links
85 - // (Mega Menu / nav / button URLs) so the finalize loop rewrites them to the
86 - // real imported permalinks — same opt-in mechanism as __attachments above.
87 - // $imported_data["templates"]["__link_rewrites"][52]
88 - // $imported_data["content"]["page"]["__link_rewrites"][35]
89 - $needs_link_rewrite = $sub_type
90 - ? isset( $imported_data[ $type ][ $sub_type ]['__link_rewrites'][ $id ] )
91 - : isset( $imported_data[ $type ]['__link_rewrites'][ $id ] );
92 -
93 - if ( ! isset( $template['data'] ) && !$has_attachment && !$needs_link_rewrite && !isset($template['has_logo']) && !$this->is_ai_content($id) && !isset($template["page_settings"]["fluent_cart_store_settings"]) ) {
65 + if ( ! isset( $template['data'] ) && !isset( $template['__attachments']) && !isset($template['has_logo']) ) {
94 66 continue;
95 67 }
96 68
97 69 // if ( ! isset( $template['data']['form'] ) && ! isset( $template['data']['nav_menus'] )) {
@@ -108,38 +80,31 @@
108 80 }
109 81 }
110 82
111 83 public function import( $data, $imported_data ): array {
112 - $this->data = &$data;
113 84 $this->imported_data = &$imported_data;
114 85
115 86 $this->json->imported_data = $this->imported_data;
116 87 $this->json->map_post_ids = Utils::map_old_new_post_ids( $this->imported_data );
117 88 $this->json->map_term_ids = Utils::map_old_new_term_ids( $this->imported_data );
118 - if ( $this->manifest['platform'] === 'elementor' ) {
119 - $this->json->set_source_url( $this->manifest['site'] ?? '' );
120 - $this->json->set_source_pages( $this->build_source_pages_map() );
121 - }
122 89 if ( ! empty( $imported_data['extra-content'] ) ) {
123 90 $this->extra_content = $imported_data['extra-content'];
124 91 }
125 92
93 + $this->log( 0 );
126 94 add_action('templately_import.finalize_gutenberg_attachment', [$this, 'post_log'], 10, 2);
127 95
128 - $this->update_settings();
129 -
130 - $this->loop( $this->options, function($type, $contents ) {
96 + foreach ( $this->options as $type => $contents ) {
131 97 $this->type = $type;
132 -
133 98 if ( $type == 'templates' ) {
134 - $this->finalize_imports( $contents, $type );
99 + $this->finalize_imports( $contents );
135 100 } else {
136 - $this->loop( $contents, function($post_type, $templates ) use($type) {
101 + foreach ( $contents as $post_type => $templates ) {
137 102 $this->sub_type = $post_type;
138 - $this->finalize_imports( $templates, $type, $post_type );
139 - }, $type);
103 + $this->finalize_imports( $templates );
104 + }
140 105 }
141 - });
106 + }
142 107
143 108 if ( $this->platform == 'gutenberg' ) {
144 109 $this->regenerate_assets();
145 110 }
@@ -146,100 +111,8 @@
146 111
147 112 return [];
148 113 }
149 114
150 - /**
151 - * Build the ORIGINAL-slug => imported-permalink map handed to ElementorHelper so
152 - * links can resolve to the page WordPress actually created (slug-change-proof).
153 - *
154 - * Keyed by the pack's original slug — which is what stored links still carry —
155 - * with the value being get_permalink() of the imported post, so a conflict rename
156 - * (about-us → about-us-2) is transparently followed. Pages win over other post
157 - * types on a slug collision. WooCommerce system pages (shop, cart, checkout,
158 - * my-account) are added as aliases since they live outside the manifest content.
159 - *
160 - * @return array
161 - */
162 - private function build_source_pages_map(): array {
163 - $map = [];
164 - $map_post_ids = $this->json->map_post_ids;
165 - $content = $this->manifest['content'] ?? [];
166 -
167 - if ( is_array( $content ) ) {
168 - foreach ( $content as $post_type => $items ) {
169 - if ( ! is_array( $items ) ) {
170 - continue;
171 - }
172 -
173 - foreach ( $items as $old_id => $entry ) {
174 - $slug = isset( $entry['slug'] ) ? strtolower( trim( (string) $entry['slug'] ) ) : '';
175 - if ( '' === $slug ) {
176 - continue;
177 - }
178 -
179 - $new_id = $map_post_ids[ $old_id ] ?? null;
180 - if ( empty( $new_id ) ) {
181 - continue;
182 - }
183 -
184 - $permalink = get_permalink( $new_id );
185 - if ( ! $permalink || is_wp_error( $permalink ) ) {
186 - continue;
187 - }
188 -
189 - // First match wins, but a real `page` always overrides another
190 - // post type that happens to share the slug.
191 - if ( ! isset( $map[ $slug ] ) || 'page' === $post_type ) {
192 - $map[ $slug ] = $permalink;
193 - }
194 - }
195 - }
196 - }
197 -
198 - $this->add_woocommerce_page_aliases( $map );
199 -
200 - return $map;
201 - }
202 -
203 - /**
204 - * Add WooCommerce system-page slugs to the resolution map. These pages are not in
205 - * the manifest content, so menu links to them (often relative, e.g. /demo/shop,
206 - * /demo/sign-in) would otherwise only get the plain domain swap.
207 - *
208 - * Heuristic: the demo's my-account page may be titled/slugged "sign-in", "login",
209 - * etc.; those common aliases are mapped to this site's WooCommerce my-account page.
210 - * Manifest pages already in the map are never overwritten.
211 - *
212 - * @param array $map slug => permalink (by reference).
213 - *
214 - * @return void
215 - */
216 - private function add_woocommerce_page_aliases( array &$map ) {
217 - if ( ! function_exists( 'wc_get_page_permalink' ) ) {
218 - return;
219 - }
220 -
221 - $aliases = [
222 - 'shop' => [ 'shop', 'store', 'products' ],
223 - 'cart' => [ 'cart' ],
224 - 'checkout' => [ 'checkout' ],
225 - 'myaccount' => [ 'my-account', 'myaccount', 'account', 'sign-in', 'signin', 'login', 'log-in', 'dashboard' ],
226 - ];
227 -
228 - foreach ( $aliases as $wc_page => $slugs ) {
229 - $permalink = wc_get_page_permalink( $wc_page );
230 - if ( ! $permalink ) {
231 - continue;
232 - }
233 -
234 - foreach ( $slugs as $slug ) {
235 - if ( ! isset( $map[ $slug ] ) ) {
236 - $map[ $slug ] = $permalink;
237 - }
238 - }
239 - }
240 - }
241 -
242 115 private function regenerate_assets() {
243 116 $upload_dir = wp_upload_dir();
244 117 if ( is_dir( $upload_dir['basedir'] . '/eb-style/' ) ) {
245 118 array_map( 'unlink', glob( $upload_dir['basedir'] . '/eb-style/*.min.css' ) );
@@ -246,116 +119,30 @@
246 119 rmdir( $upload_dir['basedir'] . '/eb-style/' );
247 120 }
248 121 }
249 122
250 - private function finalize_imports( $templates, $type, $post_type = null ) {
251 - // used for counting
252 - $processed = $this->get_loop_result([], 'finalized_imports', false);
253 - $path = $this->dir_path . $this->type . DIRECTORY_SEPARATOR;
254 -
255 - if ( ! empty( $this->sub_type ) ) {
256 - $path .= $this->sub_type . DIRECTORY_SEPARATOR;
257 - }
258 -
259 - $this->loop( $templates, function($old_template_id, $template_settings ) use($type, $post_type, $path, $processed) {
123 + private function finalize_imports( $templates ) {
124 + foreach ( $templates as $old_template_id => $template_settings ) {
260 125 try {
261 -
262 - if($post_type && isset($this->imported_data[$type]['__attachments'][$post_type][$old_template_id])){
263 - $template_settings['__attachments'] = $this->imported_data[$type]['__attachments'][$post_type][$old_template_id];
126 + $path = $this->dir_path . $this->type . DIRECTORY_SEPARATOR;
127 + if ( ! empty( $this->sub_type ) ) {
128 + $path .= $this->sub_type . DIRECTORY_SEPARATOR;
264 129 }
265 - else if(empty($post_type) && isset($this->imported_data[$type]['__attachments'][$old_template_id])){
266 - $template_settings['__attachments'] = $this->imported_data[$type]['__attachments'][$old_template_id];
267 - }
268 -
269 - // Read the original template file for non-AI content
270 - $original_file = $path . "{$old_template_id}.json";
271 - $template_json = Utils::read_json_file($original_file);
272 -
273 - $processed_pages = get_option("templately_ai_processed_pages", []);
274 - $updated_ids = $processed_pages[$this->process_id] ?? [];
275 - $ai_paths = $this->generateAiFilePaths($old_template_id);
276 - if($this->is_ai_content($old_template_id) && !file_exists($ai_paths['ai_file_path'])){
277 - // Source-agnostic seam: whichever AI-content source owns this
278 - // process (classic per-page callback, chat-id pull, or a future
279 - // source) stages the .ai.json; otherwise the shared SSE-wait runs.
280 - AIContentResolver::ensure_page_ready([
281 - 'session_id' => $this->session_id,
282 - 'process_id' => $this->process_id,
283 - 'content_id' => $old_template_id,
284 - 'ai_page_ids' => $this->ai_page_ids,
285 - 'updated_ids' => $updated_ids,
286 - 'sse_callback' => [$this, 'sse_message'],
287 - 'progress_id' => 'ai_content_time',
288 - 'additional_sse_data' => [
289 - 'name' => method_exists($this, 'get_name') ? $this->get_name() : '',
290 - 'post_type' => $post_type,
291 - 'id' => $old_template_id,
292 - ],
293 - ]);
294 - }
295 - // Check if this is AI content before processing
296 - if ($this->isAiContent($old_template_id)) {
297 - // Process AI content using AIContentHelper trait
298 - $ai_result = $this->processAiContent($old_template_id);
299 - if($ai_result['is_ai'] && !empty($ai_result['template_json'])){
300 - $template_json = $ai_result['template_json'];
301 - }
302 - }
303 -
130 + $path .= "{$old_template_id}.json";
131 + $template_json = Utils::read_json_file( $path );
304 132 $params = $this->origin->get_request_params();
305 133 $this->json->prepare( $template_json, $template_settings, $this->extra_content['form'][ $old_template_id ] ?? [], $params )->update();
306 134
307 - $processed[] = $old_template_id;
308 - // Add the template to the processed templates and update the session data
309 - $this->set_loop_result( $processed, 'finalized_imports');
310 135 // Broadcast Log
311 - $progress = floor( ( 100 * count($processed) ) / $this->total_counts );
312 - if(empty($progress)){
313 - $xyz = 0;
314 - }
136 + $this->processed_items += 1;
137 + $progress = floor( ( 100 * $this->processed_items ) / $this->total_counts );
315 138 $this->log( $progress );
316 -
317 139 } catch ( Exception $e ) {
318 -
140 + continue;
319 141 }
320 -
321 -
322 - }, "$type-$post_type");
142 + }
323 143 }
324 144
325 145 public function post_log($id, $size_dimension = null){
326 146 $this->log(-1, "Imported attachment: $id" . ( $size_dimension ? " - $size_dimension" : ''), 'eventLog');
327 147 }
328 -
329 - private function update_settings() {
330 - $data = $this->data;
331 - $map_post_ids = $this->json->map_post_ids;
332 - $saved_options = get_option('fluent_cart_store_settings', []);
333 - $mapped_keys = [
334 - 'checkout_page_id',
335 - 'custom_payment_page_id',
336 - 'registration_page_id',
337 - 'login_page_id',
338 - 'cart_page_id',
339 - 'receipt_page_id',
340 - 'shop_page_id',
341 - 'customer_profile_page_id',
342 - ];
343 -
344 - foreach ($mapped_keys as $key) {
345 - $old_id = $saved_options[$key] ?? null;
346 - if (!empty($old_id) && isset($map_post_ids[$old_id])) {
347 - $saved_options[$key] = $map_post_ids[$old_id];
348 - }
349 - else if(isset($saved_options[$key])){
350 - unset($saved_options[$key]);
351 - }
352 - }
353 -
354 - update_option('fluent_cart_store_settings', $saved_options);
355 - }
356 -
357 -
358 -
359 -
360 -
361 -}
148 +}