Skip to content
Snippets Groups Projects
Commit b27f59d0 authored by Grzegorz Rola's avatar Grzegorz Rola
Browse files

feature(init): init

parents
No related branches found
No related tags found
No related merge requests found
Pipeline #8641 failed with stages
in 3 minutes and 52 seconds
Showing
with 797 additions and 0 deletions
tests/ export-ignore
vendor/ export-ignore
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.git/ export-ignore
.gitlab-ci.yml export-ignore
.idea export-ignore
apigen.neon export-ignore
build-coverage/ export-ignore
docs/ export-ignore
LICENSE.md export-ignore
phpcs.xml.dist export-ignore
phpunit-integration.xml export-ignore
phpunit-unit.xml export-ignore
/vendor/
.idea
build-coverage
swagger
/composer.lock
variables:
DISABLE_ACCEPTANCE: "1"
DISABLE_FUNCTIONAL: "1"
IS_LIBRARY: 1
DISABLE_PHP_5_5: 1
DISABLE_CODECEPTION: 1
include: 'https://gitlab.com/wpdesk/gitlab-ci/raw/master/gitlab-ci-1.2.yml'
## [1.0.0] - 2022-05-21
### Added
- Init
\ No newline at end of file
[![pipeline status](https://gitlab.com/wpdesk/wp-plugin-flow-common/badges/master/pipeline.svg)](https://gitlab.com/wpdesk/wp-plugin-flow-common/commits/master)
Integration: [![coverage report](https://gitlab.com/wpdesk/wp-plugin-flow-common/badges/master/coverage.svg?job=integration+test+lastest+coverage)](https://gitlab.com/wpdesk/wp-plugin-flow-common/commits/master)
Unit: [![coverage report](https://gitlab.com/wpdesk/wp-plugin-flow-common/badges/master/coverage.svg?job=unit+test+lastest+coverage)](https://gitlab.com/wpdesk/wp-plugin-flow-common/commits/master)
wp-plugin-flow-common
====================
destination: docs
templateConfig: /app/theme-woocommerce/config.neon
extensions: [php]
source:
- src
exclude:
- vendor
- tests
- languages
charset: [UTF-8]
main: Wordpress plugin
title: Plugin template more info
baseUrl: "/"
templateTheme: default
php: false
sourceCode: false
tree: true
deprecated: false
todo: false
download: false
accessLevels:
- public
- private
- protected
\ No newline at end of file
{
"name": "wpdesk/wp-plugin-flow-common",
"authors": [
{
"name": "Krzysiek",
"email": "krzysiek@wpdesk.pl"
}
],
"require": {
"php": ">=7.0",
"wpdesk/wp-basic-requirements": "^3.2.3",
"wpdesk/wp-builder": "^2.0.0"
},
"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"
}
}
*
!.gitignore
!pl_PL.po
!index.php
\ No newline at end of file
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-05-21 11:08+0200\n"
"PO-Revision-Date: 2022-05-21 11:08+0200\n"
"Last-Translator: Maciej Swoboda <maciej.swoboda@gmail.com>\n"
"Language-Team: Maciej Swoboda <maciej.swoboda@gmail.com>\n"
"Language: pl_PL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Basepath: ..\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;"
"_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
"X-Generator: Poedit 2.3\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SearchPathExcluded-0: *.js\n"
<phpunit bootstrap="tests/integration/bootstrap.php"
backupGlobals="false"
>
<testsuites>
<testsuite>
<directory prefix="Test" suffix=".php">./tests/integration</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src</directory>
</whitelist>
</filter>
<logging>
<log type="junit" target="build-coverage/report.junit.xml"/>
<log type="coverage-html" target="build-coverage/coverage" charset="UTF-8" yui="true" highlight="true"/>
<log type="coverage-text" target="build-coverage/coverage.txt"/>
<log type="coverage-clover" target="build-coverage/clover.xml"/>
</logging>
<php>
<env name="WP_DEVELOP_DIR" value="/tmp/wordpress-develop"/>
<env name="WC_DEVELOP_DIR" value="/tmp/woocommerce"/>
</php>
</phpunit>
\ No newline at end of file
<phpunit bootstrap="tests/unit/bootstrap.php">
<testsuites>
<testsuite>
<directory prefix="Test" suffix=".php">./tests/unit/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src</directory>
</whitelist>
</filter>
<logging>
<log type="junit" target="build-coverage/report.junit.xml"/>
<log type="coverage-html" target="build-coverage/coverage" charset="UTF-8" yui="true" highlight="true"/>
<log type="coverage-text" target="build-coverage/coverage.txt"/>
<log type="coverage-clover" target="build-coverage/clover.xml"/>
</logging>
</phpunit>
<?php
namespace WPDesk\Plugin\Flow\Initialization;
use WPDesk\PluginBuilder\Plugin\Activateable;
use WPDesk\PluginBuilder\Plugin\Deactivateable;
use WPDesk\PluginBuilder\Plugin\SlimPlugin;
use 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( \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( \WPDesk_Plugin_Info $plugin_info, SlimPlugin $plugin ) {
if ( $plugin instanceof Activateable ) {
register_activation_hook( $plugin_info->get_plugin_file_name(), [ $plugin, 'activate' ] );
}
if ( $plugin instanceof 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( SlimPlugin $plugin ) {
$storageFactory = new StorageFactory();
$storageFactory->create_storage()->add_to_storage( get_class( $plugin ), $plugin );
}
/**
* Init integration layer of the plugin.
*
* @param SlimPlugin $plugin
*/
private function init_plugin( SlimPlugin $plugin ) {
do_action( 'wp_builder_before_plugin_init', $plugin );
$plugin->init();
do_action( 'wp_builder_before_init', $plugin );
}
}
\ No newline at end of file
<?php
namespace 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( \WPDesk_Plugin_Info $info );
}
\ No newline at end of file
<?php
namespace WPDesk\Plugin\Flow\Initialization;
use 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( \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( \WPDesk_Plugin_Info $plugin_info );
}
\ No newline at end of file
<?php
namespace 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 );
}
}
\ No newline at end of file
<?php
namespace WPDesk\Plugin\Flow\Initialization\Simple;
use WPDesk\Plugin\Flow\Initialization\InitializationFactory;
use WPDesk\Plugin\Flow\Initialization\InitializationStrategy;
/**
* Can decide if strategy is for free plugin or paid plugin
*/
class SimpleFactory implements 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( \WPDesk_Plugin_Info $info ) {
if ( $this->free ) {
return new SimpleFreeStrategy( $info );
}
return new SimplePaidStrategy( $info );
}
}
\ No newline at end of file
<?php
namespace WPDesk\Plugin\Flow\Initialization\Simple;
use WPDesk\Plugin\Flow\Initialization\ActivationTrait;
use WPDesk\Plugin\Flow\Initialization\BuilderTrait;
use WPDesk\Plugin\Flow\Initialization\InitializationStrategy;
use WPDesk\PluginBuilder\Plugin\SlimPlugin;
/**
* Initialize free plugin
* - just build it already
*/
class SimpleFreeStrategy implements InitializationStrategy {
use TrackerInstanceAsFilterTrait;
use BuilderTrait;
/** @var \WPDesk_Plugin_Info */
private $plugin_info;
/** @var SlimPlugin */
private $plugin;
public function __construct( \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( \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( \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;
}
}
\ No newline at end of file
<?php
namespace WPDesk\Plugin\Flow\Initialization\Simple;
use WPDesk\Helper\HelperRemover;
use WPDesk\Helper\PrefixedHelperAsLibrary;
use WPDesk\License\PluginRegistrator;
use WPDesk\Plugin\Flow\Initialization\ActivationTrait;
use WPDesk\Plugin\Flow\Initialization\BuilderTrait;
use WPDesk\Plugin\Flow\Initialization\PluginDisablerByFileTrait;
use WPDesk\Plugin\Flow\Initialization\InitializationStrategy;
use WPDesk\PluginBuilder\Plugin\ActivationAware;
use WPDesk\PluginBuilder\Plugin\SlimPlugin;
/**
* Initialize standard paid plugin
* - register to helper
* - initialize helper
* - build with info about plugin active flag
*/
class SimplePaidStrategy implements InitializationStrategy {
use TrackerInstanceAsFilterTrait;
use BuilderTrait;
/** @var \WPDesk_Plugin_Info */
private $plugin_info;
/** @var SlimPlugin */
private $plugin;
public function __construct( \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( \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( \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 PluginRegistrator && $registrator->is_active();
if ( $this->plugin instanceof 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 PluginRegistrator( $this->plugin_info );
$registrator->initialize_license_manager();
return $registrator;
}
}
}
\ No newline at end of file
<?php
namespace 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 \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() );
}
}
\ No newline at end of file
<?php
namespace WPDesk\Plugin\Flow;
use 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 = 'wp-plugin-flow-common';
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,
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
);
}
/**
* 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( \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 \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 \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;
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment