Initial Commit
This commit is contained in:
190
inc/helpers/class-arr.php
Normal file
190
inc/helpers/class-arr.php
Normal file
@ -0,0 +1,190 @@
|
||||
<?php
|
||||
/**
|
||||
* Array Helpers
|
||||
*
|
||||
* Heavily inspired on Laravel's Arr helper class and Lodash's PHP implementation.
|
||||
*
|
||||
* @see https://github.com/laravel/framework/blob/8.x/src/Illuminate/Collections/Arr.php
|
||||
* @see https://github.com/me-io/php-lodash/blob/master/src/Traits/Collections.php
|
||||
*
|
||||
* @package WP_Ultimo\Helpers
|
||||
* @since 2.0.11
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Helper Array class.
|
||||
*
|
||||
* @since 2.0.11
|
||||
*/
|
||||
class Arr {
|
||||
|
||||
/**
|
||||
* Returns all results.
|
||||
*/
|
||||
const RESULTS_ALL = 0;
|
||||
|
||||
/**
|
||||
* Return only the first result.
|
||||
*/
|
||||
const RESULTS_FIRST = 1;
|
||||
|
||||
/**
|
||||
* Result only the last result.
|
||||
*/
|
||||
const RESULTS_LAST = 2;
|
||||
|
||||
/**
|
||||
* Filter an array by property or key.
|
||||
*
|
||||
* @since 2.0.11
|
||||
*
|
||||
* @param array $array The array to filter.
|
||||
* @param string $property The property to filter by. Dot notation is supported.
|
||||
* @param mixed $expected_value The expected value to filter by.
|
||||
* @param integer $flag The flag determining the return type.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function filter_by_property($array, $property, $expected_value, $flag = 0) {
|
||||
|
||||
$result = Arr::filter($array, function($value) use ($property, $expected_value) {
|
||||
|
||||
return Arr::get($value, $property, null) == $expected_value; // phpcs:ignore
|
||||
|
||||
});
|
||||
|
||||
if ($flag) {
|
||||
|
||||
$result = $flag === Arr::RESULTS_FIRST ? reset($result) : end($result);
|
||||
|
||||
} // end if;
|
||||
|
||||
return $result;
|
||||
|
||||
} // end filter_by_property;
|
||||
|
||||
/**
|
||||
* Filters an array using a callback.
|
||||
*
|
||||
* @since 2.0.11
|
||||
*
|
||||
* @param array $array The array to search inside.
|
||||
* @param callable $closure The closure function to call.
|
||||
* @return array
|
||||
*/
|
||||
public static function filter($array, $closure) {
|
||||
|
||||
if ($closure) {
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
|
||||
if (call_user_func($closure, $value, $key)) {
|
||||
|
||||
$result[] = $value;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
return $result;
|
||||
|
||||
} // end if;
|
||||
|
||||
return array_filter($array);
|
||||
|
||||
} // end filter;
|
||||
|
||||
/**
|
||||
* Get a nested value inside an array. Dot notation is supported.
|
||||
*
|
||||
* @since 2.0.11
|
||||
*
|
||||
* @param array $array The array to get the value from.
|
||||
* @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.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get($array, $key, $default = null) {
|
||||
|
||||
if (is_null($key)) {
|
||||
|
||||
return $array;
|
||||
|
||||
} // end if;
|
||||
|
||||
if (isset($array[$key])) {
|
||||
|
||||
return $array[$key];
|
||||
|
||||
} // end if;
|
||||
|
||||
foreach (explode('.', $key) as $segment) {
|
||||
|
||||
if (!is_array($array) || !array_key_exists($segment, $array)) {
|
||||
|
||||
return $default;
|
||||
|
||||
} // end if;
|
||||
|
||||
$array = $array[$segment];
|
||||
|
||||
} // end foreach;
|
||||
|
||||
return $array;
|
||||
|
||||
} // end get;
|
||||
|
||||
/**
|
||||
* Set a nested value inside an array. Dot notation is supported.
|
||||
*
|
||||
* @since 2.0.11
|
||||
*
|
||||
* @param array $array The array to modify.
|
||||
* @param string $key The array key to set. Supports dot notation.
|
||||
* @param mixed $value The value to set.
|
||||
* @return array
|
||||
*/
|
||||
public static function set(&$array, $key, $value) {
|
||||
|
||||
if (is_null($key)) {
|
||||
|
||||
return $array = $value; // phpcs:ignore
|
||||
|
||||
} // end if;
|
||||
|
||||
$keys = explode('.', $key);
|
||||
|
||||
while (count($keys) > 1) {
|
||||
|
||||
$key = array_shift($keys);
|
||||
|
||||
if (!isset($array[$key]) || !is_array($array[$key])) {
|
||||
|
||||
$array[$key] = array();
|
||||
|
||||
} // end if;
|
||||
|
||||
$array =& $array[$key];
|
||||
|
||||
} // end while;
|
||||
|
||||
$array[array_shift($keys)] = $value;
|
||||
|
||||
return $array;
|
||||
|
||||
} // end set;
|
||||
|
||||
/**
|
||||
* Static class only.
|
||||
*
|
||||
* @since 2.0.11
|
||||
*/
|
||||
private function __construct() {} // end __construct;
|
||||
|
||||
} // end class Arr;
|
68
inc/helpers/class-hash.php
Normal file
68
inc/helpers/class-hash.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Handles hashing to encode ids and prevent spoofing due to auto-increments.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helper
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers;
|
||||
|
||||
use WP_Ultimo\Dependencies\Hashids\Hashids;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Handles hashing to encode ids and prevent spoofing due to auto-increments.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Hash {
|
||||
|
||||
/**
|
||||
* Hash length.
|
||||
*/
|
||||
const LENGTH = 10;
|
||||
|
||||
/**
|
||||
* Static-only class.
|
||||
*/
|
||||
private function __construct() {} // end __construct;
|
||||
|
||||
/**
|
||||
* Encodes a number or ID. Do not use to encode strings.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param integer $number Number to encode.
|
||||
* @param string $group Hash group. Used to increase entropy.
|
||||
* @return string
|
||||
*/
|
||||
public static function encode($number, $group = 'wp-ultimo') {
|
||||
|
||||
$hasher = new Hashids($group, self::LENGTH, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890');
|
||||
|
||||
return $hasher->encode($number);
|
||||
|
||||
} // end encode;
|
||||
|
||||
/**
|
||||
* Decodes a hash back into an integer.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $hash Hash to decode.
|
||||
* @param string $group Hash group. Used to increase entropy.
|
||||
* @return int
|
||||
*/
|
||||
public static function decode($hash, $group = 'wp-ultimo') {
|
||||
|
||||
$hasher = new Hashids($group, 10, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890');
|
||||
|
||||
return current($hasher->decode($hash));
|
||||
|
||||
} // end decode;
|
||||
|
||||
} // end class Hash;
|
141
inc/helpers/class-screenshot.php
Normal file
141
inc/helpers/class-screenshot.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* Takes screenshots from websites.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helper
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers;
|
||||
|
||||
use WP_Ultimo\Dependencies\Psr\Log\LogLevel;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Takes screenshots from websites.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Screenshot {
|
||||
|
||||
/**
|
||||
* Returns the api link for the screenshot.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $domain Original site domain.
|
||||
*/
|
||||
public static function api_url($domain): string {
|
||||
|
||||
$domain = esc_url($domain);
|
||||
|
||||
$url = wu_with_license_key(sprintf('https://api.wpultimo.com/screenshot?url=%s', $domain));
|
||||
|
||||
return $url . '&ext=.png';
|
||||
|
||||
} // end api_url;
|
||||
/**
|
||||
* Takes in a URL and creates it as an attachment.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $url Image URL to download.
|
||||
* @return string|false
|
||||
*/
|
||||
public static function take_screenshot($url) {
|
||||
|
||||
$url = self::api_url($url);
|
||||
|
||||
return self::save_image_from_url($url);
|
||||
|
||||
} // end take_screenshot;
|
||||
/**
|
||||
* Downloads the image from the URL.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $url Image URL to download.
|
||||
* @return int|false
|
||||
*/
|
||||
public static function save_image_from_url($url) {
|
||||
|
||||
// translators: %s is the API URL.
|
||||
$log_prefix = sprintf(__('Downloading image from "%s":'), $url) . ' ';
|
||||
|
||||
$response = wp_remote_get($url, array(
|
||||
'timeout' => 50,
|
||||
));
|
||||
|
||||
if (wp_remote_retrieve_response_code($response) !== 200) {
|
||||
|
||||
wu_log_add('screenshot-generator', $log_prefix . wp_remote_retrieve_response_message($response), LogLevel::ERROR);
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
|
||||
wu_log_add('screenshot-generator', $log_prefix . $response->get_error_message(), LogLevel::ERROR);
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
/*
|
||||
* Check if the results contain a PNG header.
|
||||
*/
|
||||
if (strncmp($response['body'], "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", strlen("\x89\x50\x4e\x47\x0d\x0a\x1a\x0a")) !== 0) {
|
||||
|
||||
wu_log_add('screenshot-generator', $log_prefix . __('Result is not a PNG file.', 'wp-ultimo'), LogLevel::ERROR);
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
$upload = wp_upload_bits('screenshot-' . gmdate('Y-m-d-H-i-s') . '.png', null, $response['body']);
|
||||
|
||||
if (!empty($upload['error'])) {
|
||||
|
||||
wu_log_add('screenshot-generator', $log_prefix . json_encode($upload['error']), LogLevel::ERROR);
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
$file_path = $upload['file'];
|
||||
$file_name = basename($file_path);
|
||||
$file_type = wp_check_filetype($file_name, null);
|
||||
$attachment_title = sanitize_file_name(pathinfo($file_name, PATHINFO_FILENAME));
|
||||
$wp_upload_dir = wp_upload_dir();
|
||||
|
||||
$post_info = array(
|
||||
'guid' => $wp_upload_dir['url'] . '/' . $file_name,
|
||||
'post_mime_type' => $file_type['type'],
|
||||
'post_title' => $attachment_title,
|
||||
'post_content' => '',
|
||||
'post_status' => 'inherit',
|
||||
);
|
||||
|
||||
// Create the attachment
|
||||
$attach_id = wp_insert_attachment($post_info, $file_path);
|
||||
|
||||
// Include image.php
|
||||
require_once(ABSPATH . 'wp-admin/includes/image.php');
|
||||
|
||||
// Define attachment metadata
|
||||
$attach_data = wp_generate_attachment_metadata($attach_id, $file_path);
|
||||
|
||||
// Assign metadata to attachment
|
||||
wp_update_attachment_metadata($attach_id, $attach_data);
|
||||
|
||||
wu_log_add('screenshot-generator', $log_prefix . __('Success!', 'wp-ultimo'));
|
||||
|
||||
return $attach_id;
|
||||
|
||||
} // end save_image_from_url;
|
||||
|
||||
} // end class Screenshot;
|
229
inc/helpers/class-sender.php
Normal file
229
inc/helpers/class-sender.php
Normal file
@ -0,0 +1,229 @@
|
||||
<?php
|
||||
/**
|
||||
* Handles the action o send a admin notice to a sub-site or a email.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helper
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers;
|
||||
|
||||
use WP_Ultimo\Models\Email_Template;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Handles hashing to encode ids and prevent spoofing due to auto-increments.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Sender {
|
||||
|
||||
/**
|
||||
* Parse attributes against the defaults.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $args The args passed.
|
||||
* @return array
|
||||
*/
|
||||
public static function parse_args($args = array()) {
|
||||
|
||||
$default_args = array(
|
||||
'from' => array(
|
||||
'name' => wu_get_setting('from_name'),
|
||||
'email' => wu_get_setting('from_email'),
|
||||
),
|
||||
'content' => '',
|
||||
'subject' => '',
|
||||
'bcc' => array(),
|
||||
'payload' => array(),
|
||||
'attachments' => array(),
|
||||
'style' => wu_get_setting('email_template_type', 'html'),
|
||||
);
|
||||
|
||||
$args = wp_parse_args($args, $default_args);
|
||||
|
||||
return $args;
|
||||
|
||||
} // end parse_args;
|
||||
|
||||
/**
|
||||
* Send an email to one or more users.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $from From whom will be send this mail.
|
||||
* @param string $to To who this email is.
|
||||
* @param array $args With content, subject and other arguments, has shortcodes, mail type.
|
||||
* @return array With the send response.
|
||||
*/
|
||||
public static function send_mail($from = array(), $to = array(), $args = array()) {
|
||||
|
||||
if (!$from) {
|
||||
|
||||
$from = array(
|
||||
'email' => wu_get_setting('from_email'),
|
||||
'name' => wu_get_setting('from_name'),
|
||||
);
|
||||
|
||||
} // end if;
|
||||
|
||||
$args = Sender::parse_args($args);
|
||||
|
||||
/*
|
||||
* First, replace shortcodes.
|
||||
*/
|
||||
$payload = wu_get_isset($args, 'payload', array());
|
||||
|
||||
$subject = Sender::process_shortcodes(wu_get_isset($args, 'subject', ''), $payload);
|
||||
|
||||
$content = Sender::process_shortcodes(wu_get_isset($args, 'content', ''), $payload);
|
||||
|
||||
/*
|
||||
* Content type and template
|
||||
*/
|
||||
$headers = array();
|
||||
|
||||
if (wu_get_isset($args, 'style', 'html') === 'html') {
|
||||
|
||||
$headers[] = 'Content-Type: text/html; charset=UTF-8';
|
||||
|
||||
$default_settings = \WP_Ultimo\Admin_Pages\Email_Template_Customize_Admin_Page::get_default_settings();
|
||||
|
||||
$template_settings = wu_get_option('email_template', $default_settings);
|
||||
|
||||
$template_settings = wp_parse_args($template_settings, $default_settings);
|
||||
|
||||
$template = wu_get_template_contents('broadcast/emails/base', array(
|
||||
'site_name' => get_network_option(null, 'site_name'),
|
||||
'site_url' => get_site_url(wu_get_main_site_id()),
|
||||
'logo_url' => wu_get_network_logo(),
|
||||
'is_editor' => false,
|
||||
'subject' => $subject,
|
||||
'content' => $content,
|
||||
'template_settings' => $template_settings,
|
||||
));
|
||||
|
||||
} else {
|
||||
|
||||
$headers[] = 'Content-Type: text/html; charset=UTF-8';
|
||||
|
||||
$template = nl2br(strip_tags($content, '<p><a><br>')); // by default, set the plain email content.
|
||||
|
||||
} // end if;
|
||||
|
||||
$bcc = '';
|
||||
|
||||
/*
|
||||
* Build the recipients list.
|
||||
*/
|
||||
if (count($to) > 1) {
|
||||
|
||||
$to = array_map(fn($item) => wu_format_email_string(wu_get_isset($item, 'email'), wu_get_isset($item, 'name')), $to);
|
||||
|
||||
/*
|
||||
* Decide which strategy to use, BCC or multiple "to"s.
|
||||
*
|
||||
* By default, we use multiple tos, but that can be changed to bcc.
|
||||
* Depending on the SMTP solution being used, that can make a difference on the number of
|
||||
* emails sent out.
|
||||
*/
|
||||
if (apply_filters('wu_sender_recipients_strategy', 'bcc') === 'bcc') {
|
||||
|
||||
$main_to = $to[0];
|
||||
|
||||
unset($to[0]);
|
||||
|
||||
$bcc_array = array_map(function($item) {
|
||||
|
||||
$email = is_array($item) ? $item['email'] : $item;
|
||||
|
||||
preg_match('/<([^>]+)>/', $email, $matches);
|
||||
|
||||
return !empty($matches[1]) ? $matches[1] : $email;
|
||||
|
||||
}, $to);
|
||||
|
||||
$bcc = implode(', ', array_filter($bcc_array));
|
||||
|
||||
$headers[] = "Bcc: $bcc";
|
||||
|
||||
$to = $main_to;
|
||||
|
||||
} // end if;
|
||||
|
||||
} else {
|
||||
|
||||
$to = array(
|
||||
wu_format_email_string(wu_get_isset($to[0], 'email'), wu_get_isset($to[0], 'name'))
|
||||
);
|
||||
|
||||
} // end if;
|
||||
|
||||
/*
|
||||
* Build From
|
||||
*/
|
||||
$from_email = wu_get_isset($from, 'email', wu_get_setting('from_email'));
|
||||
$from_name = wu_get_isset($from, 'name');
|
||||
$from_string = wu_format_email_string($from_email, $from_name);
|
||||
|
||||
$headers[] = "From: {$from_string}";
|
||||
|
||||
$attachments = $args['attachments'];
|
||||
|
||||
// if (isset($args['schedule'])) {
|
||||
|
||||
// wu_schedule_single_action($args['schedule'], 'wu_send_schedule_system_email', array(
|
||||
// 'to' => $to,
|
||||
// 'subject' => $subject,
|
||||
// 'template' => $template,
|
||||
// 'headers' => $headers,
|
||||
// 'attachments' => $attachments,
|
||||
// ));
|
||||
|
||||
// } // end if;
|
||||
|
||||
// Send the actual email
|
||||
return wp_mail($to, $subject, $template, $headers, $attachments);
|
||||
|
||||
} // end send_mail;
|
||||
|
||||
/**
|
||||
* Change the shortcodes for values in the content.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $content Content to be rendered.
|
||||
* @param array $payload Payload with the values to render in the content.
|
||||
* @return string
|
||||
*/
|
||||
public static function process_shortcodes($content, $payload = array()) {
|
||||
|
||||
if (empty($payload)) {
|
||||
|
||||
return $content;
|
||||
|
||||
} // end if;
|
||||
|
||||
$match = array();
|
||||
|
||||
preg_match_all('/{{(.*?)}}/', $content, $match);
|
||||
|
||||
$shortcodes = shortcode_atts(array_flip($match[1]), $payload);
|
||||
|
||||
foreach ($shortcodes as $shortcode_key => $shortcode_value) {
|
||||
|
||||
$shortcode_str = '{{' . $shortcode_key . '}}';
|
||||
|
||||
$content = str_replace($shortcode_str, nl2br((string) $shortcode_value), $content);
|
||||
|
||||
} // end foreach;
|
||||
|
||||
return $content;
|
||||
|
||||
} // end process_shortcodes;
|
||||
|
||||
} // end class Sender;
|
307
inc/helpers/class-site-duplicator.php
Normal file
307
inc/helpers/class-site-duplicator.php
Normal file
@ -0,0 +1,307 @@
|
||||
<?php
|
||||
/**
|
||||
* Exposes the public API to handle site duplication.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helper
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers;
|
||||
|
||||
use WP_Ultimo\Dependencies\Psr\Log\LogLevel;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
require_once WP_ULTIMO_PLUGIN_DIR . '/inc/duplication/duplicate.php';
|
||||
|
||||
if (!defined('MUCD_PRIMARY_SITE_ID')) {
|
||||
|
||||
define('MUCD_PRIMARY_SITE_ID', get_current_network_id()); // phpcs:ignore
|
||||
|
||||
} // end if;
|
||||
|
||||
/**
|
||||
* Exposes the public API to handle site duplication.
|
||||
*
|
||||
* The decision to create a buffer interface (this file), as the API layer
|
||||
* for the duplication functions is simple: it allows us to swith the duplication
|
||||
* component used without breaking backwards-compatibility in the future.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Site_Duplicator {
|
||||
|
||||
/**
|
||||
* Static-only class.
|
||||
*/
|
||||
private function __construct() {} // end __construct;
|
||||
|
||||
/**
|
||||
* Duplicate an existing network site.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $from_site_id ID of the site you wish to copy.
|
||||
* @param string $title Title of the new site.
|
||||
* @param array $args List of duplication parameters, check Site_Duplicator::process_duplication for reference.
|
||||
* @return int|\WP_Error ID of the newly created site or error.
|
||||
*/
|
||||
public static function duplicate_site($from_site_id, $title, $args = array()) {
|
||||
|
||||
$args['from_site_id'] = $from_site_id;
|
||||
$args['title'] = $title;
|
||||
|
||||
$duplicate_site = Site_Duplicator::process_duplication($args);
|
||||
|
||||
if (is_wp_error($duplicate_site)) {
|
||||
|
||||
// translators: %s id the template site id and %s is the error message returned.
|
||||
$message = sprintf(__('Attempt to duplicate site %1$d failed: %2$s', 'wp-ultimo'), $from_site_id, $duplicate_site->get_error_message());
|
||||
|
||||
wu_log_add('site-duplication', $message, LogLevel::ERROR);
|
||||
|
||||
return $duplicate_site;
|
||||
|
||||
} // end if;
|
||||
|
||||
// translators: %1$d is the ID of the site template used, and %2$d is the id of the new site.
|
||||
$message = sprintf(__('Attempt to duplicate site %1$d successful - New site id: %2$d', 'wp-ultimo'), $from_site_id, $duplicate_site);
|
||||
|
||||
wu_log_add('site-duplication', $message);
|
||||
|
||||
return $duplicate_site;
|
||||
|
||||
} // end duplicate_site;
|
||||
|
||||
/**
|
||||
* Replace the contents of a site with the contents of another.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $from_site_id Site to get the data from.
|
||||
* @param int $to_site_id Site to override.
|
||||
* @param array $args List of duplication parameters, check Site_Duplicator::process_duplication for reference.
|
||||
* @return int|false ID of the created site.
|
||||
*/
|
||||
public static function override_site($from_site_id, $to_site_id, $args = array()) {
|
||||
|
||||
$to_site = wu_get_site($to_site_id);
|
||||
|
||||
$to_site_membership_id = $to_site->get_membership_id();
|
||||
|
||||
$to_site_membership = $to_site->get_membership();
|
||||
|
||||
$to_site_customer = $to_site_membership->get_customer();
|
||||
|
||||
$args = wp_parse_args($args, array(
|
||||
'email' => $to_site_customer->get_email_address(),
|
||||
'title' => $to_site->get_title(),
|
||||
'path' => $to_site->get_path(),
|
||||
'from_site_id' => $from_site_id,
|
||||
'to_site_id' => $to_site_id,
|
||||
'meta' => $to_site->meta
|
||||
));
|
||||
|
||||
$duplicate_site_id = self::process_duplication($args);
|
||||
|
||||
if (is_wp_error($duplicate_site_id)) {
|
||||
|
||||
// translators: %s id the template site id and %s is the error message returned.
|
||||
$message = sprintf(__('Attempt to override site %1$d with data from site %2$d failed: %3$s', 'wp-ultimo'), $from_site_id, $to_site_id, $duplicate_site->get_error_message());
|
||||
|
||||
wu_log_add('site-duplication', $message, LogLevel::ERROR);
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
$new_to_site = wu_get_site($duplicate_site_id);
|
||||
|
||||
$new_to_site->set_membership_id($to_site_membership_id);
|
||||
|
||||
$new_to_site->set_customer_id($to_site->get_customer_id());
|
||||
|
||||
$new_to_site->set_template_id($from_site_id);
|
||||
|
||||
$new_to_site->set_type('customer_owned');
|
||||
|
||||
$new_to_site->set_title($to_site->get_title());
|
||||
|
||||
$saved = $new_to_site->save();
|
||||
|
||||
if ($saved) {
|
||||
|
||||
// translators: %1$d is the ID of the site template used, and %2$d is the ID of the overriden site.
|
||||
$message = sprintf(__('Attempt to override site %1$d with data from site %2$d successful.', 'wp-ultimo'), $from_site_id, $duplicate_site_id);
|
||||
|
||||
wu_log_add('site-duplication', $message);
|
||||
|
||||
return $saved;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end override_site;
|
||||
|
||||
/**
|
||||
* Processes a site duplication.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $args List of parameters of the duplication.
|
||||
* - email Email of the admin user to be created.
|
||||
* - title Title of the (new or not) site.
|
||||
* - path Path of the new site.
|
||||
* - from_site_id ID of the template site being used.
|
||||
* - to_site_id ID of the target site. Can be false to create new site.
|
||||
* - keep_users If we should keep users or not. Defaults to true.
|
||||
* - copy_files If we should copy the uploaded files or not. Defaults to true.
|
||||
* - public If the (new or not) site should be public. Defaults to true.
|
||||
* - domain The domain of the new site.
|
||||
* - network_id The network ID to allow for multi-network support.
|
||||
* @return int|WP_Error The Site ID.
|
||||
*/
|
||||
protected static function process_duplication($args) {
|
||||
|
||||
global $current_site, $wpdb;
|
||||
|
||||
$args = wp_parse_args($args, array(
|
||||
'email' => '', // Required arguments.
|
||||
'title' => '', // Required arguments.
|
||||
'path' => '/', // Required arguments.
|
||||
'from_site_id' => false, // Required arguments.
|
||||
'to_site_id' => false,
|
||||
'keep_users' => true,
|
||||
'public' => true,
|
||||
'domain' => $current_site->domain,
|
||||
'copy_files' => wu_get_setting('copy_media', true),
|
||||
'network_id' => get_current_network_id(),
|
||||
'meta' => array(),
|
||||
'user_id' => 0,
|
||||
));
|
||||
|
||||
// Checks
|
||||
$args = (object) $args;
|
||||
|
||||
$site_domain = $args->domain . $args->path;
|
||||
|
||||
$wpdb->hide_errors();
|
||||
|
||||
if (!$args->from_site_id) {
|
||||
|
||||
return new \WP_Error('from_site_id_required', __('You need to provide a valid site to duplicate.', 'wp-ultimo'));
|
||||
|
||||
} // end if;
|
||||
|
||||
$user_id = !empty($args->user_id) ? $args->user_id : self::create_admin($args->email, $site_domain);
|
||||
|
||||
if (is_wp_error($user_id)) {
|
||||
|
||||
return $user_id;
|
||||
|
||||
} // end if;
|
||||
|
||||
if (!$args->to_site_id) {
|
||||
|
||||
$meta = array_merge($args->meta, array('public' => $args->public));
|
||||
|
||||
$args->to_site_id = wpmu_create_blog($args->domain, $args->path, $args->title, $user_id, $meta, $args->network_id);
|
||||
|
||||
$wpdb->show_errors();
|
||||
|
||||
} // end if;
|
||||
|
||||
if (is_wp_error($args->to_site_id)) {
|
||||
|
||||
return $args->to_site_id;
|
||||
|
||||
} // end if;
|
||||
|
||||
if (!is_numeric($args->to_site_id)) {
|
||||
|
||||
return new \WP_Error('site_creation_failed', __('An attempt to create a new site failed.', 'wp-ultimo'));
|
||||
|
||||
} // end if;
|
||||
|
||||
if (!is_super_admin($user_id) && !get_user_option('primary_blog', $user_id)) {
|
||||
|
||||
update_user_option($user_id, 'primary_blog', $args->to_site_id, true);
|
||||
|
||||
} // end if;
|
||||
|
||||
\MUCD_Duplicate::bypass_server_limit();
|
||||
|
||||
if ($args->copy_files) {
|
||||
|
||||
$result = \MUCD_Files::copy_files($args->from_site_id, $args->to_site_id);
|
||||
|
||||
} // end if;
|
||||
|
||||
/**
|
||||
* Supress email change notification on site duplication processes.
|
||||
*/
|
||||
add_filter('send_site_admin_email_change_email', '__return_false');
|
||||
|
||||
$result = \MUCD_Data::copy_data($args->from_site_id, $args->to_site_id);
|
||||
|
||||
if ($args->keep_users) {
|
||||
|
||||
$result = \MUCD_Duplicate::copy_users($args->from_site_id, $args->to_site_id);
|
||||
|
||||
} // end if;
|
||||
|
||||
wp_cache_flush();
|
||||
|
||||
/**
|
||||
* Allow developers to hook after a site duplication happens.
|
||||
*
|
||||
* @since 1.9.4
|
||||
* @return void
|
||||
*/
|
||||
do_action('wu_duplicate_site', array(
|
||||
'site_id' => $args->to_site_id,
|
||||
));
|
||||
|
||||
return $args->to_site_id;
|
||||
|
||||
} // end process_duplication;
|
||||
|
||||
/**
|
||||
* Creates an admin user if no user exists with this email.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @param string $email The email.
|
||||
* @param string $domain The domain.
|
||||
* @return int Id of the user created.
|
||||
*/
|
||||
public static function create_admin($email, $domain) {
|
||||
|
||||
// Create New site Admin if not exists
|
||||
$password = 'N/A';
|
||||
|
||||
$user_id = email_exists($email);
|
||||
|
||||
if (!$user_id) { // Create a new user with a random password
|
||||
|
||||
$password = wp_generate_password(12, false);
|
||||
|
||||
$user_id = wpmu_create_user($domain, $password, $email);
|
||||
|
||||
if (false === $user_id) {
|
||||
|
||||
return new \WP_Error('user_creation_error', __('We were not able to create a new admin user for the site being duplicated.', 'wp-ultimo'));
|
||||
|
||||
} else {
|
||||
|
||||
wp_new_user_notification($user_id);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end if;
|
||||
|
||||
return $user_id;
|
||||
|
||||
} // end create_admin;
|
||||
|
||||
} // end class Site_Duplicator;
|
195
inc/helpers/class-validator.php
Normal file
195
inc/helpers/class-validator.php
Normal file
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
/**
|
||||
* Wraps the validation library being used by WP Ultimo.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helper
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers;
|
||||
|
||||
use \WP_Ultimo\Dependencies\Rakit\Validation\Validator as Validator_Helper;
|
||||
use \WP_Ultimo\Helpers\Validation_Rules\Unique;
|
||||
use \WP_Ultimo\Helpers\Validation_Rules\Unique_Site;
|
||||
use \WP_Ultimo\Helpers\Validation_Rules\Exists;
|
||||
use \WP_Ultimo\Helpers\Validation_Rules\Checkout_Steps;
|
||||
use \WP_Ultimo\Helpers\Validation_Rules\Price_Variations;
|
||||
use \WP_Ultimo\Helpers\Validation_Rules\Domain;
|
||||
use \WP_Ultimo\Helpers\Validation_Rules\Site_Template;
|
||||
use \WP_Ultimo\Helpers\Validation_Rules\Products;
|
||||
use \WP_Ultimo\Helpers\Validation_Rules\Country;
|
||||
use \WP_Ultimo\Helpers\Validation_Rules\State;
|
||||
use \WP_Ultimo\Helpers\Validation_Rules\City;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Wraps the validation library being used by WP Ultimo.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Validator {
|
||||
|
||||
/**
|
||||
* Holds an instance of the validator object.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var Rakit\Validation\Validator
|
||||
*/
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* Holds an instance of the validation being performed.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var Rakit\Validation\Validation
|
||||
*/
|
||||
protected $validation;
|
||||
|
||||
/**
|
||||
* Holds the errors returned from validation.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var \WP_Error
|
||||
*/
|
||||
protected $errors;
|
||||
|
||||
/**
|
||||
* Sets up the validation library and makes the error messages translatable.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
// translators: %s is the field name.
|
||||
$field_required_message = sprintf(__('The %s field is required', 'wp-ultimo'), ':attribute');
|
||||
|
||||
$validation_error_messages = apply_filters('wu_validator_error_messages', array(
|
||||
'required' => $field_required_message,
|
||||
'required_without' => $field_required_message,
|
||||
'required_with' => $field_required_message,
|
||||
// translators: %s is the email field identifier
|
||||
'email' => sprintf(__('The %s is not valid email', 'wp-ultimo'), ':attribute'),
|
||||
// translators: 1st %s is the field name; 2nd is the allowed value
|
||||
'min' => sprintf(__('The %1$s minimum is %2$s', 'wp-ultimo'), ':attribute', ':min'),
|
||||
// translators: 1st %s is the field name; 2nd is the allowed value
|
||||
'max' => sprintf(__('The %1$s maximum is %2$s', 'wp-ultimo'), ':attribute', ':max'),
|
||||
// translators: %s is the field identifier
|
||||
'alpha_dash' => sprintf(__('The %s only allows a-z, 0-9, _ and -', 'wp-ultimo'), ':attribute'),
|
||||
// translators: %s is the field identifier
|
||||
'lowercase' => sprintf(__('The %s must be lowercase', 'wp-ultimo'), ':attribute'),
|
||||
// translators: %s is the field identifier
|
||||
'integer' => sprintf(__('The %s must be integer', 'wp-ultimo'), ':attribute')
|
||||
), $this);
|
||||
|
||||
$this->validator = new Validator_Helper($validation_error_messages);
|
||||
|
||||
$this->validator->setTranslations(array(
|
||||
'and' => __('and', 'wp-ultimo'),
|
||||
'or' => __('or', 'wp-ultimo'),
|
||||
));
|
||||
|
||||
$this->validator->addValidator('unique', new Unique);
|
||||
$this->validator->addValidator('unique_site', new Unique_Site);
|
||||
$this->validator->addValidator('exists', new Exists);
|
||||
$this->validator->addValidator('checkout_steps', new Checkout_Steps);
|
||||
$this->validator->addValidator('price_variations', new Price_Variations);
|
||||
$this->validator->addValidator('domain', new Domain);
|
||||
$this->validator->addValidator('site_template', new Site_Template);
|
||||
$this->validator->addValidator('products', new Products);
|
||||
$this->validator->addValidator('country', new Country);
|
||||
$this->validator->addValidator('state', new State);
|
||||
$this->validator->addValidator('city', new City);
|
||||
|
||||
} // end __construct;
|
||||
|
||||
/**
|
||||
* Validates the data passed according to the rules passed.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @link https://github.com/rakit/validation#available-rules
|
||||
*
|
||||
* @param array $data Data to be validated.
|
||||
* @param array $rules List of rules to validate against.
|
||||
* @param array $aliases List of aliases to be used with the validator.
|
||||
* @return \WP_Ultimo\Helpers\Validator
|
||||
*/
|
||||
public function validate($data, $rules = array(), $aliases = array()) {
|
||||
|
||||
$this->errors = new \WP_Error;
|
||||
|
||||
$this->validation = $this->validator->make($data, $rules);
|
||||
|
||||
$this->validation->setAliases($aliases);
|
||||
|
||||
$this->validation->validate();
|
||||
|
||||
return $this;
|
||||
|
||||
} // end validate;
|
||||
|
||||
/**
|
||||
* Returns true when the validation fails.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return boolean
|
||||
*/
|
||||
public function fails() {
|
||||
|
||||
return $this->validation->fails();
|
||||
|
||||
} // end fails;
|
||||
|
||||
/**
|
||||
* Returns a WP_Error object containing all validation errors.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return WP_Error
|
||||
*/
|
||||
public function get_errors() {
|
||||
|
||||
$errors = $this->validation->errors()->toArray();
|
||||
|
||||
$this->cast_to_wp_error($errors);
|
||||
|
||||
return $this->errors;
|
||||
|
||||
} // end get_errors;
|
||||
|
||||
/**
|
||||
* Converts the native error structure to a WP_Error object.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $errors Array containing the errors returned.
|
||||
* @return void
|
||||
*/
|
||||
protected function cast_to_wp_error($errors) {
|
||||
|
||||
foreach ($errors as $key => $error_messages) {
|
||||
|
||||
foreach ($error_messages as $error_message) {
|
||||
|
||||
$this->errors->add($key, $error_message);
|
||||
|
||||
} // end foreach;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
} // end cast_to_wp_error;
|
||||
|
||||
/**
|
||||
* Get holds an instance of the validation being performed.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return Rakit\Validation\Validation
|
||||
*/
|
||||
public function get_validation() {
|
||||
|
||||
return $this->validation;
|
||||
|
||||
} // end get_validation;
|
||||
|
||||
} // end class Validator;
|
264
inc/helpers/class-wp-config.php
Normal file
264
inc/helpers/class-wp-config.php
Normal file
@ -0,0 +1,264 @@
|
||||
<?php
|
||||
/**
|
||||
* Handles modifications to the wp-config.php file, if permissions allow.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helper
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Handles modifications to the wp-config.php file, if permissions allow.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class WP_Config {
|
||||
|
||||
use \WP_Ultimo\Traits\Singleton;
|
||||
|
||||
/**
|
||||
* Inject the constant into the wp-config.php file.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $constant The name of the constant. e.g. WP_ULTIMO_CONSTANT.
|
||||
* @param string|int $value The value of that constant.
|
||||
* @return bool|\WP_Error
|
||||
*/
|
||||
public function inject_wp_config_constant($constant, $value) {
|
||||
|
||||
$config_path = $this->get_wp_config_path();
|
||||
|
||||
if (!is_writeable($config_path)) {
|
||||
|
||||
// translators: %s is the file name.
|
||||
return new \WP_Error('not-writeable', sprintf(__('The file %s is not writable', 'wp-ultimo'), $config_path));
|
||||
|
||||
} // end if;
|
||||
|
||||
$config = file($config_path);
|
||||
|
||||
$line = $this->find_injected_line($config, $constant);
|
||||
|
||||
$content = str_pad(sprintf("define( '%s', '%s' );", $constant, $value), 50) . '// Automatically injected by WP Ultimo;';
|
||||
|
||||
if ($line === false) {
|
||||
|
||||
// no defined, we just need to inject
|
||||
$hook_line = $this->find_reference_hook_line($config);
|
||||
|
||||
if ($hook_line === false) {
|
||||
|
||||
return new \WP_Error('unknown-wpconfig', __("WP Ultimo can't recognize your wp-config.php, please revert it to original state for further process.", 'wp-ultimo'));
|
||||
|
||||
} // end if;
|
||||
|
||||
$config = $this->inject_contents($config, $hook_line + 1, PHP_EOL . $content . PHP_EOL);
|
||||
|
||||
return file_put_contents($config_path, implode('', $config), LOCK_EX);
|
||||
|
||||
} else {
|
||||
|
||||
list($value, $line) = $line;
|
||||
|
||||
if ($value !== true) {
|
||||
|
||||
$config[$line] = $content . PHP_EOL;
|
||||
|
||||
return file_put_contents($config_path, implode('', $config), LOCK_EX);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end if;
|
||||
|
||||
return false;
|
||||
|
||||
} // end inject_wp_config_constant;
|
||||
|
||||
/**
|
||||
* Actually inserts the new lines into the array of wp-config.php lines.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $content_array Array containing the original lines of the file being edited.
|
||||
* @param int $line Line number to inject the new content at.
|
||||
* @param string $value Value to add to that specific line.
|
||||
* @return array New array containing the lines of the modified file.
|
||||
*/
|
||||
public function inject_contents($content_array, $line, $value) {
|
||||
|
||||
if (!is_array($value)) {
|
||||
|
||||
$value = array($value);
|
||||
|
||||
} // end if;
|
||||
|
||||
array_splice($content_array, $line, 0, $value);
|
||||
|
||||
return $content_array;
|
||||
|
||||
} // end inject_contents;
|
||||
|
||||
/**
|
||||
* Gets the correct path to the wp-config.php file.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return string
|
||||
*/
|
||||
public function get_wp_config_path() {
|
||||
|
||||
if (file_exists(ABSPATH . 'wp-config.php')) {
|
||||
|
||||
return (ABSPATH . 'wp-config.php');
|
||||
|
||||
} elseif (@file_exists(dirname(ABSPATH) . '/wp-config.php') && !@file_exists(dirname(ABSPATH) . '/wp-settings.php')) {
|
||||
|
||||
return (dirname(ABSPATH) . '/wp-config.php');
|
||||
|
||||
} elseif (defined('WP_TESTS_MULTISITE') && constant('WP_TESTS_MULTISITE') === true) {
|
||||
|
||||
return '/tmp/wordpress-tests-lib/wp-tests-config.php';
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end get_wp_config_path;
|
||||
|
||||
/**
|
||||
* Find reference line for injection.
|
||||
*
|
||||
* We need a hook point we can use as reference to inject our constants.
|
||||
* For now, we are using the line defining the $table_prefix.
|
||||
* e.g. $table_prefix = 'wp_';
|
||||
* We retrieve that line via RegEx.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $config Array containing the lines of the config file, for searching.
|
||||
* @return false|int Line number.
|
||||
*/
|
||||
public function find_reference_hook_line($config) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
/**
|
||||
* We check for three patterns when trying to figure our
|
||||
* where we can inject our constants:
|
||||
*
|
||||
* 1. We search for the $table_prefix variable definition;
|
||||
* 2. We search for more complex $table_prefix definitions - the ones that
|
||||
* use env variables, for example;
|
||||
* 3. If that's not available, we look for the 'Happy Publishing' comment;
|
||||
* 4. If that's also not available, we look for the beginning of the file.
|
||||
*
|
||||
* The key represents the pattern and the value the number of lines to add.
|
||||
* A negative number of lines can be passed to write before the found line,
|
||||
* instead of writing after it.
|
||||
*/
|
||||
$patterns = apply_filters('wu_wp_config_reference_hook_line_patterns', array(
|
||||
'/^\$table_prefix\s*=\s*[\'|\"]' . $wpdb->prefix . '[\'|\"]/' => 0,
|
||||
'/^( ){0,}\$table_prefix\s*=.*[\'|\"]' . $wpdb->prefix . '[\'|\"]/' => 0,
|
||||
'/(\/\* That\'s all, stop editing! Happy publishing\. \*\/)/' => -2,
|
||||
'/<\?php/' => 0,
|
||||
));
|
||||
|
||||
$line = 1;
|
||||
|
||||
foreach ($patterns as $pattern => $lines_to_add) {
|
||||
|
||||
foreach ($config as $k => $line) {
|
||||
|
||||
if (preg_match($pattern, (string) $line)) {
|
||||
|
||||
$line = $k + $lines_to_add;
|
||||
|
||||
break 2;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
return $line;
|
||||
|
||||
} // end find_reference_hook_line;
|
||||
|
||||
/**
|
||||
* Revert the injection of a constant in wp-config.php
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $constant Constant name.
|
||||
* @return mixed
|
||||
*/
|
||||
public function revert($constant) {
|
||||
|
||||
$config_path = $this->get_wp_config_path();
|
||||
|
||||
if (!is_writeable($config_path)) {
|
||||
|
||||
// translators: %s is the file name.
|
||||
return new \WP_Error('not-writeable', sprintf(__('The file %s is not writable', 'wp-ultimo'), $config_path));
|
||||
|
||||
} // end if;
|
||||
|
||||
$config = file($config_path);
|
||||
|
||||
$line = $this->find_injected_line($config, $constant);
|
||||
|
||||
if ($line === false) {
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
$value = $line[0];
|
||||
|
||||
$line = $line[1];
|
||||
|
||||
if ($value === 'true' || $value === '1') {
|
||||
|
||||
// value is true, we will remove this
|
||||
unset($config[$line]);
|
||||
|
||||
// save it
|
||||
return file_put_contents($config_path, implode('', $config), LOCK_EX);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end revert;
|
||||
/**
|
||||
* Checks for the injected line inside of the wp-config.php file.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $config Array containing the lines of the config file, for searching.
|
||||
* @param string $constant The constant name.
|
||||
* @return mixed[]|bool
|
||||
*/
|
||||
public function find_injected_line($config, $constant) {
|
||||
|
||||
$pattern = "/^define\(\s*['|\"]" . $constant . "['|\"],(.*)\)/";
|
||||
|
||||
foreach ($config as $k => $line) {
|
||||
|
||||
if (preg_match($pattern, (string) $line, $matches)) {
|
||||
|
||||
return array(trim($matches[1]), $k);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
return false;
|
||||
|
||||
} // end find_injected_line;
|
||||
|
||||
} // end class WP_Config;
|
139
inc/helpers/validation-rules/class-checkout-steps.php
Normal file
139
inc/helpers/validation-rules/class-checkout-steps.php
Normal file
@ -0,0 +1,139 @@
|
||||
<?php // phpcs:disable
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter is unique.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helpers/Validation_Rules
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers\Validation_Rules;
|
||||
|
||||
use WP_Ultimo\Dependencies\Rakit\Validation\Rule;
|
||||
use WP_Ultimo\Managers\Signup_Fields_Manager;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter is unique.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Checkout_Steps extends Rule {
|
||||
|
||||
/**
|
||||
* Error message to be returned when this value has been used.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var string
|
||||
*/
|
||||
protected $message = ':attribute is wrongly setup.';
|
||||
|
||||
/**
|
||||
* Parameters that this rule accepts.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var array
|
||||
*/
|
||||
protected $fillableParams = array(); // phpcs:ignore
|
||||
/**
|
||||
* Performs the actual check.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param mixed $value Value being checked.
|
||||
*/
|
||||
public function check($value) : bool {
|
||||
|
||||
if (is_string($value)) {
|
||||
|
||||
$value = maybe_unserialize($value);
|
||||
|
||||
} // end if;
|
||||
|
||||
$required_fields = Signup_Fields_Manager::get_instance()->get_required_fields();
|
||||
|
||||
$required_fields_list = array_keys($required_fields);
|
||||
|
||||
if (!$value || is_string($value)) {
|
||||
|
||||
return true;
|
||||
|
||||
} // end if;
|
||||
|
||||
$fields = array_column($value, 'fields');
|
||||
|
||||
if (empty($fields)) {
|
||||
|
||||
return true;
|
||||
|
||||
} // end if;
|
||||
|
||||
$all_fields = call_user_func_array('array_merge', $fields);
|
||||
|
||||
$all_fields_list = array_column($all_fields, 'type');
|
||||
|
||||
/**
|
||||
* First, we validated that all of our required fields are present.
|
||||
*/
|
||||
$all_present = true;
|
||||
|
||||
foreach ($required_fields_list as $field_slug) {
|
||||
|
||||
if (!in_array($field_slug, $all_fields_list, true)) {
|
||||
|
||||
$this->message = sprintf(__('The %s field must be present in at least one of the checkout form steps.', 'wp-ultimo'), wu_slug_to_name($field_slug));
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end if;
|
||||
|
||||
/**
|
||||
* Allow developers to bypass the check if a field is auto-submittable.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @param array $submittable_field_types The list of field types.
|
||||
* @return array
|
||||
*/
|
||||
$submittable_field_types = apply_filters(
|
||||
'wu_checkout_step_validation_submittable_field_types',
|
||||
array(
|
||||
'submit_button',
|
||||
'pricing_table',
|
||||
'template_selection',
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Second, we must validate if every step has a submit button.
|
||||
*/
|
||||
foreach ($value as $step) {
|
||||
|
||||
$found_submittable_field_types = \WP_Ultimo\Dependencies\Arrch\Arrch::find($step['fields'], array(
|
||||
'where' => array(
|
||||
array('type', $submittable_field_types),
|
||||
),
|
||||
));
|
||||
|
||||
if (empty($found_submittable_field_types)) {
|
||||
|
||||
$this->message = sprintf(__('The %s step is missing a submit field', 'wp-ultimo'), $step['name']);
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
/*
|
||||
* @todo: Plan, product selection fields must come before the order summary and payment fields.
|
||||
*/
|
||||
|
||||
return true;
|
||||
|
||||
} // end check;
|
||||
|
||||
} // end class Checkout_Steps;
|
64
inc/helpers/validation-rules/class-city.php
Normal file
64
inc/helpers/validation-rules/class-city.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* Adds a validation rules for cities
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helpers/Validation_Rules
|
||||
* @since 2.0.11
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers\Validation_Rules;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
use WP_Ultimo\Dependencies\Rakit\Validation\Rule;
|
||||
|
||||
/**
|
||||
* Validates template sites.
|
||||
*
|
||||
* @since 2.0.4
|
||||
*/
|
||||
class City extends Rule {
|
||||
|
||||
/**
|
||||
* Parameters that this rule accepts.
|
||||
*
|
||||
* @since 2.0.4
|
||||
* @var array
|
||||
*/
|
||||
protected $fillableParams = array('country', 'state'); // phpcs:ignore
|
||||
/**
|
||||
* Performs the actual check.
|
||||
*
|
||||
* @since 2.0.11
|
||||
*
|
||||
* @param mixed $city The city value detected.
|
||||
*/
|
||||
public function check($city) : bool { // phpcs:ignore
|
||||
|
||||
$check = true;
|
||||
|
||||
$country = $this->parameter('country') ?? wu_request('billing_country');
|
||||
|
||||
$state = $this->parameter('state') ?? wu_request('billing_state');
|
||||
|
||||
if ($country && $state && $city) {
|
||||
|
||||
$state = strtoupper((string) $state);
|
||||
|
||||
$allowed_cities = wu_get_country_cities(strtoupper((string) $country), $state, false);
|
||||
|
||||
if (!empty($allowed_cities)) {
|
||||
|
||||
$check = in_array($city, $allowed_cities, true);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end if;
|
||||
|
||||
return $check;
|
||||
|
||||
} // end check;
|
||||
|
||||
} // end class City;
|
56
inc/helpers/validation-rules/class-country.php
Normal file
56
inc/helpers/validation-rules/class-country.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Adds a validation rules for countries
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helpers/Validation_Rules
|
||||
* @since 2.0.11
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers\Validation_Rules;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
use WP_Ultimo\Dependencies\Rakit\Validation\Rule;
|
||||
|
||||
/**
|
||||
* Validates template sites.
|
||||
*
|
||||
* @since 2.0.4
|
||||
*/
|
||||
class Country extends Rule {
|
||||
|
||||
/**
|
||||
* Parameters that this rule accepts.
|
||||
*
|
||||
* @since 2.0.4
|
||||
* @var array
|
||||
*/
|
||||
protected $fillableParams = array(); // phpcs:ignore
|
||||
/**
|
||||
* Performs the actual check.
|
||||
*
|
||||
* @since 2.0.4
|
||||
*
|
||||
* @param mixed $country The country value detected.
|
||||
*/
|
||||
public function check($country) : bool { // phpcs:ignore
|
||||
|
||||
$check = true;
|
||||
|
||||
if ($country) {
|
||||
|
||||
$country = strtoupper((string) $country);
|
||||
|
||||
$allowed_countries = array_keys(wu_get_countries());
|
||||
|
||||
$check = in_array($country, $allowed_countries, true);
|
||||
|
||||
} // end if;
|
||||
|
||||
return $check;
|
||||
|
||||
} // end check;
|
||||
|
||||
} // end class Country;
|
52
inc/helpers/validation-rules/class-domain.php
Normal file
52
inc/helpers/validation-rules/class-domain.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter exists.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helpers/Validation_Rules
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers\Validation_Rules;
|
||||
|
||||
use WP_Ultimo\Dependencies\Rakit\Validation\Rule;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter exists.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Domain extends Rule {
|
||||
|
||||
/**
|
||||
* Error message to be returned when this value has been used.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var string
|
||||
*/
|
||||
protected $message = ':attribute :value is not valid';
|
||||
|
||||
/**
|
||||
* Parameters that this rule accepts.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var array
|
||||
*/
|
||||
protected $fillableParams = array(); // phpcs:ignore
|
||||
/**
|
||||
* Performs the actual check.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param mixed $value Value being checked.
|
||||
*/
|
||||
public function check($value) : bool { // phpcs:ignore
|
||||
|
||||
return (bool) preg_match('/^(?!\-)(?:(?:[a-zA-Z\d][a-zA-Z\d\-]{0,61})?[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63}$/', (string) $value);
|
||||
|
||||
} // end check;
|
||||
|
||||
} // end class Domain;
|
62
inc/helpers/validation-rules/class-exists.php
Normal file
62
inc/helpers/validation-rules/class-exists.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter exists.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helpers/Validation_Rules
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers\Validation_Rules;
|
||||
|
||||
use WP_Ultimo\Dependencies\Rakit\Validation\Rule;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter exists.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Exists extends Rule {
|
||||
|
||||
/**
|
||||
* Error message to be returned when this value has been used.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var string
|
||||
*/
|
||||
protected $message = ':attribute :value is not valid';
|
||||
|
||||
/**
|
||||
* Parameters that this rule accepts.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var array
|
||||
*/
|
||||
protected $fillableParams = array('model', 'column', 'except'); // phpcs:ignore
|
||||
|
||||
/**
|
||||
* Performs the actual check.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param mixed $value Value being checked.
|
||||
*/
|
||||
public function check($value) : bool {
|
||||
|
||||
$this->requireParameters(array(
|
||||
'model',
|
||||
'column'
|
||||
));
|
||||
|
||||
$column = $this->parameter('column');
|
||||
$model = $this->parameter('model');
|
||||
|
||||
// do query
|
||||
return !!$model::get_by($column, $value);
|
||||
|
||||
} // end check;
|
||||
|
||||
} // end class Exists;
|
125
inc/helpers/validation-rules/class-price-variations.php
Normal file
125
inc/helpers/validation-rules/class-price-variations.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php // phpcs:disable
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter is unique.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helpers/Validation_Rules
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers\Validation_Rules;
|
||||
|
||||
use WP_Ultimo\Dependencies\Rakit\Validation\Rule;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter is unique.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Price_Variations extends Rule {
|
||||
|
||||
/**
|
||||
* Error message to be returned when this value has been used.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var string
|
||||
*/
|
||||
protected $message = ':attribute is wrongly setup.';
|
||||
|
||||
/**
|
||||
* Parameters that this rule accepts.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var array
|
||||
*/
|
||||
protected $fillableParams = array('duration', 'duration_unit'); // phpcs:ignore
|
||||
/**
|
||||
* Performs the actual check.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param mixed $value Value being checked.
|
||||
*/
|
||||
public function check($value) : bool {
|
||||
|
||||
if (is_string($value)) {
|
||||
|
||||
$value = maybe_unserialize($value);
|
||||
|
||||
} // end if;
|
||||
|
||||
if (!is_array($value)) {
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
foreach ($value as $price_variation) {
|
||||
|
||||
/**
|
||||
* Validation Duration
|
||||
*/
|
||||
$duration = wu_get_isset($price_variation, 'duration', false);
|
||||
|
||||
if (!is_numeric($duration) || (int) $duration <= 0) {
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
/**
|
||||
* Validation Unit
|
||||
*/
|
||||
$unit = wu_get_isset($price_variation, 'duration_unit', false);
|
||||
|
||||
$allowed_units = array(
|
||||
'day',
|
||||
'week',
|
||||
'month',
|
||||
'year',
|
||||
);
|
||||
|
||||
if (!in_array($unit, $allowed_units, true)) {
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
/**
|
||||
* Check if it is the same as the main duration
|
||||
*/
|
||||
if ($this->parameter('duration') == $duration && $this->parameter('duration_unit') === $unit) {
|
||||
|
||||
$this->message = 'This product cannot have a price variation for the same duration and duration unit values as the product itself.';
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
/**
|
||||
* Validation Amount
|
||||
*/
|
||||
$amount = wu_get_isset($price_variation, 'amount', false);
|
||||
|
||||
if ($amount) {
|
||||
|
||||
$amount = wu_to_float($amount);
|
||||
|
||||
} // end if;
|
||||
|
||||
if (!is_numeric($amount)) {
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
return true;
|
||||
|
||||
} // end check;
|
||||
|
||||
} // end class Price_Variations;
|
66
inc/helpers/validation-rules/class-products.php
Normal file
66
inc/helpers/validation-rules/class-products.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* Adds a validation rule for products.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helpers/Validation_Rules
|
||||
* @since 2.0.4
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers\Validation_Rules;
|
||||
|
||||
use WP_Ultimo\Dependencies\Rakit\Validation\Rule;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Validates products.
|
||||
*
|
||||
* @since 2.0.4
|
||||
*/
|
||||
class Products extends Rule {
|
||||
|
||||
/**
|
||||
* Error message to be returned when this value has been used.
|
||||
*
|
||||
* @since 2.0.4
|
||||
* @var string
|
||||
*/
|
||||
protected $message = '';
|
||||
|
||||
/**
|
||||
* Parameters that this rule accepts.
|
||||
*
|
||||
* @since 2.0.4
|
||||
* @var array
|
||||
*/
|
||||
protected $fillableParams = array(); // phpcs:ignore
|
||||
/**
|
||||
* Performs the actual check.
|
||||
*
|
||||
* @since 2.0.4
|
||||
*
|
||||
* @param mixed $products Value being checked.
|
||||
*/
|
||||
public function check($products) : bool { // phpcs:ignore
|
||||
|
||||
$products = (array) $products;
|
||||
|
||||
$product_objects = array_map('wu_get_product', $products);
|
||||
|
||||
list($plan, $additional_products) = wu_segregate_products($product_objects);
|
||||
|
||||
if ($plan) {
|
||||
|
||||
return true;
|
||||
|
||||
} // end if;
|
||||
|
||||
$this->message = __('A plan is required.', 'wp-ultimo');
|
||||
|
||||
return false;
|
||||
|
||||
} // end check;
|
||||
|
||||
} // end class Products;
|
130
inc/helpers/validation-rules/class-site-template.php
Normal file
130
inc/helpers/validation-rules/class-site-template.php
Normal file
@ -0,0 +1,130 @@
|
||||
<?php
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter is unique.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helpers/Validation_Rules
|
||||
* @since 2.0.4
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers\Validation_Rules;
|
||||
|
||||
use \WP_Ultimo\Dependencies\Rakit\Validation\Rule;
|
||||
use \WP_Ultimo\Checkout\Checkout;
|
||||
use \WP_Ultimo\Database\Sites\Site_Type;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Validates template sites.
|
||||
*
|
||||
* @since 2.0.4
|
||||
*/
|
||||
class Site_Template extends Rule {
|
||||
|
||||
/**
|
||||
* Error message to be returned when this value has been used.
|
||||
*
|
||||
* @since 2.0.4
|
||||
* @var string
|
||||
*/
|
||||
protected $message = '';
|
||||
|
||||
/**
|
||||
* Parameters that this rule accepts.
|
||||
*
|
||||
* @since 2.0.4
|
||||
* @var array
|
||||
*/
|
||||
protected $fillableParams = array(); // phpcs:ignore
|
||||
/**
|
||||
* Performs the actual check.
|
||||
*
|
||||
* @since 2.0.4
|
||||
*
|
||||
* @param mixed $template_id Value being checked.
|
||||
*/
|
||||
public function check($template_id) : bool { // phpcs:ignore
|
||||
|
||||
$template_id = absint($template_id);
|
||||
|
||||
if (!$template_id) {
|
||||
|
||||
return true;
|
||||
|
||||
} // end if;
|
||||
|
||||
$site = wu_get_site($template_id);
|
||||
|
||||
if (!$site || ($site->get_type() !== Site_Type::SITE_TEMPLATE && $site->get_type() !== Site_Type::CUSTOMER_OWNED)) {
|
||||
|
||||
$this->message = __('The Template ID does not correspond to a valid Template', 'wp-ultimo');
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
if ($site->get_type() === Site_Type::CUSTOMER_OWNED) {
|
||||
|
||||
if (!wu_get_setting('allow_own_site_as_template')) {
|
||||
|
||||
$this->message = __('You can not use your sites as template', 'wp-ultimo');
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
$customer = wu_get_current_customer();
|
||||
|
||||
if (!$customer || $site->get_customer_id() !== $customer->get_id()) {
|
||||
|
||||
$this->message = __('The selected template is not available.', 'wp-ultimo');
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
return true;
|
||||
|
||||
} // end if;
|
||||
|
||||
$allowed_templates = false;
|
||||
|
||||
$product_ids_or_slugs = Checkout::get_instance()->request_or_session('products', array());
|
||||
|
||||
$product_ids_or_slugs = array_unique($product_ids_or_slugs);
|
||||
|
||||
if ($product_ids_or_slugs) {
|
||||
|
||||
$products = array_map('wu_get_product', $product_ids_or_slugs);
|
||||
|
||||
$limits = new \WP_Ultimo\Objects\Limitations();
|
||||
|
||||
list($plan, $additional_products) = wu_segregate_products($products);
|
||||
|
||||
$products = array_merge(array($plan), $additional_products);
|
||||
|
||||
foreach ($products as $product) {
|
||||
|
||||
$limits = $limits->merge($product->get_limitations());
|
||||
|
||||
} // end foreach;
|
||||
|
||||
$allowed_templates = $limits->site_templates->get_available_site_templates();
|
||||
|
||||
} // end if;
|
||||
|
||||
if (is_array($allowed_templates) && !in_array($template_id, $allowed_templates)) { // phpcs:ignore
|
||||
|
||||
$this->message = __('The selected template is not available for this product.', 'wp-ultimo');
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
return true;
|
||||
|
||||
} // end check;
|
||||
|
||||
} // end class Site_Template;
|
62
inc/helpers/validation-rules/class-state.php
Normal file
62
inc/helpers/validation-rules/class-state.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* Adds a validation rules for states
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helpers/Validation_Rules
|
||||
* @since 2.0.11
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers\Validation_Rules;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
use WP_Ultimo\Dependencies\Rakit\Validation\Rule;
|
||||
|
||||
/**
|
||||
* Validates template sites.
|
||||
*
|
||||
* @since 2.0.4
|
||||
*/
|
||||
class State extends Rule {
|
||||
|
||||
/**
|
||||
* Parameters that this rule accepts.
|
||||
*
|
||||
* @since 2.0.4
|
||||
* @var array
|
||||
*/
|
||||
protected $fillableParams = array('country'); // phpcs:ignore
|
||||
/**
|
||||
* Performs the actual check.
|
||||
*
|
||||
* @since 2.0.11
|
||||
*
|
||||
* @param mixed $state The state value detected.
|
||||
*/
|
||||
public function check($state) : bool { // phpcs:ignore
|
||||
|
||||
$check = true;
|
||||
|
||||
$country = $this->parameter('country') ?? wu_request('billing_country');
|
||||
|
||||
if ($country && $state) {
|
||||
|
||||
$state = strtoupper((string) $state);
|
||||
|
||||
$allowed_states = array_keys(wu_get_country_states(strtoupper((string) $country), false));
|
||||
|
||||
if (!empty($allowed_states)) {
|
||||
|
||||
$check = in_array($state, $allowed_states, true);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end if;
|
||||
|
||||
return $check;
|
||||
|
||||
} // end check;
|
||||
|
||||
} // end class State;
|
66
inc/helpers/validation-rules/class-unique-site.php
Normal file
66
inc/helpers/validation-rules/class-unique-site.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter is unique.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helpers/Validation_Rules
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers\Validation_Rules;
|
||||
|
||||
use WP_Ultimo\Dependencies\Rakit\Validation\Rule;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter is unique.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Unique_Site extends Rule {
|
||||
|
||||
/**
|
||||
* Error message to be returned when this value has been used.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var string
|
||||
*/
|
||||
protected $message = '';
|
||||
|
||||
/**
|
||||
* Parameters that this rule accepts.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var array
|
||||
*/
|
||||
protected $fillableParams = array('self_id'); // phpcs:ignore
|
||||
/**
|
||||
* Performs the actual check.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param mixed $value Value being checked.
|
||||
*/
|
||||
public function check($value) : bool { // phpcs:ignore
|
||||
|
||||
$this->requireParameters(array());
|
||||
|
||||
$self_id = $this->parameter('self_id');
|
||||
|
||||
$results = wpmu_validate_blog_signup($value, 'Test Title');
|
||||
|
||||
if ($results['errors']->has_errors()) {
|
||||
|
||||
$this->message = $results['errors']->get_error_message();
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
return true;
|
||||
|
||||
} // end check;
|
||||
|
||||
} // end class Unique_Site;
|
96
inc/helpers/validation-rules/class-unique.php
Normal file
96
inc/helpers/validation-rules/class-unique.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter is unique.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Helpers/Validation_Rules
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Helpers\Validation_Rules;
|
||||
|
||||
use WP_Ultimo\Dependencies\Rakit\Validation\Rule;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Adds a validation rules that allows us to check if a given parameter is unique.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Unique extends Rule {
|
||||
|
||||
/**
|
||||
* Error message to be returned when this value has been used.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var string
|
||||
*/
|
||||
protected $message = ':attribute :value has been used';
|
||||
|
||||
/**
|
||||
* Parameters that this rule accepts.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var array
|
||||
*/
|
||||
protected $fillableParams = array('model', 'column', 'self_id'); // phpcs:ignore
|
||||
|
||||
/**
|
||||
* Performs the actual check.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param mixed $value Value being checked.
|
||||
*/
|
||||
public function check($value) : bool {
|
||||
|
||||
$this->requireParameters(array(
|
||||
'model',
|
||||
'column',
|
||||
));
|
||||
|
||||
$column = $this->parameter('column');
|
||||
$model = $this->parameter('model');
|
||||
$self_id = $this->parameter('self_id');
|
||||
|
||||
switch ($model) {
|
||||
case '\WP_User':
|
||||
$callback = 'get_user_by';
|
||||
break;
|
||||
default:
|
||||
$callback = array($model, 'get_by');
|
||||
break;
|
||||
}
|
||||
|
||||
// do query
|
||||
$existing = call_user_func($callback, $column, $value);
|
||||
|
||||
$user_models = array(
|
||||
'\WP_User',
|
||||
'\WP_Ultimo\Models\Customer',
|
||||
);
|
||||
|
||||
/*
|
||||
* Customize the error message for the customer.
|
||||
*/
|
||||
if (in_array($model, $user_models, true)) {
|
||||
|
||||
$this->message = __('A customer with the same email address or username already exists.', 'wp-ultimo');
|
||||
|
||||
} // end if;
|
||||
|
||||
if (!$existing) {
|
||||
|
||||
return true;
|
||||
|
||||
} // end if;
|
||||
|
||||
$id = method_exists($existing, 'get_id') ? $existing->get_id() : $existing->id;
|
||||
|
||||
return absint($id) === absint($self_id);
|
||||
|
||||
} // end check;
|
||||
|
||||
} // end class Unique;
|
Reference in New Issue
Block a user