PluginProbe ʕ •ᴥ•ʔ
WooCommerce Square / 3.8.1
WooCommerce Square v3.8.1
5.4.2 5.4.1 5.4.0 trunk 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.7.0 2.8.0 2.9.0 2.9.1 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.2.0 3.3.0 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.7.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 4.0.0 4.1.0 4.2.0 4.2.1 4.2.2 4.2.3 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.2 4.6.0 4.6.1 4.6.2 4.6.3 4.6.4 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.8.4 4.8.5 4.8.6 4.8.7 4.8.8 4.9.0 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.6 4.9.7 4.9.8 4.9.9 5.0.0 5.0.1 5.1.0 5.1.1 5.1.2 5.2.0 5.3.0 5.3.1 5.3.2 5.3.3
woocommerce-square / includes / Framework / Plugin.php
woocommerce-square / includes / Framework Last commit date
Addresses 3 years ago Api 3 years ago Compatibility 3 years ago PaymentGateway 3 years ago Utilities 3 years ago Admin_Message_Handler.php 3 years ago Admin_Notice_Handler.php 3 years ago Lifecycle.php 3 years ago Plugin.php 3 years ago Plugin_Compatibility.php 3 years ago Plugin_Dependencies.php 3 years ago Square_Helper.php 4 years ago
Plugin.php
842 lines
1 <?php
2 /**
3 * WooCommerce Plugin Framework
4 *
5 * This source file is subject to the GNU General Public License v3.0
6 * that is bundled with this package in the file license.txt.
7 * It is also available through the world-wide-web at this URL:
8 * http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
9 * If you did not receive a copy of the license and are unable to
10 * obtain it through the world-wide-web, please send an email
11 * to license@skyverge.com so we can send you a copy immediately.
12 *
13 * @since 3.0.0
14 * @author WooCommerce / SkyVerge
15 * @copyright Copyright (c) 2021-2022, WooCommerce.
16 * @copyright Copyright (c) 2013-2019, SkyVerge, Inc.
17 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
18 *
19 * Modified by WooCommerce on 15 December 2021.
20 */
21
22 namespace WooCommerce\Square\Framework;
23
24 defined( 'ABSPATH' ) or exit;
25
26 /**
27 * # WooCommerce Plugin Framework
28 *
29 * This framework class provides a base level of configurable and overrideable
30 * functionality and features suitable for the implementation of a WooCommerce
31 * plugin. This class handles all the "non-feature" support tasks such
32 * as verifying dependencies are met, loading the text domain, etc.
33 */
34 abstract class Plugin {
35
36 /** @var object single instance of plugin */
37 protected static $instance;
38
39 /** @var string plugin id */
40 private $id;
41
42 /** @var string version number */
43 private $version;
44
45 /** @var string plugin path without trailing slash */
46 private $plugin_path;
47
48 /** @var string plugin uri */
49 private $plugin_url;
50
51 /** @var \WC_Logger instance */
52 private $logger;
53
54 /** @var Admin_Message_Handler instance */
55 private $message_handler;
56
57 /** @var string the plugin text domain */
58 private $text_domain;
59
60 /** @var Plugin_Dependencies dependency handler instance */
61 private $dependency_handler;
62
63 /** @var Plugin\Lifecycle lifecycle handler instance */
64 protected $lifecycle_handler;
65
66 /** @var REST_API REST API handler instance */
67 protected $rest_api_handler;
68
69 /** @var Admin\Setup_Wizard handler instance */
70 protected $setup_wizard_handler;
71
72 /** @var Admin_Notice_Handler the admin notice handler class */
73 private $admin_notice_handler;
74
75
76 /**
77 * Initialize the plugin.
78 *
79 * Child plugin classes may add their own optional arguments.
80 *
81 * @since 3.0.0
82 *
83 * @param string $id plugin id
84 * @param string $version plugin version number
85 * @param array $args {
86 * optional plugin arguments
87 *
88 * @type string $text_domain the plugin textdomain, used to set up translations
89 * @type array $dependencies {
90 * PHP extension, function, and settings dependencies
91 *
92 * @type array $php_extensions PHP extension dependencies
93 * @type array $php_functions PHP function dependencies
94 * @type array $php_settings PHP settings dependencies
95 * }
96 * }
97 */
98 public function __construct( $id, $version, $args = array() ) {
99
100 // required params
101 $this->id = $id;
102 $this->version = $version;
103
104 $args = wp_parse_args( $args, array(
105 'text_domain' => '',
106 'dependencies' => array(),
107 ) );
108
109 $this->text_domain = $args['text_domain'];
110
111 // includes that are required to be available at all times
112 $this->includes();
113
114 // initialize the dependencies manager
115 $this->init_dependencies( $args['dependencies'] );
116
117 // build the admin message handler instance
118 $this->init_admin_message_handler();
119
120 // build the admin notice handler instance
121 $this->init_admin_notice_handler();
122
123 // build the lifecycle handler instance
124 $this->init_lifecycle_handler();
125
126 // add the action & filter hooks
127 $this->add_hooks();
128 }
129
130
131 /** Init methods **********************************************************/
132
133
134 /**
135 * Initializes the plugin dependency handler.
136 *
137 * @since 3.0.0
138 *
139 * @param array $dependencies {
140 * PHP extension, function, and settings dependencies
141 *
142 * @type array $php_extensions PHP extension dependencies
143 * @type array $php_functions PHP function dependencies
144 * @type array $php_settings PHP settings dependencies
145 * }
146 */
147 protected function init_dependencies( $dependencies ) {
148
149 $this->dependency_handler = new Plugin_Dependencies( $this, $dependencies );
150 }
151
152
153 /**
154 * Builds the admin message handler instance.
155 *
156 * Plugins can override this with their own handler.
157 *
158 * @since 3.0.0
159 */
160 protected function init_admin_message_handler() {
161
162 $this->message_handler = new Admin_Message_Handler( 'square' );
163 }
164
165
166 /**
167 * Builds the admin notice handler instance.
168 *
169 * Plugins can override this with their own handler.
170 *
171 * @since 3.0.0
172 */
173 protected function init_admin_notice_handler() {
174
175 $this->admin_notice_handler = new Admin_Notice_Handler( $this );
176 }
177
178 /**
179 * Builds the lifecycle handler instance.
180 *
181 * Plugins can override this with their own handler to perform install and
182 * upgrade routines.
183 *
184 * @since 3.0.0
185 */
186 protected function init_lifecycle_handler() {
187
188 $this->lifecycle_handler = new Lifecycle( $this );
189 }
190
191 /**
192 * Adds the action & filter hooks.
193 *
194 * @since 3.0.0
195 */
196 private function add_hooks() {
197
198 // initialize the plugin
199 add_action( 'plugins_loaded', array( $this, 'init_plugin' ), 15 );
200
201 // initialize the plugin admin
202 add_action( 'admin_init', array( $this, 'init_admin' ), 0 );
203
204 // hook for translations seperately to ensure they're loaded
205 add_action( 'init', array( $this, 'load_translations' ) );
206
207 add_action( 'admin_footer', array( $this, 'add_delayed_admin_notices' ) );
208
209 // add a 'Configure' link to the plugin action links
210 add_filter( 'plugin_action_links_' . plugin_basename( $this->get_plugin_file() ), array( $this, 'plugin_action_links' ) );
211
212 // automatically log HTTP requests from Base
213 $this->add_api_request_logging();
214
215 // add any PHP incompatibilities to the system status report
216 add_filter( 'woocommerce_system_status_environment_rows', array( $this, 'add_system_status_php_information' ) );
217 }
218
219
220 /**
221 * Cloning instances is forbidden due to singleton pattern.
222 *
223 * @since 3.0.0
224 */
225 public function __clone() {
226 /* translators: Placeholders: %s - plugin name */
227 _doing_it_wrong( __FUNCTION__, sprintf( esc_html__( 'You cannot clone instances of %s.', 'woocommerce-square' ), esc_html( $this->get_plugin_name() ) ), '3.1.0' );
228 }
229
230
231 /**
232 * Unserializing instances is forbidden due to singleton pattern.
233 *
234 * @since 3.0.0
235 */
236 public function __wakeup() {
237 /* translators: Placeholders: %s - plugin name */
238 _doing_it_wrong( __FUNCTION__, sprintf( esc_html__( 'You cannot unserialize instances of %s.', 'woocommerce-square' ), esc_html( $this->get_plugin_name() ) ), '3.1.0' );
239 }
240
241
242 /**
243 * Load plugin & framework text domains.
244 *
245 * @internal
246 *
247 * @since 3.0.0
248 */
249 public function load_translations() {
250
251 $this->load_framework_textdomain();
252
253 // if this plugin passes along its text domain, load its translation files
254 if ( $this->text_domain ) {
255 $this->load_plugin_textdomain();
256 }
257 }
258
259
260 /**
261 * Loads the framework textdomain.
262 *
263 * @since 3.0.0
264 */
265 protected function load_framework_textdomain() {
266 $this->load_textdomain( 'woocommerce-square', dirname( plugin_basename( $this->get_framework_file() ) ) );
267 }
268
269
270 /**
271 * Loads the plugin textdomain.
272 *
273 * @since 3.0.0
274 */
275 protected function load_plugin_textdomain() {
276 $this->load_textdomain( $this->text_domain, dirname( plugin_basename( $this->get_plugin_file() ) ) );
277 }
278
279
280 /**
281 * Loads the plugin textdomain.
282 *
283 * @since 3.0.0
284 * @param string $textdomain the plugin textdomain
285 * @param string $path the i18n path
286 */
287 protected function load_textdomain( $textdomain, $path ) {
288
289 // user's locale if in the admin for WP 4.7+, or the site locale otherwise
290 $locale = is_admin() && is_callable( 'get_user_locale' ) ? get_user_locale() : get_locale();
291
292 $locale = apply_filters( 'plugin_locale', $locale, $textdomain );
293
294 load_textdomain( $textdomain, WP_LANG_DIR . '/' . $textdomain . '/' . $textdomain . '-' . $locale . '.mo' );
295
296 load_plugin_textdomain( $textdomain, false, untrailingslashit( $path ) . '/i18n/languages' );
297 }
298
299 /**
300 * Include any critical files which must be available as early as possible,
301 *
302 * @since 3.0.0
303 */
304 private function includes() {
305
306 $framework_path = $this->get_framework_path();
307
308 // addresses
309 require_once( $framework_path . '/Addresses/Address.php' );
310 require_once( $framework_path . '/Addresses/Customer_Address.php' );
311
312 // common utility methods
313 require_once( $framework_path . '/Square_Helper.php' );
314
315 // backwards compatibility for older WC versions
316 require_once( $framework_path . '/Plugin_Compatibility.php' );
317 require_once( $framework_path . '/Compatibility/Data_Compatibility.php' );
318 require_once( $framework_path . '/Compatibility/Order_Compatibility.php' );
319
320 // generic API base
321 require_once( $framework_path . '/Api/Base.php' );
322 require_once( $framework_path . '/Api/API_Request.php' );
323 require_once( $framework_path . '/Api/API_Response.php' );
324
325 // JSON API base
326 require_once( $framework_path . '/Api/API_JSON_Request.php' );
327 require_once( $framework_path . '/Api/API_JSON_Response.php' );
328
329 // Handlers
330 require_once( $framework_path . '/Plugin_Dependencies.php' );
331 require_once( $framework_path . '/Admin_Message_Handler.php' );
332 require_once( $framework_path . '/Admin_Notice_Handler.php' );
333 require_once( $framework_path . '/Lifecycle.php' );
334 }
335
336 /**
337 * Returns true if on the admin plugin settings page, if any
338 *
339 * @since 3.0.0
340 * @return boolean true if on the admin plugin settings page
341 */
342 public function is_plugin_settings() {
343 // optional method, not all plugins *have* a settings page
344 return false;
345 }
346
347 /**
348 * Return the plugin action links. This will only be called if the plugin
349 * is active.
350 *
351 * @since 3.0.0
352 * @param array $actions associative array of action names to anchor tags
353 * @return array associative array of plugin action links
354 */
355 public function plugin_action_links( $actions ) {
356
357 $custom_actions = array();
358
359 // settings url(s)
360 if ( $this->get_settings_link( 'square' ) ) {
361 $custom_actions['configure'] = $this->get_settings_link( 'square' );
362 }
363
364 // documentation url if any
365 if ( $this->get_documentation_url() ) {
366 /* translators: Docs as in Documentation */
367 $custom_actions['docs'] = sprintf( '<a href="%s" target="_blank">%s</a>', $this->get_documentation_url(), esc_html__( 'Docs', 'woocommerce-square' ) );
368 }
369
370 // support url if any
371 if ( $this->get_support_url() ) {
372 $custom_actions['support'] = sprintf( '<a href="%s">%s</a>', $this->get_support_url(), esc_html_x( 'Support', 'noun', 'woocommerce-square' ) );
373 }
374
375 // review url if any
376 if ( $this->get_reviews_url() ) {
377 $custom_actions['review'] = sprintf( '<a href="%s">%s</a>', $this->get_reviews_url(), esc_html_x( 'Review', 'verb', 'woocommerce-square' ) );
378 }
379
380 // add the links to the front of the actions list
381 return array_merge( $custom_actions, $actions );
382 }
383
384 /**
385 * Automatically log API requests/responses when using Base
386 *
387 * @since 3.0.0
388 * @see Base::broadcast_request()
389 */
390 public function add_api_request_logging() {
391
392 if ( ! has_action( 'wc_square_api_request_performed' ) ) {
393 add_action( 'wc_square_api_request_performed', array( $this, 'log_api_request' ), 10, 2 );
394 }
395 }
396
397
398 /**
399 * Log API requests/responses
400 *
401 * @since 3.0.0
402 * @param array $request request data, see Base::broadcast_request() for format
403 * @param array $response response data
404 * @param string|null $log_id log to write data to
405 */
406 public function log_api_request( $request, $response, $log_id = null ) {
407
408 $this->log( sprintf( "Request\n %s", $this->get_api_log_message( $request ) ), $log_id );
409
410 if ( ! empty( $response ) ) {
411 $this->log( sprintf( "Response\n %s", $this->get_api_log_message( $response ) ), $log_id );
412 }
413 }
414
415
416 /**
417 * Transform the API request/response data into a string suitable for logging
418 *
419 * @since 3.0.0
420 * @param array $data
421 * @return string
422 */
423 public function get_api_log_message( $data ) {
424
425 $messages = array();
426
427 $messages[] = isset( $data['uri'] ) && $data['uri'] ? 'Request' : 'Response';
428
429 foreach ( (array) $data as $key => $value ) {
430 $messages[] = trim( sprintf( '%s: %s', $key, is_array( $value ) || ( is_object( $value ) && 'stdClass' == get_class( $value ) ) ? print_r( (array) $value, true ) : $value ) );
431 }
432
433 return implode( "\n", $messages ) . "\n";
434 }
435
436
437 /**
438 * Adds any PHP incompatibilities to the system status report.
439 *
440 * @since 3.0.0
441 *
442 * @param array $rows WooCommerce system status rows
443 * @return array
444 */
445 public function add_system_status_php_information( $rows ) {
446
447 foreach ( $this->get_dependency_handler()->get_incompatible_php_settings() as $setting => $values ) {
448
449 if ( isset( $values['type'] ) && 'min' === $values['type'] ) {
450
451 // if this setting already has a higher minimum from another plugin, skip it
452 if ( isset( $rows[ $setting ]['expected'] ) && $values['expected'] < $rows[ $setting ]['expected'] ) {
453 continue;
454 }
455
456 $note = __( '%1$s - A minimum of %2$s is required.', 'woocommerce-square' );
457
458 } else {
459
460 // if this requirement is already listed, skip it
461 if ( isset( $rows[ $setting ] ) ) {
462 continue;
463 }
464
465 $note = __( 'Set as %1$s - %2$s is required.', 'woocommerce-square' );
466 }
467
468 $note = sprintf( $note, esc_html( $values['actual'] ), esc_html( $values['expected'] ) );
469
470 $rows[ $setting ] = array(
471 'name' => $setting,
472 'note' => $note,
473 'success' => false,
474 'expected' => $values['expected'], // WC doesn't use this, but it's useful for us
475 );
476 }
477
478 return $rows;
479 }
480
481
482 /**
483 * Saves errors or messages to WooCommerce Log (woocommerce/logs/plugin-id-xxx.txt)
484 *
485 * @since 3.0.0
486 * @param string $message error or message to save to log
487 * @param string $log_id optional log id to segment the files by, defaults to plugin id
488 */
489 public function log( $message, $log_id = null ) {
490
491 if ( is_null( $log_id ) ) {
492 $log_id = 'square';
493 }
494
495 if ( ! is_object( $this->logger ) ) {
496 $this->logger = new \WC_Logger();
497 }
498
499 $this->logger->add( $log_id, $message );
500 }
501
502 /**
503 * Gets the main plugin file.
504 *
505 * @since 3.0.0
506 *
507 * @return string
508 */
509 public function get_plugin_file() {
510
511 $slug = dirname( plugin_basename( $this->get_file() ) );
512
513 return trailingslashit( $slug ) . $slug . '.php';
514 }
515
516
517 /**
518 * The implementation for this abstract method should simply be:
519 *
520 * return __FILE__;
521 *
522 * @since 3.0.0
523 * @return string the full path and filename of the plugin file
524 */
525 abstract protected function get_file();
526
527
528 /**
529 * Returns the plugin id
530 *
531 * @since 3.0.0
532 * @return string plugin id
533 */
534 public function get_id() {
535 return $this->id;
536 }
537
538
539 /**
540 * Returns the plugin id with dashes in place of underscores, and
541 * appropriate for use in frontend element names, classes and ids
542 *
543 * @since 3.0.0
544 * @return string plugin id with dashes in place of underscores
545 */
546 public function get_id_dasherized() {
547 return str_replace( '_', '-', 'square' );
548 }
549
550
551 /**
552 * Returns the plugin full name including "WooCommerce", ie
553 * "WooCommerce X". This method is defined abstract for localization purposes
554 *
555 * @since 3.0.0
556 * @return string plugin name
557 */
558 abstract public function get_plugin_name();
559
560 /**
561 * Gets the dependency handler.
562 *
563 * @since 3.0.0
564 *
565 * @return Plugin_Dependencies
566 */
567 public function get_dependency_handler() {
568
569 return $this->dependency_handler;
570 }
571
572
573 /**
574 * Gets the lifecycle handler instance.
575 *
576 * @since 3.0.0
577 *
578 * @return Plugin\Lifecycle
579 */
580 public function get_lifecycle_handler() {
581
582 return $this->lifecycle_handler;
583 }
584
585 /**
586 * Gets the admin message handler.
587 *
588 * @since 3.0.0
589 *
590 * @return Admin_Message_Handler
591 */
592 public function get_message_handler() {
593
594 return $this->message_handler;
595 }
596
597
598 /**
599 * Gets the admin notice handler instance.
600 *
601 * @since 3.0.0
602 *
603 * @return Admin_Notice_Handler
604 */
605 public function get_admin_notice_handler() {
606
607 return $this->admin_notice_handler;
608 }
609
610
611 /**
612 * Returns the plugin version name. Defaults to wc_{plugin id}_version
613 *
614 * @since 3.0.0
615 * @return string the plugin version name
616 */
617 public function get_plugin_version_name() {
618
619 return 'wc_square_version';
620 }
621
622
623 /**
624 * Returns the current version of the plugin
625 *
626 * @since 3.0.0
627 * @return string plugin version
628 */
629 public function get_version() {
630 return $this->version;
631 }
632
633
634 /**
635 * Returns the "Configure" plugin action link to go directly to the plugin
636 * settings page (if any)
637 *
638 * @since 3.0.0
639 * @see Plugin::get_settings_url()
640 * @param string $plugin_id optional plugin identifier. Note that this can be a
641 * sub-identifier for plugins with multiple parallel settings pages
642 * (ie a gateway that supports credit cards)
643 * @return string plugin configure link
644 */
645 public function get_settings_link( $plugin_id = null ) {
646
647 $settings_url = $this->get_settings_url( $plugin_id );
648
649 if ( $settings_url ) {
650 return sprintf( '<a href="%s">%s</a>', $settings_url, esc_html__( 'Configure', 'woocommerce-square' ) );
651 }
652
653 // no settings
654 return '';
655 }
656
657
658 /**
659 * Gets the plugin configuration URL
660 *
661 * @since 3.0.0
662 * @see Plugin::get_settings_link()
663 * @param string $plugin_id optional plugin identifier. Note that this can be a
664 * sub-identifier for plugins with multiple parallel settings pages
665 * (ie a gateway that supports credit cards)
666 * @return string plugin settings URL
667 */
668 public function get_settings_url( $plugin_id = null ) {
669
670 // stub method
671 return '';
672 }
673
674 /**
675 * Returns the admin configuration url for the admin general configuration page
676 *
677 * @since 3.0.0
678 * @return string admin configuration url for the admin general configuration page
679 */
680 public function get_general_configuration_url() {
681
682 return admin_url( 'admin.php?page=wc-settings&tab=general' );
683 }
684
685
686 /**
687 * Gets the plugin documentation url, used for the 'Docs' plugin action
688 *
689 * @since 3.0.0
690 * @return string documentation URL
691 */
692 public function get_documentation_url() {
693
694 return null;
695 }
696
697
698 /**
699 * Gets the support URL, used for the 'Support' plugin action link
700 *
701 * @since 3.0.0
702 * @return string support url
703 */
704 public function get_support_url() {
705
706 return null;
707 }
708
709
710 /**
711 * Gets the plugin sales page URL.
712 *
713 * @since 3.0.0
714 *
715 * @return string
716 */
717 public function get_sales_page_url() {
718
719 return '';
720 }
721
722
723 /**
724 * Gets the plugin reviews page URL.
725 *
726 * Used for the 'Reviews' plugin action and review prompts.
727 *
728 * @since 3.0.0
729 *
730 * @return string
731 */
732 public function get_reviews_url() {
733
734 return $this->get_sales_page_url() ? $this->get_sales_page_url() . '#comments' : '';
735 }
736
737
738 /**
739 * Returns the plugin's path without a trailing slash, i.e.
740 * /path/to/wp-content/plugins/plugin-directory
741 *
742 * @since 3.0.0
743 * @return string the plugin path
744 */
745 public function get_plugin_path() {
746
747 if ( $this->plugin_path ) {
748 return $this->plugin_path;
749 }
750
751 return $this->plugin_path = untrailingslashit( plugin_dir_path( $this->get_file() ) );
752 }
753
754
755 /**
756 * Returns the plugin's url without a trailing slash, i.e.
757 *
758 * @since 3.0.0
759 * @return string the plugin URL
760 */
761 public function get_plugin_url() {
762
763 if ( $this->plugin_url ) {
764 return $this->plugin_url;
765 }
766
767 return $this->plugin_url = untrailingslashit( plugins_url( '/', $this->get_file() ) );
768 }
769
770 /**
771 * Returns the loaded framework __FILE__
772 *
773 * @since 3.0.0
774 * @return string
775 */
776 public function get_framework_file() {
777
778 return __FILE__;
779 }
780
781
782 /**
783 * Returns the loaded framework path, without trailing slash. Ths is the highest
784 * version framework that was loaded by the bootstrap.
785 *
786 * @since 3.0.0
787 * @return string
788 */
789 public function get_framework_path() {
790
791 return untrailingslashit( plugin_dir_path( $this->get_framework_file() ) );
792 }
793
794 /**
795 * Returns the loaded framework assets URL without a trailing slash
796 *
797 * @since 3.0.0
798 * @return string
799 */
800 public function get_framework_assets_url() {
801
802 return untrailingslashit( plugins_url( '/assets', $this->get_framework_file() ) );
803 }
804
805
806 /**
807 * Helper function to determine whether a plugin is active
808 *
809 * @since 3.0.0
810 * @param string $plugin_name plugin name, as the plugin-filename.php
811 * @return boolean true if the named plugin is installed and active
812 */
813 public function is_plugin_active( $plugin_name ) {
814
815 $active_plugins = (array) get_option( 'active_plugins', array() );
816
817 if ( is_multisite() ) {
818 $active_plugins = array_merge( $active_plugins, array_keys( get_site_option( 'active_sitewide_plugins', array() ) ) );
819 }
820
821 $plugin_filenames = array();
822
823 foreach ( $active_plugins as $plugin ) {
824
825 if ( Square_Helper::str_exists( $plugin, '/' ) ) {
826
827 // normal plugin name (plugin-dir/plugin-filename.php)
828 list( , $filename ) = explode( '/', $plugin );
829
830 } else {
831
832 // no directory, just plugin file
833 $filename = $plugin;
834 }
835
836 $plugin_filenames[] = $filename;
837 }
838
839 return in_array( $plugin_name, $plugin_filenames, true );
840 }
841 }
842