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