• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rtCamp / snapwp-helper / 13504100917

24 Feb 2025 05:30PM UTC coverage: 83.585% (+0.2%) from 83.424%
13504100917

Pull #89

github

web-flow
Merge 83e7d05b8 into 8e49111f1
Pull Request #89: Fix : `templateByUri.editorBlocks` to respect `flat: false`

1548 of 1852 relevant lines covered (83.59%)

13.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.56
/src/Modules/GraphQL/Model/RenderedTemplate.php
1
<?php
2
/**
3
 * RenderedTemplate Model class
4
 *
5
 * @package SnapWP\Helper\Modules\GraphQL\Model
6
 */
7

8
namespace SnapWP\Helper\Modules\GraphQL\Model;
9

10
use GraphQLRelay\Relay;
11
use SnapWP\Helper\Modules\GraphQL\Data\ContentBlocksResolver;
12
use SnapWP\Helper\Modules\GraphQL\Utils\ScriptModuleUtils;
13
use WPGraphQL\Model\Model;
14

15
/**
16
 * Class - RenderedTemplate
17
 *
18
 * @property string $id The ID of the block template.
19
 * @property ?string $content The content of the block template.
20
 * @property ?string $renderedHtml The rendered HTML of the block template.
21
 * @property ?string $uri The URI of the block template.
22
 * @property array<mixed> $enqueuedScriptsQueue The queue of enqueued scripts.
23
 * @property array<mixed> $enqueuedStylesheetsQueue The queue of enqueued stylesheets.
24
 */
