AppsService.php
2 weeks ago
CollaborationCommentService.php
1 month ago
CollaborationService.php
1 week ago
CollectionItemService.php
1 month ago
CollectionService.php
1 week ago
ContentManagerTemplateBinder.php
1 week ago
ContentManagerTemplateService.php
1 week ago
EditorService.php
1 month ago
FontService.php
2 weeks ago
FormSubmissionService.php
1 week ago
GlobalDataService.php
2 weeks ago
MediaService.php
1 month ago
PageService.php
1 week ago
PageSettingsService.php
1 month ago
PostService.php
1 week ago
UtilityPageService.php
1 week ago
ContentManagerTemplateService.php
109 lines
| 1 | <?php |
| 2 | |
| 3 | namespace Kirki\App\Services; |
| 4 | |
| 5 | defined('ABSPATH') || exit; |
| 6 | |
| 7 | use Exception; |
| 8 | use Kirki\App\Constants\PageMetaKeys; |
| 9 | use Kirki\App\Models\PostMeta; |
| 10 | use Kirki\App\Supports\Template; |
| 11 | |
| 12 | use function Kirki\Framework\with_prefix; |
| 13 | |
| 14 | /** |
| 15 | * Initializes Content Manager index/details pages entirely on the backend. |
| 16 | */ |
| 17 | class ContentManagerTemplateService |
| 18 | { |
| 19 | /** Dedicated index layouts fall back to the shared generic asset. */ |
| 20 | protected const INDEX_TEMPLATES = [ |
| 21 | 'recipes' => 'recipe-index.json', |
| 22 | 'team-members' => 'team-member-index.json', |
| 23 | 'projects' => 'project-index.json', |
| 24 | 'portfolio' => 'portfolio-index.json', |
| 25 | 'jobs' => 'job-index.json', |
| 26 | 'default' => 'index.json', |
| 27 | ]; |
| 28 | |
| 29 | /** Dedicated details layouts can be added without changing binding logic. */ |
| 30 | protected const DETAILS_TEMPLATES = [ |
| 31 | 'jobs' => 'job-details.json', |
| 32 | 'portfolio' => 'portfolio-details.json', |
| 33 | 'projects' => 'project-details.json', |
| 34 | 'recipes' => 'recipe-details.json', |
| 35 | 'team-members' => 'team-member-details.json', |
| 36 | 'default' => 'article-details.json', |
| 37 | ]; |
| 38 | |
| 39 | /** |
| 40 | * Generate and persist complete Kirki page data. |
| 41 | * |
| 42 | * @param int $page_id Page/template ID being initialized. |
| 43 | * @param int $collection_id Content Manager collection ID. |
| 44 | * @param string $page_kind Either index or details. |
| 45 | * @return void |
| 46 | * @throws Exception When the collection or page kind is invalid. |
| 47 | */ |
| 48 | public function initialize(int $page_id, int $collection_id, string $page_kind) |
| 49 | { |
| 50 | if (!in_array($page_kind, ['index', 'details'], true)) { |
| 51 | throw new Exception(esc_html__('Invalid Content Manager page kind.', 'kirki')); |
| 52 | } |
| 53 | |
| 54 | $collection = (new CollectionService())->get_single($collection_id); |
| 55 | if (empty($collection)) { |
| 56 | throw new Exception(esc_html__('Content Manager collection not found.', 'kirki')); |
| 57 | } |
| 58 | |
| 59 | $binder = new ContentManagerTemplateBinder(); |
| 60 | $preset_type = $binder->resolve_preset_type($collection); |
| 61 | |
| 62 | if (!$collection->preset_type && $preset_type !== 'generic') { |
| 63 | $fields = is_array($collection->fields->meta_value ?? null) ? $collection->fields->meta_value : []; |
| 64 | foreach ($fields as $key => $field) { |
| 65 | if (empty($field['templateKey'])) { |
| 66 | $fields[$key]['templateKey'] = $binder->normalize_key($field['title'] ?? ''); |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | PostMeta::update_meta_value($collection_id, with_prefix('cm_fields'), $fields); |
| 71 | PostMeta::update_meta_value($collection_id, with_prefix('cm_preset_type'), $preset_type); |
| 72 | $collection = (new CollectionService())->get_single($collection_id); |
| 73 | } |
| 74 | |
| 75 | $template = $this->load_template($page_kind, $preset_type); |
| 76 | $page_data = $binder->bind($template, $collection, [ |
| 77 | 'preset_type' => $preset_type, |
| 78 | 'page_kind' => $page_kind, |
| 79 | ]); |
| 80 | if (!Template::save_template_data($page_id, $page_data)) { |
| 81 | throw new Exception(esc_html__('Content Manager page template could not be saved.', 'kirki')); |
| 82 | } |
| 83 | PostMeta::update_meta_value($page_id, PageMetaKeys::CONTENT_MANAGER_COLLECTION_ID, $collection_id); |
| 84 | PostMeta::update_meta_value($page_id, PageMetaKeys::CONTENT_MANAGER_PAGE_KIND, $page_kind); |
| 85 | } |
| 86 | |
| 87 | /** Load a normalized Kirki template asset from public storage. */ |
| 88 | protected function load_template(string $page_kind, string $preset_type) |
| 89 | { |
| 90 | $file_name = $page_kind === 'index' |
| 91 | ? (static::INDEX_TEMPLATES[$preset_type] ?? static::INDEX_TEMPLATES['default']) |
| 92 | : (static::DETAILS_TEMPLATES[$preset_type] ?? static::DETAILS_TEMPLATES['default']); |
| 93 | |
| 94 | $json_file = KIRKI_PUBLIC_ASSETS_URL . '/pre-built-pages/dynamic/' . $file_name; |
| 95 | $response = wp_remote_get($json_file, ['timeout' => 15]); |
| 96 | |
| 97 | if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) { |
| 98 | throw new Exception(esc_html__('Content Manager template asset was not found.', 'kirki')); |
| 99 | } |
| 100 | |
| 101 | $template = json_decode((string) wp_remote_retrieve_body($response), true); |
| 102 | if (!is_array($template) || empty($template['blocks']) || !isset($template['styles'])) { |
| 103 | throw new Exception(esc_html__('Content Manager template asset is invalid.', 'kirki')); |
| 104 | } |
| 105 | |
| 106 | return $template; |
| 107 | } |
| 108 | } |
| 109 |