PluginProbe
Photonic Gallery & Lightbox for Flickr, SmugMug & Others / 3.36
Photonic Gallery & Lightbox for Flickr, SmugMug & Others v3.36
3.36 3.35 3.34 3.33 2.19 2.20 2.21 2.22 2.23 2.24 2.25 2.26 2.27 2.28 2.29 2.30 2.31 2.32 2.33 2.34 2.40 2.41 2.42 2.43 2.44 All 141 releases
← All changes | Admin/Authentication.php +364 -415 2.433.36 View file →
@@ -1,415 +1,364 @@
1 -<?php
2 -namespace Photonic_Plugin\Admin;
3 -
4 -use Photonic_Plugin\Core\Photonic;
5 -use Photonic_Plugin\Modules\Authenticator;
6 -use Photonic_Plugin\Modules\Core;
7 -use Photonic_Plugin\Modules\Flickr;
8 -use Photonic_Plugin\Modules\Google_Photos;
9 -use Photonic_Plugin\Modules\Instagram;
10 -use Photonic_Plugin\Modules\SmugMug;
11 -use Photonic_Plugin\Modules\Zenfolio;
12 -
13 -require_once('Admin_Page.php');
14 -
15 -class Authentication extends Admin_Page {
16 - private static $instance;
17 -
18 - private function __construct() {
19 - require_once(PHOTONIC_PATH."/Modules/Instagram.php");
20 - require_once(PHOTONIC_PATH."/Modules/Zenfolio.php");
21 - }
22 -
23 - static function get_instance() {
24 - if (self::$instance == null) {
25 - self::$instance = new Authentication();
26 - }
27 - return self::$instance;
28 - }
29 -
30 - function render_content() {
31 - ?>
32 - <form method="post" id="photonic-auth-form">
33 - <h2 id="#photonic-flickr-auth-section" class="photonic-section">Flickr</h2>
34 - <?php $this->display_flickr(); ?>
35 -
36 - <h2 id="#photonic-smugmug-auth-section" class="photonic-section">SmugMug</h2>
37 - <?php $this->display_smugmug();?>
38 -
39 - <h2 id="#photonic-google-auth-section" class="photonic-section">Google Photos</h2>
40 - <?php $this->display_google(); ?>
41 -
42 - <!-- <h3 id="#photonic-google-auth-section-bundled">Google Photos</h3>
43 - --><?php /*$this->display_google_bundled_token_getter(); */?>
44 -
45 - <h2 id="#photonic-instagram-auth-section" class="photonic-section">Instagram</h2>
46 - <?php $this->display_instagram(); ?>
47 -
48 - <h2 id="#photonic-zenfolio-auth-section" class="photonic-section">Zenfolio</h2>
49 - <?php $this->display_zenfolio(); ?>
50 - </form>
51 - <?php
52 - }
53 -
54 - function display_flickr() {
55 - global $photonic_flickr_api_key, $photonic_flickr_api_secret, $photonic_flickr_access_token;
56 - $auth = [
57 - 'api_key' => trim($photonic_flickr_api_key),
58 - 'api_secret' => trim($photonic_flickr_api_secret),
59 - 'token' => trim($photonic_flickr_access_token),
60 - ];
61 - $this->show_token_section($auth, 'flickr', 'Flickr');
62 - }
63 -
64 - function display_smugmug() {
65 - global $photonic_smug_api_key, $photonic_smug_api_secret, $photonic_smug_access_token;
66 - $auth = [
67 - 'api_key' => !empty($photonic_smug_api_key) ? trim($photonic_smug_api_key) : '86MZ8N8TqJf5x2fQ4FRWXRtJ3C6Jm7XV',
68 - 'api_secret' => trim($photonic_smug_api_secret),
69 - 'token' => trim($photonic_smug_access_token),
70 - ];
71 - $this->show_token_section($auth, 'smug', 'SmugMug');
72 - }
73 -
74 - function display_google() {
75 - global $photonic_google_client_id, $photonic_google_client_secret, $photonic_google_refresh_token;
76 - echo "<div class=\"photonic-token-header\">\n";
77 - if (empty($photonic_google_client_id) || empty($photonic_google_client_secret)) {
78 - echo sprintf(esc_html__('Please set up your Google Client ID and Client Secret under %s', 'photonic'),
79 - '<em>Photonic &rarr; Settings &rarr; Google Photos &rarr; Google Photos Settings</em>');
80 - }
81 - else {
82 - $parameters = Core::parse_parameters($_SERVER['QUERY_STRING']);
83 -
84 - if (!empty($photonic_google_refresh_token)) {
85 - $this->print_auth_done_all_good();
86 - }
87 -
88 - echo "</div>\n";
89 - echo "<div class=\"photonic-token-header\">\n";
90 - esc_html_e("You first have to authorize Photonic to connect to your Google account.", 'photonic');
91 - echo "<br/>\n";
92 - if (!isset($parameters['code']) || !isset($parameters['source']) || $parameters['source'] != 'google') {
93 -
94 - $url = add_query_arg('test', 'test');
95 - $url = remove_query_arg('test', $url);
96 - $parameters = [
97 - 'response_type' => 'code',
98 - 'redirect_uri' => admin_url('admin.php?page=photonic-auth&source=google'),
99 - 'client_id' => $photonic_google_client_id,
100 - 'scope' => 'https://www.googleapis.com/auth/photoslibrary.readonly',
101 - 'access_type' => 'offline',
102 - 'state' => md5($photonic_google_client_secret.'google').'::'.urlencode($url),
103 - 'prompt' => 'consent',
104 - ];
105 - $url = 'https://accounts.google.com/o/oauth2/auth?'.Authenticator::build_query($parameters);
106 -
107 - echo "<a href='".$url."' class='button button-primary'>".esc_html__('Step 1: Authenticate', 'photonic')."</a>";
108 -// echo "<a href='".$module->get_authorization_url(['redirect_uri' => admin_url('admin.php?page=photonic-auth&source=google'), 'prompt' => 'consent'])."' class='button button-primary'>".
109 -// esc_html__('Step 1: Authenticate', 'photonic')."</a>";
110 - echo "</div>\n";
111 - echo "<div class=\"photonic-token-header\">\n";
112 - echo esc_html__("Next, you have to obtain the token.", 'photonic').'<br/>';
113 - echo "<span class='button photonic-helper-button-disabled'>".
114 - esc_html__('Step 2: Obtain Token', 'photonic')."</span>";
115 - }
116 - else {
117 - echo "<span class='button photonic-helper-button-disabled'>".
118 - esc_html__('Step 1: Authenticate', 'photonic')."</span>";
119 - echo "</div>\n";
120 - echo "<div class=\"photonic-token-header\">\n";
121 - echo esc_html__("Next, you have to obtain the token.", 'photonic').'<br/>';
122 - echo "<a href='#' class='button button-primary photonic-google-refresh'>".
123 - esc_html__('Step 2: Obtain Token', 'photonic')."</a>";
124 - echo '<input type="hidden" value="'.$parameters['code'].'" id="photonic-google-oauth-code"/>';
125 - echo '<input type="hidden" value="'.$parameters['state'].'" id="photonic-google-oauth-state"/>';
126 - }
127 - }
128 - echo "</div>\n";
129 - echo '<div class="result" id="google-result">&nbsp;</div>';
130 - echo sprintf(esc_html__('If you are facing issues with the authentication please follow the workaround %1$shere%2$s', 'photonic'),
131 - '<a href="https://aquoid.com/plugins/photonic/google-photos/#auth-workaround" target="_blank">',
132 - '</a>');
133 - }
134 -
135 - function display_google_bundled() {
136 - global $photonic_google_refresh_token;
137 - echo "<div class=\"photonic-token-header\">\n";
138 -
139 - require_once(PHOTONIC_PATH."/Modules/Google_Photos.php");
140 - $module = Google_Photos::get_instance();
141 - $parameters = Core::parse_parameters($_SERVER['QUERY_STRING']);
142 -
143 - if (!empty($photonic_google_refresh_token) && $module->refresh_token_valid) {
144 - $this->print_auth_done_all_good();
145 - }
146 -
147 - echo "</div>\n";
148 - echo "<div class=\"photonic-token-header\">\n";
149 - esc_html_e("You first have to authorize Photonic to connect to your Google account.", 'photonic');
150 - echo "<br/>\n";
151 - if (!isset($parameters['code']) || !isset($parameters['source']) || $parameters['source'] != 'google') {
152 - echo "<a href='".$module->get_authorization_url([
153 - 'redirect_uri' => 'https://aquoid.com/photonic-router/google.php',
154 - 'state' => admin_url('admin.php?page=photonic-auth&source=google'),
155 - 'prompt' => 'consent',
156 - ])."' class='button button-primary'>".
157 - esc_html__('Step 1: Authenticate', 'photonic')."</a>";
158 - echo "</div>\n";
159 - echo "<div class=\"photonic-token-header\">\n";
160 - echo esc_html__("Next, you have to obtain the token.", 'photonic').'<br/>';
161 - echo "<span class='button photonic-helper-button-disabled'>".
162 - esc_html__('Step 2: Obtain Token', 'photonic')."</span>";
163 - }
164 - else {
165 - echo "<span class='button photonic-helper-button-disabled'>".
166 - esc_html__('Step 1: Authenticate', 'photonic')."</span>";
167 - echo "</div>\n";
168 - echo "<div class=\"photonic-token-header\">\n";
169 - echo esc_html__("Next, you have to obtain the token.", 'photonic').'<br/>';
170 - echo "<a href='#' class='button button-primary photonic-google-refresh'>".
171 - esc_html__('Step 2: Obtain Token', 'photonic')."</a>";
172 - echo '<input type="hidden" value="'.$parameters['code'].'" id="photonic-google-oauth-code"/>';
173 - }
174 - echo "</div>\n";
175 - echo '<div class="result" id="google-result">&nbsp;</div>';
176 -
177 - echo "<div class=\"photonic-token-header\">\n";
178 - echo esc_html__("If the above method is not working due to conflicts with your site's security setup try an alternative method where the authentication happens on a different site.", 'photonic').'<br/>';
179 - echo "<a href='".$module->get_authorization_url([
180 - 'redirect_uri' => 'https://aquoid.com/photonic-router/google.php',
181 - 'prompt' => 'consent',
182 - 'state' => '',
183 - ])."' class='button button-primary' target='_blank'>".
184 - esc_html__("Authenticate using Photonic's website", 'photonic')."</a>";
185 - echo "</div>\n";
186 - }
187 -
188 - function display_instagram() {
189 - global $photonic_instagram_access_token;
190 - $auth = [
191 - 'api_key' => 'not-required-but-not-empty',
192 - 'api_secret' => 'not-required-but-not-empty',
193 - 'token' => trim($photonic_instagram_access_token),
194 - ];
195 -
196 - $this->show_token_section_header($auth, 'Instagram');
197 - $response = Core::parse_parameters($_SERVER['QUERY_STRING']);
198 - if (empty($response['access_token'])) {
199 - echo "<a href='https://api.instagram.com/oauth/authorize/?client_id=1089620424711320&scope=user_profile,user_media&redirect_uri=https://aquoid.com/photonic-router/instagram/&state=" .
200 - admin_url('admin.php?page=photonic-auth') . "&response_type=code' class='button button-primary'>" .
201 - $this->get_login_button('Instagram'). "</a>";
202 - }
203 - else if (!empty($response['access_token'])) {
204 - echo "<span class='button photonic-helper-button-disabled'>" . $this->get_login_button('Instagram') . "</span>";
205 - echo '<div class="result">'.
206 - (!empty($response['access_token']) ? 'Access token: <code id="instagram-token">'.$response['access_token'].'</code><br/>' : '&nbsp;').
207 - (!empty($response['expires_in']) ? '<input type="hidden" id="instagram-token-expires-in" value="'.$response['expires_in'].'" />' : '').
208 - (!empty($response['user_id']) ? '<input type="hidden" id="instagram-token-client-id" value="'.$response['user_id'].'" />' : '').
209 - (!empty($response['user']) ? 'User name: <code id="instagram-token-user">'.$response['user'].'</code><br/>' : '').
210 - '</div>';
211 -
212 - echo "<a href='#' class='button button-primary photonic-save-token' data-photonic-provider='instagram'>" . esc_html__('Save Token', 'photonic') . "</a>";
213 - }
214 - }
215 -
216 - function display_zenfolio() {
217 - global $photonic_zenfolio_default_user;
218 - $gallery = Zenfolio::get_instance();
219 -
220 - echo "<div class=\"photonic-token-header\">\n";
221 - if (empty($photonic_zenfolio_default_user)) {
222 - echo sprintf(esc_html__('Please set up the default user for Zenfolio under %s', 'photonic'),
223 - '<em>Photonic &rarr; Settings &rarr; Zenfolio &rarr; Zenfolio Photo Settings &rarr; Default User</em>')."\n";
224 - }
225 - else if (!empty($gallery->token)) {
226 - $this->print_auth_done_all_good();
227 - }
228 - echo "</div>\n";
229 -
230 - $response = Core::parse_parameters($_SERVER['QUERY_STRING']);
231 - if (!empty($photonic_zenfolio_default_user) && (empty($response['provider']) || 'zenfolio' !== $response['provider'])) {
232 - echo "<label>".esc_html__('Password:', 'photonic')."<input type='password' name='zenfolio-password' id='zenfolio-password'></label>";
233 - }
234 -
235 - echo "<div style='display: block; width: 100%;'>\n";
236 - if (!empty($photonic_zenfolio_default_user) && (empty($response['provider']) || 'zenfolio' !== $response['provider'])) {
237 - echo "<a href='#' class='button button-primary' data-photonic-provider='zenfolio' style='margin-right: 1em;'>" . esc_html__('Login and Authenticate', 'photonic') . "</a>";
238 - }
239 -
240 - if (!empty($gallery->token)) {
241 - echo "<a href='#' class='button button-primary photonic-zenfolio-delete'>".esc_html__('Delete current Zenfolio authentication data', 'photonic')."</a>";
242 - }
243 - echo "</div>\n";
244 -
245 - echo '<div class="result" id="zenfolio-result">&nbsp;</div>';
246 - }
247 -
248 - private function show_token_section($auth, $provider_slug, $provider_text) {
249 - $this->show_token_section_header($auth, $provider_text);
250 - if (!empty($auth['api_key']) && !empty($auth['api_secret'])) {
251 - $this->show_token_section_body($provider_slug, $provider_text);
252 - }
253 - else {
254 - echo '<div class="result" id="'.$provider_slug.'-result">&nbsp;</div>';
255 - }
256 - }
257 -
258 - /**
259 - * @param $auth array
260 - * @param $provider string
261 - */
262 - private function show_token_section_header($auth, $provider) {
263 - echo "<div class=\"photonic-token-header\">\n";
264 -
265 - if (empty($auth['api_key']) || empty($auth['api_secret'])) {
266 - echo sprintf(esc_html__('Please set up your %1$s API key under %2$s.', 'photonic'), $provider, sprintf('<em>Photonic &rarr; Settings &rarr; %1$s &rarr; %1$s Settings</em>', $provider));
267 - }
268 - else if ($provider == 'Instagram' && !empty($auth['token'])) {
269 - require_once(PHOTONIC_PATH."/Modules/Instagram.php");
270 - $module = Instagram::get_instance();
271 - $expiring_soon = $module->is_token_expiring_soon(30);
272 - if (is_null($expiring_soon)) {
273 - // Not yet authenticated with the new API.
274 - echo '<p class="notice notice-error">'.esc_html__('Your authentication credentials are for the old Instagram API. Please reauthenticate to keep Photonic working.', 'photonic').'</p><br/>';
275 - }
276 - else if ($expiring_soon === 1) {
277 - echo '<p class="notice notice-warning">'.esc_html__('Your authentication credentials are expiring soon. Please reauthenticate to keep Photonic working.', 'photonic').'</p><br/>';
278 - }
279 - else if ($expiring_soon === -1) {
280 - echo '<p class="notice notice-error">'.esc_html__('Your authentication credentials have expired! Please reauthenticate to keep Photonic working.', 'photonic').'</p><br/>';
281 - }
282 - else {
283 - $cached_token = $module->get_cached_token();
284 -
285 - if (!empty($cached_token) && !empty($cached_token['user'])) {
286 - $this->print_auth_done_all_good(sprintf(esc_html__('You are logged in as %1$s.', 'photonic'), '<code>'.$cached_token['user'].'</code>'));
287 - }
288 - else {
289 - $this->print_auth_done_all_good();
290 - }
291 - }
292 - }
293 - else if (!empty($auth['token'])) {
294 - $this->print_auth_done_all_good();
295 - }
296 - echo "</div>\n";
297 - }
298 -
299 - /**
300 - * @param $provider
301 - * @param $provider_text
302 - */
303 - public function show_token_section_body($provider, $provider_text) {
304 - $photonic_authentication = get_option('photonic_authentication');
305 - $response = Core::parse_parameters($_SERVER['QUERY_STRING']);
306 -
307 - if (empty($response['provider']) || (!empty($response['provider']) && $provider !== $response['provider'])) {
308 - echo "<a href='#' class='button button-primary photonic-token-request' data-photonic-provider='$provider'>" . $this->get_login_button($provider_text) . "</a>";
309 - }
310 - else if (!empty($response['oauth_token']) && !empty($response['oauth_verifier'])) {
311 - if (in_array($provider, ['flickr', 'smug', 'smugmug'])) {
312 - if ($provider == 'flickr') {
313 - require_once(PHOTONIC_PATH."/Modules/Flickr.php");
314 - $module = Flickr::get_instance();
315 - }
316 - else {
317 - require_once(PHOTONIC_PATH."/Modules/SmugMug.php");
318 - $module = SmugMug::get_instance();
319 - }
320 - echo "<span class='button photonic-helper-button-disabled'>" . $this->get_login_button($provider_text) . "</span>";
321 - $authorization = ['oauth_token' => $response['oauth_token'], 'oauth_verifier' => $response['oauth_verifier']];
322 - if (isset($photonic_authentication) && isset($photonic_authentication[$provider]) && isset($photonic_authentication[$provider]['oauth_token_secret'])) {
323 - $authorization['oauth_token_secret'] = $photonic_authentication[$provider]['oauth_token_secret'];
324 - }
325 - $access_token = $module->get_access_token($authorization);
326 - if (isset($access_token['oauth_token'])) {
327 - echo '<div class="result">Access Token: <code id="'.$provider.'-token">' . $access_token['oauth_token'] . '</code><br/>Access Token Secret: <code id="'.$provider.'-token-secret">' . $access_token['oauth_token_secret'] . '</code></div>'."\n";
328 - echo "<a href='#' class='button button-primary photonic-save-token' data-photonic-provider='$provider'>" . esc_html__('Save Token', 'photonic') . "</a>";
329 - }
330 - }
331 - }
332 - }
333 -
334 - private function print_auth_done_all_good($additional_msg = null) {
335 - echo '<p class="notice notice-success">';
336 - esc_html_e('You have already set up your authentication. Unless you wish to regenerate the token this step is not required. ', 'photonic');
337 - if (!empty($additional_msg)) {
338 - echo $additional_msg;
339 - }
340 - echo '</p>';
341 - }
342 -
343 - private function get_login_button($provider) {
344 - return sprintf(esc_html__('Login and get Access Token from %s', 'photonic'), $provider);
345 - }
346 -
347 - function obtain_token() {
348 - $provider = sanitize_text_field($_POST['provider']);
349 - if ($provider == 'google') {
350 - $code = esc_attr($_POST['code']);
351 - require_once(PHOTONIC_PATH."/Modules/Google_Photos.php");
352 - $module = Google_Photos::get_instance();
353 - global $photonic_google_use_own_keys, $photonic_google_client_id, $photonic_google_client_secret;
354 -// if (!empty($photonic_google_use_own_keys) || (!empty($photonic_google_client_id) && !empty($photonic_google_client_secret))) {
355 - $response = Photonic::http($module->access_token_URL(), 'POST', [
356 - 'code' => $code,
357 - 'grant_type' => 'authorization_code',
358 - 'client_id' => $module->client_id,
359 - 'client_secret' => $module->client_secret,
360 - 'redirect_uri' => admin_url('admin.php?page=photonic-auth&source=google'),
361 - ]);
362 - /* }
363 - else {
364 - $response = Photonic::http($module->access_token_URL(), 'POST', [
365 - 'code' => $code,
366 - 'grant_type' => 'authorization_code',
367 - 'client_id' => $module->client_id,
368 - 'client_secret' => $module->client_secret,
369 - 'redirect_uri' => 'https://aquoid.com/photonic-router/google.php',
370 - 'state' => admin_url('admin.php?page=photonic-auth&source=google'),
371 - ]);
372 - }*/
373 -
374 - if (!is_wp_error($response) && is_array($response)) {
375 - echo($response['body']);
376 - }
377 - else {
378 - }
379 - }
380 - else if ($provider == 'flickr') {
381 - require_once(PHOTONIC_PATH."/Modules/Flickr.php");
382 - $module = Flickr::get_instance();
383 - if (empty($_POST['oauth_token']) && empty($_POST['oauth_verifier'])) {
384 - $request_token = $module->get_request_token(admin_url('admin.php?page=photonic-auth&provider=flickr'));
385 - $authorize_url = $module->get_authorize_URL($request_token);
386 - $authorize_url .= '&perms=read';
387 - $module->save_token($request_token);
388 - echo $authorize_url;
389 - }
390 - }
391 - else if ($provider == 'smug') {
392 - require_once(PHOTONIC_PATH."/Modules/SmugMug.php");
393 - $module = SmugMug::get_instance();
394 - if (empty($_POST['oauth_token']) && empty($_POST['oauth_verifier'])) {
395 - $request_token = $module->get_request_token(admin_url('admin.php?page=photonic-auth&provider=smug'));
396 - $authorize_url = $module->get_authorize_URL($request_token);
397 - $authorize_url .= '&Access=Full&Permissions=Read';
398 - $module->save_token($request_token);
399 - echo $authorize_url;
400 - }
401 - }
402 - else if ($provider == 'zenfolio') {
403 - $module = Zenfolio::get_instance();
404 - if (!empty($_POST['password'])) {
405 - $response = $module->authenticate($_POST['password']);
406 - if (!empty($response['error'])) {
407 - echo $response['error'];
408 - }
409 - else if (!empty($response['success'])) {
410 - esc_html_e('Authentication successful! All your galleries will be displayed with Authentication in place.', 'photonic');
411 - }
412 - }
413 - }
414 - }
415 -}
1 +<?php
2 +
3 +namespace Photonic_Plugin\Admin;
4 +
5 +if (!current_user_can('edit_theme_options')) {
6 + wp_die(esc_html__('You are not authorized to use this capability.', 'photonic'));
7 +}
8 +
9 +use Photonic_Plugin\Core\Photonic;
10 +use Photonic_Plugin\Platforms\Authenticator;
11 +use Photonic_Plugin\Platforms\Base;
12 +use Photonic_Plugin\Platforms\Flickr;
13 +use Photonic_Plugin\Platforms\Google_Photos;
14 +use Photonic_Plugin\Platforms\Instagram;
15 +use Photonic_Plugin\Platforms\SmugMug;
16 +use Photonic_Plugin\Platforms\Zenfolio;
17 +use Photonic_Plugin\Platforms\DeviantArt;
18 +
19 +require_once 'Admin_Page.php';
20 +
21 +class Authentication extends Admin_Page {
22 + private static ?Authentication $instance = null;
23 +
24 + private function __construct() {
25 + require_once PHOTONIC_PATH . '/Platforms/Zenfolio.php';
26 + }
27 +
28 + public static function get_instance() {
29 + if (null === self::$instance) {
30 + self::$instance = new Authentication();
31 + }
32 + return self::$instance;
33 + }
34 +
35 + public function render_content() {
36 + ?>
37 + <form method="post" id="photonic-auth-form">
38 + <h2 id="#photonic-flickr-auth-section" class="photonic-section">Flickr</h2>
39 + <?php $this->display_flickr(); ?>
40 +
41 + <h2 id="#photonic-smugmug-auth-section" class="photonic-section">SmugMug</h2>
42 + <?php $this->display_smugmug(); ?>
43 +
44 + <h2 id="#photonic-zenfolio-auth-section" class="photonic-section">Zenfolio</h2>
45 + <?php $this->display_zenfolio(); ?>
46 +
47 +<!-- <h2 id="#photonic-deviantart-auth-section" class="photonic-section">DeviantArt</h2>
48 + --><?php /*$this->display_deviantart(); */?>
49 +
50 + </form>
51 + <?php
52 + }
53 +
54 + private function display_flickr() {
55 + global $photonic_flickr_api_key, $photonic_flickr_api_secret, $photonic_flickr_access_token;
56 + $auth = [
57 + 'api_key' => trim($photonic_flickr_api_key),
58 + 'api_secret' => trim($photonic_flickr_api_secret),
59 + 'token' => trim($photonic_flickr_access_token),
60 + ];
61 + $this->show_token_section($auth, 'flickr', 'Flickr');
62 + }
63 +
64 + private function display_smugmug() {
65 + global $photonic_smug_api_key, $photonic_smug_api_secret, $photonic_smug_access_token;
66 + $auth = [
67 + 'api_key' => !empty($photonic_smug_api_key) ? trim($photonic_smug_api_key) : '86MZ8N8TqJf5x2fQ4FRWXRtJ3C6Jm7XV',
68 + 'api_secret' => trim($photonic_smug_api_secret),
69 + 'token' => trim($photonic_smug_access_token),
70 + ];
71 + $this->show_token_section($auth, 'smug', 'SmugMug');
72 + }
73 +
74 + private function display_zenfolio() {
75 + global $photonic_zenfolio_default_user;
76 + $gallery = Zenfolio::get_instance();
77 +
78 + echo "<div class=\"photonic-token-header\">\n";
79 + if (empty($photonic_zenfolio_default_user)) {
80 + /* Translators: 1: Menu location, untranslated */
81 + echo sprintf(esc_html__('Please set up the default user for Zenfolio under %s', 'photonic'), '<em>Photonic &rarr; Settings &rarr; Zenfolio &rarr; Zenfolio Photo Settings &rarr; Default User</em>') . "\n";
82 + }
83 + elseif (!empty($gallery->token)) {
84 + $this->print_auth_done_all_good();
85 + }
86 + echo "</div>\n";
87 +
88 + $response = Base::parse_parameters($_SERVER['QUERY_STRING'] ?? '');
89 + if (!empty($photonic_zenfolio_default_user) && (empty($response['provider']) || 'zenfolio' !== $response['provider'])) {
90 + echo '<label>' . esc_html__('Password:', 'photonic') . "<input type='password' name='zenfolio-password' id='zenfolio-password'></label>";
91 + }
92 +
93 + echo "<div style='display: block; width: 100%;'>\n";
94 + if (!empty($photonic_zenfolio_default_user) && (empty($response['provider']) || 'zenfolio' !== $response['provider'])) {
95 + $nonce = wp_create_nonce('zenfolio-save-token');
96 + echo "<a href='#' class='button button-primary' data-photonic-provider='zenfolio' style='margin-right: 1em;' data-photonic-nonce='" . esc_attr($nonce) . "'>" . esc_html__('Login and Authenticate', 'photonic') . '</a>';
97 + }
98 +
99 + if (!empty($gallery->token)) {
100 + $nonce = wp_create_nonce('zenfolio-delete-token');
101 + echo "<a href='#' class='button button-primary photonic-zenfolio-delete' data-photonic-nonce='" . esc_attr($nonce) . "'>" . esc_html__('Delete current Zenfolio authentication data', 'photonic') . '</a>';
102 + }
103 + echo "</div>\n";
104 +
105 + echo '<div class="result" id="zenfolio-result">&nbsp;</div>';
106 + }
107 +
108 + private function display_deviantart() {
109 + global $photonic_deviantart_client_id, $photonic_deviantart_client_secret, $photonic_deviantart_refresh_token;
110 +
111 + echo "<div class=\"photonic-token-header\">\n";
112 +
113 + if (empty($photonic_deviantart_client_id) || empty($photonic_deviantart_client_secret)) {
114 + echo sprintf(
115 + /* Translators: 1: Location in menu, untranslated */
116 + esc_html__('Please set up your DeviantArt Client ID and Client Secret under %s', 'photonic'),
117 + '<em>Photonic &rarr; Settings &rarr; DeviantArt &rarr; DeviantArt Settings</em>'
118 + );
119 + }
120 + else {
121 + require_once PHOTONIC_PATH . '/Platforms/DeviantArt.php';
122 +
123 + $parameters = Base::parse_parameters($_SERVER['QUERY_STRING'] ?? '');
124 +
125 + if (!empty($photonic_deviantart_refresh_token)) {
126 + $this->print_auth_done_all_good();
127 + }
128 +
129 + echo "</div>\n";
130 + echo "<div class=\"photonic-token-header\">\n";
131 + echo "<p>\n";
132 + esc_html_e('You first have to authorize Photonic to connect to your DeviantArt account.', 'photonic');
133 + echo "</p>\n";
134 +
135 + if (!isset($parameters['code']) || !isset($parameters['source']) || 'deviantart' !== $parameters['source']) {
136 + $url = add_query_arg('test', 'test');
137 + $url = remove_query_arg('test', $url);
138 + $parameters = [
139 + 'response_type' => 'code',
140 + 'client_id' => $photonic_deviantart_client_id,
141 + 'redirect_uri' => admin_url('admin.php?page=photonic-auth&source=deviantart'),
142 + 'scope' => 'basic browse',
143 + 'access_type' => 'offline',
144 + 'state' => md5($photonic_deviantart_client_secret . 'deviantart') . '::' . rawurlencode($url),
145 + 'prompt' => 'consent',
146 + ];
147 + $url = 'https://www.deviantart.com/oauth2/authorize?' . DeviantArt::build_query($parameters);
148 +
149 + echo "<a href='" . esc_url($url) . "' class='button button-primary'>" . esc_html__('Step 1: Authenticate', 'photonic') . '</a>';
150 + echo "</div>\n";
151 + echo "<div class=\"photonic-token-header\">\n";
152 + echo "<p>\n";
153 + echo esc_html__('Next, you have to obtain the token.', 'photonic') . '<br/>';
154 + echo "</p>\n";
155 + echo "<span class='button photonic-helper-button-disabled'>" .
156 + esc_html__('Step 2: Obtain Token', 'photonic') . '</span>';
157 + }
158 + else {
159 + echo "<span class='button photonic-helper-button-disabled'>" .
160 + esc_html__('Step 1: Authenticate', 'photonic') . '</span>';
161 + echo "</div>\n";
162 + echo "<div class=\"photonic-token-header\">\n";
163 + echo esc_html__('Next, you have to obtain the token.', 'photonic') . '<br/>';
164 + $nonce = wp_create_nonce('deviantart-obtain-token-' . $photonic_deviantart_client_secret);
165 + echo "<a href='#' class='button button-primary photonic-deviantart-refresh' data-photonic-nonce='" . esc_attr($nonce) . "' data-photonic-provider='deviantart'>" .
166 + esc_html__('Step 2: Obtain Token', 'photonic') . '</a>';
167 + echo '<input type="hidden" value="' . esc_attr($parameters['code']) . '" id="photonic-deviantart-oauth-code"/>';
168 + echo '<input type="hidden" value="' . esc_attr($parameters['state']) . '" id="photonic-deviantart-oauth-state"/>';
169 + }
170 + }
171 + echo "</div>\n";
172 + echo '<div class="result" id="deviantart-result">&nbsp;</div>';
173 + }
174 +
175 + private function show_token_section($auth, $provider_slug, $provider_text) {
176 + $this->show_token_section_header($auth, $provider_text);
177 + if (!empty($auth['api_key']) && !empty($auth['api_secret'])) {
178 + $this->show_token_section_body($auth, $provider_slug, $provider_text);
179 + }
180 + else {
181 + echo '<div class="result" id="' . esc_attr($provider_slug) . '-result">&nbsp;</div>';
182 + }
183 + }
184 +
185 + /**
186 + * @param $auth array
187 + * @param $provider string
188 + */
189 + private function show_token_section_header(array $auth, string $provider): void {
190 + echo "<div class=\"photonic-token-header\">\n";
191 +
192 + if ('Instagram' === $provider) {
193 + echo '<p class="notice notice-error">' . esc_html__("Unfortunately Instagram is no longer supported in Photonic. This is due to a change in Meta's Terms and Conditions, that only allow businesses to access their API. As Photonic is developed by an individual, the API is no longer accessible to the developer.", 'photonic') . '</p><br/>';
194 + }
195 + elseif (empty($auth['api_key']) || empty($auth['api_secret'])) {
196 + /* Translators: 1: Platform 2: Menu location */
197 + echo sprintf(esc_html__('Please set up your %1$s API key under %2$s.', 'photonic'), esc_html($provider), sprintf('<em>Photonic &rarr; Settings &rarr; %1$s &rarr; %1$s Settings</em>', esc_html($provider)));
198 + }
199 + elseif ('Instagram' === $provider && !empty($auth['token'])) {
200 + require_once PHOTONIC_PATH . '/Platforms/Instagram.php';
201 + $module = Instagram::get_instance();
202 + $expiring_soon = $module->is_token_expiring_soon(30);
203 + if (is_null($expiring_soon)) {
204 + // Not yet authenticated with the new API.
205 + echo '<p class="notice notice-error">' . esc_html__('Your authentication credentials are for the old Instagram API. Please reauthenticate to keep Photonic working.', 'photonic') . '</p><br/>';
206 + }
207 + elseif (1 === $expiring_soon) {
208 + echo '<p class="notice notice-warning">' . esc_html__('Your authentication credentials are expiring soon. Please reauthenticate to keep Photonic working.', 'photonic') . '</p><br/>';
209 + }
210 + elseif (-1 === $expiring_soon) {
211 + echo '<p class="notice notice-error">' . esc_html__('Your authentication credentials have expired! Please reauthenticate to keep Photonic working.', 'photonic') . '</p><br/>';
212 + }
213 + else {
214 + $cached_token = $module->get_cached_token();
215 +
216 + if (!empty($cached_token) && !empty($cached_token['user'])) {
217 + /* Translators: 1: User in <code> tags */
218 + $this->print_auth_done_all_good(sprintf(esc_html__('You are logged in as %1$s.', 'photonic'), '<code>' . $cached_token['user'] . '</code>'));
219 + }
220 + else {
221 + $this->print_auth_done_all_good();
222 + }
223 + }
224 + }
225 + elseif (!empty($auth['token'])) {
226 + $this->print_auth_done_all_good();
227 + }
228 + echo "</div>\n";
229 + }
230 +
231 + /**
232 + * @param $auth
233 + * @param $provider
234 + * @param $provider_text
235 + */
236 + public function show_token_section_body($auth, $provider, $provider_text) {
237 + $photonic_authentication = get_option('photonic_authentication');
238 + $response = Base::parse_parameters($_SERVER['QUERY_STRING'] ?? '');
239 +
240 + if (empty($response['provider']) || (!empty($response['provider']) && $provider !== $response['provider'])) {
241 + $nonce = wp_create_nonce($provider . '-request-token-' . $auth['api_secret']);
242 + echo "<a href='#' class='button button-primary photonic-token-request' data-photonic-provider='" . esc_attr($provider) . "' data-photonic-nonce='" . esc_attr($nonce) . "'>" . wp_kses_post($this->get_login_button($provider_text)) . '</a>';
243 + }
244 + elseif (!empty($response['oauth_token']) && !empty($response['oauth_verifier'])) {
245 + if (in_array($provider, ['flickr', 'smug', 'smugmug'], true)) {
246 + if ('flickr' === $provider) {
247 + require_once PHOTONIC_PATH . '/Platforms/Flickr.php';
248 + $module = Flickr::get_instance();
249 + }
250 + else {
251 + require_once PHOTONIC_PATH . '/Platforms/SmugMug.php';
252 + $module = SmugMug::get_instance();
253 + }
254 + echo "<span class='button photonic-helper-button-disabled'>" . wp_kses_post($this->get_login_button($provider_text)) . '</span>';
255 + $authorization = ['oauth_token' => $response['oauth_token'], 'oauth_verifier' => $response['oauth_verifier']];
256 + if (isset($photonic_authentication) && isset($photonic_authentication[$provider]) && isset($photonic_authentication[$provider]['oauth_token_secret'])) {
257 + $authorization['oauth_token_secret'] = $photonic_authentication[$provider]['oauth_token_secret'];
258 + }
259 + $access_token = $module->get_access_token($authorization);
260 + if (isset($access_token['oauth_token'])) {
261 + echo '<div class="result">Access Token: <code id="' . esc_attr($provider) . '-token">' . esc_html($access_token['oauth_token']) . '</code><br/>Access Token Secret: <code id="' . esc_attr($provider) . '-token-secret">' . esc_html($access_token['oauth_token_secret']) . '</code></div>' . "\n";
262 + $nonce = wp_create_nonce($provider . '-save-token-' . $access_token['oauth_token']);
263 + echo "<a href='#' class='button button-primary photonic-save-token' data-photonic-provider='" . esc_attr($provider) . "' data-photonic-nonce='" . esc_attr($nonce) . "'>" . esc_html__('Save Token', 'photonic') . '</a>';
264 + }
265 + }
266 + }
267 + }
268 +
269 + private function print_auth_done_all_good($additional_msg = null) {
270 + echo '<p class="notice notice-success">';
271 + esc_html_e('You have already set up your authentication. Unless you wish to regenerate the token this step is not required. ', 'photonic');
272 + if (!empty($additional_msg)) {
273 + echo esc_html($additional_msg);
274 + }
275 + echo '</p>';
276 + }
277 +
278 + private function get_login_button($provider) {
279 + /* Translators: 1: Platform, untranslated */
280 + return sprintf(esc_html__('Login and get Access Token from %s', 'photonic'), $provider);
281 + }
282 +
283 + private function show_token_deletion_button($provider) {
284 + // echo "<a href='#' class='button button-primary photonic-" . strtolower($provider) . "-delete'>" . esc_html__(sprintf('Delete current %s authentication data', $provider), 'photonic') . '</a>';
285 + }
286 +
287 + public function obtain_token() {
288 + $provider = sanitize_text_field($_POST['provider'] ?? '');
289 + global $photonic_flickr_api_secret, $photonic_smug_api_secret, $photonic_deviantart_client_secret;
290 + if ('flickr' === $provider && check_ajax_referer('flickr-request-token-' . $photonic_flickr_api_secret, '_ajax_nonce')) {
291 + require_once PHOTONIC_PATH . '/Platforms/Flickr.php';
292 + $module = Flickr::get_instance();
293 + if (empty($_POST['oauth_token']) && empty($_POST['oauth_verifier'])) {
294 + $request_token = $module->get_request_token(admin_url('admin.php?page=photonic-auth&provider=flickr'));
295 + $authorize_url = $module->get_authorize_URL($request_token);
296 + $authorize_url .= '&perms=read';
297 + $module->save_token($request_token);
298 + echo esc_url_raw($authorize_url);
299 + }
300 + }
301 + elseif ('smug' === $provider && check_ajax_referer('smug-request-token-' . $photonic_smug_api_secret, '_ajax_nonce')) {
302 + require_once PHOTONIC_PATH . '/Platforms/SmugMug.php';
303 + $module = SmugMug::get_instance();
304 + if (empty($_POST['oauth_token']) && empty($_POST['oauth_verifier'])) {
305 + $request_token = $module->get_request_token(admin_url('admin.php?page=photonic-auth&provider=smug'));
306 + $authorize_url = $module->get_authorize_URL($request_token);
307 + $authorize_url .= '&Access=Full&Permissions=Read';
308 + $module->save_token($request_token);
309 + echo esc_url_raw($authorize_url);
310 + }
311 + }
312 + elseif ('zenfolio' === $provider) {
313 + $module = Zenfolio::get_instance();
314 + if (!empty($_POST['password'])) {
315 + $response = $module->authenticate($_POST['password']);
316 + if (!empty($response['error'])) {
317 + echo wp_kses_post($response['error']);
318 + }
319 + elseif (!empty($response['success'])) {
320 + esc_html_e('Authentication successful! All your galleries will be displayed with Authentication in place.', 'photonic');
321 + }
322 + }
323 + }
324 + elseif ('deviantart' === $provider && check_ajax_referer('deviantart-obtain-token-' . $photonic_deviantart_client_secret, '_ajax_nonce')) {
325 + $code = sanitize_text_field($_POST['code'] ?? '');
326 + require_once PHOTONIC_PATH . '/Platforms/DeviantArt.php';
327 + $module = DeviantArt::get_instance();
328 + $response = Photonic::http(
329 + $module->access_token_URL(),
330 + 'POST',
331 + [
332 + 'code' => $code,
333 + 'grant_type' => 'authorization_code',
334 + 'client_id' => $module->client_id,
335 + 'client_secret' => $module->client_secret,
336 + 'redirect_uri' => admin_url('admin.php?page=photonic-auth&source=deviantart'),
337 + ]
338 + );
339 +
340 + if (!is_wp_error($response) && is_array($response)) {
341 + $body = json_decode($response['body']);
342 + // Add nonce to the response. This will be used to save the information in the options.
343 + $body->nonce = wp_create_nonce('deviantart-save-token-' . $body->refresh_token);
344 + echo(wp_json_encode($body));
345 + }
346 + }
347 + }
348 +
349 + public function delete_token_from_options() {
350 + if (isset($_POST['provider']) && check_ajax_referer($_POST['provider'] . '-delete-token')) {
351 + $provider = strtolower(sanitize_text_field($_POST['provider']));
352 + if (in_array($provider, ['flickr', 'smug', 'zenfolio', 'google', 'instagram'], true) && current_user_can('edit_theme_options')) {
353 + $photonic_authentication = get_option('photonic_authentication');
354 + if ('zenfolio' === $provider) {
355 + if (isset($photonic_authentication[$provider])) {
356 + unset($photonic_authentication[$provider]);
357 + }
358 + }
359 + update_option('photonic_authentication', $photonic_authentication);
360 + }
361 + }
362 + die();
363 + }
364 +}