Essential Content Types - Version 1.4

Version Description

(Released: December 12, 2018) = * Added: Catch Themes and Catch Plugins tabs in Add themes and Add plugins page respectively * Added: Themes by Catch Themes section under Themes panel in customizer * Bug Fixed: Undefined index when no section is selected for food items * Compatibility check up to version 5.0 * Updated: How to use link

Download this release

Release Info

Developer catchthemes
Plugin Icon Essential Content Types
Version 1.4
Comparing to
See all releases

Code changes from version 1.3 to 1.4

README.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: catchplugins, catchthemes, sakinshrestha, pratikshrestha, maheshma
3
  Donate link: https://catchplugins.com/plugins/essential-content-types-pro/
4
  Tags: custom post types, CPT, CMS, post, types, post type, taxonomy, tax, custom, content types, post types, custom content types, testimonial, portfolio, featured content, service
5
  Requires at least: 4.5
6
- Tested up to: 4.9.6
7
  Stable tag: trunk
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
@@ -195,6 +195,13 @@ Not so easy way (via FTP) :
195
 
196
  == Changelog ==
197
 
 
 
 
 
 
 
 
198
  = 1.3 (Released: July 05, 2018) =
199
  * Added: Default featured-image-size
200
  * Bug fixed: settings_page function found
3
  Donate link: https://catchplugins.com/plugins/essential-content-types-pro/
4
  Tags: custom post types, CPT, CMS, post, types, post type, taxonomy, tax, custom, content types, post types, custom content types, testimonial, portfolio, featured content, service
5
  Requires at least: 4.5
6
+ Tested up to: 5.0
7
  Stable tag: trunk
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
195
 
196
  == Changelog ==
197
 
198
+ = 1.4 (Released: December 12, 2018) =
199
+ * Added: Catch Themes and Catch Plugins tabs in Add themes and Add plugins page respectively
200
+ * Added: Themes by Catch Themes section under Themes panel in customizer
201
+ * Bug Fixed: Undefined index when no section is selected for food items
202
+ * Compatibility check up to version 5.0
203
+ * Updated: How to use link
204
+
205
  = 1.3 (Released: July 05, 2018) =
206
  * Added: Default featured-image-size
207
  * Bug fixed: settings_page function found
admin/class-food-menu.php CHANGED
@@ -1165,7 +1165,7 @@ class Essential_Content_Food_Menu {
1165
  $this->menu_item_loop_header(); // Output the menu's header
1166
  }
1167
 
1168
- $this->menu_item_loop_last_term_id = $this->menu_item_loop_current_term->term_id;
1169
  }
1170
 
