| 1 |
<?php |
| 2 |
/** |
| 3 |
* Validation class |
| 4 |
* |
| 5 |
* @package WPZinc\Social |
| 6 |
* @author WP Zinc |
| 7 |
*/ |
| 8 |
|
| 9 |
namespace WPZinc\Social; |
| 10 |
|
| 11 |
/** |
| 12 |
* Provides several validation functions which the Plugin can run |
| 13 |
* to ensure features work as expected. |
| 14 |
* |
| 15 |
* @package WPZinc\Social |
| 16 |
* @author WP Zinc |
| 17 |
* @version 3.8.1 |
| 18 |
*/ |
| 19 |
class Validation { |
| 20 |
|
| 21 |
/** |
| 22 |
* Holds the base class object. |
| 23 |
* |
| 24 |
* @since 3.8.1 |
| 25 |
* |
| 26 |
* @var object |
| 27 |
*/ |
| 28 |
public $base; |
| 29 |
|
| 30 |
/** |
| 31 |
* Constructor |
| 32 |
* |
| 33 |
* @since 3.8.1 |
| 34 |
* |
| 35 |
* @param object $base Base Plugin Class. |
| 36 |
*/ |
| 37 |
public function __construct( $base ) { |
| 38 |
|
| 39 |
// Store base class. |
| 40 |
$this->base = $base; |
| 41 |
|
| 42 |
} |
| 43 |
|
| 44 |
/** |
| 45 |
* Checks if the WordPress timezone matches the given API Timezone, |
| 46 |
* which could be a global API timezone or a profile-specific timezone. |
| 47 |
* |
| 48 |
* @since 3.8.1 |
| 49 |
* |
| 50 |
* @param string $api_profile_timezone API Timezone. |
| 51 |
* @param string $api_profile_name API Profile Name (e.g. @n7TestAcct). |
| 52 |
* @param string $api_profile_change_timezone_url URL to API service where the user can change the timezone. |
| 53 |
* @return mixed \WP_Error | true |
| 54 |
*/ |
| 55 |
public function timezones_match( $api_profile_timezone = '', $api_profile_name = '', $api_profile_change_timezone_url = '#' ) { |
| 56 |
|
| 57 |
// Pass test if we don't have API access. |
| 58 |
if ( ! $this->base->get_class( 'settings' )->account_connected() ) { |
| 59 |
return true; |
| 60 |
} |
| 61 |
|
| 62 |
// Pass test if the API date couldn't be fetched. |
| 63 |
if ( ! $api_profile_timezone ) { |
| 64 |
return true; |
| 65 |
} |
| 66 |
|
| 67 |
// Fetch timezones for WordPress, Server and API. |
| 68 |
$wordpress_timezone = $this->base->get_class( 'date' )->convert_wordpress_gmt_offset_to_offset_value( get_option( 'gmt_offset' ) ); |
| 69 |
|
| 70 |
// Fetch the current date and time, to the minute, for each of the timezones. |
| 71 |
try { |
| 72 |
$wordpress_date = new \DateTime( 'now', new \DateTimeZone( $wordpress_timezone ) ); |
| 73 |
$api_date = new \DateTime( 'now', new \DateTimeZone( $api_profile_timezone ) ); |
| 74 |
} catch ( \Exception $e ) { |
| 75 |
return new \WP_Error( $this->base->plugin->filter_name . '_date_time_zone_error', $e->getMessage() ); |
| 76 |
} |
| 77 |
|
| 78 |
// If the three dates don't match, scheduling won't work as expected. |
| 79 |
$wordpress_date = $wordpress_date->format( 'Y-m-d H:i' ); |
| 80 |
$api_date = $api_date->format( 'Y-m-d H:i' ); |
| 81 |
|
| 82 |
if ( $api_date !== $wordpress_date ) { |
| 83 |
return new \WP_Error( |
| 84 |
$this->base->plugin->filter_name . '_timezones_invalid', |
| 85 |
sprintf( |
| 86 |
'%1$s<br /><br />%2$s<br />%3$s %4$s (%5$s) [<a href="%6$s" target="_blank">%7$s</a>]<br />%8$s Profile Timezone: %9$s (%10$s) [<a href="%11$s" target="_blank">%12$s</a>]', |
| 87 |
__( 'This Profile\'s Timezone does not match your WordPress timezone. They must be the same, to ensure that statuses can be scheduled, and are scheduled at the correct time.', 'wp-to-buffer' ), |
| 88 |
__( 'Right now, your timezones are configured as:', 'wp-to-buffer' ), |
| 89 |
__( 'WordPress Timezone:', 'wp-to-buffer' ), |
| 90 |
esc_html( $wordpress_timezone ), |
| 91 |
esc_html( $wordpress_date ), |
| 92 |
admin_url( 'options-general.php#timezone_string' ), |
| 93 |
__( 'Fix', 'wp-to-buffer' ), |
| 94 |
esc_html( $api_profile_name ), |
| 95 |
esc_html( $api_profile_timezone ), |
| 96 |
esc_html( $api_date ), |
| 97 |
esc_html( $api_profile_change_timezone_url ), |
| 98 |
__( 'Fix', 'wp-to-buffer' ) |
| 99 |
) |
| 100 |
); |
| 101 |
} |
| 102 |
|
| 103 |
} |
| 104 |
|
| 105 |
/** |
| 106 |
* Iterates through all associative statuses for a given Post Type, |
| 107 |
* checking whether a profile and action combination have two or more statuses |
| 108 |
* that are the same. |
| 109 |
* |
| 110 |
* @since 3.1.1 |
| 111 |
* |
| 112 |
* @param array $settings Settings. |
| 113 |
* @return false|array Profile ID and Action with duplicates, or false |
| 114 |
*/ |
| 115 |
public function check_for_duplicates( $settings ) { |
| 116 |
|
| 117 |
// Define the status keys to compare. |
| 118 |
$status_keys_to_compare = array( |
| 119 |
'message', |
| 120 |
'conditions', |
| 121 |
'terms', |
| 122 |
'custom_fields', |
| 123 |
); |
| 124 |
|
| 125 |
/** |
| 126 |
* Defines the key values to compare across all statuses for a Post Type and Social Profile |
| 127 |
* combination, to ensure no duplicate statuses have been defined. |
| 128 |
* |
| 129 |
* @since 3.1.1 |
| 130 |
* |
| 131 |
* @param array $status_keys_to_compare Status Key Values to Compare. |
| 132 |
*/ |
| 133 |
$status_keys_to_compare = apply_filters( $this->base->plugin->filter_name . '_validate_check_for_duplicates_status_keys', $status_keys_to_compare ); |
| 134 |
|
| 135 |
// Iterate through each profile. |
| 136 |
foreach ( $settings as $profile_id => $actions ) { |
| 137 |
// Iterate through each action for this profile. |
| 138 |
foreach ( $actions as $action => $statuses ) { |
| 139 |
// Check if this action is enabled. |
| 140 |
if ( ! isset( $statuses['enabled'] ) || ! $statuses['enabled'] ) { |
| 141 |
continue; |
| 142 |
} |
| 143 |
|
| 144 |
// Build serialized strings for each status, so we can compare them. |
| 145 |
$statuses_serialized = array(); |
| 146 |
foreach ( $statuses['status'] as $status ) { |
| 147 |
// Build status comprising of just the keys we want to compare with other statuses. |
| 148 |
$status_compare = array(); |
| 149 |
foreach ( $status_keys_to_compare as $status_key_to_compare ) { |
| 150 |
$status_compare[ $status_key_to_compare ] = ( isset( $status[ $status_key_to_compare ] ) ? $status[ $status_key_to_compare ] : '' ); |
| 151 |
} |
| 152 |
|
| 153 |
// Add the status compare to the serialized array. |
| 154 |
$statuses_serialized[] = serialize( $status_compare ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions |
| 155 |
} |
| 156 |
|
| 157 |
// Check if any two values in our array are the same. |
| 158 |
// If so, this means the user is using the same status message twice, which may cause an issue. |
| 159 |
$counts = array_count_values( $statuses_serialized ); |
| 160 |
foreach ( $counts as $count ) { |
| 161 |
if ( $count > 1 ) { |
| 162 |
// Return the Profile ID and Action that contains duplicate statuses. |
| 163 |
return array( |
| 164 |
'profile_id' => $profile_id, |
| 165 |
'action' => $action, |
| 166 |
); |
| 167 |
} |
| 168 |
} |
| 169 |
} |
| 170 |
} |
| 171 |
|
| 172 |
// No duplicates found. |
| 173 |
return false; |
| 174 |
|
| 175 |
} |
| 176 |
|
| 177 |
} |
| 178 |
|