| 1 |
<?php |
| 2 |
/** |
| 3 |
* Class Photonic_Flow_Manager |
| 4 |
* This is the core module for displaying the gallery builder. This is used with two other files: |
| 5 |
* - Flow.php: contains the top-level markup for the gallery builder |
| 6 |
* - Photonic_Flow_Fields.php: contains all the fields by screen |
| 7 |
* |
| 8 |
* @package Photonic |
| 9 |
* @subpackage Flow |
| 10 |
* @since 2.00 |
| 11 |
*/ |
| 12 |
class Photonic_Flow_Manager { |
| 13 |
var $flow_fields, $field_list, $display_types, $shortcode_attributes, $aka_attributes, $date_parts, $date_part_hints, |
| 14 |
$error_mandatory, $error_no_response, $error_unknown, $error_not_found, $error_no_data_returned, $error_not_permitted, $error_authentication, $error_missing_api, |
| 15 |
$force_next_screen, $force_previous_screen, $is_gutenberg; |
| 16 |
|
| 17 |
function __construct() { |
| 18 |
require_once("Photonic_Flow_Fields.php"); |
| 19 |
$this->flow_fields = new Photonic_Flow_Fields(); |
| 20 |
|
| 21 |
$this->field_list = $this->flow_fields->get_flow_options(); |
| 22 |
$this->force_next_screen = -1; |
| 23 |
$this->force_previous_screen = -1; |
| 24 |
|
| 25 |
$this->error_mandatory = esc_html__('Please fill the mandatory fields. Mandatory fields are marked with a red "*".', 'photonic'); |
| 26 |
$this->error_no_response = esc_html__('No response from server.', 'photonic'); |
| 27 |
$this->error_not_found = esc_html__('Not found.', 'photonic'); |
| 28 |
$this->error_no_data_returned = esc_html__('No data was returned for the user you provided. Please verify that the user has the content you are looking for.', 'photonic'); |
| 29 |
$this->error_not_permitted = esc_html__('Incorrect value passed for "%1$s": %2$s', 'photonic'); |
| 30 |
$this->error_missing_api = esc_html__('Please set up your %1$s and secret under %2$s', 'photonic'); |
| 31 |
$this->error_authentication = esc_html__('Please set up your %1$s Authentication from %2$s', 'photonic'); |
| 32 |
|
| 33 |
$this->date_parts = array(0 => esc_html__('Year', 'photonic'), 1 => esc_html__('Month', 'photonic'), 2 => esc_html__('Date', 'photonic')); |
| 34 |
$this->date_part_hints = array(0 => esc_html__('Year (0 - 9999)', 'photonic'), 1 => esc_html__('Month (0 - 12)', 'photonic'), 2 => esc_html__('Date (0 - 31)', 'photonic')); |
| 35 |
|
| 36 |
$this->display_types = array( |
| 37 |
'single-photo' => 0, |
| 38 |
'multi-photo' => 1, |
| 39 |
'album-photo' => 1, |
| 40 |
'folder-photo' => 1, |
| 41 |
'user-photo' => 1, |
| 42 |
'gallery-photo' => 1, |
| 43 |
'collection-photo' => 1, |
| 44 |
'current-post' => 1, |
| 45 |
'another-post' => 1, |
| 46 |
'multi-album' => 2, |
| 47 |
'multi-gallery' => 2, |
| 48 |
'multi-collection' => 2, |
| 49 |
'multi-gallery-collection' => 2, |
| 50 |
'collection' => 3, |
| 51 |
'collections' => 3, |
| 52 |
'folder' => 3, |
| 53 |
'tree' => 3, |
| 54 |
'group' => 3, |
| 55 |
'group-hierarchy' => 3, |
| 56 |
); |
| 57 |
|
| 58 |
$this->shortcode_attributes = array( |
| 59 |
'common' => array( |
| 60 |
'columns', 'count', 'more', 'photo_count', 'photo_more', 'title_position', 'caption', 'media', 'main_size', 'thumb_size', 'tile_size', 'video_size', 'popup', 'thumbnail_effect', // All lightbox |
| 61 |
'speed', 'timeout', 'fx', 'pause', 'strip-style', 'controls', // Slideshow |
| 62 |
), |
| 63 |
'flickr' => array('user_id', 'group_id', 'collections_display', 'tags', 'tag_mode', 'text', 'sort', 'privacy_filter',), |
| 64 |
'smugmug' => array('nick_name', 'password', 'text', 'keywords', 'sort_order', 'sort_method', 'album_sort_order', ), |
| 65 |
'google' => array('user_id', 'access', 'protection', 'crop_thumb', 'content_filters',), |
| 66 |
'zenfolio' => array('login_name', 'text', 'category_code', 'sort_order', 'structure', ), |
| 67 |
'instagram' => array(), |
| 68 |
'wp' => array(), |
| 69 |
); |
| 70 |
$this->aka_attributes = array( |
| 71 |
'flickr' => array('per_page' => 'count'), |
| 72 |
'zenfolio' => array('limit' => 'count'), |
| 73 |
'wp' => array('slide_size' => 'main_size'), |
| 74 |
); |
| 75 |
} |
| 76 |
|
| 77 |
/** |
| 78 |
* Gets the content to be displayed on a flow screen. This is invoked by an AJAX call. The current screen number is passed to this function. |
| 79 |
* The function performs validations behind the scenes and if everything looks OK it returns the content for the next screen, otherwise |
| 80 |
* an error is returned. |
| 81 |
* |
| 82 |
* @return string |
| 83 |
*/ |
| 84 |
function get_screen() { |
| 85 |
$screen = isset($_POST['screen']) ? sanitize_text_field($_POST['screen']) : 0; |
| 86 |
$provider = isset($_POST['provider']) ? sanitize_text_field($_POST['provider']) : ''; |
| 87 |
$display_type = isset($_POST['display_type']) ? sanitize_text_field($_POST['display_type']) : ''; |
| 88 |
|
| 89 |
$raw_shortcode = !empty($_POST['photonic-editor-shortcode-raw']) ? sanitize_text_field($_POST['photonic-editor-shortcode-raw']) : ''; |
| 90 |
if (!empty($raw_shortcode)) { |
| 91 |
$input = base64_decode($raw_shortcode); |
| 92 |
$input = json_decode($input); |
| 93 |
if (!empty($input->shortcode) && !empty($input->shortcode->attrs) && !empty($input->shortcode->attrs->named)) { |
| 94 |
$input = $input->shortcode->attrs->named; |
| 95 |
} |
| 96 |
} |
| 97 |
else { |
| 98 |
$raw_shortcode = !empty($_POST['photonic-editor-json']) ? stripslashes_deep($_POST['photonic-editor-json']) : ''; |
| 99 |
$input = json_decode($raw_shortcode); |
| 100 |
if (!empty($_POST['photonic-gutenberg-active'])) { |
| 101 |
$this->is_gutenberg = true; |
| 102 |
} |
| 103 |
} |
| 104 |
|
| 105 |
$deconstructed = $this->deconstruct_shortcode($input); |
| 106 |
|
| 107 |
$output = $this->validate($screen, $provider, $deconstructed); |
| 108 |
if (!empty($output['error'])) { |
| 109 |
return '<div class="photonic-flow-error">' . $output['error'] . "</div>\n"; |
| 110 |
} |
| 111 |
|
| 112 |
$screen = ((int)$screen) + 1; |
| 113 |
if ($this->force_next_screen > -1) { |
| 114 |
$screen = $this->force_next_screen; |
| 115 |
} |
| 116 |
|
| 117 |
$screen_fields = array(); |
| 118 |
if (!empty($this->field_list['screen-' . $screen])) { |
| 119 |
$screen_fields = $this->field_list['screen-' . $screen]; |
| 120 |
} |
| 121 |
$ret = ''; |
| 122 |
|
| 123 |
if ($screen == 2 || $screen == '2') { |
| 124 |
/* |
| 125 |
* The display_type screen. This gathers inputs about what the user wants to show: photos from an album, a collection of |
| 126 |
* albums, user trees, single photos etc., along with who the photos are from - the default user, a different user, any user etc. |
| 127 |
*/ |
| 128 |
$fields = $screen_fields[$provider]['display']; |
| 129 |
$ret .= $this->render_all_fields($fields, $deconstructed); |
| 130 |
$ret = (empty($screen_fields[$provider]['header']) ? '' : "<h1>" . $screen_fields[$provider]['header'] . "</h1>\n") . |
| 131 |
(empty($screen_fields[$provider]['desc']) ? '' : "<p>" . $screen_fields[$provider]['desc'] . "</p>\n") . |
| 132 |
$ret; |
| 133 |
} |
| 134 |
else if ($screen == 3) { |
| 135 |
/* |
| 136 |
* The Gallery Builder screen, where all the photos / albums / folders are displayed |
| 137 |
*/ |
| 138 |
$fields = $screen_fields[$provider][$display_type]['display']; |
| 139 |
$ret .= $this->render_all_fields($fields, $deconstructed); |
| 140 |
|
| 141 |
$ret = (empty($screen_fields[$provider][$display_type]['header']) ? '' : "<h1>" . $screen_fields[$provider][$display_type]['header'] . "</h1>\n") . |
| 142 |
(empty($screen_fields[$provider][$display_type]['desc']) ? '' : "<p>" . $screen_fields[$provider][$display_type]['desc'] . "</p>\n") . |
| 143 |
str_replace('{{placeholder_value}}', $output['success'], $ret); |
| 144 |
} |
| 145 |
else if ($screen == 4) { |
| 146 |
/* |
| 147 |
* The layout selection screen |
| 148 |
*/ |
| 149 |
$ret .= $output['success']; |
| 150 |
} |
| 151 |
else { |
| 152 |
$ret .= $output['success']; |
| 153 |
} |
| 154 |
|
| 155 |
return $ret; |
| 156 |
} |
| 157 |
|
| 158 |
/** |
| 159 |
* Checks all inputs amongst themselves. If the inputs are valid, then the content for the next screen is generated by this call. |
| 160 |
* All heavy logic, including API calls and processing of the responses happens here. |
| 161 |
* |
| 162 |
* @param $screen |
| 163 |
* @param $provider |
| 164 |
* @param array $existing |
| 165 |
* @return array|string |
| 166 |
*/ |
| 167 |
function validate($screen, $provider, $existing = array()) { |
| 168 |
if (empty($screen) || !is_numeric($screen) || (is_numeric($screen) && (intval($screen) <= 0 || intval($screen) > 5))) { |
| 169 |
return array('error' => sprintf(esc_html__('Invalid screen value: %s', 'photonic'), $screen)); |
| 170 |
} |
| 171 |
if (!in_array($provider, array('wp', 'flickr', 'picasa', 'google', 'smugmug', 'zenfolio', 'instagram'))) { |
| 172 |
return array('error' => sprintf(esc_html__('Invalid photo provider: %s', 'photonic'), $provider)); |
| 173 |
} |
| 174 |
|
| 175 |
$screen = intval($screen); |
| 176 |
$display_type = isset($_POST['display_type']) ? sanitize_text_field($_POST['display_type']) : ''; |
| 177 |
|
| 178 |
if ($screen == 1) { |
| 179 |
switch ($provider) { |
| 180 |
case 'flickr': |
| 181 |
global $photonic_flickr_api_key, $photonic_flickr_api_secret; |
| 182 |
if (empty($photonic_flickr_api_key) || empty($photonic_flickr_api_secret)) { |
| 183 |
return array('error' => sprintf($this->error_missing_api, 'Flickr API key', '<em>Photonic → Settings → Flickr → Flickr Settings</em>')); |
| 184 |
} |
| 185 |
break; |
| 186 |
|
| 187 |
case 'picasa': |
| 188 |
return array('error' => esc_html__('Google has deprecated the Picasa API with effect from January 2019. Please consider using the Google Photos module.', 'photonic')); |
| 189 |
|
| 190 |
case 'google': |
| 191 |
global $photonic_google_client_id, $photonic_google_client_secret, $photonic_google_refresh_token; |
| 192 |
// if (!empty($photonic_google_use_own_keys) && (empty($photonic_google_client_id) || empty($photonic_google_client_secret))) { |
| 193 |
if (empty($photonic_google_client_id) || empty($photonic_google_client_secret)) { |
| 194 |
return array('error' => sprintf($this->error_missing_api, 'Google Client ID', '<em>Photonic → Settings → Google Photos → Google Photos Settings</em>')); |
| 195 |
} |
| 196 |
else if (empty($photonic_google_refresh_token)) { |
| 197 |
return array('error' => sprintf($this->error_authentication, 'Google Photos', '<em>Photonic → Authentication</em>')); |
| 198 |
} |
| 199 |
break; |
| 200 |
|
| 201 |
case 'smugmug': |
| 202 |
global $photonic_smug_api_key, $photonic_smug_api_secret; |
| 203 |
if (empty($photonic_smug_api_key) || empty($photonic_smug_api_secret)) { |
| 204 |
return array('error' => sprintf($this->error_missing_api, 'SmugMug API Key', '<em>Photonic → Settings → SmugMug → SmugMug Settings</em>')); |
| 205 |
} |
| 206 |
break; |
| 207 |
|
| 208 |
case 'instagram': |
| 209 |
global $photonic_instagram_access_token; |
| 210 |
if (empty($photonic_instagram_access_token)) { |
| 211 |
return array('error' => sprintf($this->error_authentication, 'Instagram', '<em>Photonic → Authentication</em>')); |
| 212 |
} |
| 213 |
break; |
| 214 |
|
| 215 |
case 'zenfolio': |
| 216 |
return ''; |
| 217 |
|
| 218 |
default: // wp |
| 219 |
return ''; |
| 220 |
} |
| 221 |
} |
| 222 |
else if ($screen == 2) { |
| 223 |
$screen_fields = $this->field_list['screen-' . $screen]; |
| 224 |
$fields = $screen_fields[$provider]['display']; |
| 225 |
$flattened_fields = array(); |
| 226 |
foreach ($fields as $id => $field) { |
| 227 |
if (!empty($field['type']) && $field['type'] != 'field_list') { |
| 228 |
$flattened_fields[$id] = $field; |
| 229 |
} |
| 230 |
else if (!empty($field['type']) && $field['type'] == 'field_list') { |
| 231 |
$flattened_fields = array_merge($field['list'], $flattened_fields); |
| 232 |
} |
| 233 |
} |
| 234 |
|
| 235 |
if (empty($display_type) || (empty($_POST['for']) && in_array($provider, array('flickr', 'smugmug', 'zenfolio')) && empty($existing))) { |
| 236 |
return array('error' => $this->error_mandatory); |
| 237 |
} |
| 238 |
|
| 239 |
if (empty($_POST['for']) && in_array($provider, array('flickr', 'smugmug', 'zenfolio')) && !empty($existing)) { |
| 240 |
return array('error' => esc_html__('While the "For whom?" setting may not be required for the shortcode to function in the front-end, it is required to edit this shortcode in this editor. Please specify a value.', 'photonic')); |
| 241 |
} |
| 242 |
|
| 243 |
if (!in_array($display_type, array_keys($flattened_fields['display_type']['options']))) { |
| 244 |
return array('error' => sprintf(esc_html__('Invalid display type: %s', 'photonic'), $display_type)); |
| 245 |
} |
| 246 |
|
| 247 |
$for = !empty($_POST['for']) ? sanitize_text_field($_POST['for']) : null; |
| 248 |
|
| 249 |
switch ($provider) { |
| 250 |
case 'flickr': |
| 251 |
if ($display_type != 'multi-photo' && in_array($for, array('group', 'any'))) { |
| 252 |
$err = esc_html__('Incompatible selections:', 'photonic') . "<br/>\n"; |
| 253 |
$err .= $flattened_fields['display_type']['desc'] . ": " . $flattened_fields['display_type']['options'][$display_type] . "<br/>\n"; |
| 254 |
$err .= $flattened_fields['for']['desc'] . ": " . $flattened_fields['for']['options'][$for] . "<br/>\n"; |
| 255 |
return array('error' => $err); |
| 256 |
} |
| 257 |
|
| 258 |
$group = sanitize_text_field($_POST['group']); |
| 259 |
$login = sanitize_text_field($_POST['login']); |
| 260 |
global $photonic_flickr_default_user, $photonic_flickr_api_key; |
| 261 |
if ($for == 'current' && empty($photonic_flickr_default_user)) { |
| 262 |
return array('error' => sprintf(esc_html__('Default user not defined under %1$s. %2$sSelect "Another user" and put in your user id.', 'photonic'), |
| 263 |
'<em>Photonic → Settings → Flickr → Flickr Settings → Default User</em>', '<br/>')); |
| 264 |
} |
| 265 |
|
| 266 |
if (($for == 'group' && empty($group)) || ($for == 'other' && empty($login))) { |
| 267 |
return array('error' => $this->error_mandatory); |
| 268 |
} |
| 269 |
|
| 270 |
$parameters = array(); |
| 271 |
$user = $for == 'current' ? $photonic_flickr_default_user : ($for == 'other' ? $login : ''); |
| 272 |
if (($for == 'other' || $for == 'current') && !empty($user)) { |
| 273 |
$url = 'https://api.flickr.com/services/rest/?format=json&nojsoncallback=1&api_key=' . $photonic_flickr_api_key . '&method=flickr.urls.lookupUser&url=' . urlencode('https://www.flickr.com/photos/') . $user; |
| 274 |
$response = wp_remote_request($url, array('sslverify' => PHOTONIC_SSL_VERIFY)); |
| 275 |
$response = $this->process_response($response, 'flickr', 'user'); |
| 276 |
if (!empty($response['error'])) { |
| 277 |
// Maybe the user provided the full URL instead of just the user name? |
| 278 |
$url = 'https://api.flickr.com/services/rest/?format=json&nojsoncallback=1&api_key=' . $photonic_flickr_api_key . '&method=flickr.urls.lookupUser&url=' . urlencode($user); |
| 279 |
$response = wp_remote_request($url, array('sslverify' => PHOTONIC_SSL_VERIFY)); |
| 280 |
$response = $this->process_response($response, 'flickr', 'user'); |
| 281 |
if (!empty($response['error'])) { |
| 282 |
return $response; |
| 283 |
} |
| 284 |
$parameters = array_merge($response['success'], $parameters); |
| 285 |
} |
| 286 |
else { |
| 287 |
$parameters = array_merge($response['success'], $parameters); |
| 288 |
} |
| 289 |
} |
| 290 |
|
| 291 |
if ($for == 'group' && !empty($group)) { |
| 292 |
$url = 'https://api.flickr.com/services/rest/?format=json&nojsoncallback=1&api_key=' . $photonic_flickr_api_key . '&method=flickr.urls.lookupGroup&url=' . urlencode('https://www.flickr.com/groups/') . $group; |
| 293 |
$response = wp_remote_request($url, array('sslverify' => PHOTONIC_SSL_VERIFY)); |
| 294 |
$response = $this->process_response($response, 'flickr', 'group'); |
| 295 |
if (!empty($response['error'])) { |
| 296 |
// Maybe the user provided the full URL instead of just the group name? |
| 297 |
$url = 'https://api.flickr.com/services/rest/?format=json&nojsoncallback=1&api_key=' . $photonic_flickr_api_key . '&method=flickr.urls.lookupGroup&url=' . urlencode($user); |
| 298 |
$response = wp_remote_request($url, array('sslverify' => PHOTONIC_SSL_VERIFY)); |
| 299 |
$response = $this->process_response($response, 'flickr', 'group'); |
| 300 |
if (!empty($response['error'])) { |
| 301 |
return $response; |
| 302 |
} |
| 303 |
$parameters = array_merge($response['success'], $parameters); |
| 304 |
} |
| 305 |
else { |
| 306 |
$parameters = array_merge($response['success'], $parameters); |
| 307 |
} |
| 308 |
} |
| 309 |
|
| 310 |
// All OK so far. Let's try to get the data for the next screen |
| 311 |
$parameters['api_key'] = $photonic_flickr_api_key; |
| 312 |
$parameters['format'] = 'json'; |
| 313 |
$parameters['nojsoncallback'] = 1; |
| 314 |
|
| 315 |
if ($display_type == 'single-photo') { |
| 316 |
$parameters['view'] = 'photo'; |
| 317 |
$parameters['method'] = 'flickr.photos.search'; |
| 318 |
$parameters['per_page'] = 500; |
| 319 |
} |
| 320 |
else if ($display_type == 'multi-photo') { |
| 321 |
$parameters['view'] = 'photos'; |
| 322 |
$parameters['method'] = 'flickr.photos.search'; |
| 323 |
} |
| 324 |
else if ($display_type == 'multi-album' || $display_type == 'album-photo') { |
| 325 |
$parameters['view'] = 'photosets'; |
| 326 |
$parameters['method'] = 'flickr.photosets.getList'; |
| 327 |
} |
| 328 |
else if ($display_type == 'multi-gallery' || $display_type == 'gallery-photo') { |
| 329 |
$parameters['view'] = 'galleries'; |
| 330 |
$parameters['method'] = 'flickr.galleries.getList'; |
| 331 |
$parameters['per_page'] = 500; |
| 332 |
} |
| 333 |
else if ($display_type == 'collection' || $display_type == 'collections') { |
| 334 |
$parameters['view'] = 'collections'; |
| 335 |
$parameters['method'] = 'flickr.collections.getTree'; |
| 336 |
} |
| 337 |
|
| 338 |
global $photonic_flickr_gallery, $photonic_flickr_access_token; |
| 339 |
if (!isset($photonic_flickr_gallery)) { |
| 340 |
$photonic_flickr_gallery = new Photonic_Flickr_Processor(); |
| 341 |
} |
| 342 |
if (!empty($photonic_flickr_access_token)) { |
| 343 |
$parameters = $photonic_flickr_gallery->sign_call('https://api.flickr.com/services/rest/', 'GET', $parameters); |
| 344 |
} |
| 345 |
|
| 346 |
$url = add_query_arg($parameters, 'https://api.flickr.com/services/rest/'); |
| 347 |
$response = wp_remote_request($url, array('sslverify' => PHOTONIC_SSL_VERIFY)); |
| 348 |
$hidden = array(); |
| 349 |
if (isset($parameters['user_id'])) $hidden['user_id'] = $parameters['user_id']; |
| 350 |
if (isset($parameters['group_id'])) $hidden['group_id'] = $parameters['group_id']; |
| 351 |
return $this->process_response($response, 'flickr', $display_type, $hidden, $existing, $url); |
| 352 |
|
| 353 |
case 'smugmug': |
| 354 |
global $photonic_smug_default_user, $photonic_smug_api_key; |
| 355 |
if ($for == 'current' && empty($photonic_smug_default_user)) { |
| 356 |
return array('error' => sprintf(esc_html__('Default user not defined under %1$s. %2$sSelect "Another user" and put in your user id.', 'photonic'), '<em>Photonic → Settings → SmugMug → SmugMug Settings → Default User</em>', '<br/>')); |
| 357 |
} |
| 358 |
|
| 359 |
if ($for == 'other' && empty($_POST['user'])) { |
| 360 |
return array('error' => $this->error_mandatory); |
| 361 |
} |
| 362 |
|
| 363 |
$nick_name = sanitize_text_field($_POST['user']); |
| 364 |
$user = $for == 'current' ? $photonic_smug_default_user : ($for == 'other' ? $nick_name : ''); |
| 365 |
$args = array( |
| 366 |
'APIKey' => $photonic_smug_api_key, |
| 367 |
'_accept' => 'application/json', |
| 368 |
'_expandmethod' => 'inline', |
| 369 |
'_verbosity' => '1', |
| 370 |
); |
| 371 |
|
| 372 |
if ($display_type == 'album-photo' || $display_type == 'multi-album') { |
| 373 |
$call = "https://api.smugmug.com/api/v2/user/$user!albums"; |
| 374 |
$args['_expand'] = 'HighlightImage.ImageSizes'; |
| 375 |
$args['count'] = 500; |
| 376 |
} |
| 377 |
else { |
| 378 |
$call = "https://api.smugmug.com/api/v2/user/$user"; |
| 379 |
} |
| 380 |
|
| 381 |
global $photonic_smugmug_gallery, $photonic_smug_access_token; |
| 382 |
if (!isset($photonic_smugmug_gallery)) { |
| 383 |
$photonic_smugmug_gallery = new Photonic_SmugMug_Processor(); |
| 384 |
} |
| 385 |
|
| 386 |
if (!empty($photonic_smug_access_token)) { |
| 387 |
$args = $photonic_smugmug_gallery->sign_call($call, 'GET', $args); |
| 388 |
} |
| 389 |
|
| 390 |
if ($display_type == 'folder' || $display_type == 'tree' || $display_type == 'folder-photo' || $display_type == 'user-photo') { |
| 391 |
// Not able to use wp_remote_request - getting a signature_invalid response |
| 392 |
$temp = Photonic::http($call, 'GET', $args, null, 300); |
| 393 |
$temp = $this->process_response($temp, 'smugmug', 'user'); |
| 394 |
|
| 395 |
if (!empty($temp['success'])) { |
| 396 |
$node = $temp['success']; |
| 397 |
$call = 'https://api.smugmug.com' . $node . '!children'; |
| 398 |
if ($display_type == 'tree' || $display_type == 'user-photo') { |
| 399 |
$args['_expand'] = 'NodeCoverImage.ImageSizes'; |
| 400 |
} |
| 401 |
else { |
| 402 |
$config = $photonic_smugmug_gallery->get_config_object(500); |
| 403 |
$config_str = json_encode($config); |
| 404 |
$args['_config'] = $config_str; |
| 405 |
} |
| 406 |
|
| 407 |
// Sign call again because we made an interim call |
| 408 |
if (!empty($photonic_smug_access_token)) { |
| 409 |
unset($args['oauth_consumer_key']); |
| 410 |
unset($args['oauth_nonce']); |
| 411 |
unset($args['oauth_signature']); |
| 412 |
unset($args['oauth_signature_method']); |
| 413 |
unset($args['oauth_timestamp']); |
| 414 |
unset($args['oauth_version']); |
| 415 |
unset($args['oauth_token']); |
| 416 |
unset($args['oauth_verifier']); |
| 417 |
$args = $photonic_smugmug_gallery->sign_call($call, 'GET', $args); |
| 418 |
} |
| 419 |
} |
| 420 |
else { |
| 421 |
return $temp; |
| 422 |
} |
| 423 |
} |
| 424 |
|
| 425 |
$response = Photonic::http($call, 'GET', $args, null, 300); |
| 426 |
return $this->process_response($response, 'smugmug', $display_type, array('nick_name' => $user), $existing, $call); |
| 427 |
|
| 428 |
case 'google': |
| 429 |
global $photonic_google_refresh_token, $photonic_google_gallery; |
| 430 |
if (!isset($photonic_google_gallery)) { |
| 431 |
$photonic_google_gallery = new Photonic_Google_Photos_Processor(); |
| 432 |
} |
| 433 |
|
| 434 |
$photonic_google_gallery->perform_back_end_authentication($photonic_google_refresh_token); |
| 435 |
|
| 436 |
$parameters = array(); |
| 437 |
|
| 438 |
// All OK so far. Let's try to get the data for the next screen |
| 439 |
$parameters['access_token'] = $photonic_google_gallery->access_token; |
| 440 |
|
| 441 |
$query_url = ''; |
| 442 |
if ($display_type == 'multi-photo') { |
| 443 |
$query_url = 'https://photoslibrary.googleapis.com/v1/mediaItems:search'; |
| 444 |
} |
| 445 |
else if ($display_type == 'multi-album' || $display_type == 'album-photo') { |
| 446 |
$query_url = 'https://photoslibrary.googleapis.com/v1/albums?pageSize=50'; |
| 447 |
} |
| 448 |
|
| 449 |
$query_url = add_query_arg($parameters, $query_url); |
| 450 |
$response = wp_remote_request($query_url, array('method' => ($display_type == 'multi-photo' ? 'POST' : 'GET'), 'sslverify' => PHOTONIC_SSL_VERIFY)); |
| 451 |
return $this->process_response($response, 'google', $display_type, array(), $existing, $query_url); |
| 452 |
|
| 453 |
case 'zenfolio': |
| 454 |
if ((!in_array($display_type, array('multi-photo', /*'multi-gallery', 'multi-collection'*/)) && $for == 'any') || |
| 455 |
(!in_array($display_type, array('single-photo', 'gallery-photo', 'collection-photo', 'multi-gallery', 'multi-collection', 'multi-gallery-collection', 'group', 'group-hierarchy')) && in_array($for, array('current', 'other')))) { |
| 456 |
$err = esc_html__('Incompatible selections:', 'photonic') . "<br/>\n"; |
| 457 |
$err .= $flattened_fields['display_type']['desc'] . ": " . $flattened_fields['display_type']['options'][$display_type] . "<br/>\n"; |
| 458 |
$err .= $flattened_fields['for']['desc'] . ": " . $flattened_fields['for']['options'][$for] . "<br/>\n"; |
| 459 |
return array('error' => $err); |
| 460 |
} |
| 461 |
|
| 462 |
if ($for == 'other' && empty($_POST['login_name'])) { |
| 463 |
return array('error' => $this->error_mandatory); |
| 464 |
} |
| 465 |
|
| 466 |
$login_name = sanitize_text_field($_POST['login_name']); |
| 467 |
global $photonic_zenfolio_default_user; |
| 468 |
if ($for == 'current' && empty($photonic_zenfolio_default_user)) { |
| 469 |
return array('error' => sprintf(esc_html__('Default user not defined under %1$s. %2$sSelect "Another user" and put in your user id.', 'photonic'), '<em>Photonic → Settings → Zenfolio → Zenfolio Photo Settings → Default User</em>', '<br/>')); |
| 470 |
} |
| 471 |
|
| 472 |
$parameters = array(); |
| 473 |
$user = $for == 'current' ? $photonic_zenfolio_default_user : ($for == 'other' ? $login_name : ''); |
| 474 |
|
| 475 |
if ($display_type == 'multi-photo') { |
| 476 |
$url = 'https://api.zenfolio.com/api/1.8/zfapi.asmx/SearchPhotoByCategory'; |
| 477 |
$parameters['searchId'] = '5'; |
| 478 |
$parameters['sortOrder'] = 'Popularity'; |
| 479 |
$parameters['categoryCode'] = '1018000'; |
| 480 |
$parameters['offset'] = 0; |
| 481 |
$parameters['limit'] = 500; |
| 482 |
} |
| 483 |
else if (in_array($display_type, array('multi-gallery', 'multi-collection')) && $for == 'any') { |
| 484 |
$url = 'https://api.zenfolio.com/api/1.8/zfapi.asmx/SearchSetByCategory'; |
| 485 |
$parameters['searchId'] = '5'; |
| 486 |
$parameters['sortOrder'] = 'Popularity'; |
| 487 |
$parameters['categoryCode'] = '1018000'; |
| 488 |
$parameters['offset'] = 0; |
| 489 |
$parameters['limit'] = 500; |
| 490 |
} |
| 491 |
else { |
| 492 |
$url = 'https://api.zenfolio.com/api/1.8/zfapi.asmx/LoadGroupHierarchy'; |
| 493 |
$parameters['loginName'] = $user; |
| 494 |
} |
| 495 |
|
| 496 |
$response = wp_remote_request($url, array('sslverify' => PHOTONIC_SSL_VERIFY, 'body' => $parameters)); |
| 497 |
return $this->process_response($response, 'zenfolio', $display_type, array('login_name' => $user), $existing, $url); |
| 498 |
|
| 499 |
case 'instagram': |
| 500 |
global $photonic_instagram_access_token; |
| 501 |
$base_url = 'https://api.instagram.com/v1/users/self/media/recent/?access_token='.$photonic_instagram_access_token; |
| 502 |
$response = wp_remote_request($base_url); |
| 503 |
return $this->process_response($response, 'instagram', $display_type, array(), $existing, $base_url); |
| 504 |
|
| 505 |
default: // wp |
| 506 |
$this->force_next_screen = 4; |
| 507 |
$this->force_previous_screen = 2; |
| 508 |
return array('success' => $this->get_layout_selector($display_type, $existing)); |
| 509 |
} |
| 510 |
} |
| 511 |
else if ($screen == 3) { |
| 512 |
//Check for display_type |
| 513 |
$screen_fields = $this->field_list['screen-' . $screen]; |
| 514 |
$provider_fields = $screen_fields[$provider]; |
| 515 |
$fields = $provider_fields[$display_type]['display']; |
| 516 |
foreach ($fields as $id => $field) { |
| 517 |
$checks = $this->do_basic_option_check($id, $field, true); |
| 518 |
if (!empty($checks)) { |
| 519 |
return $checks; |
| 520 |
} |
| 521 |
|
| 522 |
if ($id == 'selection' && sanitize_text_field($_POST['selection']) == 'selected' && empty($_POST['selected_data'])) { |
| 523 |
return array('error' => esc_html__('Please select what you want to show.', 'photonic')); |
| 524 |
} |
| 525 |
|
| 526 |
if (in_array($display_type, array('single-photo', 'album-photo', 'gallery-photo', 'folder-photo', 'collection-photo')) && empty($_POST['selected_data'])) { |
| 527 |
return array('error' => esc_html__('Please select what you want to show.', 'photonic')); |
| 528 |
} |
| 529 |
} |
| 530 |
|
| 531 |
// All OK? Get next screen |
| 532 |
if ($display_type != 'single-photo') { |
| 533 |
$output = $this->get_layout_selector($display_type, $existing); |
| 534 |
} |
| 535 |
else { |
| 536 |
$this->force_next_screen = 6; |
| 537 |
$this->force_previous_screen = 3; |
| 538 |
$output = $this->construct_shortcode(); |
| 539 |
} |
| 540 |
return array('success' => $output); |
| 541 |
} |
| 542 |
else if ($screen == 4) { |
| 543 |
$layout = isset($_POST['layout']) ? sanitize_text_field($_POST['layout']) : ''; |
| 544 |
if (empty($layout)) { |
| 545 |
return array('error' => $this->error_mandatory); |
| 546 |
} |
| 547 |
$layout_options = $this->flow_fields->get_layout_options(); |
| 548 |
if (!array_key_exists($layout, $layout_options)) { |
| 549 |
return array('error' => sprintf(esc_html__('Invalid layout: %s', 'photonic'), $layout)); |
| 550 |
} |
| 551 |
|
| 552 |
// All good. Next screen: |
| 553 |
return array('success' => $this->get_layout_options($provider, $display_type, $layout, $existing)); |
| 554 |
} |
| 555 |
else { |
| 556 |
$passworded = isset($_POST['selection_passworded']) ? sanitize_text_field($_POST['selection_passworded']) : ''; |
| 557 |
$password = isset($_POST['password']) ? sanitize_text_field($_POST['password']) : ''; |
| 558 |
if (!empty($passworded) && empty($password)) { |
| 559 |
return array('error' => $this->error_mandatory); |
| 560 |
} |
| 561 |
return array('success' => $this->construct_shortcode()); |
| 562 |
} |
| 563 |
return ''; |
| 564 |
} |
| 565 |
|
| 566 |
/** |
| 567 |
* Utility method that takes an array of fields, determines if each member is a "field list" or a "field". If it is a field |
| 568 |
* list it processes it as a field list, otherwise it processes it as a field. |
| 569 |
* |
| 570 |
* @param array $fields |
| 571 |
* @param array $existing |
| 572 |
* @return String |
| 573 |
*/ |
| 574 |
private function render_all_fields($fields, $existing = array()) { |
| 575 |
$output = ''; |
| 576 |
foreach ($fields as $id => $field) { |
| 577 |
if (!empty($field['type']) && $field['type'] == 'field_list') { |
| 578 |
$output .= $this->process_field_list($id, $field, $existing); |
| 579 |
} |
| 580 |
else if (!empty($field['type'])) { |
| 581 |
$output .= $this->process_field($id, $field, 0, null, $existing); |
| 582 |
} |
| 583 |
} |
| 584 |
return $output; |
| 585 |
} |
| 586 |
|
| 587 |
/** |
| 588 |
* Takes a "field list" and processes each field in it individually. A "field list" can contain an interdependent sequence |
| 589 |
* of fields, in which case each member gets a sequential number assigned to it. The actual logic of sequencing is handled on the |
| 590 |
* front-end. |
| 591 |
* E.g. If, for Flickr, you select "Multiple Photos", then "Another User", the front-end will show a "User" text field. |
| 592 |
* But if "Group" is selected, it shows a "Group" text field |
| 593 |
* |
| 594 |
* @param $field_list_name |
| 595 |
* @param array $field_list |
| 596 |
* @param array $existing |
| 597 |
* @return string |
| 598 |
*/ |
| 599 |
function process_field_list($field_list_name, $field_list, $existing = array()) { |
| 600 |
if (!is_array($field_list) || empty($field_list['type']) || $field_list['type'] != 'field_list' || empty($field_list['list'])) { |
| 601 |
return ''; |
| 602 |
} |
| 603 |
else { |
| 604 |
$ret = ''; |
| 605 |
$counter = 0; |
| 606 |
$sequence_group = null; |
| 607 |
foreach ($field_list['list'] as $id => $field) { |
| 608 |
if ($field_list['list_type'] == 'sequence') { |
| 609 |
$counter++; |
| 610 |
$sequence_group = $field_list_name; |
| 611 |
} |
| 612 |
$ret .= $this->process_field($id, $field, $counter, $sequence_group, $existing); |
| 613 |
} |
| 614 |
return $ret; |
| 615 |
} |
| 616 |
} |
| 617 |
|
| 618 |
/** |
| 619 |
* Main code to render an input element on the flow-screen. Almost all types of inputs have switches for display here. |
| 620 |
* |
| 621 |
* @param string $id |
| 622 |
* @param array $field |
| 623 |
* @param $sequence |
| 624 |
* @param null $sequence_group |
| 625 |
* @param array $existing |
| 626 |
* @return string |
| 627 |
*/ |
| 628 |
function process_field($id, $field, $sequence, $sequence_group = null, $existing = array()) { |
| 629 |
if (!is_array($field) || empty($field['type'])) { |
| 630 |
return ''; |
| 631 |
} |
| 632 |
|
| 633 |
if (!empty($field['post_condition']) && is_array($field['post_condition'])) { |
| 634 |
foreach ($field['post_condition'] as $var => $permitted_values) { |
| 635 |
$pass = false; |
| 636 |
foreach ($permitted_values as $permitted) { |
| 637 |
if (isset($_POST[$var]) && $_POST[$var] === $permitted) { |
| 638 |
$pass = true; |
| 639 |
break; |
| 640 |
} |
| 641 |
} |
| 642 |
if (!$pass) { |
| 643 |
// Variable has not been set in a different screen. Hide this field. |
| 644 |
return ''; |
| 645 |
} |
| 646 |
} |
| 647 |
} |
| 648 |
|
| 649 |
$req = empty($field['req']) ? '' : '<span class="photonic-required"><abbr title="'.esc_html__('Required', 'photonic').'">*</abbr></span>'; |
| 650 |
$default = !empty($existing[$id]) ? $existing[$id] : (isset($field['std']) ? $field['std'] : ''); |
| 651 |
$hint = ''; |
| 652 |
$hint_in = ''; |
| 653 |
if (!empty($field['hint'])) { |
| 654 |
$hint = "<div class='photonic-flow-hint' role='tooltip' id='{$id}-hint'>{$field['hint']}</div>\n"; |
| 655 |
$hint_in = "aria-describedby='{$id}-hint'"; |
| 656 |
} |
| 657 |
|
| 658 |
switch ($field['type']) { |
| 659 |
case 'text': |
| 660 |
$ret = "<label class='photonic-flow-option-name'>{$field['desc']}$req<input type='text' name='{$id}' value='" . $default . "' $hint_in/>$hint</label>"; |
| 661 |
break; |
| 662 |
|
| 663 |
case 'radio': |
| 664 |
$ret = !empty($field['desc']) ? '<div class="photonic-flow-option-name">' . $field['desc'] . $req . '</div>' : ''; |
| 665 |
foreach ($field['options'] as $option_value => $option_description) { |
| 666 |
$option_condition = (empty($field['option-conditions']) || empty($field['option-conditions'][$option_value])) ? '' : |
| 667 |
"data-photonic-option-condition='" . json_encode($field['option-conditions'][$option_value]) . "'"; |
| 668 |
$checked = checked($default, $option_value, false); |
| 669 |
$ret .= "\t<div class='photonic-flow-field-radio'><label><input type='radio' name='{$id}' value='$option_value' $checked $option_condition/>" . $option_description . "</label></div>\n"; |
| 670 |
} |
| 671 |
break; |
| 672 |
|
| 673 |
case 'select': |
| 674 |
$ret = "<label class='photonic-flow-option-name'>{$field['desc']}$req\n\t<select name='{$id}' $hint_in>\n"; |
| 675 |
foreach ($field['options'] as $option_value => $option_description) { |
| 676 |
$option_condition = (empty($field['option-conditions']) || empty($field['option-conditions'][$option_value])) ? '' : |
| 677 |
"data-photonic-option-condition='" . json_encode($field['option-conditions'][$option_value]) . "'"; |
| 678 |
$selected = selected($default, $option_value, false); |
| 679 |
$ret .= "\t\t<option value='$option_value' $selected $option_condition>" . esc_attr($option_description) . "</option>\n"; |
| 680 |
} |
| 681 |
$ret .= "\t</select>\n$hint</label>\n"; |
| 682 |
break; |
| 683 |
|
| 684 |
case 'image-select': |
| 685 |
$ret = ''; |
| 686 |
$ret .= '<div class="photonic-flow-option-name">' . $field['desc'] . '</div>'; |
| 687 |
if (!empty($default)) { |
| 688 |
$selection = !in_array($default, $field['options']) ? array_keys($field['options'])[0] : $default; |
| 689 |
} |
| 690 |
else { |
| 691 |
$selection = array_keys($field['options'])[0]; |
| 692 |
} |
| 693 |
foreach ($field['options'] as $option_name => $desc) { |
| 694 |
$esc_desc = esc_attr($desc); |
| 695 |
$selected = ($option_name == $selection) ? 'selected' : ''; |
| 696 |
$ret .= "<div class=\"photonic-flow-selector photonic-flow-$id-$option_name $selected\" title=\"$esc_desc\">\n\t<span class=\"photonic-flow-selector-inner photonic-$id\" data-photonic-selection-id=\"$option_name\"> </span>\n\t<div class='photonic-flow-selector-info'>$desc</div>\n</div>\n"; |
| 697 |
} |
| 698 |
if (!empty($ret)) { |
| 699 |
$ret = "<div class='photonic-flow-selector-container photonic-flow-$id' data-photonic-flow-selector-mode='single-no-plus' data-photonic-flow-selector-for=\"$id\">\n<input type=\"hidden\" id=\"$id\" name=\"$id\" value='$selection'/>\n$ret</div>\n"; |
| 700 |
} |
| 701 |
break; |
| 702 |
|
| 703 |
case 'multi-select': |
| 704 |
$ret = ''; |
| 705 |
$ret .= '<div class="photonic-flow-option-name">' . $field['desc'] . '</div>'; |
| 706 |
$selection = explode(',', $default); |
| 707 |
foreach ($field['options'] as $option_value => $desc) { |
| 708 |
$checked = in_array($option_value, $selection) ? 'checked' : ''; |
| 709 |
$ret .= "\t<label class='photonic-multi-select-item'><input type='checkbox' name='{$id}[]' value=\"$option_value\" $checked />$desc</label>\n"; |
| 710 |
} |
| 711 |
if (!empty($ret)) { |
| 712 |
$ret = "<div class='photonic-flow-multi-select-container'>\n$ret</div>\n"; |
| 713 |
} |
| 714 |
break; |
| 715 |
|
| 716 |
case 'date-filter': |
| 717 |
$ret = ''; |
| 718 |
$ret .= '<div class="photonic-flow-option-name">' . $field['desc'] . '</div>'; |
| 719 |
$dates = !empty($default) ? explode(',', $default) : array(); |
| 720 |
$count = isset($field['count']) && is_numeric($field['count']) ? intval($field['count']) : 1; |
| 721 |
$ret .= "<ol data-photonic-date-filter='$id' data-photonic-filter-count='$count'>\n"; |
| 722 |
$ctr = 0; |
| 723 |
foreach ($dates as $didx => $date) { |
| 724 |
$y_m_d = explode('/', $date); |
| 725 |
$ret .= "\t<li>\n"; |
| 726 |
$ret .= "\t\t<div class='photonic-single-date'>\n"; |
| 727 |
for ($pidx = 0; $pidx < 3; $pidx++) { |
| 728 |
$lower = strtolower($this->date_parts[$pidx]); |
| 729 |
$ret .= "\t\t\t<label class='photonic-date-filter'>\n" . |
| 730 |
"\t\t\t\t".substr($this->date_parts[$pidx], 0, 1)."<input type='text' class='photonic-date-$lower' name='{$id}_{$lower}[]' value=\"" . (isset($y_m_d[$pidx]) ? $y_m_d[$pidx] : '') . "\" aria-describedby='{$id}-{$didx}_{$lower}-hint'/>\n" . |
| 731 |
"\t\t\t\t<div class='photonic-flow-hint' role='tooltip' id='{$id}-{$didx}_{$lower}-hint'>" . $this->date_part_hints[$pidx] . "</div>\n" . |
| 732 |
"\t\t\t</label> \n"; |
| 733 |
} |
| 734 |
$ret .= "\t\t</div>\n"; |
| 735 |
$ret .= "\t\t<a href='#' class='photonic-remove-date-filter' title='Remove filter'><span class=\"dashicons dashicons-no\"> </span></a>\n"; |
| 736 |
$ret .= "\t</li>\n"; |
| 737 |
$ctr++; |
| 738 |
if ($ctr >= $count) { |
| 739 |
break; |
| 740 |
} |
| 741 |
} |
| 742 |
$ret .= "</ol>\n"; |
| 743 |
$ret .= "<input type='hidden' name='$id' value='$default'/>\n"; |
| 744 |
if ($ctr < $count) { |
| 745 |
$ret .= "<a href='#' class='photonic-add-date-filter' data-photonic-add-date='$id'><span class=\"dashicons dashicons-plus-alt\"> </span> Add filter</a>\n"; |
| 746 |
} |
| 747 |
|
| 748 |
break; |
| 749 |
|
| 750 |
case 'date-range-filter': |
| 751 |
$ret = ''; |
| 752 |
$ret .= '<div class="photonic-flow-option-name">' . $field['desc'] . '</div>'; |
| 753 |
$date_ranges = !empty($default) ? explode(',', $default) : array(); |
| 754 |
$count = isset($field['count']) && is_numeric($field['count']) ? intval($field['count']) : 1; |
| 755 |
$ret .= "<ol data-photonic-date-range-filter='$id' data-photonic-filter-count='$count'>\n"; |
| 756 |
$ctr = 0; |
| 757 |
foreach ($date_ranges as $date_range) { |
| 758 |
$from_to = explode('-', $date_range); |
| 759 |
if (count($from_to) != 2) { |
| 760 |
continue; |
| 761 |
} |
| 762 |
$ret .= "\t<li>\n"; |
| 763 |
foreach ($from_to as $didx => $date) { |
| 764 |
$ret .= "\t\t<div class='photonic-single-date'>\n"; |
| 765 |
$y_m_d = explode('/', $date); |
| 766 |
$from_or_to = $didx === 0 ? 'start' : 'end'; |
| 767 |
for ($pidx = 0; $pidx < 3; $pidx++) { |
| 768 |
$lower = strtolower($this->date_parts[$pidx]); |
| 769 |
$ret .= "\t\t\t<label class='photonic-date-filter'>\n" . |
| 770 |
"\t\t\t\t".substr($this->date_parts[$pidx], 0, 1)."<input type='text' class='photonic-date-$lower' name='{$id}_{$from_or_to}_{$lower}[]' value=\"" . (isset($y_m_d[$pidx]) ? $y_m_d[$pidx] : '') . "\" aria-describedby='{$id}-{$didx}_{$from_or_to}_{$lower}-hint'/>\n" . |
| 771 |
"\t\t\t\t<div class='photonic-flow-hint' role='tooltip' id='{$id}-{$didx}_{$from_or_to}_{$lower}-hint'>" . $this->date_part_hints[$pidx] . "</div>\n" . |
| 772 |
"\t\t\t</label> \n"; |
| 773 |
} |
| 774 |
$ret .= "\t\t</div>\n"; |
| 775 |
} |
| 776 |
$ret .= "\t\t<a href='#' class='photonic-remove-date-range-filter' title='Remove filter'><span class=\"dashicons dashicons-no\"> </span></a>\n"; |
| 777 |
$ret .= "\t</li>\n"; |
| 778 |
$ctr++; |
| 779 |
if ($ctr >= $count) { |
| 780 |
break; |
| 781 |
} |
| 782 |
} |
| 783 |
$ret .= "</ol>\n"; |
| 784 |
$ret .= "<input type='hidden' name='$id' value='$default'/>\n"; |
| 785 |
if ($ctr < $count) { |
| 786 |
$ret .= "<a href='#' class='photonic-add-date-range-filter' data-photonic-add-date-range='$id'><span class=\"dashicons dashicons-plus-alt\"> </span> Add filter</a>\n"; |
| 787 |
} |
| 788 |
|
| 789 |
break; |
| 790 |
|
| 791 |
case 'thumbnail-selector': |
| 792 |
$ret = "<div class=\"photonic-flow-selector-container\" data-photonic-flow-selector-mode=\"{$field['mode']}\" data-photonic-flow-selector-for=\"{$field['for']}\">\n{{placeholder_value}}</div>\n"; |
| 793 |
|
| 794 |
$controls = "<div class='thumb-controls'>\n"; |
| 795 |
if ($field['mode'] != 'none') { |
| 796 |
$controls .= "<input type='text' class='search-thumbs' name='thumb-search' id='thumb-search'/>\n"; |
| 797 |
} |
| 798 |
|
| 799 |
if ($field['mode'] == 'multi') { |
| 800 |
$controls .= esc_html__('Mark:', 'photonic'). |
| 801 |
sprintf(esc_html__('%1$sAll%2$s', 'photonic'), "<a href='#' class='photonic-mark photonic-mark-all' data-photonic-mark-for='{$field['for']}'>", '</a>').'|'. |
| 802 |
sprintf(esc_html__('%1$sNone%2$s', 'photonic'), "<a href='#' class='photonic-mark photonic-mark-none' data-photonic-mark-for='{$field['for']}'>", '</a>'); |
| 803 |
} |
| 804 |
$controls .= "</div>\n"; |
| 805 |
$ret = $controls.$ret; |
| 806 |
break; |
| 807 |
|
| 808 |
default: |
| 809 |
return ''; |
| 810 |
} |
| 811 |
|
| 812 |
if (!empty($ret)) { |
| 813 |
if (!empty($field['hint'])) { |
| 814 |
// $ret .= "<div class='photonic-flow-hint' role='tooltip' id='{$id}-hint'><div>{$field['hint']}</div></div>\n"; |
| 815 |
} |
| 816 |
|
| 817 |
$sequence_str = ''; |
| 818 |
if ($sequence !== 0) { |
| 819 |
$sequence_str = 'data-photonic-flow-sequence="' . $sequence . '"'; |
| 820 |
} |
| 821 |
|
| 822 |
$sequence_group_str = ''; |
| 823 |
if (!is_null($sequence_group)) { |
| 824 |
$sequence_group_str = 'data-photonic-flow-sequence-group="' . $sequence_group . '"'; |
| 825 |
} |
| 826 |
|
| 827 |
$condition = ''; |
| 828 |
if (!empty($field['conditions'])) { |
| 829 |
$condition = "data-photonic-condition='" . json_encode($field['conditions']) . "'"; |
| 830 |
} |
| 831 |
|
| 832 |
$ret = "<div class='photonic-flow-field' $sequence_str $condition $sequence_group_str>\n" . $ret . "</div>\n"; |
| 833 |
} |
| 834 |
return $ret; |
| 835 |
} |
| 836 |
|
| 837 |
/** |
| 838 |
* Performs basic checks against whitelists. More advanced checks are handled in the <code>validate</code> function |
| 839 |
* |
| 840 |
* @param $id |
| 841 |
* @param $field |
| 842 |
* @param bool $check_required |
| 843 |
* @return array|bool |
| 844 |
*/ |
| 845 |
private function do_basic_option_check($id, $field, $check_required = false) { |
| 846 |
if (empty($field['type']) || ($field['type'] != 'select' && $field['type'] != 'radio')) { |
| 847 |
return false; |
| 848 |
} |
| 849 |
|
| 850 |
if ($check_required && !empty($field['req']) && (!isset($_POST[$id]) || trim($_POST[$id]) === '')) { |
| 851 |
return array('error' => $this->error_mandatory); |
| 852 |
} |
| 853 |
|
| 854 |
if (isset($_POST[$id]) && !in_array(sanitize_text_field($_POST[$id]), array_keys($field['options']))) { |
| 855 |
return array('error' => sprintf($this->error_not_permitted, $field['name'], $_POST[$id])); |
| 856 |
} |
| 857 |
return false; |
| 858 |
} |
| 859 |
|
| 860 |
/** |
| 861 |
* A special type of selector not handled by the <code>process_field</code> call. Layouts are used only on one screen, |
| 862 |
* and are used by almost all types of providers. This displays the available layouts as icons to pick from. |
| 863 |
* |
| 864 |
* @param $display_type |
| 865 |
* @param array $existing |
| 866 |
* @return string |
| 867 |
*/ |
| 868 |
private function get_layout_selector($display_type, $existing = array()) { |
| 869 |
global $photonic_thumbnail_style; |
| 870 |
$output = ''; |
| 871 |
$level = empty($this->display_types[$display_type]) ? -1 : $this->display_types[$display_type]; |
| 872 |
$layout_from_option = empty($existing['layout']) ? (in_array($photonic_thumbnail_style, array('strip-below', 'strip-above', 'strip-right', 'no-strip')) ? 'slideshow' : $photonic_thumbnail_style) : $existing['layout']; |
| 873 |
|
| 874 |
if ($level > 0) { |
| 875 |
$layout_options = $this->flow_fields->get_layout_options(); |
| 876 |
foreach ($layout_options as $layout => $desc) { |
| 877 |
$selected = $layout == $layout_from_option ? 'selected' : ''; |
| 878 |
if (($layout == 'slideshow' && $level == 1) || $layout != 'slideshow') { |
| 879 |
$esc_desc = esc_attr($desc); |
| 880 |
$output .= "<div class=\"photonic-flow-selector photonic-flow-layout-$layout $selected\" title=\"$esc_desc\">\n\t<span class=\"photonic-flow-selector-inner photonic-layout\" data-photonic-selection-id=\"$layout\"> </span>\n\t<div class='photonic-flow-selector-info'>$desc</div>\n</div>\n"; |
| 881 |
} |
| 882 |
} |
| 883 |
if (!empty($output)) { |
| 884 |
$output = "<div class='photonic-flow-selector-container photonic-flow-layout' data-photonic-flow-selector-mode='single-no-plus' data-photonic-flow-selector-for=\"layout\">\n<input type=\"hidden\" id=\"layout\" name=\"layout\" value='$layout_from_option'/>\n$output</div>\n"; |
| 885 |
} |
| 886 |
} |
| 887 |
$output = '<h1>' . esc_html__('Pick Your Layout', 'photonic') . '</h1>' . |
| 888 |
"<p>" . sprintf(esc_html__('You can configure the default settings from %s.', 'photonic'), '<strong>Photonic → Settings → Generic Options → Generic Settings → Layouts</strong>') . "</p>\n". |
| 889 |
$output; |
| 890 |
|
| 891 |
if ($this->force_next_screen > -1) { |
| 892 |
$output .= "\n<input type='hidden' name='force_next_screen' value='{$this->force_next_screen}'/>\n"; |
| 893 |
} |
| 894 |
if ($this->force_previous_screen > -1) { |
| 895 |
$output .= "\n<input type='hidden' name='force_previous_screen' value='{$this->force_previous_screen}'/>\n"; |
| 896 |
} |
| 897 |
|
| 898 |
return $output; |
| 899 |
} |
| 900 |
|
| 901 |
/** |
| 902 |
* Layouts use similar constructs such as <code>count</code> and <code>more</code> but also have differences. |
| 903 |
* E.g. <code>columns</code> are not applicable to the justified grid or mosaic layouts etc. Similarly size options |
| 904 |
* vary from provider to provider. So in the Photonic_Flow_Fields we have a hierarchy for this screen, by level, provider and layout |
| 905 |
* |
| 906 |
* @param $provider |
| 907 |
* @param $display_type |
| 908 |
* @param $layout |
| 909 |
* @param array $existing |
| 910 |
* @return string |
| 911 |
*/ |
| 912 |
private function get_layout_options($provider, $display_type, $layout, $existing = array()) { |
| 913 |
// All levels, all layouts - media |
| 914 |
// L1, L2 All layouts - title position |
| 915 |
// L1 All layouts - count, more |
| 916 |
// L1, L2, L3 basic lightbox layouts - # of columns, constrain by etc., thumbnail size, full size |
| 917 |
// L3 Flickr - auto-expand |
| 918 |
$level = $this->display_types[$display_type]; |
| 919 |
$output = '<h1>' . esc_html__('Configure Your Layout', 'photonic') . '</h1>'; |
| 920 |
|
| 921 |
$extract = array(); |
| 922 |
if (!empty($this->field_list['screen-5'][$provider]['L' . $level])) { |
| 923 |
$extract = array_merge($this->field_list['screen-5'][$provider]['L' . $level], $extract); |
| 924 |
} |
| 925 |
|
| 926 |
if (!empty($this->field_list['screen-5'][$layout][$provider])) { |
| 927 |
$extract = array_merge($this->field_list['screen-5'][$layout][$provider], $extract); |
| 928 |
} |
| 929 |
|
| 930 |
if (!empty($this->field_list['screen-5'][$provider])) { |
| 931 |
$extract = array_merge($this->field_list['screen-5'][$provider], $extract); |
| 932 |
} |
| 933 |
|
| 934 |
if (!empty($this->field_list['screen-5']['L' . $level])) { |
| 935 |
$extract = array_merge($this->field_list['screen-5']['L' . $level], $extract); |
| 936 |
} |
| 937 |
|
| 938 |
if (!empty($this->field_list['screen-5'][$layout])) { |
| 939 |
$extract = array_merge($this->field_list['screen-5'][$layout], $extract); |
| 940 |
} |
| 941 |
|
| 942 |
$output .= $this->render_all_fields($extract, $existing); |
| 943 |
return $output; |
| 944 |
} |
| 945 |
|
| 946 |
/** |
| 947 |
* Builds out the shortcode based on inputs from all previous screens. Some attributes are passed as they are, e.g. <code>count</code>. |
| 948 |
* Others are used to determine other attributes, e.g. <code>display_type</code> |
| 949 |
* |
| 950 |
* @return string |
| 951 |
*/ |
| 952 |
private function construct_shortcode() { |
| 953 |
global $photonic_alternative_shortcode; |
| 954 |
|
| 955 |
$provider = sanitize_text_field($_POST['provider']); |
| 956 |
$display_type = sanitize_text_field($_POST['display_type']); |
| 957 |
|
| 958 |
$short_code = array(); |
| 959 |
if ($provider !== 'wp') { |
| 960 |
$short_code['type'] = $provider; |
| 961 |
} |
| 962 |
|
| 963 |
switch ($provider) { |
| 964 |
case 'flickr': |
| 965 |
if ($display_type == 'single-photo') { |
| 966 |
$short_code['view'] = 'photo'; |
| 967 |
$short_code['photo_id'] = sanitize_text_field($_POST['selected_data']); |
| 968 |
} |
| 969 |
else if ($display_type == 'multi-photo') { |
| 970 |
$short_code['view'] = 'photos'; |
| 971 |
} |
| 972 |
else if ($display_type == 'album-photo') { |
| 973 |
$short_code['view'] = 'photosets'; |
| 974 |
$short_code['photoset_id'] = sanitize_text_field($_POST['selected_data']); |
| 975 |
} |
| 976 |
else if ($display_type == 'gallery-photo') { |
| 977 |
$short_code['view'] = 'galleries'; |
| 978 |
$short_code['gallery_id'] = sanitize_text_field($_POST['selected_data']); |
| 979 |
} |
| 980 |
else if ($display_type == 'multi-album') { |
| 981 |
$short_code['view'] = 'photosets'; |
| 982 |
} |
| 983 |
else if ($display_type == 'multi-gallery') { |
| 984 |
$short_code['view'] = 'galleries'; |
| 985 |
} |
| 986 |
else if ($display_type == 'collection') { |
| 987 |
$short_code['view'] = 'collections'; |
| 988 |
$short_code['collection_id'] = sanitize_text_field($_POST['selected_data']); |
| 989 |
} |
| 990 |
else if ($display_type == 'collections') { |
| 991 |
$short_code['view'] = 'collections'; |
| 992 |
} |
| 993 |
break; |
| 994 |
|
| 995 |
case 'smugmug': |
| 996 |
if ($display_type == 'album-photo') { |
| 997 |
$short_code['view'] = 'album'; |
| 998 |
$short_code['album'] = sanitize_text_field($_POST['selected_data']); |
| 999 |
} |
| 1000 |
else if ($display_type == 'folder-photo') { |
| 1001 |
$short_code['view'] = 'images'; |
| 1002 |
$short_code['folder'] = sanitize_text_field($_POST['selected_data']); |
| 1003 |
} |
| 1004 |
else if ($display_type == 'user-photo') { |
| 1005 |
$short_code['view'] = 'images'; |
| 1006 |
} |
| 1007 |
else if ($display_type == 'multi-album') { |
| 1008 |
$short_code['view'] = 'albums'; |
| 1009 |
} |
| 1010 |
else if ($display_type == 'tree') { |
| 1011 |
$short_code['view'] = 'tree'; |
| 1012 |
} |
| 1013 |
else if ($display_type == 'folder') { |
| 1014 |
$short_code['view'] = 'folder'; |
| 1015 |
$short_code['folder'] = sanitize_text_field($_POST['selected_data']); |
| 1016 |
} |
| 1017 |
break; |
| 1018 |
|
| 1019 |
case 'google': |
| 1020 |
if ($display_type == 'album-photo') { |
| 1021 |
$short_code['view'] = 'photos'; |
| 1022 |
$short_code['album_id'] = sanitize_text_field($_POST['selected_data']); |
| 1023 |
} |
| 1024 |
else if ($display_type == 'multi-photo') { |
| 1025 |
$short_code['view'] = 'photos'; |
| 1026 |
$date_filters = !empty($_POST['date_filters']) ? sanitize_text_field($_POST['date_filters']) : ''; |
| 1027 |
$date_range_filters = !empty($_POST['date_range_filters']) ? sanitize_text_field($_POST['date_range_filters']) : ''; |
| 1028 |
$short_code['date_filters'] = trim($date_filters.','.$date_range_filters, ','); |
| 1029 |
} |
| 1030 |
else if ($display_type == 'multi-album') { |
| 1031 |
$short_code['view'] = 'albums'; |
| 1032 |
} |
| 1033 |
break; |
| 1034 |
|
| 1035 |
case 'zenfolio': |
| 1036 |
if ($display_type == 'multi-photo') { |
| 1037 |
$short_code['view'] = 'photos'; |
| 1038 |
} |
| 1039 |
else if ($display_type == 'single-photo') { |
| 1040 |
$short_code['view'] = 'photos'; |
| 1041 |
$short_code['object_id'] = sanitize_text_field($_POST['selected_data']); |
| 1042 |
} |
| 1043 |
else if ($display_type == 'gallery-photo'/* || $display_type == 'collection-photo'*/) { |
| 1044 |
$short_code['view'] = 'photosets'; |
| 1045 |
$short_code['object_id'] = sanitize_text_field($_POST['selected_data']); |
| 1046 |
} |
| 1047 |
else if ($display_type == 'multi-gallery' || $display_type == 'multi-collection' || $display_type == 'multi-gallery-collection') { |
| 1048 |
$short_code['view'] = 'photosets'; |
| 1049 |
if ($display_type == 'multi-gallery') { |
| 1050 |
$short_code['photoset_type'] = 'Gallery'; |
| 1051 |
} |
| 1052 |
else if ($display_type == 'multi-collection') { |
| 1053 |
$short_code['photoset_type'] = 'Collection'; |
| 1054 |
} |
| 1055 |
} |
| 1056 |
else if ($display_type == 'group') { |
| 1057 |
$short_code['view'] = 'group'; |
| 1058 |
$short_code['object_id'] = sanitize_text_field($_POST['selected_data']); |
| 1059 |
} |
| 1060 |
else if ($display_type == 'group-hierarchy') { |
| 1061 |
$short_code['view'] = 'hierarchy'; |
| 1062 |
} |
| 1063 |
break; |
| 1064 |
|
| 1065 |
case 'instagram': |
| 1066 |
if ($display_type == 'single-photo') { |
| 1067 |
$short_code['media_id'] = sanitize_text_field($_POST['selected_data']); |
| 1068 |
} |
| 1069 |
break; |
| 1070 |
|
| 1071 |
default: |
| 1072 |
if ($display_type == 'current-post' && !empty($_POST['post_id'])) { |
| 1073 |
$short_code['id'] = sanitize_text_field($_POST['post_id']); |
| 1074 |
} |
| 1075 |
else if (!empty($_POST['selected_data'])) { |
| 1076 |
$short_code['ids'] = sanitize_text_field($_POST['selected_data']); |
| 1077 |
} |
| 1078 |
break; |
| 1079 |
} |
| 1080 |
|
| 1081 |
if (!empty($_POST['selection'])) { |
| 1082 |
if ($_POST['selection'] != 'all') { |
| 1083 |
$short_code['filter'] = sanitize_text_field($_POST['selected_data']); |
| 1084 |
} |
| 1085 |
if ($_POST['selection'] == 'not-selected') { |
| 1086 |
$short_code['filter_type'] = 'exclude'; |
| 1087 |
} |
| 1088 |
} |
| 1089 |
|
| 1090 |
if (isset($_POST['headers']) && trim($_POST['headers'] !== '')) { |
| 1091 |
if (trim($_POST['headers']) == 'none') { |
| 1092 |
$short_code['headers'] = ''; |
| 1093 |
} |
| 1094 |
else { |
| 1095 |
$short_code['headers'] = sanitize_text_field($_POST['headers']); |
| 1096 |
} |
| 1097 |
} |
| 1098 |
|
| 1099 |
$additional_attrs = array_merge( |
| 1100 |
$this->shortcode_attributes[$provider], |
| 1101 |
$this->shortcode_attributes['common'] |
| 1102 |
); |
| 1103 |
foreach ($additional_attrs as $attr) { |
| 1104 |
if (!empty($_POST[$attr]) && is_array($_POST[$attr])) { |
| 1105 |
$short_code[$attr] = implode(',', $_POST[$attr]); |
| 1106 |
} |
| 1107 |
else if (!empty($_POST[$attr])) { |
| 1108 |
$short_code[$attr] = $_POST[$attr]; |
| 1109 |
} |
| 1110 |
} |
| 1111 |
|
| 1112 |
if (!empty($_POST['layout'])) { |
| 1113 |
$key = $provider == 'wp' ? 'style' : 'layout'; |
| 1114 |
if ($_POST['layout'] != 'slideshow') { |
| 1115 |
$short_code[$key] = sanitize_text_field($_POST['layout']); |
| 1116 |
} |
| 1117 |
else { |
| 1118 |
$short_code[$key] = sanitize_text_field($_POST['slideshow-style']); |
| 1119 |
} |
| 1120 |
} |
| 1121 |
// layout |
| 1122 |
|
| 1123 |
$raw_shortcode = !empty($_POST['photonic-editor-shortcode-raw']) ? sanitize_text_field($_POST['photonic-editor-shortcode-raw']) : ''; |
| 1124 |
if (!empty($raw_shortcode)) { |
| 1125 |
$input = base64_decode($raw_shortcode); |
| 1126 |
$input = json_decode($input); |
| 1127 |
if (!empty($input->shortcode) && !empty($input->shortcode->attrs) && !empty($input->shortcode->attrs->named)) { |
| 1128 |
$input = $input->shortcode->attrs->named; |
| 1129 |
} |
| 1130 |
} |
| 1131 |
else { |
| 1132 |
$raw_shortcode = !empty($_POST['photonic-editor-json']) ? stripslashes_deep($_POST['photonic-editor-json']) : ''; |
| 1133 |
$input = json_decode($raw_shortcode); |
| 1134 |
} |
| 1135 |
|
| 1136 |
if (!empty($input)) { |
| 1137 |
$attr_array = (array)$input; |
| 1138 |
|
| 1139 |
// If the type changes, regardless of everything else blank out the attributes |
| 1140 |
if (!(empty($short_code['type']) && (empty($attr_array['type']) || in_array($attr_array['type'], array('wp', 'default')))) && |
| 1141 |
($attr_array['type'] != $short_code['type'])) { |
| 1142 |
$attr_array = array(); |
| 1143 |
} |
| 1144 |
else { |
| 1145 |
foreach ($short_code as $key => $value) { |
| 1146 |
unset($attr_array[$key]); |
| 1147 |
} |
| 1148 |
} |
| 1149 |
|
| 1150 |
if (!empty($this->aka_attributes[$provider])) { |
| 1151 |
$aka = $this->aka_attributes[$provider]; |
| 1152 |
foreach ($aka as $key => $value) { |
| 1153 |
if (isset($short_code[$key]) || isset($short_code[$value])) unset($attr_array[$key]); |
| 1154 |
} |
| 1155 |
} |
| 1156 |
|
| 1157 |
// Others ... |
| 1158 |
if (!empty($short_code['type']) && $short_code['type'] == 'instagram') { |
| 1159 |
if (!empty($short_code['media_id'])) { |
| 1160 |
unset($attr_array['view']); |
| 1161 |
unset($attr_array['media']); |
| 1162 |
} |
| 1163 |
else if (!empty($short_code['media'])) { |
| 1164 |
unset($attr_array['media_id']); |
| 1165 |
} |
| 1166 |
} |
| 1167 |
$short_code = array_merge($short_code, $attr_array); |
| 1168 |
} |
| 1169 |
|
| 1170 |
if (!$this->is_gutenberg) { |
| 1171 |
$output = '<h1>' . esc_html__('Your shortcode', 'photonic') . '</h1>'; |
| 1172 |
$output .= "<code id='photonic_shortcode'>[" . (empty($photonic_alternative_shortcode) ? 'gallery' : $photonic_alternative_shortcode).' '; |
| 1173 |
$shortcode_attrs = array(); |
| 1174 |
foreach ($short_code as $attr => $value) { |
| 1175 |
$shortcode_attrs[] = $attr . "='" . esc_attr($value) . "'"; |
| 1176 |
} |
| 1177 |
|
| 1178 |
$output .= implode(' ', $shortcode_attrs); |
| 1179 |
$output .= ']</code>'; |
| 1180 |
$output .= '<p>'.esc_html__('The above shortcode was generated based on your selections. You can either copy the above and paste it manually into your post, or click on the buttons below to insert it into or update your post', 'photonic').'</p>'; |
| 1181 |
} |
| 1182 |
else { |
| 1183 |
$output = '<h1>' . esc_html__('Your Gallery', 'photonic') . '</h1>'; |
| 1184 |
$output .= '<p>'.esc_html__('Based on your selections a gallery with the following attributes will be generated. Please click on the buttons below to insert it into or update your post:', 'photonic').'</p>'; |
| 1185 |
$shortcode_attrs = array(); |
| 1186 |
foreach ($short_code as $attr => $value) { |
| 1187 |
$shortcode_attrs[] = '<code>'.$attr . ": " . esc_attr($value).'</code>'; |
| 1188 |
} |
| 1189 |
$output .= implode("<br/>\n", $shortcode_attrs); |
| 1190 |
|
| 1191 |
$output .= '<p>'.esc_html__('The following is the corresponding shortcode for this block. If for some reason you are unable to create a Photonic block you can paste this into a Shortcode block:', 'photonic').'</p>'; |
| 1192 |
$output .= "<code>[" . (empty($photonic_alternative_shortcode) ? 'gallery' : $photonic_alternative_shortcode).' '; |
| 1193 |
$shortcode_attrs = array(); |
| 1194 |
foreach ($short_code as $attr => $value) { |
| 1195 |
$shortcode_attrs[] = $attr . "='" . esc_attr($value) . "'"; |
| 1196 |
} |
| 1197 |
|
| 1198 |
$output .= implode(' ', $shortcode_attrs); |
| 1199 |
$output .= ']</code>'; |
| 1200 |
|
| 1201 |
$output .= "<input id='photonic_shortcode' name='photonic_shortcode' type='hidden' value='".esc_attr(json_encode($short_code))."' />\n"; |
| 1202 |
} |
| 1203 |
|
| 1204 |
if ($this->force_next_screen > -1) { |
| 1205 |
$output .= "\n<input type='hidden' name='force_next_screen' value='{$this->force_next_screen}'/>\n"; |
| 1206 |
} |
| 1207 |
if ($this->force_previous_screen > -1) { |
| 1208 |
$output .= "\n<input type='hidden' name='force_previous_screen' value='{$this->force_previous_screen}'/>\n"; |
| 1209 |
} |
| 1210 |
return $output; |
| 1211 |
} |
| 1212 |
|
| 1213 |
/** |
| 1214 |
* This is the inverse of the <code>construct_shortcode</code> method. If the Editor has a shortcode selected, this method |
| 1215 |
* splits it out into the relevant screens. |
| 1216 |
* |
| 1217 |
* @param $input |
| 1218 |
* @return array |
| 1219 |
*/ |
| 1220 |
private function deconstruct_shortcode($input) { |
| 1221 |
$deconstructed = array(); |
| 1222 |
if (!empty($input)) { |
| 1223 |
if ((!empty($input->type) && in_array($input->type, array('wp', 'default', 'flickr', 'smugmug', 'picasa', 'google', 'zenfolio', 'instagram'))) || |
| 1224 |
(empty($input->type) && !empty($input->style)) && in_array($input->style, array('square', 'circle', 'random', 'masonry', 'mosaic', 'strip-above', 'strip-below', 'strip-right', 'no-strip')) |
| 1225 |
) { |
| 1226 |
$deconstructed['provider'] = !empty($input->type) ? $input->type : 'wp'; |
| 1227 |
|
| 1228 |
switch ($deconstructed['provider']) { |
| 1229 |
case 'flickr': |
| 1230 |
// Potential for an existing (old) shortcode to not have a user_id. E.g. Just defining photoset_id. |
| 1231 |
// Rather than defaulting to the default user, we will make the user put it in this time. |
| 1232 |
if (!empty($input->user_id)) { |
| 1233 |
$deconstructed['for'] = 'other'; |
| 1234 |
$deconstructed['login'] = $input->user_id; |
| 1235 |
} |
| 1236 |
else if (!empty($input->group_id)) { |
| 1237 |
$deconstructed['for'] = 'group'; |
| 1238 |
$deconstructed['group'] = $input->group_id; |
| 1239 |
} |
| 1240 |
|
| 1241 |
if (!empty($input->view)) { |
| 1242 |
if ($input->view == 'collections' && empty($input->collection_id)) { |
| 1243 |
$deconstructed['display_type'] = 'collections'; |
| 1244 |
} |
| 1245 |
else if ($input->view == 'galleries' && empty($input->gallery_id)) { |
| 1246 |
$deconstructed['display_type'] = 'multi-gallery'; |
| 1247 |
} |
| 1248 |
else if ($input->view == 'photosets' && empty($input->photoset_id)) { |
| 1249 |
$deconstructed['display_type'] = 'multi-album'; |
| 1250 |
} |
| 1251 |
else if ($input->view == 'photos') { |
| 1252 |
$deconstructed['display_type'] = 'multi-photo'; |
| 1253 |
} |
| 1254 |
} |
| 1255 |
|
| 1256 |
if (!empty($input->collection_id)) { |
| 1257 |
$deconstructed['display_type'] = 'collection'; |
| 1258 |
$deconstructed['selected_data'] = $input->collection_id; |
| 1259 |
} |
| 1260 |
else if (!empty($input->gallery_id)) { |
| 1261 |
$deconstructed['display_type'] = 'gallery-photo'; |
| 1262 |
$deconstructed['selected_data'] = $input->gallery_id; |
| 1263 |
} |
| 1264 |
else if (!empty($input->photoset_id)) { |
| 1265 |
$deconstructed['display_type'] = 'album-photo'; |
| 1266 |
$deconstructed['selected_data'] = $input->photoset_id; |
| 1267 |
} |
| 1268 |
else if (!empty($input->photo_id)) { |
| 1269 |
$deconstructed['display_type'] = 'single-photo'; |
| 1270 |
$deconstructed['selected_data'] = $input->photo_id; |
| 1271 |
} |
| 1272 |
|
| 1273 |
break; |
| 1274 |
|
| 1275 |
case 'smugmug': |
| 1276 |
if (!empty($input->view)) { |
| 1277 |
if ($input->view == 'tree') { |
| 1278 |
$deconstructed['display_type'] = 'tree'; |
| 1279 |
} |
| 1280 |
else if ($input->view == 'folder') { |
| 1281 |
$deconstructed['display_type'] = 'folder'; |
| 1282 |
} |
| 1283 |
else if ($input->view == 'albums') { |
| 1284 |
$deconstructed['display_type'] = 'multi-album'; |
| 1285 |
} |
| 1286 |
else if ($input->view == 'images' || $input->view == 'album') { |
| 1287 |
if (!empty($input->album) || !empty($input->album_key) || !empty($input->album_id)) { |
| 1288 |
$deconstructed['display_type'] = 'album-photo'; |
| 1289 |
} |
| 1290 |
else if (!empty($input->folder)) { |
| 1291 |
$deconstructed['display_type'] = 'folder-photo'; |
| 1292 |
} |
| 1293 |
else if (!empty($input->nick_name)) { |
| 1294 |
$deconstructed['display_type'] = 'user-photo'; |
| 1295 |
} |
| 1296 |
} |
| 1297 |
|
| 1298 |
if (!empty($input->folder)) { |
| 1299 |
$deconstructed['selected_data'] = trim($input->folder); |
| 1300 |
} |
| 1301 |
else if (!empty($input->album_key)) { // old syntax |
| 1302 |
$deconstructed['selected_data'] = $input->album_key; |
| 1303 |
} |
| 1304 |
else if (!empty($input->album)) { |
| 1305 |
$album = explode('_', $input->album); |
| 1306 |
if (count($album) == 2) { |
| 1307 |
$deconstructed['selected_data'] = $album[1]; |
| 1308 |
} |
| 1309 |
else if (count($album) == 1) { |
| 1310 |
$deconstructed['selected_data'] = $album[0]; |
| 1311 |
} |
| 1312 |
} |
| 1313 |
|
| 1314 |
if (!empty($input->nick_name)) { |
| 1315 |
$deconstructed['for'] = 'other'; |
| 1316 |
$deconstructed['user'] = $input->nick_name; |
| 1317 |
} |
| 1318 |
} |
| 1319 |
break; |
| 1320 |
|
| 1321 |
case 'google': |
| 1322 |
if (!empty($input->view)) { |
| 1323 |
if ($input->view == 'photos') { |
| 1324 |
if (!empty($input->album_id)) { |
| 1325 |
$deconstructed['display_type'] = 'album-photo'; |
| 1326 |
$deconstructed['selected_data'] = sanitize_text_field($input->album_id); |
| 1327 |
} |
| 1328 |
else { |
| 1329 |
$deconstructed['display_type'] = 'multi-photo'; |
| 1330 |
if (!empty($input->date_filters)) { |
| 1331 |
$filters = sanitize_text_field($input->date_filters); |
| 1332 |
$filters = explode(',', $filters); |
| 1333 |
$date_filters = array(); |
| 1334 |
$date_range_filters = array(); |
| 1335 |
foreach ($filters as $filter) { |
| 1336 |
$maybe_range = explode('-', $filter); |
| 1337 |
if (count($maybe_range) == 2) { |
| 1338 |
$date_range_filters[] = $filter; |
| 1339 |
} |
| 1340 |
else if (count($maybe_range) == 1) { |
| 1341 |
$date_filters[] = $filter; |
| 1342 |
} |
| 1343 |
} |
| 1344 |
if (count($date_range_filters) > 5) { |
| 1345 |
$date_range_filters = array_slice($date_range_filters, 0, 5); |
| 1346 |
} |
| 1347 |
if (count($date_filters) > 5) { |
| 1348 |
$date_filters = array_slice($date_filters, 0, 5); |
| 1349 |
} |
| 1350 |
$date_range_filters = implode(',', $date_range_filters); |
| 1351 |
$date_filters = implode(',', $date_filters); |
| 1352 |
if (!empty($date_filters)) { |
| 1353 |
$deconstructed['date_filters'] = $date_filters; |
| 1354 |
} |
| 1355 |
if (!empty($date_range_filters)) { |
| 1356 |
$deconstructed['date_range_filters'] = $date_range_filters; |
| 1357 |
} |
| 1358 |
} |
| 1359 |
} |
| 1360 |
} |
| 1361 |
else if ($input->view == 'albums') { |
| 1362 |
$deconstructed['display_type'] = 'multi-album'; |
| 1363 |
} |
| 1364 |
} |
| 1365 |
break; |
| 1366 |
|
| 1367 |
case 'zenfolio': |
| 1368 |
if (!empty($input->view)) { |
| 1369 |
if ($input->view == 'photos' && empty($input->object_id)) { |
| 1370 |
$deconstructed['display_type'] = 'multi-photo'; |
| 1371 |
} |
| 1372 |
else if ($input->view == 'photos' && !empty($input->object_id)) { |
| 1373 |
$deconstructed['display_type'] = 'single-photo'; |
| 1374 |
$deconstructed['selected_data'] = $input->object_id; |
| 1375 |
} |
| 1376 |
else if ($input->view == 'photosets') { |
| 1377 |
if (!empty($input->object_id)) { |
| 1378 |
$deconstructed['display_type'] = 'gallery-photo'; |
| 1379 |
$deconstructed['selected_data'] = $input->object_id; |
| 1380 |
} |
| 1381 |
else if (empty($input->photoset_type)) { |
| 1382 |
$deconstructed['display_type'] = 'multi-gallery-collection'; |
| 1383 |
} |
| 1384 |
else if (strtolower($input->photoset_type) == 'collection') { |
| 1385 |
$deconstructed['display_type'] = 'multi-collection'; |
| 1386 |
} |
| 1387 |
else if (strtolower($input->photoset_type) == 'gallery') { |
| 1388 |
$deconstructed['display_type'] = 'multi-gallery'; |
| 1389 |
} |
| 1390 |
} |
| 1391 |
else if ($input->view == 'hierarchy') { |
| 1392 |
$deconstructed['display_type'] = 'group-hierarchy'; |
| 1393 |
} |
| 1394 |
else if ($input->view == 'group') { |
| 1395 |
$deconstructed['display_type'] = 'group'; |
| 1396 |
if (!empty($input->object_id)) { |
| 1397 |
$deconstructed['selected_data'] = $input->object_id; |
| 1398 |
} |
| 1399 |
} |
| 1400 |
|
| 1401 |
if ($input->view == 'photosets' || $input->view == 'hierarchy' || $input->view == 'group' || |
| 1402 |
$deconstructed['display_type'] == 'single-photo') { |
| 1403 |
global $photonic_zenfolio_default_user; |
| 1404 |
if (!isset($input->login_name) && !empty($photonic_zenfolio_default_user)) { |
| 1405 |
$deconstructed['for'] = 'current'; |
| 1406 |
} |
| 1407 |
else if (!empty($input->login_name)) { |
| 1408 |
$deconstructed['login_name'] = $input->login_name; |
| 1409 |
$deconstructed['for'] = 'other'; |
| 1410 |
} |
| 1411 |
} |
| 1412 |
} |
| 1413 |
break; |
| 1414 |
|
| 1415 |
case 'instagram': |
| 1416 |
if (!empty($input->media_id)) { |
| 1417 |
$deconstructed['display_type'] = 'single-photo'; |
| 1418 |
$deconstructed['selected_data'] = $input->media_id; |
| 1419 |
} |
| 1420 |
else { |
| 1421 |
$deconstructed['display_type'] = 'multi-photo'; |
| 1422 |
} |
| 1423 |
break; |
| 1424 |
|
| 1425 |
default: |
| 1426 |
case 'wp': |
| 1427 |
case 'default': |
| 1428 |
if (empty($input->id) && empty($input->ids) && empty($input->include)) { |
| 1429 |
$deconstructed['display_type'] = 'current-post'; |
| 1430 |
} |
| 1431 |
else if (!empty($input->ids) || !empty($input->include)) { |
| 1432 |
$deconstructed['display_type'] = 'multi-photo'; |
| 1433 |
$deconstructed['selected_data'] = !empty($input->ids) ? $input->ids : $input->include; |
| 1434 |
} |
| 1435 |
break; |
| 1436 |
} |
| 1437 |
|
| 1438 |
if (!empty($input->filter)) { |
| 1439 |
$deconstructed['selected_data'] = $input->filter; |
| 1440 |
if (empty($input->filter_type) && in_array($input->filter_type, array('include', 'exclude'))) { |
| 1441 |
$deconstructed['selection'] = $input->filter_type; |
| 1442 |
} |
| 1443 |
else { |
| 1444 |
$deconstructed['selection'] = 'selected'; |
| 1445 |
} |
| 1446 |
} |
| 1447 |
else { |
| 1448 |
$deconstructed['selection'] = 'all'; |
| 1449 |
} |
| 1450 |
|
| 1451 |
if (isset($this->aka_attributes[$deconstructed['provider']])) { |
| 1452 |
$aka_attributes = $this->aka_attributes[$deconstructed['provider']]; |
| 1453 |
foreach ($aka_attributes as $attr => $aka) { |
| 1454 |
if (isset($input->{$attr}) && !isset($deconstructed[$aka])) { |
| 1455 |
$deconstructed[$aka] = sanitize_text_field($input->{$attr}); |
| 1456 |
} |
| 1457 |
} |
| 1458 |
} |
| 1459 |
|
| 1460 |
$layout = empty($input->layout) ? (empty($input->style) ? '' : $input->style) : $input->layout; |
| 1461 |
if (!empty($layout)) { |
| 1462 |
if (in_array($layout, array('square', 'circle', 'random', 'masonry', 'mosaic',))) { |
| 1463 |
$deconstructed['layout'] = $layout; |
| 1464 |
} |
| 1465 |
else if (in_array($layout, array('strip-above', 'strip-below', 'strip-right', 'no-strip'))) { |
| 1466 |
$deconstructed['layout'] = 'slideshow'; |
| 1467 |
$deconstructed['slideshow-style'] = $layout; |
| 1468 |
} |
| 1469 |
} |
| 1470 |
|
| 1471 |
$same_name_attrs = array_merge($this->shortcode_attributes['common'], $this->shortcode_attributes[$deconstructed['provider']]); |
| 1472 |
foreach ($same_name_attrs as $attr) { |
| 1473 |
if (isset($input->{$attr}) && !isset($deconstructed[$attr])) { |
| 1474 |
$deconstructed[$attr] = $input->{$attr}; |
| 1475 |
} |
| 1476 |
} |
| 1477 |
} |
| 1478 |
} |
| 1479 |
return $deconstructed; |
| 1480 |
} |
| 1481 |
|
| 1482 |
/** |
| 1483 |
* Displays an array of L1, L2 or L3 objects as a series of selectable thumbnails. Titles are deliberately not displayed because they mess |
| 1484 |
* with the layout if they are too long. |
| 1485 |
* |
| 1486 |
* @param array $objects |
| 1487 |
* @param bool $provider |
| 1488 |
* @param array $existing |
| 1489 |
* @param array $present |
| 1490 |
* @param bool $more |
| 1491 |
* @return string |
| 1492 |
*/ |
| 1493 |
function get_thumbnail_display($objects, $provider = false, $existing = array(), &$present = array(), $more = false) { |
| 1494 |
$output = ''; |
| 1495 |
$selected_data = empty($existing['selected_data']) ? array() : explode(',', $existing['selected_data']); |
| 1496 |
foreach ($objects as $object) { |
| 1497 |
if (!is_array($object)) { |
| 1498 |
$output .= '<h4>'.$object."</h4>\n"; |
| 1499 |
continue; |
| 1500 |
} |
| 1501 |
if (!isset($object['id'])) { |
| 1502 |
continue; |
| 1503 |
} |
| 1504 |
$selected = ''; |
| 1505 |
if (in_array($object['id'], $selected_data) || (!empty($object['alt_id']) && in_array($object['alt_id'], $selected_data)) |
| 1506 |
|| (!empty($object['alt_id2']) && in_array($object['alt_id2'], $selected_data))) { |
| 1507 |
$selected = 'selected'; |
| 1508 |
$present[] = $object['id']; |
| 1509 |
} |
| 1510 |
$passworded = !empty($object['passworded']) ? 'passworded' : ''; |
| 1511 |
|
| 1512 |
$title = !empty($object['title']) ? esc_attr($object['title']) : ''; |
| 1513 |
$counts = !empty($object['counters']) ? ' (' . esc_attr(implode(', ', $object['counters'])) . ')' : ''; |
| 1514 |
$alt = !empty($object['alt_id']) ? "data-photonic-selection-alt-id='{$object['alt_id']}'" : ''; |
| 1515 |
$alt_2 = !empty($object['alt_id2']) ? "data-photonic-selection-alt-id-2='{$object['alt_id2']}'" : ''; |
| 1516 |
|
| 1517 |
$output .= "<div class='photonic-flow-selector $provider $selected $passworded'>\n"; |
| 1518 |
$output .= "\t<div class='photonic-flow-selector-inner' data-photonic-selection-id='{$object['id']}' $alt $alt_2>\n"; |
| 1519 |
$output .= "\t\t<img src='{$object['thumbnail']}' alt='$title$counts' title='$title$counts' />\n"; |
| 1520 |
$output .= "\t</div>\n"; |
| 1521 |
$output .= "</div>\n"; |
| 1522 |
} |
| 1523 |
if ($more) { |
| 1524 |
return $output; |
| 1525 |
} |
| 1526 |
|
| 1527 |
$output .= "<input type='hidden' name='existing_selection' id='existing_selection' value='" . (!empty($present) ? implode(',', $present) : '') . "'/>\n"; |
| 1528 |
return $output; |
| 1529 |
} |
| 1530 |
|
| 1531 |
/** |
| 1532 |
* A recursive call to traverse a SmugMug node and generate a list of objects, with each object corresponding to a folder. |
| 1533 |
* Actually a node is used instead of the folder because the folder object is deprecated by SmugMug, but nodes are only being |
| 1534 |
* used for folders in Photonic. |
| 1535 |
* |
| 1536 |
* @param array $objects |
| 1537 |
* @param $node |
| 1538 |
*/ |
| 1539 |
private function get_smugmug_folders(&$objects, $node) { |
| 1540 |
$object = array(); |
| 1541 |
if ($node->Type == 'Folder') { |
| 1542 |
$object['id'] = $node->NodeID; |
| 1543 |
$object['title'] = !empty($node->Name) ? esc_attr($node->Name) : ''; |
| 1544 |
|
| 1545 |
if (isset($node->Uris->NodeCoverImage->Image->Uris->ImageSizes->ImageSizes->ThumbImageUrl)) { |
| 1546 |
$object['thumbnail'] = $node->Uris->NodeCoverImage->Image->Uris->ImageSizes->ImageSizes->ThumbImageUrl; |
| 1547 |
} |
| 1548 |
else { |
| 1549 |
$object['thumbnail'] = trailingslashit(PHOTONIC_URL) . 'include/images/placeholder-Th.png'; |
| 1550 |
} |
| 1551 |
|
| 1552 |
if (isset($node->Uris->ChildNodes->Node)) { |
| 1553 |
$child_nodes = $node->Uris->ChildNodes->Node; |
| 1554 |
if (is_array($child_nodes)) { |
| 1555 |
foreach ($child_nodes as $child_node) { |
| 1556 |
$this->get_smugmug_folders($objects, $child_node); |
| 1557 |
} |
| 1558 |
} |
| 1559 |
} |
| 1560 |
$objects[] = $object; |
| 1561 |
} |
| 1562 |
} |
| 1563 |
|
| 1564 |
/** |
| 1565 |
* A recursive call to traverse a Zenfolio group and generate a list of objects, with each object corresponding to a photoset. |
| 1566 |
* |
| 1567 |
* @param $objects |
| 1568 |
* @param $elements |
| 1569 |
* @param $display_type |
| 1570 |
*/ |
| 1571 |
private function get_zenfolio_groups(&$objects, $elements, $display_type) { |
| 1572 |
if (!empty($elements->PhotoSet) && $display_type != 'group') { |
| 1573 |
foreach ($elements->PhotoSet as $photoset) { |
| 1574 |
if ((($display_type == 'gallery-photo' || $display_type == 'multi-gallery') && $photoset->Type == 'Gallery') || |
| 1575 |
(($display_type == 'collection-photo' || $display_type == 'multi-collection') && $photoset->Type == 'Collection') || |
| 1576 |
$display_type == 'multi-gallery-collection' || $display_type == 'group-hierarchy' || $display_type == 'single-photo' |
| 1577 |
) { |
| 1578 |
$object = array(); |
| 1579 |
$page_url = parse_url($photoset->PageUrl); |
| 1580 |
$page_url = $page_url['path']; |
| 1581 |
$page_url = explode('/', $page_url); |
| 1582 |
if (count($page_url) > 1) { |
| 1583 |
$page_url = $page_url[1]; |
| 1584 |
} |
| 1585 |
|
| 1586 |
if (!is_array($page_url) && preg_match('/^p\d{9}/', $page_url) === 0) { |
| 1587 |
$page_url = array(); |
| 1588 |
} |
| 1589 |
|
| 1590 |
$object['id'] = !is_array($page_url) ? $page_url : $photoset->Id; |
| 1591 |
$object['alt_id'] = $photoset->Id; |
| 1592 |
$object['title'] = esc_attr($photoset->Title); |
| 1593 |
$object['counters'] = array(esc_html(sprintf(_n('%s media item', '%s media items', $photoset->PhotoCount, 'photonic'), $photoset->PhotoCount))); |
| 1594 |
|
| 1595 |
$photo = $photoset->TitlePhoto; |
| 1596 |
$object['thumbnail'] = 'https://' . $photo->UrlHost . $photo->UrlCore . '-1.jpg'; |
| 1597 |
|
| 1598 |
if (!empty($photoset->AccessDescriptor) && !empty($photoset->AccessDescriptor->AccessType) && $photoset->AccessDescriptor->AccessType == 'Password') { |
| 1599 |
$object['passworded'] = 1; |
| 1600 |
} |
| 1601 |
|
| 1602 |
$objects[] = $object; |
| 1603 |
} |
| 1604 |
} |
| 1605 |
} |
| 1606 |
|
| 1607 |
if (!empty($elements->Group)) { |
| 1608 |
foreach ($elements->Group as $group) { |
| 1609 |
if ($display_type == 'group' || $display_type == 'group-hierarchy') { |
| 1610 |
$object = array(); |
| 1611 |
$object['id'] = $group->Id; |
| 1612 |
$object['title'] = $group->Title; |
| 1613 |
$object['thumbnail'] = trailingslashit(PHOTONIC_URL) . 'include/images/placeholder-Ti.png'; |
| 1614 |
$objects[] = $object; |
| 1615 |
} |
| 1616 |
|
| 1617 |
if ($display_type != 'group-hierarchy' && !empty($group->Elements)) { |
| 1618 |
$this->get_zenfolio_groups($objects, $group->Elements, $display_type); |
| 1619 |
} |
| 1620 |
} |
| 1621 |
} |
| 1622 |
} |
| 1623 |
|
| 1624 |
/** |
| 1625 |
* A wrapper function that invokes the individual <code>process_response</code> calls by provider. |
| 1626 |
* - If the call is successful the results are passed as a thumbnail grid in an array with a "success" key |
| 1627 |
* - If the call is unsuccessful an error message is passed in an array with an "error" key |
| 1628 |
* |
| 1629 |
* @param $response |
| 1630 |
* @param $provider |
| 1631 |
* @param null $display_type |
| 1632 |
* @param array $form_parameters |
| 1633 |
* @param array $existing |
| 1634 |
* @param null $url |
| 1635 |
* @param bool $more |
| 1636 |
* @return array |
| 1637 |
*/ |
| 1638 |
function process_response($response, $provider, $display_type = null, $form_parameters = array(), $existing = array(), $url = null, $more = false) { |
| 1639 |
if (!is_wp_error($response)) { |
| 1640 |
if (isset($response['response']) && isset($response['response']['code'])) { |
| 1641 |
if ($response['response']['code'] == 200) { |
| 1642 |
$pagination = array(); |
| 1643 |
if ($provider == 'flickr') { |
| 1644 |
$objects = $this->process_flickr_response($response, $display_type, $url, $pagination); |
| 1645 |
} |
| 1646 |
else if ($provider == 'smugmug') { |
| 1647 |
$objects = $this->process_smugmug_response($response, $display_type, $url, $pagination); |
| 1648 |
} |
| 1649 |
else if ($provider == 'google') { |
| 1650 |
$objects = $this->process_google_response($response, $url, $pagination); |
| 1651 |
} |
| 1652 |
else if ($provider == 'zenfolio') { |
| 1653 |
$objects = $this->process_zenfolio_response($response, $display_type); |
| 1654 |
} |
| 1655 |
else if ($provider == 'instagram') { |
| 1656 |
$objects = $this->process_instagram_response($response, $display_type, $url, $pagination); |
| 1657 |
} |
| 1658 |
|
| 1659 |
if (empty($objects)) { |
| 1660 |
return array('error' => $this->error_no_data_returned); |
| 1661 |
} |
| 1662 |
else if (!empty($objects['error']) || !empty($objects['success'])) { |
| 1663 |
// Happens for "Find user" kind of calls |
| 1664 |
return $objects; |
| 1665 |
} |
| 1666 |
|
| 1667 |
$present = array(); |
| 1668 |
$output = $this->get_thumbnail_display($objects, $provider, $existing, $present, $more); |
| 1669 |
|
| 1670 |
$selected_data = empty($existing['selected_data']) ? array() : explode(',', $existing['selected_data']); |
| 1671 |
$missing = array_diff($selected_data, $present); |
| 1672 |
if (!empty($missing)) { |
| 1673 |
// |
| 1674 |
} |
| 1675 |
|
| 1676 |
if (!empty($pagination['url'])) { |
| 1677 |
$data_display_type = empty($display_type) ? '' : $display_type; |
| 1678 |
$output .= "<div class='photonic-more-wrapper'>\n". |
| 1679 |
"\t<a href='#' class='photonic-flow-more' data-photonic-more-link='{$pagination['url']}' data-photonic-display-type='$data_display_type' data-photonic-provider='$provider'>".esc_html__('Load More', 'photonic')."</a>\n". |
| 1680 |
"</div>"; |
| 1681 |
} |
| 1682 |
|
| 1683 |
if (!$more) { |
| 1684 |
foreach ($form_parameters as $id => $value) { |
| 1685 |
$output .= "<input type='hidden' name='$id' value='" . esc_attr($value) . "' />\n"; |
| 1686 |
} |
| 1687 |
} |
| 1688 |
return array('success' => $output); |
| 1689 |
} |
| 1690 |
else { |
| 1691 |
Photonic::log($response['response']); |
| 1692 |
return array('error' => sprintf(esc_html__('No data returned. Error code %s', 'photonic'), $response['response']['code'])); |
| 1693 |
} |
| 1694 |
} |
| 1695 |
else { |
| 1696 |
Photonic::log($response); |
| 1697 |
return array('error' => esc_html__('No data returned. Empty response, or empty error code.', 'photonic')); |
| 1698 |
} |
| 1699 |
} |
| 1700 |
else { |
| 1701 |
return array('error' => $response->get_error_message()); |
| 1702 |
} |
| 1703 |
} |
| 1704 |
|
| 1705 |
/** |
| 1706 |
* Processes a response from Flickr to build it out into a gallery of thumbnails. Flickr has L1, L2 and L3 displays in the flow. |
| 1707 |
* |
| 1708 |
* @param $response |
| 1709 |
* @param $display_type |
| 1710 |
* @param null $url |
| 1711 |
* @param array $pagination |
| 1712 |
* @return array |
| 1713 |
*/ |
| 1714 |
private function process_flickr_response($response, $display_type, $url = null, &$pagination = array()) { |
| 1715 |
$objects = array(); |
| 1716 |
$body = json_decode(wp_remote_retrieve_body($response)); |
| 1717 |
|
| 1718 |
if (isset($body->stat) && $body->stat == 'fail') { |
| 1719 |
Photonic::log($response); |
| 1720 |
return array('error' => $body->message); |
| 1721 |
} |
| 1722 |
|
| 1723 |
if (isset($body->photosets) && isset($body->photosets->photoset)) { |
| 1724 |
// $page = (int)($body->photosets->page); // Not needed because apparently the photosets.getList call returns all photosets for now |
| 1725 |
// $pages = (int)($body->photosets->pages); // Not needed because apparently the photosets.getList call returns all photosets for now |
| 1726 |
$photosets = $body->photosets->photoset; |
| 1727 |
foreach ($photosets as $flickr_object) { |
| 1728 |
$object = array(); |
| 1729 |
$object['id'] = $flickr_object->id; |
| 1730 |
$object['title'] = esc_attr($flickr_object->title->_content); |
| 1731 |
$object['counters'] = array(); |
| 1732 |
if (!empty($flickr_object->photos)) $object['counters'][] = esc_html(sprintf(_n('%s photo', '%s photos', $flickr_object->photos, 'photonic'), $flickr_object->photos)); |
| 1733 |
if (!empty($flickr_object->videos)) $object['counters'][] = esc_html(sprintf(_n('%s video', '%s videos', $flickr_object->videos, 'photonic'), $flickr_object->videos)); |
| 1734 |
$object['thumbnail'] = "https://farm" . $flickr_object->farm . ".static.flickr.com/" . $flickr_object->server . "/" . $flickr_object->primary . "_" . $flickr_object->secret . "_q.jpg"; |
| 1735 |
$objects[] = $object; |
| 1736 |
} |
| 1737 |
} |
| 1738 |
else if (isset($body->galleries) && isset($body->galleries->gallery)) { |
| 1739 |
$page = (int)($body->galleries->page); |
| 1740 |
$pages = (int)($body->galleries->pages); |
| 1741 |
$galleries = $body->galleries->gallery; |
| 1742 |
foreach ($galleries as $flickr_object) { |
| 1743 |
$object = array(); |
| 1744 |
$object['id'] = $flickr_object->id; |
| 1745 |
$object['title'] = esc_attr($flickr_object->title->_content); |
| 1746 |
$object['counters'] = array(); |
| 1747 |
if (!empty($flickr_object->count_photos)) $object['counters'][] = esc_html(sprintf(_n('%s photo', '%s photos', $flickr_object->count_photos, 'photonic'), $flickr_object->count_photos)); |
| 1748 |
if (!empty($flickr_object->count_videos)) $object['counters'][] = esc_html(sprintf(_n('%s video', '%s videos', $flickr_object->count_videos, 'photonic'), $flickr_object->count_videos)); |
| 1749 |
$object['thumbnail'] = "https://farm" . $flickr_object->primary_photo_farm . ".static.flickr.com/" . $flickr_object->primary_photo_server . "/" . $flickr_object->primary_photo_id . "_" . $flickr_object->primary_photo_secret . "_q.jpg"; |
| 1750 |
$objects[] = $object; |
| 1751 |
} |
| 1752 |
} |
| 1753 |
else if (isset($body->photos) && isset($body->photos->photo)) { |
| 1754 |
if ($display_type == 'single-photo') { |
| 1755 |
$page = (int)($body->photos->page); |
| 1756 |
$pages = (int)($body->photos->pages); |
| 1757 |
if ($page < $pages && !empty($url)) { |
| 1758 |
$url = remove_query_arg('page', $url); |
| 1759 |
$pagination['url'] = add_query_arg(array('page' => $page + 1), $url); |
| 1760 |
} |
| 1761 |
} |
| 1762 |
$photos = $body->photos->photo; |
| 1763 |
foreach ($photos as $flickr_object) { |
| 1764 |
$object = array(); |
| 1765 |
$object['id'] = $flickr_object->id; |
| 1766 |
$object['title'] = esc_attr($flickr_object->title); |
| 1767 |
$object['thumbnail'] = 'https://farm' . $flickr_object->farm . '.static.flickr.com/' . $flickr_object->server . '/' . $flickr_object->id . '_' . $flickr_object->secret . '_q.jpg'; |
| 1768 |
$objects[] = $object; |
| 1769 |
} |
| 1770 |
} |
| 1771 |
else if (isset($body->collections) && isset($body->collections->collection)) { |
| 1772 |
$collections = $body->collections->collection; |
| 1773 |
foreach ($collections as $flickr_object) { |
| 1774 |
$object = array(); |
| 1775 |
$object['id'] = $flickr_object->id; |
| 1776 |
$object['title'] = esc_attr($flickr_object->title); |
| 1777 |
$object['counters'] = array(); |
| 1778 |
if (!empty($flickr_object->set)) $object['counters'][] = esc_html(sprintf(_n('%s album', '%s albums', count($flickr_object->set), 'photonic'), count($flickr_object->set))); |
| 1779 |
$object['thumbnail'] = $flickr_object->iconlarge; |
| 1780 |
$objects[] = $object; |
| 1781 |
} |
| 1782 |
} |
| 1783 |
else if (isset($body->user)) { |
| 1784 |
return array('success' => array('user_id' => $body->user->id)); |
| 1785 |
} |
| 1786 |
else if (isset($body->group)) { |
| 1787 |
return array('success' => array('group_id' => $body->group->id)); |
| 1788 |
} |
| 1789 |
|
| 1790 |
if (!empty($page) && !empty($pages) && $page < $pages && !empty($url)) { |
| 1791 |
$url = remove_query_arg('page', $url); |
| 1792 |
$pagination['url'] = add_query_arg(array('page' => $page + 1), $url); |
| 1793 |
} |
| 1794 |
return $objects; |
| 1795 |
} |
| 1796 |
|
| 1797 |
/** |
| 1798 |
* Processes a response from SmugMug to build it out into a gallery of thumbnails. SmugMug has L1, L2 and L3 displays in the flow. |
| 1799 |
* |
| 1800 |
* @param $response |
| 1801 |
* @param $display_type |
| 1802 |
* @param null $url |
| 1803 |
* @param array $pagination |
| 1804 |
* @return array |
| 1805 |
*/ |
| 1806 |
private function process_smugmug_response($response, $display_type, $url = null, &$pagination = array()) { |
| 1807 |
$objects = array(); |
| 1808 |
$body = json_decode(wp_remote_retrieve_body($response)); |
| 1809 |
if (isset($body->Response) && isset($body->Response->Album)) { |
| 1810 |
$albums = $body->Response->Album; |
| 1811 |
foreach ($albums as $album) { |
| 1812 |
$object = array(); |
| 1813 |
if (isset($album->AlbumKey)) { |
| 1814 |
$object['id'] = $album->AlbumKey; |
| 1815 |
} |
| 1816 |
else { |
| 1817 |
$uri = $album->Uris->Album->Uri; |
| 1818 |
$uri = explode('/', $uri); |
| 1819 |
$object['id'] = $uri[count($uri) - 1]; |
| 1820 |
} |
| 1821 |
$object['title'] = !empty($album->Name) ? esc_attr($album->Name) : ''; |
| 1822 |
if (isset($album->ImageCount)) { |
| 1823 |
$object['counters'] = array(esc_html(sprintf(_n('%s media item', '%s media items', $album->ImageCount, 'photonic'), $album->ImageCount))); |
| 1824 |
} |
| 1825 |
|
| 1826 |
$highlight = $album->Uris->HighlightImage; |
| 1827 |
if (isset($highlight->Image)) { |
| 1828 |
$thumbURL = $highlight->Image->Uris->ImageSizes->ImageSizes->ThumbImageUrl; |
| 1829 |
} |
| 1830 |
else { |
| 1831 |
$thumbURL = trailingslashit(PHOTONIC_URL) . 'include/images/placeholder-Th.png'; |
| 1832 |
} |
| 1833 |
|
| 1834 |
$object['thumbnail'] = $thumbURL; |
| 1835 |
if (isset($album->SecurityType) && $album->SecurityType == 'Password') { |
| 1836 |
$object['passworded'] = 1; |
| 1837 |
} |
| 1838 |
|
| 1839 |
$objects[] = $object; |
| 1840 |
} |
| 1841 |
|
| 1842 |
if (isset($body->Response->Pages)) { |
| 1843 |
$pages = $body->Response->Pages; |
| 1844 |
if ($pages->Start + $pages->Count - 1 < $pages->Total) { |
| 1845 |
$pagination['url'] = add_query_arg(array('start' => $pages->Start + $pages->Count), remove_query_arg(array('start'), $url)); |
| 1846 |
} |
| 1847 |
} |
| 1848 |
} |
| 1849 |
else if (isset($body->Response) && isset($body->Response->Node)) { |
| 1850 |
$nodes = $body->Response->Node; |
| 1851 |
foreach ($nodes as $node) { |
| 1852 |
if ($display_type == 'folder' && $node->Type == 'Album') { |
| 1853 |
continue; |
| 1854 |
} |
| 1855 |
else if ($display_type == 'folder') { |
| 1856 |
$this->get_smugmug_folders($objects, $node); |
| 1857 |
} |
| 1858 |
else { |
| 1859 |
$object = array(); |
| 1860 |
if ($node->Type == 'Album') { |
| 1861 |
$uri = $node->Uris->Album->Uri; |
| 1862 |
$uri = explode('/', $uri); |
| 1863 |
$uri = $uri[count($uri) - 1]; |
| 1864 |
$object['id'] = $uri; |
| 1865 |
} |
| 1866 |
else if ($node->Type == 'Folder') { |
| 1867 |
$object['id'] = $node->NodeID; |
| 1868 |
} |
| 1869 |
$object['title'] = !empty($node->Name) ? esc_attr($node->Name) : ''; |
| 1870 |
if ($display_type == 'tree') { |
| 1871 |
$object['title'] .= " ({$node->Type})"; |
| 1872 |
} |
| 1873 |
if (isset($node->Uris->NodeCoverImage->Image->Uris->ImageSizes->ImageSizes->ThumbImageUrl)) { |
| 1874 |
$object['thumbnail'] = $node->Uris->NodeCoverImage->Image->Uris->ImageSizes->ImageSizes->ThumbImageUrl; |
| 1875 |
} |
| 1876 |
else { |
| 1877 |
$object['thumbnail'] = trailingslashit(PHOTONIC_URL) . 'include/images/placeholder-Th.png'; |
| 1878 |
} |
| 1879 |
$objects[] = $object; |
| 1880 |
} |
| 1881 |
} |
| 1882 |
} |
| 1883 |
else if (isset($body->Response) && isset($body->Response->User)) { |
| 1884 |
$user = $body->Response->User; |
| 1885 |
return array('success' => $user->Uris->Node->Uri); |
| 1886 |
} |
| 1887 |
else { |
| 1888 |
Photonic::log($body); |
| 1889 |
return array('error' => $this->error_not_found); |
| 1890 |
} |
| 1891 |
|
| 1892 |
return $objects; |
| 1893 |
} |
| 1894 |
|
| 1895 |
/** |
| 1896 |
* Processes a response from Google to build it out into a gallery of thumbnails. Google has both, L1 and L2 displays in the flow. |
| 1897 |
* |
| 1898 |
* @param $response |
| 1899 |
* @param $url |
| 1900 |
* @param array $pagination |
| 1901 |
* @return array |
| 1902 |
*/ |
| 1903 |
function process_google_response($response, $url, &$pagination = array()) { |
| 1904 |
$objects = array(); |
| 1905 |
$body = json_decode(wp_remote_retrieve_body($response)); |
| 1906 |
if (isset($body->albums)) { |
| 1907 |
$albums = $body->albums; |
| 1908 |
foreach ($albums as $album) { |
| 1909 |
$object = array(); |
| 1910 |
$object['id'] = $album->id; |
| 1911 |
$object['title'] = !empty($album->title) ? esc_attr($album->title) : ''; |
| 1912 |
$object['counters'] = array(esc_html(sprintf(_n('%s media item', '%s media items', $album->mediaItemsCount, 'photonic'), $album->mediaItemsCount))); |
| 1913 |
$object['thumbnail'] = $album->coverPhotoBaseUrl . "=w150-h150-c"; |
| 1914 |
$objects[] = $object; |
| 1915 |
} |
| 1916 |
if (!empty($body->nextPageToken)) { |
| 1917 |
$pagination['url'] = add_query_arg(array('pageToken' => $body->nextPageToken), remove_query_arg(array('pageToken'), $url)); |
| 1918 |
} |
| 1919 |
} |
| 1920 |
else if (isset($body->mediaItems)) { |
| 1921 |
$photos = $body->mediaItems; |
| 1922 |
foreach ($photos as $photo) { |
| 1923 |
$object = array(); |
| 1924 |
$object['id'] = $photo->id; |
| 1925 |
$object['title'] = !empty($photo->description) ? esc_attr($photo->description) : ''; |
| 1926 |
$object['thumbnail'] = $photo->baseUrl . "=w150-h150-c"; |
| 1927 |
$objects[] = $object; |
| 1928 |
} |
| 1929 |
} |
| 1930 |
else if (isset($body->error)) { |
| 1931 |
$objects['error'] = $body->error->message; |
| 1932 |
} |
| 1933 |
return $objects; |
| 1934 |
} |
| 1935 |
|
| 1936 |
/** |
| 1937 |
* Processes a response from Zenfolio to build it out into a gallery of thumbnails. Zenfolio has both, L1 and L2 displays in the flow. |
| 1938 |
* |
| 1939 |
* @param $response |
| 1940 |
* @param $display_type |
| 1941 |
* @return array |
| 1942 |
*/ |
| 1943 |
function process_zenfolio_response($response, $display_type) { |
| 1944 |
$body = wp_remote_retrieve_body($response); |
| 1945 |
$body = preg_replace('/"Id":(\d+)/', '"Id":"$1"', $body); |
| 1946 |
$body = simplexml_load_string($body); |
| 1947 |
$objects = array(); |
| 1948 |
if ($display_type != 'multi-photo') { |
| 1949 |
if (!empty($body->Elements)) { |
| 1950 |
$elements = $body->Elements; |
| 1951 |
$this->get_zenfolio_groups($objects, $elements, $display_type); |
| 1952 |
} |
| 1953 |
else if (!empty($body->PhotoSets)) { |
| 1954 |
$photosets = $body->PhotoSets; |
| 1955 |
$this->get_zenfolio_groups($objects, $photosets, $display_type); |
| 1956 |
} |
| 1957 |
|
| 1958 |
if ($display_type == 'single-photo') { |
| 1959 |
$photo_array = array(); |
| 1960 |
global $photonic_zenfolio_gallery; |
| 1961 |
if (!isset($photonic_zenfolio_gallery)) { |
| 1962 |
$photonic_zenfolio_gallery = new Photonic_Zenfolio_Processor(); |
| 1963 |
} |
| 1964 |
$requests = array(); |
| 1965 |
foreach ($objects as $object) { |
| 1966 |
$parameters = array(); |
| 1967 |
$parameters['photoSetId'] = substr($object['id'], 1); |
| 1968 |
$parameters['level'] = 'Level1'; |
| 1969 |
$parameters['includePhotos'] = 'true'; |
| 1970 |
|
| 1971 |
$request = $photonic_zenfolio_gallery->prepare_request('LoadPhotoSet', $parameters); |
| 1972 |
$requests[] = array( |
| 1973 |
'url' => 'https://api.zenfolio.com/api/1.8/zfapi.asmx', |
| 1974 |
'type' => 'POST', |
| 1975 |
'headers' => $request['headers'], |
| 1976 |
'data' => $request['body'], |
| 1977 |
); |
| 1978 |
} |
| 1979 |
$responses = Requests::request_multiple($requests); |
| 1980 |
if (!empty($responses)) { |
| 1981 |
foreach ($responses as $ps_response) { |
| 1982 |
if (is_a($ps_response, 'Requests_Response')) { |
| 1983 |
$ps_response = json_decode($ps_response->body); |
| 1984 |
if (!empty($ps_response->result)) { |
| 1985 |
$ps_response = $ps_response->result; |
| 1986 |
if (!empty($ps_response->Photos)) { |
| 1987 |
$photo_array['psid'.$ps_response->Id] = $ps_response->Title; |
| 1988 |
foreach ($ps_response->Photos as $ps_photo) { |
| 1989 |
if (array_key_exists($ps_photo->Id, $photo_array)) { |
| 1990 |
continue; |
| 1991 |
} |
| 1992 |
$photo = array(); |
| 1993 |
$photo['id'] = $ps_photo->Id; |
| 1994 |
$url_parts = explode('/', $ps_photo->UrlCore); |
| 1995 |
$photo['alt_id'] = 'h'.dechex((int)substr($url_parts[count($url_parts) - 1], 1)); |
| 1996 |
$photo['alt_id2'] = $url_parts[count($url_parts) - 1]; |
| 1997 |
$photo['title'] = esc_attr($ps_photo->Title); |
| 1998 |
$photo['thumbnail'] = 'https://' . $ps_photo->UrlHost . $ps_photo->UrlCore . '-1.jpg'; |
| 1999 |
$photo_array[$ps_photo->Id] = $photo; |
| 2000 |
} |
| 2001 |
} |
| 2002 |
} |
| 2003 |
} |
| 2004 |
} |
| 2005 |
} |
| 2006 |
$objects = array_values($photo_array); |
| 2007 |
} |
| 2008 |
return $objects; |
| 2009 |
} |
| 2010 |
else { |
| 2011 |
$photos = $body->Photos; |
| 2012 |
foreach ($photos->Photo as $photo) { |
| 2013 |
$object = array(); |
| 2014 |
$object['id'] = $photo->Id; |
| 2015 |
$object['title'] = esc_attr($photo->Title); |
| 2016 |
$object['thumbnail'] = 'https://' . $photo->UrlHost . $photo->UrlCore . '-1.jpg'; |
| 2017 |
$objects[] = $object; |
| 2018 |
} |
| 2019 |
return $objects; |
| 2020 |
} |
| 2021 |
} |
| 2022 |
|
| 2023 |
/** |
| 2024 |
* Processes a response from Instagram to build it out into a gallery of thumbnails. Instagram only has L1 displays. |
| 2025 |
* |
| 2026 |
* @param $response |
| 2027 |
* @param $display_type |
| 2028 |
* @param $url |
| 2029 |
* @param array $pagination |
| 2030 |
* @return array |
| 2031 |
*/ |
| 2032 |
function process_instagram_response($response, $display_type, $url, &$pagination = array()) { |
| 2033 |
$objects = array(); |
| 2034 |
$body = json_decode($response['body']); |
| 2035 |
if (isset($body->data)) { |
| 2036 |
$data = $body->data; |
| 2037 |
foreach ($data as $photo) { |
| 2038 |
if (isset($photo->type) && ($photo->type == 'image' || $photo->type == 'carousel' || $photo->type == 'video') && isset($photo->images)) { |
| 2039 |
$object = array(); |
| 2040 |
$link = $photo->link; |
| 2041 |
$link = explode('/', $link); |
| 2042 |
if (empty($link[count($link) - 1])) { |
| 2043 |
$link = $link[count($link) - 2]; |
| 2044 |
} |
| 2045 |
else { |
| 2046 |
$link = $link[count($link) - 1]; |
| 2047 |
} |
| 2048 |
$object['id'] = $link; |
| 2049 |
if (isset($photo->caption) && isset($photo->caption->text)) { |
| 2050 |
$object['title'] = esc_attr($photo->caption->text); |
| 2051 |
} |
| 2052 |
else { |
| 2053 |
$object['title'] = ''; |
| 2054 |
} |
| 2055 |
$object['thumbnail'] = $photo->images->thumbnail->url; |
| 2056 |
$objects[] = $object; |
| 2057 |
} |
| 2058 |
} |
| 2059 |
if (isset($body->pagination) && isset($body->pagination->next_max_id) && $display_type == 'single-photo') { |
| 2060 |
$pagination['url'] = add_query_arg(array('max_id' => $body->pagination->next_max_id), remove_query_arg(array('max_id'), $url)); |
| 2061 |
} |
| 2062 |
} |
| 2063 |
return $objects; |
| 2064 |
} |
| 2065 |
} |
| 2066 |
|