1171
  /**
@@ -1192,9 +1192,9 @@ class Essential_Content_Food_Menu {
1192
  function menu_item_loop_header() {
1193
  $this->menu_item_loop_open_element( 'menu_header' );
1194
  $this->menu_item_loop_open_element( 'menu_title' );
1195
- echo esc_html( $this->menu_item_loop_current_term->name ); // @todo tax filter
1196
  $this->menu_item_loop_close_element( 'menu_title' );
1197
- if ( $this->menu_item_loop_current_term->description ) :
1198
  $this->menu_item_loop_open_element( 'menu_description' );
1199
  echo esc_html( $this->menu_item_loop_current_term->description ); // @todo kses, tax filter
1200
  $this->menu_item_loop_close_element( 'menu_description' );
1165
  $this->menu_item_loop_header(); // Output the menu's header
1166
  }
1167
 
1168
+ $this->menu_item_loop_last_term_id = isset( $this->menu_item_loop_current_term->term_id ) ? $this->menu_item_loop_current_term->term_id : '' ;
1169
  }
1170
 
1171
  /**
1192
  function menu_item_loop_header() {
1193
  $this->menu_item_loop_open_element( 'menu_header' );
1194
  $this->menu_item_loop_open_element( 'menu_title' );
1195
+ echo isset( $this->menu_item_loop_current_term->name ) ? esc_html( $this->menu_item_loop_current_term->name ) : ''; // @todo tax filter
1196
  $this->menu_item_loop_close_element( 'menu_title' );
1197
+ if ( isset( $this->menu_item_loop_current_term->description ) && $this->menu_item_loop_current_term->description ) :
1198
  $this->menu_item_loop_open_element( 'menu_description' );
1199
  echo esc_html( $this->menu_item_loop_current_term->description ); // @todo kses, tax filter
1200
  $this->menu_item_loop_close_element( 'menu_description' );
admin/js/our-themes.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ jQuery(document).ready(function($){
2
+ var our_themes = '<li><a href="#" data-sort="catchthemes">Catch Themes</a></li>';
3
+ $('.filter-links').append( our_themes );
4
+ });
admin/partials/dashboard-display.php CHANGED
@@ -43,7 +43,7 @@
43
 
44
  <p><?php printf( esc_html__( '%1$sClick here%2$s to view Portfolio Archive Options.', 'essential-content-types' ) , '<a href ="' . esc_url( admin_url( 'customize.php?autofocus[control]=jetpack_portfolio_title' ) ) . '" target="_blank">', '</a>' ); ?></p>
45
 
46
- <p>For more information on <strong>How to use Portfolio Shortcodes</strong>, <a href="https://catchplugins.com/blog/essential-content-types-plugin/#Portfolio" title="Essential Content Type: Portfolio Shortcode" target="_blank">Click here</a></p>
47
  </div>
48
  </div><!-- #module-portfolio -->
49
  </div><!-- .module-wrap -->
@@ -70,7 +70,7 @@
70
 
71
  <p><?php printf( esc_html__( '%1$sClick here%2$s to view Testimonial Archive Options.', 'essential-content-types' ) , '<a href ="' . esc_url( admin_url( 'customize.php?autofocus[control]=jetpack_testimonials[page-title]' ) ) . '" target="_blank">', '</a>' ); ?></p>
72
 
73
- <p>For more information on <strong>How to use Testimonials Shortcodes</strong>, <a href="https://catchplugins.com/blog/essential-content-types-plugin/#Testimonial" title="Essential Content Type: Testimonial Shortcode" target="_blank">Click here</a></p>
74
  </div>
75
  </div><!-- #module-testimonial -->
76
  </div><!-- .module-wrap -->
@@ -98,7 +98,7 @@
98
 
99
  <p><?php printf( esc_html__( '%1$sClick here%2$s to view Featured Content Archive Options.', 'essential-content-types' ) , '<a href ="' . esc_url( admin_url( 'customize.php?autofocus[control]=featured_content_title' ) ) . '" target="_blank">', '</a>' ); ?></p>
100
 
101
- <p>For more information on <strong>How to use Featured Content Shortcodes</strong>, <a href="https://catchplugins.com/blog/essential-content-types-plugin/#FeaturedContent" title="Essential Content Type: Featured Content Shortcode" target="_blank">Click here</a></p>
102
  </div>
103
  </div><!-- #module-featured-content -->
104
  </div><!-- .module-wrap -->
@@ -126,7 +126,7 @@
126
 
127
  <p><?php printf( esc_html__( '%1$sClick here%2$s to view Service Archive Options.', 'essential-content-types' ) , '<a href ="' . esc_url( admin_url( 'customize.php?autofocus[control]=ect_service_title' ) ) . '" target="_blank">', '</a>' ); ?></p>
128
 
129
- <p>For more information on <strong>How to use Service Shortcodes</strong>, <a href="https://catchplugins.com/blog/essential-content-types-plugin/#Service" title="Essential Content Type: Service Shortcode" target="_blank">Click here</a></p>
130
  </div>
131
  </div><!-- #module-service -->
132
  </div><!-- .module-wrap -->
@@ -154,7 +154,7 @@
154
 
155
  <p><?php esc_html_e( 'Once enabled, Food Menu Items Post Type options will appear on Dashboard Menu', 'essential-content-types' ); ?></p>
156
 
157
- <p>For more information on <strong>How to use Food Menu Shortcodes</strong>, <a href="https://catchplugins.com/blog/added-food-menu-essential-content-types-plugin-pro-free" title="Essential Content Type: Food Menu Shortcode" target="_blank">Click here</a></p>
158
  </div>
159
  </div><!-- #module-food-menu -->
160
  </div><!-- .module-wrap -->
43
 
44
  <p><?php printf( esc_html__( '%1$sClick here%2$s to view Portfolio Archive Options.', 'essential-content-types' ) , '<a href ="' . esc_url( admin_url( 'customize.php?autofocus[control]=jetpack_portfolio_title' ) ) . '" target="_blank">', '</a>' ); ?></p>
45
 
46
+ <p>For more information on <strong>How to use Portfolio Shortcodes</strong>, <a href="https://catchplugins.com/blog/essential-content-types-pro/#Portfolio" title="Essential Content Type: Portfolio Shortcode" target="_blank">Click here</a></p>
47
  </div>
48
  </div><!-- #module-portfolio -->
49
  </div><!-- .module-wrap -->
70
 
71
  <p><?php printf( esc_html__( '%1$sClick here%2$s to view Testimonial Archive Options.', 'essential-content-types' ) , '<a href ="' . esc_url( admin_url( 'customize.php?autofocus[control]=jetpack_testimonials[page-title]' ) ) . '" target="_blank">', '</a>' ); ?></p>
72
 
73
+ <p>For more information on <strong>How to use Testimonials Shortcodes</strong>, <a href="https://catchplugins.com/blog/essential-content-types-pro/#Testimonial" title="Essential Content Type: Testimonial Shortcode" target="_blank">Click here</a></p>
74
  </div>
75
  </div><!-- #module-testimonial -->
76
  </div><!-- .module-wrap -->
98
 
99
  <p><?php printf( esc_html__( '%1$sClick here%2$s to view Featured Content Archive Options.', 'essential-content-types' ) , '<a href ="' . esc_url( admin_url( 'customize.php?autofocus[control]=featured_content_title' ) ) . '" target="_blank">', '</a>' ); ?></p>
100
 
101
+ <p>For more information on <strong>How to use Featured Content Shortcodes</strong>, <a href="https://catchplugins.com/blog/essential-content-types-pro/#FeaturedContent" title="Essential Content Type: Featured Content Shortcode" target="_blank">Click here</a></p>
102
  </div>
103
  </div><!-- #module-featured-content -->
104
  </div><!-- .module-wrap -->
126
 
127
  <p><?php printf( esc_html__( '%1$sClick here%2$s to view Service Archive Options.', 'essential-content-types' ) , '<a href ="' . esc_url( admin_url( 'customize.php?autofocus[control]=ect_service_title' ) ) . '" target="_blank">', '</a>' ); ?></p>
128
 
129
+ <p>For more information on <strong>How to use Service Shortcodes</strong>, <a href="https://catchplugins.com/blog/essential-content-types-pro/#Service" title="Essential Content Type: Service Shortcode" target="_blank">Click here</a></p>
130
  </div>
131
  </div><!-- #module-service -->
132
  </div><!-- .module-wrap -->
154
 
155
  <p><?php esc_html_e( 'Once enabled, Food Menu Items Post Type options will appear on Dashboard Menu', 'essential-content-types' ); ?></p>
156
 
157
+ <p>For more information on <strong>How to use Food Menu Shortcodes</strong>, <a href="https://catchplugins.com/blog/essential-content-types-pro/#FoodMenu" title="Essential Content Type: Food Menu Shortcode" target="_blank">Click here</a></p>
158
  </div>
159
  </div><!-- #module-food-menu -->
160
  </div><!-- .module-wrap -->
ect-templates/content-featured-content.php CHANGED
@@ -15,7 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) {
15
  }
16
  ?>
17
 
18
- <h2 class="featured-content-entry-title entry-title"><a href="<?php echo esc_url( get_permalink() ); ?>" title="<?php echo esc_attr( the_title_attribute( ) ); ?>"><?php the_title(); ?></a></h2>
19
  <?php if ( false != $atts['display_types'] || false != $atts['display_tags'] || false != $atts['display_author'] ) : ?>
20
  <div class="featured-content-entry-meta entry-meta">
21
  <?php
15
  }
16
  ?>
17
 
18
+ <h2 class="featured-content-entry-title entry-title"><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
19
  <?php if ( false != $atts['display_types'] || false != $atts['display_tags'] || false != $atts['display_author'] ) : ?>
20
  <div class="featured-content-entry-meta entry-meta">
21
  <?php
ect-templates/content-portfolio.php CHANGED
@@ -12,7 +12,7 @@ if ( ! defined( 'ABSPATH' ) ) {
12
  echo essential_content_get_portfolio_thumbnail_link( get_the_ID(), 'ect-jetpack-portfolio-featured' );
13
  ?>
14
 
15
- <h2 class="portfolio-entry-title entry-title"><a href="<?php echo esc_url( get_permalink() ); ?>" title="<?php echo esc_attr( the_title_attribute( ) ); ?>"><?php the_title(); ?></a></h2>
16
  <?php if ( false != $atts['display_types'] || false != $atts['display_tags'] || false != $atts['display_author'] ) : ?>
17
  <div class="portfolio-entry-meta entry-meta">
18
  <?php
12
  echo essential_content_get_portfolio_thumbnail_link( get_the_ID(), 'ect-jetpack-portfolio-featured' );
13
  ?>
14
 
15
+ <h2 class="portfolio-entry-title entry-title"><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
16
  <?php if ( false != $atts['display_types'] || false != $atts['display_tags'] || false != $atts['display_author'] ) : ?>
17
  <div class="portfolio-entry-meta entry-meta">
18
  <?php
ect-templates/content-service.php CHANGED
@@ -16,7 +16,7 @@ echo '</pre>'; die();*/
16
  }
