PluginProbe
Photonic Gallery & Lightbox for Flickr, SmugMug & Others / 3.36
Photonic Gallery & Lightbox for Flickr, SmugMug & Others v3.36
3.36 3.35 3.34 3.33 2.19 2.20 2.21 2.22 2.23 2.24 2.25 2.26 2.27 2.28 2.29 2.30 2.31 2.32 2.33 2.34 2.40 2.41 2.42 2.43 2.44 All 141 releases
photonic / Platforms / Base.php

Base.php in Photonic Gallery & Lightbox for Flickr, SmugMug & Others 3.36, at Platforms/Base.php

278 lines 9.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Photonic_Plugin\Platforms;
4
5 use Photonic_Plugin\Components\Stack_Trace;
6 use Photonic_Plugin\Core\Photonic;
7 use WP_Error;
8
9 require_once PHOTONIC_PATH . '/Components/Printable.php';
10 require_once PHOTONIC_PATH . '/Components/Stack_Trace.php';
11 require_once PHOTONIC_PATH . '/Components/Header.php';
12 require_once PHOTONIC_PATH . '/Components/Error.php';
13 require_once PHOTONIC_PATH . '/Components/Comment.php';
14
15 /**
16 * Gallery processor class to be extended by individual processors. This class has an abstract method called <code>get_gallery_images</code>
17 * that has to be defined by each inheriting processor.
18 *
19 * This is also where the OAuth support is implemented. The URLs are defined using abstract functions, while a handful of utility functions are defined.
20 * Most utility functions have been adapted from the OAuth PHP package distributed here: https://code.google.com/p/oauth-php/.
21 */
22 abstract class Base {
23 public $api_key;
24 public $api_secret, $provider, $user_agent, $nonce, $oauth_timestamp, $signature_parameters, $link_lightbox_title,
25 $oauth_version, $oauth_done, $show_more_link, $gallery_index, $common_parameters,
26 $doc_links, $password_protected, $token, $token_secret, $show_buy_link, $stack_trace;
27
28 protected function __construct() {
29 global $photonic_enable_popup, $photonic_thumbnail_style;
30
31 $this->nonce = self::nonce();
32 $this->user_agent = 'PhotonicWP/' . PHOTONIC_VERSION . '; ' . get_home_url();
33 $this->oauth_timestamp = time();
34 $this->oauth_version = '1.0';
35 $this->show_more_link = false;
36 $this->gallery_index = 0;
37
38 $bypass_popup = empty($photonic_enable_popup) || 'off' === $photonic_enable_popup || 'hide' === $photonic_enable_popup;
39 $this->common_parameters = [
40 'columns' => 'auto',
41 'layout' => !empty($photonic_thumbnail_style) ? $photonic_thumbnail_style : 'square',
42 'display' => 'local', // local: on the same page, lightbox: in a lightbox, modal: in a modal popup, template: using the page template
43 'popup' => $bypass_popup ? 'hide' : $photonic_enable_popup, // While popups are not possible for slideshows, this shortcode value is needed in Platform sub-classes, to determine whether a `gallery_url` should be associated with an album thumbnail.
44 'filter' => '',
45 'filter_type' => 'include',
46 'more' => '',
47 'panel' => '',
48 'custom_classes' => '',
49 'alignment' => '',
50 ];
51 $this->common_parameters['photo_layout'] = $this->common_parameters['layout'];
52
53 $this->doc_links = [];
54 $this->password_protected = esc_html__('This album is password-protected. Please provide a valid password.', 'photonic');
55 $this->show_buy_link = false;
56 $this->stack_trace = [];
57
58 $this->add_hooks();
59 }
60
61 final public static function get_instance() {
62 static $instances = array();
63 $called_class = get_called_class();
64
65 if (!isset($instances[$called_class])) {
66 $instances[$called_class] = new $called_class();
67 }
68 return $instances[$called_class];
69 }
70
71 /**
72 * Main function that fetches the images associated with the shortcode. This is implemented by all sub-classes.
73 *
74 * @abstract
75 * @param array $attr
76 * @return array
77 */
78 abstract public function get_gallery_images($attr = []): array;
79
80 /**
81 * Generates a nonce for use in signing calls.
82 *
83 * @static
84 * @return string
85 */
86 public static function nonce(): string {
87 $mt = microtime();
88 $rand = mt_rand();
89 return md5($mt . $rand);
90 }
91
92 /**
93 * Takes a string of parameters in an HTML encoded string, then returns an array of name-value pairs, with the parameter
94 * name and the associated value.
95 *
96 * @static
97 * @param $input
98 * @return array
99 */
100 public static function parse_parameters($input): array {
101 if (!isset($input) || !$input) {
102 return [];
103 }
104
105 $pairs = explode('&', $input);
106
107 $parsed_parameters = [];
108 foreach ($pairs as $pair) {
109 $split = explode('=', $pair, 2);
110 $parameter = sanitize_text_field(urldecode($split[0]));
111 $value = isset($split[1]) ? sanitize_text_field(urldecode($split[1])) : '';
112
113 if (isset($parsed_parameters[$parameter])) {
114 // We have already recieved parameter(s) with this name, so add to the list
115 // of parameters with this name
116 if (is_scalar($parsed_parameters[$parameter])) {
117 // This is the first duplicate, so transform scalar (string) into an array
118 // so we can add the duplicates
119 $parsed_parameters[$parameter] = [$parsed_parameters[$parameter]];
120 }
121
122 $parsed_parameters[$parameter][] = $value;
123 }
124 else {
125 $parsed_parameters[$parameter] = $value;
126 }
127 }
128 return $parsed_parameters;
129 }
130
131 public function get_header_display($args): array {
132 if (!isset($args['headers'])) {
133 return [
134 'thumbnail' => 'inherit',
135 'title' => 'inherit',
136 'counter' => 'inherit',
137 ];
138 }
139 elseif (empty($args['headers'])) {
140 return [
141 'thumbnail' => 'none',
142 'title' => 'none',
143 'counter' => 'none',
144 ];
145 }
146 else {
147 $header_array = explode(',', $args['headers']);
148 return [
149 'thumbnail' => in_array('thumbnail', $header_array, true) ? 'show' : 'none',
150 'title' => in_array('title', $header_array, true) ? 'show' : 'none',
151 'counter' => in_array('counter', $header_array, true) ? 'show' : 'none',
152 ];
153 }
154 }
155
156 public function get_hidden_headers($arg_headers, $setting_headers): array {
157 return [
158 'thumbnail' => 'inherit' === $arg_headers['thumbnail'] ? $setting_headers['thumbnail'] : 'none' === $arg_headers['thumbnail'],
159 'title' => 'inherit' === $arg_headers['title'] ? $setting_headers['title'] : 'none' === $arg_headers['title'],
160 'counter' => 'inherit' === $arg_headers['counter'] ? $setting_headers['counter'] : 'none' === $arg_headers['counter'],
161 ];
162 }
163
164 /**
165 * Wraps an error message in appropriately-styled markup for display in the front-end
166 *
167 * @param $message
168 * @return string
169 */
170 public function error($message): string {
171 return "<div class='photonic-error photonic-{$this->provider}-error' id='photonic-{$this->provider}-error-{$this->gallery_index}'>\n\t<span class='photonic-error-icon photonic-icon'>&nbsp;</span>\n\t<div class='photonic-message'>\n\t\t$message\n\t</div>\n</div>\n";
172 }
173
174 /**
175 * Retrieves the error messages from a WP_Response object and formats them in a display-ready markup.
176 *
177 * @param WP_Error $response
178 * @param bool $server_msg
179 * @return string
180 */
181 public function wp_error_message(WP_Error $response, bool $server_msg = true): string {
182 $ret = '';
183 if ($server_msg) {
184 $ret = $this->get_server_error() . "<br/>\n";
185 }
186 if (is_wp_error($response)) {
187 $messages = $response->get_error_messages();
188 $ret .= '<strong>' . esc_html(sprintf(_n('%s Message:', '%s Messages:', count($messages), 'photonic'), count($messages))) . "</strong><br/>\n";
189 foreach ($messages as $message) {
190 $ret .= $message . "<br>\n";
191 }
192 }
193 return $ret;
194 }
195
196 public function push_to_stack($event) {
197 global $photonic_performance_logging;
198 if (empty($photonic_performance_logging)) {
199 return;
200 }
201
202 if (!isset($this->stack_trace[$this->gallery_index])) {
203 $stack_trace = new Stack_Trace();
204 }
205 else {
206 $stack_trace = $this->stack_trace[$this->gallery_index];
207 }
208
209 $stack_trace->add_to_first_open_event($event);
210 $this->stack_trace[$this->gallery_index] = $stack_trace;
211 }
212
213 public function pop_from_stack() {
214 global $photonic_performance_logging;
215 if (empty($photonic_performance_logging)) {
216 return;
217 }
218
219 if (isset($this->stack_trace[$this->gallery_index])) {
220 /** @var Stack_Trace $stack_trace */
221 $stack_trace = $this->stack_trace[$this->gallery_index];
222 $stack_trace->pop_from_first_open_event();
223 $this->stack_trace[$this->gallery_index] = $stack_trace;
224 }
225 }
226
227 protected function get_gallery_url($short_code, $meta): string {
228 global $photonic_alternative_shortcode, $photonic_gallery_template_page;
229
230 $shortcode_tag = $photonic_alternative_shortcode ?: 'gallery';
231 $shortcode_parts = [];
232 foreach ($short_code as $attr => $value) {
233 if (is_array($value)) {
234 continue;
235 }
236 $shortcode_parts[] = $attr . '="' . esc_attr($value) . '"';
237 }
238 $raw_shortcode = '[' . $shortcode_tag . ' ' . implode(' ', $shortcode_parts) . ']';
239
240 $gallery_url = add_query_arg(
241 [
242 'photonic_gallery' => base64_encode($raw_shortcode), // Encode the shortcode to avoid issues in passing the data around in URLs. This is decoded in Template.php
243 'photonic_gallery_title' => rawurlencode($meta['title']),
244 ],
245 get_page_link($photonic_gallery_template_page)
246 );
247 return $gallery_url;
248 }
249
250 public function ssl_verify_peer(&$handle) {
251 // Photonic mostly uses wp_remote_get, but for bulk requests, it needs to use the 'WpOrg\Requests\Hooks' class, which needs 'curl.before_multi_add'.
252 curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false); // phpcs:ignore WordPress.WP.AlternativeFunctions
253 }
254
255 public function get_server_error(): string {
256 return sprintf(esc_html__('There was an error connecting to %s. Please try again later.', 'photonic'), $this->provider);
257 }
258
259 /**
260 * Helper execution, implemented by child classes
261 *
262 * @param array $args
263 * @return string
264 */
265 public function execute_helper(array $args = []): string { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter
266 // Blank method, to be overridden by child classes
267 return '';
268 }
269
270 public function add_hooks() {
271 // Blank method, implemented by child classes, if required
272 }
273
274 public function increment_gallery_index() {
275 $this->gallery_index++;
276 }
277 }
278