PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.8.0
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.8.0
3.8.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 All 112 releases
templately / modules / mcp-core / Support / DependencyGateResolver.php

DependencyGateResolver.php in Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! 3.8.0, at modules/mcp-core/Support/DependencyGateResolver.php

108 lines 3.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Import-time dependency gating (FR-003, spec.md Edge Cases, analyze finding
4 * G2): blocks an import before any changes are made when a required plugin
5 * dependency is not active on this site.
6 *
7 * @package Templately\Modules\McpCore\Support
8 */
9
10 namespace Templately\Modules\McpCore\Support;
11
12 use WP_Error;
13
14 class DependencyGateResolver {
15
16 /**
17 * @param int $template_id
18 * @param string $platform
19 * @return true|WP_Error True if the import may proceed; a WP_Error
20 * ('not_found' or 'dependency_required') otherwise.
21 */
22 public static function check( int $template_id, string $platform = 'elementor' ) {
23 $item = self::resolve_item( $template_id );
24
25 if ( is_wp_error( $item ) ) {
26 return $item;
27 }
28
29 if ( empty( $item ) || empty( $item['id'] ) ) {
30 return new WP_Error( 'not_found', __( 'Template not found.', 'templately' ) );
31 }
32
33 $dependencies = $item['dependencies'] ?? [];
34
35 if ( empty( $dependencies ) ) {
36 return true;
37 }
38
39 $checked = RestDispatcher::dispatch( 'POST', '/templately/v1/dependencies/check', [
40 'dependencies' => $dependencies,
41 'platform' => $platform,
42 ] );
43
44 if ( is_wp_error( $checked ) ) {
45 // Resolver failure should not itself block import — the real
46 // import call will still surface any genuine problem.
47 return true;
48 }
49
50 $data = $checked->get_data();
51 $unmet = array_values( array_filter( $data['dependencies'] ?? [], static function ( $dep ) {
52 $is_active = is_object( $dep ) ? ( $dep->is_active ?? null ) : ( $dep['is_active'] ?? null );
53 return empty( $is_active );
54 } ) );
55
56 if ( ! empty( $unmet ) ) {
57 return new WP_Error(
58 'dependency_required',
59 __( 'This template requires plugins that are not active on this site.', 'templately' ),
60 [ 'dependencies' => $unmet ]
61 );
62 }
63
64 return true;
65 }
66
67 /**
68 * Resolve a template's item detail regardless of which backend collection
69 * it lives in.
70 *
71 * `/items/{id}` scopes its GraphQL lookup by the `type` param, and each
72 * template type lives in a different collection: block/section templates in
73 * `items`, page templates in `pages`, packs in `packs`. Hardcoding a single
74 * `type` here silently 404s ("Item data not found") for every other type —
75 * that is why page-type templates failed the dependency gate before the
76 * import could run. Try each collection until one resolves.
77 *
78 * @param int $template_id
79 * @return array|WP_Error The item detail array, or the last WP_Error.
80 */
81 private static function resolve_item( int $template_id ) {
82 $last = null;
83
84 foreach ( [ 'items', 'pages', 'packs' ] as $type ) {
85 $detail = RestDispatcher::dispatch( 'GET', '/templately/v1/items/' . $template_id, [ 'type' => $type ] );
86
87 if ( is_wp_error( $detail ) ) {
88 $last = $detail;
89 continue;
90 }
91
92 $data = $detail->get_data();
93
94 if ( ! empty( $data['id'] ) ) {
95 return $data;
96 }
97
98 $last = $data;
99 }
100
101 if ( is_wp_error( $last ) ) {
102 return $last;
103 }
104
105 return new WP_Error( 'not_found', __( 'Template not found.', 'templately' ) );
106 }
107 }
108