PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 4.2.4
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v4.2.4
4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.14 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.10 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.10 4.4.11 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5.0 4.5.1
embedpress / EmbedPress / Providers / GooglePhotos.php
embedpress / EmbedPress / Providers Last commit date
TemplateLayouts 1 year ago AirTable.php 1 year ago Boomplay.php 1 year ago Calendly.php 2 years ago Canva.php 1 year ago Giphy.php 2 years ago GitHub.php 3 years ago GoogleDocs.php 2 years ago GoogleDrive.php 2 years ago GoogleMaps.php 2 years ago GooglePhotos.php 1 year ago Gumroad.php 2 years ago InstagramFeed.php 1 year ago LinkedIn.php 2 years ago NRKRadio.php 2 years ago OpenSea.php 2 years ago SelfHosted.php 2 years ago Spreaker.php 1 year ago TikTok.php 2 years ago Twitch.php 2 years ago Wrapper.php 3 years ago X.php 2 years ago Youtube.php 1 year ago index.html 7 years ago
GooglePhotos.php
325 lines
1 <?php
2
3 namespace EmbedPress\Providers;
4
5 use EmbedPress\Includes\Classes\Helper;
6 use Embera\Provider\ProviderAdapter;
7 use Embera\Provider\ProviderInterface;
8 use Embera\Url;
9
10 (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
11
12 class GooglePhotos extends ProviderAdapter implements ProviderInterface
13 {
14 protected static $hosts = ["photos.app.goo.gl", "photos.google.com"];
15 private $player_js = "https://cdn.jsdelivr.net/npm/publicalbum@latest/embed-ui.min.js";
16 private $min_expiration = 60;
17 private $allowed_url_patttern = "/^https:\/\/photos\.app\.goo\.gl\/|^https:\/\/photos\.google\.com(?:\/u\/\d+)?\/share\//";
18
19 static public $name = "google-photos-album";
20
21 /** @var array Array with allowed params for the current Provider */
22 protected $allowedParams = [
23 'mode',
24 'maxwidth',
25 'google_photos_width',
26 'google_photos_height',
27 'maxheight',
28 'imageWidth',
29 'imageHeight',
30 'playerAutoplay',
31 'delay',
32 'repeat',
33 'mediaitemsAspectRatio',
34 'mediaitemsEnlarge',
35 'mediaitemsStretch',
36 'mediaitemsCover',
37 'backgroundColor',
38 'expiration',
39 ];
40
41
42 /** inline {@inheritdoc} */
43 protected $httpsSupport = true;
44
45 public function getAllowedParams()
46 {
47 return $this->allowedParams;
48 }
49
50 public function __construct($url, array $config = [])
51 {
52 parent::__construct($url, $config);
53 }
54
55 public function validateUrl(Url $url)
56 {
57 return preg_match('~^https:\/\/(photos\.app\.goo\.gl|photos\.google\.com)\/.*$~i', (string) $url);
58 }
59
60 public function get_embeded_content($link, $width = 0, $height = 480, $imageWidth = 1920, $imageHeight = 1080, $expiration = 60, $mode = 'gallery-player', $playerAutoplay = false, $delay = 5, $repeat = true, $aspectRatio = true, $enlarge = true, $stretch = true, $cover = false, $backgroundColor = '#000000')
61 {
62 if (is_object($link)) {
63 return $this->get_html($link, $expiration);
64 }
65
66 $props = $this->create_default_attr();
67 $props->link = $link;
68 $props->width = $width;
69 $props->height = $height;
70 $props->imageWidth = $imageWidth;
71 $props->imageHeight = $imageHeight;
72 $props->mode = $mode;
73 $props->slideshowAutoplay = $playerAutoplay;
74 $props->slideshowDelay = $delay;
75 $props->repeat = $repeat;
76 $props->backgroundColor = $backgroundColor;
77
78 $html = $this->get_html($props, $expiration);
79
80 return $html;
81 }
82
83
84 private function get_html($props, $expiration = 0)
85 {
86
87
88 // Generate a hash from the $props object for uniqueness
89 $props_hash = md5(serialize($props));
90 $url_hash = md5($props->link);
91 $transient = sprintf('%s-%s-%s', self::$name, $url_hash, $props_hash);
92
93 $html = get_transient($transient);
94 if ($html) {
95 return $html;
96 }
97
98 $html = $this->get_embed_google_photos_html($props);
99 if ($html) {
100 $expiration = $expiration > 0 ? $expiration : $this->min_expiration;
101 set_transient($transient, $html, $expiration * 60);
102 return $html;
103 }
104
105 return null;
106 }
107
108
109 private function get_remote_contents($url)
110 {
111 if (preg_match($this->allowed_url_patttern, $url)) {
112 $response = wp_remote_get($url);
113 if (!is_wp_error($response)) {
114 return wp_remote_retrieve_body($response);
115 }
116 }
117 return null;
118 }
119
120 private function parse_ogtags($contents)
121 {
122 preg_match_all('~<\s*meta\s+property="(og:[^"]+)"\s+content="([^"]*)~i', $contents, $m);
123 $ogtags = [];
124 for ($i = 0; $i < count($m[1]); $i++) {
125 $ogtags[$m[1][$i]] = $m[2][$i];
126 }
127 return $ogtags;
128 }
129
130 private function parse_photos($contents)
131 {
132 preg_match_all('~\"(http[^"]+)\"\,[0-9^,]+\,[0-9^,]+~i', $contents, $m);
133 $photos = array_unique($m[1]);
134
135 // Use preg_replace_callback to remove width/height parameters directly in the matched URLs
136 return preg_replace_callback('/=[^&]+$/', function ($matches) {
137 return ''; // Remove the width/height parameters at the end
138 }, $photos);
139 }
140
141
142 private function get_embed_google_photos_html($props)
143 {
144 if ($contents = $this->get_remote_contents($props->link)) {
145 $og = $this->parse_ogtags($contents);
146 $title = $og['og:title'] ?? null;
147 $photos = $this->parse_photos($contents);
148
149
150 error_log(print_r($contents, true));
151
152 $style = sprintf(
153 'display: none; width: %s; height: %s; max-width: 100%%;',
154 $props->width === 0 ? '100%' : ($props->width . 'px'),
155 $props->height === 0 ? '100%' : ('100%')
156 );
157
158 $items_code = '';
159
160 if ($props->mode == 'gallery-justify' || $props->mode == 'gallery-masonary' || $props->mode == 'gallery-grid') {
161 $items_code .= sprintf('<div class="photos-%s">', esc_attr($props->mode));
162 $counter = 0;
163
164 foreach ($photos as $photo) {
165 // Preview image URL (small version for fast loading)
166 $preview_src = sprintf('%s=w%d-h%d', $photo, $props->imageWidth, $props->imageHeight);
167
168 // Full image URL (original size or any desired size)
169 $full_src = $photo . '=w2500';
170
171 // Add image items with preview and full image source
172 $items_code .= sprintf(
173 '<div class="photo-item" data-item-number="%d" id="photo-%s">
174 <img data-photo-src="%s" src="%s" loading="lazy" alt="Photo"/>
175 </div>',
176 esc_attr($counter++),
177 md5($preview_src),
178 esc_url($full_src), // Full image source for later use
179 esc_url($preview_src) // Preview image source for fast loading
180 );
181 }
182
183 $items_code .= '</div>';
184
185 return sprintf(
186 "<div class=\"google-photos-%s-widget\"><h3 style='text-align:left; margin: 22px 10px;'>%s</h3>%s</div>\n",
187 esc_attr($props->mode),
188 $title,
189 $items_code
190 );
191 } else {
192 foreach ($photos as $photo) {
193 // Preview image URL (small version for fast loading)
194 $preview_src = sprintf('%s=w%d-h%d', $photo, $props->imageWidth, $props->imageHeight);
195
196 // Full image URL (original size or any desired size)
197 $full_src = $photo;
198
199 // Add image items with preview and full image source
200 $items_code .= sprintf(
201 '<object data="%s"></object>',
202 esc_url($preview_src) // Using preview image for non-gallery mode
203 );
204 }
205 }
206
207
208 $attributes = [
209 'data-link' => $props->link,
210 'data-found' => count($photos),
211 'data-title' => $title,
212 'data-mediaitems-aspect-ratio' => true,
213 'data-mediaitems-enlarge' => '',
214 'data-mediaitems-stretch' => '',
215 'data-mediaitems-cover' => '',
216 'data-background-color' => $props->backgroundColor,
217 ];
218
219 // Apply filter to allow modification of attributes
220 $attributes = apply_filters('embedpress_google_photos_attributes', $attributes, $props);
221
222 $attributes_string = '';
223 foreach ($attributes as $key => $value) {
224 if ($value !== null) {
225 $attributes_string .= sprintf(' %s="%s"', $key, $value);
226 }
227 }
228
229 return sprintf(
230 "<div class=\"pa-%s-widget\" style=\"%s\"%s>%s</div>\n",
231 esc_attr($props->mode),
232 $style,
233 $attributes_string,
234 $items_code
235 );
236 }
237 return null;
238 }
239
240 private function create_default_attr()
241 {
242 $props = new \stdClass();
243 $props->mode = 'gallery-player';
244 $props->width = 600;
245 $props->height = 450;
246 $props->imageWidth = 1920;
247 $props->imageHeight = 1080;
248 $props->slideshowAutoplay = false;
249 $props->slideshowDelay = 5;
250 $props->repeat = true;
251 $props->mediaitemsAspectRatio = true;
252 $props->mediaitemsEnlarge = true;
253 $props->mediaitemsStretch = true;
254 $props->mediaitemsCover = false;
255 $props->backgroundColor = '#000000';
256 return $props;
257 }
258
259 public function fakeResponse()
260 {
261 $src_url = urldecode($this->url);
262
263 // Fetch parameters
264 $params = $this->getParams();
265
266 // Extract configuration or set defaults
267 $width = isset($this->config['maxwidth']) ? $this->config['maxwidth'] : 600;
268 $height = isset($this->config['maxheight']) ? $this->config['maxheight'] : 450;
269
270
271 $expiration = $params['expiration'] ?? 60;
272 $mode = $params['mode'] ?? 'carousel';
273 $playerAutoplay = isset($params['playerAutoplay']) ? Helper::getBooleanParam($params['playerAutoplay']) : false;
274 $delay = $params['delay'] ?? 5;
275 $repeat = isset($params['repeat']) ? Helper::getBooleanParam($params['repeat']) : false;
276 $aspectRatio = isset($params['mediaitemsAspectRatio']) ? Helper::getBooleanParam($params['mediaitemsAspectRatio']) : false;
277 $enlarge = isset($params['mediaitemsEnlarge']) ? Helper::getBooleanParam($params['mediaitemsEnlarge']) : false;
278 $stretch = isset($params['mediaitemsStretch']) ? Helper::getBooleanParam($params['mediaitemsStretch']) : false;
279 $cover = isset($params['mediaitemsCover']) ? Helper::getBooleanParam($params['mediaitemsCover']) : false;
280 $backgroundColor = $params['backgroundColor'] ?? '#000000';
281
282 $html = $this->get_embeded_content(
283 $src_url,
284 $width,
285 $height,
286 $width,
287 $height,
288 $expiration,
289 $mode,
290 $playerAutoplay,
291 $delay,
292 $repeat,
293 $aspectRatio,
294 $enlarge,
295 $stretch,
296 $cover,
297 $backgroundColor
298 );
299
300 // Conditionally load player JS only if mode is 'carousel' or autoplay is enabled
301 if ($mode === 'carousel' || $mode === 'gallery-player') {
302 $html .= '<script src="' . $this->player_js . '"></script>';
303 }
304 if ($mode === 'gallery-justify') {
305 $html .= '<script src="' . EMBEDPRESS_PLUGIN_DIR_URL . 'assets/js/gallery-justify.js"></script>';
306 }
307
308 // Always load gallery layout script (or make this conditional too if needed)
309
310 return [
311 'type' => 'rich',
312 'provider_name' => 'Google Photos',
313 'provider_url' => 'https://photos.app.goo.gl',
314 'title' => $params['title'] ?? 'Unknown title',
315 'html' => $html,
316 ];
317
318 }
319
320 public function modifyResponse(array $response = [])
321 {
322 return $this->fakeResponse();
323 }
324 }
325