17
  ?>
18
 
19
- <h2 class="service-entry-title entry-title"><a href="<?php echo esc_url( get_permalink() ); ?>" title="<?php echo esc_attr( the_title_attribute( ) ); ?>"><?php the_title(); ?></a></h2>
20
  <?php if ( false != $atts['display_types'] || false != $atts['display_tags'] || false != $atts['display_author'] ) : ?>
21
  <div class="service-entry-meta entry-meta">
22
  <?php
16
  }
17
  ?>
18
 
19
+ <h2 class="service-entry-title entry-title"><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
20
  <?php if ( false != $atts['display_types'] || false != $atts['display_tags'] || false != $atts['display_author'] ) : ?>
21
  <div class="service-entry-meta entry-meta">
22
  <?php
essential-content-types.php CHANGED
@@ -16,7 +16,7 @@
16
  * Plugin Name: Essential Content Types
17
  * Plugin URI: https://catchplugins.com/plugins/essential-content-types/
18
  * Description: Essential Content Types allows you to feature the impressive content through different content/post types on your website just the way you want it. These content/post types are missed by the themes in WordPress Theme Directory as the feature falls more towards the plugins’ territory.
19
- * Version: 1.3
20
  * Author: Catch Plugins
21
  * Author URI: https://catchplugins.com
