Instagram Widget by WPZOOM - Version 1.4.4

Version Description

  • New option to hide video thumbnails. Sometimes video thubmanils may show as blank squares, so the new option will help to fix this problem.
Download this release

Release Info

Developer WPZOOM
Plugin Icon 128x128 Instagram Widget by WPZOOM
Version 1.4.4
Comparing to
See all releases

Version 1.4.4

class-wpzoom-instagram-widget-api.php ADDED
@@ -0,0 +1,514 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Wpzoom_Instagram_Widget_API {
4
+ /**
5
+ * @var Wpzoom_Instagram_Widget_API The reference to *Singleton* instance of this class
6
+ */
7
+ private static $instance;
8
+
9
+ /**
10
+ * Instagram Access Token
11
+ *
12
+ * @var string
13
+ */
14
+ protected $access_token;
15
+
16
+ /**
17
+ * Returns the *Singleton* instance of this class.
18
+ *
19
+ * @return Wpzoom_Instagram_Widget_API The *Singleton* instance.
20
+ */
21
+ public static function getInstance()
22
+ {
23
+ if ( null === self::$instance ) {
24
+ self::$instance = new self();
25
+ }
26
+
27
+ return self::$instance;
28
+ }
29
+
30
+ protected function __construct() {
31
+ $options = get_option( 'wpzoom-instagram-widget-settings' );
32
+ $this->access_token = $options['access-token'];
33
+ $this->username = !empty($options['username']) ? $options['username'] : '';
34
+ $this->request_type = !empty($options['request_type']) ? $options['request_type'] : '';
35
+ $this->transient_lifetime_type = !empty($options['transient-lifetime-type']) ? $options['transient-lifetime-type'] : 'days';
36
+ $this->transient_lifetime_value = !empty($options['transient-lifetime-value']) ? $options['transient-lifetime-value'] : 1;
37
+
38
+ }
39
+
40
+ function get_transient_lifetime() {
41
+
42
+ $values = array( 'minutes' => MINUTE_IN_SECONDS, 'hours' => HOUR_IN_SECONDS, 'days' => DAY_IN_SECONDS );
43
+ $keys = array_keys( $values );
44
+ $type = in_array( $this->transient_lifetime_type, $keys ) ? $values[ $this->transient_lifetime_type ] : $values['minutes'];
45
+
46
+ return $type * $this->transient_lifetime_value;
47
+ }
48
+
49
+ function get_user_info_without_token( $user ) {
50
+
51
+ $response = $this->get_response_without_token( $user );
52
+
53
+ if ( empty( $response ) ) {
54
+ return new WP_Error( 'empty-json', __( 'Empty json decoded data.', 'wpzoom-instagram-widget' ) );
55
+ }
56
+
57
+ if ( isset( $response->entry_data->ProfilePage[0]->graphql->user ) ) {
58
+ $user_info = $response->entry_data->ProfilePage[0]->graphql->user;
59
+ } else {
60
+ return new WP_Error( 'empty-json', __( 'Empty json decoded data.', 'wpzoom-instagram-widget' ) );
61
+ }
62
+
63
+ $converted = new stdClass;
64
+
65
+ $converted->data = (object) array(
66
+ 'bio' => ! empty( $user_info->biography ) ? $user_info->biography : '',
67
+ 'counts' => (object) array(
68
+ 'followed_by' => ! empty( $user_info->edge_followed_by->count ) ? $user_info->edge_followed_by->count : 0,
69
+ 'follows' => ! empty( $user_info->edge_follow->count ) ? $user_info->edge_follow->count : 0,
70
+ 'media' => ! empty( $user_info->edge_owner_to_timeline_media->count ) ? $user_info->edge_owner_to_timeline_media->count : 0,
71
+ ),
72
+ 'full_name' => ! empty( $user_info->full_name ) ? $user_info->full_name : '',
73
+ 'id' => ! empty( $user_info->id ) ? $user_info->id : '',
74
+ 'is_business' => ! empty( $user_info->is_business_account ) ? $user_info->is_business_account : '',
75
+ 'profile_picture' => ! empty( $user_info->profile_pic_url ) ? $user_info->profile_pic_url : '',
76
+ 'username' => ! empty( $user_info->username ) ? $user_info->username : '',
77
+ 'website' => ! empty( $user_info->external_url ) ? $user_info->external_url : ''
78
+ );
79
+
80
+ return $converted;
81
+
82
+ }
83
+
84
+ function get_response_without_token( $user ) {
85
+
86
+ $user = trim( $user );
87
+ $url = $url = 'https://instagram.com/' . str_replace( '@', '', $user );
88
+
89
+ $request = wp_remote_get( $url );
90
+
91
+ if ( is_wp_error( $request ) || empty( $request ) ) {
92
+ return new WP_Error( 'invalid_response', __( 'Invalid response from Instagram', 'wpzoom-instagram-widget' ) );
93
+ }
94
+
95
+ $body = wp_remote_retrieve_body( $request );
96
+
97
+ $doc = new DOMDocument();
98
+
99
+ @$doc->loadHTML( $body );
100
+
101
+ $script_tags = $doc->getElementsByTagName( 'script' );
102
+
103
+ $json = '';
104
+
105
+ foreach ( $script_tags as $script_tag ) {
106
+ if ( strpos( $script_tag->nodeValue, 'window._sharedData = ' ) !== false ) {
107
+ $json = $script_tag->nodeValue;
108
+ break;
109
+ }
110
+ }
111
+
112
+ $json = str_replace( array( 'window._sharedData = ', '};' ), array( '', '}' ), $json );
113
+ $result = json_decode( $json );
114
+
115
+ if ( empty( $result ) ) {
116
+ return new WP_Error( 'empty-json', __( 'Empty json decoded data.', 'wpzoom-instagram-widget' ) );
117
+ }
118
+
119
+ return $result;
120
+ }
121
+
122
+ function get_items_without_token( $user ) {
123
+
124
+
125
+ $result = $this->get_response_without_token( $user );
126
+
127
+ if ( empty( $result ) ) {
128
+ return new WP_Error( 'empty-json', __( 'Empty json decoded data.', 'wpzoom-instagram-widget' ) );
129
+ }
130
+
131
+ if ( isset( $result->entry_data->ProfilePage[0]->graphql->user->edge_owner_to_timeline_media->edges ) ) {
132
+ $edges = $result->entry_data->ProfilePage[0]->graphql->user->edge_owner_to_timeline_media->edges;
133
+ } else {
134
+ return new WP_Error( 'empty-json', __( 'Empty json decoded data.', 'wpzoom-instagram-widget' ) );
135
+ }
136
+
137
+ $converted = new stdClass;
138
+ $converted->data = array();
139
+ foreach ( $edges as $edge ) {
140
+
141
+ $node = $edge->node;
142
+
143
+ $converted->data[] = (object) array(
144
+ 'user' => (object) array(
145
+ 'id' => $node->owner->id,
146
+ 'fullname' => '',
147
+ 'profile_picture' => '',
148
+ 'username' => $node->owner->username
149
+ ),
150
+ 'images' => (object) array(
151
+ 'thumbnail' => (object) array(
152
+ 'url' => $node->thumbnail_resources[0]->src,
153
+ 'width' => $node->thumbnail_resources[0]->config_width,
154
+ 'height' => $node->thumbnail_resources[0]->config_height
155
+ ),
156
+ 'low_resolution' => (object) array(
157
+ 'url' => $node->thumbnail_resources[2]->src,
158
+ 'width' => $node->thumbnail_resources[2]->config_width,
159
+ 'height' => $node->thumbnail_resources[2]->config_height
160
+ ),
161
+ 'standard_resolution' => (object) array(
162
+ 'url' => $node->thumbnail_resources[4]->src,
163
+ 'width' => $node->thumbnail_resources[4]->config_width,
164
+ 'height' => $node->thumbnail_resources[4]->config_height
165
+ ),
166
+ ),
167
+ 'type' => empty($node->is_video) ? 'image': 'video',
168
+ 'likes' => isset( $node->edge_liked_by ) ? $node->edge_liked_by : 0,
169
+ 'comments' => isset( $node->edge_media_to_comment ) ? $node->edge_media_to_comment : 0,
170
+ 'created_time' => $node->taken_at_timestamp,
171
+ 'link' => sprintf( 'https://www.instagram.com/p/%s/', $node->shortcode ),
172
+ 'caption' => (object) array(
173
+ 'text' => isset( $node->edge_media_to_caption->edges[0]->node->text ) ? $node->edge_media_to_caption->edges[0]->node->text : ''
174
+ )
175
+ );
176
+ }
177
+
178
+ return $converted;
179
+ }
180
+
181
+ /**
182
+ * @param $screen_name string Instagram username
183
+ * @param $image_limit int Number of images to retrieve
184
+ * @param $image_width int Desired image width to retrieve
185
+ *
186
+ * @return array|bool Array of tweets or false if method fails
187
+ */
188
+ public function get_items( $instance ) {
189
+
190
+ $sliced = wp_array_slice_assoc( $instance, array(
191
+ 'image-limit',
192
+ 'image-width',
193
+ 'image-resolution',
194
+ 'username',
195
+ 'disable-video-thumbs'
196
+ ) );
197
+
198
+ $image_limit = $sliced['image-limit'];
199
+ $image_width = $sliced['image-width'];
200
+ $image_resolution = ! empty( $sliced['image-resolution'] ) ? $sliced['image-resolution'] : 'default_algorithm';
201
+ $injected_username = ! empty( $sliced['username'] ) ? $sliced['username'] : '';
202
+ $disable_video_thumbs = ! empty( $sliced['disable-video-thumbs'] );
203
+
204
+ $transient = 'zoom_instagram_is_configured';
205
+
206
+ $injected_username = trim( $injected_username );
207
+
208
+ if ( ! empty( $injected_username ) ) {
209
+ $injected_username = str_replace( '@', '', $injected_username );
210
+ $transient = $transient . '_' . $injected_username;
211
+ }
212
+
213
+ if ( false !== ( $data = get_transient( $transient ) ) && is_object( $data ) && ! empty( $data->data ) ) {
214
+
215
+ return $this->processing_response_data( $data, $image_width, $image_resolution, $image_limit, $disable_video_thumbs );
216
+ }
217
+
218
+ $is_external_username = ! empty( $this->username ) || ! empty( $injected_username );
219
+ $external_username = ! empty( $injected_username ) ? $injected_username : $this->username;
220
+
221
+
222
+ if ( ! empty( $this->access_token ) ) {
223
+ $api_image_limit = 30;
224
+ $response = wp_remote_get( sprintf( 'https://api.instagram.com/v1/users/self/media/recent/?access_token=%s&count=%s', $this->access_token, $api_image_limit ) );
225
+
226
+ if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) {
227
+ set_transient( $transient, false, MINUTE_IN_SECONDS );
228
+
229
+ return false;
230
+ }
231
+
232
+ $data = json_decode( wp_remote_retrieve_body( $response ) );
233
+
234
+ $token_username = ! empty( $data->data[0]->user->username ) ? $data->data[0]->user->username : '';
235
+
236
+
237
+ if ( ! empty( $token_username ) && ! empty( $is_external_username ) ) {
238
+
239
+ if ( $external_username !== $token_username ) {
240
+
241
+ $data = $this->get_items_without_token( $external_username );
242
+
243
+ if ( is_wp_error( $data ) ) {
244
+ set_transient( $transient, false, MINUTE_IN_SECONDS );
245
+
246
+ return false;
247
+ }
248
+ }
249
+ }
250
+ }
251
+
252
+ if ( empty( $this->access_token ) && ! empty( $is_external_username ) ) {
253
+
254
+
255
+ $data = $this->get_items_without_token( $external_username );
256
+
257
+ if ( is_wp_error( $data ) ) {
258
+ set_transient( $transient, false, MINUTE_IN_SECONDS );
259
+
260
+ return false;
261
+ }
262
+
263
+ }
264
+
265
+ if ( ! empty( $data->data ) ) {
266
+ set_transient( $transient, $data, $this->get_transient_lifetime() );
267
+ } else {
268
+ set_transient( $transient, false, MINUTE_IN_SECONDS );
269
+
270
+ return false;
271
+ }
272
+
273
+ return $this->processing_response_data( $data, $image_width, $image_resolution, $image_limit, $disable_video_thumbs );
274
+ }
275
+
276
+ public function processing_response_data( $data, $image_width, $image_resolution = 'default_algorithm', $image_limit, $disable_video_thumbs = false ) {
277
+
278
+ $result = array();
279
+ $username = '';
280
+
281
+ foreach ( $data->data as $key => $item ) {
282
+
283
+ if ( empty( $username ) ) {
284
+ $username = $item->user->username;
285
+ }
286
+
287
+ if ( $key === $image_limit ) {
288
+ break;
289
+ }
290
+
291
+ if ( ! empty( $disable_video_thumbs ) && isset( $item->type ) && 'video' == $item->type ) {
292
+ $image_limit++;
293
+ continue;
294
+
295
+ }
296
+
297
+ $result[] = array(
298
+ 'link' => $item->link,
299
+ 'image-url' => $item->images->{$this->get_best_size( $image_width, $image_resolution )}->url,
300
+ 'image-caption' => ! empty( $item->caption->text ) ? esc_attr( $item->caption->text ) : '',
301
+ 'likes_count' => ! empty( $item->likes->count ) ? esc_attr( $item->likes->count ) : 0,
302
+ 'comments_count' => ! empty( $item->comments->count ) ? esc_attr( $item->comments->count ) : 0
303
+ );
304
+ }
305
+
306
+ $result = array( 'items' => $result, 'username' => $username );
307
+
308
+ return $result;
309
+ }
310
+
311
+ public function get_user_info( $injected_username = '' ) {
312
+
313
+
314
+ $transient = 'zoom_instagram_user_info';
315
+
316
+ $injected_username = rtrim( $injected_username );
317
+
318
+ if ( ! empty( $injected_username ) ) {
319
+ $injected_username = str_replace( '@', '', $injected_username );
320
+ $transient = $transient . '_' . $injected_username;
321
+ }
322
+
323
+ if ( false !== ( $data = get_transient( $transient ) ) && is_object( $data ) && ! empty( $data->data ) ) {
324
+
325
+ return $data;
326
+ }
327
+
328
+ $is_external_username = ! empty( $this->username ) || ! empty( $injected_username );
329
+ $external_username = ! empty( $injected_username ) ? $injected_username : $this->username;
330
+
331
+ if ( ! empty( $this->access_token ) ) {
332
+
333
+ $response = wp_remote_get( sprintf( 'https://api.instagram.com/v1/users/self/?access_token=%s', $this->access_token ) );
334
+
335
+ if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) {
336
+ set_transient( $transient, false, MINUTE_IN_SECONDS );
337
+
338
+ return false;
339
+ }
340
+
341
+ $data = json_decode( wp_remote_retrieve_body( $response ) );
342
+
343
+ $token_username = ! empty( $data->data->username ) ? $data->data->username : '';
344
+
345
+ if ( ! empty( $token_username ) && ! empty( $is_external_username ) ) {
346
+
347
+ if ( $external_username !== $token_username ) {
348
+
349
+ $data = $this->get_user_info_without_token( $external_username );
350
+
351
+ if ( is_wp_error( $data ) ) {
352
+ set_transient( $transient, false, MINUTE_IN_SECONDS );
353
+
354
+ return false;
355
+ }
356
+ }
357
+ }
358
+
359
+ }
360
+
361
+ if ( empty( $this->access_token ) && ! empty( $is_external_username ) ) {
362
+
363
+ $data = $this->get_user_info_without_token( $external_username );
364
+
365
+ if ( is_wp_error( $data ) ) {
366
+ set_transient( $transient, false, MINUTE_IN_SECONDS );
367
+
368
+ return false;
369
+ }
370
+
371
+ }
372
+
373
+ if ( ! empty( $data->data ) ) {
374
+ set_transient( $transient, $data, $this->get_transient_lifetime() );
375
+ } else {
376
+ set_transient( $transient, false, MINUTE_IN_SECONDS );
377
+
378
+ return false;
379
+ }
380
+
381
+ return $data;
382
+
383
+ }
384
+
385
+ /**
386
+ * @param $screen_name string Instagram username
387
+ *
388
+ * @return bool|int Instagram user id or false on error
389
+ */
390
+ protected function get_user_id( $screen_name ) {
391
+ $user_id_option = 'zoom_instagram_uid_' . $screen_name;
392
+
393
+ if ( false !== ( $user_id = get_option( $user_id_option ) ) ) {
394
+ return $user_id;
395
+ }
396
+
397
+ $response = wp_remote_get( sprintf( 'https://api.instagram.com/v1/users/search?q=%s&access_token=%s', $screen_name, $this->access_token ) );
398
+
399
+ if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) {
400
+ return false;
401
+ }
402
+
403
+ $result = json_decode( wp_remote_retrieve_body( $response ) );
404
+
405
+ if ( ! isset( $result->data ) ) {
406
+ return false;
407
+ }
408
+
409
+ $user_id = false;
410
+
411
+ foreach ( $result->data as $user ) {
412
+ if ( $user->username === $screen_name ) {
413
+ $user_id = $user->id;
414
+
415
+ break;
416
+ }
417
+ }
418
+
419
+ update_option( $user_id_option, $user_id );
420
+
421
+ return $user_id;
422
+ }
423
+
424
+ /**
425
+ * @param $desired_width int Desired image width in pixels
426
+ *
427
+ * @return string Image size for Instagram API
428
+ */
429
+ protected function get_best_size( $desired_width, $image_resolution = 'default_algorithm' ) {
430
+ $size = 'thumbnail';
431
+ $sizes = array(
432
+ 'thumbnail' => 150,
433
+ 'low_resolution' => 306,
434
+ 'standard_resolution' => 640
435
+ );
436
+
437
+ $diff = PHP_INT_MAX;
438
+
439
+ if ( array_key_exists( $image_resolution, $sizes ) ) {
440
+ return $image_resolution;
441
+ }
442
+
443
+ foreach ( $sizes as $key => $value ) {
444
+ if ( abs( $desired_width - $value ) < $diff ) {
445
+ $size = $key;
446
+ $diff = abs( $desired_width - $value );
447
+ }
448
+ }
449
+
450
+ return $size;
451
+ }
452
+
453
+ /**
454
+ * Check if given access token is valid for Instagram Api.
455
+ */
456
+ public static function is_access_token_valid( $access_token ) {
457
+ $response = wp_remote_get( sprintf( 'https://api.instagram.com/v1/users/self/?access_token=%s', $access_token ) );
458
+
459
+ if ( is_wp_error( $response ) ) {
460
+ return $response;
461
+ }
462
+
463
+ if ( 200 != wp_remote_retrieve_response_code( $response ) ) {
464
+ return false;
465
+ }
466
+
467
+ return true;
468
+ }
469
+
470
+ public function is_configured() {
471
+ $transient = 'zoom_instagram_is_configured';
472
+
473
+ if ( false !== ( $result = get_transient( $transient ) ) ) {
474
+ if ( 'yes' === $result ) {
475
+ return true;
476
+ }
477
+
478
+ if ( 'no' === $result ) {
479
+ return false;
480
+ }
481
+ }
482
+
483
+ if(empty($this->username)){
484
+ $condition = $this->is_access_token_valid( $this->access_token );
485
+
486
+ } else{
487
+ $condition = true;
488
+ }
489
+
490
+
491
+ if ( true === $condition ) {
492
+ set_transient( $transient, 'yes', DAY_IN_SECONDS );
493
+
494
+ return true;
495
+ }
496
+
497
+ set_transient( $transient, 'no', DAY_IN_SECONDS );
498
+
499
+ return false;
500
+ }
501
+
502
+ public static function reset_cache() {
503
+ delete_transient( 'zoom_instagram_is_configured' );
504
+ delete_transient( 'zoom_instagram_user_info' );
505
+ }
506
+
507
+ public function get_access_token() {
508
+ return $this->access_token;
509
+ }
510
+
511
+ public function set_access_token( $access_token ) {
512
+ $this->access_token = $access_token;
513
+ }
514
+ }
class-wpzoom-instagram-widget-settings.php ADDED
@@ -0,0 +1,307 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Wpzoom_Instagram_Widget_Settings {
4
+ public function __construct() {
5
+ add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
6
+ add_action( 'admin_init', array( $this, 'settings_init' ) );
7
+
8
+ add_filter( 'plugin_action_links', array( $this, 'add_action_links' ), 10, 2 );
9
+
10
+ add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ),9 );
11
+ }
12
+
13
+ function add_action_links( $links, $file ) {
14
+ if ( $file != plugin_basename( dirname( __FILE__ ) . '/instagram-widget-by-wpzoom.php' ) ) {
15
+ return $links;
16
+ }
17
+
18
+ $settings_link = sprintf(
19
+ '<a href="%1$s">%2$s</a>',
20
+ menu_page_url( 'wpzoom-instagram-widget', false ),
21
+ esc_html__( 'Settings', 'wpzoom-instagram-widget' )
22
+ );
23
+
24
+ array_unshift( $links, $settings_link );
25
+
26
+ return $links;
27
+ }
28
+
29
+ public function add_admin_menu() {
30
+ add_options_page(
31
+ 'Instagram Widget',
32
+ 'Instagram Widget',
33
+ 'manage_options',
34
+ 'wpzoom-instagram-widget',
35
+ array( $this, 'settings_page' )
36
+ );
37
+ }
38
+
39
+ public function settings_init() {
40
+ register_setting(
41
+ 'wpzoom-instagram-widget-settings-group',
42
+ 'wpzoom-instagram-widget-settings',
43
+ array( $this, 'sanitize' )
44
+ );
45
+
46
+ add_settings_section(
47
+ 'wpzoom-instagram-widget-settings-general',
48
+ null,
49
+ '__return_false',
50
+ 'wpzoom-instagram-widget-settings-group'
51
+ );
52
+
53
+ add_settings_field(
54
+ 'wpzoom-instagram-widget-request-type',
55
+ __( 'Request Type', 'wpzoom-instagram-widget' ),
56
+ array( $this, 'settings_field_request_type' ),
57
+ 'wpzoom-instagram-widget-settings-group',
58
+ 'wpzoom-instagram-widget-settings-general',
59
+ array('class' => 'wpzoom-instagram-widget-with-token-group')
60
+ );
61
+
62
+ add_settings_field(
63
+ 'wpzoom-instagram-widget-access-token-button',
64
+ __( '', 'wpzoom-instagram-widget' ),
65
+ array( $this, 'settings_field_access_token_button' ),
66
+ 'wpzoom-instagram-widget-settings-group',
67
+ 'wpzoom-instagram-widget-settings-general',
68
+ array('class' => 'wpzoom-instagram-widget-with-access-token-group')
69
+
70
+ );
71
+
72
+ add_settings_field(
73
+ 'wpzoom-instagram-widget-access-token-input',
74
+ __( 'Access Token', 'wpzoom-instagram-widget' ),
75
+ array( $this, 'settings_field_access_token_input' ),
76
+ 'wpzoom-instagram-widget-settings-group',
77
+ 'wpzoom-instagram-widget-settings-general',
78
+ array('class' => 'wpzoom-instagram-widget-with-access-token-group')
79
+
80
+ );
81
+
82
+ add_settings_field(
83
+ 'wpzoom-instagram-widget-username-description',
84
+ __( '', 'wpzoom-instagram-widget' ),
85
+ array( $this, 'settings_field_username_description' ),
86
+ 'wpzoom-instagram-widget-settings-group',
87
+ 'wpzoom-instagram-widget-settings-general',
88
+ array('class' => 'wpzoom-instagram-widget-without-access-token-group')
89
+ );
90
+
91
+ add_settings_field(
92
+ 'wpzoom-instagram-widget-username',
93
+ __( 'Username', 'wpzoom-instagram-widget' ),
94
+ array( $this, 'settings_field_username' ),
95
+ 'wpzoom-instagram-widget-settings-group',
96
+ 'wpzoom-instagram-widget-settings-general',
97
+ array('class' => 'wpzoom-instagram-widget-without-access-token-group')
98
+
99
+ );
100
+
101
+ add_settings_field(
102
+ 'wpzoom-instagram-widget-transient-lifetime',
103
+ __( 'Check for new Instagram posts every', 'wpzoom-instagram-widget' ),
104
+ array( $this, 'settings_field_transient_lifetime' ),
105
+ 'wpzoom-instagram-widget-settings-group',
106
+ 'wpzoom-instagram-widget-settings-general'
107
+ );
108
+
109
+
110
+ }
111
+
112
+ public function settings_field_access_token_button() {
113
+ $oauth_url = 'https://instagram.com/oauth/authorize/?client_id=955bdb2319484968b93de8d6a1032c66&response_type=token&redirect_uri=https://www.wpzoom.com/instagram/';
114
+ $oauth_url .= '?auth_site=' . esc_url( admin_url( 'options-general.php?page=wpzoom-instagram-widget' ) );
115
+ $oauth_url.='&hl=en';
116
+ ?>
117
+
118
+ <p class="description"><?php _e( 'Using this method, you will be prompted to authorize the plugin to access your Instagram photos. The widget will automatically display the latest photos of the account which was authorized on this page.', 'wpzoom-instagram-widget' ); ?></p>
119
+
120
+ <br />
121
+
122
+ <a class="button button-connect" href="<?php echo esc_url( $oauth_url ); ?>">
123
+ <?php if ( ! Wpzoom_Instagram_Widget_API::getInstance()->is_configured() ) : ?>
124
+ <span><?php _e( 'Connect with Instagram', 'wpzoom-instagram-widget' ); ?></span>
125
+ <?php else: ?>
126
+ <span class="zoom-instagarm-widget-connected"><?php _e( 'Re-connect with Instagram', 'wpzoom-instagram-widget' ); ?></span>
127
+ <?php endif; ?>
128
+ </a>
129
+ </p>
130
+ <?php
131
+ }
132
+
133
+ public function settings_field_transient_lifetime() {
134
+ $settings = get_option( 'wpzoom-instagram-widget-settings' );
135
+ $lifetime_value = ! empty( $settings['transient-lifetime-value'] ) ? $settings['transient-lifetime-value'] : 1;
136
+ $lifetime_type = ! empty( $settings['transient-lifetime-type'] ) ? $settings['transient-lifetime-type'] : 'days';
137
+ ?>
138
+ <input class="regular-text code"
139
+ id="wpzoom-instagram-widget-settings_transient-lifetime-value"
140
+ name="wpzoom-instagram-widget-settings[transient-lifetime-value]"
141
+ value="<?php echo esc_attr( $lifetime_value ) ?>"
142
+ type="number"
143
+ min="1">
144
+
145
+ <select class="regular-text code"
146
+ id="wpzoom-instagram-widget-settings_transient-lifetime-type"
147
+ name="wpzoom-instagram-widget-settings[transient-lifetime-type]">
148
+ <option <?php selected( $lifetime_type, 'hours' ); ?> value="hours"><?php _e( 'Hours', 'wpzoom-instagram-widget' ) ?></option>
149
+ <option <?php selected( $lifetime_type, 'days' ); ?> value="days"><?php _e( 'Days', 'wpzoom-instagram-widget' ) ?></option>
150
+ <option <?php selected( $lifetime_type, 'minutes' ); ?> value="minutes"><?php _e( 'Minutes', 'wpzoom-instagram-widget' ) ?></option>
151
+ </select>
152
+ <?php
153
+ }
154
+
155
+ public function settings_field_access_token_input() {
156
+ $settings = get_option( 'wpzoom-instagram-widget-settings' );
157
+ ?>
158
+ <input class="regular-text code" id="wpzoom-instagram-widget-settings_access-token" name="wpzoom-instagram-widget-settings[access-token]" value="<?php echo esc_attr( $settings['access-token'] ) ?>" type="text">
159
+ <p class="description">
160
+ <?php
161
+ printf(
162
+ __(
163
+ 'The Instagram Access Token is a long string of characters unique to your account that grants other applications access to your Instagram feed. You can also get it manually from <a href="%1$s">here</a>.',
164
+ 'wpzoom-instagram-widget'
165
+ ),
166
+ 'https://www.wpzoom.com/instagram/'
167
+ );
168
+ ?>
169
+ </p>
170
+ <?php
171
+ }
172
+
173
+ public function settings_field_username_description() {
174
+ ?>
175
+ <p class="description"><?php _e( 'Using this method, a public feed, limited to <strong>12 photos</strong>, will be displayed in the widget.<br/>This option is useful if you want to display the feed of an Instagram account which you don\'t own or you have troubles getting your Access Token.', 'wpzoom-instagram-widget' ); ?></p>
176
+
177
+ </p>
178
+ <?php
179
+ }
180
+
181
+ public function settings_field_username() {
182
+ $settings = get_option( 'wpzoom-instagram-widget-settings' );
183
+ ?>
184
+ <input class="regular-text code" id="wpzoom-instagram-widget-settings_username" name="wpzoom-instagram-widget-settings[username]" value="<?php echo esc_attr( $settings['username'] ) ?>" type="text">
185
+ <p class="description">
186
+ <?php
187
+ printf(
188
+ __(
189
+ 'The username entered here will be used in the Instagram feed, unless a different username will be entered in the widget settings.',
190
+ 'wpzoom-instagram-widget'
191
+ )
192
+ );
193
+ ?>
194
+ </p>
195
+ <?php
196
+ }
197
+
198
+ public function settings_field_request_type() {
199
+ $settings = get_option( 'wpzoom-instagram-widget-settings' );
200
+ $request_type = empty( $settings['request-type'] ) ? 'with-access-token' : $settings['request-type'];
201
+ ?>
202
+
203
+ <div class="wpzoom-instagram-widget-settins-request-type-wrapper">
204
+ <p><label for="wpzoom-instagram-widget-settings_with-access-token"><input class="code" id="wpzoom-instagram-widget-settings_with-access-token"
205
+ name="wpzoom-instagram-widget-settings[request-type]"
206
+ value="with-access-token" <?php checked( $request_type, 'with-access-token' ) ?> type="radio"> <?php _e('With Access Token', 'wpzoom-instagram-widget')?>&nbsp;&nbsp;</label>
207
+ <label for="wpzoom-instagram-widget-settings_without-access-token"><input class="code" id="wpzoom-instagram-widget-settings_without-access-token"
208
+ name="wpzoom-instagram-widget-settings[request-type]" value="without-access-token"
209
+ <?php checked( $request_type, 'without-access-token' ) ?>type="radio"><?php _e('Public Feed (12 photos)', 'wpzoom-instagram-widget')?></label>
210
+ </p>
211
+ </div>
212
+
213
+ <?php
214
+ }
215
+
216
+ public function settings_page() {
217
+ ?>
218
+
219
+ <div class="wrap">
220
+
221
+ <h1><?php _e( 'Instagram Widget by WPZOOM', 'wpzoom-instagram-widget' ); ?></h1>
222
+
223
+ <div class="zoom-instagram-widget">
224
+
225
+ <h2><?php _e( 'Connect your account', 'wpzoom-instagram-widget' ); ?></h2>
226
+
227
+ <p><?php _e( 'To get started, select an option below. If you want to show your own feed, use the first option: <strong>With Access Token</strong>. If you want to show the feed of an Instagram account which you don\'t own, use the option <strong>Public Feed</strong>.', 'wpzoom-instagram-widget' ); ?></p>
228
+
229
+ <form action="options.php" method="post">
230
+
231
+ <?php
232
+ settings_fields( 'wpzoom-instagram-widget-settings-group' );
233
+ do_settings_sections( 'wpzoom-instagram-widget-settings-group' );
234
+ submit_button();
235
+ ?>
236
+
237
+ </form>
238
+
239
+ </div>
240
+
241
+ <div class="zoom-themes-link">
242
+
243
+ <h2><?php _e( 'Premium WordPress Themes by WPZOOM', 'wpzoom-instagram-widget' ); ?></h2>
244
+
245
+ <p><?php _e( 'Are you looking to give your website a new look?<br/> Check out our collection of <strong>40 expertly-crafted themes</strong> and find the perfect one for your needs!', 'wpzoom-instagram-widget' ); ?></p>
246
+
247
+ <p><?php printf( __( '<a class="cta-button" target="_blank" href="%1$s"">View our Themes &rarr;</a>' ), 'https://www.wpzoom.com/themes/' ); ?></p>
248
+
249
+ </div>
250
+
251
+ </div>
252
+
253
+ <?php
254
+ }
255
+
256
+ public function scripts( $hook ) {
257
+ if ( $hook != 'settings_page_wpzoom-instagram-widget' ) {
258
+ return;
259
+ }
260
+
261
+ wp_enqueue_style( 'zoom-instagram-widget-admin', plugin_dir_url( dirname( __FILE__ ) . '/instagram-widget-by-wpzoom.php' ) . 'css/admin-instagram-widget.css', array(), '1.4.2' );
262
+ wp_enqueue_script( 'zoom-instagram-widget-admin', plugin_dir_url( dirname( __FILE__ ) . '/instagram-widget-by-wpzoom.php' ) . 'js/admin-instagram-widget.js', array( 'jquery' ), '1.4.2' );
263
+ wp_localize_script( 'zoom-instagram-widget-admin', 'zoom_instagram_widget_admin', array(
264
+ 'i18n_connect_confirm' => __( "Instagram Widget is already connected to Instagram.\r\n\r\nDo you want to connect again?", 'wpzoom-instagram-widget' ),
265
+ ) );
266
+ }
267
+
268
+ public function sanitize( $input ) {
269
+ $result = array();
270
+
271
+ $result['access-token'] = sanitize_text_field( $input['access-token'] );
272
+
273
+ if ( ! empty( $result['access-token'] ) ) {
274
+ $validation_result = Wpzoom_Instagram_Widget_API::is_access_token_valid( $result['access-token'] );
275
+
276
+ if ( $validation_result !== true ) {
277
+ $access_token_error_message = __( 'Provided Access Token has been rejected by Instagram API. Please try again or use the other option.', 'wpzoom-instagram-widget' );
278
+
279
+ if ( is_wp_error( $validation_result ) ) {
280
+ $access_token_error_message = $validation_result->get_error_message();
281
+ }
282
+
283
+ if ( $validation_result !== true ) {
284
+ add_settings_error(
285
+ 'wpzoom-instagram-widget-access-token',
286
+ esc_attr( 'wpzoom-instagram-widget-access-token-invalid' ),
287
+ $access_token_error_message,
288
+ 'error'
289
+ );
290
+ }
291
+
292
+ $result['access-token'] = '';
293
+ }
294
+ }
295
+
296
+ $result['username'] = sanitize_text_field( $input['username'] );
297
+ $result['request-type'] = sanitize_text_field( $input['request-type'] );
298
+ $result['transient-lifetime-value'] = sanitize_text_field( $input['transient-lifetime-value'] );
299
+ $result['transient-lifetime-type'] = sanitize_text_field( $input['transient-lifetime-type'] );
300
+
301
+ Wpzoom_Instagram_Widget_API::reset_cache();
302
+
303
+ return $result;
304
+ }
305
+ }
306
+
307
+ new Wpzoom_Instagram_Widget_Settings();
class-wpzoom-instagram-widget.php ADDED
@@ -0,0 +1,449 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Wpzoom_Instagram_Widget extends WP_Widget {
4
+ /**
5
+ * @var Wpzoom_Instagram_Widget_API
6
+ */
7
+ protected $api;
8
+
9
+ /**
10
+ * @var array Default widget settings.
11
+ */
12
+ protected $defaults;
13
+
14
+ public function __construct() {
15
+ parent::__construct(
16
+ 'wpzoom_instagram_widget',
17
+ esc_html__( 'Instagram Widget by WPZOOM', 'wpzoom-instagram-widget' ),
18
+ array(
19
+ 'classname' => 'zoom-instagram-widget',
20
+ 'description' => __( 'Displays a user\'s Instagram timeline.', 'wpzoom-instagram-widget' ),
21
+ )
22
+ );
23
+
24
+ $this->defaults = array(
25
+ 'title' => esc_html__( 'Instagram', 'wpzoom-instagram-widget' ),
26
+ 'button_text' => esc_html__( 'View on Instagram', 'wpzoom-instagram-widget' ),
27
+ 'image-limit' => 9,
28
+ 'show-view-on-instagram-button' => true,
29
+ 'show-counts-on-hover' => false,
30
+ 'show-user-info' => false,
31
+ 'show-user-bio' => false,
32
+ 'lazy-load-images' => false,
33
+ 'disable-video-thumbs' => false,
34
+ 'images-per-row' => 3,
35
+ 'image-width' => 120,
36
+ 'image-spacing' => 10,
37
+ 'image-resolution' => 'default_algorithm',
38
+ 'username' => '',
39
+ );
40
+
41
+ $this->api = Wpzoom_Instagram_Widget_API::getInstance();
42
+
43
+ add_action( 'wp_enqueue_scripts', array( $this, 'scripts' ) );
44
+ }
45
+
46
+ /**
47
+ * Widget specific scripts & styles
48
+ */
49
+ public function scripts() {
50
+ wp_enqueue_style( 'zoom-instagram-widget', plugin_dir_url( dirname( __FILE__ ) . '/instagram-widget-by-wpzoom.php' ) . 'css/instagram-widget.css', array('dashicons'), '1.4.2' );
51
+ wp_enqueue_script( 'zoom-instagram-widget-lazy-load', plugin_dir_url( dirname( __FILE__ ) . '/instagram-widget-by-wpzoom.php' ) . 'js/jquery.lazy.min.js', array( 'jquery' ), '1.4.2' );
52
+ wp_enqueue_script( 'zoom-instagram-widget', plugin_dir_url( dirname( __FILE__ ) . '/instagram-widget-by-wpzoom.php' ) . 'js/instagram-widget.js', array( 'jquery' ), '1.4.2' );
53
+ }
54
+
55
+ /**
56
+ * Front-end display of widget.
57
+ *
58
+ * @see WP_Widget::widget()
59
+ *
60
+ * @param array $args Widget arguments.
61
+ * @param array $instance Saved values from database.
62
+ */
63
+ public function widget( $args, $instance ) {
64
+ $instance = wp_parse_args( (array) $instance, $this->defaults );
65
+
66
+ echo $args['before_widget'];
67
+
68
+ if ( $instance['title'] ) {
69
+ echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
70
+ }
71
+
72
+
73
+ $items = $this->api->get_items( $instance );
74
+
75
+ if ( ! is_array( $items ) ) {
76
+ $this->display_errors();
77
+ } else {
78
+
79
+ if ( ! empty( $instance['show-user-info'] ) ) {
80
+ $user_info = $this->api->get_user_info($instance['username']);
81
+
82
+ if (
83
+ is_object( $user_info ) &&
84
+ ! empty( $user_info ) &&
85
+ ! empty( $user_info->data )
86
+ ) {
87
+ $this->display_user_info( $instance, $user_info );
88
+ }
89
+ }
90
+
91
+ $this->display_items( $items['items'], $instance );
92
+ $this->display_instagram_button( $instance, $items['username'] );
93
+ }
94
+
95
+
96
+ echo $args['after_widget'];
97
+ }
98
+
99
+ /**
100
+ * Sanitize widget form values as they are saved.
101
+ *
102
+ * @see WP_Widget::update()
103
+ *
104
+ * @param array $new_instance Values just sent to be saved.
105
+ * @param array $old_instance Previously saved values from database.
106
+ *
107
+ * @return array Updated safe values to be saved.
108
+ */
109
+ public function update( $new_instance, $old_instance ) {
110
+ $instance['title'] = sanitize_text_field( $new_instance['title'] );
111
+ $instance['button_text'] = sanitize_text_field( $new_instance['button_text'] );
112
+
113
+ $instance['image-limit'] = ( 0 !== (int) $new_instance['image-limit'] ) ? (int) $new_instance['image-limit'] : null;
114
+
115
+ $instance['images-per-row'] = ( 0 !== (int) $new_instance['images-per-row'] ) ? (int) $new_instance['images-per-row'] : null;
116
+ $instance['image-width'] = ( 0 !== (int) $new_instance['image-width'] ) ? (int) $new_instance['image-width'] : null;
117
+ $instance['image-spacing'] = ( 0 <= (int) $new_instance['image-spacing'] ) ? (int) $new_instance['image-spacing'] : null;
118
+ $instance['image-resolution'] = !empty($new_instance['image-resolution']) ? $new_instance['image-resolution'] : $this->defaults['image-resolution'];
119
+ $instance['username'] = !empty($new_instance['username']) ? $new_instance['username'] : $this->defaults['username'];
120
+
121
+ $instance['show-view-on-instagram-button'] = ! empty( $new_instance['show-view-on-instagram-button'] );
122
+ $instance['show-counts-on-hover'] = ! empty( $new_instance['show-counts-on-hover'] );
123
+ $instance['show-user-info'] = ! empty( $new_instance['show-user-info'] );
124
+ $instance['show-user-bio'] = ! empty( $new_instance['show-user-bio'] );
125
+ $instance['lazy-load-images'] = ! empty( $new_instance['lazy-load-images'] );
126
+ $instance['disable-video-thumbs'] = ! empty( $new_instance['disable-video-thumbs'] );
127
+
128
+
129
+ return $instance;
130
+ }
131
+
132
+ /**
133
+ * Back-end widget form.
134
+ *
135
+ * @see WP_Widget::form()
136
+ *
137
+ * @param array $instance Previously saved values from database.
138
+ *
139
+ * @return string|void
140
+ */
141
+ public function form( $instance ) {
142
+ $instance = wp_parse_args( (array) $instance, $this->defaults );
143
+ ?>
144
+
145
+ <?php if ( empty($instance['username']) && ! $this->api->is_configured() ) : ?>
146
+
147
+ <p style="color: #d54e21">
148
+ <?php
149
+ printf( __( 'You need to configure <a href="%1$s">plugin settings</a> before using this widget.', 'wpzoom-instagram-widget' ),
150
+ menu_page_url( 'wpzoom-instagram-widget', false ) );
151
+ ?>
152
+ </p>
153
+
154
+ <?php endif; ?>
155
+
156
+ <p>
157
+ <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( 'Title:', 'wpzoom-instagram-widget' ); ?></label>
158
+ <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $instance['title'] ); ?>"/>
159
+ </p>
160
+
161
+
162
+ <p>
163
+ <label for="<?php echo $this->get_field_id( 'image-limit' ); ?>"><?php esc_html_e( 'Number of Images Shown:', 'wpzoom-instagram-widget' ); ?></label>
164
+ <input class="widefat" id="<?php echo $this->get_field_id( 'image-limit' ); ?>" name="<?php echo $this->get_field_name( 'image-limit' ); ?>" type="number" min="1" max="30" value="<?php echo esc_attr( $instance['image-limit'] ); ?>"/>
165
+ </p>
166
+
167
+ <p>
168
+ <label for="<?php echo $this->get_field_id( 'images-per-row' ); ?>"><?php esc_html_e( 'Desired number of Images per row:', 'wpzoom-instagram-widget' ); ?></label>
169
+ <input class="widefat" id="<?php echo $this->get_field_id( 'images-per-row' ); ?>" name="<?php echo $this->get_field_name( 'images-per-row' ); ?>" type="number" min="1" max="20" value="<?php echo esc_attr( $instance['images-per-row'] ); ?>"/>
170
+ </p>
171
+
172
+ <p>
173
+ <label for="<?php echo $this->get_field_id( 'image-width' ); ?>"><?php esc_html_e( 'Desired Image width in pixels:', 'wpzoom-instagram-widget' ); ?> <small>(Just integer)</small></label>
174
+ <input class="widefat" id="<?php echo $this->get_field_id( 'image-width' ); ?>" name="<?php echo $this->get_field_name( 'image-width' ); ?>" type="number" min="20" value="<?php echo esc_attr( $instance['image-width'] ); ?>"/>
175
+ </p>
176
+
177
+ <p>
178
+ <label for="<?php echo $this->get_field_id( 'image-spacing' ); ?>"><?php esc_html_e( 'Image spacing in pixels:', 'wpzoom-instagram-widget' ); ?> <small>(Just integer)</small></label>
179
+ <input class="widefat" id="<?php echo $this->get_field_id( 'image-spacing' ); ?>" name="<?php echo $this->get_field_name( 'image-spacing' ); ?>" type="number" min="0" max="50" value="<?php echo esc_attr( $instance['image-spacing'] ); ?>"/>
180
+ </p>
181
+
182
+ <p class="description">
183
+ <?php
184
+ echo wp_kses_post(
185
+ __( 'Fields above do not influence directly widget appearance. Final number of images per row and image width is calculated depending on browser resolution. This ensures your photos look beautiful on all devices.', 'wpzoom-instagram-widget' )
186
+ );
187
+ ?>
188
+ </p>
189
+
190
+ <p>
191
+ <label for="<?php echo $this->get_field_id( 'username' ); ?>"><strong><?php esc_html_e( 'Instagram @username:', 'wpzoom-instagram-widget' ); ?></strong></label>
192
+ <input class="widefat" id="<?php echo $this->get_field_id( 'username' ); ?>" name="<?php echo $this->get_field_name( 'username' ); ?>" type="text" value="<?php echo esc_attr( $instance['username'] ); ?>"/>
193
+ </p>
194
+
195
+ <p class="description">
196
+
197
+ <?php
198
+ printf( __( 'If you have already connected your Instagram account in the <a href="%1$s">plugin settings</a>, leave this field empty. You can use this option if you want to display the feed of a different Instagram account.', 'wpzoom-instagram-widget' ),
199
+ menu_page_url( 'wpzoom-instagram-widget', false ) );
200
+ ?>
201
+
202
+ </p>
203
+
204
+ <p>
205
+ <label for="<?php echo $this->get_field_id( 'image-resolution' ); ?>"><?php esc_html_e( 'Set forced image resolution:', 'wpzoom-instagram-widget' ); ?></label>
206
+ <select class="widefat" id="<?php echo $this->get_field_id( 'image-resolution' ); ?>" name="<?php echo $this->get_field_name( 'image-resolution' ); ?>">
207
+ <option value="default_algorithm" <?php selected( $instance['image-resolution'], "default_algorithm" ); ?>>
208
+ <?php _e('By Default Algorithm', 'wpzoom-instagram-widget' ); ?>
209
+ </option>
210
+ <option value="thumbnail" <?php selected( $instance['image-resolution'], "thumbnail" ); ?>>
211
+ <?php _e('Thumbnail ( 150x150px )', 'wpzoom-instagram-widget' ); ?>
212
+ </option>
213
+ <option value="low_resolution" <?php selected( $instance['image-resolution'], "low_resolution" ); ?>>
214
+ <?php _e('Low Resolution ( 320x320px )', 'wpzoom-instagram-widget' ); ?>
215
+
216
+ </option>
217
+ <option value="standard_resolution" <?php selected( $instance['image-resolution'], "standard_resolution" ); ?>>
218
+ <?php _e('Standard Resolution ( 640x640px )', 'wpzoom-instagram-widget' ); ?>
219
+ </option>
220
+ </select>
221
+ </p>
222
+ <p>
223
+ <input class="checkbox" type="checkbox" <?php checked( $instance['show-user-info'] ); ?> id="<?php echo $this->get_field_id( 'show-user-info' ); ?>" name="<?php echo $this->get_field_name( 'show-user-info' ); ?>" />
224
+ <label for="<?php echo $this->get_field_id( 'show-user-info' ); ?>"><?php _e(' Display <strong>User Details</strong>', 'wpzoom-instagram-widget' ); ?></label>
225
+ </p>
226
+
227
+ <p>
228
+ <input class="checkbox" type="checkbox" <?php checked( $instance['show-user-bio'] ); ?> id="<?php echo $this->get_field_id( 'show-user-bio' ); ?>" name="<?php echo $this->get_field_name( 'show-user-bio' ); ?>" />
229
+ <label for="<?php echo $this->get_field_id( 'show-user-bio' ); ?>"><?php _e(' Display <strong>Bio in User Details</strong>', 'wpzoom-instagram-widget' ); ?></label>
230
+ </p>
231
+
232
+ <p>
233
+ <input class="checkbox" type="checkbox" <?php checked( $instance['show-view-on-instagram-button'] ); ?> id="<?php echo $this->get_field_id( 'show-view-on-instagram-button' ); ?>" name="<?php echo $this->get_field_name( 'show-view-on-instagram-button' ); ?>" />
234
+ <label for="<?php echo $this->get_field_id( 'show-view-on-instagram-button' ); ?>"><?php _e(' Display <strong>View on Instagram</strong> button', 'wpzoom-instagram-widget' ); ?></label>
235
+ </p>
236
+
237
+ <p>
238
+ <input class="checkbox" type="checkbox" <?php checked( $instance['show-counts-on-hover'] ); ?> id="<?php echo $this->get_field_id( 'show-counts-on-hover' ); ?>" name="<?php echo $this->get_field_name( 'show-counts-on-hover' ); ?>" />
239
+ <label for="<?php echo $this->get_field_id( 'show-counts-on-hover' ); ?>"><?php _e(' Show <strong>overlay with number of comments and likes</strong> on hover', 'wpzoom-instagram-widget' ); ?></label>
240
+ </p>
241
+
242
+ <p>
243
+ <input class="checkbox" type="checkbox" <?php checked( $instance['lazy-load-images'] ); ?> id="<?php echo $this->get_field_id( 'lazy-load-images' ); ?>" name="<?php echo $this->get_field_name( 'lazy-load-images' ); ?>" />
244
+ <label for="<?php echo $this->get_field_id( 'lazy-load-images' ); ?>"><?php _e('Lazy Load <strong>images</strong>', 'wpzoom-instagram-widget' ); ?></label>
245
+ </p>
246
+ <p>
247
+ <input class="checkbox" type="checkbox" <?php checked( $instance['disable-video-thumbs'] ); ?> id="<?php echo $this->get_field_id( 'disable-video-thumbs' ); ?>" name="<?php echo $this->get_field_name( 'disable-video-thumbs' ); ?>" />
248
+ <label for="<?php echo $this->get_field_id( 'disable-video-thumbs' ); ?>"><?php _e('Hide video <strong>thumbnails</strong>', 'wpzoom-instagram-widget' ); ?></label>
249
+ </p>
250
+ <p>
251
+ <label for="<?php echo $this->get_field_id( 'button_text' ); ?>"><?php esc_html_e( 'Button Text:', 'wpzoom-instagram-widget' ); ?></label>
252
+ <input class="widefat" id="<?php echo $this->get_field_id( 'button_text' ); ?>" name="<?php echo $this->get_field_name( 'button_text' ); ?>" type="text" value="<?php echo esc_attr( $instance['button_text'] ); ?>"/>
253
+ </p>
254
+
255
+
256
+
257
+ <?php
258
+ }
259
+
260
+ protected function display_items( $items, $instance ) {
261
+ $count = 0;
262
+ $show_overlay = wp_validate_boolean($instance['show-counts-on-hover']);
263
+ $small_class = (!empty($instance['image-width']) && $instance['image-width'] <= 180) ? 'small' : '';
264
+ ?>
265
+ <ul class="zoom-instagram-widget__items zoom-instagram-widget__items--no-js"
266
+ data-images-per-row="<?php echo esc_attr( $instance['images-per-row'] ); ?>"
267
+ data-image-width="<?php echo esc_attr( $instance['image-width'] ); ?>"
268
+ data-image-spacing="<?php echo esc_attr( $instance['image-spacing'] ); ?>"
269
+ data-image-lazy-loading="<?php echo esc_attr( $instance['lazy-load-images'] ); ?>">
270
+
271
+ <?php foreach ( $items as $item ) : ?>
272
+ <?php
273
+ $link = $item['link'];
274
+ $src = $item['image-url'];
275
+ $alt = esc_attr($item['image-caption']);
276
+ $likes = $item['likes_count'];
277
+ $comments = $item['comments_count'];
278
+ ?>
279
+
280
+ <li class="zoom-instagram-widget__item">
281
+
282
+ <?php
283
+ $inline_style = 'width:'.esc_attr( $instance['image-width']).'px;';
284
+ $inline_style .= 'height:'.esc_attr( $instance['image-width']).'px;';
285
+ if(empty( $instance['lazy-load-images'] )){
286
+ $inline_style.= "background-image: url('".$src."');";
287
+ }
288
+
289
+ if($show_overlay):?>
290
+ <div class='hover-layout zoom-instagram-widget__overlay zoom-instagram-widget__black <?php echo $small_class?>'>
291
+
292
+ <div class='hover-controls'>
293
+ <span class="dashicons dashicons-heart"></span>
294
+ <span class="counter"><?php echo $this->format_number($likes); ?></span>
295
+ <span class="dashicons dashicons-format-chat"></span>
296
+ <span class="counter"><?php echo $this->format_number($comments); ?></span>
297
+ </div>
298
+ <div class='zoom-instagram-icon-wrap'>
299
+ <a class="zoom-svg-instagram-stroke" href="<?php echo $link; ?>" rel="noopener" target="_blank" title="<?php echo $alt; ?>"></a>
300
+ </div>
301
+
302
+
303
+ <a class='zoom-instagram-link' data-src="<?php echo $src; ?>" style="<?php echo $inline_style; ?>"
304
+ href="<?php echo $link; ?>" target="_blank" rel="noopener" title="<?php echo $alt; ?>"
305
+ >
306
+ </a>
307
+ </div>
308
+ <?php else: ?>
309
+ <a class='zoom-instagram-link' data-src="<?php echo $src; ?>" style="<?php echo $inline_style; ?>"
310
+ href="<?php echo $link; ?>" target="_blank" rel="noopener" title="<?php echo $alt; ?>"
311
+ >
312
+ </a>
313
+ <?php endif; ?>
314
+ </li>
315
+
316
+ <?php if ( ++$count === $instance['image-limit'] ) break; ?>
317
+
318
+ <?php endforeach; ?>
319
+
320
+ </ul>
321
+
322
+ <div style="clear:both;"></div>
323
+ <?php
324
+ }
325
+
326
+
327
+ protected function display_user_info( $instance, $user_info ) {
328
+ ?>
329
+ <div class="zoom-instagram-widget-user-info">
330
+ <?php if ( ! empty( $user_info->data->profile_picture ) ): ?>
331
+ <div class="zoom-instagram-widget-user-info-picture">
332
+ <a target="_blank" rel="noopener" href="<?php printf( 'http://instagram.com/%s?ref=badge', esc_attr( $user_info->data->username ) ); ?>"><img width="90" src="<?php echo $user_info->data->profile_picture ?>" alt="<?php echo esc_attr( $user_info->data->full_name ) ?>"/></a>
333
+ </div>
334
+ <?php endif; ?>
335
+ <div class="zoom-instagram-widget-user-info-meta">
336
+ <div class="zoom-instagram-widget-user-info-about-data">
337
+ <div class="zoom-instagram-widget-user-info-names-wrapper">
338
+ <?php if ( ! empty( $user_info->data->full_name ) ): ?>
339
+ <div class="zoom-instagram-widget-user-info-fullname">
340
+ <?php esc_html_e( $user_info->data->full_name ) ?>
341
+ </div>
342
+ <?php endif; ?>
343
+ <?php if ( ! empty( $user_info->data->username ) ): ?>
344
+ <div class="zoom-instagram-widget-user-info-username">
345
+ <?php esc_html_e( '@' . $user_info->data->username ) ?>
346
+ </div>
347
+ <?php endif; ?>
348
+ </div>
349
+ <div>
350
+ <a class="zoom-instagram-widget-user-info-follow-button" target="_blank" rel="noopener" href="<?php printf( 'http://instagram.com/%s?ref=badge', esc_attr( $user_info->data->username ) ); ?>">
351
+ <?php _e( 'Follow', 'wpzoom-instagram-widget' ) ?>
352
+ </a>
353
+ </div>
354
+ </div>
355
+ <div class="zoom-instagram-widget-user-info-stats">
356
+ <?php if ( ! empty( $user_info->data->counts->media ) ): ?>
357
+ <div>
358
+ <div class="zoom-instagram-widget-user-info-counts"
359
+ title="<?php echo number_format($user_info->data->counts->media)?>">
360
+ <?php echo $this->format_number($user_info->data->counts->media); ?>
361
+ </div>
362
+ <div class="zoom-instagram-widget-user-info-counts-subhead">
363
+ <?php _e( 'posts', 'wpzoom-instagram-widget' ); ?>
364
+ </div>
365
+ </div>
366
+ <?php endif; ?>
367
+ <?php if ( ! empty( $user_info->data->counts->followed_by ) ): ?>
368
+ <div class="zoom-instagram-widget-user-info-middle-cell">
369
+ <div class="zoom-instagram-widget-user-info-counts"
370
+ title="<?php echo number_format($user_info->data->counts->followed_by)?>">
371
+ <?php echo $this->format_number($user_info->data->counts->followed_by); ?>
372
+ </div>
373
+ <div class="zoom-instagram-widget-user-info-counts-subhead">
374
+ <?php _e( 'followers', 'wpzoom-instagram-widget' ); ?>
375
+ </div>
376
+ </div>
377
+ <?php endif; ?>
378
+ <?php if ( ! empty( $user_info->data->counts->follows ) ): ?>
379
+ <div>
380
+ <div class="zoom-instagram-widget-user-info-counts"
381
+ title="<?php echo number_format($user_info->data->counts->follows)?>">
382
+ <?php echo $this->format_number($user_info->data->counts->follows); ?>
383
+ </div>
384
+ <div class="zoom-instagram-widget-user-info-counts-subhead">
385
+ <?php _e( 'following', 'wpzoom-instagram-widget' ); ?>
386
+ </div>
387
+ </div>
388
+ <?php endif; ?>
389
+ </div>
390
+ </div>
391
+
392
+ </div>
393
+ <?php
394
+ if ( ! empty( $instance['show-user-bio'] ) ) {
395
+
396
+ if ( ! empty( $user_info->data->bio ) ): ?>
397
+ <div class="zoom-instagram-widget-user-info-bio"><?php echo nl2br( $user_info->data->bio ) ?></div>
398
+ <?php endif;
399
+
400
+ } ?>
401
+
402
+ <?php
403
+ }
404
+
405
+ public function format_number( $num ) {
406
+
407
+ if ( $num < 10000 ) {
408
+ return number_format( $num );
409
+ }
410
+
411
+ $units = array( '', 'k', 'm', 'b', 't' );
412
+ for ( $i = 0; $num >= 1000; $i ++ ) {
413
+ $num /= 1000;
414
+ }
415
+
416
+ return round( $num, 1 ) . $units[ $i ];
417
+ }
418
+
419
+ protected function display_instagram_button( $instance, $username) {
420
+ $show_view_on_instagram_button = $instance['show-view-on-instagram-button'];
421
+
422
+ if ( ! $show_view_on_instagram_button ) {
423
+ return;
424
+ }
425
+
426
+ ?>
427
+ <div class="zoom-instagram-widget__follow-me">
428
+ <a href="<?php printf( 'http://instagram.com/%s?ref=badge', esc_attr( $username ) ); ?>" class="ig-b- ig-b-v-24" rel="noopener" target="_blank"><?php echo esc_attr( $instance['button_text'] ); ?></a>
429
+ </div>
430
+ <?php
431
+ }
432
+
433
+ /**
434
+ * Output errors if widget is misconfigured and current user can manage options (plugin settings).
435
+ *
436
+ * @return void
437
+ */
438
+ protected function display_errors() {
439
+ if ( current_user_can( 'edit_theme_options' ) ) {
440
+ ?>
441
+ <p>
442
+ <?php _e( 'Instagram Widget misconfigured, check plugin &amp; widget settings.', 'wpzoom-instagram-widget' ); ?>
443
+ </p>
444
+ <?php
445
+ } else {
446
+ echo "&#8230;";
447
+ }
448
+ }
449
+ }
css/admin-instagram-widget.css ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .zoom-instagram-widget .button-connect {
2
+ /*height: auto;*/
3
+ /*padding: 9px 12px;*/
4
+ color: #fff;
5
+ border: 1px solid #1c5380;
6
+ border-radius: 3px;
7
+ background-color: #6f97b6;
8
+ background-image: -webkit-linear-gradient(top, #6f97b6, #3f729b);
9
+ background-image: linear-gradient(to bottom, #6f97b6, #3f729b);
10
+ background-position: 50% 50%;
11
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1), inset 1px 0 0 rgba(255, 255, 255, 0.05), inset -1px 0 0 rgba(255, 255, 255, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.2);
12
+ text-shadow: 0 1px 1px #1c5380;
13
+ }
14
+
15
+ .zoom-instagram-widget .button-connect:focus,
16
+ .zoom-instagram-widget .button-connect:hover {
17
+ border-color: #1c5380;
18
+ color: #fff;
19
+ background-image: -webkit-linear-gradient(top, #5D87A8, #3f729b);
20
+ background-image: linear-gradient(to bottom, #5D87A8, #3f729b);
21
+ }
22
+
23
+ .zoom-instagram-widget {
24
+ background: #fff;
25
+ padding: 30px;
26
+ border: 1px solid #DDD;
27
+ border-radius: 3px;
28
+ margin: 30px 10px 30px 0 !important;
29
+ box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
30
+ max-width: 700px;
31
+ }
32
+
33
+ .zoom-themes-link {
34
+ border: 1px solid #E2E9EC;
35
+ background: #F7FAFA url('../images/wpzoom.png') no-repeat center bottom;
36
+ padding: 30px 30px 260px 30px;
37
+ border-radius: 3px;
38
+ margin: 30px 0 30px 0 !important;
39
+ box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
40
+ max-width: 700px;
41
+ text-align: center;
42
+ }
43
+
44
+ .zoom-themes-link p {
45
+ font-size: 15px;
46
+ line-height: 1.6;
47
+ }
48
+
49
+ .cta-button {
50
+ text-align: center;
51
+ text-decoration: none;
52
+ color: #fff;
53
+ background: #3EBD3E;
54
+ padding: 10px 15px;
55
+ display: inline-block;
56
+ border-radius: 3px;
57
+ box-shadow: 0 -1px 1px rgba(0,0,0, 0.2) inset;
58
+ border: 1px solid #259425;
59
+ font-size: 16px;
60
+ text-shadow: 1px 1px rgba(0, 0, 0, 0.3);
61
+ }
62
+ .cta-button:hover {
63
+ background: #2A9B2A;
64
+ color: #fff;
65
+ }
66
+
67
+ #wpzoom-instagram-widget-settings_transient-lifetime-value{
68
+ max-width: 150px;
69
+ float: left;
70
+ }
71
+
72
+ #wpzoom-instagram-widget-settings_transient-lifetime-type{
73
+ float: left;
74
+ max-width: 100px;
75
+ }
css/instagram-widget.css ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Widget Grid */
2
+ .zoom-instagram-widget__follow-me { margin-top: 15px; text-align: center; }
3
+
4
+ .zoom-instagram-widget__items { list-style: none; }
5
+ .zoom-instagram-widget__item { float: left; position: relative; margin-top: 0 !important;}
6
+
7
+ .zoom-instagram-widget__items--no-js .zoom-instagram-widget__item { margin-right: 10px; margin-bottom: 10px; }
8
+
9
+
10
+ /* View on Instagram button */
11
+ .ig-b- {
12
+ display: inline-block;
13
+ }
14
+
15
+ a.ig-b-v-24 {
16
+ border-color: #3897f0;
17
+ color: #3897f0 !important;
18
+ border-radius: 3px;
19
+ border-style: solid;
20
+ border-width: 1px;
21
+ font-weight: 600 !important;
22
+ outline: none;
23
+ overflow: hidden;
24
+ white-space: nowrap;
25
+ -webkit-appearance: none;
26
+ font-family: sans-serif;
27
+ padding: 5px 15px;
28
+ font-size: 14px;
29
+ transition: all 0.15s ease-in-out;
30
+ -moz-transition: all 0.15s ease-in-out;
31
+ -webkit-transition: all 0.15s ease-in-out;
32
+ -webkit-font-smoothing: antialiased;
33
+ -moz-osx-font-smoothing: grayscale;
34
+ text-decoration: none !important;
35
+ }
36
+
37
+ a.ig-b-v-24:hover {
38
+ background: #3897f0;
39
+ border-color: #3897f0;
40
+ color: #ffffff !important;
41
+ }
42
+ .zoom-instagram-widget__item .hover-controls{
43
+ opacity: 0;
44
+ z-index: 9;
45
+ margin-top: -15px;
46
+ position: absolute;
47
+ top:40%;
48
+ width: 100%;
49
+ text-align: center;
50
+ transition: opacity 0.25s ease-in-out;
51
+ -moz-transition: opacity 0.25s ease-in-out;
52
+ -webkit-transition: opacity 0.25s ease-in-out;
53
+ }
54
+ .zoom-instagram-widget__item .zoom-instagram-icon-wrap{
55
+ width: 100%;
56
+ position: absolute;
57
+ bottom: 10%;
58
+ z-index: 9;
59
+ text-align: center;
60
+ }
61
+ .zoom-instagram-widget__item:hover .hover-controls{
62
+ opacity: 1;
63
+ }
64
+ .zoom-instagram-widget__item .zoom-instagram-icon-wrap{
65
+ opacity: 0;
66
+ transition: opacity 0.25s ease-in-out;
67
+ -moz-transition: opacity 0.25s ease-in-out;
68
+ -webkit-transition: opacity 0.25s ease-in-out;
69
+ }
70
+ .zoom-instagram-widget__item:hover .zoom-instagram-icon-wrap{
71
+ opacity: 1;
72
+ }
73
+ .zoom-instagram-widget__item .hover-controls .dashicons{
74
+ font-size: 20px;
75
+ width: 20px;
76
+ height: 20px;
77
+ color: #FFFFFF;
78
+ vertical-align: middle;
79
+ }
80
+ .zoom-instagram-widget__item .hover-controls .counter{
81
+ padding-left: 1px;
82
+ padding-right: 12px;
83
+ font-weight: 500;
84
+ color: #FFFFFF;
85
+ font-size: 14px;
86
+ opacity: .8;
87
+ font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
88
+ }
89
+
90
+ .zoom-instagram-widget__overlay {
91
+ position: relative;
92
+ }
93
+
94
+ .zoom-instagram-widget__overlay:after {
95
+ position: absolute;
96
+ content:"";
97
+ top:0;
98
+ left:0;
99
+ width:100%;
100
+ height:100%;
101
+ opacity:0;
102
+ transition: opacity 0.25s ease-in-out;
103
+ -moz-transition: opacity 0.25s ease-in-out;
104
+ -webkit-transition: opacity 0.25s ease-in-out;
105
+ }
106
+
107
+ .zoom-instagram-widget__overlay:hover:after {
108
+ opacity: 0.7;
109
+ background-color: #000000;
110
+ }
111
+
112
+ .zoom-instagram-widget__black:after {
113
+ background-color: #000000;
114
+ }
115
+
116
+ .zoom-svg-instagram-simple {
117
+ display: inline-block;
118
+ width: 30px;
119
+ height: 30px;
120
+ background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjBweCIgeT0iMHB4IgogICAgIHdpZHRoPSI1MCIgaGVpZ2h0PSI1MCIKICAgICB2aWV3Qm94PSIwIDAgNTAgNTAiCiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjsiPiAgICA8cGF0aCBzdHlsZT0ibGluZS1oZWlnaHQ6bm9ybWFsO3RleHQtaW5kZW50OjA7dGV4dC1hbGlnbjpzdGFydDt0ZXh0LWRlY29yYXRpb24tbGluZTpub25lO3RleHQtZGVjb3JhdGlvbi1zdHlsZTpzb2xpZDt0ZXh0LWRlY29yYXRpb24tY29sb3I6IzAwMDt0ZXh0LXRyYW5zZm9ybTpub25lO2Jsb2NrLXByb2dyZXNzaW9uOnRiO2lzb2xhdGlvbjphdXRvO21peC1ibGVuZC1tb2RlOm5vcm1hbCIgZD0iTSAxNiAzIEMgOC44MzI0ODM5IDMgMyA4LjgzMjQ4MzkgMyAxNiBMIDMgMzQgQyAzIDQxLjE2NzUxNiA4LjgzMjQ4MzkgNDcgMTYgNDcgTCAzNCA0NyBDIDQxLjE2NzUxNiA0NyA0NyA0MS4xNjc1MTYgNDcgMzQgTCA0NyAxNiBDIDQ3IDguODMyNDgzOSA0MS4xNjc1MTYgMyAzNCAzIEwgMTYgMyB6IE0gMTYgNSBMIDM0IDUgQyA0MC4wODY0ODQgNSA0NSA5LjkxMzUxNjEgNDUgMTYgTCA0NSAzNCBDIDQ1IDQwLjA4NjQ4NCA0MC4wODY0ODQgNDUgMzQgNDUgTCAxNiA0NSBDIDkuOTEzNTE2MSA0NSA1IDQwLjA4NjQ4NCA1IDM0IEwgNSAxNiBDIDUgOS45MTM1MTYxIDkuOTEzNTE2MSA1IDE2IDUgeiBNIDM3IDExIEEgMiAyIDAgMCAwIDM1IDEzIEEgMiAyIDAgMCAwIDM3IDE1IEEgMiAyIDAgMCAwIDM5IDEzIEEgMiAyIDAgMCAwIDM3IDExIHogTSAyNSAxNCBDIDE4LjkzNjcxMiAxNCAxNCAxOC45MzY3MTIgMTQgMjUgQyAxNCAzMS4wNjMyODggMTguOTM2NzEyIDM2IDI1IDM2IEMgMzEuMDYzMjg4IDM2IDM2IDMxLjA2MzI4OCAzNiAyNSBDIDM2IDE4LjkzNjcxMiAzMS4wNjMyODggMTQgMjUgMTQgeiBNIDI1IDE2IEMgMjkuOTgyNDA3IDE2IDM0IDIwLjAxNzU5MyAzNCAyNSBDIDM0IDI5Ljk4MjQwNyAyOS45ODI0MDcgMzQgMjUgMzQgQyAyMC4wMTc1OTMgMzQgMTYgMjkuOTgyNDA3IDE2IDI1IEMgMTYgMjAuMDE3NTkzIDIwLjAxNzU5MyAxNiAyNSAxNiB6IiBmb250LXdlaWdodD0iNDAwIiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgd2hpdGUtc3BhY2U9Im5vcm1hbCIgb3ZlcmZsb3c9InZpc2libGUiPjwvcGF0aD48L3N2Zz4=') 50% 50% no-repeat;
121
+ background-size: 100%;
122
+ }
123
+
124
+ .zoom-svg-instagram-stroke {
125
+ display: inline-block;
126
+ width: 30px;
127
+ height: 30px;
128
+ background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjBweCIgeT0iMHB4IgogICAgIHdpZHRoPSI1MCIgaGVpZ2h0PSI1MCIKICAgICB2aWV3Qm94PSIwIDAgMjUyIDI1MiIKICAgICBzdHlsZT0iZmlsbDojMDAwMDAwOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMi4zOTQsMi4zOTQpIHNjYWxlKDAuOTgxLDAuOTgxKSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJub256ZXJvIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiIHN0cm9rZS1saW5lam9pbj0ibm9uZSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtZGFzaGFycmF5PSIiIHN0cm9rZS1kYXNob2Zmc2V0PSIwIiBmb250LWZhbWlseT0ibm9uZSIgZm9udC13ZWlnaHQ9Im5vbmUiIGZvbnQtc2l6ZT0ibm9uZSIgdGV4dC1hbmNob3I9Im5vbmUiIHN0eWxlPSJtaXgtYmxlbmQtbW9kZTogbm9ybWFsIj48ZyBpZD0ib3JpZ2luYWwtaWNvbiAxIiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iNSIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTE3MS4zNiwxNS4xMmMzNi4xMjQyOCwwIDY1LjUyLDI5LjM5NTcyIDY1LjUyLDY1LjUydjkwLjcyYzAsMzYuMTI0MjggLTI5LjM5NTcyLDY1LjUyIC02NS41Miw2NS41MmgtOTAuNzJjLTM2LjEyNDI4LDAgLTY1LjUyLC0yOS4zOTU3MiAtNjUuNTIsLTY1LjUydi05MC43MmMwLC0zNi4xMjQyOCAyOS4zOTU3MiwtNjUuNTIgNjUuNTIsLTY1LjUyek0yNS4yLDgwLjY0djkwLjcyYzAsMzAuNjc1ODggMjQuNzY0MTIsNTUuNDQgNTUuNDQsNTUuNDRoOTAuNzJjMzAuNjc1ODgsMCA1NS40NCwtMjQuNzY0MTIgNTUuNDQsLTU1LjQ0di05MC43MmMwLC0zMC42NzU4OCAtMjQuNzY0MTIsLTU1LjQ0IC01NS40NCwtNTUuNDRoLTkwLjcyYy0zMC42NzU4OCwwIC01NS40NCwyNC43NjQxMiAtNTUuNDQsNTUuNDR6TTE5Ni41Niw2NS41MmMwLDUuNTY3MDMgLTQuNTEyOTcsMTAuMDggLTEwLjA4LDEwLjA4Yy01LjU2NzAzLDAgLTEwLjA4LC00LjUxMjk3IC0xMC4wOCwtMTAuMDhjMCwtNS41NjcwMyA0LjUxMjk3LC0xMC4wOCAxMC4wOCwtMTAuMDhjNS41NjcwMywwIDEwLjA4LDQuNTEyOTcgMTAuMDgsMTAuMDh6TTE4MS40NCwxMjZjMCwzMC41NTg5NyAtMjQuODgxMDMsNTUuNDQgLTU1LjQ0LDU1LjQ0Yy0zMC41NTg5NywwIC01NS40NCwtMjQuODgxMDMgLTU1LjQ0LC01NS40NGMwLC0zMC41NTg5NyAyNC44ODEwMywtNTUuNDQgNTUuNDQsLTU1LjQ0YzMwLjU1ODk3LDAgNTUuNDQsMjQuODgxMDMgNTUuNDQsNTUuNDR6TTgwLjY0LDEyNmMwLDI1LjExMTMzIDIwLjI0ODY3LDQ1LjM2IDQ1LjM2LDQ1LjM2YzI1LjExMTMzLDAgNDUuMzYsLTIwLjI0ODY3IDQ1LjM2LC00NS4zNmMwLC0yNS4xMTEzMyAtMjAuMjQ4NjcsLTQ1LjM2IC00NS4zNiwtNDUuMzZjLTI1LjExMTMzLDAgLTQ1LjM2LDIwLjI0ODY3IC00NS4zNiw0NS4zNnoiPjwvcGF0aD48L2c+PHBhdGggZD0iTTAsMjUydi0yNTJoMjUydjI1MnoiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBzdHJva2UtbGluZWpvaW49Im1pdGVyIj48L3BhdGg+PGcgaWQ9Im9yaWdpbmFsLWljb24iIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBzdHJva2UtbGluZWpvaW49Im1pdGVyIj48cGF0aCBkPSJNODAuNjQsMTUuMTJjLTM2LjEyNDI4LDAgLTY1LjUyLDI5LjM5NTcyIC02NS41Miw2NS41MnY5MC43MmMwLDM2LjEyNDI4IDI5LjM5NTcyLDY1LjUyIDY1LjUyLDY1LjUyaDkwLjcyYzM2LjEyNDI4LDAgNjUuNTIsLTI5LjM5NTcyIDY1LjUyLC02NS41MnYtOTAuNzJjMCwtMzYuMTI0MjggLTI5LjM5NTcyLC02NS41MiAtNjUuNTIsLTY1LjUyek04MC42NCwyNS4yaDkwLjcyYzMwLjY3NTg4LDAgNTUuNDQsMjQuNzY0MTIgNTUuNDQsNTUuNDR2OTAuNzJjMCwzMC42NzU4OCAtMjQuNzY0MTIsNTUuNDQgLTU1LjQ0LDU1LjQ0aC05MC43MmMtMzAuNjc1ODgsMCAtNTUuNDQsLTI0Ljc2NDEyIC01NS40NCwtNTUuNDR2LTkwLjcyYzAsLTMwLjY3NTg4IDI0Ljc2NDEyLC01NS40NCA1NS40NCwtNTUuNDR6TTE4Ni40OCw1NS40NGMtNS41NjcwMywwIC0xMC4wOCw0LjUxMjk3IC0xMC4wOCwxMC4wOGMwLDUuNTY3MDMgNC41MTI5NywxMC4wOCAxMC4wOCwxMC4wOGM1LjU2NzAzLDAgMTAuMDgsLTQuNTEyOTcgMTAuMDgsLTEwLjA4YzAsLTUuNTY3MDMgLTQuNTEyOTcsLTEwLjA4IC0xMC4wOCwtMTAuMDh6TTEyNiw3MC41NmMtMzAuNTU4OTcsMCAtNTUuNDQsMjQuODgxMDMgLTU1LjQ0LDU1LjQ0YzAsMzAuNTU4OTcgMjQuODgxMDMsNTUuNDQgNTUuNDQsNTUuNDRjMzAuNTU4OTcsMCA1NS40NCwtMjQuODgxMDMgNTUuNDQsLTU1LjQ0YzAsLTMwLjU1ODk3IC0yNC44ODEwMywtNTUuNDQgLTU1LjQ0LC01NS40NHpNMTI2LDgwLjY0YzI1LjExMTMzLDAgNDUuMzYsMjAuMjQ4NjcgNDUuMzYsNDUuMzZjMCwyNS4xMTEzMyAtMjAuMjQ4NjcsNDUuMzYgLTQ1LjM2LDQ1LjM2Yy0yNS4xMTEzMywwIC00NS4zNiwtMjAuMjQ4NjcgLTQ1LjM2LC00NS4zNmMwLC0yNS4xMTEzMyAyMC4yNDg2NywtNDUuMzYgNDUuMzYsLTQ1LjM2eiI+PC9wYXRoPjwvZz48cGF0aCBkPSJNMTI2LDI1MmMtNjkuNTg3ODgsMCAtMTI2LC01Ni40MTIxMiAtMTI2LC0xMjZ2MGMwLC02OS41ODc4OCA1Ni40MTIxMiwtMTI2IDEyNiwtMTI2djBjNjkuNTg3ODgsMCAxMjYsNTYuNDEyMTIgMTI2LDEyNnYwYzAsNjkuNTg3ODggLTU2LjQxMjEyLDEyNiAtMTI2LDEyNnoiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBzdHJva2UtbGluZWpvaW49Im1pdGVyIj48L3BhdGg+PHBhdGggZD0iTTEyNiwyNDYuOTZjLTY2LjgwNDM2LDAgLTEyMC45NiwtNTQuMTU1NjQgLTEyMC45NiwtMTIwLjk2djBjMCwtNjYuODA0MzYgNTQuMTU1NjQsLTEyMC45NiAxMjAuOTYsLTEyMC45NmgwYzY2LjgwNDM2LDAgMTIwLjk2LDU0LjE1NTY0IDEyMC45NiwxMjAuOTZ2MGMwLDY2LjgwNDM2IC01NC4xNTU2NCwxMjAuOTYgLTEyMC45NiwxMjAuOTZ6IiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciI+PC9wYXRoPjxwYXRoIGQ9IiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiPjwvcGF0aD48cGF0aCBkPSIiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBzdHJva2UtbGluZWpvaW49Im1pdGVyIj48L3BhdGg+PHBhdGggZD0iIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciI+PC9wYXRoPjxwYXRoIGQ9IiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiPjwvcGF0aD48L2c+PC9nPjwvc3ZnPg==') 50% 50% no-repeat;
129
+ background-size: 100%;
130
+ }
131
+
132
+ .zoom-instagram-widget__item .hover-layout.small .hover-controls .dashicons{
133
+ font-size: 15px;
134
+ width: 15px;
135
+ height: 15px;
136
+ }
137
+
138
+ .zoom-instagram-widget__item .hover-layout.small .zoom-instagram-icon-wrap .zoom-svg-instagram-stroke{
139
+ width: 18px;
140
+ height: 18px;
141
+ }
142
+ .zoom-instagram-widget__item .hover-layout.small .zoom-instagram-icon-wrap{
143
+ bottom: 6%;
144
+ }
145
+
146
+ .zoom-instagram-widget__item .hover-layout.small .hover-controls .counter{
147
+ padding-left: 1px;
148
+ padding-right: 4px;
149
+ font-size: 11px;
150
+ }
151
+
152
+ /** Instagram user info **/
153
+
154
+ .zoom-instagram-widget-user-info {
155
+ display: flex;
156
+ padding: 0 0px 20px;
157
+ /*justify-content: space-between;*/
158
+ }
159
+
160
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-picture {
161
+ flex: 1;
162
+ }
163
+
164
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-picture img {
165
+ border-radius: 50%;
166
+ }
167
+
168
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-meta {
169
+ display: flex;
170
+ flex: 3;
171
+ flex-direction: column;
172
+ margin-left: 15px;
173
+ text-align: left;
174
+ }
175
+
176
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-about-data {
177
+
178
+ display: flex;
179
+ justify-content: space-between;
180
+ margin-bottom: 10px;
181
+
182
+ }
183
+
184
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-stats{
185
+ font-size: 14px;
186
+ line-height: 1.2;
187
+ justify-content: space-between;
188
+ display: flex;
189
+ text-align: center;
190
+ }
191
+
192
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-follow-button {
193
+ padding: 0px 24px;
194
+ margin-top: 10px;
195
+ background: #3897f0;
196
+ color: #fff !important;
197
+ font-size: 14px;
198
+ font-weight: 600;
199
+ line-height: 26px;
200
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
201
+ text-transform: none;
202
+ border-radius: 3px;
203
+ outline: 0;
204
+ overflow: hidden;
205
+ text-overflow: ellipsis;
206
+ display: block;
207
+ border: none;
208
+ box-shadow: none;
209
+ text-decoration: none !important;
210
+ }
211
+
212
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-follow-button:hover {
213
+ color: #fff;
214
+ opacity: .8;
215
+ box-shadow: none;
216
+ border: none;
217
+ text-decoration: none;
218
+ }
219
+
220
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-counts{
221
+ font-weight: 600;
222
+ }
223
+
224
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-counts-subhead{
225
+ /*color: #999;*/
226
+ opacity: .7;
227
+ font-size: 14px;
228
+ }
229
+
230
+ .zoom-instagram-widget-user-info-grey-color{
231
+ /*color: #b0b0b0;*/
232
+ }
233
+ .zoom-instagram-widget-user-info-middle-cell{
234
+ padding: 0px 20px;
235
+ }
236
+
237
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-fullname{
238
+ font-weight: 600;
239
+ font-size: 16px;
240
+ }
241
+
242
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-names-wrapper{
243
+ padding-right: 20px;
244
+ word-break: break-word;
245
+ }
246
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-username{
247
+ font-size: 14px;
248
+ font-weight: 600;
249
+ word-break: break-all;
250
+ opacity: .7;
251
+ }
252
+
253
+ .zoom-instagram-widget-user-info-bio {
254
+ text-align: left;
255
+ font-size: 14px;
256
+ margin: 0 0 15px;
257
+ }
258
+
259
+ .zoom-instagram-widget-user-info .zoom-instagram-widget-user-info-fullname{
260
+ /*color: #262626;*/
261
+ }
262
+
263
+ .zoom-instagram-widget__items .zoom-instagram-widget__item .zoom-instagram-link{
264
+ display: block;
265
+ background-size: cover;
266
+ background-position: center center;
267
+ background-repeat: no-repeat
268
+ }
images/wpzoom.png ADDED
Binary file
instagram-widget-by-wpzoom.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Plugin Name: WPZOOM Social Feed Widget
5
+ * Plugin URI: https://www.wpzoom.com/plugins/instagram-widget/
6
+ * Description: Simple and responsive widget for WordPress to display your Instagram feed
7
+ * Author: WPZOOM
8
+ * Author URI: https://www.wpzoom.com/
9
+ * Version: 1.4.4
10
+ * License: GPLv2 or later
11
+ */
12
+
13
+ require_once( plugin_dir_path( __FILE__ ) . 'class-wpzoom-instagram-widget-api.php' );
14
+ require_once( plugin_dir_path( __FILE__ ) . 'class-wpzoom-instagram-widget-settings.php' );
15
+ require_once( plugin_dir_path( __FILE__ ) . 'class-wpzoom-instagram-widget.php' );
16
+
17
+ add_action( 'widgets_init', 'zoom_instagram_widget_register' );
18
+ function zoom_instagram_widget_register() {
19
+ register_widget( 'Wpzoom_Instagram_Widget' );
20
+ }
21
+
22
+ /* Display a notice that can be dismissed */
23
+
24
+ add_action('admin_notices', 'wpzoom_instagram_admin_notice');
25
+
26
+ function wpzoom_instagram_admin_notice() {
27
+ global $current_user ;
28
+ $user_id = $current_user->ID;
29
+ /* Check that the user hasn't already clicked to ignore the message */
30
+ if ( ! get_user_meta($user_id, 'wpzoom_instagram_admin_notice') ) {
31
+ echo '<div class="error notice" style="position:relative"><p>';
32
+ printf(__('<strong>Please configure Instagram Widget</strong><br /><br/> If you have just installed or updated this plugin, please go to the <a href="options-general.php?page=wpzoom-instagram-widget">Settings page</a> and <strong>connect</strong> it with your Instagram account.<br/> You can ignore this message if you have already configured it. <a style="text-decoration: none" class="notice-dismiss" href="%1$s"></a>'), '?wpzoom_instagram_ignore_admin_notice=0');
33
+ echo "</p></div>";
34
+ }
35
+ }
36
+
37
+ add_action('admin_init', 'wpzoom_instagram_ignore_admin_notice');
38
+
39
+ function wpzoom_instagram_ignore_admin_notice() {
40
+ global $current_user;
41
+ $user_id = $current_user->ID;
42
+ /* If user clicks to ignore the notice, add that to their user meta */
43
+ if ( isset($_GET['wpzoom_instagram_ignore_admin_notice']) && '0' == $_GET['wpzoom_instagram_ignore_admin_notice'] ) {
44
+ add_user_meta($user_id, 'wpzoom_instagram_admin_notice', 'true', true);
45
+ }
46
+ }
js/admin-instagram-widget.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use strict';
2
+
3
+ jQuery(function($) {
4
+
5
+ $('.wpzoom-instagram-widget-settins-request-type-wrapper').find('input[type=radio]').on('change', function (e) {
6
+ e.preventDefault();
7
+
8
+ var activeClass = $(this).val();
9
+ var oposite = activeClass == 'with-access-token' ? 'without-access-token' : 'with-access-token';
10
+
11
+ $(this).closest('.form-table').find('.wpzoom-instagram-widget-' + activeClass + '-group').show();
12
+ $(this).closest('.form-table').find('.wpzoom-instagram-widget-' + oposite + '-group').hide();
13
+
14
+
15
+ });
16
+
17
+ $('.wpzoom-instagram-widget-settins-request-type-wrapper').find('input[type=radio]:checked').change();
18
+
19
+ var hash = window.location.hash;
20
+
21
+ if (hash.indexOf('access_token') > 0) {
22
+ var input = $('#wpzoom-instagram-widget-settings_access-token');
23
+
24
+ input.val(hash.split('=').pop());
25
+
26
+ input.closest('.form-table').find('input[type=radio]').removeAttr('checked');
27
+
28
+ var $radio = input.closest('.form-table').find('#wpzoom-instagram-widget-settings_with-access-token');
29
+ $radio.prop('checked', true);
30
+ $radio.trigger('change');
31
+
32
+ input.parents('form').find('#submit').click();
33
+ }
34
+
35
+ $('.zoom-instagram-widget .button-connect').on('click', function(event) {
36
+ if ($(this).find('.zoom-instagarm-widget-connected').length) {
37
+ var confirm = window.confirm(zoom_instagram_widget_admin.i18n_connect_confirm);
38
+
39
+ if (!confirm) {
40
+ event.preventDefault();
41
+ }
42
+ }
43
+ });
44
+
45
+
46
+ });
js/instagram-widget.js ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function($) {
2
+ var ticking = false;
3
+
4
+ $.fn.zoomInstagramWidget = function () {
5
+ return $(this).each(function () {
6
+ var $list = $(this);
7
+
8
+ var minItemsPerRow = $list.data('images-per-row');
9
+ var desiredItemWidth = $list.data('image-width');
10
+ var itemSpacing = $list.data('image-spacing');
11
+ var imageLazyLoading = $list.data('image-lazy-loading');
12
+
13
+ var containerWidth = $list.width();
14
+
15
+ var fitPerRow;
16
+ var itemWidth;
17
+
18
+ if (containerWidth / desiredItemWidth < minItemsPerRow) {
19
+ fitPerRow = minItemsPerRow;
20
+ itemWidth = Math.floor((containerWidth - 1 - (minItemsPerRow - 1) * itemSpacing) / minItemsPerRow);
21
+ } else {
22
+ fitPerRow = Math.floor((containerWidth - 1) / desiredItemWidth);
23
+ itemWidth = Math.floor((containerWidth - 1 - (fitPerRow - 1) * itemSpacing) / fitPerRow);
24
+ }
25
+
26
+ $list.find('li').each(function(i) {
27
+ if ( ++i % fitPerRow == 0 ) {
28
+ $(this).css('margin-right', '0');
29
+ } else {
30
+ $(this).css('margin-right', itemSpacing + 'px');
31
+ $(this).css('margin-bottom', itemSpacing + 'px');
32
+ }
33
+ });
34
+
35
+ $list.find('a.zoom-instagram-link').css({
36
+ width: itemWidth,
37
+ height: itemWidth
38
+ });
39
+
40
+ if (imageLazyLoading) {
41
+ $list.find('a.zoom-instagram-link').lazy();
42
+ }
43
+
44
+ $list.removeClass('zoom-instagram-widget__items--no-js');
45
+ });
46
+ };
47
+
48
+ function requestTick() {
49
+ if (!ticking) {
50
+ ticking = true;
51
+ requestAnimationFrame()(update);
52
+ }
53
+ }
54
+
55
+ function requestAnimationFrame() {
56
+ return window.requestAnimationFrame ||
57
+ window.webkitRequestAnimationFrame ||
58
+ window.mozRequestAnimationFrame ||
59
+ function (callback){
60
+ window.setTimeout(callback, 1000 / 60);
61
+ };
62
+ }
63
+
64
+ function update() {
65
+ $('.zoom-instagram-widget__items').zoomInstagramWidget();
66
+ ticking = false;
67
+ }
68
+
69
+ $(window).on('resize orientationchange', requestTick);
70
+ requestTick();
71
+ });
js/jquery.lazy.min.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ /*! jQuery & Zepto Lazy v1.7.10 - http://jquery.eisbehr.de/lazy - MIT&GPL-2.0 license - Copyright 2012-2018 Daniel 'Eisbehr' Kern */
2
+ !function(t,e){"use strict";function r(r,a,i,u,l){function f(){L=t.devicePixelRatio>1,i=c(i),a.delay>=0&&setTimeout(function(){s(!0)},a.delay),(a.delay<0||a.combined)&&(u.e=v(a.throttle,function(t){"resize"===t.type&&(w=B=-1),s(t.all)}),u.a=function(t){t=c(t),i.push.apply(i,t)},u.g=function(){return i=n(i).filter(function(){return!n(this).data(a.loadedName)})},u.f=function(t){for(var e=0;e<t.length;e++){var r=i.filter(function(){return this===t[e]});r.length&&s(!1,r)}},s(),n(a.appendScroll).on("scroll."+l+" resize."+l,u.e))}function c(t){var i=a.defaultImage,o=a.placeholder,u=a.imageBase,l=a.srcsetAttribute,f=a.loaderAttribute,c=a._f||{};t=n(t).filter(function(){var t=n(this),r=m(this);return!t.data(a.handledName)&&(t.attr(a.attribute)||t.attr(l)||t.attr(f)||c[r]!==e)}).data("plugin_"+a.name,r);for(var s=0,d=t.length;s<d;s++){var A=n(t[s]),g=m(t[s]),h=A.attr(a.imageBaseAttribute)||u;g===N&&h&&A.attr(l)&&A.attr(l,b(A.attr(l),h)),c[g]===e||A.attr(f)||A.attr(f,c[g]),g===N&&i&&!A.attr(E)?A.attr(E,i):g===N||!o||A.css(O)&&"none"!==A.css(O)||A.css(O,"url('"+o+"')")}return t}function s(t,e){if(!i.length)return void(a.autoDestroy&&r.destroy());for(var o=e||i,u=!1,l=a.imageBase||"",f=a.srcsetAttribute,c=a.handledName,s=0;s<o.length;s++)if(t||e||A(o[s])){var g=n(o[s]),h=m(o[s]),b=g.attr(a.attribute),v=g.attr(a.imageBaseAttribute)||l,p=g.attr(a.loaderAttribute);g.data(c)||a.visibleOnly&&!g.is(":visible")||!((b||g.attr(f))&&(h===N&&(v+b!==g.attr(E)||g.attr(f)!==g.attr(F))||h!==N&&v+b!==g.css(O))||p)||(u=!0,g.data(c,!0),d(g,h,v,p))}u&&(i=n(i).filter(function(){return!n(this).data(c)}))}function d(t,e,r,i){++z;var o=function(){y("onError",t),p(),o=n.noop};y("beforeLoad",t);var u=a.attribute,l=a.srcsetAttribute,f=a.sizesAttribute,c=a.retinaAttribute,s=a.removeAttribute,d=a.loadedName,A=t.attr(c);if(i){var g=function(){s&&t.removeAttr(a.loaderAttribute),t.data(d,!0),y(T,t),setTimeout(p,1),g=n.noop};t.off(I).one(I,o).one(D,g),y(i,t,function(e){e?(t.off(D),g()):(t.off(I),o())})||t.trigger(I)}else{var h=n(new Image);h.one(I,o).one(D,function(){t.hide(),e===N?t.attr(C,h.attr(C)).attr(F,h.attr(F)).attr(E,h.attr(E)):t.css(O,"url('"+h.attr(E)+"')"),t[a.effect](a.effectTime),s&&(t.removeAttr(u+" "+l+" "+c+" "+a.imageBaseAttribute),f!==C&&t.removeAttr(f)),t.data(d,!0),y(T,t),h.remove(),p()});var m=(L&&A?A:t.attr(u))||"";h.attr(C,t.attr(f)).attr(F,t.attr(l)).attr(E,m?r+m:null),h.complete&&h.trigger(D)}}function A(t){var e=t.getBoundingClientRect(),r=a.scrollDirection,n=a.threshold,i=h()+n>e.top&&-n<e.bottom,o=g()+n>e.left&&-n<e.right;return"vertical"===r?i:"horizontal"===r?o:i&&o}function g(){return w>=0?w:w=n(t).width()}function h(){return B>=0?B:B=n(t).height()}function m(t){return t.tagName.toLowerCase()}function b(t,e){if(e){var r=t.split(",");t="";for(var a=0,n=r.length;a<n;a++)t+=e+r[a].trim()+(a!==n-1?",":"")}return t}function v(t,e){var n,i=0;return function(o,u){function l(){i=+new Date,e.call(r,o)}var f=+new Date-i;n&&clearTimeout(n),f>t||!a.enableThrottle||u?l():n=setTimeout(l,t-f)}}function p(){--z,i.length||z||y("onFinishedAll")}function y(t,e,n){return!!(t=a[t])&&(t.apply(r,[].slice.call(arguments,1)),!0)}var z=0,w=-1,B=-1,L=!1,T="afterLoad",D="load",I="error",N="img",E="src",F="srcset",C="sizes",O="background-image";"event"===a.bind||o?f():n(t).on(D+"."+l,f)}function a(a,o){var u=this,l=n.extend({},u.config,o),f={},c=l.name+"-"+ ++i;return u.config=function(t,r){return r===e?l[t]:(l[t]=r,u)},u.addItems=function(t){return f.a&&f.a("string"===n.type(t)?n(t):t),u},u.getItems=function(){return f.g?f.g():{}},u.update=function(t){return f.e&&f.e({},!t),u},u.force=function(t){return f.f&&f.f("string"===n.type(t)?n(t):t),u},u.loadAll=function(){return f.e&&f.e({all:!0},!0),u},u.destroy=function(){return n(l.appendScroll).off("."+c,f.e),n(t).off("."+c),f={},e},r(u,l,a,f,c),l.chainable?a:u}var n=t.jQuery||t.Zepto,i=0,o=!1;n.fn.Lazy=n.fn.lazy=function(t){return new a(this,t)},n.Lazy=n.lazy=function(t,r,i){if(n.isFunction(r)&&(i=r,r=[]),n.isFunction(i)){t=n.isArray(t)?t:[t],r=n.isArray(r)?r:[r];for(var o=a.prototype.config,u=o._f||(o._f={}),l=0,f=t.length;l<f;l++)(o[t[l]]===e||n.isFunction(o[t[l]]))&&(o[t[l]]=i);for(var c=0,s=r.length;c<s;c++)u[r[c]]=t[0]}},a.prototype.config={name:"lazy",chainable:!0,autoDestroy:!0,bind:"load",threshold:500,visibleOnly:!1,appendScroll:t,scrollDirection:"both",imageBase:null,defaultImage:"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==",placeholder:null,delay:-1,combined:!1,attribute:"data-src",srcsetAttribute:"data-srcset",sizesAttribute:"data-sizes",retinaAttribute:"data-retina",loaderAttribute:"data-loader",imageBaseAttribute:"data-imagebase",removeAttribute:!0,handledName:"handled",loadedName:"loaded",effect:"show",effectTime:0,enableThrottle:!0,throttle:250,beforeLoad:e,afterLoad:e,onError:e,onFinishedAll:e},n(t).on("load",function(){o=!0})}(window);
readme.txt ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === WPZOOM Social Feed Widget ===
2
+ Contributors: WPZOOM, nvartolomei, ciorici
3
+ Donate link: https://www.wpzoom.com/
4
+ Tags: instagram, widget, timeline, social network, latest images, feed, instagram feed, story, stories, insta, instagram widget
5
+ Requires at least: 4.3
6
+ Tested up to: 5.2
7
+ Requires PHP: 5.6
8
+ Stable tag: trunk
9
+ License: GPLv2 or later
10
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
+
12
+ Formerly known as "Instagram Widget by WPZOOM". Fully customisable and responsive widget for WordPress to display your Instagram feed.
13
+
14
+ == Description ==
15
+
16
+ Formerly known as *Instagram Widget by WPZOOM*, **WPZOOM Social Feed Widget** is a fully customisable and responsive widget for WordPress to display your **Instagram feed**.
17
+
18
+
19
+ **[View Demo](http://demo.wpzoom.com/instagram-widget/)**
20
+
21
+
22
+ > Did you find this plugin helpful? Please consider [leaving a 5-star review](https://wordpress.org/support/view/plugin-reviews/instagram-widget-by-wpzoom).
23
+
24
+
25
+ **WPZOOM Social Feed Widget** gives you a WordPress Widget that you can place anywhere you want and be able to fully customize it's design using CSS.
26
+
27
+
28
+ = What's New in version 1.4? =
29
+
30
+ You can now display a public feed limited to 12 photos of any Instagram account you want. You are no longer limited to display just your own feed.
31
+
32
+
33
+ = Where I can view a Demo? =
34
+
35
+ You can view the widget live in all our themes at [WPZOOM](http://www.wpzoom.com/themes/).
36
+
37
+
38
+ = Get Involved =
39
+
40
+ Looking to contribute code to this plugin? Go ahead and [fork the repository over at GitHub](https://github.com/wpzoom/instagram-widget/).
41
+
42
+ == Installation ==
43
+
44
+ Simply search for the plugin via the **Plugins -> Add New** dialog and click install, or download and extract the plugin, and copy the plugin folder into your wp-content/plugins directory and activate.
45
+
46
+ After installation go to the **Settings > Instagram Widget** page and connect the plugin with your Instagram account.
47
+
48
+ Once connected, go to the **Widgets** page and add the widget **Instagram Widget by WPZOOM** to a widget area like Sidebar.
49
+
50
+
51
+
52
+ == Frequently Asked Questions ==
53
+
54
+ = I just installed plugin and widget shows nothing =
55
+
56
+ Make sure to connect your Instagram account with the plugin. You can do that in the **Settings > Instagram Widget** page from the Dashboard.
57
+
58
+
59
+ == Screenshots ==
60
+
61
+ 1. Examples of how the widget can be used
62
+ 2. More examples
63
+ 3. Perfect for Sidebar or Footer column
64
+ 4. Customized button using CSS
65
+ 5. Settings
66
+
67
+
68
+ == Changelog ==
69
+
70
+ = 1.4.4 =
71
+ * New option to hide video thumbnails. Sometimes video thubmanils may show as blank squares, so the new option will help to fix this problem.
72
+
73
+ = 1.4.3 =
74
+ * Minor bug fix
75
+
76
+ = 1.4.2 =
77
+ * New feature: "Lazy Load Images". You can enable it the widget settings.
78
+
79
+ = 1.4.1 =
80
+ * New option in the settings page to control the refresh rate of your Instagram feed.
81
+ * A few more fixes and improvements to the Instagram API integration.
82
+
83
+ = 1.4.0 =
84
+ * Added an alternative option to display the public feed limited to 12 photos of your account or any other Instagram user.
85
+
86
+ = 1.3.1 =
87
+ * Minor bug fix with a caching issue
88
+
89
+ = 1.3.0 =
90
+ * Added new option: Display User Details
91
+ * Added new option: Display User Bio
92
+
93
+ = 1.2.11 =
94
+ * Fixed a conflict with some CSS classes
95
+
96
+ = 1.2.10 =
97
+ * Minor fixes to new overlay feature
98
+
99
+ = 1.2.9 =
100
+ * New option: show number of likes and comments on image hover
101
+ * Minor bug fixes
102
+
103
+ = 1.2.8 =
104
+ * Minor bug fix
105
+
106
+ = 1.2.7 =
107
+ * Minor bug fix
108
+
109
+ = 1.2.6 =
110
+ * Fixing a bug to prevent exceeding of the Instagram API rate limit (200 request per hour as of March 30, 2018).
111
+
112
+ = 1.2.5 =
113
+ * Minor bug fix
114
+
115
+ = 1.2.4 =
116
+ * Minor bug fix with missing images
117
+
118
+ = 1.2.3 =
119
+ * Minor bug fix
120
+
121
+ = 1.2.2 =
122
+ * Bug fix with incorrect thumbnail size on non-square images
123
+
124
+ = 1.2.1 =
125
+ * Minor modification to show Alt text when hovering images
126
+
127
+ = 1.2.0 =
128
+ * Updated "View on Instagram" button
129
+ * Support for WordPress 4.6
130
+
131
+ = 1.1.0 =
132
+ * IMPORTANT: Due to the recent Instagram API changes, in order for the Instagram Feed plugin to continue working after June 1st you must obtain a new Access Token by using the Instagram button on the plugin's Settings page. This is true even if you recently already obtained a new token. Apologies for any inconvenience.
133
+ * Compatible with Instagram's new API changes effective June 1st
134
+
135
+ = 1.0.4 =
136
+ * Look for exact matching username when searching for user id.
137
+
138
+ = 1.0.3 =
139
+ * Make Instagram image links open a new tab.
140
+
141
+ = 1.0.2 =
142
+ * Load higher quality images when needed.
143
+ * Unique cache key for each widget, previously all widgets on the page used same options on subsequent page loads.
144
+
145
+ = 1.0.1 =
146
+ * Work directly with image list and do not rely on widget ids and classes handled by theme. This broke widget when theme sidebars weren't properly registered.
147
+ * Use requestAnimationFrame for updating image sizes, improved performance and also fixes safari bug.
148
+ * Fix error caused by boolean to string conversion (get|set)_transient.
149
+
150
+ = 1.0 =
151
+ * Initial release.
screenshot-1.jpg ADDED
Binary file
screenshot-2.jpg ADDED
Binary file
screenshot-3.jpg ADDED
Binary file
screenshot-4.jpg ADDED
Binary file
screenshot-5.jpg ADDED
Binary file