5 Commits

Author SHA1 Message Date
bb405f24f2 Fix issues #10 and #15: Move Site_Query loading to Sunrise class and fix textdomain loading 2025-04-15 00:05:50 +01:00
410571a802 Update version number to 2.4.0 2025-04-14 11:58:44 -06:00
2dfe5ae78a Update build 2025-04-14 11:47:23 -06:00
d3e1f2896a Prep for release 2025-04-14 11:45:51 -06:00
d88e50df38 Prep Plugin for release on WordPress.org (#23)
* Update translation text domain
* Escape everything that should be escaped.
* Add nonce checks where needed.
* Sanitize all inputs.
* Apply Code style changes across the codebase.
* Correct many deprecation notices.
* Optimize load order of many filters.
* Add Proper Build script
* Use emojii flags
* Fix i18n deprecation  notice for translating too early
* Put all scripts in footer and load async
2025-04-14 11:36:46 -06:00
44 changed files with 528 additions and 428 deletions

View File

@ -2,7 +2,7 @@
"name": "devstone/wp-multisite-waas", "name": "devstone/wp-multisite-waas",
"url": "https://wpmultisitewaas.org", "url": "https://wpmultisitewaas.org",
"description": "The WordPress Multisite Website as a Service (WaaS) plugin.", "description": "The WordPress Multisite Website as a Service (WaaS) plugin.",
"version": "2.3.3", "version": "2.4.0",
"authors": [ "authors": [
{ {
"name": "Arindo Duque", "name": "Arindo Duque",
@ -93,7 +93,11 @@
"build.sh", "build.sh",
"package.json", "package.json",
"package-lock.json", "package-lock.json",
"setuptest.sh" "setuptest.sh",
"utils",
"update.sh",
"phpstan.neon.dist",
"rector.php"
] ]
}, },
"extra": { "extra": {

View File

@ -959,7 +959,7 @@ class Legacy_Checkout {
public function has_plan_step(): bool { public function has_plan_step(): bool {
$transient = static::get_transient(); $transient = static::get_transient();
return !(isset($transient['skip_plan']) && isset($transient['plan_id']) && isset($transient['plan_freq'])); return ! (isset($transient['skip_plan']) && isset($transient['plan_id']) && isset($transient['plan_freq']));
} }
/** /**

View File

@ -59,7 +59,10 @@ class Scripts {
* } * }
* @return void * @return void
*/ */
public function register_script($handle, $src, $deps = [], $args = ['async' => true, 'in_footer' => true]): void { public function register_script($handle, $src, $deps = [], $args = [
'async' => true,
'in_footer' => true,
]): void {
wp_register_script($handle, $src, $deps, wu_get_version(), $args); wp_register_script($handle, $src, $deps, wu_get_version(), $args);
} }

View File

@ -115,6 +115,7 @@ class Sunrise {
require_once __DIR__ . '/functions/array-helpers.php'; require_once __DIR__ . '/functions/array-helpers.php';
require_once __DIR__ . '/traits/trait-singleton.php'; require_once __DIR__ . '/traits/trait-singleton.php';
require_once __DIR__ . '/objects/class-limitations.php'; require_once __DIR__ . '/objects/class-limitations.php';
require_once __DIR__ . '/models/interface-limitable.php';
require_once __DIR__ . '/models/traits/trait-limitable.php'; require_once __DIR__ . '/models/traits/trait-limitable.php';
require_once __DIR__ . '/models/traits/trait-notable.php'; require_once __DIR__ . '/models/traits/trait-notable.php';
require_once __DIR__ . '/models/traits/trait-billable.php'; require_once __DIR__ . '/models/traits/trait-billable.php';
@ -136,8 +137,11 @@ class Sunrise {
require_once __DIR__ . '/class-settings.php'; require_once __DIR__ . '/class-settings.php';
require_once __DIR__ . '/limits/class-plugin-limits.php'; require_once __DIR__ . '/limits/class-plugin-limits.php';
require_once __DIR__ . '/limits/class-theme-limits.php'; require_once __DIR__ . '/limits/class-theme-limits.php';
require_once __DIR__ . '/limits/class-theme-limits.php';
require_once __DIR__ . '/models/class-membership.php'; require_once __DIR__ . '/models/class-membership.php';
// Make sure we have all the necessary database classes loaded
require_once __DIR__ . '/database/sites/class-sites-schema.php';
} }
/** /**

View File

@ -29,7 +29,7 @@ final class WP_Ultimo {
* @since 2.1.0 * @since 2.1.0
* @var string * @var string
*/ */
const VERSION = '2.3.4'; const VERSION = '2.4.0';
/** /**
* Version of the Plugin. * Version of the Plugin.
@ -37,7 +37,7 @@ final class WP_Ultimo {
* @deprecated use the const version instead. * @deprecated use the const version instead.
* @var string * @var string
*/ */
public $version = '2.3.4'; public $version = self::VERSION;
/** /**
* Tables registered by WP Multisite WaaS. * Tables registered by WP Multisite WaaS.
@ -235,9 +235,11 @@ final class WP_Ultimo {
*/ */
public function setup_textdomain(): void { public function setup_textdomain(): void {
/* /*
* Loads the translation files. * Loads the translation files at the init action to prevent "too early" warnings in WP 6.7+
*/ */
add_action('init', function() {
load_plugin_textdomain('wp-ultimo', false, dirname((string) WP_ULTIMO_PLUGIN_BASENAME) . '/lang'); load_plugin_textdomain('wp-ultimo', false, dirname((string) WP_ULTIMO_PLUGIN_BASENAME) . '/lang');
});
} }
/** /**

View File

@ -413,7 +413,7 @@ class WU_Multi_Network {
*/ */
public static function __callStatic($method_name, $args) { public static function __callStatic($method_name, $args) {
_deprecated_function(self::class . "::$method_name()", '2.0.0'); _deprecated_function(self::class . esc_html("::$method_name()"), '2.0.0');
return false; return false;
} }
@ -710,21 +710,21 @@ class WU_Site extends \WP_Ultimo\Models\Site {
* *
* @since 2.0.0 * @since 2.0.0
* *
* @param mixed $object Object containing the parameters. * @param mixed $object_model Object containing the parameters.
*/ */
public function __construct($object = null) { public function __construct($object_model = null) {
_deprecated_function(self::class, '2.0.0', \WP_Ultimo\Models\Site::class); _deprecated_function(self::class, '2.0.0', esc_html(\WP_Ultimo\Models\Site::class));
if (is_numeric($object)) { if (is_numeric($object_model)) {
$object = wu_get_site($object); $object_model = wu_get_site($object_model);
} }
if ($object) { if ( $object_model) {
$object = get_object_vars($object); $object_model = get_object_vars($object_model);
} }
parent::__construct($object); parent::__construct($object_model);
} }
} }
@ -740,21 +740,21 @@ class WU_Site_Template extends \WP_Ultimo\Models\Site {
* *
* @deprecated 2.0.0 * @deprecated 2.0.0
* *
* @param mixed $object Object containing the parameters. * @param mixed $object_model Object containing the parameters.
*/ */
public function __construct($object = null) { public function __construct($object_model = null) {
_deprecated_function(self::class, '2.0.0', \WP_Ultimo\Models\Site::class); _deprecated_function(self::class, '2.0.0', esc_html(\WP_Ultimo\Models\Site::class));
if (is_numeric($object)) { if (is_numeric($object_model)) {
$object = wu_get_site($object); $object_model = wu_get_site($object_model);
} }
if ($object) { if ( $object_model) {
$object = get_object_vars($object); $object_model = get_object_vars($object_model);
} }
parent::__construct($object); parent::__construct($object_model);
} }
} }
@ -843,22 +843,22 @@ class WU_Coupon extends \WP_Ultimo\Models\Discount_Code {
* *
* @deprecated 2.0.0 * @deprecated 2.0.0
* *
* @param mixed $object Object containing the parameters. * @param mixed $object_model Object containing the parameters.
*/ */
public function __construct($object = null) { public function __construct($object_model = null) {
_deprecated_function(self::class, '2.0.0', \WP_Ultimo\Models\Discount_Code::class); _deprecated_function(self::class, '2.0.0', \WP_Ultimo\Models\Discount_Code::class);
if (is_numeric($object)) { if (is_numeric($object_model) ) {
$object = wu_get_discount_code($object); $object_model = wu_get_discount_code($object_model);
} }
if ($object) { if ( $object_model ) {
$object = get_object_vars($object); $object_model = get_object_vars($object_model);
} }
if (is_array($object)) { if (is_array($object_model)) {
foreach ($object as $att => $value) { foreach ( $object_model as $att => $value) {
$this->{$att} = $value; $this->{$att} = $value;
} }
} }
@ -898,29 +898,29 @@ class WU_Plan extends \WP_Ultimo\Models\Product {
* *
* @deprecated 2.0.0 * @deprecated 2.0.0
* *
* @param mixed $object Object containing the parameters. * @param mixed $object_model Object containing the parameters.
*/ */
public function __construct($object = null) { public function __construct($object_model = null) {
_deprecated_function(self::class, '2.0.0', \WP_Ultimo\Models\Product::class); _deprecated_function(self::class, '2.0.0', esc_html(\WP_Ultimo\Models\Product::class));
if (is_numeric($object)) { if (is_numeric($object_model)) {
$object = wu_get_product($object); $object_model = wu_get_product($object_model);
} }
if ($object) { if ($object_model ) {
$object = get_object_vars($object); $object_model = get_object_vars($object_model);
} }
if (is_array($object)) { if (is_array($object_model)) {
foreach ($object as $att => $value) { foreach ($object_model as $att => $value) {
$this->{$att} = $value; $this->{$att} = $value;
} }
} }
$this->set_slug(uniqid()); $this->set_slug(uniqid());
parent::__construct($object); parent::__construct($object_model);
} }
/** /**
@ -973,21 +973,21 @@ class WU_Subscription extends \WP_Ultimo\Models\Membership {
* *
* @deprecated 2.0.0 * @deprecated 2.0.0
* *
* @param mixed $object Object containing the parameters. * @param mixed $object_model Object containing the parameters.
*/ */
public function __construct($object = null) { public function __construct($object_model = null) {
_deprecated_function(self::class, '2.0.0', \WP_Ultimo\Models\Membership::class); _deprecated_function(self::class, '2.0.0', esc_html(\WP_Ultimo\Models\Membership::class));
if (is_numeric($object)) { if (is_numeric($object_model)) {
$object = wu_get_membership($object); $object_model = wu_get_membership($object_model);
} }
if ($object) { if ($object_model ) {
$object = get_object_vars($object); $object_model = get_object_vars($object_model);
} }
parent::__construct($object); parent::__construct($object_model);
} }
/** /**

View File

@ -47,8 +47,7 @@ class Arr {
* @param integer $flag The flag determining the return type. * @param integer $flag The flag determining the return type.
* *
* @return mixed * @return mixed
*@since 2.0.11 * @since 2.0.11
*
*/ */
public static function filter_by_property($array_to_filter, $property, $expected_value, $flag = 0) { public static function filter_by_property($array_to_filter, $property, $expected_value, $flag = 0) {
@ -74,8 +73,7 @@ class Arr {
* @param callable $closure The closure function to call. * @param callable $closure The closure function to call.
* *
* @return array * @return array
*@since 2.0.11 * @since 2.0.11
*
*/ */
public static function filter($array_to_search, $closure) { public static function filter($array_to_search, $closure) {
@ -99,13 +97,12 @@ class Arr {
* *
* @param array $array_target The array to get the value from. * @param array $array_target The array to get the value from.
* @param string $key The array key to get. Supports dot notation. * @param string $key The array key to get. Supports dot notation.
* @param mixed $default The value to return ibn the case the key does not exist. * @param mixed $default_value The value to return ibn the case the key does not exist.
* *
* @return mixed * @return mixed
*@since 2.0.11 * @since 2.0.11
*
*/ */
public static function get($array_target, $key, $default = null) { public static function get($array_target, $key, $default_value = null) {
if (is_null($key)) { if (is_null($key)) {
return $array_target; return $array_target;
@ -117,7 +114,7 @@ class Arr {
foreach (explode('.', $key) as $segment) { foreach (explode('.', $key) as $segment) {
if ( ! is_array($array_target) || ! array_key_exists($segment, $array_target)) { if ( ! is_array($array_target) || ! array_key_exists($segment, $array_target)) {
return $default; return $default_value;
} }
$array_target = $array_target[ $segment ]; $array_target = $array_target[ $segment ];
@ -134,8 +131,7 @@ class Arr {
* @param mixed $value The value to set. * @param mixed $value The value to set.
* *
* @return array * @return array
*@since 2.0.11 * @since 2.0.11
*
*/ */
public static function set(&$array_to_modify, $key, $value) { public static function set(&$array_to_modify, $key, $value) {

View File

@ -10,7 +10,6 @@
namespace WP_Ultimo\Integrations\Host_Providers; namespace WP_Ultimo\Integrations\Host_Providers;
use Psr\Log\LogLevel; use Psr\Log\LogLevel;
use WP_Ultimo\Integrations\Host_Providers\Base_Host_Provider;
use WP_Ultimo\Integrations\Host_Providers\CPanel_API\CPanel_API; use WP_Ultimo\Integrations\Host_Providers\CPanel_API\CPanel_API;
// Exit if accessed directly // Exit if accessed directly
@ -85,7 +84,7 @@ class CPanel_Host_Provider extends Base_Host_Provider {
* Holds the API object. * Holds the API object.
* *
* @since 2.0.0 * @since 2.0.0
* @var WP_Ultimo\Integrations\Host_Providers\CPanel_API\CPanel_API * @var \WP_Ultimo\Integrations\Host_Providers\CPanel_API\CPanel_API
*/ */
protected $api = null; protected $api = null;
@ -237,7 +236,7 @@ class CPanel_Host_Provider extends Base_Host_Provider {
* Load the CPanel API. * Load the CPanel API.
* *
* @since 2.0.0 * @since 2.0.0
* @return WU_CPanel * @return CPanel_API
*/ */
public function load_api() { public function load_api() {
@ -293,17 +292,19 @@ class CPanel_Host_Provider extends Base_Host_Provider {
* *
* @since 1.6.2 * @since 1.6.2
* @param object $results Results of the cPanel call. * @param object $results Results of the cPanel call.
* @return bool * @return void
*/ */
public function log_calls($results) { public function log_calls($results) {
if (is_object($results->cpanelresult->data)) { if (is_object($results->cpanelresult->data)) {
return wu_log_add('integration-cpanel', $results->cpanelresult->data->reason); wu_log_add('integration-cpanel', $results->cpanelresult->data->reason);
return;
} elseif ( ! isset($results->cpanelresult->data[0])) { } elseif ( ! isset($results->cpanelresult->data[0])) {
return wu_log_add('integration-cpanel', __('Unexpected error ocurred trying to sync domains with CPanel', 'wp-multisite-waas'), LogLevel::ERROR); wu_log_add('integration-cpanel', __('Unexpected error ocurred trying to sync domains with CPanel', 'wp-multisite-waas'), LogLevel::ERROR);
return;
} }
return wu_log_add('integration-cpanel', $results->cpanelresult->data[0]->reason); wu_log_add('integration-cpanel', $results->cpanelresult->data[0]->reason);
} }
/** /**

View File

@ -250,33 +250,33 @@ class Payment_List_Table extends Base_List_Table {
'label' => __('All Payments', 'wp-multisite-waas'), 'label' => __('All Payments', 'wp-multisite-waas'),
'count' => 0, 'count' => 0,
], ],
Payment_Status::COMPLETED() => [ Payment_Status::COMPLETED => [
'field' => 'status', 'field' => 'status',
'url' => add_query_arg('status', Payment_Status::COMPLETED()), 'url' => add_query_arg('status', Payment_Status::COMPLETED),
'label' => __('Completed', 'wp-multisite-waas'), 'label' => __('Completed', 'wp-multisite-waas'),
'count' => 0, 'count' => 0,
], ],
Payment_Status::PENDING() => [ Payment_Status::PENDING => [
'field' => 'status', 'field' => 'status',
'url' => add_query_arg('status', Payment_Status::PENDING()), 'url' => add_query_arg('status', Payment_Status::PENDING),
'label' => __('Pending', 'wp-multisite-waas'), 'label' => __('Pending', 'wp-multisite-waas'),
'count' => 0, 'count' => 0,
], ],
Payment_Status::PARTIAL_REFUND() => [ Payment_Status::PARTIAL_REFUND => [
'field' => 'status', 'field' => 'status',
'url' => add_query_arg('status', Payment_Status::PARTIAL_REFUND()), 'url' => add_query_arg('status', Payment_Status::PARTIAL_REFUND),
'label' => __('Partially Refunded', 'wp-multisite-waas'), 'label' => __('Partially Refunded', 'wp-multisite-waas'),
'count' => 0, 'count' => 0,
], ],
Payment_Status::REFUND() => [ Payment_Status::REFUND => [
'field' => 'status', 'field' => 'status',
'url' => add_query_arg('status', Payment_Status::REFUND()), 'url' => add_query_arg('status', Payment_Status::REFUND),
'label' => __('Refunded', 'wp-multisite-waas'), 'label' => __('Refunded', 'wp-multisite-waas'),
'count' => 0, 'count' => 0,
], ],
Payment_Status::FAILED() => [ Payment_Status::FAILED => [
'field' => 'status', 'field' => 'status',
'url' => add_query_arg('status', Payment_Status::FAILED()), 'url' => add_query_arg('status', Payment_Status::FAILED),
'label' => __('Failed', 'wp-multisite-waas'), 'label' => __('Failed', 'wp-multisite-waas'),
'count' => 0, 'count' => 0,
], ],

View File

@ -228,22 +228,22 @@ class Limitation_Manager {
* *
* @since 2.0.0 * @since 2.0.0
* *
* @param \WP_Ultimo\Models\Trait\Trait_Limitable $object Model to test. * @param \WP_Ultimo\Models\Limitable $object_model Model to test.
* @return string * @return string
*/ */
public function get_object_type($object) { public function get_object_type($object_model) {
$model = false; $model = false;
if (is_a($object, \WP_Ultimo\Models\Site::class)) { if (is_a($object_model, \WP_Ultimo\Models\Site::class)) {
$model = 'site'; $model = 'site';
} elseif (is_a($object, WP_Ultimo\Models\Membership::class)) { } elseif (is_a($object_model, \WP_Ultimo\Models\Membership::class)) {
$model = 'membership'; $model = 'membership';
} elseif (is_a($object, \WP_Ultimo\Models\Product::class)) { } elseif (is_a($object_model, \WP_Ultimo\Models\Product::class)) {
$model = 'product'; $model = 'product';
} }
return apply_filters('wu_limitations_get_object_type', $model); return apply_filters('wu_limitations_get_object_type', $model, $object_model);
} }
/** /**
@ -252,12 +252,12 @@ class Limitation_Manager {
* @since 2.0.0 * @since 2.0.0
* *
* @param array $sections List of tabbed widget sections. * @param array $sections List of tabbed widget sections.
* @param \WP_Ultimo\Models\Trait\Trait_Limitable $object The model being edited. * @param \WP_Ultimo\Models\Limitable $object_model The model being edited.
* @return array * @return array
*/ */
public function add_limitation_sections($sections, $object) { public function add_limitation_sections($sections, $object_model) {
if ($this->get_object_type($object) === 'site' && $object->get_type() !== Site_Type::CUSTOMER_OWNED) { if ( $this->get_object_type($object_model) === 'site' && $object_model->get_type() !== Site_Type::CUSTOMER_OWNED) {
$html = sprintf('<span class="wu--mt-4 wu-p-2 wu-bg-blue-100 wu-text-blue-600 wu-rounded wu-block">%s</span>', __('Limitations are only available for customer-owned sites. You need to change the type to Customer-owned and save this site before the options are shown.', 'wp-multisite-waas')); $html = sprintf('<span class="wu--mt-4 wu-p-2 wu-bg-blue-100 wu-text-blue-600 wu-rounded wu-block">%s</span>', __('Limitations are only available for customer-owned sites. You need to change the type to Customer-owned and save this site before the options are shown.', 'wp-multisite-waas'));
$sections['sites'] = [ $sections['sites'] = [
@ -275,15 +275,15 @@ class Limitation_Manager {
return $sections; return $sections;
} }
if ($this->get_object_type($object) !== 'site') { if ( $this->get_object_type($object_model) !== 'site') {
$sections['sites'] = [ $sections['sites'] = [
'title' => __('Sites', 'wp-multisite-waas'), 'title' => __('Sites', 'wp-multisite-waas'),
'desc' => __('Control limitations imposed to the number of sites allowed for memberships attached to this product.', 'wp-multisite-waas'), 'desc' => __('Control limitations imposed to the number of sites allowed for memberships attached to this product.', 'wp-multisite-waas'),
'icon' => 'dashicons-wu-browser', 'icon' => 'dashicons-wu-browser',
'fields' => $this->get_sites_fields($object), 'fields' => $this->get_sites_fields($object_model),
'v-show' => "get_state_value('product_type', 'none') !== 'service'", 'v-show' => "get_state_value('product_type', 'none') !== 'service'",
'state' => [ 'state' => [
'limit_sites' => $object->get_limitations()->sites->is_enabled(), 'limit_sites' => $object_model->get_limitations()->sites->is_enabled(),
], ],
]; ];
} }
@ -298,7 +298,7 @@ class Limitation_Manager {
'icon' => 'dashicons-wu-man', 'icon' => 'dashicons-wu-man',
'v-show' => "get_state_value('product_type', 'none') !== 'service'", 'v-show' => "get_state_value('product_type', 'none') !== 'service'",
'state' => [ 'state' => [
'limit_visits' => $object->get_limitations()->visits->is_enabled(), 'limit_visits' => $object_model->get_limitations()->visits->is_enabled(),
], ],
'fields' => [ 'fields' => [
'modules[visits][enabled]' => [ 'modules[visits][enabled]' => [
@ -313,8 +313,8 @@ class Limitation_Manager {
], ],
]; ];
if ('product' !== $object->model) { if ( 'product' !== $object_model->model) {
$sections['visits']['fields']['modules_visits_overwrite'] = $this->override_notice($object->get_limitations(false)->visits->has_own_enabled()); $sections['visits']['fields']['modules_visits_overwrite'] = $this->override_notice($object_model->get_limitations(false)->visits->has_own_enabled());
} }
$sections['visits']['fields']['modules[visits][limit]'] = [ $sections['visits']['fields']['modules[visits][limit]'] = [
@ -322,7 +322,7 @@ class Limitation_Manager {
'title' => __('Unique Visits Quota', 'wp-multisite-waas'), 'title' => __('Unique Visits Quota', 'wp-multisite-waas'),
'desc' => __('Set a top limit for the number of monthly unique visits. Leave empty or 0 to allow for unlimited visits.', 'wp-multisite-waas'), 'desc' => __('Set a top limit for the number of monthly unique visits. Leave empty or 0 to allow for unlimited visits.', 'wp-multisite-waas'),
'placeholder' => __('e.g. 10000', 'wp-multisite-waas'), 'placeholder' => __('e.g. 10000', 'wp-multisite-waas'),
'value' => $object->get_limitations()->visits->get_limit(), 'value' => $object_model->get_limitations()->visits->get_limit(),
'wrapper_html_attr' => [ 'wrapper_html_attr' => [
'v-show' => 'limit_visits', 'v-show' => 'limit_visits',
'v-cloak' => '1', 'v-cloak' => '1',
@ -332,20 +332,20 @@ class Limitation_Manager {
], ],
]; ];
if ('product' !== $object->model) { if ( 'product' !== $object_model->model) {
$sections['visits']['fields']['allowed_visits_overwrite'] = $this->override_notice($object->get_limitations(false)->visits->has_own_limit(), ['limit_visits']); $sections['visits']['fields']['allowed_visits_overwrite'] = $this->override_notice($object_model->get_limitations(false)->visits->has_own_limit(), ['limit_visits']);
} }
/* /*
* If this is a site edit screen, show the current values * If this is a site edit screen, show the current values
* for visits and the reset date * for visits and the reset date
*/ */
if ($this->get_object_type($object) === 'site') { if ( $this->get_object_type($object_model) === 'site') {
$sections['visits']['fields']['visits_count'] = [ $sections['visits']['fields']['visits_count'] = [
'type' => 'text-display', 'type' => 'text-display',
'title' => __('Current Unique Visits Count this Month', 'wp-multisite-waas'), 'title' => __('Current Unique Visits Count this Month', 'wp-multisite-waas'),
'desc' => __('Current visits count for this particular site.', 'wp-multisite-waas'), 'desc' => __('Current visits count for this particular site.', 'wp-multisite-waas'),
'display_value' => sprintf('%s visit(s)', $object->get_visits_count()), 'display_value' => sprintf('%s visit(s)', $object_model->get_visits_count()),
'wrapper_html_attr' => [ 'wrapper_html_attr' => [
'v-show' => 'limit_visits', 'v-show' => 'limit_visits',
'v-cloak' => '1', 'v-cloak' => '1',
@ -360,7 +360,7 @@ class Limitation_Manager {
'icon' => 'dashicons-wu-users', 'icon' => 'dashicons-wu-users',
'v-show' => "get_state_value('product_type', 'none') !== 'service'", 'v-show' => "get_state_value('product_type', 'none') !== 'service'",
'state' => [ 'state' => [
'limit_users' => $object->get_limitations()->users->is_enabled(), 'limit_users' => $object_model->get_limitations()->users->is_enabled(),
], ],
'fields' => [ 'fields' => [
'modules[users][enabled]' => [ 'modules[users][enabled]' => [
@ -374,11 +374,11 @@ class Limitation_Manager {
], ],
]; ];
if ('product' !== $object->model) { if ( 'product' !== $object_model->model) {
$sections['users']['fields']['modules_user_overwrite'] = $this->override_notice($object->get_limitations(false)->users->has_own_enabled()); $sections['users']['fields']['modules_user_overwrite'] = $this->override_notice($object_model->get_limitations(false)->users->has_own_enabled());
} }
$this->register_user_fields($sections, $object); $this->register_user_fields($sections, $object_model);
$sections['post_types'] = [ $sections['post_types'] = [
'title' => __('Post Types', 'wp-multisite-waas'), 'title' => __('Post Types', 'wp-multisite-waas'),
@ -386,7 +386,7 @@ class Limitation_Manager {
'icon' => 'dashicons-wu-book', 'icon' => 'dashicons-wu-book',
'v-show' => "get_state_value('product_type', 'none') !== 'service'", 'v-show' => "get_state_value('product_type', 'none') !== 'service'",
'state' => [ 'state' => [
'limit_post_types' => $object->get_limitations()->post_types->is_enabled(), 'limit_post_types' => $object_model->get_limitations()->post_types->is_enabled(),
], ],
'fields' => [ 'fields' => [
'modules[post_types][enabled]' => [ 'modules[post_types][enabled]' => [
@ -401,8 +401,8 @@ class Limitation_Manager {
], ],
]; ];
if ('product' !== $object->model) { if ( 'product' !== $object_model->model) {
$sections['post_types']['fields']['post_quota_overwrite'] = $this->override_notice($object->get_limitations(false)->post_types->has_own_enabled()); $sections['post_types']['fields']['post_quota_overwrite'] = $this->override_notice($object_model->get_limitations(false)->post_types->has_own_enabled());
} }
$sections['post_types']['post_quota_note'] = [ $sections['post_types']['post_quota_note'] = [
@ -414,7 +414,7 @@ class Limitation_Manager {
], ],
]; ];
$this->register_post_type_fields($sections, $object); $this->register_post_type_fields($sections, $object_model);
$sections['limit_disk_space'] = [ $sections['limit_disk_space'] = [
'title' => __('Disk Space', 'wp-multisite-waas'), 'title' => __('Disk Space', 'wp-multisite-waas'),
@ -422,7 +422,7 @@ class Limitation_Manager {
'icon' => 'dashicons-wu-drive', 'icon' => 'dashicons-wu-drive',
'v-show' => "get_state_value('product_type', 'none') !== 'service'", 'v-show' => "get_state_value('product_type', 'none') !== 'service'",
'state' => [ 'state' => [
'limit_disk_space' => $object->get_limitations()->disk_space->is_enabled(), 'limit_disk_space' => $object_model->get_limitations()->disk_space->is_enabled(),
], ],
'fields' => [ 'fields' => [
'modules[disk_space][enabled]' => [ 'modules[disk_space][enabled]' => [
@ -437,8 +437,8 @@ class Limitation_Manager {
], ],
]; ];
if ('product' !== $object->model) { if ( 'product' !== $object_model->model) {
$sections['limit_disk_space']['fields']['disk_space_modules_overwrite'] = $this->override_notice($object->get_limitations(false)->disk_space->has_own_enabled()); $sections['limit_disk_space']['fields']['disk_space_modules_overwrite'] = $this->override_notice($object_model->get_limitations(false)->disk_space->has_own_enabled());
} }
$sections['limit_disk_space']['fields']['modules[disk_space][limit]'] = [ $sections['limit_disk_space']['fields']['modules[disk_space][limit]'] = [
@ -447,15 +447,15 @@ class Limitation_Manager {
'desc' => __('Set a limit in MBs for the disk space for <strong>each</strong> individual site.', 'wp-multisite-waas'), 'desc' => __('Set a limit in MBs for the disk space for <strong>each</strong> individual site.', 'wp-multisite-waas'),
'min' => 0, 'min' => 0,
'placeholder' => 100, 'placeholder' => 100,
'value' => $object->get_limitations()->disk_space->get_limit(), 'value' => $object_model->get_limitations()->disk_space->get_limit(),
'wrapper_html_attr' => [ 'wrapper_html_attr' => [
'v-show' => "get_state_value('product_type', 'none') !== 'service' && limit_disk_space", 'v-show' => "get_state_value('product_type', 'none') !== 'service' && limit_disk_space",
'v-cloak' => '1', 'v-cloak' => '1',
], ],
]; ];
if ('product' !== $object->model) { if ( 'product' !== $object_model->model) {
$sections['limit_disk_space']['fields']['disk_space_override'] = $this->override_notice($object->get_limitations(false)->disk_space->has_own_limit(), ['limit_disk_space']); $sections['limit_disk_space']['fields']['disk_space_override'] = $this->override_notice($object_model->get_limitations(false)->disk_space->has_own_limit(), ['limit_disk_space']);
} }
$sections['custom_domain'] = [ $sections['custom_domain'] = [
@ -464,14 +464,14 @@ class Limitation_Manager {
'icon' => 'dashicons-wu-link1', 'icon' => 'dashicons-wu-link1',
'v-show' => "get_state_value('product_type', 'none') !== 'service'", 'v-show' => "get_state_value('product_type', 'none') !== 'service'",
'state' => [ 'state' => [
'allow_domain_mapping' => $object->get_limitations()->domain_mapping->is_enabled(), 'allow_domain_mapping' => $object_model->get_limitations()->domain_mapping->is_enabled(),
], ],
'fields' => [ 'fields' => [
'modules[domain_mapping][enabled]' => [ 'modules[domain_mapping][enabled]' => [
'type' => 'toggle', 'type' => 'toggle',
'title' => __('Allow Custom Domains', 'wp-multisite-waas'), 'title' => __('Allow Custom Domains', 'wp-multisite-waas'),
'desc' => __('Toggle this option on to allow this plan to enable custom domains for sign-ups on this plan.', 'wp-multisite-waas'), 'desc' => __('Toggle this option on to allow this plan to enable custom domains for sign-ups on this plan.', 'wp-multisite-waas'),
'value' => $object->get_limitations()->domain_mapping->is_enabled(), 'value' => $object_model->get_limitations()->domain_mapping->is_enabled(),
'wrapper_html_attr' => [ 'wrapper_html_attr' => [
'v-cloak' => '1', 'v-cloak' => '1',
], ],
@ -482,8 +482,8 @@ class Limitation_Manager {
], ],
]; ];
if ('product' !== $object->model) { if ( 'product' !== $object_model->model) {
$sections['custom_domain']['fields']['custom_domain_override'] = $this->override_notice($object->get_limitations(false)->domain_mapping->has_own_enabled(), ['allow_domain_mapping']); $sections['custom_domain']['fields']['custom_domain_override'] = $this->override_notice($object_model->get_limitations(false)->domain_mapping->has_own_enabled(), ['allow_domain_mapping']);
} }
$sections['allowed_themes'] = [ $sections['allowed_themes'] = [
@ -499,7 +499,7 @@ class Limitation_Manager {
'type' => 'html', 'type' => 'html',
'title' => __('Themes', 'wp-multisite-waas'), 'title' => __('Themes', 'wp-multisite-waas'),
'desc' => __('Select how the themes installed on the network should behave.', 'wp-multisite-waas'), 'desc' => __('Select how the themes installed on the network should behave.', 'wp-multisite-waas'),
'content' => fn() => $this->get_theme_selection_list($object, $sections['allowed_themes']), 'content' => fn() => $this->get_theme_selection_list($object_model, $sections['allowed_themes']),
], ],
], ],
]; ];
@ -514,7 +514,7 @@ class Limitation_Manager {
'type' => 'html', 'type' => 'html',
'title' => __('Plugins', 'wp-multisite-waas'), 'title' => __('Plugins', 'wp-multisite-waas'),
'desc' => __('Select how the plugins installed on the network should behave.', 'wp-multisite-waas'), 'desc' => __('Select how the plugins installed on the network should behave.', 'wp-multisite-waas'),
'content' => fn() => $this->get_plugin_selection_list($object), 'content' => fn() => $this->get_plugin_selection_list($object_model),
], ],
], ],
]; ];
@ -522,8 +522,8 @@ class Limitation_Manager {
$reset_url = wu_get_form_url( $reset_url = wu_get_form_url(
'confirm_limitations_reset', 'confirm_limitations_reset',
[ [
'id' => $object->get_id(), 'id' => $object_model->get_id(),
'model' => $object->model, 'model' => $object_model->model,
] ]
); );
@ -574,17 +574,17 @@ class Limitation_Manager {
* @since 2.0.0 * @since 2.0.0
* *
* @param array $sections Sections and fields. * @param array $sections Sections and fields.
* @param \WP_Ultimo\Models\Trait\Trait_Limitable $object The object being edit. * @param \WP_Ultimo\Models\Limitable $object_model The object being edit.
* @return void * @return void
*/ */
public function register_user_fields(&$sections, $object): void { public function register_user_fields(&$sections, $object_model): void {
$user_roles = get_editable_roles(); $user_roles = get_editable_roles();
$sections['users']['state']['roles'] = []; $sections['users']['state']['roles'] = [];
foreach ($user_roles as $user_role_slug => $user_role) { foreach ($user_roles as $user_role_slug => $user_role) {
$sections['users']['state']['roles'][ $user_role_slug ] = $object->get_limitations()->users->{$user_role_slug}; $sections['users']['state']['roles'][ $user_role_slug ] = $object_model->get_limitations()->users->{$user_role_slug};
$sections['users']['fields'][ "control_{$user_role_slug}" ] = [ $sections['users']['fields'][ "control_{$user_role_slug}" ] = [
'type' => 'group', 'type' => 'group',
@ -620,8 +620,8 @@ class Limitation_Manager {
/* /*
* Add override notice. * Add override notice.
*/ */
if ('product' !== $object->model) { if ('product' !== $object_model->model) {
$sections['users']['fields'][ "override_{$user_role_slug}" ] = $this->override_notice($object->get_limitations(false)->users->exists($user_role_slug), ['limit_users']); $sections['users']['fields'][ "override_{$user_role_slug}" ] = $this->override_notice($object_model->get_limitations(false)->users->exists($user_role_slug), ['limit_users']);
} }
} }
} }
@ -632,17 +632,17 @@ class Limitation_Manager {
* @since 2.0.0 * @since 2.0.0
* *
* @param array $sections Sections and fields. * @param array $sections Sections and fields.
* @param \WP_Ultimo\Models\Trait\Trait_Limitable $object The object being edit. * @param \WP_Ultimo\Models\Limitable $object_model The object being edit.
* @return void * @return void
*/ */
public function register_post_type_fields(&$sections, $object): void { public function register_post_type_fields(&$sections, $object_model): void {
$post_types = get_post_types([], 'objects'); $post_types = get_post_types([], 'objects');
$sections['post_types']['state']['types'] = []; $sections['post_types']['state']['types'] = [];
foreach ($post_types as $post_type_slug => $post_type) { foreach ($post_types as $post_type_slug => $post_type) {
$sections['post_types']['state']['types'][ $post_type_slug ] = $object->get_limitations()->post_types->{$post_type_slug}; $sections['post_types']['state']['types'][ $post_type_slug ] = $object_model->get_limitations()->post_types->{$post_type_slug};
$sections['post_types']['fields'][ "control_{$post_type_slug}" ] = [ $sections['post_types']['fields'][ "control_{$post_type_slug}" ] = [
'type' => 'group', 'type' => 'group',
@ -678,9 +678,9 @@ class Limitation_Manager {
/* /*
* Add override notice. * Add override notice.
*/ */
if ('product' !== $object->model) { if ('product' !== $object_model->model) {
$sections['post_types']['fields'][ "override_{$post_type_slug}" ] = $this->override_notice( $sections['post_types']['fields'][ "override_{$post_type_slug}" ] = $this->override_notice(
$object->get_limitations(false)->post_types->exists($post_type_slug), $object_model->get_limitations(false)->post_types->exists($post_type_slug),
[ [
'limit_post_types', 'limit_post_types',
] ]
@ -694,25 +694,25 @@ class Limitation_Manager {
* *
* @since 2.0.0 * @since 2.0.0
* *
* @param \WP_Ultimo\Models\Trait\Trait_Limitable $object The model being edited. * @param \WP_Ultimo\Models\Limitable $object_model The model being edited.
* @return array * @return array
*/ */
protected function get_sites_fields($object) { protected function get_sites_fields($object_model) {
$fields = [ $fields = [
'modules[sites][enabled]' => [ 'modules[sites][enabled]' => [
'type' => 'toggle', 'type' => 'toggle',
'title' => __('Limit Sites', 'wp-multisite-waas'), 'title' => __('Limit Sites', 'wp-multisite-waas'),
'desc' => __('Enable site limitations for this product.', 'wp-multisite-waas'), 'desc' => __('Enable site limitations for this product.', 'wp-multisite-waas'),
'value' => $object->get_limitations()->sites->is_enabled(), 'value' => $object_model->get_limitations()->sites->is_enabled(),
'html_attr' => [ 'html_attr' => [
'v-model' => 'limit_sites', 'v-model' => 'limit_sites',
], ],
], ],
]; ];
if ('product' !== $object->model) { if ('product' !== $object_model->model) {
$fields['sites_overwrite'] = $this->override_notice($object->get_limitations(false)->sites->has_own_enabled()); $fields['sites_overwrite'] = $this->override_notice($object_model->get_limitations(false)->sites->has_own_enabled());
} }
/* /*
@ -734,18 +734,18 @@ class Limitation_Manager {
'title' => __('Site Allowance', 'wp-multisite-waas'), 'title' => __('Site Allowance', 'wp-multisite-waas'),
'desc' => __('This is the number of sites the customer will be able to create under this membership.', 'wp-multisite-waas'), 'desc' => __('This is the number of sites the customer will be able to create under this membership.', 'wp-multisite-waas'),
'placeholder' => 1, 'placeholder' => 1,
'value' => $object->get_limitations()->sites->get_limit(), 'value' => $object_model->get_limitations()->sites->get_limit(),
'wrapper_html_attr' => [ 'wrapper_html_attr' => [
'v-show' => "get_state_value('product_type', 'none') !== 'service' && limit_sites", 'v-show' => "get_state_value('product_type', 'none') !== 'service' && limit_sites",
'v-cloak' => '1', 'v-cloak' => '1',
], ],
]; ];
if ('product' !== $object->model) { if ('product' !== $object_model->model) {
$fields['sites_overwrite_2'] = $this->override_notice($object->get_limitations(false)->sites->has_own_limit(), ["get_state_value('product_type', 'none') !== 'service' && limit_sites"]); $fields['sites_overwrite_2'] = $this->override_notice($object_model->get_limitations(false)->sites->has_own_limit(), ["get_state_value('product_type', 'none') !== 'service' && limit_sites"]);
} }
return apply_filters('wu_limitations_get_sites_fields', $fields, $object, $this); return apply_filters('wu_limitations_get_sites_fields', $fields, $object_model, $this);
} }
/** /**
@ -753,10 +753,10 @@ class Limitation_Manager {
* *
* @since 2.0.0 * @since 2.0.0
* *
* @param \WP_Ultimo\Models\Trait\Trait_Limitable $object The model being edited. * @param \WP_Ultimo\Models\Limitable $object_model The model being edited.
* @return string * @return string
*/ */
public function get_plugin_selection_list($object) { public function get_plugin_selection_list($object_model) {
$all_plugins = $this->get_all_plugins(); $all_plugins = $this->get_all_plugins();
@ -764,7 +764,7 @@ class Limitation_Manager {
'limitations/plugin-selector', 'limitations/plugin-selector',
[ [
'plugins' => $all_plugins, 'plugins' => $all_plugins,
'object' => $object, 'object' => $object_model,
] ]
); );
} }
@ -774,7 +774,7 @@ class Limitation_Manager {
* *
* @since 2.0.0 * @since 2.0.0
* *
* @param \WP_Ultimo\Models\Traits\Limitable $obj The model being edited. * @param \WP_Ultimo\Models\Limitable $obj The model being edited.
* @param array $section The section array. * @param array $section The section array.
* @return string * @return string
*/ */

View File

@ -9,6 +9,8 @@
namespace WP_Ultimo\Models; namespace WP_Ultimo\Models;
use stdClass;
use WP_Ultimo\Database\Engine\Schema;
use WP_Ultimo\Helpers\Hash; use WP_Ultimo\Helpers\Hash;
// Exit if accessed directly // Exit if accessed directly
@ -132,22 +134,21 @@ abstract class Base_Model implements \JsonSerializable {
* Constructs the object via the constructor arguments * Constructs the object via the constructor arguments
* *
* @since 2.0.0 * @since 2.0.0
* * @param mixed $object_model Std object with model parameters.
* @param mixed $object Std object with model parameters.
*/ */
public function __construct($object = null) { public function __construct($object_model = null) {
$this->model = sanitize_key((new \ReflectionClass($this))->getShortName()); $this->model = sanitize_key((new \ReflectionClass($this))->getShortName());
if (is_array($object)) { if (is_array($object_model)) {
$object = (object) $object; $object_model = (object) $object_model;
} }
if ( ! is_object($object)) { if ( ! is_object($object_model)) {
return; return;
} }
$this->setup_model($object); $this->setup_model($object_model);
} }
/** /**
@ -182,7 +183,7 @@ abstract class Base_Model implements \JsonSerializable {
$value = call_user_func([$this, "get_{$field}"]); $value = call_user_func([$this, "get_{$field}"]);
if ( ! is_numeric($value)) { if ( ! is_numeric($value)) {
_doing_it_wrong(__METHOD__, __('You can only use numeric fields to generate hashes.', 'wp-multisite-waas'), '2.0.0'); _doing_it_wrong(__METHOD__, esc_html__('You can only use numeric fields to generate hashes.', 'wp-multisite-waas'), '2.0.0');
return false; return false;
} }
@ -193,22 +194,21 @@ abstract class Base_Model implements \JsonSerializable {
/** /**
* Setup properties. * Setup properties.
* *
* @param object $object Row from the database. * @param object $object_model Row from the database.
* *
* @access private
* @since 2.0.0 * @since 2.0.0
* @return bool * @return bool
*/ */
private function setup_model($object) { private function setup_model($object_model) {
if ( ! is_object($object)) { if ( ! is_object($object_model)) {
return false; return false;
} }
$vars = get_object_vars($object); $vars = get_object_vars($object_model);
$this->attributes($vars); $this->attributes($vars);
return !empty($this->id); return ! empty($this->id);
} }
/** /**
@ -256,6 +256,7 @@ abstract class Base_Model implements \JsonSerializable {
* *
* @since 2.0.0 * @since 2.0.0
* @return Schema * @return Schema
* @throws \ReflectionException
*/ */
public static function get_schema() { public static function get_schema() {
@ -687,7 +688,7 @@ abstract class Base_Model implements \JsonSerializable {
} }
// _doing_it_wrong(__METHOD__, __('Model metadata only works for already saved models.', 'wp-multisite-waas'), '2.0.0'); // _doing_it_wrong(__METHOD__, __('Model metadata only works for already saved models.', 'wp-multisite-waas'), '2.0.0');
return !(! $this->get_id() && ! $this->_mocked); return ! (! $this->get_id() && ! $this->_mocked);
} }
/** /**
@ -696,14 +697,14 @@ abstract class Base_Model implements \JsonSerializable {
* @since 2.0.0 * @since 2.0.0
* *
* @param string $key The meta key. * @param string $key The meta key.
* @param mixed $default The default value to be passed. * @param mixed $default_value The default value to be passed.
* @param bool $single To return single values or not. * @param bool $single To return single values or not.
* @return mixed * @return mixed
*/ */
public function get_meta($key, $default = false, $single = true) { public function get_meta($key, $default_value = false, $single = true) {
if ( ! $this->is_meta_available()) { if ( ! $this->is_meta_available()) {
return $default; return $default_value;
} }
$meta_type = $this->get_meta_type_name(); $meta_type = $this->get_meta_type_name();
@ -712,7 +713,7 @@ abstract class Base_Model implements \JsonSerializable {
return get_metadata($meta_type, $this->get_id(), $key, $single); return get_metadata($meta_type, $this->get_id(), $key, $single);
} }
return $default; return $default_value;
} }
/** /**
@ -730,7 +731,7 @@ abstract class Base_Model implements \JsonSerializable {
} }
if ( ! is_array($meta)) { if ( ! is_array($meta)) {
_doing_it_wrong(__METHOD__, __('This method expects an array as argument.', 'wp-multisite-waas'), '2.0.0'); _doing_it_wrong(__METHOD__, esc_html__('This method expects an array as argument.', 'wp-multisite-waas'), '2.0.0');
return false; return false;
} }
@ -838,7 +839,7 @@ abstract class Base_Model implements \JsonSerializable {
* Allows use as a callback, such as in `array_map` * Allows use as a callback, such as in `array_map`
* *
* @param stdClass $data Raw mapping data. * @param stdClass $data Raw mapping data.
* @return Mapping * @return Base_model
*/ */
protected static function to_instance($data) { protected static function to_instance($data) {
@ -1038,7 +1039,7 @@ abstract class Base_Model implements \JsonSerializable {
* Creates a copy of the given model adn resets it's id to a 'new' state. * Creates a copy of the given model adn resets it's id to a 'new' state.
* *
* @since 2.0.0 * @since 2.0.0
* @return \WP_Ultimo\Model\Base_Model * @return Base_Model
*/ */
public function duplicate() { public function duplicate() {

View File

@ -82,17 +82,17 @@ class Broadcast extends Post_Base_Model {
* *
* @since 2.0.7 * @since 2.0.7
* *
* @param mixed $object Std object with model parameters. * @param mixed $object_model Std object with model parameters.
*/ */
public function __construct($object = null) { public function __construct($object_model = null) {
$object = (array) $object; $object_model = (array) $object_model;
if ( ! wu_get_isset($object, 'migrated_from_id')) { if ( ! wu_get_isset($object_model, 'migrated_from_id')) {
unset($object['migrated_from_id']); unset($object_model['migrated_from_id']);
} }
parent::__construct($object); parent::__construct($object_model);
} }
/** /**

View File

@ -317,11 +317,11 @@ class Membership extends Base_Model {
* *
* @since 2.0.0 * @since 2.0.0
* *
* @param object $object Std object with model parameters. * @param object $object_model Std object with model parameters.
*/ */
public function __construct($object = null) { public function __construct($object_model = null) {
parent::__construct($object); parent::__construct($object_model);
$this->_gateway_info = [ $this->_gateway_info = [
'gateway' => $this->get_gateway(), 'gateway' => $this->get_gateway(),

View File

@ -23,7 +23,7 @@ defined('ABSPATH') || exit;
* *
* @since 2.0.0 * @since 2.0.0
*/ */
class Site extends Base_Model { class Site extends Base_Model implements Limitable {
use Traits\Limitable; use Traits\Limitable;
use \WP_Ultimo\Traits\WP_Ultimo_Site_Deprecated; use \WP_Ultimo\Traits\WP_Ultimo_Site_Deprecated;
@ -1255,14 +1255,14 @@ class Site extends Base_Model {
* *
* @since 2.0.0 * @since 2.0.0
* *
* @param mixed $object Object containing the parameters. * @param mixed $object_model Object containing the parameters.
*/ */
public function __construct($object = null) { public function __construct($object_model = null) {
parent::__construct($object); parent::__construct($object_model);
if (is_array($object)) { if (is_array($object_model)) {
$object = (object) $object; $object_model = (object) $object_model;
} }
$details = get_blog_details($this->get_blog_id()); $details = get_blog_details($this->get_blog_id());
@ -1274,11 +1274,11 @@ class Site extends Base_Model {
/* /*
* Quick fix for WP CLI, since it uses the --path arg to do other things. * Quick fix for WP CLI, since it uses the --path arg to do other things.
*/ */
if ( ! $this->path && is_object($object) && isset($object->site_path)) { if ( ! $this->path && is_object($object_model) && isset($object_model->site_path)) {
$this->path = $object->site_path; $this->path = $object_model->site_path;
} }
$object = (object) $object; $object_model = (object) $object_model;
} }
/** /**

View File

@ -0,0 +1,99 @@
<?php
/**
* Limitable interface.
*
* @package WP_Ultimo
* @subpackage Models
*/
namespace WP_Ultimo\Models;
interface Limitable {
/**
* List of limitations that need to be merged.
*
* Every model that is limitable (imports this trait)
* needs to declare explicitly the limitations that need to be
* merged. This allows us to chain the merges, and gives us
* a final list of limitations at the end of the process.
*
* @since 2.0.0
* @return array
*/
public function limitations_to_merge();
/**
* Returns the limitations of this particular blog.
*
* @since 2.0.0
*
* @param bool $waterfall If we should construct the limitations object recursively.
* @param bool $skip_self If we should skip the current limitations.
* @return \WP_Ultimo\Objects\Limitations
*/
public function get_limitations($waterfall = true, $skip_self = false);
/**
* Checks if this site has limitations or not.
*
* @since 2.0.0
* @return boolean
*/
public function has_limitations();
/**
* Checks if a particular module is being limited.
*
* @since 2.0.0
*
* @param string $module Module to check.
* @return boolean
*/
public function has_module_limitation($module);
/**
* Returns all user role quotas.
*
* @since 2.0.0
* @return array
*/
public function get_user_role_quotas();
/**
* Proxy method to retrieve the allowed user roles.
*
* @since 2.0.0
* @return array
*/
public function get_allowed_user_roles();
/**
* Schedules plugins to be activated or deactivated based on the current limitations;
*
* @since 2.0.5
* @return void
*/
public function sync_plugins(): void;
/**
* Makes sure we save limitations when we are supposed to.
*
* This is called on the handle_save method of the inc/admin-pages/class-edit-admin-page.php
* for all models that have the trait Limitable.
*
* @see inc/admin-pages/class-edit-admin-page.php
*
* @since 2.0.0
* @return void
*/
public function handle_limitations(): void;
/**
* Returns the list of product slugs associated with this model.
*
* @since 2.0.0
* @return array
*/
public function get_applicable_product_slugs();
}

View File

@ -26,26 +26,12 @@ trait Limitable {
protected $_limitations = []; protected $_limitations = [];
/** /**
* List of limitations that need to be merged. * @inheritDoc
*
* Every model that is limitable (imports this trait)
* needs to declare explicitly the limitations that need to be
* merged. This allows us to chain the merges, and gives us
* a final list of limitations at the end of the process.
*
* @since 2.0.0
* @return array
*/ */
abstract public function limitations_to_merge(); abstract public function limitations_to_merge();
/** /**
* Returns the limitations of this particular blog. * @inheritdoc
*
* @since 2.0.0
*
* @param bool $waterfall If we should construct the limitations object recursively.
* @param bool $skip_self If we should skip the current limitations.
* @return \WP_Ultimo\Objects\Limitations
*/ */
public function get_limitations($waterfall = true, $skip_self = false) { public function get_limitations($waterfall = true, $skip_self = false) {
@ -104,10 +90,7 @@ trait Limitable {
} }
/** /**
* Checks if this site has limitations or not. * @inheritdoc
*
* @since 2.0.0
* @return boolean
*/ */
public function has_limitations() { public function has_limitations() {
@ -191,15 +174,7 @@ trait Limitable {
} }
/** /**
* Makes sure we save limitations when we are supposed to. * @inheritdoc
*
* This is called on the handle_save method of the inc/admin-pages/class-edit-admin-page.php
* for all models that have the trait Limitable.
*
* @see inc/admin-pages/class-edit-admin-page.php
*
* @since 2.0.0
* @return void
*/ */
public function handle_limitations(): void { public function handle_limitations(): void {
/* /*
@ -247,7 +222,7 @@ trait Limitable {
* Set the new permissions, based on the diff. * Set the new permissions, based on the diff.
*/ */
$limitations = wu_array_recursive_diff($modules_to_save, $current_limitations->to_array()); $limitations = wu_array_recursive_diff($modules_to_save, $current_limitations->to_array());
} elseif ('product' === $this->model && $this->get_type() !== 'plan') { } elseif ($this->get_type() !== 'plan') {
$limitations = wu_array_recursive_diff($modules_to_save, Limitations::get_empty()->to_array()); $limitations = wu_array_recursive_diff($modules_to_save, Limitations::get_empty()->to_array());
} else { } else {
$limitations = $modules_to_save; $limitations = $modules_to_save;
@ -257,10 +232,7 @@ trait Limitable {
} }
/** /**
* Returns the list of product slugs associated with this model. * @inheritdoc
*
* @since 2.0.0
* @return array
*/ */
public function get_applicable_product_slugs() { public function get_applicable_product_slugs() {

View File

@ -30,7 +30,7 @@ class Limitations {
* @since 2.0.0 * @since 2.0.0
* @var array * @var array
*/ */
static $limitations_cache = []; private static $limitations_cache = [];
/** /**
* Version of the limitation schema. * Version of the limitation schema.

View File

@ -19,16 +19,16 @@ trait Singleton {
* *
* @var object * @var object
*/ */
public static $instance; public static object $instance;
/** /**
* Returns the instance of WP_Ultimo * Returns the instance of WP_Ultimo
* *
* @return object * @return object
*/ */
public static function get_instance() { public static function get_instance(): object {
if ( ! static::$instance instanceof static) { if ( ! isset(static::$instance) || ! static::$instance instanceof static) {
static::$instance = new static(); static::$instance = new static();
static::$instance->init(); static::$instance->init();
@ -54,7 +54,7 @@ trait Singleton {
* @since 2.0.11 * @since 2.0.11
* @return boolean * @return boolean
*/ */
public function has_parents() { public function has_parents(): bool {
return (bool) class_parents($this); return (bool) class_parents($this);
} }

View File

@ -9,7 +9,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2025-04-07T17:38:26+00:00\n" "POT-Creation-Date: 2025-04-14T17:47:37+00:00\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"X-Generator: WP-CLI 2.11.0\n" "X-Generator: WP-CLI 2.11.0\n"
"X-Domain: wp-multisite-waas\n" "X-Domain: wp-multisite-waas\n"
@ -1241,7 +1241,7 @@ msgstr ""
#: inc/models/class-payment.php:557 #: inc/models/class-payment.php:557
#: views/admin-pages/fields/field-text-display.php:43 #: views/admin-pages/fields/field-text-display.php:43
#: views/admin-pages/fields/field-text-edit.php:47 #: views/admin-pages/fields/field-text-edit.php:47
#: views/base/customers/grid-item.php:118 #: views/base/customers/grid-item.php:130
msgid "None" msgid "None"
msgstr "" msgstr ""
@ -4357,12 +4357,12 @@ msgid "Activated"
msgstr "" msgstr ""
#: inc/admin-pages/class-setup-wizard-admin-page.php:853 #: inc/admin-pages/class-setup-wizard-admin-page.php:853
#: inc/class-scripts.php:177 #: inc/class-scripts.php:180
msgid "Select an Image." msgid "Select an Image."
msgstr "" msgstr ""
#: inc/admin-pages/class-setup-wizard-admin-page.php:854 #: inc/admin-pages/class-setup-wizard-admin-page.php:854
#: inc/class-scripts.php:178 #: inc/class-scripts.php:181
msgid "Use this image" msgid "Use this image"
msgstr "" msgstr ""
@ -6345,7 +6345,7 @@ msgstr ""
#: inc/api/trait-rest-api.php:169 #: inc/api/trait-rest-api.php:169
#: inc/api/trait-rest-api.php:242 #: inc/api/trait-rest-api.php:242
#: inc/api/trait-rest-api.php:300 #: inc/api/trait-rest-api.php:300
#: inc/models/class-base-model.php:610 #: inc/models/class-base-model.php:611
#: inc/models/class-site.php:1440 #: inc/models/class-site.php:1440
msgid "Item not found." msgid "Item not found."
msgstr "" msgstr ""
@ -7684,16 +7684,16 @@ msgid "here"
msgstr "" msgstr ""
#. translators: the day/month/year date format used by WP Multisite WaaS. You can changed it to localize this date format to your language. the default value is d/m/Y, which is the format 31/12/2021. #. translators: the day/month/year date format used by WP Multisite WaaS. You can changed it to localize this date format to your language. the default value is d/m/Y, which is the format 31/12/2021.
#: inc/class-scripts.php:274 #: inc/class-scripts.php:277
msgid "d/m/Y" msgid "d/m/Y"
msgstr "" msgstr ""
#: inc/class-scripts.php:284 #: inc/class-scripts.php:287
msgid "in %s" msgid "in %s"
msgstr "" msgstr ""
#. translators: %s a unit of time. #. translators: %s a unit of time.
#: inc/class-scripts.php:285 #: inc/class-scripts.php:288
#: inc/functions/date.php:155 #: inc/functions/date.php:155
#: inc/list-tables/class-base-list-table.php:830 #: inc/list-tables/class-base-list-table.php:830
#: inc/list-tables/class-membership-list-table.php:209 #: inc/list-tables/class-membership-list-table.php:209
@ -7702,59 +7702,59 @@ msgstr ""
msgid "%s ago" msgid "%s ago"
msgstr "" msgstr ""
#: inc/class-scripts.php:286 #: inc/class-scripts.php:289
msgid "a few seconds" msgid "a few seconds"
msgstr "" msgstr ""
#: inc/class-scripts.php:287 #: inc/class-scripts.php:290
msgid "%d seconds" msgid "%d seconds"
msgstr "" msgstr ""
#: inc/class-scripts.php:288 #: inc/class-scripts.php:291
msgid "a minute" msgid "a minute"
msgstr "" msgstr ""
#: inc/class-scripts.php:289 #: inc/class-scripts.php:292
msgid "%d minutes" msgid "%d minutes"
msgstr "" msgstr ""
#: inc/class-scripts.php:290 #: inc/class-scripts.php:293
msgid "an hour" msgid "an hour"
msgstr "" msgstr ""
#: inc/class-scripts.php:291 #: inc/class-scripts.php:294
msgid "%d hours" msgid "%d hours"
msgstr "" msgstr ""
#: inc/class-scripts.php:292 #: inc/class-scripts.php:295
msgid "a day" msgid "a day"
msgstr "" msgstr ""
#: inc/class-scripts.php:293 #: inc/class-scripts.php:296
msgid "%d days" msgid "%d days"
msgstr "" msgstr ""
#: inc/class-scripts.php:294 #: inc/class-scripts.php:297
msgid "a week" msgid "a week"
msgstr "" msgstr ""
#: inc/class-scripts.php:295 #: inc/class-scripts.php:298
msgid "%d weeks" msgid "%d weeks"
msgstr "" msgstr ""
#: inc/class-scripts.php:296 #: inc/class-scripts.php:299
msgid "a month" msgid "a month"
msgstr "" msgstr ""
#: inc/class-scripts.php:297 #: inc/class-scripts.php:300
msgid "%d months" msgid "%d months"
msgstr "" msgstr ""
#: inc/class-scripts.php:298 #: inc/class-scripts.php:301
msgid "a year" msgid "a year"
msgstr "" msgstr ""
#: inc/class-scripts.php:299 #: inc/class-scripts.php:302
msgid "%d years" msgid "%d years"
msgstr "" msgstr ""
@ -8418,11 +8418,11 @@ msgid "Remove all saved data for WP Multisite WaaS when the plugin is uninstalle
msgstr "" msgstr ""
#. translators: the placeholder is an error message #. translators: the placeholder is an error message
#: inc/class-sunrise.php:274 #: inc/class-sunrise.php:276
msgid "Sunrise copy failed: %s" msgid "Sunrise copy failed: %s"
msgstr "" msgstr ""
#: inc/class-sunrise.php:277 #: inc/class-sunrise.php:279
msgid "Sunrise upgrade attempt succeeded." msgid "Sunrise upgrade attempt succeeded."
msgstr "" msgstr ""
@ -14782,43 +14782,43 @@ msgstr ""
msgid "Focus on your business and avoid all the web hosting hassles. Our managed hosting guarantees unmatched performance, reliability and choice with 24/7 support that acts as your extended team, making Cloudways an ultimate choice for growing agencies and e-commerce businesses." msgid "Focus on your business and avoid all the web hosting hassles. Our managed hosting guarantees unmatched performance, reliability and choice with 24/7 support that acts as your extended team, making Cloudways an ultimate choice for growing agencies and e-commerce businesses."
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:115 #: inc/integrations/host-providers/class-cpanel-host-provider.php:114
msgid "cPanel Username" msgid "cPanel Username"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:116 #: inc/integrations/host-providers/class-cpanel-host-provider.php:115
msgid "e.g. username" msgid "e.g. username"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:120 #: inc/integrations/host-providers/class-cpanel-host-provider.php:119
msgid "cPanel Password" msgid "cPanel Password"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:121 #: inc/integrations/host-providers/class-cpanel-host-provider.php:120
msgid "password" msgid "password"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:124 #: inc/integrations/host-providers/class-cpanel-host-provider.php:123
msgid "cPanel Host" msgid "cPanel Host"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:125 #: inc/integrations/host-providers/class-cpanel-host-provider.php:124
msgid "e.g. yourdomain.com" msgid "e.g. yourdomain.com"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:128 #: inc/integrations/host-providers/class-cpanel-host-provider.php:127
msgid "cPanel Port" msgid "cPanel Port"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:129 #: inc/integrations/host-providers/class-cpanel-host-provider.php:128
msgid "Defaults to 2083" msgid "Defaults to 2083"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:133 #: inc/integrations/host-providers/class-cpanel-host-provider.php:132
msgid "Root Directory" msgid "Root Directory"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:134 #: inc/integrations/host-providers/class-cpanel-host-provider.php:133
msgid "Defaults to /public_html" msgid "Defaults to /public_html"
msgstr "" msgstr ""
@ -14826,15 +14826,15 @@ msgstr ""
msgid "Unexpected error ocurred trying to sync domains with CPanel" msgid "Unexpected error ocurred trying to sync domains with CPanel"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:317 #: inc/integrations/host-providers/class-cpanel-host-provider.php:318
msgid "cPanel is the management panel being used on a large number of shared and dedicated hosts across the globe." msgid "cPanel is the management panel being used on a large number of shared and dedicated hosts across the globe."
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:362 #: inc/integrations/host-providers/class-cpanel-host-provider.php:363
msgid "Add a new Addon Domain on cPanel whenever a new domain mapping gets created on your network" msgid "Add a new Addon Domain on cPanel whenever a new domain mapping gets created on your network"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:368 #: inc/integrations/host-providers/class-cpanel-host-provider.php:369
msgid "Add a new SubDomain on cPanel whenever a new site gets created on your network" msgid "Add a new SubDomain on cPanel whenever a new site gets created on your network"
msgstr "" msgstr ""
@ -15256,7 +15256,7 @@ msgid "Send an email to this customer"
msgstr "" msgstr ""
#: inc/list-tables/class-customer-list-table.php:152 #: inc/list-tables/class-customer-list-table.php:152
#: views/base/customers/grid-item.php:115 #: views/base/customers/grid-item.php:127
msgid "Switch To" msgid "Switch To"
msgstr "" msgstr ""
@ -15265,7 +15265,7 @@ msgstr ""
#: inc/list-tables/class-payment-list-table.php:143 #: inc/list-tables/class-payment-list-table.php:143
#: inc/list-tables/class-site-list-table.php:256 #: inc/list-tables/class-site-list-table.php:256
#: views/admin-pages/fields/field-text.php:44 #: views/admin-pages/fields/field-text.php:44
#: views/base/customers/grid-item.php:95 #: views/base/customers/grid-item.php:107
#: views/base/responsive-table-row.php:130 #: views/base/responsive-table-row.php:130
msgid "View" msgid "View"
msgstr "" msgstr ""
@ -15297,7 +15297,7 @@ msgstr ""
#: inc/list-tables/class-customer-list-table.php:363 #: inc/list-tables/class-customer-list-table.php:363
#: inc/list-tables/class-site-customer-list-table.php:62 #: inc/list-tables/class-site-customer-list-table.php:62
#: views/base/customers/grid-item.php:64 #: views/base/customers/grid-item.php:76
msgid "Online" msgid "Online"
msgstr "" msgstr ""
@ -16588,11 +16588,11 @@ msgstr ""
msgid "You do not have enough permissions to read the logs of this webhook." msgid "You do not have enough permissions to read the logs of this webhook."
msgstr "" msgstr ""
#: inc/models/class-base-model.php:185 #: inc/models/class-base-model.php:186
msgid "You can only use numeric fields to generate hashes." msgid "You can only use numeric fields to generate hashes."
msgstr "" msgstr ""
#: inc/models/class-base-model.php:733 #: inc/models/class-base-model.php:734
msgid "This method expects an array as argument." msgid "This method expects an array as argument."
msgstr "" msgstr ""
@ -17980,7 +17980,7 @@ msgid "Preview Image"
msgstr "" msgstr ""
#: views/admin-pages/fields/field-image.php:90 #: views/admin-pages/fields/field-image.php:90
#: views/settings/fields/field-image.php:50 #: views/settings/fields/field-image.php:47
msgid "Remove Image" msgid "Remove Image"
msgstr "" msgstr ""
@ -18083,48 +18083,48 @@ msgstr ""
msgid "Your browser doesn't support iframes" msgid "Your browser doesn't support iframes"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:45 #: views/base/customers/grid-item.php:57
msgid "No email address" msgid "No email address"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:50 #: views/base/customers/grid-item.php:62
msgid "VIP Customer" msgid "VIP Customer"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:50 #: views/base/customers/grid-item.php:62
msgid "Regular Customer" msgid "Regular Customer"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:59 #: views/base/customers/grid-item.php:71
msgid "Last Login:" msgid "Last Login:"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:66
#: views/base/customers/grid-item.php:78 #: views/base/customers/grid-item.php:78
#: views/base/customers/grid-item.php:90
msgid "ago" msgid "ago"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:68 #: views/base/customers/grid-item.php:80
msgid "Never logged in" msgid "Never logged in"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:75 #: views/base/customers/grid-item.php:87
msgid "Customer Since:" msgid "Customer Since:"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:84 #: views/base/customers/grid-item.php:96
msgid "Memberships:" msgid "Memberships:"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:106 #: views/base/customers/grid-item.php:118
msgid "Actions:" msgid "Actions:"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:134 #: views/base/customers/grid-item.php:146
msgid "Select Customer" msgid "Select Customer"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:138 #: views/base/customers/grid-item.php:150
#: views/base/sites/grid-item.php:67 #: views/base/sites/grid-item.php:67
#: views/dashboard-widgets/my-sites.php:151 #: views/dashboard-widgets/my-sites.php:151
msgid "Manage" msgid "Manage"

View File

@ -14,7 +14,7 @@
"translate": true "translate": true
}, },
"scripts": { "scripts": {
"prebuild": "composer install --no-dev", "prebuild": "composer install -o --no-dev",
"prebuild:dev": "composer install", "prebuild:dev": "composer install",
"build": "npm run uglify && npm run makepot && npm run cleancss && npm run archive", "build": "npm run uglify && npm run makepot && npm run cleancss && npm run archive",
"build:dev": "npm run uglify && npm run makepot && npm run cleancss", "build:dev": "npm run uglify && npm run makepot && npm run cleancss",

View File

@ -1,12 +1,12 @@
includes:
- vendor/szepeviktor/phpstan-wordpress/extension.neon
parameters: parameters:
level: max level: 0
inferPrivatePropertyTypeFromConstructor: true inferPrivatePropertyTypeFromConstructor: true
checkMissingIterableValueType: false
treatPhpDocTypesAsCertain: false treatPhpDocTypesAsCertain: false
paths: paths:
- / - ./views
- ./inc
- ./wp-multisite-waas.php
ignoreErrors: ignoreErrors:
# Uses func_get_args() -
- '/^Function apply_filters(_ref_array)? invoked with [34567] parameters, 2 required\.$/' message: '#Variable \$.* might not be defined.#'
path: ./views/*

View File

@ -1,7 +1,7 @@
=== WP Multisite WaaS === === WP Multisite WaaS ===
Requires at least: 5.3 Requires at least: 5.3
Requires PHP: 7.4.30 Requires PHP: 7.4.30
Tested up to: 6.7.1 Tested up to: 6.7.2
License: GPLv2 License: GPLv2
License URI: http://www.gnu.org/licenses/gpl-2.0.html License URI: http://www.gnu.org/licenses/gpl-2.0.html
Contributors: aanduque, superdav42 Contributors: aanduque, superdav42
@ -84,6 +84,20 @@ For support, please open an issue on the [GitHub repository](https://github.com/
We recommend running this in a staging environment before updating your production environment. We recommend running this in a staging environment before updating your production environment.
== Changelog == == Changelog ==
Version [2.4.0] - Released on 2025-XX-XX
- Improved: Prep Plugin for release on WordPress.org
- Improved: Update translation text domain
- Fixed: Escape everything that should be escaped.
- Fixed: Add nonce checks where needed.
- Fixed: Sanitize all inputs.
- Improved: Apply Code style changes across the codebase.
- Fixed: Many deprecation notices.
- Improved: Load order of many filters.
- Improved: Add Proper Build script
- Improved: Use emojii flags
- Fixed: i18n deprecation notice for translating too early
- Improved: Put all scripts in footer and load async
Version [2.3.4] - Released on 2024-01-31 Version [2.3.4] - Released on 2024-01-31
- Fixed: Unable to checkout with any payment gateway - Fixed: Unable to checkout with any payment gateway
- Fixed: Warning Undefined global variable $pagenow - Fixed: Warning Undefined global variable $pagenow

View File

@ -18,21 +18,19 @@ use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
/** /**
* @see \Rector\Tests\TypeDeclaration\Rector\YodaConditionsRector\YodaConditionsRectorTest * @see \Rector\Tests\TypeDeclaration\Rector\YodaConditionsRector\YodaConditionsRectorTest
*/ */
final class YodaConditionsRector extends AbstractRector final class YodaConditionsRector extends AbstractRector {
{
/** /**
* @return array<class-string<Node>> * @return array<class-string<Node>>
*/ */
public function getNodeTypes(): array public function getNodeTypes(): array {
{
return [Equal::class, NotEqual::class, Identical::class, NotIdentical::class]; return [Equal::class, NotEqual::class, Identical::class, NotIdentical::class];
} }
/** /**
* @param \PhpParser\Node\Stmt\Class_ $node * @param \PhpParser\Node\Stmt\Class_ $node
*/ */
public function refactor(Node $node): ?Node public function refactor(Node $node): ?Node {
{
// Ensure the left operand is not a constant // Ensure the left operand is not a constant
if (( if ((
$node->left instanceof Node\Expr\Variable || $node->left instanceof Node\Expr\Variable ||

View File

@ -6,23 +6,20 @@ namespace Rector\Tests\TypeDeclaration\Rector\YodaConditionsRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase; use Rector\Testing\PHPUnit\AbstractRectorTestCase;
final class YodaConditionsRectorTest extends AbstractRectorTestCase final class YodaConditionsRectorTest extends AbstractRectorTestCase {
{
/** /**
* @dataProvider provideData() * @dataProvider provideData()
*/ */
public function test(string $filePath): void public function test(string $filePath): void {
{
$this->doTestFile($filePath); $this->doTestFile($filePath);
} }
public static function provideData(): \Iterator public static function provideData(): \Iterator {
{
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
} }
public function provideConfigFilePath(): string public function provideConfigFilePath(): string {
{
return __DIR__ . '/config/configured_rule.php'; return __DIR__ . '/config/configured_rule.php';
} }
} }

View File

@ -5,7 +5,7 @@
* @since 2.0.0 * @since 2.0.0
*/ */
?> ?>
<li class="<?php echo esc_attr(trim($field->wrapper_classes)); ?>" <?php echo($field->get_wrapper_html_attributes(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> <li class="<?php echo esc_attr(trim($field->wrapper_classes)); ?>" <?php echo($field->get_wrapper_html_attributes()); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
<div class="wu-block wu-w-full"> <div class="wu-block wu-w-full">

View File

@ -11,7 +11,19 @@
<div <div
class="wu--mt-8 wu-py-8 wu-bg-gray-100 wu-bg-cover wu-bg-center" class="wu--mt-8 wu-py-8 wu-bg-gray-100 wu-bg-cover wu-bg-center"
style="opacity: 0.15; background-image: url(<?php echo esc_url(get_avatar_url($item->get_user_id(), array('default' => 'identicon', 'size' => 320))); ?>)" style="opacity: 0.15; background-image: url(
<?php
echo esc_url(
get_avatar_url(
$item->get_user_id(),
array(
'default' => 'identicon',
'size' => 320,
)
)
);
?>
)"
> >
&nbsp; &nbsp;
</div> </div>

View File

@ -8,7 +8,7 @@
<?php // translators: %s: Customer Name ?> <?php // translators: %s: Customer Name ?>
<p><?php printf(esc_html__('Hey %s,', 'wp-multisite-waas'), '{{customer_name}}'); ?></p> <p><?php printf(esc_html__('Hey %s,', 'wp-multisite-waas'), '{{customer_name}}'); ?></p>
<?php // translators: %1$s: Site Title, %2$s: Site Url ?> <?php // translators: %1$s: Site Title, %2$s: Site Url ?>
<p><?php echo wp_kses(sprintf(__('We have great news! The site <b>%1$s</b> (%2$s) was created successfully and is ready!', 'wp-multisite-waas'), '{{site_title}}', '<a href="{{site_url}}" style="text-decoration: none;" rel="nofollow">{{site_url}}</a>'),'pre_user_description'); ?></p> <p><?php echo wp_kses(sprintf(__('We have great news! The site <b>%1$s</b> (%2$s) was created successfully and is ready!', 'wp-multisite-waas'), '{{site_title}}', '<a href="{{site_url}}" style="text-decoration: none;" rel="nofollow">{{site_url}}</a>'), 'pre_user_description'); ?></p>
<h2><b><?php esc_html_e('Your Site', 'wp-multisite-waas'); ?></b></h2> <h2><b><?php esc_html_e('Your Site', 'wp-multisite-waas'); ?></b></h2>

View File

@ -11,14 +11,12 @@
wp_enqueue_media(); wp_enqueue_media();
wp_enqueue_script('media'); wp_enqueue_script('media');
$suffix = WU_Scripts()->suffix(); wp_enqueue_script('wu-field-button-upload', wu_get_asset('wu-field-image.js', 'js'), [], wu_get_version(), true);
wp_enqueue_script('wu-field-button-upload', WP_Ultimo()->get_asset("wu-field-image$suffix.js", 'js'));
?> ?>
<tr> <tr>
<th scope="row"><label for="<?php echo $field_slug; ?>"><?php echo $field['title']; ?></label></th> <th scope="row"><label for="<?php echo esc_attr($field_slug); ?>"><?php echo esc_html($field['title']); ?></label></th>
<td> <td>
<?php <?php
@ -29,33 +27,32 @@ wp_enqueue_script('wu-field-button-upload', WP_Ultimo()->get_asset("wu-field-ima
} }
if ( $image_url ) { if ( $image_url ) {
$image = '<img id="%s" src="%s" alt="%s" style="width:%s; height:auto">';
printf( printf(
$image, '<img id="%s" src="%s" alt="%s" style="width:%s; height:auto">',
$field_slug . '-preview', esc_attr($field_slug . '-preview'),
$image_url, esc_attr($image_url),
get_bloginfo('name'), esc_attr(get_bloginfo('name')),
$field['width'] . 'px' esc_attr($field['width'] . 'px')
); );
} }
?> ?>
<br> <br>
<a href="#" class="button wu-field-button-upload" data-target="<?php echo $field_slug; ?>"> <a href="#" class="button wu-field-button-upload" data-target="<?php echo esc_attr($field_slug); ?>">
<?php echo $field['button']; ?> <?php echo esc_html($field['button']); ?>
</a> </a>
<a data-default="<?php echo $field['default']; ?>" href="#" class="button wu-field-button-upload-remove" data-target="<?php echo $field_slug; ?>"> <a data-default="<?php echo esc_attr($field['default']); ?>" href="#" class="button wu-field-button-upload-remove" data-target="<?php echo esc_attr($field_slug); ?>">
<?php esc_html_e('Remove Image', 'wp-multisite-waas'); ?> <?php esc_html_e('Remove Image', 'wp-multisite-waas'); ?>
</a> </a>
<?php if ( ! empty($field['desc'])) : ?> <?php if ( ! empty($field['desc'])) : ?>
<p class="description" id="<?php echo $field_slug; ?>-desc"> <p class="description" id="<?php echo esc_attr($field_slug); ?>-desc">
<?php echo $field['desc']; ?> <?php echo esc_html($field['desc']); ?>
</p> </p>
<input type="hidden" name="<?php echo $field_slug; ?>" id="<?php echo $field_slug; ?>" value="<?php echo wu_get_setting($field_slug) ?: $field['default']; ?>"> <input type="hidden" name="<?php echo esc_attr($field_slug); ?>" id="<?php echo esc_attr($field_slug); ?>" value="<?php echo esc_attr(wu_get_setting($field_slug) ?: $field['default']); ?>">
<?php endif; ?> <?php endif; ?>

View File

@ -54,7 +54,7 @@
<div> <div>
<span class="wu-text-sm wu-text-gray-800 wu-inline-block wu-py-4"> <span class="wu-text-sm wu-text-gray-800 wu-inline-block wu-py-4">
<?php esc_html_e('This integration will <strong>not</strong>:', 'wp-multisite-waas'); ?> <?php echo wp_kses(__('This integration will <strong>not</strong>:', 'wp-multisite-waas'), ['strong' => []]); ?>
</span> </span>
<ul class="wu--mx-5 wu-my-0 wu-border-t wu-border-solid wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300"> <ul class="wu--mx-5 wu-my-0 wu-border-t wu-border-solid wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300">

View File

@ -4,7 +4,7 @@
* Description: The WordPress Multisite Website as a Service (WaaS) plugin. * Description: The WordPress Multisite Website as a Service (WaaS) plugin.
* Plugin URI: https://wpmultisitewaas.org * Plugin URI: https://wpmultisitewaas.org
* Text Domain: wp-multisite-waas * Text Domain: wp-multisite-waas
* Version: 2.3.4 * Version: 2.4.0
* Author: WP Multisite Community * Author: WP Multisite Community
* Author URI: https://github.com/superdav42/wp-multisite-waas * Author URI: https://github.com/superdav42/wp-multisite-waas
* GitHub Plugin URI: https://github.com/superdav42/wp-multisite-waas * GitHub Plugin URI: https://github.com/superdav42/wp-multisite-waas
@ -27,10 +27,10 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with WP Multisite WaaS. If not, see <http://www.gnu.org/licenses/>. * along with WP Multisite WaaS. If not, see <http://www.gnu.org/licenses/>.
* *
* @author Arindo Duque and NextPress * @author Arindo Duque and NextPress and WP Multisite Community
* @category Core * @category Core
* @package WP_Ultimo * @package WP_Ultimo
* @version 2.3.4 * @version 2.4.0
*/ */
// Exit if accessed directly // Exit if accessed directly
@ -81,9 +81,9 @@ if ( ! function_exists('WP_Ultimo')) {
* @return WP_Ultimo * @return WP_Ultimo
* @since 2.0.0 * @since 2.0.0
*/ */
function WP_Ultimo() { // phpcs:ignore function WP_Ultimo() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
return WP_Ultimo::get_instance(); return WP_Ultimo::get_instance();
} // end WP_Ultimo; }
} }
// Initialize and set to global for back-compat // Initialize and set to global for back-compat
$GLOBALS['WP_Ultimo'] = WP_Ultimo(); $GLOBALS['WP_Ultimo'] = WP_Ultimo();