PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.2
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.2
4.9.2 4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 All 200 releases
← All changes | includes/Utils/Enqueue.php +126 -66 3.4.04.9.2 View file →
@@ -1,85 +1,145 @@
1 1 <?php
2 2 namespace WPDeveloper\BetterDocs\Utils;
3 3
4 4 class Enqueue extends Base {
5 - private $plugin_url;
6 - private $plugin_path;
7 - private $version;
5 + private $plugin_url;
6 + private $plugin_path;
7 + private $version;
8 8
9 - public function __construct( $plugin_url, $plugin_path, $version ) {
10 - $this->plugin_url = $plugin_url;
11 - $this->plugin_path = $plugin_path;
12 - $this->version = $version;
13 - }
9 + public function __construct( $plugin_url, $plugin_path, $version ) {
10 + $this->plugin_url = $plugin_url;
11 + $this->plugin_path = $plugin_path;
12 + $this->version = $version;
13 + }
14 14
15 - public function enqueue( $handle, $filename, $dependencies = [], $args = null ) {
16 - $config = $this->asset_config( $filename, $dependencies, $args );
17 - $this->call_wp_func( 'wp_enqueue', $handle, $config );
18 - }
15 + public function enqueue( $handle, $filename, $dependencies = [], $args = null ) {
16 + $config = $this->asset_config( $filename, $dependencies, $args );
17 + $this->call_wp_func( 'wp_enqueue', $handle, $config );
18 + }
19 19
20 - public function register( $handle, $filename, $dependencies = [], $args = null ) {
21 - $config = $this->asset_config( $filename, $dependencies, $args );
22 - $this->call_wp_func( 'wp_register', $handle, $config );
23 - }
20 + public function register( $handle, $filename, $dependencies = [], $args = null ) {
21 + $config = $this->asset_config( $filename, $dependencies, $args );
22 + $this->call_wp_func( 'wp_register', $handle, $config );
23 + }
24 24
25 - public function localize( $handle, $name, $args ) {
26 - wp_localize_script( $handle, $name, $args );
27 - }
25 + public function localize( $handle, $name, $args ) {
26 + wp_localize_script( $handle, $name, $args );
27 + }
28 28
29 - private function call_wp_func( $action, $handle, $config ) {
30 - call_user_func(
31 - $action . '_' . $config['type'],
32 - $handle,
33 - $config['url'],
34 - $config['dependencies'],
35 - $config['version'],
36 - $config['args']
37 - );
29 + private function call_wp_func( $action, $handle, $config ) {
30 + call_user_func(
31 + $action . '_' . $config['type'],
32 + $handle,
33 + $config['url'],
34 + $config['dependencies'],
35 + $config['version'],
36 + $config['args']
37 + );
38 38
39 - // if ( 'script' === $config['type'] && in_array( 'wp-i18n', $config['dependencies'], true ) ) {
40 - // wp_set_script_translations( $handle, 'betterdocs' );
41 - // }
42 - }
39 + if ( 'script' === $config['type'] && in_array( 'wp-i18n', $config['dependencies'], true ) ) {
40 + $url = isset( $config['url'] ) ? $config['url'] : '';
41 + preg_match( '~/plugins/([^/]+)~', $url, $matches );
42 + $url_portion = isset( $matches[1] ) ? $matches[1] : '';
43 + if ( $url_portion == 'betterdocs-pro' ) {
44 + wp_set_script_translations( $handle, 'betterdocs-pro' );
45 + } elseif ( $url_portion == 'betterdocs-ai-chatbot' ) {
46 + wp_set_script_translations( $handle, 'betterdocs-ai-chatbot' );
47 + } elseif ( $url_portion == 'betterdocs' ) {
48 + wp_set_script_translations( $handle, 'betterdocs' );
49 + }
50 + }
51 + }
43 52
44 - public function asset_config( $filename, $dependencies = [], $args = null ) {
45 - $is_js = preg_match( '/\.js$/', $filename );
46 - $basename = preg_replace( '/\.\w+$/', '', $filename );
47 - $url = $this->asset_url( $filename );
48 - $version = $this->version;
49 - $asset_config_path = $this->dist_path( $basename . '.asset.php' );
53 + public function asset_config( $filename, $dependencies = [], $args = null ) {
54 + $is_js = preg_match( '/\.js$/', $filename );
55 + $basename = preg_replace( '/\.\w+$/', '', $filename );
56 + $url = $this->asset_url( $filename );
57 + $version = $this->version;
58 + $asset_config_path = $this->dist_path( $basename . '.asset.php' );
50 59
51 - if ( file_exists( $asset_config_path ) ) {
52 - $asset_config = require $asset_config_path;
60 + if ( file_exists( $asset_config_path ) ) {
61 + $asset_config = require $asset_config_path;
53 62
54 - if ( $is_js ) {
55 - $dependencies = array_unique( array_merge( $asset_config['dependencies'], $dependencies ) );
56 - }
57 - $version = $asset_config['version'];
58 - }
63 + if ( $is_js ) {
64 + $dependencies = array_unique( array_merge( $asset_config['dependencies'], $dependencies ) );
65 + }
66 + $version = $asset_config['version'];
67 + } else {
68 + // webpack only emits `<name>.asset.php` (with its content hash) for JS
69 + // entries, so stylesheets used to fall through to the plugin version
70 + // and never cache-busted between builds — browsers kept serving a
71 + // stale CSS against freshly-changed markup. Fall back to the file's
72 + // mtime so any rebuilt asset gets a new URL.
73 + $asset_path = $this->dist_path( $filename );
59 74
60 - return [
61 - 'url' => $url,
62 - 'dependencies' => $dependencies,
63 - 'version' => $version,
64 - 'type' => $is_js ? 'script' : 'style',
65 - 'args' => null !== $args ? $args : ( $is_js ? true : 'all' )
66 - ];
67 - }
75 + if ( file_exists( $asset_path ) ) {
76 + $version = (string) filemtime( $asset_path );
77 + }
78 + }
68 79
69 - public function asset_url( $filename ) {
70 - if ( filter_var( $filename, FILTER_VALIDATE_URL ) ) {
71 - return $filename;
72 - }
80 + return [
81 + 'url' => $url,
82 + 'dependencies' => $dependencies,
83 + 'version' => $version,
84 + 'type' => $is_js ? 'script' : 'style',
85 + 'args' => null !== $args ? $args : ( $is_js ? true : 'all' )
86 + ];
87 + }
73 88
74 - return esc_url( $this->plugin_url . 'assets/' . $filename );
75 - }
89 + /**
90 + * Resolve the assets sub-folder for a file: webpack output lives under
91 + * assets/build/, committed static assets under assets/static/. Prefer the
92 + * build copy when present, otherwise fall back to static. This lets every
93 + * enqueue/register call use the same relative path regardless of which
94 + * folder the file ends up in.
95 + *
96 + * The final `assets/` fallback matters for the Free/Pro version skew this
97 + * class is shared across. Pro constructs this same Enqueue against its OWN
98 + * plugin path, so when Free 4.8.0 runs alongside a Pro that predates the
99 + * Node 24 restructure, Pro's files are still flat under assets/. Without
100 + * this branch every one of them resolved to a non-existent assets/static/
101 + * path and 404'd. Ordering is deliberate: a matched pair never reaches the
102 + * legacy branch, so this costs nothing in the normal case.
103 + *
104 + * Kept `protected` so a paired plugin can refine the search order.
105 + */
106 + protected function asset_base( $filename ) {
107 + foreach ( [ 'assets/build/', 'assets/static/', 'assets/' ] as $base ) {
108 + if ( file_exists( path_join( $this->plugin_path, $base . $filename ) ) ) {
109 + return $base;
110 + }
111 + }
76 112
77 - public function dist_path( $file ) {
78 - return path_join( $this->plugin_path, 'assets/' . $file );
79 - }
113 + // Nothing on disk — keep the historical default so a genuinely missing
114 + // file produces the same (broken) URL it always did, not a new shape.
115 + return 'assets/static/';
116 + }
80 117
81 - public function icon( $name, $is_admin = false ) {
82 - $_path = $is_admin ? 'assets/admin/images/' : 'assets/images/';
83 - return esc_url( $this->plugin_url . $_path . $name . '?v=' . $this->version );
84 - }
118 + public function asset_url( $filename ) {
119 + if ( filter_var( $filename, FILTER_VALIDATE_URL ) ) {
120 + return $filename;
121 + }
122 +
123 + return esc_url( $this->plugin_url . $this->asset_base( $filename ) . $filename );
124 + }
125 +
126 + /**
127 + * Explicit URL for a committed static asset under assets/static/.
128 + */
129 + public function static_url( $filename ) {
130 + if ( filter_var( $filename, FILTER_VALIDATE_URL ) ) {
131 + return $filename;
132 + }
133 +
134 + return esc_url( $this->plugin_url . 'assets/static/' . $filename );
135 + }
136 +
137 + public function dist_path( $file ) {
138 + return path_join( $this->plugin_path, $this->asset_base( $file ) . $file );
139 + }
140 +
141 + public function icon( $name, $is_admin = false ) {
142 + $_path = $is_admin ? 'assets/static/admin/images/' : 'assets/static/images/';
143 + return esc_url( $this->plugin_url . $_path . $name . '?v=' . $this->version );
144 + }
85 145 }