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