| 1 |
<?php |
| 2 |
|
| 3 |
declare(strict_types=1); |
| 4 |
|
| 5 |
/** |
| 6 |
* Setting: Player Version |
| 7 |
* |
| 8 |
* @package Beyondwords\Wordpress |
| 9 |
* @author Stuart McAlpine <stu@beyondwords.io> |
| 10 |
* @since 4.0.0 |
| 11 |
*/ |
| 12 |
|
| 13 |
namespace Beyondwords\Wordpress\Component\Settings\PlayerVersion; |
| 14 |
|
| 15 |
use Beyondwords\Wordpress\Component\Settings\SettingsUtils; |
| 16 |
|
| 17 |
/** |
| 18 |
* PlayerVersion setup |
| 19 |
* |
| 20 |
* @since 4.0.0 |
| 21 |
*/ |
| 22 |
class PlayerVersion |
| 23 |
{ |
| 24 |
/** |
| 25 |
* Version 0: "Legacy" |
| 26 |
*/ |
| 27 |
public const LEGACY_VERSION = '0'; |
| 28 |
|
| 29 |
/** |
| 30 |
* Version 1: "Latest" |
| 31 |
*/ |
| 32 |
public const LATEST_VERSION = '1'; |
| 33 |
|
| 34 |
/** |
| 35 |
* API Client |
| 36 |
*/ |
| 37 |
private $apiClient; |
| 38 |
|
| 39 |
/** |
| 40 |
* Constructor |
| 41 |
*/ |
| 42 |
public function __construct($apiClient) |
| 43 |
{ |
| 44 |
$this->apiClient = $apiClient; |
| 45 |
|
| 46 |
add_action('admin_init', array($this, 'init')); |
| 47 |
add_action('add_option_beyondwords_player_version', array($this, 'onAddPlayerVersionOption'), 10, 2); |
| 48 |
add_action('update_option_beyondwords_player_version', array($this, 'onUpdatePlayerVersionOption'), 10, 2); |
| 49 |
} |
| 50 |
|
| 51 |
/** |
| 52 |
* Init setting. |
| 53 |
* |
| 54 |
* @since 4.0.0 |
| 55 |
* |
| 56 |
* @return void |
| 57 |
*/ |
| 58 |
public function init() |
| 59 |
{ |
| 60 |
if (! SettingsUtils::hasApiSettings()) { |
| 61 |
return; |
| 62 |
} |
| 63 |
|
| 64 |
register_setting( |
| 65 |
'beyondwords', |
| 66 |
'beyondwords_player_version', |
| 67 |
[ |
| 68 |
'default' => PlayerVersion::LATEST_VERSION, |
| 69 |
'sanitize_callback' => array($this, 'sanitize'), |
| 70 |
] |
| 71 |
); |
| 72 |
|
| 73 |
add_settings_field( |
| 74 |
'beyondwords-player-version', |
| 75 |
__('Player version', 'speechkit'), |
| 76 |
array($this, 'render'), |
| 77 |
'beyondwords', |
| 78 |
'player' |
| 79 |
); |
| 80 |
} |
| 81 |
|
| 82 |
/** |
| 83 |
* Render setting field. |
| 84 |
* |
| 85 |
* @since 4.0.0 |
| 86 |
* |
| 87 |
* @return void |
| 88 |
**/ |
| 89 |
public function render() |
| 90 |
{ |
| 91 |
$playerVersion = get_option('beyondwords_player_version', PlayerVersion::LATEST_VERSION); |
| 92 |
|
| 93 |
// Remove any "reverted" notifications if player is "Latest" |
| 94 |
if ($playerVersion === PlayerVersion::LATEST_VERSION) { |
| 95 |
delete_transient('beyondwords_player_reverted'); |
| 96 |
} |
| 97 |
|
| 98 |
// Sync Player Version with API |
| 99 |
$playerSettings = $this->apiClient->getPlayerSettings(); |
| 100 |
|
| 101 |
$syncedPlayerMessage = ''; |
| 102 |
|
| 103 |
// TODO refactor - it's a bit messy :/ |
| 104 |
// Does the API response have a player_version? |
| 105 |
if ($playerSettings && array_key_exists('player_version', $playerSettings)) { |
| 106 |
$apiPlayerVersion = $playerSettings['player_version']; |
| 107 |
|
| 108 |
if ($apiPlayerVersion !== $playerVersion) { |
| 109 |
$allPlayerVersions = PlayerVersion::getAllPlayerVersions(); |
| 110 |
|
| 111 |
if (array_key_exists($apiPlayerVersion, $allPlayerVersions)) { |
| 112 |
$versionLabel = $allPlayerVersions[$apiPlayerVersion]; |
| 113 |
$syncedPlayerMessage = sprintf( |
| 114 |
/* translators: %s is replaced with the player version from the BeyondWords API */ |
| 115 |
__('The player version on this WordPress site doesn’t match the “%s” player in your BeyondWords account. Saving the WordPress plugin settings will update your BeyondWords account to keep the player version in sync.', 'speechkit'), // phpcs:ignore Generic.Files.LineLength.TooLong |
| 116 |
$versionLabel |
| 117 |
); |
| 118 |
} else { |
| 119 |
$syncedPlayerMessage = __('Your BeyondWords account is currently using another player.', 'speechkit'); // phpcs:ignore Generic.Files.LineLength.TooLong |
| 120 |
} |
| 121 |
} |
| 122 |
} |
| 123 |
?> |
| 124 |
<div class="beyondwords-setting--player--player-version"> |
| 125 |
<select name="beyondwords_player_version"> |
| 126 |
<?php |
| 127 |
$playerVersions = PlayerVersion::getAllPlayerVersions(); |
| 128 |
|
| 129 |
foreach ($playerVersions as $version => $label) { |
| 130 |
printf( |
| 131 |
'<option value="%s" %s>%s</option>', |
| 132 |
esc_attr($version), |
| 133 |
selected($version, $playerVersion), |
| 134 |
esc_html($label) |
| 135 |
); |
| 136 |
} |
| 137 |
?> |
| 138 |
</select> |
| 139 |
</div> |
| 140 |
<?php if ($syncedPlayerMessage) : ?> |
| 141 |
<p class="description" style="color: #b32d2e;"> |
| 142 |
<?php echo esc_html($syncedPlayerMessage); ?> |
| 143 |
</p> |
| 144 |
<?php endif; ?> |
| 145 |
<p class="description"> |
| 146 |
<?php |
| 147 |
_e( |
| 148 |
'We sync changes to the player version with your Beyondwords account when these settings are saved.', // phpcs:ignore Generic.Files.LineLength.TooLong |
| 149 |
'speechkit' |
| 150 |
); |
| 151 |
?> |
| 152 |
</p> |
| 153 |
<p class="description"> |
| 154 |
<?php |
| 155 |
_e( |
| 156 |
'If caching is enabled you may need to clear the cache to change the player version for existing posts.', // phpcs:ignore Generic.Files.LineLength.TooLong |
| 157 |
'speechkit' |
| 158 |
); |
| 159 |
?> |
| 160 |
</p> |
| 161 |
<?php |
| 162 |
} |
| 163 |
|
| 164 |
/** |
| 165 |
* Sanitise the setting value. |
| 166 |
* |
| 167 |
* No sanitization is performed in this method. Instead we use it to set a |
| 168 |
* transient notification if the setting changes from "Latest" to "Legacy" |
| 169 |
* to help us provide technical support for player downgrades. |
| 170 |
* |
| 171 |
* @since 4.0.0 |
| 172 |
* |
| 173 |
* @param array $value The submitted value. |
| 174 |
* |
| 175 |
* @return void |
| 176 |
**/ |
| 177 |
public function sanitize($value) |
| 178 |
{ |
| 179 |
$currentPlayerVersion = get_option('beyondwords_player_version'); |
| 180 |
|
| 181 |
// Hide "reverted" notification if player is "Latest" |
| 182 |
if ($value === PlayerVersion::LATEST_VERSION) { |
| 183 |
delete_transient('beyondwords_player_reverted'); |
| 184 |
} |
| 185 |
|
| 186 |
// Are we downgrading from "Latest" to "Legacy"? |
| 187 |
if ($currentPlayerVersion === PlayerVersion::LATEST_VERSION && $value === PlayerVersion::LEGACY_VERSION) { |
| 188 |
// Display "reverted" notification for 7 days |
| 189 |
set_transient('beyondwords_player_reverted', gmdate(DATE_ISO8601), 604800); |
| 190 |
} |
| 191 |
|
| 192 |
return $value; |
| 193 |
} |
| 194 |
|
| 195 |
/** |
| 196 |
* Fires after the beyondwords_player_version option has been added. |
| 197 |
* |
| 198 |
* @SuppressWarnings(PHPMD.UnusedFormalParameter) |
| 199 |
* |
| 200 |
* @since 4.0.0 |
| 201 |
* |
| 202 |
* @param string $option Name of the option to add. |
| 203 |
* @param mixed $value Value of the option. |
| 204 |
* |
| 205 |
* @return void |
| 206 |
*/ |
| 207 |
public function onAddPlayerVersionOption($option, $value) |
| 208 |
{ |
| 209 |
$this->syncPlayerVersionSettingWithApi($value); |
| 210 |
} |
| 211 |
|
| 212 |
/** |
| 213 |
* Fires after the value of the beyondwords_player_version option has been |
| 214 |
* successfully updated. |
| 215 |
* |
| 216 |
* @SuppressWarnings(PHPMD.UnusedFormalParameter) |
| 217 |
* |
| 218 |
* @since 4.0.0 |
| 219 |
* |
| 220 |
* @param mixed $oldValue The old option value. |
| 221 |
* @param mixed $value The new option value. |
| 222 |
* |
| 223 |
* @return void |
| 224 |
*/ |
| 225 |
public function onUpdatePlayerVersionOption($oldValue, $value) |
| 226 |
{ |
| 227 |
$this->syncPlayerVersionSettingWithApi($value); |
| 228 |
} |
| 229 |
|
| 230 |
/** |
| 231 |
* Sync "Player version" setting with BeyondWords API. |
| 232 |
* |
| 233 |
* @since 4.0.0 |
| 234 |
* |
| 235 |
* @param mixed $value The new option value. |
| 236 |
* |
| 237 |
* @return void |
| 238 |
*/ |
| 239 |
public function syncPlayerVersionSettingWithApi($value) |
| 240 |
{ |
| 241 |
// Exit if there are no API settings (required to make the API call) |
| 242 |
if (! SettingsUtils::hasApiSettings()) { |
| 243 |
return; |
| 244 |
} |
| 245 |
|
| 246 |
// Send updated "Player version" value to our API |
| 247 |
$response = $this->apiClient->updatePlayerSettings([ |
| 248 |
'player_version' => $value, |
| 249 |
]); |
| 250 |
|
| 251 |
if ( |
| 252 |
! is_array($response) |
| 253 |
|| ! array_key_exists('player_version', $response) |
| 254 |
|| $response['player_version'] !== $value |
| 255 |
) { |
| 256 |
$errors = get_transient('beyondwords_settings_errors', []); |
| 257 |
|
| 258 |
if (empty($value)) { |
| 259 |
$errors['Settings/PlayerVersion'] = __( |
| 260 |
'There was an error syncing the player version with your BeyondWords account. The versions may be different. Sign in to your BeyondWords dashboard and change the player version there if you need them to be in sync.', // phpcs:ignore Generic.Files.LineLength.TooLong |
| 261 |
'speechkit' |
| 262 |
); |
| 263 |
set_transient('beyondwords_settings_errors', $errors); |
| 264 |
} |
| 265 |
} |
| 266 |
} |
| 267 |
|
| 268 |
/** |
| 269 |
* Get all player versions. |
| 270 |
* |
| 271 |
* @since 4.0.0 |
| 272 |
* |
| 273 |
* @static |
| 274 |
* |
| 275 |
* @return string[] Associative array of player versions and labels. |
| 276 |
**/ |
| 277 |
public static function getAllPlayerVersions() |
| 278 |
{ |
| 279 |
return [ |
| 280 |
PlayerVersion::LATEST_VERSION => __('Latest', 'speechkit'), |
| 281 |
PlayerVersion::LEGACY_VERSION => __('Legacy', 'speechkit'), |
| 282 |
]; |
| 283 |
} |
| 284 |
} |
| 285 |
|