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
ever-compare / includes / classes / Admin / Recommended_Plugins.php

Recommended_Plugins.php in Ever Compare – Products Compare Plugin for WooCommerce trunk, at includes/classes/Admin/Recommended_Plugins.php

480 lines 21.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace EverCompare\Admin;
3
4 defined( 'ABSPATH' ) || exit;
5 /**
6 * Recommended Plugins handlers class
7 */
8 class Recommended_Plugins {
9
10 /**
11 * [$_instance]
12 * @var null
13 */
14 private static $_instance = null;
15
16 /**
17 * [$plugins_allowedtags] allow tag
18 * @var array
19 */
20 public $plugins_allowedtags = array(
21 'a' => array(
22 'href' => array(),
23 'title' => array(),
24 'target' => array(),
25 ),
26 'abbr' => array( 'title' => array() ),
27 'acronym' => array( 'title' => array() ),
28 'code' => array(),
29 'pre' => array(),
30 'em' => array(),
31 'strong' => array(),
32 'ul' => array(),
33 'ol' => array(),
34 'li' => array(),
35 'p' => array(),
36 'br' => array(),
37 );
38
39 /**
40 * Veriable Initialize
41 */
42 public $text_domain = '';
43 public $parent_menu_slug = '';
44 public $menu_label = '';
45 public $menu_page_slug = '';
46 public $menu_capability = '';
47 public $priority = '';
48 public $hook_suffix = '';
49 public $assets_url = '';
50 public $tab_list = [];
51
52 /**
53 * [instance] Initializes a singleton instance
54 * @return [Recommended_Plugins]
55 */
56 public static function instance( $args = [] ) {
57 if ( is_null( self::$_instance ) ) {
58 self::$_instance = new self( $args );
59 }
60 return self::$_instance;
61 }
62
63 /**
64 * [__construct] Class construct
65 */
66 function __construct( $args ) {
67
68 // Initialize properties
69 $this->text_domain = !empty( $args['text_domain'] ) ? $args['text_domain'] : 'htrp';
70 $this->parent_menu_slug = !empty( $args['parent_menu_slug'] ) ? $args['parent_menu_slug'] : 'plugins.php';
71 $this->menu_label = !empty( $args['menu_label'] ) ? $args['menu_label'] : esc_html__( 'Recommendations', 'ever-compare' );
72 $this->menu_capability = !empty( $args['menu_capability'] ) ? $args['menu_capability'] : 'manage_options';
73 $this->menu_page_slug = !empty( $args['menu_page_slug'] ) ? $args['menu_page_slug'] : $this->text_domain . '_extensions';
74 $this->priority = !empty( $args['priority'] ) ? $args['priority'] : 100;
75 $this->hook_suffix = !empty( $args['hook_suffix'] ) ? $args['hook_suffix'] : '';
76 $this->assets_url = !empty( $args['assets_url'] ) ? $args['assets_url'] : plugins_url( '', __FILE__ );
77 $this->tab_list = !empty( $args['tab_list'] ) ? $args['tab_list'] : [];
78
79
80 add_action( 'admin_menu', [ $this, 'admin_menu' ], $this->priority );
81 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
82
83 // Ajax Action
84 add_action( 'wp_ajax_'.$this->text_domain.'_ajax_plugin_activation', [ $this, 'plugin_activation' ] );
85
86 }
87
88 /**
89 * [admin_menu] Add Recommended Menu
90 * @return [void]
91 */
92 public function admin_menu(){
93 add_submenu_page(
94 $this->parent_menu_slug,
95 $this->menu_label,
96 $this->menu_label,
97 $this->menu_capability,
98 $this->menu_page_slug,
99 [ $this, 'render_html' ]
100 );
101 }
102
103 /**
104 * [enqueue_assets]
105 * @param [string] $hook_suffix Current page hook
106 * @return [void]
107 */
108 public function enqueue_assets( $hook_suffix ) {
109 if( $this->hook_suffix ){
110 if( $this->hook_suffix == $hook_suffix ){
111 wp_enqueue_script( 'htrp-plugin-install-manager', $this->assets_url . '/js/plugins_install_manager.js', array('jquery','wp-util', 'updates'), '1.0.0', true );
112 }
113 } else {
114 wp_enqueue_script( 'htrp-plugin-install-manager', $this->assets_url . '/js/plugins_install_manager.js', array('jquery','wp-util', 'updates'), '1.0.0', true );
115 }
116
117 /**
118 * Thickbox assest
119 */
120 add_thickbox();
121
122 /**
123 * localize data
124 */
125 $localize_vars['ajaxurl'] = admin_url('admin-ajax.php');
126 $localize_vars['text_domain'] = sanitize_title_with_dashes( $this->text_domain );
127 $localize_vars['nonce'] = wp_create_nonce('htrp_nonce');
128 $localize_vars['buttontxt'] = array(
129 'buynow' => esc_html__( 'Buy Now', 'ever-compare' ),
130 'preview' => esc_html__( 'Preview', 'ever-compare' ),
131 'installing' => esc_html__( 'Installing..', 'ever-compare' ),
132 'activating' => esc_html__( 'Activating..', 'ever-compare' ),
133 'active' => esc_html__( 'Activated', 'ever-compare' ),
134 );
135 wp_localize_script( 'htrp-plugin-install-manager', 'htrp_params', $localize_vars );
136
137 }
138
139 /**
140 * [add_new_tab]
141 * @param [void] set tab content
142 */
143 public function add_new_tab( $tab_list ){
144 $this->tab_list[] = $tab_list;
145 }
146
147 /**
148 * [render_html]
149 * @return [void] Render HTML
150 */
151 public function render_html(){
152 if ( ! function_exists('plugins_api') ){ include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); }
153
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 }
161 $prepare_plugin = $this->get_plugins_info( $requested_slugs );
162
163 ?>
164 <div class="wrap">
165 <h2><?php echo esc_html(get_admin_page_title()); ?></h2>
166 <style>
167 .htrp-admin-tab-pane{
168 display: none;
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. */
173 .htrp-admin-tab-pane.htrp-active{
174 display: flex;
175 flex-wrap: wrap;
176 gap: 16px;
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 }
186 .htrp-extension-admin-tab-area .filter-links li>a:focus, .htrp-extension-admin-tab-area .filter-links li>a:hover {
187 color: inherit;
188 box-shadow: none;
189 }
190 .filter-links .htrp-active{
191 box-shadow: none;
192 border-bottom: 4px solid #646970;
193 color: #1d2327;
194 }
195 .downloaded-count{
196 display: block;
197 margin-top:5px;
198 }
199 </style>
200
201 <div class="htrp-extension-admin-tab-area wp-filter">
202 <ul class="htrp-admin-tabs filter-links">
203 <?php
204 foreach( $this->tab_list as $tab ){
205 $active_class = isset( $tab['active'] ) && $tab['active'] ? 'htrp-active' : '';
206 ?>
207 <li>
208 <a href="#<?php echo esc_attr( sanitize_title_with_dashes( $tab['title'] ) ) ?>" class="<?php echo esc_attr( $active_class ) ?>"><?php echo esc_html( $tab['title'] ) ?></a>
209 </li>
210 <?php
211 }
212 ?>
213 </ul>
214 </div>
215
216 <?php
217 $plugins_type = '';
218 foreach( $this->tab_list as $tab ):
219
220 $active_class = isset( $tab['active'] ) && $tab['active'] ? 'htrp-active' : '';
221 $plugins = $tab['plugins'];
222
223 echo '<div id="'.esc_attr( sanitize_title_with_dashes( $tab['title'] ) ).'" class="htrp-admin-tab-pane '.esc_attr( $active_class ).'">';
224 foreach( $plugins as $plugin ):
225
226 $data = array(
227 'slug' => isset( $plugin['slug'] ) ? $plugin['slug'] : '',
228 'location' => isset( $plugin['location'] ) ? $plugin['slug'].'/'.$plugin['location'] : '',
229 'name' => isset( $plugin['name'] ) ? $plugin['name'] : '',
230 );
231 if( array_key_exists( $plugin['slug'], $prepare_plugin ) ){
232 $plugins_type = 'free';
233 $title = $data['name'] ? $data['name'] : $prepare_plugin[$plugin['slug']]['name'];
234 $title = wp_kses( $title, $this->plugins_allowedtags );
235 $image_url = $this->plugin_icon( $plugins_type, $prepare_plugin[$data['slug']]['icons'] );
236 $description = wp_strip_all_tags( $prepare_plugin[$data['slug']]['description'] );
237 $author_name = wp_kses( $prepare_plugin[$data['slug']]['author'], $this->plugins_allowedtags );
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');
239 $target = '_self';
240 $modal_class = 'thickbox open-plugin-details-modal';
241
242 }else{
243 $plugins_type = 'pro';
244 $title = wp_kses( $plugin['name'], $this->plugins_allowedtags );
245 $image_url = $this->plugin_icon( $plugins_type, $plugin['slug'] );
246 $description = isset( $plugin['description'] ) ? $plugin['description'] : '';
247 $author_name = esc_html__( 'HasTheme', 'ever-compare' );
248 $author_link = isset( $plugin['author_link'] ) ? $plugin['author_link'] : '';
249 $details_link = isset( $plugin['link'] ) ? $plugin['link'] : '';
250 $button_text = esc_html__('Buy Now', 'ever-compare' );
251 $button_classes = 'button button-primary';
252 $target = '_blank';
253 $modal_class = '';
254 }
255
256 if ( ! is_wp_error( $data ) ):
257
258 // Installed but Inactive.
259 if ( file_exists( WP_PLUGIN_DIR . '/' . $data['location'] ) && is_plugin_inactive( $data['location'] ) ) {
260
261 $button_classes = 'button htrp-activate-now button-primary';
262 $button_text = esc_html__( 'Activate', 'ever-compare' );
263
264 // Not Installed.
265 } elseif ( ! file_exists( WP_PLUGIN_DIR . '/' . $data['location'] ) ) {
266
267 $button_classes = 'button htrp-install-now';
268 $button_text = esc_html__( 'Install Now', 'ever-compare' );
269
270 // Active.
271 } else {
272 $button_classes = 'button disabled';
273 $button_text = esc_html__( 'Activated', 'ever-compare' );
274 }
275
276 ?>
277 <div class="plugin-card htrp-plugin-<?php echo sanitize_html_class( $plugin['slug'] ); ?>">
278 <div class="plugin-card-top">
279 <div class="name column-name" style="margin-right: 0;">
280 <h3>
281 <a href="<?php echo esc_url( $details_link ) ?>" target="<?php echo esc_attr( $target ) ?>" class="<?php echo esc_attr($modal_class); ?>" >
282 <?php echo esc_html( $title ) ?>
283 <img src="<?php echo esc_url( $image_url ) ?>" class="plugin-icon" alt="<?php echo esc_attr( $title ) ?>">
284 </a>
285 </h3>
286 </div>
287 <div class="desc column-description" style="margin-right: 0;">
288 <p><?php echo esc_html(wp_trim_words( $description, 23, '....')); ?></p>
289 <p class="authors">
290 <cite><?php echo esc_html__( 'By ', 'ever-compare' ); ?>
291 <?php if( $plugins_type == 'free' ): ?>
292 <?php echo wp_kses_post( $author_name); ?>
293 <?php else: ?>
294 <a href="<?php echo esc_url( $author_link ); ?>" target="_blank" ><?php echo esc_html($author_name); ?></a>
295 <?php endif; ?>
296 </cite>
297 </p>
298 </div>
299 </div>
300 <div class="plugin-card-bottom">
301 <div class="column-updated">
302 <?php
303 if (! file_exists( WP_PLUGIN_DIR . '/' . $data['location'] ) && $plugins_type == 'pro' ) {
304 echo '<a class="button button-primary" href="'.esc_url( $details_link ).'" target="'.esc_attr( $target ).'">'.esc_html__( 'Buy Now', 'ever-compare' ).'</a>';
305 }else{
306 ?>
307 <button class="<?php echo esc_attr($button_classes); ?>" data-pluginopt='<?php echo wp_json_encode( $data ); ?>'><?php echo esc_html($button_text); ?></button>
308
309 <?php } ?>
310 </div>
311 <div class="column-downloaded">
312 <a href="<?php echo esc_url( $details_link ) ?>" target="<?php echo esc_attr( $target ) ?>" class=" <?php echo esc_attr($modal_class); ?>" ><?php echo esc_html__('More Details', 'ever-compare') ?></a>
313 <span class="downloaded-count">
314 <?php
315 if( $plugins_type == 'free' ){
316 /* translators: %s: Number of installations. */
317 printf( esc_html__( '%s Active Installations', 'ever-compare' ), esc_html($this->active_install_count( $prepare_plugin[$data['slug']]['active_installs'] )) );
318 }
319 ?>
320 </span>
321 </div>
322 </div>
323 </div>
324 <?php
325 endif;
326 endforeach;
327 echo '</div>';
328
329 endforeach;
330 ?>
331
332 </div>
333 <?php
334
335 }
336
337 /**
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.
344 */
345 public function get_plugins_info( $slugs ) {
346
347 if ( empty( $slugs ) ) {
348 return array();
349 }
350
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;
391 }
392
393 /**
394 * [plugin_icon] Generate plugin icon
395 * @param string $type plugin type
396 * @param [array|string] $icon
397 * @return [URL] icon URL
398 */
399 public function plugin_icon( $type = 'free', $icon = '' ){
400 if( $type === 'free' ){
401 if ( ! empty( $icon['svg'] ) ) {
402 $plugin_icon_url = $icon['svg'];
403 } elseif ( ! empty( $icon['2x'] ) ) {
404 $plugin_icon_url = $icon['2x'];
405 } elseif ( ! empty( $icon['1x'] ) ) {
406 $plugin_icon_url = $icon['1x'];
407 } else {
408 $plugin_icon_url = $icon['default'];
409 }
410 }else{
411 $plugin_icon_url = $this->assets_url .'/images/extensions/'.$icon.'.png';
412 }
413
414 return $plugin_icon_url;
415
416 }
417
418 /**
419 * [active_install_count] Manage Active install count
420 * @param [int] $active_installs
421 * @return [string]
422 */
423 public function active_install_count( $active_installs ){
424
425 if ( $active_installs >= 1000000 ) {
426 $active_installs_millions = floor( $active_installs / 1000000 );
427 $active_installs_text = sprintf(
428 /* translators: %s: Number of millions. */
429 _nx( '%s+ Million', '%s+ Million', $active_installs_millions, 'Active plugin installations', 'ever-compare' ),
430 number_format_i18n( $active_installs_millions )
431 );
432 } elseif ( 0 === $active_installs ) {
433 $active_installs_text = _x( 'Less Than 10', 'Active plugin installations', 'ever-compare' );
434 } else {
435 $active_installs_text = number_format_i18n( $active_installs ) . '+';
436 }
437 return $active_installs_text;
438
439 }
440
441 /**
442 * [plugin_activation] Plugin activation ajax callable function
443 * @return [JSON]
444 */
445 public function plugin_activation() {
446
447 check_ajax_referer('htrp_nonce', 'nonce');
448
449 if ( ! current_user_can( 'install_plugins' ) || empty( sanitize_text_field( wp_unslash($_POST['location']) ) ) ) {
450 wp_send_json_error(
451 array(
452 'success' => false,
453 'message' => esc_html__( 'Plugin Not Found', 'ever-compare' ),
454 )
455 );
456 }
457
458 $plugin_location = ! empty( sanitize_text_field(wp_unslash($_POST['location'])) ) ? sanitize_text_field(wp_unslash($_POST['location'])) : '';
459 $activate = activate_plugin( $plugin_location, '', false, true );
460
461 if ( is_wp_error( $activate ) ) {
462 wp_send_json_error(
463 array(
464 'success' => false,
465 'message' => $activate->get_error_message(),
466 )
467 );
468 }
469
470 wp_send_json_success(
471 array(
472 'success' => true,
473 'message' => esc_html__( 'Plugin Successfully Activated', 'ever-compare' ),
474 )
475 );
476
477 }
478
479
480 }