FEEDZY RSS Feeds Lite - Version 3.6.0

Version Description

Download this release

Release Info

Developer themeisle
Plugin Icon 128x128 FEEDZY RSS Feeds Lite
Version 3.6.0
Comparing to
See all releases

Code changes from version 3.5.2 to 3.6.0

Files changed (52) hide show
  1. CHANGELOG.md +11 -1
  2. CONTRIBUTING.md +13 -0
  3. css/feedzy-rss-feeds.css +1 -1
  4. form/form.php +2 -7
  5. includes/abstract/feedzy-rss-feeds-admin-abstract.php +277 -200
  6. includes/admin/feedzy-rss-feeds-admin.php +75 -40
  7. includes/admin/feedzy-rss-feeds-import.php +311 -193
  8. includes/admin/feedzy-rss-feeds-options.php +1 -1
  9. includes/admin/feedzy-rss-feeds-ui-lang.php +32 -32
  10. includes/admin/feedzy-rss-feeds-ui.php +8 -8
  11. includes/admin/feedzy-wp-widget.php +44 -38
  12. includes/feedzy-rss-feeds-activator.php +2 -1
  13. includes/feedzy-rss-feeds-feed-tweaks.php +150 -0
  14. includes/feedzy-rss-feeds.php +5 -3
  15. includes/gutenberg/feedzy-rss-feeds-gutenberg-block.php +28 -23
  16. includes/layouts/feedzy-improve.php +1 -1
  17. includes/layouts/feedzy-support.php +7 -6
  18. includes/layouts/feedzy-tutorial.php +3 -3
  19. includes/layouts/feedzy-upsell.php +9 -9
  20. includes/layouts/settings.php +31 -29
  21. includes/util/feedzy-rss-feeds-util-simplepie.php +3 -3
  22. includes/views/import-metabox-edit.php +108 -96
  23. includes/views/js/chosen.js +1358 -1323
  24. includes/views/js/import-metabox-edit.js +7 -0
  25. includes/views/misc-view.php +3 -9
  26. readme.txt +16 -2
  27. themeisle-hash.json +0 -1
  28. vendor/autoload.php +2 -2
  29. vendor/codeinwp/themeisle-sdk/CHANGELOG.md +17 -0
  30. vendor/codeinwp/themeisle-sdk/README.md +0 -32
  31. vendor/codeinwp/themeisle-sdk/docker-compose.local.yml +0 -28
  32. vendor/codeinwp/themeisle-sdk/load.php +1 -1
  33. vendor/codeinwp/themeisle-sdk/src/Common/Abstract_module.php +19 -2
  34. vendor/codeinwp/themeisle-sdk/src/Common/Module_factory.php +1 -1
  35. vendor/codeinwp/themeisle-sdk/src/Modules/Dashboard_widget.php +36 -32
  36. vendor/codeinwp/themeisle-sdk/src/Modules/Licenser.php +157 -119
  37. vendor/codeinwp/themeisle-sdk/src/Modules/Logger.php +1 -1
  38. vendor/codeinwp/themeisle-sdk/src/Modules/Notification.php +3 -3
  39. vendor/codeinwp/themeisle-sdk/src/Modules/Recommendation.php +13 -10
  40. vendor/codeinwp/themeisle-sdk/src/Modules/Rollback.php +9 -7
  41. vendor/codeinwp/themeisle-sdk/src/Modules/Translate.php +1 -1
  42. vendor/codeinwp/themeisle-sdk/src/Modules/Uninstall_feedback.php +28 -28
  43. vendor/codeinwp/themeisle-sdk/src/Product.php +1 -1
  44. vendor/codeinwp/themeisle-sdk/start.php +19 -19
  45. vendor/composer/ClassLoader.php +83 -17
  46. vendor/composer/InstalledVersions.php +293 -0
  47. vendor/composer/LICENSE +1 -1
  48. vendor/composer/autoload_classmap.php +1 -0
  49. vendor/composer/autoload_real.php +32 -18
  50. vendor/composer/autoload_static.php +24 -0
  51. vendor/composer/installed.json +50 -44
  52. vendor/composer/installed.php +34 -0
CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
 
1
 
2
- ### v3.5.2 - 2020-12-24
 
 
 
 
 
 
 
 
 
3
  **Changes:**
4
  * [Fix] Compatibility with WP 5.6
5
  * [Fix] Composer requiring PHP greater than 7.1.0
1
+ #### [Version 3.6.0](https://github.com/Codeinwp/feedzy-rss-feeds/compare/v3.5.2...v3.6.0) (2021-04-20)
2
 
3
+ #### Fixes
4
+ * Fix PHP notices reported on import when debug mode is on
5
+ * Fix inconsistent behavior with certain valid feed URLs
6
+ * Improve compatibilities with the latest PHP and WordPress versions
7
+ * Improve compatibilities with non-Latin charsets
8
+
9
+ #### Feature
10
+ * Add ability to use external images on import for featured images.
11
+
12
+ ### v3.5.2 - 2020-12-24
13
  **Changes:**
14
  * [Fix] Compatibility with WP 5.6
15
  * [Fix] Composer requiring PHP greater than 7.1.0
CONTRIBUTING.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Releasing
2
+
3
+ This repository uses conventional [changelog commit](https://github.com/Codeinwp/conventional-changelog-simple-preset) messages to trigger release
4
+
5
+ How to release a new version:
6
+
7
+ - Clone the master branch
8
+ - Do your changes
9
+ - Send a PR to master and merge it using the following subject message
10
+ - `release: <release short description>` - for patch release
11
+ - `release(minor): <release short description>` - for minor release
12
+ - `release(major): <release short description>` - for major release
13
+ The release notes will inherit the body of the commit message which triggered the release. For more details check the [simple-preset](https://github.com/Codeinwp/conventional-changelog-simple-preset) that we use.
css/feedzy-rss-feeds.css CHANGED
@@ -2,7 +2,7 @@
2
  * feedzy-rss-feeds.css
3
  * Feedzy RSS Feed
4
  * Copyright: (c) 2016 Themeisle, themeisle.com
5
- * Version: 3.5.2
6
  * Plugin Name: FEEDZY RSS Feeds
7
  * Plugin URI: http://themeisle.com/plugins/feedzy-rss-feeds/
8
  * Author: Themeisle
2
  * feedzy-rss-feeds.css
3
  * Feedzy RSS Feed
4
  * Copyright: (c) 2016 Themeisle, themeisle.com
5
+ * Version: 3.6.0
6
  * Plugin Name: FEEDZY RSS Feeds
7
  * Plugin URI: http://themeisle.com/plugins/feedzy-rss-feeds/
8
  * Author: Themeisle
form/form.php CHANGED
@@ -21,12 +21,7 @@ $html_parts = Feedzy_Rss_Feeds_Ui_Lang::get_form_elements();
21
  <meta http-equiv="cache-control" content="no-cache"/>
22
  <meta http-equiv="expires" content="0"/>
23
  <meta http-equiv="pragma" content="no-cache"/>
24
- <link rel="stylesheet" href="
25
- <?php
26
- // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
27
- echo FEEDZY_ABSURL . 'css/form.css?h=' . date( 'dmYHis' );
28
- ?>
29
- " type="text/css" media="all"/>
30
  </head>
31
  <body>
32
  <div class="feedzy-popup-form container">
@@ -106,7 +101,7 @@ $html_parts = Feedzy_Rss_Feeds_Ui_Lang::get_form_elements();
106
  $output .= '</div>';
107
  } // End foreach().
108
  } // End if().
109
- echo $output;
110
  ?>
111
  </div>
112
  <script type="text/javascript">
21
  <meta http-equiv="cache-control" content="no-cache"/>
22
  <meta http-equiv="expires" content="0"/>
23
  <meta http-equiv="pragma" content="no-cache"/>
24
+ <?php echo sprintf( '<link rel="stylesheet" href="%s" type="text/css" media="all"/>', esc_url( FEEDZY_ABSURL . 'css/form.css?h=' . date( 'dmYHis' ) ) ); //phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet ?>
 
 
 
 
 
25
  </head>
26
  <body>
27
  <div class="feedzy-popup-form container">
101
  $output .= '</div>';
102
  } // End foreach().
103
  } // End if().
104
+ echo wp_kses( $output, apply_filters( 'feedzy_wp_kses_allowed_html', array() ) );
105
  ?>
106
  </div>
107
  <script type="text/javascript">
includes/abstract/feedzy-rss-feeds-admin-abstract.php CHANGED
@@ -55,17 +55,17 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
55
  public function get_usage_data( $data ) {
56
  global $wpdb;
57
 
58
- // how many categories created
59
  $categories = 0;
60
- $terms = get_terms( array( 'taxonomy' => 'feedzy_categories' ) );
61
  if ( is_array( $terms ) ) {
62
  $categories = count( $terms );
63
  }
64
- // imports
65
- $imports = array();
66
- $license = 'free';
67
  if ( feedzy_is_pro() ) {
68
- $license = 'pro';
69
  if ( apply_filters( 'feedzy_is_license_of_type', false, 'agency' ) ) {
70
  $license = 'agency';
71
  } elseif ( apply_filters( 'feedzy_is_license_of_type', false, 'business' ) ) {
@@ -73,7 +73,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
73
  }
74
 
75
  $integrations = array();
76
- $settings = get_option( 'feedzy-rss-feeds-settings' );
77
  if ( 'agency' === $license && $settings ) {
78
  if ( isset( $settings['spinnerchief_licence'] ) && 'yes' === $settings['spinnerchief_licence'] ) {
79
  $integrations[] = 'spinnerchief';
@@ -83,22 +83,52 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
83
  }
84
  }
85
 
86
- $imports = apply_filters(
87
- 'feedzy_usage_data', array(
88
- // how many active imports are created
89
- 'publish' => count( get_posts( array( 'post_type' => 'feedzy_imports', 'post_status' => 'publish', 'numberposts' => 299, 'fields' => 'ids' ) ) ),
 
 
 
 
 
 
 
 
 
 
90
  // how many draft imports are created
91
- 'draft' => count( get_posts( array( 'post_type' => 'feedzy_imports', 'post_status' => 'draft', 'numberposts' => 299, 'fields' => 'ids' ) ) ),
 
 
 
 
 
 
 
 
 
92
  // how many posts were imported by the imports
93
- 'imported' => count( get_posts( array( 'post_type' => 'post', 'post_status' => array( 'publish', 'private', 'draft', 'trash' ), 'numberposts' => 2999, 'fields' => 'ids', 'meta_key' => 'feedzy', 'meta_value' => 1 ) ) ),
 
 
 
 
 
 
 
 
 
 
 
94
  // integrations
95
- 'integrations' => $integrations,
96
  )
97
  );
98
  }
99
 
100
  $settings = apply_filters( 'feedzy_get_settings', null );
101
- $config = array();
102
  if ( $settings ) {
103
  $proxy = isset( $settings['proxy'] ) && is_array( $settings['proxy'] ) && ! empty( $settings['proxy'] ) ? array_filter( $settings['proxy'] ) : array();
104
  if ( ! empty( $proxy ) ) {
@@ -108,13 +138,13 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
108
 
109
  // how many posts contain the shortcode
110
  global $wpdb;
111
- $shortcodes = $wpdb->get_var( "SELECT count(*) FROM {$wpdb->prefix}posts WHERE post_status IN ('publish', 'private') AND post_content LIKE '%[feedzy-rss %'" );
112
- $data = array(
113
- 'categories' => $categories,
114
- 'imports' => $imports,
115
- 'shortcodes' => $shortcodes,
116
- 'license' => $license,
117
- 'config' => $config,
118
  );
119
 
120
  return $data;
@@ -141,7 +171,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
141
  // Or if this is in the dry run window.
142
  // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
143
  $show_error = is_admin() || ( is_user_logged_in() && $post && get_current_user_id() == $post->post_author );
144
- $error_msg = '';
145
 
146
  if ( is_array( $errors ) ) {
147
  foreach ( $errors as $i => $error ) {
@@ -197,7 +227,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
197
  public function feedzy_add_item_padding( $item_attr, $sizes ) {
198
  $padding_top = number_format( ( 15 / 150 ) * $sizes['height'], 0 );
199
  $padding_bottom = number_format( ( 25 / 150 ) * $sizes['height'], 0 );
200
- $style_padding = ' style="padding: ' . $padding_top . 'px 0 ' . $padding_bottom . 'px"';
201
 
202
  return $item_attr . $style_padding;
203
  }
@@ -237,7 +267,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
237
  * @return string
238
  */
239
  public function feedzy_summary_input_filter( $description, $content, $feed_url ) {
240
- $description = trim( strip_tags( $description ) );
241
  $description = trim( str_replace( array( '[…]', '[…]', '[&hellip;]' ), '', $description ) );
242
 
243
  return $description;
@@ -317,10 +347,10 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
317
  global $post;
318
  if ( has_post_thumbnail( $post->ID ) ) {
319
  $post_thumbnail_id = get_post_thumbnail_id( $post->ID );
320
- $attachment_meta = wp_get_attachment_metadata( $post_thumbnail_id );
321
- $image_url = wp_get_attachment_image_src( $post_thumbnail_id, 'medium' );
322
- echo '<enclosure url="' . $image_url[0] . '" length="' . filesize( get_attached_file( $post_thumbnail_id ) ) . '" type="image/jpg" />';
323
- echo '<media:content url="' . $image_url[0] . '" width="' . $attachment_meta['sizes']['medium']['width'] . '" height="' . $attachment_meta['sizes']['medium']['height'] . '" medium="image" type="' . $attachment_meta['sizes']['medium']['mime-type'] . '" />';
324
 
325
  }
326
  }
@@ -337,19 +367,20 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
337
  * @return bool|string
338
  */
339
  public function process_feed_source( $src ) {
340
- $regex = '((https?|ftp)\:\/\/)?'; // Contains Protocol
341
- $regex .= '([a-z0-9+!*(),;?&=\$_.-]+(\:[a-z0-9+!*(),;?&=\$_.-]+)?@)?'; // Uses User and Pass
342
- $regex .= '([a-z0-9-.]*)\.([a-z]{2,3})'; // Has Host or IP
343
- $regex .= '(\:[0-9]{2,5})?'; // Uses Port
344
- $regex .= '(\/([a-z0-9+\$_-]\.?)+)*\/?'; // Has Path
345
- $regex .= '(\?[a-z+&\$_.-][a-z0-9;:@&%=+\/\$_.-]*)?'; // Has GET Query
346
- $regex .= '(#[a-z_.-][a-z0-9+\$_.-]*)?'; // Uses Anchor
347
  if ( preg_match( "/^$regex$/", $src ) ) {
348
  // If it matches Regex ( it's not a slug ) so return the sources.
349
  return $src;
350
  } else {
351
- $src = trim( $src );
352
- if ( $post = get_page_by_path( $src, OBJECT, 'feedzy_categories' ) ) {
 
353
  return trim( preg_replace( '/\s+/', ' ', get_post_meta( $post->ID, 'feedzy_category_feed', true ) ) );
354
  } else {
355
  return $src;
@@ -370,32 +401,31 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
370
  * @return mixed
371
  */
372
  public function feedzy_rss( $atts, $content = '' ) {
373
- wp_enqueue_style( $this->plugin_name );
374
  $sc = $this->get_short_code_attributes( $atts );
375
  $feed_url = $this->normalize_urls( $sc['feeds'] );
376
  if ( empty( $feed_url ) ) {
377
  return $content;
378
  }
379
- $cache = $sc['refresh'];
380
 
381
  // Disregard the pseudo-shortcode coming from Gutenberg as a lazy one.
382
- // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
383
- if ( $sc['lazy'] == 'yes' && ! isset( $sc['gutenberg'] ) ) {
384
  $attributes = '';
385
  foreach ( $sc as $key => $val ) {
386
  // ignore the feedData, its not required.
387
- if ( $key === 'feedData' ) {
388
  continue;
389
  }
390
  if ( is_array( $val ) ) {
391
  $val = implode( ',', $val );
392
  }
393
- $attributes .= 'data-' . $key . '="' . esc_attr( $val ) . '"';
394
  }
395
  $content = get_transient( sprintf( 'feedzy-lazy-%s', is_array( $feed_url ) ? implode( ',', $feed_url ) : $feed_url ) );
396
 
397
- $class = array_filter( apply_filters( 'feedzy_add_classes_block', array( $sc['className'], 'feedzy-' . md5( is_array( $feed_url ) ? implode( ',', $feed_url ) : $feed_url ) ), $sc, null, $feed_url ) );
398
- $html = "<div class='feedzy-lazy' $attributes>";
399
  // the first time the shortcode is being called it will not have any content.
400
  if ( empty( $content ) ) {
401
  $content = apply_filters( 'feedzy_lazyload_loading_msg', __( 'Loading', 'feedzy-rss-feeds' ) . '...', $feed_url );
@@ -404,22 +434,30 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
404
 
405
  wp_register_script( $this->plugin_name . '-lazy', FEEDZY_ABSURL . 'js/feedzy-lazy.js', array( 'jquery' ), $this->version, 'all' );
406
  wp_enqueue_script( $this->plugin_name . '-lazy' );
407
- wp_localize_script( $this->plugin_name . '-lazy', 'feedzy', array( 'url' => get_rest_url( null, 'feedzy/v' . FEEDZY_REST_VERSION . '/lazy/' ), 'rest_nonce' => wp_create_nonce( 'wp_rest' ), 'nonce' => wp_create_nonce( 'feedzy' ) ) );
 
 
 
 
 
 
 
 
408
  return $html;
409
  }
410
 
411
  if ( isset( $sc['_dry_run_tags_'] ) ) {
412
  if ( strpos( $sc['_dry_run_tags_'], 'item_full_content' ) !== false ) {
413
- $sc_clone = $sc;
414
  $sc_clone['__jobID'] = ''; // pro expects this but keep it empty.
415
- $feedURL = apply_filters( 'feedzy_import_feed_url', $feed_url, '[#item_full_content]', $sc_clone );
416
- if ( ! is_wp_error( $feedURL ) ) {
417
- $feed_url = $feedURL;
418
  }
419
  }
420
  }
421
 
422
- $feed = $this->fetch_feed( $feed_url, $cache, $sc );
423
  if ( is_string( $feed ) ) {
424
  return $feed;
425
  }
@@ -435,16 +473,18 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
435
  */
436
  public function rest_route() {
437
  register_rest_route(
438
- 'feedzy/v' . FEEDZY_REST_VERSION, '/lazy/', array(
439
- 'methods' => 'POST',
440
- 'callback' => array( $this, 'feedzy_lazy_load' ),
 
 
441
  'permission_callback' => '__return_true',
442
- 'args' => array(
443
  'nonce' => array(
444
  'validate_callback' => function( $value ) {
445
  return wp_verify_nonce( $value, 'feedzy' );
446
  },
447
- 'required' => true,
448
  ),
449
  ),
450
  )
@@ -460,10 +500,10 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
460
  * @param array $data The attributes passed by the ajax call.
461
  */
462
  public function feedzy_lazy_load( $data ) {
463
- $atts = $data['args'];
464
- $sc = $this->get_short_code_attributes( $atts );
465
  $feed_url = $this->normalize_urls( $sc['feeds'] );
466
- $feed = $this->fetch_feed( $feed_url, $sc['refresh'], $sc );
467
  if ( is_string( $feed ) ) {
468
  return $feed;
469
  }
@@ -487,64 +527,64 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
487
  * @return array
488
  */
489
  public function get_short_code_attributes( $atts ) {
490
- // Retrieve & extract shorcode parameters
491
  $sc = shortcode_atts(
492
  array(
493
- // comma separated feeds url
494
  'feeds' => '',
495
- // number of feeds items (0 for unlimited)
496
  'max' => '5',
497
- // display feed title yes/no
498
  'feed_title' => 'yes',
499
  // _blank, _self
500
  'target' => '_blank',
501
- // empty or no for nofollow
502
  'follow' => '',
503
  // strip title after X char. X can be 0 too, which will remove the title.
504
  'title' => '',
505
  // yes (author, date, time), no (NEITHER), author, date, time, categories
506
  // tz=local (for date/time in blog time)
507
  // tz=gmt (for date/time in UTC time, this is the default)
508
- // tz=no (for date/time in the feed, without conversion)
509
  'meta' => 'yes',
510
  // yes (all), no (NEITHER)
511
- // source: show feed title
512
- 'multiple_meta' => 'no',
513
- // strip title
514
  'summary' => 'yes',
515
- // strip summary after X char
516
  'summarylength' => '',
517
- // yes, no, auto
518
  'thumb' => 'auto',
519
- // default thumb URL if no image found (only if thumb is set to yes or auto)
520
  'default' => '',
521
- // thumbs pixel size
522
  'size' => '',
523
- // only display item if title contains specific keywords (comma-separated list/case sensitive)
524
  'keywords_title' => '',
525
- // only display item if title OR content contains specific keywords (comma-separated list/case sensitive)
526
- 'keywords_inc' => '',
527
- // cache refresh
528
  'refresh' => '12_hours',
529
  // sorting.
530
  'sort' => '',
531
  // https = force https
532
  // default = fall back to default image
533
- // auto = continue as it is
534
- 'http' => 'auto',
535
- // message to show when feed is empty
536
- 'error_empty' => 'Feed has no items.',
537
  // to disable amp support, use 'no'. This is currently not available as part of the shortcode tinymce form.
538
- 'amp' => 'yes',
539
- // paginate
540
- 'offset' => 0,
541
- // class name of this block
542
- 'className' => '',
543
  // lazy loading of feeds?
544
- 'lazy' => 'no',
545
- // this are only for internal purposes
546
- '_dryrun_' => 'no',
547
- '_dry_run_tags_' => '',
548
  ),
549
  $atts,
550
  'feedzy_default'
@@ -565,7 +605,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
565
  * @return mixed|void Urls of the feeds.
566
  */
567
  public function normalize_urls( $raw ) {
568
- $feeds = apply_filters( 'feedzy_process_feed_source', $raw );
569
  $feed_url = apply_filters( 'feedzy_get_feed_url', $feeds );
570
  if ( is_array( $feed_url ) ) {
571
  foreach ( $feed_url as $index => $url ) {
@@ -590,7 +630,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
590
  // Automatically fix deprecated google news feeds.
591
  if ( false !== strpos( $url, 'news.google.' ) ) {
592
 
593
- $parts = parse_url( $url );
594
  parse_str( $parts['query'], $query );
595
 
596
  if ( isset( $query['q'] ) ) {
@@ -618,13 +658,13 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
618
  * @return SimplePie|string|void|WP_Error The feed resource.
619
  */
620
  public function fetch_feed( $feed_url, $cache = '12_hours', $sc ) {
621
- // Load SimplePie if not already
622
  do_action( 'feedzy_pre_http_setup', $feed_url );
623
 
624
- // Load SimplePie Instance
625
  $feed = $this->init_feed( $feed_url, $cache, $sc ); // Not used as log as #41304 is Opened.
626
 
627
- // Report error when is an error loading the feed
628
  if ( is_wp_error( $feed ) ) {
629
  // Fallback for different edge cases.
630
  if ( is_array( $feed_url ) ) {
@@ -641,12 +681,10 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
641
 
642
  do_action( 'feedzy_post_http_teardown', $feed_url );
643
 
644
- // var_dump( $feed );
645
  return $feed;
646
  }
647
 
648
  /**
649
- *
650
  * Method to avoid using core implementation in order
651
  * order to fix issues reported here: https://core.trac.wordpress.org/ticket/41304
652
  * Bug: #41304 with WP wp_kses sanitizer used by WP SimplePie implementation.
@@ -659,6 +697,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
659
  * @param string $feed_url The feed URL.
660
  * @param string $cache The cache string (eg. 1_hour, 30_min etc.).
661
  * @param array $sc The shortcode attributes.
 
662
  *
663
  * @return SimplePie
664
  */
@@ -669,7 +708,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
669
  'days' => DAY_IN_SECONDS,
670
  );
671
  $cache_time = 12 * HOUR_IN_SECONDS;
672
- if ( isset( $cache ) && $cache !== '' ) {
673
  list( $value, $unit ) = explode( '_', $cache );
674
  if ( isset( $value ) && is_numeric( $value ) && $value >= 1 && $value <= 100 ) {
675
  if ( isset( $unit ) && in_array( strtolower( $unit ), array( 'mins', 'hours', 'days' ), true ) ) {
@@ -687,8 +726,8 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
687
  )
688
  );
689
  }
690
- require_once( ABSPATH . WPINC . '/class-wp-feed-cache-transient.php' );
691
- require_once( ABSPATH . WPINC . '/class-wp-simplepie-file.php' );
692
 
693
  $feed->set_file_class( 'WP_SimplePie_File' );
694
  $default_agent = $this->get_default_user_agent( $feed_url );
@@ -697,18 +736,22 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
697
  SimplePie_Cache::register( 'wp_transient', 'WP_Feed_Cache_Transient' );
698
  $feed->set_cache_location( 'wp_transient' );
699
  add_filter(
700
- 'wp_feed_cache_transient_lifetime', function( $time ) use ( $cache_time ) {
 
701
  return $cache_time;
702
- }, 10, 1
 
 
703
  );
704
  } else {
705
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
706
  WP_Filesystem();
707
  global $wp_filesystem;
708
 
709
- $dir = $wp_filesystem->wp_content_dir() . 'uploads/simplepie';
710
  if ( ! $wp_filesystem->exists( $dir ) ) {
711
- if ( ( $done = $wp_filesystem->mkdir( $dir ) ) === false ) {
 
712
  do_action( 'themeisle_log_event', FEEDZY_NAME, sprintf( 'Unable to create directory %s', $dir ), 'error', __FILE__, __LINE__ );
713
  }
714
  }
@@ -723,9 +766,14 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
723
  $cloned_feed = clone $feed;
724
 
725
  // set the url as the last step, because we need to be able to clone this feed without the url being set
726
- // so that we can fall back to raw data in case of an error
727
  $feed->set_feed_url( $feed_url );
728
 
 
 
 
 
 
729
  global $feedzy_current_error_reporting;
730
  $feedzy_current_error_reporting = error_reporting();
731
 
@@ -734,7 +782,8 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
734
  error_reporting( E_ALL ^ E_WARNING );
735
  // reset the error_reporting back to its original value.
736
  add_action(
737
- 'shutdown', function() {
 
738
  global $feedzy_current_error_reporting;
739
  error_reporting( $feedzy_current_error_reporting );
740
  }
@@ -758,13 +807,13 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
758
  $feed = $this->init_feed( $feed_url, $cache, $sc, false );
759
  } elseif ( is_string( $feed_url ) || ( is_array( $feed_url ) && 1 === count( $feed_url ) ) ) {
760
  do_action( 'themeisle_log_event', FEEDZY_NAME, 'Trying to use raw data', 'debug', __FILE__, __LINE__ );
761
- $data = wp_remote_retrieve_body( wp_remote_get( $feed_url, array( 'user-agent' => $default_agent ) ) );
762
  $cloned_feed->set_raw_data( $data );
763
  $cloned_feed->init();
764
  $error_raw = $cloned_feed->error();
765
  if ( empty( $error_raw ) ) {
766
  // only if using the raw url produces no errors, will we consider the new feed as good to go.
767
- // otherwise we will use the old feed
768
  $feed = $cloned_feed;
769
  }
770
  } else {
@@ -816,7 +865,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
816
  $valid_feed_url[] = $url;
817
  } else {
818
  if ( $echo ) {
819
- echo sprintf( __( 'Feed URL: %s not valid and removed from fetch.', 'feedzy-rss-feeds' ), '<b>' . $url . '</b>' );
820
  }
821
  }
822
  }
@@ -825,7 +874,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
825
  $valid_feed_url[] = $feed_url;
826
  } else {
827
  if ( $echo ) {
828
- echo sprintf( __( 'Feed URL: %s not valid and removed from fetch.', 'feedzy-rss-feeds' ), '<b>' . $feed_url . '</b>' );
829
  }
830
  }
831
  }
@@ -845,11 +894,18 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
845
  * @return bool
846
  */
847
  protected function check_valid_xml( $url, $cache ) {
 
848
  $feed = $this->init_feed( $url, $cache, array() );
849
  if ( $feed->error() ) {
850
  return false;
851
  }
852
 
 
 
 
 
 
 
853
  return true;
854
  }
855
 
@@ -866,7 +922,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
866
  */
867
  public function sanitize_attr( $sc, $feed_url ) {
868
  // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
869
- if ( $sc['max'] == '0' ) {
870
  $sc['max'] = '999';
871
  } elseif ( empty( $sc['max'] ) || ! is_numeric( $sc['max'] ) ) {
872
  $sc['max'] = '5';
@@ -925,9 +981,9 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
925
  'height' => $sc['size'],
926
  );
927
  $sizes = apply_filters( 'feedzy_thumb_sizes', $sizes, $feed_url );
 
928
  $feed_title['use_title'] = false;
929
  if ( $sc['feed_title'] === 'yes' ) {
930
- $feed_title = $this->get_feed_title_filter( $feed, $sc, $feed_url );
931
  $feed_title['use_title'] = true;
932
  }
933
  // Display the error message and quit (before showing the template for pro).
@@ -936,8 +992,8 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
936
  }
937
 
938
  $feed_items = apply_filters( 'feedzy_get_feed_array', array(), $sc, $feed, $feed_url, $sizes );
939
- $class = array_filter( apply_filters( 'feedzy_add_classes_block', array( $sc['className'], 'feedzy-' . md5( is_array( $feed_url ) ? implode( ',', $feed_url ) : $feed_url ) ), $sc, $feed, $feed_url ) );
940
- $content .= '<div class="feedzy-rss ' . implode( ' ', $class ) . '">';
941
  if ( $feed_title['use_title'] ) {
942
  $content .= '<div class="rss_header">';
943
  $content .= '<h2><a href="' . $feed->get_permalink() . '" class="rss_title" rel="noopener">' . html_entity_decode( $feed->get_title() ) . '</a> <span class="rss_description"> ' . $feed->get_description() . '</span></h2>';
@@ -952,14 +1008,14 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
952
  return $content;
953
  }
954
 
955
- $anchor1 = '<a href="%s" target="%s" rel="%s noopener" title="%s" style="%s">%s</a>';
956
- $anchor2 = '<a href="%s" target="%s" rel="%s noopener">%s</a>';
957
- $line_item = '<li %s>%s<span class="title">%s</span><div class="%s" style="%s">%s%s</div></li>';
958
  $dry_run_item = '<li %s><span class="title">%s</span><div class="dry_run">%s</div></li>';
959
- $is_dry_run = isset( $sc['_dryrun_'] ) && $sc['_dryrun_'] === 'yes';
960
  foreach ( $feed_items as $item ) {
961
  if ( $is_dry_run ) {
962
- $details = $this->get_dry_run_results( $sc, $item );
963
  $content .= sprintf(
964
  $dry_run_item,
965
  $item['itemAttr'],
@@ -970,7 +1026,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
970
  $content .= sprintf(
971
  $line_item,
972
  $item['itemAttr'],
973
- ! empty( $item['item_img'] ) && $sc['thumb'] !== 'no' ? sprintf( '<div class="%s" style="%s">%s</div>', $item['item_img_class'], $item['item_img_style'], sprintf( $anchor1, $item['item_url'], $item['item_url_target'], $item['item_url_follow'], $item['item_url_title'], $item['item_img_style'], $item['item_img'] ) ) : '',
974
  sprintf( $anchor2, $item['item_url'], $item['item_url_target'], $item['item_url_follow'], $item['item_title'] ),
975
  $item['item_content_class'],
976
  $item['item_content_style'],
@@ -999,23 +1055,38 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
999
  */
1000
  private function get_dry_run_results( $sc, $item ) {
1001
  $statuses = array();
1002
- $details = '';
1003
  if ( true === apply_filters( 'feedzy_is_license_of_type', false, 'business' ) ) {
1004
  if ( ! empty( $item['full_content_error'] ) ) {
1005
- $statuses[] = array( 'success' => false, 'msg' => sprintf( __( 'Full content: %s', 'feedzy-rss-feeds' ), $item['full_content_error'] ) );
 
 
 
1006
  } elseif ( isset( $item['item_full_content'] ) ) {
1007
  if ( ! empty( $item['item_full_content'] ) ) {
1008
- $statuses[] = array( 'success' => true, 'msg' => __( 'Full content extracted', 'feedzy-rss-feeds' ) );
 
 
 
1009
  } else {
1010
- $statuses[] = array( 'success' => true, 'msg' => __( 'Full content extracted (is empty)', 'feedzy-rss-feeds' ) );
 
 
 
1011
  }
1012
  }
1013
  }
1014
  if ( strpos( $sc['_dry_run_tags_'], 'item_image' ) !== false ) {
1015
  if ( ! empty( $item['item_img_path'] ) ) {
1016
- $statuses[] = array( 'success' => true, 'msg' => __( 'Image', 'feedzy-rss-feeds' ) );
 
 
 
1017
  } else {
1018
- $statuses[] = array( 'success' => false, 'msg' => __( 'Unable to find image', 'feedzy-rss-feeds' ) );
 
 
 
1019
  }
1020
  }
1021
 
@@ -1051,7 +1122,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1051
  'rss_title' => html_entity_decode( $feed->get_title() ),
1052
  'rss_description_class' => 'rss_description',
1053
  'rss_description' => $feed->get_description(),
1054
- 'rss_classes' => array( $sc['className'], 'feedzy-' . md5( $feed_url ) ),
1055
  );
1056
  }
1057
 
@@ -1068,10 +1139,10 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1068
  public function get_feed_url( $feeds ) {
1069
  $feed_url = '';
1070
  if ( ! empty( $feeds ) ) {
1071
- $feeds = rtrim( $feeds, ',' );
1072
- $feeds = explode( ',', $feeds );
1073
  $feed_url = array();
1074
- // Remove SSL from HTTP request to prevent fetching errors
1075
  foreach ( $feeds as $feed ) {
1076
  $feed = trim( $feed );
1077
  // scheme-less URLs.
@@ -1113,12 +1184,12 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1113
  $index = 0;
1114
  foreach ( (array) $items as $item ) {
1115
  $continue = apply_filters( 'feedzy_item_keyword', true, $sc, $item, $feed_url, $index );
1116
- if ( $continue === true ) {
1117
  // Count items. This should be > and not >= because max, when not defined and empty, becomes 0.
1118
  if ( $count >= $sc['max'] ) {
1119
  break;
1120
  }
1121
- $item_attr = apply_filters( 'feedzy_item_attributes', $item_attr = '', $sizes, $item, $feed_url, $sc, $index );
1122
  $feed_items[ $count ] = $this->get_feed_item_filter( $sc, $sizes, $item, $feed_url, $count, $index );
1123
  $feed_items[ $count ]['itemAttr'] = $item_attr;
1124
  $count++;
@@ -1146,27 +1217,27 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1146
  */
1147
  private function get_feed_item_filter( $sc, $sizes, $item, $feed_url, $index, $item_index ) {
1148
  $item_link = $item->get_permalink();
1149
- // if the item has no link (possible in some cases), use the feed link
1150
  if ( empty( $item_link ) ) {
1151
  $item_link = $item->get_feed()->get_permalink();
1152
  }
1153
- $new_link = apply_filters( 'feedzy_item_url_filter', $item_link, $sc, $item );
1154
 
1155
- // Fetch image thumbnail
1156
- if ( $sc['thumb'] === 'yes' || $sc['thumb'] === 'auto' ) {
1157
  $the_thumbnail = $this->feedzy_retrieve_image( $item, $sc );
1158
  }
1159
- if ( $sc['thumb'] === 'yes' || $sc['thumb'] === 'auto' ) {
1160
  $content_thumb = '';
1161
- if ( ( ! empty( $the_thumbnail ) && $sc['thumb'] === 'auto' ) || $sc['thumb'] === 'yes' ) {
1162
  if ( ! empty( $the_thumbnail ) ) {
1163
- $the_thumbnail = $this->feedzy_image_encode( $the_thumbnail );
1164
  $content_thumb .= '<span class="fetched" style="background-image: url(\'' . $the_thumbnail . '\');" title="' . esc_html( $item->get_title() ) . '"></span>';
1165
  if ( ! isset( $sc['amp'] ) || 'no' !== $sc['amp'] ) {
1166
  $content_thumb .= '<amp-img width="' . $sizes['width'] . '" height="' . $sizes['height'] . '" src="' . $the_thumbnail . '">';
1167
  }
1168
  }
1169
- if ( empty( $the_thumbnail ) && $sc['thumb'] === 'yes' ) {
1170
  $content_thumb .= '<span class="default" style="background-image:url(' . $sc['default'] . ');" title="' . esc_html( $item->get_title() ) . '"></span>';
1171
  if ( ! isset( $sc['amp'] ) || 'no' !== $sc['amp'] ) {
1172
  $content_thumb .= '<amp-img width="' . $sizes['width'] . '" height="' . $sizes['height'] . '" src="' . $sc['default'] . '">';
@@ -1175,7 +1246,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1175
  }
1176
  $content_thumb = apply_filters( 'feedzy_thumb_output', $content_thumb, $feed_url, $sizes, $item );
1177
  } else {
1178
- $content_thumb = '';
1179
  $content_thumb .= '<span class="default" style="width:' . $sizes['width'] . 'px; height:' . $sizes['height'] . 'px; background-image:url(' . $sc['default'] . ');" title="' . $item->get_title() . '"></span>';
1180
  if ( ! isset( $sc['amp'] ) || 'no' !== $sc['amp'] ) {
1181
  $content_thumb .= '<amp-img width="' . $sizes['width'] . '" height="' . $sizes['height'] . '" src="' . $sc['default'] . '">';
@@ -1187,7 +1258,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1187
  $length = intval( $sc['title'] );
1188
  if ( $length > 0 && strlen( $content_title ) > $length ) {
1189
  $content_title = preg_replace( '/\s+?(\S+)?$/', '', substr( $content_title, 0, $length ) ) . '...';
1190
- } elseif ( $length === 0 ) {
1191
  $content_title = '';
1192
  }
1193
  }
@@ -1196,12 +1267,12 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1196
  // meta=yes is for backward compatibility, otherwise its always better to provide the fields with granularity.
1197
  // if meta=yes, then meta will be placed in default order. Otherwise in the order stated by the user.
1198
  $meta_args = array(
1199
- 'author' => $sc['meta'] === 'yes' || strpos( $sc['meta'], 'author' ) !== false,
1200
- 'date' => $sc['meta'] === 'yes' || strpos( $sc['meta'], 'date' ) !== false,
1201
- 'time' => $sc['meta'] === 'yes' || strpos( $sc['meta'], 'time' ) !== false,
1202
- 'source' => $sc['multiple_meta'] === 'yes' || strpos( $sc['multiple_meta'], 'source' ) !== false,
1203
  'categories' => strpos( $sc['meta'], 'categories' ) !== false,
1204
- 'tz' => 'gmt',
1205
  'date_format' => get_option( 'date_format' ),
1206
  'time_format' => get_option( 'time_format' ),
1207
  );
@@ -1213,30 +1284,31 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1213
  if ( strpos( $configs, '=' ) === false ) {
1214
  continue;
1215
  }
1216
- $config = explode( '=', $configs );
1217
  $meta_args[ $config[0] ] = $config[1];
1218
  }
1219
  }
1220
 
1221
- // Filter: feedzy_meta_args
1222
- $meta_args = apply_filters( 'feedzy_meta_args', $meta_args, $feed_url, $item );
1223
 
1224
  // order of the meta tags.
1225
  $meta_order = array( 'author', 'date', 'time', 'categories' );
1226
- if ( $sc['meta'] !== 'yes' ) {
1227
  $meta_order = array_map( 'trim', explode( ',', $sc['meta'] ) );
1228
  }
1229
 
1230
  $content_meta_values = array();
1231
 
1232
  // multiple sources?
1233
- $is_multiple = is_array( $feed_url );
1234
- $feed_source = $item->get_feed()->get_title();
1235
 
1236
  // author.
1237
  if ( $item->get_author() && $meta_args['author'] ) {
1238
- $author = $item->get_author();
1239
- if ( ! $author_name = $author->get_name() ) {
 
1240
  $author_name = $author->get_email();
1241
  }
1242
 
@@ -1247,30 +1319,30 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1247
  }
1248
 
1249
  if ( $author_name ) {
1250
- $domain = parse_url( $new_link );
1251
- $author_url = '//' . $domain['host'];
1252
- $author_url = apply_filters( 'feedzy_author_url', $author_url, $author_name, $feed_url, $item );
1253
  $content_meta_values['author'] = apply_filters( 'feedzy_meta_author', __( 'by', 'feedzy-rss-feeds' ) . ' <a href="' . $author_url . '" target="' . $sc['target'] . '" title="' . $domain['host'] . '" >' . $author_name . '</a> ', $author_name, $author_url, $feed_source, $feed_url, $item );
1254
  }
1255
  }
1256
 
1257
  // date/time.
1258
- $date_time = $item->get_date( 'U' );
1259
- if ( $meta_args['tz'] === 'local' ) {
1260
- $date_time = get_date_from_gmt( $item->get_date( 'Y-m-d H:i:s' ), 'U' );
1261
  // strings such as Asia/Kolkata need special handling.
1262
  $tz = get_option( 'timezone_string' );
1263
  if ( $tz ) {
1264
  $date_time = gmdate( 'U', $date_time + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
1265
  }
1266
- } elseif ( $meta_args['tz'] === 'no' ) {
1267
  // change the tz component of the date to UTC.
1268
- $raw_date = preg_replace( '/\++(\d\d\d\d)/', '+0000', $item->get_date( '' ) );
1269
- $date = DateTime::createFromFormat( DATE_RFC2822, $raw_date );
1270
- $date_time = $date->format( 'U' );
1271
  }
1272
 
1273
- $date_time = apply_filters( 'feedzy_feed_timestamp', $date_time, $feed_url, $item );
1274
  if ( $meta_args['date'] && ! empty( $meta_args['date_format'] ) ) {
1275
  $content_meta_values['date'] = apply_filters( 'feedzy_meta_date', __( 'on', 'feedzy-rss-feeds' ) . ' ' . date_i18n( $meta_args['date_format'], $date_time ) . ' ', $date_time, $feed_url, $item );
1276
  }
@@ -1287,7 +1359,8 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1287
  }
1288
  }
1289
 
1290
- $content_meta = $content_meta_date = '';
 
1291
  foreach ( $meta_order as $meta ) {
1292
  if ( isset( $content_meta_values[ $meta ] ) ) {
1293
  // collect date/time values separately too.
@@ -1300,9 +1373,9 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1300
 
1301
  $content_meta = apply_filters( 'feedzy_meta_output', $content_meta, $feed_url, $item, $content_meta_values, $meta_order );
1302
  $content_summary = '';
1303
- if ( $sc['summary'] === 'yes' ) {
1304
- $description = $item->get_description();
1305
- $description = apply_filters( 'feedzy_summary_input', $description, $item->get_content(), $feed_url, $item );
1306
  $content_summary = $description;
1307
  if ( is_numeric( $sc['summarylength'] ) && strlen( $description ) > $sc['summarylength'] ) {
1308
  $content_summary = preg_replace( '/\s+?(\S+)?$/', '', substr( $description, 0, $sc['summarylength'] ) ) . ' [&hellip;]';
@@ -1310,24 +1383,24 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1310
  $content_summary = apply_filters( 'feedzy_summary_output', $content_summary, $new_link, $feed_url, $item );
1311
  }
1312
  $item_array = array(
1313
- 'item_img_class' => 'rss_image',
1314
- 'item_img_style' => 'width:' . $sizes['width'] . 'px; height:' . $sizes['height'] . 'px;',
1315
- 'item_url' => $new_link,
1316
- 'item_url_target' => $sc['target'],
1317
- 'item_url_follow' => isset( $sc['follow'] ) && 'no' === $sc['follow'] ? 'nofollow' : '',
1318
- 'item_url_title' => $item->get_title(),
1319
- 'item_img' => $content_thumb,
1320
- 'item_img_path' => $this->feedzy_retrieve_image( $item, $sc ),
1321
- 'item_title' => $content_title,
1322
- 'item_content_class' => 'rss_content',
1323
- 'item_content_style' => '',
1324
- 'item_meta' => $content_meta,
1325
- 'item_date' => $item->get_date( 'U' ),
1326
  'item_date_formatted' => $content_meta_date,
1327
- 'item_author' => $item->get_author(),
1328
- 'item_description' => $content_summary,
1329
- 'item_content' => apply_filters( 'feedzy_content', $item->get_content( false ), $item ),
1330
- 'item_source' => $feed_source,
1331
  );
1332
  $item_array = apply_filters( 'feedzy_item_filter', $item_array, $item, $sc, $index, $item_index );
1333
 
@@ -1356,10 +1429,12 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1356
  $image_mime_types = apply_filters( 'feedzy_image_mime_types', $image_mime_types );
1357
 
1358
  $the_thumbnail = '';
1359
- if ( $enclosures = $item->get_enclosures() ) {
 
1360
  foreach ( (array) $enclosures as $enclosure ) {
1361
- // Item thumbnail
1362
- if ( $thumbnail = $enclosure->get_thumbnail() ) {
 
1363
  $the_thumbnail = $thumbnail;
1364
  }
1365
  if ( isset( $enclosure->thumbnails ) ) {
@@ -1367,7 +1442,8 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1367
  $the_thumbnail = $thumbnail;
1368
  }
1369
  }
1370
- if ( $thumbnail = $enclosure->embed() ) {
 
1371
  $pattern = '/https?:\/\/.*\.(?:jpg|JPG|jpeg|JPEG|jpe|JPE|gif|GIF|png|PNG)/i';
1372
  if ( preg_match( $pattern, $thumbnail, $matches ) ) {
1373
  $the_thumbnail = $matches[0];
@@ -1384,25 +1460,25 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1384
  break;
1385
  }
1386
  }
1387
- // Break loop if thumbnail is found
1388
  if ( ! empty( $the_thumbnail ) ) {
1389
  break;
1390
  }
1391
  }
1392
  }
1393
- // xmlns:itunes podcast
1394
  if ( empty( $the_thumbnail ) ) {
1395
  $data = $item->get_item_tags( 'http://www.itunes.com/dtds/podcast-1.0.dtd', 'image' );
1396
  if ( isset( $data['0']['attribs']['']['href'] ) && ! empty( $data['0']['attribs']['']['href'] ) ) {
1397
  $the_thumbnail = $data['0']['attribs']['']['href'];
1398
  }
1399
  }
1400
- // Content image
1401
  if ( empty( $the_thumbnail ) ) {
1402
  $feed_description = $item->get_content();
1403
  $the_thumbnail = $this->feedzy_return_image( $feed_description );
1404
  }
1405
- // Description image
1406
  if ( empty( $the_thumbnail ) ) {
1407
  $feed_description = $item->get_description();
1408
  $the_thumbnail = $this->feedzy_return_image( $feed_description );
@@ -1539,8 +1615,8 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1539
  * @return string
1540
  */
1541
  public function feedzy_image_encode( $string ) {
1542
- // Check if img url is set as an URL parameter
1543
- $url_tab = parse_url( $string );
1544
  if ( isset( $url_tab['query'] ) ) {
1545
  preg_match_all( '/(http|https):\/\/[^ ]+(\.gif|\.GIF|\.jpg|\.JPG|\.jpeg|\.JPEG|\.png|\.PNG)/', $url_tab['query'], $img_url );
1546
  if ( isset( $img_url[0][0] ) ) {
@@ -1561,7 +1637,8 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1561
  * @access public
1562
  */
1563
  public function get_tinymce_form() {
1564
- die( include FEEDZY_ABSPATH . '/form/form.php' );
 
1565
  }
1566
 
1567
  /**
@@ -1585,7 +1662,7 @@ abstract class Feedzy_Rss_Feeds_Admin_Abstract {
1585
  * @return mixed
1586
  */
1587
  public function load_layout( $layout_name ) {
1588
- include( FEEDZY_ABSPATH . '/includes/layouts/' . $layout_name . '.php' );
1589
  }
1590
 
1591
  /**
55
  public function get_usage_data( $data ) {
56
  global $wpdb;
57
 
58
+ // how many categories created.
59
  $categories = 0;
60
+ $terms = get_terms( array( 'taxonomy' => 'feedzy_categories' ) );
61
  if ( is_array( $terms ) ) {
62
  $categories = count( $terms );
63
  }
64
+ // imports.
65
+ $imports = array();
66
+ $license = 'free';
67
  if ( feedzy_is_pro() ) {
68
+ $license = 'pro';
69
  if ( apply_filters( 'feedzy_is_license_of_type', false, 'agency' ) ) {
70
  $license = 'agency';
71
  } elseif ( apply_filters( 'feedzy_is_license_of_type', false, 'business' ) ) {
73
  }
74
 
75
  $integrations = array();
76
+ $settings = get_option( 'feedzy-rss-feeds-settings' );
77
  if ( 'agency' === $license && $settings ) {
78
  if ( isset( $settings['spinnerchief_licence'] ) && 'yes' === $settings['spinnerchief_licence'] ) {
79
  $integrations[] = 'spinnerchief';
83
  }
84
  }
85
 
86
+ $imports = apply_filters(
87
+ 'feedzy_usage_data',
88
+ array(
89
+ // how many active imports are created.
90
+ 'publish' => count(
91
+ get_posts(
92
+ array(
93
+ 'post_type' => 'feedzy_imports',
94
+ 'post_status' => 'publish',
95
+ 'numberposts' => 99,
96
+ 'fields' => 'ids',
97
+ )
98
+ )
99
+ ),
100
  // how many draft imports are created
101
+ 'draft' => count(
102
+ get_posts(
103
+ array(
104
+ 'post_type' => 'feedzy_imports',
105
+ 'post_status' => 'draft',
106
+ 'numberposts' => 99,
107
+ 'fields' => 'ids',
108
+ )
109
+ )
110
+ ),
111
  // how many posts were imported by the imports
112
+ 'imported' => count(
113
+ get_posts(
114
+ array(
115
+ 'post_type' => 'post',
116
+ 'post_status' => array( 'publish', 'private', 'draft', 'trash' ),
117
+ 'numberposts' => 2999, //phpcs:ignore WordPress.WP.PostsPerPage.posts_per_page_numberposts
118
+ 'fields' => 'ids',
119
+ 'meta_key' => 'feedzy', //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
120
+ 'meta_value' => 1, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
121
+ )
122
+ )
123
+ ),
124
  // integrations
125
+ 'integrations' => $integrations,
126
  )
127
  );
128
  }
129
 
130
  $settings = apply_filters( 'feedzy_get_settings', null );
131
+ $config = array();
132
  if ( $settings ) {
133
  $proxy = isset( $settings['proxy'] ) && is_array( $settings['proxy'] ) && ! empty( $settings['proxy'] ) ? array_filter( $settings['proxy'] ) : array();
134
  if ( ! empty( $proxy ) ) {
138
 
139
  // how many posts contain the shortcode
140
  global $wpdb;
141
+ $shortcodes = $wpdb->get_var( "SELECT count(*) FROM {$wpdb->prefix}posts WHERE post_status IN ('publish', 'private') AND post_content LIKE '%[feedzy-rss %'" ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
142
+ $data = array(
143
+ 'categories' => $categories,
144
+ 'imports' => $imports,
145
+ 'shortcodes' => $shortcodes,
146
+ 'license' => $license,
147
+ 'config' => $config,
148
  );
149
 
150
  return $data;
171
  // Or if this is in the dry run window.
172
  // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
173
  $show_error = is_admin() || ( is_user_logged_in() && $post && get_current_user_id() == $post->post_author );
174
+ $error_msg = '';
175
 
176
  if ( is_array( $errors ) ) {
177
  foreach ( $errors as $i => $error ) {
227
  public function feedzy_add_item_padding( $item_attr, $sizes ) {
228
  $padding_top = number_format( ( 15 / 150 ) * $sizes['height'], 0 );
229
  $padding_bottom = number_format( ( 25 / 150 ) * $sizes['height'], 0 );
230
+ $style_padding = ' style="padding: ' . $padding_top . 'px 0 ' . $padding_bottom . 'px"';
231
 
232
  return $item_attr . $style_padding;
233
  }
267
  * @return string
268
  */
269
  public function feedzy_summary_input_filter( $description, $content, $feed_url ) {
270
+ $description = trim( wp_strip_all_tags( $description ) );
271
  $description = trim( str_replace( array( '[…]', '[…]', '[&hellip;]' ), '', $description ) );
272
 
273
  return $description;
347
  global $post;
348
  if ( has_post_thumbnail( $post->ID ) ) {
349
  $post_thumbnail_id = get_post_thumbnail_id( $post->ID );
350
+ $attachment_meta = wp_get_attachment_metadata( $post_thumbnail_id );
351
+ $image_url = wp_get_attachment_image_src( $post_thumbnail_id, 'medium' );
352
+ echo '<enclosure url="' . esc_url( $image_url[0] ) . '" length="' . esc_attr( filesize( get_attached_file( $post_thumbnail_id ) ) ) . '" type="image/jpg" />';
353
+ echo '<media:content url="' . esc_url( $image_url[0] ) . '" width="' . esc_attr( $attachment_meta['sizes']['medium']['width'] ) . '" height="' . esc_attr( $attachment_meta['sizes']['medium']['height'] ) . '" medium="image" type="' . esc_attr( $attachment_meta['sizes']['medium']['mime-type'] ) . '" />';
354
 
355
  }
356
  }
367
  * @return bool|string
368
  */
369
  public function process_feed_source( $src ) {
370
+ $regex = '((https?|ftp)\:\/\/)?'; // Contains Protocol.
371
+ $regex .= '([a-z0-9+!*(),;?&=\$_.-]+(\:[a-z0-9+!*(),;?&=\$_.-]+)?@)?'; // Uses User and Pass.
372
+ $regex .= '([a-z0-9-.]*)\.([a-z]{2,3})'; // Has Host or IP.
373
+ $regex .= '(\:[0-9]{2,5})?'; // Uses Port.
374
+ $regex .= '(\/([a-z0-9+\$_-]\.?)+)*\/?'; // Has Path.
375
+ $regex .= '(\?[a-z+&\$_.-][a-z0-9;:@&%=+\/\$_.-]*)?'; // Has GET Query.
376
+ $regex .= '(#[a-z_.-][a-z0-9+\$_.-]*)?'; // Uses Anchor.
377
  if ( preg_match( "/^$regex$/", $src ) ) {
378
  // If it matches Regex ( it's not a slug ) so return the sources.
379
  return $src;
380
  } else {
381
+ $src = trim( $src );
382
+ $post = get_page_by_path( $src, OBJECT, 'feedzy_categories' );
383
+ if ( $post ) {
384
  return trim( preg_replace( '/\s+/', ' ', get_post_meta( $post->ID, 'feedzy_category_feed', true ) ) );
385
  } else {
386
  return $src;
401
  * @return mixed
402
  */
403
  public function feedzy_rss( $atts, $content = '' ) {
404
+ wp_print_styles( $this->plugin_name );
405
  $sc = $this->get_short_code_attributes( $atts );
406
  $feed_url = $this->normalize_urls( $sc['feeds'] );
407
  if ( empty( $feed_url ) ) {
408
  return $content;
409
  }
410
+ $cache = $sc['refresh'];
411
 
412
  // Disregard the pseudo-shortcode coming from Gutenberg as a lazy one.
413
+ if ( ( true === $sc['lazy'] || 'yes' === $sc['lazy'] ) && ! isset( $sc['gutenberg'] ) ) {
 
414
  $attributes = '';
415
  foreach ( $sc as $key => $val ) {
416
  // ignore the feedData, its not required.
417
+ if ( 'feedData' === $key ) {
418
  continue;
419
  }
420
  if ( is_array( $val ) ) {
421
  $val = implode( ',', $val );
422
  }
423
+ $attributes .= 'data-' . esc_attr( $key ) . '="' . esc_attr( $val ) . '"';
424
  }
425
  $content = get_transient( sprintf( 'feedzy-lazy-%s', is_array( $feed_url ) ? implode( ',', $feed_url ) : $feed_url ) );
426
 
427
+ $class = array_filter( apply_filters( 'feedzy_add_classes_block', array( $sc['className'], 'feedzy-' . md5( is_array( $feed_url ) ? implode( ',', $feed_url ) : $feed_url ) ), $sc, null, $feed_url ) );
428
+ $html = "<div class='feedzy-lazy' $attributes>";
429
  // the first time the shortcode is being called it will not have any content.
430
  if ( empty( $content ) ) {
431
  $content = apply_filters( 'feedzy_lazyload_loading_msg', __( 'Loading', 'feedzy-rss-feeds' ) . '...', $feed_url );
434
 
435
  wp_register_script( $this->plugin_name . '-lazy', FEEDZY_ABSURL . 'js/feedzy-lazy.js', array( 'jquery' ), $this->version, 'all' );
436
  wp_enqueue_script( $this->plugin_name . '-lazy' );
437
+ wp_localize_script(
438
+ $this->plugin_name . '-lazy',
439
+ 'feedzy',
440
+ array(
441
+ 'url' => get_rest_url( null, 'feedzy/v' . FEEDZY_REST_VERSION . '/lazy/' ),
442
+ 'rest_nonce' => wp_create_nonce( 'wp_rest' ),
443
+ 'nonce' => wp_create_nonce( 'feedzy' ),
444
+ )
445
+ );
446
  return $html;
447
  }
448
 
449
  if ( isset( $sc['_dry_run_tags_'] ) ) {
450
  if ( strpos( $sc['_dry_run_tags_'], 'item_full_content' ) !== false ) {
451
+ $sc_clone = $sc;
452
  $sc_clone['__jobID'] = ''; // pro expects this but keep it empty.
453
+ $tmp_feed_url = apply_filters( 'feedzy_import_feed_url', $feed_url, '[#item_full_content]', $sc_clone );
454
+ if ( ! is_wp_error( $tmp_feed_url ) ) {
455
+ $feed_url = $tmp_feed_url;
456
  }
457
  }
458
  }
459
 
460
+ $feed = $this->fetch_feed( $feed_url, $cache, $sc );
461
  if ( is_string( $feed ) ) {
462
  return $feed;
463
  }
473
  */
474
  public function rest_route() {
475
  register_rest_route(
476
+ 'feedzy/v' . FEEDZY_REST_VERSION,
477
+ '/lazy/',
478
+ array(
479
+ 'methods' => 'POST',
480
+ 'callback' => array( $this, 'feedzy_lazy_load' ),
481
  'permission_callback' => '__return_true',
482
+ 'args' => array(
483
  'nonce' => array(
484
  'validate_callback' => function( $value ) {
485
  return wp_verify_nonce( $value, 'feedzy' );
486
  },
487
+ 'required' => true,
488
  ),
489
  ),
490
  )
500
  * @param array $data The attributes passed by the ajax call.
501
  */
502
  public function feedzy_lazy_load( $data ) {
503
+ $atts = $data['args'];
504
+ $sc = $this->get_short_code_attributes( $atts );
505
  $feed_url = $this->normalize_urls( $sc['feeds'] );
506
+ $feed = $this->fetch_feed( $feed_url, $sc['refresh'], $sc );
507
  if ( is_string( $feed ) ) {
508
  return $feed;
509
  }
527
  * @return array
528
  */
529
  public function get_short_code_attributes( $atts ) {
530
+ // Retrieve & extract shortcode parameters.
531
  $sc = shortcode_atts(
532
  array(
533
+ // comma separated feeds url.
534
  'feeds' => '',
535
+ // number of feeds items (0 for unlimited).
536
  'max' => '5',
537
+ // display feed title yes/no.
538
  'feed_title' => 'yes',
539
  // _blank, _self
540
  'target' => '_blank',
541
+ // empty or no for nofollow.
542
  'follow' => '',
543
  // strip title after X char. X can be 0 too, which will remove the title.
544
  'title' => '',
545
  // yes (author, date, time), no (NEITHER), author, date, time, categories
546
  // tz=local (for date/time in blog time)
547
  // tz=gmt (for date/time in UTC time, this is the default)
548
+ // tz=no (for date/time in the feed, without conversion).
549
  'meta' => 'yes',
550
  // yes (all), no (NEITHER)
551
+ // source: show feed title.
552
+ 'multiple_meta' => 'no',
553
+ // strip title.
554
  'summary' => 'yes',
555
+ // strip summary after X char.
556
  'summarylength' => '',
557
+ // yes, no, auto.
558
  'thumb' => 'auto',
559
+ // default thumb URL if no image found (only if thumb is set to yes or auto).
560
  'default' => '',
561
+ // thumbs pixel size.
562
  'size' => '',
563
+ // only display item if title contains specific keywords (comma-separated list/case sensitive).
564
  'keywords_title' => '',
565
+ // only display item if title OR content contains specific keywords (comma-separated list/case sensitive).
566
+ 'keywords_inc' => '',
567
+ // cache refresh.
568
  'refresh' => '12_hours',
569
  // sorting.
570
  'sort' => '',
571
  // https = force https
572
  // default = fall back to default image
573
+ // auto = continue as it is.
574
+ 'http' => 'auto',
575
+ // message to show when feed is empty.
576
+ 'error_empty' => 'Feed has no items.',
577
  // to disable amp support, use 'no'. This is currently not available as part of the shortcode tinymce form.
578
+ 'amp' => 'yes',
579
+ // paginate.
580
+ 'offset' => 0,
581
+ // class name of this block.
582
+ 'className' => '',
583
  // lazy loading of feeds?
584
+ 'lazy' => 'no',
585
+ // these are only for internal purposes.
586
+ '_dryrun_' => 'no',
587
+ '_dry_run_tags_' => '',
588
  ),
589
  $atts,
590
  'feedzy_default'
605
  * @return mixed|void Urls of the feeds.
606
  */
607
  public function normalize_urls( $raw ) {
608
+ $feeds = apply_filters( 'feedzy_process_feed_source', $raw );
609
  $feed_url = apply_filters( 'feedzy_get_feed_url', $feeds );
610
  if ( is_array( $feed_url ) ) {
611
  foreach ( $feed_url as $index => $url ) {
630
  // Automatically fix deprecated google news feeds.
631
  if ( false !== strpos( $url, 'news.google.' ) ) {
632
 
633
+ $parts = wp_parse_url( $url );
634
  parse_str( $parts['query'], $query );
635
 
636
  if ( isset( $query['q'] ) ) {
658
  * @return SimplePie|string|void|WP_Error The feed resource.
659
  */
660
  public function fetch_feed( $feed_url, $cache = '12_hours', $sc ) {
661
+ // Load SimplePie if not already.
662
  do_action( 'feedzy_pre_http_setup', $feed_url );
663
 
664
+ // Load SimplePie Instance.
665
  $feed = $this->init_feed( $feed_url, $cache, $sc ); // Not used as log as #41304 is Opened.
666
 
667
+ // Report error when is an error loading the feed.
668
  if ( is_wp_error( $feed ) ) {
669
  // Fallback for different edge cases.
670
  if ( is_array( $feed_url ) ) {
681
 
682
  do_action( 'feedzy_post_http_teardown', $feed_url );
683
 
 
684
  return $feed;
685
  }
686
 
687
  /**
 
688
  * Method to avoid using core implementation in order
689
  * order to fix issues reported here: https://core.trac.wordpress.org/ticket/41304
690
  * Bug: #41304 with WP wp_kses sanitizer used by WP SimplePie implementation.
697
  * @param string $feed_url The feed URL.
698
  * @param string $cache The cache string (eg. 1_hour, 30_min etc.).
699
  * @param array $sc The shortcode attributes.
700
+ * @param bool $allow_https Defaults to constant FEEDZY_ALLOW_HTTPS.
701
  *
702
  * @return SimplePie
703
  */
708
  'days' => DAY_IN_SECONDS,
709
  );
710
  $cache_time = 12 * HOUR_IN_SECONDS;
711
+ if ( isset( $cache ) && '' !== $cache ) {
712
  list( $value, $unit ) = explode( '_', $cache );
713
  if ( isset( $value ) && is_numeric( $value ) && $value >= 1 && $value <= 100 ) {
714
  if ( isset( $unit ) && in_array( strtolower( $unit ), array( 'mins', 'hours', 'days' ), true ) ) {
726
  )
727
  );
728
  }
729
+ require_once ABSPATH . WPINC . '/class-wp-feed-cache-transient.php';
730
+ require_once ABSPATH . WPINC . '/class-wp-simplepie-file.php';
731
 
732
  $feed->set_file_class( 'WP_SimplePie_File' );
733
  $default_agent = $this->get_default_user_agent( $feed_url );
736
  SimplePie_Cache::register( 'wp_transient', 'WP_Feed_Cache_Transient' );
737
  $feed->set_cache_location( 'wp_transient' );
738
  add_filter(
739
+ 'wp_feed_cache_transient_lifetime',
740
+ function( $time ) use ( $cache_time ) {
741
  return $cache_time;
742
+ },
743
+ 10,
744
+ 1
745
  );
746
  } else {
747
+ require_once ABSPATH . 'wp-admin/includes/file.php';
748
  WP_Filesystem();
749
  global $wp_filesystem;
750
 
751
+ $dir = $wp_filesystem->wp_content_dir() . 'uploads/simplepie';
752
  if ( ! $wp_filesystem->exists( $dir ) ) {
753
+ $done = $wp_filesystem->mkdir( $dir );
754
+ if ( false === $done ) {
755
  do_action( 'themeisle_log_event', FEEDZY_NAME, sprintf( 'Unable to create directory %s', $dir ), 'error', __FILE__, __LINE__ );
756
  }
757
  }
766
  $cloned_feed = clone $feed;
767
 
768
  // set the url as the last step, because we need to be able to clone this feed without the url being set
769
+ // so that we can fall back to raw data in case of an error.
770
  $feed->set_feed_url( $feed_url );
771
 
772
+ if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
773
+ $set_server_agent = sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) );
774
+ $feed->set_useragent( apply_filters( 'http_headers_useragent', $set_server_agent ) );
775
+ }
776
+
777
  global $feedzy_current_error_reporting;
778
  $feedzy_current_error_reporting = error_reporting();
779
 
782
  error_reporting( E_ALL ^ E_WARNING );
783
  // reset the error_reporting back to its original value.
784
  add_action(
785
+ 'shutdown',
786
+ function() {
787
  global $feedzy_current_error_reporting;
788
  error_reporting( $feedzy_current_error_reporting );
789
  }
807
  $feed = $this->init_feed( $feed_url, $cache, $sc, false );
808
  } elseif ( is_string( $feed_url ) || ( is_array( $feed_url ) && 1 === count( $feed_url ) ) ) {
809
  do_action( 'themeisle_log_event', FEEDZY_NAME, 'Trying to use raw data', 'debug', __FILE__, __LINE__ );
810
+ $data = wp_remote_retrieve_body( wp_remote_get( $feed_url, array( 'user-agent' => $default_agent ) ) );
811
  $cloned_feed->set_raw_data( $data );
812
  $cloned_feed->init();
813
  $error_raw = $cloned_feed->error();
814
  if ( empty( $error_raw ) ) {
815
  // only if using the raw url produces no errors, will we consider the new feed as good to go.
816
+ // otherwise we will use the old feed.
817
  $feed = $cloned_feed;
818
  }
819
  } else {
865
  $valid_feed_url[] = $url;
866
  } else {
867
  if ( $echo ) {
868
+ echo wp_kses_post( sprintf( __( 'Feed URL: %s not valid and removed from fetch.', 'feedzy-rss-feeds' ), '<b>' . esc_url( $url ) . '</b>' ) );
869
  }
870
  }
871
  }
874
  $valid_feed_url[] = $feed_url;
875
  } else {
876
  if ( $echo ) {
877
+ echo wp_kses_post( sprintf( __( 'Feed URL: %s not valid and removed from fetch.', 'feedzy-rss-feeds' ), '<b>' . esc_url( $feed_url ) . '</b>' ) );
878
  }
879
  }
880
  }
894
  * @return bool
895
  */
896
  protected function check_valid_xml( $url, $cache ) {
897
+ global $post;
898
  $feed = $this->init_feed( $url, $cache, array() );
899
  if ( $feed->error() ) {
900
  return false;
901
  }
902
 
903
+ $feed_child = array_keys( $feed->get_item()->data['child'] );
904
+ $feed_child = array_filter( $feed_child );
905
+ if ( ! in_array( SIMPLEPIE_NAMESPACE_DC_10, $feed_child, true ) && ! in_array( SIMPLEPIE_NAMESPACE_DC_11, $feed_child, true ) ) {
906
+ update_post_meta( $post->ID, '__transient_feedzy_invalid_dc_namespace', array( $url ) );
907
+ return false;
908
+ }
909
  return true;
910
  }
911
 
922
  */
923
  public function sanitize_attr( $sc, $feed_url ) {
924
  // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
925
+ if ( '0' == $sc['max'] ) {
926
  $sc['max'] = '999';
927
  } elseif ( empty( $sc['max'] ) || ! is_numeric( $sc['max'] ) ) {
928
  $sc['max'] = '5';
981
  'height' => $sc['size'],
982
  );
983
  $sizes = apply_filters( 'feedzy_thumb_sizes', $sizes, $feed_url );
984
+ $feed_title = $this->get_feed_title_filter( $feed, $sc, $feed_url );
985
  $feed_title['use_title'] = false;
986
  if ( $sc['feed_title'] === 'yes' ) {
 
987
  $feed_title['use_title'] = true;
988
  }
989
  // Display the error message and quit (before showing the template for pro).
992
  }
993
 
994
  $feed_items = apply_filters( 'feedzy_get_feed_array', array(), $sc, $feed, $feed_url, $sizes );
995
+ $class = array_filter( apply_filters( 'feedzy_add_classes_block', array( $sc['className'], 'feedzy-' . md5( is_array( $feed_url ) ? implode( ',', $feed_url ) : $feed_url ) ), $sc, $feed, $feed_url ) );
996
+ $content .= '<div class="feedzy-rss ' . implode( ' ', $class ) . '">';
997
  if ( $feed_title['use_title'] ) {
998
  $content .= '<div class="rss_header">';
999
  $content .= '<h2><a href="' . $feed->get_permalink() . '" class="rss_title" rel="noopener">' . html_entity_decode( $feed->get_title() ) . '</a> <span class="rss_description"> ' . $feed->get_description() . '</span></h2>';
1008
  return $content;
1009
  }
1010
 
1011
+ $anchor1 = '<a href="%s" target="%s" rel="%s noopener" title="%s" style="%s">%s</a>';
1012
+ $anchor2 = '<a href="%s" target="%s" rel="%s noopener">%s</a>';
1013
+ $line_item = '<li %s>%s<span class="title">%s</span><div class="%s" style="%s">%s%s</div></li>';
1014
  $dry_run_item = '<li %s><span class="title">%s</span><div class="dry_run">%s</div></li>';
1015
+ $is_dry_run = isset( $sc['_dryrun_'] ) && 'yes' === $sc['_dryrun_'];
1016
  foreach ( $feed_items as $item ) {
1017
  if ( $is_dry_run ) {
1018
+ $details = $this->get_dry_run_results( $sc, $item );
1019
  $content .= sprintf(
1020
  $dry_run_item,
1021
  $item['itemAttr'],
1026
  $content .= sprintf(
1027
  $line_item,
1028
  $item['itemAttr'],
1029
+ ! empty( $item['item_img'] ) && 'no' !== $sc['thumb'] ? sprintf( '<div class="%s" style="%s">%s</div>', $item['item_img_class'], $item['item_img_style'], sprintf( $anchor1, $item['item_url'], $item['item_url_target'], $item['item_url_follow'], $item['item_url_title'], $item['item_img_style'], $item['item_img'] ) ) : '',
1030
  sprintf( $anchor2, $item['item_url'], $item['item_url_target'], $item['item_url_follow'], $item['item_title'] ),
1031
  $item['item_content_class'],
1032
  $item['item_content_style'],
1055
  */
1056
  private function get_dry_run_results( $sc, $item ) {
1057
  $statuses = array();
1058
+ $details = '';
1059
  if ( true === apply_filters( 'feedzy_is_license_of_type', false, 'business' ) ) {
1060
  if ( ! empty( $item['full_content_error'] ) ) {
1061
+ $statuses[] = array(
1062
+ 'success' => false,
1063
+ 'msg' => sprintf( __( 'Full content: %s', 'feedzy-rss-feeds' ), $item['full_content_error'] ),
1064
+ );
1065
  } elseif ( isset( $item['item_full_content'] ) ) {
1066
  if ( ! empty( $item['item_full_content'] ) ) {
1067
+ $statuses[] = array(
1068
+ 'success' => true,
1069
+ 'msg' => __( 'Full content extracted', 'feedzy-rss-feeds' ),
1070
+ );
1071
  } else {
1072
+ $statuses[] = array(
1073
+ 'success' => true,
1074
+ 'msg' => __( 'Full content extracted (is empty)', 'feedzy-rss-feeds' ),
1075
+ );
1076
  }
1077
  }
1078
  }
1079
  if ( strpos( $sc['_dry_run_tags_'], 'item_image' ) !== false ) {
1080
  if ( ! empty( $item['item_img_path'] ) ) {
1081
+ $statuses[] = array(
1082
+ 'success' => true,
1083
+ 'msg' => __( 'Image', 'feedzy-rss-feeds' ),
1084
+ );
1085
  } else {
1086
+ $statuses[] = array(
1087
+ 'success' => false,
1088
+ 'msg' => __( 'Unable to find image', 'feedzy-rss-feeds' ),
1089
+ );
1090
  }
1091
  }
1092
 
1122
  'rss_title' => html_entity_decode( $feed->get_title() ),
1123
  'rss_description_class' => 'rss_description',
1124
  'rss_description' => $feed->get_description(),
1125
+ 'rss_classes' => array( $sc['className'], 'feedzy-' . md5( $feed_url ) ),
1126
  );
1127
  }
1128
 
1139
  public function get_feed_url( $feeds ) {
1140
  $feed_url = '';
1141
  if ( ! empty( $feeds ) ) {
1142
+ $feeds = rtrim( $feeds, ',' );
1143
+ $feeds = explode( ',', $feeds );
1144
  $feed_url = array();
1145
+ // Remove SSL from HTTP request to prevent fetching errors.
1146
  foreach ( $feeds as $feed ) {
1147
  $feed = trim( $feed );
1148
  // scheme-less URLs.
1184
  $index = 0;
1185
  foreach ( (array) $items as $item ) {
1186
  $continue = apply_filters( 'feedzy_item_keyword', true, $sc, $item, $feed_url, $index );
1187
+ if ( true === $continue ) {
1188
  // Count items. This should be > and not >= because max, when not defined and empty, becomes 0.
1189
  if ( $count >= $sc['max'] ) {
1190
  break;
1191
  }
1192
+ $item_attr = apply_filters( 'feedzy_item_attributes', $item_attr = '', $sizes, $item, $feed_url, $sc, $index );
1193
  $feed_items[ $count ] = $this->get_feed_item_filter( $sc, $sizes, $item, $feed_url, $count, $index );
1194
  $feed_items[ $count ]['itemAttr'] = $item_attr;
1195
  $count++;
1217
  */
1218
  private function get_feed_item_filter( $sc, $sizes, $item, $feed_url, $index, $item_index ) {
1219
  $item_link = $item->get_permalink();
1220
+ // if the item has no link (possible in some cases), use the feed link.
1221
  if ( empty( $item_link ) ) {
1222
  $item_link = $item->get_feed()->get_permalink();
1223
  }
1224
+ $new_link = apply_filters( 'feedzy_item_url_filter', $item_link, $sc, $item );
1225
 
1226
+ // Fetch image thumbnail.
1227
+ if ( 'yes' === $sc['thumb'] || 'auto' === $sc['thumb'] ) {
1228
  $the_thumbnail = $this->feedzy_retrieve_image( $item, $sc );
1229
  }
1230
+ if ( 'yes' === $sc['thumb'] || 'auto' === $sc['thumb'] ) {
1231
  $content_thumb = '';
1232
+ if ( ( ! empty( $the_thumbnail ) && 'auto' === $sc['thumb'] ) || 'yes' === $sc['thumb'] ) {
1233
  if ( ! empty( $the_thumbnail ) ) {
1234
+ $the_thumbnail = $this->feedzy_image_encode( $the_thumbnail );
1235
  $content_thumb .= '<span class="fetched" style="background-image: url(\'' . $the_thumbnail . '\');" title="' . esc_html( $item->get_title() ) . '"></span>';
1236
  if ( ! isset( $sc['amp'] ) || 'no' !== $sc['amp'] ) {
1237
  $content_thumb .= '<amp-img width="' . $sizes['width'] . '" height="' . $sizes['height'] . '" src="' . $the_thumbnail . '">';
1238
  }
1239
  }
1240
+ if ( empty( $the_thumbnail ) && 'yes' === $sc['thumb'] ) {
1241
  $content_thumb .= '<span class="default" style="background-image:url(' . $sc['default'] . ');" title="' . esc_html( $item->get_title() ) . '"></span>';
1242
  if ( ! isset( $sc['amp'] ) || 'no' !== $sc['amp'] ) {
1243
  $content_thumb .= '<amp-img width="' . $sizes['width'] . '" height="' . $sizes['height'] . '" src="' . $sc['default'] . '">';
1246
  }
1247
  $content_thumb = apply_filters( 'feedzy_thumb_output', $content_thumb, $feed_url, $sizes, $item );
1248
  } else {
1249
+ $content_thumb = '';
1250
  $content_thumb .= '<span class="default" style="width:' . $sizes['width'] . 'px; height:' . $sizes['height'] . 'px; background-image:url(' . $sc['default'] . ');" title="' . $item->get_title() . '"></span>';
1251
  if ( ! isset( $sc['amp'] ) || 'no' !== $sc['amp'] ) {
1252
  $content_thumb .= '<amp-img width="' . $sizes['width'] . '" height="' . $sizes['height'] . '" src="' . $sc['default'] . '">';
1258
  $length = intval( $sc['title'] );
1259
  if ( $length > 0 && strlen( $content_title ) > $length ) {
1260
  $content_title = preg_replace( '/\s+?(\S+)?$/', '', substr( $content_title, 0, $length ) ) . '...';
1261
+ } elseif ( 0 === $length ) {
1262
  $content_title = '';
1263
  }
1264
  }
1267
  // meta=yes is for backward compatibility, otherwise its always better to provide the fields with granularity.
1268
  // if meta=yes, then meta will be placed in default order. Otherwise in the order stated by the user.
1269
  $meta_args = array(
1270
+ 'author' => 'yes' === $sc['meta'] || strpos( $sc['meta'], 'author' ) !== false,
1271
+ 'date' => 'yes' === $sc['meta'] || strpos( $sc['meta'], 'date' ) !== false,
1272
+ 'time' => 'yes' === $sc['meta'] || strpos( $sc['meta'], 'time' ) !== false,
1273
+ 'source' => 'yes' === $sc['multiple_meta'] || strpos( $sc['multiple_meta'], 'source' ) !== false,
1274
  'categories' => strpos( $sc['meta'], 'categories' ) !== false,
1275
+ 'tz' => 'gmt',
1276
  'date_format' => get_option( 'date_format' ),
1277
  'time_format' => get_option( 'time_format' ),
1278
  );
1284
  if ( strpos( $configs, '=' ) === false ) {
1285
  continue;
1286
  }
1287
+ $config = explode( '=', $configs );
1288
  $meta_args[ $config[0] ] = $config[1];
1289
  }
1290
  }
1291
 
1292
+ // Filter: feedzy_meta_args.
1293
+ $meta_args = apply_filters( 'feedzy_meta_args', $meta_args, $feed_url, $item );
1294
 
1295
  // order of the meta tags.
1296
  $meta_order = array( 'author', 'date', 'time', 'categories' );
1297
+ if ( 'yes' !== $sc['meta'] ) {
1298
  $meta_order = array_map( 'trim', explode( ',', $sc['meta'] ) );
1299
  }
1300
 
1301
  $content_meta_values = array();
1302
 
1303
  // multiple sources?
1304
+ $is_multiple = is_array( $feed_url );
1305
+ $feed_source = $item->get_feed()->get_title();
1306
 
1307
  // author.
1308
  if ( $item->get_author() && $meta_args['author'] ) {
1309
+ $author = $item->get_author();
1310
+ $author_name = $author->get_name();
1311
+ if ( ! $author_name ) {
1312
  $author_name = $author->get_email();
1313
  }
1314
 
1319
  }
1320
 
1321
  if ( $author_name ) {
1322
+ $domain = wp_parse_url( $new_link );
1323
+ $author_url = '//' . $domain['host'];
1324
+ $author_url = apply_filters( 'feedzy_author_url', $author_url, $author_name, $feed_url, $item );
1325
  $content_meta_values['author'] = apply_filters( 'feedzy_meta_author', __( 'by', 'feedzy-rss-feeds' ) . ' <a href="' . $author_url . '" target="' . $sc['target'] . '" title="' . $domain['host'] . '" >' . $author_name . '</a> ', $author_name, $author_url, $feed_source, $feed_url, $item );
1326
  }
1327
  }
1328
 
1329
  // date/time.
1330
+ $date_time = $item->get_date( 'U' );
1331
+ if ( 'local' === $meta_args['tz'] ) {
1332
+ $date_time = get_date_from_gmt( $item->get_date( 'Y-m-d H:i:s' ), 'U' );
1333
  // strings such as Asia/Kolkata need special handling.
1334
  $tz = get_option( 'timezone_string' );
1335
  if ( $tz ) {
1336
  $date_time = gmdate( 'U', $date_time + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
1337
  }
1338
+ } elseif ( 'no' === $meta_args['tz'] ) {
1339
  // change the tz component of the date to UTC.
1340
+ $raw_date = preg_replace( '/\++(\d\d\d\d)/', '+0000', $item->get_date( '' ) );
1341
+ $date = DateTime::createFromFormat( DATE_RFC2822, $raw_date );
1342
+ $date_time = $date->format( 'U' );
1343
  }
1344
 
1345
+ $date_time = apply_filters( 'feedzy_feed_timestamp', $date_time, $feed_url, $item );
1346
  if ( $meta_args['date'] && ! empty( $meta_args['date_format'] ) ) {
1347
  $content_meta_values['date'] = apply_filters( 'feedzy_meta_date', __( 'on', 'feedzy-rss-feeds' ) . ' ' . date_i18n( $meta_args['date_format'], $date_time ) . ' ', $date_time, $feed_url, $item );
1348
  }
1359
  }
1360
  }
1361
 
1362
+ $content_meta = '';
1363
+ $content_meta_date = '';
1364
  foreach ( $meta_order as $meta ) {
1365
  if ( isset( $content_meta_values[ $meta ] ) ) {
1366
  // collect date/time values separately too.
1373
 
1374
  $content_meta = apply_filters( 'feedzy_meta_output', $content_meta, $feed_url, $item, $content_meta_values, $meta_order );
1375
  $content_summary = '';
1376
+ if ( 'yes' === $sc['summary'] ) {
1377
+ $description = $item->get_description();
1378
+ $description = apply_filters( 'feedzy_summary_input', $description, $item->get_content(), $feed_url, $item );
1379
  $content_summary = $description;
1380
  if ( is_numeric( $sc['summarylength'] ) && strlen( $description ) > $sc['summarylength'] ) {
1381
  $content_summary = preg_replace( '/\s+?(\S+)?$/', '', substr( $description, 0, $sc['summarylength'] ) ) . ' [&hellip;]';
1383
  $content_summary = apply_filters( 'feedzy_summary_output', $content_summary, $new_link, $feed_url, $item );
1384
  }
1385
  $item_array = array(
1386
+ 'item_img_class' => 'rss_image',
1387
+ 'item_img_style' => 'width:' . $sizes['width'] . 'px; height:' . $sizes['height'] . 'px;',
1388
+ 'item_url' => $new_link,
1389
+ 'item_url_target' => $sc['target'],
1390
+ 'item_url_follow' => isset( $sc['follow'] ) && 'no' === $sc['follow'] ? 'nofollow' : '',
1391
+ 'item_url_title' => $item->get_title(),
1392
+ 'item_img' => $content_thumb,
1393
+ 'item_img_path' => $this->feedzy_retrieve_image( $item, $sc ),
1394
+ 'item_title' => $content_title,
1395
+ 'item_content_class' => 'rss_content',
1396
+ 'item_content_style' => '',
1397
+ 'item_meta' => $content_meta,
1398
+ 'item_date' => $item->get_date( 'U' ),
1399
  'item_date_formatted' => $content_meta_date,
1400
+ 'item_author' => $item->get_author(),
1401
+ 'item_description' => $content_summary,
1402
+ 'item_content' => apply_filters( 'feedzy_content', $item->get_content( false ), $item ),
1403
+ 'item_source' => $feed_source,
1404
  );
1405
  $item_array = apply_filters( 'feedzy_item_filter', $item_array, $item, $sc, $index, $item_index );
1406
 
1429
  $image_mime_types = apply_filters( 'feedzy_image_mime_types', $image_mime_types );
1430
 
1431
  $the_thumbnail = '';
1432
+ $enclosures = $item->get_enclosures();
1433
+ if ( $enclosures ) {
1434
  foreach ( (array) $enclosures as $enclosure ) {
1435
+ // Item thumbnail.
1436
+ $thumbnail = $enclosure->get_thumbnail();
1437
+ if ( $thumbnail ) {
1438
  $the_thumbnail = $thumbnail;
1439
  }
1440
  if ( isset( $enclosure->thumbnails ) ) {
1442
  $the_thumbnail = $thumbnail;
1443
  }
1444
  }
1445
+ $thumbnail = $enclosure->embed();
1446
+ if ( $thumbnail ) {
1447
  $pattern = '/https?:\/\/.*\.(?:jpg|JPG|jpeg|JPEG|jpe|JPE|gif|GIF|png|PNG)/i';
1448
  if ( preg_match( $pattern, $thumbnail, $matches ) ) {
1449
  $the_thumbnail = $matches[0];
1460
  break;
1461
  }
1462
  }
1463
+ // Break loop if thumbnail is found.
1464
  if ( ! empty( $the_thumbnail ) ) {
1465
  break;
1466
  }
1467
  }
1468
  }
1469
+ // xmlns:itunes podcast.
1470
  if ( empty( $the_thumbnail ) ) {
1471
  $data = $item->get_item_tags( 'http://www.itunes.com/dtds/podcast-1.0.dtd', 'image' );
1472
  if ( isset( $data['0']['attribs']['']['href'] ) && ! empty( $data['0']['attribs']['']['href'] ) ) {
1473
  $the_thumbnail = $data['0']['attribs']['']['href'];
1474
  }
1475
  }
1476
+ // Content image.
1477
  if ( empty( $the_thumbnail ) ) {
1478
  $feed_description = $item->get_content();
1479
  $the_thumbnail = $this->feedzy_return_image( $feed_description );
1480
  }
1481
+ // Description image.
1482
  if ( empty( $the_thumbnail ) ) {
1483
  $feed_description = $item->get_description();
1484
  $the_thumbnail = $this->feedzy_return_image( $feed_description );
1615
  * @return string
1616
  */
1617
  public function feedzy_image_encode( $string ) {
1618
+ // Check if img url is set as an URL parameter.
1619
+ $url_tab = wp_parse_url( $string );
1620
  if ( isset( $url_tab['query'] ) ) {
1621
  preg_match_all( '/(http|https):\/\/[^ ]+(\.gif|\.GIF|\.jpg|\.JPG|\.jpeg|\.JPEG|\.png|\.PNG)/', $url_tab['query'], $img_url );
1622
  if ( isset( $img_url[0][0] ) ) {
1637
  * @access public
1638
  */
1639
  public function get_tinymce_form() {
1640
+ include FEEDZY_ABSPATH . '/form/form.php';
1641
+ die();
1642
  }
1643
 
1644
  /**
1662
  * @return mixed
1663
  */
1664
  public function load_layout( $layout_name ) {
1665
+ include FEEDZY_ABSPATH . '/includes/layouts/' . $layout_name . '.php';
1666
  }
1667
 
1668
  /**
includes/admin/feedzy-rss-feeds-admin.php CHANGED
@@ -116,7 +116,7 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
116
  return;
117
  }
118
 
119
- if ( $screen->post_type === 'feedzy_categories' ) {
120
  wp_enqueue_script(
121
  $this->plugin_name . '_categories',
122
  FEEDZY_ABSURL . 'js/categories.js',
@@ -131,12 +131,12 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
131
  'feedzy',
132
  array(
133
  'ajax' => array(
134
- 'security' => wp_create_nonce( FEEDZY_NAME ),
135
  ),
136
  'l10n' => array(
137
- 'validate' => __( 'Validate & Clean', 'feedzy-rss-feeds' ),
138
  'validating' => __( 'Validating', 'feedzy-rss-feeds' ) . '...',
139
- 'validated' => __( 'Removed # URL(s)!', 'feedzy-rss-feeds' ),
140
  ),
141
  )
142
  );
@@ -151,8 +151,8 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
151
  if ( ! in_array( $screen->base, $upsell_screens, true ) && strpos( $screen->id, 'feedzy' ) === false ) {
152
  return;
153
  }
154
- wp_enqueue_style( $this->plugin_name . '-settings', FEEDZY_ABSURL . 'css/settings.css' );
155
- wp_enqueue_style( $this->plugin_name . '-metabox', FEEDZY_ABSURL . 'css/metabox-settings.css', array( $this->plugin_name . '-settings' ) );
156
  }
157
 
158
  /**
@@ -269,8 +269,8 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
269
  */
270
  public function feedzy_category_feed() {
271
  global $post;
272
- $nonce = wp_create_nonce( FEEDZY_BASEFILE );
273
- $feed = get_post_meta( $post->ID, 'feedzy_category_feed', true );
274
  $invalid = $this->get_source_validity_error( '', $post );
275
 
276
  $output = '
@@ -279,7 +279,7 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
279
  . $invalid
280
  . '<textarea name="feedzy_category_feed" rows="15" class="widefat" placeholder="' . __( 'Place your URL\'s here followed by a comma.', 'feedzy-rss-feeds' ) . '" >' . $feed . '</textarea>
281
  ';
282
- echo $output;
283
  }
284
 
285
  /**
@@ -295,16 +295,21 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
295
  * @return mixed|integer
296
  */
297
  public function save_feedzy_post_type_meta( $post_id, $post ) {
 
 
 
298
  if (
299
  empty( $_POST ) ||
300
- ! wp_verify_nonce( $_POST['feedzy_category_meta_noncename'], FEEDZY_BASEFILE ) ||
 
301
  ! current_user_can( 'edit_post', $post_id )
302
  ) {
303
  return $post_id;
304
  }
 
305
  $category_meta['feedzy_category_feed'] = array();
306
  if ( isset( $_POST['feedzy_category_feed'] ) ) {
307
- $category_meta['feedzy_category_feed'] = $_POST['feedzy_category_feed'];
308
  }
309
  if ( $post->post_type === 'revision' ) {
310
  return true;
@@ -386,13 +391,13 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
386
  case 'slug':
387
  $slug = $post->post_name;
388
  if ( empty( $slug ) ) {
389
- echo __( 'Undefined', 'feedzy-rss-feeds' );
390
  } else {
391
- echo '<code>' . $slug . '</code>';
392
  }
393
  break;
394
  case 'actions':
395
- echo sprintf( '<button class="button button-primary validate-category" title="%s" data-category-id="%d">%s</button>', __( 'Click to remove invalid URLs from this category', 'feedzy-rss-feeds' ), $post_id, __( 'Validate & Clean', 'feedzy-rss-feeds' ) );
396
  break;
397
  default:
398
  break;
@@ -413,7 +418,7 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
413
  */
414
  public function feedzy_filter_plugin_row_meta( $links, $file ) {
415
  if ( strpos( $file, 'feedzy-rss-feed.php' ) !== false ) {
416
- $new_links = array();
417
  $new_links['doc'] = '<a href="https://docs.themeisle.com/article/658-feedzy-rss-feeds" target="_blank" title="' . __( 'Documentation and examples', 'feedzy-rss-feeds' ) . '">' . __( 'Documentation and examples', 'feedzy-rss-feeds' ) . '</a>';
418
 
419
  if ( ! feedzy_is_pro() ) {
@@ -421,7 +426,7 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
421
  } elseif ( false === apply_filters( 'feedzy_is_license_of_type', false, 'agency' ) ) {
422
  $new_links['more_features'] = '<a href="' . FEEDZY_UPSELL_LINK . '" target="_blank" title="' . __( 'More Features', 'feedzy-rss-feeds' ) . '">' . __( 'Upgrade your license', 'feedzy-rss-feeds' ) . '<i style="width: 17px; height: 17px; margin-left: 4px; color: #ffca54; font-size: 17px; vertical-align: -3px;" class="dashicons dashicons-unlock more-features-icon"></i></a>';
423
  }
424
- $links = array_merge( $links, $new_links );
425
  }
426
 
427
  return $links;
@@ -467,13 +472,13 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
467
  * @access public
468
  */
469
  public function feedzy_settings_page() {
470
- if ( isset( $_POST['feedzy-settings-submit'] ) && isset( $_POST['tab'] ) && wp_verify_nonce( $_POST['nonce'], $_POST['tab'] ) ) {
471
  $this->save_settings();
472
  $this->notice = __( 'Your settings were saved.', 'feedzy-rss-feeds' );
473
  }
474
 
475
  $settings = apply_filters( 'feedzy_get_settings', array() );
476
- include( FEEDZY_ABSPATH . '/includes/layouts/settings.php' );
477
  }
478
 
479
  /**
@@ -482,24 +487,32 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
482
  * @access private
483
  */
484
  private function save_settings() {
 
 
 
 
 
 
 
 
485
  $settings = apply_filters( 'feedzy_get_settings', array() );
486
- switch ( $_POST['tab'] ) {
487
  case 'general':
488
- $settings['general']['rss-feeds'] = isset( $_POST['rss-feeds'] ) ? $_POST['rss-feeds'] : '';
489
  break;
490
  case 'headers':
491
- $settings['header']['user-agent'] = $_POST['user-agent'];
492
  break;
493
  case 'proxy':
494
  $settings['proxy'] = array(
495
- 'host' => $_POST['proxy-host'],
496
- 'port' => $_POST['proxy-port'],
497
- 'user' => $_POST['proxy-user'],
498
- 'pass' => $_POST['proxy-pass'],
499
  );
500
  break;
501
  default:
502
- $settings = apply_filters( 'feedzy_save_tab_settings', $settings, $_POST['tab'] );
503
  }
504
 
505
  update_option( 'feedzy-settings', $settings );
@@ -635,7 +648,15 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
635
  if ( get_option( 'feedzy-activated' ) ) {
636
  delete_option( 'feedzy-activated' );
637
  if ( ! headers_sent() ) {
638
- wp_redirect( add_query_arg( array( 'page' => 'feedzy-support', 'tab' => 'help#shortcode' ), admin_url( 'admin.php' ) ) );
 
 
 
 
 
 
 
 
639
  exit();
640
  }
641
  }
@@ -663,7 +684,7 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
663
  * @access public
664
  */
665
  public function check_source_validity( $src, $post_id, $add_pseudo_transient, $return_valid ) {
666
- $urls_in = $src;
667
  $post_type = get_post_type( $post_id );
668
  if ( 'feedzy_imports' === $post_type && strpos( $src, 'http' ) === false && strpos( $src, 'https' ) === false ) {
669
  // category
@@ -684,7 +705,7 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
684
  if ( ! is_array( $urls ) ) {
685
  $urls = array( $urls );
686
  }
687
- $valid = $this->get_valid_feed_urls( $urls, '1_mins', false );
688
  $invalid = array_diff( $urls, $valid );
689
 
690
  if ( $add_pseudo_transient && ( empty( $valid ) || ! empty( $invalid ) ) ) {
@@ -694,14 +715,17 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
694
  update_post_meta( $post_id, '__transient_feedzy_category_feed', $invalid );
695
  break;
696
  case 'feedzy_imports':
697
- update_post_meta( $post_id, '__transient_feedzy_invalid_source', $invalid );
 
 
 
698
  break;
699
  }
700
  }
701
 
702
  if ( is_null( $return_valid ) ) {
703
  return array(
704
- 'valid' => $valid,
705
  'invalid' => $invalid,
706
  );
707
  }
@@ -722,14 +746,22 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
722
  $invalid = $text = null;
723
  switch ( $post->post_type ) {
724
  case 'feedzy_categories':
725
- $text = __( 'We found the following invalid URLs that we have removed from the list', 'feedzy-rss-feeds' );
726
  $invalid = get_post_meta( $post->ID, '__transient_feedzy_category_feed', true );
727
  delete_post_meta( $post->ID, '__transient_feedzy_category_feed' );
728
  break;
729
  case 'feedzy_imports':
730
- $text = __( 'This source has invalid URLs. Please correct/remove the following', 'feedzy-rss-feeds' );
731
- $invalid = get_post_meta( $post->ID, '__transient_feedzy_invalid_source', true );
732
- delete_post_meta( $post->ID, '__transient_feedzy_invalid_source' );
 
 
 
 
 
 
 
 
733
  break;
734
  default:
735
  return $message;
@@ -757,16 +789,19 @@ class Feedzy_Rss_Feeds_Admin extends Feedzy_Rss_Feeds_Admin_Abstract {
757
  public function ajax() {
758
  check_ajax_referer( FEEDZY_NAME, 'security' );
759
 
760
- switch ( $_POST['_action'] ) {
 
 
 
761
  case 'validate_clean':
762
  // remove invalid URLs from this category.
763
- $urls = get_post_meta( $_POST['id'], 'feedzy_category_feed', true );
764
- $return = $this->check_source_validity( $urls, $_POST['id'], false, null );
765
- $valid = $return['valid'];
766
  $invalid = $return['invalid'];
767
  if ( ! empty( $valid ) ) {
768
  remove_filter( 'update_post_metadata', array( $this, 'validate_category_feeds' ) );
769
- update_post_meta( $_POST['id'], 'feedzy_category_feed', implode( ', ', $valid ) );
770
  }
771
  wp_send_json_success( array( 'invalid' => count( $invalid ) ) );
772
  break;
116
  return;
117
  }
118
 
119
+ if ( 'feedzy_categories' === $screen->post_type ) {
120
  wp_enqueue_script(
121
  $this->plugin_name . '_categories',
122
  FEEDZY_ABSURL . 'js/categories.js',
131
  'feedzy',
132
  array(
133
  'ajax' => array(
134
+ 'security' => wp_create_nonce( FEEDZY_NAME ),
135
  ),
136
  'l10n' => array(
137
+ 'validate' => __( 'Validate & Clean', 'feedzy-rss-feeds' ),
138
  'validating' => __( 'Validating', 'feedzy-rss-feeds' ) . '...',
139
+ 'validated' => __( 'Removed # URL(s)!', 'feedzy-rss-feeds' ),
140
  ),
141
  )
142
  );
151
  if ( ! in_array( $screen->base, $upsell_screens, true ) && strpos( $screen->id, 'feedzy' ) === false ) {
152
  return;
153
  }
154
+ wp_enqueue_style( $this->plugin_name . '-settings', FEEDZY_ABSURL . 'css/settings.css', [], $this->version );
155
+ wp_enqueue_style( $this->plugin_name . '-metabox', FEEDZY_ABSURL . 'css/metabox-settings.css', array( $this->plugin_name . '-settings' ), $this->version );
156
  }
157
 
158
  /**
269
  */
270
  public function feedzy_category_feed() {
271
  global $post;
272
+ $nonce = wp_create_nonce( FEEDZY_BASEFILE );
273
+ $feed = get_post_meta( $post->ID, 'feedzy_category_feed', true );
274
  $invalid = $this->get_source_validity_error( '', $post );
275
 
276
  $output = '
279
  . $invalid
280
  . '<textarea name="feedzy_category_feed" rows="15" class="widefat" placeholder="' . __( 'Place your URL\'s here followed by a comma.', 'feedzy-rss-feeds' ) . '" >' . $feed . '</textarea>
281
  ';
282
+ echo wp_kses( $output, apply_filters( 'feedzy_wp_kses_allowed_html', array() ) );
283
  }
284
 
285
  /**
295
  * @return mixed|integer
296
  */
297
  public function save_feedzy_post_type_meta( $post_id, $post ) {
298
+ if ( empty( $_POST ) ) {
299
+ return $post_id;
300
+ }
301
  if (
302
  empty( $_POST ) ||
303
+ ! isset( $_POST['feedzy_category_meta_noncename'] ) ||
304
+ ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['feedzy_category_meta_noncename'] ) ), FEEDZY_BASEFILE ) ||
305
  ! current_user_can( 'edit_post', $post_id )
306
  ) {
307
  return $post_id;
308
  }
309
+
310
  $category_meta['feedzy_category_feed'] = array();
311
  if ( isset( $_POST['feedzy_category_feed'] ) ) {
312
+ $category_meta['feedzy_category_feed'] = wp_strip_all_tags( wp_unslash( $_POST['feedzy_category_feed'] ) );
313
  }
314
  if ( $post->post_type === 'revision' ) {
315
  return true;
391
  case 'slug':
392
  $slug = $post->post_name;
393
  if ( empty( $slug ) ) {
394
+ echo esc_html__( 'Undefined', 'feedzy-rss-feeds' );
395
  } else {
396
+ echo wp_kses_post( '<code>' . $slug . '</code>' );
397
  }
398
  break;
399
  case 'actions':
400
+ echo wp_kses_post( sprintf( '<button class="button button-primary validate-category" title="%s" data-category-id="%d">%s</button>', __( 'Click to remove invalid URLs from this category', 'feedzy-rss-feeds' ), $post_id, __( 'Validate & Clean', 'feedzy-rss-feeds' ) ) );
401
  break;
402
  default:
403
  break;
418
  */
419
  public function feedzy_filter_plugin_row_meta( $links, $file ) {
420
  if ( strpos( $file, 'feedzy-rss-feed.php' ) !== false ) {
421
+ $new_links = array();
422
  $new_links['doc'] = '<a href="https://docs.themeisle.com/article/658-feedzy-rss-feeds" target="_blank" title="' . __( 'Documentation and examples', 'feedzy-rss-feeds' ) . '">' . __( 'Documentation and examples', 'feedzy-rss-feeds' ) . '</a>';
423
 
424
  if ( ! feedzy_is_pro() ) {
426
  } elseif ( false === apply_filters( 'feedzy_is_license_of_type', false, 'agency' ) ) {
427
  $new_links['more_features'] = '<a href="' . FEEDZY_UPSELL_LINK . '" target="_blank" title="' . __( 'More Features', 'feedzy-rss-feeds' ) . '">' . __( 'Upgrade your license', 'feedzy-rss-feeds' ) . '<i style="width: 17px; height: 17px; margin-left: 4px; color: #ffca54; font-size: 17px; vertical-align: -3px;" class="dashicons dashicons-unlock more-features-icon"></i></a>';
428
  }
429
+ $links = array_merge( $links, $new_links );
430
  }
431
 
432
  return $links;
472
  * @access public
473
  */
474
  public function feedzy_settings_page() {
475
+ if ( isset( $_POST['feedzy-settings-submit'] ) && isset( $_POST['tab'] ) && wp_verify_nonce( filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_STRING ), filter_input( INPUT_POST, 'tab', FILTER_SANITIZE_STRING ) ) ) {
476
  $this->save_settings();
477
  $this->notice = __( 'Your settings were saved.', 'feedzy-rss-feeds' );
478
  }
479
 
480
  $settings = apply_filters( 'feedzy_get_settings', array() );
481
+ include FEEDZY_ABSPATH . '/includes/layouts/settings.php';
482
  }
483
 
484
  /**
487
  * @access private
488
  */
489
  private function save_settings() {
490
+ if ( ! isset( $_POST['tab'] ) ) {
491
+ return;
492
+ }
493
+ if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_STRING ), filter_input( INPUT_POST, 'tab', FILTER_SANITIZE_STRING ) ) ) {
494
+ return;
495
+ }
496
+ $post_tab = isset( $_POST['tab'] ) ? filter_input( INPUT_POST, 'tab', FILTER_SANITIZE_STRING ) : '';
497
+
498
  $settings = apply_filters( 'feedzy_get_settings', array() );
499
+ switch ( $post_tab ) {
500
  case 'general':
501
+ $settings['general']['rss-feeds'] = isset( $_POST['rss-feeds'] ) ? (int) filter_input( INPUT_POST, 'rss-feeds', FILTER_SANITIZE_NUMBER_INT ) : '';
502
  break;
503
  case 'headers':
504
+ $settings['header']['user-agent'] = isset( $_POST['user-agent'] ) ? filter_input( INPUT_POST, 'user-agent', FILTER_SANITIZE_STRING ) : '';
505
  break;
506
  case 'proxy':
507
  $settings['proxy'] = array(
508
+ 'host' => isset( $_POST['proxy-host'] ) ? filter_input( INPUT_POST, 'proxy-host', FILTER_SANITIZE_STRING ) : '',
509
+ 'port' => isset( $_POST['proxy-port'] ) ? filter_input( INPUT_POST, 'proxy-port', FILTER_SANITIZE_NUMBER_INT ) : '',
510
+ 'user' => isset( $_POST['proxy-user'] ) ? filter_input( INPUT_POST, 'proxy-user', FILTER_SANITIZE_STRING ) : '',
511
+ 'pass' => isset( $_POST['proxy-pass'] ) ? filter_input( INPUT_POST, 'proxy-pass', FILTER_SANITIZE_STRING ) : '',
512
  );
513
  break;
514
  default:
515
+ $settings = apply_filters( 'feedzy_save_tab_settings', $settings, $post_tab );
516
  }
517
 
518
  update_option( 'feedzy-settings', $settings );
648
  if ( get_option( 'feedzy-activated' ) ) {
649
  delete_option( 'feedzy-activated' );
650
  if ( ! headers_sent() ) {
651
+ wp_safe_redirect(
652
+ add_query_arg(
653
+ array(
654
+ 'page' => 'feedzy-support',
655
+ 'tab' => 'help#shortcode',
656
+ ),
657
+ admin_url( 'admin.php' )
658
+ )
659
+ );
660
  exit();
661
  }
662
  }
684
  * @access public
685
  */
686
  public function check_source_validity( $src, $post_id, $add_pseudo_transient, $return_valid ) {
687
+ $urls_in = $src;
688
  $post_type = get_post_type( $post_id );
689
  if ( 'feedzy_imports' === $post_type && strpos( $src, 'http' ) === false && strpos( $src, 'https' ) === false ) {
690
  // category
705
  if ( ! is_array( $urls ) ) {
706
  $urls = array( $urls );
707
  }
708
+ $valid = $this->get_valid_feed_urls( $urls, '1_mins', false );
709
  $invalid = array_diff( $urls, $valid );
710
 
711
  if ( $add_pseudo_transient && ( empty( $valid ) || ! empty( $invalid ) ) ) {
715
  update_post_meta( $post_id, '__transient_feedzy_category_feed', $invalid );
716
  break;
717
  case 'feedzy_imports':
718
+ $invalid_dc_namespace = get_post_meta( $post_id, '__transient_feedzy_invalid_dc_namespace', true );
719
+ if ( empty( $invalid_dc_namespace ) ) {
720
+ update_post_meta( $post_id, '__transient_feedzy_invalid_source', $invalid );
721
+ }
722
  break;
723
  }
724
  }
725
 
726
  if ( is_null( $return_valid ) ) {
727
  return array(
728
+ 'valid' => $valid,
729
  'invalid' => $invalid,
730
  );
731
  }
746
  $invalid = $text = null;
747
  switch ( $post->post_type ) {
748
  case 'feedzy_categories':
749
+ $text = __( 'We found the following invalid URLs that we have removed from the list', 'feedzy-rss-feeds' );
750
  $invalid = get_post_meta( $post->ID, '__transient_feedzy_category_feed', true );
751
  delete_post_meta( $post->ID, '__transient_feedzy_category_feed' );
752
  break;
753
  case 'feedzy_imports':
754
+ $invalid_source = get_post_meta( $post->ID, '__transient_feedzy_invalid_source', true );
755
+ $invalid_dc_namespace = get_post_meta( $post->ID, '__transient_feedzy_invalid_dc_namespace', true );
756
+ if ( $invalid_source ) {
757
+ $text = __( 'This source has invalid URLs. Please correct/remove the following', 'feedzy-rss-feeds' );
758
+ $invalid = $invalid_source;
759
+ delete_post_meta( $post->ID, '__transient_feedzy_invalid_source' );
760
+ } elseif ( $invalid_dc_namespace ) {
761
+ $text = __( 'This source URL is valid but the XML namespace DC (xmlns:dc) is not valid. Please correct/remove the following', 'feedzy-rss-feeds' );
762
+ $invalid = $invalid_dc_namespace;
763
+ delete_post_meta( $post->ID, '__transient_feedzy_invalid_dc_namespace' );
764
+ }
765
  break;
766
  default:
767
  return $message;
789
  public function ajax() {
790
  check_ajax_referer( FEEDZY_NAME, 'security' );
791
 
792
+ $post_action = isset( $_POST['_action'] ) ? filter_input( INPUT_POST, '_action', FILTER_SANITIZE_STRING ) : '';
793
+ $post_id = isset( $_POST['id'] ) ? filter_input( INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT ) : '';
794
+
795
+ switch ( $post_action ) {
796
  case 'validate_clean':
797
  // remove invalid URLs from this category.
798
+ $urls = get_post_meta( $post_id, 'feedzy_category_feed', true );
799
+ $return = $this->check_source_validity( $urls, $post_id, false, null );
800
+ $valid = $return['valid'];
801
  $invalid = $return['invalid'];
802
  if ( ! empty( $valid ) ) {
803
  remove_filter( 'update_post_metadata', array( $this, 'validate_category_feeds' ) );
804
+ update_post_meta( $post_id, 'feedzy_category_feed', implode( ', ', $valid ) );
805
  }
806
  wp_send_json_success( array( 'invalid' => count( $invalid ) ) );
807
  break;
includes/admin/feedzy-rss-feeds-import.php CHANGED
@@ -71,7 +71,7 @@ class Feedzy_Rss_Feeds_Import {
71
  $this->plugin_name = $plugin_name;
72
  $this->version = $version;
73
 
74
- $this->settings = get_option( 'feedzy-rss-feeds-settings', array() );
75
  $this->free_settings = get_option( 'feedzy-settings', array() );
76
  }
77
 
@@ -140,15 +140,15 @@ class Feedzy_Rss_Feeds_Import {
140
  'feedzy',
141
  array(
142
  'ajax' => array(
143
- 'security' => wp_create_nonce( FEEDZY_BASEFILE ),
144
  ),
145
  'i10n' => array(
146
- 'importing' => __( 'Importing', 'feedzy-rss-feeds' ) . '...',
147
- 'run_now' => __( 'Run Now', 'feedzy-rss-feeds' ),
148
  'dry_run_loading' => '<p class="hide-when-loaded">' . __( 'Processing the source and loading the items that will be imported when it runs', 'feedzy-rss-feeds' ) . '...</p>'
149
  . '<p><b>' . __( 'Please note that if some of these items have already have been imported in previous runs with the same filters, they may be shown here but will not be imported again.', 'feedzy-rss-feeds' ) . '</b></p>'
150
  . '<p class="loading-img hide-when-loaded"><img src="' . includes_url( 'images/wpspin-2x.gif' ) . '"></p><div></div>',
151
- 'dry_run_title' => __( 'Importable Items', 'feedzy-rss-feeds' ),
152
  ),
153
  )
154
  );
@@ -174,10 +174,10 @@ class Feedzy_Rss_Feeds_Import {
174
 
175
  // If set to true, SimplePie will return a unique MD5 hash for the item.
176
  // If set to false, it will check <guid>, <link>, and <title> before defaulting to the hash.
177
- $itemArray['item_id'] = $item->get_id( false );
178
 
179
- $itemArray['item'] = $item;
180
- $itemArray['item_index'] = $item_index;
181
  return $itemArray;
182
  }
183
 
@@ -273,21 +273,21 @@ class Feedzy_Rss_Feeds_Import {
273
  */
274
  public function feedzy_import_feed_options() {
275
  global $post;
276
- $args = array(
277
  'post_type' => 'feedzy_categories',
278
  'posts_per_page' => 100,
279
  );
280
- $feed_categories = get_posts( $args );
281
- $post_types = get_post_types( '', 'names' );
282
- $post_types = array_diff( $post_types, array( 'feedzy_imports', 'feedzy_categories' ) );
283
- $published_status = array( 'publish', 'draft' );
284
- $import_post_type = get_post_meta( $post->ID, 'import_post_type', true );
285
- $import_post_term = get_post_meta( $post->ID, 'import_post_term', true );
286
  if ( metadata_exists( $import_post_type, $post->ID, 'import_post_status' ) ) {
287
- $import_post_status = get_post_meta( $post->ID, 'import_post_status', true );
288
  } else {
289
  add_post_meta( $post->ID, 'import_post_status', 'publish' );
290
- $import_post_status = get_post_meta( $post->ID, 'import_post_status', true );
291
  }
292
  $source = get_post_meta( $post->ID, 'source', true );
293
  $inc_key = get_post_meta( $post->ID, 'inc_key', true );
@@ -295,6 +295,8 @@ class Feedzy_Rss_Feeds_Import {
295
  $import_title = get_post_meta( $post->ID, 'import_post_title', true );
296
  $import_date = get_post_meta( $post->ID, 'import_post_date', true );
297
  $import_content = get_post_meta( $post->ID, 'import_post_content', true );
 
 
298
  $import_featured_img = get_post_meta( $post->ID, 'import_post_featured_img', true );
299
 
300
  // default values so that post is not created empty.
@@ -305,15 +307,15 @@ class Feedzy_Rss_Feeds_Import {
305
  $import_content = '[#item_content]';
306
  }
307
 
308
- $import_link_author_admin = get_post_meta( $post->ID, 'import_link_author_admin', true );
309
- $import_link_author_public = get_post_meta( $post->ID, 'import_link_author_public', true );
310
 
311
- // admin, public
312
  $import_link_author = array( '', '' );
313
- if ( $import_link_author_admin === 'yes' ) {
314
  $import_link_author[0] = 'checked';
315
  }
316
- if ( $import_link_author_public === 'yes' ) {
317
  $import_link_author[1] = 'checked';
318
  }
319
 
@@ -325,20 +327,20 @@ class Feedzy_Rss_Feeds_Import {
325
  if ( empty( $import_feed_limit ) ) {
326
  $import_feed_limit = 10;
327
  }
328
- $import_feed_delete_days = intval( get_post_meta( $post->ID, 'import_feed_delete_days', true ) );
329
  if ( empty( $import_feed_delete_days ) ) {
330
  $import_feed_delete_days = 0;
331
  }
332
- $post_status = $post->post_status;
333
- $nonce = wp_create_nonce( FEEDZY_BASEFILE );
334
- $invalid_source_msg = apply_filters( 'feedzy_get_source_validity_error', '', $post );
335
- $output = '
336
  <input type="hidden" name="feedzy_category_meta_noncename" id="feedzy_category_meta_noncename" value="' . $nonce . '" />
337
  ';
338
 
339
  add_thickbox();
340
  include FEEDZY_ABSPATH . '/includes/views/import-metabox-edit.php';
341
- echo $output;
342
  }
343
 
344
  /**
@@ -364,17 +366,47 @@ class Feedzy_Rss_Feeds_Import {
364
  * @return bool
365
  */
366
  public function save_feedzy_import_feed_meta( $post_id, $post ) {
 
 
 
 
 
 
367
  if (
368
- empty( $_POST ) ||
369
  get_post_type( $post_id ) !== 'feedzy_imports' ||
370
- ( ! defined( 'TI_UNIT_TESTING' ) && ! wp_verify_nonce( $_POST['feedzy_category_meta_noncename'], FEEDZY_BASEFILE ) ) ||
371
  ! current_user_can( 'edit_post', $post_id )
372
  ) {
373
  return $post_id;
374
  }
375
- $data_meta = isset( $_POST['feedzy_meta_data'] ) ? ( is_array( $_POST['feedzy_meta_data'] ) ? $_POST['feedzy_meta_data'] : array() ) : array();
376
- $custom_fields_keys = isset( $_POST['custom_vars_key'] ) ? ( is_array( $_POST['custom_vars_key'] ) ? $_POST['custom_vars_key'] : array() ) : array();
377
- $custom_fields_values = isset( $_POST['custom_vars_value'] ) ? ( is_array( $_POST['custom_vars_value'] ) ? $_POST['custom_vars_value'] : array() ) : array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
  $custom_fields = array();
379
  foreach ( $custom_fields_keys as $index => $key_value ) {
380
  $value = '';
@@ -390,15 +422,18 @@ class Feedzy_Rss_Feeds_Import {
390
 
391
  // we will activate this import only if the source has no invalid URL(s)
392
  $source_is_valid = false;
393
-
 
394
  foreach ( $data_meta as $key => $value ) {
395
  $value = is_array( $value ) ? implode( ',', $value ) : implode( ',', (array) $value );
396
  if ( 'source' === $key ) {
397
  // check if the source is valid
398
- $invalid_urls = apply_filters( 'feedzy_check_source_validity', $value, $post_id, true, false );
399
  $source_is_valid = empty( $invalid_urls );
400
  }
401
-
 
 
402
  if ( get_post_meta( $post_id, $key, false ) ) {
403
  update_post_meta( $post_id, $key, wp_kses( $value, wp_kses_allowed_html( 'post' ) ) );
404
  } else {
@@ -440,7 +475,8 @@ class Feedzy_Rss_Feeds_Import {
440
  // if invalid source has been found, redirect back to edit screen
441
  // where errors can be shown
442
  $invalid = get_post_meta( $post_id, '__transient_feedzy_invalid_source', true );
443
- if ( empty( $invalid ) ) {
 
444
  return admin_url( 'edit.php?post_type=feedzy_imports' );
445
  }
446
  }
@@ -538,32 +574,33 @@ class Feedzy_Rss_Feeds_Import {
538
  } else {
539
  // else link it to the feed but shorten it if it is too long.
540
  $too_long = 65;
541
- $src = sprintf( '%s%s%s', '<a href="' . $src . '" target="_blank" title="' . __( 'Click to view', 'feedzy-rss-feeds' ) . '">', ( strlen( $src ) > $too_long ? substr( $src, 0, $too_long ) . '...' : $src ), '</a>' );
542
  }
543
- echo $src;
544
  break;
545
  case 'feedzy-status':
546
  $status = $post->post_status;
547
  if ( empty( $status ) ) {
548
- echo __( 'Undefined', 'feedzy-rss-feeds' );
549
  } else {
550
  if ( $status === 'publish' ) {
551
  $checked = 'checked';
552
  } else {
553
  $checked = '';
554
  }
555
- echo '
556
- <div class="switch">
557
- <input id="feedzy-toggle_' . $post->ID . '" class="feedzy-toggle feedzy-toggle-round" type="checkbox" value="' . $post->ID . '" ' . $checked . '>
558
- <label for="feedzy-toggle_' . $post->ID . '"></label>
559
- <span class="feedzy-spinner spinner"></span>
560
- </div>
561
- ';
 
562
  }
563
  break;
564
  case 'feedzy-last_run':
565
- $last = get_post_meta( $post_id, 'last_run', true );
566
- $msg = __( 'Never Run', 'feedzy-rss-feeds' );
567
  if ( $last ) {
568
  $now = new DateTime();
569
  $then = new DateTime();
@@ -573,10 +610,10 @@ class Feedzy_Rss_Feeds_Import {
573
  }
574
 
575
  $msg .= $this->get_last_run_details( $post_id );
576
- echo $msg;
577
 
578
  if ( 'publish' === $post->post_status ) {
579
- echo sprintf( '<p><input type="button" class="button button-primary feedzy-run-now" data-id="%d" value="%s"></p>', $post_id, __( 'Run Now', 'feedzy-rss-feeds' ) );
580
  }
581
 
582
  break;
@@ -587,7 +624,7 @@ class Feedzy_Rss_Feeds_Import {
587
  $then = new DateTime();
588
  $then = $then->setTimestamp( $next );
589
  $in = $now->diff( $then );
590
- echo sprintf( __( 'In %1$d hours %2$d minutes', 'feedzy-rss-feeds' ), $in->format( '%h' ), $in->format( '%i' ) );
591
  }
592
  break;
593
  default:
@@ -607,15 +644,15 @@ class Feedzy_Rss_Feeds_Import {
607
  $msg = '';
608
  $last = get_post_meta( $post_id, 'last_run', true );
609
  $status = array(
610
- 'total' => '-',
611
- 'items' => '-',
612
  'duplicates' => '-',
613
  'cumulative' => '-',
614
  );
615
  if ( $last ) {
616
  $status = array(
617
- 'total' => 0,
618
- 'items' => 0,
619
  'duplicates' => 0,
620
  'cumulative' => 0,
621
  );
@@ -623,13 +660,36 @@ class Feedzy_Rss_Feeds_Import {
623
  }
624
 
625
  // link to the posts listing for this job.
626
- $job_linked_posts = add_query_arg( array( 'feedzy_job_id' => $post_id, 'post_type' => get_post_meta( $post_id, 'import_post_type', true ) ), admin_url( 'edit.php' ) );
 
 
 
 
 
 
 
 
 
 
 
627
 
628
  // link to the posts listing for this job run.
629
- $job_run_linked_posts = '';
630
- $job_run_id = get_post_meta( $post_id, 'last_run_id', true );
631
  if ( ! empty( $job_run_id ) ) {
632
- $job_run_linked_posts = add_query_arg( array( 'feedzy_job_id' => $post_id, 'feedzy_job_time' => $job_run_id, 'post_type' => get_post_meta( $post_id, 'import_post_type', true ) ), admin_url( 'edit.php' ) );
 
 
 
 
 
 
 
 
 
 
 
 
633
  }
634
 
635
  // popup for items found.
@@ -731,20 +791,20 @@ class Feedzy_Rss_Feeds_Import {
731
  * @access private
732
  */
733
  private function get_complete_import_status( $post_id ) {
734
- $items_count = get_post_meta( $post_id, 'imported_items_count', true );
735
- $items = get_post_meta( $post_id, 'imported_items_hash', true );
736
  if ( empty( $items ) ) {
737
- $items = get_post_meta( $post_id, 'imported_items', true );
738
  }
739
- $count = $items_count;
740
  if ( '' === $count && $items ) {
741
  // backward compatibility where imported_items_count post_meta has not been populated yet
742
- $count = count( $items );
743
  }
744
 
745
  $status = array(
746
- 'total' => $count,
747
- 'items' => 0,
748
  'duplicates' => 0,
749
  'cumulative' => 0,
750
  );
@@ -767,9 +827,9 @@ class Feedzy_Rss_Feeds_Import {
767
  }
768
  }
769
 
770
- $items = get_post_meta( $post_id, 'imported_items_hash', true );
771
  if ( empty( $items ) ) {
772
- $items = get_post_meta( $post_id, 'imported_items', true );
773
  }
774
  if ( $items ) {
775
  $status['cumulative'] = count( $items );
@@ -786,7 +846,7 @@ class Feedzy_Rss_Feeds_Import {
786
  * @access private
787
  */
788
  private function get_import_errors( $post_id ) {
789
- $msg = '';
790
  $import_errors = get_post_meta( $post_id, 'import_errors', true );
791
  if ( $import_errors ) {
792
  $errors = '';
@@ -804,7 +864,7 @@ class Feedzy_Rss_Feeds_Import {
804
 
805
  // the pro messages may not have the dashicons, so let's add them.
806
  if ( $pro_msg && strpos( $pro_msg, 'dashicons-warning' ) === false ) {
807
- $errors = '';
808
  $pro_errors = explode( '<br>', $pro_msg );
809
  if ( is_array( $pro_errors ) ) {
810
  foreach ( $pro_errors as $err ) {
@@ -829,9 +889,10 @@ class Feedzy_Rss_Feeds_Import {
829
  public function ajax() {
830
  check_ajax_referer( FEEDZY_BASEFILE, 'security' );
831
 
832
- $_POST['feedzy_category_meta_noncename'] = $_POST['security'];
 
833
 
834
- switch ( $_POST['_action'] ) {
835
  case 'import_status':
836
  $this->import_status();
837
  break;
@@ -858,12 +919,15 @@ class Feedzy_Rss_Feeds_Import {
858
  */
859
  private function import_status() {
860
  global $wpdb;
861
- $id = $_POST['id'];
862
- $status = $_POST['status'];
 
 
 
863
  $publish = 'draft';
864
 
865
  // no activation till source is not valid.
866
- if ( $status === 'true' ) {
867
  $invalid_urls = apply_filters( 'feedzy_check_source_validity', get_post_meta( $id, 'source', true ), $id, true, false );
868
  if ( ! empty( $invalid_urls ) ) {
869
  $msg = apply_filters( 'feedzy_get_source_validity_error', '', get_post( $id ), '' );
@@ -879,7 +943,7 @@ class Feedzy_Rss_Feeds_Import {
879
  );
880
 
881
  remove_action( 'save_post_feedzy_imports', array( $this, 'save_feedzy_import_feed_meta' ), 1, 2 );
882
- $post_id = wp_update_post( $new_post_status );
883
  add_action( 'save_post_feedzy_imports', array( $this, 'save_feedzy_import_feed_meta' ), 1, 2 );
884
 
885
  if ( is_wp_error( $post_id ) ) {
@@ -896,7 +960,9 @@ class Feedzy_Rss_Feeds_Import {
896
  * @access private
897
  */
898
  private function get_taxonomies() {
899
- $post_type = $_POST['post_type'];
 
 
900
  $taxonomies = get_object_taxonomies(
901
  array(
902
  'post_type' => $post_type,
@@ -914,7 +980,7 @@ class Feedzy_Rss_Feeds_Import {
914
  $results[ $taxonomy ] = $terms;
915
  }
916
  }
917
- echo json_encode( $results );
918
  wp_die();
919
  }
920
 
@@ -925,11 +991,13 @@ class Feedzy_Rss_Feeds_Import {
925
  * @access private
926
  */
927
  private function run_now() {
928
- $job = get_post( $_POST['id'] );
929
- $count = $this->run_job( $job, 100 );
 
 
930
 
931
- $msg = $count > 0 ? __( 'Successfully run!', 'feedzy-rss-feeds' ) : __( 'Nothing imported!', 'feedzy-rss-feeds' );
932
- $msg .= ' (' . __( 'Refresh this page for the updated status', 'feedzy-rss-feeds' ) . ')';
933
 
934
  wp_send_json_success( array( 'msg' => $msg ) );
935
  }
@@ -941,13 +1009,16 @@ class Feedzy_Rss_Feeds_Import {
941
  * @access private
942
  */
943
  private function dry_run() {
944
- $fields = urldecode( $_POST['fields'] );
 
 
945
  parse_str( $fields, $data );
946
 
947
  $feedzy_meta_data = $data['feedzy_meta_data'];
948
 
949
  add_filter(
950
- 'feedzy_default_error', function( $errors, $feed, $url ) {
 
951
  $errors .=
952
  sprintf( __( 'For %1$ssingle feeds%2$s, this could be because of the following reasons:', 'feedzy-rss-feeds' ), '<b>', '</b>' )
953
  . '<ol>'
@@ -961,7 +1032,9 @@ class Feedzy_Rss_Feeds_Import {
961
  . '</ol>';
962
 
963
  return $errors;
964
- }, 11, 3
 
 
965
  );
966
 
967
  // we will add tags corresponding to the most potential problems.
@@ -1004,7 +1077,7 @@ class Feedzy_Rss_Feeds_Import {
1004
  $args = array(
1005
  'post_type' => 'feedzy_imports',
1006
  'post_status' => 'publish',
1007
- 'numberposts' => 300,
1008
  );
1009
  $feedzy_imports = get_posts( $args );
1010
  foreach ( $feedzy_imports as $job ) {
@@ -1031,23 +1104,24 @@ class Feedzy_Rss_Feeds_Import {
1031
  $import_post_type = get_post_meta( $job->ID, 'import_post_type', true );
1032
  $import_post_term = get_post_meta( $job->ID, 'import_post_term', true );
1033
  $import_feed_limit = get_post_meta( $job->ID, 'import_feed_limit', true );
 
1034
  $max = $import_feed_limit;
1035
  if ( metadata_exists( $import_post_type, $job->ID, 'import_post_status' ) ) {
1036
- $import_post_status = get_post_meta( $job->ID, 'import_post_status', true );
1037
  } else {
1038
  add_post_meta( $job->ID, 'import_post_status', 'publish' );
1039
- $import_post_status = get_post_meta( $job->ID, 'import_post_status', true );
1040
  }
1041
 
1042
  // the array of imported items that uses the old scheme of custom hashing the url and date
1043
- $imported_items = array();
1044
- $imported_items_old = get_post_meta( $job->ID, 'imported_items', true );
1045
  if ( ! is_array( $imported_items_old ) ) {
1046
  $imported_items_old = array();
1047
  }
1048
 
1049
  // the array of imported items that uses the new scheme of SimplePie's hash/id
1050
- $imported_items_new = get_post_meta( $job->ID, 'imported_items_hash', true );
1051
  if ( ! is_array( $imported_items_new ) ) {
1052
  $imported_items_new = array();
1053
  }
@@ -1056,37 +1130,39 @@ class Feedzy_Rss_Feeds_Import {
1056
  // the date, because if the title can have UTC date and content can have local date then it
1057
  // all goes sideways.
1058
  // also if the user provides multiple date types, local will win.
1059
- $meta = 'yes';
1060
  if ( strpos( $import_title, '[#item_date_local]' ) !== false ) {
1061
- $meta = 'author, date, time, tz=local';
1062
  } elseif ( strpos( $import_title, '[#item_date_feed]' ) !== false ) {
1063
- $meta = 'author, date, time, tz=no';
1064
  }
1065
 
1066
  $options = apply_filters(
1067
- 'feedzy_shortcode_options', array(
1068
- 'feeds' => $source,
1069
- 'max' => $max,
1070
- 'feed_title' => 'no',
1071
- 'target' => '_blank',
1072
- 'title' => '',
1073
- 'meta' => $meta,
1074
- 'summary' => 'yes',
1075
- 'summarylength' => '',
1076
- 'thumb' => 'auto',
1077
- 'default' => '',
1078
- 'size' => '250',
1079
- 'keywords_inc' => $inc_key, // this is not keywords_title
1080
- 'keywords_ban' => $exc_key, // to support old pro that does not support keywords_exc
1081
- 'keywords_exc' => $exc_key, // this is not keywords_ban
1082
- 'columns' => 1,
1083
- 'offset' => 0,
1084
- 'multiple_meta' => 'no',
1085
- 'refresh' => '55_mins',
1086
- ), $job
 
 
1087
  );
1088
 
1089
- $admin = Feedzy_Rss_Feeds::instance()->get_admin();
1090
  $options = $admin->sanitize_attr( $options, $source );
1091
 
1092
  $options['__jobID'] = $job->ID;
@@ -1124,14 +1200,14 @@ class Feedzy_Rss_Feeds_Import {
1124
  // or the new scheme of depending on SimplePie's hash/id
1125
  // basically if the old scheme hasn't be used before, use the new scheme
1126
  // BUT if the old scheme has been used, continue with it.
1127
- $use_new_hash = empty( $imported_items_old );
1128
  $imported_items = $use_new_hash ? $imported_items_new : $imported_items_old;
1129
 
1130
  $start_import = true;
1131
  // bail if both title and content are empty because the post will not be created.
1132
  if ( empty( $import_title ) && empty( $import_content ) ) {
1133
  $import_errors[] = __( 'Title & Content are both empty.', 'feedzy-rss-feeds' );
1134
- $start_import = false;
1135
  }
1136
 
1137
  if ( ! $start_import ) {
@@ -1142,8 +1218,8 @@ class Feedzy_Rss_Feeds_Import {
1142
  $duplicates = $items_found = array();
1143
 
1144
  foreach ( $result as $item ) {
1145
- $item_hash = $use_new_hash ? $item['item_id'] : hash( 'sha256', $item['item_url'] . '_' . $item['item_date'] );
1146
- $is_duplicate = $use_new_hash ? in_array( $item_hash, $imported_items_new, true ) : in_array( $item_hash, $imported_items_old, true );
1147
  $items_found[ $item['item_url'] ] = $item['item_title'];
1148
 
1149
  if ( $is_duplicate ) {
@@ -1153,7 +1229,7 @@ class Feedzy_Rss_Feeds_Import {
1153
  continue;
1154
  }
1155
 
1156
- $author = '';
1157
  if ( $item['item_author'] ) {
1158
  if ( is_string( $item['item_author'] ) ) {
1159
  $author = $item['item_author'];
@@ -1197,10 +1273,10 @@ class Feedzy_Rss_Feeds_Import {
1197
 
1198
  $post_title = apply_filters( 'feedzy_invoke_services', $post_title, 'title', $item['item_title'], $job );
1199
 
1200
- $item_link = '<a href="' . $item['item_url'] . '" target="_blank">' . __( 'Read More', 'feedzy-rss-feeds' ) . '</a>';
1201
- $image_html = '';
1202
  if ( ! empty( $item['item_img_path'] ) ) {
1203
- $image_html = '<img src="' . $item['item_img_path'] . '" title="' . $item['item_title'] . '" />';
1204
  }
1205
  $post_content = str_replace(
1206
  array(
@@ -1252,23 +1328,24 @@ class Feedzy_Rss_Feeds_Import {
1252
  $post_content = apply_filters( 'feedzy_parse_custom_tags', $post_content, $results['feed'], $item['item_index'] );
1253
  }
1254
 
1255
- $post_content = apply_filters( 'feedzy_invoke_services', $post_content, 'content', $item['item_description'], $job );
1256
 
1257
  // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
1258
  $item_date = date( 'Y-m-d H:i:s', $item['item_date'] );
1259
  // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
1260
- $now = date( 'Y-m-d H:i:s' );
1261
  if ( trim( $import_date ) === '' ) {
1262
  $post_date = $now;
1263
  }
1264
- $post_date = str_replace( '[#item_date]', $item_date, $import_date );
1265
- $post_date = str_replace( '[#post_date]', $now, $post_date );
1266
 
1267
- $new_post = apply_filters(
1268
- 'feedzy_insert_post_args', array(
 
1269
  'post_type' => $import_post_type,
1270
- 'post_title' => $post_title,
1271
- 'post_content' => $post_content,
1272
  'post_date' => $post_date,
1273
  'post_status' => $import_post_status,
1274
  ),
@@ -1308,11 +1385,11 @@ class Feedzy_Rss_Feeds_Import {
1308
  if ( $import_post_term !== 'none' && strpos( $import_post_term, '_' ) > 0 ) {
1309
  // let's get the slug of the uncategorized category, even if it renamed.
1310
  $uncategorized = get_category( 1 );
1311
- $terms = explode( ',', $import_post_term );
1312
  foreach ( $terms as $term ) {
1313
  // this handles both x_2, where 2 is the term id and x is the taxonomy AND x_2_3_4 where 4 is the term id and the taxonomy name is "x 2 3 4".
1314
- $array = explode( '_', $term );
1315
- $term_id = array_pop( $array );
1316
  $taxonomy = implode( '_', $array );
1317
 
1318
  // uncategorized
@@ -1328,7 +1405,7 @@ class Feedzy_Rss_Feeds_Import {
1328
  do_action( 'feedzy_import_extra', $job, $results, $new_post_id, $index, $item['item_index'], $import_errors, $import_info );
1329
 
1330
  if ( ! empty( $import_featured_img ) ) {
1331
- $image_url = '';
1332
  $img_success = true;
1333
 
1334
  // image tag
@@ -1352,8 +1429,13 @@ class Feedzy_Rss_Feeds_Import {
1352
  }
1353
 
1354
  if ( ! empty( $image_url ) ) {
1355
- // if import_featured_img is a tag
1356
- $img_success = $this->generate_featured_image( $image_url, $new_post_id, $item['item_title'], $import_errors, $import_info );
 
 
 
 
 
1357
  }
1358
 
1359
  if ( ! $img_success ) {
@@ -1388,7 +1470,7 @@ class Feedzy_Rss_Feeds_Import {
1388
  update_post_meta( $job->ID, 'import_errors', $import_errors );
1389
 
1390
  // the order of these matters in how they are finally shown in the summary.
1391
- $import_info['total'] = $items_found;
1392
  $import_info['duplicates'] = $duplicates;
1393
 
1394
  update_post_meta( $job->ID, 'import_info', $import_info );
@@ -1420,7 +1502,10 @@ class Feedzy_Rss_Feeds_Import {
1420
  return $feedURL;
1421
  }
1422
 
1423
- $feed = $admin->fetch_feed( $feedURL, isset( $options['refresh'] ) ? $options['refresh'] : '12_hours', $options );
 
 
 
1424
 
1425
  if ( is_string( $feed ) ) {
1426
  return array();
@@ -1458,18 +1543,18 @@ class Feedzy_Rss_Feeds_Import {
1458
  private function generate_featured_image( $file, $post_id, $desc, &$import_errors, &$import_info ) {
1459
  do_action( 'themeisle_log_event', FEEDZY_NAME, sprintf( 'Trying to generate featured image for %s and postID %d', $file, $post_id ), 'debug', __FILE__, __LINE__ );
1460
 
1461
- require_once( ABSPATH . 'wp-admin' . '/includes/image.php' );
1462
- require_once( ABSPATH . 'wp-admin' . '/includes/file.php' );
1463
- require_once( ABSPATH . 'wp-admin' . '/includes/media.php' );
1464
 
1465
- $file_array = array();
1466
- $local_file = download_url( $file );
1467
  if ( is_wp_error( $local_file ) ) {
1468
  do_action( 'themeisle_log_event', FEEDZY_NAME, sprintf( 'Unable to download file = %s and postID %d', print_r( $local_file, true ), $post_id ), 'error', __FILE__, __LINE__ );
1469
  return false;
1470
  }
1471
 
1472
- $type = mime_content_type( $local_file );
1473
  // the file is downloaded with a .tmp extension
1474
  // if the URL mentions the extension of the file, the upload succeeds
1475
  // but if the URL is like https://source.unsplash.com/random, then the upload fails
@@ -1488,7 +1573,7 @@ class Feedzy_Rss_Feeds_Import {
1488
  $file_array['tmp_name'] = $local_file;
1489
  $file_array['name'] = basename( $local_file );
1490
 
1491
- $id = media_handle_sideload( $file_array, $post_id, $desc );
1492
  if ( is_wp_error( $id ) ) {
1493
  do_action( 'themeisle_log_event', FEEDZY_NAME, sprintf( 'Unable to attach file for postID %d = %s', $post_id, print_r( $id, true ) ), 'error', __FILE__, __LINE__ );
1494
  unlink( $file_array['tmp_name'] );
@@ -1522,19 +1607,19 @@ class Feedzy_Rss_Feeds_Import {
1522
  * @access public
1523
  */
1524
  public function admin_notices() {
1525
- $screen = get_current_screen();
1526
- $allowed = array( 'edit-feedzy_categories', 'edit-feedzy_imports', 'feedzy-rss_page_feedzy-settings' );
1527
  // only show in the feedzy screens.
1528
  if ( ! in_array( $screen->id, $allowed, true ) ) {
1529
  return;
1530
  }
1531
 
1532
  if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
1533
- echo '<div class="notice notice-error feedzy-error-critical is-dismissible"><p>' . __( 'WP Cron is disabled. Your feeds would not get updated. Please contact your hosting provider or system administrator', 'feedzy-rss-feeds' ) . '</p></div>';
1534
  }
1535
 
1536
  if ( false === wp_next_scheduled( 'feedzy_cron' ) ) {
1537
- echo '<div class="notice notice-error"><p>' . __( 'Unable to register cron job. Your feeds might not get updated', 'feedzy-rss-feeds' ) . '</p></div>';
1538
  }
1539
 
1540
  }
@@ -1598,7 +1683,6 @@ class Feedzy_Rss_Feeds_Import {
1598
  * @access public
1599
  */
1600
  public function update_settings_page() {
1601
- $post_data = $_POST['feedzy_settings'];
1602
  $this->save_settings();
1603
  wp_die();
1604
  }
@@ -1613,8 +1697,8 @@ class Feedzy_Rss_Feeds_Import {
1613
  $this->free_settings = get_option( 'feedzy-settings', array() );
1614
 
1615
  $fields[] = array(
1616
- 'content' => $this->render_view( $tab ),
1617
- 'ajax' => false,
1618
  );
1619
  return $fields;
1620
  }
@@ -1646,8 +1730,12 @@ class Feedzy_Rss_Feeds_Import {
1646
  * @access public
1647
  */
1648
  public function save_tab_settings( $settings, $tab ) {
 
 
 
 
1649
  if ( 'misc' === $tab ) {
1650
- $settings['canonical'] = isset( $_POST['canonical'] ) ? $_POST['canonical'] : 0;
1651
  }
1652
  return $settings;
1653
  }
@@ -1696,12 +1784,12 @@ class Feedzy_Rss_Feeds_Import {
1696
  $disabled[ str_replace( ':disabled', '', $tag ) ] = $label;
1697
  continue;
1698
  }
1699
- $default .= '<a class="dropdown-item" href="#" data-field-name="' . $type . '" data-field-tag="' . $tag . '">' . $label . ' -- <small>[#' . $tag . ']</small></a>';
1700
  }
1701
 
1702
  if ( $disabled ) {
1703
  foreach ( $disabled as $tag => $label ) {
1704
- $default .= '<span disabled title="' . __( 'Upgrade your license to use this tag', 'feedzy-rss-feeds' ) . '" class="dropdown-item">' . $label . ' -- <small>[#' . $tag . ']</small></span>';
1705
  }
1706
  }
1707
  }
@@ -1717,17 +1805,17 @@ class Feedzy_Rss_Feeds_Import {
1717
  * @param array $default The default tags, empty.
1718
  */
1719
  public function magic_tags_title( $default ) {
1720
- $default['item_title'] = __( 'Item Title', 'feedzy-rss-feeds' );
1721
- $default['item_author'] = __( 'Item Author', 'feedzy-rss-feeds' );
1722
- $default['item_date'] = __( 'Item Date (UTC/GMT)', 'feedzy-rss-feeds' );
1723
- $default['item_date_local'] = __( 'Item Date (local timezone)', 'feedzy-rss-feeds' );
1724
- $default['item_date_feed'] = __( 'Item Date (feed timezone)', 'feedzy-rss-feeds' );
1725
- $default['item_source'] = __( 'Item Source', 'feedzy-rss-feeds' );
1726
-
1727
- // disabled tags
1728
  if ( ! feedzy_is_pro() ) {
1729
- $default['title_spinnerchief:disabled'] = __( 'Title from SpinnerChief', 'feedzy-rss-feeds' );
1730
- $default['title_wordai:disabled'] = __( 'Title from WordAI', 'feedzy-rss-feeds' );
1731
  }
1732
  return $default;
1733
  }
@@ -1741,8 +1829,8 @@ class Feedzy_Rss_Feeds_Import {
1741
  * @param array $default The default tags, empty.
1742
  */
1743
  public function magic_tags_date( $default ) {
1744
- $default['item_date'] = __( 'Item Date', 'feedzy-rss-feeds' );
1745
- $default['post_date'] = __( 'Post Date', 'feedzy-rss-feeds' );
1746
  return $default;
1747
  }
1748
 
@@ -1755,20 +1843,20 @@ class Feedzy_Rss_Feeds_Import {
1755
  * @param array $default The default tags, empty.
1756
  */
1757
  public function magic_tags_content( $default ) {
1758
- $default['item_content'] = __( 'Item Content', 'feedzy-rss-feeds' );
1759
- $default['item_description'] = __( 'Item Description', 'feedzy-rss-feeds' );
1760
- $default['item_image'] = __( 'Item Image', 'feedzy-rss-feeds' );
1761
- $default['item_url'] = __( 'Item URL', 'feedzy-rss-feeds' );
1762
- $default['item_categories'] = __( 'Item Categories', 'feedzy-rss-feeds' );
1763
- $default['item_source'] = __( 'Item Source', 'feedzy-rss-feeds' );
1764
-
1765
- // disabled tags
1766
  if ( ! feedzy_is_pro() ) {
1767
- $default['item_full_content:disabled'] = __( 'Item Full Content', 'feedzy-rss-feeds' );
1768
- $default['content_spinnerchief:disabled'] = __( 'Content from SpinnerChief', 'feedzy-rss-feeds' );
1769
- $default['full_content_spinnerchief:disabled'] = __( 'Full content from SpinnerChief', 'feedzy-rss-feeds' );
1770
- $default['content_wordai:disabled'] = __( 'Content from WordAI', 'feedzy-rss-feeds' );
1771
- $default['full_content_wordai:disabled'] = __( 'Full content from WordAI', 'feedzy-rss-feeds' );
1772
  }
1773
  return $default;
1774
  }
@@ -1782,7 +1870,7 @@ class Feedzy_Rss_Feeds_Import {
1782
  * @param array $default The default tags, empty.
1783
  */
1784
  public function magic_tags_image( $default ) {
1785
- $default['item_image'] = __( 'Item Image', 'feedzy-rss-feeds' );
1786
  return $default;
1787
  }
1788
 
@@ -1828,7 +1916,7 @@ class Feedzy_Rss_Feeds_Import {
1828
 
1829
  // let's check if the post has been imported by feedzy.
1830
  if ( 1 === intval( get_post_meta( $post->ID, 'feedzy', true ) ) ) {
1831
- $url = get_post_meta( $post->ID, 'feedzy_item_url', true );
1832
  if ( ! empty( $url ) ) {
1833
  $canonical_url = $url;
1834
  }
@@ -1867,8 +1955,10 @@ class Feedzy_Rss_Feeds_Import {
1867
  * @access private
1868
  */
1869
  private function purge_data() {
1870
- $id = $_POST['id'];
1871
- $post = get_post( $id );
 
 
1872
  if ( $post->post_type !== 'feedzy_imports' ) {
1873
  wp_die();
1874
  }
@@ -1889,26 +1979,54 @@ class Feedzy_Rss_Feeds_Import {
1889
  * @access public
1890
  */
1891
  public function pre_get_posts( $query ) {
1892
- if ( is_admin() && $query->is_main_query() && ! empty( $_GET['feedzy_job_id'] ) ) {
 
 
 
 
 
 
 
1893
  $meta_query = array(
1894
  array(
1895
- 'key' => 'feedzy',
1896
  'value' => 1,
1897
  ),
1898
  array(
1899
- 'key' => 'feedzy_job',
1900
- 'value' => $_GET['feedzy_job_id'],
1901
  ),
1902
  );
1903
 
1904
- if ( ! empty( $_GET['feedzy_job_time'] ) ) {
1905
  $meta_query[] = array(
1906
- 'key' => 'feedzy_job_time',
1907
- 'value' => $_GET['feedzy_job_time'],
1908
  );
1909
  }
1910
 
1911
  $query->set( 'meta_query', $meta_query );
1912
  }
1913
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1914
  }
71
  $this->plugin_name = $plugin_name;
72
  $this->version = $version;
73
 
74
+ $this->settings = get_option( 'feedzy-rss-feeds-settings', array() );
75
  $this->free_settings = get_option( 'feedzy-settings', array() );
76
  }
77
 
140
  'feedzy',
141
  array(
142
  'ajax' => array(
143
+ 'security' => wp_create_nonce( FEEDZY_BASEFILE ),
144
  ),
145
  'i10n' => array(
146
+ 'importing' => __( 'Importing', 'feedzy-rss-feeds' ) . '...',
147
+ 'run_now' => __( 'Run Now', 'feedzy-rss-feeds' ),
148
  'dry_run_loading' => '<p class="hide-when-loaded">' . __( 'Processing the source and loading the items that will be imported when it runs', 'feedzy-rss-feeds' ) . '...</p>'
149
  . '<p><b>' . __( 'Please note that if some of these items have already have been imported in previous runs with the same filters, they may be shown here but will not be imported again.', 'feedzy-rss-feeds' ) . '</b></p>'
150
  . '<p class="loading-img hide-when-loaded"><img src="' . includes_url( 'images/wpspin-2x.gif' ) . '"></p><div></div>',
151
+ 'dry_run_title' => __( 'Importable Items', 'feedzy-rss-feeds' ),
152
  ),
153
  )
154
  );
174
 
175
  // If set to true, SimplePie will return a unique MD5 hash for the item.
176
  // If set to false, it will check <guid>, <link>, and <title> before defaulting to the hash.
177
+ $itemArray['item_id'] = $item->get_id( false );
178
 
179
+ $itemArray['item'] = $item;
180
+ $itemArray['item_index'] = $item_index;
181
  return $itemArray;
182
  }
183
 
273
  */
274
  public function feedzy_import_feed_options() {
275
  global $post;
276
+ $args = array(
277
  'post_type' => 'feedzy_categories',
278
  'posts_per_page' => 100,
279
  );
280
+ $feed_categories = get_posts( $args );
281
+ $post_types = get_post_types( '', 'names' );
282
+ $post_types = array_diff( $post_types, array( 'feedzy_imports', 'feedzy_categories' ) );
283
+ $published_status = array( 'publish', 'draft' );
284
+ $import_post_type = get_post_meta( $post->ID, 'import_post_type', true );
285
+ $import_post_term = get_post_meta( $post->ID, 'import_post_term', true );
286
  if ( metadata_exists( $import_post_type, $post->ID, 'import_post_status' ) ) {
287
+ $import_post_status = get_post_meta( $post->ID, 'import_post_status', true );
288
  } else {
289
  add_post_meta( $post->ID, 'import_post_status', 'publish' );
290
+ $import_post_status = get_post_meta( $post->ID, 'import_post_status', true );
291
  }
292
  $source = get_post_meta( $post->ID, 'source', true );
293
  $inc_key = get_post_meta( $post->ID, 'inc_key', true );
295
  $import_title = get_post_meta( $post->ID, 'import_post_title', true );
296
  $import_date = get_post_meta( $post->ID, 'import_post_date', true );
297
  $import_content = get_post_meta( $post->ID, 'import_post_content', true );
298
+ $import_item_img_url = get_post_meta( $post->ID, 'import_use_external_image', true );
299
+ $import_item_img_url = 'yes' === $import_item_img_url ? 'checked' : '';
300
  $import_featured_img = get_post_meta( $post->ID, 'import_post_featured_img', true );
301
 
302
  // default values so that post is not created empty.
307
  $import_content = '[#item_content]';
308
  }
309
 
310
+ $import_link_author_admin = get_post_meta( $post->ID, 'import_link_author_admin', true );
311
+ $import_link_author_public = get_post_meta( $post->ID, 'import_link_author_public', true );
312
 
313
+ // Admin / Public
314
  $import_link_author = array( '', '' );
315
+ if ( 'yes' === $import_link_author_admin ) {
316
  $import_link_author[0] = 'checked';
317
  }
318
+ if ( 'yes' === $import_link_author_public ) {
319
  $import_link_author[1] = 'checked';
320
  }
321
 
327
  if ( empty( $import_feed_limit ) ) {
328
  $import_feed_limit = 10;
329
  }
330
+ $import_feed_delete_days = intval( get_post_meta( $post->ID, 'import_feed_delete_days', true ) );
331
  if ( empty( $import_feed_delete_days ) ) {
332
  $import_feed_delete_days = 0;
333
  }
334
+ $post_status = $post->post_status;
335
+ $nonce = wp_create_nonce( FEEDZY_BASEFILE );
336
+ $invalid_source_msg = apply_filters( 'feedzy_get_source_validity_error', '', $post );
337
+ $output = '
338
  <input type="hidden" name="feedzy_category_meta_noncename" id="feedzy_category_meta_noncename" value="' . $nonce . '" />
339
  ';
340
 
341
  add_thickbox();
342
  include FEEDZY_ABSPATH . '/includes/views/import-metabox-edit.php';
343
+ echo wp_kses_post( $output );
344
  }
345
 
346
  /**
366
  * @return bool
367
  */
368
  public function save_feedzy_import_feed_meta( $post_id, $post ) {
369
+ if ( empty( $_POST ) ) {
370
+ return $post_id;
371
+ }
372
+ if ( ! isset( $_POST['feedzy_post_nonce'] ) ) {
373
+ return $post_id;
374
+ }
375
  if (
 
376
  get_post_type( $post_id ) !== 'feedzy_imports' ||
377
+ ( ! defined( 'TI_UNIT_TESTING' ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['feedzy_post_nonce'] ) ), 'feedzy_post_nonce' ) ) ||
378
  ! current_user_can( 'edit_post', $post_id )
379
  ) {
380
  return $post_id;
381
  }
382
+
383
+ $data_meta = array();
384
+ if ( isset( $_POST['feedzy_meta_data'] ) && is_array( $_POST['feedzy_meta_data'] ) ) {
385
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
386
+ foreach ( wp_unslash( $_POST['feedzy_meta_data'] ) as $key => $val ) {
387
+ if ( is_array( $val ) ) {
388
+ foreach ( $val as $sub_key => $sub_val ) {
389
+ $data_meta[ sanitize_text_field( $key ) ][ sanitize_text_field( $sub_key ) ] = wp_kses( $sub_val, apply_filters( 'feedzy_wp_kses_allowed_html', array() ) );
390
+ }
391
+ } else {
392
+ $data_meta[ sanitize_text_field( $key ) ] = wp_kses( $val, apply_filters( 'feedzy_wp_kses_allowed_html', array() ) );
393
+ }
394
+ }
395
+ }
396
+ $custom_fields_keys = array();
397
+ if ( isset( $_POST['custom_vars_key'] ) && is_array( $_POST['custom_vars_key'] ) ) {
398
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
399
+ foreach ( wp_unslash( $_POST['custom_vars_key'] ) as $key => $val ) {
400
+ $custom_fields_keys[ sanitize_text_field( $key ) ] = esc_html( $val );
401
+ }
402
+ }
403
+ $custom_fields_values = array();
404
+ if ( isset( $_POST['custom_vars_value'] ) && is_array( $_POST['custom_vars_value'] ) ) {
405
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
406
+ foreach ( wp_unslash( $_POST['custom_vars_value'] ) as $key => $val ) {
407
+ $custom_fields_values[ sanitize_text_field( $key ) ] = esc_html( $val );
408
+ }
409
+ }
410
  $custom_fields = array();
411
  foreach ( $custom_fields_keys as $index => $key_value ) {
412
  $value = '';
422
 
423
  // we will activate this import only if the source has no invalid URL(s)
424
  $source_is_valid = false;
425
+ // Check feeds external image URL checkbox checked OR not.
426
+ $data_meta['import_use_external_image'] = isset( $data_meta['import_use_external_image'] ) ? $data_meta['import_use_external_image'] : 'no';
427
  foreach ( $data_meta as $key => $value ) {
428
  $value = is_array( $value ) ? implode( ',', $value ) : implode( ',', (array) $value );
429
  if ( 'source' === $key ) {
430
  // check if the source is valid
431
+ $invalid_urls = apply_filters( 'feedzy_check_source_validity', $value, $post_id, true, false );
432
  $source_is_valid = empty( $invalid_urls );
433
  }
434
+ if ( 'import_post_content' === $key ) {
435
+ add_filter( 'wp_kses_allowed_html', array( $this, 'allow_iframe_tag_item_content' ), 10, 2 );
436
+ }
437
  if ( get_post_meta( $post_id, $key, false ) ) {
438
  update_post_meta( $post_id, $key, wp_kses( $value, wp_kses_allowed_html( 'post' ) ) );
439
  } else {
475
  // if invalid source has been found, redirect back to edit screen
476
  // where errors can be shown
477
  $invalid = get_post_meta( $post_id, '__transient_feedzy_invalid_source', true );
478
+ $invalid_dc_namespace = get_post_meta( $post_id, '__transient_feedzy_invalid_dc_namespace', true );
479
+ if ( empty( $invalid ) && empty( $invalid_dc_namespace ) ) {
480
  return admin_url( 'edit.php?post_type=feedzy_imports' );
481
  }
482
  }
574
  } else {
575
  // else link it to the feed but shorten it if it is too long.
576
  $too_long = 65;
577
+ $src = sprintf( '%s%s%s', '<a href="' . $src . '" target="_blank" title="' . __( 'Click to view', 'feedzy-rss-feeds' ) . '">', ( strlen( $src ) > $too_long ? substr( $src, 0, $too_long ) . '...' : $src ), '</a>' );
578
  }
579
+ echo wp_kses_post( $src );
580
  break;
581
  case 'feedzy-status':
582
  $status = $post->post_status;
583
  if ( empty( $status ) ) {
584
+ esc_html_e( 'Undefined', 'feedzy-rss-feeds' );
585
  } else {
586
  if ( $status === 'publish' ) {
587
  $checked = 'checked';
588
  } else {
589
  $checked = '';
590
  }
591
+ echo wp_kses(
592
+ '<div class="switch">
593
+ <input id="feedzy-toggle_' . $post->ID . '" class="feedzy-toggle feedzy-toggle-round" type="checkbox" value="' . $post->ID . '" ' . $checked . '>
594
+ <label for="feedzy-toggle_' . $post->ID . '"></label>
595
+ <span class="feedzy-spinner spinner"></span>
596
+ </div>',
597
+ apply_filters( 'feedzy_wp_kses_allowed_html', array() )
598
+ );
599
  }
600
  break;
601
  case 'feedzy-last_run':
602
+ $last = get_post_meta( $post_id, 'last_run', true );
603
+ $msg = __( 'Never Run', 'feedzy-rss-feeds' );
604
  if ( $last ) {
605
  $now = new DateTime();
606
  $then = new DateTime();
610
  }
611
 
612
  $msg .= $this->get_last_run_details( $post_id );
613
+ echo ( $msg ); //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
614
 
615
  if ( 'publish' === $post->post_status ) {
616
+ echo sprintf( '<p><input type="button" class="button button-primary feedzy-run-now" data-id="%d" value="%s"></p>', esc_attr( $post_id ), esc_attr__( 'Run Now', 'feedzy-rss-feeds' ) );
617
  }
618
 
619
  break;
624
  $then = new DateTime();
625
  $then = $then->setTimestamp( $next );
626
  $in = $now->diff( $then );
627
+ echo wp_kses_post( sprintf( __( 'In %1$d hours %2$d minutes', 'feedzy-rss-feeds' ), $in->format( '%h' ), $in->format( '%i' ) ) );
628
  }
629
  break;
630
  default:
644
  $msg = '';
645
  $last = get_post_meta( $post_id, 'last_run', true );
646
  $status = array(
647
+ 'total' => '-',
648
+ 'items' => '-',
649
  'duplicates' => '-',
650
  'cumulative' => '-',
651
  );
652
  if ( $last ) {
653
  $status = array(
654
+ 'total' => 0,
655
+ 'items' => 0,
656
  'duplicates' => 0,
657
  'cumulative' => 0,
658
  );
660
  }
661
 
662
  // link to the posts listing for this job.
663
+ $job_linked_posts = add_query_arg(
664
+ array(
665
+ 'feedzy_job_id' => $post_id,
666
+ 'post_type' => get_post_meta(
667
+ $post_id,
668
+ 'import_post_type',
669
+ true
670
+ ),
671
+ '_nonce' => wp_create_nonce( 'job_run_linked_posts' ),
672
+ ),
673
+ admin_url( 'edit.php' )
674
+ );
675
 
676
  // link to the posts listing for this job run.
677
+ $job_run_linked_posts = '';
678
+ $job_run_id = get_post_meta( $post_id, 'last_run_id', true );
679
  if ( ! empty( $job_run_id ) ) {
680
+ $job_run_linked_posts = add_query_arg(
681
+ array(
682
+ 'feedzy_job_id' => $post_id,
683
+ 'feedzy_job_time' => $job_run_id,
684
+ '_nonce' => wp_create_nonce( 'job_run_linked_posts' ),
685
+ 'post_type' => get_post_meta(
686
+ $post_id,
687
+ 'import_post_type',
688
+ true
689
+ ),
690
+ ),
691
+ admin_url( 'edit.php' )
692
+ );
693
  }
694
 
695
  // popup for items found.
791
  * @access private
792
  */
793
  private function get_complete_import_status( $post_id ) {
794
+ $items_count = get_post_meta( $post_id, 'imported_items_count', true );
795
+ $items = get_post_meta( $post_id, 'imported_items_hash', true );
796
  if ( empty( $items ) ) {
797
+ $items = get_post_meta( $post_id, 'imported_items', true );
798
  }
799
+ $count = $items_count;
800
  if ( '' === $count && $items ) {
801
  // backward compatibility where imported_items_count post_meta has not been populated yet
802
+ $count = count( $items );
803
  }
804
 
805
  $status = array(
806
+ 'total' => $count,
807
+ 'items' => 0,
808
  'duplicates' => 0,
809
  'cumulative' => 0,
810
  );
827
  }
828
  }
829
 
830
+ $items = get_post_meta( $post_id, 'imported_items_hash', true );
831
  if ( empty( $items ) ) {
832
+ $items = get_post_meta( $post_id, 'imported_items', true );
833
  }
834
  if ( $items ) {
835
  $status['cumulative'] = count( $items );
846
  * @access private
847
  */
848
  private function get_import_errors( $post_id ) {
849
+ $msg = '';
850
  $import_errors = get_post_meta( $post_id, 'import_errors', true );
851
  if ( $import_errors ) {
852
  $errors = '';
864
 
865
  // the pro messages may not have the dashicons, so let's add them.
866
  if ( $pro_msg && strpos( $pro_msg, 'dashicons-warning' ) === false ) {
867
+ $errors = '';
868
  $pro_errors = explode( '<br>', $pro_msg );
869
  if ( is_array( $pro_errors ) ) {
870
  foreach ( $pro_errors as $err ) {
889
  public function ajax() {
890
  check_ajax_referer( FEEDZY_BASEFILE, 'security' );
891
 
892
+ $_POST['feedzy_category_meta_noncename'] = filter_input( INPUT_POST, 'security', FILTER_SANITIZE_STRING );
893
+ $_action = filter_input( INPUT_POST, '_action', FILTER_SANITIZE_STRING );
894
 
895
+ switch ( $_action ) {
896
  case 'import_status':
897
  $this->import_status();
898
  break;
919
  */
920
  private function import_status() {
921
  global $wpdb;
922
+
923
+ check_ajax_referer( FEEDZY_BASEFILE, 'security' );
924
+
925
+ $id = filter_input( INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT );
926
+ $status = filter_input( INPUT_POST, 'status', FILTER_SANITIZE_STRING );
927
  $publish = 'draft';
928
 
929
  // no activation till source is not valid.
930
+ if ( 'true' === $status ) {
931
  $invalid_urls = apply_filters( 'feedzy_check_source_validity', get_post_meta( $id, 'source', true ), $id, true, false );
932
  if ( ! empty( $invalid_urls ) ) {
933
  $msg = apply_filters( 'feedzy_get_source_validity_error', '', get_post( $id ), '' );
943
  );
944
 
945
  remove_action( 'save_post_feedzy_imports', array( $this, 'save_feedzy_import_feed_meta' ), 1, 2 );
946
+ $post_id = wp_update_post( $new_post_status );
947
  add_action( 'save_post_feedzy_imports', array( $this, 'save_feedzy_import_feed_meta' ), 1, 2 );
948
 
949
  if ( is_wp_error( $post_id ) ) {
960
  * @access private
961
  */
962
  private function get_taxonomies() {
963
+ check_ajax_referer( FEEDZY_BASEFILE, 'security' );
964
+
965
+ $post_type = filter_input( INPUT_POST, 'post_type', FILTER_SANITIZE_STRING );
966
  $taxonomies = get_object_taxonomies(
967
  array(
968
  'post_type' => $post_type,
980
  $results[ $taxonomy ] = $terms;
981
  }
982
  }
983
+ echo wp_json_encode( $results );
984
  wp_die();
985
  }
986
 
991
  * @access private
992
  */
993
  private function run_now() {
994
+ check_ajax_referer( FEEDZY_BASEFILE, 'security' );
995
+
996
+ $job = get_post( filter_input( INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT ) );
997
+ $count = $this->run_job( $job, 100 );
998
 
999
+ $msg = $count > 0 ? __( 'Successfully run!', 'feedzy-rss-feeds' ) : __( 'Nothing imported!', 'feedzy-rss-feeds' );
1000
+ $msg .= ' (' . __( 'Refresh this page for the updated status', 'feedzy-rss-feeds' ) . ')';
1001
 
1002
  wp_send_json_success( array( 'msg' => $msg ) );
1003
  }
1009
  * @access private
1010
  */
1011
  private function dry_run() {
1012
+ check_ajax_referer( FEEDZY_BASEFILE, 'security' );
1013
+
1014
+ $fields = urldecode( filter_input( INPUT_POST, 'fields', FILTER_SANITIZE_URL ) );
1015
  parse_str( $fields, $data );
1016
 
1017
  $feedzy_meta_data = $data['feedzy_meta_data'];
1018
 
1019
  add_filter(
1020
+ 'feedzy_default_error',
1021
+ function( $errors, $feed, $url ) {
1022
  $errors .=
1023
  sprintf( __( 'For %1$ssingle feeds%2$s, this could be because of the following reasons:', 'feedzy-rss-feeds' ), '<b>', '</b>' )
1024
  . '<ol>'
1032
  . '</ol>';
1033
 
1034
  return $errors;
1035
+ },
1036
+ 11,
1037
+ 3
1038
  );
1039
 
1040
  // we will add tags corresponding to the most potential problems.
1077
  $args = array(
1078
  'post_type' => 'feedzy_imports',
1079
  'post_status' => 'publish',
1080
+ 'numberposts' => 99,
1081
  );
1082
  $feedzy_imports = get_posts( $args );
1083
  foreach ( $feedzy_imports as $job ) {
1104
  $import_post_type = get_post_meta( $job->ID, 'import_post_type', true );
1105
  $import_post_term = get_post_meta( $job->ID, 'import_post_term', true );
1106
  $import_feed_limit = get_post_meta( $job->ID, 'import_feed_limit', true );
1107
+ $import_item_img_url = get_post_meta( $job->ID, 'import_use_external_image', true );
1108
  $max = $import_feed_limit;
1109
  if ( metadata_exists( $import_post_type, $job->ID, 'import_post_status' ) ) {
1110
+ $import_post_status = get_post_meta( $job->ID, 'import_post_status', true );
1111
  } else {
1112
  add_post_meta( $job->ID, 'import_post_status', 'publish' );
1113
+ $import_post_status = get_post_meta( $job->ID, 'import_post_status', true );
1114
  }
1115
 
1116
  // the array of imported items that uses the old scheme of custom hashing the url and date
1117
+ $imported_items = array();
1118
+ $imported_items_old = get_post_meta( $job->ID, 'imported_items', true );
1119
  if ( ! is_array( $imported_items_old ) ) {
1120
  $imported_items_old = array();
1121
  }
1122
 
1123
  // the array of imported items that uses the new scheme of SimplePie's hash/id
1124
+ $imported_items_new = get_post_meta( $job->ID, 'imported_items_hash', true );
1125
  if ( ! is_array( $imported_items_new ) ) {
1126
  $imported_items_new = array();
1127
  }
1130
  // the date, because if the title can have UTC date and content can have local date then it
1131
  // all goes sideways.
1132
  // also if the user provides multiple date types, local will win.
1133
+ $meta = 'yes';
1134
  if ( strpos( $import_title, '[#item_date_local]' ) !== false ) {
1135
+ $meta = 'author, date, time, tz=local';
1136
  } elseif ( strpos( $import_title, '[#item_date_feed]' ) !== false ) {
1137
+ $meta = 'author, date, time, tz=no';
1138
  }
1139
 
1140
  $options = apply_filters(
1141
+ 'feedzy_shortcode_options',
1142
+ array(
1143
+ 'feeds' => $source,
1144
+ 'max' => $max,
1145
+ 'feed_title' => 'no',
1146
+ 'target' => '_blank',
1147
+ 'title' => '',
1148
+ 'meta' => $meta,
1149
+ 'summary' => 'yes',
1150
+ 'summarylength' => '',
1151
+ 'thumb' => 'auto',
1152
+ 'default' => '',
1153
+ 'size' => '250',
1154
+ 'keywords_inc' => $inc_key, // this is not keywords_title
1155
+ 'keywords_ban' => $exc_key, // to support old pro that does not support keywords_exc
1156
+ 'keywords_exc' => $exc_key, // this is not keywords_ban
1157
+ 'columns' => 1,
1158
+ 'offset' => 0,
1159
+ 'multiple_meta' => 'no',
1160
+ 'refresh' => '55_mins',
1161
+ ),
1162
+ $job
1163
  );
1164
 
1165
+ $admin = Feedzy_Rss_Feeds::instance()->get_admin();
1166
  $options = $admin->sanitize_attr( $options, $source );
1167
 
1168
  $options['__jobID'] = $job->ID;
1200
  // or the new scheme of depending on SimplePie's hash/id
1201
  // basically if the old scheme hasn't be used before, use the new scheme
1202
  // BUT if the old scheme has been used, continue with it.
1203
+ $use_new_hash = empty( $imported_items_old );
1204
  $imported_items = $use_new_hash ? $imported_items_new : $imported_items_old;
1205
 
1206
  $start_import = true;
1207
  // bail if both title and content are empty because the post will not be created.
1208
  if ( empty( $import_title ) && empty( $import_content ) ) {
1209
  $import_errors[] = __( 'Title & Content are both empty.', 'feedzy-rss-feeds' );
1210
+ $start_import = false;
1211
  }
1212
 
1213
  if ( ! $start_import ) {
1218
  $duplicates = $items_found = array();
1219
 
1220
  foreach ( $result as $item ) {
1221
+ $item_hash = $use_new_hash ? $item['item_id'] : hash( 'sha256', $item['item_url'] . '_' . $item['item_date'] );
1222
+ $is_duplicate = $use_new_hash ? in_array( $item_hash, $imported_items_new, true ) : in_array( $item_hash, $imported_items_old, true );
1223
  $items_found[ $item['item_url'] ] = $item['item_title'];
1224
 
1225
  if ( $is_duplicate ) {
1229
  continue;
1230
  }
1231
 
1232
+ $author = '';
1233
  if ( $item['item_author'] ) {
1234
  if ( is_string( $item['item_author'] ) ) {
1235
  $author = $item['item_author'];
1273
 
1274
  $post_title = apply_filters( 'feedzy_invoke_services', $post_title, 'title', $item['item_title'], $job );
1275
 
1276
+ $item_link = '<a href="' . $item['item_url'] . '" target="_blank">' . __( 'Read More', 'feedzy-rss-feeds' ) . '</a>';
1277
+ $image_html = '';
1278
  if ( ! empty( $item['item_img_path'] ) ) {
1279
+ $image_html = '<img src="' . $item['item_img_path'] . '" title="' . $item['item_title'] . '" />';
1280
  }
1281
  $post_content = str_replace(
1282
  array(
1328
  $post_content = apply_filters( 'feedzy_parse_custom_tags', $post_content, $results['feed'], $item['item_index'] );
1329
  }
1330
 
1331
+ $post_content = apply_filters( 'feedzy_invoke_services', $post_content, 'content', $item['item_description'], $job );
1332
 
1333
  // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
1334
  $item_date = date( 'Y-m-d H:i:s', $item['item_date'] );
1335
  // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
1336
+ $now = date( 'Y-m-d H:i:s' );
1337
  if ( trim( $import_date ) === '' ) {
1338
  $post_date = $now;
1339
  }
1340
+ $post_date = str_replace( '[#item_date]', $item_date, $import_date );
1341
+ $post_date = str_replace( '[#post_date]', $now, $post_date );
1342
 
1343
+ $new_post = apply_filters(
1344
+ 'feedzy_insert_post_args',
1345
+ array(
1346
  'post_type' => $import_post_type,
1347
+ 'post_title' => wp_kses( $post_title, apply_filters( 'feedzy_wp_kses_allowed_html', array() ) ),
1348
+ 'post_content' => wp_kses( $post_content, apply_filters( 'feedzy_wp_kses_allowed_html', array() ) ),
1349
  'post_date' => $post_date,
1350
  'post_status' => $import_post_status,
1351
  ),
1385
  if ( $import_post_term !== 'none' && strpos( $import_post_term, '_' ) > 0 ) {
1386
  // let's get the slug of the uncategorized category, even if it renamed.
1387
  $uncategorized = get_category( 1 );
1388
+ $terms = explode( ',', $import_post_term );
1389
  foreach ( $terms as $term ) {
1390
  // this handles both x_2, where 2 is the term id and x is the taxonomy AND x_2_3_4 where 4 is the term id and the taxonomy name is "x 2 3 4".
1391
+ $array = explode( '_', $term );
1392
+ $term_id = array_pop( $array );
1393
  $taxonomy = implode( '_', $array );
1394
 
1395
  // uncategorized
1405
  do_action( 'feedzy_import_extra', $job, $results, $new_post_id, $index, $item['item_index'], $import_errors, $import_info );
1406
 
1407
  if ( ! empty( $import_featured_img ) ) {
1408
+ $image_url = '';
1409
  $img_success = true;
1410
 
1411
  // image tag
1429
  }
1430
 
1431
  if ( ! empty( $image_url ) ) {
1432
+ if ( 'yes' === $import_item_img_url ) {
1433
+ // Set external image URL.
1434
+ update_post_meta( $new_post_id, 'feedzy_item_external_url', $image_url );
1435
+ } else {
1436
+ // if import_featured_img is a tag.
1437
+ $img_success = $this->generate_featured_image( $image_url, $new_post_id, $item['item_title'], $import_errors, $import_info );
1438
+ }
1439
  }
1440
 
1441
  if ( ! $img_success ) {
1470
  update_post_meta( $job->ID, 'import_errors', $import_errors );
1471
 
1472
  // the order of these matters in how they are finally shown in the summary.
1473
+ $import_info['total'] = $items_found;
1474
  $import_info['duplicates'] = $duplicates;
1475
 
1476
  update_post_meta( $job->ID, 'import_info', $import_info );
1502
  return $feedURL;
1503
  }
1504
 
1505
+ $feed = $admin->fetch_feed( $feedURL, isset( $options['refresh'] ) ? $options['refresh'] : '12_hours', $options );
1506
+
1507
+ $feed->force_feed( true );
1508
+ $feed->enable_order_by_date( false );
1509
 
1510
  if ( is_string( $feed ) ) {
1511
  return array();
1543
  private function generate_featured_image( $file, $post_id, $desc, &$import_errors, &$import_info ) {
1544
  do_action( 'themeisle_log_event', FEEDZY_NAME, sprintf( 'Trying to generate featured image for %s and postID %d', $file, $post_id ), 'debug', __FILE__, __LINE__ );
1545
 
1546
+ require_once ABSPATH . 'wp-admin' . '/includes/image.php';
1547
+ require_once ABSPATH . 'wp-admin' . '/includes/file.php';
1548
+ require_once ABSPATH . 'wp-admin' . '/includes/media.php';
1549
 
1550
+ $file_array = array();
1551
+ $local_file = download_url( $file );
1552
  if ( is_wp_error( $local_file ) ) {
1553
  do_action( 'themeisle_log_event', FEEDZY_NAME, sprintf( 'Unable to download file = %s and postID %d', print_r( $local_file, true ), $post_id ), 'error', __FILE__, __LINE__ );
1554
  return false;
1555
  }
1556
 
1557
+ $type = mime_content_type( $local_file );
1558
  // the file is downloaded with a .tmp extension
1559
  // if the URL mentions the extension of the file, the upload succeeds
1560
  // but if the URL is like https://source.unsplash.com/random, then the upload fails
1573
  $file_array['tmp_name'] = $local_file;
1574
  $file_array['name'] = basename( $local_file );
1575
 
1576
+ $id = media_handle_sideload( $file_array, $post_id, $desc );
1577
  if ( is_wp_error( $id ) ) {
1578
  do_action( 'themeisle_log_event', FEEDZY_NAME, sprintf( 'Unable to attach file for postID %d = %s', $post_id, print_r( $id, true ) ), 'error', __FILE__, __LINE__ );
1579
  unlink( $file_array['tmp_name'] );
1607
  * @access public
1608
  */
1609
  public function admin_notices() {
1610
+ $screen = get_current_screen();
1611
+ $allowed = array( 'edit-feedzy_categories', 'edit-feedzy_imports', 'feedzy-rss_page_feedzy-settings' );
1612
  // only show in the feedzy screens.
1613
  if ( ! in_array( $screen->id, $allowed, true ) ) {
1614
  return;
1615
  }
1616
 
1617
  if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
1618
+ echo wp_kses_post( '<div class="notice notice-error feedzy-error-critical is-dismissible"><p>' . __( 'WP Cron is disabled. Your feeds would not get updated. Please contact your hosting provider or system administrator', 'feedzy-rss-feeds' ) . '</p></div>' );
1619
  }
1620
 
1621
  if ( false === wp_next_scheduled( 'feedzy_cron' ) ) {
1622
+ echo wp_kses_post( '<div class="notice notice-error"><p>' . __( 'Unable to register cron job. Your feeds might not get updated', 'feedzy-rss-feeds' ) . '</p></div>' );
1623
  }
1624
 
1625
  }
1683
  * @access public
1684
  */
1685
  public function update_settings_page() {
 
1686
  $this->save_settings();
1687
  wp_die();
1688
  }
1697
  $this->free_settings = get_option( 'feedzy-settings', array() );
1698
 
1699
  $fields[] = array(
1700
+ 'content' => $this->render_view( $tab ),
1701
+ 'ajax' => false,
1702
  );
1703
  return $fields;
1704
  }
1730
  * @access public
1731
  */
1732
  public function save_tab_settings( $settings, $tab ) {
1733
+ if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_STRING ), $tab ) ) {
1734
+ return;
1735
+ }
1736
+
1737
  if ( 'misc' === $tab ) {
1738
+ $settings['canonical'] = isset( $_POST['canonical'] ) ? filter_input( INPUT_POST, 'canonical', FILTER_SANITIZE_NUMBER_INT ) : 0;
1739
  }
1740
  return $settings;
1741
  }
1784
  $disabled[ str_replace( ':disabled', '', $tag ) ] = $label;
1785
  continue;
1786
  }
1787
+ $default .= '<a class="dropdown-item" href="#" data-field-name="' . $type . '" data-field-tag="' . $tag . '">' . $label . ' -- <small>[#' . $tag . ']</small></a>';
1788
  }
1789
 
1790
  if ( $disabled ) {
1791
  foreach ( $disabled as $tag => $label ) {
1792
+ $default .= '<span disabled title="' . __( 'Upgrade your license to use this tag', 'feedzy-rss-feeds' ) . '" class="dropdown-item">' . $label . ' -- <small>[#' . $tag . ']</small></span>';
1793
  }
1794
  }
1795
  }
1805
  * @param array $default The default tags, empty.
1806
  */
1807
  public function magic_tags_title( $default ) {
1808
+ $default['item_title'] = __( 'Item Title', 'feedzy-rss-feeds' );
1809
+ $default['item_author'] = __( 'Item Author', 'feedzy-rss-feeds' );
1810
+ $default['item_date'] = __( 'Item Date (UTC/GMT)', 'feedzy-rss-feeds' );
1811
+ $default['item_date_local'] = __( 'Item Date (local timezone)', 'feedzy-rss-feeds' );
1812
+ $default['item_date_feed'] = __( 'Item Date (feed timezone)', 'feedzy-rss-feeds' );
1813
+ $default['item_source'] = __( 'Item Source', 'feedzy-rss-feeds' );
1814
+
1815
+ // disabled tags.
1816
  if ( ! feedzy_is_pro() ) {
1817
+ $default['title_spinnerchief:disabled'] = __( 'Title from SpinnerChief', 'feedzy-rss-feeds' );
1818
+ $default['title_wordai:disabled'] = __( 'Title from WordAI', 'feedzy-rss-feeds' );
1819
  }
1820
  return $default;
1821
  }
1829
  * @param array $default The default tags, empty.
1830
  */
1831
  public function magic_tags_date( $default ) {
1832
+ $default['item_date'] = __( 'Item Date', 'feedzy-rss-feeds' );
1833
+ $default['post_date'] = __( 'Post Date', 'feedzy-rss-feeds' );
1834
  return $default;
1835
  }
1836
 
1843
  * @param array $default The default tags, empty.
1844
  */
1845
  public function magic_tags_content( $default ) {
1846
+ $default['item_content'] = __( 'Item Content', 'feedzy-rss-feeds' );
1847
+ $default['item_description'] = __( 'Item Description', 'feedzy-rss-feeds' );
1848
+ $default['item_image'] = __( 'Item Image', 'feedzy-rss-feeds' );
1849
+ $default['item_url'] = __( 'Item URL', 'feedzy-rss-feeds' );
1850
+ $default['item_categories'] = __( 'Item Categories', 'feedzy-rss-feeds' );
1851
+ $default['item_source'] = __( 'Item Source', 'feedzy-rss-feeds' );
1852
+
1853
+ // disabled tags.
1854
  if ( ! feedzy_is_pro() ) {
1855
+ $default['item_full_content:disabled'] = __( 'Item Full Content', 'feedzy-rss-feeds' );
1856
+ $default['content_spinnerchief:disabled'] = __( 'Content from SpinnerChief', 'feedzy-rss-feeds' );
1857
+ $default['full_content_spinnerchief:disabled'] = __( 'Full content from SpinnerChief', 'feedzy-rss-feeds' );
1858
+ $default['content_wordai:disabled'] = __( 'Content from WordAI', 'feedzy-rss-feeds' );
1859
+ $default['full_content_wordai:disabled'] = __( 'Full content from WordAI', 'feedzy-rss-feeds' );
1860
  }
1861
  return $default;
1862
  }
1870
  * @param array $default The default tags, empty.
1871
  */
1872
  public function magic_tags_image( $default ) {
1873
+ $default['item_image'] = __( 'Item Image', 'feedzy-rss-feeds' );
1874
  return $default;
1875
  }
1876
 
1916
 
1917
  // let's check if the post has been imported by feedzy.
1918
  if ( 1 === intval( get_post_meta( $post->ID, 'feedzy', true ) ) ) {
1919
+ $url = get_post_meta( $post->ID, 'feedzy_item_url', true );
1920
  if ( ! empty( $url ) ) {
1921
  $canonical_url = $url;
1922
  }
1955
  * @access private
1956
  */
1957
  private function purge_data() {
1958
+ check_ajax_referer( FEEDZY_BASEFILE, 'security' );
1959
+
1960
+ $id = filter_input( INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT );
1961
+ $post = get_post( $id );
1962
  if ( $post->post_type !== 'feedzy_imports' ) {
1963
  wp_die();
1964
  }
1979
  * @access public
1980
  */
1981
  public function pre_get_posts( $query ) {
1982
+ if ( ! wp_verify_nonce( filter_input( INPUT_GET, '_nonce', FILTER_SANITIZE_STRING ), 'job_run_linked_posts' ) ) {
1983
+ return;
1984
+ }
1985
+
1986
+ $feedzy_job_id = filter_input( INPUT_GET, 'feedzy_job_id', FILTER_SANITIZE_NUMBER_INT );
1987
+ $feedzy_job_time = filter_input( INPUT_GET, 'feedzy_job_time', FILTER_SANITIZE_STRING );
1988
+
1989
+ if ( is_admin() && $query->is_main_query() && ! empty( $feedzy_job_id ) ) {
1990
  $meta_query = array(
1991
  array(
1992
+ 'key' => 'feedzy',
1993
  'value' => 1,
1994
  ),
1995
  array(
1996
+ 'key' => 'feedzy_job',
1997
+ 'value' => $feedzy_job_id,
1998
  ),
1999
  );
2000
 
2001
+ if ( ! empty( $feedzy_job_time ) ) {
2002
  $meta_query[] = array(
2003
+ 'key' => 'feedzy_job_time',
2004
+ 'value' => $feedzy_job_time,
2005
  );
2006
  }
2007
 
2008
  $query->set( 'meta_query', $meta_query );
2009
  }
2010
  }
2011
+
2012
+ /**
2013
+ * Add iframe to allowed wp_kses_post tags.
2014
+ *
2015
+ * @param array $tags Allowed tags, attributes, and/or entities.
2016
+ * @param string $context Context.
2017
+ *
2018
+ * @return array
2019
+ */
2020
+ public function allow_iframe_tag_item_content( $tags, $context ) {
2021
+ if ( ! isset( $tags['iframe'] ) ) {
2022
+ $tags['iframe'] = array(
2023
+ 'src' => true,
2024
+ 'height' => true,
2025
+ 'width' => true,
2026
+ 'frameborder' => true,
2027
+ 'allowfullscreen' => true,
2028
+ );
2029
+ }
2030
+ return $tags;
2031
+ }
2032
  }
includes/admin/feedzy-rss-feeds-options.php CHANGED
@@ -37,7 +37,7 @@ if ( ! class_exists( 'Feedy_Rss_Feeds_Options' ) ) {
37
  */
38
  public static function instance() {
39
  if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Feedzy_Rss_Feeds_Options ) ) {
40
- self::$instance = new Feedzy_Rss_Feeds_Options;
41
  self::$instance->init();
42
  }
43
 
37
  */
38
  public static function instance() {
39
  if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Feedzy_Rss_Feeds_Options ) ) {
40
+ self::$instance = new Feedzy_Rss_Feeds_Options();
41
  self::$instance->init();
42
  }
43
 
includes/admin/feedzy-rss-feeds-ui-lang.php CHANGED
@@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
22
  */
23
 
24
  if ( ! class_exists( '_WP_Editors' ) ) {
25
- require( ABSPATH . WPINC . '/class-wp-editor.php' );
26
  }
27
 
28
  /**
@@ -88,36 +88,36 @@ class Feedzy_Rss_Feeds_Ui_Lang {
88
  * @return array|mixed|void
89
  */
90
  public static function get_form_elements() {
91
- $meta = sprintf( __( 'Should we display additional meta fields out of %1$sauthor%2$s, %3$sdate%4$s and %5$stime%6$s? (comma-separated list, in order of display). View documentation %7$shere%8$s.', 'feedzy-rss-feeds' ), '<code>', '</code>', '<code>', '</code>', '<code>', '</code>', '<a href="https://docs.themeisle.com/article/1089-how-to-display-author-date-or-time-from-the-feed" target="_new">', '</a>' );
92
  if ( has_filter( 'feedzy_retrieve_categories' ) ) {
93
- $meta = sprintf( __( 'Should we display additional meta fields out of %1$sauthor%2$s, %3$sdate%4$s, %5$stime%6$s and %7$scategories%8$s? (comma-separated list). View documentation %9$shere%10$s.', 'feedzy-rss-feeds' ), '<code>', '</code>', '<code>', '</code>', '<code>', '</code>', '<code>', '</code>', '<a href="https://docs.themeisle.com/article/1089-how-to-display-author-date-or-time-from-the-feed" target="_new">', '</a>' );
94
  }
95
 
96
- $multiple = sprintf( __( 'When using multiple sources, should we display additional meta fields? %1$ssource%2$s (feed title).', 'feedzy-rss-feeds' ), '<code>', '</code>', '<a href="https://docs.themeisle.com/article/1089-how-to-display-author-date-or-time-from-the-feed" target="_new">', '</a>' );
97
 
98
  $elements = array(
99
  'section_feed' => array(
100
  'title' => __( 'Feed Source', 'feedzy-rss-feeds' ),
101
  'elements' => array(
102
- 'feeds' => array(
103
  'label' => __( 'The feed(s) URL (comma-separated list).', 'feedzy-rss-feeds' ) . ' ' . sprintf( __( 'Click %1$shere%2$s to check if feed is valid.', 'feedzy-rss-feeds' ), '<a href="https://validator.w3.org/feed/" target="_new">', '</a>' ) . '<br><b>' . __( 'Invalid feeds will NOT display items.', 'feedzy-rss-feeds' ) . '</b>',
104
  'placeholder' => __( 'Feed URL', 'feedzy-rss-feeds' ),
105
  'type' => 'text',
106
  'value' => '',
107
  ),
108
- 'max' => array(
109
  'label' => __( 'Number of items to display.', 'feedzy-rss-feeds' ),
110
  'placeholder' => __( '(eg: 5)', 'feedzy-rss-feeds' ),
111
  'type' => 'text',
112
  'value' => '',
113
  ),
114
- 'offset' => array(
115
  'label' => __( 'Ignore the first N items of the feed.', 'feedzy-rss-feeds' ),
116
  'placeholder' => __( '(eg: 5, if you want to start from the 6th item.)', 'feedzy-rss-feeds' ),
117
  'type' => 'text',
118
  'value' => '0',
119
  ),
120
- 'feed_title' => array(
121
  'label' => __( 'Should we display the RSS title?', 'feedzy-rss-feeds' ),
122
  'type' => 'select',
123
  'value' => '',
@@ -132,7 +132,7 @@ class Feedzy_Rss_Feeds_Ui_Lang {
132
  ),
133
  ),
134
  ),
135
- 'refresh' => array(
136
  'label' => __( 'For how long we will cache the feed results.', 'feedzy-rss-feeds' ),
137
  'placeholder' => __( '(eg: 1_days, defaults: 12_hours)', 'feedzy-rss-feeds' ),
138
  'type' => 'select',
@@ -164,12 +164,12 @@ class Feedzy_Rss_Feeds_Ui_Lang {
164
  ),
165
  ),
166
  ),
167
- 'sort' => array(
168
  'label' => __( 'Sorting order.', 'feedzy-rss-feeds' ),
169
  'type' => 'select',
170
  'value' => '',
171
  'opts' => array(
172
- '' => array(
173
  'label' => __( 'Default', 'feedzy-rss-feeds' ),
174
  'value' => '',
175
  ),
@@ -191,13 +191,13 @@ class Feedzy_Rss_Feeds_Ui_Lang {
191
  ),
192
  ),
193
  ),
194
- 'error_empty' => array(
195
- 'label' => __( 'Message to show when feed is empty', 'feedzy-rss-feeds' ),
196
  'placeholder' => __( 'Feed has no items.', 'feedzy-rss-feeds' ),
197
  'type' => 'text',
198
  'value' => '',
199
  ),
200
- 'lazy' => array(
201
  'label' => __( 'Lazy load the feed (without slowing down the page)', 'feedzy-rss-feeds' ),
202
  'type' => 'select',
203
  'value' => 'no',
@@ -253,11 +253,11 @@ class Feedzy_Rss_Feeds_Ui_Lang {
253
  'type' => 'select',
254
  'value' => '',
255
  'opts' => array(
256
- 'auto' => array(
257
  'label' => __( 'No', 'feedzy-rss-feeds' ),
258
  'value' => '',
259
  ),
260
- '_blank' => array(
261
  'label' => __( 'Yes', 'feedzy-rss-feeds' ),
262
  'value' => 'no',
263
  ),
@@ -270,16 +270,16 @@ class Feedzy_Rss_Feeds_Ui_Lang {
270
  'value' => '',
271
  ),
272
  'meta' => array(
273
- 'label' => $meta,
274
  'placeholder' => __( '(eg: author, date, time, tz=local)', 'feedzy-rss-feeds' ),
275
- 'type' => 'text',
276
- 'value' => '',
277
  ),
278
- 'multiple_meta' => array(
279
- 'label' => $multiple,
280
  'placeholder' => __( '(eg: source)', 'feedzy-rss-feeds' ),
281
- 'type' => 'text',
282
- 'value' => '',
283
  ),
284
  'summary' => array(
285
  'label' => __( 'Should we display a description (abstract) of the retrieved item?', 'feedzy-rss-feeds' ),
@@ -355,7 +355,7 @@ class Feedzy_Rss_Feeds_Ui_Lang {
355
  'type' => 'text',
356
  'value' => '',
357
  ),
358
- 'http' => array(
359
  'label' => __( 'How should we treat HTTP images?', 'feedzy-rss-feeds' ),
360
  'type' => 'select',
361
  'value' => '',
@@ -410,12 +410,12 @@ class Feedzy_Rss_Feeds_Ui_Lang {
410
  'disabled' => true,
411
  'value' => '1',
412
  ),
413
- 'mapping' => array(
414
- 'label' => sprintf( __( 'Provide mapping for custom feed elements as per %1$sthis document here%2$s. This will only work for single feeds, not comma-separated feeds.', 'feedzy-rss-feeds' ), '<a href="https://docs.themeisle.com/article/977-how-do-i-extract-values-from-custom-tags-in-feedzy" target="_blank">', '</a>' ),
415
- 'type' => 'text',
416
- 'disabled' => true,
417
- 'value' => '',
418
- 'placeholder' => '',
419
  ),
420
  'template' => array(
421
  'label' => __( 'Template to use when displaying the feed.', 'feedzy-rss-feeds' ),
@@ -457,7 +457,7 @@ class Feedzy_Rss_Feeds_Ui_Lang {
457
  public function feedzy_tinymce_translation() {
458
 
459
  $locale = _WP_Editors::$mce_locale;
460
- $translated = 'tinyMCE.addI18n("' . $locale . '.feedzy_tinymce_plugin", ' . json_encode( $this->strings ) . ");\n";
461
 
462
  return $translated;
463
  }
@@ -477,4 +477,4 @@ class Feedzy_Rss_Feeds_Ui_Lang {
477
  }
478
 
479
  $feedzy_lang_class = new Feedzy_Rss_Feeds_Ui_Lang();
480
- $strings = $feedzy_lang_class->feedzy_tinymce_translation();
22
  */
23
 
24
  if ( ! class_exists( '_WP_Editors' ) ) {
25
+ require ABSPATH . WPINC . '/class-wp-editor.php';
26
  }
27
 
28
  /**
88
  * @return array|mixed|void
89
  */
90
  public static function get_form_elements() {
91
+ $meta = sprintf( __( 'Should we display additional meta fields out of %1$sauthor%2$s, %3$sdate%4$s and %5$stime%6$s? (comma-separated list, in order of display). View documentation %7$shere%8$s.', 'feedzy-rss-feeds' ), '<code>', '</code>', '<code>', '</code>', '<code>', '</code>', '<a href="https://docs.themeisle.com/article/1089-how-to-display-author-date-or-time-from-the-feed" target="_new">', '</a>' );
92
  if ( has_filter( 'feedzy_retrieve_categories' ) ) {
93
+ $meta = sprintf( __( 'Should we display additional meta fields out of %1$sauthor%2$s, %3$sdate%4$s, %5$stime%6$s and %7$scategories%8$s? (comma-separated list). View documentation %9$shere%10$s.', 'feedzy-rss-feeds' ), '<code>', '</code>', '<code>', '</code>', '<code>', '</code>', '<code>', '</code>', '<a href="https://docs.themeisle.com/article/1089-how-to-display-author-date-or-time-from-the-feed" target="_new">', '</a>' );
94
  }
95
 
96
+ $multiple = sprintf( __( 'When using multiple sources, should we display additional meta fields? %1$ssource%2$s (feed title).', 'feedzy-rss-feeds' ), '<code>', '</code>', '<a href="https://docs.themeisle.com/article/1089-how-to-display-author-date-or-time-from-the-feed" target="_new">', '</a>' );
97
 
98
  $elements = array(
99
  'section_feed' => array(
100
  'title' => __( 'Feed Source', 'feedzy-rss-feeds' ),
101
  'elements' => array(
102
+ 'feeds' => array(
103
  'label' => __( 'The feed(s) URL (comma-separated list).', 'feedzy-rss-feeds' ) . ' ' . sprintf( __( 'Click %1$shere%2$s to check if feed is valid.', 'feedzy-rss-feeds' ), '<a href="https://validator.w3.org/feed/" target="_new">', '</a>' ) . '<br><b>' . __( 'Invalid feeds will NOT display items.', 'feedzy-rss-feeds' ) . '</b>',
104
  'placeholder' => __( 'Feed URL', 'feedzy-rss-feeds' ),
105
  'type' => 'text',
106
  'value' => '',
107
  ),
108
+ 'max' => array(
109
  'label' => __( 'Number of items to display.', 'feedzy-rss-feeds' ),
110
  'placeholder' => __( '(eg: 5)', 'feedzy-rss-feeds' ),
111
  'type' => 'text',
112
  'value' => '',
113
  ),
114
+ 'offset' => array(
115
  'label' => __( 'Ignore the first N items of the feed.', 'feedzy-rss-feeds' ),
116
  'placeholder' => __( '(eg: 5, if you want to start from the 6th item.)', 'feedzy-rss-feeds' ),
117
  'type' => 'text',
118
  'value' => '0',
119
  ),
120
+ 'feed_title' => array(
121
  'label' => __( 'Should we display the RSS title?', 'feedzy-rss-feeds' ),
122
  'type' => 'select',
123
  'value' => '',
132
  ),
133
  ),
134
  ),
135
+ 'refresh' => array(
136
  'label' => __( 'For how long we will cache the feed results.', 'feedzy-rss-feeds' ),
137
  'placeholder' => __( '(eg: 1_days, defaults: 12_hours)', 'feedzy-rss-feeds' ),
138
  'type' => 'select',
164
  ),
165
  ),
166
  ),
167
+ 'sort' => array(
168
  'label' => __( 'Sorting order.', 'feedzy-rss-feeds' ),
169
  'type' => 'select',
170
  'value' => '',
171
  'opts' => array(
172
+ '' => array(
173
  'label' => __( 'Default', 'feedzy-rss-feeds' ),
174
  'value' => '',
175
  ),
191
  ),
192
  ),
193
  ),
194
+ 'error_empty' => array(
195
+ 'label' => __( 'Message to show when feed is empty', 'feedzy-rss-feeds' ),
196
  'placeholder' => __( 'Feed has no items.', 'feedzy-rss-feeds' ),
197
  'type' => 'text',
198
  'value' => '',
199
  ),
200
+ 'lazy' => array(
201
  'label' => __( 'Lazy load the feed (without slowing down the page)', 'feedzy-rss-feeds' ),
202
  'type' => 'select',
203
  'value' => 'no',
253
  'type' => 'select',
254
  'value' => '',
255
  'opts' => array(
256
+ 'auto' => array(
257
  'label' => __( 'No', 'feedzy-rss-feeds' ),
258
  'value' => '',
259
  ),
260
+ '_blank' => array(
261
  'label' => __( 'Yes', 'feedzy-rss-feeds' ),
262
  'value' => 'no',
263
  ),
270
  'value' => '',
271
  ),
272
  'meta' => array(
273
+ 'label' => $meta,
274
  'placeholder' => __( '(eg: author, date, time, tz=local)', 'feedzy-rss-feeds' ),
275
+ 'type' => 'text',
276
+ 'value' => '',
277
  ),
278
+ 'multiple_meta' => array(
279
+ 'label' => $multiple,
280
  'placeholder' => __( '(eg: source)', 'feedzy-rss-feeds' ),
281
+ 'type' => 'text',
282
+ 'value' => '',
283
  ),
284
  'summary' => array(
285
  'label' => __( 'Should we display a description (abstract) of the retrieved item?', 'feedzy-rss-feeds' ),
355
  'type' => 'text',
356
  'value' => '',
357
  ),
358
+ 'http' => array(
359
  'label' => __( 'How should we treat HTTP images?', 'feedzy-rss-feeds' ),
360
  'type' => 'select',
361
  'value' => '',
410
  'disabled' => true,
411
  'value' => '1',
412
  ),
413
+ 'mapping' => array(
414
+ 'label' => sprintf( __( 'Provide mapping for custom feed elements as per %1$sthis document here%2$s. This will only work for single feeds, not comma-separated feeds.', 'feedzy-rss-feeds' ), '<a href="https://docs.themeisle.com/article/977-how-do-i-extract-values-from-custom-tags-in-feedzy" target="_blank">', '</a>' ),
415
+ 'type' => 'text',
416
+ 'disabled' => true,
417
+ 'value' => '',
418
+ 'placeholder' => '',
419
  ),
420
  'template' => array(
421
  'label' => __( 'Template to use when displaying the feed.', 'feedzy-rss-feeds' ),
457
  public function feedzy_tinymce_translation() {
458
 
459
  $locale = _WP_Editors::$mce_locale;
460
+ $translated = 'tinyMCE.addI18n("' . $locale . '.feedzy_tinymce_plugin", ' . wp_json_encode( $this->strings ) . ");\n";
461
 
462
  return $translated;
463
  }
477
  }
478
 
479
  $feedzy_lang_class = new Feedzy_Rss_Feeds_Ui_Lang();
480
+ $strings = $feedzy_lang_class->feedzy_tinymce_translation();
includes/admin/feedzy-rss-feeds-ui.php CHANGED
@@ -57,8 +57,8 @@ class Feedzy_Rss_Feeds_Ui {
57
  public function __construct( $plugin_name, $version, Feedzy_Rss_Feeds_Loader $loader ) {
58
 
59
  $this->plugin_name = $plugin_name;
60
- $this->version = $version;
61
- $this->loader = $loader;
62
 
63
  }
64
 
@@ -69,9 +69,9 @@ class Feedzy_Rss_Feeds_Ui {
69
  * @access private
70
  */
71
  private function is_block_editor() {
72
- require_once( ABSPATH . 'wp-admin/includes/screen.php' );
73
  global $current_screen;
74
- $current_screen = get_current_screen();
75
  return method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor();
76
  }
77
 
@@ -100,10 +100,10 @@ class Feedzy_Rss_Feeds_Ui {
100
  * @since ?
101
  * @access friendly
102
  */
103
- function get_strings_for_block( $settings ) {
104
  $feedzy_lang_class = new Feedzy_Rss_Feeds_Ui_Lang();
105
- $strings = $feedzy_lang_class->get_strings();
106
- $array = array( 'feedzy_tinymce_plugin' => json_encode( $strings ) );
107
  return array_merge( $settings, $array );
108
  }
109
 
@@ -139,7 +139,7 @@ class Feedzy_Rss_Feeds_Ui {
139
  public function feedzy_add_tinymce_lang( $arr ) {
140
  $feedzy_rss_feeds_ui_lang = FEEDZY_ABSPATH . '/includes/admin/feedzy-rss-feeds-ui-lang.php';
141
  $feedzy_rss_feeds_ui_lang = apply_filters( 'feedzy_rss_feeds_ui_lang_filter', $feedzy_rss_feeds_ui_lang );
142
- $arr[] = $feedzy_rss_feeds_ui_lang;
143
  return $arr;
144
  }
145
 
57
  public function __construct( $plugin_name, $version, Feedzy_Rss_Feeds_Loader $loader ) {
58
 
59
  $this->plugin_name = $plugin_name;
60
+ $this->version = $version;
61
+ $this->loader = $loader;
62
 
63
  }
64
 
69
  * @access private
70
  */
71
  private function is_block_editor() {
72
+ require_once ABSPATH . 'wp-admin/includes/screen.php';
73
  global $current_screen;
74
+ $current_screen = get_current_screen(); //phpcs:ignore
75
  return method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor();
76
  }
77
 
100
  * @since ?
101
  * @access friendly
102
  */
103
+ public function get_strings_for_block( $settings ) {
104
  $feedzy_lang_class = new Feedzy_Rss_Feeds_Ui_Lang();
105
+ $strings = $feedzy_lang_class->get_strings();
106
+ $array = array( 'feedzy_tinymce_plugin' => wp_json_encode( $strings ) );
107
  return array_merge( $settings, $array );
108
  }
109
 
139
  public function feedzy_add_tinymce_lang( $arr ) {
140
  $feedzy_rss_feeds_ui_lang = FEEDZY_ABSPATH . '/includes/admin/feedzy-rss-feeds-ui-lang.php';
141
  $feedzy_rss_feeds_ui_lang = apply_filters( 'feedzy_rss_feeds_ui_lang_filter', $feedzy_rss_feeds_ui_lang );
142
+ $arr[] = $feedzy_rss_feeds_ui_lang;
143
  return $arr;
144
  }
145
 
includes/admin/feedzy-wp-widget.php CHANGED
@@ -50,7 +50,7 @@ class feedzy_wp_widget extends WP_Widget {
50
  * @return feedzy_wp_widget
51
  */
52
  public static function get_instance() {
53
- if ( self::$instance === null ) {
54
  self::$instance = new self();
55
  }
56
 
@@ -101,21 +101,21 @@ class feedzy_wp_widget extends WP_Widget {
101
  if ( isset( $element['disabled'] ) && $element['disabled'] ) {
102
  continue;
103
  }
104
- if ( $id === 'feed_title' ) {
105
  continue;
106
  }
107
- if ( $id === 'title' ) {
108
  $id = 'titlelength';
109
  }
110
  $widget_form .= '<p>';
111
  $widget_form .= '<label for="' . $this->get_field_id( $id ) . '">' . $element['label'] . '</label>';
112
- if ( $element['type'] === 'text' || $element['type'] === 'file' ) {
113
  $widget_form .= '<input class="widefat" id="' . $this->get_field_id( $id ) . '" name="' . $this->get_field_name( $id ) . '" type="text" value="' . esc_attr( $instance[ $id ] ) . '" />';
114
  }
115
- if ( $element['type'] === 'number' ) {
116
  $widget_form .= '<input class="widefat" id="' . $this->get_field_id( $id ) . '" name="' . $this->get_field_name( $id ) . '" type="number" value="' . esc_attr( $instance[ $id ] ) . '" />';
117
  }
118
- if ( $element['type'] === 'select' || $element['type'] === 'radio' ) {
119
  $widget_form .= '<select class="widefat" id="' . $this->get_field_id( $id ) . '" name="' . $this->get_field_name( $id ) . '" >';
120
  foreach ( $element['opts'] as $select_option ) {
121
  $widget_form .= '<option ' . selected( esc_attr( $select_option['value'] ), self::bool_to_enum( $instance[ $id ] ), false ) . 'value="' . esc_attr( $select_option['value'] ) . '">' . esc_html( $select_option['label'] ) . '</option>';
@@ -127,7 +127,8 @@ class feedzy_wp_widget extends WP_Widget {
127
  }
128
  }
129
  $widget_form .= '<hr/>';
130
- $widget_form = apply_filters( 'feedzy_widget_form_filter', $widget_form, $instance, $this->get_widget_defaults() );
 
131
  echo $widget_form;
132
 
133
  }
@@ -139,7 +140,7 @@ class feedzy_wp_widget extends WP_Widget {
139
  */
140
  public function get_widget_defaults() {
141
  $defaults = Feedzy_Rss_Feeds_Ui_Lang::get_form_defaults();
142
- // rename title to title length as widget instance already have one
143
  $defaults['titlelength'] = $defaults['title'];
144
  $defaults['title'] = '';
145
  $defaults['textarea'] = '';
@@ -160,14 +161,14 @@ class feedzy_wp_widget extends WP_Widget {
160
  }
161
  $value = strval( $value );
162
  // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
163
- if ( $value == '1' || $value == 'true' ) {
164
  return 'yes';
165
  }
166
  // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
167
- if ( $value == '0' || $value == 'false' ) {
168
  return 'no';
169
  }
170
- if ( $value === '' ) {
171
  return 'auto';
172
  }
173
  return $value;
@@ -188,7 +189,7 @@ class feedzy_wp_widget extends WP_Widget {
188
  */
189
  public function update( $new_instance, $old_instance ) {
190
  $instance = $old_instance;
191
- $instance['title'] = strip_tags( $new_instance['title'] );
192
  if ( current_user_can( 'unfiltered_html' ) ) {
193
  $instance['textarea'] = $new_instance['textarea'];
194
  } else {
@@ -196,7 +197,7 @@ class feedzy_wp_widget extends WP_Widget {
196
  }
197
  $forms_ids = array_keys( $this->get_widget_defaults() );
198
  foreach ( $forms_ids as $key ) {
199
- $instance[ $key ] = strip_tags( isset( $new_instance[ $key ] ) ? $new_instance[ $key ] : '' );
200
  }
201
  $instance = apply_filters( 'feedzy_widget_update_filter', $instance, $new_instance );
202
 
@@ -217,42 +218,47 @@ class feedzy_wp_widget extends WP_Widget {
217
  public function widget( $args, $instance ) {
218
  $title = apply_filters( 'widget_title', $instance['title'] );
219
  $textarea = apply_filters( 'widget_textarea', empty( $instance['textarea'] ) ? '' : $instance['textarea'], $instance );
220
- // Display the widget body
 
221
  echo $args['before_widget'];
222
- // Check if title is set
223
  if ( $title ) {
224
- echo $args['before_title'] . $title . $args['after_title'];
 
225
  }
226
- // Check if text intro is set
227
  if ( isset( $instance['textarea'] ) && ! empty( $instance['textarea'] ) ) {
228
- echo '<p class="feedzy-widget-intro">' . wpautop( $textarea ) . '</p>';
 
229
  }
230
  $feedzy_widget_shortcode_attributes = array(
231
- 'feeds' => $instance['feeds'],
232
- 'max' => $instance['max'],
233
  'feed_title' => 'no',
234
- 'target' => $instance['target'],
235
- 'title' => $instance['titlelength'],
236
- 'meta' => self::bool_to_enum( $instance['meta'] ),
237
- 'summary' => self::bool_to_enum( $instance['summary'] ),
238
- 'summarylength' => $instance['summarylength'],
239
- 'thumb' => self::bool_to_enum( $instance['thumb'] ),
240
- 'default' => $instance['default'],
241
- 'size' => $instance['size'],
242
- 'keywords_title' => ! empty( $instance['keywords_title'] ) ? $instance['keywords_title'] : '',
243
- 'keywords_ban' => ! empty( $instance['keywords_ban'] ) ? $instance['keywords_ban'] : '',
244
- 'error_empty' => $instance['error_empty'],
245
- 'sort' => $instance['sort'],
246
- 'refresh' => $instance['refresh'],
247
- 'follow' => $instance['follow'],
248
- 'http' => $instance['http'],
249
- 'lazy' => ! empty( $instance['lazy'] ) ? self::bool_to_enum( $instance['lazy'] ) : false,
250
- 'offset' => ! empty( $instance['offset'] ) ? $instance['offset'] : '',
251
- 'multiple_meta' => ! empty( $instance['multiple_meta'] ) ? $instance['multiple_meta'] : '',
252
  );
253
  $feedzy_widget_shortcode_attributes = apply_filters( 'feedzy_widget_shortcode_attributes_filter', $feedzy_widget_shortcode_attributes, $args, $instance );
254
 
 
255
  echo feedzy_rss( $feedzy_widget_shortcode_attributes );
 
256
  echo $args['after_widget'];
257
 
258
  }
50
  * @return feedzy_wp_widget
51
  */
52
  public static function get_instance() {
53
+ if ( null === self::$instance ) {
54
  self::$instance = new self();
55
  }
56
 
101
  if ( isset( $element['disabled'] ) && $element['disabled'] ) {
102
  continue;
103
  }
104
+ if ( 'feed_title' === $id ) {
105
  continue;
106
  }
107
+ if ( 'title' === $id ) {
108
  $id = 'titlelength';
109
  }
110
  $widget_form .= '<p>';
111
  $widget_form .= '<label for="' . $this->get_field_id( $id ) . '">' . $element['label'] . '</label>';
112
+ if ( 'text' === $element['type'] || 'file' === $element['type'] ) {
113
  $widget_form .= '<input class="widefat" id="' . $this->get_field_id( $id ) . '" name="' . $this->get_field_name( $id ) . '" type="text" value="' . esc_attr( $instance[ $id ] ) . '" />';
114
  }
115
+ if ( 'number' === $element['type'] ) {
116
  $widget_form .= '<input class="widefat" id="' . $this->get_field_id( $id ) . '" name="' . $this->get_field_name( $id ) . '" type="number" value="' . esc_attr( $instance[ $id ] ) . '" />';
117
  }
118
+ if ( 'select' === $element['type'] || 'radio' === $element['type'] ) {
119
  $widget_form .= '<select class="widefat" id="' . $this->get_field_id( $id ) . '" name="' . $this->get_field_name( $id ) . '" >';
120
  foreach ( $element['opts'] as $select_option ) {
121
  $widget_form .= '<option ' . selected( esc_attr( $select_option['value'] ), self::bool_to_enum( $instance[ $id ] ), false ) . 'value="' . esc_attr( $select_option['value'] ) . '">' . esc_html( $select_option['label'] ) . '</option>';
127
  }
128
  }
129
  $widget_form .= '<hr/>';
130
+ $widget_form = apply_filters( 'feedzy_widget_form_filter', $widget_form, $instance, $this->get_widget_defaults() );
131
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
132
  echo $widget_form;
133
 
134
  }
140
  */
141
  public function get_widget_defaults() {
142
  $defaults = Feedzy_Rss_Feeds_Ui_Lang::get_form_defaults();
143
+ // rename title to title length as widget instance already have one.
144
  $defaults['titlelength'] = $defaults['title'];
145
  $defaults['title'] = '';
146
  $defaults['textarea'] = '';
161
  }
162
  $value = strval( $value );
163
  // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
164
+ if ( '1' == $value || 'true' == $value ) {
165
  return 'yes';
166
  }
167
  // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
168
+ if ( '0' == $value || 'false' == $value ) {
169
  return 'no';
170
  }
171
+ if ( '' === $value ) {
172
  return 'auto';
173
  }
174
  return $value;
189
  */
190
  public function update( $new_instance, $old_instance ) {
191
  $instance = $old_instance;
192
+ $instance['title'] = wp_strip_all_tags( $new_instance['title'] );
193
  if ( current_user_can( 'unfiltered_html' ) ) {
194
  $instance['textarea'] = $new_instance['textarea'];
195
  } else {
197
  }
198
  $forms_ids = array_keys( $this->get_widget_defaults() );
199
  foreach ( $forms_ids as $key ) {
200
+ $instance[ $key ] = wp_strip_all_tags( isset( $new_instance[ $key ] ) ? $new_instance[ $key ] : '' );
201
  }
202
  $instance = apply_filters( 'feedzy_widget_update_filter', $instance, $new_instance );
203
 
218
  public function widget( $args, $instance ) {
219
  $title = apply_filters( 'widget_title', $instance['title'] );
220
  $textarea = apply_filters( 'widget_textarea', empty( $instance['textarea'] ) ? '' : $instance['textarea'], $instance );
221
+ // Display the widget body.
222
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
223
  echo $args['before_widget'];
224
+ // Check if title is set.
225
  if ( $title ) {
226
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
227
+ echo $args['before_title'] . wp_kses_post( $title ) . $args['after_title'];
228
  }
229
+ // Check if text intro is set.
230
  if ( isset( $instance['textarea'] ) && ! empty( $instance['textarea'] ) ) {
231
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
232
+ echo '<p class="feedzy-widget-intro">' . wp_kses_post( wpautop( $textarea ) ) . '</p>';
233
  }
234
  $feedzy_widget_shortcode_attributes = array(
235
+ 'feeds' => isset( $instance['feeds'] ) ? $instance['feeds'] : '',
236
+ 'max' => isset( $instance['max'] ) ? $instance['max'] : '',
237
  'feed_title' => 'no',
238
+ 'target' => isset( $instance['target'] ) ? $instance['target'] : '',
239
+ 'title' => isset( $instance['titlelength'] ) ? $instance['titlelength'] : '',
240
+ 'meta' => self::bool_to_enum( isset( $instance['meta'] ) ? $instance['meta'] : '' ),
241
+ 'summary' => self::bool_to_enum( isset( $instance['summary'] ) ? $instance['summary'] : '' ),
242
+ 'summarylength' => isset( $instance['summarylength'] ) ? $instance['summarylength'] : '',
243
+ 'thumb' => self::bool_to_enum( isset( $instance['thumb'] ) ? $instance['thumb'] : '' ),
244
+ 'default' => isset( $instance['default'] ) ? $instance['default'] : '',
245
+ 'size' => isset( $instance['size'] ) ? $instance['size'] : '',
246
+ 'keywords_title' => isset( $instance['keywords_title'] ) ? $instance['keywords_title'] : '',
247
+ 'keywords_ban' => isset( $instance['keywords_ban'] ) ? $instance['keywords_ban'] : '',
248
+ 'error_empty' => isset( $instance['error_empty'] ) ? $instance['error_empty'] : '',
249
+ 'sort' => isset( $instance['sort'] ) ? $instance['sort'] : '',
250
+ 'refresh' => isset( $instance['refresh'] ) ? $instance['refresh'] : '',
251
+ 'follow' => isset( $instance['follow'] ) ? $instance['follow'] : '',
252
+ 'http' => isset( $instance['http'] ) ? $instance['http'] : '',
253
+ 'lazy' => isset( $instance['lazy'] ) ? self::bool_to_enum( $instance['lazy'] ) : false,
254
+ 'offset' => isset( $instance['offset'] ) ? $instance['offset'] : '',
255
+ 'multiple_meta' => isset( $instance['multiple_meta'] ) ? $instance['multiple_meta'] : '',
256
  );
257
  $feedzy_widget_shortcode_attributes = apply_filters( 'feedzy_widget_shortcode_attributes_filter', $feedzy_widget_shortcode_attributes, $args, $instance );
258
 
259
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
260
  echo feedzy_rss( $feedzy_widget_shortcode_attributes );
261
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
262
  echo $args['after_widget'];
263
 
264
  }
includes/feedzy-rss-feeds-activator.php CHANGED
@@ -38,7 +38,8 @@ class Feedzy_Rss_Feeds_Activator {
38
  }
39
  if ( ! isset( $options['is_new'] ) ) {
40
  update_option(
41
- Feedzy_Rss_Feeds::get_plugin_name(), array(
 
42
  'is_new' => 'yes',
43
  )
44
  );
38
  }
39
  if ( ! isset( $options['is_new'] ) ) {
40
  update_option(
41
+ Feedzy_Rss_Feeds::get_plugin_name(),
42
+ array(
43
  'is_new' => 'yes',
44
  )
45
  );
includes/feedzy-rss-feeds-feed-tweaks.php CHANGED
@@ -34,6 +34,64 @@ function feedzy_insert_thumbnail( $content ) {
34
  add_filter( 'the_excerpt_rss', 'feedzy_insert_thumbnail' );
35
  add_filter( 'the_content_feed', 'feedzy_insert_thumbnail' );
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  /**
38
  * Boostrap the plugin view.
39
  *
@@ -80,3 +138,95 @@ function feedzy_is_pro() {
80
  function feedzy_is_pro_older_than( $version ) {
81
  return version_compare( FEEDZY_PRO_VERSION, $version, '<' );
82
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  add_filter( 'the_excerpt_rss', 'feedzy_insert_thumbnail' );
35
  add_filter( 'the_content_feed', 'feedzy_insert_thumbnail' );
36
 
37
+ /**
38
+ * Filters the post thumbnail HTML.
39
+ *
40
+ * @since 3.5.2
41
+ *
42
+ * @param string $html The post thumbnail HTML.
43
+ * @param int $post_id The post ID.
44
+ * @param int $post_thumbnail_id The post thumbnail ID.
45
+ * @param string|int[] $size Requested image size. Can be any registered image size name, or
46
+ * an array of width and height values in pixels (in that order).
47
+ * @param string $attr Query string of attributes.
48
+ * @return string post thumbnail HTML.
49
+ */
50
+ function display_external_post_image( $html, $post_id, $post_thumbnail_id, $size, $attr ) {
51
+ $url = get_post_meta( $post_id, 'feedzy_item_external_url', true );
52
+ if ( ! empty( $url ) ) {
53
+ $alt = get_the_title( $post_id );
54
+ $attr = array(
55
+ 'alt' => $alt,
56
+ );
57
+ $attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, '', '' );
58
+ $attr = array_map( 'esc_attr', $attr );
59
+ $html = sprintf( '<img src="%s"', esc_url( $url ) );
60
+ foreach ( $attr as $name => $value ) {
61
+ $html .= " $name=" . '"' . $value . '"';
62
+ }
63
+ $html .= ' />';
64
+ }
65
+ return $html;
66
+ }
67
+ add_filter( 'post_thumbnail_html', 'display_external_post_image', 10, 5 );
68
+
69
+ /**
70
+ * Filters whether a post has a post thumbnail.
71
+ *
72
+ * @since 3.5.2
73
+ *
74
+ * @param bool $has_thumbnail true if the post has a post thumbnail, otherwise false.
75
+ * @param int|WP_Post|null $post Post ID or WP_Post object. Default is global `$post`.
76
+ * @param int|false $thumbnail_id Post thumbnail ID or false if the post does not exist.
77
+ * @return bool
78
+ */
79
+ function enable_external_url_support( $has_thumbnail, $post, $thumbnail_id ) {
80
+ $post_id = get_the_ID();
81
+ if ( $post && is_object( $post ) ) {
82
+ $post_id = $post->ID;
83
+ } elseif ( $post && is_numeric( $post ) ) {
84
+ $post_id = $post;
85
+ }
86
+ $feedzy_item_external_url = get_post_meta( $post_id, 'feedzy_item_external_url', true );
87
+ // Check external URL exists OR not.
88
+ if ( ! empty( $feedzy_item_external_url ) ) {
89
+ $has_thumbnail = true;
90
+ }
91
+ return $has_thumbnail;
92
+ }
93
+ add_filter( 'has_post_thumbnail', 'enable_external_url_support', 10, 3 );
94
+
95
  /**
96
  * Boostrap the plugin view.
97
  *
138
  function feedzy_is_pro_older_than( $version ) {
139
  return version_compare( FEEDZY_PRO_VERSION, $version, '<' );
140
  }
141
+
142
+ add_filter(
143
+ 'feedzy_wp_kses_allowed_html',
144
+ function( $allowed_html = array() ) {
145
+ return array(
146
+ 'select' => array(
147
+ 'type' => array(),
148
+ 'id' => array(),
149
+ 'name' => array(),
150
+ 'value' => array(),
151
+ 'class' => array(),
152
+ 'selected' => array(),
153
+ 'data-feedzy' => array(),
154
+ ),
155
+ 'option' => array(
156
+ 'type' => array(),
157
+ 'id' => array(),
158
+ 'name' => array(),
159
+ 'value' => array(),
160
+ 'class' => array(),
161
+ 'selected' => array(),
162
+ ),
163
+ 'input' => array(
164
+ 'type' => array(),
165
+ 'id' => array(),
166
+ 'name' => array(),
167
+ 'value' => array(),
168
+ 'class' => array(),
169
+ 'checked' => array(),
170
+ 'placeholder' => array(),
171
+ 'data-feedzy' => array(),
172
+ ),
173
+ 'textarea' => array(
174
+ 'id' => array(),
175
+ 'name' => array(),
176
+ 'value' => array(),
177
+ 'class' => array(),
178
+ 'data-feedzy' => array(),
179
+ ),
180
+ 'button' => array(
181
+ 'class' => array(),
182
+ 'id' => array(),
183
+ ),
184
+ 'p' => array(
185
+ 'class' => array(),
186
+ ),
187
+ 'span' => array(
188
+ 'class' => array(),
189
+ ),
190
+ 'div' => array(
191
+ 'class' => array(),
192
+ ),
193
+ 'h1' => array(
194
+ 'class' => array(),
195
+ ),
196
+ 'h2' => array(
197
+ 'class' => array(),
198
+ ),
199
+ 'h3' => array(
200
+ 'class' => array(),
201
+ ),
202
+ 'h4' => array(
203
+ 'class' => array(),
204
+ ),
205
+ 'h5' => array(
206
+ 'class' => array(),
207
+ ),
208
+ 'h6' => array(
209
+ 'class' => array(),
210
+ ),
211
+ 'label' => array(
212
+ 'id' => array(),
213
+ 'for' => array(),
214
+ ),
215
+ 'a' => array(
216
+ 'href' => array(),
217
+ 'title' => array(),
218
+ 'class' => array(),
219
+ ),
220
+ 'br' => array(),
221
+ 'em' => array(),
222
+ 'strong' => array(),
223
+ 'iframe' => array(
224
+ 'src' => array(),
225
+ 'height' => array(),
226
+ 'width' => array(),
227
+ 'frameborder' => array(),
228
+ 'allowfullscreen' => array(),
229
+ ),
230
+ );
231
+ }
232
+ );
includes/feedzy-rss-feeds.php CHANGED
@@ -85,7 +85,7 @@ class Feedzy_Rss_Feeds {
85
  */
86
  public static function instance() {
87
  if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Feedzy_Rss_Feeds ) ) {
88
- self::$instance = new Feedzy_Rss_Feeds;
89
  self::$instance->init();
90
  }
91
 
@@ -104,7 +104,7 @@ class Feedzy_Rss_Feeds {
104
  */
105
  public function init() {
106
  self::$plugin_name = 'feedzy-rss-feeds';
107
- self::$version = '3.5.2';
108
  self::$instance->load_dependencies();
109
  self::$instance->set_locale();
110
  self::$instance->define_admin_hooks();
@@ -260,11 +260,13 @@ class Feedzy_Rss_Feeds {
260
  self::$instance->loader->add_filter( 'feedzy_retrieve_categories', $plugin_import, 'retrieve_categories', 10, 2 );
261
  self::$instance->loader->add_filter( 'feedzy_is_license_of_type', $plugin_import, 'feedzy_is_license_of_type', 10, 2 );
262
  self::$instance->loader->add_filter( 'post_row_actions', $plugin_import, 'add_import_actions', 10, 2 );
 
263
  }
264
 
265
  if ( ! defined( 'TI_UNIT_TESTING' ) ) {
266
  add_action(
267
- 'plugins_loaded', function () {
 
268
  if ( function_exists( 'register_block_type' ) ) {
269
  Feedzy_Rss_Feeds_Gutenberg_Block::get_instance();
270
  }}
85
  */
86
  public static function instance() {
87
  if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Feedzy_Rss_Feeds ) ) {
88
+ self::$instance = new Feedzy_Rss_Feeds();
89
  self::$instance->init();
90
  }
91
 
104
  */
105
  public function init() {
106
  self::$plugin_name = 'feedzy-rss-feeds';
107
+ self::$version = '3.6.0';
108
  self::$instance->load_dependencies();
109
  self::$instance->set_locale();
110
  self::$instance->define_admin_hooks();
260
  self::$instance->loader->add_filter( 'feedzy_retrieve_categories', $plugin_import, 'retrieve_categories', 10, 2 );
261
  self::$instance->loader->add_filter( 'feedzy_is_license_of_type', $plugin_import, 'feedzy_is_license_of_type', 10, 2 );
262
  self::$instance->loader->add_filter( 'post_row_actions', $plugin_import, 'add_import_actions', 10, 2 );
263
+ self::$instance->loader->add_filter( 'wp_kses_allowed_html', $plugin_import, 'allow_iframe_tag_item_content', 10, 2 );
264
  }
265
 
266
  if ( ! defined( 'TI_UNIT_TESTING' ) ) {
267
  add_action(
268
+ 'plugins_loaded',
269
+ function () {
270
  if ( function_exists( 'register_block_type' ) ) {
271
  Feedzy_Rss_Feeds_Gutenberg_Block::get_instance();
272
  }}
includes/gutenberg/feedzy-rss-feeds-gutenberg-block.php CHANGED
@@ -57,11 +57,12 @@ class Feedzy_Rss_Feeds_Gutenberg_Block {
57
  }
58
 
59
  // Enqueue the bundled block JS file
60
- wp_enqueue_script( 'feedzy-gutenberg-block-js', FEEDZY_ABSURL . 'includes/gutenberg/build/block.js', array( 'wp-i18n', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-editor', 'wp-api', 'lodash' ), $version );
61
 
62
  // Pass in REST URL
63
  wp_localize_script(
64
- 'feedzy-gutenberg-block-js', 'feedzyjs',
 
65
  array(
66
  'imagepath' => esc_url( FEEDZY_ABSURL . 'img/' ),
67
  'isPro' => feedzy_is_pro(),
@@ -78,7 +79,8 @@ class Feedzy_Rss_Feeds_Gutenberg_Block {
78
  */
79
  public function feedzy_register_block_type() {
80
  register_block_type(
81
- 'feedzy-rss-feeds/feedzy-block', array(
 
82
  'render_callback' => array( $this, 'feedzy_gutenberg_block_callback' ),
83
  'attributes' => array(
84
  'feeds' => array(
@@ -88,7 +90,7 @@ class Feedzy_Rss_Feeds_Gutenberg_Block {
88
  'type' => 'number',
89
  'default' => '5',
90
  ),
91
- 'offset' => array(
92
  'type' => 'number',
93
  'default' => '0',
94
  ),
@@ -112,17 +114,17 @@ class Feedzy_Rss_Feeds_Gutenberg_Block {
112
  'type' => 'number',
113
  ),
114
  'meta' => array(
115
- 'type' => 'boolean',
116
  ),
117
  'lazy' => array(
118
  'type' => 'boolean',
119
  'default' => false,
120
  ),
121
- 'metafields' => array(
122
- 'type' => 'string',
123
  ),
124
- 'multiple_meta' => array(
125
- 'type' => 'string',
126
  ),
127
  'summary' => array(
128
  'type' => 'boolean',
@@ -206,13 +208,15 @@ class Feedzy_Rss_Feeds_Gutenberg_Block {
206
  */
207
  public function feedzy_register_rest_route() {
208
  register_rest_route(
209
- 'feedzy/v1', '/feed/', array(
210
- 'methods' => 'POST',
211
- 'callback' => array( $this, 'feedzy_rest_route' ),
 
 
212
  'permission_callback' => function () {
213
  return is_user_logged_in();
214
  },
215
- 'args' => array(
216
  'url' => array(
217
  'sanitize_callback' => array( $this, 'feedzy_sanitize_feeds' ),
218
  ),
@@ -244,9 +248,9 @@ class Feedzy_Rss_Feeds_Gutenberg_Block {
244
  );
245
 
246
  $instance = Feedzy_Rss_Feeds::instance();
247
- $admin = $instance->get_admin();
248
- $feed = $admin->fetch_feed( $feed, '12_hours', array( '' ) );
249
- $feedy = array();
250
 
251
  if ( ! $feed->init() ) {
252
  $feedy['error'] = __( 'Invalid Feed URL', 'feedzy-rss-feeds' );
@@ -265,17 +269,18 @@ class Feedzy_Rss_Feeds_Gutenberg_Block {
265
  }
266
 
267
  $feedy['items'] = array();
268
- $items = $feed->get_items();
269
- $is_multiple = ! empty( $feed->multifeed_url ) && is_array( $feed->multifeed_url );
270
  foreach ( $items as $item ) {
271
  $item_attrs = apply_filters( 'feedzy_item_filter', array(), $item );
272
 
273
  array_push(
274
- $feedy['items'], array(
 
275
  'title' => ( ( $item->get_title() ) ? $item->get_title() : null ),
276
  'link' => ( ( $item->get_permalink() ) ? $item->get_permalink() : null ),
277
  'creator' => ( ( $item->get_author() ) ? $item->get_author()->get_name() : null ),
278
- 'source' => $is_multiple && $item->get_feed()->get_title() ? $item->get_feed()->get_title() : '',
279
  'pubDate' => ( ( $item->get_date() ) ? $item->get_date( 'U' ) : null ),
280
  'date' => ( ( $item->get_date() ) ? date_i18n( $meta_args['date_format'], $item->get_date( 'U' ) ) : null ),
281
  'time' => ( ( $item->get_date() ) ? date_i18n( $meta_args['time_format'], $item->get_date( 'U' ) ) : null ),
@@ -303,7 +308,7 @@ class Feedzy_Rss_Feeds_Gutenberg_Block {
303
  * Sanitize Rest API Return
304
  */
305
  public function feedzy_sanitize_feeds( $input ) {
306
- if ( sizeof( $input ) === 1 ) {
307
  $feed = esc_url( $input[0] );
308
  return $feed;
309
  } else {
@@ -320,11 +325,11 @@ class Feedzy_Rss_Feeds_Gutenberg_Block {
320
  */
321
  public function feedzy_sanitize_categories( $input ) {
322
  if ( $post = get_page_by_path( $input, OBJECT, 'feedzy_categories' ) ) {
323
- $id = $post->ID;
324
  $value = get_post_meta( $id, 'feedzy_category_feed', true );
325
  $value = trim( $value );
326
  $value = explode( ',', $value );
327
- if ( sizeof( $value ) === 1 ) {
328
  $value = esc_url( $value[0] );
329
  return $value;
330
  } else {
57
  }
58
 
59
  // Enqueue the bundled block JS file
60
+ wp_enqueue_script( 'feedzy-gutenberg-block-js', FEEDZY_ABSURL . 'includes/gutenberg/build/block.js', array( 'wp-i18n', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-editor', 'wp-api', 'lodash' ), $version, true );
61
 
62
  // Pass in REST URL
63
  wp_localize_script(
64
+ 'feedzy-gutenberg-block-js',
65
+ 'feedzyjs',
66
  array(
67
  'imagepath' => esc_url( FEEDZY_ABSURL . 'img/' ),
68
  'isPro' => feedzy_is_pro(),
79
  */
80
  public function feedzy_register_block_type() {
81
  register_block_type(
82
+ 'feedzy-rss-feeds/feedzy-block',
83
+ array(
84
  'render_callback' => array( $this, 'feedzy_gutenberg_block_callback' ),
85
  'attributes' => array(
86
  'feeds' => array(
90
  'type' => 'number',
91
  'default' => '5',
92
  ),
93
+ 'offset' => array(
94
  'type' => 'number',
95
  'default' => '0',
96
  ),
114
  'type' => 'number',
115
  ),
116
  'meta' => array(
117
+ 'type' => 'boolean',
118
  ),
119
  'lazy' => array(
120
  'type' => 'boolean',
121
  'default' => false,
122
  ),
123
+ 'metafields' => array(
124
+ 'type' => 'string',
125
  ),
126
+ 'multiple_meta' => array(
127
+ 'type' => 'string',
128
  ),
129
  'summary' => array(
130
  'type' => 'boolean',
208
  */
209
  public function feedzy_register_rest_route() {
210
  register_rest_route(
211
+ 'feedzy/v1',
212
+ '/feed/',
213
+ array(
214
+ 'methods' => 'POST',
215
+ 'callback' => array( $this, 'feedzy_rest_route' ),
216
  'permission_callback' => function () {
217
  return is_user_logged_in();
218
  },
219
+ 'args' => array(
220
  'url' => array(
221
  'sanitize_callback' => array( $this, 'feedzy_sanitize_feeds' ),
222
  ),
248
  );
249
 
250
  $instance = Feedzy_Rss_Feeds::instance();
251
+ $admin = $instance->get_admin();
252
+ $feed = $admin->fetch_feed( $feed, '12_hours', array( '' ) );
253
+ $feedy = array();
254
 
255
  if ( ! $feed->init() ) {
256
  $feedy['error'] = __( 'Invalid Feed URL', 'feedzy-rss-feeds' );
269
  }
270
 
271
  $feedy['items'] = array();
272
+ $items = $feed->get_items();
273
+ $is_multiple = ! empty( $feed->multifeed_url ) && is_array( $feed->multifeed_url );
274
  foreach ( $items as $item ) {
275
  $item_attrs = apply_filters( 'feedzy_item_filter', array(), $item );
276
 
277
  array_push(
278
+ $feedy['items'],
279
+ array(
280
  'title' => ( ( $item->get_title() ) ? $item->get_title() : null ),
281
  'link' => ( ( $item->get_permalink() ) ? $item->get_permalink() : null ),
282
  'creator' => ( ( $item->get_author() ) ? $item->get_author()->get_name() : null ),
283
+ 'source' => $is_multiple && $item->get_feed()->get_title() ? $item->get_feed()->get_title() : '',
284
  'pubDate' => ( ( $item->get_date() ) ? $item->get_date( 'U' ) : null ),
285
  'date' => ( ( $item->get_date() ) ? date_i18n( $meta_args['date_format'], $item->get_date( 'U' ) ) : null ),
286
  'time' => ( ( $item->get_date() ) ? date_i18n( $meta_args['time_format'], $item->get_date( 'U' ) ) : null ),
308
  * Sanitize Rest API Return
309
  */
310
  public function feedzy_sanitize_feeds( $input ) {
311
+ if ( count( $input ) === 1 ) {
312
  $feed = esc_url( $input[0] );
313
  return $feed;
314
  } else {
325
  */
326
  public function feedzy_sanitize_categories( $input ) {
327
  if ( $post = get_page_by_path( $input, OBJECT, 'feedzy_categories' ) ) {
328
+ $id = $post->ID;
329
  $value = get_post_meta( $id, 'feedzy_category_feed', true );
330
  $value = trim( $value );
331
  $value = explode( ',', $value );
332
+ if ( count( $value ) === 1 ) {
333
  $value = esc_url( $value[0] );
334
  return $value;
335
  } else {
includes/layouts/feedzy-improve.php CHANGED
@@ -2,7 +2,7 @@
2
  <div class="fz-feature-inner">
3
  <div class="fz-feature-features">
4
  <h2>Answer a few questions for us to help us improve the product</h2>
5
- <p>We're always looking for suggestions to further improve Feedzy RSS Feeds. If you'd like to help us, please fill out this <a href="<?php echo FEEDZY_SURVEY; ?>" target="_blank">survey</a>.</p>
6
  <?php if ( ! feedzy_is_pro() ) { ?>
7
  <p>If your feedback is especially helpful and we choose to do an interview with you to discuss your suggestions, you will even gain a yearly membership for free for your trouble.</p>
8
  <?php } ?>
2
  <div class="fz-feature-inner">
3
  <div class="fz-feature-features">
4
  <h2>Answer a few questions for us to help us improve the product</h2>
5
+ <p>We're always looking for suggestions to further improve Feedzy RSS Feeds. If you'd like to help us, please fill out this <a href="<?php echo esc_url( FEEDZY_SURVEY ); ?>" target="_blank">survey</a>.</p>
6
  <?php if ( ! feedzy_is_pro() ) { ?>
7
  <p>If your feedback is especially helpful and we choose to do an interview with you to discuss your suggestions, you will even gain a yearly membership for free for your trouble.</p>
8
  <?php } ?>
includes/layouts/feedzy-support.php CHANGED
@@ -3,25 +3,26 @@
3
  <?php load_template( FEEDZY_ABSPATH . '/includes/layouts/header.php' ); ?>
4
 
5
  <?php
6
- $active_tab = isset( $_REQUEST['tab'] ) ? sanitize_text_field( $_REQUEST['tab'] ) : 'help';
7
- $show_more = ! feedzy_is_pro() || false === apply_filters( 'feedzy_is_license_of_type', false, 'agency' );
 
8
  ?>
9
 
10
  <h2 class="nav-tab-wrapper">
11
  <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-support&tab=help' ) ); ?>"
12
- class="nav-tab <?php echo $active_tab === 'help' ? 'nav-tab-active' : ''; ?>"><?php _e( 'Support', 'feedzy-rss-feeds' ); ?></a>
13
  <?php
14
  if ( $show_more ) {
15
  ?>
16
  <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-support&tab=more' ) ); ?>"
17
- class="nav-tab <?php echo $active_tab === 'more' ? 'nav-tab-active' : ''; ?>"><?php _e( 'More Features', 'feedzy-rss-feeds' ); ?></a>
18
  <?php
19
  }
20
  ?>
21
  <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-support&tab=improve' ) ); ?>"
22
- class="nav-tab <?php echo $active_tab === 'improve' ? 'nav-tab-active' : ''; ?>"><?php _e( 'Help us improve!', 'feedzy-rss-feeds' ); ?></a>
23
 
24
- <?php echo apply_filters( 'feedzy_support_tab_heading', '', $active_tab ); ?>
25
  </h2>
26
 
27
  <div class="fz-features-content">
3
  <?php load_template( FEEDZY_ABSPATH . '/includes/layouts/header.php' ); ?>
4
 
5
  <?php
6
+ // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification
7
+ $active_tab = isset( $_REQUEST['tab'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['tab'] ) ) : 'help';
8
+ $show_more = ! feedzy_is_pro() || false === apply_filters( 'feedzy_is_license_of_type', false, 'agency' );
9
  ?>
10
 
11
  <h2 class="nav-tab-wrapper">
12
  <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-support&tab=help' ) ); ?>"
13
+ class="nav-tab <?php echo 'help' === $active_tab ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( 'Support', 'feedzy-rss-feeds' ); ?></a>
14
  <?php
15
  if ( $show_more ) {
16
  ?>
17
  <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-support&tab=more' ) ); ?>"
18
+ class="nav-tab <?php echo 'more' === $active_tab ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( 'More Features', 'feedzy-rss-feeds' ); ?></a>
19
  <?php
20
  }
21
  ?>
22
  <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-support&tab=improve' ) ); ?>"
23
+ class="nav-tab <?php echo 'improve' === $active_tab ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( 'Help us improve!', 'feedzy-rss-feeds' ); ?></a>
24
 
25
+ <?php echo wp_kses_post( apply_filters( 'feedzy_support_tab_heading', '', $active_tab ) ); ?>
26
  </h2>
27
 
28
  <div class="fz-features-content">
includes/layouts/feedzy-tutorial.php CHANGED
@@ -31,10 +31,10 @@ Layout For Tutorial Page of Feedzy RSS Feeds
31
  </ul>
32
 
33
  <?php if ( ! $is_pro ) { ?>
34
- <p>We have many more features and offer email & chat support if you purchase our <a href="<?php echo FEEDZY_UPSELL_LINK; ?>" target="_blank">Pro Version</a>.</p>
35
  <?php } ?>
36
 
37
- <p>Ready to begin? Let's <a href="<?php echo add_query_arg( 'post_type', 'feedzy_imports', admin_url( 'post-new.php' ) ); ?>">import a post</a> or <a href="<?php echo add_query_arg( 'post_type', 'feedzy_categories', admin_url( 'post-new.php' ) ); ?>" target="_blank">create a category</a>!
38
 
39
  </div>
40
  <div class="clear"></div>
@@ -117,7 +117,7 @@ Layout For Tutorial Page of Feedzy RSS Feeds
117
  <p>Through WordAI integration, Feedzy will give you unlimited new content. Your SpinnerChief or WordAI subscriptions (not included) integrate seamlessly with Feedzy, so you won't ever have to worry about duplicate content - or Google penalties - again. <a href="https://docs.themeisle.com/article/746-how-to-use-wordai-to-rephrase-rss-content-in-feedzy" target="_blank">Check this out here.</a></p>
118
  </div>
119
  <div class="fz-feature-image">
120
- <img src="<?php echo FEEDZY_ABSURL; ?>/img/feedzy-rss-feeds-wordai.jpg" alt="WordAi integration">
121
  </div>
122
  <div class="clear"></div>
123
  </div>
31
  </ul>
32
 
33
  <?php if ( ! $is_pro ) { ?>
34
+ <p>We have many more features and offer email & chat support if you purchase our <a href="<?php echo esc_url( FEEDZY_UPSELL_LINK ); ?>" target="_blank">Pro Version</a>.</p>
35
  <?php } ?>
36
 
37
+ <p>Ready to begin? Let's <a href="<?php echo esc_url( add_query_arg( 'post_type', 'feedzy_imports', admin_url( 'post-new.php' ) ) ); ?>">import a post</a> or <a href="<?php echo esc_url( add_query_arg( 'post_type', 'feedzy_categories', admin_url( 'post-new.php' ) ) ); ?>" target="_blank">create a category</a>!
38
 
39
  </div>
40
  <div class="clear"></div>
117
  <p>Through WordAI integration, Feedzy will give you unlimited new content. Your SpinnerChief or WordAI subscriptions (not included) integrate seamlessly with Feedzy, so you won't ever have to worry about duplicate content - or Google penalties - again. <a href="https://docs.themeisle.com/article/746-how-to-use-wordai-to-rephrase-rss-content-in-feedzy" target="_blank">Check this out here.</a></p>
118
  </div>
119
  <div class="fz-feature-image">
120
+ <img src="<?php echo esc_url( FEEDZY_ABSURL ); ?>/img/feedzy-rss-feeds-wordai.jpg" alt="WordAi integration">
121
  </div>
122
  <div class="clear"></div>
123
  </div>
includes/layouts/feedzy-upsell.php CHANGED
@@ -20,7 +20,7 @@ Layout For Upsell Page of Feedzy RSS Feeds
20
  </div>
21
  <div class="fz-feature-image">
22
  <div class="header-btns">
23
- <a target="_blank" href="<?php echo FEEDZY_UPSELL_LINK; ?>" class="buy-now"><span class="dashicons dashicons-cart"></span> Upgrade to Feedzy Pro now</a>
24
  </div>
25
  </div>
26
  <div class="clear"></div>
@@ -37,7 +37,7 @@ Layout For Upsell Page of Feedzy RSS Feeds
37
  <p>Feedzy will automatically filter each feed item and place it wherever you want in your site. Easy to install and ready to go.</p>
38
  </div>
39
  <div class="fz-feature-image">
40
- <img src="<?php echo FEEDZY_ABSURL; ?>/img/features-feed-to-post.jpg" alt="Feed to post">
41
  </div>
42
  <div class="clear"></div>
43
  </div>
@@ -52,7 +52,7 @@ Layout For Upsell Page of Feedzy RSS Feeds
52
  <p>If you like to roll your own templates, <a href="https://docs.themeisle.com/article/1162-feedzy-custom-templates" target="_blank">template tags</a> are available to help you do just that!</p>
53
  </div>
54
  <div class="fz-feature-image">
55
- <img src="<?php echo FEEDZY_ABSURL; ?>/img/features-templates.jpg" alt="Feed templates">
56
  </div>
57
  <div class="clear"></div>
58
  </div>
@@ -67,7 +67,7 @@ Layout For Upsell Page of Feedzy RSS Feeds
67
  <p>Feature affiliate links on your site with Feedzy. Pro automatically includes your referral/affiliate ID on feed links. You can even import prices from product sources to create extra value for your readers.</p>
68
  </div>
69
  <div class="fz-feature-image">
70
- <img src="<?php echo FEEDZY_ABSURL; ?>/img/features-affiliate-ready.jpg" alt="Protect your Brand">
71
  </div>
72
  <div class="clear"></div>
73
  </div>
@@ -81,7 +81,7 @@ Layout For Upsell Page of Feedzy RSS Feeds
81
  <p>Take control of your content: blacklist specific keywords to show only the content you want to display on your site.</p>
82
  </div>
83
  <div class="fz-feature-image">
84
- <img src="<?php echo FEEDZY_ABSURL; ?>/img/Protect-your-Brand.jpg" alt="Affiliate ready">
85
  </div>
86
  <div class="clear"></div>
87
  </div>
@@ -101,7 +101,7 @@ Layout For Upsell Page of Feedzy RSS Feeds
101
  <p>Feedzy will automatically filter each feed item and place it wherever you want in your site. Easy to install and ready to go.</p>
102
  </div>
103
  <div class="fz-feature-image">
104
- <img src="<?php echo FEEDZY_ABSURL; ?>/img/features-feed-to-post.jpg" alt="Feed to post">
105
  </div>
106
  <div class="clear"></div>
107
  </div>
@@ -119,7 +119,7 @@ Layout For Upsell Page of Feedzy RSS Feeds
119
  <p>Through WordAI integration, Feedzy will give you unlimited new content. Your SpinnerChief or WordAI subscriptions (not included) integrate seamlessly with Feedzy, so you won't ever have to worry about duplicate content - or Google penalties - again. <a href="https://docs.themeisle.com/article/746-how-to-use-wordai-to-rephrase-rss-content-in-feedzy" target="_blank">Check this out here.</a></p>
120
  </div>
121
  <div class="fz-feature-image">
122
- <img src="<?php echo FEEDZY_ABSURL; ?>/img/feedzy-rss-feeds-wordai.jpg" alt="WordAi integration">
123
  </div>
124
  <div class="clear"></div>
125
  </div>
@@ -137,7 +137,7 @@ Layout For Upsell Page of Feedzy RSS Feeds
137
  <p>We're proud to serve over 10,000 happy customers and provide unlimited support/updates for the duration of your subscription. If you need help, our customer service and developer teams are on-hand to offer personalized, priority assistance to Pro customers.</p>
138
  </div>
139
  <div class="fz-feature-image">
140
- <img src="<?php echo FEEDZY_ABSURL; ?>/img/World-class-support.jpg" alt="World Class Support">
141
  </div>
142
  <div class="clear"></div>
143
  </div>
@@ -154,7 +154,7 @@ Layout For Upsell Page of Feedzy RSS Feeds
154
  if ( $is_pro || false === apply_filters( 'feedzy_is_license_of_type', false, 'agency' ) ) {
155
  ?>
156
  <div class="header-btns">
157
- <a href="<?php echo FEEDZY_UPSELL_LINK; ?>" class="buy-now">
158
  <span class="dashicons dashicons-cart"></span> Upgrade <?php echo $is_pro ? 'your license to a higher plan' : 'to Feedzy Pro'; ?></a>
159
  </div>
160
  <?php
20
  </div>
21
  <div class="fz-feature-image">
22
  <div class="header-btns">
23
+ <a target="_blank" href="<?php echo esc_url( FEEDZY_UPSELL_LINK ); ?>" class="buy-now"><span class="dashicons dashicons-cart"></span> Upgrade to Feedzy Pro now</a>
24
  </div>
25
  </div>
26
  <div class="clear"></div>
37
  <p>Feedzy will automatically filter each feed item and place it wherever you want in your site. Easy to install and ready to go.</p>
38
  </div>
39
  <div class="fz-feature-image">
40
+ <img src="<?php echo esc_url( FEEDZY_ABSURL ); ?>/img/features-feed-to-post.jpg" alt="Feed to post">
41
  </div>
42
  <div class="clear"></div>
43
  </div>
52
  <p>If you like to roll your own templates, <a href="https://docs.themeisle.com/article/1162-feedzy-custom-templates" target="_blank">template tags</a> are available to help you do just that!</p>
53
  </div>
54
  <div class="fz-feature-image">
55
+ <img src="<?php echo esc_url( FEEDZY_ABSURL ); ?>/img/features-templates.jpg" alt="Feed templates">
56
  </div>
57
  <div class="clear"></div>
58
  </div>
67
  <p>Feature affiliate links on your site with Feedzy. Pro automatically includes your referral/affiliate ID on feed links. You can even import prices from product sources to create extra value for your readers.</p>
68
  </div>
69
  <div class="fz-feature-image">
70
+ <img src="<?php echo esc_url( FEEDZY_ABSURL ); ?>/img/features-affiliate-ready.jpg" alt="Protect your Brand">
71
  </div>
72
  <div class="clear"></div>
73
  </div>
81
  <p>Take control of your content: blacklist specific keywords to show only the content you want to display on your site.</p>
82
  </div>
83
  <div class="fz-feature-image">
84
+ <img src="<?php echo esc_url( FEEDZY_ABSURL ); ?>/img/Protect-your-Brand.jpg" alt="Affiliate ready">
85
  </div>
86
  <div class="clear"></div>
87
  </div>
101
  <p>Feedzy will automatically filter each feed item and place it wherever you want in your site. Easy to install and ready to go.</p>
102
  </div>
103
  <div class="fz-feature-image">
104
+ <img src="<?php echo esc_url( FEEDZY_ABSURL ); ?>/img/features-feed-to-post.jpg" alt="Feed to post">
105
  </div>
106
  <div class="clear"></div>
107
  </div>
119
  <p>Through WordAI integration, Feedzy will give you unlimited new content. Your SpinnerChief or WordAI subscriptions (not included) integrate seamlessly with Feedzy, so you won't ever have to worry about duplicate content - or Google penalties - again. <a href="https://docs.themeisle.com/article/746-how-to-use-wordai-to-rephrase-rss-content-in-feedzy" target="_blank">Check this out here.</a></p>
120
  </div>
121
  <div class="fz-feature-image">
122
+ <img src="<?php echo esc_url( FEEDZY_ABSURL ); ?>/img/feedzy-rss-feeds-wordai.jpg" alt="WordAi integration">
123
  </div>
124
  <div class="clear"></div>
125
  </div>
137
  <p>We're proud to serve over 10,000 happy customers and provide unlimited support/updates for the duration of your subscription. If you need help, our customer service and developer teams are on-hand to offer personalized, priority assistance to Pro customers.</p>
138
  </div>
139
  <div class="fz-feature-image">
140
+ <img src="<?php echo esc_url( FEEDZY_ABSURL ); ?>/img/World-class-support.jpg" alt="World Class Support">
141
  </div>
142
  <div class="clear"></div>
143
  </div>
154
  if ( $is_pro || false === apply_filters( 'feedzy_is_license_of_type', false, 'agency' ) ) {
155
  ?>
156
  <div class="header-btns">
157
+ <a href="<?php echo esc_url( FEEDZY_UPSELL_LINK ); ?>" class="buy-now">
158
  <span class="dashicons dashicons-cart"></span> Upgrade <?php echo $is_pro ? 'your license to a higher plan' : 'to Feedzy Pro'; ?></a>
159
  </div>
160
  <?php
includes/layouts/settings.php CHANGED
@@ -3,24 +3,25 @@
3
  <?php load_template( FEEDZY_ABSPATH . '/includes/layouts/header.php' ); ?>
4
 
5
  <?php
6
- $active_tab = isset( $_REQUEST['tab'] ) ? sanitize_text_field( $_REQUEST['tab'] ) : 'general';
 
7
  $show_button = true;
8
  ?>
9
 
10
  <h2 class="nav-tab-wrapper">
11
  <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-settings&tab=general' ) ); ?>"
12
- class="nav-tab <?php echo $active_tab === 'general' ? 'nav-tab-active' : ''; ?>"><?php _e( 'General', 'feedzy-rss-feeds' ); ?></a>
13
  <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-settings&tab=headers' ) ); ?>"
14
- class="nav-tab <?php echo $active_tab === 'headers' ? 'nav-tab-active' : ''; ?>"><?php _e( 'Headers', 'feedzy-rss-feeds' ); ?></a>
15
  <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-settings&tab=proxy' ) ); ?>"
16
- class="nav-tab <?php echo $active_tab === 'proxy' ? 'nav-tab-active' : ''; ?>"><?php _e( 'Proxy', 'feedzy-rss-feeds' ); ?></a>
17
  <?php
18
- $tabs = apply_filters( 'feedzy_settings_tabs', array() );
19
- if ( $tabs ) {
20
- foreach ( $tabs as $tab => $label ) {
21
  ?>
22
- <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-settings&tab=' . $tab ) ); ?>"
23
- class="nav-tab <?php echo $active_tab === $tab ? 'nav-tab-active' : ''; ?>"><?php echo $label; ?></a>
24
  <?php
25
  }
26
  }
@@ -28,11 +29,11 @@
28
  </h2>
29
 
30
  <?php if ( $this->notice ) { ?>
31
- <div class="updated"><p><?php echo $this->notice; ?></p></div>
32
  <?php } ?>
33
 
34
  <?php if ( $this->error ) { ?>
35
- <div class="error"><p><?php echo $this->error; ?></p></div>
36
  <?php } ?>
37
 
38
 
@@ -52,69 +53,70 @@
52
  switch ( $active_tab ) {
53
  case 'general':
54
  ?>
55
- <h2><?php _e( 'General', 'feedzy-rss-feeds' ); ?></h2>
56
  <div class="fz-form-group">
57
  <input type="checkbox" id="rss-feeds" class="fz-form-control" name="rss-feeds"
58
- value="1" <?php echo $disble_featured_image; ?> />
59
- <label for="rss-feeds"><?php echo __( 'Do NOT add the featured image to the website\'s RSS feed.', 'feedzy-rss-feeds' ); ?></label>
60
 
61
  </div>
62
  <?php
63
  break;
64
  case 'headers':
65
  ?>
66
- <h2><?php _e( 'Headers', 'feedzy-rss-feeds' ); ?></h2>
67
  <div class="fz-form-group">
68
- <label><?php echo __( 'User Agent to use when accessing the feed', 'feedzy-rss-feeds' ); ?>
69
  :</label>
70
  </div>
71
  <div class="fz-form-group">
72
  <input type="text" class="fz-form-control" name="user-agent"
73
- value="<?php echo isset( $settings['header']['user-agent'] ) ? $settings['header']['user-agent'] : ''; ?>">
74
  </div>
75
  <?php
76
  break;
77
  case 'proxy':
78
  ?>
79
- <h2><?php _e( 'Proxy Settings', 'feedzy-rss-feeds' ); ?></h2>
80
  <div class="fz-form-group">
81
- <label><?php echo __( 'Host', 'feedzy-rss-feeds' ); ?>:</label>
82
  </div>
83
  <div class="fz-form-group">
84
  <input type="text" class="fz-form-control" name="proxy-host"
85
- value="<?php echo isset( $settings['proxy']['host'] ) ? $settings['proxy']['host'] : ''; ?>">
86
  </div>
87
 
88
  <div class="fz-form-group">
89
- <label><?php echo __( 'Port', 'feedzy-rss-feeds' ); ?>:</label>
90
  </div>
91
  <div class="fz-form-group">
92
  <input type="number" min="0" max="65535" class="fz-form-control" name="proxy-port"
93
- value="<?php echo isset( $settings['proxy']['port'] ) ? $settings['proxy']['port'] : ''; ?>">
94
  </div>
95
 
96
  <div class="fz-form-group">
97
- <label><?php echo __( 'Username', 'feedzy-rss-feeds' ); ?>:</label>
98
  </div>
99
  <div class="fz-form-group">
100
  <input type="text" class="fz-form-control" name="proxy-user"
101
- value="<?php echo isset( $settings['proxy']['user'] ) ? $settings['proxy']['user'] : ''; ?>">
102
  </div>
103
 
104
  <div class="fz-form-group">
105
- <label><?php echo __( 'Password', 'feedzy-rss-feeds' ); ?>:</label>
106
  </div>
107
  <div class="fz-form-group">
108
  <input type="password" class="fz-form-control" name="proxy-pass"
109
- value="<?php echo isset( $settings['proxy']['pass'] ) ? $settings['proxy']['pass'] : ''; ?>">
110
  </div>
111
  <?php
112
  break;
113
  default:
114
  $fields = apply_filters( 'feedzy_display_tab_settings', array(), $active_tab );
115
  if ( $fields ) {
 
116
  foreach ( $fields as $field ) {
117
- echo $field['content'];
118
  if ( isset( $field['ajax'] ) && $field['ajax'] ) {
119
  $show_button = false;
120
  }
@@ -124,14 +126,14 @@
124
  }
125
  ?>
126
 
127
- <input type="hidden" name="tab" value="<?php echo $active_tab; ?>">
128
 
129
  <?php
130
  wp_nonce_field( $active_tab, 'nonce' );
131
  if ( $show_button ) {
132
  ?>
133
  <button type="submit" class="fz-btn fz-btn-submit fz-btn-activate" id="feedzy-settings-submit"
134
- name="feedzy-settings-submit"><?php _e( 'Save', 'feedzy-rss-feeds' ); ?></button>
135
  <?php
136
  }
137
  ?>
3
  <?php load_template( FEEDZY_ABSPATH . '/includes/layouts/header.php' ); ?>
4
 
5
  <?php
6
+ // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification
7
+ $active_tab = isset( $_REQUEST['tab'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['tab'] ) ) : 'general';
8
  $show_button = true;
9
  ?>
10
 
11
  <h2 class="nav-tab-wrapper">
12
  <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-settings&tab=general' ) ); ?>"
13
+ class="nav-tab <?php echo 'general' === $active_tab ? esc_attr( 'nav-tab-active' ) : ''; ?>"><?php esc_html_e( 'General', 'feedzy-rss-feeds' ); ?></a>
14
  <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-settings&tab=headers' ) ); ?>"
15
+ class="nav-tab <?php echo 'headers' === $active_tab ? esc_attr( 'nav-tab-active' ) : ''; ?>"><?php esc_html_e( 'Headers', 'feedzy-rss-feeds' ); ?></a>
16
  <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-settings&tab=proxy' ) ); ?>"
17
+ class="nav-tab <?php echo 'proxy' === $active_tab ? esc_attr( 'nav-tab-active' ) : ''; ?>"><?php esc_html_e( 'Proxy', 'feedzy-rss-feeds' ); ?></a>
18
  <?php
19
+ $_tabs = apply_filters( 'feedzy_settings_tabs', array() );
20
+ if ( $_tabs ) {
21
+ foreach ( $_tabs as $_tab => $label ) {
22
  ?>
23
+ <a href="<?php echo esc_url( admin_url( 'admin.php?page=feedzy-settings&tab=' . $_tab ) ); ?>"
24
+ class="nav-tab <?php echo $_tab === $active_tab ? esc_attr( 'nav-tab-active' ) : ''; ?>"><?php echo wp_kses_post( $label ); ?></a>
25
  <?php
26
  }
27
  }
29
  </h2>
30
 
31
  <?php if ( $this->notice ) { ?>
32
+ <div class="updated"><p><?php echo wp_kses_post( $this->notice ); ?></p></div>
33
  <?php } ?>
34
 
35
  <?php if ( $this->error ) { ?>
36
+ <div class="error"><p><?php echo wp_kses_post( $this->error ); ?></p></div>
37
  <?php } ?>
38
 
39
 
53
  switch ( $active_tab ) {
54
  case 'general':
55
  ?>
56
+ <h2><?php esc_html_e( 'General', 'feedzy-rss-feeds' ); ?></h2>
57
  <div class="fz-form-group">
58
  <input type="checkbox" id="rss-feeds" class="fz-form-control" name="rss-feeds"
59
+ value="1" <?php echo esc_html( $disble_featured_image ); ?> />
60
+ <label for="rss-feeds"><?php echo esc_html_e( 'Do NOT add the featured image to the website\'s RSS feed.', 'feedzy-rss-feeds' ); ?></label>
61
 
62
  </div>
63
  <?php
64
  break;
65
  case 'headers':
66
  ?>
67
+ <h2><?php esc_html_e( 'Headers', 'feedzy-rss-feeds' ); ?></h2>
68
  <div class="fz-form-group">
69
+ <label><?php esc_html_e( 'User Agent to use when accessing the feed', 'feedzy-rss-feeds' ); ?>
70
  :</label>
71
  </div>
72
  <div class="fz-form-group">
73
  <input type="text" class="fz-form-control" name="user-agent"
74
+ value="<?php echo isset( $settings['header']['user-agent'] ) ? esc_attr( $settings['header']['user-agent'] ) : ''; ?>">
75
  </div>
76
  <?php
77
  break;
78
  case 'proxy':
79
  ?>
80
+ <h2><?php esc_html_e( 'Proxy Settings', 'feedzy-rss-feeds' ); ?></h2>
81
  <div class="fz-form-group">
82
+ <label><?php esc_html_e( 'Host', 'feedzy-rss-feeds' ); ?>:</label>
83
  </div>
84
  <div class="fz-form-group">
85
  <input type="text" class="fz-form-control" name="proxy-host"
86
+ value="<?php echo isset( $settings['proxy']['host'] ) ? esc_attr( $settings['proxy']['host'] ) : ''; ?>">
87
  </div>
88
 
89
  <div class="fz-form-group">
90
+ <label><?php esc_html_e( 'Port', 'feedzy-rss-feeds' ); ?>:</label>
91
  </div>
92
  <div class="fz-form-group">
93
  <input type="number" min="0" max="65535" class="fz-form-control" name="proxy-port"
94
+ value="<?php echo isset( $settings['proxy']['port'] ) ? esc_attr( (int) $settings['proxy']['port'] ) : ''; ?>">
95
  </div>
96
 
97
  <div class="fz-form-group">
98
+ <label><?php esc_html_e( 'Username', 'feedzy-rss-feeds' ); ?>:</label>
99
  </div>
100
  <div class="fz-form-group">
101
  <input type="text" class="fz-form-control" name="proxy-user"
102
+ value="<?php echo isset( $settings['proxy']['user'] ) ? esc_attr( $settings['proxy']['user'] ) : ''; ?>">
103
  </div>
104
 
105
  <div class="fz-form-group">
106
+ <label><?php esc_html_e( 'Password', 'feedzy-rss-feeds' ); ?>:</label>
107
  </div>
108
  <div class="fz-form-group">
109
  <input type="password" class="fz-form-control" name="proxy-pass"
110
+ value="<?php echo isset( $settings['proxy']['pass'] ) ? esc_attr( $settings['proxy']['pass'] ) : ''; ?>">
111
  </div>
112
  <?php
113
  break;
114
  default:
115
  $fields = apply_filters( 'feedzy_display_tab_settings', array(), $active_tab );
116
  if ( $fields ) {
117
+
118
  foreach ( $fields as $field ) {
119
+ echo wp_kses( $field['content'], apply_filters( 'feedzy_wp_kses_allowed_html', array() ) );
120
  if ( isset( $field['ajax'] ) && $field['ajax'] ) {
121
  $show_button = false;
122
  }
126
  }
127
  ?>
128
 
129
+ <input type="hidden" name="tab" value="<?php echo esc_attr( $active_tab ); ?>">
130
 
131
  <?php
132
  wp_nonce_field( $active_tab, 'nonce' );
133
  if ( $show_button ) {
134
  ?>
135
  <button type="submit" class="fz-btn fz-btn-submit fz-btn-activate" id="feedzy-settings-submit"
136
+ name="feedzy-settings-submit"><?php esc_html_e( 'Save', 'feedzy-rss-feeds' ); ?></button>
137
  <?php
138
  }
139
  ?>
includes/util/feedzy-rss-feeds-util-simplepie.php CHANGED
@@ -9,9 +9,9 @@
9
  */
10
 
11
  if ( ! class_exists( 'SimplePie' ) ) {
12
- require_once( ABSPATH . WPINC . '/class-simplepie.php' );
13
- require_once( ABSPATH . WPINC . '/class-wp-feed-cache-transient.php' );
14
- require_once( ABSPATH . WPINC . '/class-wp-simplepie-file.php' );
15
  }
16
 
17
  /**
9
  */
10
 
11
  if ( ! class_exists( 'SimplePie' ) ) {
12
+ require_once ABSPATH . WPINC . '/class-simplepie.php';
13
+ require_once ABSPATH . WPINC . '/class-wp-feed-cache-transient.php';
14
+ require_once ABSPATH . WPINC . '/class-wp-simplepie-file.php';
15
  }
16
 
17
  /**
includes/views/import-metabox-edit.php CHANGED
@@ -8,32 +8,34 @@
8
  ?>
9
  <div class="f1" id="feedzy-import-form">
10
 
11
- <h3><span class="dashicons dashicons-rss"></span> <?php echo __( 'Sources', 'feedzy-rss-feeds' ); ?></h3>
12
 
13
  <div class="form-group">
14
- <label class="feedzy-sr-only"><?php echo __( 'RSS Feed sources (comma separated URLs or Feed Categories slug)', 'feedzy-rss-feeds' ); ?></label>
15
  </div>
16
 
17
- <?php echo $invalid_source_msg; ?>
 
 
18
 
19
  <div class="form-group input-group">
20
  <div class="feedzy-button-inside">
21
- <input type="text" id="feedzy-import-source" title="<?php _e( 'Make sure you validate the feed by using the validate button on the right', 'feedzy-rss-feeds' ); ?>" name="feedzy_meta_data[source]" placeholder="<?php echo __( 'Source', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo $source; ?>"/>
22
- <a class="feedzy-inside" target="_blank" data-href-base="https://validator.w3.org/feed/check.cgi?url=" href="#" title="<?php _e( 'Validate Feed', 'feedzy-rss-feeds' ); ?>"><i title="<?php _e( 'Validate Feed', 'feedzy-rss-feeds' ); ?>" class="dashicons dashicons-external"></i></a>
23
  </div>
24
- <small><i class="dashicons dashicons-lightbulb"></i><?php _e( 'Make sure to use the validate button. Invalid feeds may not import anything.', 'feedzy-rss-feeds' ); ?></small>
25
  <div class="input-group-btn">
26
  <?php
27
  if ( isset( $feed_categories ) && ! empty( $feed_categories ) ) {
28
  ?>
29
  <button type="button" class="btn btn-add-fields dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
30
- <?php echo __( 'Use Feed Category', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-arrow-down-alt2"></span>
31
  </button>
32
  <div class="dropdown-menu dropdown-menu-right">
33
  <?php
34
  foreach ( $feed_categories as $category ) {
35
  ?>
36
- <a class="dropdown-item source" href="#" data-field-name="source" data-field-tag="<?php echo $category->post_name; ?>"><?php echo $category->post_title; ?></a>
37
  <?php
38
  }
39
  ?>
@@ -42,7 +44,7 @@
42
  } else {
43
  ?>
44
  <button type="button" class=" disabled btn-add-fields btn " >
45
- <?php echo __( 'No feed categories available', 'feedzy-rss-feeds' ); ?>
46
  </button>
47
  <?php
48
 
@@ -51,101 +53,97 @@
51
  </div>
52
  </div>
53
 
54
- <h3><span class="dashicons dashicons-filter"></span> <?php echo __( 'Filters', 'feedzy-rss-feeds' ); ?></h3>
55
 
56
  <div class="feedzy-rows">
57
- <div class="feedzy-row <?php echo apply_filters( 'feedzy_upsell_class', '' ); ?>">
58
- <?php echo apply_filters( 'feedzy_upsell_content', '' ); ?>
59
  <div class="label_description">
60
- <label class="feedzy-sr-only"><?php echo __( 'Display item only if the title or content contains specific keyword(s)', 'feedzy-rss-feeds' ); ?></label>
61
  <div>
62
- <small><?php echo sprintf( __( 'You can provide comma-separated words. Remember, these words are %1$scase sensitive%2$s .e.g. News, news, STOCK', 'feedzy-rss-feeds' ), '<b>', '</b>' ); ?></small>
63
  </div>
64
  </div>
65
  <div class="feedzy-separator"></div>
66
  <div class="form-group input-group form_item">
67
- <input type="text" name="feedzy_meta_data[inc_key]" placeholder="<?php echo __( '(eg. news, Sports, STOCK etc.)', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo $inc_key; ?>"/>
68
  </div>
69
  </div>
70
 
71
- <div class="feedzy-row <?php echo apply_filters( 'feedzy_upsell_class', '' ); ?>">
72
- <?php echo apply_filters( 'feedzy_upsell_content', '' ); ?>
73
  <div class="label_description">
74
- <label class="feedzy-sr-only"><?php echo __( 'Exclude item if the title or content contains specific keyword(s)', 'feedzy-rss-feeds' ); ?></label>
75
  <div>
76
- <small><?php echo sprintf( __( 'You can provide comma-separated words. Remember, these words are %1$scase sensitive%2$s .e.g. News, news, STOCK', 'feedzy-rss-feeds' ), '<b>', '</b>' ); ?></small>
77
  </div>
78
  </div>
79
  <div class="feedzy-separator"></div>
80
  <div class="form-group input-group form_item">
81
- <input type="text" name="feedzy_meta_data[exc_key]" placeholder="<?php echo __( '(eg. news, Sports, STOCK etc.)', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo $exc_key; ?>"/>
82
  </div>
83
  </div>
84
 
85
  <div class="feedzy-row">
86
  <div class="label_description">
87
- <label class="feedzy-sr-only"><?php _e( 'How many feed items to import from the source?', 'feedzy-rss-feeds' ); ?></label>
88
  <div>
89
- <small><?php echo sprintf( __( 'If you choose a high number, please check that your configuration can support it or your imports may fail.', 'feedzy-rss-feeds' ), '<b>', '</b>' ); ?></small>
90
  </div>
91
  </div>
92
  <div class="feedzy-separator"></div>
93
  <div class="form-group input-group form_item">
94
- <input type="number" min="0" max="9999" id="feedzy_item_limit" name="feedzy_meta_data[import_feed_limit]" class="form-control" value="<?php echo $import_feed_limit; ?>"/>
95
  </div>
96
  </div>
97
 
98
- <div class="feedzy-row <?php echo apply_filters( 'feedzy_upsell_class', '' ); ?>">
99
- <?php echo apply_filters( 'feedzy_upsell_content', '' ); ?>
100
  <div class="label_description">
101
- <label class="feedzy-sr-only"><?php _e( 'Automatically delete the posts created for this import after how many days?', 'feedzy-rss-feeds' ); ?></label>
102
  <div>
103
- <small><?php _e( 'Helpful if you want to remove stale or old items automatically. If you choose 0, the imported items will not be automatically deleted.', 'feedzy-rss-feeds' ); ?></small>
104
  </div>
105
  </div>
106
  <div class="feedzy-separator"></div>
107
  <div class="form-group input-group form_item">
108
- <input type="number" min="0" max="9999" id="feedzy_delete_days" name="feedzy_meta_data[import_feed_delete_days]" class="form-control" value="<?php echo $import_feed_delete_days; ?>"/>
109
  </div>
110
  </div>
111
 
112
  </div>
113
 
114
 
115
- <h3><span class="dashicons dashicons-feedback"></span> <?php echo __( 'Assign Elements', 'feedzy-rss-feeds' ); ?></h3>
116
 
117
- <p><?php _e( 'Using magic tags, specify what part(s) of the source should form part of the imported post.', 'feedzy-rss-feeds' ); ?>
118
  <?php if ( false === apply_filters( 'feedzy_is_license_of_type', false, 'agency' ) ) { ?>
119
- <?php echo sprintf( __( 'The magic tags that are greyed out and disabled are unavailable for your current license. You can consider %1$supgrading%2$s.', 'feedzy-rss-feeds' ), '<a href="' . FEEDZY_UPSELL_LINK . '" target="_blank" title="' . __( 'Upgrade', 'feedzy-rss-feeds' ) . '">', '</a>' ); ?>
120
  <?php } ?>
121
  </p>
122
 
123
  <div class="feedzy-rows">
124
  <div class="feedzy-row">
125
  <div class="label_description">
126
- <h4><?php echo __( 'Post Element', 'feedzy-rss-feeds' ); ?></h4>
127
  </div>
128
  <div class="feedzy-separator"></div>
129
  <div class="label_description">
130
- <h4><?php echo __( 'Element Value', 'feedzy-rss-feeds' ); ?></h4>
131
  </div>
132
  </div>
133
  <div class="feedzy-row">
134
  <div class="label_description">
135
- <label class="feedzy-sr-only" for="f1-post-type"><?php echo __( 'Post Type', 'feedzy-rss-feeds' ); ?></label><br/>
136
- <small><?php _e( 'The post type you want to use for the generated post.', 'feedzy-rss-feeds' ); ?></small>
137
  </div>
138
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
139
  <div class="form-group input-group form_item">
140
- <select id="feedzy_post_type" class="form-control feedzy-chosen" name="feedzy_meta_data[import_post_type]" data-tax="<?php echo $import_post_term; ?>" >
141
  <?php
142
- foreach ( $post_types as $post_type ) {
143
- $selected = '';
144
- if ( $post_type === $import_post_type ) {
145
- $selected = 'selected';
146
- }
147
  ?>
148
- <option value="<?php echo $post_type; ?>" <?php echo $selected; ?>><?php echo $post_type; ?></option>
149
  <?php
150
  }
151
  ?>
@@ -154,8 +152,8 @@
154
  </div>
155
  <div class="feedzy-row">
156
  <div class="label_description">
157
- <label class="feedzy-sr-only" for="f1-post-type"><?php echo __( 'Post Taxonomy', 'feedzy-rss-feeds' ); ?></label><br/>
158
- <small><?php _e( 'Assign to a taxonomy (eg. "Post Category", "Post Tag" etc.). Leave blank, if unsure.', 'feedzy-rss-feeds' ); ?></small>
159
  </div>
160
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
161
  <div class="form-group input-group form_item">
@@ -165,10 +163,10 @@
165
  </div>
166
  <div class="feedzy-row">
167
  <div class="label_description">
168
- <label class="feedzy-sr-only" for="f1-post-status"><?php echo __( 'Post Status', 'feedzy-rss-feeds' ); ?></label><br/>
169
  <small>
170
  <?php
171
- echo __( 'The post status you want your posts to have. You can choose Publish if you want to publish your posts right away, or you can use Draft if you want to draft your posts and publish it after reviewing them manually.', 'feedzy-rss-feeds' );
172
  ?>
173
  </small>
174
  </div>
@@ -176,13 +174,9 @@
176
  <div class="form-group input-group form_item">
177
  <select id="feedzy_post_status" class="form-control feedzy-chosen" name="feedzy_meta_data[import_post_status]" >
178
  <?php
179
- foreach ( $published_status as $status ) {
180
- $selected = '';
181
- if ( $status === $import_post_status ) {
182
- $selected = 'selected';
183
- }
184
  ?>
185
- <option value="<?php echo $status; ?>" <?php echo $selected; ?>><?php echo ucfirst( $status ); ?></option>
186
  <?php
187
  }
188
  ?>
@@ -191,7 +185,7 @@
191
  </div>
192
  <div class="feedzy-row">
193
  <div class="label_description">
194
- <label class="feedzy-sr-only" for="f1-post-title"><?php echo __( 'Post Title', 'feedzy-rss-feeds' ); ?></label><br/>
195
  <small>
196
  <?php
197
  $magic_tags = array(
@@ -201,48 +195,48 @@
201
  );
202
  $magic_tags = apply_filters( 'feedzy_get_service_magic_tags', $magic_tags, 'title' );
203
 
204
- _e( 'The title for the generated post. This field is mandatory - without this, a post will not be created.', 'feedzy-rss-feeds' );
205
  ?>
206
  </small>
207
  </div>
208
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
209
  <div class="form-group input-group form_item">
210
- <input type="text" name="feedzy_meta_data[import_post_title]" placeholder="<?php echo __( 'Post Title', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo $import_title; ?>"/>
211
  <div class="input-group-btn">
212
  <button type="button" class="btn btn-add-fields dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
213
- <?php echo __( 'Insert Tag', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-arrow-down-alt2"></span>
214
  </button>
215
  <div class="dropdown-menu dropdown-menu-right">
216
- <?php echo apply_filters( 'feedzy_render_magic_tags', '', apply_filters( 'feedzy_magic_tags_title', array() ), 'import_post_title' ); ?>
217
  </div>
218
  </div>
219
  </div>
220
  </div>
221
  <div class="feedzy-row">
222
  <div class="label_description">
223
- <label class="feedzy-sr-only" for="f1-post-title"><?php echo __( 'Post Date', 'feedzy-rss-feeds' ); ?></label><br/>
224
  <small>
225
  <?php
226
- _e( 'The date for the generated post. Leave blank, if unsure.', 'feedzy-rss-feeds' );
227
  ?>
228
  </small>
229
  </div>
230
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
231
  <div class="form-group input-group form_item">
232
- <input type="text" name="feedzy_meta_data[import_post_date]" placeholder="<?php echo __( 'Post Date', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo $import_date; ?>"/>
233
  <div class="input-group-btn">
234
  <button type="button" class="btn btn-add-fields dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
235
- <?php echo __( 'Insert Tag', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-arrow-down-alt2"></span>
236
  </button>
237
  <div class="dropdown-menu dropdown-menu-right">
238
- <?php echo apply_filters( 'feedzy_render_magic_tags', '', apply_filters( 'feedzy_magic_tags_date', array() ), 'import_post_date' ); ?>
239
  </div>
240
  </div>
241
  </div>
242
  </div>
243
  <div class="feedzy-row">
244
  <div class="label_description">
245
- <label class="feedzy-sr-only" for="f1-post-content"><?php echo __( 'Item Content', 'feedzy-rss-feeds' ); ?></label><br/>
246
  <small>
247
  <?php
248
  $magic_tags = array(
@@ -261,16 +255,16 @@
261
  }
262
  $magic_tags = apply_filters( 'feedzy_get_service_magic_tags', $magic_tags, 'content' );
263
 
264
- _e( 'The content for the generated post. This field is mandatory - without this, a post will not be created.', 'feedzy-rss-feeds' );
265
  ?>
266
  </small>
267
 
268
  <p class="feedzy-highlight"><i class="dashicons dashicons-megaphone"></i>
269
  <?php
270
  if ( apply_filters( 'feedzy_is_license_of_type', false, 'business' ) ) {
271
- echo sprintf( __( 'You can add custom magic tags to extract custom elements from your feed as explained %1$shere%2$s. This will work only for single-feeds (i.e. not if you have specified a feed category that contains multiple feeds or using comma-separated feeds in the source).', 'feedzy-rss-feeds' ), '<a href="https://docs.themeisle.com/article/977-how-do-i-extract-values-from-custom-tags-in-feedzy" target="_blank">', '</a>' );
272
  } else {
273
- echo sprintf( __( 'Want to extract custom elements from your feed as explained %1$shere%2$s? Upgrade your %3$slicense%4$s today!', 'feedzy-rss-feeds' ), '<a href="https://docs.themeisle.com/article/977-how-do-i-extract-values-from-custom-tags-in-feedzy" target="_blank">', '</a>', '<a href="' . FEEDZY_UPSELL_LINK . '" target="_blank">', '</a>' );
274
  }
275
  ?>
276
  </p>
@@ -278,70 +272,88 @@
278
  </div>
279
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
280
  <div class="form-group input-group form_item">
281
- <textarea name="feedzy_meta_data[import_post_content]" placeholder="<?php echo __( 'Post Content', 'feedzy-rss-feeds' ); ?>" class="form-control"><?php echo $import_content; ?></textarea>
282
  <div class="input-group-btn">
283
  <button type="button" class="btn btn-add-fields dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
284
- <?php echo __( 'Insert Tag', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-arrow-down-alt2"></span>
285
  </button>
286
  <div class="dropdown-menu dropdown-menu-right">
287
- <?php echo apply_filters( 'feedzy_render_magic_tags', '', apply_filters( 'feedzy_magic_tags_content', array() ), 'import_post_content' ); ?>
288
  </div>
289
  </div>
290
  </div>
291
  </div>
292
 
293
- <?php echo do_action( 'feedzy_metabox_show_rows', '', $post->ID, 'language-dropdown' ); ?>
294
 
295
  <div class="feedzy-row">
296
  <div class="label_description">
297
- <label class="feedzy-sr-only" for="f1-post-content"><?php echo __( 'Featured Image', 'feedzy-rss-feeds' ); ?></label><br/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  <small>
299
  <?php
300
- _e( 'The URL for the featured image. You can use the magic tags, use your own URL or leave it empty.', 'feedzy-rss-feeds' );
301
  ?>
302
  </small>
303
  </div>
304
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
305
  <div class="form-group input-group form_item">
306
- <input type="text" name="feedzy_meta_data[import_post_featured_img]" placeholder="<?php echo __( 'Featured Image', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo $import_featured_img; ?>"/>
307
  <div class="input-group-btn">
308
  <button type="button" class="btn btn-add-fields dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
309
- <?php echo __( 'Insert Tag', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-arrow-down-alt2"></span>
310
  </button>
311
  <div class="dropdown-menu dropdown-menu-right">
312
- <?php echo apply_filters( 'feedzy_render_magic_tags', '', apply_filters( 'feedzy_magic_tags_image', array() ), 'import_post_featured_img' ); ?>
313
  </div>
314
  </div>
315
  </div>
316
  </div>
317
- <div class="feedzy-row <?php echo apply_filters( 'feedzy_upsell_class', '' ); ?>">
318
- <?php echo apply_filters( 'feedzy_upsell_content', '' ); ?>
319
  <div class="label_description">
320
- <label class="feedzy-sr-only" for="f1-post-content"><?php echo __( 'Post Author', 'feedzy-rss-feeds' ); ?></label><br/>
321
  <small>
322
  <?php
323
- _e( 'Show the original author of the source item.', 'feedzy-rss-feeds' );
324
  ?>
325
  </small>
326
  </div>
327
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
328
  <div class="form-group input-group form_item">
329
  <div>
330
- <input id="feedzy-toggle_author_admin" name="feedzy_meta_data[import_link_author_admin]" class="feedzy-toggle feedzy-toggle-round" type="checkbox" value="yes" <?php echo $import_link_author[0]; ?>>
331
  <label for="feedzy-toggle_author_admin" class="feedzy-inline"></label>
332
- <label class="feedzy-inline" style="margin-left: 10px;" for="import_link_author_admin"><?php echo __( 'In the backend, on the post listing screen', 'feedzy-rss-feeds' ); ?></label>
333
  </div>
334
  <div>
335
- <input id="feedzy-toggle_author_public" name="feedzy_meta_data[import_link_author_public]" class="feedzy-toggle feedzy-toggle-round" type="checkbox" value="yes" <?php echo $import_link_author[1]; ?>>
336
  <label for="feedzy-toggle_author_public" class="feedzy-inline"></label>
337
- <label class="feedzy-inline" style="margin-left: 10px;" for="import_link_author_public"><?php echo __( 'In the frontend, link to the original post', 'feedzy-rss-feeds' ); ?></label>
338
  </div>
339
  </div>
340
  </div>
341
 
342
 
343
- <div class="custom_fields <?php echo apply_filters( 'feedzy_upsell_class', '' ); ?>">
344
- <?php echo apply_filters( 'feedzy_upsell_content', '' ); ?>
345
  <!-- Custom Fields Added By JS -->
346
  <?php
347
  if ( isset( $import_custom_fields ) && ! empty( $import_custom_fields ) ) {
@@ -350,11 +362,11 @@
350
  <div class="row">
351
  <div class="feedzy-row fields">
352
  <div class="form-group form_item">
353
- <input type="text" name="custom_vars_key[]" placeholder="<?php echo __( 'Key Name', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo $custom_field_key; ?>"/>
354
  </div>
355
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
356
  <div class="form-group input-group form_item">
357
- <input type="text" name="custom_vars_value[]" placeholder="<?php echo __( 'Value', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo $custom_field_value; ?>"/>
358
  <div class="input-group-btn">
359
  <button type="button" class="btn btn-remove-fields">
360
  <span class="dashicons dashicons-trash"></span>
@@ -369,22 +381,22 @@
369
  ?>
370
  </div>
371
 
372
- <button id="new_custom_fields" type="button" class="btn btn-add-fields" style="width: 100%; margin-bottom: 16px; margin-top: 16px;" ><?php echo __( 'Add custom fields', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-plus-alt"></span></button>
373
  </div>
374
 
375
 
376
  <div class="f1-buttons">
377
  <input type="hidden" id="custom_post_status" name="custom_post_status" value="draft" />
378
- <button type="button" id="preflight" name="check" class="btn btn-previous" value="Check" title="<?php _e( 'Click to see what items will be imported from the source, according to the filters specified', 'feedzy-rss-feeds' ); ?>"><?php _e( 'Dry Run', 'feedzy-rss-feeds' ); ?></button>
379
  <?php
380
- if ( $post_status === 'publish' ) {
381
  ?>
382
- <button type="submit" name="publish" class="btn btn-submit" value="Publish"><?php _e( 'Save', 'feedzy-rss-feeds' ); ?></button>
383
  <?php
384
  } else {
385
  ?>
386
- <button type="submit" name="save" class="btn btn-submit" value="Save Draft" style="float: none;"><?php _e( 'Save', 'feedzy-rss-feeds' ); ?></button>
387
- <button type="submit" name="publish" class="btn btn-submit btn-activate" value="Publish" ><?php _e( 'Save & Activate', 'feedzy-rss-feeds' ); ?></button>
388
  <?php
389
  }
390
  ?>
@@ -392,14 +404,14 @@
392
  </div>
393
 
394
  <script id="empty_select_tpl" type="text/template">
395
- <option value="none"><?php echo __( 'None', 'feedzy-rss-feeds' ); ?></option>
396
  </script>
397
 
398
  <script id="loading_select_tpl" type="text/template">
399
- <option value=""><?php echo __( 'Loading...', 'feedzy-rss-feeds' ); ?></option>
400
  </script>
401
 
402
  <script id="new_field_tpl" type="text/template">
403
- <?php echo apply_filters( 'feedzy_custom_field_template', '' ); ?>
404
  </script>
405
 
8
  ?>
9
  <div class="f1" id="feedzy-import-form">
10
 
11
+ <h3><span class="dashicons dashicons-rss"></span> <?php esc_html_e( 'Sources', 'feedzy-rss-feeds' ); ?></h3>
12
 
13
  <div class="form-group">
14
+ <label class="feedzy-sr-only"><?php esc_html_e( 'RSS Feed sources (comma separated URLs or Feed Categories slug)', 'feedzy-rss-feeds' ); ?></label>
15
  </div>
16
 
17
+ <?php echo wp_kses_post( $invalid_source_msg ); ?>
18
+
19
+ <input type="hidden" id="feedzy_post_nonce" name="feedzy_post_nonce" value="<?php echo esc_attr( wp_create_nonce( 'feedzy_post_nonce' ) ); ?>"/>
20
 
21
  <div class="form-group input-group">
22
  <div class="feedzy-button-inside">
23
+ <input type="text" id="feedzy-import-source" title="<?php esc_attr_e( 'Make sure you validate the feed by using the validate button on the right', 'feedzy-rss-feeds' ); ?>" name="feedzy_meta_data[source]" placeholder="<?php esc_attr_e( 'Source', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo esc_attr( $source ); ?>"/>
24
+ <a class="feedzy-inside" target="_blank" data-href-base="https://validator.w3.org/feed/check.cgi?url=" href="#" title="<?php esc_attr_e( 'Validate Feed', 'feedzy-rss-feeds' ); ?>"><i title="<?php esc_attr_e( 'Validate Feed', 'feedzy-rss-feeds' ); ?>" class="dashicons dashicons-external"></i></a>
25
  </div>
26
+ <small><i class="dashicons dashicons-lightbulb"></i><?php esc_html_e( 'Make sure to use the validate button. Invalid feeds may not import anything.', 'feedzy-rss-feeds' ); ?></small>
27
  <div class="input-group-btn">
28
  <?php
29
  if ( isset( $feed_categories ) && ! empty( $feed_categories ) ) {
30
  ?>
31
  <button type="button" class="btn btn-add-fields dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
32
+ <?php esc_html_e( 'Use Feed Category', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-arrow-down-alt2"></span>
33
  </button>
34
  <div class="dropdown-menu dropdown-menu-right">
35
  <?php
36
  foreach ( $feed_categories as $category ) {
37
  ?>
38
+ <a class="dropdown-item source" href="#" data-field-name="source" data-field-tag="<?php echo esc_attr( $category->post_name ); ?>"><?php echo wp_kses_post( $category->post_title ); ?></a>
39
  <?php
40
  }
41
  ?>
44
  } else {
45
  ?>
46
  <button type="button" class=" disabled btn-add-fields btn " >
47
+ <?php esc_html_e( 'No feed categories available', 'feedzy-rss-feeds' ); ?>
48
  </button>
49
  <?php
50
 
53
  </div>
54
  </div>
55
 
56
+ <h3><span class="dashicons dashicons-filter"></span> <?php esc_html_e( 'Filters', 'feedzy-rss-feeds' ); ?></h3>
57
 
58
  <div class="feedzy-rows">
59
+ <div class="feedzy-row <?php echo esc_attr( apply_filters( 'feedzy_upsell_class', '' ) ); ?>">
60
+ <?php echo wp_kses_post( apply_filters( 'feedzy_upsell_content', '' ) ); ?>
61
  <div class="label_description">
62
+ <label class="feedzy-sr-only"><?php esc_html_e( 'Display item only if the title or content contains specific keyword(s)', 'feedzy-rss-feeds' ); ?></label>
63
  <div>
64
+ <small><?php echo wp_kses_post( sprintf( __( 'You can provide comma-separated words. Remember, these words are %1$scase sensitive%2$s .e.g. News, news, STOCK', 'feedzy-rss-feeds' ), '<b>', '</b>' ) ); ?></small>
65
  </div>
66
  </div>
67
  <div class="feedzy-separator"></div>
68
  <div class="form-group input-group form_item">
69
+ <input type="text" name="feedzy_meta_data[inc_key]" placeholder="<?php esc_html_e( '(eg. news, Sports, STOCK etc.)', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo esc_attr( $inc_key ); ?>"/>
70
  </div>
71
  </div>
72
 
73
+ <div class="feedzy-row <?php echo esc_attr( apply_filters( 'feedzy_upsell_class', '' ) ); ?>">
74
+ <?php echo wp_kses_post( apply_filters( 'feedzy_upsell_content', '' ) ); ?>
75
  <div class="label_description">
76
+ <label class="feedzy-sr-only"><?php esc_html_e( 'Exclude item if the title or content contains specific keyword(s)', 'feedzy-rss-feeds' ); ?></label>
77
  <div>
78
+ <small><?php echo wp_kses_post( sprintf( __( 'You can provide comma-separated words. Remember, these words are %1$scase sensitive%2$s .e.g. News, news, STOCK', 'feedzy-rss-feeds' ), '<b>', '</b>' ) ); ?></small>
79
  </div>
80
  </div>
81
  <div class="feedzy-separator"></div>
82
  <div class="form-group input-group form_item">
83
+ <input type="text" name="feedzy_meta_data[exc_key]" placeholder="<?php esc_html_e( '(eg. news, Sports, STOCK etc.)', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo esc_attr( $exc_key ); ?>"/>
84
  </div>
85
  </div>
86
 
87
  <div class="feedzy-row">
88
  <div class="label_description">
89
+ <label class="feedzy-sr-only"><?php esc_html_e( 'How many feed items to import from the source?', 'feedzy-rss-feeds' ); ?></label>
90
  <div>
91
+ <small><?php echo wp_kses_post( sprintf( __( 'If you choose a high number, please check that your configuration can support it or your imports may fail.', 'feedzy-rss-feeds' ), '<b>', '</b>' ) ); ?></small>
92
  </div>
93
  </div>
94
  <div class="feedzy-separator"></div>
95
  <div class="form-group input-group form_item">
96
+ <input type="number" min="0" max="9999" id="feedzy_item_limit" name="feedzy_meta_data[import_feed_limit]" class="form-control" value="<?php echo esc_attr( (int) $import_feed_limit ); ?>"/>
97
  </div>
98
  </div>
99
 
100
+ <div class="feedzy-row <?php echo esc_attr( apply_filters( 'feedzy_upsell_class', '' ) ); ?>">
101
+ <?php echo wp_kses_post( apply_filters( 'feedzy_upsell_content', '' ) ); ?>
102
  <div class="label_description">
103
+ <label class="feedzy-sr-only"><?php esc_html_e( 'Automatically delete the posts created for this import after how many days?', 'feedzy-rss-feeds' ); ?></label>
104
  <div>
105
+ <small><?php esc_html_e( 'Helpful if you want to remove stale or old items automatically. If you choose 0, the imported items will not be automatically deleted.', 'feedzy-rss-feeds' ); ?></small>
106
  </div>
107
  </div>
108
  <div class="feedzy-separator"></div>
109
  <div class="form-group input-group form_item">
110
+ <input type="number" min="0" max="9999" id="feedzy_delete_days" name="feedzy_meta_data[import_feed_delete_days]" class="form-control" value="<?php echo esc_attr( (int) $import_feed_delete_days ); ?>"/>
111
  </div>
112
  </div>
113
 
114
  </div>
115
 
116
 
117
+ <h3><span class="dashicons dashicons-feedback"></span> <?php esc_html_e( 'Assign Elements', 'feedzy-rss-feeds' ); ?></h3>
118
 
119
+ <p><?php esc_html_e( 'Using magic tags, specify what part(s) of the source should form part of the imported post.', 'feedzy-rss-feeds' ); ?>
120
  <?php if ( false === apply_filters( 'feedzy_is_license_of_type', false, 'agency' ) ) { ?>
121
+ <?php echo wp_kses_post( sprintf( __( 'The magic tags that are greyed out and disabled are unavailable for your current license. You can consider %1$supgrading%2$s.', 'feedzy-rss-feeds' ), '<a href="' . esc_url( FEEDZY_UPSELL_LINK ) . '" target="_blank" title="' . __( 'Upgrade', 'feedzy-rss-feeds' ) . '">', '</a>' ) ); ?>
122
  <?php } ?>
123
  </p>
124
 
125
  <div class="feedzy-rows">
126
  <div class="feedzy-row">
127
  <div class="label_description">
128
+ <h4><?php esc_html_e( 'Post Element', 'feedzy-rss-feeds' ); ?></h4>
129
  </div>
130
  <div class="feedzy-separator"></div>
131
  <div class="label_description">
132
+ <h4><?php esc_html_e( 'Element Value', 'feedzy-rss-feeds' ); ?></h4>
133
  </div>
134
  </div>
135
  <div class="feedzy-row">
136
  <div class="label_description">
137
+ <label class="feedzy-sr-only" for="f1-post-type"><?php esc_html_e( 'Post Type', 'feedzy-rss-feeds' ); ?></label><br/>
138
+ <small><?php esc_html_e( 'The post type you want to use for the generated post.', 'feedzy-rss-feeds' ); ?></small>
139
  </div>
140
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
141
  <div class="form-group input-group form_item">
142
+ <select id="feedzy_post_type" class="form-control feedzy-chosen" name="feedzy_meta_data[import_post_type]" data-tax="<?php echo esc_attr( $import_post_term ); ?>" >
143
  <?php
144
+ foreach ( $post_types as $_post_type ) {
 
 
 
 
145
  ?>
146
+ <option value="<?php echo esc_attr( $_post_type ); ?>" <?php selected( $import_post_type, $_post_type ); ?>><?php echo esc_html( $_post_type ); ?></option>
147
  <?php
148
  }
149
  ?>
152
  </div>
153
  <div class="feedzy-row">
154
  <div class="label_description">
155
+ <label class="feedzy-sr-only" for="f1-post-type"><?php esc_html_e( 'Post Taxonomy', 'feedzy-rss-feeds' ); ?></label><br/>
156
+ <small><?php esc_html_e( 'Assign to a taxonomy (eg. "Post Category", "Post Tag" etc.). Leave blank, if unsure.', 'feedzy-rss-feeds' ); ?></small>
157
  </div>
158
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
159
  <div class="form-group input-group form_item">
163
  </div>
164
  <div class="feedzy-row">
165
  <div class="label_description">
166
+ <label class="feedzy-sr-only" for="f1-post-status"><?php esc_html_e( 'Post Status', 'feedzy-rss-feeds' ); ?></label><br/>
167
  <small>
168
  <?php
169
+ esc_html_e( 'The post status you want your posts to have. You can choose Publish if you want to publish your posts right away, or you can use Draft if you want to draft your posts and publish it after reviewing them manually.', 'feedzy-rss-feeds' );
170
  ?>
171
  </small>
172
  </div>
174
  <div class="form-group input-group form_item">
175
  <select id="feedzy_post_status" class="form-control feedzy-chosen" name="feedzy_meta_data[import_post_status]" >
176
  <?php
177
+ foreach ( $published_status as $_status ) {
 
 
 
 
178
  ?>
179
+ <option value="<?php echo esc_attr( $_status ); ?>" <?php selected( $import_post_status, $_status ); ?>><?php echo esc_html( ucfirst( $_status ) ); ?></option>
180
  <?php
181
  }
182
  ?>
185
  </div>
186
  <div class="feedzy-row">
187
  <div class="label_description">
188
+ <label class="feedzy-sr-only" for="f1-post-title"><?php esc_html_e( 'Post Title', 'feedzy-rss-feeds' ); ?></label><br/>
189
  <small>
190
  <?php
191
  $magic_tags = array(
195
  );
196
  $magic_tags = apply_filters( 'feedzy_get_service_magic_tags', $magic_tags, 'title' );
197
 
198
+ esc_html_e( 'The title for the generated post. This field is mandatory - without this, a post will not be created.', 'feedzy-rss-feeds' );
199
  ?>
200
  </small>
201
  </div>
202
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
203
  <div class="form-group input-group form_item">
204
+ <input type="text" name="feedzy_meta_data[import_post_title]" placeholder="<?php esc_html_e( 'Post Title', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo esc_attr( $import_title ); ?>"/>
205
  <div class="input-group-btn">
206
  <button type="button" class="btn btn-add-fields dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
207
+ <?php esc_html_e( 'Insert Tag', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-arrow-down-alt2"></span>
208
  </button>
209
  <div class="dropdown-menu dropdown-menu-right">
210
+ <?php echo wp_kses_post( apply_filters( 'feedzy_render_magic_tags', '', apply_filters( 'feedzy_magic_tags_title', array() ), 'import_post_title' ) ); ?>
211
  </div>
212
  </div>
213
  </div>
214
  </div>
215
  <div class="feedzy-row">
216
  <div class="label_description">
217
+ <label class="feedzy-sr-only" for="f1-post-title"><?php esc_html_e( 'Post Date', 'feedzy-rss-feeds' ); ?></label><br/>
218
  <small>
219
  <?php
220
+ esc_html_e( 'The date for the generated post. Leave blank, if unsure.', 'feedzy-rss-feeds' );
221
  ?>
222
  </small>
223
  </div>
224
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
225
  <div class="form-group input-group form_item">
226
+ <input type="text" name="feedzy_meta_data[import_post_date]" placeholder="<?php esc_html_e( 'Post Date', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo esc_attr( $import_date ); ?>"/>
227
  <div class="input-group-btn">
228
  <button type="button" class="btn btn-add-fields dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
229
+ <?php esc_html_e( 'Insert Tag', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-arrow-down-alt2"></span>
230
  </button>
231
  <div class="dropdown-menu dropdown-menu-right">
232
+ <?php echo wp_kses_post( apply_filters( 'feedzy_render_magic_tags', '', apply_filters( 'feedzy_magic_tags_date', array() ), 'import_post_date' ) ); ?>
233
  </div>
234
  </div>
235
  </div>
236
  </div>
237
  <div class="feedzy-row">
238
  <div class="label_description">
239
+ <label class="feedzy-sr-only" for="f1-post-content"><?php esc_html_e( 'Item Content', 'feedzy-rss-feeds' ); ?></label><br/>
240
  <small>
241
  <?php
242
  $magic_tags = array(
255
  }
256
  $magic_tags = apply_filters( 'feedzy_get_service_magic_tags', $magic_tags, 'content' );
257
 
258
+ esc_html_e( 'The content for the generated post. This field is mandatory - without this, a post will not be created.', 'feedzy-rss-feeds' );
259
  ?>
260
  </small>
261
 
262
  <p class="feedzy-highlight"><i class="dashicons dashicons-megaphone"></i>
263
  <?php
264
  if ( apply_filters( 'feedzy_is_license_of_type', false, 'business' ) ) {
265
+ echo wp_kses_post( sprintf( __( 'You can add custom magic tags to extract custom elements from your feed as explained %1$shere%2$s. This will work only for single-feeds (i.e. not if you have specified a feed category that contains multiple feeds or using comma-separated feeds in the source).', 'feedzy-rss-feeds' ), '<a href="https://docs.themeisle.com/article/977-how-do-i-extract-values-from-custom-tags-in-feedzy" target="_blank">', '</a>' ) );
266
  } else {
267
+ echo wp_kses_post( sprintf( __( 'Want to extract custom elements from your feed as explained %1$shere%2$s? Upgrade your %3$slicense%4$s today!', 'feedzy-rss-feeds' ), '<a href="https://docs.themeisle.com/article/977-how-do-i-extract-values-from-custom-tags-in-feedzy" target="_blank">', '</a>', '<a href="' . FEEDZY_UPSELL_LINK . '" target="_blank">', '</a>' ) );
268
  }
269
  ?>
270
  </p>
272
  </div>
273
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
274
  <div class="form-group input-group form_item">
275
+ <textarea name="feedzy_meta_data[import_post_content]" placeholder="<?php esc_html_e( 'Post Content', 'feedzy-rss-feeds' ); ?>" class="form-control"><?php echo wp_kses_post( $import_content ); ?></textarea>
276
  <div class="input-group-btn">
277
  <button type="button" class="btn btn-add-fields dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
278
+ <?php esc_html_e( 'Insert Tag', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-arrow-down-alt2"></span>
279
  </button>
280
  <div class="dropdown-menu dropdown-menu-right">
281
+ <?php echo wp_kses_post( apply_filters( 'feedzy_render_magic_tags', '', apply_filters( 'feedzy_magic_tags_content', array() ), 'import_post_content' ) ); ?>
282
  </div>
283
  </div>
284
  </div>
285
  </div>
286
 
287
+ <?php do_action( 'feedzy_metabox_show_rows', '', $post->ID, 'language-dropdown' ); ?>
288
 
289
  <div class="feedzy-row">
290
  <div class="label_description">
291
+ <label class="feedzy-sr-only" for="f1-post-content"><?php esc_html_e( 'External Image URL?', 'feedzy-rss-feeds' ); ?></label><br/>
292
+ <small>
293
+ <?php
294
+ esc_attr_e( 'The image url will be 3rd party url, We will not download image to your site.', 'feedzy-rss-feeds' );
295
+ ?>
296
+ </small>
297
+ </div>
298
+ <div class="feedzy-separator dashicons dashicons-leftright"></div>
299
+ <div class="form-group input-group form_item">
300
+ <div>
301
+ <input id="use-external-image" name="feedzy_meta_data[import_use_external_image]" class="feedzy-toggle feedzy-toggle-round" type="checkbox" value="yes" <?php echo esc_attr( $import_item_img_url ); ?>>
302
+ <label for="use-external-image" class="feedzy-inline"></label>
303
+ <label class="feedzy-inline" style="margin-left: 10px;" for="import_use_external_image"><?php esc_html_e( 'User external image URL, Ignore feature post thumbnail', 'feedzy-rss-feeds' ); ?></label>
304
+ </div>
305
+ </div>
306
+ </div>
307
+ <div class="feedzy-row">
308
+ <div class="label_description">
309
+ <label class="feedzy-sr-only" for="f1-post-content"><?php esc_html_e( 'Featured Image', 'feedzy-rss-feeds' ); ?></label><br/>
310
  <small>
311
  <?php
312
+ esc_html_e( 'The URL for the featured image. You can use the magic tags, use your own URL or leave it empty.', 'feedzy-rss-feeds' );
313
  ?>
314
  </small>
315
  </div>
316
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
317
  <div class="form-group input-group form_item">
318
+ <input type="text" name="feedzy_meta_data[import_post_featured_img]" placeholder="<?php esc_html_e( 'Featured Image', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo esc_attr( $import_featured_img ); ?>"/>
319
  <div class="input-group-btn">
320
  <button type="button" class="btn btn-add-fields dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
321
+ <?php esc_html_e( 'Insert Tag', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-arrow-down-alt2"></span>
322
  </button>
323
  <div class="dropdown-menu dropdown-menu-right">
324
+ <?php echo wp_kses_post( apply_filters( 'feedzy_render_magic_tags', '', apply_filters( 'feedzy_magic_tags_image', array() ), 'import_post_featured_img' ) ); ?>
325
  </div>
326
  </div>
327
  </div>
328
  </div>
329
+ <div class="feedzy-row <?php echo esc_attr( apply_filters( 'feedzy_upsell_class', '' ) ); ?>">
330
+ <?php echo wp_kses_post( apply_filters( 'feedzy_upsell_content', '' ) ); ?>
331
  <div class="label_description">
332
+ <label class="feedzy-sr-only" for="f1-post-content"><?php esc_html_e( 'Post Author', 'feedzy-rss-feeds' ); ?></label><br/>
333
  <small>
334
  <?php
335
+ esc_html_e( 'Show the original author of the source item.', 'feedzy-rss-feeds' );
336
  ?>
337
  </small>
338
  </div>
339
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
340
  <div class="form-group input-group form_item">
341
  <div>
342
+ <input id="feedzy-toggle_author_admin" name="feedzy_meta_data[import_link_author_admin]" class="feedzy-toggle feedzy-toggle-round" type="checkbox" value="yes" <?php echo wp_kses_post( $import_link_author[0] ); ?>>
343
  <label for="feedzy-toggle_author_admin" class="feedzy-inline"></label>
344
+ <label class="feedzy-inline" style="margin-left: 10px;" for="import_link_author_admin"><?php esc_html_e( 'In the backend, on the post listing screen', 'feedzy-rss-feeds' ); ?></label>
345
  </div>
346
  <div>
347
+ <input id="feedzy-toggle_author_public" name="feedzy_meta_data[import_link_author_public]" class="feedzy-toggle feedzy-toggle-round" type="checkbox" value="yes" <?php echo wp_kses_post( $import_link_author[1] ); ?>>
348
  <label for="feedzy-toggle_author_public" class="feedzy-inline"></label>
349
+ <label class="feedzy-inline" style="margin-left: 10px;" for="import_link_author_public"><?php esc_html_e( 'In the frontend, link to the original post', 'feedzy-rss-feeds' ); ?></label>
350
  </div>
351
  </div>
352
  </div>
353
 
354
 
355
+ <div class="custom_fields <?php echo esc_attr( apply_filters( 'feedzy_upsell_class', '' ) ); ?>">
356
+ <?php echo wp_kses_post( apply_filters( 'feedzy_upsell_content', '' ) ); ?>
357
  <!-- Custom Fields Added By JS -->
358
  <?php
359
  if ( isset( $import_custom_fields ) && ! empty( $import_custom_fields ) ) {
362
  <div class="row">
363
  <div class="feedzy-row fields">
364
  <div class="form-group form_item">
365
+ <input type="text" name="custom_vars_key[]" placeholder="<?php esc_html_e( 'Key Name', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo esc_attr( $custom_field_key ); ?>"/>
366
  </div>
367
  <div class="feedzy-separator dashicons dashicons-leftright"></div>
368
  <div class="form-group input-group form_item">
369
+ <input type="text" name="custom_vars_value[]" placeholder="<?php esc_html_e( 'Value', 'feedzy-rss-feeds' ); ?>" class="form-control" value="<?php echo esc_attr( $custom_field_value ); ?>"/>
370
  <div class="input-group-btn">
371
  <button type="button" class="btn btn-remove-fields">
372
  <span class="dashicons dashicons-trash"></span>
381
  ?>
382
  </div>
383
 
384
+ <button id="new_custom_fields" type="button" class="btn btn-add-fields" style="width: 100%; margin-bottom: 16px; margin-top: 16px;" ><?php esc_html_e( 'Add custom fields', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-plus-alt"></span></button>
385
  </div>
386
 
387
 
388
  <div class="f1-buttons">
389
  <input type="hidden" id="custom_post_status" name="custom_post_status" value="draft" />
390
+ <button type="button" id="preflight" name="check" class="btn btn-previous" value="Check" title="<?php esc_html_e( 'Click to see what items will be imported from the source, according to the filters specified', 'feedzy-rss-feeds' ); ?>"><?php esc_html_e( 'Dry Run', 'feedzy-rss-feeds' ); ?></button>
391
  <?php
392
+ if ( 'publish' === $post_status ) {
393
  ?>
394
+ <button type="submit" name="publish" class="btn btn-submit" value="Publish"><?php esc_html_e( 'Save', 'feedzy-rss-feeds' ); ?></button>
395
  <?php
396
  } else {
397
  ?>
398
+ <button type="submit" name="save" class="btn btn-submit" value="Save Draft" style="float: none;"><?php esc_html_e( 'Save', 'feedzy-rss-feeds' ); ?></button>
399
+ <button type="submit" name="publish" class="btn btn-submit btn-activate" value="Publish" ><?php esc_html_e( 'Save & Activate', 'feedzy-rss-feeds' ); ?></button>
400
  <?php
401
  }
402
  ?>
404
  </div>
405
 
406
  <script id="empty_select_tpl" type="text/template">
407
+ <option value="none"><?php esc_html_e( 'None', 'feedzy-rss-feeds' ); ?></option>
408
  </script>
409
 
410
  <script id="loading_select_tpl" type="text/template">
411
+ <option value=""><?php esc_html_e( 'Loading...', 'feedzy-rss-feeds' ); ?></option>
412
  </script>
413
 
414
  <script id="new_field_tpl" type="text/template">
415
+ <?php echo wp_kses_post( apply_filters( 'feedzy_custom_field_template', '' ) ); ?>
416
  </script>
417
 
includes/views/js/chosen.js CHANGED
@@ -5,1327 +5,1362 @@
5
  * @since 1.2.0
6
  * @package feedzy-rss-feeds-pro
7
  */
8
- /*!
9
- Chosen, a Select Box Enhancer for jQuery and Prototype
10
- by Patrick Filler for Harvest, http://getharvest.com
11
-
12
- Version 1.7.0
13
- Full source at https://github.com/harvesthq/chosen
14
- Copyright (c) 2011-2017 Harvest http://getharvest.com
15
-
16
- MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
17
- This file is generated by `grunt build`, do not edit it by hand.
18
- */
19
- /* jshint ignore:start */
20
  (function() {
21
- var $, AbstractChosen, Chosen, SelectParser, _ref,
22
- __bind = function(fn, me){ return function(){ return fn.apply( me, arguments ); }; },
23
- __hasProp = {}.hasOwnProperty,
24
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call( parent, key )) { child[key] = parent[key];
25
- } } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
26
-
27
- SelectParser = (function() {
28
- function SelectParser() {
29
- this.options_index = 0;
30
- this.parsed = [];
31
- }
32
-
33
- SelectParser.prototype.add_node = function(child) {
34
- if (child.nodeName.toUpperCase() === "OPTGROUP") {
35
- return this.add_group( child );
36
- } else {
37
- return this.add_option( child );
38
- }
39
- };
40
-
41
- SelectParser.prototype.add_group = function(group) {
42
- var group_position, option, _i, _len, _ref, _results;
43
- group_position = this.parsed.length;
44
- this.parsed.push({
45
- array_index: group_position,
46
- group: true,
47
- label: this.escapeExpression( group.label ),
48
- title: group.title ? group.title : void 0,
49
- children: 0,
50
- disabled: group.disabled,
51
- classes: group.className
52
- });
53
- _ref = group.childNodes;
54
- _results = [];
55
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
56
- option = _ref[_i];
57
- _results.push( this.add_option( option, group_position, group.disabled ) );
58
- }
59
- return _results;
60
- };
61
-
62
- SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
63
- if (option.nodeName.toUpperCase() === "OPTION") {
64
- if (option.text !== "") {
65
- if (group_position != null) {
66
- this.parsed[group_position].children += 1;
67
- }
68
- this.parsed.push({
69
- array_index: this.parsed.length,
70
- options_index: this.options_index,
71
- value: option.value,
72
- text: option.text,
73
- html: option.innerHTML,
74
- title: option.title ? option.title : void 0,
75
- selected: option.selected,
76
- disabled: group_disabled === true ? group_disabled : option.disabled,
77
- group_array_index: group_position,
78
- group_label: group_position != null ? this.parsed[group_position].label : null,
79
- classes: option.className,
80
- style: option.style.cssText
81
- });
82
- } else {
83
- this.parsed.push({
84
- array_index: this.parsed.length,
85
- options_index: this.options_index,
86
- empty: true
87
- });
88
- }
89
- return this.options_index += 1;
90
- }
91
- };
92
-
93
- SelectParser.prototype.escapeExpression = function(text) {
94
- var map, unsafe_chars;
95
- if ((text == null) || text === false) {
96
- return "";
97
- }
98
- if ( ! / [\&\ < \ > \"\'\`] / .test( text )) {
99
- return text;
100
- }
101
- map = {
102
- "<": "&lt;",
103
- ">": "&gt;",
104
- '"': "&quot;",
105
- "'": "&#x27;",
106
- "`": "&#x60;"
107
- };
108
- unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
109
- return text.replace(unsafe_chars, function(chr) {
110
- return map[chr] || "&amp;";
111
- });
112
- };
113
-
114
- return SelectParser;
115
-
116
- })();
117
-
118
- SelectParser.select_to_array = function(select) {
119
- var child, parser, _i, _len, _ref;
120
- parser = new SelectParser();
121
- _ref = select.childNodes;
122
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
123
- child = _ref[_i];
124
- parser.add_node( child );
125
- }
126
- return parser.parsed;
127
- };
128
-
129
- AbstractChosen = (function() {
130
- function AbstractChosen(form_field, options) {
131
- this.form_field = form_field;
132
- this.options = options != null ? options : {};
133
- this.label_click_handler = __bind( this.label_click_handler, this );
134
- if ( ! AbstractChosen.browser_is_supported()) {
135
- return;
136
- }
137
- this.is_multiple = this.form_field.multiple;
138
- this.set_default_text();
139
- this.set_default_values();
140
- this.setup();
141
- this.set_up_html();
142
- this.register_observers();
143
- this.on_ready();
144
- }
145
-
146
- AbstractChosen.prototype.set_default_values = function() {
147
- var _this = this;
148
- this.click_test_action = function(evt) {
149
- return _this.test_active_click( evt );
150
- };
151
- this.activate_action = function(evt) {
152
- return _this.activate_field( evt );
153
- };
154
- this.active_field = false;
155
- this.mouse_on_container = false;
156
- this.results_showing = false;
157
- this.result_highlighted = null;
158
- this.is_rtl = this.options.rtl || /\bchosen-rtl\b/.test( this.form_field.className );
159
- this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
160
- this.disable_search_threshold = this.options.disable_search_threshold || 0;
161
- this.disable_search = this.options.disable_search || false;
162
- this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
163
- this.group_search = this.options.group_search != null ? this.options.group_search : true;
164
- this.search_contains = this.options.search_contains || false;
165
- this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
166
- this.max_selected_options = this.options.max_selected_options || Infinity;
167
- this.inherit_select_classes = this.options.inherit_select_classes || false;
168
- this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
169
- this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
170
- this.include_group_label_in_selected = this.options.include_group_label_in_selected || false;
171
- this.max_shown_results = this.options.max_shown_results || Number.POSITIVE_INFINITY;
172
- this.case_sensitive_search = this.options.case_sensitive_search || false;
173
- return this.hide_results_on_select = this.options.hide_results_on_select != null ? this.options.hide_results_on_select : true;
174
- };
175
-
176
- AbstractChosen.prototype.set_default_text = function() {
177
- if (this.form_field.getAttribute( "data-placeholder" )) {
178
- this.default_text = this.form_field.getAttribute( "data-placeholder" );
179
- } else if (this.is_multiple) {
180
- this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
181
- } else {
182
- this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
183
- }
184
- this.default_text = this.escape_html( this.default_text );
185
- return this.results_none_found = this.form_field.getAttribute( "data-no_results_text" ) || this.options.no_results_text || AbstractChosen.default_no_result_text;
186
- };
187
-
188
- AbstractChosen.prototype.choice_label = function(item) {
189
- if (this.include_group_label_in_selected && (item.group_label != null)) {
190
- return "<b class='group-name'>" + item.group_label + "</b>" + item.html;
191
- } else {
192
- return item.html;
193
- }
194
- };
195
-
196
- AbstractChosen.prototype.mouse_enter = function() {
197
- return this.mouse_on_container = true;
198
- };
199
-
200
- AbstractChosen.prototype.mouse_leave = function() {
201
- return this.mouse_on_container = false;
202
- };
203
-
204
- AbstractChosen.prototype.input_focus = function(evt) {
205
- var _this = this;
206
- if (this.is_multiple) {
207
- if ( ! this.active_field) {
208
- return setTimeout((function() {
209
- return _this.container_mousedown();
210
- }), 50);
211
- }
212
- } else {
213
- if ( ! this.active_field) {
214
- return this.activate_field();
215
- }
216
- }
217
- };
218
-
219
- AbstractChosen.prototype.input_blur = function(evt) {
220
- var _this = this;
221
- if ( ! this.mouse_on_container) {
222
- this.active_field = false;
223
- return setTimeout((function() {
224
- return _this.blur_test();
225
- }), 100);
226
- }
227
- };
228
-
229
- AbstractChosen.prototype.label_click_handler = function(evt) {
230
- if (this.is_multiple) {
231
- return this.container_mousedown( evt );
232
- } else {
233
- return this.activate_field();
234
- }
235
- };
236
-
237
- AbstractChosen.prototype.results_option_build = function(options) {
238
- var content, data, data_content, shown_results, _i, _len, _ref;
239
- content = '';
240
- shown_results = 0;
241
- _ref = this.results_data;
242
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
243
- data = _ref[_i];
244
- data_content = '';
245
- if (data.group) {
246
- data_content = this.result_add_group( data );
247
- } else {
248
- data_content = this.result_add_option( data );
249
- }
250
- if (data_content !== '') {
251
- shown_results++;
252
- content += data_content;
253
- }
254
- if (options != null ? options.first : void 0) {
255
- if (data.selected && this.is_multiple) {
256
- this.choice_build( data );
257
- } else if (data.selected && ! this.is_multiple) {
258
- this.single_set_selected_text( this.choice_label( data ) );
259
- }
260
- }
261
- if (shown_results >= this.max_shown_results) {
262
- break;
263
- }
264
- }
265
- return content;
266
- };
267
-
268
- AbstractChosen.prototype.result_add_option = function(option) {
269
- var classes, option_el;
270
- if ( ! option.search_match) {
271
- return '';
272
- }
273
- if ( ! this.include_option_in_results( option )) {
274
- return '';
275
- }
276
- classes = [];
277
- if ( ! option.disabled && ! (option.selected && this.is_multiple)) {
278
- classes.push( "active-result" );
279
- }
280
- if (option.disabled && ! (option.selected && this.is_multiple)) {
281
- classes.push( "disabled-result" );
282
- }
283
- if (option.selected) {
284
- classes.push( "result-selected" );
285
- }
286
- if (option.group_array_index != null) {
287
- classes.push( "group-option" );
288
- }
289
- if (option.classes !== "") {
290
- classes.push( option.classes );
291
- }
292
- option_el = document.createElement( "li" );
293
- option_el.className = classes.join( " " );
294
- option_el.style.cssText = option.style;
295
- option_el.setAttribute( "data-option-array-index", option.array_index );
296
- option_el.innerHTML = option.search_text;
297
- if (option.title) {
298
- option_el.title = option.title;
299
- }
300
- return this.outerHTML( option_el );
301
- };
302
-
303
- AbstractChosen.prototype.result_add_group = function(group) {
304
- var classes, group_el;
305
- if ( ! (group.search_match || group.group_match)) {
306
- return '';
307
- }
308
- if ( ! (group.active_options > 0)) {
309
- return '';
310
- }
311
- classes = [];
312
- classes.push( "group-result" );
313
- if (group.classes) {
314
- classes.push( group.classes );
315
- }
316
- group_el = document.createElement( "li" );
317
- group_el.className = classes.join( " " );
318
- group_el.innerHTML = group.search_text;
319
- if (group.title) {
320
- group_el.title = group.title;
321
- }
322
- return this.outerHTML( group_el );
323
- };
324
-
325
- AbstractChosen.prototype.results_update_field = function() {
326
- this.set_default_text();
327
- if ( ! this.is_multiple) {
328
- this.results_reset_cleanup();
329
- }
330
- this.result_clear_highlight();
331
- this.results_build();
332
- if (this.results_showing) {
333
- return this.winnow_results();
334
- }
335
- };
336
-
337
- AbstractChosen.prototype.reset_single_select_options = function() {
338
- var result, _i, _len, _ref, _results;
339
- _ref = this.results_data;
340
- _results = [];
341
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
342
- result = _ref[_i];
343
- if (result.selected) {
344
- _results.push( result.selected = false );
345
- } else {
346
- _results.push( void 0 );
347
- }
348
- }
349
- return _results;
350
- };
351
-
352
- AbstractChosen.prototype.results_toggle = function() {
353
- if (this.results_showing) {
354
- return this.results_hide();
355
- } else {
356
- return this.results_show();
357
- }
358
- };
359
-
360
- AbstractChosen.prototype.results_search = function(evt) {
361
- if (this.results_showing) {
362
- return this.winnow_results();
363
- } else {
364
- return this.results_show();
365
- }
366
- };
367
-
368
- AbstractChosen.prototype.winnow_results = function() {
369
- var escapedSearchText, highlightRegex, option, regex, results, results_group, searchText, startpos, text, _i, _len, _ref;
370
- this.no_results_clear();
371
- results = 0;
372
- searchText = this.get_search_text();
373
- escapedSearchText = searchText.replace( /[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&" );
374
- regex = this.get_search_regex( escapedSearchText );
375
- highlightRegex = this.get_highlight_regex( escapedSearchText );
376
- _ref = this.results_data;
377
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
378
- option = _ref[_i];
379
- option.search_match = false;
380
- results_group = null;
381
- if (this.include_option_in_results( option )) {
382
- if (option.group) {
383
- option.group_match = false;
384
- option.active_options = 0;
385
- }
386
- if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
387
- results_group = this.results_data[option.group_array_index];
388
- if (results_group.active_options === 0 && results_group.search_match) {
389
- results += 1;
390
- }
391
- results_group.active_options += 1;
392
- }
393
- option.search_text = option.group ? option.label : option.html;
394
- if ( ! (option.group && ! this.group_search)) {
395
- option.search_match = this.search_string_match( option.search_text, regex );
396
- if (option.search_match && ! option.group) {
397
- results += 1;
398
- }
399
- if (option.search_match) {
400
- if (searchText.length) {
401
- startpos = option.search_text.search( highlightRegex );
402
- text = option.search_text.substr( 0, startpos + searchText.length ) + '</em>' + option.search_text.substr( startpos + searchText.length );
403
- option.search_text = text.substr( 0, startpos ) + '<em>' + text.substr( startpos );
404
- }
405
- if (results_group != null) {
406
- results_group.group_match = true;
407
- }
408
- } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
409
- option.search_match = true;
410
- }
411
- }
412
- }
413
- }// End for().
414
- this.result_clear_highlight();
415
- if (results < 1 && searchText.length) {
416
- this.update_results_content( "" );
417
- return this.no_results( searchText );
418
- } else {
419
- this.update_results_content( this.results_option_build() );
420
- return this.winnow_results_set_highlight();
421
- }
422
- };
423
-
424
- AbstractChosen.prototype.get_search_regex = function(escaped_search_string) {
425
- var regex_anchor, regex_flag;
426
- regex_anchor = this.search_contains ? "" : "^";
427
- regex_flag = this.case_sensitive_search ? "" : "i";
428
- return new RegExp( regex_anchor + escaped_search_string, regex_flag );
429
- };
430
-
431
- AbstractChosen.prototype.get_highlight_regex = function(escaped_search_string) {
432
- var regex_anchor, regex_flag;
433
- regex_anchor = this.search_contains ? "" : "\\b";
434
- regex_flag = this.case_sensitive_search ? "" : "i";
435
- return new RegExp( regex_anchor + escaped_search_string, regex_flag );
436
- };
437
-
438
- AbstractChosen.prototype.search_string_match = function(search_string, regex) {
439
- var part, parts, _i, _len;
440
- if (regex.test( search_string )) {
441
- return true;
442
- } else if (this.enable_split_word_search && (search_string.indexOf( " " ) >= 0 || search_string.indexOf( "[" ) === 0)) {
443
- parts = search_string.replace( /\[|\]/g, "" ).split( " " );
444
- if (parts.length) {
445
- for (_i = 0, _len = parts.length; _i < _len; _i++) {
446
- part = parts[_i];
447
- if (regex.test( part )) {
448
- return true;
449
- }
450
- }
451
- }
452
- }
453
- };
454
-
455
- AbstractChosen.prototype.choices_count = function() {
456
- var option, _i, _len, _ref;
457
- if (this.selected_option_count != null) {
458
- return this.selected_option_count;
459
- }
460
- this.selected_option_count = 0;
461
- _ref = this.form_field.options;
462
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
463
- option = _ref[_i];
464
- if (option.selected) {
465
- this.selected_option_count += 1;
466
- }
467
- }
468
- return this.selected_option_count;
469
- };
470
-
471
- AbstractChosen.prototype.choices_click = function(evt) {
472
- evt.preventDefault();
473
- this.activate_field();
474
- if ( ! (this.results_showing || this.is_disabled)) {
475
- return this.results_show();
476
- }
477
- };
478
-
479
- AbstractChosen.prototype.keydown_checker = function(evt) {
480
- var stroke, _ref;
481
- stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
482
- this.search_field_scale();
483
- if (stroke !== 8 && this.pending_backstroke) {
484
- this.clear_backstroke();
485
- }
486
- switch (stroke) {
487
- case 8:
488
- this.backstroke_length = this.get_search_field_value().length;
489
- break;
490
- case 9:
491
- if (this.results_showing && ! this.is_multiple) {
492
- this.result_select( evt );
493
- }
494
- this.mouse_on_container = false;
495
- break;
496
- case 13:
497
- if (this.results_showing) {
498
- evt.preventDefault();
499
- }
500
- break;
501
- case 27:
502
- if (this.results_showing) {
503
- evt.preventDefault();
504
- }
505
- break;
506
- case 32:
507
- if (this.disable_search) {
508
- evt.preventDefault();
509
- }
510
- break;
511
- case 38:
512
- evt.preventDefault();
513
- this.keyup_arrow();
514
- break;
515
- case 40:
516
- evt.preventDefault();
517
- this.keydown_arrow();
518
- break;
519
- }
520
- };
521
-
522
- AbstractChosen.prototype.keyup_checker = function(evt) {
523
- var stroke, _ref;
524
- stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
525
- this.search_field_scale();
526
- switch (stroke) {
527
- case 8:
528
- if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
529
- this.keydown_backstroke();
530
- } else if ( ! this.pending_backstroke) {
531
- this.result_clear_highlight();
532
- this.results_search();
533
- }
534
- break;
535
- case 13:
536
- evt.preventDefault();
537
- if (this.results_showing) {
538
- this.result_select( evt );
539
- }
540
- break;
541
- case 27:
542
- if (this.results_showing) {
543
- this.results_hide();
544
- }
545
- break;
546
- case 9:
547
- case 16:
548
- case 17:
549
- case 18:
550
- case 38:
551
- case 40:
552
- case 91:
553
- break;
554
- default:
555
- this.results_search();
556
- break;
557
- }
558
- };
559
-
560
- AbstractChosen.prototype.clipboard_event_checker = function(evt) {
561
- var _this = this;
562
- if (this.is_disabled) {
563
- return;
564
- }
565
- return setTimeout((function() {
566
- return _this.results_search();
567
- }), 50);
568
- };
569
-
570
- AbstractChosen.prototype.container_width = function() {
571
- if (this.options.width != null) {
572
- return this.options.width;
573
- } else {
574
- return "" + this.form_field.offsetWidth + "px";
575
- }
576
- };
577
-
578
- AbstractChosen.prototype.include_option_in_results = function(option) {
579
- if (this.is_multiple && ( ! this.display_selected_options && option.selected)) {
580
- return false;
581
- }
582
- if ( ! this.display_disabled_options && option.disabled) {
583
- return false;
584
- }
585
- if (option.empty) {
586
- return false;
587
- }
588
- return true;
589
- };
590
-
591
- AbstractChosen.prototype.search_results_touchstart = function(evt) {
592
- this.touch_started = true;
593
- return this.search_results_mouseover( evt );
594
- };
595
-
596
- AbstractChosen.prototype.search_results_touchmove = function(evt) {
597
- this.touch_started = false;
598
- return this.search_results_mouseout( evt );
599
- };
600
-
601
- AbstractChosen.prototype.search_results_touchend = function(evt) {
602
- if (this.touch_started) {
603
- return this.search_results_mouseup( evt );
604
- }
605
- };
606
-
607
- AbstractChosen.prototype.outerHTML = function(element) {
608
- var tmp;
609
- if (element.outerHTML) {
610
- return element.outerHTML;
611
- }
612
- tmp = document.createElement( "div" );
613
- tmp.appendChild( element );
614
- return tmp.innerHTML;
615
- };
616
-
617
- AbstractChosen.prototype.get_single_html = function() {
618
- return "<a class=\"chosen-single chosen-default\">\n <span>" + this.default_text + "</span>\n <div><b></b></div>\n</a>\n<div class=\"chosen-drop\">\n <div class=\"chosen-search\">\n <input class=\"chosen-search-input\" type=\"text\" autocomplete=\"off\" />\n </div>\n <ul class=\"chosen-results\"></ul>\n</div>";
619
- };
620
-
621
- AbstractChosen.prototype.get_multi_html = function() {
622
- return "<ul class=\"chosen-choices\">\n <li class=\"search-field\">\n <input class=\"chosen-search-input\" type=\"text\" autocomplete=\"off\" value=\"" + this.default_text + "\" />\n </li>\n</ul>\n<div class=\"chosen-drop\">\n <ul class=\"chosen-results\"></ul>\n</div>";
623
- };
624
-
625
- AbstractChosen.prototype.get_no_results_html = function(terms) {
626
- return "<li class=\"no-results\">\n " + this.results_none_found + " <span>" + terms + "</span>\n</li>";
627
- };
628
-
629
- AbstractChosen.browser_is_supported = function() {
630
- if ("Microsoft Internet Explorer" === window.navigator.appName) {
631
- return document.documentMode >= 8;
632
- }
633
- if (/iP(od|hone)/i.test( window.navigator.userAgent ) || /IEMobile/i.test( window.navigator.userAgent ) || /Windows Phone/i.test( window.navigator.userAgent ) || /BlackBerry/i.test( window.navigator.userAgent ) || /BB10/i.test( window.navigator.userAgent ) || /Android.*Mobile/i.test( window.navigator.userAgent )) {
634
- return false;
635
- }
636
- return true;
637
- };
638
-
639
- AbstractChosen.default_multiple_text = "Select Some Options";
640
-
641
- AbstractChosen.default_single_text = "Select an Option";
642
-
643
- AbstractChosen.default_no_result_text = "No results match";
644
-
645
- return AbstractChosen;
646
-
647
- })();
648
-
649
- $ = jQuery;
650
-
651
- $.fn.extend({
652
- chosen: function(options) {
653
- if ( ! AbstractChosen.browser_is_supported()) {
654
- return this;
655
- }
656
- return this.each(function(input_field) {
657
- var $this, chosen;
658
- $this = $( this );
659
- chosen = $this.data( 'chosen' );
660
- if (options === 'destroy') {
661
- if (chosen instanceof Chosen) {
662
- chosen.destroy();
663
- }
664
- return;
665
- }
666
- if ( ! (chosen instanceof Chosen)) {
667
- $this.data( 'chosen', new Chosen( this, options ) );
668
- }
669
- });
670
- }
671
- });
672
-
673
- Chosen = (function(_super) {
674
- __extends( Chosen, _super );
675
-
676
- function Chosen() {
677
- _ref = Chosen.__super__.constructor.apply( this, arguments );
678
- return _ref;
679
- }
680
-
681
- Chosen.prototype.setup = function() {
682
- this.form_field_jq = $( this.form_field );
683
- return this.current_selectedIndex = this.form_field.selectedIndex;
684
- };
685
-
686
- Chosen.prototype.set_up_html = function() {
687
- var container_classes, container_props;
688
- container_classes = ["chosen-container"];
689
- container_classes.push( "chosen-container-" + (this.is_multiple ? "multi" : "single") );
690
- if (this.inherit_select_classes && this.form_field.className) {
691
- container_classes.push( this.form_field.className );
692
- }
693
- if (this.is_rtl) {
694
- container_classes.push( "chosen-rtl" );
695
- }
696
- container_props = {
697
- 'class': container_classes.join( ' ' ),
698
- 'title': this.form_field.title
699
- };
700
- if (this.form_field.id.length) {
701
- container_props.id = this.form_field.id.replace( /[^\w]/g, '_' ) + "_chosen";
702
- }
703
- this.container = $( "<div />", container_props );
704
- this.container.width( this.container_width() );
705
- if (this.is_multiple) {
706
- this.container.html( this.get_multi_html() );
707
- } else {
708
- this.container.html( this.get_single_html() );
709
- }
710
- this.form_field_jq.hide().after( this.container );
711
- this.dropdown = this.container.find( 'div.chosen-drop' ).first();
712
- this.search_field = this.container.find( 'input' ).first();
713
- this.search_results = this.container.find( 'ul.chosen-results' ).first();
714
- this.search_field_scale();
715
- this.search_no_results = this.container.find( 'li.no-results' ).first();
716
- if (this.is_multiple) {
717
- this.search_choices = this.container.find( 'ul.chosen-choices' ).first();
718
- this.search_container = this.container.find( 'li.search-field' ).first();
719
- } else {
720
- this.search_container = this.container.find( 'div.chosen-search' ).first();
721
- this.selected_item = this.container.find( '.chosen-single' ).first();
722
- }
723
- this.results_build();
724
- this.set_tab_index();
725
- return this.set_label_behavior();
726
- };
727
-
728
- Chosen.prototype.on_ready = function() {
729
- return this.form_field_jq.trigger("chosen:ready", {
730
- chosen: this
731
- });
732
- };
733
-
734
- Chosen.prototype.register_observers = function() {
735
- var _this = this;
736
- this.container.bind('touchstart.chosen', function(evt) {
737
- _this.container_mousedown( evt );
738
- });
739
- this.container.bind('touchend.chosen', function(evt) {
740
- _this.container_mouseup( evt );
741
- });
742
- this.container.bind('mousedown.chosen', function(evt) {
743
- _this.container_mousedown( evt );
744
- });
745
- this.container.bind('mouseup.chosen', function(evt) {
746
- _this.container_mouseup( evt );
747
- });
748
- this.container.bind('mouseenter.chosen', function(evt) {
749
- _this.mouse_enter( evt );
750
- });
751
- this.container.bind('mouseleave.chosen', function(evt) {
752
- _this.mouse_leave( evt );
753
- });
754
- this.search_results.bind('mouseup.chosen', function(evt) {
755
- _this.search_results_mouseup( evt );
756
- });
757
- this.search_results.bind('mouseover.chosen', function(evt) {
758
- _this.search_results_mouseover( evt );
759
- });
760
- this.search_results.bind('mouseout.chosen', function(evt) {
761
- _this.search_results_mouseout( evt );
762
- });
763
- this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
764
- _this.search_results_mousewheel( evt );
765
- });
766
- this.search_results.bind('touchstart.chosen', function(evt) {
767
- _this.search_results_touchstart( evt );
768
- });
769
- this.search_results.bind('touchmove.chosen', function(evt) {
770
- _this.search_results_touchmove( evt );
771
- });
772
- this.search_results.bind('touchend.chosen', function(evt) {
773
- _this.search_results_touchend( evt );
774
- });
775
- this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
776
- _this.results_update_field( evt );
777
- });
778
- this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
779
- _this.activate_field( evt );
780
- });
781
- this.form_field_jq.bind("chosen:open.chosen", function(evt) {
782
- _this.container_mousedown( evt );
783
- });
784
- this.form_field_jq.bind("chosen:close.chosen", function(evt) {
785
- _this.close_field( evt );
786
- });
787
- this.search_field.bind('blur.chosen', function(evt) {
788
- _this.input_blur( evt );
789
- });
790
- this.search_field.bind('keyup.chosen', function(evt) {
791
- _this.keyup_checker( evt );
792
- });
793
- this.search_field.bind('keydown.chosen', function(evt) {
794
- _this.keydown_checker( evt );
795
- });
796
- this.search_field.bind('focus.chosen', function(evt) {
797
- _this.input_focus( evt );
798
- });
799
- this.search_field.bind('cut.chosen', function(evt) {
800
- _this.clipboard_event_checker( evt );
801
- });
802
- this.search_field.bind('paste.chosen', function(evt) {
803
- _this.clipboard_event_checker( evt );
804
- });
805
- if (this.is_multiple) {
806
- return this.search_choices.bind('click.chosen', function(evt) {
807
- _this.choices_click( evt );
808
- });
809
- } else {
810
- return this.container.bind('click.chosen', function(evt) {
811
- evt.preventDefault();
812
- });
813
- }
814
- };
815
-
816
- Chosen.prototype.destroy = function() {
817
- $( this.container[0].ownerDocument ).unbind( 'click.chosen', this.click_test_action );
818
- if (this.form_field_label.length > 0) {
819
- this.form_field_label.unbind( 'click.chosen' );
820
- }
821
- if (this.search_field[0].tabIndex) {
822
- this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
823
- }
824
- this.container.remove();
825
- this.form_field_jq.removeData( 'chosen' );
826
- return this.form_field_jq.show();
827
- };
828
-
829
- Chosen.prototype.search_field_disabled = function() {
830
- this.is_disabled = this.form_field.disabled || this.form_field_jq.parents( 'fieldset' ).is( ':disabled' );
831
- this.container.toggleClass( 'chosen-disabled', this.is_disabled );
832
- this.search_field[0].disabled = this.is_disabled;
833
- if ( ! this.is_multiple) {
834
- this.selected_item.unbind( 'focus.chosen', this.activate_field );
835
- }
836
- if (this.is_disabled) {
837
- return this.close_field();
838
- } else if ( ! this.is_multiple) {
839
- return this.selected_item.bind( 'focus.chosen', this.activate_field );
840
- }
841
- };
842
-
843
- Chosen.prototype.container_mousedown = function(evt) {
844
- var _ref1;
845
- if (this.is_disabled) {
846
- return;
847
- }
848
- if (evt && ((_ref1 = evt.type) === 'mousedown' || _ref1 === 'touchstart') && ! this.results_showing) {
849
- evt.preventDefault();
850
- }
851
- if ( ! ((evt != null) && ($( evt.target )).hasClass( "search-choice-close" ))) {
852
- if ( ! this.active_field) {
853
- if (this.is_multiple) {
854
- this.search_field.val( "" );
855
- }
856
- $( this.container[0].ownerDocument ).bind( 'click.chosen', this.click_test_action );
857
- this.results_show();
858
- } else if ( ! this.is_multiple && evt && (($( evt.target )[0] === this.selected_item[0]) || $( evt.target ).parents( "a.chosen-single" ).length)) {
859
- evt.preventDefault();
860
- this.results_toggle();
861
- }
862
- return this.activate_field();
863
- }
864
- };
865
-
866
- Chosen.prototype.container_mouseup = function(evt) {
867
- if (evt.target.nodeName === "ABBR" && ! this.is_disabled) {
868
- return this.results_reset( evt );
869
- }
870
- };
871
-
872
- Chosen.prototype.search_results_mousewheel = function(evt) {
873
- var delta;
874
- if (evt.originalEvent) {
875
- delta = evt.originalEvent.deltaY || -evt.originalEvent.wheelDelta || evt.originalEvent.detail;
876
- }
877
- if (delta != null) {
878
- evt.preventDefault();
879
- if (evt.type === 'DOMMouseScroll') {
880
- delta = delta * 40;
881
- }
882
- return this.search_results.scrollTop( delta + this.search_results.scrollTop() );
883
- }
884
- };
885
-
886
- Chosen.prototype.blur_test = function(evt) {
887
- if ( ! this.active_field && this.container.hasClass( "chosen-container-active" )) {
888
- return this.close_field();
889
- }
890
- };
891
-
892
- Chosen.prototype.close_field = function() {
893
- $( this.container[0].ownerDocument ).unbind( "click.chosen", this.click_test_action );
894
- this.active_field = false;
895
- this.results_hide();
896
- this.container.removeClass( "chosen-container-active" );
897
- this.clear_backstroke();
898
- this.show_search_field_default();
899
- this.search_field_scale();
900
- return this.search_field.blur();
901
- };
902
-
903
- Chosen.prototype.activate_field = function() {
904
- if (this.is_disabled) {
905
- return;
906
- }
907
- this.container.addClass( "chosen-container-active" );
908
- this.active_field = true;
909
- this.search_field.val( this.search_field.val() );
910
- return this.search_field.focus();
911
- };
912
-
913
- Chosen.prototype.test_active_click = function(evt) {
914
- var active_container;
915
- active_container = $( evt.target ).closest( '.chosen-container' );
916
- if (active_container.length && this.container[0] === active_container[0]) {
917
- return this.active_field = true;
918
- } else {
919
- return this.close_field();
920
- }
921
- };
922
-
923
- Chosen.prototype.results_build = function() {
924
- this.parsing = true;
925
- this.selected_option_count = null;
926
- this.results_data = SelectParser.select_to_array( this.form_field );
927
- if (this.is_multiple) {
928
- this.search_choices.find( "li.search-choice" ).remove();
929
- } else if ( ! this.is_multiple) {
930
- this.single_set_selected_text();
931
- if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
932
- this.search_field[0].readOnly = true;
933
- this.container.addClass( "chosen-container-single-nosearch" );
934
- } else {
935
- this.search_field[0].readOnly = false;
936
- this.container.removeClass( "chosen-container-single-nosearch" );
937
- }
938
- }
939
- this.update_results_content(this.results_option_build({
940
- first: true
941
- }));
942
- this.search_field_disabled();
943
- this.show_search_field_default();
944
- this.search_field_scale();
945
- return this.parsing = false;
946
- };
947
-
948
- Chosen.prototype.result_do_highlight = function(el) {
949
- var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
950
- if (el.length) {
951
- this.result_clear_highlight();
952
- this.result_highlight = el;
953
- this.result_highlight.addClass( "highlighted" );
954
- maxHeight = parseInt( this.search_results.css( "maxHeight" ), 10 );
955
- visible_top = this.search_results.scrollTop();
956
- visible_bottom = maxHeight + visible_top;
957
- high_top = this.result_highlight.position().top + this.search_results.scrollTop();
958
- high_bottom = high_top + this.result_highlight.outerHeight();
959
- if (high_bottom >= visible_bottom) {
960
- return this.search_results.scrollTop( (high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0 );
961
- } else if (high_top < visible_top) {
962
- return this.search_results.scrollTop( high_top );
963
- }
964
- }
965
- };
966
-
967
- Chosen.prototype.result_clear_highlight = function() {
968
- if (this.result_highlight) {
969
- this.result_highlight.removeClass( "highlighted" );
970
- }
971
- return this.result_highlight = null;
972
- };
973
-
974
- Chosen.prototype.results_show = function() {
975
- if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
976
- this.form_field_jq.trigger("chosen:maxselected", {
977
- chosen: this
978
- });
979
- return false;
980
- }
981
- this.container.addClass( "chosen-with-drop" );
982
- this.results_showing = true;
983
- this.search_field.focus();
984
- this.search_field.val( this.get_search_field_value() );
985
- this.winnow_results();
986
- return this.form_field_jq.trigger("chosen:showing_dropdown", {
987
- chosen: this
988
- });
989
- };
990
-
991
- Chosen.prototype.update_results_content = function(content) {
992
- return this.search_results.html( content );
993
- };
994
-
995
- Chosen.prototype.results_hide = function() {
996
- if (this.results_showing) {
997
- this.result_clear_highlight();
998
- this.container.removeClass( "chosen-with-drop" );
999
- this.form_field_jq.trigger("chosen:hiding_dropdown", {
1000
- chosen: this
1001
- });
1002
- }
1003
- return this.results_showing = false;
1004
- };
1005
-
1006
- Chosen.prototype.set_tab_index = function(el) {
1007
- var ti;
1008
- if (this.form_field.tabIndex) {
1009
- ti = this.form_field.tabIndex;
1010
- this.form_field.tabIndex = -1;
1011
- return this.search_field[0].tabIndex = ti;
1012
- }
1013
- };
1014
-
1015
- Chosen.prototype.set_label_behavior = function() {
1016
- this.form_field_label = this.form_field_jq.parents( "label" );
1017
- if ( ! this.form_field_label.length && this.form_field.id.length) {
1018
- this.form_field_label = $( "label[for='" + this.form_field.id + "']" );
1019
- }
1020
- if (this.form_field_label.length > 0) {
1021
- return this.form_field_label.bind( 'click.chosen', this.label_click_handler );
1022
- }
1023
- };
1024
-
1025
- Chosen.prototype.show_search_field_default = function() {
1026
- if (this.is_multiple && this.choices_count() < 1 && ! this.active_field) {
1027
- this.search_field.val( this.default_text );
1028
- return this.search_field.addClass( "default" );
1029
- } else {
1030
- this.search_field.val( "" );
1031
- return this.search_field.removeClass( "default" );
1032
- }
1033
- };
1034
-
1035
- Chosen.prototype.search_results_mouseup = function(evt) {
1036
- var target;
1037
- target = $( evt.target ).hasClass( "active-result" ) ? $( evt.target ) : $( evt.target ).parents( ".active-result" ).first();
1038
- if (target.length) {
1039
- this.result_highlight = target;
1040
- this.result_select( evt );
1041
- return this.search_field.focus();
1042
- }
1043
- };
1044
-
1045
- Chosen.prototype.search_results_mouseover = function(evt) {
1046
- var target;
1047
- target = $( evt.target ).hasClass( "active-result" ) ? $( evt.target ) : $( evt.target ).parents( ".active-result" ).first();
1048
- if (target) {
1049
- return this.result_do_highlight( target );
1050
- }
1051
- };
1052
-
1053
- Chosen.prototype.search_results_mouseout = function(evt) {
1054
- if ($( evt.target ).hasClass( "active-result" || $( evt.target ).parents( '.active-result' ).first() )) {
1055
- return this.result_clear_highlight();
1056
- }
1057
- };
1058
-
1059
- Chosen.prototype.choice_build = function(item) {
1060
- var choice, close_link,
1061
- _this = this;
1062
- choice = $('<li />', {
1063
- "class": "search-choice"
1064
- }).html( "<span>" + (this.choice_label( item )) + "</span>" );
1065
- if (item.disabled) {
1066
- choice.addClass( 'search-choice-disabled' );
1067
- } else {
1068
- close_link = $('<a />', {
1069
- "class": 'search-choice-close',
1070
- 'data-option-array-index': item.array_index
1071
- });
1072
- close_link.bind('click.chosen', function(evt) {
1073
- return _this.choice_destroy_link_click( evt );
1074
- });
1075
- choice.append( close_link );
1076
- }
1077
- return this.search_container.before( choice );
1078
- };
1079
-
1080
- Chosen.prototype.choice_destroy_link_click = function(evt) {
1081
- evt.preventDefault();
1082
- evt.stopPropagation();
1083
- if ( ! this.is_disabled) {
1084
- return this.choice_destroy( $( evt.target ) );
1085
- }
1086
- };
1087
-
1088
- Chosen.prototype.choice_destroy = function(link) {
1089
- if (this.result_deselect( link[0].getAttribute( "data-option-array-index" ) )) {
1090
- if (this.active_field) {
1091
- this.search_field.focus();
1092
- } else {
1093
- this.show_search_field_default();
1094
- }
1095
- if (this.is_multiple && this.choices_count() > 0 && this.get_search_field_value().length < 1) {
1096
- this.results_hide();
1097
- }
1098
- link.parents( 'li' ).first().remove();
1099
- return this.search_field_scale();
1100
- }
1101
- };
1102
-
1103
- Chosen.prototype.results_reset = function() {
1104
- this.reset_single_select_options();
1105
- this.form_field.options[0].selected = true;
1106
- this.single_set_selected_text();
1107
- this.show_search_field_default();
1108
- this.results_reset_cleanup();
1109
- this.trigger_form_field_change();
1110
- if (this.active_field) {
1111
- return this.results_hide();
1112
- }
1113
- };
1114
-
1115
- Chosen.prototype.results_reset_cleanup = function() {
1116
- this.current_selectedIndex = this.form_field.selectedIndex;
1117
- return this.selected_item.find( "abbr" ).remove();
1118
- };
1119
-
1120
- Chosen.prototype.result_select = function(evt) {
1121
- var high, item;
1122
- if (this.result_highlight) {
1123
- high = this.result_highlight;
1124
- this.result_clear_highlight();
1125
- if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
1126
- this.form_field_jq.trigger("chosen:maxselected", {
1127
- chosen: this
1128
- });
1129
- return false;
1130
- }
1131
- if (this.is_multiple) {
1132
- high.removeClass( "active-result" );
1133
- } else {
1134
- this.reset_single_select_options();
1135
- }
1136
- high.addClass( "result-selected" );
1137
- item = this.results_data[high[0].getAttribute( "data-option-array-index" )];
1138
- item.selected = true;
1139
- this.form_field.options[item.options_index].selected = true;
1140
- this.selected_option_count = null;
1141
- if (this.is_multiple) {
1142
- this.choice_build( item );
1143
- } else {
1144
- this.single_set_selected_text( this.choice_label( item ) );
1145
- }
1146
- if ( ! (this.is_multiple && ( ! this.hide_results_on_select || (evt.metaKey || evt.ctrlKey)))) {
1147
- this.results_hide();
1148
- this.show_search_field_default();
1149
- }
1150
- if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
1151
- this.trigger_form_field_change({
1152
- selected: this.form_field.options[item.options_index].value
1153
- });
1154
- }
1155
- this.current_selectedIndex = this.form_field.selectedIndex;
1156
- evt.preventDefault();
1157
- return this.search_field_scale();
1158
- }// End if().
1159
- };
1160
-
1161
- Chosen.prototype.single_set_selected_text = function(text) {
1162
- if (text == null) {
1163
- text = this.default_text;
1164
- }
1165
- if (text === this.default_text) {
1166
- this.selected_item.addClass( "chosen-default" );
1167
- } else {
1168
- this.single_deselect_control_build();
1169
- this.selected_item.removeClass( "chosen-default" );
1170
- }
1171
- return this.selected_item.find( "span" ).html( text );
1172
- };
1173
-
1174
- Chosen.prototype.result_deselect = function(pos) {
1175
- var result_data;
1176
- result_data = this.results_data[pos];
1177
- if ( ! this.form_field.options[result_data.options_index].disabled) {
1178
- result_data.selected = false;
1179
- this.form_field.options[result_data.options_index].selected = false;
1180
- this.selected_option_count = null;
1181
- this.result_clear_highlight();
1182
- if (this.results_showing) {
1183
- this.winnow_results();
1184
- }
1185
- this.trigger_form_field_change({
1186
- deselected: this.form_field.options[result_data.options_index].value
1187
- });
1188
- this.search_field_scale();
1189
- return true;
1190
- } else {
1191
- return false;
1192
- }
1193
- };
1194
-
1195
- Chosen.prototype.single_deselect_control_build = function() {
1196
- if ( ! this.allow_single_deselect) {
1197
- return;
1198
- }
1199
- if ( ! this.selected_item.find( "abbr" ).length) {
1200
- this.selected_item.find( "span" ).first().after( "<abbr class=\"search-choice-close\"></abbr>" );
1201
- }
1202
- return this.selected_item.addClass( "chosen-single-with-deselect" );
1203
- };
1204
-
1205
- Chosen.prototype.get_search_field_value = function() {
1206
- return this.search_field.val();
1207
- };
1208
-
1209
- Chosen.prototype.get_search_text = function() {
1210
- return this.escape_html( $.trim( this.get_search_field_value() ) );
1211
- };
1212
-
1213
- Chosen.prototype.escape_html = function(text) {
1214
- return $( '<div/>' ).text( text ).html();
1215
- };
1216
-
1217
- Chosen.prototype.winnow_results_set_highlight = function() {
1218
- var do_high, selected_results;
1219
- selected_results = ! this.is_multiple ? this.search_results.find( ".result-selected.active-result" ) : [];
1220
- do_high = selected_results.length ? selected_results.first() : this.search_results.find( ".active-result" ).first();
1221
- if (do_high != null) {
1222
- return this.result_do_highlight( do_high );
1223
- }
1224
- };
1225
-
1226
- Chosen.prototype.no_results = function(terms) {
1227
- var no_results_html;
1228
- no_results_html = this.get_no_results_html( terms );
1229
- this.search_results.append( no_results_html );
1230
- return this.form_field_jq.trigger("chosen:no_results", {
1231
- chosen: this
1232
- });
1233
- };
1234
-
1235
- Chosen.prototype.no_results_clear = function() {
1236
- return this.search_results.find( ".no-results" ).remove();
1237
- };
1238
-
1239
- Chosen.prototype.keydown_arrow = function() {
1240
- var next_sib;
1241
- if (this.results_showing && this.result_highlight) {
1242
- next_sib = this.result_highlight.nextAll( "li.active-result" ).first();
1243
- if (next_sib) {
1244
- return this.result_do_highlight( next_sib );
1245
- }
1246
- } else {
1247
- return this.results_show();
1248
- }
1249
- };
1250
-
1251
- Chosen.prototype.keyup_arrow = function() {
1252
- var prev_sibs;
1253
- if ( ! this.results_showing && ! this.is_multiple) {
1254
- return this.results_show();
1255
- } else if (this.result_highlight) {
1256
- prev_sibs = this.result_highlight.prevAll( "li.active-result" );
1257
- if (prev_sibs.length) {
1258
- return this.result_do_highlight( prev_sibs.first() );
1259
- } else {
1260
- if (this.choices_count() > 0) {
1261
- this.results_hide();
1262
- }
1263
- return this.result_clear_highlight();
1264
- }
1265
- }
1266
- };
1267
-
1268
- Chosen.prototype.keydown_backstroke = function() {
1269
- var next_available_destroy;
1270
- if (this.pending_backstroke) {
1271
- this.choice_destroy( this.pending_backstroke.find( "a" ).first() );
1272
- return this.clear_backstroke();
1273
- } else {
1274
- next_available_destroy = this.search_container.siblings( "li.search-choice" ).last();
1275
- if (next_available_destroy.length && ! next_available_destroy.hasClass( "search-choice-disabled" )) {
1276
- this.pending_backstroke = next_available_destroy;
1277
- if (this.single_backstroke_delete) {
1278
- return this.keydown_backstroke();
1279
- } else {
1280
- return this.pending_backstroke.addClass( "search-choice-focus" );
1281
- }
1282
- }
1283
- }
1284
- };
1285
-
1286
- Chosen.prototype.clear_backstroke = function() {
1287
- if (this.pending_backstroke) {
1288
- this.pending_backstroke.removeClass( 'search-choice-focus' );
1289
- }
1290
- this.pending_backstroke = null;
1291
- return this.pending_backstroke;
1292
- };
1293
-
1294
- Chosen.prototype.search_field_scale = function() {
1295
- var container_width, div, style, style_block, styles, width, _i, _len;
1296
- if ( ! this.is_multiple) {
1297
- return;
1298
- }
1299
- style_block = {
1300
- position: 'absolute',
1301
- left: '-1000px',
1302
- top: '-1000px',
1303
- display: 'none',
1304
- whiteSpace: 'pre'
1305
- };
1306
- styles = ['fontSize', 'fontStyle', 'fontWeight', 'fontFamily', 'lineHeight', 'textTransform', 'letterSpacing'];
1307
- for (_i = 0, _len = styles.length; _i < _len; _i++) {
1308
- style = styles[_i];
1309
- style_block[style] = this.search_field.css( style );
1310
- }
1311
- div = $( '<div />' ).css( style_block );
1312
- div.text( this.get_search_field_value() );
1313
- $( 'body' ).append( div );
1314
- width = div.width() + 25;
1315
- div.remove();
1316
- container_width = this.container.outerWidth();
1317
- width = Math.min( container_width - 10, width );
1318
- return this.search_field.width( width );
1319
- };
1320
-
1321
- Chosen.prototype.trigger_form_field_change = function(extra) {
1322
- this.form_field_jq.trigger( 'input', extra );
1323
- return this.form_field_jq.trigger( 'change', extra );
1324
- };
1325
-
1326
- return Chosen;
1327
-
1328
- })(AbstractChosen);
1329
-
1330
- }).call( this );
1331
- /* jshint ignore:end */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  * @since 1.2.0
6
  * @package feedzy-rss-feeds-pro
7
  */
8
+ /*!
9
+ Chosen, a Select Box Enhancer for jQuery and Prototype
10
+ by Patrick Filler for Harvest, http://getharvest.com
11
+
12
+ Version 1.8.7
13
+ Full source at https://github.com/harvesthq/chosen
14
+ Copyright (c) 2011-2018 Harvest http://getharvest.com
15
+
16
+ MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
17
+ This file is generated by `grunt build`, do not edit it by hand.
18
+ */
19
+ /*jshint -W018 */
20
  (function() {
21
+ var $, AbstractChosen, Chosen, SelectParser,
22
+ bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
23
+ extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
24
+ hasProp = {}.hasOwnProperty;
25
+
26
+ SelectParser = (function() {
27
+ function SelectParser() {
28
+ this.options_index = 0;
29
+ this.parsed = [];
30
+ }
31
+
32
+ SelectParser.prototype.add_node = function(child) {
33
+ if (child.nodeName.toUpperCase() === "OPTGROUP") {
34
+ return this.add_group(child);
35
+ } else {
36
+ return this.add_option(child);
37
+ }
38
+ };
39
+
40
+ SelectParser.prototype.add_group = function(group) {
41
+ var group_position, i, len, option, ref, results1;
42
+ group_position = this.parsed.length;
43
+ this.parsed.push({
44
+ array_index: group_position,
45
+ group: true,
46
+ label: group.label,
47
+ title: group.title ? group.title : void 0,
48
+ children: 0,
49
+ disabled: group.disabled,
50
+ classes: group.className
51
+ });
52
+ ref = group.childNodes;
53
+ results1 = [];
54
+ for (i = 0, len = ref.length; i < len; i++) {
55
+ option = ref[i];
56
+ results1.push(this.add_option(option, group_position, group.disabled));
57
+ }
58
+ return results1;
59
+ };
60
+
61
+ SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
62
+ if (option.nodeName.toUpperCase() === "OPTION") {
63
+ if (option.text !== "") {
64
+ if (group_position != null) {
65
+ this.parsed[group_position].children += 1;
66
+ }
67
+ this.parsed.push({
68
+ array_index: this.parsed.length,
69
+ options_index: this.options_index,
70
+ value: option.value,
71
+ text: option.text,
72
+ html: option.innerHTML,
73
+ title: option.title ? option.title : void 0,
74
+ selected: option.selected,
75
+ disabled: group_disabled === true ? group_disabled : option.disabled,
76
+ group_array_index: group_position,
77
+ group_label: group_position != null ? this.parsed[group_position].label : null,
78
+ classes: option.className,
79
+ style: option.style.cssText
80
+ });
81
+ } else {
82
+ this.parsed.push({
83
+ array_index: this.parsed.length,
84
+ options_index: this.options_index,
85
+ empty: true
86
+ });
87
+ }
88
+ return this.options_index += 1;
89
+ }
90
+ };
91
+
92
+ return SelectParser;
93
+
94
+ })();
95
+
96
+ SelectParser.select_to_array = function(select) {
97
+ var child, i, len, parser, ref;
98
+ parser = new SelectParser();
99
+ ref = select.childNodes;
100
+ for (i = 0, len = ref.length; i < len; i++) {
101
+ child = ref[i];
102
+ parser.add_node(child);
103
+ }
104
+ return parser.parsed;
105
+ };
106
+
107
+ AbstractChosen = (function() {
108
+ function AbstractChosen(form_field, options1) {
109
+ this.form_field = form_field;
110
+ this.options = options1 != null ? options1 : {};
111
+ this.label_click_handler = bind(this.label_click_handler, this);
112
+ if (!AbstractChosen.browser_is_supported()) {
113
+ return;
114
+ }
115
+ this.is_multiple = this.form_field.multiple;
116
+ this.set_default_text();
117
+ this.set_default_values();
118
+ this.setup();
119
+ this.set_up_html();
120
+ this.register_observers();
121
+ this.on_ready();
122
+ }
123
+
124
+ AbstractChosen.prototype.set_default_values = function() {
125
+ this.click_test_action = (function(_this) {
126
+ return function(evt) {
127
+ return _this.test_active_click(evt);
128
+ };
129
+ })(this);
130
+ this.activate_action = (function(_this) {
131
+ return function(evt) {
132
+ return _this.activate_field(evt);
133
+ };
134
+ })(this);
135
+ this.active_field = false;
136
+ this.mouse_on_container = false;
137
+ this.results_showing = false;
138
+ this.result_highlighted = null;
139
+ this.is_rtl = this.options.rtl || /\bchosen-rtl\b/.test(this.form_field.className);
140
+ this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
141
+ this.disable_search_threshold = this.options.disable_search_threshold || 0;
142
+ this.disable_search = this.options.disable_search || false;
143
+ this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
144
+ this.group_search = this.options.group_search != null ? this.options.group_search : true;
145
+ this.search_contains = this.options.search_contains || false;
146
+ this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
147
+ this.max_selected_options = this.options.max_selected_options || Infinity;
148
+ this.inherit_select_classes = this.options.inherit_select_classes || false;
149
+ this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
150
+ this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
151
+ this.include_group_label_in_selected = this.options.include_group_label_in_selected || false;
152
+ this.max_shown_results = this.options.max_shown_results || Number.POSITIVE_INFINITY;
153
+ this.case_sensitive_search = this.options.case_sensitive_search || false;
154
+ return this.hide_results_on_select = this.options.hide_results_on_select != null ? this.options.hide_results_on_select : true;
155
+ };
156
+
157
+ AbstractChosen.prototype.set_default_text = function() {
158
+ if (this.form_field.getAttribute("data-placeholder")) {
159
+ this.default_text = this.form_field.getAttribute("data-placeholder");
160
+ } else if (this.is_multiple) {
161
+ this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
162
+ } else {
163
+ this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
164
+ }
165
+ this.default_text = this.escape_html(this.default_text);
166
+ return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
167
+ };
168
+
169
+ AbstractChosen.prototype.choice_label = function(item) {
170
+ if (this.include_group_label_in_selected && (item.group_label != null)) {
171
+ return "<b class='group-name'>" + (this.escape_html(item.group_label)) + "</b>" + item.html;
172
+ } else {
173
+ return item.html;
174
+ }
175
+ };
176
+
177
+ AbstractChosen.prototype.mouse_enter = function() {
178
+ return this.mouse_on_container = true;
179
+ };
180
+
181
+ AbstractChosen.prototype.mouse_leave = function() {
182
+ return this.mouse_on_container = false;
183
+ };
184
+
185
+ AbstractChosen.prototype.input_focus = function(evt) {
186
+ if (this.is_multiple) {
187
+ if (!this.active_field) {
188
+ return setTimeout(((function(_this) {
189
+ return function() {
190
+ return _this.container_mousedown();
191
+ };
192
+ })(this)), 50);
193
+ }
194
+ } else {
195
+ if (!this.active_field) {
196
+ return this.activate_field();
197
+ }
198
+ }
199
+ };
200
+
201
+ AbstractChosen.prototype.input_blur = function(evt) {
202
+ if (!this.mouse_on_container) {
203
+ this.active_field = false;
204
+ return setTimeout(((function(_this) {
205
+ return function() {
206
+ return _this.blur_test();
207
+ };
208
+ })(this)), 100);
209
+ }
210
+ };
211
+
212
+ AbstractChosen.prototype.label_click_handler = function(evt) {
213
+ if (this.is_multiple) {
214
+ return this.container_mousedown(evt);
215
+ } else {
216
+ return this.activate_field();
217
+ }
218
+ };
219
+
220
+ AbstractChosen.prototype.results_option_build = function(options) {
221
+ var content, data, data_content, i, len, ref, shown_results;
222
+ content = '';
223
+ shown_results = 0;
224
+ ref = this.results_data;
225
+ for (i = 0, len = ref.length; i < len; i++) {
226
+ data = ref[i];
227
+ data_content = '';
228
+ if (data.group) {
229
+ data_content = this.result_add_group(data);
230
+ } else {
231
+ data_content = this.result_add_option(data);
232
+ }
233
+ if (data_content !== '') {
234
+ shown_results++;
235
+ content += data_content;
236
+ }
237
+ if (options != null ? options.first : void 0) {
238
+ if (data.selected && this.is_multiple) {
239
+ this.choice_build(data);
240
+ } else if (data.selected && !this.is_multiple) {
241
+ this.single_set_selected_text(this.choice_label(data));
242
+ }
243
+ }
244
+ if (shown_results >= this.max_shown_results) {
245
+ break;
246
+ }
247
+ }
248
+ return content;
249
+ };
250
+
251
+ AbstractChosen.prototype.result_add_option = function(option) {
252
+ var classes, option_el;
253
+ if (!option.search_match) {
254
+ return '';
255
+ }
256
+ if (!this.include_option_in_results(option)) {
257
+ return '';
258
+ }
259
+ classes = [];
260
+ if (!option.disabled && !(option.selected && this.is_multiple)) {
261
+ classes.push("active-result");
262
+ }
263
+ if (option.disabled && !(option.selected && this.is_multiple)) {
264
+ classes.push("disabled-result");
265
+ }
266
+ if (option.selected) {
267
+ classes.push("result-selected");
268
+ }
269
+ if (option.group_array_index != null) {
270
+ classes.push("group-option");
271
+ }
272
+ if (option.classes !== "") {
273
+ classes.push(option.classes);
274
+ }
275
+ option_el = document.createElement("li");
276
+ option_el.className = classes.join(" ");
277
+ if (option.style) {
278
+ option_el.style.cssText = option.style;
279
+ }
280
+ option_el.setAttribute("data-option-array-index", option.array_index);
281
+ option_el.innerHTML = option.highlighted_html || option.html;
282
+ if (option.title) {
283
+ option_el.title = option.title;
284
+ }
285
+ return this.outerHTML(option_el);
286
+ };
287
+
288
+ AbstractChosen.prototype.result_add_group = function(group) {
289
+ var classes, group_el;
290
+ if (!(group.search_match || group.group_match)) {
291
+ return '';
292
+ }
293
+ if (!(group.active_options > 0)) {
294
+ return '';
295
+ }
296
+ classes = [];
297
+ classes.push("group-result");
298
+ if (group.classes) {
299
+ classes.push(group.classes);
300
+ }
301
+ group_el = document.createElement("li");
302
+ group_el.className = classes.join(" ");
303
+ group_el.innerHTML = group.highlighted_html || this.escape_html(group.label);
304
+ if (group.title) {
305
+ group_el.title = group.title;
306
+ }
307
+ return this.outerHTML(group_el);
308
+ };
309
+
310
+ AbstractChosen.prototype.results_update_field = function() {
311
+ this.set_default_text();
312
+ if (!this.is_multiple) {
313
+ this.results_reset_cleanup();
314
+ }
315
+ this.result_clear_highlight();
316
+ this.results_build();
317
+ if (this.results_showing) {
318
+ return this.winnow_results();
319
+ }
320
+ };
321
+
322
+ AbstractChosen.prototype.reset_single_select_options = function() {
323
+ var i, len, ref, result, results1;
324
+ ref = this.results_data;
325
+ results1 = [];
326
+ for (i = 0, len = ref.length; i < len; i++) {
327
+ result = ref[i];
328
+ if (result.selected) {
329
+ results1.push(result.selected = false);
330
+ } else {
331
+ results1.push(void 0);
332
+ }
333
+ }
334
+ return results1;
335
+ };
336
+
337
+ AbstractChosen.prototype.results_toggle = function() {
338
+ if (this.results_showing) {
339
+ return this.results_hide();
340
+ } else {
341
+ return this.results_show();
342
+ }
343
+ };
344
+
345
+ AbstractChosen.prototype.results_search = function(evt) {
346
+ if (this.results_showing) {
347
+ return this.winnow_results();
348
+ } else {
349
+ return this.results_show();
350
+ }
351
+ };
352
+
353
+ AbstractChosen.prototype.winnow_results = function(options) {
354
+ var escapedQuery, fix, i, len, option, prefix, query, ref, regex, results, results_group, search_match, startpos, suffix, text;
355
+ this.no_results_clear();
356
+ results = 0;
357
+ query = this.get_search_text();
358
+ escapedQuery = query.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
359
+ regex = this.get_search_regex(escapedQuery);
360
+ ref = this.results_data;
361
+ for (i = 0, len = ref.length; i < len; i++) {
362
+ option = ref[i];
363
+ option.search_match = false;
364
+ results_group = null;
365
+ search_match = null;
366
+ option.highlighted_html = '';
367
+ if (this.include_option_in_results(option)) {
368
+ if (option.group) {
369
+ option.group_match = false;
370
+ option.active_options = 0;
371
+ }
372
+ if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
373
+ results_group = this.results_data[option.group_array_index];
374
+ if (results_group.active_options === 0 && results_group.search_match) {
375
+ results += 1;
376
+ }
377
+ results_group.active_options += 1;
378
+ }
379
+ text = option.group ? option.label : option.text;
380
+ if (!(option.group && !this.group_search)) {
381
+ search_match = this.search_string_match(text, regex);
382
+ option.search_match = search_match != null;
383
+ if (option.search_match && !option.group) {
384
+ results += 1;
385
+ }
386
+ if (option.search_match) {
387
+ if (query.length) {
388
+ startpos = search_match.index;
389
+ prefix = text.slice(0, startpos);
390
+ fix = text.slice(startpos, startpos + query.length);
391
+ suffix = text.slice(startpos + query.length);
392
+ option.highlighted_html = (this.escape_html(prefix)) + "<em>" + (this.escape_html(fix)) + "</em>" + (this.escape_html(suffix));
393
+ }
394
+ if (results_group != null) {
395
+ results_group.group_match = true;
396
+ }
397
+ } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
398
+ option.search_match = true;
399
+ }
400
+ }
401
+ }
402
+ }
403
+ this.result_clear_highlight();
404
+ if (results < 1 && query.length) {
405
+ this.update_results_content("");
406
+ return this.no_results(query);
407
+ } else {
408
+ this.update_results_content(this.results_option_build());
409
+ if (!(options != null ? options.skip_highlight : void 0)) {
410
+ return this.winnow_results_set_highlight();
411
+ }
412
+ }
413
+ };
414
+
415
+ AbstractChosen.prototype.get_search_regex = function(escaped_search_string) {
416
+ var regex_flag, regex_string;
417
+ regex_string = this.search_contains ? escaped_search_string : "(^|\\s|\\b)" + escaped_search_string + "[^\\s]*";
418
+ if (!(this.enable_split_word_search || this.search_contains)) {
419
+ regex_string = "^" + regex_string;
420
+ }
421
+ regex_flag = this.case_sensitive_search ? "" : "i";
422
+ return new RegExp(regex_string, regex_flag);
423
+ };
424
+
425
+ AbstractChosen.prototype.search_string_match = function(search_string, regex) {
426
+ var match;
427
+ match = regex.exec(search_string);
428
+ if (!this.search_contains && (match != null ? match[1] : void 0)) {
429
+ match.index += 1;
430
+ }
431
+ return match;
432
+ };
433
+
434
+ AbstractChosen.prototype.choices_count = function() {
435
+ var i, len, option, ref;
436
+ if (this.selected_option_count != null) {
437
+ return this.selected_option_count;
438
+ }
439
+ this.selected_option_count = 0;
440
+ ref = this.form_field.options;
441
+ for (i = 0, len = ref.length; i < len; i++) {
442
+ option = ref[i];
443
+ if (option.selected) {
444
+ this.selected_option_count += 1;
445
+ }
446
+ }
447
+ return this.selected_option_count;
448
+ };
449
+
450
+ AbstractChosen.prototype.choices_click = function(evt) {
451
+ evt.preventDefault();
452
+ this.activate_field();
453
+ if (!(this.results_showing || this.is_disabled)) {
454
+ return this.results_show();
455
+ }
456
+ };
457
+
458
+ AbstractChosen.prototype.keydown_checker = function(evt) {
459
+ var ref, stroke;
460
+ stroke = (ref = evt.which) != null ? ref : evt.keyCode;
461
+ this.search_field_scale();
462
+ if (stroke !== 8 && this.pending_backstroke) {
463
+ this.clear_backstroke();
464
+ }
465
+ switch (stroke) {
466
+ case 8:
467
+ this.backstroke_length = this.get_search_field_value().length;
468
+ break;
469
+ case 9:
470
+ if (this.results_showing && !this.is_multiple) {
471
+ this.result_select(evt);
472
+ }
473
+ this.mouse_on_container = false;
474
+ break;
475
+ case 13:
476
+ if (this.results_showing) {
477
+ evt.preventDefault();
478
+ }
479
+ break;
480
+ case 27:
481
+ if (this.results_showing) {
482
+ evt.preventDefault();
483
+ }
484
+ break;
485
+ case 32:
486
+ if (this.disable_search) {
487
+ evt.preventDefault();
488
+ }
489
+ break;
490
+ case 38:
491
+ evt.preventDefault();
492
+ this.keyup_arrow();
493
+ break;
494
+ case 40:
495
+ evt.preventDefault();
496
+ this.keydown_arrow();
497
+ break;
498
+ }
499
+ };
500
+
501
+ AbstractChosen.prototype.keyup_checker = function(evt) {
502
+ var ref, stroke;
503
+ stroke = (ref = evt.which) != null ? ref : evt.keyCode;
504
+ this.search_field_scale();
505
+ switch (stroke) {
506
+ case 8:
507
+ if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
508
+ this.keydown_backstroke();
509
+ } else if (!this.pending_backstroke) {
510
+ this.result_clear_highlight();
511
+ this.results_search();
512
+ }
513
+ break;
514
+ case 13:
515
+ evt.preventDefault();
516
+ if (this.results_showing) {
517
+ this.result_select(evt);
518
+ }
519
+ break;
520
+ case 27:
521
+ if (this.results_showing) {
522
+ this.results_hide();
523
+ }
524
+ break;
525
+ case 9:
526
+ case 16:
527
+ case 17:
528
+ case 18:
529
+ case 38:
530
+ case 40:
531
+ case 91:
532
+ break;
533
+ default:
534
+ this.results_search();
535
+ break;
536
+ }
537
+ };
538
+
539
+ AbstractChosen.prototype.clipboard_event_checker = function(evt) {
540
+ if (this.is_disabled) {
541
+ return;
542
+ }
543
+ return setTimeout(((function(_this) {
544
+ return function() {
545
+ return _this.results_search();
546
+ };
547
+ })(this)), 50);
548
+ };
549
+
550
+ AbstractChosen.prototype.container_width = function() {
551
+ if (this.options.width != null) {
552
+ return this.options.width;
553
+ } else {
554
+ return this.form_field.offsetWidth + "px";
555
+ }
556
+ };
557
+
558
+ AbstractChosen.prototype.include_option_in_results = function(option) {
559
+ if (this.is_multiple && (!this.display_selected_options && option.selected)) {
560
+ return false;
561
+ }
562
+ if (!this.display_disabled_options && option.disabled) {
563
+ return false;
564
+ }
565
+ if (option.empty) {
566
+ return false;
567
+ }
568
+ return true;
569
+ };
570
+
571
+ AbstractChosen.prototype.search_results_touchstart = function(evt) {
572
+ this.touch_started = true;
573
+ return this.search_results_mouseover(evt);
574
+ };
575
+
576
+ AbstractChosen.prototype.search_results_touchmove = function(evt) {
577
+ this.touch_started = false;
578
+ return this.search_results_mouseout(evt);
579
+ };
580
+
581
+ AbstractChosen.prototype.search_results_touchend = function(evt) {
582
+ if (this.touch_started) {
583
+ return this.search_results_mouseup(evt);
584
+ }
585
+ };
586
+
587
+ AbstractChosen.prototype.outerHTML = function(element) {
588
+ var tmp;
589
+ if (element.outerHTML) {
590
+ return element.outerHTML;
591
+ }
592
+ tmp = document.createElement("div");
593
+ tmp.appendChild(element);
594
+ return tmp.innerHTML;
595
+ };
596
+
597
+ AbstractChosen.prototype.get_single_html = function() {
598
+ return "<a class=\"chosen-single chosen-default\">\n <span>" + this.default_text + "</span>\n <div><b></b></div>\n</a>\n<div class=\"chosen-drop\">\n <div class=\"chosen-search\">\n <input class=\"chosen-search-input\" type=\"text\" autocomplete=\"off\" />\n </div>\n <ul class=\"chosen-results\"></ul>\n</div>";
599
+ };
600
+
601
+ AbstractChosen.prototype.get_multi_html = function() {
602
+ return "<ul class=\"chosen-choices\">\n <li class=\"search-field\">\n <input class=\"chosen-search-input\" type=\"text\" autocomplete=\"off\" value=\"" + this.default_text + "\" />\n </li>\n</ul>\n<div class=\"chosen-drop\">\n <ul class=\"chosen-results\"></ul>\n</div>";
603
+ };
604
+
605
+ AbstractChosen.prototype.get_no_results_html = function(terms) {
606
+ return "<li class=\"no-results\">\n " + this.results_none_found + " <span>" + (this.escape_html(terms)) + "</span>\n</li>";
607
+ };
608
+
609
+ AbstractChosen.browser_is_supported = function() {
610
+ if ("Microsoft Internet Explorer" === window.navigator.appName) {
611
+ return document.documentMode >= 8;
612
+ }
613
+ if (/iP(od|hone)/i.test(window.navigator.userAgent) || /IEMobile/i.test(window.navigator.userAgent) || /Windows Phone/i.test(window.navigator.userAgent) || /BlackBerry/i.test(window.navigator.userAgent) || /BB10/i.test(window.navigator.userAgent) || /Android.*Mobile/i.test(window.navigator.userAgent)) {
614
+ return false;
615
+ }
616
+ return true;
617
+ };
618
+
619
+ AbstractChosen.default_multiple_text = "Select Some Options";
620
+
621
+ AbstractChosen.default_single_text = "Select an Option";
622
+
623
+ AbstractChosen.default_no_result_text = "No results match";
624
+
625
+ return AbstractChosen;
626
+
627
+ })();
628
+
629
+ $ = jQuery;
630
+
631
+ $.fn.extend({
632
+ chosen: function(options) {
633
+ if (!AbstractChosen.browser_is_supported()) {
634
+ return this;
635
+ }
636
+ return this.each(function(input_field) {
637
+ var $this, chosen;
638
+ $this = $(this);
639
+ chosen = $this.data('chosen');
640
+ if (options === 'destroy') {
641
+ if (chosen instanceof Chosen) {
642
+ chosen.destroy();
643
+ }
644
+ return;
645
+ }
646
+ if (!(chosen instanceof Chosen)) {
647
+ $this.data('chosen', new Chosen(this, options));
648
+ }
649
+ });
650
+ }
651
+ });
652
+
653
+ Chosen = (function(superClass) {
654
+ extend(Chosen, superClass);
655
+
656
+ function Chosen() {
657
+ return Chosen.__super__.constructor.apply(this, arguments);
658
+ }
659
+
660
+ Chosen.prototype.setup = function() {
661
+ this.form_field_jq = $(this.form_field);
662
+ return this.current_selectedIndex = this.form_field.selectedIndex;
663
+ };
664
+
665
+ Chosen.prototype.set_up_html = function() {
666
+ var container_classes, container_props;
667
+ container_classes = ["chosen-container"];
668
+ container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
669
+ if (this.inherit_select_classes && this.form_field.className) {
670
+ container_classes.push(this.form_field.className);
671
+ }
672
+ if (this.is_rtl) {
673
+ container_classes.push("chosen-rtl");
674
+ }
675
+ container_props = {
676
+ 'class': container_classes.join(' '),
677
+ 'title': this.form_field.title
678
+ };
679
+ if (this.form_field.id.length) {
680
+ container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
681
+ }
682
+ this.container = $("<div />", container_props);
683
+ this.container.width(this.container_width());
684
+ if (this.is_multiple) {
685
+ this.container.html(this.get_multi_html());
686
+ } else {
687
+ this.container.html(this.get_single_html());
688
+ }
689
+ this.form_field_jq.hide().after(this.container);
690
+ this.dropdown = this.container.find('div.chosen-drop').first();
691
+ this.search_field = this.container.find('input').first();
692
+ this.search_results = this.container.find('ul.chosen-results').first();
693
+ this.search_field_scale();
694
+ this.search_no_results = this.container.find('li.no-results').first();
695
+ if (this.is_multiple) {
696
+ this.search_choices = this.container.find('ul.chosen-choices').first();
697
+ this.search_container = this.container.find('li.search-field').first();
698
+ } else {
699
+ this.search_container = this.container.find('div.chosen-search').first();
700
+ this.selected_item = this.container.find('.chosen-single').first();
701
+ }
702
+ this.results_build();
703
+ this.set_tab_index();
704
+ return this.set_label_behavior();
705
+ };
706
+
707
+ Chosen.prototype.on_ready = function() {
708
+ return this.form_field_jq.trigger("chosen:ready", {
709
+ chosen: this
710
+ });
711
+ };
712
+
713
+ Chosen.prototype.register_observers = function() {
714
+ this.container.on('touchstart.chosen', (function(_this) {
715
+ return function(evt) {
716
+ _this.container_mousedown(evt);
717
+ };
718
+ })(this));
719
+ this.container.on('touchend.chosen', (function(_this) {
720
+ return function(evt) {
721
+ _this.container_mouseup(evt);
722
+ };
723
+ })(this));
724
+ this.container.on('mousedown.chosen', (function(_this) {
725
+ return function(evt) {
726
+ _this.container_mousedown(evt);
727
+ };
728
+ })(this));
729
+ this.container.on('mouseup.chosen', (function(_this) {
730
+ return function(evt) {
731
+ _this.container_mouseup(evt);
732
+ };
733
+ })(this));
734
+ this.container.on('mouseenter.chosen', (function(_this) {
735
+ return function(evt) {
736
+ _this.mouse_enter(evt);
737
+ };
738
+ })(this));
739
+ this.container.on('mouseleave.chosen', (function(_this) {
740
+ return function(evt) {
741
+ _this.mouse_leave(evt);
742
+ };
743
+ })(this));
744
+ this.search_results.on('mouseup.chosen', (function(_this) {
745
+ return function(evt) {
746
+ _this.search_results_mouseup(evt);
747
+ };
748
+ })(this));
749
+ this.search_results.on('mouseover.chosen', (function(_this) {
750
+ return function(evt) {
751
+ _this.search_results_mouseover(evt);
752
+ };
753
+ })(this));
754
+ this.search_results.on('mouseout.chosen', (function(_this) {
755
+ return function(evt) {
756
+ _this.search_results_mouseout(evt);
757
+ };
758
+ })(this));
759
+ this.search_results.on('mousewheel.chosen DOMMouseScroll.chosen', (function(_this) {
760
+ return function(evt) {
761
+ _this.search_results_mousewheel(evt);
762
+ };
763
+ })(this));
764
+ this.search_results.on('touchstart.chosen', (function(_this) {
765
+ return function(evt) {
766
+ _this.search_results_touchstart(evt);
767
+ };
768
+ })(this));
769
+ this.search_results.on('touchmove.chosen', (function(_this) {
770
+ return function(evt) {
771
+ _this.search_results_touchmove(evt);
772
+ };
773
+ })(this));
774
+ this.search_results.on('touchend.chosen', (function(_this) {
775
+ return function(evt) {
776
+ _this.search_results_touchend(evt);
777
+ };
778
+ })(this));
779
+ this.form_field_jq.on("chosen:updated.chosen", (function(_this) {
780
+ return function(evt) {
781
+ _this.results_update_field(evt);
782
+ };
783
+ })(this));
784
+ this.form_field_jq.on("chosen:activate.chosen", (function(_this) {
785
+ return function(evt) {
786
+ _this.activate_field(evt);
787
+ };
788
+ })(this));
789
+ this.form_field_jq.on("chosen:open.chosen", (function(_this) {
790
+ return function(evt) {
791
+ _this.container_mousedown(evt);
792
+ };
793
+ })(this));
794
+ this.form_field_jq.on("chosen:close.chosen", (function(_this) {
795
+ return function(evt) {
796
+ _this.close_field(evt);
797
+ };
798
+ })(this));
799
+ this.search_field.on('blur.chosen', (function(_this) {
800
+ return function(evt) {
801
+ _this.input_blur(evt);
802
+ };
803
+ })(this));
804
+ this.search_field.on('keyup.chosen', (function(_this) {
805
+ return function(evt) {
806
+ _this.keyup_checker(evt);
807
+ };
808
+ })(this));
809
+ this.search_field.on('keydown.chosen', (function(_this) {
810
+ return function(evt) {
811
+ _this.keydown_checker(evt);
812
+ };
813
+ })(this));
814
+ this.search_field.on('focus.chosen', (function(_this) {
815
+ return function(evt) {
816
+ _this.input_focus(evt);
817
+ };
818
+ })(this));
819
+ this.search_field.on('cut.chosen', (function(_this) {
820
+ return function(evt) {
821
+ _this.clipboard_event_checker(evt);
822
+ };
823
+ })(this));
824
+ this.search_field.on('paste.chosen', (function(_this) {
825
+ return function(evt) {
826
+ _this.clipboard_event_checker(evt);
827
+ };
828
+ })(this));
829
+ if (this.is_multiple) {
830
+ return this.search_choices.on('click.chosen', (function(_this) {
831
+ return function(evt) {
832
+ _this.choices_click(evt);
833
+ };
834
+ })(this));
835
+ } else {
836
+ return this.container.on('click.chosen', function(evt) {
837
+ evt.preventDefault();
838
+ });
839
+ }
840
+ };
841
+
842
+ Chosen.prototype.destroy = function() {
843
+ $(this.container[0].ownerDocument).off('click.chosen', this.click_test_action);
844
+ if (this.form_field_label.length > 0) {
845
+ this.form_field_label.off('click.chosen');
846
+ }
847
+ if (this.search_field[0].tabIndex) {
848
+ this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
849
+ }
850
+ this.container.remove();
851
+ this.form_field_jq.removeData('chosen');
852
+ return this.form_field_jq.show();
853
+ };
854
+
855
+ Chosen.prototype.search_field_disabled = function() {
856
+ this.is_disabled = this.form_field.disabled || this.form_field_jq.parents('fieldset').is(':disabled');
857
+ this.container.toggleClass('chosen-disabled', this.is_disabled);
858
+ this.search_field[0].disabled = this.is_disabled;
859
+ if (!this.is_multiple) {
860
+ this.selected_item.off('focus.chosen', this.activate_field);
861
+ }
862
+ if (this.is_disabled) {
863
+ return this.close_field();
864
+ } else if (!this.is_multiple) {
865
+ return this.selected_item.on('focus.chosen', this.activate_field);
866
+ }
867
+ };
868
+
869
+ Chosen.prototype.container_mousedown = function(evt) {
870
+ var ref;
871
+ if (this.is_disabled) {
872
+ return;
873
+ }
874
+ if (evt && ((ref = evt.type) === 'mousedown' || ref === 'touchstart') && !this.results_showing) {
875
+ evt.preventDefault();
876
+ }
877
+ if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
878
+ if (!this.active_field) {
879
+ if (this.is_multiple) {
880
+ this.search_field.val("");
881
+ }
882
+ $(this.container[0].ownerDocument).on('click.chosen', this.click_test_action);
883
+ this.results_show();
884
+ } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
885
+ evt.preventDefault();
886
+ this.results_toggle();
887
+ }
888
+ return this.activate_field();
889
+ }
890
+ };
891
+
892
+ Chosen.prototype.container_mouseup = function(evt) {
893
+ if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
894
+ return this.results_reset(evt);
895
+ }
896
+ };
897
+
898
+ Chosen.prototype.search_results_mousewheel = function(evt) {
899
+ var delta;
900
+ if (evt.originalEvent) {
901
+ delta = evt.originalEvent.deltaY || -evt.originalEvent.wheelDelta || evt.originalEvent.detail;
902
+ }
903
+ if (delta != null) {
904
+ evt.preventDefault();
905
+ if (evt.type === 'DOMMouseScroll') {
906
+ delta = delta * 40;
907
+ }
908
+ return this.search_results.scrollTop(delta + this.search_results.scrollTop());
909
+ }
910
+ };
911
+
912
+ Chosen.prototype.blur_test = function(evt) {
913
+ if (!this.active_field && this.container.hasClass("chosen-container-active")) {
914
+ return this.close_field();
915
+ }
916
+ };
917
+
918
+ Chosen.prototype.close_field = function() {
919
+ $(this.container[0].ownerDocument).off("click.chosen", this.click_test_action);
920
+ this.active_field = false;
921
+ this.results_hide();
922
+ this.container.removeClass("chosen-container-active");
923
+ this.clear_backstroke();
924
+ this.show_search_field_default();
925
+ this.search_field_scale();
926
+ return this.search_field.blur();
927
+ };
928
+
929
+ Chosen.prototype.activate_field = function() {
930
+ if (this.is_disabled) {
931
+ return;
932
+ }
933
+ this.container.addClass("chosen-container-active");
934
+ this.active_field = true;
935
+ this.search_field.val(this.search_field.val());
936
+ return this.search_field.focus();
937
+ };
938
+
939
+ Chosen.prototype.test_active_click = function(evt) {
940
+ var active_container;
941
+ active_container = $(evt.target).closest('.chosen-container');
942
+ if (active_container.length && this.container[0] === active_container[0]) {
943
+ return this.active_field = true;
944
+ } else {
945
+ return this.close_field();
946
+ }
947
+ };
948
+
949
+ Chosen.prototype.results_build = function() {
950
+ this.parsing = true;
951
+ this.selected_option_count = null;
952
+ this.results_data = SelectParser.select_to_array(this.form_field);
953
+ if (this.is_multiple) {
954
+ this.search_choices.find("li.search-choice").remove();
955
+ } else {
956
+ this.single_set_selected_text();
957
+ if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
958
+ this.search_field[0].readOnly = true;
959
+ this.container.addClass("chosen-container-single-nosearch");
960
+ } else {
961
+ this.search_field[0].readOnly = false;
962
+ this.container.removeClass("chosen-container-single-nosearch");
963
+ }
964
+ }
965
+ this.update_results_content(this.results_option_build({
966
+ first: true
967
+ }));
968
+ this.search_field_disabled();
969
+ this.show_search_field_default();
970
+ this.search_field_scale();
971
+ return this.parsing = false;
972
+ };
973
+
974
+ Chosen.prototype.result_do_highlight = function(el) {
975
+ var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
976
+ if (el.length) {
977
+ this.result_clear_highlight();
978
+ this.result_highlight = el;
979
+ this.result_highlight.addClass("highlighted");
980
+ maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
981
+ visible_top = this.search_results.scrollTop();
982
+ visible_bottom = maxHeight + visible_top;
983
+ high_top = this.result_highlight.position().top + this.search_results.scrollTop();
984
+ high_bottom = high_top + this.result_highlight.outerHeight();
985
+ if (high_bottom >= visible_bottom) {
986
+ return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
987
+ } else if (high_top < visible_top) {
988
+ return this.search_results.scrollTop(high_top);
989
+ }
990
+ }
991
+ };
992
+
993
+ Chosen.prototype.result_clear_highlight = function() {
994
+ if (this.result_highlight) {
995
+ this.result_highlight.removeClass("highlighted");
996
+ }
997
+ return this.result_highlight = null;
998
+ };
999
+
1000
+ Chosen.prototype.results_show = function() {
1001
+ if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
1002
+ this.form_field_jq.trigger("chosen:maxselected", {
1003
+ chosen: this
1004
+ });
1005
+ return false;
1006
+ }
1007
+ this.container.addClass("chosen-with-drop");
1008
+ this.results_showing = true;
1009
+ this.search_field.focus();
1010
+ this.search_field.val(this.get_search_field_value());
1011
+ this.winnow_results();
1012
+ return this.form_field_jq.trigger("chosen:showing_dropdown", {
1013
+ chosen: this
1014
+ });
1015
+ };
1016
+
1017
+ Chosen.prototype.update_results_content = function(content) {
1018
+ return this.search_results.html(content);
1019
+ };
1020
+
1021
+ Chosen.prototype.results_hide = function() {
1022
+ if (this.results_showing) {
1023
+ this.result_clear_highlight();
1024
+ this.container.removeClass("chosen-with-drop");
1025
+ this.form_field_jq.trigger("chosen:hiding_dropdown", {
1026
+ chosen: this
1027
+ });
1028
+ }
1029
+ return this.results_showing = false;
1030
+ };
1031
+
1032
+ Chosen.prototype.set_tab_index = function(el) {
1033
+ var ti;
1034
+ if (this.form_field.tabIndex) {
1035
+ ti = this.form_field.tabIndex;
1036
+ this.form_field.tabIndex = -1;
1037
+ return this.search_field[0].tabIndex = ti;
1038
+ }
1039
+ };
1040
+
1041
+ Chosen.prototype.set_label_behavior = function() {
1042
+ this.form_field_label = this.form_field_jq.parents("label");
1043
+ if (!this.form_field_label.length && this.form_field.id.length) {
1044
+ this.form_field_label = $("label[for='" + this.form_field.id + "']");
1045
+ }
1046
+ if (this.form_field_label.length > 0) {
1047
+ return this.form_field_label.on('click.chosen', this.label_click_handler);
1048
+ }
1049
+ };
1050
+
1051
+ Chosen.prototype.show_search_field_default = function() {
1052
+ if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
1053
+ this.search_field.val(this.default_text);
1054
+ return this.search_field.addClass("default");
1055
+ } else {
1056
+ this.search_field.val("");
1057
+ return this.search_field.removeClass("default");
1058
+ }
1059
+ };
1060
+
1061
+ Chosen.prototype.search_results_mouseup = function(evt) {
1062
+ var target;
1063
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
1064
+ if (target.length) {
1065
+ this.result_highlight = target;
1066
+ this.result_select(evt);
1067
+ return this.search_field.focus();
1068
+ }
1069
+ };
1070
+
1071
+ Chosen.prototype.search_results_mouseover = function(evt) {
1072
+ var target;
1073
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
1074
+ if (target) {
1075
+ return this.result_do_highlight(target);
1076
+ }
1077
+ };
1078
+
1079
+ Chosen.prototype.search_results_mouseout = function(evt) {
1080
+ if ($(evt.target).hasClass("active-result") || $(evt.target).parents('.active-result').first()) {
1081
+ return this.result_clear_highlight();
1082
+ }
1083
+ };
1084
+
1085
+ Chosen.prototype.choice_build = function(item) {
1086
+ var choice, close_link;
1087
+ choice = $('<li />', {
1088
+ "class": "search-choice"
1089
+ }).html("<span>" + (this.choice_label(item)) + "</span>");
1090
+ if (item.disabled) {
1091
+ choice.addClass('search-choice-disabled');
1092
+ } else {
1093
+ close_link = $('<a />', {
1094
+ "class": 'search-choice-close',
1095
+ 'data-option-array-index': item.array_index
1096
+ });
1097
+ close_link.on('click.chosen', (function(_this) {
1098
+ return function(evt) {
1099
+ return _this.choice_destroy_link_click(evt);
1100
+ };
1101
+ })(this));
1102
+ choice.append(close_link);
1103
+ }
1104
+ return this.search_container.before(choice);
1105
+ };
1106
+
1107
+ Chosen.prototype.choice_destroy_link_click = function(evt) {
1108
+ evt.preventDefault();
1109
+ evt.stopPropagation();
1110
+ if (!this.is_disabled) {
1111
+ return this.choice_destroy($(evt.target));
1112
+ }
1113
+ };
1114
+
1115
+ Chosen.prototype.choice_destroy = function(link) {
1116
+ if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
1117
+ if (this.active_field) {
1118
+ this.search_field.focus();
1119
+ } else {
1120
+ this.show_search_field_default();
1121
+ }
1122
+ if (this.is_multiple && this.choices_count() > 0 && this.get_search_field_value().length < 1) {
1123
+ this.results_hide();
1124
+ }
1125
+ link.parents('li').first().remove();
1126
+ return this.search_field_scale();
1127
+ }
1128
+ };
1129
+
1130
+ Chosen.prototype.results_reset = function() {
1131
+ this.reset_single_select_options();
1132
+ this.form_field.options[0].selected = true;
1133
+ this.single_set_selected_text();
1134
+ this.show_search_field_default();
1135
+ this.results_reset_cleanup();
1136
+ this.trigger_form_field_change();
1137
+ if (this.active_field) {
1138
+ return this.results_hide();
1139
+ }
1140
+ };
1141
+
1142
+ Chosen.prototype.results_reset_cleanup = function() {
1143
+ this.current_selectedIndex = this.form_field.selectedIndex;
1144
+ return this.selected_item.find("abbr").remove();
1145
+ };
1146
+
1147
+ Chosen.prototype.result_select = function(evt) {
1148
+ var high, item;
1149
+ if (this.result_highlight) {
1150
+ high = this.result_highlight;
1151
+ this.result_clear_highlight();
1152
+ if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
1153
+ this.form_field_jq.trigger("chosen:maxselected", {
1154
+ chosen: this
1155
+ });
1156
+ return false;
1157
+ }
1158
+ if (this.is_multiple) {
1159
+ high.removeClass("active-result");
1160
+ } else {
1161
+ this.reset_single_select_options();
1162
+ }
1163
+ high.addClass("result-selected");
1164
+ item = this.results_data[high[0].getAttribute("data-option-array-index")];
1165
+ item.selected = true;
1166
+ this.form_field.options[item.options_index].selected = true;
1167
+ this.selected_option_count = null;
1168
+ if (this.is_multiple) {
1169
+ this.choice_build(item);
1170
+ } else {
1171
+ this.single_set_selected_text(this.choice_label(item));
1172
+ }
1173
+ if (this.is_multiple && (!this.hide_results_on_select || (evt.metaKey || evt.ctrlKey))) {
1174
+ if (evt.metaKey || evt.ctrlKey) {
1175
+ this.winnow_results({
1176
+ skip_highlight: true
1177
+ });
1178
+ } else {
1179
+ this.search_field.val("");
1180
+ this.winnow_results();
1181
+ }
1182
+ } else {
1183
+ this.results_hide();
1184
+ this.show_search_field_default();
1185
+ }
1186
+ if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
1187
+ this.trigger_form_field_change({
1188
+ selected: this.form_field.options[item.options_index].value
1189
+ });
1190
+ }
1191
+ this.current_selectedIndex = this.form_field.selectedIndex;
1192
+ evt.preventDefault();
1193
+ return this.search_field_scale();
1194
+ }
1195
+ };
1196
+
1197
+ Chosen.prototype.single_set_selected_text = function(text) {
1198
+ if (text == null) {
1199
+ text = this.default_text;
1200
+ }
1201
+ if (text === this.default_text) {
1202
+ this.selected_item.addClass("chosen-default");
1203
+ } else {
1204
+ this.single_deselect_control_build();
1205
+ this.selected_item.removeClass("chosen-default");
1206
+ }
1207
+ return this.selected_item.find("span").html(text);
1208
+ };
1209
+
1210
+ Chosen.prototype.result_deselect = function(pos) {
1211
+ var result_data;
1212
+ result_data = this.results_data[pos];
1213
+ if (!this.form_field.options[result_data.options_index].disabled) {
1214
+ result_data.selected = false;
1215
+ this.form_field.options[result_data.options_index].selected = false;
1216
+ this.selected_option_count = null;
1217
+ this.result_clear_highlight();
1218
+ if (this.results_showing) {
1219
+ this.winnow_results();
1220
+ }
1221
+ this.trigger_form_field_change({
1222
+ deselected: this.form_field.options[result_data.options_index].value
1223
+ });
1224
+ this.search_field_scale();
1225
+ return true;
1226
+ } else {
1227
+ return false;
1228
+ }
1229
+ };
1230
+
1231
+ Chosen.prototype.single_deselect_control_build = function() {
1232
+ if (!this.allow_single_deselect) {
1233
+ return;
1234
+ }
1235
+ if (!this.selected_item.find("abbr").length) {
1236
+ this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
1237
+ }
1238
+ return this.selected_item.addClass("chosen-single-with-deselect");
1239
+ };
1240
+
1241
+ Chosen.prototype.get_search_field_value = function() {
1242
+ return this.search_field.val();
1243
+ };
1244
+
1245
+ Chosen.prototype.get_search_text = function() {
1246
+ return $.trim(this.get_search_field_value());
1247
+ };
1248
+
1249
+ Chosen.prototype.escape_html = function(text) {
1250
+ return $('<div/>').text(text).html();
1251
+ };
1252
+
1253
+ Chosen.prototype.winnow_results_set_highlight = function() {
1254
+ var do_high, selected_results;
1255
+ selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
1256
+ do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
1257
+ if (do_high != null) {
1258
+ return this.result_do_highlight(do_high);
1259
+ }
1260
+ };
1261
+
1262
+ Chosen.prototype.no_results = function(terms) {
1263
+ var no_results_html;
1264
+ no_results_html = this.get_no_results_html(terms);
1265
+ this.search_results.append(no_results_html);
1266
+ return this.form_field_jq.trigger("chosen:no_results", {
1267
+ chosen: this
1268
+ });
1269
+ };
1270
+
1271
+ Chosen.prototype.no_results_clear = function() {
1272
+ return this.search_results.find(".no-results").remove();
1273
+ };
1274
+
1275
+ Chosen.prototype.keydown_arrow = function() {
1276
+ var next_sib;
1277
+ if (this.results_showing && this.result_highlight) {
1278
+ next_sib = this.result_highlight.nextAll("li.active-result").first();
1279
+ if (next_sib) {
1280
+ return this.result_do_highlight(next_sib);
1281
+ }
1282
+ } else {
1283
+ return this.results_show();
1284
+ }
1285
+ };
1286
+
1287
+ Chosen.prototype.keyup_arrow = function() {
1288
+ var prev_sibs;
1289
+ if (!this.results_showing && !this.is_multiple) {
1290
+ return this.results_show();
1291
+ } else if (this.result_highlight) {
1292
+ prev_sibs = this.result_highlight.prevAll("li.active-result");
1293
+ if (prev_sibs.length) {
1294
+ return this.result_do_highlight(prev_sibs.first());
1295
+ } else {
1296
+ if (this.choices_count() > 0) {
1297
+ this.results_hide();
1298
+ }
1299
+ return this.result_clear_highlight();
1300
+ }
1301
+ }
1302
+ };
1303
+
1304
+ Chosen.prototype.keydown_backstroke = function() {
1305
+ var next_available_destroy;
1306
+ if (this.pending_backstroke) {
1307
+ this.choice_destroy(this.pending_backstroke.find("a").first());
1308
+ return this.clear_backstroke();
1309
+ } else {
1310
+ next_available_destroy = this.search_container.siblings("li.search-choice").last();
1311
+ if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
1312
+ this.pending_backstroke = next_available_destroy;
1313
+ if (this.single_backstroke_delete) {
1314
+ return this.keydown_backstroke();
1315
+ } else {
1316
+ return this.pending_backstroke.addClass("search-choice-focus");
1317
+ }
1318
+ }
1319
+ }
1320
+ };
1321
+
1322
+ Chosen.prototype.clear_backstroke = function() {
1323
+ if (this.pending_backstroke) {
1324
+ this.pending_backstroke.removeClass("search-choice-focus");
1325
+ }
1326
+ return this.pending_backstroke = null;
1327
+ };
1328
+
1329
+ Chosen.prototype.search_field_scale = function() {
1330
+ var div, i, len, style, style_block, styles, width;
1331
+ if (!this.is_multiple) {
1332
+ return;
1333
+ }
1334
+ style_block = {
1335
+ position: 'absolute',
1336
+ left: '-1000px',
1337
+ top: '-1000px',
1338
+ display: 'none',
1339
+ whiteSpace: 'pre'
1340
+ };
1341
+ styles = ['fontSize', 'fontStyle', 'fontWeight', 'fontFamily', 'lineHeight', 'textTransform', 'letterSpacing'];
1342
+ for (i = 0, len = styles.length; i < len; i++) {
1343
+ style = styles[i];
1344
+ style_block[style] = this.search_field.css(style);
1345
+ }
1346
+ div = $('<div />').css(style_block);
1347
+ div.text(this.get_search_field_value());
1348
+ $('body').append(div);
1349
+ width = div.width() + 25;
1350
+ div.remove();
1351
+ if (this.container.is(':visible')) {
1352
+ width = Math.min(this.container.outerWidth() - 10, width);
1353
+ }
1354
+ return this.search_field.width(width);
1355
+ };
1356
+
1357
+ Chosen.prototype.trigger_form_field_change = function(extra) {
1358
+ this.form_field_jq.trigger("input", extra);
1359
+ return this.form_field_jq.trigger("change", extra);
1360
+ };
1361
+
1362
+ return Chosen;
1363
+
1364
+ })(AbstractChosen);
1365
+
1366
+ }).call(this);
includes/views/js/import-metabox-edit.js CHANGED
@@ -265,6 +265,13 @@
265
  }
266
  });
267
  });
 
 
 
 
 
 
 
268
  }
269
 
270
  function initSummary() {
265
  }
266
  });
267
  });
268
+
269
+ // Click on pro/upgrade button.
270
+ $( document ).on( 'click', '.only-pro-inner a', function( e ) {
271
+ if ( $( this ).parents( '.only-pro-content' ).css( 'opacity' ) == 0 ) {
272
+ e.preventDefault();
273
+ }
274
+ } );
275
  }
276
 
277
  function initSummary() {
includes/views/misc-view.php CHANGED
@@ -1,13 +1,7 @@
1
- <?php
2
- $canonical_checked = '';
3
- if ( isset( $this->free_settings['canonical'] ) && 1 === intval( $this->free_settings['canonical'] ) ) {
4
- $canonical_checked = 'checked';
5
- }
6
- ?>
7
- <h2><?php echo __( 'Import Posts', 'feedzy-rss-feeds' ); ?></h2>
8
  <div class="fz-form-group">
9
  <input type="checkbox" id="canonical" class="fz-form-control" name="canonical"
10
- value="1" <?php echo $canonical_checked; ?> />
11
- <label><?php echo __( 'Add canonical URL to imported posts from RSS feeds.', 'feedzy-rss-feeds' ); ?></label>
12
 
13
  </div>
1
+ <h2><?php esc_html_e( 'Import Posts', 'feedzy-rss-feeds' ); ?></h2>
 
 
 
 
 
 
2
  <div class="fz-form-group">
3
  <input type="checkbox" id="canonical" class="fz-form-control" name="canonical"
4
+ value="1" <?php checked( 1, intval( $this->free_settings['canonical'] ) ); ?> />
5
+ <label for="canonical"><?php esc_html_e( 'Add canonical URL to imported posts from RSS feeds.', 'feedzy-rss-feeds' ); ?></label>
6
 
7
  </div>
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: themeisle,codeinwp,hardeepasrani,rozroz
3
  Tags: rss aggregator, news aggregator, autoblogging, feed to post, rss import
4
  Requires at least: 3.7
5
- Requires PHP: 5.3
6
- Tested up to: 5.6
7
  Stable tag: trunk
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -461,6 +461,20 @@ You have to check first if your feed is valid. Please test it here: https://vali
461
 
462
 
463
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
464
  = 3.5.2 - 2020-12-24 =
465
 
466
  * [Fix] Compatibility with WP 5.6
2
  Contributors: themeisle,codeinwp,hardeepasrani,rozroz
3
  Tags: rss aggregator, news aggregator, autoblogging, feed to post, rss import
4
  Requires at least: 3.7
5
+ Requires PHP: 5.6
6
+ Tested up to: 5.7
7
  Stable tag: trunk
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
461
 
462
 
463
  == Changelog ==
464
+
465
+ #### [Version 3.6.0](https://github.com/Codeinwp/feedzy-rss-feeds/compare/v3.5.2...v3.6.0) (2021-04-20)
466
+
467
+ #### Fixes
468
+ * Fix PHP notices reported on import when debug mode is on
469
+ * Fix inconsistent behavior with certain valid feed URLs
470
+ * Improve compatibilities with the latest PHP and WordPress versions
471
+ * Improve compatibilities with non-Latin charsets
472
+
473
+ #### Feature
474
+ * Add ability to use external images on import for featured images.
475
+
476
+
477
+
478
  = 3.5.2 - 2020-12-24 =
479
 
480
  * [Fix] Compatibility with WP 5.6
themeisle-hash.json DELETED
@@ -1 +0,0 @@
1
- {"feedzy-rss-feed.php":"7ec860bb8fff4bc5fbc54b24a7823788","index.php":"71c0755260138a4b7b2182c3c61179f6","uninstall.php":"cdb21f8648e005cbb9c73481d1750186"}
 
vendor/autoload.php CHANGED
@@ -2,6 +2,6 @@
2
 
3
  // autoload.php @generated by Composer
4
 
5
- require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit4f93c5e0c4064494ba1171bd88732555::getLoader();
2
 
3
  // autoload.php @generated by Composer
4
 
5
+ require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit6219981e6410a5c15ec2675a8b39fd84::getLoader();
vendor/codeinwp/themeisle-sdk/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ##### [Version 3.2.16](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.15...v3.2.16) (2020-11-17)
2
 
3
  * Fix long texts on rollback.
1
+ ##### [Version 3.2.20](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.19...v3.2.20) (2021-03-30)
2
+
3
+ add wp-config support
4
+
5
+ ##### [Version 3.2.19](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.18...v3.2.19) (2021-03-12)
6
+
7
+ * Adds compatibility with latest PHPCS coding standards.
8
+ * Adds compatibility with core auto-update.
9
+
10
+ ##### [Version 3.2.18](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.17...v3.2.18) (2021-03-04)
11
+
12
+ * Fix regression on rollback order
13
+
14
+ ##### [Version 3.2.17](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.16...v3.2.17) (2021-03-04)
15
+
16
+ * Fix compatibility with PHP 8 due to usort
17
+
18
  ##### [Version 3.2.16](https://github.com/Codeinwp/themeisle-sdk/compare/v3.2.15...v3.2.16) (2020-11-17)
19
 
20
  * Fix long texts on rollback.
vendor/codeinwp/themeisle-sdk/README.md DELETED
@@ -1,32 +0,0 @@
1
- # Themeisle SDK
2
-
3
- ThemeIsle SDK used to register common features for products in the portfolio.
4
-
5
- Can be installed using composer:
6
- `composer require codeinwp/themeisle-sdk`
7
- and manually autoloading the load.php file in the composer.json file of your project:
8
-
9
- ```
10
-
11
- "autoload": {
12
- "files": [
13
- "vendor/codeinwp/themeisle-sdk/load.php"
14
- ]
15
- }
16
-
17
- ```
18
-
19
-
20
- ### Features
21
-
22
- * Loads the most recent version of the library across all the products on the same wordpress instance. For instance if there is a theme which bundles v2.0.0 of the SDK and one plugin which bundles the v1.9.1, it will load on the most recent one, v2.0.0 for both products.
23
- * If there are two products using the same version, it will load the first one that register the SDK, unless it's explicitly overwritten.
24
- * Each functionality is bundled into modules, which are loaded based on the product type. Free/Pro, is available on wordpress or not.
25
-
26
- ### How to register product
27
-
28
- * The library works out of the box by simply loading the autoloader into the plugin/theme files.
29
- * Some modules are loaded only if the product is not available on WordPress.org ( licenser/review ). You can define if the product is available on wordpress.org by adding this file header `WordPress Available: <yes|no>` where `<yes|no>` will be replaced with the proper status.
30
- * If the product requires is a premium one and requires a licesing mechanism, we can use `Requires License: <yes|no>` to specifically tell that the product requires license.
31
-
32
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/docker-compose.local.yml DELETED
@@ -1,28 +0,0 @@
1
- version: '3.1'
2
-
3
- services:
4
- wordpress:
5
- depends_on:
6
- - mysql
7
- image: hardeepasrani/pirate-brewery
8
- ports:
9
- - 999:80
10
- volumes:
11
- - ./tests/sample_products/sample_plugin:/var/www/html/wp-content/plugins/sample_plugin
12
- - ./:/var/www/html/wp-content/plugins/sample_plugin/vendor
13
- restart: always
14
- environment:
15
- WORDPRESS_DB_NAME: wordpress
16
- WORDPRESS_DB_USER: wordpress
17
- WORDPRESS_DB_PASSWORD: wordpress
18
- WORDPRESS_DB_ROOT_PASSWORD: wordpress
19
- mysql:
20
- image: mysql:5.7
21
- volumes:
22
- - ~/db_data:/var/lib/mysql
23
- restart: always
24
- environment:
25
- MYSQL_ROOT_PASSWORD: wordpress
26
- MYSQL_DATABASE: wordpress
27
- MYSQL_USER: wordpress
28
- MYSQL_PASSWORD: wordpress
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/load.php CHANGED
@@ -14,7 +14,7 @@ if ( ! defined( 'ABSPATH' ) ) {
14
  return;
15
  }
16
  // Current SDK version and path.
17
- $themeisle_sdk_version = '3.2.16';
18
  $themeisle_sdk_path = dirname( __FILE__ );
19
 
20
  global $themeisle_sdk_max_version;
14
  return;
15
  }
16
  // Current SDK version and path.
17
+ $themeisle_sdk_version = '3.2.20';
18
  $themeisle_sdk_path = dirname( __FILE__ );
19
 
20
  global $themeisle_sdk_max_version;
vendor/codeinwp/themeisle-sdk/src/Common/Abstract_module.php CHANGED
@@ -37,14 +37,14 @@ abstract class Abstract_Module {
37
  *
38
  * @return bool Should load module?
39
  */
40
- public abstract function can_load( $product );
41
 
42
  /**
43
  * Bootstrap the module.
44
  *
45
  * @param Product $product Product object.
46
  */
47
- public abstract function load( $product );
48
 
49
  /**
50
  * Check if the product is from partner.
@@ -63,4 +63,21 @@ abstract class Abstract_Module {
63
 
64
  return array_key_exists( $product->get_slug(), Module_Factory::$slugs );
65
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  }
37
  *
38
  * @return bool Should load module?
39
  */
40
+ abstract public function can_load( $product );
41
 
42
  /**
43
  * Bootstrap the module.
44
  *
45
  * @param Product $product Product object.
46
  */
47
+ abstract public function load( $product );
48
 
49
  /**
50
  * Check if the product is from partner.
63
 
64
  return array_key_exists( $product->get_slug(), Module_Factory::$slugs );
65
  }
66
+
67
+ /**
68
+ * Wrapper for wp_remote_get on VIP environments.
69
+ *
70
+ * @param string $url Url to check.
71
+ * @param array $args Option params.
72
+ *
73
+ * @return array|\WP_Error
74
+ */
75
+ public function safe_get( $url, $args = array() ) {
76
+ return function_exists( 'vip_safe_wp_remote_get' )
77
+ ? vip_safe_wp_remote_get( $url )
78
+ : wp_remote_get( //phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_remote_get_wp_remote_get, Already used.
79
+ $url,
80
+ $args
81
+ );
82
+ }
83
  }
vendor/codeinwp/themeisle-sdk/src/Common/Module_factory.php CHANGED
@@ -88,7 +88,7 @@ class Module_Factory {
88
  *
89
  * @var Abstract_Module $module_object Module instance.
90
  */
91
- $module_object = new $class( $product );
92
 
93
  if ( ! $module_object->can_load( $product ) ) {
94
  continue;
88
  *
89
  * @var Abstract_Module $module_object Module instance.
90
  */
91
+ $module_object = new $class( $product );
92
 
93
  if ( ! $module_object->can_load( $product ) ) {
94
  continue;
vendor/codeinwp/themeisle-sdk/src/Modules/Dashboard_widget.php CHANGED
@@ -96,7 +96,7 @@ class Dashboard_Widget extends Abstract_Module {
96
  *
97
  * @return string|void
98
  */
99
- function add_widget() {
100
  global $wp_meta_boxes;
101
  if ( isset( $wp_meta_boxes['dashboard']['normal']['core']['themeisle'] ) ) {
102
  return;
@@ -114,7 +114,7 @@ class Dashboard_Widget extends Abstract_Module {
114
  /**
115
  * Render widget content
116
  */
117
- function render_dashboard_widget() {
118
  $this->setup_feeds();
119
  if ( empty( $this->items ) || ! is_array( $this->items ) ) {
120
  return;
@@ -220,19 +220,21 @@ class Dashboard_Widget extends Abstract_Module {
220
  <li class="ti-dw-feed-item">
221
  <a href="
222
  <?php
223
- echo add_query_arg(
224
- array(
225
- 'utm_source' => 'wpadmin',
226
- 'utm_campaign' => 'feed',
227
- 'utm_medium' => 'dashboard_widget',
228
- ),
229
- $item['link']
 
 
230
  );
231
  ?>
232
  " target="_blank">
233
  <span class="ti-dw-date-container"><span
234
- class="ti-dw-day-container"><?php echo date( 'd', $item['date'] ); ?></span> <span
235
- class="ti-dw-month-container"><?php echo substr( date( 'M', $item['date'] ), 0, 3 ); ?></span></span><?php echo $item['title']; ?>
236
  </a>
237
  </li>
238
  <?php
@@ -275,26 +277,28 @@ class Dashboard_Widget extends Abstract_Module {
275
  ?>
276
  <div class="ti-dw-footer">
277
  <span class="ti-dw-recommend-item ">
278
- <span class="ti-dw-recommend"><?php echo apply_filters( 'themeisle_sdk_dashboard_popular_label', sprintf( 'Popular %s', ucwords( $type ) ) ); ?>
279
  : </span>
280
  <?php
281
- echo trim(
282
- str_replace(
283
- array(
284
- 'lite',
285
- 'Lite',
286
- '(Lite)',
287
- '(lite)',
288
- ),
289
- '',
290
- $recommend['name']
 
 
291
  )
292
  );
293
  ?>
294
  (<a class="thickbox open-plugin-details-modal"
295
- href="<?php echo $url . '&TB_iframe=true&width=600&height=500'; ?>"><?php echo apply_filters( 'themeisle_sdk_dashboard_install_label', 'Install' ); ?></a>)
296
  </span>
297
- <span class="ti-dw-powered-by"><span><?php echo apply_filters( 'themeisle_sdk_dashboard_widget_powered_by', esc_attr( sprintf( 'Powered by %s', $this->product->get_friendly_name() ) ) ); ?></span></span>
298
  </div>
299
 
300
  <?php
@@ -305,7 +309,7 @@ class Dashboard_Widget extends Abstract_Module {
305
  * Setup feed items.
306
  */
307
  private function setup_feeds() {
308
- if ( false === ( $items_normalized = get_transient( 'themeisle_sdk_feed_items' ) ) ) {
309
  // Load SimplePie Instance.
310
  $feed = fetch_feed( $this->feeds );
311
  // TODO report error when is an error loading the feed.
@@ -353,7 +357,7 @@ class Dashboard_Widget extends Abstract_Module {
353
  /**
354
  * Contact the API and fetch the recommended plugins/themes
355
  */
356
- function recommend_plugin_or_theme() {
357
  $products = $this->get_product_from_api();
358
  if ( ! is_array( $products ) ) {
359
  $products = array();
@@ -374,8 +378,8 @@ class Dashboard_Widget extends Abstract_Module {
374
  *
375
  * @return array|mixed The list of products to use in recomended section.
376
  */
377
- function get_product_from_api() {
378
- if ( false === ( $products = get_transient( 'themeisle_sdk_products' ) ) ) {
379
  $products = array();
380
  $all_themes = $this->get_themes_from_wporg( 'themeisle' );
381
  $all_plugins = $this->get_plugins_from_wporg( 'themeisle' );
@@ -429,8 +433,8 @@ class Dashboard_Widget extends Abstract_Module {
429
  *
430
  * @return array The list of themes.
431
  */
432
- function get_themes_from_wporg( $author ) {
433
- $products = wp_remote_get(
434
  'https://api.wordpress.org/themes/info/1.1/?action=query_themes&request[author]=' . $author . '&request[per_page]=30&request[fields][active_installs]=true'
435
  );
436
  $products = json_decode( wp_remote_retrieve_body( $products ) );
@@ -450,8 +454,8 @@ class Dashboard_Widget extends Abstract_Module {
450
  *
451
  * @return array The list of plugins for the selected author.
452
  */
453
- function get_plugins_from_wporg( $author ) {
454
- $products = wp_remote_get(
455
  'https://api.wordpress.org/plugins/info/1.1/?action=query_plugins&request[author]=' . $author . '&request[per_page]=40&request[fields][active_installs]=true'
456
  );
457
  $products = json_decode( wp_remote_retrieve_body( $products ) );
96
  *
97
  * @return string|void
98
  */
99
+ public function add_widget() {
100
  global $wp_meta_boxes;
101
  if ( isset( $wp_meta_boxes['dashboard']['normal']['core']['themeisle'] ) ) {
102
  return;
114
  /**
115
  * Render widget content
116
  */
117
+ public function render_dashboard_widget() {
118
  $this->setup_feeds();
119
  if ( empty( $this->items ) || ! is_array( $this->items ) ) {
120
  return;
220
  <li class="ti-dw-feed-item">
221
  <a href="
222
  <?php
223
+ echo esc_url(
224
+ add_query_arg(
225
+ array(
226
+ 'utm_source' => 'wpadmin',
227
+ 'utm_campaign' => 'feed',
228
+ 'utm_medium' => 'dashboard_widget',
229
+ ),
230
+ $item['link']
231
+ )
232
  );
233
  ?>
234
  " target="_blank">
235
  <span class="ti-dw-date-container"><span
236
+ class="ti-dw-day-container"><?php echo esc_attr( gmdate( 'd', $item['date'] ) ); ?></span> <span
237
+ class="ti-dw-month-container"><?php echo esc_attr( substr( gmdate( 'M', $item['date'] ), 0, 3 ) ); ?></span></span><?php echo esc_attr( $item['title'] ); ?>
238
  </a>
239
  </li>
240
  <?php
277
  ?>
278
  <div class="ti-dw-footer">
279
  <span class="ti-dw-recommend-item ">
280
+ <span class="ti-dw-recommend"><?php echo esc_attr( apply_filters( 'themeisle_sdk_dashboard_popular_label', sprintf( 'Popular %s', ucwords( $type ) ) ) ); ?>
281
  : </span>
282
  <?php
283
+ echo esc_attr(
284
+ trim(
285
+ str_replace(
286
+ array(
287
+ 'lite',
288
+ 'Lite',
289
+ '(Lite)',
290
+ '(lite)',
291
+ ),
292
+ '',
293
+ $recommend['name']
294
+ )
295
  )
296
  );
297
  ?>
298
  (<a class="thickbox open-plugin-details-modal"
299
+ href="<?php echo esc_url( $url . '&TB_iframe=true&width=600&height=500' ); ?>"><?php echo esc_attr( apply_filters( 'themeisle_sdk_dashboard_install_label', 'Install' ) ); ?></a>)
300
  </span>
301
+ <span class="ti-dw-powered-by"><span><?php echo esc_attr( apply_filters( 'themeisle_sdk_dashboard_widget_powered_by', sprintf( 'Powered by %s', $this->product->get_friendly_name() ) ) ); ?></span></span>
302
  </div>
303
 
304
  <?php
309
  * Setup feed items.
310
  */
311
  private function setup_feeds() {
312
+ if ( false === ( $items_normalized = get_transient( 'themeisle_sdk_feed_items' ) ) ) { //phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
313
  // Load SimplePie Instance.
314
  $feed = fetch_feed( $this->feeds );
315
  // TODO report error when is an error loading the feed.
357
  /**
358
  * Contact the API and fetch the recommended plugins/themes
359
  */
360
+ public function recommend_plugin_or_theme() {
361
  $products = $this->get_product_from_api();
362
  if ( ! is_array( $products ) ) {
363
  $products = array();
378
  *
379
  * @return array|mixed The list of products to use in recomended section.
380
  */
381
+ public function get_product_from_api() {
382
+ if ( false === ( $products = get_transient( 'themeisle_sdk_products' ) ) ) { //phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
383
  $products = array();
384
  $all_themes = $this->get_themes_from_wporg( 'themeisle' );
385
  $all_plugins = $this->get_plugins_from_wporg( 'themeisle' );
433
  *
434
  * @return array The list of themes.
435
  */
436
+ public function get_themes_from_wporg( $author ) {
437
+ $products = $this->safe_get(
438
  'https://api.wordpress.org/themes/info/1.1/?action=query_themes&request[author]=' . $author . '&request[per_page]=30&request[fields][active_installs]=true'
439
  );
440
  $products = json_decode( wp_remote_retrieve_body( $products ) );
454
  *
455
  * @return array The list of plugins for the selected author.
456
  */
457
+ public function get_plugins_from_wporg( $author ) {
458
+ $products = $this->safe_get(
459
  'https://api.wordpress.org/plugins/info/1.1/?action=query_plugins&request[author]=' . $author . '&request[per_page]=40&request[fields][active_installs]=true'
460
  );
461
  $products = json_decode( wp_remote_retrieve_body( $products ) );
vendor/codeinwp/themeisle-sdk/src/Modules/Licenser.php CHANGED
@@ -62,6 +62,12 @@ class Licenser extends Abstract_Module {
62
  * @var null Local license object.
63
  */
64
  private $license_local = null;
 
 
 
 
 
 
65
 
66
  /**
67
  * Disable wporg updates for premium products.
@@ -71,7 +77,7 @@ class Licenser extends Abstract_Module {
71
  *
72
  * @return mixed List of themes to check for update.
73
  */
74
- function disable_wporg_update( $r, $url ) {
75
 
76
  if ( 0 !== strpos( $url, 'https://api.wordpress.org/themes/update-check/' ) ) {
77
  return $r;
@@ -83,7 +89,7 @@ class Licenser extends Abstract_Module {
83
  unset( $themes->themes->{$this->product->get_slug()} );
84
 
85
  // Encode the updated JSON response.
86
- $r['body']['themes'] = json_encode( $themes );
87
 
88
  return $r;
89
  }
@@ -172,18 +178,18 @@ class Licenser extends Abstract_Module {
172
  <?php
173
  echo sprintf(
174
  '<p>%s<input class="themeisle-sdk-license-input %s" type="text" id="%s_license" name="%s_license" value="%s" /><a class="%s">%s</a>&nbsp;&nbsp;&nbsp;<button name="%s_btn_trigger" class="button button-primary themeisle-sdk-licenser-button-cta" value="yes" type="submit" >%s</button></p><p class="description">%s</p>%s',
175
- ( ( 'valid' === $status ) ? sprintf( '<input type="hidden" value="%s" name="%s_license" />', $value, $this->product->get_key() ) : '' ),
176
  ( ( 'valid' === $status ) ? 'themeisle-sdk-text-input-valid' : '' ),
177
- $this->product->get_key(),
178
- ( ( 'valid' === $status ) ? $this->product->get_key() . '_mask' : $this->product->get_key() ),
179
- ( ( 'valid' === $status ) ? ( str_repeat( '*', 30 ) . substr( $value, - 5 ) ) : $value ),
180
- ( 'valid' === $status ? 'themeisle-sdk-license-deactivate-cta' : 'themeisle-sdk-license-activate-cta' ),
181
- ( 'valid' === $status ? $valid_string : $invalid_string ),
182
- $this->product->get_key(),
183
- ( 'valid' === $status ? $deactivate_string : $activate_string ),
184
- sprintf( $license_message, '<a href="' . $this->get_api_url() . '">' . $this->get_distributor_name() . '</a> ', $this->product->get_type() ),
185
- empty( $error_message ) ? '' : sprintf( '<p style="color:#dd3d36">%s</p>', $error_message )
186
- );
187
 
188
  }
189
 
@@ -210,17 +216,12 @@ class Licenser extends Abstract_Module {
210
  }
211
 
212
  /**
213
- * License price id.
214
  *
215
- * @return int License plan.
216
  */
217
- public function get_plan() {
218
- $license_data = get_option( $this->product->get_key() . '_license_data', '' );
219
- if ( ! isset( $license_data->price_id ) ) {
220
- return -1;
221
- }
222
-
223
- return (int) $license_data->price_id;
224
  }
225
 
226
  /**
@@ -249,12 +250,26 @@ class Licenser extends Abstract_Module {
249
  return $this->product->get_store_name();
250
  }
251
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  /**
253
  * Show the admin notice regarding the license status.
254
  *
255
  * @return bool Should we show the notice ?
256
  */
257
- function show_notice() {
258
  if ( ! is_admin() ) {
259
  return false;
260
  }
@@ -274,10 +289,10 @@ class Licenser extends Abstract_Module {
274
  <p><strong>
275
  <?php
276
  echo sprintf(
277
- $no_activations_string,
278
- $this->product->get_name(),
279
- $this->product->get_name(),
280
- '<a href="' . $this->get_api_url() . '" target="_blank">' . $this->get_distributor_name() . '</a>'
281
  );
282
  ?>
283
  </strong>
@@ -292,7 +307,7 @@ class Licenser extends Abstract_Module {
292
  ?>
293
  <div class="error">
294
  <p>
295
- <strong><?php echo sprintf( $expired_license_string, $this->product->get_name() . ' ' . $this->product->get_type(), $this->get_api_url() . '?license=' . $this->license_key ); ?> </strong>
296
  </p>
297
  </div>
298
  <?php
@@ -304,7 +319,7 @@ class Licenser extends Abstract_Module {
304
  ?>
305
  <div class="error">
306
  <p>
307
- <strong><?php echo sprintf( $no_valid_string, $this->product->get_name() . ' ' . $this->product->get_type(), $this->get_api_url(), admin_url( 'options-general.php' ) . '#' . $this->product->get_key() . '_license' ); ?> </strong>
308
  </p>
309
  </div>
310
  <?php
@@ -335,7 +350,7 @@ class Licenser extends Abstract_Module {
335
  *
336
  * @return bool
337
  */
338
- function check_expiration() {
339
  $license_data = get_option( $this->product->get_key() . '_license_data', '' );
340
  if ( '' === $license_data ) {
341
  return false;
@@ -355,7 +370,7 @@ class Licenser extends Abstract_Module {
355
  *
356
  * @return string The renew url.
357
  */
358
- function renew_url() {
359
  $license_data = get_option( $this->product->get_key() . '_license_data', '' );
360
  if ( '' === $license_data ) {
361
  return $this->get_api_url();
@@ -371,7 +386,7 @@ class Licenser extends Abstract_Module {
371
  * Run the license check call.
372
  */
373
  public function product_valid() {
374
- if ( false !== ( $license = get_transient( $this->product->get_key() . '_license_data' ) ) ) {
375
  return;
376
  }
377
  $license = $this->check_license();
@@ -423,42 +438,6 @@ class Licenser extends Abstract_Module {
423
 
424
  }
425
 
426
- /**
427
- * Increment the failed checks.
428
- */
429
- private function increment_failed_checks() {
430
- $this->failed_checks ++;
431
- update_option( $this->product->get_key() . '_failed_checks', $this->failed_checks );
432
- }
433
-
434
- /**
435
- * Reset the failed checks
436
- */
437
- private function reset_failed_checks() {
438
- $this->failed_checks = 1;
439
- update_option( $this->product->get_key() . '_failed_checks', $this->failed_checks );
440
- }
441
-
442
- /**
443
- * Set license validation error message.
444
- *
445
- * @param string $message Error message.
446
- */
447
- public function set_error( $message = '' ) {
448
- set_transient( $this->product->get_key() . 'act_err', $message, MINUTE_IN_SECONDS );
449
-
450
- return;
451
- }
452
-
453
- /**
454
- * Return the last error message.
455
- *
456
- * @return mixed Error message.
457
- */
458
- public function get_error() {
459
- return get_transient( $this->product->get_key() . 'act_err' );
460
- }
461
-
462
  /**
463
  * Do license activation/deactivation.
464
  *
@@ -486,7 +465,7 @@ class Licenser extends Abstract_Module {
486
 
487
  // Call the custom API.
488
  if ( 'check' === $action ) {
489
- $response = wp_remote_get( sprintf( '%slicense/check/%s/%s/%s/%s', Product::API_URL, rawurlencode( $this->product->get_name() ), $license, rawurlencode( home_url() ), Loader::get_cache_token() ) );
490
  } else {
491
  $response = wp_remote_post(
492
  sprintf( '%slicense/%s/%s/%s', Product::API_URL, $action, rawurlencode( $this->product->get_name() ), $license ),
@@ -550,15 +529,42 @@ class Licenser extends Abstract_Module {
550
  return true;
551
  }
552
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
553
  /**
554
  * Activate the license remotely.
555
  */
556
- function process_license() {
557
  // listen for our activate button to be clicked.
558
  if ( ! isset( $_POST[ $this->product->get_key() . '_btn_trigger' ] ) ) {
559
  return;
560
  }
561
- $license = $_POST[ $this->product->get_key() . '_license' ];
 
 
 
 
 
 
 
 
 
 
 
562
  $response = $this->do_license_process( $license, 'toggle' );
563
  if ( is_wp_error( $response ) ) {
564
  $this->set_error( $response->get_error_message() );
@@ -568,14 +574,22 @@ class Licenser extends Abstract_Module {
568
  if ( true === $response ) {
569
  $this->set_error( '' );
570
  }
 
 
 
 
 
 
 
 
 
571
 
572
- return;
573
  }
574
 
575
  /**
576
  * Load the Themes screen.
577
  */
578
- function load_themes_screen() {
579
  add_thickbox();
580
  add_action( 'admin_notices', array( &$this, 'update_nag' ) );
581
  }
@@ -583,7 +597,7 @@ class Licenser extends Abstract_Module {
583
  /**
584
  * Alter the nag for themes update.
585
  */
586
- function update_nag() {
587
  $theme = wp_get_theme( $this->product->get_slug() );
588
  $api_response = get_transient( $this->product_key );
589
  if ( false === $api_response || ! isset( $api_response->new_version ) ) {
@@ -596,16 +610,16 @@ class Licenser extends Abstract_Module {
596
  echo '<div id="update-nag">';
597
  printf(
598
  '<strong>%1$s %2$s</strong> is available. <a href="%3$s" class="thickbox" title="%4s">Check out what\'s new</a> or <a href="%5$s"%6$s>update now</a>.',
599
- $theme->get( 'Name' ),
600
- $api_response->new_version,
601
- sprintf( '%s&TB_iframe=true&amp;width=1024&amp;height=800', $this->product->get_changelog() ),
602
- $theme->get( 'Name' ),
603
- $update_url,
604
- $update_onclick
605
  );
606
  echo '</div>';
607
- echo '<div id="' . $this->product->get_slug() . '_' . 'changelog" style="display:none;">';
608
- echo wpautop( $api_response->sections['changelog'] );
609
  echo '</div>';
610
  }
611
  }
@@ -617,7 +631,7 @@ class Licenser extends Abstract_Module {
617
  *
618
  * @return mixed
619
  */
620
- function theme_update_transient( $value ) {
621
  $update_data = $this->check_for_update();
622
  if ( $update_data ) {
623
  $value->response[ $this->product->get_slug() ] = $update_data;
@@ -631,7 +645,7 @@ class Licenser extends Abstract_Module {
631
  *
632
  * @return array|bool Either the update data or false in case of failure.
633
  */
634
- function check_for_update() {
635
  $update_data = get_transient( $this->product_key );
636
 
637
  if ( false === $update_data ) {
@@ -669,7 +683,7 @@ class Licenser extends Abstract_Module {
669
  */
670
  private function get_version_data() {
671
 
672
- $response = wp_remote_get(
673
  sprintf(
674
  '%slicense/version/%s/%s/%s/%s',
675
  Product::API_URL,
@@ -679,7 +693,7 @@ class Licenser extends Abstract_Module {
679
  rawurlencode( home_url() )
680
  ),
681
  array(
682
- 'timeout' => 15,
683
  'sslverify' => false,
684
  )
685
  );
@@ -706,8 +720,8 @@ class Licenser extends Abstract_Module {
706
  /**
707
  * Delete the update transient
708
  */
709
- function delete_theme_update_transient() {
710
- delete_transient( $this->product_key );
711
  }
712
 
713
  /**
@@ -727,6 +741,8 @@ class Licenser extends Abstract_Module {
727
  if ( false !== $api_response && is_object( $api_response ) && isset( $api_response->new_version ) ) {
728
  if ( version_compare( $this->product->get_version(), $api_response->new_version, '<' ) ) {
729
  $_transient_data->response[ $this->product->get_slug() . '/' . $this->product->get_file() ] = $api_response;
 
 
730
  }
731
  }
732
 
@@ -782,7 +798,7 @@ class Licenser extends Abstract_Module {
782
  *
783
  * @return array $array
784
  */
785
- function http_request_args( $args, $url ) {
786
  // If it is an https request and we are performing a package download, disable ssl verification.
787
  if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
788
  $args['sslverify'] = false;
@@ -829,6 +845,7 @@ class Licenser extends Abstract_Module {
829
  $namespace = apply_filters( 'themesle_sdk_namespace_' . md5( $product->get_basefile() ), false );
830
 
831
  if ( false !== $namespace ) {
 
832
  add_filter( 'themeisle_sdk_license_process_' . $namespace, [ $this, 'do_license_process' ], 10, 2 );
833
  add_filter( 'product_' . $namespace . '_license_status', [ $this, 'get_license_status' ], PHP_INT_MAX );
834
  add_filter( 'product_' . $namespace . '_license_key', [ $this->product, 'get_license' ] );
@@ -850,17 +867,17 @@ class Licenser extends Abstract_Module {
850
  ]
851
  );
852
  add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
853
- add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 );
854
 
855
  return $this;
856
  }
857
  if ( $this->product->is_theme() ) {
858
  add_filter( 'site_transient_update_themes', array( &$this, 'theme_update_transient' ) );
859
- add_filter( 'delete_site_transient_update_themes', array( &$this, 'delete_theme_update_transient' ) );
860
  add_action( 'load-update-core.php', array( &$this, 'delete_theme_update_transient' ) );
861
  add_action( 'load-themes.php', array( &$this, 'delete_theme_update_transient' ) );
862
  add_action( 'load-themes.php', array( &$this, 'load_themes_screen' ) );
863
- add_filter( 'http_request_args', array( $this, 'disable_wporg_update' ), 5, 2 );
864
 
865
  return $this;
866
 
@@ -870,42 +887,74 @@ class Licenser extends Abstract_Module {
870
  }
871
 
872
  /**
873
- * Run license activation on plugin activate.
874
  */
875
- public function auto_activate() {
876
- if ( ! current_user_can( 'switch_themes' ) ) {
877
- return;
878
- }
879
- $status = $this->get_license_status();
880
- if ( 'not_active' !== $status ) {
881
- return;
882
- }
 
 
 
 
 
 
883
 
884
  $license_file = dirname( $this->product->get_basefile() ) . '/license.json';
885
 
886
  global $wp_filesystem;
887
  if ( ! is_file( $license_file ) ) {
888
- return;
889
  }
890
 
891
- require_once( ABSPATH . '/wp-admin/includes/file.php' );
892
  \WP_Filesystem();
893
  $content = json_decode( $wp_filesystem->get_contents( $license_file ) );
894
  if ( ! is_object( $content ) ) {
895
- return;
896
  }
897
  if ( ! isset( $content->key ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
898
  return;
899
  }
900
- $this->license_local = $content;
 
 
901
  $lock_key = $this->product->get_key() . '_autoactivated';
902
 
903
  if ( 'yes' === get_option( $lock_key, '' ) ) {
904
  return;
905
  }
906
- $response = $this->do_license_process( $content->key, 'activate' );
 
 
 
907
 
908
- update_option( $lock_key, 'yes' );
909
 
910
  if ( apply_filters( $this->product->get_key() . '_hide_license_notices', false ) ) {
911
  return;
@@ -922,7 +971,7 @@ class Licenser extends Abstract_Module {
922
  public function autoactivate_notice() {
923
  ?>
924
  <div class="notice notice-success is-dismissible">
925
- <p><?php echo sprintf( '<strong>%s</strong> has been successfully activated using <strong>%s</strong> license !', $this->product->get_name(), str_repeat( '*', 20 ) . substr( $this->license_local->key, - 10 ) ); ?></p>
926
  </div>
927
  <?php
928
  }
@@ -989,15 +1038,4 @@ class Licenser extends Abstract_Module {
989
 
990
  \WP_CLI::halt( 1 );
991
  }
992
-
993
- /**
994
- * Register license fields for the products.
995
- */
996
- public function register_license_hooks() {
997
- add_action( 'admin_init', array( $this, 'register_settings' ) );
998
- add_action( 'admin_init', array( $this, 'process_license' ) );
999
- add_action( 'admin_init', array( $this, 'product_valid' ), 99999999 );
1000
- add_action( 'admin_notices', array( $this, 'show_notice' ) );
1001
- add_filter( $this->product->get_key() . '_license_status', array( $this, 'get_license_status' ) );
1002
- }
1003
  }
62
  * @var null Local license object.
63
  */
64
  private $license_local = null;
65
+ /**
66
+ * Product namespace, used for fixed name filters/cli commands.
67
+ *
68
+ * @var string $namespace Product namespace.
69
+ */
70
+ private $namespace = null;
71
 
72
  /**
73
  * Disable wporg updates for premium products.
77
  *
78
  * @return mixed List of themes to check for update.
79
  */
80
+ public function disable_wporg_update( $r, $url ) {
81
 
82
  if ( 0 !== strpos( $url, 'https://api.wordpress.org/themes/update-check/' ) ) {
83
  return $r;
89
  unset( $themes->themes->{$this->product->get_slug()} );
90
 
91
  // Encode the updated JSON response.
92
+ $r['body']['themes'] = wp_json_encode( $themes );
93
 
94
  return $r;
95
  }
178
  <?php
179
  echo sprintf(
180
  '<p>%s<input class="themeisle-sdk-license-input %s" type="text" id="%s_license" name="%s_license" value="%s" /><a class="%s">%s</a>&nbsp;&nbsp;&nbsp;<button name="%s_btn_trigger" class="button button-primary themeisle-sdk-licenser-button-cta" value="yes" type="submit" >%s</button></p><p class="description">%s</p>%s',
181
+ ( ( 'valid' === $status ) ? sprintf( '<input type="hidden" value="%s" name="%s_license" />', esc_attr( $value ), esc_attr( $this->product->get_key() ) ) : '' ),
182
  ( ( 'valid' === $status ) ? 'themeisle-sdk-text-input-valid' : '' ),
183
+ esc_attr( $this->product->get_key() ),
184
+ esc_attr( ( ( 'valid' === $status ) ? $this->product->get_key() . '_mask' : $this->product->get_key() ) ),
185
+ esc_attr( ( ( 'valid' === $status ) ? ( str_repeat( '*', 30 ) . substr( $value, - 5 ) ) : $value ) ),
186
+ esc_attr( ( 'valid' === $status ? 'themeisle-sdk-license-deactivate-cta' : 'themeisle-sdk-license-activate-cta' ) ),
187
+ esc_attr( 'valid' === $status ? $valid_string : $invalid_string ),
188
+ esc_attr( $this->product->get_key() ),
189
+ esc_attr( 'valid' === $status ? $deactivate_string : $activate_string ),
190
+ sprintf( wp_kses_data( $license_message ), '<a href="' . esc_url( $this->get_api_url() ) . '">' . esc_attr( $this->get_distributor_name() ) . '</a> ', esc_attr( $this->product->get_type() ) ),
191
+ wp_kses_data( empty( $error_message ) ? '' : sprintf( '<p style="color:#dd3d36">%s</p>', ( $error_message ) ) )
192
+ ) . wp_nonce_field( $this->product->get_key() . 'nonce', $this->product->get_key() . 'nonce_field', false, false );//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
193
 
194
  }
195
 
216
  }
217
 
218
  /**
219
+ * Return the last error message.
220
  *
221
+ * @return mixed Error message.
222
  */
223
+ public function get_error() {
224
+ return get_transient( $this->product->get_key() . 'act_err' );
 
 
 
 
 
225
  }
226
 
227
  /**
250
  return $this->product->get_store_name();
251
  }
252
 
253
+ /**
254
+ * License price id.
255
+ *
256
+ * @return int License plan.
257
+ */
258
+ public function get_plan() {
259
+ $license_data = get_option( $this->product->get_key() . '_license_data', '' );
260
+ if ( ! isset( $license_data->price_id ) ) {
261
+ return - 1;
262
+ }
263
+
264
+ return (int) $license_data->price_id;
265
+ }
266
+
267
  /**
268
  * Show the admin notice regarding the license status.
269
  *
270
  * @return bool Should we show the notice ?
271
  */
272
+ public function show_notice() {
273
  if ( ! is_admin() ) {
274
  return false;
275
  }
289
  <p><strong>
290
  <?php
291
  echo sprintf(
292
+ wp_kses_data( $no_activations_string ),
293
+ esc_attr( $this->product->get_name() ),
294
+ esc_attr( $this->product->get_name() ),
295
+ '<a href="' . esc_url( $this->get_api_url() ) . '" target="_blank">' . esc_attr( $this->get_distributor_name() ) . '</a>'
296
  );
297
  ?>
298
  </strong>
307
  ?>
308
  <div class="error">
309
  <p>
310
+ <strong><?php echo sprintf( wp_kses_data( $expired_license_string ), esc_attr( $this->product->get_name() . ' ' . $this->product->get_type() ), esc_url( $this->get_api_url() . '?license=' . $this->license_key ) ); ?> </strong>
311
  </p>
312
  </div>
313
  <?php
319
  ?>
320
  <div class="error">
321
  <p>
322
+ <strong><?php echo sprintf( wp_kses_data( $no_valid_string ), esc_attr( $this->product->get_name() . ' ' . $this->product->get_type() ), esc_url( $this->get_api_url() ), esc_url( admin_url( 'options-general.php' ) . '#' . $this->product->get_key() . '_license' ) ); ?> </strong>
323
  </p>
324
  </div>
325
  <?php
350
  *
351
  * @return bool
352
  */
353
+ public function check_expiration() {
354
  $license_data = get_option( $this->product->get_key() . '_license_data', '' );
355
  if ( '' === $license_data ) {
356
  return false;
370
  *
371
  * @return string The renew url.
372
  */
373
+ public function renew_url() {
374
  $license_data = get_option( $this->product->get_key() . '_license_data', '' );
375
  if ( '' === $license_data ) {
376
  return $this->get_api_url();
386
  * Run the license check call.
387
  */
388
  public function product_valid() {
389
+ if ( false !== ( $license = get_transient( $this->product->get_key() . '_license_data' ) ) ) { //phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
390
  return;
391
  }
392
  $license = $this->check_license();
438
 
439
  }
440
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  /**
442
  * Do license activation/deactivation.
443
  *
465
 
466
  // Call the custom API.
467
  if ( 'check' === $action ) {
468
+ $response = $this->safe_get( sprintf( '%slicense/check/%s/%s/%s/%s', Product::API_URL, rawurlencode( $this->product->get_name() ), $license, rawurlencode( home_url() ), Loader::get_cache_token() ) );
469
  } else {
470
  $response = wp_remote_post(
471
  sprintf( '%slicense/%s/%s/%s', Product::API_URL, $action, rawurlencode( $this->product->get_name() ), $license ),
529
  return true;
530
  }
531
 
532
+ /**
533
+ * Reset the failed checks
534
+ */
535
+ private function reset_failed_checks() {
536
+ $this->failed_checks = 1;
537
+ update_option( $this->product->get_key() . '_failed_checks', $this->failed_checks );
538
+ }
539
+
540
+ /**
541
+ * Increment the failed checks.
542
+ */
543
+ private function increment_failed_checks() {
544
+ $this->failed_checks ++;
545
+ update_option( $this->product->get_key() . '_failed_checks', $this->failed_checks );
546
+ }
547
+
548
  /**
549
  * Activate the license remotely.
550
  */
551
+ public function process_license() {
552
  // listen for our activate button to be clicked.
553
  if ( ! isset( $_POST[ $this->product->get_key() . '_btn_trigger' ] ) ) {
554
  return;
555
  }
556
+ if ( ! isset( $_POST[ $this->product->get_key() . 'nonce_field' ] )
557
+ || ! wp_verify_nonce( $_POST[ $this->product->get_key() . 'nonce_field' ], $this->product->get_key() . 'nonce' ) //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
558
+ ) {
559
+ return;
560
+ }
561
+ if ( ! current_user_can( 'manage_options' ) ) {
562
+ return;
563
+ }
564
+ $license = isset( $_POST[ $this->product->get_key() . '_license' ] )
565
+ ? sanitize_text_field( $_POST[ $this->product->get_key() . '_license' ] )
566
+ : '';
567
+
568
  $response = $this->do_license_process( $license, 'toggle' );
569
  if ( is_wp_error( $response ) ) {
570
  $this->set_error( $response->get_error_message() );
574
  if ( true === $response ) {
575
  $this->set_error( '' );
576
  }
577
+ }
578
+
579
+ /**
580
+ * Set license validation error message.
581
+ *
582
+ * @param string $message Error message.
583
+ */
584
+ public function set_error( $message = '' ) {
585
+ set_transient( $this->product->get_key() . 'act_err', $message, MINUTE_IN_SECONDS );
586
 
 
587
  }
588
 
589
  /**
590
  * Load the Themes screen.
591
  */
592
+ public function load_themes_screen() {
593
  add_thickbox();
594
  add_action( 'admin_notices', array( &$this, 'update_nag' ) );
595
  }
597
  /**
598
  * Alter the nag for themes update.
599
  */
600
+ public function update_nag() {
601
  $theme = wp_get_theme( $this->product->get_slug() );
602
  $api_response = get_transient( $this->product_key );
603
  if ( false === $api_response || ! isset( $api_response->new_version ) ) {
610
  echo '<div id="update-nag">';
611
  printf(
612
  '<strong>%1$s %2$s</strong> is available. <a href="%3$s" class="thickbox" title="%4s">Check out what\'s new</a> or <a href="%5$s"%6$s>update now</a>.',
613
+ esc_attr( $theme->get( 'Name' ) ),
614
+ esc_attr( $api_response->new_version ),
615
+ esc_url( sprintf( '%s&TB_iframe=true&amp;width=1024&amp;height=800', $this->product->get_changelog() ) ),
616
+ esc_attr( $theme->get( 'Name' ) ),
617
+ esc_url( $update_url ),
618
+ $update_onclick // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Already escaped.
619
  );
620
  echo '</div>';
621
+ echo '<div id="' . esc_attr( $this->product->get_slug() ) . '_changelog" style="display:none;">';
622
+ echo wp_kses_data( wpautop( $api_response->sections['changelog'] ) );
623
  echo '</div>';
624
  }
625
  }
631
  *
632
  * @return mixed
633
  */
634
+ public function theme_update_transient( $value ) {
635
  $update_data = $this->check_for_update();
636
  if ( $update_data ) {
637
  $value->response[ $this->product->get_slug() ] = $update_data;
645
  *
646
  * @return array|bool Either the update data or false in case of failure.
647
  */
648
+ public function check_for_update() {
649
  $update_data = get_transient( $this->product_key );
650
 
651
  if ( false === $update_data ) {
683
  */
684
  private function get_version_data() {
685
 
686
+ $response = $this->safe_get(
687
  sprintf(
688
  '%slicense/version/%s/%s/%s/%s',
689
  Product::API_URL,
693
  rawurlencode( home_url() )
694
  ),
695
  array(
696
+ 'timeout' => 15, //phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout, Inherited by wp_remote_get only, for vip environment we use defaults.
697
  'sslverify' => false,
698
  )
699
  );
720
  /**
721
  * Delete the update transient
722
  */
723
+ public function delete_theme_update_transient() {
724
+ return delete_transient( $this->product_key );
725
  }
726
 
727
  /**
741
  if ( false !== $api_response && is_object( $api_response ) && isset( $api_response->new_version ) ) {
742
  if ( version_compare( $this->product->get_version(), $api_response->new_version, '<' ) ) {
743
  $_transient_data->response[ $this->product->get_slug() . '/' . $this->product->get_file() ] = $api_response;
744
+ } else {
745
+ $_transient_data->no_update[ $this->product->get_slug() . '/' . $this->product->get_file() ] = $api_response;
746
  }
747
  }
748
 
798
  *
799
  * @return array $array
800
  */
801
+ public function http_request_args( $args, $url ) {
802
  // If it is an https request and we are performing a package download, disable ssl verification.
803
  if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
804
  $args['sslverify'] = false;
845
  $namespace = apply_filters( 'themesle_sdk_namespace_' . md5( $product->get_basefile() ), false );
846
 
847
  if ( false !== $namespace ) {
848
+ $this->namespace = $namespace;
849
  add_filter( 'themeisle_sdk_license_process_' . $namespace, [ $this, 'do_license_process' ], 10, 2 );
850
  add_filter( 'product_' . $namespace . '_license_status', [ $this, 'get_license_status' ], PHP_INT_MAX );
851
  add_filter( 'product_' . $namespace . '_license_key', [ $this->product, 'get_license' ] );
867
  ]
868
  );
869
  add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
870
+ add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 ); //phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args
871
 
872
  return $this;
873
  }
874
  if ( $this->product->is_theme() ) {
875
  add_filter( 'site_transient_update_themes', array( &$this, 'theme_update_transient' ) );
876
+ add_action( 'delete_site_transient_update_themes', array( &$this, 'delete_theme_update_transient' ) );
877
  add_action( 'load-update-core.php', array( &$this, 'delete_theme_update_transient' ) );
878
  add_action( 'load-themes.php', array( &$this, 'delete_theme_update_transient' ) );
879
  add_action( 'load-themes.php', array( &$this, 'load_themes_screen' ) );
880
+ add_filter( 'http_request_args', array( $this, 'disable_wporg_update' ), 5, 2 ); //phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args
881
 
882
  return $this;
883
 
887
  }
888
 
889
  /**
890
+ * Register license fields for the products.
891
  */
892
+ public function register_license_hooks() {
893
+ add_action( 'admin_init', array( $this, 'register_settings' ) );
894
+ add_action( 'admin_init', array( $this, 'process_license' ) );
895
+ add_action( 'admin_init', array( $this, 'product_valid' ), 99999999 );
896
+ add_action( 'admin_notices', array( $this, 'show_notice' ) );
897
+ add_filter( $this->product->get_key() . '_license_status', array( $this, 'get_license_status' ) );
898
+ }
899
+
900
+ /**
901
+ * Check license on filesystem.
902
+ *
903
+ * @return mixed License key.
904
+ */
905
+ public function get_file_license() {
906
 
907
  $license_file = dirname( $this->product->get_basefile() ) . '/license.json';
908
 
909
  global $wp_filesystem;
910
  if ( ! is_file( $license_file ) ) {
911
+ return false;
912
  }
913
 
914
+ require_once ABSPATH . '/wp-admin/includes/file.php';
915
  \WP_Filesystem();
916
  $content = json_decode( $wp_filesystem->get_contents( $license_file ) );
917
  if ( ! is_object( $content ) ) {
918
+ return false;
919
  }
920
  if ( ! isset( $content->key ) ) {
921
+ return false;
922
+ }
923
+ return $content->key;
924
+ }
925
+ /**
926
+ * Run license activation on plugin activate.
927
+ */
928
+ public function auto_activate() {
929
+ $status = $this->get_license_status();
930
+ if ( 'not_active' !== $status ) {
931
+ return false;
932
+ }
933
+
934
+ if ( ! empty( $this->namespace ) ) {
935
+ $license_key = apply_filters( 'product_' . $this->namespace . '_license_key_constant', '' );
936
+ }
937
+
938
+ if ( empty( $license_key ) ) {
939
+ $license_key = $this->get_file_license();
940
+ }
941
+ if ( empty( $license_key ) ) {
942
  return;
943
  }
944
+
945
+
946
+ $this->license_local = $license_key;
947
  $lock_key = $this->product->get_key() . '_autoactivated';
948
 
949
  if ( 'yes' === get_option( $lock_key, '' ) ) {
950
  return;
951
  }
952
+ if ( 'yes' === get_transient( $lock_key ) ) {
953
+ return;
954
+ }
955
+ $response = $this->do_license_process( $license_key, 'activate' );
956
 
957
+ set_transient( $lock_key, 'yes', 6 * HOUR_IN_SECONDS );
958
 
959
  if ( apply_filters( $this->product->get_key() . '_hide_license_notices', false ) ) {
960
  return;
971
  public function autoactivate_notice() {
972
  ?>
973
  <div class="notice notice-success is-dismissible">
974
+ <p><?php echo sprintf( '<strong>%s</strong> has been successfully activated using <strong>%s</strong> license !', esc_attr( $this->product->get_name() ), esc_attr( str_repeat( '*', 20 ) . substr( $this->license_local, - 10 ) ) ); ?></p>
975
  </div>
976
  <?php
977
  }
1038
 
1039
  \WP_CLI::halt( 1 );
1040
  }
 
 
 
 
 
 
 
 
 
 
 
1041
  }
vendor/codeinwp/themeisle-sdk/src/Modules/Logger.php CHANGED
@@ -78,7 +78,7 @@ class Logger extends Abstract_Module {
78
  }
79
  $action_key = $this->product->get_key() . '_log_activity';
80
  if ( ! wp_next_scheduled( $action_key ) ) {
81
- wp_schedule_single_event( time() + ( rand( 1, 24 ) * 3600 ), $action_key );
82
  }
83
  add_action( $action_key, array( $this, 'send_log' ) );
84
 
78
  }
79
  $action_key = $this->product->get_key() . '_log_activity';
80
  if ( ! wp_next_scheduled( $action_key ) ) {
81
+ wp_schedule_single_event( time() + ( wp_rand( 1, 24 ) * 3600 ), $action_key );
82
  }
83
  add_action( $action_key, array( $this, 'send_log' ) );
84
 
vendor/codeinwp/themeisle-sdk/src/Modules/Notification.php CHANGED
@@ -84,7 +84,7 @@ class Notification extends Abstract_Module {
84
  $notification_html = self::get_notification_html( $notification_details );
85
  do_action( $notification_details['id'] . '_before_render' );
86
 
87
- echo $notification_html;
88
 
89
  do_action( $notification_details['id'] . '_after_render' );
90
  self::render_snippets();
@@ -340,7 +340,7 @@ class Notification extends Abstract_Module {
340
  $.post(
341
  ajaxurl,
342
  {
343
- 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
344
  'action': 'themeisle_sdk_dismiss_notice',
345
  'id': notification_id,
346
  'confirm': confirm
@@ -365,7 +365,7 @@ class Notification extends Abstract_Module {
365
  /**
366
  * Dismiss the notification.
367
  */
368
- static function dismiss() {
369
  check_ajax_referer( (string) __CLASS__, 'nonce' );
370
 
371
  $id = isset( $_POST['id'] ) ? sanitize_text_field( $_POST['id'] ) : '';
84
  $notification_html = self::get_notification_html( $notification_details );
85
  do_action( $notification_details['id'] . '_before_render' );
86
 
87
+ echo $notification_html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, already escaped internally.
88
 
89
  do_action( $notification_details['id'] . '_after_render' );
90
  self::render_snippets();
340
  $.post(
341
  ajaxurl,
342
  {
343
+ 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
344
  'action': 'themeisle_sdk_dismiss_notice',
345
  'id': notification_id,
346
  'confirm': confirm
365
  /**
366
  * Dismiss the notification.
367
  */
368
+ public static function dismiss() {
369
  check_ajax_referer( (string) __CLASS__, 'nonce' );
370
 
371
  $id = isset( $_POST['id'] ) ? sanitize_text_field( $_POST['id'] ) : '';
vendor/codeinwp/themeisle-sdk/src/Modules/Recommendation.php CHANGED
@@ -64,7 +64,7 @@ class Recommendation extends Abstract_Module {
64
  * @param array $strings - list of translated strings.
65
  * @param array $preferences - list of preferences.
66
  */
67
- function render_products_box( $plugins_list, $themes_list, $strings, $preferences = array() ) {
68
 
69
  if ( empty( $plugins_list ) && empty( $themes_list ) ) {
70
  return;
@@ -90,7 +90,7 @@ class Recommendation extends Abstract_Module {
90
 
91
  foreach ( $list as $theme ) {
92
  echo '<div class="plugin_box">';
93
- echo ' <img class="theme-banner" src="' . $theme->screenshot_url . '">';
94
  echo ' <div class="title-action-wrapper">';
95
  echo ' <span class="plugin-name">' . esc_html( $theme->custom_name ) . '</span>';
96
  if ( ! isset( $preferences['description'] ) || ( isset( $preferences['description'] ) && $preferences['description'] ) ) {
@@ -118,7 +118,7 @@ class Recommendation extends Abstract_Module {
118
 
119
  foreach ( $list as $current_plugin ) {
120
  echo '<div class="plugin_box">';
121
- echo ' <img class="plugin-banner" src="' . $current_plugin->custom_image . '">';
122
  echo ' <div class="title-action-wrapper">';
123
  echo ' <span class="plugin-name">' . esc_html( $current_plugin->custom_name ) . '</span>';
124
  if ( ! isset( $preferences['description'] ) || ( isset( $preferences['description'] ) && $preferences['description'] ) ) {
@@ -185,7 +185,7 @@ class Recommendation extends Abstract_Module {
185
  return $theme;
186
  }
187
 
188
- $products = wp_remote_get(
189
  'https://api.wordpress.org/themes/info/1.1/?action=query_themes&request[theme]=' . $slug . '&request[per_page]=1'
190
  );
191
  $products = json_decode( wp_remote_retrieve_body( $products ) );
@@ -246,7 +246,7 @@ class Recommendation extends Abstract_Module {
246
  * @return array|mixed|object
247
  */
248
  private function call_plugin_api( $slug ) {
249
- include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
250
 
251
  $call_api = get_transient( 'ti_plugin_info_' . $slug );
252
 
@@ -303,27 +303,30 @@ class Recommendation extends Abstract_Module {
303
  }
304
 
305
  .recommend-product .theme-banner {
306
- width:200px;
307
  margin: auto;
308
  }
 
309
  .recommend-product .plugin-banner {
310
  width: 100px;
311
  margin: auto;
312
  }
313
 
314
- .recommend-product .plugin_box .button span{
315
 
316
  margin-top: 2px;
317
  margin-right: 7px;
318
  }
319
- .recommend-product .plugin_box .button{
320
- margin-bottom:10px;
 
321
  }
 
322
  .recommend-product .plugin_box {
323
  margin-bottom: 20px;
324
  padding-top: 5px;
325
  display: flex;
326
- box-shadow: 0px 0px 10px -5px rgba(0,0,0,0.55);
327
  background: #fff;
328
  border-radius: 5px;
329
  flex-direction: column;
64
  * @param array $strings - list of translated strings.
65
  * @param array $preferences - list of preferences.
66
  */
67
+ public function render_products_box( $plugins_list, $themes_list, $strings, $preferences = array() ) {
68
 
69
  if ( empty( $plugins_list ) && empty( $themes_list ) ) {
70
  return;
90
 
91
  foreach ( $list as $theme ) {
92
  echo '<div class="plugin_box">';
93
+ echo ' <img class="theme-banner" src="' . esc_url( $theme->screenshot_url ) . '">';
94
  echo ' <div class="title-action-wrapper">';
95
  echo ' <span class="plugin-name">' . esc_html( $theme->custom_name ) . '</span>';
96
  if ( ! isset( $preferences['description'] ) || ( isset( $preferences['description'] ) && $preferences['description'] ) ) {
118
 
119
  foreach ( $list as $current_plugin ) {
120
  echo '<div class="plugin_box">';
121
+ echo ' <img class="plugin-banner" src="' . esc_url( $current_plugin->custom_image ) . '">';
122
  echo ' <div class="title-action-wrapper">';
123
  echo ' <span class="plugin-name">' . esc_html( $current_plugin->custom_name ) . '</span>';
124
  if ( ! isset( $preferences['description'] ) || ( isset( $preferences['description'] ) && $preferences['description'] ) ) {
185
  return $theme;
186
  }
187
 
188
+ $products = $this->safe_get(
189
  'https://api.wordpress.org/themes/info/1.1/?action=query_themes&request[theme]=' . $slug . '&request[per_page]=1'
190
  );
191
  $products = json_decode( wp_remote_retrieve_body( $products ) );
246
  * @return array|mixed|object
247
  */
248
  private function call_plugin_api( $slug ) {
249
+ include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
250
 
251
  $call_api = get_transient( 'ti_plugin_info_' . $slug );
252
 
303
  }
304
 
305
  .recommend-product .theme-banner {
306
+ width: 200px;
307
  margin: auto;
308
  }
309
+
310
  .recommend-product .plugin-banner {
311
  width: 100px;
312
  margin: auto;
313
  }
314
 
315
+ .recommend-product .plugin_box .button span {
316
 
317
  margin-top: 2px;
318
  margin-right: 7px;
319
  }
320
+
321
+ .recommend-product .plugin_box .button {
322
+ margin-bottom: 10px;
323
  }
324
+
325
  .recommend-product .plugin_box {
326
  margin-bottom: 20px;
327
  padding-top: 5px;
328
  display: flex;
329
+ box-shadow: 0px 0px 10px -5px rgba(0, 0, 0, 0.55);
330
  background: #fff;
331
  border-radius: 5px;
332
  flex-direction: column;
vendor/codeinwp/themeisle-sdk/src/Modules/Rollback.php CHANGED
@@ -120,7 +120,9 @@ class Rollback extends Abstract_Module {
120
  if ( empty( $url ) ) {
121
  return [];
122
  }
123
- $response = wp_remote_get( $url );
 
 
124
  if ( is_wp_error( $response ) ) {
125
  return array();
126
  }
@@ -191,7 +193,7 @@ class Rollback extends Abstract_Module {
191
  * Start the rollback operation.
192
  */
193
  public function start_rollback() {
194
- if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], $this->product->get_key() . '_rollback' ) ) {
195
  wp_nonce_ays( '' );
196
  }
197
 
@@ -233,7 +235,7 @@ class Rollback extends Abstract_Module {
233
 
234
  if ( false === $transient ) {
235
  set_transient( $this->product->get_key() . '_warning_rollback', 'in progress', 30 );
236
- require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
237
  $title = sprintf( apply_filters( $this->product->get_key() . '_rollback_message', 'Rolling back %s to v%s' ), $this->product->get_name(), $version );
238
  $plugin = $plugin_folder . '/' . $plugin_file;
239
  $nonce = 'upgrade-plugin_' . $plugin;
@@ -244,7 +246,7 @@ class Rollback extends Abstract_Module {
244
  delete_transient( $this->product->get_key() . '_warning_rollback' );
245
  wp_die(
246
  '',
247
- $title,
248
  array(
249
  'response' => 200,
250
  )
@@ -276,7 +278,7 @@ class Rollback extends Abstract_Module {
276
 
277
  if ( false === $transient ) {
278
  set_transient( $this->product->get_key() . '_warning_rollback', 'in progress', 30 );
279
- require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
280
  $title = sprintf( apply_filters( $this->product->get_key() . '_rollback_message', 'Rolling back %s to v%s' ), $this->product->get_name(), $version );
281
  $theme = $folder . '/style.css';
282
  $nonce = 'upgrade-theme_' . $theme;
@@ -287,7 +289,7 @@ class Rollback extends Abstract_Module {
287
  delete_transient( $this->product->get_key() . '_warning_rollback' );
288
  wp_die(
289
  '',
290
- $title,
291
  array(
292
  'response' => 200,
293
  )
@@ -341,7 +343,7 @@ class Rollback extends Abstract_Module {
341
  * @return bool Which version is greater?
342
  */
343
  public function sort_rollback_array( $a, $b ) {
344
- return version_compare( $a['version'], $b['version'], '<' ) > 0;
345
  }
346
 
347
  /**
120
  if ( empty( $url ) ) {
121
  return [];
122
  }
123
+ $response = function_exists( 'wp_remote_get_wp_remote_get' )
124
+ ? wp_remote_get_wp_remote_get( $url )
125
+ : wp_remote_get( $url ); //phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_remote_get_wp_remote_get
126
  if ( is_wp_error( $response ) ) {
127
  return array();
128
  }
193
  * Start the rollback operation.
194
  */
195
  public function start_rollback() {
196
+ if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], $this->product->get_key() . '_rollback' ) ) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
197
  wp_nonce_ays( '' );
198
  }
199
 
235
 
236
  if ( false === $transient ) {
237
  set_transient( $this->product->get_key() . '_warning_rollback', 'in progress', 30 );
238
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
239
  $title = sprintf( apply_filters( $this->product->get_key() . '_rollback_message', 'Rolling back %s to v%s' ), $this->product->get_name(), $version );
240
  $plugin = $plugin_folder . '/' . $plugin_file;
241
  $nonce = 'upgrade-plugin_' . $plugin;
246
  delete_transient( $this->product->get_key() . '_warning_rollback' );
247
  wp_die(
248
  '',
249
+ esc_attr( $title ),
250
  array(
251
  'response' => 200,
252
  )
278
 
279
  if ( false === $transient ) {
280
  set_transient( $this->product->get_key() . '_warning_rollback', 'in progress', 30 );
281
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
282
  $title = sprintf( apply_filters( $this->product->get_key() . '_rollback_message', 'Rolling back %s to v%s' ), $this->product->get_name(), $version );
283
  $theme = $folder . '/style.css';
284
  $nonce = 'upgrade-theme_' . $theme;
289
  delete_transient( $this->product->get_key() . '_warning_rollback' );
290
  wp_die(
291
  '',
292
+ esc_attr( $title ),
293
  array(
294
  'response' => 200,
295
  )
343
  * @return bool Which version is greater?
344
  */
345
  public function sort_rollback_array( $a, $b ) {
346
+ return version_compare( $b['version'], $a['version'] );
347
  }
348
 
349
  /**
vendor/codeinwp/themeisle-sdk/src/Modules/Translate.php CHANGED
@@ -805,7 +805,7 @@ class Translate extends Abstract_Module {
805
  $translations = get_transient( $cache_key );
806
 
807
  if ( false === $translations ) {
808
- require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
809
  $translations = translations_api(
810
  $product->get_type() . 's',
811
  array(
805
  $translations = get_transient( $cache_key );
806
 
807
  if ( false === $translations ) {
808
+ require_once ABSPATH . 'wp-admin/includes/translation-install.php';
809
  $translations = translations_api(
810
  $product->get_type() . 's',
811
  array(
vendor/codeinwp/themeisle-sdk/src/Modules/Uninstall_feedback.php CHANGED
@@ -132,7 +132,7 @@ class Uninstall_Feedback extends Abstract_Module {
132
  /**
133
  * Loads the additional resources
134
  */
135
- function load_resources() {
136
  $screen = get_current_screen();
137
 
138
  if ( ! $screen || ! in_array( $screen->id, array( 'theme-install', 'plugins' ) ) ) {
@@ -178,7 +178,7 @@ class Uninstall_Feedback extends Abstract_Module {
178
  echo wp_kses_post( $info_disclosure_link );
179
  echo wp_kses_post( $this->get_disclosure_labels() );
180
  echo '<div class="buttons">';
181
- echo get_submit_button(
182
  $button_submit,
183
  'secondary',
184
  $this->product->get_key() . 'ti-deactivate-yes',
@@ -414,7 +414,7 @@ class Uninstall_Feedback extends Abstract_Module {
414
  display: block;
415
  }
416
 
417
- tr[data-plugin^="<?php echo $this->product->get_slug(); ?>"] .deactivate {
418
  position: relative;
419
  }
420
 
@@ -475,20 +475,20 @@ class Uninstall_Feedback extends Abstract_Module {
475
  var radio = $(this);
476
  if (radio.parent().find('textarea').length > 0 &&
477
  radio.parent().find('textarea').val().length === 0) {
478
- $('#<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
479
  radio.parent().find('textarea').on('keyup', function (e) {
480
  if ($(this).val().length === 0) {
481
- $('#<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
482
  } else {
483
- $('#<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled');
484
  }
485
  });
486
  } else {
487
- $('#<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled');
488
  }
489
  });
490
 
491
- $('#<?php echo $key; ?>ti-deactivate-yes').on('click', function (e) {
492
  e.preventDefault();
493
  e.stopPropagation();
494
 
@@ -496,7 +496,7 @@ class Uninstall_Feedback extends Abstract_Module {
496
  '.ti-theme-uninstall-feedback-drawer input[name="ti-deactivate-option"]:checked');
497
  $.post(ajaxurl, {
498
  'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>',
499
- 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
500
  'id': selectedOption.parent().attr('ti-option-id'),
501
  'msg': selectedOption.parent().find('textarea').val(),
502
  'type': 'theme',
@@ -529,12 +529,12 @@ class Uninstall_Feedback extends Abstract_Module {
529
  <li ti-option-id="<?php echo esc_attr( $attributes['id'] ); ?>">
530
  <input type="radio" name="ti-deactivate-option" id="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
531
  <label for="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
532
- <?php echo str_replace( '{theme}', $this->product->get_name(), $title ); ?>
533
  </label>
534
  <?php
535
  if ( array_key_exists( 'type', $attributes ) ) {
536
  $placeholder = array_key_exists( 'placeholder', $attributes ) ? $attributes['placeholder'] : '';
537
- echo '<textarea width="100%" rows="' . $inputs_row_map[ $attributes['type'] ] . '" name="comments" placeholder="' . esc_attr( $placeholder ) . '"></textarea>';
538
  }
539
  ?>
540
  </li>
@@ -567,13 +567,13 @@ class Uninstall_Feedback extends Abstract_Module {
567
  echo wp_kses_post( $info_disclosure_link );
568
  echo wp_kses_post( $this->get_disclosure_labels() );
569
  echo '<div class="buttons">';
570
- echo get_submit_button(
571
  $button_cancel,
572
  'secondary',
573
  $this->product->get_key() . 'ti-deactivate-no',
574
  false
575
  );
576
- echo get_submit_button(
577
  $button_submit,
578
  'primary',
579
  $this->product->get_key() . 'ti-deactivate-yes',
@@ -602,7 +602,7 @@ class Uninstall_Feedback extends Abstract_Module {
602
  <script type="text/javascript" id="ti-deactivate-js">
603
  (function ($) {
604
  $(document).ready(function () {
605
- var targetElement = 'tr[data-plugin^="<?php echo $this->product->get_slug(); ?>/"] span.deactivate a';
606
  var redirectUrl = $(targetElement).attr('href');
607
  if ($('.ti-feedback-overlay').length === 0) {
608
  $('body').prepend('<div class="ti-feedback-overlay"></div>');
@@ -628,20 +628,20 @@ class Uninstall_Feedback extends Abstract_Module {
628
  var radio = $(this);
629
  if (radio.parent().find('textarea').length > 0 &&
630
  radio.parent().find('textarea').val().length === 0) {
631
- $('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
632
  radio.parent().find('textarea').on('keyup', function (e) {
633
  if ($(this).val().length === 0) {
634
- $('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
635
  } else {
636
- $('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled');
637
  }
638
  });
639
  } else {
640
- $('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled');
641
  }
642
  });
643
 
644
- $('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-no').on('click', function (e) {
645
  e.preventDefault();
646
  e.stopPropagation();
647
  $(targetElement).unbind('click');
@@ -652,7 +652,7 @@ class Uninstall_Feedback extends Abstract_Module {
652
  }
653
  });
654
 
655
- $('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').on('click', function (e) {
656
  e.preventDefault();
657
  e.stopPropagation();
658
  $(targetElement).unbind('click');
@@ -660,7 +660,7 @@ class Uninstall_Feedback extends Abstract_Module {
660
  '<?php echo esc_attr( $popup_id ); ?> input[name="ti-deactivate-option"]:checked');
661
  var data = {
662
  'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>',
663
- 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
664
  'id': selectedOption.parent().attr('ti-option-id'),
665
  'msg': selectedOption.parent().find('textarea').val(),
666
  'type': 'plugin',
@@ -725,7 +725,7 @@ class Uninstall_Feedback extends Abstract_Module {
725
  *
726
  * @param array $options The options array.
727
  */
728
- function randomize_options( $options ) {
729
  $new = array();
730
  $keys = array_keys( $options );
731
  shuffle( $keys );
@@ -740,7 +740,7 @@ class Uninstall_Feedback extends Abstract_Module {
740
  /**
741
  * Called when the deactivate button is clicked.
742
  */
743
- function post_deactivate() {
744
  check_ajax_referer( (string) __CLASS__, 'nonce' );
745
 
746
  $this->post_deactivate_or_cancel();
@@ -754,8 +754,8 @@ class Uninstall_Feedback extends Abstract_Module {
754
  $this->call_api(
755
  array(
756
  'type' => 'deactivate',
757
- 'id' => $_POST['id'],
758
- 'comment' => isset( $_POST['msg'] ) ? $_POST['msg'] : '',
759
  )
760
  );
761
  wp_send_json( [] );
@@ -766,14 +766,14 @@ class Uninstall_Feedback extends Abstract_Module {
766
  * Called when the deactivate/cancel button is clicked.
767
  */
768
  private function post_deactivate_or_cancel() {
769
- if ( ! isset( $_POST['type'] ) || ! isset( $_POST['key'] ) ) {
770
  return;
771
  }
772
- if ( 'theme' !== $_POST['type'] ) {
773
  return;
774
  }
775
 
776
- set_transient( 'ti_sdk_pause_' . $_POST['key'], true, self::PAUSE_DEACTIVATE_WINDOW_DAYS * DAY_IN_SECONDS );
777
 
778
  }
779
 
132
  /**
133
  * Loads the additional resources
134
  */
135
+ public function load_resources() {
136
  $screen = get_current_screen();
137
 
138
  if ( ! $screen || ! in_array( $screen->id, array( 'theme-install', 'plugins' ) ) ) {
178
  echo wp_kses_post( $info_disclosure_link );
179
  echo wp_kses_post( $this->get_disclosure_labels() );
180
  echo '<div class="buttons">';
181
+ echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function has an internal sanitization.
182
  $button_submit,
183
  'secondary',
184
  $this->product->get_key() . 'ti-deactivate-yes',
414
  display: block;
415
  }
416
 
417
+ tr[data-plugin^="<?php echo esc_attr( $this->product->get_slug() ); ?>"] .deactivate {
418
  position: relative;
419
  }
420
 
475
  var radio = $(this);
476
  if (radio.parent().find('textarea').length > 0 &&
477
  radio.parent().find('textarea').val().length === 0) {
478
+ $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
479
  radio.parent().find('textarea').on('keyup', function (e) {
480
  if ($(this).val().length === 0) {
481
+ $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
482
  } else {
483
+ $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
484
  }
485
  });
486
  } else {
487
+ $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
488
  }
489
  });
490
 
491
+ $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').on('click', function (e) {
492
  e.preventDefault();
493
  e.stopPropagation();
494
 
496
  '.ti-theme-uninstall-feedback-drawer input[name="ti-deactivate-option"]:checked');
497
  $.post(ajaxurl, {
498
  'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>',
499
+ 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
500
  'id': selectedOption.parent().attr('ti-option-id'),
501
  'msg': selectedOption.parent().find('textarea').val(),
502
  'type': 'theme',
529
  <li ti-option-id="<?php echo esc_attr( $attributes['id'] ); ?>">
530
  <input type="radio" name="ti-deactivate-option" id="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
531
  <label for="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
532
+ <?php echo esc_attr( str_replace( '{theme}', $this->product->get_name(), $title ) ); ?>
533
  </label>
534
  <?php
535
  if ( array_key_exists( 'type', $attributes ) ) {
536
  $placeholder = array_key_exists( 'placeholder', $attributes ) ? $attributes['placeholder'] : '';
537
+ echo '<textarea width="100%" rows="' . esc_attr( $inputs_row_map[ $attributes['type'] ] ) . '" name="comments" placeholder="' . esc_attr( $placeholder ) . '"></textarea>';
538
  }
539
  ?>
540
  </li>
567
  echo wp_kses_post( $info_disclosure_link );
568
  echo wp_kses_post( $this->get_disclosure_labels() );
569
  echo '<div class="buttons">';
570
+ echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function internals are escaped.
571
  $button_cancel,
572
  'secondary',
573
  $this->product->get_key() . 'ti-deactivate-no',
574
  false
575
  );
576
+ echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function internals are escaped.
577
  $button_submit,
578
  'primary',
579
  $this->product->get_key() . 'ti-deactivate-yes',
602
  <script type="text/javascript" id="ti-deactivate-js">
603
  (function ($) {
604
  $(document).ready(function () {
605
+ var targetElement = 'tr[data-plugin^="<?php echo esc_attr( $this->product->get_slug() ); ?>/"] span.deactivate a';
606
  var redirectUrl = $(targetElement).attr('href');
607
  if ($('.ti-feedback-overlay').length === 0) {
608
  $('body').prepend('<div class="ti-feedback-overlay"></div>');
628
  var radio = $(this);
629
  if (radio.parent().find('textarea').length > 0 &&
630
  radio.parent().find('textarea').val().length === 0) {
631
+ $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
632
  radio.parent().find('textarea').on('keyup', function (e) {
633
  if ($(this).val().length === 0) {
634
+ $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
635
  } else {
636
+ $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
637
  }
638
  });
639
  } else {
640
+ $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
641
  }
642
  });
643
 
644
+ $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-no').on('click', function (e) {
645
  e.preventDefault();
646
  e.stopPropagation();
647
  $(targetElement).unbind('click');
652
  }
653
  });
654
 
655
+ $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').on('click', function (e) {
656
  e.preventDefault();
657
  e.stopPropagation();
658
  $(targetElement).unbind('click');
660
  '<?php echo esc_attr( $popup_id ); ?> input[name="ti-deactivate-option"]:checked');
661
  var data = {
662
  'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>',
663
+ 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
664
  'id': selectedOption.parent().attr('ti-option-id'),
665
  'msg': selectedOption.parent().find('textarea').val(),
666
  'type': 'plugin',
725
  *
726
  * @param array $options The options array.
727
  */
728
+ public function randomize_options( $options ) {
729
  $new = array();
730
  $keys = array_keys( $options );
731
  shuffle( $keys );
740
  /**
741
  * Called when the deactivate button is clicked.
742
  */
743
+ public function post_deactivate() {
744
  check_ajax_referer( (string) __CLASS__, 'nonce' );
745
 
746
  $this->post_deactivate_or_cancel();
754
  $this->call_api(
755
  array(
756
  'type' => 'deactivate',
757
+ 'id' => sanitize_key( $_POST['id'] ),
758
+ 'comment' => isset( $_POST['msg'] ) ? sanitize_textarea_field( $_POST['msg'] ) : '',
759
  )
760
  );
761
  wp_send_json( [] );
766
  * Called when the deactivate/cancel button is clicked.
767
  */
768
  private function post_deactivate_or_cancel() {
769
+ if ( ! isset( $_POST['type'] ) || ! isset( $_POST['key'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing, Nonce already present in caller function.
770
  return;
771
  }
772
+ if ( 'theme' !== $_POST['type'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing, Nonce already present in caller function.
773
  return;
774
  }
775
 
776
+ set_transient( 'ti_sdk_pause_' . sanitize_text_field( $_POST['key'] ), true, self::PAUSE_DEACTIVATE_WINDOW_DAYS * DAY_IN_SECONDS );//phpcs:ignore WordPress.Security.NonceVerification.Missing, Nonce already present in caller function.
777
 
778
  }
779
 
vendor/codeinwp/themeisle-sdk/src/Product.php CHANGED
@@ -157,7 +157,7 @@ class Product {
157
  *
158
  * @return string $name The normalized string.
159
  */
160
- static function key_ready_name( $string ) {
161
  return str_replace( '-', '_', strtolower( trim( $string ) ) );
162
  }
163
 
157
  *
158
  * @return string $name The normalized string.
159
  */
160
+ public static function key_ready_name( $string ) {
161
  return str_replace( '-', '_', strtolower( trim( $string ) ) );
162
  }
163
 
vendor/codeinwp/themeisle-sdk/start.php CHANGED
@@ -13,25 +13,25 @@ namespace ThemeisleSDK;
13
  if ( ! defined( 'ABSPATH' ) ) {
14
  exit;
15
  }
16
- $products = apply_filters( 'themeisle_sdk_products', array() );
17
- $path = dirname( __FILE__ );
18
- $files_to_load = [
19
- $path . '/src/' . 'Loader.php',
20
- $path . '/src/' . 'Product.php',
21
-
22
- $path . '/src/' . 'Common/Abstract_module.php',
23
- $path . '/src/' . 'Common/Module_factory.php',
24
-
25
- $path . '/src/' . 'Modules/Dashboard_widget.php',
26
- $path . '/src/' . 'Modules/Rollback.php',
27
- $path . '/src/' . 'Modules/Uninstall_feedback.php',
28
- $path . '/src/' . 'Modules/Licenser.php',
29
- $path . '/src/' . 'Modules/Endpoint.php',
30
- $path . '/src/' . 'Modules/Notification.php',
31
- $path . '/src/' . 'Modules/Logger.php',
32
- $path . '/src/' . 'Modules/Translate.php',
33
- $path . '/src/' . 'Modules/Review.php',
34
- $path . '/src/' . 'Modules/Recommendation.php',
35
  ];
36
 
37
  $files_to_load = array_merge( $files_to_load, apply_filters( 'themeisle_sdk_required_files', [] ) );
13
  if ( ! defined( 'ABSPATH' ) ) {
14
  exit;
15
  }
16
+ $products = apply_filters( 'themeisle_sdk_products', array() );
17
+ $themeisle_library_path = dirname( __FILE__ );
18
+ $files_to_load = [
19
+ $themeisle_library_path . '/src/Loader.php',
20
+ $themeisle_library_path . '/src/Product.php',
21
+
22
+ $themeisle_library_path . '/src/Common/Abstract_module.php',
23
+ $themeisle_library_path . '/src/Common/Module_factory.php',
24
+
25
+ $themeisle_library_path . '/src/Modules/Dashboard_widget.php',
26
+ $themeisle_library_path . '/src/Modules/Rollback.php',
27
+ $themeisle_library_path . '/src/Modules/Uninstall_feedback.php',
28
+ $themeisle_library_path . '/src/Modules/Licenser.php',
29
+ $themeisle_library_path . '/src/Modules/Endpoint.php',
30
+ $themeisle_library_path . '/src/Modules/Notification.php',
31
+ $themeisle_library_path . '/src/Modules/Logger.php',
32
+ $themeisle_library_path . '/src/Modules/Translate.php',
33
+ $themeisle_library_path . '/src/Modules/Review.php',
34
+ $themeisle_library_path . '/src/Modules/Recommendation.php',
35
  ];
36
 
37
  $files_to_load = array_merge( $files_to_load, apply_filters( 'themeisle_sdk_required_files', [] ) );
vendor/composer/ClassLoader.php CHANGED
@@ -37,11 +37,13 @@ namespace Composer\Autoload;
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
- * @see http://www.php-fig.org/psr/psr-0/
41
- * @see http://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
 
 
45
  // PSR-4
46
  private $prefixLengthsPsr4 = array();
47
  private $prefixDirsPsr4 = array();
@@ -53,13 +55,21 @@ class ClassLoader
53
 
54
  private $useIncludePath = false;
55
  private $classMap = array();
56
-
57
  private $classMapAuthoritative = false;
 
 
 
 
 
 
 
 
 
58
 
59
  public function getPrefixes()
60
  {
61
  if (!empty($this->prefixesPsr0)) {
62
- return call_user_func_array('array_merge', $this->prefixesPsr0);
63
  }
64
 
65
  return array();
@@ -271,6 +281,26 @@ class ClassLoader
271
  return $this->classMapAuthoritative;
272
  }
273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  /**
275
  * Registers this instance as an autoloader.
276
  *
@@ -279,6 +309,17 @@ class ClassLoader
279
  public function register($prepend = false)
280
  {
281
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
 
 
 
 
 
 
 
 
 
 
 
282
  }
283
 
284
  /**
@@ -287,6 +328,10 @@ class ClassLoader
287
  public function unregister()
288
  {
289
  spl_autoload_unregister(array($this, 'loadClass'));
 
 
 
 
290
  }
291
 
292
  /**
@@ -313,34 +358,49 @@ class ClassLoader
313
  */
314
  public function findFile($class)
315
  {
316
- // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
317
- if ('\\' == $class[0]) {
318
- $class = substr($class, 1);
319
- }
320
-
321
  // class map lookup
322
  if (isset($this->classMap[$class])) {
323
  return $this->classMap[$class];
324
  }
325
- if ($this->classMapAuthoritative) {
326
  return false;
327
  }
 
 
 
 
 
 
328
 
329
  $file = $this->findFileWithExtension($class, '.php');
330
 
331
  // Search for Hack files if we are running on HHVM
332
- if ($file === null && defined('HHVM_VERSION')) {
333
  $file = $this->findFileWithExtension($class, '.hh');
334
  }
335
 
336
- if ($file === null) {
 
 
 
 
337
  // Remember that this class does not exist.
338
- return $this->classMap[$class] = false;
339
  }
340
 
341
  return $file;
342
  }
343
 
 
 
 
 
 
 
 
 
 
 
344
  private function findFileWithExtension($class, $ext)
345
  {
346
  // PSR-4 lookup
@@ -348,10 +408,14 @@ class ClassLoader
348
 
349
  $first = $class[0];
350
  if (isset($this->prefixLengthsPsr4[$first])) {
351
- foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
352
- if (0 === strpos($class, $prefix)) {
353
- foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
354
- if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
 
 
 
 
355
  return $file;
356
  }
357
  }
@@ -399,6 +463,8 @@ class ClassLoader
399
  if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
400
  return $file;
401
  }
 
 
402
  }
403
  }
404
 
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see https://www.php-fig.org/psr/psr-0/
41
+ * @see https://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
45
+ private $vendorDir;
46
+
47
  // PSR-4
48
  private $prefixLengthsPsr4 = array();
49
  private $prefixDirsPsr4 = array();
55
 
56
  private $useIncludePath = false;
57
  private $classMap = array();
 
58
  private $classMapAuthoritative = false;
59
+ private $missingClasses = array();
60
+ private $apcuPrefix;
61
+
62
+ private static $registeredLoaders = array();
63
+
64
+ public function __construct($vendorDir = null)
65
+ {
66
+ $this->vendorDir = $vendorDir;
67
+ }
68
 
69
  public function getPrefixes()
70
  {
71
  if (!empty($this->prefixesPsr0)) {
72
+ return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
73
  }
74
 
75
  return array();
281
  return $this->classMapAuthoritative;
282
  }
283
 
284
+ /**
285
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
286
+ *
287
+ * @param string|null $apcuPrefix
288
+ */
289
+ public function setApcuPrefix($apcuPrefix)
290
+ {
291
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
292
+ }
293
+
294
+ /**
295
+ * The APCu prefix in use, or null if APCu caching is not enabled.
296
+ *
297
+ * @return string|null
298
+ */
299
+ public function getApcuPrefix()
300
+ {
301
+ return $this->apcuPrefix;
302
+ }
303
+
304
  /**
305
  * Registers this instance as an autoloader.
306
  *
309
  public function register($prepend = false)
310
  {
311
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
312
+
313
+ if (null === $this->vendorDir) {
314
+ return;
315
+ }
316
+
317
+ if ($prepend) {
318
+ self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
319
+ } else {
320
+ unset(self::$registeredLoaders[$this->vendorDir]);
321
+ self::$registeredLoaders[$this->vendorDir] = $this;
322
+ }
323
  }
324
 
325
  /**
328
  public function unregister()
329
  {
330
  spl_autoload_unregister(array($this, 'loadClass'));
331
+
332
+ if (null !== $this->vendorDir) {
333
+ unset(self::$registeredLoaders[$this->vendorDir]);
334
+ }
335
  }
336
 
337
  /**
358
  */
359
  public function findFile($class)
360
  {
 
 
 
 
 
361
  // class map lookup
362
  if (isset($this->classMap[$class])) {
363
  return $this->classMap[$class];
364
  }
365
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
366
  return false;
367
  }
368
+ if (null !== $this->apcuPrefix) {
369
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
370
+ if ($hit) {
371
+ return $file;
372
+ }
373
+ }
374
 
375
  $file = $this->findFileWithExtension($class, '.php');
376
 
377
  // Search for Hack files if we are running on HHVM
378
+ if (false === $file && defined('HHVM_VERSION')) {
379
  $file = $this->findFileWithExtension($class, '.hh');
380
  }
381
 
382
+ if (null !== $this->apcuPrefix) {
383
+ apcu_add($this->apcuPrefix.$class, $file);
384
+ }
385
+
386
+ if (false === $file) {
387
  // Remember that this class does not exist.
388
+ $this->missingClasses[$class] = true;
389
  }
390
 
391
  return $file;
392
  }
393
 
394
+ /**
395
+ * Returns the currently registered loaders indexed by their corresponding vendor directories.
396
+ *
397
+ * @return self[]
398
+ */
399
+ public static function getRegisteredLoaders()
400
+ {
401
+ return self::$registeredLoaders;
402
+ }
403
+
404
  private function findFileWithExtension($class, $ext)
405
  {
406
  // PSR-4 lookup
408
 
409
  $first = $class[0];
410
  if (isset($this->prefixLengthsPsr4[$first])) {
411
+ $subPath = $class;
412
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
413
+ $subPath = substr($subPath, 0, $lastPos);
414
+ $search = $subPath . '\\';
415
+ if (isset($this->prefixDirsPsr4[$search])) {
416
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
417
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
418
+ if (file_exists($file = $dir . $pathEnd)) {
419
  return $file;
420
  }
421
  }
463
  if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
464
  return $file;
465
  }
466
+
467
+ return false;
468
  }
469
  }
470
 
vendor/composer/InstalledVersions.php ADDED
@@ -0,0 +1,293 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+ namespace Composer;
14
+
15
+ use Composer\Autoload\ClassLoader;
16
+ use Composer\Semver\VersionParser;
17
+
18
+
19
+
20
+
21
+
22
+
23
+ class InstalledVersions
24
+ {
25
+ private static $installed = array (
26
+ 'root' =>
27
+ array (
28
+ 'pretty_version' => 'v3.6.0',
29
+ 'version' => '3.6.0.0',
30
+ 'aliases' =>
31
+ array (
32
+ ),
33
+ 'reference' => '6c087252b667eef5ef9e0777b96c19e17f5bfafe',
34
+ 'name' => 'codeinwp/feedzy-rss-feeds',
35
+ ),
36
+ 'versions' =>
37
+ array (
38
+ 'codeinwp/feedzy-rss-feeds' =>
39
+ array (
40
+ 'pretty_version' => 'v3.6.0',
41
+ 'version' => '3.6.0.0',
42
+ 'aliases' =>
43
+ array (
44
+ ),
45
+ 'reference' => '6c087252b667eef5ef9e0777b96c19e17f5bfafe',
46
+ ),
47
+ 'codeinwp/themeisle-sdk' =>
48
+ array (
49
+ 'pretty_version' => 'dev-master',
50
+ 'version' => 'dev-master',
51
+ 'aliases' =>
52
+ array (
53
+ 0 => '9999999-dev',
54
+ ),
55
+ 'reference' => 'aeef3f159c1b35451d87672b6984ccde36c0d21d',
56
+ ),
57
+ ),
58
+ );
59
+ private static $canGetVendors;
60
+ private static $installedByVendor = array();
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+ public static function getInstalledPackages()
69
+ {
70
+ $packages = array();
71
+ foreach (self::getInstalled() as $installed) {
72
+ $packages[] = array_keys($installed['versions']);
73
+ }
74
+
75
+
76
+ if (1 === \count($packages)) {
77
+ return $packages[0];
78
+ }
79
+
80
+ return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
81
+ }
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+ public static function isInstalled($packageName)
92
+ {
93
+ foreach (self::getInstalled() as $installed) {
94
+ if (isset($installed['versions'][$packageName])) {
95
+ return true;
96
+ }
97
+ }
98
+
99
+ return false;
100
+ }
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+ public static function satisfies(VersionParser $parser, $packageName, $constraint)
116
+ {
117
+ $constraint = $parser->parseConstraints($constraint);
118
+ $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
119
+
120
+ return $provided->matches($constraint);
121
+ }
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+ public static function getVersionRanges($packageName)
133
+ {
134
+ foreach (self::getInstalled() as $installed) {
135
+ if (!isset($installed['versions'][$packageName])) {
136
+ continue;
137
+ }
138
+
139
+ $ranges = array();
140
+ if (isset($installed['versions'][$packageName]['pretty_version'])) {
141
+ $ranges[] = $installed['versions'][$packageName]['pretty_version'];
142
+ }
143
+ if (array_key_exists('aliases', $installed['versions'][$packageName])) {
144
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
145
+ }
146
+ if (array_key_exists('replaced', $installed['versions'][$packageName])) {
147
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
148
+ }
149
+ if (array_key_exists('provided', $installed['versions'][$packageName])) {
150
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
151
+ }
152
+
153
+ return implode(' || ', $ranges);
154
+ }
155
+
156
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
157
+ }
158
+
159
+
160
+
161
+
162
+
163
+ public static function getVersion($packageName)
164
+ {
165
+ foreach (self::getInstalled() as $installed) {
166
+ if (!isset($installed['versions'][$packageName])) {
167
+ continue;
168
+ }
169
+
170
+ if (!isset($installed['versions'][$packageName]['version'])) {
171
+ return null;
172
+ }
173
+
174
+ return $installed['versions'][$packageName]['version'];
175
+ }
176
+
177
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
178
+ }
179
+
180
+
181
+
182
+
183
+
184
+ public static function getPrettyVersion($packageName)
185
+ {
186
+ foreach (self::getInstalled() as $installed) {
187
+ if (!isset($installed['versions'][$packageName])) {
188
+ continue;
189
+ }
190
+
191
+ if (!isset($installed['versions'][$packageName]['pretty_version'])) {
192
+ return null;
193
+ }
194
+
195
+ return $installed['versions'][$packageName]['pretty_version'];
196
+ }
197
+
198
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
199
+ }
200
+
201
+
202
+
203
+
204
+
205
+ public static function getReference($packageName)
206
+ {
207
+ foreach (self::getInstalled() as $installed) {
208
+ if (!isset($installed['versions'][$packageName])) {
209
+ continue;
210
+ }
211
+
212
+ if (!isset($installed['versions'][$packageName]['reference'])) {
213
+ return null;
214
+ }
215
+
216
+ return $installed['versions'][$packageName]['reference'];
217
+ }
218
+
219
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
220
+ }
221
+
222
+
223
+
224
+
225
+
226
+ public static function getRootPackage()
227
+ {
228
+ $installed = self::getInstalled();
229
+
230
+ return $installed[0]['root'];
231
+ }
232
+
233
+
234
+
235
+
236
+
237
+
238
+
239
+ public static function getRawData()
240
+ {
241
+ return self::$installed;
242
+ }
243
+
244
+
245
+
246
+
247
+
248
+
249
+
250
+
251
+
252
+
253
+
254
+
255
+
256
+
257
+
258
+
259
+
260
+
261
+
262
+ public static function reload($data)
263
+ {
264
+ self::$installed = $data;
265
+ self::$installedByVendor = array();
266
+ }
267
+
268
+
269
+
270
+
271
+ private static function getInstalled()
272
+ {
273
+ if (null === self::$canGetVendors) {
274
+ self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
275
+ }
276
+
277
+ $installed = array();
278
+
279
+ if (self::$canGetVendors) {
280
+ foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
281
+ if (isset(self::$installedByVendor[$vendorDir])) {
282
+ $installed[] = self::$installedByVendor[$vendorDir];
283
+ } elseif (is_file($vendorDir.'/composer/installed.php')) {
284
+ $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
285
+ }
286
+ }
287
+ }
288
+
289
+ $installed[] = self::$installed;
290
+
291
+ return $installed;
292
+ }
293
+ }
vendor/composer/LICENSE CHANGED
@@ -1,5 +1,5 @@
1
 
2
- Copyright (c) 2016 Nils Adermann, Jordi Boggiano
3
 
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
  of this software and associated documentation files (the "Software"), to deal
1
 
2
+ Copyright (c) Nils Adermann, Jordi Boggiano
3
 
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
  of this software and associated documentation files (the "Software"), to deal
vendor/composer/autoload_classmap.php CHANGED
@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
9
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
10
  );
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit4f93c5e0c4064494ba1171bd88732555
6
  {
7
  private static $loader;
8
 
@@ -13,43 +13,57 @@ class ComposerAutoloaderInit4f93c5e0c4064494ba1171bd88732555
13
  }
14
  }
15
 
 
 
 
16
  public static function getLoader()
17
  {
18
  if (null !== self::$loader) {
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit4f93c5e0c4064494ba1171bd88732555', 'loadClassLoader'), true, true);
23
- self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit4f93c5e0c4064494ba1171bd88732555', 'loadClassLoader'));
25
 
26
- $map = require __DIR__ . '/autoload_namespaces.php';
27
- foreach ($map as $namespace => $path) {
28
- $loader->set($namespace, $path);
29
- }
30
 
31
- $map = require __DIR__ . '/autoload_psr4.php';
32
- foreach ($map as $namespace => $path) {
33
- $loader->setPsr4($namespace, $path);
34
- }
 
 
35
 
36
- $classMap = require __DIR__ . '/autoload_classmap.php';
37
- if ($classMap) {
38
- $loader->addClassMap($classMap);
 
 
 
 
 
 
39
  }
40
 
41
  $loader->register(true);
42
 
43
- $includeFiles = require __DIR__ . '/autoload_files.php';
 
 
 
 
44
  foreach ($includeFiles as $fileIdentifier => $file) {
45
- composerRequire4f93c5e0c4064494ba1171bd88732555($fileIdentifier, $file);
46
  }
47
 
48
  return $loader;
49
  }
50
  }
51
 
52
- function composerRequire4f93c5e0c4064494ba1171bd88732555($fileIdentifier, $file)
53
  {
54
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
55
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit6219981e6410a5c15ec2675a8b39fd84
6
  {
7
  private static $loader;
8
 
13
  }
14
  }
15
 
16
+ /**
17
+ * @return \Composer\Autoload\ClassLoader
18
+ */
19
  public static function getLoader()
20
  {
21
  if (null !== self::$loader) {
22
  return self::$loader;
23
  }
24
 
25
+ spl_autoload_register(array('ComposerAutoloaderInit6219981e6410a5c15ec2675a8b39fd84', 'loadClassLoader'), true, true);
26
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
27
+ spl_autoload_unregister(array('ComposerAutoloaderInit6219981e6410a5c15ec2675a8b39fd84', 'loadClassLoader'));
28
 
29
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
+ if ($useStaticLoader) {
31
+ require __DIR__ . '/autoload_static.php';
 
32
 
33
+ call_user_func(\Composer\Autoload\ComposerStaticInit6219981e6410a5c15ec2675a8b39fd84::getInitializer($loader));
34
+ } else {
35
+ $map = require __DIR__ . '/autoload_namespaces.php';
36
+ foreach ($map as $namespace => $path) {
37
+ $loader->set($namespace, $path);
38
+ }
39
 
40
+ $map = require __DIR__ . '/autoload_psr4.php';
41
+ foreach ($map as $namespace => $path) {
42
+ $loader->setPsr4($namespace, $path);
43
+ }
44
+
45
+ $classMap = require __DIR__ . '/autoload_classmap.php';
46
+ if ($classMap) {
47
+ $loader->addClassMap($classMap);
48
+ }
49
  }
50
 
51
  $loader->register(true);
52
 
53
+ if ($useStaticLoader) {
54
+ $includeFiles = Composer\Autoload\ComposerStaticInit6219981e6410a5c15ec2675a8b39fd84::$files;
55
+ } else {
56
+ $includeFiles = require __DIR__ . '/autoload_files.php';
57
+ }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
+ composerRequire6219981e6410a5c15ec2675a8b39fd84($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
+ function composerRequire6219981e6410a5c15ec2675a8b39fd84($fileIdentifier, $file)
67
  {
68
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
  require $file;
vendor/composer/autoload_static.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_static.php @generated by Composer
4
+
5
+ namespace Composer\Autoload;
6
+
7
+ class ComposerStaticInit6219981e6410a5c15ec2675a8b39fd84
8
+ {
9
+ public static $files = array (
10
+ '3df8ee254224091c21b9aebb792d2f8b' => __DIR__ . '/..' . '/codeinwp/themeisle-sdk/load.php',
11
+ );
12
+
13
+ public static $classMap = array (
14
+ 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
15
+ );
16
+
17
+ public static function getInitializer(ClassLoader $loader)
18
+ {
19
+ return \Closure::bind(function () use ($loader) {
20
+ $loader->classMap = ComposerStaticInit6219981e6410a5c15ec2675a8b39fd84::$classMap;
21
+
22
+ }, null, ClassLoader::class);
23
+ }
24
+ }
vendor/composer/installed.json CHANGED
@@ -1,44 +1,50 @@
1
- [
2
- {
3
- "name": "codeinwp/themeisle-sdk",
4
- "version": "dev-master",
5
- "version_normalized": "9999999-dev",
6
- "source": {
7
- "type": "git",
8
- "url": "https://github.com/Codeinwp/themeisle-sdk.git",
9
- "reference": "b116dffbe39ea9e37169fdd683bab54c545fe560"
10
- },
11
- "dist": {
12
- "type": "zip",
13
- "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/b116dffbe39ea9e37169fdd683bab54c545fe560",
14
- "reference": "b116dffbe39ea9e37169fdd683bab54c545fe560",
15
- "shasum": ""
16
- },
17
- "require-dev": {
18
- "automattic/vipwpcs": "^1.0.0",
19
- "dealerdirect/phpcodesniffer-composer-installer": "0.7.0",
20
- "phpcompatibility/php-compatibility": "^9",
21
- "squizlabs/php_codesniffer": "^3.3",
22
- "wp-coding-standards/wpcs": "^1"
23
- },
24
- "time": "2020-11-17 08:35:16",
25
- "type": "library",
26
- "installation-source": "source",
27
- "notification-url": "https://packagist.org/downloads/",
28
- "license": [
29
- "GPL-2.0+"
30
- ],
31
- "authors": [
32
- {
33
- "name": "ThemeIsle team",
34
- "email": "friends@themeisle.com",
35
- "homepage": "https://themeisle.com"
36
- }
37
- ],
38
- "description": "ThemeIsle SDK",
39
- "homepage": "https://github.com/Codeinwp/themeisle-sdk",
40
- "keywords": [
41
- "wordpress"
42
- ]
43
- }
44
- ]
 
 
 
 
 
 
1
+ {
2
+ "packages": [
3
+ {
4
+ "name": "codeinwp/themeisle-sdk",
5
+ "version": "dev-master",
6
+ "version_normalized": "dev-master",
7
+ "source": {
8
+ "type": "git",
9
+ "url": "https://github.com/Codeinwp/themeisle-sdk.git",
10
+ "reference": "aeef3f159c1b35451d87672b6984ccde36c0d21d"
11
+ },
12
+ "dist": {
13
+ "type": "zip",
14
+ "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/aeef3f159c1b35451d87672b6984ccde36c0d21d",
15
+ "reference": "aeef3f159c1b35451d87672b6984ccde36c0d21d",
16
+ "shasum": ""
17
+ },
18
+ "require-dev": {
19
+ "codeinwp/phpcs-ruleset": "dev-main"
20
+ },
21
+ "time": "2021-03-30T09:16:29+00:00",
22
+ "default-branch": true,
23
+ "type": "library",
24
+ "installation-source": "dist",
25
+ "notification-url": "https://packagist.org/downloads/",
26
+ "license": [
27
+ "GPL-2.0+"
28
+ ],
29
+ "authors": [
30
+ {
31
+ "name": "ThemeIsle team",
32
+ "email": "friends@themeisle.com",
33
+ "homepage": "https://themeisle.com"
34
+ }
35
+ ],
36
+ "description": "ThemeIsle SDK",
37
+ "homepage": "https://github.com/Codeinwp/themeisle-sdk",
38
+ "keywords": [
39
+ "wordpress"
40
+ ],
41
+ "support": {
42
+ "issues": "https://github.com/Codeinwp/themeisle-sdk/issues",
43
+ "source": "https://github.com/Codeinwp/themeisle-sdk/tree/v3.2.20"
44
+ },
45
+ "install-path": "../codeinwp/themeisle-sdk"
46
+ }
47
+ ],
48
+ "dev": false,
49
+ "dev-package-names": []
50
+ }
vendor/composer/installed.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php return array (
2
+ 'root' =>
3
+ array (
4
+ 'pretty_version' => 'v3.6.0',
5
+ 'version' => '3.6.0.0',
6
+ 'aliases' =>
7
+ array (
8
+ ),
9
+ 'reference' => '6c087252b667eef5ef9e0777b96c19e17f5bfafe',
10
+ 'name' => 'codeinwp/feedzy-rss-feeds',
11
+ ),
12
+ 'versions' =>
13
+ array (
14
+ 'codeinwp/feedzy-rss-feeds' =>
15
+ array (
16
+ 'pretty_version' => 'v3.6.0',
17
+ 'version' => '3.6.0.0',
18
+ 'aliases' =>
19
+ array (
20
+ ),
21
+ 'reference' => '6c087252b667eef5ef9e0777b96c19e17f5bfafe',
22
+ ),
23
+ 'codeinwp/themeisle-sdk' =>
24
+ array (
25
+ 'pretty_version' => 'dev-master',
26
+ 'version' => 'dev-master',
27
+ 'aliases' =>
28
+ array (
29
+ 0 => '9999999-dev',
30
+ ),
31
+ 'reference' => 'aeef3f159c1b35451d87672b6984ccde36c0d21d',
32
+ ),
33
+ ),
34
+ );