Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 69
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
WPCOM_JSON_API_Render_Endpoint
0.00% covered (danger)
0.00%
0 / 67
0.00% covered (danger)
0.00%
0 / 5
420
0.00% covered (danger)
0.00%
0 / 1
 process_render
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
6
 add_assets
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
182
 get_version
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 do_shortcode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 do_embed
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
1<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3if ( ! defined( 'ABSPATH' ) ) {
4    exit( 0 );
5}
6
7/**
8 * These are helpers for the shortcode and embed render endpoints.
9 */
10abstract class WPCOM_JSON_API_Render_Endpoint extends WPCOM_JSON_API_Endpoint {
11    /**
12     * Figure out what scripts and styles to load.
13     * props to o2's o2_Read_API::poll() function for inspiration.
14     *
15     * In short we figure out what scripts load for a "normal" page load by executing wp_head and wp_footer
16     * then we render the embed/shortcode (to both get our result, and to have the shortcode files enqueue their resources)
17     * then we load wp_head and wp_footer again to see what new resources were added
18     * finally we find out the url to the source file and any extra info (like media or init js)
19     *
20     * @param mixed $callback - the function callback.
21     * @param mixed $callback_arg - the callback arguments.
22     *
23     * @return array
24     */
25    public function process_render( $callback, $callback_arg ) {
26        global $wp_scripts, $wp_styles;
27
28        if ( false === defined( 'STYLESHEETPATH' ) ) {
29            wp_templating_constants();
30        }
31
32        // initial scripts & styles (to subtract)
33        ob_start();
34        wp_head();
35        wp_footer();
36        ob_end_clean();
37        $initial_scripts = $wp_scripts->done;
38        $initial_styles  = $wp_styles->done;
39
40        // actually render the shortcode, get the result, and do the resource loading again so we can subtract..
41        ob_start();
42        wp_head();
43        ob_end_clean();
44        $result = call_user_func( $callback, $callback_arg );
45        ob_start();
46        wp_footer();
47        ob_end_clean();
48
49        // find the difference (the new resource files)
50        $loaded_scripts = array_diff( $wp_scripts->done, $initial_scripts );
51        $loaded_styles  = array_diff( $wp_styles->done, $initial_styles );
52        return array(
53            'result'         => $result,
54            'loaded_scripts' => $loaded_scripts,
55            'loaded_styles'  => $loaded_styles,
56        );
57    }
58
59    /**
60     * Takes the list of styles and scripts and adds them to the JSON response.
61     *
62     * @param array $return - what was returned.
63     * @param array $loaded_scripts - the loaded scripts.
64     * @param array $loaded_styles - the loaded styles.
65     *
66     * @return array
67     */
68    public function add_assets( $return, $loaded_scripts, $loaded_styles ) {
69        global $wp_scripts, $wp_styles;
70        // scripts first, just cuz
71        if ( $loaded_scripts !== array() ) {
72            $scripts = array();
73            foreach ( $loaded_scripts as $handle ) {
74                if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
75                    continue;
76                }
77
78                $src = $wp_scripts->registered[ $handle ]->src;
79
80                // attach version and an extra query parameters
81                $ver = $this->get_version( $wp_scripts->registered[ $handle ]->ver, $wp_scripts->default_version );
82                if ( isset( $wp_scripts->args[ $handle ] ) ) {
83                    $ver = $ver ? $ver . '&amp;' . $wp_scripts->args[ $handle ] : $wp_scripts->args[ $handle ];
84                }
85                $src = add_query_arg( 'ver', $ver, $src );
86
87                // add to an aray so we can return all this info
88                $scripts[ $handle ] = array(
89                    'src' => $src,
90                );
91                $extra              = $wp_scripts->print_extra_script( $handle, false );
92                if ( ! empty( $extra ) ) {
93                    $scripts[ $handle ]['extra'] = $extra;
94                }
95            }
96            $return['scripts'] = $scripts;
97        }
98        // now styles
99        if ( $loaded_styles !== array() ) {
100            $styles = array();
101            foreach ( $loaded_styles as $handle ) {
102                if ( ! isset( $wp_styles->registered[ $handle ] ) ) {
103                    continue;
104                }
105
106                $src = $wp_styles->registered[ $handle ]->src;
107
108                // attach version and an extra query parameters
109                $ver = $this->get_version( $wp_styles->registered[ $handle ]->ver, $wp_styles->default_version );
110                if ( isset( $wp_styles->args[ $handle ] ) ) {
111                    $ver = $ver ? $ver . '&amp;' . $wp_styles->args[ $handle ] : $wp_styles->args[ $handle ];
112                }
113                $src = add_query_arg( 'ver', $ver, $src );
114
115                // is there a special media (print, screen, etc) for this? if not, default to 'all'
116                $media = 'all';
117                if ( isset( $wp_styles->registered[ $handle ]->args ) ) {
118                    $media = esc_attr( $wp_styles->registered[ $handle ]->args );
119                }
120
121                // add to an array so we can return all this info
122                $styles[ $handle ] = array(
123                    'src'   => $src,
124                    'media' => $media,
125                );
126            }
127
128            $return['styles'] = $styles;
129        }
130
131        return $return;
132    }
133
134    /**
135     * Returns the 'version' string set by the shortcode so different versions of scripts/styles can be loaded.
136     *
137     * @param string $this_scripts_version - this scripts version.
138     * @param string $default_version - the default version.
139     *
140     * @return string
141     */
142    public function get_version( $this_scripts_version, $default_version ) {
143        if ( null === $this_scripts_version ) {
144            $ver = '';
145        } else {
146            $ver = $this_scripts_version ? $this_scripts_version : $default_version;
147        }
148        return $ver;
149    }
150
151    /**
152     * Given a shortcode, process and return the result.
153     *
154     * @param string $shortcode - the shortcode.
155     */
156    public function do_shortcode( $shortcode ) {
157        return do_shortcode( $shortcode );
158    }
159
160    /**
161     * Given a one-line embed URL, process and return the result.
162     *
163     * @param string $embed_url - the embed URL.
164     *
165     * @return string|false
166     */
167    public function do_embed( $embed_url ) {
168        global $wp_embed;
169        return $wp_embed->shortcode( array(), $embed_url );
170    }
171}