PluginProbe
BetterLinks – Link Shortener, Link Cloaking, Redirects, Affiliate Link Manager & MCP / trunk
BetterLinks – Link Shortener, Link Cloaking, Redirects, Affiliate Link Manager & MCP vtrunk
3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 3.0.0 2.4.13 2.4.12 2.4.11 2.4.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 All 110 releases
betterlinks / includes / Admin / Assets.php

Assets.php in BetterLinks – Link Shortener, Link Cloaking, Redirects, Affiliate Link Manager & MCP trunk, at includes/Admin/Assets.php

218 lines 12.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace BetterLinks\Admin;
4 if ( ! defined( 'ABSPATH' ) ) { exit; }
5
6 use BetterLinks\Helper;
7
8 class Assets
9 {
10 public function __construct()
11 {
12 add_action('admin_enqueue_scripts', [$this, 'plugin_scripts']);
13 add_action('enqueue_block_editor_assets', [$this, 'block_editor_assets']);
14 add_filter( 'fluent_boards/asset_listed_slugs', function($approvedSlugs) {
15 return wp_parse_args( [ 'betterlinks-intflboards' ], $approvedSlugs );
16 });
17 }
18
19 /**
20 * Enqueue Files on Start Plugin
21 *
22 * @function plugin_script
23 */
24 public function plugin_scripts($hook)
25 {
26 if (\BetterLinks\Helper::plugin_page_hook_suffix($hook)) {
27 add_action(
28 'wp_print_scripts',
29 function () {
30 $isSkip = apply_filters('BetterLinks/Admin/skip_no_conflict', false);
31
32 if ($isSkip) {
33 return;
34 }
35
36 global $wp_scripts;
37 if (!$wp_scripts) {
38 return;
39 }
40
41 $pluginUrl = plugins_url();
42 foreach ($wp_scripts->queue as $script) {
43 $src = $wp_scripts->registered[$script]->src;
44 if (strpos($src, $pluginUrl) !== false && !strpos($src, BETTERLINKS_PLUGIN_SLUG) !== false) {
45 wp_dequeue_script($wp_scripts->registered[$script]->handle);
46 }
47 }
48 },
49 1
50 );
51 $dependencies = include_once BETTERLINKS_ASSETS_DIR_PATH . 'js/betterlinks.core.min.asset.php';
52 // Version the stylesheet from its own mtime, not from the JS bundle
53 // hash: a build that only changes SCSS leaves that hash untouched,
54 // so browsers kept serving stale CSS and style fixes looked like
55 // they had no effect.
56 $admin_style_path = BETTERLINKS_ASSETS_DIR_PATH . 'css/betterlinks.css';
57 $admin_style_ver = file_exists($admin_style_path) ? (string) filemtime($admin_style_path) : $dependencies['version'];
58 wp_enqueue_style('betterlinks-admin-style', BETTERLINKS_ASSETS_URI . 'css/betterlinks.css', [], $admin_style_ver, 'all');
59 wp_enqueue_script(
60 'betterlinks-admin-core',
61 BETTERLINKS_ASSETS_URI . 'js/betterlinks.core.min.js',
62 array_merge($dependencies['dependencies'], ['regenerator-runtime']),
63 $dependencies['version'],
64 true
65 );
66 global $betterlinks_settings;
67 $prefix = !empty($betterlinks_settings['prefix']) ? $betterlinks_settings['prefix'] : '';
68 wp_localize_script('betterlinks-admin-core', 'betterLinksGlobal', [
69 'betterlinks_nonce' => wp_create_nonce('betterlinks_admin_nonce'),
70 'nonce' => wp_create_nonce('wp_rest'),
71 'rest_url' => rest_url(),
72 'ajaxurl' => admin_url('admin-ajax.php'),
73 'namespace' => BETTERLINKS_PLUGIN_SLUG . '/v1/',
74 'plugin_root_url' => BETTERLINKS_PLUGIN_ROOT_URI,
75 'plugin_root_path' => BETTERLINKS_ROOT_DIR_PATH,
76 'site_url' => apply_filters('betterlinks/site_url', site_url()),
77 'route_path' => wp_parse_url(admin_url(), PHP_URL_PATH),
78 'exists_links_json' => BETTERLINKS_EXISTS_LINKS_JSON,
79 'exists_clicks_json' => BETTERLINKS_EXISTS_CLICKS_JSON,
80 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only page slug used to bootstrap admin assets, no state mutation.
81 'page' => isset($_GET['page']) ? sanitize_text_field(wp_unslash( $_GET['page'] )) : '',
82 'is_pro_enabled' => apply_filters('betterlinks/pro_enabled', false),
83 'prefix' => $prefix,
84 'betterlinkspro_version' => defined('BETTERLINKS_PRO_VERSION') ? BETTERLINKS_PRO_VERSION : null,
85 'is_extra_data_tracking_compatible' => apply_filters('betterlinks/is_extra_data_tracking_compatible', false),
86 'menu_notice' => defined('BETTERLINKS_MENU_NOTICE') ? BETTERLINKS_MENU_NOTICE : null,
87 'betterlinks_custom_domain_menu' => get_option( BETTERLINKS_CUSTOM_DOMAIN_MENU, 0 ),
88 'betterlinks_settings' => $betterlinks_settings,
89 // Quick Link Creation credential. No longer md5(AUTH_KEY): that was a
90 // site-wide secret with no user binding, no expiry and no way to
91 // revoke it from the plugin. This is a per-user, expiring,
92 // revocable token issued by \BetterLinks\CLEToken.
93 'betterlinks_auth' => \BetterLinks\Helper::get_cle_token_for_display(),
94 'betterlinks_cle_endpoint' => rest_url(BETTERLINKS_PLUGIN_SLUG . '/v1/quick-link'),
95 'betterlinks_date_format' => get_option( 'date_format' ),
96 'is_fbs_enabled' => defined('FLUENT_BOARDS'),
97 'betterlinks_quick_setup_step' => get_option( 'betterlinks_quick_setup_step', false ),
98 'migratable_plugins' => Helper::get_migratable_plugins(),
99 // Add user permission information for free version
100 'user_can_manage_options' => current_user_can('manage_options'),
101 // Term IDs that cannot be edited/deleted in the UI (Uncategorized + extensions).
102 'protected_term_ids' => array_values(array_map('intval', (array) apply_filters('betterlinks/protected_term_ids', array(1)))),
103 // Categories a feature owns but keeps off Manage Links. The links query
104 // already excludes them, but the board re-adds empty categories from the
105 // /terms payload, so the SPA needs the same list to stay consistent.
106 'dashboard_hidden_term_ids' => array_values(array_unique(array_filter(array_map('intval', (array) apply_filters('betterlinks/dashboard_hidden_term_ids', array(), (array) $betterlinks_settings))))),
107 // MCP connector bootstrap. `abilities_api_available` is what tells
108 // the MCP page whether the bundled runtime actually loaded — with
109 // it missing, a client connects and is offered no tools at all.
110 'mcp' => [
111 'abilities_api_available' => function_exists('wp_register_ability'),
112 'endpoint' => home_url('/betterlinks/mcp'),
113 ],
114 ]);
115
116 $menu_notice = get_option('betterlinks_menu_notice', 0);
117 if( defined( 'BETTERLINKS_MENU_NOTICE' ) && BETTERLINKS_MENU_NOTICE !== $menu_notice ) {
118 update_option('betterlinks_menu_notice', BETTERLINKS_MENU_NOTICE);
119 }
120 }
121 wp_set_script_translations('betterlinks-admin-core', 'betterlinks', BETTERLINKS_ROOT_DIR_PATH . 'languages/');
122 if ( ! in_array( $hook, ['post.php', 'post-new.php'] ) ) {
123 // Version from the file's mtime (not BETTERLINKS_VERSION) so CSS-only
124 // edits invalidate the browser cache — same reason as betterlinks.css above.
125 $notice_style_path = BETTERLINKS_ASSETS_DIR_PATH . 'css/betterlinks-admin-notice.css';
126 $notice_style_ver = file_exists($notice_style_path) ? (string) filemtime($notice_style_path) : BETTERLINKS_VERSION;
127 wp_enqueue_style('betterlinks-admin-notice', BETTERLINKS_ASSETS_URI . 'css/betterlinks-admin-notice.css', [], $notice_style_ver, 'all');
128 }
129 if( 'toplevel_page_fluent-boards' == $hook ){
130 $dependencies = include_once BETTERLINKS_ASSETS_DIR_PATH . 'js/betterlinks-intflboards.core.min.asset.php';
131 wp_enqueue_script(
132 'betterlinks-intflboards',
133 BETTERLINKS_ASSETS_URI . 'js/betterlinks-intflboards.core.min.js',
134 array_merge($dependencies['dependencies'], ['regenerator-runtime']),
135 $dependencies['version'],
136 [
137 'in_footer' => true,
138 ]
139 );
140 $settings = Cache::get_json_settings();
141 wp_localize_script('betterlinks-intflboards', 'betterLinksFlbIntegration', [
142 'plugin_root_url' => BETTERLINKS_PLUGIN_ROOT_URI,
143 'TASKS' => 'tasks/',
144 'betterlinks_nonce' => wp_create_nonce('betterlinks_admin_nonce'),
145 'site_url' => apply_filters('betterlinks/site_url', site_url()),
146 'admin_url' => admin_url('/admin.php'),
147 'fbs_settings' => isset($settings['fbs']) ? $settings['fbs'] : null
148 ]);
149 wp_enqueue_style('betterlinks-intflboards', BETTERLINKS_ASSETS_URI . 'css/integrations/btl-fbs.css', [], $dependencies['version'], 'all');
150 }
151 }
152
153 /**
154 * Enqueue Guten Scripts
155 */
156 public function block_editor_assets()
157 {
158 global $pagenow;
159 if( 'customize.php' === $pagenow ) return;
160 global $betterlinks_settings;
161
162 $is_allow_gutenberg = isset( $betterlinks_settings['is_allow_gutenberg'] ) ? $betterlinks_settings['is_allow_gutenberg'] : false;
163 $affiliate_link_disclosure = isset( $betterlinks_settings['affiliate_link_disclosure'] ) ? $betterlinks_settings['affiliate_link_disclosure'] : false;
164 $enable_auto_link = isset( $betterlinks_settings['enable_auto_link'] ) ? $betterlinks_settings['enable_auto_link'] : false;
165
166 if( !($is_allow_gutenberg || $affiliate_link_disclosure || $enable_auto_link) ) return;
167
168 $dependencies = include_once BETTERLINKS_ASSETS_DIR_PATH . 'js/betterlinks-gutenberg.core.min.asset.php';
169 wp_enqueue_style(
170 'betterlinks-gutenberg',
171 BETTERLINKS_ASSETS_URI . 'css/betterlinks-gutenberg.css',
172 [],
173 $dependencies['version']
174 );
175
176 wp_enqueue_script(
177 'betterlinks-gutenberg',
178 BETTERLINKS_ASSETS_URI . 'js/betterlinks-gutenberg.core.min.js',
179 array_merge($dependencies['dependencies'], ['regenerator-runtime']),
180 filemtime(BETTERLINKS_ASSETS_DIR_PATH . 'js/betterlinks-gutenberg.core.min.js'),
181 true
182 );
183
184
185 $prefix = isset($betterlinks_settings['prefix']) ? $betterlinks_settings['prefix'] : '';
186 wp_localize_script('betterlinks-gutenberg', 'betterLinksGlobal', [
187 'post_type' => get_post_type(),
188 'betterlinks_nonce' => wp_create_nonce('betterlinks_admin_nonce'),
189 'nonce' => wp_create_nonce('wp_rest'),
190 'rest_url' => rest_url(),
191 // Needed by AJAX helpers used in the block editor (e.g. shortURLUniqueCheckGutenberg
192 // in the AutoLink sidebar); without it those calls logged "ajaxurl is not defined".
193 'ajaxurl' => admin_url('admin-ajax.php'),
194 'namespace' => BETTERLINKS_PLUGIN_SLUG . '/v1/',
195 'plugin_root_url' => BETTERLINKS_PLUGIN_ROOT_URI,
196 'plugin_root_path' => BETTERLINKS_ROOT_DIR_PATH,
197 'site_url' => apply_filters('betterlinks/site_url', site_url()),
198 'actual_site_url' => site_url(),
199 'route_path' => wp_parse_url(admin_url(), PHP_URL_PATH),
200 'is_pro_enabled' => apply_filters('betterlinks/pro_enabled', false),
201 // Needed by pro_version_check() in the editor (e.g. the AI Link Assistant
202 // 2.8.0+ gate). Without it the check falls back to its "no Pro" early-return.
203 'betterlinkspro_version' => defined('BETTERLINKS_PRO_VERSION') ? BETTERLINKS_PRO_VERSION : null,
204 'prefix' => $prefix,
205 'betterlinks_settings' => $betterlinks_settings,
206 // Add user permission information for free version
207 'user_can_manage_options' => current_user_can('manage_options'),
208 // Categories a feature owns but keeps off Manage Links (the bio pages'
209 // "Link in Bio", Fluent Boards' task category). The editor sidebar needs
210 // the same list the dashboard query uses: a link filed under one of these
211 // saves correctly but never appears on Manage Links, so Instant Redirect
212 // must neither offer them nor fall back to one.
213 'dashboard_hidden_term_ids' => array_values(array_unique(array_filter(array_map('intval', (array) apply_filters('betterlinks/dashboard_hidden_term_ids', array(), (array) $betterlinks_settings))))),
214 ]);
215 wp_set_script_translations('betterlinks-gutenberg', 'betterlinks', BETTERLINKS_ROOT_DIR_PATH . 'languages/');
216 }
217 }
218