PluginProbe ʕ •ᴥ•ʔ
Royal Addons for Elementor – Addons and Templates Kit for Elementor / 1.7.1064
Royal Addons for Elementor – Addons and Templates Kit for Elementor v1.7.1064
1.7.1064 1.7.1063 1.7.1062 1.7.1061 1.7.1060 1.7.1059 1.7.1058 trunk 1.0.0 1.1.0 1.2 1.3 1.3.1 1.3.2 1.3.21 1.3.22 1.3.23 1.3.24 1.3.25 1.3.26 1.3.27 1.3.28 1.3.29 1.3.30 1.3.31 1.3.32 1.3.33 1.3.34 1.3.35 1.3.36 1.3.37 1.3.38 1.3.39 1.3.40 1.3.41 1.3.42 1.3.43 1.3.44 1.3.45 1.3.46 1.3.47 1.3.48 1.3.49 1.3.50 1.3.51 1.3.52 1.3.53 1.3.54 1.3.55 1.3.56 1.3.57 1.3.58 1.3.59 1.3.60 1.3.61 1.3.62 1.3.63 1.3.64 1.3.65 1.3.66 1.3.67 1.3.68 1.3.69 1.3.70 1.3.71 1.3.72 1.3.73 1.3.74 1.3.75 1.3.76 1.3.77 1.3.78 1.3.79 1.3.80 1.3.81 1.3.82 1.3.83 1.3.84 1.3.85 1.3.86 1.3.87 1.3.88 1.3.89 1.3.90 1.3.91 1.3.92 1.3.93 1.3.94 1.3.95 1.3.96 1.3.97 1.3.971 1.3.972 1.3.973 1.3.974 1.3.975 1.3.976 1.3.977 1.3.978 1.3.979 1.3.980 1.3.981 1.3.982 1.3.983 1.3.984 1.3.985 1.3.986 1.3.987 1.7.1 1.7.1001 1.7.1002 1.7.1003 1.7.1004 1.7.1005 1.7.1006 1.7.1007 1.7.1008 1.7.1009 1.7.1010 1.7.1011 1.7.1012 1.7.1013 1.7.1014 1.7.1015 1.7.1016 1.7.1017 1.7.1018 1.7.1019 1.7.1020 1.7.1021 1.7.1022 1.7.1023 1.7.1024 1.7.1025 1.7.1026 1.7.1027 1.7.1028 1.7.1029 1.7.1030 1.7.1031 1.7.1032 1.7.1033 1.7.1034 1.7.1035 1.7.1036 1.7.1037 1.7.1038 1.7.1039 1.7.1040 1.7.1041 1.7.1042 1.7.1043 1.7.1044 1.7.1045 1.7.1046 1.7.1047 1.7.1048 1.7.1049 1.7.1050 1.7.1051 1.7.1052 1.7.1053 1.7.1054 1.7.1055 1.7.1056 1.7.1057
royal-elementor-addons / freemius / templates / add-ons.php
royal-elementor-addons / freemius / templates Last commit date
account 5 days ago checkout 5 days ago connect 5 days ago debug 5 days ago forms 5 days ago js 5 days ago partials 5 days ago plugin-info 5 days ago account.php 5 days ago add-ons.php 5 days ago add-trial-to-pricing.php 5 days ago admin-notice.php 5 days ago ajax-loader.php 5 days ago api-connectivity-message-js.php 5 days ago auto-installation.php 5 days ago checkout.php 5 days ago clone-resolution-js.php 5 days ago connect.php 5 days ago contact.php 5 days ago debug.php 5 days ago email.php 5 days ago gdpr-optin-js.php 5 days ago index.php 5 days ago plugin-icon.php 5 days ago pricing.php 5 days ago secure-https-header.php 5 days ago sticky-admin-notice-js.php 5 days ago tabs-capture-js.php 5 days ago tabs.php 5 days ago
add-ons.php
500 lines
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.3
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * @var array $VARS
15 * @var Freemius
16 */
17 $fs = freemius( $VARS['id'] );
18
19 $slug = $fs->get_slug();
20
21 $open_addon_slug = fs_request_get( 'slug' );
22
23 $open_addon = false;
24
25 $is_data_debug_mode = $fs->is_data_debug_mode();
26 $is_whitelabeled = $fs->is_whitelabeled();
27
28 /**
29 * @var FS_Plugin[]
30 */
31 $addons = $fs->get_addons();
32
33 $has_addons = ( is_array( $addons ) && 0 < count( $addons ) );
34
35 $account_addon_ids = $fs->get_updated_account_addons();
36
37 $download_latest_text = fs_text_x_inline( 'Download Latest', 'as download latest version', 'download-latest', $slug );
38 $view_details_text = fs_text_inline( 'View details', 'view-details', $slug );
39
40 $has_tabs = $fs->_add_tabs_before_content();
41
42 $fs_blog_id = ( is_multisite() && ! is_network_admin() ) ?
43 get_current_blog_id() :
44 0;
45 ?>
46 <div id="fs_addons" class="wrap fs-section">
47 <?php if ( ! $has_tabs ) : ?>
48 <h2><?php echo esc_html( sprintf( fs_text_inline( 'Add Ons for %s', 'add-ons-for-x', $slug ), $fs->get_plugin_name() ) ) ?></h2>
49 <?php endif ?>
50
51 <?php $fs->do_action( 'addons/after_title' ) ?>
52
53 <div id="poststuff">
54 <?php if ( ! $has_addons ) : ?>
55 <h3><?php echo esc_html( sprintf(
56 '%s... %s',
57 fs_text_x_inline( 'Oops', 'exclamation', 'oops', $slug ),
58 fs_text_inline( 'We couldn\'t load the add-ons list. It\'s probably an issue on our side, please try to come back in few minutes.', 'add-ons-missing', $slug )
59 ) ) ?></h3>
60 <?php endif ?>
61 <ul class="fs-cards-list">
62 <?php if ( $has_addons ) : ?>
63 <?php
64 $plans_and_pricing_by_addon_id = $fs->_get_addons_plans_and_pricing_map_by_id();
65
66 $active_plugins_directories_map = Freemius::get_active_plugins_directories_map( $fs_blog_id );
67 ?>
68 <?php
69 $hide_all_addons_data = false;
70
71 if ( $fs->is_whitelabeled_by_flag() ) {
72 $hide_all_addons_data = true;
73
74 $addon_ids = $fs->get_updated_account_addons();
75 $installed_addons = $fs->get_installed_addons();
76 foreach ( $installed_addons as $fs_addon ) {
77 $addon_ids[] = $fs_addon->get_id();
78 }
79
80 if ( ! empty( $addon_ids ) ) {
81 $addon_ids = array_unique( $addon_ids );
82 }
83
84 foreach ( $addon_ids as $addon_id ) {
85 $addon = $fs->get_addon( $addon_id );
86
87 if ( ! is_object( $addon ) ) {
88 continue;
89 }
90
91 $addon_storage = FS_Storage::instance( WP_FS__MODULE_TYPE_PLUGIN, $addon->slug );
92
93 if ( ! $addon_storage->is_whitelabeled ) {
94 $hide_all_addons_data = false;
95 break;
96 }
97
98 if ( $is_data_debug_mode ) {
99 $is_whitelabeled = false;
100 }
101 }
102 }
103 ?>
104 <?php foreach ( $addons as $addon ) : ?>
105 <?php
106 $basename = $fs->get_addon_basename( $addon->id );
107
108 $is_addon_installed = file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $basename ) );
109
110 if ( ! $is_addon_installed && $hide_all_addons_data ) {
111 continue;
112 }
113
114 $is_addon_activated = $is_addon_installed ?
115 $fs->is_addon_activated( $addon->id ) :
116 false;
117
118 $is_plugin_active = (
119 $is_addon_activated ||
120 isset( $active_plugins_directories_map[ dirname( $basename ) ] )
121 );
122
123 $open_addon = ( $open_addon || ( $open_addon_slug === $addon->slug ) );
124
125 $price = 0;
126 $has_trial = false;
127 $has_free_plan = false;
128 $has_paid_plan = false;
129
130 if ( isset( $plans_and_pricing_by_addon_id[$addon->id] ) ) {
131 $plans = $plans_and_pricing_by_addon_id[$addon->id];
132
133 if ( is_array( $plans ) && 0 < count( $plans ) ) {
134 foreach ( $plans as $plan ) {
135 if ( ! isset( $plan->pricing ) ||
136 ! is_array( $plan->pricing ) ||
137 0 == count( $plan->pricing )
138 ) {
139 // No pricing means a free plan.
140 $has_free_plan = true;
141 continue;
142 }
143
144
145 $has_paid_plan = true;
146 $has_trial = $has_trial || ( is_numeric( $plan->trial_period ) && ( $plan->trial_period > 0 ) );
147
148 $min_price = 999999;
149 foreach ( $plan->pricing as $pricing ) {
150 $pricing = new FS_Pricing( $pricing );
151
152 if ( ! $pricing->is_usd() ) {
153 /**
154 * Skip non-USD pricing.
155 *
156 * @author Leo Fajardo (@leorw)
157 * @since 2.3.1
158 */
159 continue;
160 }
161
162 if ( $pricing->has_annual() ) {
163 $min_price = min( $min_price, $pricing->annual_price );
164 } else if ( $pricing->has_monthly() ) {
165 $min_price = min( $min_price, 12 * $pricing->monthly_price );
166 }
167 }
168
169 if ( $min_price < 999999 ) {
170 $price = $min_price;
171 }
172
173 }
174 }
175
176 if ( ! $has_paid_plan && ! $has_free_plan ) {
177 continue;
178 }
179 }
180 ?>
181 <li class="fs-card fs-addon" data-slug="<?php echo $addon->slug ?>">
182 <?php
183 $view_details_link = sprintf( '<a href="%s" aria-label="%s" data-title="%s"',
184 esc_url( network_admin_url( 'plugin-install.php?fs_allow_updater_and_dialog=true' . ( ! empty( $fs_blog_id ) ? '&fs_blog_id=' . $fs_blog_id : '' ) . '&tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
185 '&TB_iframe=true&width=600&height=550' ) ),
186 esc_attr( sprintf( fs_text_inline( 'More information about %s', 'more-information-about-x', $slug ), $addon->title ) ),
187 esc_attr( $addon->title )
188 ) . ' class="thickbox%s">%s</a>';
189
190 echo sprintf(
191 $view_details_link,
192 /**
193 * Additional class.
194 *
195 * @author Leo Fajardo (@leorw)
196 * @since 2.2.4
197 */
198 ' fs-overlay',
199 /**
200 * Set the view details link text to an empty string since it is an overlay that
201 * doesn't really need a text and whose purpose is to open the details dialog when
202 * the card is clicked.
203 *
204 * @author Leo Fajardo (@leorw)
205 * @since 2.2.4
206 */
207 ''
208 );
209 ?>
210 <?php
211 if ( is_null( $addon->info ) ) {
212 $addon->info = new stdClass();
213 }
214 if ( ! isset( $addon->info->card_banner_url ) ) {
215 $addon->info->card_banner_url = '//dashboard.freemius.com/assets/img/marketing/blueprint-300x100.jpg';
216 }
217 if ( ! isset( $addon->info->short_description ) ) {
218 $addon->info->short_description = 'What\'s the one thing your add-on does really, really well?';
219 }
220 ?>
221 <div class="fs-inner">
222 <ul>
223 <li class="fs-card-banner"
224 style="background-image: url('<?php echo $addon->info->card_banner_url ?>');"><?php
225 if ( $is_plugin_active || $is_addon_installed ) {
226 echo sprintf(
227 '<span class="fs-badge fs-installed-addon-badge">%s</span>',
228 esc_html( $is_plugin_active ?
229 fs_text_x_inline( 'Active', 'active add-on', 'active-addon', $slug ) :
230 fs_text_x_inline( 'Installed', 'installed add-on', 'installed-addon', $slug )
231 )
232 );
233 }
234 ?></li>
235 <!-- <li class="fs-tag"></li> -->
236 <li class="fs-title"><?php echo $addon->title ?></li>
237 <li class="fs-offer">
238 <span
239 class="fs-price"><?php
240 if ( $is_whitelabeled ) {
241 echo '&nbsp;';
242 } else {
243 $descriptors = array();
244
245 if ($has_free_plan)
246 $descriptors[] = fs_text_inline( 'Free', 'free', $slug );
247 if ($has_paid_plan && $price > 0)
248 $descriptors[] = '$' . number_format( $price, 2 );
249 if ($has_trial)
250 $descriptors[] = fs_text_x_inline( 'Trial', 'trial period', 'trial', $slug );
251
252 echo implode(' - ', $descriptors);
253
254 } ?></span>
255 </li>
256 <li class="fs-description"><?php echo ! empty( $addon->info->short_description ) ? $addon->info->short_description : 'SHORT DESCRIPTION' ?></li>
257 <?php
258 $is_free_only_wp_org_compliant = ( ! $has_paid_plan && $addon->is_wp_org_compliant );
259
260 $is_allowed_to_install = (
261 $fs->is_allowed_to_install() ||
262 $is_free_only_wp_org_compliant
263 );
264
265 $show_premium_activation_or_installation_action = true;
266
267 if ( ! in_array( $addon->id, $account_addon_ids ) ) {
268 $show_premium_activation_or_installation_action = false;
269 } else if ( $is_addon_installed ) {
270 /**
271 * If any add-on's version (free or premium) is installed, check if the
272 * premium version can be activated and show the relevant action. Otherwise,
273 * show the relevant action for the free version.
274 *
275 * @author Leo Fajardo (@leorw)
276 * @since 2.4.5
277 */
278 $fs_addon = $is_addon_activated ?
279 $fs->get_addon_instance( $addon->id ) :
280 null;
281
282 $premium_plugin_basename = is_object( $fs_addon ) ?
283 $fs_addon->premium_plugin_basename() :
284 "{$addon->premium_slug}/{$addon->slug}.php";
285
286 if (
287 ( $is_addon_activated && $fs_addon->is_premium() ) ||
288 file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $premium_plugin_basename ) )
289 ) {
290 $basename = $premium_plugin_basename;
291 }
292
293 $show_premium_activation_or_installation_action = (
294 ( ! $is_addon_activated || ! $fs_addon->is_premium() ) &&
295 /**
296 * This check is needed for cases when an active add-on doesn't have an
297 * associated Freemius instance.
298 *
299 * @author Leo Fajardo (@leorw)
300 * @since 2.4.5
301 */
302 ( ! $is_plugin_active )
303 );
304 }
305 ?>
306 <?php if ( ! $show_premium_activation_or_installation_action ) : ?>
307 <li class="fs-cta"><a class="button"><?php echo esc_html( $view_details_text ) ?></a></li>
308 <?php else : ?>
309 <?php
310 $latest_download_local_url = $is_free_only_wp_org_compliant ?
311 null :
312 $fs->_get_latest_download_local_url( $addon->id );
313 ?>
314
315 <li class="fs-cta fs-dropdown">
316 <div class="button-group">
317 <?php if ( $is_allowed_to_install ) : ?>
318 <?php
319 if ( ! $is_addon_installed ) {
320 echo sprintf(
321 '<a class="button button-primary" href="%s">%s</a>',
322 wp_nonce_url( self_admin_url( 'update.php?' . ( ( $has_paid_plan || ! $addon->is_wp_org_compliant ) ? 'fs_allow_updater_and_dialog=true&' : '' ) . 'action=install-plugin&plugin=' . $addon->slug ), 'install-plugin_' . $addon->slug ),
323 fs_esc_html_inline( 'Install Now', 'install-now', $slug )
324 );
325 } else {
326 echo sprintf(
327 '<a class="button button-primary edit" href="%s" title="%s" target="_parent">%s</a>',
328 wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $basename, 'activate-plugin_' . $basename ),
329 fs_esc_attr_inline( 'Activate this add-on', 'activate-this-addon', $addon->slug ),
330 fs_text_inline( 'Activate', 'activate', $addon->slug )
331 );
332 }
333 ?>
334 <?php else : ?>
335 <a target="_blank" rel="noopener" class="button button-primary" href="<?php echo $latest_download_local_url ?>"><?php echo esc_html( $download_latest_text ) ?></a>
336 <?php endif ?>
337 <div class="button button-primary fs-dropdown-arrow-button"><span class="fs-dropdown-arrow"></span><ul class="fs-dropdown-list" style="display: none">
338 <?php if ( $is_allowed_to_install && ! empty( $latest_download_local_url ) ) : ?>
339 <li><a target="_blank" rel="noopener" href="<?php echo $latest_download_local_url ?>"><?php echo esc_html( $download_latest_text ) ?></a></li>
340 <?php endif ?>
341 <li><?php
342 echo sprintf(
343 $view_details_link,
344 /**
345 * No additional class.
346 *
347 * @author Leo Fajardo (@leorw)
348 * @since 2.2.4
349 */
350 '',
351 /**
352 * Set the view details link text to a non-empty string since it is an
353 * item in the dropdown list and the text should be visible.
354 *
355 * @author Leo Fajardo (@leorw)
356 * @since 2.2.4
357 */
358 esc_html( $view_details_text )
359 );
360 ?></li>
361 </ul></div>
362 </div>
363 </li>
364 <?php endif ?>
365 </ul>
366 </div>
367 </li>
368 <?php endforeach ?>
369 <?php endif ?>
370 </ul>
371 </div>
372
373 <?php $fs->do_action( 'addons/after_addons' ) ?>
374 </div>
375 <script type="text/javascript">
376 (function( $, undef ) {
377 $( 'a.thickbox' ).on( 'click', function () {
378 setTimeout( function () {
379 $( '#TB_window' ).addClass( 'plugin-details-modal' );
380 }, 0 );
381 } );
382
383 <?php if ( $open_addon ) : ?>
384
385 var interval = setInterval(function () {
386 // Open add-on information page.
387 <?php
388 /**
389 * @author Vova Feldman
390 *
391 * This code does NOT expose an XSS vulnerability because:
392 * 1. This page only renders for admins, so if an attacker manage to get
393 * admin access, they can do more harm.
394 * 2. This code won't be rendered unless $open_addon_slug matches any of
395 * the plugin's add-ons slugs.
396 */
397 ?>
398 $('.fs-card[data-slug=<?php echo $open_addon_slug ?>] a').click();
399 if ($('#TB_iframeContent').length > 0) {
400 clearInterval(interval);
401 interval = null;
402 }
403 }, 200);
404
405 <?php else : ?>
406
407 $( '.fs-card.fs-addon' )
408 .mouseover(function() {
409 var $this = $( this );
410
411 $this.find( '.fs-cta .button' ).addClass( 'button-primary' );
412
413 if ( 0 === $this.find( '.fs-dropdown-arrow-button.active' ).length ) {
414 /**
415 * When hovering over a card, close the dropdown on any other card.
416 *
417 * @author Leo Fajardo (@leorw)
418 * @since 2.2.4
419 */
420 toggleDropdown();
421 }
422 }).mouseout(function( evt ) {
423 var $relatedTarget = $( evt.relatedTarget );
424
425 if ( 0 !== $relatedTarget.parents( '.fs-addon' ).length ) {
426 return true;
427 }
428
429 var $this = $( this );
430
431 /**
432 * Set the color of the "View details" button to "secondary".
433 *
434 * @author Leo Fajardo (@leorw)
435 * @since 2.2.4
436 */
437 $this.find( '.fs-cta .button' ).filter(function() {
438 /**
439 * Keep the "primary" color of the dropdown arrow button, "Install Now" button, and
440 * "Download Latest" button.
441
442 * @author Leo Fajardo (@leorw)
443 * @since 2.2.4
444 */
445 return $( this ).parent().is( ':not(.button-group)' );
446 }).removeClass('button-primary');
447
448 toggleDropdown( $this.find( '.fs-dropdown' ), false );
449 }).find( 'a.thickbox, .button:not(.fs-dropdown-arrow-button)' ).click(function() {
450 toggleDropdown();
451 });
452
453 <?php endif ?>
454
455 var $dropdowns = $( '.fs-dropdown' );
456 if ( 0 !== $dropdowns.length ) {
457 $dropdowns.find( '.fs-dropdown-arrow-button' ).click(function() {
458 var $this = $( this ),
459 $dropdown = $this.parents( '.fs-dropdown' );
460
461 toggleDropdown( $dropdown, ! $dropdown.hasClass( 'active' ) );
462 });
463 }
464
465 /**
466 * Returns the default state of the dropdown arrow button and hides the dropdown list.
467 *
468 * @author Leo Fajardo (@leorw)
469 * @since 2.2.4
470 *
471 * @param {(Object|undefined)} [$dropdown]
472 * @param {(Boolean|undefined)} [state]
473 */
474 function toggleDropdown( $dropdown, state ) {
475 if ( undef === $dropdown ) {
476 var $activeDropdown = $dropdowns.find( '.active' );
477 if ( 0 !== $activeDropdown.length ) {
478 $dropdown = $activeDropdown;
479 }
480 }
481
482 if ( undef === $dropdown ) {
483 return;
484 }
485
486 if ( undef === state ) {
487 state = false;
488 }
489
490 $dropdown.toggleClass( 'active', state );
491 $dropdown.find( '.fs-dropdown-list' ).toggle( state );
492 $dropdown.find( '.fs-dropdown-arrow-button' ).toggleClass( 'active', state );
493 }
494 })( jQuery );
495 </script>
496 <?php
497 if ( $has_tabs ) {
498 $fs->_add_tabs_after_content();
499 }
500