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