first commit

This commit is contained in:
2026-03-05 13:07:40 +01:00
commit 64ba0721ee
25709 changed files with 4691006 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
{
"name": "wpdesk\/wp-plugin-flow-common",
"description": "WP Desk Plugin Flow Common",
"license": "MIT",
"keywords": [
"wordpress",
"plugin"
],
"homepage": "https:\/\/gitlab.com\/wpdesk\/library\/wp-plugin-flow-common",
"authors": [
{
"name": "Krzysiek",
"email": "krzysiek@wpdesk.pl"
}
],
"config": {
"platform": {
"php": "7.0"
}
},
"require": {
"php": ">=7.0",
"wpdesk\/wp-basic-requirements": "^3.2.3",
"wpdesk\/wp-builder": "^2.0.0",
"wpdesk\/wp-wpdesk-tracker": "^3"
},
"require-dev": {
"phpunit\/phpunit": "<7",
"wp-coding-standards\/wpcs": "^0.14.1",
"squizlabs\/php_codesniffer": "^3.0.2",
"mockery\/mockery": "*",
"10up\/wp_mock": "*"
},
"autoload": {
"classmap": [
"src"
]
},
"autoload-dev": {
"classmap": [
"vendor\/wpdesk\/wp-basic-requirements",
"tests\/Stub"
]
},
"extra": {
"text-domain": "wp-plugin-flow-common",
"translations-folder": "lang",
"po-files": {
"pl_PL": "pl_PL.po"
}
},
"scripts": {
"phpunit-unit": "phpunit --configuration phpunit-unit.xml --coverage-text --colors=never",
"phpunit-unit-fast": "phpunit --configuration phpunit-unit.xml --no-coverage",
"phpunit-integration": "phpunit --configuration phpunit-integration.xml --coverage-text --colors=never",
"phpunit-integration-fast": "phpunit --configuration phpunit-integration.xml --no-coverage"
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace DPDVendor\WPDesk\Plugin\Flow\Initialization;
use DPDVendor\WPDesk\PluginBuilder\Plugin\Activateable;
use DPDVendor\WPDesk\PluginBuilder\Plugin\Deactivateable;
use DPDVendor\WPDesk\PluginBuilder\Plugin\SlimPlugin;
use DPDVendor\WPDesk\PluginBuilder\Storage\StorageFactory;
/**
* Helps with plugin building concepts.
*
* @package WPDesk\Plugin\Flow\Initialization
*/
trait BuilderTrait
{
/**
* Build plugin from info.
*
* @param \WPDesk_Plugin_Info $plugin_info
*
* @return SlimPlugin
*/
private function build_plugin(\DPDVendor\WPDesk_Plugin_Info $plugin_info)
{
$class_name = \apply_filters('wp_builder_plugin_class', $plugin_info->get_class_name());
/** @var SlimPlugin $plugin */
$plugin = new $class_name($plugin_info);
return $plugin;
}
/**
* Initialize WP register hooks that have to be fire before any other.
*
* @param \WPDesk_Plugin_Info $plugin_info
* @param SlimPlugin $plugin
*
* @return SlimPlugin
*/
private function init_register_hooks(\DPDVendor\WPDesk_Plugin_Info $plugin_info, \DPDVendor\WPDesk\PluginBuilder\Plugin\SlimPlugin $plugin)
{
if ($plugin instanceof \DPDVendor\WPDesk\PluginBuilder\Plugin\Activateable) {
\register_activation_hook($plugin_info->get_plugin_file_name(), [$plugin, 'activate']);
}
if ($plugin instanceof \DPDVendor\WPDesk\PluginBuilder\Plugin\Deactivateable) {
\register_deactivation_hook($plugin_info->get_plugin_file_name(), [$plugin, 'deactivate']);
}
return $plugin;
}
/**
* Store plugin for others to use.
*
* @param SlimPlugin $plugin
*/
private function store_plugin(\DPDVendor\WPDesk\PluginBuilder\Plugin\SlimPlugin $plugin)
{
$storageFactory = new \DPDVendor\WPDesk\PluginBuilder\Storage\StorageFactory();
$storageFactory->create_storage()->add_to_storage(\get_class($plugin), $plugin);
}
/**
* Init integration layer of the plugin.
*
* @param SlimPlugin $plugin
*/
private function init_plugin(\DPDVendor\WPDesk\PluginBuilder\Plugin\SlimPlugin $plugin)
{
\do_action('wp_builder_before_plugin_init', $plugin);
$plugin->init();
\do_action('wp_builder_before_init', $plugin);
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace DPDVendor\WPDesk\Plugin\Flow\Initialization;
/**
* Interface for factory of plugin initialization strategy
*/
interface InitializationFactory
{
/**
* @param \WPDesk_Plugin_Info $info
*
* @return InitializationStrategy
*/
public function create_initialization_strategy(\DPDVendor\WPDesk_Plugin_Info $info);
}

View File

@@ -0,0 +1,27 @@
<?php
namespace DPDVendor\WPDesk\Plugin\Flow\Initialization;
use DPDVendor\WPDesk\PluginBuilder\Plugin\SlimPlugin;
/**
* Interface for initialization strategy for plugin. How to initialize it?
*/
interface InitializationStrategy
{
/**
* Run tasks that prepares plugin to work. Have to run before plugin loaded.
*
* @param \WPDesk_Plugin_Info $plugin_info
*
* @return SlimPlugin
*/
public function run_before_init(\DPDVendor\WPDesk_Plugin_Info $plugin_info);
/**
* Run task that integrates plugin with other dependencies. Can be run in plugins_loaded.
*
* @param \WPDesk_Plugin_Info $plugin_info
*
* @return SlimPlugin
*/
public function run_init(\DPDVendor\WPDesk_Plugin_Info $plugin_info);
}

View File

@@ -0,0 +1,48 @@
<?php
namespace DPDVendor\WPDesk\Plugin\Flow\Initialization;
/**
* Can disable shared plugin before it's loaded using plugin filename
*/
class PluginDisablerByFileTrait
{
/** @var string */
private $plugin_file;
/**
* @param string $plugin_file
*/
public function __construct($plugin_file)
{
$this->plugin_file = $plugin_file;
}
/**
* @return void
*/
public function disable()
{
/**
* @param WPDesk_Loader[] $loaders
*
* @return array
*/
$false_for_helper = function ($loaders) {
return \array_filter($loaders, function ($loader) {
try {
// BIG HACK TO GET PRIVATE PROPERTY
$reflection = new \ReflectionClass($loader);
$property = $reflection->getProperty('loader_info');
$property->setAccessible(\true);
/** @var WPDesk_Composer_Loader_Info $inner_info */
$inner_info = $property->getValue($loader);
$plugin_info = $inner_info->get_plugin_info();
return \basename($plugin_info->get_plugin_file_name()) !== \basename($this->plugin_file);
} catch (\Exception $e) {
return \true;
}
});
};
\add_filter('wp_autoloader_loader_loaders_to_load', $false_for_helper);
\add_filter('wp_autoloader_loader_loaders_to_create', $false_for_helper);
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace DPDVendor\WPDesk\Plugin\Flow\Initialization\Simple;
use DPDVendor\WPDesk\Plugin\Flow\Initialization\InitializationFactory;
use DPDVendor\WPDesk\Plugin\Flow\Initialization\InitializationStrategy;
/**
* Can decide if strategy is for free plugin or paid plugin
*/
class SimpleFactory implements \DPDVendor\WPDesk\Plugin\Flow\Initialization\InitializationFactory
{
/** @var bool */
private $free;
/**
* @param bool $free True for free/repository plugin
*/
public function __construct($free = \false)
{
$this->free = $free;
}
/**
* Create strategy according to the given flag
*
* @param \WPDesk_Plugin_Info $info
*
* @return InitializationStrategy
*/
public function create_initialization_strategy(\DPDVendor\WPDesk_Plugin_Info $info)
{
if ($this->free) {
return new \DPDVendor\WPDesk\Plugin\Flow\Initialization\Simple\SimpleFreeStrategy($info);
}
return new \DPDVendor\WPDesk\Plugin\Flow\Initialization\Simple\SimplePaidStrategy($info);
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace DPDVendor\WPDesk\Plugin\Flow\Initialization\Simple;
use DPDVendor\WPDesk\Plugin\Flow\Initialization\ActivationTrait;
use DPDVendor\WPDesk\Plugin\Flow\Initialization\BuilderTrait;
use DPDVendor\WPDesk\Plugin\Flow\Initialization\InitializationStrategy;
use DPDVendor\WPDesk\PluginBuilder\Plugin\SlimPlugin;
/**
* Initialize free plugin
* - just build it already
*/
class SimpleFreeStrategy implements \DPDVendor\WPDesk\Plugin\Flow\Initialization\InitializationStrategy
{
use TrackerInstanceAsFilterTrait;
use BuilderTrait;
/** @var \WPDesk_Plugin_Info */
private $plugin_info;
/** @var SlimPlugin */
private $plugin;
public function __construct(\DPDVendor\WPDesk_Plugin_Info $plugin_info)
{
$this->plugin_info = $plugin_info;
}
/**
* Run tasks that prepares plugin to work. Have to run before plugin loaded.
*
* @param \WPDesk_Plugin_Info $plugin_info
*
* @return SlimPlugin
*/
public function run_before_init(\DPDVendor\WPDesk_Plugin_Info $plugin_info)
{
$this->plugin = $this->build_plugin($plugin_info);
$this->init_register_hooks($plugin_info, $this->plugin);
}
/**
* Run task that integrates plugin with other dependencies. Can be run in plugins_loaded.
*
* @param \WPDesk_Plugin_Info $plugin_info
*
* @return SlimPlugin
*/
public function run_init(\DPDVendor\WPDesk_Plugin_Info $plugin_info)
{
if (!$this->plugin) {
$this->plugin = $this->build_plugin($plugin_info);
}
$this->prepare_tracker_action();
$this->store_plugin($this->plugin);
$this->init_plugin($this->plugin);
return $this->plugin;
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace DPDVendor\WPDesk\Plugin\Flow\Initialization\Simple;
use DPDVendor\WPDesk\Helper\HelperRemover;
use DPDVendor\WPDesk\Helper\PrefixedHelperAsLibrary;
use DPDVendor\WPDesk\License\PluginRegistrator;
use DPDVendor\WPDesk\Plugin\Flow\Initialization\ActivationTrait;
use DPDVendor\WPDesk\Plugin\Flow\Initialization\BuilderTrait;
use DPDVendor\WPDesk\Plugin\Flow\Initialization\PluginDisablerByFileTrait;
use DPDVendor\WPDesk\Plugin\Flow\Initialization\InitializationStrategy;
use DPDVendor\WPDesk\PluginBuilder\Plugin\ActivationAware;
use DPDVendor\WPDesk\PluginBuilder\Plugin\SlimPlugin;
/**
* Initialize standard paid plugin
* - register to helper
* - initialize helper
* - build with info about plugin active flag
*/
class SimplePaidStrategy implements \DPDVendor\WPDesk\Plugin\Flow\Initialization\InitializationStrategy
{
use TrackerInstanceAsFilterTrait;
use BuilderTrait;
/** @var \WPDesk_Plugin_Info */
private $plugin_info;
/** @var SlimPlugin */
private $plugin;
public function __construct(\DPDVendor\WPDesk_Plugin_Info $plugin_info)
{
$this->plugin_info = $plugin_info;
}
/**
* Run tasks that prepares plugin to work. Have to run before plugin loaded.
*
* @param \WPDesk_Plugin_Info $plugin_info
*
* @return SlimPlugin
*/
public function run_before_init(\DPDVendor\WPDesk_Plugin_Info $plugin_info)
{
$this->plugin = $this->build_plugin($plugin_info);
$this->init_register_hooks($plugin_info, $this->plugin);
}
/**
* Run task that integrates plugin with other dependencies. Can be run in plugins_loaded.
*
* @param \WPDesk_Plugin_Info $plugin_info
*
* @return SlimPlugin
*/
public function run_init(\DPDVendor\WPDesk_Plugin_Info $plugin_info)
{
if (!$this->plugin) {
$this->plugin = $this->build_plugin($plugin_info);
}
$this->prepare_tracker_action();
$registrator = $this->register_plugin();
\add_action('plugins_loaded', function () use($registrator) {
$is_plugin_subscription_active = $registrator instanceof \DPDVendor\WPDesk\License\PluginRegistrator && $registrator->is_active();
if ($this->plugin instanceof \DPDVendor\WPDesk\PluginBuilder\Plugin\ActivationAware && $is_plugin_subscription_active) {
$this->plugin->set_active();
}
$this->store_plugin($this->plugin);
$this->init_plugin($this->plugin);
}, $priority_before_flow_2_5_after_2_6 = -45);
return $this->plugin;
}
/**
* Register plugin for subscriptions and updates
*
* @return PluginRegistrator
*
*/
private function register_plugin()
{
if (\apply_filters('wpdesk_can_register_plugin', \true, $this->plugin_info)) {
$registrator = new \DPDVendor\WPDesk\License\PluginRegistrator($this->plugin_info);
$registrator->initialize_license_manager();
return $registrator;
}
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace DPDVendor\WPDesk\Plugin\Flow\Initialization\Simple;
/**
* Trait helps with tracker initialization
*
* @package WPDesk\Plugin\Flow\Initialization\Simple\
*/
trait TrackerInstanceAsFilterTrait
{
/** @var \WPDesk_Tracker_Interface */
private static $tracker_instance;
/**
* Returns filter action name for tracker instance
*
* @return string
*/
private function get_tracker_action_name()
{
return 'wpdesk_tracker_instance';
}
/**
* Returns version of the tracker. Inc when trackker is changed and should be instantiated fist.
*
* @return int
*/
private function get_tracker_version()
{
return 2;
}
/**
* @return \WPDesk_Tracker_Interface
*/
private function get_tracker_instance()
{
return \apply_filters($this->get_tracker_action_name(), null);
}
/**
* Prepare tracker to be instantiated using wpdesk_tracker_instance filter
*
* @return void|\WPDesk_Tracker
*/
private function prepare_tracker_action()
{
\class_exists(\WPDesk_Tracker_Factory::class);
//autoload this class
\add_filter($this->get_tracker_action_name(), function ($tracker_instance) {
if (\is_object($tracker_instance)) {
return $tracker_instance;
}
if (\is_object(self::$tracker_instance)) {
return self::$tracker_instance;
}
if (\apply_filters('wpdesk_can_start_tracker', \true, $this->plugin_info)) {
$tracker_factory = new \DPDVendor\WPDesk_Tracker_Factory_Prefixed();
self::$tracker_instance = $tracker_factory->create_tracker(\basename($this->plugin_info->get_plugin_file_name()));
\do_action('wpdesk_tracker_started', self::$tracker_instance, $this->plugin_info);
return self::$tracker_instance;
}
}, 10 - $this->get_tracker_version());
}
}

View File

@@ -0,0 +1,156 @@
<?php
namespace DPDVendor\WPDesk\Plugin\Flow;
use DPDVendor\WPDesk\Plugin\Flow\Initialization\InitializationFactory;
/**
* Bootstrap plugin loading
* - check requirements
* - prepare plugin info
* - delegate plugin building to the initializator
*/
final class PluginBootstrap
{
const LIBRARY_TEXT_DOMAIN = 'woocommerce-dpd';
const PRIORITY_BEFORE_FLOW_2_5 = -50;
/** @var string */
private $plugin_version;
/** @var string */
private $plugin_name;
/** @var string */
private $plugin_class_name;
/** @var string */
private $plugin_text_domain;
/** @var string */
private $plugin_dir;
/** @var string */
private $plugin_file;
/** @var array */
private $requirements;
/** @var string */
private $product_id;
/** @var array */
private $plugin_shops;
/**
* Factory to build strategy how initialize that plugin
*
* @var InitializationFactory
*/
private $initialization_factory;
/**
* WPDesk_Plugin_Bootstrap constructor.
*
* @param string $plugin_version
* @param string $plugin_release_timestamp
* @param string $plugin_name
* @param string $plugin_class_name
* @param string $plugin_text_domain
* @param string $plugin_dir
* @param string $plugin_file
* @param array $requirements
* @param string $product_id
* @param InitializationFactory $build_factory
* @param array $plugin_shops
*/
public function __construct($plugin_version, $plugin_release_timestamp, $plugin_name, $plugin_class_name, $plugin_text_domain, $plugin_dir, $plugin_file, array $requirements, $product_id, \DPDVendor\WPDesk\Plugin\Flow\Initialization\InitializationFactory $build_factory, $plugin_shops)
{
$this->plugin_version = $plugin_version;
$this->plugin_name = $plugin_name;
$this->plugin_class_name = $plugin_class_name;
$this->plugin_text_domain = $plugin_text_domain;
$this->plugin_dir = $plugin_dir;
$this->plugin_file = $plugin_file;
$this->requirements = $requirements;
$this->product_id = $product_id;
$this->initialization_factory = $build_factory;
$this->plugin_shops = $plugin_shops;
}
/**
* Run the plugin bootstrap
*/
public function run()
{
$plugin_info = $this->get_plugin_info();
$this->init_translations($plugin_info);
$strategy = $this->initialization_factory->create_initialization_strategy($plugin_info);
$requirements_checker = $this->create_requirements_checker();
if ($requirements_checker->are_requirements_met()) {
$strategy->run_before_init($plugin_info);
}
$this->add_activation_hook_for_save_activation_date();
\add_action('plugins_loaded', static function () use($strategy, $requirements_checker, $plugin_info) {
if ($requirements_checker->are_requirements_met()) {
$strategy->run_init($plugin_info);
} else {
$requirements_checker->render_notices();
}
}, self::PRIORITY_BEFORE_FLOW_2_5);
\add_action('before_woocommerce_init', static function () use($plugin_info) {
$features_util_class = '\\' . 'Automattic' . '\\' . 'WooCommerce' . '\\' . 'Utilities' . '\\' . 'FeaturesUtil';
if (\class_exists($features_util_class)) {
$features_util_class::declare_compatibility('custom_order_tables', $plugin_info->get_plugin_file_name(), \true);
}
});
}
/**
* Initialize activated_plugin action.
* Action stores plugin activation date.
* Example option name: plugin_activation_flexible-shipping/flexible-shipping.php
*/
private function add_activation_hook_for_save_activation_date()
{
\add_action('activated_plugin', static function ($plugin_file, $network_wide = \false) {
if (!$network_wide) {
$option_name = 'plugin_activation_' . $plugin_file;
$activation_date = \get_option($option_name, '');
if ('' === $activation_date) {
$activation_date = \current_time('mysql');
\update_option($option_name, $activation_date);
}
}
});
}
/**
* Adds text domain used in a library
*/
private function init_translations(\DPDVendor\WPDesk_Plugin_Info $plugin_info)
{
$lang_dir = 'lang';
if (\method_exists($plugin_info, 'get_language_dir')) {
$lang_dir = $plugin_info->get_language_dir();
}
\load_plugin_textdomain($plugin_info->get_text_domain(), \false, \basename($plugin_info->get_plugin_dir()) . "/{$lang_dir}/");
}
/**
* Factory method creates requirement checker to run the checks
*
* @return \WPDesk_Requirement_Checker
*/
private function create_requirements_checker()
{
/** @var \WPDesk_Requirement_Checker_Factory $requirements_checker_factory */
$requirements_checker_factory = new \DPDVendor\WPDesk_Basic_Requirement_Checker_Factory();
return $requirements_checker_factory->create_from_requirement_array(__FILE__, $this->plugin_name, $this->requirements, $this->plugin_text_domain);
}
/**
* Factory method creates \WPDesk_Plugin_Info to bootstrap info about plugin in one place
*
* TODO: move to WPDesk_Plugin_Info factory
*
* @return \WPDesk_Plugin_Info
*/
private function get_plugin_info()
{
$plugin_info = new \DPDVendor\WPDesk_Plugin_Info();
$plugin_info->set_plugin_file_name(\plugin_basename($this->plugin_file));
$plugin_info->set_plugin_name($this->plugin_name);
$plugin_info->set_plugin_dir($this->plugin_dir);
$plugin_info->set_class_name($this->plugin_class_name);
$plugin_info->set_version($this->plugin_version);
$plugin_info->set_product_id($this->product_id);
$plugin_info->set_text_domain($this->plugin_text_domain);
$plugin_info->set_plugin_url(\plugins_url(\dirname(\plugin_basename($this->plugin_file))));
$plugin_info->set_plugin_shops($this->plugin_shops);
return $plugin_info;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace DPDVendor;
/**
* @var string $plugin_version
* @var string $plugin_name
* @var string $plugin_class_name
* @var string $plugin_text_domain
* @var string $plugin_dir
* @var string $plugin_file
* @var array $requirements
* @var string $product_id
*/
if (!\defined('ABSPATH')) {
die;
}
// Code in PHP >= 5.3 but understandable by older parsers
if (\PHP_VERSION_ID > 50300) {
require_once $plugin_dir . '/vendor/autoload.php';
$plugin_init_factory = new \DPDVendor\WPDesk\Plugin\Flow\Initialization\Simple\SimpleFactory(\true);
}
require \dirname(__FILE__) . '/plugin-init-php52.php';

View File

@@ -0,0 +1,49 @@
<?php
namespace DPDVendor;
/**
* @var string $plugin_version
* @var string $plugin_name
* @var string $plugin_class_name
* @var string $plugin_text_domain
* @var string $plugin_dir
* @var string $plugin_file
* @var array $requirements
* @var string $product_id
* @var WPDesk\Plugin\Flow\Initialization\InitializationFactory|void $plugin_init_factory
*/
if (!\defined('ABSPATH')) {
die;
}
// Code in PHP >= 5.3 but understandable by older parsers
if (\PHP_VERSION_ID > 50300) {
require_once $plugin_dir . '/vendor/autoload.php';
if (!isset($plugin_init_factory)) {
$plugin_init_factory = new \DPDVendor\WPDesk\Plugin\Flow\Initialization\Simple\SimpleFactory();
}
if (!isset($plugin_shops) || !\is_array($plugin_shops)) {
$plugin_shops = array();
}
$bootstrap = new \DPDVendor\WPDesk\Plugin\Flow\PluginBootstrap(
$plugin_version,
null,
// deprecated
$plugin_name,
$plugin_class_name,
$plugin_text_domain,
$plugin_dir,
$plugin_file,
$requirements,
$product_id,
$plugin_init_factory,
$plugin_shops
);
$bootstrap->run();
// all optional vars must be cleared
unset($plugin_init_factory);
} else {
/** @noinspection PhpDeprecationInspection */
$php52_function = \create_function('', 'echo sprintf( __("<p><strong style=\'color: red;\'>PHP version is older than 5.3 so no WP Desk plugins will work. Please contact your host and ask them to upgrade. </strong></p>", \'wp-plugin-flow-common\') );');
\add_action('admin_notices', $php52_function);
}