PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.14
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.14
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
visualizer / vendor / codeinwp / themeisle-sdk / src / Modules / Featured_plugins.php

Featured_plugins.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.11.14, at vendor/codeinwp/themeisle-sdk/src/Modules/Featured_plugins.php

264 lines 7.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * File responsible for showing plugins inside the featured tab.
4 *
5 * This is used to display information about limited events, such as Black Friday.
6 *
7 * @package ThemeIsleSDK
8 * @subpackage Modules
9 * @copyright Copyright (c) 2017, Marius Cristea
10 * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
11 * @since 3.3.0
12 */
13 namespace ThemeisleSDK\Modules;
14
15 use ThemeisleSDK\Common\Abstract_Module;
16 use ThemeisleSDK\Loader;
17 use ThemeisleSDK\Product;
18
19 // Exit if accessed directly.
20 if ( ! defined( 'ABSPATH' ) ) {
21 exit;
22 }
23
24 /**
25 * Featured_Plugins module for the ThemeIsle SDK.
26 */
27 class Featured_Plugins extends Abstract_Module {
28
29 /**
30 * The transient key prefix.
31 *
32 * @var string $transient_key
33 */
34 private $transient_key = 'themeisle_sdk_featured_plugins_';
35
36 /**
37 * The current product instance.
38 *
39 * @var Product|null
40 */
41 protected $product = null;
42
43 /**
44 * Check if the module can be loaded.
45 *
46 * @param Product $product Product data.
47 *
48 * @return bool
49 */
50 public function can_load( $product ) {
51 if ( $this->is_from_partner( $product ) ) {
52 return false;
53 }
54
55 if ( $product->is_wordpress_available() ) {
56 return false;
57 }
58
59 return ! apply_filters( 'themeisle_sdk_disable_featured_plugins', false );
60 }
61
62 /**
63 * Load the module for the selected product.
64 *
65 * @param Product $product Product data.
66 *
67 * @return void
68 */
69 public function load( $product ) {
70 $this->product = $product;
71
72 if ( ! current_user_can( 'install_plugins' ) ) {
73 return;
74 }
75
76 // bail if we already registered a filter for the plugin API.
77 if ( apply_filters( 'themeisle_sdk_plugin_api_filter_registered', false ) ) {
78 return;
79 }
80 add_filter( 'themeisle_sdk_plugin_api_filter_registered', '__return_true' );
81
82 add_filter( 'plugins_api_result', [ $this, 'filter_plugin_api_results' ], 11, 3 );
83
84 // Enqueue inline JS only on plugin-install.php.
85 add_action( 'admin_enqueue_scripts', [ $this, 'maybe_add_inline_js' ] );
86 }
87
88 /**
89 * Enqueue inline JavaScript only on plugin-install.php.
90 *
91 * @return void
92 */
93 public function maybe_add_inline_js() {
94 $screen = get_current_screen();
95 if ( isset( $screen->base ) && 'plugin-install' === $screen->base ) {
96 add_action(
97 'admin_footer',
98 function() {
99 $text = esc_html( sprintf( Loader::$labels['promotions']['recommended'], $this->product->get_friendly_name() ) );
100
101 echo '<script>(function(){
102 function onPluginCardFound(card) {
103 var recommendedDiv = document.createElement("div");
104 Object.assign(recommendedDiv.style, {
105 display: "block",
106 textAlign: "center",
107 padding: "0 12px 12px",
108 background: "#f6f7f7"
109 });
110 recommendedDiv.innerHTML = "' . esc_html( $text ) . '";
111 card.appendChild(recommendedDiv);
112 }
113
114 function checkAndRun() {
115 var card = document.querySelector(".plugin-card-learning-management-system");
116 if (card && !card.dataset.recommendedAdded) {
117 onPluginCardFound(card);
118 card.dataset.recommendedAdded = "true";
119 }
120 }
121
122 var observer = new MutationObserver(function(mutations) {
123 checkAndRun();
124 });
125
126 observer.observe(document.body, { childList: true, subtree: true });
127
128 // Initial check in case the card is already present.
129 checkAndRun();
130 })();</script>';
131 }
132 );
133 }
134 }
135
136 /**
137 * Filter the plugin API results to include the featured plugins.
138 *
139 * @param object $res The result object.
140 * @param string $action The type of information being requested from the Plugin Install API.
141 * @param object $args Plugin API arguments.
142 *
143 * @return object
144 */
145 public function filter_plugin_api_results( $res, $action, $args ) {
146
147 if ( 'query_plugins' !== $action ) {
148 return $res;
149 }
150
151 if ( isset( $args->page ) && 1 === (int) $args->page && isset( $args->search ) && ! empty( $args->search ) ) {
152 $res->plugins = $this->maybe_prepend_lms_plugin( $res->plugins, $args );
153 return $res;
154 }
155
156 if ( ! isset( $args->browse ) || $args->browse !== 'featured' ) {
157 return $res;
158 }
159
160 $featured = $this->query_plugins_by_author( $args );
161
162 $plugins = array_merge( $featured, (array) $res->plugins );
163 $plugins = array_slice( $plugins, 0, $res->info['results'] );
164 $res->plugins = $plugins;
165
166 return $res;
167 }
168
169 /**
170 * Prepend the LMS plugin if the search query matches LMS-related terms.
171 *
172 * @param array $plugins The plugins array.
173 * @param object $args The plugin API arguments.
174 * @return array
175 */
176 private function maybe_prepend_lms_plugin( $plugins, $args ) {
177 $search = isset( $args->search ) ? strtolower( $args->search ) : '';
178 if (
179 strpos( $search, 'lms' ) !== false ||
180 strpos( $search, 'learn' ) !== false
181 ) {
182 $filter_slugs = apply_filters( 'themeisle_sdk_masteriyo_filter_slugs', [ 'learning-management-system' ] );
183 $masteriyo = $this->get_plugins_filtered_from_author( $args, $filter_slugs, 'masteriyo' );
184
185 if ( ! empty( $masteriyo ) ) {
186 // Remove existing LMS plugin if present to avoid duplicates.
187 $plugins = array_filter(
188 $plugins,
189 function( $plugin ) {
190 return ( is_object( $plugin ) && isset( $plugin->slug ) && $plugin->slug !== 'learning-management-system' ) ||
191 ( is_array( $plugin ) && isset( $plugin['slug'] ) && $plugin['slug'] !== 'learning-management-system' );
192 }
193 );
194
195 $plugins = array_merge( $masteriyo, $plugins );
196 }
197 }
198 return $plugins;
199 }
200
201 /**
202 * Query plugins by author.
203 *
204 * @param object $args The arguments for the query.
205 *
206 * @return array
207 */
208 private function query_plugins_by_author( $args ) {
209 $featured = [];
210
211 $optimole_filter_slugs = apply_filters( 'themeisle_sdk_optimole_filter_slugs', [ 'optimole-wp' ] );
212 $filtered_from_optimole = $this->get_plugins_filtered_from_author( $args, $optimole_filter_slugs, 'Optimole' );
213 $featured = array_merge( $featured, $filtered_from_optimole );
214
215 $themeisle_filter_slugs = apply_filters( 'themeisle_sdk_themeisle_filter_slugs', [ 'otter-blocks', 'wp-cloudflare-page-cache' ] );
216 $filtered_from_themeisle = $this->get_plugins_filtered_from_author( $args, $themeisle_filter_slugs );
217 $featured = array_merge( $featured, $filtered_from_themeisle );
218
219 return $featured;
220 }
221
222 /**
223 * Get plugins filtered from an author.
224 *
225 * @param object $args The arguments for the query.
226 * @param array $filter_slugs The slugs to filter.
227 * @param string $author The author to filter.
228 *
229 * @return array
230 */
231 protected function get_plugins_filtered_from_author( $args, $filter_slugs = [], $author = 'Themeisle' ) {
232
233 $cached = get_transient( $this->transient_key . $author );
234 if ( $cached ) {
235 return $cached;
236 }
237
238 $new_args = [
239 'page' => 1,
240 'per_page' => 36,
241 'locale' => get_user_locale(),
242 'author' => $author,
243 'wp_version' => isset( $args->wp_version ) ? $args->wp_version : get_bloginfo( 'version' ),
244 ];
245
246 $api = plugins_api( 'query_plugins', $new_args );
247 if ( is_wp_error( $api ) ) {
248 return [];
249 }
250
251 $filtered = array_filter(
252 $api->plugins,
253 function( $plugin ) use ( $filter_slugs ) {
254 $array_plugin = (array) $plugin;
255 return in_array( $array_plugin['slug'], $filter_slugs );
256 }
257 );
258
259 set_transient( $this->transient_key . $author, $filtered, 12 * HOUR_IN_SECONDS );
260
261 return $filtered;
262 }
263 }
264