PluginProbe
Ever Compare – Products Compare Plugin for WooCommerce / trunk
Ever Compare – Products Compare Plugin for WooCommerce vtrunk
1.3.7 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 trunk 1.0.0 1.0.1 1.0.2 All 31 releases
← All changes | includes/classes/Admin/Recommended_Plugins.php +76 -23 1.3.4trunk View file →
@@ -1,6 +1,8 @@
1 1 <?php
2 2 namespace EverCompare\Admin;
3 +
4 +defined( 'ABSPATH' ) || exit;
3 5 /**
4 6 * Recommended Plugins handlers class
5 7 */
6 8 class Recommended_Plugins {
@@ -71,9 +73,9 @@
71 73 $this->menu_page_slug = !empty( $args['menu_page_slug'] ) ? $args['menu_page_slug'] : $this->text_domain . '_extensions';
72 74 $this->priority = !empty( $args['priority'] ) ? $args['priority'] : 100;
73 75 $this->hook_suffix = !empty( $args['hook_suffix'] ) ? $args['hook_suffix'] : '';
74 76 $this->assets_url = !empty( $args['assets_url'] ) ? $args['assets_url'] : plugins_url( '', __FILE__ );
75 - $this->tab_list = !empty( $args['tab_list'] ) ? $args['assets_url'] : [];
77 + $this->tab_list = !empty( $args['tab_list'] ) ? $args['tab_list'] : [];
76 78
77 79
78 80 add_action( 'admin_menu', [ $this, 'admin_menu' ], $this->priority );
79 81 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
@@ -148,17 +150,16 @@
148 150 */
149 151 public function render_html(){
150 152 if ( ! function_exists('plugins_api') ){ include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); }
151 153
152 - $htplugins_plugin_list = $this->get_plugins();
153 - $palscode_plugin_list = $this->get_plugins( 'palscode' );
154 -
155 - $plugin_list = array_merge( $htplugins_plugin_list, $palscode_plugin_list );
156 -
157 - $prepare_plugin = array();
158 - foreach ( $plugin_list as $plugin_key => $plugin ) {
159 - $prepare_plugin[$plugin['slug']] = $plugin;
154 + $requested_slugs = array();
155 + foreach ( $this->tab_list as $tab ) {
156 + if ( empty( $tab['plugins'] ) ) { continue; }
157 + foreach ( $tab['plugins'] as $plugin ) {
158 + if ( ! empty( $plugin['slug'] ) ) { $requested_slugs[] = $plugin['slug']; }
159 + }
160 160 }
161 + $prepare_plugin = $this->get_plugins_info( $requested_slugs );
161 162
162 163 ?>
163 164 <div class="wrap">
164 165 <h2><?php echo esc_html(get_admin_page_title()); ?></h2>
@@ -165,11 +166,24 @@
165 166 <style>
166 167 .htrp-admin-tab-pane{
167 168 display: none;
168 169 }
170 + /* Grid layout is normally provided by core's .plugin-install-php #the-list rule,
171 + which is scoped to WP's own Add Plugins screen and never matches this page -
172 + define it ourselves so the cards don't just stack in a single column. */
169 173 .htrp-admin-tab-pane.htrp-active{
170 - display: block;
174 + display: flex;
175 + flex-wrap: wrap;
176 + gap: 16px;
171 177 }
178 + .plugin-card{
179 + display: flex;
180 + flex-direction: column;
181 + justify-content: space-between;
182 + }
183 + .plugin-card h3 a{
184 + text-decoration: none;
185 + }
172 186 .htrp-extension-admin-tab-area .filter-links li>a:focus, .htrp-extension-admin-tab-area .filter-links li>a:hover {
173 187 color: inherit;
174 188 box-shadow: none;
175 189 }
@@ -213,12 +227,12 @@
213 227 'slug' => isset( $plugin['slug'] ) ? $plugin['slug'] : '',
214 228 'location' => isset( $plugin['location'] ) ? $plugin['slug'].'/'.$plugin['location'] : '',
215 229 'name' => isset( $plugin['name'] ) ? $plugin['name'] : '',
216 230 );
217 - $title = wp_kses( $plugin['name'], $this->plugins_allowedtags );
218 -
219 231 if( array_key_exists( $plugin['slug'], $prepare_plugin ) ){
220 232 $plugins_type = 'free';
233 + $title = $data['name'] ? $data['name'] : $prepare_plugin[$plugin['slug']]['name'];
234 + $title = wp_kses( $title, $this->plugins_allowedtags );
221 235 $image_url = $this->plugin_icon( $plugins_type, $prepare_plugin[$data['slug']]['icons'] );
222 236 $description = wp_strip_all_tags( $prepare_plugin[$data['slug']]['description'] );
223 237 $author_name = wp_kses( $prepare_plugin[$data['slug']]['author'], $this->plugins_allowedtags );
224 238 $details_link = self_admin_url('plugin-install.php?tab=plugin-information&amp;plugin=' . $plugin['slug'] .'&amp;TB_iframe=true&amp;width=772&amp;height=577');
@@ -226,8 +240,9 @@
226 240 $modal_class = 'thickbox open-plugin-details-modal';
227 241
228 242 }else{
229 243 $plugins_type = 'pro';
244 + $title = wp_kses( $plugin['name'], $this->plugins_allowedtags );
230 245 $image_url = $this->plugin_icon( $plugins_type, $plugin['slug'] );
231 246 $description = isset( $plugin['description'] ) ? $plugin['description'] : '';
232 247 $author_name = esc_html__( 'HasTheme', 'ever-compare' );
233 248 $author_link = isset( $plugin['author_link'] ) ? $plugin['author_link'] : '';
@@ -319,23 +334,61 @@
319 334
320 335 }
321 336
322 337 /**
323 - * [get_plugins] Get plugin from wp.org API
324 - * @param string $username wo.org username
325 - * @return [array] plugin list
338 + * [get_plugins_info] Look up wp.org plugin info by slug (not by author account —
339 + * wp.org's author-query filters by actual SVN repo ownership, which can differ
340 + * from a plugin's displayed "Author:" line and silently miss real plugins).
341 + * @param array $slugs Plugin slugs to look up.
342 + * @return array Associative array keyed by slug; slugs plugins_api() can't
343 + * resolve (pro-only/paid, not on wp.org) are simply absent.
326 344 */
327 - public function get_plugins( $username = 'htplugins' ){
328 - $transient_var = 'htrp_htplugins_list_'.$username;
329 - $org_plugins_list = get_transient( $transient_var );
345 + public function get_plugins_info( $slugs ) {
330 346
331 - if ( false === $org_plugins_list ) {
332 - $plugins_list_by_author = plugins_api( 'query_plugins', array( 'author' => $username, 'per_page' => 100 ) );
333 - set_transient( $transient_var, $plugins_list_by_author->plugins, 1 * WEEK_IN_SECONDS );
334 - $org_plugins_list = $plugins_list_by_author->plugins;
347 + if ( empty( $slugs ) ) {
348 + return array();
335 349 }
336 350
337 - return $org_plugins_list;
351 + $slugs = array_unique( $slugs );
352 + sort( $slugs ); // deterministic cache key regardless of tab iteration order
353 +
354 + $transient_var = 'htrp_htplugins_info_' . md5( implode( ',', $slugs ) );
355 + $plugins_info = get_transient( $transient_var );
356 +
357 + if ( false === $plugins_info ) {
358 +
359 + $plugins_info = array();
360 +
361 + foreach ( $slugs as $slug ) {
362 + $plugin_info = plugins_api( 'plugin_information', array(
363 + 'slug' => $slug,
364 + 'fields' => array(
365 + 'short_description' => true, 'sections' => false, 'icons' => true,
366 + 'active_installs' => true, 'author' => true, 'versions' => false,
367 + 'ratings' => false, 'reviews' => false, 'banners' => false,
368 + 'compatibility' => false, 'homepage' => false, 'donate_link' => false,
369 + 'tags' => false,
370 + ),
371 + ) );
372 +
373 + if ( is_wp_error( $plugin_info ) ) {
374 + continue; // not on wp.org (pro-only / paid slug) — stays in the "pro" render branch
375 + }
376 +
377 + $plugins_info[ $slug ] = array(
378 + 'name' => $plugin_info->name,
379 + 'slug' => $plugin_info->slug,
380 + 'icons' => (array) $plugin_info->icons,
381 + 'description' => $plugin_info->short_description,
382 + 'author' => $plugin_info->author,
383 + 'active_installs' => $plugin_info->active_installs,
384 + );
385 + }
386 +
387 + set_transient( $transient_var, $plugins_info, 1 * WEEK_IN_SECONDS );
388 + }
389 +
390 + return $plugins_info;
338 391 }
339 392
340 393 /**
341 394 * [plugin_icon] Generate plugin icon