22
  * License: GPL-3.0+
@@ -34,6 +34,24 @@ if ( ! defined( 'WPINC' ) ) {
34
  * The code that runs during plugin activation.
35
  * This action is documented in includes/class-essential-content-types-activator.php
36
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  function activate_essential_content_types() {
38
  $required = 'essential-content-types-pro/essential-content-types-pro.php';
39
  if ( is_plugin_active( $required ) ) {
@@ -175,3 +193,12 @@ function ect_body_classes( $classes ){
175
  return $classes;
176
  }
177
  add_filter( 'body_class', 'ect_body_classes' );
 
 
 
 
 
 
 
 
 
16
  * Plugin Name: Essential Content Types
17
  * Plugin URI: https://catchplugins.com/plugins/essential-content-types/
18
  * Description: Essential Content Types allows you to feature the impressive content through different content/post types on your website just the way you want it. These content/post types are missed by the themes in WordPress Theme Directory as the feature falls more towards the plugins’ territory.
19
+ * Version: 1.4
20
  * Author: Catch Plugins
21
  * Author URI: https://catchplugins.com
22
  * License: GPL-3.0+
34
  * The code that runs during plugin activation.
35
  * This action is documented in includes/class-essential-content-types-activator.php
36
  */
37
+ // The URL of the directory that contains the plugin
38
+ if ( !defined( 'ESSENTIAL_CONTENT_TYPES_URL' ) )
39
+ define( 'ESSENTIAL_CONTENT_TYPES_URL', plugin_dir_url( __FILE__ ) );
40
+
41
+
42
+ // The absolute path of the directory that contains the file
43
+ if ( !defined( 'ESSENTIAL_CONTENT_TYPES_PATH' ) )
44
+ define( 'ESSENTIAL_CONTENT_TYPES_PATH', plugin_dir_path( __FILE__ ) );
45
+
46
+
47
+ // Gets the path to a plugin file or directory, relative to the plugins directory, without the leading and trailing slashes.
48
+ if ( !defined( 'ESSENTIAL_CONTENT_TYPES_BASENAME' ) )
49
+ define( 'ESSENTIAL_CONTENT_TYPES_BASENAME', plugin_basename( __FILE__ ) );
50
+
51
+ /**
52
+ * Make plugin available for translation
53
+ * Translations can be filed in the /languages/ directory
54
+ */
55
  function activate_essential_content_types() {
56
  $required = 'essential-content-types-pro/essential-content-types-pro.php';
57
  if ( is_plugin_active( $required ) ) {
193
  return $classes;
194
  }
195
  add_filter( 'body_class', 'ect_body_classes' );
196
+ /* Adds Catch Themes tab in Add theme page and Themes by Catch Themes in Customizer's change theme option. */
197
+ require plugin_dir_path( __FILE__ ) . 'includes/our-themes.php';
198
+
199
+
200
+ /* Adds Catch Plugins tab in Add theme page. */
201
+ require plugin_dir_path( __FILE__ ) . 'includes/our-plugins.php';
202
+
203
+
204
+
includes/class-essential-content-types.php CHANGED
@@ -69,7 +69,7 @@ class Essential_Content_Types {
69
  public function __construct() {
70
 
71
  $this->plugin_name = 'essential-content-types';
72
- $this->version = '1.2.1';
73
 
74
  $this->load_dependencies();
75
  $this->set_locale();
69
  public function __construct() {
70
 
71
  $this->plugin_name = 'essential-content-types';
72
+ $this->version = '1.4';
73
 
74
  $this->load_dependencies();
75
  $this->set_locale();
includes/our-plugins.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* Adds Catch Plugins tab in Add Plugin page to show all plugins by Catch Plugins in wordpress.org */
3
+ if( ! function_exists( 'add_our_plugins_tab' ) ) {
4
+ function add_our_plugins_tab($tabs) {
5
+ // Add our filter here
6
+ $tabs['catchplugins'] = _x( 'Catch Plugins', 'Plugin Installer' );
7
+
8
+ return $tabs;
9
+ }
10
+ add_filter( 'install_plugins_tabs', 'add_our_plugins_tab', 1 );
11
+ }
12
+
13
+ if( ! function_exists( 'catchplugins' ) ) {
14
+ function catchplugins() {
15
+ /* From CORE Start */
16
+ global $paged, $tab;
17
+ wp_reset_vars( array( 'tab' ) );
18
+
19
+ $defined_class = new WP_Plugin_Install_List_Table();
20
+ $paged = $defined_class->get_pagenum();
21
+
22
+ $per_page = 30;
23
+ //$installed_plugins = catch_get_installed_plugins();
24
+
25
+ $args = array(
26
+ 'page' => $paged,
27
+ 'per_page' => $per_page,
28
+ 'fields' => array(
29
+ 'last_updated' => true,
30
+ 'icons' => true,
31
+ 'active_installs' => true
32
+ ),
33
+ // Send the locale and installed plugin slugs to the API so it can provide context-sensitive results.
34
+ 'locale' => get_user_locale(),
35
+ //'installed_plugins' => array_keys( $installed_plugins ),
36
+ );
37
+ /* From CORE End */
38
+
39
+ // Add author filter for our plugins
40
+ $args['author'] = 'catchplugins';
41
+
42
+ return $args;
43
+ }
44
+ add_filter( "install_plugins_table_api_args_catchplugins", 'catchplugins', 1 );
45
+ }
46
+
47
+ if( ! function_exists( 'cathcplugins_plugins_table' ) ) {
48
+ add_action( 'install_plugins_catchplugins', 'cathcplugins_plugins_table' );
49
+ function cathcplugins_plugins_table() {
50
+ global $wp_list_table;
51
+ printf(
52
+ '<p class="catch-plugins-list">' . __( 'You can use any of our free plugins or premium plugins from <a href="%s" target="_blank">Catch Plugins</a>' ) . '.</p>',
53
+ 'https://catchplugins.com/'
54
+ );
55
+ ?>
56
+ <form id="plugin-filter" method="post">
57
+ <?php $wp_list_table->display(); ?>
58
+ </form>
59
+ <?php
60
+ }
61
+ }
includes/our-themes.php ADDED
@@ -0,0 +1,386 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* Adds Catch Themes tab in Add Theme page to show all themes by Catch Themes in wordpress.org */
3
+ if( ! function_exists( 'wp_ajax_custom_query_themes' ) ) {
4
+ function wp_ajax_custom_query_themes() {
5
+ global $themes_allowedtags, $theme_field_defaults;
6
+
7
+ if ( ! current_user_can( 'install_themes' ) ) {
8
+ wp_send_json_error();
9
+ }
10
+
11
+ $args = wp_parse_args( wp_unslash( $_REQUEST['request'] ), array(
12
+ 'per_page' => 20,
13
+ 'fields' => $theme_field_defaults
14
+ ) );
15
+
16
+ if ( isset( $args['browse'] ) && 'catchthemes' === $args['browse'] && ! isset( $args['user'] ) ) {
17
+ $args['author'] = 'catchthemes';
18
+ }
19
+
20
+ if ( isset( $args['browse'] ) && 'favorites' === $args['browse'] && ! isset( $args['user'] ) ) {
21
+ $user = get_user_option( 'wporg_favorites' );
22
+ if ( $user ) {
23
+ $args['user'] = $user;
24
+ }
25
+ }
26
+
27
+ $old_filter = isset( $args['browse'] ) ? $args['browse'] : 'search';
28
+
29
+ /** This filter is documented in wp-admin/includes/class-wp-theme-install-list-table.php */
30
+ $args = apply_filters( 'install_themes_table_api_args_' . $old_filter, $args );
31
+
32
+ $api = themes_api( 'query_themes', $args );
33
+
34
+ if ( is_wp_error( $api ) ) {
35
+ wp_send_json_error();
36
+ }
37
+
38
+ $update_php = network_admin_url( 'update.php?action=install-theme' );
39
+ foreach ( $api->themes as &$theme ) {
40
+ $theme->install_url = add_query_arg( array(
41
+ 'theme' => $theme->slug,
42
+ '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug )
43
+ ), $update_php );
44
+
45
+ if ( current_user_can( 'switch_themes' ) ) {
46
+ if ( is_multisite() ) {
47
+ $theme->activate_url = add_query_arg( array(
48
+ 'action' => 'enable',
49
+ '_wpnonce' => wp_create_nonce( 'enable-theme_' . $theme->slug ),
50
+ 'theme' => $theme->slug,
51
+ ), network_admin_url( 'themes.php' ) );
52
+ } else {
53
+ $theme->activate_url = add_query_arg( array(
54
+ 'action' => 'activate',
55
+ '_wpnonce' => wp_create_nonce( 'switch-theme_' . $theme->slug ),
56
+ 'stylesheet' => $theme->slug,
57
+ ), admin_url( 'themes.php' ) );
58
+ }
59
+ }
60
+
61
+ if ( ! is_multisite() && current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
62
+ $theme->customize_url = add_query_arg( array(
63
+ 'return' => urlencode( network_admin_url( 'theme-install.php', 'relative' ) ),
64
+ ), wp_customize_url( $theme->slug ) );
65
+ }
66
+
67
+ $theme->name = wp_kses( $theme->name, $themes_allowedtags );
68
+ $theme->author = wp_kses( $theme->author, $themes_allowedtags );
69
+ $theme->version = wp_kses( $theme->version, $themes_allowedtags );
70
+ $theme->description = wp_kses( $theme->description, $themes_allowedtags );
71
+ $theme->stars = wp_star_rating( array( 'rating' => $theme->rating, 'type' => 'percent', 'number' => $theme->num_ratings, 'echo' => false ) );
72
+ $theme->num_ratings = number_format_i18n( $theme->num_ratings );
73
+ $theme->preview_url = set_url_scheme( $theme->preview_url );
74
+ }
75
+
76
+ wp_send_json_success( $api );
77
+ }
78
+ remove_action( 'wp_ajax_query-themes', 'wp_ajax_query_themes', 1 );
79
+ add_action( 'wp_ajax_query-themes', 'wp_ajax_custom_query_themes', 1 );
80
+ }
81
+
82
+ if( ! function_exists( 'catchthemes_our_themes_script' ) ) {
83
+ function catchthemes_our_themes_script( $hook_suffix ) {
84
+
85
+ if( 'theme-install.php' == $hook_suffix ) {
86
+ wp_enqueue_script( 'our-themes-script', ESSENTIAL_CONTENT_TYPES_URL . 'admin/js/our-themes.js', array( 'jquery' ), '2018-05-16' );
87
+ }
88
+ }
89
+ add_action( 'admin_enqueue_scripts', 'catchthemes_our_themes_script' );
90
+ }
91
+
92
+
93
+ /* Add Catch Themes Section in Theme in Customizer */
94
+ if( ! function_exists( 'catchthemes_customize_register' ) ) {
95
+ function catchthemes_customize_register($wp_customize) {
96
+ $wp_customize->add_section( new WP_Customize_Themes_Section( $wp_customize, 'catchthemes', array(
97
+ 'title' => __( 'Themes by CatchThemes', 'catch-web-tools' ),
98
+ 'action' => 'catchthemes',
99
+ 'capability' => 'install_themes',
100
+ 'panel' => 'themes',
101
+ 'priority' => 6,
102
+ ) ) );
103
+ }
104
+ if ( ! is_multisite() ) {
105
+ add_action( 'customize_register', 'catchthemes_customize_register' );
106
+ }
107
+ }
108
+
109
+ if( ! function_exists( 'catchthemes_handle_load_themes_request' ) ) {
110
+ global $wp_customize;
111
+ remove_action( 'wp_ajax_customize_load_themes', array( $wp_customize, 'handle_load_themes_request' ) );
112
+ add_action( 'wp_ajax_customize_load_themes', 'catchthemes_handle_load_themes_request' );
113
+ /**
114
+ * Load themes into the theme browsing/installation UI.
115
+ * taken from wp-includes/cllass-wp-customize-manager.php
116
+ * @since 4.9.0
117
+ */
118
+ function catchthemes_handle_load_themes_request() {
119
+ check_ajax_referer( 'switch_themes', 'nonce' );
120
+ if ( ! current_user_can( 'switch_themes' ) ) {
121
+ wp_die( -1 );
122
+ }
123
+
124
+ if ( empty( $_POST['theme_action'] ) ) {
125
+ wp_send_json_error( 'missing_theme_action' );
126
+ }
127
+ $theme_action = sanitize_key( $_POST['theme_action'] );
128
+ $themes = array();
129
+ $args = array();
130
+
131
+ // Define query filters based on user input.
132
+ if ( ! array_key_exists( 'search', $_POST ) ) {
133
+ $args['search'] = '';
134
+ } else {
135
+ $args['search'] = sanitize_text_field( wp_unslash( $_POST['search'] ) );
136
+ }
137
+
138
+ if ( ! array_key_exists( 'tags', $_POST ) ) {
139
+ $args['tag'] = '';
140
+ } else {
141
+ $args['tag'] = array_map( 'sanitize_text_field', wp_unslash( (array) $_POST['tags'] ) );
142
+ }
143
+
144
+ if ( ! array_key_exists( 'page', $_POST ) ) {
145
+ $args['page'] = 1;
146
+ } else {
147
+ $args['page'] = absint( $_POST['page'] );
148
+ }
149
+
150
+ require_once ABSPATH . 'wp-admin/includes/theme.php';
151
+
152
+ if ( 'installed' === $theme_action ) {
153
+
154
+ // Load all installed themes from wp_prepare_themes_for_js().
155
+ $themes = array( 'themes' => wp_prepare_themes_for_js() );
156
+ foreach ( $themes['themes'] as &$theme ) {
157
+ $theme['type'] = 'installed';
158
+ $theme['active'] = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme['id'] );
159
+ }
160
+
161
+ } elseif ( 'catchthemes' === $theme_action ) {
162
+
163
+ // Load WordPress.org themes from the .org API and normalize data to match installed theme objects.
164
+ if ( ! current_user_can( 'install_themes' ) ) {
165
+ wp_die( -1 );
166
+ }
167
+
168
+ // Arguments for all queries.
169
+ $wporg_args = array(
170
+ 'per_page' => -1,
171
+ 'fields' => array(
172
+ 'screenshot_url' => true,
173
+ 'description' => true,
174
+ 'rating' => true,
175
+ 'downloaded' => true,
176
+ 'downloadlink' => true,
177
+ 'last_updated' => true,
178
+ 'homepage' => true,
179
+ 'num_ratings' => true,
180
+ 'tags' => true,
181
+ 'parent' => true,
182
+ // 'extended_author' => true, @todo: WordPress.org throws a 500 server error when this is here.
183
+ ),
184
+ );
185
+
186
+ $args = array_merge( $wporg_args, $args );
187
+
188
+ if ( '' === $args['search'] && '' === $args['tag'] ) {
189
+ $args['browse'] = 'new'; // Sort by latest themes by default.
190
+ }
191
+
192
+ $args['author'] = 'catchthemes';
193
+
194
+ // Load themes from the .org API.
195
+ $themes = themes_api( 'query_themes', $args );
196
+ if ( is_wp_error( $themes ) ) {
197
+ wp_send_json_error();
198
+ }
199
+
200
+ // This list matches the allowed tags in wp-admin/includes/theme-install.php.
201
+ $themes_allowedtags = array_fill_keys(
202
+ array( 'a', 'abbr', 'acronym', 'code', 'pre', 'em', 'strong', 'div', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img' ),
203
+ array()
204
+ );
205
+ $themes_allowedtags['a'] = array_fill_keys( array( 'href', 'title', 'target' ), true );
206
+ $themes_allowedtags['acronym']['title'] = true;
207
+ $themes_allowedtags['abbr']['title'] = true;
208
+ $themes_allowedtags['img'] = array_fill_keys( array( 'src', 'class', 'alt' ), true );
209
+
210
+ // Prepare a list of installed themes to check against before the loop.
211
+ $installed_themes = array();
212
+ $wp_themes = wp_get_themes();
213
+ foreach ( $wp_themes as $theme ) {
214
+ $installed_themes[] = $theme->get_stylesheet();
215
+ }
216
+ $update_php = network_admin_url( 'update.php?action=install-theme' );
217
+
218
+ // Set up properties for themes available on WordPress.org.
219
+ foreach ( $themes->themes as &$theme ) {
220
+ $theme->install_url = add_query_arg( array(
221
+ 'theme' => $theme->slug,
222
+ '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ),
223
+ ), $update_php );
224
+
225
+ $theme->name = wp_kses( $theme->name, $themes_allowedtags );
226
+ $theme->author = wp_kses( $theme->author, $themes_allowedtags );
227
+ $theme->version = wp_kses( $theme->version, $themes_allowedtags );
228
+ $theme->description = wp_kses( $theme->description, $themes_allowedtags );
229
+ $theme->tags = implode( ', ', $theme->tags );
230
+ $theme->stars = wp_star_rating( array(
231
+ 'rating' => $theme->rating,
232
+ 'type' => 'percent',
233
+ 'number' => $theme->num_ratings,
234
+ 'echo' => false,
235
+ ) );
236
+ $theme->num_ratings = number_format_i18n( $theme->num_ratings );
237
+ $theme->preview_url = set_url_scheme( $theme->preview_url );
238
+
239
+ // Handle themes that are already installed as installed themes.
240
+ if ( in_array( $theme->slug, $installed_themes, true ) ) {
241
+ $theme->type = 'installed';
242
+ } else {
243
+ $theme->type = $theme_action;
244
+ }
245
+
246
+ // Set active based on customized theme.
247
+ $theme->active = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme->slug );
248
+
249
+ // Map available theme properties to installed theme properties.
250
+ $theme->id = $theme->slug;
251
+ $theme->screenshot = array( $theme->screenshot_url );
252
+ $theme->authorAndUri = $theme->author;
253
+ // The .org API can return the full parent theme details if passed the 'parent' arg, or if passed the 'template' option it'll return that in the event it's a child theme.
254
+ if ( isset( $theme->parent ) ) {
255
+ $theme->parent = $theme->parent['slug'];
256
+ } else {
257
+ $theme->parent = false;
258
+ }
259
+ unset( $theme->slug );
260
+ unset( $theme->screenshot_url );
261
+ unset( $theme->author );
262
+ } // End foreach().
263
+ } elseif ( 'wporg' === $theme_action ) {
264
+
265
+ // Load WordPress.org themes from the .org API and normalize data to match installed theme objects.
266
+ if ( ! current_user_can( 'install_themes' ) ) {
267
+ wp_die( -1 );
268
+ }
269
+
270
+ // Arguments for all queries.
271
+ $wporg_args = array(
272
+ 'per_page' => 100,
273
+ 'fields' => array(
274
+ 'screenshot_url' => true,
275
+ 'description' => true,
276
+ 'rating' => true,
277
+ 'downloaded' => true,
278
+ 'downloadlink' => true,
279
+ 'last_updated' => true,
280
+ 'homepage' => true,
281
+ 'num_ratings' => true,
282
+ 'tags' => true,
283
+ 'parent' => true,
284
+ // 'extended_author' => true, @todo: WordPress.org throws a 500 server error when this is here.
285
+ ),
286
+ );
287
+
288
+ $args = array_merge( $wporg_args, $args );
289
+
290
+ if ( '' === $args['search'] && '' === $args['tag'] ) {
291
+ $args['browse'] = 'new'; // Sort by latest themes by default.
292
+ }
293
+
294
+ // Load themes from the .org API.
295
+ $themes = themes_api( 'query_themes', $args );
296
+ if ( is_wp_error( $themes ) ) {
297
+ wp_send_json_error();
298
+ }
299
+
300
+ // This list matches the allowed tags in wp-admin/includes/theme-install.php.
301
+ $themes_allowedtags = array_fill_keys(
302
+ array( 'a', 'abbr', 'acronym', 'code', 'pre', 'em', 'strong', 'div', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img' ),
303
+ array()
304
+ );
305
+ $themes_allowedtags['a'] = array_fill_keys( array( 'href', 'title', 'target' ), true );
306
+ $themes_allowedtags['acronym']['title'] = true;
307
+ $themes_allowedtags['abbr']['title'] = true;
308
+ $themes_allowedtags['img'] = array_fill_keys( array( 'src', 'class', 'alt' ), true );
309
+
310
+ // Prepare a list of installed themes to check against before the loop.
311
+ $installed_themes = array();
312
+ $wp_themes = wp_get_themes();
313
+ foreach ( $wp_themes as $theme ) {
314
+ $installed_themes[] = $theme->get_stylesheet();
315
+ }
316
+ $update_php = network_admin_url( 'update.php?action=install-theme' );
317
+
318
+ // Set up properties for themes available on WordPress.org.
319
+ foreach ( $themes->themes as &$theme ) {
320
+ $theme->install_url = add_query_arg( array(
321
+ 'theme' => $theme->slug,
322
+ '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ),
323
+ ), $update_php );
324
+
325
+ $theme->name = wp_kses( $theme->name, $themes_allowedtags );
326
+ $theme->author = wp_kses( $theme->author, $themes_allowedtags );
327
+ $theme->version = wp_kses( $theme->version, $themes_allowedtags );
328
+ $theme->description = wp_kses( $theme->description, $themes_allowedtags );
329
+ $theme->tags = implode( ', ', $theme->tags );
330
+ $theme->stars = wp_star_rating( array(
331
+ 'rating' => $theme->rating,
332
+ 'type' => 'percent',
333
+ 'number' => $theme->num_ratings,
334
+ 'echo' => false,
335
+ ) );
336
+ $theme->num_ratings = number_format_i18n( $theme->num_ratings );
337
+ $theme->preview_url = set_url_scheme( $theme->preview_url );
338
+
339
+ // Handle themes that are already installed as installed themes.
340
+ if ( in_array( $theme->slug, $installed_themes, true ) ) {
341
+ $theme->type = 'installed';
342
+ } else {
343
+ $theme->type = $theme_action;
344
+ }
345
+
346
+ // Set active based on customized theme.
347
+ $theme->active = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme->slug );
348
+
349
+ // Map available theme properties to installed theme properties.
350
+ $theme->id = $theme->slug;
351
+ $theme->screenshot = array( $theme->screenshot_url );
352
+ $theme->authorAndUri = $theme->author;
353
+ // The .org API can return the full parent theme details if passed the 'parent' arg, or if passed the 'template' option it'll return that in the event it's a child theme.
354
+ if ( isset( $theme->parent ) ) {
355
+ $theme->parent = $theme->parent['slug'];
356
+ } else {
357
+ $theme->parent = false;
358
+ }
359
+ unset( $theme->slug );
360
+ unset( $theme->screenshot_url );
361
+ unset( $theme->author );
362
+ } // End foreach().
363
+ } // End if().
364
+
365
+ /**
366
+ * Filters the theme data loaded in the customizer.
367
+ *
368
+ * This allows theme data to be loading from an external source,
369
+ * or modification of data loaded from `wp_prepare_themes_for_js()`
370
+ * or WordPress.org via `themes_api()`.
371
+ *
372
+ * @since 4.9.0
373
+ *
374
+ * @see wp_prepare_themes_for_js()
375
+ * @see themes_api()
376
+ * @see WP_Customize_Manager::__construct()
377
+ *
378
+ * @param array $themes Nested array of theme data.
379
+ * @param array $args List of arguments, such as page, search term, and tags to query for.
380
+ * @param WP_Customize_Manager $manager Instance of Customize manager.
381
+ */
382
+ $themes = apply_filters( 'customize_load_themes', $themes, $args, $wp_customize );
383
+
384
+ wp_send_json_success( $themes );
385
+ }
386
+ }