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