PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / 6.0.13
Kirki – Freeform Page Builder, Website Builder & Customizer v6.0.13
6.1.1 6.1.0 6.0.14 6.0.13 6.0.12 6.0.11 6.0.10 6.0.9 6.0.8 6.0.7 6.0.6 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0.19 4.0.20 4.0.21 4.0.22 4.0.23 4.0.24 4.1 4.2.0 5.0.0 5.1.0 5.1.1 5.2.0 5.2.1 5.2.2 5.2.3 6.0.0 trunk 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.1.0 3.1.1 3.1.2
kirki / app / Supports / Template.php
kirki / app / Supports Last commit date
Facades 3 weeks ago Canvas.php 3 weeks ago CollectionItem.php 3 weeks ago ContentManager.php 3 weeks ago DateTime.php 3 weeks ago EditorPreview.php 3 weeks ago FileHandler.php 3 weeks ago FilterHooks.php 3 weeks ago PageUrl.php 3 weeks ago Role.php 3 weeks ago Template.php 3 weeks ago
Template.php
407 lines
1 <?php
2
3 namespace Kirki\App\Supports;
4
5 defined('ABSPATH') || exit;
6
7 use Kirki\App\Constants\UtilityPageType;
8 use Kirki\App\DTO\Page\EditorPagePayloadDTO;
9 use Kirki\App\DTO\Symbol\SymbolDTO;
10 use Kirki\App\Models\Page as PageModel;
11 use Kirki\App\Models\Post as PostModel;
12 use Kirki\App\Services\PageService;
13 use Kirki\App\Supports\Facades\Symbol;
14 use Kirki\Framework\Sanitizer;
15 use Kirki\Framework\Supports\Facades\File;
16
17 use function Kirki\App\is_truthy;
18
19 class Template
20 {
21 /**
22 * @param string|string[] $name
23 * @param string|null $prefix
24 *
25 * @return string|string[]
26 */
27 public static function add_prefix_to_class_name($name, $prefix = null)
28 {
29
30 if (is_array($name)) {
31 foreach ($name as $key => $class_name) {
32 $name[$key] = static::add_prefix_to_class_name($class_name, $prefix);
33 }
34
35 return $name;
36 }
37
38 $name = strtolower($name);
39
40 if (!in_array($name, KIRKI_PRESERVED_CLASS_LIST)) {
41 $name = $prefix ? strtolower($prefix) . '-' . $name : $name;
42 }
43
44 return $name;
45 }
46
47 /**
48 * Assign utility page template
49 *
50 * @param int $page_id
51 * @param string $utility_page_type
52 *
53 * @return bool
54 */
55 public static function assign_utility_page_template(int $page_id, string $utility_page_type) {
56 if (in_array($utility_page_type, UtilityPageType::get_constant_values(), true)) {
57 $remote_url = KIRKI_PUBLIC_ASSETS_URL . '/pre-built-pages/basic/' . $utility_page_type . '.zip';
58 return static::process_template($page_id, $remote_url);
59 }
60
61 return false;
62 }
63
64 /**
65 * Assign custom page template
66 *
67 * @param int $page_id
68 * @param string $template_url
69 *
70 * @return bool
71 */
72 public static function assign_custom_page_template(int $page_id, string $template_url) {
73 return static::process_template($page_id, $template_url);
74 }
75
76 /**
77 * Process kirki template zip
78 *
79 * @param int $page_id
80 * @param string $remote_url
81 *
82 * @return bool
83 */
84 protected static function process_template(int $page_id, string $remote_url)
85 {
86 $file_name_new = uniqid('', true) . '.zip'; // 'random.ext'
87 $zip_file_path = FileHandler::download_zip_from_remote($remote_url, $file_name_new);
88
89 if ($zip_file_path) {
90 $json_data = static::save_kirki_template_from_zip($page_id, $zip_file_path);
91
92 if (!empty($json_data)) {
93 // delete zip file
94 File::delete($zip_file_path);
95 return true;
96 }
97 }
98
99 return false;
100 }
101
102 /**
103 * Process kirki template zip
104 *
105 * @param int $page_id
106 * @param string $zip_path
107 * @return bool|array
108 */
109 protected static function save_kirki_template_from_zip(int $page_id, string $zip_path)
110 {
111 if ($page_id === 0) {
112 return false;
113 }
114
115 $kirki_json_data = static::get_kirki_template_from_zip($zip_path);
116
117 $is_include_media = true;
118 $should_process_symbols = true;
119 $kirki_json_data = static::process_template_from_json(
120 $kirki_json_data,
121 !$is_include_media,
122 !$should_process_symbols
123 );
124
125 if (!is_truthy($kirki_json_data)) {
126 return false;
127 }
128
129 $kirki_json_data['blocks']['root'] = [
130 'accept' => '*',
131 'children' => ['body'],
132 'id' => 'root',
133 'name' => 'root',
134 'styleIds' => [],
135 'title' => 'Root',
136 ];
137
138 foreach ($kirki_json_data['styles'] as $key => $style) {
139 $style['name'] = static::add_prefix_to_class_name($style['name'], 'post-' . $page_id);
140 unset($style['isGlobal']);
141 unset($style['isDefault']);
142 $kirki_json_data['styles'][$key] = $style;
143 }
144
145 $payload = EditorPagePayloadDTO::from_array([
146 'page' => PageModel::find($page_id),
147 'data' => $kirki_json_data
148 ]);
149
150 PageService::create()->save_page_data($payload);
151 }
152
153 /**
154 * Process kirki template zip
155 *
156 * @param string $zip_path
157 * @return false|string
158 */
159 protected static function get_kirki_template_from_zip(string $zip_path)
160 {
161 $temp_folder_path = FileHandler::get_temp_folder_path();
162
163 $result = FileHandler::extract_zip_file($zip_path, $temp_folder_path);
164
165 if ($result === false) {
166 File::delete($temp_folder_path);
167 return false;
168 }
169
170 $kirki_json_file = $temp_folder_path . '/kirki-data.json';
171
172 if (File::missing($kirki_json_file)) {
173 File::delete($temp_folder_path);
174
175 return false;
176 }
177
178 $kirki_json_data = File::get($kirki_json_file);
179
180 // delete temp folder
181 File::delete($temp_folder_path);
182
183 if (empty($kirki_json_data)) {
184 return false;
185 }
186
187 return $kirki_json_data;
188 }
189
190 /**
191 * Process kirki template zip
192 *
193 * @param string $kirki_json_data
194 * @param boolean $is_include_media
195 * @param boolean $should_process_symbols
196 *
197 * @return array
198 */
199 protected static function process_template_from_json(string $kirki_json_data, bool $is_include_media = false, bool $should_process_symbols = true)
200 {
201 $kirki_json_data = json_decode($kirki_json_data, true);
202
203 $asset_urls = $kirki_json_data['asset_urls'] ?? [];
204 $blocks = $kirki_json_data['blocks'] ?? [];
205 $symbols = $kirki_json_data['symbols'] ?? [];
206
207 if ($is_include_media) {
208 $uploaded_attachment_ids = static::attach_assets_from_zip($asset_urls);
209 $assets_urls_map = [];
210
211 if (!empty($uploaded_attachment_ids)) {
212 $uploaded_attachment_urls = PostModel::query()
213 ->where_in('ID', array_filter(array_values($uploaded_attachment_ids)))
214 ->get(['ID', 'guid'])
215 ->pluck('guid', 'ID')
216 ->to_array();
217
218 foreach ($asset_urls as $key => $asset_item) {
219 $url = $asset_item['url'];
220 $assets_urls_map[$asset_item['id']] = $asset_item;
221
222 if (!isset($uploaded_attachment_ids[$url])) {
223 $asset_urls[$key] = array_merge($asset_item, [
224 'url' => null,
225 'attachment_id' => 0,
226 'index' => isset($asset_item['index']) ? $asset_item['index'] : null,
227 'thumbnail' => isset($asset_item['thumbnail']) ? $asset_item['thumbnail'] : false,
228 ]);
229
230 continue;
231 }
232
233 $attachment_id = $uploaded_attachment_ids[$url] ?? 0;
234 $attachment_url = $uploaded_attachment_urls[$attachment_id] ?? null;
235
236 $asset_urls[$key] = array_merge($asset_item, [
237 'url' => $attachment_url,
238 'attachment_id' => $attachment_id,
239 'index' => isset($asset_item['index']) ? $asset_item['index'] : null,
240 'thumbnail' => isset($asset_item['thumbnail']) ? $asset_item['thumbnail'] : false,
241 ]);
242 }
243 }
244
245 // update blocks with new asset urls
246 foreach ($asset_urls as $key => $asset_item) {
247 if (
248 !isset($blocks[$asset_item['id']]['name'], $asset_item['name'])
249 || $blocks[$asset_item['id']]['name'] !== $asset_item['name']
250 ) {
251 continue;
252 }
253
254 switch($asset_item['name']) {
255 case 'image':
256 $blocks[$asset_item['id']]['properties']['attributes']['src'] = $asset_item['url'];
257 $blocks[$asset_item['id']]['properties']['wp_attachment_id'] = $asset_item['attachment_id'];
258
259 break;
260 case 'video':
261 if ($asset_item['thumbnail']) {
262 $blocks[$asset_item['id']]['properties']['thumbnail']['url'] = $asset_item['url'];
263 break;
264 }
265
266 $blocks[$asset_item['id']]['properties']['attributes']['src'] = $asset_item['url'];
267 break;
268 case 'lottie':
269 $blocks[$asset_item['id']]['properties']['lottie']['src'] = $asset_item['url'];
270 break;
271 case 'lightbox':
272 if ($asset_item['thumbnail']) {
273 $blocks[ $asset_item['id'] ]['properties']['lightbox']['thumbnail']['src'] = $asset_item['url'];
274 break;
275 }
276
277 $blocks[$asset_item['id']]['properties']['lightbox']['media'][$asset_item['index']]['sources']['original'] = $asset_item['url'];
278 break;
279 }
280 }
281
282 if ($should_process_symbols) {
283 // update symbols with new asset urls
284 foreach ($symbols as $sym_key => $symbol) {
285 foreach ($symbol['symbolData']['data'] as $key => $block) {
286 $block_id = $block['id'];
287
288 if (isset($assets_urls_map[$block_id])) {
289 switch($assets_urls_map[$block_id]['name']) {
290 case 'image':
291 $symbol['symbolData']['data'][$key]['attributes']['src'] = $assets_urls_map[$block_id]['url'];
292 $symbol['symbolData']['data'][$key]['wp_attachment_id'] = $assets_urls_map[$block_id]['attachment_id'];
293 break;
294 case 'video':
295 if ($assets_urls_map[$block_id]['thumbnail']) {
296 $symbol['symbolData']['data'][$key]['thumbnail']['url'] = $assets_urls_map[$block_id]['url'];
297 break;
298 }
299
300 $symbol['symbolData']['data'][$key]['attributes']['src'] = $assets_urls_map[$block_id]['url'];
301 break;
302 case 'lottie':
303 $symbol['symbolData']['data'][$key]['lottie']['src'] = $assets_urls_map[$block_id]['url'];
304 break;
305 case 'lightbox':
306 if ( $assets_urls_map[$block_id]['thumbnail'] ) {
307 $symbol['symbolData']['data'][$key]['lightbox']['thumbnail']['src'] = $assets_urls_map[$block_id]['url'];
308 break;
309 }
310
311 $symbol['symbolData']['data'][$key]['lightbox']['media'][$assets_urls_map[$block_id]['index']]['sources']['original'] = $assets_urls_map[$block_id]['url'];
312 break;
313
314 }
315 }
316 }
317
318 $symbols[$sym_key]['symbolData']['data'] = $symbol['symbolData']['data'];
319 }
320 }
321 }
322
323 $saved_symbols_tracker = [];
324
325 if ($should_process_symbols && is_truthy($symbols)) {
326 foreach ($symbols as $symbol) {
327 $symbol_id = $symbol['id'];
328 $symbol_element_id = $symbol['elementId'];
329
330 // Check if the symbol is already saved
331 if (!isset($saved_symbols_tracker[$symbol_id])) {
332 // Save the symbol to the database
333 $saved_symbol = Symbol::save(SymbolDTO::from_array($symbol));
334
335 // Add the saved symbol to the tracker
336 if ($saved_symbol) {
337 $saved_symbols_tracker[$symbol_id] = $saved_symbol->id ?? null;
338 }
339 }
340
341 // Update all relevant elements with the symbol's ID
342 if (
343 isset($blocks[$symbol_element_id], $saved_symbols_tracker[$symbol_id])
344 && $blocks[$symbol_element_id]['name'] === 'symbol'
345 ) {
346 $blocks[$symbol_element_id]['properties']['symbolId'] = $saved_symbols_tracker[$symbol_id];
347 }
348 }
349 }
350
351 // remove asset_urls
352 unset($kirki_json_data['asset_urls']);
353
354 $kirki_json_data['blocks'] = $blocks;
355 $kirki_json_data['symbols'] = $symbols;
356
357 return $kirki_json_data;
358 }
359
360 protected static function attach_assets_from_zip(array $asset_urls)
361 {
362 $uploaded_attachment_ids = [];
363
364 foreach ($asset_urls as $asset_item) {
365 $url = $asset_item['url'];
366
367 if (isset($uploaded_attachment_ids[$url]) && !empty($uploaded_attachment_ids[$url])) {
368 continue;
369 }
370
371 $attachment_id = null;
372 $asset_name = basename($asset_item['url']);
373 $temp_folder_path = FileHandler::get_temp_folder_path();
374 $source_file_path = $temp_folder_path . '/' . Sanitizer::apply_rule($asset_name, Sanitizer::FILE_NAME);
375
376 if (File::exists($source_file_path)) {
377 $file_name = basename($source_file_path);
378
379 // Upload the file
380 $_FILES['file'] = [
381 'name' => Sanitizer::apply_rule($file_name, Sanitizer::FILE_NAME),
382 'tmp_name' => $source_file_path,
383 ];
384
385 if (!function_exists('media_handle_upload')) {
386 require_once ABSPATH . 'wp-admin/includes/image.php';
387 require_once ABSPATH . 'wp-admin/includes/media.php';
388 }
389
390 $attachment_id = media_handle_upload('file', 0, [], [
391 'test_form' => false,
392 'action' => 'upload-attachment',
393 ]
394 );
395
396 // Check if the upload was successful
397 if (is_wp_error($attachment_id)) {
398 $attachment_id = null;
399 }
400 }
401
402 $uploaded_attachment_ids[$url] = $attachment_id ? (int) $attachment_id : null;
403 }
404
405 return $uploaded_attachment_ids;
406 }
407 }