first commit

This commit is contained in:
2026-04-28 15:13:50 +02:00
commit a95acc355b
63745 changed files with 9487948 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
{
"name": "wpdesk\/ltv-dashboard-widget",
"description": "Library for displaying ltv widget in WordPress dashboard.",
"license": "MIT",
"keywords": [
"wordpress",
"notice",
"admin"
],
"minimum-stability": "stable",
"config": {
"platform": {
"php": "7.4"
}
},
"require": {
"php": ">=7.4"
},
"require-dev": {
"phpunit\/phpunit": "^8",
"wp-coding-standards\/wpcs": "^0.14.1",
"squizlabs\/php_codesniffer": "^3.0.2",
"mockery\/mockery": "*",
"10up\/wp_mock": "*",
"wimg\/php-compatibility": "^8"
},
"autoload": {
"psr-4": {
"Przelewy24Vendor\\WPDesk\\Dashboard\\": "src\/"
}
},
"extra": {
"text-domain": "wpdesk_ltv_dashboard_widget",
"translations-folder": "lang",
"po-files": {
"pl_PL": "wpdesk-ltv-dashboard-widget-pl_PL.po"
}
},
"autoload-dev": {},
"scripts": {
"phpcs": "phpcs",
"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,316 @@
<?php
namespace Przelewy24Vendor\WPDesk\Dashboard;
final class DashboardWidget
{
const ID = 'woocommerce-gateway-przelewy24';
const WP_DESK_CARE_ID = 296222;
const AUTOPAY_ID = 349143;
const MUTEX_HOOK = 'wpdesk/ltvdashboard/initialized';
const PL_LOCALE = 'pl_PL';
/**
*
* @var string
*/
private $widget_title = '';
/**
*
* @var bool
*/
private $show_widget_header = \true;
/**
*
* @var bool
*/
private $show_widget_footer = \true;
/**
*
* @var int
*/
private $plugins_limit = 3;
/**
*
* @var int
*/
private $cache_timeout = 0;
/**
*
* @var int
*/
private $cache_retry_timeout = 0;
/**
*
* @var string
*/
private $locale;
/**
*
* @var array
*/
private $cache_data = [];
/**
*
* @var string
*/
private $utm_base = 'utm_source=dashboard-metabox&utm_campaign=dashboard-metabox';
public function __construct()
{
$this->cache_timeout = 24 * 60 * 60;
$this->cache_retry_timeout = 6 * 60 * 60;
$this->locale = get_user_locale();
}
private static function get_default_widget_title(): string
{
return __('Grow your business with WP Desk', 'woocommerce-gateway-przelewy24');
}
public function set_widget_title(string $title)
{
$this->widget_title = $title;
}
public function show_widget_header(bool $bool)
{
$this->show_widget_header = $bool;
}
public function show_widget_footer(bool $bool)
{
$this->show_widget_footer = $bool;
}
public function set_plugins_limit(int $limit)
{
$this->plugins_limit = $limit;
}
public function set_cache_timeout(int $timeout)
{
$this->cache_timeout = $timeout;
}
public function set_locale(string $locale)
{
$this->locale = $locale;
}
public function set_utm_base(string $utm_base)
{
$this->utm_base = $utm_base;
}
public function hooks()
{
if (apply_filters('wpdesk/ltvdashboard/disable', \false) === \true) {
return;
}
if (apply_filters(self::MUTEX_HOOK, \false) === \false) {
add_filter(self::MUTEX_HOOK, '__return_true');
add_action('wp_dashboard_setup', [$this, 'add_widget']);
}
}
public function add_widget()
{
wp_add_dashboard_widget(self::ID, $this->widget_title ?: self::get_default_widget_title(), [$this, 'widget_output'], null, null, 'normal', 'high');
}
private function get_all_plugins_dirs(): array
{
$all_plugins = array_keys(get_plugins());
return array_map('dirname', $all_plugins);
}
private function filter_plugins_to_show(array $plugins, int $limit, bool $for_free = \false): array
{
if ($limit === 0) {
return [];
}
usort($plugins, static function ($a, $b) {
$a['priority'] = $a['priority'] ?? '0';
$b['priority'] = $b['priority'] ?? '0';
return strnatcmp($a['priority'], $b['priority']);
});
$installed_plugins_dir = $this->get_all_plugins_dirs();
$plugins = array_filter($plugins, static function ($plugin) use ($installed_plugins_dir, $for_free) {
$installed = !\in_array($plugin['slug'], $installed_plugins_dir, \true);
if ($for_free) {
$installed = \in_array($plugin['free_plugin_slug'], $installed_plugins_dir, \true) && $installed;
}
return $installed;
});
return array_slice($plugins, 0, $limit);
}
private function get_server(): string
{
$locale = $this->locale;
if ($locale === self::PL_LOCALE) {
return 'www.wpdesk.pl';
}
return 'www.wpdesk.net';
}
private function has_cached_data(): bool
{
if ($this->cache_timeout <= 0) {
return \false;
}
$cache_data = $this->get_raw_cached_data();
return null === $cache_data || \is_array($cache_data);
}
private function get_cached_data_key(): string
{
return sprintf('wpdesk_ltv_%1$s_%2$s', self::ID, $this->locale);
}
/**
*
* @return mixed
*/
private function get_raw_cached_data()
{
return get_transient($this->get_cached_data_key());
}
private function get_cached_data(): array
{
if (!empty($this->cache_data)) {
return $this->cache_data;
}
$cache_data = $this->get_raw_cached_data();
$this->cache_data = is_array($cache_data) ? $cache_data : [];
return $this->cache_data;
}
/**
*
* @param mixed $data
* @param int $timeout
*
* @return void
*/
private function set_data_to_cache($data, int $timeout)
{
$cache_key = $this->get_cached_data_key();
set_transient($cache_key, $data, $timeout);
}
private function get_widget_data(): array
{
if ($this->has_cached_data()) {
return $this->get_cached_data();
}
$response_data = $this->get_widget_data_from_remote();
if ($response_data !== null) {
$this->set_data_to_cache($response_data, $this->cache_timeout);
return $response_data;
} else {
$this->set_data_to_cache(null, $this->cache_retry_timeout);
}
return [];
}
/**
* @return array|null
*/
private function get_widget_data_from_remote()
{
$response = wp_remote_get(sprintf('https://%s?wpdesk_api=1&t=1', $this->get_server()), ['timeout' => 10, 'sslverify' => \false]);
if (!is_array($response)) {
return null;
}
$ret = json_decode($response['body'], \true);
if (!$ret || !is_array($ret)) {
return null;
}
$for_free_plugins = $this->filter_plugins_to_show($ret['for_free_plugins'] ?? [], $this->plugins_limit, \true);
$plugins = $this->filter_plugins_to_show($ret['plugins'] ?? [], $this->plugins_limit - count($for_free_plugins), \false);
return ['header' => $ret['header'] ?? null, 'for_free_plugins' => $for_free_plugins, 'plugins' => $plugins, 'footer' => $ret['footer'] ?? null];
}
public function widget_output()
{
$widget_data = $this->get_widget_data();
if (!empty($widget_data)) {
echo '<div class="wpdesk-ltv-dashboard-widget">';
if ($this->show_widget_header && $widget_data['header']) {
echo wp_kses_post($widget_data['header']);
}
echo '<ul class="ltv-rows">';
$this->show_plugins($widget_data['for_free_plugins'] ?? [], \true);
$this->show_plugins($widget_data['plugins'] ?? [], \false);
echo '</ul>';
echo '<div class="ltv-footer">';
if ($this->show_widget_footer && $widget_data['footer']) {
echo wp_kses_post($widget_data['footer']);
}
echo '</div>';
echo '</div>';
?>
<style>
.wpdesk-ltv-dashboard-widget .ltv-rows {
margin-left: -12px;
margin-right: -12px;
}
.wpdesk-ltv-dashboard-widget .ltv-row {
padding: 6px 12px 24px;
}
.wpdesk-ltv-dashboard-widget .ltv-row:nth-child(odd) {
background-color: #f6f7f7;
}
.wpdesk-ltv-dashboard-widget .ltv-row-description p {
margin-top: 6px;
}
.wpdesk-ltv-dashboard-widget img {
display: block;
margin: 0 auto 10px;
width: 250px;
max-width: 100%;
}
.wpdesk-ltv-dashboard-widget .ltv-buttons {
display: flex;
justify-content: space-around;
}
.ltv-buttons a.button.button-large {
width: 100%;
text-align: center;
}
.wpdesk-ltv-dashboard-widget .ltv-footer {
margin: 0 -12px;
padding: 0 12px;
}
.wpdesk-ltv-dashboard-widget .ltv-footer p {
margin: 0;
}
</style>
<?php
}
}
private function show_plugins(array $plugins, bool $for_free = \false)
{
$server = $this->get_server();
$utm_base = $this->utm_base;
foreach ($plugins as $plugin) {
$slug = $plugin['slug'];
if ($for_free && isset($plugin['free_plugin_slug'])) {
$slug = $plugin['free_plugin_slug'];
}
$plugin_url = sprintf('%1$s?%2$s&utm_medium=more-info-button&utm_term=%3$s', $plugin['url'], $utm_base, $slug);
$add_to_cart_url = sprintf('https://%1$s/?add-to-cart=%2$s&%3$s&utm_medium=buy-now-button&utm_term=%4$s', $server, $plugin['add_to_cart_id'], $utm_base, $slug);
$add_to_cart_button_label = esc_html__('Buy now', 'woocommerce-gateway-przelewy24');
if ($plugin['add_to_cart_id'] === self::WP_DESK_CARE_ID) {
$add_to_cart_button_label = esc_html__('Learn more', 'woocommerce-gateway-przelewy24');
$add_to_cart_url = $plugin_url;
} else if ($plugin['add_to_cart_id'] === self::AUTOPAY_ID) {
$add_to_cart_button_label = esc_html__('Download', 'woocommerce-gateway-przelewy24');
$add_to_cart_url = esc_url("https://wpdesk.link/autopay-wpdeskpl");
}
echo '<li class="ltv-row">';
if ($plugin['image']) {
echo '<img src="' . esc_url($plugin['image']) . '" alt="" />';
}
echo '<p><strong>' . esc_html($plugin['name']) . '</strong></p>';
echo '<div class="ltv-row-description">' . wp_kses_post($plugin['description']) . '</div>';
echo '<div class="ltv-buttons">';
if ($for_free) {
echo '<a class="button button-primary" href="' . \esc_url($plugin_url) . '" target="_blank">' . esc_html__('More info', 'woocommerce-gateway-przelewy24') . '</a>';
echo '<a class="button button-secondary" href="' . \esc_url($add_to_cart_url) . '" target="_blank">' . $add_to_cart_button_label . '</a>';
} else {
echo '<a class="button button-primary button-large" href="' . esc_url($add_to_cart_url) . '" target="_blank">' . $add_to_cart_button_label . '</a>';
}
echo '</div>';
echo '</li>';
}
}
}

View File

@@ -0,0 +1,35 @@
{
"name": "wpdesk\/php-scoper-woocommerce-excludes",
"description": "A list of all WooCommerce core classes, functions and constants. Meant to be used with the PHP-Scoper exclusion functionality.",
"minimum-stability": "stable",
"keywords": [
"WooCommerce",
"PHP-scoper",
"php-scoper",
"scoping Woocommerce"
],
"license": "MIT",
"authors": [
{
"name": "Calvin Alkan",
"email": "calvin@snicco.de"
},
{
"name": "Marlon Alkan",
"email": "marlon@snicco.de"
}
],
"require-dev": {
"php": "^7.2",
"sniccowp\/php-scoper-excludes": "dev-master",
"php-stubs\/woocommerce-stubs": "*"
},
"config": {
"platform": {
"php": "7.4.33"
}
},
"scripts": {
"generate:excludes": "generate-excludes --json --exclude-empty"
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare (strict_types=1);
namespace Przelewy24Vendor;
use Przelewy24Vendor\PhpParser\ParserFactory;
use Przelewy24Vendor\Snicco\PhpScoperExcludes\Option;
return [
Option::EMULATE_PHP_VERSION => Option::PHP_8_0,
// use the current working directory
Option::OUTPUT_DIR => __DIR__ . '/generated',
// pass files as command arguments
Option::FILES => [__DIR__ . '/vendor/php-stubs/woocommerce-stubs/woocommerce-packages-stubs.php', __DIR__ . '/vendor/php-stubs/woocommerce-stubs/woocommerce-stubs.php'],
Option::PREFER_PHP_VERSION => ParserFactory::PREFER_PHP7,
];

View File

@@ -0,0 +1,51 @@
{
"name": "wpdesk\/wp-basic-requirements",
"authors": [
{
"name": "Krzysiek",
"email": "krzysiek@wpdesk.pl"
}
],
"require": {
"php": ">=5.3"
},
"require-dev": {
"php": ">=5.5",
"phpunit\/phpunit": "^8",
"mockery\/mockery": "*",
"10up\/wp_mock": "*",
"wimg\/php-compatibility": "^8",
"wpdesk\/wp-code-sniffer": "^1.2"
},
"autoload": {},
"autoload-dev": {
"classmap": [
"src",
"tests"
]
},
"extra": {
"text-domain": "wp-basic-requirements",
"translations-folder": "lang",
"po-files": {
"pl_PL": "pl_PL.po",
"en_AU": "en_AU.po",
"en_CA": "en_CA.po",
"en_GB": "en_GB.po",
"de_DE": "de_DE.po"
}
},
"scripts": {
"phpcs": "phpcs",
"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",
"docs": "apigen generate"
},
"config": {
"allow-plugins": {
"dealerdirect\/phpcodesniffer-composer-installer": true
}
}
}

View File

@@ -0,0 +1,590 @@
<?php
namespace Przelewy24Vendor;
if (!\interface_exists('Przelewy24Vendor\WPDesk_Requirement_Checker')) {
require_once __DIR__ . '/Requirement_Checker.php';
}
if (!\class_exists('Przelewy24Vendor\WPDesk_Basic_Requirement_Checker')) {
/**
* Checks requirements for plugin
* have to be compatible with PHP 5.3.x
*/
class WPDesk_Basic_Requirement_Checker implements WPDesk_Requirement_Checker
{
const EXTENSION_NAME_OPENSSL = 'openssl';
const HOOK_ADMIN_NOTICES_ACTION = 'admin_notices';
const HOOK_PLUGIN_DEACTIVATED_ACTION = 'deactivated_plugin';
const HOOK_PLUGIN_ACTIVATED_ACTION = 'activated_plugin';
const PLUGIN_INFO_KEY_NICE_NAME = 'nice_name';
const PLUGIN_INFO_KEY_NAME = 'name';
const PLUGIN_INFO_VERSION = 'version';
const PLUGIN_INFO_FAKE_REQUIRED_MINIMUM_VERSION = '0.0';
const PLUGIN_INFO_APPEND_PLUGIN_DATA = 'required_version';
const PLUGIN_INFO_TRANSIENT_NAME = 'wpdesk_requirements_plugins_data';
const CACHE_TIME = 16;
const EXPIRATION_TIME = 'expiration_time';
const PLUGINS = 'plugins';
/** @var string */
protected $plugin_name;
/** @var string */
private $plugin_file;
/** @var string */
private $min_php_version;
/** @var string */
private $min_wp_version;
/** @var string|null */
private $min_wc_version = null;
/** @var int|null */
private $min_openssl_version = null;
/** @var array */
protected $plugin_require;
/** @var bool */
protected $should_check_plugin_versions = \false;
/** @var array */
private $module_require;
/** @var array */
private $setting_require;
/** @var array */
protected $notices;
/** @var @string */
private $text_domain;
/**
* @var mixed|true
*/
private $use_transients;
/**
* @param string $plugin_file
* @param string $plugin_name
* @param string $text_domain
* @param string $php_version
* @param string $wp_version
* @param bool $use_transients
*/
public function __construct($plugin_file, $plugin_name, $text_domain, $php_version, $wp_version, $use_transients = \true)
{
$this->plugin_file = $plugin_file;
$this->plugin_name = $plugin_name;
$this->text_domain = $text_domain;
$this->use_transients = $use_transients;
$this->set_min_php_require($php_version);
$this->set_min_wp_require($wp_version);
$this->plugin_require = array();
$this->module_require = array();
$this->setting_require = array();
$this->notices = array();
}
/**
* @param string $version
*
* @return $this
*/
public function set_min_php_require($version)
{
$this->min_php_version = $version;
return $this;
}
/**
* @param string $version
*
* @return $this
*/
public function set_min_wp_require($version)
{
$this->min_wp_version = $version;
return $this;
}
/**
* @param string $version
*
* @return $this
*/
public function set_min_wc_require($version)
{
$this->min_wc_version = $version;
return $this;
}
/**
* @param $version
*
* @return $this
*/
public function set_min_openssl_require($version)
{
$this->min_openssl_version = $version;
return $this;
}
/**
* @param string $plugin_name Name in wp format dir/file.php
* @param string $nice_plugin_name Nice plugin name for better looks in notice
* @param string $plugin_require_version required plugin minimum version
*
* @return $this
*/
public function add_plugin_require($plugin_name, $nice_plugin_name = null, $plugin_require_version = null)
{
if ($plugin_require_version) {
$this->should_check_plugin_versions = \true;
}
$this->plugin_require[$plugin_name] = array(self::PLUGIN_INFO_KEY_NAME => $plugin_name, self::PLUGIN_INFO_KEY_NICE_NAME => $nice_plugin_name === null ? $plugin_name : $nice_plugin_name, self::PLUGIN_INFO_VERSION => $plugin_require_version === null ? self::PLUGIN_INFO_FAKE_REQUIRED_MINIMUM_VERSION : $plugin_require_version);
return $this;
}
/**
* Add plugin to require list. Plugin is from repository so we can ask for installation.
*
* @param string $plugin_name Name in wp format dir/file.php
* @param string $version Required version of the plugin.
* @param string $nice_plugin_name Nice plugin name for better looks in notice
*
* @return $this
*/
public function add_plugin_repository_require($plugin_name, $version, $nice_plugin_name = null)
{
$this->plugin_require[$plugin_name] = array(self::PLUGIN_INFO_KEY_NAME => $plugin_name, self::PLUGIN_INFO_VERSION => $version, 'repository_url' => 'http://downloads.wordpress.org/plugin/' . \dirname($plugin_name) . '.latest-stable.zip', self::PLUGIN_INFO_KEY_NICE_NAME => $nice_plugin_name === null ? $plugin_name : $nice_plugin_name);
return $this;
}
/**
* @param string $module_name
* @param string $nice_name Nice module name for better looks in notice
*
* @return $this
*/
public function add_php_module_require($module_name, $nice_name = null)
{
if ($nice_name === null) {
$this->module_require[$module_name] = $module_name;
} else {
$this->module_require[$module_name] = $nice_name;
}
return $this;
}
/**
* @param string $setting
* @param mixed $value
*
* @return $this
*/
public function add_php_setting_require($setting, $value)
{
$this->setting_require[$setting] = $value;
return $this;
}
/**
* Returns true if are requirements are met.
*
* @return bool
*/
public function are_requirements_met()
{
$this->notices = $this->prepare_requirement_notices();
return \count($this->notices) === 0;
}
/**
* @return array
*/
private function prepare_requirement_notices()
{
$notices = array();
if (!self::is_php_at_least($this->min_php_version)) {
$notices[] = $this->prepare_notice_message(\sprintf(\__('The &#8220;%s&#8221; plugin cannot run on PHP versions older than %s. Please contact your host and ask them to upgrade.', 'woocommerce-gateway-przelewy24'), \esc_html($this->plugin_name), $this->min_php_version));
}
if (!self::is_wp_at_least($this->min_wp_version)) {
$notices[] = $this->prepare_notice_message(\sprintf(\__('The &#8220;%s&#8221; plugin cannot run on WordPress versions older than %s. Please update WordPress.', 'woocommerce-gateway-przelewy24'), \esc_html($this->plugin_name), $this->min_wp_version));
}
if ($this->min_wc_version !== null && $this->can_check_plugin_version() && !self::is_wc_at_least($this->min_wc_version)) {
$notices[] = $this->prepare_notice_message(\sprintf(\__('The &#8220;%s&#8221; plugin cannot run on WooCommerce versions older than %s. Please update WooCommerce.', 'woocommerce-gateway-przelewy24'), \esc_html($this->plugin_name), $this->min_wc_version));
}
if ($this->min_openssl_version !== null && !self::is_open_ssl_at_least($this->min_openssl_version)) {
$notices[] = $this->prepare_notice_message(\sprintf(\__('The &#8220;%s&#8221; plugin cannot run without OpenSSL module version at least %s. Please update OpenSSL module.', 'woocommerce-gateway-przelewy24'), \esc_html($this->plugin_name), '0x' . \dechex($this->min_openssl_version)));
}
$notices = $this->append_plugin_require_notices($notices);
$notices = $this->append_module_require_notices($notices);
$notices = $this->append_settings_require_notices($notices);
if ($this->should_check_plugin_versions) {
$notices = $this->check_minimum_require_plugins_version_and_append_notices($notices);
}
return $notices;
}
/**
* @param $min_version
*
* @return mixed
*/
public static function is_php_at_least($min_version)
{
return \version_compare(\PHP_VERSION, $min_version, '>=');
}
/**
* Prepares message in html format
*
* @param string $message
*
* @return string
*/
protected function prepare_notice_message($message)
{
return '<div class="error"><p>' . $message . '</p></div>';
}
public function get_text_domain()
{
return $this->text_domain;
}
/**
* @param string $min_version
*
* @return bool
*/
public static function is_wp_at_least($min_version)
{
return \version_compare(\get_bloginfo('version'), $min_version, '>=');
}
/**
* Are plugins loaded so we can check the version
*
* @return bool
*/
private function can_check_plugin_version()
{
return \did_action('plugins_loaded') > 0;
}
/**
* Checks if plugin is active and have designated version. Needs to be enabled in deferred way.
*
* @param string $min_version
*
* @return bool
*/
public static function is_wc_at_least($min_version)
{
return \defined('WC_VERSION') && \version_compare(\WC_VERSION, $min_version, '>=');
}
/**
* Checks if ssl version is valid
*
* @param int $required_version Version in hex. Version 9.6 is 0x000906000
*
* @return bool
* @see https://www.openssl.org/docs/man1.1.0/crypto/OPENSSL_VERSION_NUMBER.html
*
*/
public static function is_open_ssl_at_least($required_version)
{
return \defined('OPENSSL_VERSION_NUMBER') && \OPENSSL_VERSION_NUMBER > (int) $required_version;
}
/**
* @param $notices array
*
* @return array
*/
private function check_minimum_require_plugins_version_and_append_notices($notices)
{
$required_plugins = $this->retrieve_required_plugins_data();
if (\count($required_plugins) > 0) {
foreach ($required_plugins as $plugin) {
if (isset($plugin['Version']) && \version_compare($plugin['Version'], $plugin[self::PLUGIN_INFO_APPEND_PLUGIN_DATA], '<=')) {
$notices[] = $this->prepare_notice_message(\sprintf(\__('The &#8220;%1$s&#8221; plugin requires at least %2$s version of %3$s to work correctly. Please update it to its latest release.', 'woocommerce-gateway-przelewy24'), \esc_html($this->plugin_name), $plugin[self::PLUGIN_INFO_APPEND_PLUGIN_DATA], $plugin['Name']));
}
}
}
return $notices;
}
/**
* Check the plugins directory and retrieve all plugin files with plugin data.
*
* @param bool $use_transients
*
* @return array In format [ 'plugindir/pluginfile.php' => ['Name' => 'Plugin Name', 'Version' => '1.0.1', ...], ]
*/
private static function retrieve_plugins_data_in_transient($use_transients = \true)
{
$current_time = \time();
$plugins = self::get_plugins_data_from_cache($use_transients, $current_time);
if ($plugins === \false) {
static $never_executed = \true;
if ($never_executed) {
$never_executed = \false;
/** Required when WC starts later and these data should be in cache */
\add_filter('extra_plugin_headers', function ($headers = array()) {
$headers[] = 'WC tested up to';
$headers[] = 'WC requires at least';
$headers[] = 'Woo';
return \array_unique($headers);
});
}
if (!\function_exists('get_plugins') && !\function_exists('Przelewy24Vendor\get_plugins')) {
require_once \ABSPATH . '/wp-admin/includes/plugin.php';
}
$plugins = \function_exists('get_plugins') ? \get_plugins() : array();
self::update_plugins_data_in_cache($plugins, $use_transients, $current_time);
}
return $plugins;
}
/**
* @param bool $use_transients
* @param int $current_time
*
* @return array|false
*/
private static function get_plugins_data_from_cache($use_transients, $current_time)
{
if ($use_transients) {
return \get_transient(self::PLUGIN_INFO_TRANSIENT_NAME);
} else {
$plugins_option_value = \get_option(self::PLUGIN_INFO_TRANSIENT_NAME);
if (\is_array($plugins_option_value) && isset($plugins_option_value[self::EXPIRATION_TIME], $plugins_option_value[self::PLUGINS]) && (int) $plugins_option_value[self::EXPIRATION_TIME] > $current_time) {
return $plugins_option_value[self::PLUGINS];
}
}
return \false;
}
/**
* @param array $plugins
* @param bool $use_transients
* @param int $current_time
*/
private static function update_plugins_data_in_cache($plugins, $use_transients, $current_time)
{
if ($use_transients) {
\set_transient(self::PLUGIN_INFO_TRANSIENT_NAME, $plugins, self::CACHE_TIME);
} else {
\update_option(self::PLUGIN_INFO_TRANSIENT_NAME, array(self::EXPIRATION_TIME => $current_time + self::CACHE_TIME, self::PLUGINS => $plugins));
}
}
/**
* Check the plugins directory and retrieve all required plugin files with plugin data.
*
* @return array In format [ 'plugindir/pluginfile.php' => ['Name' => 'Plugin Name', 'Version' => '1.0.1', 'required_version' => '1.0.2']... ]
*/
private function retrieve_required_plugins_data()
{
$require_plugins = array();
$plugins = self::retrieve_plugins_data_in_transient($this->use_transients);
if (\is_array($plugins)) {
if (\count($plugins) > 0) {
if (!empty($this->plugin_require)) {
foreach ($this->plugin_require as $plugin) {
$plugin_file_name = $plugin[self::PLUGIN_INFO_KEY_NAME];
$plugin_version = $plugin[self::PLUGIN_INFO_VERSION];
if (self::is_wp_plugin_active($plugin_file_name)) {
$require_plugins[$plugin_file_name] = $plugins[$plugin_file_name];
$require_plugins[$plugin_file_name][self::PLUGIN_INFO_APPEND_PLUGIN_DATA] = $plugin_version;
}
}
}
}
}
return $require_plugins;
}
/**
* @param array $notices
*
* @return array
*/
private function append_plugin_require_notices($notices)
{
if (\count($this->plugin_require) > 0) {
foreach ($this->plugin_require as $plugin_name => $plugin_info) {
$notice = null;
if (isset($plugin_info['repository_url'])) {
$notice = $this->prepare_plugin_repository_require_notice($plugin_info);
} elseif (!self::is_wp_plugin_active($plugin_name)) {
$notice = $this->prepare_notice_message(\sprintf(\__('The &#8220;%s&#8221; plugin cannot run without %s active. Please install and activate %s plugin.', 'woocommerce-gateway-przelewy24'), \esc_html($this->plugin_name), \esc_html(\basename($plugin_info[self::PLUGIN_INFO_KEY_NICE_NAME])), \esc_html(\basename($plugin_info[self::PLUGIN_INFO_KEY_NICE_NAME]))));
}
if ($notice !== null) {
$notices[] = $notice;
}
}
}
return $notices;
}
/**
* Prepares WP install url and injects info about plugin to the WP update engine.
*
* @param array $plugin_info
*
* @return string
*/
private function prepare_plugin_repository_install_url($plugin_info)
{
$slug = \basename(\explode('/', $plugin_info[self::PLUGIN_INFO_KEY_NAME])[0]);
$install_url = \self_admin_url('update.php?action=install-plugin&plugin=' . $slug);
if (\function_exists('wp_nonce_url') && \function_exists('wp_create_nonce')) {
$install_url = \wp_nonce_url($install_url, 'install-plugin_' . $slug);
}
return $install_url;
}
/**
* @param array $plugin_info Internal required plugin info data.
*
* @return string|null Return null if no notice is needed.
*/
private function prepare_plugin_repository_require_notice($plugin_info)
{
$name = $plugin_info[self::PLUGIN_INFO_KEY_NAME];
$nice_name = $plugin_info[self::PLUGIN_INFO_KEY_NICE_NAME];
if (!self::is_wp_plugin_active($name)) {
if (!self::is_wp_plugin_installed($name, $this->use_transients)) {
$install_url = $this->prepare_plugin_repository_install_url($plugin_info);
return $this->prepare_notice_message(\sprintf(\wp_kses(\__('The &#8220;%s&#8221; plugin requires free %s plugin. <a href="%s">Install %s</a>', 'woocommerce-gateway-przelewy24'), array('a' => array('href' => array()))), $this->plugin_name, $nice_name, \esc_url($install_url), $nice_name));
}
$activate_url = 'plugins.php?action=activate&plugin=' . \urlencode($plugin_info[self::PLUGIN_INFO_KEY_NAME]) . '&plugin_status=all&paged=1&s';
if (\function_exists('wp_create_nonce')) {
$activate_url .= '&_wpnonce=' . \urlencode(\wp_create_nonce('activate-plugin_' . $name));
}
return $this->prepare_notice_message(\sprintf(\wp_kses(\__('The &#8220;%s&#8221; plugin requires activating %s plugin. <a href="%s">Activate %s</a>', 'woocommerce-gateway-przelewy24'), array('a' => array('href' => array()))), $this->plugin_name, $nice_name, \esc_url(\admin_url($activate_url)), $nice_name));
}
return null;
}
/**
* Checks if plugin is active. Needs to be used in deferred way.
*
* @param string $plugin_file
*
* @return bool
*/
public static function is_wp_plugin_active($plugin_file)
{
$active_plugins = (array) \get_option('active_plugins', array());
if (\is_multisite()) {
$active_plugins = \array_merge($active_plugins, \get_site_option('active_sitewide_plugins', array()));
}
return \in_array($plugin_file, $active_plugins) || \array_key_exists($plugin_file, $active_plugins);
}
/**
* Checks if plugin is installed. Needs to be enabled in deferred way.
*
* @param string $plugin_file
* @param bool $use_transients
*
* @return bool
*/
public static function is_wp_plugin_installed($plugin_file, $use_transients = \false)
{
$plugins_data = self::retrieve_plugins_data_in_transient($use_transients);
return \array_key_exists($plugin_file, (array) $plugins_data);
}
/**
* @param array $notices
*
* @return array
*/
private function append_module_require_notices($notices)
{
if (\count($this->module_require) > 0) {
foreach ($this->module_require as $module_name => $nice_module_name) {
if (!self::is_module_active($module_name)) {
$notices[] = $this->prepare_notice_message(\sprintf(\__('The &#8220;%s&#8221; plugin cannot run without %s PHP module installed. Please contact your host and ask them to install %s.', 'woocommerce-gateway-przelewy24'), \esc_html($this->plugin_name), \esc_html(\basename($nice_module_name)), \esc_html(\basename($nice_module_name))));
}
}
}
return $notices;
}
/**
* @param string $name
*
* @return bool
*/
public static function is_module_active($name)
{
return \extension_loaded($name);
}
/**
* @param array $notices
*
* @return array
*/
private function append_settings_require_notices($notices)
{
if (\count($this->setting_require) > 0) {
foreach ($this->setting_require as $setting => $value) {
if (!self::is_setting_set($setting, $value)) {
$notices[] = $this->prepare_notice_message(\sprintf(\__('The &#8220;%s&#8221; plugin cannot run without %s PHP setting set to %s. Please contact your host and ask them to set %s.', 'woocommerce-gateway-przelewy24'), \esc_html($this->plugin_name), \esc_html(\basename($setting)), \esc_html(\basename($value)), \esc_html(\basename($setting))));
}
}
}
return $notices;
}
/**
* @param string $name
* @param mixed $value
*
* @return bool
*/
public static function is_setting_set($name, $value)
{
return \ini_get($name) === (string) $value;
}
/**
* @return void
*
* @deprecated use render_notices or disable_plugin
*/
public function disable_plugin_render_notice()
{
\add_action(self::HOOK_ADMIN_NOTICES_ACTION, array($this, 'handle_render_notices_action'));
}
/**
* Renders requirement notices in admin panel
*
* @return void
*/
public function render_notices()
{
\add_action(self::HOOK_ADMIN_NOTICES_ACTION, array($this, 'handle_render_notices_action'));
}
/**
* Renders requirement notices in admin panel
*
* @return void
*/
public function disable_plugin()
{
\add_action(self::HOOK_ADMIN_NOTICES_ACTION, array($this, 'handle_deactivate_action'));
}
/**
* @return void
* @internal Do not use as public. Public only for wp action.
*
*/
public function handle_deactivate_action()
{
if (isset($this->plugin_file)) {
\deactivate_plugins(\plugin_basename($this->plugin_file));
$this->clear_plugin_info_data();
}
}
/**
* Triggers the transient delete after plugin deactivated
*
* @return void
*/
public function transient_delete_on_plugin_version_changed()
{
\add_action(self::HOOK_PLUGIN_DEACTIVATED_ACTION, array($this, 'clear_plugin_info_data'));
\add_action(self::HOOK_PLUGIN_ACTIVATED_ACTION, array($this, 'clear_plugin_info_data'));
}
/**
* Handles the transient delete
*
* @return void
*/
public function clear_plugin_info_data()
{
\delete_transient(self::PLUGIN_INFO_TRANSIENT_NAME);
\delete_option(self::PLUGIN_INFO_TRANSIENT_NAME);
}
/**
* Should be called as WordPress action
*
* @return void
* @internal Do not use as public. Public only for wp action.
*
*/
public function handle_render_notices_action()
{
foreach ($this->notices as $notice) {
echo \wp_kses_post($notice);
}
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Przelewy24Vendor;
if (!\class_exists('Przelewy24Vendor\Basic_Requirement_Checker')) {
require_once __DIR__ . '/Basic_Requirement_Checker.php';
}
if (!\class_exists('Przelewy24Vendor\WPDesk_Basic_Requirement_Checker_With_Update_Disable')) {
require_once __DIR__ . '/Basic_Requirement_Checker_With_Update_Disable.php';
}
/**
* Falicitates createion of requirement checker
*/
class WPDesk_Basic_Requirement_Checker_Factory
{
const LIBRARY_TEXT_DOMAIN = 'woocommerce-gateway-przelewy24';
/**
* Creates a simplest possible version of requirement checker.
*
* @param string $plugin_file
* @param string $plugin_name
* @param string|null $text_domain Text domain to use. If null try to use library text domain.
*
* @return WPDesk_Requirement_Checker
*/
public function create_requirement_checker($plugin_file, $plugin_name, $text_domain = null)
{
return new WPDesk_Basic_Requirement_Checker($plugin_file, $plugin_name, $text_domain, null, null);
}
/**
* Creates a requirement checker according to given requirements array info.
*
* @param string $plugin_file
* @param string $plugin_name
* @param string $text_domain Text domain to use. If null try to use library text domain.
* @param array $requirements Requirements array as given by plugin.
*
* @return WPDesk_Requirement_Checker
*/
public function create_from_requirement_array($plugin_file, $plugin_name, $requirements, $text_domain = null)
{
$requirements_checker = new WPDesk_Basic_Requirement_Checker_With_Update_Disable($plugin_file, $plugin_name, $text_domain, $requirements['php'], $requirements['wp'], (bool) \wp_using_ext_object_cache());
if (isset($requirements['plugins'])) {
foreach ($requirements['plugins'] as $requirement) {
$version = isset($requirement['version']) ? $requirement['version'] : null;
$requirements_checker->add_plugin_require($requirement['name'], $requirement['nice_name'], $version);
}
$requirements_checker->transient_delete_on_plugin_version_changed();
}
if (isset($requirements['repo_plugins'])) {
foreach ($requirements['repo_plugins'] as $requirement) {
$requirements_checker->add_plugin_repository_require($requirement['name'], $requirement['version'], $requirement['nice_name']);
}
}
if (isset($requirements['modules'])) {
foreach ($requirements['modules'] as $requirement) {
$requirements_checker->add_php_module_require($requirement['name'], $requirement['nice_name']);
}
}
return $requirements_checker;
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Przelewy24Vendor;
if (!\class_exists('Przelewy24Vendor\WPDesk_Basic_Requirement_Checker')) {
require_once __DIR__ . '/Basic_Requirement_Checker.php';
}
if (!\class_exists('Przelewy24Vendor\WPDesk_Basic_Requirement_Checker_With_Update_Disable')) {
/**
* Checks requirements for plugin. When required plugin is updated right now, then say that requirements are not met temporary.
* have to be compatible with PHP 5.2.x
*/
class WPDesk_Basic_Requirement_Checker_With_Update_Disable extends WPDesk_Basic_Requirement_Checker
{
/**
* Returns true if are requirements are met.
*
* @return bool
*/
public function are_requirements_met()
{
$has_been_met = parent::are_requirements_met();
if (!$has_been_met) {
return $has_been_met;
}
foreach ($this->plugin_require as $name => $plugin_info) {
if ($this->is_currently_updated($name)) {
$nice_name = $plugin_info[self::PLUGIN_INFO_KEY_NICE_NAME];
$this->notices[] = $this->prepare_notice_message(\sprintf(\__('The &#8220;%s&#8221; plugin is temporarily disabled since the required %s plugin is being upgraded.', 'woocommerce-gateway-przelewy24'), $this->plugin_name, $nice_name, $nice_name));
}
}
return \count($this->notices) === 0;
}
/**
* Is plugin upgrading right now?
*
* @param string $name
*
* @return bool
*/
private function is_currently_updated($name)
{
return isset($_GET['action']) && $_GET['action'] === 'upgrade-plugin' && $_GET['plugin'] === $name;
}
}
}

View File

@@ -0,0 +1,74 @@
<?php
namespace Przelewy24Vendor;
/**
* Checks requirements for plugin
* have to be compatible with PHP 5.2.x
*/
interface WPDesk_Requirement_Checker
{
/**
* @param string $version
*
* @return $this
*/
public function set_min_php_require($version);
/**
* @param string $version
*
* @return $this
*/
public function set_min_wp_require($version);
/**
* @param string $version
*
* @return $this
*/
public function set_min_wc_require($version);
/**
* @param $version
*
* @return $this
*/
public function set_min_openssl_require($version);
/**
* @param string $plugin_name
* @param string $nice_plugin_name Nice plugin name for better looks in notice
*
* @return $this
*/
public function add_plugin_require($plugin_name, $nice_plugin_name = null);
/**
* @param string $module_name
* @param string $nice_name Nice module name for better looks in notice
*
* @return $this
*/
public function add_php_module_require($module_name, $nice_name = null);
/**
* @param string $setting
* @param mixed $value
*
* @return $this
*/
public function add_php_setting_require($setting, $value);
/**
* @return bool
*/
public function are_requirements_met();
/**
* @return void
*/
public function disable_plugin_render_notice();
/**
* @return void
*/
public function render_notices();
/**
* Renders requirement notices in admin panel
*
* @return void
*/
public function disable_plugin();
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Przelewy24Vendor;
interface WPDesk_Requirement_Checker_Factory
{
/**
* @param $plugin_file
* @param $plugin_name
* @param $text_domain
* @param $php_version
* @param $wp_version
*
* @return WPDesk_Requirement_Checker
*/
public function create_requirement_checker($plugin_file, $plugin_name, $text_domain);
}

View File

@@ -0,0 +1,51 @@
{
"name": "wpdesk\/wp-builder",
"authors": [
{
"name": "Krzysiek",
"email": "krzysiek@wpdesk.pl"
}
],
"require": {
"php": ">=7.4 || ^8"
},
"require-dev": {
"phpunit\/phpunit": "^9",
"10up\/wp_mock": "^1",
"wpdesk\/wp-code-sniffer": "^1",
"wpdesk\/phpstan-rules": "^1"
},
"autoload": {
"psr-4": {
"Przelewy24Vendor\\WPDesk\\PluginBuilder\\": "src\/"
},
"classmap": [
"src\/Plugin\/WithoutNamespace"
]
},
"extra": {
"text-domain": "wpdesk-wp-builder",
"translations-folder": "lang",
"po-files": {
"pl_PL": "pl_PL.po"
}
},
"scripts": {
"phpcs": "phpcs",
"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"
},
"archive": {
"exclude": [
"\/tests"
]
},
"config": {
"allow-plugins": {
"dealerdirect\/phpcodesniffer-composer-installer": true,
"phpstan\/extension-installer": true
}
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\BuildDirector;
use Przelewy24Vendor\WPDesk\PluginBuilder\Builder\AbstractBuilder;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\AbstractPlugin;
use Przelewy24Vendor\WPDesk\PluginBuilder\Storage\StorageFactory;
class LegacyBuildDirector
{
/** @var AbstractBuilder */
private $builder;
public function __construct(AbstractBuilder $builder)
{
$this->builder = $builder;
}
/**
* Builds plugin
*/
public function build_plugin()
{
$this->builder->build_plugin();
$this->builder->init_plugin();
$storage = new StorageFactory();
$this->builder->store_plugin($storage->create_storage());
}
/**
* Returns built plugin
*
* @return AbstractPlugin
*/
public function get_plugin()
{
return $this->builder->get_plugin();
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Builder;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\AbstractPlugin;
use Przelewy24Vendor\WPDesk\PluginBuilder\Storage\PluginStorage;
abstract class AbstractBuilder
{
/**
* Create plugin class
*/
public function build_plugin()
{
}
/**
* Store plugin class in some kind of storage
*/
public function store_plugin(PluginStorage $storage)
{
}
/**
* Init plugin internal structure
*/
public function init_plugin()
{
}
/**
* Return built plugin
* @return AbstractPlugin
*/
abstract function get_plugin();
/**
* Set settings class in plugin
*
* @param $settings
*/
public function set_settings($settings)
{
}
/**
* Set view class in plugin
*
* @param $view
*/
public function set_view($view)
{
}
/**
* Set tracker class in plugin
*
* @param $tracker
*/
public function set_tracker($tracker)
{
}
/**
* Set helper class in plugin
*
* @param $helper
*/
public function set_helper($helper)
{
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Builder;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\AbstractPlugin;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\ActivationAware;
use Przelewy24Vendor\WPDesk\PluginBuilder\Storage\PluginStorage;
/**
* Builder that have info about activations
*
* Warning: We can't extend InfoBuilder.php as some old plugins(without wp-flow) will load the old version od InfoBuilder class that have private plugin property.
*
* @package WPDesk\PluginBuilder\Builder
*/
class InfoActivationBuilder extends AbstractBuilder
{
const FILTER_PLUGIN_CLASS = 'wp_builder_plugin_class';
const HOOK_BEFORE_PLUGIN_INIT = 'wp_builder_before_plugin_init';
const HOOK_AFTER_PLUGIN_INIT = 'wp_builder_before_init';
/** @var AbstractPlugin */
private $plugin;
/** @var \WPDesk_Buildable */
private $info;
/** @var string */
protected $storage_id;
/**
* @var bool
*/
private $is_active;
/**
* @param \WPDesk_Buildable $info
* @param bool $is_active
*/
public function __construct(\Przelewy24Vendor\WPDesk_Buildable $info, $is_active)
{
$this->info = $info;
$this->storage_id = $info->get_class_name();
$this->is_active = $is_active;
}
/**
* Builds instance of plugin
*/
public function build_plugin()
{
$class_name = apply_filters(self::FILTER_PLUGIN_CLASS, $this->info->get_class_name());
/** @var AbstractPlugin $plugin */
$this->plugin = new $class_name($this->info);
if ($this->plugin instanceof ActivationAware && $this->is_active) {
$this->plugin->set_active();
}
return $this->plugin;
}
public function store_plugin(PluginStorage $storage)
{
$storage->add_to_storage($this->storage_id, $this->plugin);
}
public function init_plugin()
{
do_action(self::HOOK_BEFORE_PLUGIN_INIT, $this->plugin);
$this->plugin->init();
do_action(self::HOOK_AFTER_PLUGIN_INIT, $this->plugin);
}
/**
* @return AbstractPlugin
*/
public function get_plugin()
{
return $this->plugin;
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Builder;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\AbstractPlugin;
use Przelewy24Vendor\WPDesk\PluginBuilder\Storage\PluginStorage;
/**
* @deprecated Should not be used as some old plugins are using it and we can't touch this.
*
* @package WPDesk\PluginBuilder\Builder
*/
class InfoBuilder extends AbstractBuilder
{
const FILTER_PLUGIN_CLASS = 'wp_builder_plugin_class';
const HOOK_BEFORE_PLUGIN_INIT = 'wp_builder_before_plugin_init';
const HOOK_AFTER_PLUGIN_INIT = 'wp_builder_before_init';
/** @var AbstractPlugin */
private $plugin;
/** @var \WPDesk_Buildable */
private $info;
/** @var string */
protected $storage_id;
public function __construct(\Przelewy24Vendor\WPDesk_Buildable $info)
{
$this->info = $info;
$this->storage_id = $info->get_class_name();
}
/**
* Builds instance of plugin
*/
public function build_plugin()
{
$class_name = apply_filters(self::FILTER_PLUGIN_CLASS, $this->info->get_class_name());
/** @var AbstractPlugin $plugin */
$this->plugin = new $class_name($this->info);
}
public function store_plugin(PluginStorage $storage)
{
$storage->add_to_storage($this->storage_id, $this->plugin);
}
public function init_plugin()
{
do_action(self::HOOK_BEFORE_PLUGIN_INIT, $this->plugin);
$this->plugin->init();
do_action(self::HOOK_AFTER_PLUGIN_INIT, $this->plugin);
}
/**
* @return AbstractPlugin
*/
public function get_plugin()
{
return $this->plugin;
}
}

View File

@@ -0,0 +1,193 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
/**
* Base plugin with most basic functionalities used by every WPDesk plugin.
*
*
* Known issues:
*
* The class name is too generic but can't be changed as it would introduce a major incompatibility for most of the plugins.
* The $plugin_url, $docs_url and most other fields should be removed as they only litter the place but for compatibility reasons we can't do it right now.
* Hook methods should be moved to external classes but for compatibility reasons we can't do it right now.
*/
abstract class AbstractPlugin extends SlimPlugin
{
/**
* Most info about plugin internals.
*
* @var \WPDesk_Plugin_Info
*/
protected $plugin_info;
/**
* Unique string for this plugin in [a-z_]+ format.
*
* @var string
*/
protected $plugin_namespace;
/**
* Absolute URL to the plugin dir.
*
* @var string
*/
protected $plugin_url;
/**
* Absolute URL to the plugin docs.
*
* @var string
*/
protected $docs_url;
/**
* Absolute URL to the plugin settings url.
*
* @var string
*/
protected $settings_url;
/**
* Support URL.
*
* @var string
*/
protected $support_url;
/**
* AbstractPlugin constructor.
*
* @param \WPDesk_Plugin_Info $plugin_info
*/
public function __construct($plugin_info)
{
$this->plugin_info = $plugin_info;
$this->plugin_namespace = strtolower($plugin_info->get_plugin_dir());
$this->plugin_url = $this->plugin_info->get_plugin_url();
$this->init_base_variables();
}
/**
* Initialize internal state of the plugin.
*
* @return void
* @deprecated Just use __construct to initialize plugin internal state.
*
*/
public function init_base_variables()
{
}
/**
* Initializes plugin external state.
*
* The plugin internal state is initialized in the constructor and the plugin should be internally consistent after creation.
* The external state includes hooks execution, communication with other plugins, integration with WC etc.
*
* @return void
*/
public function init()
{
$this->hooks();
}
/**
* Returns absolute path to the plugin dir.
*
* @return string
*/
public function get_plugin_file_path()
{
return $this->plugin_info->get_plugin_file_name();
}
/**
* Returns plugin text domain.
*
* @return string
*/
public function get_text_domain()
{
return $this->plugin_info->get_text_domain();
}
/**
* Returns unique string for plugin in [a-z_]+ format. Can be used as plugin id in various places like plugin slug etc.
*
* @return string
*/
public function get_namespace()
{
return $this->plugin_namespace;
}
/**
* Returns plugin absolute URL.
*
* @return string
*/
public function get_plugin_url()
{
return esc_url(trailingslashit($this->plugin_url));
}
/**
* Returns plugin absolute URL to dir with front end assets.
*
* @return string
*/
public function get_plugin_assets_url()
{
return esc_url(trailingslashit($this->get_plugin_url() . 'assets'));
}
/**
* @return $this
* @deprecated For backward compatibility.
*
*/
public function get_plugin()
{
return $this;
}
/**
* Integrate with WordPress and with other plugins using action/filter system.
*
* @return void
*/
protected function hooks()
{
add_action('admin_enqueue_scripts', [$this, 'admin_enqueue_scripts']);
add_action('wp_enqueue_scripts', [$this, 'wp_enqueue_scripts']);
add_filter('plugin_action_links_' . plugin_basename($this->get_plugin_file_path()), [$this, 'links_filter']);
}
/**
* Append JS scripts in the WordPress admin panel. This is a hook function. Do not execute directly.
*
* @return void
*/
public function admin_enqueue_scripts()
{
}
/**
* Append JS scripts in WordPress. This is a hook function. Do not execute directly.
*
* @return void
*/
public function wp_enqueue_scripts()
{
}
/**
* Initialize plugin admin links. This is a hook function. Do not execute directly.
*
* @param string[] $links
*
* @return string[]
*/
public function links_filter($links)
{
$support_link = get_locale() === 'pl_PL' ? 'https://www.wpdesk.pl/support/' : 'https://www.wpdesk.net/support';
if ($this->support_url) {
$support_link = $this->support_url;
}
$plugin_links = ['<a target="_blank" href="' . $support_link . '">' . esc_html__('Support', 'woocommerce-gateway-przelewy24') . '</a>'];
$links = array_merge($plugin_links, $links);
if ($this->docs_url) {
$plugin_links = ['<a target="_blank" href="' . $this->docs_url . '">' . esc_html__('Docs', 'woocommerce-gateway-przelewy24') . '</a>'];
$links = array_merge($plugin_links, $links);
}
if ($this->settings_url) {
$plugin_links = ['<a href="' . $this->settings_url . '">' . esc_html__('Settings', 'woocommerce-gateway-przelewy24') . '</a>'];
$links = array_merge($plugin_links, $links);
}
return $links;
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
/**
* Tag the plugin with this ingterface to hook it to the WordPress activation hook.
*
* Note: works from plugin flow ^2.2.
*
* @package WPDesk\PluginBuilder\Plugin
*/
interface Activateable
{
/**
* Plugin activated in WordPress. Do not execute directly.
*
* @return void
*/
public function activate();
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
/**
* It means that this class is should know about SUBSCRIPTION activation
*
* @package WPDesk\PluginBuilder\Plugin
*/
interface ActivationAware
{
/**
* Set the activation flag to true
*
* @return void
*/
public function set_active();
/**
* Is subscription active?
*
* @return bool
*/
public function is_active();
}

View File

@@ -0,0 +1,70 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
/**
* @deprecated nobody uses it :) And also this library is not a place for this class
*
* @package WPDesk\PluginBuilder\Plugin
*/
class ActivationTracker
{
/**
* Namespace.
*
* @var string
*/
private $namespace;
/**
* ActivationTracker constructor.
*
* @param string $namespace Namespace for settings.
*/
public function __construct($namespace)
{
$this->namespace = $namespace;
}
/**
* Option name for date storage
*
* @return string
*/
private function get_option_name_activation_date()
{
return $this->namespace . '_activation';
}
/**
* Returns activation date and sets it if were not set before
*
* @return int unix timestamp for activation datetime
*/
public function get_activation_date()
{
$activation_date = get_option($this->get_option_name_activation_date());
if (empty($activation_date)) {
return $this->touch_activation_date();
}
return intval($activation_date);
}
/**
* Was activation more than two weeks before today
*
* @return bool
*/
public function is_activated_more_than_two_weeks()
{
$two_weeks = 60 * 60 * 24 * 7 * 2;
return $this->get_activation_date() + $two_weeks < time();
}
/**
* Sets activatiion date for today
*
* @return int unit timestamp for now
*/
public function touch_activation_date()
{
$now = time();
update_option($this->get_option_name_activation_date(), $now);
return $now;
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
/**
* Something that can be instantiated/hooked conditionally.
*
* @see https://github.com/mwpd/basic-scaffold/blob/master/src/Infrastructure/Conditional.php by Alain Schlesser
*
* @package WPDesk\PluginBuilder\Plugin
*/
interface Conditional
{
/**
* Check whether the conditional object is currently needed.
*
* @return bool Whether the conditional object is needed.
*/
public static function is_needed();
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
/**
* Tag the plugin with this ingterface to hook it to the WordPress deactivation hook.
*
* Note: works from plugin flow ^2.2.
*
* @package WPDesk\PluginBuilder\Plugin
*/
interface Deactivateable
{
/**
* Plugin deactivate in WordPress. Do not execute directly.
*
* @return void
*/
public function deactivate();
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
interface Hookable
{
/**
* Init hooks (actions and filters).
*
* @return void
*/
public function hooks();
}

View File

@@ -0,0 +1,21 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
interface HookableCollection extends Hookable
{
/**
* Add hookable object.
*
* @param Hookable|HookablePluginDependant $hookable_object Hookable object.
*/
public function add_hookable(Hookable $hookable_object);
/**
* Get hookable instance.
*
* @param string $class_name Class name.
*
* @return false|Hookable
*/
public function get_hookable_instance_by_class_name($class_name);
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
trait HookableParent
{
/**
* Hookable objects.
*
* @var array[Hookable]
*/
private $hookable_objects = array();
/**
* Add hookable object.
*
* @param Hookable|HookablePluginDependant $hookable_object Hookable object.
*/
public function add_hookable(Hookable $hookable_object)
{
if ($hookable_object instanceof HookablePluginDependant) {
$hookable_object->set_plugin($this);
}
$this->hookable_objects[] = $hookable_object;
}
/**
* Get hookable instance.
*
* @param string $class_name Class name.
*
* @return false|Hookable
*/
public function get_hookable_instance_by_class_name($class_name)
{
foreach ($this->hookable_objects as $hookable_object) {
if ($hookable_object instanceof $class_name) {
return $hookable_object;
}
}
return \false;
}
/**
* Run hooks method on all hookable objects.
*/
protected function hooks_on_hookable_objects()
{
/** @var Hookable $hookable_object $hookable_object */
foreach ($this->hookable_objects as $hookable_object) {
if ($hookable_object instanceof Conditional) {
if ($hookable_object::is_needed()) {
$hookable_object->hooks();
}
} else {
$hookable_object->hooks();
}
}
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
interface HookablePluginDependant extends Hookable
{
/**
* Set Plugin.
*
* @param AbstractPlugin $plugin Plugin.
*
* @return null
*/
public function set_plugin(AbstractPlugin $plugin);
/**
* Get plugin.
*
* @return AbstractPlugin.
*/
public function get_plugin();
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
/**
* @package WPDesk\PluginBuilder\Plugin
*/
trait PluginAccess
{
/**
* Plugin.
*
* @var AbstractPlugin
*/
private $plugin;
/**
* Set plugin.
*
* @param AbstractPlugin $plugin Plugin.
*/
public function set_plugin(AbstractPlugin $plugin)
{
$this->plugin = $plugin;
}
/**
* Get plugin.
*
* @return AbstractPlugin
*/
public function get_plugin()
{
return $this->plugin;
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
/**
* Most clean plugin class with only most important details.
*/
abstract class SlimPlugin implements \Przelewy24Vendor\WPDesk_Translatable
{
/**
* Initializes plugin external state.
*
* The plugin internal state is initialized in the constructor and the plugin should be internally consistent after creation.
* The external state includes hooks execution, communication with other plugins, integration with WC etc.
*
* @return void
*/
abstract public function init();
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Plugin;
/**
* @deprecated Use wpdesk/wp-view
*
* @package WPDesk\PluginBuilder\Plugin
*/
trait TemplateLoad
{
/**
* Plugin path.
*
* @var string
*/
protected $plugin_path;
/**
* Template path.
*
* @var string
*/
protected $template_path;
/**
* Init base variables for plugin
*/
public function init_template_base_variables()
{
$this->plugin_path = $this->plugin_info->get_plugin_dir();
$this->template_path = $this->plugin_info->get_text_domain();
}
/**
* Renders end returns selected template
*
* @param string $name Name of the template.
* @param string $path Additional inner path to the template.
* @param array $args args Accessible from template.
*
* @return string
*/
public function load_template($name, $path = '', $args = array())
{
$plugin_template_path = trailingslashit($this->plugin_path) . 'templates/';
// Look within passed path within the theme - this is priority.
$template = locate_template(array(trailingslashit($this->get_template_path()) . trailingslashit($path) . $name . '.php'));
if (!$template) {
$template = $plugin_template_path . trailingslashit($path) . $name . '.php';
}
extract($args);
ob_start();
include $template;
return ob_get_clean();
}
/**
* Get template path.
*
* @return string
*/
public function get_template_path()
{
return trailingslashit($this->template_path);
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Przelewy24Vendor;
/**
* Have info about what class should be built by WPDesk_Builder
*
* have to be compatible with PHP 5.2.x
*/
interface WPDesk_Buildable
{
/** @return string */
public function get_class_name();
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Przelewy24Vendor;
if (!\interface_exists('Przelewy24Vendor\WPDesk_Translatable')) {
require_once __DIR__ . '/Translatable.php';
}
/**
* Have MUST HAVE info for plugin instantion
*
* have to be compatible with PHP 5.2.x
*/
interface WPDesk_Has_Plugin_Info extends WPDesk_Translatable
{
/**
* @return string
*/
public function get_plugin_file_name();
/**
* @return string
*/
public function get_plugin_dir();
/**
* @return string
*/
public function get_version();
}

View File

@@ -0,0 +1,190 @@
<?php
namespace Przelewy24Vendor;
if (!\interface_exists('Przelewy24Vendor\WPDesk_Translatable')) {
require_once __DIR__ . '/Translatable.php';
}
if (!\interface_exists('Przelewy24Vendor\WPDesk_Buildable')) {
require_once __DIR__ . '/Buildable.php';
}
if (!\interface_exists('Przelewy24Vendor\WPDesk_Has_Plugin_Info')) {
require_once __DIR__ . '/Has_Plugin_Info.php';
}
/**
* Structure with core info about plugin
*
* have to be compatible with PHP 5.2.x
*/
class WPDesk_Plugin_Info implements WPDesk_Translatable, WPDesk_Buildable, WPDesk_Has_Plugin_Info
{
/** @var string */
private $plugin_file_name;
/** @var string */
private $plugin_dir;
/** @var string */
private $plugin_url;
/** @var string */
private $class_name;
/** @var string */
private $version;
/** @var string */
private $product_id;
/** @var string */
private $plugin_name;
/** @var \DateTimeInterface */
private $release_date;
/** string */
private $text_domain;
/**
* @var array
*/
private $plugin_shops;
/**
* @return string
*/
public function get_plugin_file_name()
{
return $this->plugin_file_name;
}
/**
* @param string $plugin_name
*/
public function set_plugin_file_name($plugin_name)
{
$this->plugin_file_name = $plugin_name;
}
/**
* @return string
*/
public function get_plugin_dir()
{
return $this->plugin_dir;
}
/**
* @param string $plugin_dir
*/
public function set_plugin_dir($plugin_dir)
{
$this->plugin_dir = $plugin_dir;
}
/**
* @return string
*/
public function get_plugin_url()
{
return $this->plugin_url;
}
/**
* @param string $plugin_url
*/
public function set_plugin_url($plugin_url)
{
$this->plugin_url = $plugin_url;
}
/**
* @return string
*/
public function get_version()
{
return $this->version;
}
/**
* @param string $version
*/
public function set_version($version)
{
$this->version = $version;
}
/**
* @return string
*/
public function get_product_id()
{
return $this->product_id;
}
/**
* @param string $product_id
*/
public function set_product_id($product_id)
{
$this->product_id = $product_id;
}
/**
* @return string
*/
public function get_plugin_name()
{
return $this->plugin_name;
}
/**
* @param string $plugin_name
*/
public function set_plugin_name($plugin_name)
{
$this->plugin_name = $plugin_name;
}
/**
* @return DateTimeInterface
*/
public function get_release_date()
{
return $this->release_date;
}
/**
* @param \DateTimeInterface $release_date
*/
public function set_release_date($release_date)
{
$this->release_date = $release_date;
}
/**
* @return string
*/
public function get_class_name()
{
return $this->class_name;
}
/**
* @param string $class_name
*/
public function set_class_name($class_name)
{
$this->class_name = $class_name;
}
/**
* @return string
*/
public function get_text_domain()
{
return $this->text_domain;
}
/**
* @param $value
*/
public function set_text_domain($value)
{
$this->text_domain = $value;
}
/**
* @return array
*/
public function get_plugin_shops()
{
return $this->plugin_shops;
}
/**
* @param array $plugin_shops
*/
public function set_plugin_shops($plugin_shops)
{
$this->plugin_shops = $plugin_shops;
}
/**
* @return string
*/
public function get_plugin_slug()
{
return \basename($this->get_plugin_dir());
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace Przelewy24Vendor;
/**
* @deprecated Have typo so better use WPDesk_Translatable
*/
interface WPDesk_Translable
{
/** @return string */
public function get_text_domain();
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Przelewy24Vendor;
if (!\interface_exists('Przelewy24Vendor\WPDesk_Translable')) {
require_once 'Translable.php';
}
/**
* Have info about textdomain - how to translate texts
*
* have to be compatible with PHP 5.2.x
*/
interface WPDesk_Translatable extends WPDesk_Translable
{
/** @return string */
public function get_text_domain();
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Storage\Exception;
class ClassAlreadyExists extends \RuntimeException
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Storage\Exception;
class ClassNotExists extends \RuntimeException
{
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Storage;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\AbstractPlugin;
interface PluginStorage
{
/**
* @param string $class
* @param AbstractPlugin $object
*/
public function add_to_storage($class, $object);
/**
* @param string $class
*
* @return AbstractPlugin
*/
public function get_from_storage($class);
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Storage;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\AbstractPlugin;
/**
* Can store plugin instances in static variable
*
* @package WPDesk\PluginBuilder\Storage
*/
class StaticStorage implements PluginStorage
{
protected static $instances = [];
/**
* @param string $class
* @param AbstractPlugin $object
*/
public function add_to_storage($class, $object)
{
if (isset(self::$instances[$class])) {
throw new Exception\ClassAlreadyExists("Class {$class} already exists");
}
self::$instances[$class] = $object;
}
/**
* @param string $class
*
* @return AbstractPlugin
*/
public function get_from_storage($class)
{
if (isset(self::$instances[$class])) {
return self::$instances[$class];
}
throw new Exception\ClassNotExists("Class {$class} not exists in storage");
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Storage;
class StorageFactory
{
/**
* @return PluginStorage
*/
public function create_storage()
{
return new WordpressFilterStorage();
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Przelewy24Vendor\WPDesk\PluginBuilder\Storage;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\AbstractPlugin;
/**
* Can store plugin instances in WordPress filter system.
*
* @package WPDesk\PluginBuilder\Storage
*/
class WordpressFilterStorage implements PluginStorage
{
const STORAGE_FILTER_NAME = 'wpdesk_plugin_instances';
/**
* @param string $class
* @param AbstractPlugin $object
*/
public function add_to_storage($class, $object)
{
add_filter(self::STORAGE_FILTER_NAME, static function ($plugins) use ($class, $object) {
if (isset($plugins[$class])) {
throw new Exception\ClassAlreadyExists("Class {$class} already exists");
}
$plugins[$class] = $object;
return $plugins;
});
}
/**
* @param string $class
*
* @return AbstractPlugin
*/
public function get_from_storage($class)
{
$plugins = apply_filters(self::STORAGE_FILTER_NAME, []);
if (isset($plugins[$class])) {
return $plugins[$class];
}
throw new Exception\ClassNotExists("Class {$class} not exists in storage");
}
}

View File

@@ -0,0 +1 @@
.wpdesk-notice-gutenberg { display: none; }

View File

@@ -0,0 +1,29 @@
jQuery( document ).ready(function() {
jQuery('.wpdesk-notice-gutenberg').each(function( index ) {
var classList = jQuery(this).attr('class').split(/\s+/);
var type = '';
jQuery.each(classList, function(index, item) {
if (item.startsWith('notice-')) {
type = item.replace('notice-','');
}
});
content = this.innerText;
actions = [];
jQuery.each(jQuery(this).find('a'), function(index, item) {
text = item.innerText;
actions.push({
url: item.href,
label: text.charAt(0).toUpperCase() + text.slice(1),
});
});
isDismiss = jQuery(this).hasClass('is-dismissible');
window.wp.data.dispatch( 'core/notices' ).createNotice(
type,
content,
{
isDismissible: isDismiss,
actions: actions
}
);
});
} );

View File

@@ -0,0 +1,27 @@
jQuery( document ).ready(function() {
jQuery(document).on('click', '.notice-dismiss', function () {
const $notice_div= jQuery(this).closest('div.notice');
const notice_name = $notice_div.data('notice-name');
const source = $notice_div.data('source');
const security = $notice_div.data('security');
if ('' !== notice_name) {
jQuery.ajax({
url: ajaxurl,
type: 'post',
data: {
security: security,
action: 'wpdesk_notice_dismiss',
notice_name: notice_name,
source: source,
},
success: function (response) {
}
});
}
});
jQuery( document ).on( 'click', '.notice-dismiss-link', function() {
jQuery(this).closest('div.notice').data('source',jQuery(this).data('source'));
jQuery(this).closest('div.notice').find('.notice-dismiss').click();
});
} );

View File

@@ -0,0 +1,62 @@
{
"name": "wpdesk\/wp-notice",
"description": "Library for displaying Wordpress notices.",
"license": "MIT",
"keywords": [
"wordpress",
"notice",
"admin"
],
"homepage": "https:\/\/gitlab.com\/wpdesk\/wp-notice",
"minimum-stability": "stable",
"authors": [
{
"name": "grola",
"email": "grola@wpdesk.net"
}
],
"config": {
"platform": {
"php": "7.4.33"
},
"allow-plugins": {
"kylekatarnls\/update-helper": true,
"wpdesk\/wp-codeception": true
}
},
"require": {
"php": ">=7.4",
"wpdesk\/wp-builder": "^1.0|^2.0"
},
"require-dev": {
"wp-coding-standards\/wpcs": "^0.14.1",
"squizlabs\/php_codesniffer": "^3.0.2",
"mockery\/mockery": "*",
"10up\/wp_mock": "*",
"wimg\/php-compatibility": "^8",
"wpdesk\/wp-codeception": "^2",
"phpunit\/phpunit": "^8"
},
"autoload": {
"psr-4": {
"Przelewy24Vendor\\WPDesk\\Notice\\": "src\/WPDesk\/Notice\/"
},
"files": [
"src\/WPDesk\/notice-functions.php"
]
},
"autoload-dev": {},
"scripts": {
"phpcs": "phpcs",
"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"
},
"repositories": {
"wpdesk": {
"type": "composer",
"url": "https:\/\/gitlab.wpdesk.dev\/api\/v4\/group\/wpdesk\/-\/packages\/composer\/"
}
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Przelewy24Vendor;
require_once __DIR__ . '/vendor/autoload.php';
if (!\class_exists('Przelewy24Vendor\WPDesk\Notice\AjaxHandler')) {
require_once __DIR__ . '/src/WPDesk/Notice/AjaxHandler.php';
}
if (!\class_exists('Przelewy24Vendor\WPDesk\Notice\Notice')) {
require_once __DIR__ . 'src/WPDesk/Notice/Notice.php';
}
if (!\class_exists('Przelewy24Vendor\WPDesk\Notice\PermanentDismissibleNotice')) {
require_once __DIR__ . '/src/WPDesk/Notice/PermanentDismissibleNotice.php';
}
if (!\class_exists('Przelewy24Vendor\WPDesk\Notice\Factory')) {
require_once __DIR__ . '/src/WPDesk/Notice/Factory.php';
}
require_once __DIR__ . '/src/WPDesk/notice-functions.php';

View File

@@ -0,0 +1,96 @@
<?php
namespace Przelewy24Vendor\WPDesk\Notice;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\HookablePluginDependant;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\PluginAccess;
/**
* Class AjaxHandler
*
* AjaxHandler for dismissible notices.
*
* @package WPDesk\Notice
*/
class AjaxHandler implements HookablePluginDependant
{
use PluginAccess;
const POST_FIELD_NOTICE_NAME = 'notice_name';
const POST_FIELD_SOURCE = 'source';
const POST_FIELD_SECURITY = 'security';
const SCRIPTS_VERSION = '4';
const SCRIPT_HANDLE = 'wpdesk_notice';
const SCRIPT_HANDLE_GUTENBERG = 'wpdesk_notice_gutenberg';
/**
* @var string
*/
private $assetsURL;
/**
* AjaxHandler constructor.
*
* @param string|null $assetsURL Assets URL.
*/
public function __construct($assetsURL = null)
{
$this->assetsURL = $assetsURL ?? plugins_url('/assets/', dirname(__FILE__, 3));
}
/**
* Hooks.
*/
public function hooks()
{
add_action('admin_enqueue_scripts', [$this, 'enqueueAdminScripts']);
add_action('wp_ajax_wpdesk_notice_dismiss', [$this, 'processAjaxNoticeDismiss']);
}
public function isBlockEditor(): bool
{
if (!function_exists('get_current_screen')) {
return \false;
}
$screen = \get_current_screen();
return is_object($screen) ? $screen->is_block_editor() : \false;
}
/**
* Enqueue admin scripts.
*/
public function enqueueAdminScripts()
{
wp_register_script(self::SCRIPT_HANDLE, trailingslashit($this->assetsURL) . 'js/notice.js', ['jquery'], self::SCRIPTS_VERSION);
wp_enqueue_script(self::SCRIPT_HANDLE);
if ($this->isBlockEditor()) {
wp_register_script(self::SCRIPT_HANDLE_GUTENBERG, trailingslashit($this->assetsURL) . 'js/gutenberg.js', ['jquery'], self::SCRIPTS_VERSION);
wp_enqueue_script(self::SCRIPT_HANDLE_GUTENBERG);
} else {
wp_register_style(self::SCRIPT_HANDLE, trailingslashit($this->assetsURL) . 'css/admin.css', [], self::SCRIPTS_VERSION);
wp_enqueue_style(self::SCRIPT_HANDLE);
}
}
/**
* Process AJAX notice dismiss.
*
* Updates corresponded WordPress option and fires wpdesk_notice_dismissed_notice action with notice name.
*/
public function processAjaxNoticeDismiss()
{
if (isset($_POST[self::POST_FIELD_NOTICE_NAME])) {
$noticeName = sanitize_text_field($_POST[self::POST_FIELD_NOTICE_NAME]);
$optionName = PermanentDismissibleNotice::OPTION_NAME_PREFIX . $noticeName;
check_ajax_referer($optionName, self::POST_FIELD_SECURITY);
if (!current_user_can('edit_posts')) {
wp_send_json_error();
}
if (isset($_POST[self::POST_FIELD_SOURCE])) {
$source = sanitize_text_field($_POST[self::POST_FIELD_SOURCE]);
} else {
$source = null;
}
update_option($optionName, PermanentDismissibleNotice::OPTION_VALUE_DISMISSED);
do_action('wpdesk_notice_dismissed_notice', $noticeName, $source);
if (defined('DOING_AJAX') && \DOING_AJAX) {
wp_send_json_success();
}
}
if (defined('DOING_AJAX') && \DOING_AJAX) {
wp_send_json_error();
}
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Przelewy24Vendor\WPDesk\Notice;
/**
* Class Factory
*
* Factory for notices.
* @package WPDesk\Notice
*/
class Factory
{
/**
* Creates Notice object.
*
* @param string $noticeType Notice type.
* @param string $noticeContent Notice content.
* @param bool $isDismissible Is dismissible.
* @param int $priority Priority.
*
* @return Notice
*/
public static function notice($noticeContent = '', $noticeType = 'info', $isDismissible = \false, $priority = 10)
{
return new Notice($noticeContent, $noticeType, $isDismissible, $priority);
}
/**
* Creates PermanentDismissibleNotice object.
*
* @param string $noticeContent
* @param string $noticeType
* @param string $noticeName
* @param int $priority
*
* @return PermanentDismissibleNotice
*/
public static function permanentDismissibleNotice($noticeContent = '', $noticeName = '', $noticeType = '', $priority = 10)
{
return new PermanentDismissibleNotice($noticeContent, $noticeName, $noticeType, $priority);
}
}

View File

@@ -0,0 +1,231 @@
<?php
namespace Przelewy24Vendor\WPDesk\Notice;
/**
* Class Notice
*
* WordPress admin notice.
* @package WPDesk\Notice
*/
class Notice
{
const NOTICE_TYPE_ERROR = 'error';
const NOTICE_TYPE_WARNING = 'warning';
const NOTICE_TYPE_SUCCESS = 'success';
const NOTICE_TYPE_INFO = 'info';
const ADMIN_FOOTER_BASE_PRIORITY = 9999999;
/**
* Notice type.
*
* @var string
*/
protected $noticeType;
/**
* Notice content.
*
* @var string
*/
protected $noticeContent;
/**
* Is dismissible.
*
* @var bool
*/
protected $dismissible;
/**
* Notice hook priority.
* @var int;
*/
protected $priority;
/**
* Is action added?
* @var bool
*/
private $actionAdded = \false;
/**
* Attributes.
*
* @var string[]
*/
protected $attributes = array();
/**
* Show notice in gutenberg editor.
*
* @var bool
*/
protected $showInGutenberg = \false;
/**
* WPDesk_Flexible_Shipping_Notice constructor.
*
* @param string $noticeContent Notice content.
* @param string $noticeType Notice type.
* @param bool $dismissible Is dismissible.
* @param int $priority Notice priority.
* @param array $attributes Attributes.
* @param bool $showInGutenberg Show notice in gutenberg editor.
*/
public function __construct($noticeContent, $noticeType = 'info', $dismissible = \false, $priority = 10, $attributes = array(), $showInGutenberg = \false)
{
$this->noticeContent = $noticeContent;
$this->noticeType = $noticeType;
$this->dismissible = $dismissible;
$this->priority = $priority;
$this->attributes = $attributes;
$this->showInGutenberg = $showInGutenberg;
$this->addAction();
}
/**
* @return string
*/
public function getNoticeContent()
{
return $this->noticeContent;
}
/**
* @param string $noticeContent
*/
public function setNoticeContent($noticeContent)
{
$this->noticeContent = $noticeContent;
}
/**
* @return string
*/
public function getNoticeType()
{
return $this->noticeType;
}
/**
* @param string $noticeType
*/
public function setNoticeType($noticeType)
{
$this->noticeType = $noticeType;
}
/**
* @return bool
*/
public function isDismissible()
{
return $this->dismissible;
}
/**
* @param bool $dismissible
*/
public function setDismissible($dismissible)
{
$this->dismissible = $dismissible;
}
/**
* @return int
*/
public function getPriority()
{
return $this->priority;
}
/**
* @param int $priority
*/
public function setPriority($priority)
{
$this->priority = $priority;
if ($this->actionAdded) {
$this->removeAction();
$this->addAction();
}
}
/**
* Add notice action.
*/
protected function addAction()
{
if (!$this->actionAdded) {
add_action('admin_notices', [$this, 'showNotice'], $this->priority);
add_action('admin_footer', [$this, 'showNotice'], self::ADMIN_FOOTER_BASE_PRIORITY + intval($this->priority));
$this->actionAdded = \true;
}
}
/**
* Remove action.
*/
protected function removeAction()
{
if ($this->actionAdded) {
remove_action('admin_notices', [$this, 'showNotice'], $this->priority);
remove_action('admin_footer', [$this, 'showNotice'], self::ADMIN_FOOTER_BASE_PRIORITY + intval($this->priority));
$this->actionAdded = \false;
}
}
/**
* Add attribute.
*
* @param string $name Name
* @param string $value Value.
*/
public function addAttribute($name, $value)
{
$this->attributes[$name] = $value;
}
/**
* Get notice class.
*
* @return string
*/
protected function getNoticeClass()
{
$notice_classes = ['notice'];
if ('updated' === $this->noticeType) {
$notice_classes[] = $this->noticeType;
} else {
$notice_classes[] = 'notice-' . $this->noticeType;
}
if ($this->dismissible) {
$notice_classes[] = 'is-dismissible';
}
if (isset($this->attributes['class'])) {
$notice_classes[] = $this->attributes['class'];
}
if ($this->showInGutenberg) {
$notice_classes[] = 'wpdesk-notice-gutenberg';
}
return implode(' ', $notice_classes);
}
/**
* Get attributes as string.
*
* @return string
*/
protected function getAttributesAsString()
{
$attribute_string = sprintf('class="%1$s"', esc_attr($this->getNoticeClass()));
foreach ($this->attributes as $attribute_name => $attribute_value) {
if ('class' !== $attribute_name) {
$attribute_string .= sprintf(' %1$s="%2$s"', esc_html($attribute_name), esc_attr($attribute_value));
}
}
return $attribute_string;
}
private function addParagraphToContent()
{
if (0 === strpos($this->noticeContent, '<p>')) {
return \false;
}
if (0 === strpos($this->noticeContent, '<div>') || 0 === strpos($this->noticeContent, '<div ')) {
return \false;
}
return \true;
}
/**
* Show notice;
*/
public function showNotice()
{
$this->removeAction();
$noticeFormat = '<div %1$s>%2$s</div>';
if ($this->addParagraphToContent()) {
$noticeFormat = '<div %1$s><p>%2$s</p></div>';
}
echo \wp_kses_post(sprintf($noticeFormat, $this->getAttributesAsString(), $this->noticeContent));
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace Przelewy24Vendor\WPDesk\Notice;
/**
* Class PermanentDismissibleNotice
*
* WordPress admin dismissible notice.
* @package WPDesk\Notice
*/
class PermanentDismissibleNotice extends Notice
{
const OPTION_NAME_PREFIX = 'wpdesk_notice_dismiss_';
const OPTION_VALUE_DISMISSED = '1';
/**
* @var string
*/
private $noticeName;
/**
* @var string
*/
private $noticeSecurity;
/**
* @var string
*/
private $noticeDismissOptionName;
/**
* WPDesk_Flexible_Shipping_Notice constructor.
*
* @param string $noticeContent Notice content.
* @param string $noticeName Notice dismiss option name.
* @param string $noticeType Notice type.
* @param int $priority Priority
* @param array $attributes Attributes.
* @param bool $showInGutenberg Show notice in gutenberg editor.
*/
public function __construct($noticeContent, $noticeName, $noticeType = 'info', $priority = 10, $attributes = array(), $showInGutenberg = \false)
{
parent::__construct($noticeContent, $noticeType, \true, $priority, $attributes, $showInGutenberg);
$this->noticeName = $noticeName;
$this->noticeDismissOptionName = static::OPTION_NAME_PREFIX . $noticeName;
if (self::OPTION_VALUE_DISMISSED === get_option($this->noticeDismissOptionName, '')) {
$this->removeAction();
} else {
$this->noticeSecurity = wp_create_nonce($this->noticeDismissOptionName);
}
}
/**
* Undo dismiss notice.
*/
public function undoDismiss()
{
delete_option($this->noticeDismissOptionName);
$this->addAction();
}
/**
* Get attributes as string.
*
* @return string
*/
protected function getAttributesAsString()
{
$attributesAsString = parent::getAttributesAsString();
$attributesAsString .= sprintf(' data-notice-name="%1$s"', esc_attr($this->noticeName));
$attributesAsString .= sprintf(' data-security="%1$s"', esc_attr($this->noticeSecurity));
$attributesAsString .= sprintf(' id="wpdesk-notice-%1$s"', esc_attr($this->noticeName));
return $attributesAsString;
}
}

View File

@@ -0,0 +1,228 @@
<?php
namespace Przelewy24Vendor;
if (!\function_exists('Przelewy24Vendor\WPDeskInitWpNoticeAjaxHandler')) {
/**
* Init notices AJAX Handler.
*
* @param string|null $assetsUrl
*
* @return \WPDesk\Notice\AjaxHandler
*/
function WPDeskInitWpNoticeAjaxHandler($assetsUrl = null)
{
$ajax_handler = new \Przelewy24Vendor\WPDesk\Notice\AjaxHandler($assetsUrl);
$ajax_handler->hooks();
return $ajax_handler;
}
}
if (!\function_exists('Przelewy24Vendor\wpdesk_init_wp_notice_ajax_handler')) {
/**
* Alias for {@see WPDeskInitNoticeAjaxHandler()} function.
*
* @param null $assetsUrl
*
* @return \WPDesk\Notice\AjaxHandler
*/
function wpdesk_init_wp_notice_ajax_handler($assetsUrl = null)
{
return WPDeskInitWpNoticeAjaxHandler($assetsUrl);
}
}
if (!\function_exists('Przelewy24Vendor\WPDeskWpNotice')) {
/**
* Creates Notice.
*
* @param string $noticeContent Notice content.
* @param string $noticeType Notice type.
* @param bool $dismissible Dismissible notice.
* @param int $priority Notice priority,
*
* @return \WPDesk\Notice\Notice
*/
function WPDeskWpNotice($noticeContent, $noticeType = 'info', $dismissible = \false, $priority = 10)
{
return \Przelewy24Vendor\WPDesk\Notice\Factory::notice($noticeContent, $noticeType, $dismissible, $priority);
}
}
if (!\function_exists('Przelewy24Vendor\wpdesk_wp_notice')) {
/**
* Creates Notice.
*
* Alias for {@see WPDeskNotice()} function.
*
* @param string $noticeContent Notice content.
* @param string $noticeType Notice type.
* @param bool $dismissible Dismissible notice.
* @param int $priority Notice priority,
*
* @return \WPDesk\Notice\Notice
*/
function wpdesk_wp_notice($noticeContent, $noticeType = 'info', $dismissible = \false, $priority = 10)
{
return WPDeskWpNotice($noticeContent, $noticeType, $dismissible, $priority);
}
}
if (!\function_exists('Przelewy24Vendor\WPDeskWpNoticeInfo')) {
/**
* Creates Notice Info.
*
* @param string $noticeContent Notice content.
* @param bool $dismissible Dismissible notice.
* @param int $priority Notice priority,
*
* @return \WPDesk\Notice\Notice
*/
function WPDeskWpNoticeInfo($noticeContent, $dismissible = \false, $priority = 10)
{
return \Przelewy24Vendor\WPDesk\Notice\Factory::notice($noticeContent, \Przelewy24Vendor\WPDesk\Notice\Notice::NOTICE_TYPE_INFO, $dismissible, $priority);
}
}
if (!\function_exists('Przelewy24Vendor\wpdesk_wp_notice_info')) {
/**
* Creates Notice Info.
*
* Alias for {@see WPDeskNoticeInfo()} function.
*
* @param string $noticeContent Notice content.
* @param bool $dismissible Dismissible notice.
* @param int $priority Notice priority,
*
* @return \WPDesk\Notice\Notice
*/
function wpdesk_wp_notice_info($noticeContent, $dismissible = \false, $priority = 10)
{
return WPDeskWpNoticeInfo($noticeContent, $dismissible, $priority);
}
}
if (!\function_exists('Przelewy24Vendor\WPDeskWpNoticeError')) {
/**
* Creates Notice Error.
*
* @param string $noticeContent Notice content.
* @param bool $dismissible Dismissible notice.
* @param int $priority Notice priority,
*
* @return \WPDesk\Notice\Notice
*/
function WPDeskWpNoticeError($noticeContent, $dismissible = \false, $priority = 10)
{
return \Przelewy24Vendor\WPDesk\Notice\Factory::notice($noticeContent, \Przelewy24Vendor\WPDesk\Notice\Notice::NOTICE_TYPE_ERROR, $dismissible, $priority);
}
}
if (!\function_exists('Przelewy24Vendor\wpdesk_wp_notice_error')) {
/**
* Creates Notice Error.
*
* Alias for {@see WPDeskNoticeError()} function.
*
* @param string $noticeContent Notice content.
* @param bool $dismissible Dismissible notice.
* @param int $priority Notice priority,
*
* @return \WPDesk\Notice\Notice
*/
function wpdesk_wp_notice_error($noticeContent, $dismissible = \false, $priority = 10)
{
return WPDeskWpNoticeError($noticeContent, $dismissible, $priority);
}
}
if (!\function_exists('Przelewy24Vendor\WPDeskWpNoticeWarning')) {
/**
* Creates Notice Warning.
*
* @param string $noticeContent Notice content.
* @param bool $dismissible Dismissible notice.
* @param int $priority Notice priority,
*
* @return \WPDesk\Notice\Notice
*/
function WPDeskWpNoticeWarning($noticeContent, $dismissible = \false, $priority = 10)
{
return \Przelewy24Vendor\WPDesk\Notice\Factory::notice($noticeContent, \Przelewy24Vendor\WPDesk\Notice\Notice::NOTICE_TYPE_WARNING, $dismissible, $priority);
}
}
if (!\function_exists('Przelewy24Vendor\wpdesk_wp_notice_warning')) {
/**
* Creates Notice Warning.
*
* Alias for {@see WPDeskNoticeWarning()} function.
*
* @param string $noticeContent Notice content.
* @param bool $dismissible Dismissible notice.
* @param int $priority Notice priority,
*
* @return \WPDesk\Notice\Notice
*/
function wpdesk_wp_notice_warning($noticeContent, $dismissible = \false, $priority = 10)
{
return WPDeskWpNoticeWarning($noticeContent, $dismissible, $priority);
}
}
if (!\function_exists('Przelewy24Vendor\WPDeskWpNoticeSuccess')) {
/**
* Creates Notice Success.
*
* @param string $noticeContent Notice content.
* @param bool $dismissible Dismissible notice.
* @param int $priority Notice priority,
*
* @return \WPDesk\Notice\Notice
*/
function WPDeskWpNoticeSuccess($noticeContent, $dismissible = \false, $priority = 10)
{
return \Przelewy24Vendor\WPDesk\Notice\Factory::notice($noticeContent, \Przelewy24Vendor\WPDesk\Notice\Notice::NOTICE_TYPE_SUCCESS, $dismissible, $priority);
}
}
if (!\function_exists('Przelewy24Vendor\wpdesk_wp_notice_success')) {
/**
* Creates Notice Success.
*
* Alias for {@see WPDeskNoticeSuccess()} function.
*
* @param string $noticeContent Notice content.
* @param bool $dismissible Dismissible notice.
* @param int $priority Notice priority,
*
* @return \WPDesk\Notice\Notice
*/
function wpdesk_wp_notice_success($noticeContent, $dismissible = \false, $priority = 10)
{
return WPDeskWpNoticeSuccess($noticeContent, $dismissible, $priority);
}
}
if (!\function_exists('Przelewy24Vendor\WPDeskPermanentDismissibleWpNotice')) {
/**
* Creates Permanent Dismissible Notice.
*
* @param string $noticeContent Notice content.
* @param string $noticeType Notice type.
* @param string $noticeName Notice name.
* @param int $priority Notice priority.
*
* @return \WPDesk\Notice\Notice
*/
function WPDeskPermanentDismissibleWpNotice($noticeContent, $noticeName, $noticeType = 'info', $priority = 10)
{
return \Przelewy24Vendor\WPDesk\Notice\Factory::permanentDismissibleNotice($noticeContent, $noticeName, $noticeType, $priority);
}
}
if (!\function_exists('Przelewy24Vendor\wpdesk_permanent_dismissible_wp_notice')) {
/**
* Creates Permanent Dismissible Notice.
*
* Alias for {@see WPDeskPermanentDismissibleNotice()} function.
*
* @param string $noticeContent Notice content.
* @param string $noticeName Notice name.
* @param string $noticeType Notice type.
* @param int $priority Notice priority.
*
* @return \WPDesk\Notice\Notice
*/
function wpdesk_permanent_dismissible_wp_notice($noticeContent, $noticeName, $noticeType = 'info', $priority = 10)
{
return WPDeskPermanentDismissibleWpNotice($noticeContent, $noticeName, $noticeType, $priority);
}
}

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.4"
}
},
"require": {
"php": ">=7.4",
"wpdesk\/wp-basic-requirements": "^3.2.3",
"wpdesk\/wp-builder": "^2.0.0",
"wpdesk\/wp-wpdesk-tracker": "^3"
},
"require-dev": {
"phpunit\/phpunit": "^7||^8||^9",
"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 Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\Activateable;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\Deactivateable;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\SlimPlugin;
use Przelewy24Vendor\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(\Przelewy24Vendor\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(\Przelewy24Vendor\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);
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Przelewy24Vendor\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(\Przelewy24Vendor\WPDesk_Plugin_Info $info);
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization;
use Przelewy24Vendor\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(\Przelewy24Vendor\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(\Przelewy24Vendor\WPDesk_Plugin_Info $plugin_info);
}

View File

@@ -0,0 +1,48 @@
<?php
namespace Przelewy24Vendor\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 Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\Simple;
use Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\InitializationFactory;
use Przelewy24Vendor\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(\Przelewy24Vendor\WPDesk_Plugin_Info $info)
{
if ($this->free) {
return new SimpleFreeStrategy($info);
}
return new SimplePaidStrategy($info);
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\Simple;
use Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\ActivationTrait;
use Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\BuilderTrait;
use Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\InitializationStrategy;
use Przelewy24Vendor\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(\Przelewy24Vendor\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(\Przelewy24Vendor\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(\Przelewy24Vendor\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);
// Flush usage tracker late, to remain backward compatible with plugins which could instantiate
// the tracker on their own through `wpdesk_tracker_instance` filter.
$this->get_tracker_instance();
$this->register_tracker_ui_extensions();
return $this->plugin;
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\Simple;
use Przelewy24Vendor\WPDesk\Helper\HelperRemover;
use Przelewy24Vendor\WPDesk\Helper\PrefixedHelperAsLibrary;
use Przelewy24Vendor\WPDesk\License\PluginRegistrator;
use Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\ActivationTrait;
use Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\BuilderTrait;
use Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\PluginDisablerByFileTrait;
use Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\InitializationStrategy;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\ActivationAware;
use Przelewy24Vendor\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(\Przelewy24Vendor\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(\Przelewy24Vendor\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(\Przelewy24Vendor\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);
// Flush usage tracker late, to remain backward compatible with plugins which could instantiate
// the tracker on their own through `wpdesk_tracker_instance` filter.
$this->get_tracker_instance();
$this->register_tracker_ui_extensions();
}, $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;
}
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\Simple;
use Przelewy24Vendor\WPDesk\Tracker\OptInOptOut;
/**
* 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 \Przelewy24Vendor\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());
}
private function register_tracker_ui_extensions()
{
$shops = $this->plugin_info->get_plugin_shops();
$shop_url = $shops[get_locale()] ?? $shops['default'] ?? 'https://wpdesk.net';
$tracker_ui = new OptInOptOut($this->plugin_info->get_plugin_file_name(), $this->plugin_info->get_plugin_slug(), $shop_url, $this->plugin_info->get_plugin_name());
$tracker_ui->create_objects();
$tracker_ui->hooks();
}
}

View File

@@ -0,0 +1,163 @@
<?php
namespace Przelewy24Vendor\WPDesk\Plugin\Flow;
use Przelewy24Vendor\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-gateway-przelewy24';
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);
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 = 'activation_plugin_' . $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(\Przelewy24Vendor\WPDesk_Plugin_Info $plugin_info)
{
$lang_dir = 'lang';
if (method_exists($plugin_info, 'get_language_dir')) {
$lang_dir = $plugin_info->get_language_dir();
}
$text_domain = $plugin_info->get_text_domain();
add_filter('doing_it_wrong_trigger_error', function ($doing_it_wrong, $function, $message, $version) use ($text_domain) {
if (wp_get_environment_type() === 'production' && $function === '_load_textdomain_just_in_time' && strpos($message, '<code>' . $text_domain . '</code>') !== \false) {
return \false;
}
return $doing_it_wrong;
}, 10, 4);
\load_plugin_textdomain($plugin_info->get_text_domain(), '', 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 \Przelewy24Vendor\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 \Przelewy24Vendor\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('', $this->plugin_file));
$plugin_info->set_plugin_shops($this->plugin_shops);
return $plugin_info;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Przelewy24Vendor;
/**
* @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 \Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\Simple\SimpleFactory(\true);
}
require \dirname(__FILE__) . '/plugin-init-php52.php';

View File

@@ -0,0 +1,49 @@
<?php
namespace Przelewy24Vendor;
/**
* @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 \Przelewy24Vendor\WPDesk\Plugin\Flow\Initialization\Simple\SimpleFactory();
}
if (!isset($plugin_shops) || !\is_array($plugin_shops)) {
$plugin_shops = array();
}
$bootstrap = new 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);
}

View File

@@ -0,0 +1,37 @@
{
"name": "wpdesk\/wp-plugin-flow-paid",
"description": "WP Desk Plugin Flow Paid",
"license": "propertiary",
"keywords": [
"wordpress",
"plugin"
],
"type": "library",
"authors": [
{
"name": "Krzysiek",
"email": "krzysiek@wpdesk.pl"
}
],
"require": {
"php": ">=7.4 || ^8",
"wpdesk\/wp-wpdesk-license": "^4.0.0",
"wpdesk\/wp-plugin-flow-common": "^1.0.1"
},
"config": {
"gitlab-domains": [
"gitlab.wpdesk.dev"
]
},
"autoload-dev": {
"classmap": [
"vendor\/wpdesk\/wp-basic-requirements"
]
},
"repositories": {
"wpdesk": {
"type": "composer",
"url": "https:\/\/gitlab.wpdesk.dev\/api\/v4\/group\/wpdesk\/-\/packages\/composer\/"
}
}
}

View File

@@ -0,0 +1,45 @@
{
"name": "wpdesk\/wp-view",
"license": "MIT",
"authors": [
{
"name": "WP Desk",
"role": "Owner"
},
{
"name": "Krzysiek",
"email": "krzysiek@wpdesk.pl"
}
],
"require": {
"php": ">=7.4 | ^8"
},
"require-dev": {
"phpunit\/phpunit": "^7||^8||^9",
"wpdesk\/wp-code-sniffer": "^1",
"mockery\/mockery": "*",
"10up\/wp_mock": "*",
"wpdesk\/phpstan-rules": "^1.1"
},
"autoload": {
"psr-4": {
"Przelewy24Vendor\\WPDesk\\View\\": "src\/"
}
},
"scripts": {
"phpcs": "phpcs",
"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"
},
"config": {
"platform": {
"php": "7.4"
},
"allow-plugins": {
"dealerdirect\/phpcodesniffer-composer-installer": true,
"phpstan\/extension-installer": true
}
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace Przelewy24Vendor\WPDesk\View;
use Przelewy24Vendor\WPDesk\View\Renderer\SimplePhpRenderer;
use Przelewy24Vendor\WPDesk\View\Resolver\ChainResolver;
use Przelewy24Vendor\WPDesk\View\Resolver\DirResolver;
use Przelewy24Vendor\WPDesk\View\Resolver\WPThemeResolver;
/**
* Facilitates building of the default plugin renderer.
*
* @package WPDesk\View
*/
class PluginViewBuilder
{
/** @var string */
private $plugin_dir;
/** @var string[] */
private $template_dirs;
/**
* @param string $plugin_dir Plugin directory path(absolute path)
* @param string|string[] $template_dir Directory or list of directories with templates to render
*/
public function __construct($plugin_dir, $template_dir = 'templates')
{
$this->plugin_dir = $plugin_dir;
if (!is_array($template_dir)) {
$this->template_dirs = [$template_dir];
} else {
$this->template_dirs = $template_dir;
}
}
/**
* Creates simple renderer that search for the templates in plugin dir and in theme/child dir.
*
* For example if your plugin dir is /plugin, template dir is /templates, theme is /theme, and a child theme is /child
* the templates will be loaded from(order is important):
* - /child/plugin/*.php
* - /theme/plugin/*.php
* - /plugin/templates/*.php
*
* @return SimplePhpRenderer
*/
public function createSimpleRenderer()
{
$resolver = new ChainResolver();
$resolver->appendResolver(new WPThemeResolver(basename($this->plugin_dir)));
foreach ($this->template_dirs as $dir) {
$dir = trailingslashit($this->plugin_dir) . trailingslashit($dir);
$resolver->appendResolver(new DirResolver($dir));
}
return new SimplePhpRenderer($resolver);
}
/**
* Load templates using simple renderer.
*
* @param string $name Name of the template
* @param string $path Additional path of the template ie. for path "path" the templates would be loaded from /plugin/templates/path/*.php
* @param array $args Arguments for templates to use
*
* @return string Rendered template.
*/
public function loadTemplate($name, $path = '.', $args = [])
{
$renderer = $this->createSimpleRenderer();
return $renderer->render(trailingslashit($path) . $name, $args);
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Przelewy24Vendor\WPDesk\View\Renderer;
use Przelewy24Vendor\WPDesk\View\Resolver\Resolver;
/**
* Can render templates
*/
class LoadTemplatePlugin implements Renderer
{
private $plugin;
private $path;
public function __construct($plugin, $path = '')
{
$this->plugin = $plugin;
$this->path = $path;
}
public function set_resolver(Resolver $resolver)
{
}
public function render($template, ?array $params = null)
{
return $this->plugin->load_template($template, $this->path, $params);
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Przelewy24Vendor\WPDesk\View\Renderer;
use Przelewy24Vendor\WPDesk\View\Resolver\Resolver;
/**
* Can render templates
*/
interface Renderer
{
/**
* Set the resolver used to map a template name to a resource the renderer may consume.
*
* @param Resolver $resolver
*/
public function set_resolver(Resolver $resolver);
/**
* @param string $template
* @param array $params
*
* @return string
*/
public function render(string $template, ?array $params = null);
/**
* @param string $template
* @param array $params
*/
public function output_render(string $template, ?array $params = null);
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Przelewy24Vendor\WPDesk\View\Renderer;
use Przelewy24Vendor\WPDesk\View\Resolver\Resolver;
/**
* Can render templates
*/
class SimplePhpRenderer implements Renderer
{
/** @var Resolver */
private $resolver;
public function __construct(Resolver $resolver)
{
$this->set_resolver($resolver);
}
/**
* @param Resolver $resolver
*
* @return void|Resolver
*/
public function set_resolver(Resolver $resolver)
{
$this->resolver = $resolver;
}
/**
* @param string $template
* @param array|null $params
*
* @return string
*/
public function render(string $template, ?array $params = null)
{
ob_start();
$this->output_render($template, $params);
return ob_get_clean();
}
/**
* @param string $template
* @param array|null $params
*/
public function output_render(string $template, ?array $params = null)
{
if ($params !== null) {
extract($params, \EXTR_SKIP);
}
include $this->resolver->resolve($template . '.php');
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace Przelewy24Vendor\WPDesk\View\Resolver;
use Przelewy24Vendor\WPDesk\View\Renderer\Renderer;
use Przelewy24Vendor\WPDesk\View\Resolver\Exception\CanNotResolve;
/**
* Provide resolvers and this class can try them one after another
*
* @package WPDesk\View\Resolver
*/
class ChainResolver implements Resolver
{
/** @var Resolver[] */
private $resolvers;
/**
* Warning: function with variadic input. Input should be list of Resolver instances.
*/
public function __construct()
{
$args = func_get_args();
foreach ($args as $resolver) {
$this->appendResolver($resolver);
}
}
/**
* Append resolver to the end of the list
*
* @param Resolver $resolver
*/
public function appendResolver($resolver)
{
$this->resolvers[] = $resolver;
}
/**
* Resolve name to full path
*
* @param string $name
* @param Renderer|null $renderer
*
* @return string
*/
public function resolve($name, ?Renderer $renderer = null)
{
foreach ($this->resolvers as $resolver) {
try {
return $resolver->resolve($name);
} catch (CanNotResolve $e) {
// not interested
}
}
throw new CanNotResolve("Cannot resolve {$name}");
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Przelewy24Vendor\WPDesk\View\Resolver;
use Przelewy24Vendor\WPDesk\View\Renderer\Renderer;
use Przelewy24Vendor\WPDesk\View\Resolver\Exception\CanNotResolve;
/**
* Class should resolve name by serching in provided dir. If empty then current dir
*
* @package WPDesk\View\Resolver
*/
class DirResolver implements Resolver
{
/** @var string */
private $dir;
/**
* Base path for templates ie. subdir
*
* @param $dir
*/
public function __construct($dir)
{
$this->dir = $dir;
}
/**
* Resolve name to full path
*
* @param string $name
* @param Renderer|null $renderer
*
* @return string
*/
public function resolve($name, ?Renderer $renderer = null)
{
$dir = rtrim($this->dir, '/');
$fullName = $dir . '/' . $name;
if (file_exists($fullName)) {
return $fullName;
}
throw new CanNotResolve("Cannot resolve {$name}");
}
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Przelewy24Vendor\WPDesk\View\Resolver\Exception;
class CanNotResolve extends \RuntimeException
{
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Przelewy24Vendor\WPDesk\View\Resolver;
use Przelewy24Vendor\WPDesk\View\Renderer\Renderer;
use Przelewy24Vendor\WPDesk\View\Resolver\Exception\CanNotResolve;
/**
* This resolver never finds the file
*
* @package WPDesk\View\Resolver
*/
class NullResolver implements Resolver
{
public function resolve($name, ?Renderer $renderer = null)
{
throw new CanNotResolve('Null Cannot resolve');
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Przelewy24Vendor\WPDesk\View\Resolver;
use Przelewy24Vendor\WPDesk\View\Renderer\Renderer;
/**
* Can resolve template name to a file
*/
interface Resolver
{
/**
* Resolve a template/pattern name to a resource the renderer can consume
*
* @param string $name
* @param null|Resolver $renderer
*
* @return string
*/
public function resolve($name, ?Renderer $renderer = null);
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Przelewy24Vendor\WPDesk\View\Resolver;
use Przelewy24Vendor\WPDesk\View\Renderer\Renderer;
use Przelewy24Vendor\WPDesk\View\Resolver\Exception\CanNotResolve;
/**
* Class should resolve name by standard wp theme resolve
*
* @package WPDesk\View\Resolver
*/
class WPThemeResolver implements Resolver
{
/** @var string */
private $template_base_path;
/**
* Base path for templates ie. subdir
*
* @param $template_base_path
*/
public function __construct($template_base_path)
{
$this->template_base_path = $template_base_path;
}
/**
* Resolve name to full path
*
* @param string $name
* @param Renderer|null $renderer
*
* @return string
*/
public function resolve($name, ?Renderer $renderer = null)
{
$templateFile = locate_template([trailingslashit($this->template_base_path) . $name]);
if (!$templateFile) {
throw new CanNotResolve("Cannot resolve {$name}");
}
return $templateFile;
}
}

View File

@@ -0,0 +1,30 @@
<?php
declare (strict_types=1);
namespace Przelewy24Vendor\WPDesk\View\Resolver;
use Przelewy24Vendor\WPDesk\View\Renderer\Renderer;
use Przelewy24Vendor\WPDesk\View\Resolver\Exception\CanNotResolve;
/**
* Locate templates, respecting WooCommerce template load order, prepending custom path to seek for templates. This supports user's template overrides by default.
*/
class WooTemplateResolver implements Resolver
{
/** @var string */
private $base_path;
public function __construct(string $base_path)
{
if (!function_exists('wc_locate_template')) {
throw new \RuntimeException(sprintf('The "%s" resolver needs the WooCommerce plugin. Make sure it is installed and active.', __CLASS__));
}
$this->base_path = $base_path;
}
public function resolve($name, ?Renderer $renderer = null): string
{
$template = wc_locate_template($name, '', $this->base_path);
if ($template === '') {
throw new CanNotResolve("Cannot resolve template {$name}");
}
return $template;
}
}

View File

@@ -0,0 +1,55 @@
{
"name": "wpdesk\/wp-wpdesk-license",
"type": "library",
"authors": [
{
"name": "Krzysiek",
"email": "krzysiek@wpdesk.pl"
}
],
"license": "proprietary",
"require": {
"php": ">=7.4 || ^8",
"ext-curl": "*",
"ext-json": "*",
"psr\/log": "^1 || ^2 || ^3"
},
"require-dev": {
"phpunit\/phpunit": "^9",
"wpdesk\/wp-code-sniffer": "^1",
"wpdesk\/phpstan-rules": "^1",
"10up\/wp_mock": "^1"
},
"suggest": {
"wpdesk\/wp-logs": "^1.10"
},
"autoload": {
"psr-4": {
"Przelewy24Vendor\\WPDesk\\License\\": "src\/"
}
},
"extra": {
"text-domain": "wp-wpdesk-license",
"translations-folder": "lang",
"po-files": {
"pl_PL": "pl_PL.po",
"de_DE": "de_DE.po"
}
},
"scripts": {
"phpunit-unit": "phpunit --configuration phpunit-unit.xml --coverage-text --colors=never",
"phpunit-unit-fast": "phpunit --configuration phpunit-unit.xml --no-coverage",
"lint:phpstan": "phpstan analyze --level 6 src",
"lint:style": "phpcs",
"lint": [
"@lint:phpstan",
"@lint:style"
]
},
"config": {
"allow-plugins": {
"dealerdirect\/phpcodesniffer-composer-installer": true,
"phpstan\/extension-installer": true
}
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Przelewy24Vendor\WPDesk\License\Changelog\Filter;
use FilterIterator;
use Iterator;
/**
* Filters items by version.
*/
class ByVersion extends FilterIterator
{
private string $version;
public function __construct(Iterator $changes, string $version)
{
parent::__construct($changes);
$this->version = $version;
}
public function accept(): bool
{
$change = $this->getInnerIterator()->current();
return version_compare($change['version'], $this->version, '>');
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace Przelewy24Vendor\WPDesk\License\Changelog;
use Iterator;
/**
* Can format changelog.
*/
class Formatter
{
private Iterator $changes;
private array $types;
public function __construct(Iterator $changes)
{
$this->changes = $changes;
}
public function set_changelog_types(array $types): void
{
$this->types = $types;
}
public function prepare_formatted_html(): string
{
$output = '';
foreach ($this->get_changes_data() as $name => $changes) {
if (empty($changes)) {
continue;
}
$output .= sprintf("\n\n<strong>%s</strong>: <br/>* %s", $name, implode(' <br />* ', array_map('esc_html', $changes)));
}
return wp_kses_post(nl2br(trim($output)));
}
private function get_changes_data(): array
{
$changes = [];
foreach ($this->types as $type) {
$changes[$type] = [];
}
foreach ($this->changes as $item) {
foreach ($item['changes'] as $type => $change) {
if (!isset($changes[$type])) {
$changes[$type] = [];
}
$changes[$type] = array_merge($changes[$type], $change);
}
}
return array_filter($changes);
}
}

View File

@@ -0,0 +1,84 @@
<?php
namespace Przelewy24Vendor\WPDesk\License\Changelog;
use ArrayObject;
use Przelewy24Vendor\WPDesk\License\Changelog\Parser\Line;
/**
* Can parse changelog.
*/
class Parser
{
private string $changelog;
private array $changelog_parsed_data = [];
private array $types = [];
/**
* Parser constructor.
*/
public function __construct(string $changelog)
{
$this->changelog = $changelog;
}
/**
* @return ArrayObject
*/
public function get_parsed_changelog(): ArrayObject
{
return new ArrayObject($this->changelog_parsed_data);
}
/**
* @return Parser $this
*/
public function parse(): self
{
$this->changelog_parsed_data = [];
$version = $type = null;
// phpcs:ignore
foreach ($this->get_lines() as $line) {
if (!$this->types && $types = $line->get_types()) {
// phpcs:ignore
$this->types = $types;
continue;
}
if ($release = $line->get_release_details()) {
// phpcs:ignore
$version = $release['version'];
$type = null;
continue;
}
if ($type_details = $line->get_type_details()) {
// phpcs:ignore
$type = $type_details;
continue;
}
if (!$version || !$type) {
continue;
}
if (!isset($this->changelog_parsed_data[$version])) {
$this->changelog_parsed_data[$version] = ['version' => $version, 'changes' => []];
}
$this->changelog_parsed_data[$version]['changes'][$type][] = $line->get_value();
}
return $this;
}
/**
* @return array
*/
public function get_types(): array
{
return $this->types;
}
/**
* @return Line[]
*/
private function get_lines(): array
{
$content = base64_decode($this->changelog);
if (!$content) {
return [];
}
return array_map(function ($line) {
return new Line($line);
}, array_filter(preg_split("/\r\n|\n|\r/", wp_kses_post($content))));
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Przelewy24Vendor\WPDesk\License\Changelog\Parser;
/**
* Can parse single changelog line.
*/
class Line
{
private string $line;
public function __construct(string $line)
{
$this->line = $line;
}
/**
* @return array{version: string, date: string}
*/
public function get_release_details(): array
{
preg_match('/## \[(.*)\] - (.*)/', $this->line, $output_array);
if (!isset($output_array[1], $output_array[2])) {
return [];
}
return ['version' => $output_array[1], 'date' => $output_array[2]];
}
public function get_type_details(): string
{
preg_match('/### (.*)/', $this->line, $output_array);
if (!isset($output_array[1])) {
return '';
}
return $output_array[1];
}
/** @return string[] */
public function get_types(): array
{
preg_match('/##### (.*)/', $this->line, $output_array);
if (!isset($output_array[1])) {
return [];
}
return (array) wp_parse_list($output_array[1]);
}
public function get_value(): string
{
return ltrim($this->line, '- ');
}
}

View File

@@ -0,0 +1,18 @@
<?php
declare (strict_types=1);
namespace Przelewy24Vendor\WPDesk\License\LicenseServer;
use Przelewy24Vendor\Psr\Log\LoggerInterface;
use Przelewy24Vendor\Psr\Log\LoggerTrait;
/**
* Dummy implementation of LoggerInterface.
*/
class DummyLogger implements LoggerInterface
{
use LoggerTrait;
public function log($level, $message, array $context = [])
{
error_log('wpdesk.license ' . $level . ': ' . $message);
}
}

View File

@@ -0,0 +1,26 @@
<?php
declare (strict_types=1);
namespace Przelewy24Vendor\WPDesk\License\LicenseServer;
/**
* Show message that plugin cannot be upgraded, if the license server is not in use, i.e. the plugin
* have not been downloaded from original source.
*/
final class ImpossibleToUpgrade
{
private PluginVersionInfo $plugin_info;
public function __construct(PluginVersionInfo $plugin_info)
{
$this->plugin_info = $plugin_info;
}
public function hooks(): void
{
add_action('after_plugin_row_' . $this->plugin_info->get_plugin_file_name(), $this);
}
public function __invoke(): void
{
$plugin_info = $this->plugin_info;
include __DIR__ . '/../../templates/impossible-to-upgrade.php';
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Przelewy24Vendor\WPDesk\License\LicenseServer;
/**
* Idea is to have a class that will be responsible for checking if external requests are blocked.
* Can show a notice if external requests are blocked.
*/
class PluginExternalBlocking
{
private PluginVersionInfo $plugin_info;
private string $server;
public function __construct(PluginVersionInfo $plugin_info, string $server)
{
$this->plugin_info = $plugin_info;
$this->server = $server;
}
/**
* Check for external blocking constants
*/
public function display_info_when_external_blocking(): void
{
// show notice if external requests are blocked through the WP_HTTP_BLOCK_EXTERNAL constant
if (defined('Przelewy24Vendor\WP_HTTP_BLOCK_EXTERNAL') && \Przelewy24Vendor\WP_HTTP_BLOCK_EXTERNAL === \true) {
// check if our API endpoint is in the allowed hosts
$host = parse_url($this->server, \PHP_URL_HOST);
if (!defined('Przelewy24Vendor\WP_ACCESSIBLE_HOSTS') || stristr(\Przelewy24Vendor\WP_ACCESSIBLE_HOSTS, $host) === \false) {
?>
<div class="error">
<p>
<?php
printf(wp_kses_post(__('<b>Warning!</b> You\'re blocking external requests which means you won\'t be able to get %1$s updates. Please add %2$s to %3$s.', 'woocommerce-gateway-przelewy24')), esc_html($this->plugin_info->get_plugin_name()), wp_kses_post('<strong>' . $host . '</strong>'), wp_kses_post('<code>WP_ACCESSIBLE_HOSTS</code>'));
?>
</p>
</div>
<?php
}
}
}
public function hooks(): void
{
add_action('admin_notices', [$this, 'display_info_when_external_blocking']);
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Przelewy24Vendor\WPDesk\License\LicenseServer;
/**
* Provides plugin license information and gives a change to modify it.
*/
class PluginLicense
{
private const ACTIVATED_VALUE = 'Activated';
private PluginVersionInfo $plugin_info;
public function __construct(PluginVersionInfo $info)
{
$this->plugin_info = $info;
}
public function is_active(): bool
{
return get_option($this->prepare_option_is_active()) === self::ACTIVATED_VALUE;
}
public function set_active(): void
{
update_option($this->prepare_option_is_active(), self::ACTIVATED_VALUE);
}
public function set_inactive(): void
{
update_option($this->prepare_option_is_active(), 'Inactive');
}
private function prepare_option_is_active(): string
{
return $this->prepare_option_name('activated');
}
private function prepare_option_name(string $field): string
{
return sprintf('api_%1$s_%2$s', $this->plugin_info->get_plugin_slug(), $field);
}
}

View File

@@ -0,0 +1,74 @@
<?php
namespace Przelewy24Vendor\WPDesk\License\LicenseServer;
use Przelewy24Vendor\Psr\Log\LoggerInterface;
/**
* New server license manager.
* Fields in this class can be replaced during build process and/or package preparation on the license server.
*/
class PluginRegistrator
{
private PluginVersionInfo $plugin_info;
private LoggerInterface $logger;
/**
* Field CAN be replaced during build process.
*
* @var string License server URL.
*/
private string $server = 'https://license.wpdesk.dev';
/**
* Token WILL BE REPLACED during package preparation on the license server.
*
* @var string User token.
*/
private static string $token = '95aa5470-afb2-4c29-a2aa-ec29d8cd6f50';
/**
* This field WILL BE REPLACED during package preparation on the license server.
* Thanks to this field we know whether a plugin has been downloaded from license server.
*
* @var bool Should use license server.
*/
private static bool $should_use_license_server = true;
public static function get_token(): string
{
return apply_filters('wpdesk/license/token', self::$token);
}
public static function should_use_license_server(): bool
{
return apply_filters('wpdesk/license/use_license', self::$should_use_license_server);
}
/**
* @param PluginVersionInfo|\WPDesk_Plugin_Info $plugin_info
*
* @throws \InvalidArgumentException
*/
public function __construct($plugin_info, ?LoggerInterface $logger = null)
{
if ($plugin_info instanceof PluginVersionInfo) {
$this->plugin_info = $plugin_info;
} else {
try {
$this->plugin_info = PluginVersionInfo::from_legacy_plugin_info($plugin_info);
} catch (\Exception $e) {
throw new \InvalidArgumentException(sprintf('Plugin info is not valid. Error: %s', $e->getMessage()));
}
}
$this->logger = $logger ?? new DummyLogger();
}
public function is_active(): bool
{
return (new PluginLicense($this->plugin_info))->is_active();
}
public function initialize_license_manager(): void
{
$this->server = apply_filters('wpdesk/license/server', $this->server);
if (self::should_use_license_server()) {
(new PluginUpgrade($this->plugin_info, $this->server, self::get_token(), $this->logger))->hooks();
(new PluginExternalBlocking($this->plugin_info, $this->server))->hooks();
(new PluginViewVersionInfo($this->plugin_info, $this->server, $this->logger))->hooks();
} else {
(new ImpossibleToUpgrade($this->plugin_info))->hooks();
}
}
}

View File

@@ -0,0 +1,182 @@
<?php
namespace Przelewy24Vendor\WPDesk\License\LicenseServer;
use Przelewy24Vendor\Psr\Log\LoggerInterface;
/**
* Retrieves updates from license server.
*/
class PluginUpgrade
{
private string $server;
private string $token;
private PluginVersionInfo $plugin_info;
private LoggerInterface $logger;
public function __construct(PluginVersionInfo $plugin_info, string $server, string $token, LoggerInterface $logger)
{
$this->server = $server;
$this->token = $token;
$this->plugin_info = $plugin_info;
$this->logger = $logger;
}
/**
* @param string|array|\WP_Error|\stdClass $value Any response from remote server or request routine.
*
* @return mixed|\stdClass
* @internal
*/
public function inject_info_about_plugin_update_from_remote($value)
{
// on info about upgrade
if ($value instanceof \stdClass) {
// every each time only timestamp mutex is saved and when it's not the stdClass is here
$plugin_filename = $this->plugin_info->get_plugin_file_name();
if (isset($value->response[$plugin_filename])) {
// pre_set_site_transient is used two times and we need only once
return $value;
}
$remote_response = $this->request_remote_plugin_info_plugin_update_check();
if ($remote_response instanceof \WP_Error) {
// WP Error while connecting to remote server
$value->response[$plugin_filename] = $this->react_to_wp_error_response($remote_response);
} else {
// there is a response
$parsed_response = json_decode($remote_response['body'], \true);
if (!empty($parsed_response) && $parsed_response['code'] >= 200) {
// response makes sense and had been parsed
if ($parsed_response['code'] !== 503) {
$value->response[$plugin_filename] = $this->react_to_valid_remote_response($parsed_response);
}
if (empty($value->response[$plugin_filename]->message) && empty($value->response[$plugin_filename]->need_update)) {
unset($value->response[$plugin_filename]);
}
} else {
// there is a response, but it makes no sense and cannot be parsed
$value->response[$plugin_filename] = $this->react_to_nonsense_response($remote_response);
}
}
}
return $value;
}
/**
* @return array|\WP_Error The same typ of response as wp_remote_request
*/
private function request_remote_plugin_info_plugin_update_check()
{
global $wp_version;
$params = ['site_url' => defined('Przelewy24Vendor\WP_HOME') ? \Przelewy24Vendor\WP_HOME : get_home_url(), 'plugin_name' => $this->plugin_info->get_plugin_name(), 'plugin_slug' => $this->plugin_info->get_plugin_slug(), 'plugin_version' => $this->plugin_info->get_version(), 'php_version' => \PHP_VERSION, 'wc_version' => class_exists('WooCommerce') ? \WooCommerce::instance()->version : '', 'wp_version' => $wp_version, 'locale' => str_replace('-', '_', get_bloginfo('language'))];
$product_id = rawurlencode($this->plugin_info->get_product_id());
return wp_remote_request("{$this->server}/api/v1/cid/{$this->token}/plugin/{$product_id}", ['body' => json_encode($params), 'method' => 'POST']);
}
/**
* React when there an error while retrieving data from remote server.
*
* @param \WP_Error $remote_response
*
* @return \stdClass
*/
private function react_to_wp_error_response(\WP_Error $remote_response): \stdClass
{
$response = $this->prepare_transient_base();
$response->message = wp_kses_post('<span style="color: red" class="error">' . sprintf(esc_html__('Error while connecting to remote server %s. Please contact your hosting provider or try again later. Errors: ', 'woocommerce-gateway-przelewy24'), $this->server) . implode(', ', $remote_response->get_error_messages()) . '</span>');
$response->new_version = '';
return $response;
}
/**
* Prepares response object to store in WP transient to avoid code duplication.
*
* @return \stdClass
*/
private function prepare_transient_base(): \stdClass
{
$response = new \stdClass();
$response->id = $this->plugin_info->get_plugin_slug();
$response->slug = $this->plugin_info->get_plugin_slug();
$response->plugin = $this->plugin_info->get_plugin_file_name();
return $response;
}
/**
* We have a valid response from server so we can react to it: show upgrade possibility or not.
*
* @param array $parsed_response
*
* @return \stdClass
*/
private function react_to_valid_remote_response(array $parsed_response): \stdClass
{
$response = $this->prepare_transient_base();
// Just setting these two fields below is enough to show upgrade possibility
$response->new_version = $parsed_response['version'] ?? null;
$response->package = $parsed_response['package'] ?? null;
$response->requires_php = $parsed_response['requires_php'] ?? null;
$response->need_update = $parsed_response['need_update'] ?? null;
$response->changelog = $parsed_response['changelog'] ?? null;
$response->message = $parsed_response['message'] ?? null;
// Set license status
if (empty($parsed_response['package'])) {
(new PluginLicense($this->plugin_info))->set_inactive();
} else {
(new PluginLicense($this->plugin_info))->set_active();
}
return $response;
}
private function render_changelog(string $plugin_version, string $changelog): string
{
$parser = new \Przelewy24Vendor\WPDesk\License\Changelog\Parser($changelog);
$parser->parse();
$parsed_changelog = $parser->get_parsed_changelog()->getIterator();
$changes = new \Przelewy24Vendor\WPDesk\License\Changelog\Filter\ByVersion($parsed_changelog, $plugin_version);
if (iterator_count($changes) > 0) {
$changelogFormatter = new \Przelewy24Vendor\WPDesk\License\Changelog\Formatter($changes);
$changelogFormatter->set_changelog_types($parser->get_types());
$formatted_changelog = $changelogFormatter->prepare_formatted_html();
if ($formatted_changelog) {
return wp_kses_post('<br /><br />' . $formatted_changelog);
}
}
return '';
}
/**
* It was not possible to parse a response. Show some error message.
*
* @param mixed $remote_response
*
* @return \stdClass
*/
private function react_to_nonsense_response($remote_response): \stdClass
{
$response = $this->prepare_transient_base();
$this->logger->notice("Update for {$this->plugin_info->get_plugin_name()} cannot be retrieved. Remote response invalid: " . json_encode($remote_response));
if (isset($remote_response['response']['code'])) {
if (in_array($remote_response['response']['code'], [503, 502], \true)) {
$message = esc_html__('License server is currently unavailable. Please, try again later.', 'woocommerce-gateway-przelewy24');
} else {
$message = sprintf(esc_html__('Error while connecting to remote server %1$s. Please contact with your hosting provider. Cannot parse response. Response code: %2$s Message: %3$s', 'woocommerce-gateway-przelewy24'), $this->server, $remote_response['response']['code'], $remote_response['body']);
}
} else {
$message = sprintf(esc_html__('Error while connecting to remote server %1$s. Please contact with your hosting provider. Cannot parse response: %2$s', 'woocommerce-gateway-przelewy24'), $this->server, json_encode($remote_response));
}
$response->new_version = '';
$response->message = wp_kses_post("<span style='color: red' class='upgrade-error'>{$message}</span>");
return $response;
}
public function show_messages_from_transients(array $plugin_data, \stdClass $response): void
{
$transient = \get_site_transient('update_plugins');
$message = $transient->response[$this->plugin_info->get_plugin_file_name()]->message ?? '';
$changelog = $transient->response[$this->plugin_info->get_plugin_file_name()]->changelog ?? '';
// Server could have sent as some message to show. Show it.
if (!empty($message)) {
echo \wp_kses_post('<br><br>' . $message);
}
if (!empty($changelog)) {
echo $this->render_changelog($plugin_data['Version'], $changelog);
// phpcs:ignore
}
}
public function hooks(): void
{
add_filter('pre_set_site_transient_update_plugins', [$this, 'inject_info_about_plugin_update_from_remote'], 10);
add_action('in_plugin_update_message-' . $this->plugin_info->get_plugin_file_name(), [$this, 'show_messages_from_transients'], 10, 2);
}
}

View File

@@ -0,0 +1,68 @@
<?php
declare (strict_types=1);
namespace Przelewy24Vendor\WPDesk\License\LicenseServer;
/**
* Internal Value Object holding basic plugin information required by license server.
*/
final class PluginVersionInfo
{
private string $plugin_file_name;
private string $plugin_slug;
private string $version;
private string $product_id;
private string $plugin_name;
private array $plugin_shops;
public function __construct(string $plugin_name, string $version, string $product_id, string $plugin_slug, string $plugin_file_name, array $plugin_shops = [])
{
$this->plugin_name = $plugin_name;
$this->version = $version;
$this->product_id = $product_id;
$this->plugin_slug = $plugin_slug;
$this->plugin_file_name = $plugin_file_name;
$this->plugin_shops = $plugin_shops;
}
public function get_plugin_file_name(): string
{
return $this->plugin_file_name;
}
public function get_version(): string
{
return $this->version;
}
public function get_product_id(): string
{
return $this->product_id;
}
public function get_plugin_name(): string
{
return $this->plugin_name;
}
public function get_plugin_slug(): string
{
return $this->plugin_slug;
}
public function get_shop_url(): string
{
return $this->plugin_shops[get_user_locale()] ?? $this->plugin_shops['default'] ?? $this->plugin_shops[0] ?? 'https://wpdesk.net/';
}
public function get_customer_account_url(): string
{
return rtrim($this->get_shop_url(), '/') . '/sk/' . $this->get_plugin_slug() . '-downloads-' . $this->get_shop_short_slug();
}
private function get_shop_short_slug(): string
{
$host = parse_url($this->get_shop_url(), \PHP_URL_HOST);
$shop = str_replace('www.', '', $host ?? '');
$slugs = ['wpdesk.pl' => 'pl', 'wpdesk.net' => 'net', 'shopmagic.app' => 'sm', 'flexibleinvoices.com' => 'fi', 'flexiblecoupons.com' => 'fc'];
return $slugs[$shop] ?? 'net';
}
/**
* @param \WPDesk_Plugin_Info $info
*/
public static function from_legacy_plugin_info($info): self
{
return new self($info->get_plugin_name(), $info->get_version(), $info->get_product_id(), $info->get_plugin_slug(), $info->get_plugin_file_name(), empty($info->get_plugin_shops()) ? [] : $info->get_plugin_shops());
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Przelewy24Vendor\WPDesk\License\LicenseServer;
use Przelewy24Vendor\Psr\Log\LoggerInterface;
/**
* Attaches to WordPress hooks to display plugin version info.
*/
class PluginViewVersionInfo
{
private string $server;
private PluginVersionInfo $plugin_info;
private LoggerInterface $logger;
public function __construct(PluginVersionInfo $plugin_info, string $server, LoggerInterface $logger)
{
$this->plugin_info = $plugin_info;
$this->server = $server;
$this->logger = $logger;
}
public function hooks(): void
{
add_filter('plugins_api', function ($false, $action, $args) {
if ($action === 'plugin_information' && $args->slug === $this->plugin_info->get_plugin_slug()) {
$remote_response = wp_remote_get("{$this->server}/api/v1/plugin/{$this->plugin_info->get_product_id()}");
if ($remote_response instanceof \WP_Error) {
$this->logger->notice('Error while trying to get plugin info: ' . json_encode($remote_response));
return $false;
}
$parsed_response = json_decode($remote_response['body'], \true);
if ($parsed_response) {
$response = new \stdClass();
$response->name = $this->plugin_info->get_plugin_name();
$response->slug = $parsed_response['slug'];
$response->version = $parsed_response['version'];
$response->homepage = $parsed_response['homepage'];
$response->requires = $parsed_response['requires'];
$response->tested = $parsed_response['tested'];
$response->testedWC = $parsed_response['testedWC'];
$response->requiresWC = $parsed_response['requiresWC'];
$response->last_updated = date_i18n('Y-n-d H:i:s', $parsed_response['last_updated']);
$response->requires_php = $parsed_response['requires_php'];
$response->sections = [];
$response->sections['description'] = $parsed_response['sections']['description'] ?? '';
$response->sections['changelog'] = nl2br($parsed_response['sections']['changelog'] ?? '');
return $response;
}
$this->logger->notice('Response from license server cannot be parsed: ' . json_encode($remote_response));
}
return $false;
}, 10, 3);
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Przelewy24Vendor\WPDesk\License;
/**
* @depreacted 4.0.0 Use LicenseServer\PluginRegistrator directly
*/
final class PluginRegistrator extends \Przelewy24Vendor\WPDesk\License\LicenseServer\PluginRegistrator
{
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Przelewy24Vendor;
\defined('ABSPATH') || exit;
?>
<tr class="plugin-update-tr active">
<td colspan="4" class="plugin-update colspanchange">
<div class="update-message notice inline notice-warning notice-alt">
<p>
<?php
\printf(\esc_html__('This version of %1$s plugin cannot be automatically upgraded. Download the plugin from %2$syour account%3$s to receive automatic updates in future.', 'woocommerce-gateway-przelewy24'), \esc_html($plugin_info->get_plugin_name()), '<a href="' . \esc_url_raw($plugin_info->get_customer_account_url()) . '" target=\'_blank\'>', '</a>');
?>
</p>
</div>
</td>
</tr>
<?php

View File

@@ -0,0 +1,70 @@
{
"name": "wpdesk\/wp-wpdesk-tracker",
"license": "MIT",
"authors": [
{
"name": "WP Desk",
"homepage": "https:\/\/wpdesk.net"
},
{
"name": "Krzysiek",
"email": "krzysiek@wpdesk.pl"
}
],
"require": {
"php": ">=7.4 || ^8",
"wpdesk\/wp-builder": "^2.0",
"wpdesk\/wp-notice": "^3.1",
"wpdesk\/wp-view": "^2",
"psr\/log": "^1 || ^2"
},
"require-dev": {
"phpunit\/phpunit": "^7 || ^8 || ^9",
"wpdesk\/phpstan-rules": "^1",
"wpdesk\/wp-code-sniffer": "^1",
"10up\/wp_mock": "^1"
},
"autoload": {
"classmap": [
"src\/"
],
"exclude-from-classmap": [
"scr\/PSR\/"
],
"psr-4": {
"Przelewy24Vendor\\": "src\/PSR\/"
}
},
"autoload-dev": {
"classmap": [
"tests\/"
]
},
"extra": {
"text-domain": "wpdesk-tracker",
"translations-folder": "lang",
"po-files": {
"pl_PL": "pl_PL.po",
"es_ES": "es_ES.po",
"en_AU": "en_AU.po",
"en_CA": "en_CA.po",
"en_GB": "en_GB.po",
"de_DE": "de_DE.po"
}
},
"scripts": {
"test": "echo composer is alive",
"phpcs": "phpcs",
"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",
"docs": "apigen generate"
},
"config": {
"allow-plugins": {
"dealerdirect\/phpcodesniffer-composer-installer": true,
"phpstan\/extension-installer": true
}
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Przelewy24Vendor\WPDesk\Tracker;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\Hookable;
/**
* Can enqueue assets.
*/
class Assets implements Hookable
{
/**
* @var string
*/
private $script_version = '1';
/**
* @var string
*/
private $plugin_slug;
/**
* @param string $plugin_slug
*/
public function __construct($plugin_slug)
{
$this->plugin_slug = $plugin_slug;
}
public function hooks()
{
add_action('admin_enqueue_scripts', [$this, 'admin_enqueue_scripts']);
}
public function admin_enqueue_scripts()
{
$screen = get_current_screen();
if ($screen->id === 'admin_page_wpdesk_tracker_' . $this->plugin_slug) {
$handle = 'wpdesk-helper-tracker_' . $this->plugin_slug;
wp_register_style($handle, plugin_dir_url(__FILE__) . '../../../assets/css/tracker.css', [], $this->script_version);
wp_register_script($handle, plugin_dir_url(__FILE__) . '../../../assets/js/admin.js', [], $this->script_version);
wp_enqueue_style($handle);
wp_enqueue_script($handle);
}
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace Przelewy24Vendor\WPDesk\Tracker;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\HookableCollection;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\HookableParent;
class OptInOptOut implements HookableCollection
{
use HookableParent;
/**
* @var string
*/
private $plugin_file;
/**
* @var string
*/
private $plugin_slug;
/**
* @var string
*/
private $shop_url;
/**
* @var string
*/
private $plugin_name;
/**
* @param string $plugin_file
* @param string $plugin_slug
* @param string $shop_url
* @param string $plugin_name
*/
public function __construct($plugin_file, $plugin_slug, $shop_url, $plugin_name)
{
$this->plugin_file = $plugin_file;
$this->plugin_slug = $plugin_slug;
$this->shop_url = $shop_url;
$this->plugin_name = $plugin_name;
}
/**
* Creates hookable objects.
*/
public function create_objects()
{
$this->add_hookable(new PluginActionLinks($this->plugin_file, $this->plugin_slug, $this->shop_url));
$this->add_hookable(new OptInPage($this->plugin_file, $this->plugin_slug));
$this->add_hookable(new OptOut($this->plugin_slug, $this->plugin_name));
$this->add_hookable(new Assets($this->plugin_slug));
}
public function hooks()
{
$this->hooks_on_hookable_objects();
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace Przelewy24Vendor\WPDesk\Tracker;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\Hookable;
use Przelewy24Vendor\WPDesk\View\Renderer\SimplePhpRenderer;
use Przelewy24Vendor\WPDesk\View\Resolver\DirResolver;
class OptInPage implements Hookable
{
public const WPDESK_TRACKER_ACTION = 'wpdesk_tracker_action';
public const WPDESK_TRACKER_NONCE = 'nonce';
/**
* @var string
*/
private $plugin_file;
/**
* @var string
*/
private $plugin_slug;
/** @var Shop|null */
private $shop;
/**
* @param string $plugin_file
* @param string $plugin_slug
* @param Shop|null $shop_url
*/
public function __construct($plugin_file, $plugin_slug, $shop = null)
{
$this->plugin_file = $plugin_file;
$this->plugin_slug = $plugin_slug;
$this->shop = $shop ?? new Shop('', $this->plugin_slug);
}
public function hooks()
{
add_action('admin_menu', [$this, 'add_submenu_page']);
add_action('admin_init', [$this, 'admin_init']);
}
public function add_submenu_page()
{
add_submenu_page('wpdesk_tracker', 'WP Desk Tracker', 'WP Desk Tracker', 'manage_options', 'wpdesk_tracker_' . $this->plugin_slug, [$this, 'output']);
}
/** @return void */
public function output()
{
$user = wp_get_current_user();
$username = $user->first_name ? $user->first_name : $user->user_login;
$allow_url = admin_url('admin.php?wpdesk_tracker=' . $this->plugin_slug);
$allow_url = add_query_arg('security', wp_create_nonce($this->plugin_slug), $allow_url);
$allow_url = add_query_arg('ctx', 'box', $allow_url);
$allow_url = add_query_arg('plugin', $this->plugin_slug, $allow_url);
$skip_url = $allow_url;
$allow_url = add_query_arg('allow', '1', $allow_url);
$skip_url = add_query_arg('allow', '0', $skip_url);
if (current_user_can('activate_plugins') && \false !== check_ajax_referer(self::WPDESK_TRACKER_ACTION, self::WPDESK_TRACKER_NONCE, \false) && isset($_GET['shop_url'])) {
$shop = new Shop(sanitize_text_field(wp_unslash($_GET['shop_url'])), $this->plugin_slug);
} else {
$shop = $this->shop;
}
$terms_url = $shop->get_usage_tracking_page();
$logo = $shop->get_shop_logo_file();
$logo_url = plugin_dir_url(__FILE__) . '../../../assets/images/' . $logo;
$renderer = new SimplePhpRenderer(new DirResolver(__DIR__ . '/views'));
$renderer->output_render('tracker-connect', ['logo_url' => apply_filters('wpdesk/tracker/logo_url', $logo_url, $this->plugin_slug), 'shop_name' => $shop->get_shop_name(), 'username' => $username, 'allow_url' => $allow_url, 'skip_url' => $skip_url, 'terms_url' => $terms_url]);
}
/**
* @deprecated Use OptInPage::output()
*/
public function wpdesk_tracker_page()
{
$this->output();
}
public function admin_init()
{
if (isset($_GET['wpdesk_tracker']) && $_GET['wpdesk_tracker'] === $this->plugin_slug) {
if (isset($_GET['allow']) && current_user_can('activate_plugins') && isset($_GET['security']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['security'])), $this->plugin_slug)) {
if ($_GET['allow'] === '1') {
$persistence = new \Przelewy24Vendor\WPDesk_Tracker_Persistence_Consent();
$persistence->set_active(\true);
delete_option('wpdesk_tracker_notice');
update_option('wpdesk_tracker_agree', '1');
}
if (wp_safe_redirect($this->determine_redirect_point())) {
exit;
}
}
}
}
/**
* Quick and dirty way to guess, where user should be redirected after submitting consent.
*/
private function determine_redirect_point(): string
{
$referer = wp_get_referer();
if ($referer === \false) {
return admin_url('plugins.php');
}
$query = parse_url($referer, \PHP_URL_QUERY) ?? '';
if (str_contains($query, 'page=wpdesk_tracker')) {
// If request came from dedicated page, redirect to plugins.
return admin_url('plugins.php');
}
return $referer;
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Przelewy24Vendor\WPDesk\Tracker;
use Przelewy24Vendor\WPDesk\Notice\Notice;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\Hookable;
class OptOut implements Hookable
{
/**
* @var string
*/
private $plugin_slug;
/**
* @var string
*/
private $plugin_name;
/**
* @param string $plugin_slug
* @param string $plugin_name
*/
public function __construct($plugin_slug, $plugin_name)
{
$this->plugin_slug = $plugin_slug;
$this->plugin_name = $plugin_name;
}
public function hooks()
{
add_action('admin_notices', [$this, 'handle_opt_out']);
}
/**
* @internal
*/
public function handle_opt_out()
{
$screen = get_current_screen();
if ('plugins' === $screen->id && isset($_GET['wpdesk_tracker_opt_out_' . $this->plugin_slug])) {
$security = sanitize_text_field(wp_unslash($_GET['security'] ?? ''));
if (wp_verify_nonce($security, $this->plugin_slug)) {
$persistence = new \Przelewy24Vendor\WPDesk_Tracker_Persistence_Consent();
$persistence->set_active(\false);
delete_option('wpdesk_tracker_notice');
new Notice(sprintf(esc_html__('You successfully opted out of collecting usage data by %1$s. If you change your mind, you can always opt in later in the plugin\'s quick links.', 'woocommerce-gateway-przelewy24'), esc_html($this->plugin_name)));
}
}
}
}

View File

@@ -0,0 +1,100 @@
<?php
namespace Przelewy24Vendor\WPDesk\Tracker;
use Przelewy24Vendor\WPDesk\PluginBuilder\Plugin\Hookable;
/**
* Can add Plugin actions links: opt-in/opt-out to tracker.
*/
class PluginActionLinks implements Hookable
{
/**
* @var string
*/
private $plugin_file;
/**
* @var string
*/
private $plugin_slug;
/**
* @var string|null
*/
private $shop_url;
/**
* @param string $plugin_file
* @param string $plugin_slug
* @param string|null $shop_url
*/
public function __construct($plugin_file, $plugin_slug, $shop_url = null)
{
$this->plugin_file = $plugin_file;
$this->plugin_slug = $plugin_slug;
$this->shop_url = $shop_url;
}
public function hooks()
{
add_filter('plugin_row_meta', [$this, 'append_plugin_action_links_to_row_meta'], 10, 2);
}
/**
* @param array $plugin_meta
* @param string $plugin_file
*
* @return array
*/
public function append_plugin_action_links_to_row_meta($plugin_meta, $plugin_file)
{
if ($plugin_file === $this->plugin_file) {
return $this->append_opt_link($plugin_meta);
}
return $plugin_meta;
}
/**
* @param array $links
*
* @return array
*/
private function append_opt_link($links)
{
if (!$this->tracker_enabled() || apply_filters('wpdesk_tracker_do_not_ask', \false) || !is_array($links)) {
return $links;
}
$tracker_consent = new \Przelewy24Vendor\WPDesk_Tracker_Persistence_Consent();
$plugin_links = [];
if (!$tracker_consent->is_active()) {
$opt_in_link = wp_nonce_url(admin_url('admin.php?page=wpdesk_tracker_' . $this->plugin_slug), OptInPage::WPDESK_TRACKER_ACTION, OptInPage::WPDESK_TRACKER_NONCE);
if (is_string($this->shop_url) && strlen($this->shop_url) > 0) {
$opt_in_link = add_query_arg('shop_url', $this->shop_url, $opt_in_link);
}
$opt_in_link = add_query_arg('plugin', $this->plugin_slug, $opt_in_link);
$opt_in_link = add_query_arg('ctx', 'links', $opt_in_link);
$plugin_links[] = '<a href="' . esc_url($opt_in_link) . '">' . esc_html__('Enable usage tracking', 'woocommerce-gateway-przelewy24') . '</a>';
} else {
$opt_in_link = admin_url('plugins.php?wpdesk_tracker_opt_out_' . $this->plugin_slug . '=1&security=' . wp_create_nonce($this->plugin_slug));
$opt_in_link = add_query_arg('plugin', $this->plugin_slug, $opt_in_link);
$opt_in_link = add_query_arg('ctx', 'links', $opt_in_link);
$plugin_links[] = '<a href="' . esc_url($opt_in_link) . '">' . esc_html__('Disable usage tracking', 'woocommerce-gateway-przelewy24') . '</a>';
}
return array_merge($links, $plugin_links);
}
/**
* @return bool
*/
private function tracker_enabled()
{
$tracker_enabled = \true;
$server = sanitize_text_field(wp_unslash($_SERVER['SERVER_NAME'] ?? ''));
if (!empty($server) && $this->is_localhost($server)) {
$tracker_enabled = \false;
}
return (bool) apply_filters('wpdesk_tracker_enabled', $tracker_enabled);
}
/**
* @param string $address
*
* @return bool
*/
private function is_localhost($address)
{
return in_array($address, ['127.0.0.1', '::1'], \true);
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace Przelewy24Vendor\WPDesk\Tracker;
/**
* Provides shop data.
*/
class Shop
{
/**
* @var string
*/
private $default_shop = 'wpdesk.pl';
/**
* @var string
*/
private $default_shop_name = 'WP Desk';
/**
* @var string
*/
private $default_logo = 'logo.png';
/**
* @var array<string, string>
*/
private $shops_usage_tracking_pages = ['wpdesk.pl' => 'https://www.wpdesk.pl/sk/', 'wpdesk.net' => 'https://www.wpdesk.net/sk/', 'octolize.com' => 'https://octolize.com/usage-tracking/', 'shopmagic.app' => 'https://www.shopmagic.app/sk/', 'flexibleinvoices.com' => 'https://www.flexibleinvoices.com/sk/', 'flexiblecoupons.net' => 'https://www.flexiblecoupons.net/sk/'];
/**
* @var array<string, string>
*/
private $shop_short_slug = ['wpdesk.pl' => 'pl', 'wpdesk.net' => 'net', 'shopmagic.app' => 'sm', 'flexibleinvoices.com' => 'fi', 'flexiblecoupons.net' => 'fc'];
/**
* @var array<string, string>
*/
private $shops_usage_tracking_names = ['octolize.com' => 'Octolize'];
/**
* @var string
*/
private $shop;
/**
* @var string
*/
private $plugin_slug;
/**
* @param string $shop_url
* @param string $plugin_slug
*/
public function __construct($shop_url, $plugin_slug)
{
$this->shop = $this->prepare_shop_from_shop_url($shop_url);
$this->plugin_slug = $plugin_slug;
}
/**
* @return string
*/
public function get_usage_tracking_page()
{
$usage_tracking_page = isset($this->shops_usage_tracking_pages[$this->shop]) ? $this->shops_usage_tracking_pages[$this->shop] : $this->shops_usage_tracking_pages[$this->default_shop];
if ($this->shop !== 'octolize.com') {
$shop_shor_slug = isset($this->shop_short_slug[$this->shop]) ? $this->shop_short_slug[$this->default_shop] : 'pl';
$usage_tracking_page .= $this->plugin_slug . '-usage-tracking-' . $shop_shor_slug;
}
return apply_filters('wpdesk/tracker/usage_tracking_page', $usage_tracking_page, $this->shop);
}
/**
* @return string
*/
public function get_shop_name()
{
return apply_filters('wpdesk/tracker/shop_name', $this->shops_usage_tracking_names[$this->shop] ?? $this->default_shop_name, $this->shop);
}
/**
* @return string
*/
public function get_shop_logo_file()
{
$logo_file = isset($this->shops_usage_tracking_pages[$this->shop]) ? $this->shop : $this->default_shop;
$logo_file .= '.png';
$logo_file = apply_filters('wpdesk/tracker/logo_file', $logo_file, $this->shop);
// Look for our assets folder from package root directory.
if (!file_exists(dirname(__DIR__, 3) . '/assets/images/' . $logo_file)) {
$logo_file = $this->default_logo;
}
return $logo_file;
}
/**
* @param string $shop_url
*/
private function prepare_shop_from_shop_url($shop_url)
{
$host = parse_url($shop_url, \PHP_URL_HOST);
return str_replace('www.', '', $host ?? '');
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace Przelewy24Vendor;
/**
* @var $logo_url string
* @var $username string
* @var $allow_url string
* @var $skip_url string
* @var $terms_url string
* @var $shop_name string
*/
if (!\defined('ABSPATH')) {
exit;
}
?><div id="wpdesk_tracker_connect" class="plugin-card">
<div class="message plugin-card-top">
<span><img class="logo" src="<?php
echo \esc_attr($logo_url);
?>" /></span>
<p>
<?php
\printf(\esc_html__('Hey %s,', 'woocommerce-gateway-przelewy24'), \esc_html($username));
?><br/>
<?php
\esc_html_e('Please help us improve our plugins! If you opt-in, we will collect some non-sensitive data and usage information anonymously. If you skip this, that\'s okay! All plugins will work just fine.', 'woocommerce-gateway-przelewy24');
?>
</p>
</div>
<div class="actions plugin-card-bottom">
<a id="wpdesk_tracker_allow_button" href="<?php
echo \esc_url($allow_url);
?>" class="button button-primary button-allow button-large"><?php
\esc_html_e('Allow & Continue &rarr;', 'woocommerce-gateway-przelewy24');
?></a>
<a href="<?php
echo \esc_url($skip_url);
?>" class="button button-secondary"><?php
\esc_html_e('Skip', 'woocommerce-gateway-przelewy24');
?></a>
<div class="clear"></div>
</div>
<div class="permissions">
<a class="trigger" href="#"><?php
\esc_html_e('What permissions are being granted?', 'woocommerce-gateway-przelewy24');
?></a>
<div class="permissions-details">
<ul>
<li id="permission-site" class="permission site">
<i class="dashicons dashicons-admin-settings"></i>
<div>
<span><?php
\esc_html_e('Your Site Overview', 'woocommerce-gateway-przelewy24');
?></span>
<p><?php
\esc_html_e('WP version, PHP info', 'woocommerce-gateway-przelewy24');
?></p>
</div>
</li>
<li id="permission-events" class="permission events">
<i class="dashicons dashicons-admin-plugins"></i>
<div>
<span><?php
\esc_html_e('Plugin Usage', 'woocommerce-gateway-przelewy24');
?></span>
<p><?php
\printf(\esc_html__('Current settings and usage information of %1$s plugins', 'woocommerce-gateway-przelewy24'), \esc_html($shop_name));
?></p>
</div>
</li>
<li id="permission-store" class="permission store">
<i class="dashicons dashicons-store"></i>
<div>
<span><?php
\esc_html_e('Your Store Overview', 'woocommerce-gateway-przelewy24');
?></span>
<p><?php
\esc_html_e('Anonymized and non-sensitive store usage information', 'woocommerce-gateway-przelewy24');
?></p>
</div>
</li>
</ul>
<div class="terms">
<a href="<?php
echo \esc_url_raw($terms_url);
?>" target="_blank"><?php
\esc_html_e('Find out more &raquo;', 'woocommerce-gateway-przelewy24');
?></a>
</div>
</div>
</div>
</div>
<?php

View File

@@ -0,0 +1,107 @@
/* Connect */
#wpdesk_tracker_connect {
margin-top: 30px;
}
#wpdesk_tracker_connect span.wpdesk-logo {
background-image: url(../images/logo.png);
background-repeat: no-repeat;
background-size: 215px 62px;
display: block;
height: 62px;
margin: 0 auto;
width: 215px;
}
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
#wpdesk_tracker_connect span.wpdesk-logo {
background-image: url(../images/logo@2x.png);
background-size: 215px 62px;
}
}
#wpdesk_tracker_connect img.logo {
width: 215px;
}
#wpdesk_tracker_connect .message p {
font-size: 14px;
}
#wpdesk_tracker_connect .plugin-card-bottom {
border-bottom: 1px solid #ddd;
margin-bottom: 10px;
}
#wpdesk_tracker_connect .button-allow {
float: right;
}
#wpdesk_tracker_connect .permissions .trigger {
display: block;
font-size: .9em;
text-align: center;
margin-bottom: 10px;
text-decoration: none;
}
#wpdesk_tracker_connect .permissions .permissions-details {
height: 0;
overflow: hidden;
margin: 0;
}
#wpdesk_tracker_connect .permissions.open .permissions-details {
height: auto;
padding: 10px 20px;
}
#wpdesk_tracker_connect .permissions ul {
margin: 0;
}
#wpdesk_tracker_connect .permissions ul li {
margin-bottom: 12px;
}
#wpdesk_tracker_connect .permissions ul li i.dashicons {
float: left;
font-size: 40px;
width: 40px;
height: 40px;
}
#wpdesk_tracker_connect .permissions ul li div {
margin-left: 55px;
}
#wpdesk_tracker_connect .permissions ul li div span {
font-weight: bold;
}
#wpdesk_tracker_connect .permissions ul li div p {
margin: 2px 0 0 0;
}
#wpdesk_tracker_connect .terms {
font-size: .9em;
padding: 5px;
}
#wpdesk_tracker_connect .terms a {
color: #999;
}
/* Deactivate */
.wpdesk_tracker_deactivate .reason-input {
display: none;
}
.wpdesk_tracker_deactivate .reason-input input[type=text] {
margin-left: 25px;
width: 350px;
}
.wpdesk-tracker-test div {
color: yellow !important;
}

View File

@@ -0,0 +1 @@
#wpdesk_tracker_connect{margin-top:30px;}#wpdesk_tracker_connect span.wpdesk-logo{background-image:url(../images/logo.png);background-repeat:no-repeat;background-size:215px 62px;display:block;height:62px;margin:0 auto;width:215px;}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#wpdesk_tracker_connect span.wpdesk-logo{background-image:url(../images/logo@2x.png);background-size:215px 62px}}#wpdesk_tracker_connect img.logo{width:215px;}#wpdesk_tracker_connect .message p{font-size:14px;}#wpdesk_tracker_connect .plugin-card-bottom{border-bottom:1px solid #ddd;margin-bottom:10px;}#wpdesk_tracker_connect .button-allow{float:right;}#wpdesk_tracker_connect .permissions .trigger{display:block;font-size:.9em;text-align:center;margin-bottom:10px;text-decoration:none;}#wpdesk_tracker_connect .permissions .permissions-details{height:0;overflow:hidden;margin:0;}#wpdesk_tracker_connect .permissions.open .permissions-details{height:auto;padding:10px 20px;}#wpdesk_tracker_connect .permissions ul{margin:0;}#wpdesk_tracker_connect .permissions ul li{margin-bottom:12px;}#wpdesk_tracker_connect .permissions ul li i.dashicons{float:left;font-size:40px;width:40px;height:40px;}#wpdesk_tracker_connect .permissions ul li div{margin-left:55px;}#wpdesk_tracker_connect .permissions ul li div span{font-weight:bold;}#wpdesk_tracker_connect .permissions ul li div p{margin:2px 0 0 0;}#wpdesk_tracker_connect .terms{font-size:.9em;padding:5px;}#wpdesk_tracker_connect .terms a{color:#999;}.wpdesk_tracker_deactivate .reason-input{display:none;}.wpdesk_tracker_deactivate .reason-input input[type=text]{margin-left:25px;width:350px;}.wpdesk-tracker-test div{color:yellow!important;}

Some files were not shown because too many files have changed in this diff Show More