woocommerce/plugins/woocommerce-admin/src/FeaturePlugin.php

304 lines
9.0 KiB
PHP
Raw Normal View History

<?php
/**
* WooCommerce Admin: Feature plugin main class.
*/
namespace Automattic\WooCommerce\Admin;
defined( 'ABSPATH' ) || exit;
use \Automattic\WooCommerce\Admin\Notes\Notes;
use \Automattic\WooCommerce\Admin\Notes\Historical_Data;
use \Automattic\WooCommerce\Admin\Notes\Order_Milestones;
use \Automattic\WooCommerce\Admin\Notes\Woo_Subscriptions_Notes;
use \Automattic\WooCommerce\Admin\Notes\Tracking_Opt_In;
use \Automattic\WooCommerce\Admin\Notes\WooCommerce_Payments;
use \Automattic\WooCommerce\Admin\Notes\Install_JP_And_WCS_Plugins;
use \Automattic\WooCommerce\Admin\Notes\Draw_Attention;
use \Automattic\WooCommerce\Admin\Notes\Coupon_Page_Moved;
Remote inbox notification delivery (https://github.com/woocommerce/woocommerce-admin/pull/4143) * Poll and persist specs * Process specs into admin notes * Add send at time rule processor * Fix style issues * Clear actions before recreating them to avoid dupes * Trigger the RINDS engine when a plugin is activated * Unit test SendAtTimeRuleProcessor * Implement plugins activated rule processor * Don't throw exception for unrecognised rule type. Also unit test around this. * add url_is_action_query to tell whether to wrap the URL in wc_admin_url() call or not * Add NOT rule * revert change to install.php * Drop unimplemented resend after dismissal rule * Add OR rule * Explicitly make "fail" a type of rule that can be applied to a spec * Add plugin version rule processor * Tidy up, don't need to pass $spec everywhere * Remove meta record for action state - not really needed * Move spec runner into it's own class, add some checks around re-unactioning a note * Replace if..else with switch * Just update the option * Check that the JSON coming in is an array * Change OR rule to accept an array of operands * Add Pass rule processor * Fix specs that are initially not published * Rename send at rule to publish after * Add publish before rule * Remove unused interface * Can't use PHP7's anonymous classes * New notification: How to draw attention to your online store * Add feature flag for rule-base inbox notes * rename everything to RemoteInboxNotifications from RINDS * Fix merge fail * fix test * Change preunactioned to pending * Move feature flag check into Events.php * Refactor reading a data source * Rename poll_data_sources function * Refactor EvaluateAndGetStatus::evaluate to take the rule evaluator directly * Check that the response body exists * Add validation and defensive checks * Add rule processor interface * Update note created time on status change * Move non-test dependencies into processor constructors * Update to proposed live URL * Remove setting icon as it's being deprecated Co-authored-by: Rebecca Scott <me@becdetat.com>
2020-06-05 01:51:25 +00:00
use \Automattic\WooCommerce\Admin\RemoteInboxNotifications\RemoteInboxNotificationsEngine;
use \Automattic\WooCommerce\Admin\Notes\Home_Screen_Feedback;
use \Automattic\WooCommerce\Admin\Notes\Set_Up_Additional_Payment_Types;
use \Automattic\WooCommerce\Admin\Notes\Test_Checkout;
use \Automattic\WooCommerce\Admin\Notes\Selling_Online_Courses;
/**
* Feature plugin main class.
*
* @internal This file will not be bundled with woo core, only the feature plugin.
* @internal Note this is not called WC_Admin due to a class already existing in core with that name.
*/
class FeaturePlugin {
/**
* The single instance of the class.
*
* @var object
*/
protected static $instance = null;
/**
* Constructor
*
* @return void
*/
protected function __construct() {}
/**
* Get class instance.
*
* @return object Instance.
*/
final public static function instance() {
if ( null === static::$instance ) {
static::$instance = new static();
}
return static::$instance;
}
/**
* Init the feature plugin, only if we can detect both Gutenberg and WooCommerce.
*/
public function init() {
/**
* Filter allowing WooCommerce Admin to be disabled.
*
* @param bool $disabled False.
*/
if ( apply_filters( 'woocommerce_admin_disabled', false ) ) {
return;
}
$this->define_constants();
require_once WC_ADMIN_ABSPATH . '/includes/core-functions.php';
require_once WC_ADMIN_ABSPATH . '/includes/feature-config.php';
require_once WC_ADMIN_ABSPATH . '/includes/page-controller-functions.php';
require_once WC_ADMIN_ABSPATH . '/includes/wc-admin-update-functions.php';
register_activation_hook( WC_ADMIN_PLUGIN_FILE, array( $this, 'on_activation' ) );
register_deactivation_hook( WC_ADMIN_PLUGIN_FILE, array( $this, 'on_deactivation' ) );
if ( did_action( 'plugins_loaded' ) ) {
self::on_plugins_loaded();
} else {
// Make sure we hook into `plugins_loaded` before core's Automattic\WooCommerce\Package::init().
// If core is network activated but we aren't, the packaged version of WooCommerce Admin will
// attempt to use a data store that hasn't been loaded yet - because we've defined our constants here.
// See: https://github.com/woocommerce/woocommerce-admin/issues/3869.
add_action( 'plugins_loaded', array( $this, 'on_plugins_loaded' ), 9 );
}
}
/**
* Install DB and create cron events when activated.
*
* @return void
*/
public function on_activation() {
Install::create_tables();
Install::create_events();
}
/**
* Remove WooCommerce Admin scheduled actions on deactivate.
*
* @return void
*/
public function on_deactivation() {
// Don't clean up if the WooCommerce Admin package is in core.
// NOTE: Any future divergence from the core package will need to be accounted for here.
if ( defined( 'WC_ADMIN_PACKAGE_EXISTS' ) && WC_ADMIN_PACKAGE_EXISTS ) {
return;
}
// Check if we are deactivating due to dependencies not being satisfied.
// If WooCommerce is disabled we can't include files that depend upon it.
if ( ! $this->has_satisfied_dependencies() ) {
return;
}
$this->includes();
ReportsSync::clear_queued_actions();
Notes::clear_queued_actions();
wp_clear_scheduled_hook( 'wc_admin_daily' );
wp_clear_scheduled_hook( 'generate_category_lookup_table' );
}
/**
* Setup plugin once all other plugins are loaded.
*
* @return void
*/
public function on_plugins_loaded() {
$this->load_plugin_textdomain();
if ( ! $this->has_satisfied_dependencies() ) {
add_action( 'admin_init', array( $this, 'deactivate_self' ) );
add_action( 'admin_notices', array( $this, 'render_dependencies_notice' ) );
return;
}
$this->includes();
$this->hooks();
}
/**
* Define Constants.
*/
protected function define_constants() {
$this->define( 'WC_ADMIN_APP', 'wc-admin-app' );
$this->define( 'WC_ADMIN_ABSPATH', dirname( __DIR__ ) . '/' );
$this->define( 'WC_ADMIN_DIST_JS_FOLDER', 'dist/' );
$this->define( 'WC_ADMIN_DIST_CSS_FOLDER', 'dist/' );
$this->define( 'WC_ADMIN_PLUGIN_FILE', WC_ADMIN_ABSPATH . 'woocommerce-admin.php' );
// WARNING: Do not directly edit this version number constant.
// It is updated as part of the prebuild process from the package.json value.
$this->define( 'WC_ADMIN_VERSION_NUMBER', '1.7.0-dev' );
}
/**
* Load Localisation files.
*/
protected function load_plugin_textdomain() {
load_plugin_textdomain( 'woocommerce-admin', false, basename( dirname( __DIR__ ) ) . '/languages' );
}
/**
* Include WC Admin classes.
*/
public function includes() {
// Initialize the WC API extensions.
ReportsSync::init();
Install::init();
Events::instance()->init();
API\Init::instance();
ReportExporter::init();
// CRUD classes.
Notes::init();
// Initialize category lookup.
CategoryLookup::instance()->init();
// Admin note providers.
// @todo These should be bundled in the features/ folder, but loading them from there currently has a load order issue.
new Woo_Subscriptions_Notes();
new Historical_Data();
new Order_Milestones();
new Tracking_Opt_In();
new WooCommerce_Payments();
new Install_JP_And_WCS_Plugins();
new Draw_Attention();
new Home_Screen_Feedback();
new Set_Up_Additional_Payment_Types();
new Test_Checkout();
new Selling_Online_Courses();
Remote inbox notification delivery (https://github.com/woocommerce/woocommerce-admin/pull/4143) * Poll and persist specs * Process specs into admin notes * Add send at time rule processor * Fix style issues * Clear actions before recreating them to avoid dupes * Trigger the RINDS engine when a plugin is activated * Unit test SendAtTimeRuleProcessor * Implement plugins activated rule processor * Don't throw exception for unrecognised rule type. Also unit test around this. * add url_is_action_query to tell whether to wrap the URL in wc_admin_url() call or not * Add NOT rule * revert change to install.php * Drop unimplemented resend after dismissal rule * Add OR rule * Explicitly make "fail" a type of rule that can be applied to a spec * Add plugin version rule processor * Tidy up, don't need to pass $spec everywhere * Remove meta record for action state - not really needed * Move spec runner into it's own class, add some checks around re-unactioning a note * Replace if..else with switch * Just update the option * Check that the JSON coming in is an array * Change OR rule to accept an array of operands * Add Pass rule processor * Fix specs that are initially not published * Rename send at rule to publish after * Add publish before rule * Remove unused interface * Can't use PHP7's anonymous classes * New notification: How to draw attention to your online store * Add feature flag for rule-base inbox notes * rename everything to RemoteInboxNotifications from RINDS * Fix merge fail * fix test * Change preunactioned to pending * Move feature flag check into Events.php * Refactor reading a data source * Rename poll_data_sources function * Refactor EvaluateAndGetStatus::evaluate to take the rule evaluator directly * Check that the response body exists * Add validation and defensive checks * Add rule processor interface * Update note created time on status change * Move non-test dependencies into processor constructors * Update to proposed live URL * Remove setting icon as it's being deprecated Co-authored-by: Rebecca Scott <me@becdetat.com>
2020-06-05 01:51:25 +00:00
// Initialize RemoteInboxNotificationsEngine.
RemoteInboxNotificationsEngine::init();
}
/**
* Set up our admin hooks and plugin loader.
*/
protected function hooks() {
add_filter( 'woocommerce_admin_features', array( $this, 'replace_supported_features' ), 0 );
Loader::get_instance();
}
/**
* Get an array of dependency error messages.
*
* @return array
*/
protected function get_dependency_errors() {
$errors = array();
$wordpress_version = get_bloginfo( 'version' );
$minimum_wordpress_version = '5.3';
$minimum_woocommerce_version = '3.6';
$wordpress_minimum_met = version_compare( $wordpress_version, $minimum_wordpress_version, '>=' );
$woocommerce_minimum_met = class_exists( 'WooCommerce' ) && version_compare( WC_VERSION, $minimum_woocommerce_version, '>=' );
if ( ! $woocommerce_minimum_met ) {
$errors[] = sprintf(
/* translators: 1: URL of WooCommerce plugin, 2: The minimum WooCommerce version number */
__( 'The WooCommerce Admin feature plugin requires <a href="%1$s">WooCommerce</a> %2$s or greater to be installed and active.', 'woocommerce-admin' ),
'https://wordpress.org/plugins/woocommerce/',
$minimum_woocommerce_version
);
}
if ( ! $wordpress_minimum_met ) {
$errors[] = sprintf(
/* translators: 1: URL of WordPress.org, 2: The minimum WordPress version number */
__( 'The WooCommerce Admin feature plugin requires <a href="%1$s">WordPress</a> %2$s or greater to be installed and active.', 'woocommerce-admin' ),
'https://wordpress.org/',
$minimum_wordpress_version
);
}
return $errors;
}
/**
* Returns true if all dependencies for the wc-admin plugin are loaded.
*
* @return bool
*/
public function has_satisfied_dependencies() {
$dependency_errors = $this->get_dependency_errors();
return 0 === count( $dependency_errors );
}
/**
* Deactivates this plugin.
*/
public function deactivate_self() {
deactivate_plugins( plugin_basename( WC_ADMIN_PLUGIN_FILE ) );
unset( $_GET['activate'] ); // phpcs:ignore CSRF ok.
}
/**
* Notify users of the plugin requirements.
*/
public function render_dependencies_notice() {
$message = $this->get_dependency_errors();
printf( '<div class="error"><p>%s</p></div>', implode( ' ', $message ) ); /* phpcs:ignore xss ok. */
}
/**
* Overwrites the allowed features array using a local `feature-config.php` file.
*
* @param array $features Array of feature slugs.
*/
public function replace_supported_features( $features ) {
$feature_config = apply_filters( 'woocommerce_admin_get_feature_config', wc_admin_get_feature_config() );
$features = array_keys( array_filter( $feature_config ) );
return $features;
}
/**
* Define constant if not already set.
*
* @param string $name Constant name.
* @param string|bool $value Constant value.
*/
protected function define( $name, $value ) {
if ( ! defined( $name ) ) {
define( $name, $value );
}
}
/**
* Prevent cloning.
*/
private function __clone() {}
/**
* Prevent unserializing.
*/
public function __wakeup() {
die();
}
2019-08-14 23:35:02 +00:00
}