PluginProbe ʕ •ᴥ•ʔ
Code Manager / 1.0.17
Code Manager v1.0.17
1.0.48 1.0.47 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.2 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 1.0.25 1.0.26 1.0.27 1.0.28 1.0.3 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 1.0.39 1.0.4 1.0.40 1.0.41 1.0.42 1.0.43 1.0.44 1.0.45 1.0.46 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9
code-manager / freemius / templates / forms / license-activation.php
code-manager / freemius / templates / forms Last commit date
deactivation 4 years ago affiliation.php 4 years ago data-debug-mode.php 4 years ago index.php 4 years ago license-activation.php 4 years ago optout.php 4 years ago premium-versions-upgrade-handler.php 4 years ago premium-versions-upgrade-metadata.php 4 years ago resend-key.php 4 years ago subscription-cancellation.php 4 years ago trial-start.php 4 years ago user-change.php 4 years ago
license-activation.php
870 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.1.9
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * @var array $VARS
15 *
16 * @var Freemius $fs
17 */
18 $fs = freemius( $VARS['id'] );
19 $slug = $fs->get_slug();
20 $unique_affix = $fs->get_unique_affix();
21
22 $cant_find_license_key_text = fs_text_inline( "Can't find your license key?", 'cant-find-license-key', $slug );
23 $message_above_input_field = fs_text_inline( 'Please enter the license key that you received in the email right after the purchase:', 'activate-license-message', $slug );
24 $message_below_input_field = '';
25
26 $header_title = $fs->is_free_plan() ?
27 fs_text_inline( 'Activate License', 'activate-license', $slug ) :
28 fs_text_inline( 'Update License', 'update-license', $slug );
29
30 if ( $fs->is_registered() ) {
31 $activate_button_text = $header_title;
32 } else {
33 $freemius_site_url = $fs->has_paid_plan() ?
34 'https://freemius.com/' :
35 // Insights platform information.
36 $fs->get_usage_tracking_terms_url();
37
38 $freemius_link = '<a href="' . $freemius_site_url . '" target="_blank" rel="noopener" tabindex="0">freemius.com</a>';
39
40 $message_below_input_field = sprintf(
41 fs_text_inline( 'The %1$s will be periodically sending data to %2$s to check for security and feature updates, and verify the validity of your license.', 'license-sync-disclaimer', $slug ),
42 $fs->get_module_label( true ),
43 $freemius_link
44 );
45
46 $activate_button_text = fs_text_inline( 'Agree & Activate License', 'agree-activate-license', $slug );
47 }
48
49 $license_key_text = fs_text_inline( 'License key', 'license-key' , $slug );
50
51 $is_network_activation = (
52 $fs->is_network_active() &&
53 fs_is_network_admin() &&
54 ! $fs->is_delegated_connection()
55 );
56 $network_activation_html = '';
57
58 $sites_details = array();
59 if ( $is_network_activation ) {
60 $all_sites = Freemius::get_sites();
61
62 foreach ( $all_sites as $site ) {
63 $site_details = $fs->get_site_info( $site );
64
65 $blog_id = Freemius::get_site_blog_id( $site );
66 $install = $fs->get_install_by_blog_id($blog_id);
67
68 if ( is_object( $install ) && FS_Plugin_License::is_valid_id( $install->license_id ) ) {
69 $site_details['license_id'] = $install->license_id;
70 }
71
72 $sites_details[] = $site_details;
73 }
74
75 if ( $is_network_activation ) {
76 $vars = array(
77 'id' => $fs->get_id(),
78 'sites' => $sites_details,
79 'require_license_key' => true
80 );
81
82 $network_activation_html = fs_get_template( 'partials/network-activation.php', $vars );
83 }
84 }
85
86 $premium_licenses = $fs->get_available_premium_licenses();
87 $available_licenses = array();
88 foreach ( $premium_licenses as $premium_license ) {
89 $activations_left = $premium_license->left();
90 if ( ! ( $activations_left > 0 ) ) {
91 continue;
92 }
93
94 $available_licenses[ $activations_left . '_' . $premium_license->id ] = $premium_license;
95 }
96
97 $total_available_licenses = count( $available_licenses );
98 if ( $total_available_licenses > 0 ) {
99 $license_input_html = <<< HTML
100 <div class="fs-license-options-container">
101 <table>
102 <tbody>
103 <tr class="fs-available-license-key-container">
104 <td><input type="radio" name="license_type" value="available"></td>
105 <td>
106 HTML;
107
108 if ( $total_available_licenses > 1 ) {
109 // Sort the licenses by number of activations left in descending order.
110 krsort( $available_licenses );
111
112 $license_input_html .= '<select class="fs-licenses">';
113
114 /**
115 * @var FS_Plugin_License $license
116 */
117 foreach ( $available_licenses as $license ) {
118 $plan = $fs->_get_plan_by_id( $license->plan_id );
119
120 $label = sprintf(
121 "%s-Site %s License - %s",
122 ( 1 == $license->quota ?
123 'Single' :
124 ( $license->is_unlimited() ? 'Unlimited' : $license->quota )
125 ),
126 ( is_object( $plan ) ? $plan->title : '' ),
127 $license->get_html_escaped_masked_secret_key()
128 );
129
130 $license_input_html .= "<option data-id='{$license->id}' value='{$license->secret_key}' data-left='{$license->left()}'>{$label}</option>";
131 }
132
133 $license_input_html .= '</select>';
134 } else {
135 $available_licenses = array_values( $available_licenses );
136
137 /**
138 * @var FS_Plugin_License $available_license
139 */
140 $available_license = $available_licenses[0];
141 $value = sprintf(
142 "%s-Site %s License - %s",
143 ( 1 == $available_license->quota ?
144 'Single' :
145 ( $available_license->is_unlimited() ? 'Unlimited' : $available_license->quota )
146 ),
147 $fs->_get_plan_by_id( $available_license->plan_id )->title,
148 $available_license->get_html_escaped_masked_secret_key()
149 );
150
151 $license_input_html .= <<< HTML
152 <input
153 class="fs-available-license-key"
154 type="text"
155 value="{$value}"
156 data-id="{$available_license->id}"
157 data-license-key="{$available_license->secret_key}"
158 data-left="{$available_license->left()}"
159 readonly />
160 HTML;
161 }
162
163 $license_input_html .= <<< HTML
164 </td>
165 </tr>
166 <tr>
167 <td><input type="radio" name="license_type" value="other"></td>
168 <td class="fs-other-license-key-container">
169 <label for="other_license_key_{$unique_affix}">Other: </label>
170 <div>
171 <input id="other_license_key_{$unique_affix}" class="fs-license-key" type="text" placeholder="Enter license key" tabindex="1">
172 </div>
173 </td>
174 </tr>
175 </tbody>
176 </table>
177 </div>
178 HTML;
179 } else {
180 $license_input_html = "<input class='fs-license-key' type='text' placeholder='{$license_key_text}' tabindex='1' />";
181 }
182
183 $ownership_change_option_text = fs_text_inline( "Associate with the license owner's account.", 'associate-account-with-license-owner', $slug );
184 $ownership_change_option_html = "<div class='ownership-change-option-container' style='display: none'><label><input type='checkbox' /> <strong>{$ownership_change_option_text}</strong></label></div>";
185
186 /**
187 * IMPORTANT:
188 * DO NOT ADD MAXLENGTH OR LIMIT THE LICENSE KEY LENGTH SINCE
189 * WE DO WANT TO ALLOW INPUT OF LONGER KEYS (E.G. WooCommerce Keys)
190 * FOR MIGRATED MODULES.
191 */
192 $modal_content_html = <<< HTML
193 <div class="notice notice-error inline license-activation-message"><p></p></div>
194 <p>{$message_above_input_field}</p>
195 {$license_input_html}
196 <a class="show-license-resend-modal show-license-resend-modal-{$fs->get_unique_affix()}" href="!#" tabindex="2">{$cant_find_license_key_text}</a>
197 {$network_activation_html}
198 <p>{$message_below_input_field}</p>
199 {$ownership_change_option_html}
200 HTML;
201
202 /**
203 * Handle the ownership change option if not an add-on or if no license yet is activated for the
204 * parent product in case of an add-on.
205 *
206 * @author Leo Fajardo (@leorw)
207 * @since 2.3.2
208 */
209 $is_user_change_supported = ( ! $fs->is_addon() || ! $fs->get_parent_instance()->has_active_valid_license() );
210
211 fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
212 ?>
213 <script type="text/javascript">
214 (function( $ ) {
215 $( document ).ready(function() {
216 var modalContentHtml = <?php echo json_encode($modal_content_html); ?>,
217 modalHtml =
218 '<div class="fs-modal fs-modal-license-activation fs-modal-license-activation-<?php echo $unique_affix ?>">'
219 + ' <div class="fs-modal-dialog">'
220 + ' <div class="fs-modal-header">'
221 + ' <h4><?php echo esc_js($header_title) ?></h4>'
222 + ' <a href="!#" class="fs-close"><i class="dashicons dashicons-no" title="<?php echo esc_js( fs_text_x_inline( 'Dismiss', 'as close a window', 'dismiss', $slug ) ) ?>"></i></a>'
223 + ' </div>'
224 + ' <div class="fs-modal-body">'
225 + ' <div class="fs-modal-panel active">' + modalContentHtml + '</div>'
226 + ' </div>'
227 + ' <div class="fs-modal-footer">'
228 + ' <button class="button button-secondary button-close" tabindex="4"><?php fs_esc_js_echo_inline( 'Cancel', 'cancel', $slug ) ?></button>'
229 + ' <button class="button button-primary button-activate-license" tabindex="3"><?php echo esc_js( $activate_button_text ) ?></button>'
230 + ' </div>'
231 + ' </div>'
232 + '</div>',
233 $modal = $(modalHtml),
234 $activateLicenseButton = $modal.find('.button-activate-license'),
235 $licenseKeyInput = $modal.find( 'input.fs-license-key' ),
236 $licenseActivationMessage = $modal.find( '.license-activation-message' ),
237 isNetworkActivation = <?php echo $is_network_activation ? 'true' : 'false' ?>,
238 isUserChangeSupported = <?php echo $is_user_change_supported ? 'true' : 'false' ?>,
239 isSingleSiteActivation = false,
240 $ownershipChangeOptionContainer = $modal.find( '.ownership-change-option-container' ),
241 $body = $( 'body' );
242
243 $modal.appendTo( $body );
244
245 var
246 $licensesDropdown = $modal.find( '.fs-licenses' ),
247 $licenseTypes = $modal.find( 'input[type="radio"][name="license_type"]' ),
248 $applyOnAllSites = $modal.find( '.fs-apply-on-all-sites-checkbox' ),
249 $sitesListContainer = $modal.find( '.fs-sites-list-container' ),
250 $availableLicenseKey = $modal.find( '.fs-available-license-key' ),
251 $otherLicenseKey = $modal.find( '#other_license_key_<?php echo $unique_affix ?>' ),
252 $multisiteOptionsContainer = $modal.find( '.fs-multisite-options-container' ),
253 $activationsLeft = null,
254 hasLicensesDropdown = ( $licensesDropdown.length > 0 ),
255 hasLicenseTypes = ( $licenseTypes.length > 0 ),
256 maxSitesListHeight = null,
257 totalSites = <?php echo count( $sites_details ) ?>,
258 singleBlogID = null;
259
260 var
261 previousLicenseKey = null,
262 otherLicenseOwnerID = null,
263 /**
264 * @author Leo Fajardo (@leorw)
265 * @since 2.3.2
266 */
267 resetLoadingMode = function () {
268 // Reset loading mode.
269 $activateLicenseButton.text( <?php echo json_encode( $activate_button_text ) ?> );
270 $activateLicenseButton.prop( 'disabled', false );
271 $( document.body ).css( { 'cursor': 'auto' } );
272 $( '.fs-loading' ).removeClass( 'fs-loading' );
273
274 console.log( 'resetLoadingMode - Primary button was enabled' );
275 },
276 /**
277 * @author Leo Fajardo (@leorw)
278 * @since 2.3.2
279 */
280 setLoadingMode = function () {
281 $( document.body ).css( { 'cursor': 'wait' } );
282 },
283 /**
284 * @author Leo Fajardo (@leorw)
285 * @since 2.3.2
286 */
287 afterLicenseUserDataLoaded = function () {
288 if (
289 null !== otherLicenseOwnerID &&
290 otherLicenseOwnerID != <?php echo $fs->is_registered() ? $fs->get_user()->id : 'null' ?>
291 ) {
292 $ownershipChangeOptionContainer.show();
293 } else {
294 $ownershipChangeOptionContainer.hide();
295 $activateLicenseButton.focus();
296 }
297 },
298 /**
299 * @author Leo Fajardo (@leorw)
300 * @since 2.3.2
301 */
302 fetchLicenseUserData = function () {
303 var hideAndUncheckUserChangeCheckbox = ( ! isUserChangeSupported ),
304 otherLicenseKeyIsSelected = isOtherLicenseKeySelected();
305
306 if ( ! hideAndUncheckUserChangeCheckbox ) {
307 // User change is supported only on the site level.
308 hideAndUncheckUserChangeCheckbox = ( isNetworkActivation || isSingleSiteActivation );
309 }
310
311 if ( ! hideAndUncheckUserChangeCheckbox ) {
312 hideAndUncheckUserChangeCheckbox = ( hasLicenseTypes && ! otherLicenseKeyIsSelected );
313 }
314
315 var licenseKey = $licenseKeyInput.val().trim();
316
317 if ( ! hideAndUncheckUserChangeCheckbox && otherLicenseKeyIsSelected ) {
318 hideAndUncheckUserChangeCheckbox = ( licenseKey.length < 32 );
319 }
320
321 if ( licenseKey !== previousLicenseKey ) {
322 // If the license key has not been changed, keep the owner ID in order to prevent another API call.
323 otherLicenseOwnerID = null;
324 }
325
326 if ( hideAndUncheckUserChangeCheckbox ) {
327 $ownershipChangeOptionContainer.hide().find( 'input' ).attr( 'checked', false );
328
329 return;
330 }
331
332 if ( null !== otherLicenseOwnerID ) {
333 afterLicenseUserDataLoaded();
334 return;
335 }
336
337 setLoadingMode();
338
339 $activateLicenseButton.addClass( 'fs-loading' );
340 $activateLicenseButton.attr( 'disabled', 'disabled' );
341 $activateLicenseButton.html( '<?php fs_esc_js_echo_inline( 'Please wait', 'please-wait', $slug ) ?>...' );
342
343 $.ajax( {
344 url : ajaxurl,
345 method : 'POST',
346 data : {
347 action : '<?php echo $fs->get_ajax_action( 'fetch_is_marketing_required_flag_value' ) ?>',
348 security : '<?php echo $fs->get_ajax_security( 'fetch_is_marketing_required_flag_value' ) ?>',
349 license_key: licenseKey,
350 module_id : '<?php echo $fs->get_id() ?>'
351 },
352 success: function ( result ) {
353 resetLoadingMode();
354
355 if ( result.success ) {
356 result = result.data;
357
358 // Cache license owner's ID.
359 otherLicenseOwnerID = result.license_owner_id;
360 }
361
362 afterLicenseUserDataLoaded();
363 }
364 } );
365 };
366
367 function registerEventHandlers() {
368 var
369 $otherLicenseKeyContainer = $modal.find( '.fs-other-license-key-container' );
370
371 if ( isNetworkActivation ) {
372 $applyOnAllSites.click(function() {
373 var applyOnAllSites = $( this ).is( ':checked' );
374
375 $multisiteOptionsContainer.toggleClass( 'fs-apply-on-all-sites', applyOnAllSites );
376
377 showSites( ! applyOnAllSites );
378
379 if ( hasValidLicenseKey() && ( applyOnAllSites || hasSelectedSite() ) ) {
380 enableActivateLicenseButton();
381 } else {
382 disableActivateLicenseButton();
383 }
384 });
385
386 $sitesListContainer.delegate( 'td:not(:first-child)', 'click', function() {
387 // If a site row is clicked, trigger a click on the checkbox.
388 $( this ).parent().find( 'td:first-child input' ).click();
389 });
390
391 $sitesListContainer.delegate( 'input[type="checkbox"]', 'click', function() {
392 enableDisableSitesSelection();
393
394 if ( hasValidLicenseKey() && hasSelectedSite() ) {
395 enableActivateLicenseButton();
396 } else {
397 disableActivateLicenseButton();
398 }
399 });
400 }
401
402 if ( hasLicensesDropdown ) {
403 $licensesDropdown.change(function() {
404 // When a license is selected, select the associated radio button.
405 $licenseTypes.filter( '[value="available"]' ).attr( 'checked', true );
406
407 if ( ! isNetworkActivation || $modal.hasClass( 'is-single-site-activation' ) ) {
408 enableActivateLicenseButton();
409 return true;
410 }
411
412 toggleActivationOnAllSites();
413 })
414 }
415
416 if ( hasLicenseTypes ) {
417 $licenseTypes.change(function() {
418 var
419 licenseKey = $modal.find( 'input.fs-license-key' ).val().trim(),
420 otherLicenseKeySelected = isOtherLicenseKeySelected();
421
422 if ( ( licenseKey.length > 0 || ( hasLicenseTypes && ! otherLicenseKeySelected ) ) &&
423 ( $modal.hasClass( 'is-single-site-activation' ) || ! isNetworkActivation || hasSelectedSite() )
424 ) {
425 /**
426 * If the "other" license is not empty or an available license is selected, enable the activate
427 * button.
428 *
429 * @author Leo Fajardo (@leorw)
430 */
431 enableActivateLicenseButton();
432 } else {
433 disableActivateLicenseButton();
434 }
435
436 if ( '' !== licenseKey ) {
437 fetchLicenseUserData();
438 }
439
440 if ( ! isNetworkActivation ) {
441 return;
442 }
443
444 if ( otherLicenseKeySelected ) {
445 $applyOnAllSites.attr( 'disabled', false );
446 enableDisableSitesSelection();
447 resetActivateLicenseCheckboxLabel();
448 } else if ( ! $modal.hasClass( 'is-single-site-activation' ) ) {
449 toggleActivationOnAllSites();
450 }
451 });
452
453 if ( ! hasLicensesDropdown ) {
454 $availableLicenseKey.click(function() {
455 $licenseTypes.filter( '[value="available"]' ).click();
456 });
457 }
458
459 $otherLicenseKeyContainer.click(function() {
460 $licenseTypes.filter( '[value="other"]' ).click();
461 });
462 }
463
464 $body.on( 'click', 'span.activate-license.<?php echo $unique_affix ?> a, .activate-license-trigger.<?php echo $unique_affix ?>', function (evt) {
465 evt.preventDefault();
466
467 showModal( evt );
468 });
469
470 var licenseTimeout = null;
471
472 /**
473 * Disable activation button when license key is empty.
474 *
475 * @author Leo Fajardo (@leorw)
476 * @since 2.3.2
477 */
478 $modal.on( 'keyup paste delete cut', 'input.fs-license-key', function () {
479 clearTimeout(licenseTimeout);
480
481 licenseTimeout = setTimeout( function () {
482 var licenseKey = $licenseKeyInput.val().trim();
483
484 if ( licenseKey == previousLicenseKey ) {
485 afterLicenseUserDataLoaded();
486 return;
487 }
488
489 if ( '' === licenseKey ) {
490 disableActivateLicenseButton();
491 $ownershipChangeOptionContainer.hide();
492 } else {
493 enableActivateLicenseButton();
494
495 if ( 32 <= licenseKey.length ) {
496 fetchLicenseUserData();
497 } else {
498 $ownershipChangeOptionContainer.hide();
499 }
500 }
501
502 previousLicenseKey = licenseKey;
503 }, 200 );
504 } ).focus();
505
506 $modal.on('input propertychange', 'input.fs-license-key', function () {
507
508 var licenseKey = $(this).val().trim();
509
510 /**
511 * If license key is not empty, enable the license activation button.
512 */
513 if ( licenseKey.length > 0 && ( $modal.hasClass( 'is-single-site-activation' ) || ! isNetworkActivation || hasSelectedSite() ) ) {
514 enableActivateLicenseButton();
515 }
516 });
517
518 $modal.on( 'blur', 'input.fs-license-key', function( evt ) {
519 var
520 licenseKey = $(this).val().trim(),
521 $focusedElement = $( evt.relatedTarget ),
522 hasSelectedAvailableLicense = ( hasLicenseTypes && $focusedElement.parents( '.fs-available-license-key-container' ).length > 0 );
523
524 /**
525 * If license key is empty, disable the license activation button.
526 */
527 if ( ( 0 === licenseKey.length && ( ! hasLicenseTypes || ! hasSelectedAvailableLicense ) ) ||
528 ( isNetworkActivation && ! hasSelectedSite() )
529 ) {
530 disableActivateLicenseButton();
531 }
532 });
533
534 $modal.on('click', '.button-activate-license', function (evt) {
535 evt.preventDefault();
536
537 if ($(this).hasClass('disabled')) {
538 return;
539 }
540
541 var
542 licenseKey = '';
543
544 if ( hasLicenseTypes ) {
545 if ( isOtherLicenseKeySelected() ) {
546 licenseKey = $otherLicenseKey.val();
547 } else {
548 if ( ! hasLicensesDropdown ) {
549 licenseKey = $availableLicenseKey.data( 'license-key' );
550 } else {
551 licenseKey = $licensesDropdown.val();
552 }
553 }
554 } else {
555 licenseKey = $licenseKeyInput.val().trim();
556 }
557
558 disableActivateLicenseButton();
559
560 if (0 === licenseKey.length) {
561 return;
562 }
563
564 var data = {
565 action : '<?php echo $fs->get_ajax_action( 'activate_license' ) ?>',
566 security : '<?php echo $fs->get_ajax_security( 'activate_license' ) ?>',
567 license_key: licenseKey,
568 module_id : '<?php echo $fs->get_id() ?>'
569 };
570
571 if ( isNetworkActivation ) {
572 var
573 sites = [];
574
575 if ( null === singleBlogID ) {
576 var
577 applyOnAllSites = $applyOnAllSites.is( ':checked' );
578
579 $sitesListContainer.find( 'tr' ).each(function() {
580 var
581 $this = $( this ),
582 includeSite = ( applyOnAllSites || $this.find( 'input' ).is( ':checked' ) );
583
584 if ( ! includeSite )
585 return;
586
587 var site = {
588 uid : $this.find( '.uid' ).val(),
589 url : $this.find( '.url' ).val(),
590 title : $this.find( '.title' ).val(),
591 language: $this.find( '.language' ).val(),
592 charset : $this.find( '.charset' ).val(),
593 blog_id : $this.find( '.blog-id' ).find( 'span' ).text()
594 };
595
596 sites.push( site );
597 });
598 } else {
599 data.blog_id = singleBlogID;
600 }
601
602 data.sites = sites;
603 }
604
605 if ( $ownershipChangeOptionContainer.find( 'input:checked' ).length > 0 ) {
606 data.user_id = otherLicenseOwnerID;
607 }
608
609 $.ajax({
610 url: ajaxurl,
611 method: 'POST',
612 data: data,
613 beforeSend: function () {
614 $activateLicenseButton.text( '<?php fs_esc_js_echo_inline( 'Activating license', 'activating-license', $slug ) ?>...' );
615 },
616 success: function( result ) {
617 var resultObj = $.parseJSON( result );
618 if ( resultObj.success ) {
619 closeModal();
620
621 // Redirect to the "Account" page and sync the license.
622 window.location.href = resultObj.next_page;
623 } else {
624 showError( resultObj.error.message ? resultObj.error.message : resultObj.error );
625 resetActivateLicenseButton();
626 }
627 }
628 });
629 });
630
631 // If the user has clicked outside the window, close the modal.
632 $modal.on('click', '.fs-close, .button-secondary', function () {
633 closeModal();
634 return false;
635 });
636 }
637
638 registerEventHandlers();
639
640 $body.trigger('licenseActivationLoaded');
641
642 /**
643 * @author Leo Fajardo (@leorw)
644 * @since 2.0.0
645 */
646 function enableDisableSitesSelection() {
647 var
648 canApplyOnAllSites = $applyOnAllSites.is( ':enabled' ),
649 disableSitesSelection = null;
650
651 if ( ! canApplyOnAllSites ) {
652 var
653 selectedSites = $sitesListContainer.find( 'input[type="checkbox"]:checked' ).length,
654 activationsLeft = Math.max( 0, $activationsLeft.data( 'left' ) - selectedSites );
655
656 disableSitesSelection = ( 0 === activationsLeft );
657
658 $activationsLeft.text( activationsLeft );
659 } else {
660 disableSitesSelection = false;
661 }
662
663 $sitesListContainer
664 .find( 'input[type="checkbox"]:not(:checked)' )
665 .attr( 'disabled', disableSitesSelection );
666 }
667
668 /**
669 * @author Leo Fajardo (@leorw)
670 * @since 2.0.0
671 *
672 * @returns {Boolean}
673 */
674 function isOtherLicenseKeySelected() {
675 return ( hasLicenseTypes && 'other' === $licenseTypes.filter( ':checked' ).val() );
676 }
677
678 /**
679 * @author Leo Fajardo (@leorw)
680 * @since 2.0.0
681 *
682 * @returns {Boolean}
683 */
684 function hasValidLicenseKey() {
685 var licenseKey = '';
686 if ( hasLicenseTypes ) {
687 if ( 'available' === $licenseTypes.filter( ':checked' ).val() ) {
688 return true;
689 } else {
690 licenseKey = $otherLicenseKey.val();
691 }
692 } else {
693 licenseKey = $modal.find( 'input.fs-license-key' ).val();
694 }
695
696 return ( licenseKey.trim().length > 0 );
697 }
698
699 /**
700 * @author Leo Fajardo (@leorw)
701 * @since 2.0.0
702 *
703 * @returns {Boolean}
704 */
705 function hasSelectedSite() {
706 return ( $applyOnAllSites.is( ':checked' ) ||
707 $sitesListContainer.find( 'input[type="checkbox"]:checked:not(:disabled)' ).length > 0 );
708 }
709
710 /**
711 * @author Leo Fajardo (@leorw)
712 * @since 2.0.0
713 */
714 function toggleActivationOnAllSites() {
715 var activationsLeft,
716 licenseID;
717
718 if (hasLicensesDropdown) {
719 var $selectedOption = $licensesDropdown.find( ':selected' );
720 activationsLeft = $selectedOption.data('left');
721 licenseID = $selectedOption.data('id');
722 } else {
723 activationsLeft = $availableLicenseKey.data('left');
724 licenseID = $availableLicenseKey.data('id');
725 }
726
727 // Cleanup previously auto-selected site.
728 $modal.find( '.fs-sites-list-container input[type=checkbox]:disabled' )
729 .attr('disabled', false)
730 .attr('checked', false);
731
732 var $blogsWithActiveLicense = $modal.find( '.fs-sites-list-container tr[data-license-id=' + licenseID + '] input[type=checkbox]' );
733
734 if ($blogsWithActiveLicense.length > 0) {
735 $blogsWithActiveLicense.attr('checked', true)
736 .attr('disabled', true);
737
738 activationsLeft += $blogsWithActiveLicense.length;
739 }
740
741 if ( activationsLeft >= totalSites ) {
742 $applyOnAllSites.attr( 'disabled', false );
743 enableDisableSitesSelection();
744
745 resetActivateLicenseCheckboxLabel();
746
747 return;
748 }
749
750 $applyOnAllSites.attr( 'checked', false );
751 $applyOnAllSites.attr( 'disabled', true );
752
753 showSites( true );
754
755 var
756 activateLicenseCheckboxLabel = '<?php fs_esc_js_echo_inline( 'Choose up to %s site(s) to activate the license on.', 'choose-up-to-n-sites-to-activate-the-license-on', $slug ) ?>';
757
758 activateLicenseCheckboxLabel = activateLicenseCheckboxLabel.replace( '%s', '<span data-left="' + activationsLeft + '" class="activations-left">' + activationsLeft + '</span>' );
759
760 // Update the label of the "Activate license on all sites" checkbox.
761 $applyOnAllSites.parent().find( 'span' ).html( activateLicenseCheckboxLabel );
762 $activationsLeft = $modal.find( '.activations-left' );
763
764 if ( hasSelectedSite() ) {
765 enableActivateLicenseButton();
766 enableDisableSitesSelection();
767 } else {
768 disableActivateLicenseButton();
769 }
770 }
771
772 /**
773 * @author Leo Fajardo (@leorw)
774 * @since 2.0.0
775 */
776 function resetActivateLicenseCheckboxLabel() {
777 var activateLicenseCheckboxLabel = '<?php fs_esc_js_echo_inline( 'Activate license on all sites in the network.', 'activate-license-on-all-sites-in-the-network', $slug ) ?>';
778 $applyOnAllSites.parent().find( 'span' ).text( activateLicenseCheckboxLabel );
779 }
780
781 /**
782 * @author Leo Fajardo (@leorw)
783 * @since 2.0.0
784 *
785 * @param {Boolean} show
786 */
787 function showSites( show ) {
788 $sitesListContainer.toggle( show );
789 if ( show && null === maxSitesListHeight ) {
790 /**
791 * Set the visible number of rows to 5 (5 * height of the first row).
792 *
793 * @author Leo Fajardo (@leorw)
794 */
795 maxSitesListHeight = ( 5 * $sitesListContainer.find( 'tr:first' ).height() );
796 $sitesListContainer.css( 'max-height', maxSitesListHeight );
797 }
798 }
799
800 function showModal( evt ) {
801 resetModal();
802
803 // Display the dialog box.
804 $modal.addClass('active');
805 $body.addClass('has-fs-modal');
806
807 var
808 $singleInstallDetails = $( evt.target ).parents( 'tr.fs-install-details' ),
809 isSingleSiteActivation = ( $singleInstallDetails.length > 0 );
810
811 $modal.toggleClass( 'is-single-site-activation', isSingleSiteActivation );
812
813 singleBlogID = isSingleSiteActivation ?
814 $singleInstallDetails.prev().data( 'blog-id' ) :
815 null;
816
817 <?php if ( $fs->apply_filters( 'enable_per_site_activation', true ) ) : ?>
818 $multisiteOptionsContainer.toggle( isNetworkActivation && ! isSingleSiteActivation );
819 <?php endif ?>
820
821 if ( hasLicenseTypes ) {
822 $licenseTypes.attr( 'checked', false );
823
824 if ( hasLicensesDropdown ) {
825 $licensesDropdown.find( 'option:first' ).attr( 'selected', true ).trigger( 'change' );
826 } else {
827 $licenseTypes.filter( '[value="available"]' ).click();
828 }
829
830 $otherLicenseKey.val( '' );
831 } else {
832 $licenseKeyInput.val( '' );
833 $licenseKeyInput.focus();
834 }
835 }
836
837 function closeModal() {
838 $modal.removeClass('active');
839 $body.removeClass('has-fs-modal');
840 }
841
842 function resetActivateLicenseButton() {
843 enableActivateLicenseButton();
844 $activateLicenseButton.text( <?php echo json_encode( $activate_button_text ) ?> );
845 }
846
847 function resetModal() {
848 hideError();
849 resetActivateLicenseButton();
850 }
851
852 function enableActivateLicenseButton() {
853 $activateLicenseButton.removeClass( 'disabled' );
854 }
855
856 function disableActivateLicenseButton() {
857 $activateLicenseButton.addClass( 'disabled' );
858 }
859
860 function hideError() {
861 $licenseActivationMessage.hide();
862 }
863
864 function showError( msg ) {
865 $licenseActivationMessage.find( ' > p' ).html( msg );
866 $licenseActivationMessage.show();
867 }
868 });
869 })( jQuery );
870 </script>