PluginProbe
Code Snippets / trunk
Code Snippets vtrunk
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
code-snippets / php / Plugin.php

Plugin.php in Code Snippets trunk, at php/Plugin.php

409 lines 11.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Code_Snippets;
4
5 use Code_Snippets\Admin\Bootstrap_Admin;
6 use Code_Snippets\Admin\Feedback_Error_Capture;
7 use Code_Snippets\Admin\Feedback_Panel;
8 use Code_Snippets\Admin\Menus\Manage\Manage_Menu;
9 use Code_Snippets\Client\Feedback_Client;
10 use Code_Snippets\Controller\Cloud_Search_Controller;
11 use Code_Snippets\Core\DB;
12 use Code_Snippets\Core\Licensing;
13 use Code_Snippets\Core\Upgrader;
14 use Code_Snippets\Integration\Admin_Bar;
15 use Code_Snippets\Integration\Classic_Editor\MCE_Plugin;
16 use Code_Snippets\Integration\Evaluate_Content;
17 use Code_Snippets\Integration\Evaluate_Functions;
18 use Code_Snippets\Integration\Promotions\Promotion_Manager;
19 use Code_Snippets\Integration\Shortcodes;
20 use Code_Snippets\Model\Basic_Cloud_Connection;
21 use Code_Snippets\Model\Feedback_Connection;
22 use Code_Snippets\REST_API\Cloud\Cloud_Snippets_REST_Controller;
23 use Code_Snippets\REST_API\Feedback\Feedback_REST_Controller;
24 use Code_Snippets\REST_API\Import\File_Import_REST_Controller;
25 use Code_Snippets\REST_API\Import\Plugins_Import_REST_Controller;
26 use Code_Snippets\REST_API\Preferences\Demos_Seen_REST_Controller;
27 use Code_Snippets\REST_API\Preferences\Insights_View_Rest_Controller;
28 use Code_Snippets\REST_API\Preferences\Snippet_View_REST_Controller;
29 use Code_Snippets\REST_API\Snippets\Recently_Active_REST_Controller;
30 use Code_Snippets\REST_API\Snippets\Snippets_REST_Controller;
31 use function Code_Snippets\Settings\are_settings_unified;
32
33 /**
34 * The main plugin class
35 *
36 * @package Code_Snippets
37 */
38 class Plugin {
39
40 /**
41 * Current plugin version number
42 *
43 * @deprecated Use the PLUGIN_VERSION constant instead.
44 *
45 * @var string
46 */
47 public string $version = PLUGIN_VERSION;
48
49 /**
50 * Filesystem path to the main plugin file
51 *
52 * @deprecated Use the PLUGIN_FILE constant instead.
53 *
54 * @var string
55 */
56 public string $file = PLUGIN_FILE;
57
58 /**
59 * Database class
60 *
61 * @var DB
62 */
63 public DB $db;
64
65 /**
66 * Class for managing shortcodes.
67 *
68 * @var Shortcodes
69 */
70 public Shortcodes $shortcodes;
71
72 /**
73 * Administration area class
74 *
75 * @var Bootstrap_Admin
76 */
77 public Bootstrap_Admin $admin;
78
79 /**
80 * Handles licensing and plugin updates.
81 *
82 * @var Licensing
83 */
84 public Licensing $licensing;
85
86 /**
87 * Handles snippet handler registration.
88 *
89 * @var Flat_Files\Handler_Registry
90 */
91 public Flat_Files\Handler_Registry $snippet_handler_registry;
92
93 /**
94 * Instance of connection to Code Snippets Cloud.
95 *
96 * @var Basic_Cloud_Connection
97 */
98 public Basic_Cloud_Connection $cloud_connection;
99
100 /**
101 * Class constructor
102 */
103 public function __construct() {
104 wp_cache_add_global_groups( CACHE_GROUP );
105 add_action( 'allowed_redirect_hosts', [ $this, 'allow_code_snippets_redirect' ] );
106 }
107
108 /**
109 * Load the plugin utilities.
110 */
111 private function load_utilities() {
112 require_once __DIR__ . '/Utils/editor.php';
113 require_once __DIR__ . '/Utils/options.php';
114 require_once __DIR__ . '/Settings/settings.php';
115 require_once __DIR__ . '/snippet-ops.php';
116 }
117
118 /**
119 * Initialize the plugin and load all necessary classes.
120 */
121 public function load_plugin() {
122 $this->load_utilities();
123
124 $this->db = new DB();
125 $this->licensing = new Licensing();
126
127 $this->cloud_connection = new Basic_Cloud_Connection();
128
129 new Evaluate_Content( $this->db );
130 new Evaluate_Functions( $this->db );
131
132 $this->shortcodes = new Shortcodes();
133
134 if ( is_admin() ) {
135 $this->admin = new Bootstrap_Admin();
136 new Promotion_Manager();
137 new Feedback_Error_Capture( new Feedback_Panel() );
138 }
139
140 new Shortcodes();
141 new MCE_Plugin();
142 new Upgrader( PLUGIN_VERSION, $this->db );
143 new Admin_Bar();
144
145 $this->init_snippet_files();
146
147 add_action( 'rest_api_init', [ $this, 'init_rest_api' ], 1 );
148 }
149
150 /**
151 * Load REST API controller classes when serving REST API requests.
152 *
153 * @return void
154 */
155 public function init_rest_api() {
156 $cloud_search = new Cloud_Search_Controller( $this->cloud_connection );
157
158 new Snippets_REST_Controller();
159 new Recently_Active_REST_Controller();
160
161 new Snippet_View_REST_Controller();
162 new Insights_View_Rest_Controller();
163 new Demos_Seen_REST_Controller();
164
165 new Plugins_Import_REST_Controller();
166 new File_Import_REST_Controller();
167
168 new Cloud_Snippets_REST_Controller( $cloud_search );
169
170 new Feedback_REST_Controller( new Feedback_Client( new Feedback_Connection() ) );
171 }
172
173 /**
174 * Initializes the snippet files component.
175 *
176 * @return void
177 */
178 private function init_snippet_files() {
179 $this->snippet_handler_registry = new Flat_Files\Handler_Registry(
180 [
181 'php' => new Flat_Files\Handlers\Functions_Snippet_Handler(),
182 'html' => new Flat_Files\Handlers\Content_Snippet_Handler(),
183 ]
184 );
185
186 $fs = new Flat_Files\WP_Filesystem_Adapter();
187 $config_repo = new Flat_Files\Flat_File_Config_Repository( $fs );
188
189 $snippet_files = new Flat_Files\Snippet_Files( $this->snippet_handler_registry, $fs, $config_repo );
190 $snippet_files->register_hooks();
191 }
192
193 /**
194 * Determine whether the menu is full or compact.
195 *
196 * @return bool
197 */
198 public function is_compact_menu(): bool {
199 return ! is_network_admin() && apply_filters( 'code_snippets_compact_menu', false );
200 }
201
202 /**
203 * Fetch the admin menu slug for a menu.
204 *
205 * @param string $menu Name of menu to retrieve the slug for.
206 *
207 * @return string The menu's slug.
208 */
209 public function get_menu_slug( string $menu = '' ): string {
210 $add = [ 'single', 'add', 'add-new', 'add-snippet', 'new-snippet', 'add-new-snippet' ];
211 $edit = [ 'edit', 'edit-snippet' ];
212 $import = [ 'import', 'import-snippets', 'import-code-snippets' ];
213 $settings = [ 'settings', 'snippets-settings' ];
214 $cloud = [ 'cloud', 'cloud-snippets' ];
215 $insights = [ 'insights', 'code-snippets-insights' ];
216 $welcome = [ 'welcome', 'getting-started', 'code-snippets' ];
217
218 if ( in_array( $menu, $edit, true ) ) {
219 return 'edit-snippet';
220 } elseif ( in_array( $menu, $add, true ) ) {
221 return 'add-snippet';
222 } elseif ( in_array( $menu, $import, true ) ) {
223 return 'import-code-snippets';
224 } elseif ( in_array( $menu, $settings, true ) ) {
225 return 'snippets-settings';
226 } elseif ( in_array( $menu, $cloud, true ) ) {
227 return 'snippets&subpage=cloud-community';
228 } elseif ( in_array( $menu, $insights, true ) ) {
229 return 'code-snippets-insights';
230 } elseif ( in_array( $menu, $welcome, true ) ) {
231 return 'code-snippets-welcome';
232 } else {
233 return 'snippets';
234 }
235 }
236
237 /**
238 * Fetch the URL to a snippets admin menu.
239 *
240 * @param string $menu Name of menu to retrieve the URL to.
241 * @param string $context URL scheme to use.
242 *
243 * @return string The menu's URL.
244 */
245 public function get_menu_url( string $menu = '', string $context = 'self' ): string {
246 $slug = $this->get_menu_slug( $menu );
247
248 if ( $this->is_compact_menu() && 'network' !== $context ) {
249 $base_slug = $this->get_menu_slug();
250 $url = 'tools.php?page=' . $base_slug;
251
252 if ( $slug !== $base_slug ) {
253 $url .= '&sub=' . $slug;
254 }
255 } else {
256 $url = 'admin.php?page=' . $slug;
257 }
258
259 if ( 'snippets-settings' === $slug && are_settings_unified() ) {
260 return network_admin_url( $url );
261 }
262
263 switch ( $context ) {
264 case 'network':
265 return network_admin_url( $url );
266
267 case 'admin':
268 return admin_url( $url );
269
270 default:
271 return self_admin_url( $url );
272 }
273 }
274
275 /**
276 * Allow redirecting to the Code Snippets site.
277 *
278 * @param string[] $hosts Allowed hosts.
279 *
280 * @return array Modified allowed hosts.
281 */
282 public function allow_code_snippets_redirect( array $hosts ): array {
283 $hosts[] = 'codesnippets.pro';
284 $hosts[] = 'snipco.de';
285 return $hosts;
286 }
287
288 /**
289 * Determine whether the current user can perform actions on snippets.
290 *
291 * @return bool Whether the current user has the required capability.
292 *
293 * @since 2.8.6
294 */
295 public function current_user_can(): bool {
296 return current_user_can( $this->get_cap() );
297 }
298
299 /**
300 * Retrieve the name of the capability required to manage sub-site snippets.
301 *
302 * @return string
303 */
304 public function get_cap_name(): string {
305 return apply_filters( 'code_snippets_cap', 'manage_options' );
306 }
307
308 /**
309 * Retrieve the name of the capability required to manage network snippets.
310 *
311 * @return string
312 */
313 public function get_network_cap_name(): string {
314 return apply_filters( 'code_snippets_network_cap', 'manage_network_options' );
315 }
316
317 /**
318 * Determine if a subsite user menu is enabled via *Network Settings > Enable administration menus*.
319 *
320 * @return bool
321 */
322 public function is_subsite_menu_enabled(): bool {
323 if ( ! is_multisite() ) {
324 return true;
325 }
326
327 $menu_perms = get_site_option( 'menu_items', array() );
328 return ! empty( $menu_perms['snippets'] );
329 }
330
331 /**
332 * Determine if the current user should have the network snippets capability.
333 *
334 * @return bool
335 */
336 public function user_can_manage_network_snippets(): bool {
337 return is_super_admin() || current_user_can( $this->get_network_cap_name() );
338 }
339
340 /**
341 * Get the required capability to perform a certain action on snippets.
342 * Does not check if the user has this capability or not.
343 *
344 * If multisite, adjusts the capability based on whether the user is viewing
345 * the network dashboard or a subsite and whether the menu is enabled for subsites.
346 *
347 * @return string The capability required to manage snippets.
348 *
349 * @since 2.0
350 */
351 public function get_cap(): string {
352 return is_multisite() && ( is_network_admin() || ! $this->is_subsite_menu_enabled() )
353 ? $this->get_network_cap_name()
354 : $this->get_cap_name();
355 }
356
357 /**
358 * Localize a plugin script to provide the CODE_SNIPPETS object.
359 *
360 * @param string $handle Script handle.
361 *
362 * @return void
363 */
364 public function localize_script( string $handle ) {
365 wp_localize_script(
366 $handle,
367 'CODE_SNIPPETS',
368 [
369 'debug' => defined( 'WP_DEBUG' ) && WP_DEBUG,
370 'isLicensed' => $this->licensing->is_licensed(),
371 'isCloudConnected' => $this->cloud_connection->is_authenticated(),
372 'hideUpsell' => Settings\get_setting( 'general', 'hide_upgrade_menu' ),
373 'snippetView' => Snippet_View_REST_Controller::get_snippet_view(),
374 'insightsChartViews' => Insights_View_Rest_Controller::get_insights_chart_views(),
375 'demosSeen' => Demos_Seen_REST_Controller::get_demos_seen(),
376 'restAPI' => [
377 'base' => esc_url_raw( rest_url() ),
378 'snippets' => esc_url_raw( rest_url( Snippets_REST_Controller::get_base_route() ) ),
379 'recentlyActive' => esc_url_raw( rest_url( Recently_Active_REST_Controller::get_base_route() ) ),
380 'snippetView' => esc_url_raw( rest_url( Snippet_View_REST_Controller::get_base_route() ) ),
381 'insightsView' => esc_url_raw( rest_url( Insights_View_Rest_Controller::get_base_route() ) ),
382 'demosSeen' => esc_url_raw( rest_url( Demos_Seen_REST_Controller::get_base_route() ) ),
383 'importPlugins' => esc_url_raw( rest_url( Plugins_Import_REST_Controller::get_base_route() ) ),
384 'importFiles' => esc_url_raw( rest_url( File_Import_REST_Controller::get_base_route() ) ),
385 'nonce' => wp_create_nonce( 'wp_rest' ),
386 'cloud' => [
387 'token' => $this->cloud_connection->get_local_token(),
388 'snippets' => esc_url_raw( rest_url( Cloud_Snippets_REST_Controller::get_base_route() ) ),
389 ],
390 ],
391 'urls' => [
392 'plugin' => esc_url_raw( plugins_url( '', PLUGIN_FILE ) ),
393 'manage' => esc_url_raw( $this->get_menu_url() ),
394 'edit' => esc_url_raw( $this->get_menu_url( 'edit' ) ),
395 'addNew' => esc_url_raw( $this->get_menu_url( 'add' ) ),
396 'insights' => esc_url_raw( $this->get_menu_url( 'insights' ) ),
397 'welcome' => esc_url_raw( $this->get_menu_url( 'welcome' ) ),
398 'import' => esc_url_raw( $this->get_menu_url( 'import' ) ),
399 'cloud' => esc_url_raw( $this->cloud_connection->get_base_url() ),
400 'demoReset' => esc_url_raw( Manage_Menu::get_demo_reset_url() ),
401 'settings' => ! are_settings_unified() || is_super_admin()
402 ? esc_url_raw( $this->get_menu_url( 'settings' ) )
403 : null,
404 ],
405 ]
406 );
407 }
408 }
409