25
class RenderedTemplate extends Model {
26
        /**
27
         * {@inheritDoc}
28
         *
29
         * @var array{uri:string,content:?string}
30
         */
31
        protected $data;
32

33
        /**
34
         * Store parsed blocks.
35
         *
36
         * @var array<mixed>
37
         */
38
        public $parsed_blocks;
39

40
        /**
41
         * Constructor.
42
         *
43
         * @param array<mixed> $resolved_template_data The resolved template data.
44
         *
45
         * @throws \InvalidArgumentException If the required keys are not present in the resolved template data.
46
         */
47
        public function __construct( array $resolved_template_data ) {
31✔
48
                // translators: %s: array key name.
49
                $error_message = __( 'The %s key is required to resolve the RenderedTemplate GraphQL model.', 'snapwp-helper' );
31✔
50

51
                if ( ! isset( $resolved_template_data['uri'] ) ) {
31✔
52
                        throw new \InvalidArgumentException( esc_html( sprintf( $error_message, 'uri' ) ) );
×
53
                }
54

55
                if ( ! isset( $resolved_template_data['content'] ) ) {
31✔
56
                        throw new \InvalidArgumentException( esc_html( sprintf( $error_message, 'content' ) ) );
×
57
                }
58

59
                $this->data = $resolved_template_data;
31✔
60

61
                // Resolve the content blocks early, so everything is ready when the hooks are called.
62
                $this->parsed_blocks = $this->resolve_content_blocks();
31✔
63

64
                parent::__construct();
31✔
65
        }
66

67
        /**
68
         * {@inheritDoc}
69
         */
70
        public function setup() {
31✔
71

72
                // Simulate WP template rendering.
73
                ob_start();
31✔
74
                wp_head();
31✔
75
                wp_footer();
31✔
76
                ob_end_clean();
31✔
77
        }
78

79
        /**
80
         * Initializes the object
81
         *
82
         * @return void
83
         */
84
        protected function init() {
31✔
85
                if ( empty( $this->fields ) ) {
31✔
86
                        $this->fields = [
31✔
87
                                'id'                         => function (): string {
31✔
88
                                        return Relay::toGlobalId( 'rendered-template', $this->data['uri'] );
1✔
89
                                },
31✔
90
                                'bodyClasses'                => static function (): ?array {
31✔
91
                                        $body_classes = get_body_class();
19✔
92
                                        return ! empty( $body_classes ) ? $body_classes : null;
19✔
93
                                },
31✔
94
                                'content'                    => fn (): ?string => ! empty( $this->data['content'] ) ? $this->data['content'] : null,
31✔
95
                                'enqueuedScriptsQueue'       => function () {
31✔
96
                                        global $wp_scripts;
4✔
97

98
                                        // Get the list of enqueued scripts.
99
                                        $enqueued_scripts = $wp_scripts->queue ?? [];
4✔
100

101
                                        $queue = $this->flatten_enqueued_assets_list( $enqueued_scripts, $wp_scripts );
4✔
102

103
                                        // Reset the scripts queue to avoid conflicts with other queries.
104
                                        $wp_scripts->reset();
4✔
105
                                        $wp_scripts->queue = [];
4✔
106

107
                                        return $queue;
4✔
108
                                },
31✔
109
                                'enqueuedScriptModulesQueue' => static function () {
31✔
110
                                        // Simulate WP template rendering.
111
                                        $script_modules = ScriptModuleUtils::get_enqueued_script_modules();
3✔
112

113
                                        if ( empty( $script_modules ) ) {
3✔
114
                                                return [];
×
115
                                        }
116

117
                                        $queue = [];
3✔
118

119
                                        foreach ( $script_modules as $module ) {
3✔
120
                                                // Sanitize the module ID into a valid WordPress handle.
121
                                                $handle = $module['id'];
3✔
122
                                                if ( ! in_array( $handle, $queue, true ) ) {
3✔
123
                                                        $queue[] = $handle;
3✔
124
                                                }
125
                                        }
126

127
                                        return $queue;
3✔
128
                                },
31✔
129
                                'enqueuedStylesheetsQueue'   => function () {
31✔
130
                                        global $wp_styles;
4✔
131

132
                                        // Get the list of enqueued styles.
133
                                        $enqueued_styles = $wp_styles->queue ?? [];
4✔
134

135
                                        // Use the existing flatten_enqueued_assets_list method.
136
                                        $queue = $this->flatten_enqueued_assets_list( $enqueued_styles, $wp_styles );
4✔
137

138
                                        // Reset the styles queue to avoid conflicts with other queries.
139
                                        $wp_styles->reset();
4✔
140
                                        $wp_styles->queue = [];
4✔
141

142
                                        return $queue;
4✔
143
                                },
31✔
144
                                'uri'                        => fn (): ?string => ! empty( $this->data['uri'] ) ? $this->data['uri'] : null,
31✔
145
                        ];
31✔
146
                }
147
        }
148

149
        /**
150
         * Resolves the content blocks.
151
         *
152
         * We use this instead of ::resolve_content_blocks() directly to ensure the global state is set correctly.
153
         *
154
         * @return array<mixed> The resolved content blocks.
155
         */
156
        protected function resolve_content_blocks() {
31✔
157
                global $_wp_current_template_id, $wp_query;
31✔
158

159
                $blocks = [];
31✔
160

161
                /**
162
                 * Work around template files that don't enter the loop.
163
                 *
164
                 * @see get_the_block_template_html()
165
                 */
166
                if (
167
                        $_wp_current_template_id &&
31✔
168
                        str_starts_with( $_wp_current_template_id, get_stylesheet() . '//' ) &&
31✔
169
                        is_singular() &&
31✔
170
                        1 === $wp_query->post_count &&
31✔
171
                        have_posts()
31✔
172
                ) {
173
                        while ( have_posts() ) {
17✔
174
                                the_post();
17✔
175
                                $blocks = ContentBlocksResolver::resolve_content_blocks(
17✔
176
                                        $this->data,
17✔
177
                                        [
17✔
178
                                                'flat' => false,
17✔
179
                                        ]
17✔
180
                                );
17✔
181
                        }
182
                } else {
183
                        $blocks = ContentBlocksResolver::resolve_content_blocks(
18✔
184
                                $this->data,
18✔
185
                                [
18✔
186
                                        'flat' => false,
18✔
187
                                ]
18✔
188
                        );
18✔
189
                }
190

191
                return $blocks;
31✔
192
        }
193

194
        /**
195
         * Get the handles of all scripts enqueued for a given content node.
196
         *
197
         * @param array<string,string> $queue            List of scripts for a given content node.
198
         * @param \WP_Dependencies     $wp_dependencies  A Global assets object.
199
         *
200
         * @return array<string>
201
         */
202
        protected function flatten_enqueued_assets_list( array $queue, \WP_Dependencies $wp_dependencies ): array {
8✔
203
                $registered_assets = $wp_dependencies->registered;
8✔
204
                $handles           = [];
8✔
205

206
                foreach ( $queue as $handle ) {
8✔
207

208
                        // If the script is not registered, skip to the next iteration.
209
                        if ( empty( $registered_assets[ $handle ] ) ) {
8✔
210
                                continue;
×
211
                        }
212

213
                        // Retrieve the registered script object from the queue.
214
                        /** @var \_WP_Dependency $script */
215
                        $script = $registered_assets[ $handle ];
8✔
216

217
                        // Add the script handle to the list of handles.
218
                        $handles[] = $script->handle;
8✔
219

220
                        // Recursively get the dependencies of the current script.
221
                        $dependencies = self::flatten_enqueued_assets_list( $script->deps, $wp_dependencies );
8✔
222
                        if ( empty( $dependencies ) ) {
8✔
223
                                continue;
8✔
224
                        }
225

226
                        array_unshift( $handles, ...$dependencies );
3✔
227
                }
228

229
                // Remove duplicates and re-index the array of handles before returning it.
230
                return array_values( array_unique( $handles ) );
8✔
231
        }
232
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc