12 Commits

Author SHA1 Message Date
2bdefa2886 Updates deps and allow php 7 2025-04-07 11:48:48 -06:00
89a53def32 Add new js file 2025-04-07 11:40:43 -06:00
a8a0330685 Add Proper Build script 2025-04-07 11:40:19 -06:00
d86e54544b Remove overzealous escaping 2025-04-07 09:47:01 -06:00
816abe7360 Update views/wizards/setup/default.php 2025-04-07 09:37:05 -06:00
47f8e8339d Merge remote-tracking branch 'origin/main' into plugin-check
# Conflicts:
#	inc/class-whitelabel.php
2025-04-07 09:19:56 -06:00
a815fdf179 Prep Plugin for release on WordPress.org
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.
2025-04-07 09:15:21 -06:00
f05ab77418 Update tranlation text domain 2025-02-15 23:19:24 -07:00
217009caab Put all scripts in footer and load async 2025-02-15 15:07:06 -07:00
eb29a438a5 Fix i18n deprecation notice for translating too early 2025-02-15 15:06:43 -07:00
6d7e7cef66 Use emojii flags 2025-02-15 14:57:51 -07:00
3113413c3d Only enqueue style when needed 2025-02-15 09:36:25 -07:00
44 changed files with 425 additions and 521 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.4.0", "version": "2.3.3",
"authors": [ "authors": [
{ {
"name": "Arindo Duque", "name": "Arindo Duque",
@ -93,11 +93,7 @@
"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,10 +59,7 @@ class Scripts {
* } * }
* @return void * @return void
*/ */
public function register_script($handle, $src, $deps = [], $args = [ public function register_script($handle, $src, $deps = [], $args = ['async' => true, 'in_footer' => true]): void {
'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,7 +115,6 @@ 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';
@ -139,7 +138,6 @@ class Sunrise {
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__ . '/limits/class-theme-limits.php';
require_once __DIR__ . '/models/class-membership.php'; require_once __DIR__ . '/models/class-membership.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.4.0'; const VERSION = '2.3.4';
/** /**
* 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 = self::VERSION; public $version = '2.3.4';
/** /**
* Tables registered by WP Multisite WaaS. * Tables registered by WP Multisite WaaS.

View File

@ -26,15 +26,15 @@ class Domain_Stage extends Enum {
*/ */
const __default = 'checking-dns'; // phpcs:ignore const __default = 'checking-dns'; // phpcs:ignore
const FAILED = 'failed'; const FAILED = 'failed';
const CHECKING_DNS = 'checking-dns'; const CHECKING_DNS = 'checking-dns';
const CHECKING_SSL = 'checking-ssl-cert'; const CHECKING_SSL = 'checking-ssl-cert';
const DONE_WITHOUT_SSL = 'done-without-ssl'; const DONE_WITHOUT_SSL = 'done-without-ssl';
const DONE = 'done'; const DONE = 'done';
/** /**
* Returns an array with values => CSS Classes. * Returns an array with values => CSS Classes.

View File

@ -51,7 +51,7 @@ abstract class Table extends \BerlinDB\Database\Table {
return false; return false;
} }
return (bool) is_main_site(); return (bool) is_main_site();
} }
/** /**

View File

@ -26,15 +26,15 @@ class Membership_Status extends Enum {
*/ */
const __default = 'pending'; // phpcs:ignore const __default = 'pending'; // phpcs:ignore
const PENDING = 'pending'; const PENDING = 'pending';
const ACTIVE = 'active'; const ACTIVE = 'active';
const TRIALING = 'trialing'; const TRIALING = 'trialing';
const EXPIRED = 'expired'; const EXPIRED = 'expired';
const ON_HOLD = 'on-hold'; const ON_HOLD = 'on-hold';
const CANCELLED = 'cancelled'; const CANCELLED = 'cancelled';

View File

@ -26,19 +26,19 @@ class Payment_Status extends Enum {
*/ */
const __default = 'pending'; // phpcs:ignore const __default = 'pending'; // phpcs:ignore
const PENDING = 'pending'; const PENDING = 'pending';
const COMPLETED = 'completed'; const COMPLETED = 'completed';
const REFUND = 'refunded'; const REFUND = 'refunded';
const PARTIAL_REFUND = 'partially-refunded'; const PARTIAL_REFUND = 'partially-refunded';
const PARTIAL = 'partially-paid'; const PARTIAL = 'partially-paid';
const FAILED = 'failed'; const FAILED = 'failed';
const CANCELLED = 'cancelled'; const CANCELLED = 'cancelled';
/** /**
* Returns an array with values => CSS Classes. * Returns an array with values => CSS Classes.

View File

@ -26,7 +26,7 @@ class Product_Type extends Enum {
*/ */
const __default = 'plan'; // phpcs:ignore const __default = 'plan'; // phpcs:ignore
const PLAN = 'plan'; const PLAN = 'plan';
const PACKAGE = 'package'; const PACKAGE = 'package';

View File

@ -26,17 +26,17 @@ class Site_Type extends Enum {
*/ */
const __default = 'default'; // phpcs:ignore const __default = 'default'; // phpcs:ignore
const REGULAR = 'default'; const REGULAR = 'default';
const SITE_TEMPLATE = 'site_template'; const SITE_TEMPLATE = 'site_template';
const CUSTOMER_OWNED = 'customer_owned'; const CUSTOMER_OWNED = 'customer_owned';
const PENDING = 'pending'; const PENDING = 'pending';
const EXTERNAL = 'external'; const EXTERNAL = 'external';
const MAIN = 'main'; const MAIN = 'main';
/** /**
* Returns an array with values => CSS Classes. * Returns an array with values => CSS Classes.

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 . esc_html("::$method_name()"), '2.0.0'); _deprecated_function(self::class . "::$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_model Object containing the parameters. * @param mixed $object Object containing the parameters.
*/ */
public function __construct($object_model = null) { public function __construct($object = null) {
_deprecated_function(self::class, '2.0.0', esc_html(\WP_Ultimo\Models\Site::class)); _deprecated_function(self::class, '2.0.0', \WP_Ultimo\Models\Site::class);
if (is_numeric($object_model)) { if (is_numeric($object)) {
$object_model = wu_get_site($object_model); $object = wu_get_site($object);
} }
if ( $object_model) { if ($object) {
$object_model = get_object_vars($object_model); $object = get_object_vars($object);
} }
parent::__construct($object_model); parent::__construct($object);
} }
} }
@ -740,21 +740,21 @@ class WU_Site_Template extends \WP_Ultimo\Models\Site {
* *
* @deprecated 2.0.0 * @deprecated 2.0.0
* *
* @param mixed $object_model Object containing the parameters. * @param mixed $object Object containing the parameters.
*/ */
public function __construct($object_model = null) { public function __construct($object = null) {
_deprecated_function(self::class, '2.0.0', esc_html(\WP_Ultimo\Models\Site::class)); _deprecated_function(self::class, '2.0.0', \WP_Ultimo\Models\Site::class);
if (is_numeric($object_model)) { if (is_numeric($object)) {
$object_model = wu_get_site($object_model); $object = wu_get_site($object);
} }
if ( $object_model) { if ($object) {
$object_model = get_object_vars($object_model); $object = get_object_vars($object);
} }
parent::__construct($object_model); parent::__construct($object);
} }
} }
@ -843,22 +843,22 @@ class WU_Coupon extends \WP_Ultimo\Models\Discount_Code {
* *
* @deprecated 2.0.0 * @deprecated 2.0.0
* *
* @param mixed $object_model Object containing the parameters. * @param mixed $object Object containing the parameters.
*/ */
public function __construct($object_model = null) { public function __construct($object = 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_model) ) { if (is_numeric($object)) {
$object_model = wu_get_discount_code($object_model); $object = wu_get_discount_code($object);
} }
if ( $object_model ) { if ($object) {
$object_model = get_object_vars($object_model); $object = get_object_vars($object);
} }
if (is_array($object_model)) { if (is_array($object)) {
foreach ( $object_model as $att => $value) { foreach ($object 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_model Object containing the parameters. * @param mixed $object Object containing the parameters.
*/ */
public function __construct($object_model = null) { public function __construct($object = null) {
_deprecated_function(self::class, '2.0.0', esc_html(\WP_Ultimo\Models\Product::class)); _deprecated_function(self::class, '2.0.0', \WP_Ultimo\Models\Product::class);
if (is_numeric($object_model)) { if (is_numeric($object)) {
$object_model = wu_get_product($object_model); $object = wu_get_product($object);
} }
if ($object_model ) { if ($object) {
$object_model = get_object_vars($object_model); $object = get_object_vars($object);
} }
if (is_array($object_model)) { if (is_array($object)) {
foreach ($object_model as $att => $value) { foreach ($object as $att => $value) {
$this->{$att} = $value; $this->{$att} = $value;
} }
} }
$this->set_slug(uniqid()); $this->set_slug(uniqid());
parent::__construct($object_model); parent::__construct($object);
} }
/** /**
@ -973,21 +973,21 @@ class WU_Subscription extends \WP_Ultimo\Models\Membership {
* *
* @deprecated 2.0.0 * @deprecated 2.0.0
* *
* @param mixed $object_model Object containing the parameters. * @param mixed $object Object containing the parameters.
*/ */
public function __construct($object_model = null) { public function __construct($object = null) {
_deprecated_function(self::class, '2.0.0', esc_html(\WP_Ultimo\Models\Membership::class)); _deprecated_function(self::class, '2.0.0', \WP_Ultimo\Models\Membership::class);
if (is_numeric($object_model)) { if (is_numeric($object)) {
$object_model = wu_get_membership($object_model); $object = wu_get_membership($object);
} }
if ($object_model ) { if ($object) {
$object_model = get_object_vars($object_model); $object = get_object_vars($object);
} }
parent::__construct($object_model); parent::__construct($object);
} }
/** /**

View File

@ -75,7 +75,7 @@ if ( ! class_exists('MUCD_Functions') ) {
return true; return true;
} }
return get_blog_option($blog_id, 'mucd_duplicable', 'no') == 'yes'; return get_blog_option($blog_id, 'mucd_duplicable', 'no') == 'yes';
} }
/** /**

View File

@ -565,8 +565,8 @@ class PayPal_Gateway extends Base_Gateway {
]; ];
$args['PAYMENTREQUEST_0_ITEMAMT'] += $sub_total; $args['PAYMENTREQUEST_0_ITEMAMT'] += $sub_total;
$args['PAYMENTREQUEST_0_TAXAMT'] += $tax_amount; $args['PAYMENTREQUEST_0_TAXAMT'] += $tax_amount;
$args['PAYMENTREQUEST_0_AMT'] = $args['PAYMENTREQUEST_0_AMT'] + $sub_total + $tax_amount; $args['PAYMENTREQUEST_0_AMT'] = $args['PAYMENTREQUEST_0_AMT'] + $sub_total + $tax_amount;
$args = array_merge($args, $product_args); $args = array_merge($args, $product_args);
@ -588,7 +588,7 @@ class PayPal_Gateway extends Base_Gateway {
); );
$args['PAYMENTREQUEST_0_ITEMAMT'] += $discounts_total; $args['PAYMENTREQUEST_0_ITEMAMT'] += $discounts_total;
$args['PAYMENTREQUEST_0_AMT'] += $discounts_total; $args['PAYMENTREQUEST_0_AMT'] += $discounts_total;
++$product_index; ++$product_index;
} }

View File

@ -47,7 +47,8 @@ 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) {
@ -73,7 +74,8 @@ 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) {
@ -97,12 +99,13 @@ 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_value The value to return ibn the case the key does not exist. * @param mixed $default 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_value = null) { public static function get($array_target, $key, $default = null) {
if (is_null($key)) { if (is_null($key)) {
return $array_target; return $array_target;
@ -114,7 +117,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_value; return $default;
} }
$array_target = $array_target[ $segment ]; $array_target = $array_target[ $segment ];
@ -131,7 +134,8 @@ 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,6 +10,7 @@
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
@ -84,7 +85,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;
@ -236,7 +237,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 CPanel_API * @return WU_CPanel
*/ */
public function load_api() { public function load_api() {
@ -292,19 +293,17 @@ 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 void * @return bool
*/ */
public function log_calls($results) { public function log_calls($results) {
if (is_object($results->cpanelresult->data)) { if (is_object($results->cpanelresult->data)) {
wu_log_add('integration-cpanel', $results->cpanelresult->data->reason); return wu_log_add('integration-cpanel', $results->cpanelresult->data->reason);
return;
} elseif ( ! isset($results->cpanelresult->data[0])) { } elseif ( ! isset($results->cpanelresult->data[0])) {
wu_log_add('integration-cpanel', __('Unexpected error ocurred trying to sync domains with CPanel', 'wp-multisite-waas'), LogLevel::ERROR); return wu_log_add('integration-cpanel', __('Unexpected error ocurred trying to sync domains with CPanel', 'wp-multisite-waas'), LogLevel::ERROR);
return;
} }
wu_log_add('integration-cpanel', $results->cpanelresult->data[0]->reason); return wu_log_add('integration-cpanel', $results->cpanelresult->data[0]->reason);
} }
/** /**

View File

@ -312,9 +312,9 @@ class CPanel_API {
} }
$url = $this->get_base_url() . $this->cpsess . '/json-api/cpanel' . $url = $this->get_base_url() . $this->cpsess . '/json-api/cpanel' .
'?cpanel_jsonapi_version=2' . '?cpanel_jsonapi_version=2' .
"&cpanel_jsonapi_func={$function_name}" . "&cpanel_jsonapi_func={$function_name}" .
"&cpanel_jsonapi_module={$module}&" . $parameters; "&cpanel_jsonapi_module={$module}&" . $parameters;
return json_decode((string) $this->request($url, $parameters)); return json_decode((string) $this->request($url, $parameters));
} }

View File

@ -244,39 +244,39 @@ class Payment_List_Table extends Base_List_Table {
public function get_views() { public function get_views() {
return [ return [
'all' => [ 'all' => [
'field' => 'status', 'field' => 'status',
'url' => add_query_arg('status', 'all'), 'url' => add_query_arg('status', 'all'),
'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\Limitable $object_model Model to test. * @param \WP_Ultimo\Models\Trait\Trait_Limitable $object Model to test.
* @return string * @return string
*/ */
public function get_object_type($object_model) { public function get_object_type($object) {
$model = false; $model = false;
if (is_a($object_model, \WP_Ultimo\Models\Site::class)) { if (is_a($object, \WP_Ultimo\Models\Site::class)) {
$model = 'site'; $model = 'site';
} elseif (is_a($object_model, \WP_Ultimo\Models\Membership::class)) { } elseif (is_a($object, WP_Ultimo\Models\Membership::class)) {
$model = 'membership'; $model = 'membership';
} elseif (is_a($object_model, \WP_Ultimo\Models\Product::class)) { } elseif (is_a($object, \WP_Ultimo\Models\Product::class)) {
$model = 'product'; $model = 'product';
} }
return apply_filters('wu_limitations_get_object_type', $model, $object_model); return apply_filters('wu_limitations_get_object_type', $model);
} }
/** /**
@ -251,13 +251,13 @@ 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\Limitable $object_model The model being edited. * @param \WP_Ultimo\Models\Trait\Trait_Limitable $object The model being edited.
* @return array * @return array
*/ */
public function add_limitation_sections($sections, $object_model) { public function add_limitation_sections($sections, $object) {
if ( $this->get_object_type($object_model) === 'site' && $object_model->get_type() !== Site_Type::CUSTOMER_OWNED) { if ($this->get_object_type($object) === 'site' && $object->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_model) !== 'site') { if ($this->get_object_type($object) !== '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_model), 'fields' => $this->get_sites_fields($object),
'v-show' => "get_state_value('product_type', 'none') !== 'service'", 'v-show' => "get_state_value('product_type', 'none') !== 'service'",
'state' => [ 'state' => [
'limit_sites' => $object_model->get_limitations()->sites->is_enabled(), 'limit_sites' => $object->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_model->get_limitations()->visits->is_enabled(), 'limit_visits' => $object->get_limitations()->visits->is_enabled(),
], ],
'fields' => [ 'fields' => [
'modules[visits][enabled]' => [ 'modules[visits][enabled]' => [
@ -313,8 +313,8 @@ class Limitation_Manager {
], ],
]; ];
if ( 'product' !== $object_model->model) { if ('product' !== $object->model) {
$sections['visits']['fields']['modules_visits_overwrite'] = $this->override_notice($object_model->get_limitations(false)->visits->has_own_enabled()); $sections['visits']['fields']['modules_visits_overwrite'] = $this->override_notice($object->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_model->get_limitations()->visits->get_limit(), 'value' => $object->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->model) { if ('product' !== $object->model) {
$sections['visits']['fields']['allowed_visits_overwrite'] = $this->override_notice($object_model->get_limitations(false)->visits->has_own_limit(), ['limit_visits']); $sections['visits']['fields']['allowed_visits_overwrite'] = $this->override_notice($object->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_model) === 'site') { if ($this->get_object_type($object) === '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_model->get_visits_count()), 'display_value' => sprintf('%s visit(s)', $object->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_model->get_limitations()->users->is_enabled(), 'limit_users' => $object->get_limitations()->users->is_enabled(),
], ],
'fields' => [ 'fields' => [
'modules[users][enabled]' => [ 'modules[users][enabled]' => [
@ -374,11 +374,11 @@ class Limitation_Manager {
], ],
]; ];
if ( 'product' !== $object_model->model) { if ('product' !== $object->model) {
$sections['users']['fields']['modules_user_overwrite'] = $this->override_notice($object_model->get_limitations(false)->users->has_own_enabled()); $sections['users']['fields']['modules_user_overwrite'] = $this->override_notice($object->get_limitations(false)->users->has_own_enabled());
} }
$this->register_user_fields($sections, $object_model); $this->register_user_fields($sections, $object);
$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_model->get_limitations()->post_types->is_enabled(), 'limit_post_types' => $object->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->model) { if ('product' !== $object->model) {
$sections['post_types']['fields']['post_quota_overwrite'] = $this->override_notice($object_model->get_limitations(false)->post_types->has_own_enabled()); $sections['post_types']['fields']['post_quota_overwrite'] = $this->override_notice($object->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_model); $this->register_post_type_fields($sections, $object);
$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_model->get_limitations()->disk_space->is_enabled(), 'limit_disk_space' => $object->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->model) { if ('product' !== $object->model) {
$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']['disk_space_modules_overwrite'] = $this->override_notice($object->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_model->get_limitations()->disk_space->get_limit(), 'value' => $object->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->model) { if ('product' !== $object->model) {
$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['limit_disk_space']['fields']['disk_space_override'] = $this->override_notice($object->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_model->get_limitations()->domain_mapping->is_enabled(), 'allow_domain_mapping' => $object->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_model->get_limitations()->domain_mapping->is_enabled(), 'value' => $object->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->model) { if ('product' !== $object->model) {
$sections['custom_domain']['fields']['custom_domain_override'] = $this->override_notice($object_model->get_limitations(false)->domain_mapping->has_own_enabled(), ['allow_domain_mapping']); $sections['custom_domain']['fields']['custom_domain_override'] = $this->override_notice($object->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_model, $sections['allowed_themes']), 'content' => fn() => $this->get_theme_selection_list($object, $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_model), 'content' => fn() => $this->get_plugin_selection_list($object),
], ],
], ],
]; ];
@ -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_model->get_id(), 'id' => $object->get_id(),
'model' => $object_model->model, 'model' => $object->model,
] ]
); );
@ -573,18 +573,18 @@ 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\Limitable $object_model The object being edit. * @param \WP_Ultimo\Models\Trait\Trait_Limitable $object The object being edit.
* @return void * @return void
*/ */
public function register_user_fields(&$sections, $object_model): void { public function register_user_fields(&$sections, $object): 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_model->get_limitations()->users->{$user_role_slug}; $sections['users']['state']['roles'][ $user_role_slug ] = $object->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->model) { if ('product' !== $object->model) {
$sections['users']['fields'][ "override_{$user_role_slug}" ] = $this->override_notice($object_model->get_limitations(false)->users->exists($user_role_slug), ['limit_users']); $sections['users']['fields'][ "override_{$user_role_slug}" ] = $this->override_notice($object->get_limitations(false)->users->exists($user_role_slug), ['limit_users']);
} }
} }
} }
@ -631,18 +631,18 @@ 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\Limitable $object_model The object being edit. * @param \WP_Ultimo\Models\Trait\Trait_Limitable $object The object being edit.
* @return void * @return void
*/ */
public function register_post_type_fields(&$sections, $object_model): void { public function register_post_type_fields(&$sections, $object): 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_model->get_limitations()->post_types->{$post_type_slug}; $sections['post_types']['state']['types'][ $post_type_slug ] = $object->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->model) { if ('product' !== $object->model) {
$sections['post_types']['fields'][ "override_{$post_type_slug}" ] = $this->override_notice( $sections['post_types']['fields'][ "override_{$post_type_slug}" ] = $this->override_notice(
$object_model->get_limitations(false)->post_types->exists($post_type_slug), $object->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\Limitable $object_model The model being edited. * @param \WP_Ultimo\Models\Trait\Trait_Limitable $object The model being edited.
* @return array * @return array
*/ */
protected function get_sites_fields($object_model) { protected function get_sites_fields($object) {
$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_model->get_limitations()->sites->is_enabled(), 'value' => $object->get_limitations()->sites->is_enabled(),
'html_attr' => [ 'html_attr' => [
'v-model' => 'limit_sites', 'v-model' => 'limit_sites',
], ],
], ],
]; ];
if ('product' !== $object_model->model) { if ('product' !== $object->model) {
$fields['sites_overwrite'] = $this->override_notice($object_model->get_limitations(false)->sites->has_own_enabled()); $fields['sites_overwrite'] = $this->override_notice($object->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_model->get_limitations()->sites->get_limit(), 'value' => $object->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->model) { if ('product' !== $object->model) {
$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"]); $fields['sites_overwrite_2'] = $this->override_notice($object->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_model, $this); return apply_filters('wu_limitations_get_sites_fields', $fields, $object, $this);
} }
/** /**
@ -753,10 +753,10 @@ class Limitation_Manager {
* *
* @since 2.0.0 * @since 2.0.0
* *
* @param \WP_Ultimo\Models\Limitable $object_model The model being edited. * @param \WP_Ultimo\Models\Trait\Trait_Limitable $object The model being edited.
* @return string * @return string
*/ */
public function get_plugin_selection_list($object_model) { public function get_plugin_selection_list($object) {
$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_model, 'object' => $object,
] ]
); );
} }
@ -774,8 +774,8 @@ class Limitation_Manager {
* *
* @since 2.0.0 * @since 2.0.0
* *
* @param \WP_Ultimo\Models\Limitable $obj The model being edited. * @param \WP_Ultimo\Models\Traits\Limitable $obj The model being edited.
* @param array $section The section array. * @param array $section The section array.
* @return string * @return string
*/ */
public function get_theme_selection_list($obj, &$section) { public function get_theme_selection_list($obj, &$section) {

View File

@ -9,8 +9,6 @@
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
@ -134,21 +132,22 @@ 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_model = null) { public function __construct($object = null) {
$this->model = sanitize_key((new \ReflectionClass($this))->getShortName()); $this->model = sanitize_key((new \ReflectionClass($this))->getShortName());
if (is_array($object_model)) { if (is_array($object)) {
$object_model = (object) $object_model; $object = (object) $object;
} }
if ( ! is_object($object_model)) { if ( ! is_object($object)) {
return; return;
} }
$this->setup_model($object_model); $this->setup_model($object);
} }
/** /**
@ -183,7 +182,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__, esc_html__('You can only use numeric fields to generate hashes.', 'wp-multisite-waas'), '2.0.0'); _doing_it_wrong(__METHOD__, __('You can only use numeric fields to generate hashes.', 'wp-multisite-waas'), '2.0.0');
return false; return false;
} }
@ -194,21 +193,22 @@ abstract class Base_Model implements \JsonSerializable {
/** /**
* Setup properties. * Setup properties.
* *
* @param object $object_model Row from the database. * @param object $object Row from the database.
* *
* @access private
* @since 2.0.0 * @since 2.0.0
* @return bool * @return bool
*/ */
private function setup_model($object_model) { private function setup_model($object) {
if ( ! is_object($object_model)) { if ( ! is_object($object)) {
return false; return false;
} }
$vars = get_object_vars($object_model); $vars = get_object_vars($object);
$this->attributes($vars); $this->attributes($vars);
return ! empty($this->id); return !empty($this->id);
} }
/** /**
@ -256,7 +256,6 @@ 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,8 +686,8 @@ abstract class Base_Model implements \JsonSerializable {
return false; return false;
} }
// _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);
} }
/** /**
@ -697,14 +696,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_value The default value to be passed. * @param mixed $default 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_value = false, $single = true) { public function get_meta($key, $default = false, $single = true) {
if ( ! $this->is_meta_available()) { if ( ! $this->is_meta_available()) {
return $default_value; return $default;
} }
$meta_type = $this->get_meta_type_name(); $meta_type = $this->get_meta_type_name();
@ -713,7 +712,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_value; return $default;
} }
/** /**
@ -731,7 +730,7 @@ abstract class Base_Model implements \JsonSerializable {
} }
if ( ! is_array($meta)) { if ( ! is_array($meta)) {
_doing_it_wrong(__METHOD__, esc_html__('This method expects an array as argument.', 'wp-multisite-waas'), '2.0.0'); _doing_it_wrong(__METHOD__, __('This method expects an array as argument.', 'wp-multisite-waas'), '2.0.0');
return false; return false;
} }
@ -839,7 +838,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 Base_model * @return Mapping
*/ */
protected static function to_instance($data) { protected static function to_instance($data) {
@ -1039,7 +1038,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 Base_Model * @return \WP_Ultimo\Model\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_model Std object with model parameters. * @param mixed $object Std object with model parameters.
*/ */
public function __construct($object_model = null) { public function __construct($object = null) {
$object_model = (array) $object_model; $object = (array) $object;
if ( ! wu_get_isset($object_model, 'migrated_from_id')) { if ( ! wu_get_isset($object, 'migrated_from_id')) {
unset($object_model['migrated_from_id']); unset($object['migrated_from_id']);
} }
parent::__construct($object_model); parent::__construct($object);
} }
/** /**

View File

@ -25,11 +25,11 @@ class Event extends Base_Model {
const SEVERITY_NEUTRAL = 2; const SEVERITY_NEUTRAL = 2;
const SEVERITY_INFO = 3; const SEVERITY_INFO = 3;
const SEVERITY_WARNING = 4; const SEVERITY_WARNING = 4;
const SEVERITY_FATAL = 5; const SEVERITY_FATAL = 5;
/** /**
* Severity of the problem. * Severity of the problem.

View File

@ -317,11 +317,11 @@ class Membership extends Base_Model {
* *
* @since 2.0.0 * @since 2.0.0
* *
* @param object $object_model Std object with model parameters. * @param object $object Std object with model parameters.
*/ */
public function __construct($object_model = null) { public function __construct($object = null) {
parent::__construct($object_model); parent::__construct($object);
$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 implements Limitable { class Site extends Base_Model {
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 implements Limitable {
* *
* @since 2.0.0 * @since 2.0.0
* *
* @param mixed $object_model Object containing the parameters. * @param mixed $object Object containing the parameters.
*/ */
public function __construct($object_model = null) { public function __construct($object = null) {
parent::__construct($object_model); parent::__construct($object);
if (is_array($object_model)) { if (is_array($object)) {
$object_model = (object) $object_model; $object = (object) $object;
} }
$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 implements Limitable {
/* /*
* 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_model) && isset($object_model->site_path)) { if ( ! $this->path && is_object($object) && isset($object->site_path)) {
$this->path = $object_model->site_path; $this->path = $object->site_path;
} }
$object_model = (object) $object_model; $object = (object) $object;
} }
/** /**

View File

@ -1,99 +0,0 @@
<?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,12 +26,26 @@ trait Limitable {
protected $_limitations = []; protected $_limitations = [];
/** /**
* @inheritDoc * 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
*/ */
abstract public function limitations_to_merge(); abstract public function limitations_to_merge();
/** /**
* @inheritdoc * 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) { public function get_limitations($waterfall = true, $skip_self = false) {
@ -90,7 +104,10 @@ trait Limitable {
} }
/** /**
* @inheritdoc * Checks if this site has limitations or not.
*
* @since 2.0.0
* @return boolean
*/ */
public function has_limitations() { public function has_limitations() {
@ -174,7 +191,15 @@ trait Limitable {
} }
/** /**
* @inheritdoc * 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 { public function handle_limitations(): void {
/* /*
@ -222,7 +247,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 ($this->get_type() !== 'plan') { } elseif ('product' === $this->model && $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;
@ -232,7 +257,10 @@ trait Limitable {
} }
/** /**
* @inheritdoc * Returns the list of product slugs associated with this model.
*
* @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
*/ */
private static $limitations_cache = []; 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 object $instance; public static $instance;
/** /**
* Returns the instance of WP_Ultimo * Returns the instance of WP_Ultimo
* *
* @return object * @return object
*/ */
public static function get_instance(): object { public static function get_instance() {
if ( ! isset(static::$instance) || ! static::$instance instanceof static) { if ( ! 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(): bool { public function has_parents() {
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-14T17:47:37+00:00\n" "POT-Creation-Date: 2025-04-07T17:38:26+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:130 #: views/base/customers/grid-item.php:118
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:180 #: inc/class-scripts.php:177
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:181 #: inc/class-scripts.php:178
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:611 #: inc/models/class-base-model.php:610
#: 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:277 #: inc/class-scripts.php:274
msgid "d/m/Y" msgid "d/m/Y"
msgstr "" msgstr ""
#: inc/class-scripts.php:287 #: inc/class-scripts.php:284
msgid "in %s" msgid "in %s"
msgstr "" msgstr ""
#. translators: %s a unit of time. #. translators: %s a unit of time.
#: inc/class-scripts.php:288 #: inc/class-scripts.php:285
#: 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:289 #: inc/class-scripts.php:286
msgid "a few seconds" msgid "a few seconds"
msgstr "" msgstr ""
#: inc/class-scripts.php:290 #: inc/class-scripts.php:287
msgid "%d seconds" msgid "%d seconds"
msgstr "" msgstr ""
#: inc/class-scripts.php:291 #: inc/class-scripts.php:288
msgid "a minute" msgid "a minute"
msgstr "" msgstr ""
#: inc/class-scripts.php:292 #: inc/class-scripts.php:289
msgid "%d minutes" msgid "%d minutes"
msgstr "" msgstr ""
#: inc/class-scripts.php:293 #: inc/class-scripts.php:290
msgid "an hour" msgid "an hour"
msgstr "" msgstr ""
#: inc/class-scripts.php:294 #: inc/class-scripts.php:291
msgid "%d hours" msgid "%d hours"
msgstr "" msgstr ""
#: inc/class-scripts.php:295 #: inc/class-scripts.php:292
msgid "a day" msgid "a day"
msgstr "" msgstr ""
#: inc/class-scripts.php:296 #: inc/class-scripts.php:293
msgid "%d days" msgid "%d days"
msgstr "" msgstr ""
#: inc/class-scripts.php:297 #: inc/class-scripts.php:294
msgid "a week" msgid "a week"
msgstr "" msgstr ""
#: inc/class-scripts.php:298 #: inc/class-scripts.php:295
msgid "%d weeks" msgid "%d weeks"
msgstr "" msgstr ""
#: inc/class-scripts.php:299 #: inc/class-scripts.php:296
msgid "a month" msgid "a month"
msgstr "" msgstr ""
#: inc/class-scripts.php:300 #: inc/class-scripts.php:297
msgid "%d months" msgid "%d months"
msgstr "" msgstr ""
#: inc/class-scripts.php:301 #: inc/class-scripts.php:298
msgid "a year" msgid "a year"
msgstr "" msgstr ""
#: inc/class-scripts.php:302 #: inc/class-scripts.php:299
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:276 #: inc/class-sunrise.php:274
msgid "Sunrise copy failed: %s" msgid "Sunrise copy failed: %s"
msgstr "" msgstr ""
#: inc/class-sunrise.php:279 #: inc/class-sunrise.php:277
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:114 #: inc/integrations/host-providers/class-cpanel-host-provider.php:115
msgid "cPanel Username" msgid "cPanel Username"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:115 #: inc/integrations/host-providers/class-cpanel-host-provider.php:116
msgid "e.g. username" msgid "e.g. username"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:119 #: inc/integrations/host-providers/class-cpanel-host-provider.php:120
msgid "cPanel Password" msgid "cPanel Password"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:120 #: inc/integrations/host-providers/class-cpanel-host-provider.php:121
msgid "password" msgid "password"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:123 #: inc/integrations/host-providers/class-cpanel-host-provider.php:124
msgid "cPanel Host" msgid "cPanel Host"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:124 #: inc/integrations/host-providers/class-cpanel-host-provider.php:125
msgid "e.g. yourdomain.com" msgid "e.g. yourdomain.com"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:127 #: inc/integrations/host-providers/class-cpanel-host-provider.php:128
msgid "cPanel Port" msgid "cPanel Port"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:128 #: inc/integrations/host-providers/class-cpanel-host-provider.php:129
msgid "Defaults to 2083" msgid "Defaults to 2083"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:132 #: inc/integrations/host-providers/class-cpanel-host-provider.php:133
msgid "Root Directory" msgid "Root Directory"
msgstr "" msgstr ""
#: inc/integrations/host-providers/class-cpanel-host-provider.php:133 #: inc/integrations/host-providers/class-cpanel-host-provider.php:134
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:318 #: inc/integrations/host-providers/class-cpanel-host-provider.php:317
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:363 #: inc/integrations/host-providers/class-cpanel-host-provider.php:362
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:369 #: inc/integrations/host-providers/class-cpanel-host-provider.php:368
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:127 #: views/base/customers/grid-item.php:115
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:107 #: views/base/customers/grid-item.php:95
#: 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:76 #: views/base/customers/grid-item.php:64
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:186 #: inc/models/class-base-model.php:185
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:734 #: inc/models/class-base-model.php:733
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:47 #: views/settings/fields/field-image.php:50
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:57 #: views/base/customers/grid-item.php:45
msgid "No email address" msgid "No email address"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:62 #: views/base/customers/grid-item.php:50
msgid "VIP Customer" msgid "VIP Customer"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:62 #: views/base/customers/grid-item.php:50
msgid "Regular Customer" msgid "Regular Customer"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:71 #: views/base/customers/grid-item.php:59
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:80 #: views/base/customers/grid-item.php:68
msgid "Never logged in" msgid "Never logged in"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:87 #: views/base/customers/grid-item.php:75
msgid "Customer Since:" msgid "Customer Since:"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:96 #: views/base/customers/grid-item.php:84
msgid "Memberships:" msgid "Memberships:"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:118 #: views/base/customers/grid-item.php:106
msgid "Actions:" msgid "Actions:"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:146 #: views/base/customers/grid-item.php:134
msgid "Select Customer" msgid "Select Customer"
msgstr "" msgstr ""
#: views/base/customers/grid-item.php:150 #: views/base/customers/grid-item.php:138
#: 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 -o --no-dev", "prebuild": "composer install --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: 0 level: max
inferPrivatePropertyTypeFromConstructor: true inferPrivatePropertyTypeFromConstructor: true
checkMissingIterableValueType: false
treatPhpDocTypesAsCertain: false treatPhpDocTypesAsCertain: false
paths: paths:
- ./views - /
- ./inc
- ./wp-multisite-waas.php
ignoreErrors: ignoreErrors:
- # Uses func_get_args()
message: '#Variable \$.* might not be defined.#' - '/^Function apply_filters(_ref_array)? invoked with [34567] parameters, 2 required\.$/'
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.2 Tested up to: 6.7.1
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,20 +84,6 @@ 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,19 +18,21 @@ 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>>
*/
public function getNodeTypes(): array
{
return [Equal::class, NotEqual::class, Identical::class, NotIdentical::class];
}
/** /**
* @return array<class-string<Node>> * @param \PhpParser\Node\Stmt\Class_ $node
*/ */
public function getNodeTypes(): array { public function refactor(Node $node): ?Node
return [Equal::class, NotEqual::class, Identical::class, NotIdentical::class]; {
}
/**
* @param \PhpParser\Node\Stmt\Class_ $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 ||
@ -45,6 +47,6 @@ final class YodaConditionsRector extends AbstractRector {
$this->mirrorComments($node->right, $node->left); $this->mirrorComments($node->right, $node->left);
[$node->left, $node->right] = [$node->right, $node->left]; [$node->left, $node->right] = [$node->right, $node->left];
} }
return $node; return $node;
} }
} }

View File

@ -6,20 +6,23 @@ 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()
*/
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}
/** public static function provideData(): \Iterator
* @dataProvider provideData() {
*/ return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
public function test(string $filePath): void { }
$this->doTestFile($filePath);
}
public static function provideData(): \Iterator { public function provideConfigFilePath(): string
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); {
} return __DIR__ . '/config/configured_rule.php';
}
public function provideConfigFilePath(): string {
return __DIR__ . '/config/configured_rule.php';
}
} }

View File

@ -5,5 +5,5 @@ declare(strict_types=1);
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig): void { return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(\Utils\Rector\Rector\YodaConditionsRector::class); $rectorConfig->rule(\Utils\Rector\Rector\YodaConditionsRector::class);
}; };

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,19 +11,7 @@
<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( style="opacity: 0.15; background-image: url(<?php echo esc_url(get_avatar_url($item->get_user_id(), array('default' => 'identicon', 'size' => 320))); ?>)"
<?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,12 +11,14 @@
wp_enqueue_media(); wp_enqueue_media();
wp_enqueue_script('media'); wp_enqueue_script('media');
wp_enqueue_script('wu-field-button-upload', wu_get_asset('wu-field-image.js', 'js'), [], wu_get_version(), true); $suffix = WU_Scripts()->suffix();
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 esc_attr($field_slug); ?>"><?php echo esc_html($field['title']); ?></label></th> <th scope="row"><label for="<?php echo $field_slug; ?>"><?php echo $field['title']; ?></label></th>
<td> <td>
<?php <?php
@ -27,32 +29,33 @@ wp_enqueue_script('wu-field-button-upload', wu_get_asset('wu-field-image.js', 'j
} }
if ( $image_url ) { if ( $image_url ) {
$image = '<img id="%s" src="%s" alt="%s" style="width:%s; height:auto">';
printf( printf(
'<img id="%s" src="%s" alt="%s" style="width:%s; height:auto">', $image,
esc_attr($field_slug . '-preview'), $field_slug . '-preview',
esc_attr($image_url), $image_url,
esc_attr(get_bloginfo('name')), get_bloginfo('name'),
esc_attr($field['width'] . 'px') $field['width'] . 'px'
); );
} }
?> ?>
<br> <br>
<a href="#" class="button wu-field-button-upload" data-target="<?php echo esc_attr($field_slug); ?>"> <a href="#" class="button wu-field-button-upload" data-target="<?php echo $field_slug; ?>">
<?php echo esc_html($field['button']); ?> <?php echo $field['button']; ?>
</a> </a>
<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); ?>"> <a data-default="<?php echo $field['default']; ?>" href="#" class="button wu-field-button-upload-remove" data-target="<?php echo $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 esc_attr($field_slug); ?>-desc"> <p class="description" id="<?php echo $field_slug; ?>-desc">
<?php echo esc_html($field['desc']); ?> <?php echo $field['desc']; ?>
</p> </p>
<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']); ?>"> <input type="hidden" name="<?php echo $field_slug; ?>" id="<?php echo $field_slug; ?>" value="<?php echo 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 echo wp_kses(__('This integration will <strong>not</strong>:', 'wp-multisite-waas'), ['strong' => []]); ?> <?php esc_html_e('This integration will <strong>not</strong>:', 'wp-multisite-waas'); ?>
</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

@ -6,23 +6,23 @@
*/ */
?> ?>
<article id="fullArticle"> <article id="fullArticle">
<h1 id="step-1-getting-a-serverpilot-api-key" class="intercom-align-left" data-post-processed="true">Step 1: Getting the API Key and the Client ID</h1> <h1 id="step-1-getting-a-serverpilot-api-key" class="intercom-align-left" data-post-processed="true">Step 1: Getting the API Key and the Client ID</h1>
<p class="intercom-align-left">In Your ServerPilot admin panel, first go to the Account Settings page and navigate to the API link, there you can get the API Key and Client ID (if the API Key field is empty, click the New API Key button). <b>Paste those values somewhere as we'll need them in a later step.</b> </p> <p class="intercom-align-left">In Your ServerPilot admin panel, first go to the Account Settings page and navigate to the API link, there you can get the API Key and Client ID (if the API Key field is empty, click the New API Key button). <b>Paste those values somewhere as we'll need them in a later step.</b> </p>
<div class="intercom-container intercom-align-left"> <div class="intercom-container intercom-align-left">
<img class="wu-w-full" src="<?php echo esc_url(wu_get_asset('serverpilot-1.webp', 'img/hosts')); ?>"> <img class="wu-w-full" src="<?php echo esc_url(wu_get_asset('serverpilot-1.webp', 'img/hosts')); ?>">
</div> </div>
<h1 id="step-2-get-the-server-id" class="intercom-align-left" data-post-processed="true">Step 2: Getting the App ID</h1> <h1 id="step-2-get-the-server-id" class="intercom-align-left" data-post-processed="true">Step 2: Getting the App ID</h1>
<p class="intercom-align-left">Next, well need to get the App ID for your WordPress site. To find that ID, navigate to your apps manage page:</p> <p class="intercom-align-left">Next, well need to get the App ID for your WordPress site. To find that ID, navigate to your apps manage page:</p>
<div class="intercom-container intercom-align-left"> <div class="intercom-container intercom-align-left">
<img class="wu-w-full" src="<?php echo esc_url(wu_get_asset('serverpilot-2.webp', 'img/hosts')); ?>"> <img class="wu-w-full" src="<?php echo esc_url(wu_get_asset('serverpilot-2.webp', 'img/hosts')); ?>">
</div> </div>
<p class="intercom-align-left">Then, take a look at the URL at the top of your browser. The APP ID is the portion between the app/ and the /settings segments of the URL.</p> <p class="intercom-align-left">Then, take a look at the URL at the top of your browser. The APP ID is the portion between the app/ and the /settings segments of the URL.</p>
<div class="intercom-container intercom-align-left"> <div class="intercom-container intercom-align-left">
<img class="wu-w-full" src="<?php echo esc_url(wu_get_asset('serverpilot-3.webp', 'img/hosts')); ?>"> <img class="wu-w-full" src="<?php echo esc_url(wu_get_asset('serverpilot-3.webp', 'img/hosts')); ?>">
</div> </div>
<p class="intercom-align-left">After this you can proceed to the next integration step where you can paste these values in the related fields.</p> <p class="intercom-align-left">After this you can proceed to the next integration step where you can paste these values in the related fields.</p>
</article> </article>

View File

@ -6,37 +6,37 @@
*/ */
?> ?>
<h1> <h1>
<?php echo esc_html($title); ?> <?php echo esc_html($title); ?>
</h1> </h1>
<?php if ($description) : ?> <?php if ($description) : ?>
<p class="wu-text-lg wu-text-gray-600 wu-mt-4 wu-mb-0"> <p class="wu-text-lg wu-text-gray-600 wu-mt-4 wu-mb-0">
<?php echo esc_html($description); ?> <?php echo esc_html($description); ?>
</p> </p>
<?php endif; ?> <?php endif; ?>
<div class="wu-bg-white wu-p-4 wu--mx-5"> <div class="wu-bg-white wu-p-4 wu--mx-5">
<?php echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> <?php echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div> </div>
<!-- Submit Box --> <!-- Submit Box -->
<div class="wu-flex wu-justify-between wu-bg-gray-100 wu--m-in wu-mt-4 wu-p-4 wu-overflow-hidden wu-border-t wu-border-solid wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300"> <div class="wu-flex wu-justify-between wu-bg-gray-100 wu--m-in wu-mt-4 wu-p-4 wu-overflow-hidden wu-border-t wu-border-solid wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300">
<?php if ($back) : ?> <?php if ($back) : ?>
<a href="<?php echo esc_url($page->get_prev_section_link()); ?>" class="wu-self-center button button-large wu-float-left"> <a href="<?php echo esc_url($page->get_prev_section_link()); ?>" class="wu-self-center button button-large wu-float-left">
<?php echo esc_html($back_label); ?> <?php echo esc_html($back_label); ?>
</a> </a>
<?php endif; ?> <?php endif; ?>
<div class="wu-text-right wu-relative wu-w-full"> <div class="wu-text-right wu-relative wu-w-full">
<?php if ($skip) : ?> <?php if ($skip) : ?>
<a href="<?php echo esc_url($page->get_next_section_link()); ?>" class="wu-skip-button button button-large"> <a href="<?php echo esc_url($page->get_next_section_link()); ?>" class="wu-skip-button button button-large">
<?php echo esc_html($skip_label); ?> <?php echo esc_html($skip_label); ?>
</a> </a>
<?php endif; ?> <?php endif; ?>
<?php if ($next) : ?> <?php if ($next) : ?>
<button name="next" value="1" class="wu-next-button button button-primary button-large wu-ml-2"> <button name="next" value="1" class="wu-next-button button button-primary button-large wu-ml-2">
<?php echo esc_html($next_label); ?> <?php echo esc_html($next_label); ?>
</button> </button>
<?php endif; ?> <?php endif; ?>
</div> </div>
</div> </div>
<!-- End Submit Box --> <!-- End Submit Box -->

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.4.0 * Version: 2.3.4
* 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 and WP Multisite Community * @author Arindo Duque and NextPress
* @category Core * @category Core
* @package WP_Ultimo * @package WP_Ultimo
* @version 2.4.0 * @version 2.3.4
*/ */
// 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 WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid function WP_Ultimo() { // phpcs:ignore
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();