PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.1
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.1
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 3.5.2 All 199 releases
betterdocs / includes / Utils / Enqueue.php

Enqueue.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.9.1, at includes/Utils/Enqueue.php

146 lines 5.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace WPDeveloper\BetterDocs\Utils;
3
4 class Enqueue extends Base {
5 private $plugin_url;
6 private $plugin_path;
7 private $version;
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 }
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 }
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 }
24
25 public function localize( $handle, $name, $args ) {
26 wp_localize_script( $handle, $name, $args );
27 }
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 );
38
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 }
52
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' );
59
60 if ( file_exists( $asset_config_path ) ) {
61 $asset_config = require $asset_config_path;
62
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 );
74
75 if ( file_exists( $asset_path ) ) {
76 $version = (string) filemtime( $asset_path );
77 }
78 }
79
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 }
88
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 }
112
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 }
117
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 }
145 }
146