076cad37 by Jeremy Groot

plugin updates

1 parent 01f7a082
Showing 183 changed files with 4648 additions and 21 deletions
...@@ -310,6 +310,17 @@ class Password_Protected_Admin { ...@@ -310,6 +310,17 @@ class Password_Protected_Admin {
310 'password-protected-advanced-tab' 310 'password-protected-advanced-tab'
311 ); 311 );
312 312
313 add_settings_field(
314 'password-protected-use-transient',
315 __( 'Use Transients', 'password-protected' ),
316 array( $this, 'password_protected_use_transient' ),
317 'password-protected&tab=advanced',
318 'password-protected-advanced-tab',
319 array(
320 'label_for' => 'password-protected-use-transient',
321 )
322 );
323
313 // password protected help tab 324 // password protected help tab
314 add_settings_section( 325 add_settings_section(
315 'password-protected-help', 326 'password-protected-help',
...@@ -318,6 +329,7 @@ class Password_Protected_Admin { ...@@ -318,6 +329,7 @@ class Password_Protected_Admin {
318 'password-protected-help' 329 'password-protected-help'
319 ); 330 );
320 331
332
321 // sidebar login designer compatibity 333 // sidebar login designer compatibity
322 if( !$this->login_designer_is_installed_and_activated() ) { 334 if( !$this->login_designer_is_installed_and_activated() ) {
323 add_settings_section( 335 add_settings_section(
...@@ -347,6 +359,7 @@ class Password_Protected_Admin { ...@@ -347,6 +359,7 @@ class Password_Protected_Admin {
347 register_setting( $this->options_group, 'password_protected_allowed_ip_addresses', array( $this, 'sanitize_ip_addresses' ) ); 359 register_setting( $this->options_group, 'password_protected_allowed_ip_addresses', array( $this, 'sanitize_ip_addresses' ) );
348 register_setting( $this->options_group, 'password_protected_remember_me', 'boolval' ); 360 register_setting( $this->options_group, 'password_protected_remember_me', 'boolval' );
349 register_setting( $this->options_group, 'password_protected_remember_me_lifetime', 'intval' ); 361 register_setting( $this->options_group, 'password_protected_remember_me_lifetime', 'intval' );
362 register_setting( $this->options_group . '-advanced', 'password_protected_use_transient' );
350 register_setting( $this->options_group.'-advanced', 'password_protected_text_above_password', array( 'type' => 'string' ) ); 363 register_setting( $this->options_group.'-advanced', 'password_protected_text_above_password', array( 'type' => 'string' ) );
351 register_setting( $this->options_group.'-advanced', 'password_protected_text_below_password', array( 'type' => 'string' ) ); 364 register_setting( $this->options_group.'-advanced', 'password_protected_text_below_password', array( 'type' => 'string' ) );
352 365
...@@ -474,8 +487,7 @@ class Password_Protected_Admin { ...@@ -474,8 +487,7 @@ class Password_Protected_Admin {
474 * Allowed IP Addresses Field 487 * Allowed IP Addresses Field
475 */ 488 */
476 public function password_protected_allowed_ip_addresses_field() { 489 public function password_protected_allowed_ip_addresses_field() {
477 490 echo '<textarea name="password_protected_allowed_ip_addresses" id="password_protected_allowed_ip_addresses" rows="3" />' . esc_html( get_option( 'password_protected_allowed_ip_addresses' ) ) . '</textarea>';
478 echo '<textarea name="password_protected_allowed_ip_addresses" id="password_protected_allowed_ip_addresses" rows="3" />' . get_option( 'password_protected_allowed_ip_addresses' ) . '</textarea>';
479 491
480 echo '<p class="description">' . esc_html__( 'Enter one IP address per line.', 'password-protected' ); 492 echo '<p class="description">' . esc_html__( 'Enter one IP address per line.', 'password-protected' );
481 if ( isset( $_SERVER['REMOTE_ADDR'] ) ) { 493 if ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
...@@ -514,14 +526,20 @@ class Password_Protected_Admin { ...@@ -514,14 +526,20 @@ class Password_Protected_Admin {
514 * Password Protected text above passsword 526 * Password Protected text above passsword
515 */ 527 */
516 public function password_protected_text_above_password() { 528 public function password_protected_text_above_password() {
517 echo '<label><textarea id="password_protected_text_above_password" name="password_protected_text_above_password" rows="4" cols="50" class="regular-text">' . get_option('password_protected_text_above_password') . '</textarea></label>'; 529 echo '<label><textarea id="password_protected_text_above_password" name="password_protected_text_above_password" rows="4" cols="50" class="regular-text">' . esc_attr( get_option('password_protected_text_above_password') ) . '</textarea></label>';
518 } 530 }
519 531
520 /** 532 /**
521 * Password Protected below above passsword 533 * Password Protected below above passsword
522 */ 534 */
523 public function password_protected_text_below_password() { 535 public function password_protected_text_below_password() {
524 echo '<label><textarea id="password_protected_text_below_password" name="password_protected_text_below_password" rows="4" cols="50" class="regular-text">' . get_option('password_protected_text_below_password') . '</textarea></label>'; 536 echo '<label><textarea id="password_protected_text_below_password" name="password_protected_text_below_password" rows="4" cols="50" class="regular-text">' . esc_attr( get_option('password_protected_text_below_password') ) . '</textarea></label>';
537 }
538
539 public function password_protected_use_transient() {
540 $use_transient = get_option( 'password_protected_use_transient', false );
541 $checked = empty( $use_transient ) ? '' : 'checked="checked"';
542 echo '<lable for="password-protected-use-transient"><input ' . esc_attr( $checked ) . ' type="checkbox" name="password_protected_use_transient" value="1" id="password-protected-use-transient" /> ' . esc_attr__( 'This option will save your passwords in transients for your IP instead of cookies. Only use it if you face any cache-related issues on your site.', 'password-protected' ) . '</lable>';
525 } 543 }
526 544
527 /** 545 /**
...@@ -535,15 +553,34 @@ class Password_Protected_Admin { ...@@ -535,15 +553,34 @@ class Password_Protected_Admin {
535 /** 553 /**
536 * Try pro sideabr 554 * Try pro sideabr
537 */ 555 */
538 public function password_protected_try_pro(){ 556 public function password_protected_try_pro() {
539 $image = plugin_dir_url( __DIR__ ) . "assets/images/login-designer-demo.gif"; 557 $pro_url = 'https://passwordwp.com/?utm=wp-dash';
558 if ( ! pp_free_fs()->is_plugin_activation() ) {
559 $pro_url = pp_free_fs()->checkout_url(
560 'annual',
561 false,
562 array(
563 'pricing_id' => 24710,
564 'plugin_id' => 12504
565 )
566 );
567 }
540 echo ' 568 echo '
541 <div id="pp-sidebar-box"> 569 <div id="pp-sidebar-box">
542 <h3> 570 <h3>
543 ' . esc_attr__( 'Looking for more options?', 'password-protected' ) . ' 571 ' . esc_attr__( 'Looking for more options?', 'password-protected' ) . '
544 </h3> 572 </h3>
545 <p class="pro-features"><a href="'.esc_url( "https://passwordwp.com/?utm=wp-dash" ).'">Click here to learn more about pro features</a></p> 573 <ol>
546 <h3><a href="'.esc_url( "https://passwordwp.com/?utm=wp-dash" ).'" class="pp-try button-primary">' . esc_attr__( '👉 Try Pro', 'password-protected' ) . '</a></h3> 574 <li>⚡ Get the option to exclude specific pages and posts.</li>
575 <li>⚡ You can exclude specific post types.</li>
576 <li>🔐 Feature to limit password attempts for a certain interval.</li>
577 <li>⚡ You get the capability of managing multiple passwords with the following options.:
578 </li>
579 <li>📃 Display activity log for each password attempt.</li>
580 <li>🔗 Get Bypass URL - You can access without a password using a unique link.</li>
581 </ol>
582
583 <h3><a href="'.esc_url( $pro_url ).'" class="pp-try pp-pro-try button-primary" target="_blank">' . esc_attr__( '👉 Try Pro', 'password-protected' ) . '</a></h3>
547 584
548 </div>'; 585 </div>';
549 } 586 }
...@@ -739,20 +776,34 @@ class Password_Protected_Admin { ...@@ -739,20 +776,34 @@ class Password_Protected_Admin {
739 <div class="pro_container"> 776 <div class="pro_container">
740 <h2>Pro Features</h2> 777 <h2>Pro Features</h2>
741 <ol> 778 <ol>
742 <li><p>Option to exclude individual pages and posts.</p></li> 779 <li>⚡ Get the option to exclude specific pages and posts.</li>
743 <li><p>Exclude specific post types.</p></li> 780 <li>⚡ You can exclude specific post types.</li>
744 <li><p>Feature to limit password attempts for certain interval.</p></li> 781 <li>🔐 Feature to limit password attempts for a certain interval.</li>
745 <li><p>Ability to manage multiple passwords with the following options:</p> 782 <li>⚡ You get the capability of managing multiple passwords with the following options.:
746 <ol style="list-style-type: lower-alpha;margin-top: 5px;"> 783 <ol>
747 <li>Option to activate and deactivate manually.</li> 784 <li>👉 Option to activate and deactivate manually.</li>
748 <li>Set the expiry date for each password.</li> 785 <li>👉 Set the expiry date for each Password.</li>
749 <li>Set the usage limit for each password.</li> 786 <li>👉 Set the usage limit for each Password.</li>
750 </ol> 787 </ol>
751 </li> 788 </li>
752 <li><p>Display activity log for each password attempt.</p></li> 789 <li>📃 Display activity log for each password attempt.</li>
790 <li>🔗 Get Bypass URL - You can access without a password using a unique link.</li>
753 </ol> 791 </ol>
754 792 <?php
755 <a href="<?php echo esc_url( "https://passwordwp.com/?utm=wp-dash" ); ?>" class="get_pro_btn">Get Pro Now</a> 793 $pro_url = 'https://passwordwp.com/?utm=wp-dash';
794
795 if ( ! pp_free_fs()->is_plugin_activation() ) {
796 $pro_url = pp_free_fs()->checkout_url(
797 'annual',
798 false,
799 array(
800 'pricing_id' => 24710,
801 'plugin_id' => 12504
802 )
803 );
804 }
805 ?>
806 <a target="_blank" href="<?php echo esc_url( $pro_url ); ?>" class="get_pro_btn">Get Pro Now</a>
756 </div> 807 </div>
757 </div> 808 </div>
758 </div> 809 </div>
......
...@@ -53,16 +53,20 @@ div#pp-sidebar-box { ...@@ -53,16 +53,20 @@ div#pp-sidebar-box {
53 a.get_pro_btn { 53 a.get_pro_btn {
54 margin-top: 20px; 54 margin-top: 20px;
55 display: block; 55 display: block;
56 background: #2271b1; 56 background: #ff8900;
57 padding: 10px 20px; 57 padding: 10px 20px;
58 color: #FFF; 58 color: #FFF;
59 text-decoration: none; 59 text-decoration: none;
60 border-radius: 30px;
61 font-weight: bold; 60 font-weight: bold;
62 font-size: 16px; 61 font-size: 16px;
63 width: 105px; 62 width: 105px;
64 text-align: center; 63 text-align: center;
65 } 64 }
65 .pp-pro-try {
66 background-color: #ff8900 !important;
67 border-color: #ff8900 !important;
68 outline-color: #ff8900 !important;
69 }
66 .pro_container p { 70 .pro_container p {
67 margin: 0; 71 margin: 0;
68 font-size: 14px; 72 font-size: 14px;
......
1 label.fs-tag,span.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-notice[data-id=license_not_whitelabeled].success,.fs-notice[data-id=license_whitelabeled].success{color:inherit;border-left-color:#00a0d2}.fs-notice[data-id=license_not_whitelabeled].success label.fs-plugin-title,.fs-notice[data-id=license_whitelabeled].success label.fs-plugin-title{display:none}#fs_account .postbox,#fs_account .widefat{max-width:800px}#fs_account h3{font-size:1.3em;padding:12px 15px;margin:0 0 12px 0;line-height:1.4;border-bottom:1px solid #f1f1f1}#fs_account h3 .dashicons{width:26px;height:26px;font-size:1.3em}#fs_account i.dashicons{font-size:1.2em;height:1.2em;width:1.2em}#fs_account .dashicons{vertical-align:middle}#fs_account .fs-header-actions{position:absolute;top:17px;right:15px;font-size:.9em}#fs_account .fs-header-actions ul{margin:0}#fs_account .fs-header-actions li{float:left}#fs_account .fs-header-actions li form{display:inline-block}#fs_account .fs-header-actions li a{text-decoration:none}#fs_account_details .button-group{float:right}.rtl #fs_account .fs-header-actions{left:15px;right:auto}.fs-key-value-table{width:100%}.fs-key-value-table form{display:inline-block}.fs-key-value-table tr td:first-child{text-align:right}.fs-key-value-table tr td:first-child nobr{font-weight:bold}.fs-key-value-table tr td:first-child form{display:block}.fs-key-value-table tr td.fs-right{text-align:right}.fs-key-value-table tr.fs-odd{background:#ebebeb}.fs-key-value-table td,.fs-key-value-table th{padding:10px}.fs-key-value-table code{line-height:28px}.fs-key-value-table var,.fs-key-value-table code,.fs-key-value-table input[type=text]{color:#0073aa;font-size:16px;background:none}.fs-key-value-table input[type=text]{width:100%;font-weight:bold}.fs-field-beta_program label{margin-left:7px}label.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error{background:#dc3232}#fs_sites .fs-scrollable-table .fs-table-body{max-height:200px;overflow:auto;border:1px solid #e5e5e5}#fs_sites .fs-scrollable-table .fs-table-body>table.widefat{border:none !important}#fs_sites .fs-scrollable-table .fs-main-column{width:100%}#fs_sites .fs-scrollable-table .fs-site-details td:first-of-type{text-align:right;color:gray;width:1px}#fs_sites .fs-scrollable-table .fs-site-details td:last-of-type{text-align:right}#fs_sites .fs-scrollable-table .fs-install-details table tr td{width:1px;white-space:nowrap}#fs_sites .fs-scrollable-table .fs-install-details table tr td:last-of-type{width:auto}#fs_addons h3{border:none;margin-bottom:0;padding:4px 5px}#fs_addons td{vertical-align:middle}#fs_addons thead{white-space:nowrap}#fs_addons td:first-child,#fs_addons th:first-child{text-align:left;font-weight:bold}#fs_addons td:last-child,#fs_addons th:last-child{text-align:right}#fs_addons th{font-weight:bold}#fs_billing_address{width:100%}#fs_billing_address tr td{width:50%;padding:5px}#fs_billing_address tr:first-of-type td{padding-top:0}#fs_billing_address span{font-weight:bold}#fs_billing_address input,#fs_billing_address select{display:block;width:100%;margin-top:5px}#fs_billing_address input::-moz-placeholder,#fs_billing_address select::-moz-placeholder{color:transparent;opacity:1}#fs_billing_address input:-ms-input-placeholder,#fs_billing_address select:-ms-input-placeholder{color:transparent}#fs_billing_address input::-webkit-input-placeholder,#fs_billing_address select::-webkit-input-placeholder{color:transparent}#fs_billing_address input.fs-read-mode,#fs_billing_address select.fs-read-mode{border-color:transparent;color:#777;border-bottom:1px dashed #ccc;padding-left:0;background:none}#fs_billing_address.fs-read-mode td span{display:none}#fs_billing_address.fs-read-mode input,#fs_billing_address.fs-read-mode select{border-color:transparent;color:#777;border-bottom:1px dashed #ccc;padding-left:0;background:none}#fs_billing_address.fs-read-mode input::-moz-placeholder,#fs_billing_address.fs-read-mode select::-moz-placeholder{color:#ccc;opacity:1}#fs_billing_address.fs-read-mode input:-ms-input-placeholder,#fs_billing_address.fs-read-mode select:-ms-input-placeholder{color:#ccc}#fs_billing_address.fs-read-mode input::-webkit-input-placeholder,#fs_billing_address.fs-read-mode select::-webkit-input-placeholder{color:#ccc}#fs_billing_address button{display:block;width:100%}@media screen and (max-width: 639px){#fs_account .fs-header-actions{position:static;padding:0 15px 12px 15px;margin:0 0 12px 0}#fs_account .fs-header-actions li{float:none;display:inline-block}#fs_account #fs_account_details{display:block}#fs_account #fs_account_details tbody,#fs_account #fs_account_details tr,#fs_account #fs_account_details td,#fs_account #fs_account_details th{display:block}#fs_account #fs_account_details tr td:first-child{text-align:left}#fs_account #fs_account_details tr td:nth-child(2){padding:0 12px}#fs_account #fs_account_details tr td:nth-child(2) code{margin:0;padding:0}#fs_account #fs_account_details tr td:nth-child(2) label{margin-left:0}#fs_account #fs_account_details tr td:nth-child(3){text-align:left}#fs_account #fs_account_details tr.fs-field-plan td:nth-child(2) .button-group{float:none;margin:12px 0}}
1 #fs_affiliation_content_wrapper #messages{margin-top:25px}#fs_affiliation_content_wrapper h3{font-size:24px;padding:0;margin-left:0}#fs_affiliation_content_wrapper ul li{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;list-style-type:none}#fs_affiliation_content_wrapper ul li:before{content:"✓";margin-right:10px;font-weight:bold}#fs_affiliation_content_wrapper p:not(.description),#fs_affiliation_content_wrapper li,#fs_affiliation_content_wrapper label{font-size:16px !important;line-height:26px !important}#fs_affiliation_content_wrapper .button{margin-top:20px;margin-bottom:7px;line-height:35px;height:40px;font-size:16px}#fs_affiliation_content_wrapper .button#cancel_button{margin-right:5px}#fs_affiliation_content_wrapper form .input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form .input-container .input-label{font-weight:bold;display:block;width:100%}#fs_affiliation_content_wrapper form .input-container.input-container-text label,#fs_affiliation_content_wrapper form .input-container.input-container-text input,#fs_affiliation_content_wrapper form .input-container.input-container-text textarea{display:block}#fs_affiliation_content_wrapper form .input-container #add_domain,#fs_affiliation_content_wrapper form .input-container .remove-domain{text-decoration:none;display:inline-block;margin-top:3px}#fs_affiliation_content_wrapper form .input-container #add_domain:focus,#fs_affiliation_content_wrapper form .input-container .remove-domain:focus{box-shadow:none}#fs_affiliation_content_wrapper form .input-container #add_domain.disabled,#fs_affiliation_content_wrapper form .input-container .remove-domain.disabled{color:#aaa;cursor:default}#fs_affiliation_content_wrapper form #extra_domains_container .description{margin-top:0;position:relative;top:-4px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain{display:inline-block;margin-right:5px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain:last-of-type{margin-bottom:0}
1 @media screen and (max-width: 782px){#wpbody-content{padding-bottom:0 !important}}
1 .fs-notice[data-id^=clone_resolution_options_notice]{padding:0;color:inherit !important}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-body{padding:0;margin-bottom:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-header{padding:5px 10px}.fs-notice[data-id^=clone_resolution_options_notice] ol{margin-top:0;margin-bottom:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{display:flex;flex-direction:row;padding:0 10px 10px}@media(max-width: 750px){.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{flex-direction:column}}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option{border:1px solid #ccc;padding:10px 10px 15px 10px;flex:auto;margin:5px}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:first-child{margin-left:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:last-child{margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option strong{font-size:1.2em;padding:2px;line-height:1.5em}.fs-notice[data-id^=clone_resolution_options_notice] a{text-decoration:none}.fs-notice[data-id^=clone_resolution_options_notice] .button{margin-right:10px}.rtl .fs-notice[data-id^=clone_resolution_options_notice] .button{margin-right:0;margin-left:10px}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-documentation-container{padding:0 10px 15px}.fs-notice[data-id=temporary_duplicate_notice] #fs_clone_resolution_error_message{border:1px solid #d3135a;background:#fee;color:#d3135a;padding:10px}.fs-notice[data-id=temporary_duplicate_notice] ol{margin-top:0}
1 .fs-badge{position:absolute;top:10px;right:0;background:#71ae00;color:#fff;text-transform:uppercase;padding:5px 10px;-moz-border-radius:3px 0 0 3px;-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;font-weight:bold;border-right:0;-moz-box-shadow:0 2px 1px -1px rgba(0,0,0,.3);-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,.3);box-shadow:0 2px 1px -1px rgba(0,0,0,.3)}.theme-browser .theme .fs-premium-theme-badge-container{position:absolute;right:0;top:0}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge{position:relative;top:0;margin-top:10px;text-align:center}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-premium-theme-badge{font-size:1.1em}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-beta-theme-badge{background:#00a0d2}.fs-switch{position:relative;display:inline-block;color:#ccc;text-shadow:0 1px 1px rgba(255,255,255,.8);height:18px;padding:6px 6px 5px 6px;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);background:#ececec;box-shadow:0 0 4px rgba(0,0,0,.1),inset 0 1px 3px 0 rgba(0,0,0,.1);cursor:pointer}.fs-switch span{display:inline-block;width:35px;text-transform:uppercase}.fs-switch .fs-toggle{position:absolute;top:1px;width:37px;height:25px;border:1px solid #ccc;border:1px solid rgba(0,0,0,.3);border-radius:4px;background:#fff;background-color:#fff;background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #ececec), color-stop(1, #fff));background-image:-webkit-linear-gradient(top, #ececec, #fff);background-image:-moz-linear-gradient(top, #ececec, #fff);background-image:-ms-linear-gradient(top, #ececec, #fff);background-image:-o-linear-gradient(top, #ececec, #fff);background-image:linear-gradient(top, bottom, #ececec, #fff);box-shadow:inset 0 1px 0 0 rgba(255,255,255,.5);z-index:999;-moz-transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1);-o-transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1);-ms-transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1);-webkit-transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1);transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1)}.fs-switch.fs-off .fs-toggle{left:2%}.fs-switch.fs-on .fs-toggle{left:54%}.fs-switch.fs-round{top:8px;padding:4px 25px;-moz-border-radius:24px;-webkit-border-radius:24px;border-radius:24px}.fs-switch.fs-round .fs-toggle{top:0;width:24px;height:24px;-moz-border-radius:24px;-webkit-border-radius:24px;border-radius:24px}.fs-switch.fs-round.fs-off .fs-toggle{left:-1px}.fs-switch.fs-round.fs-on{background:#0085ba}.fs-switch.fs-round.fs-on .fs-toggle{left:25px}.fs-switch.fs-small.fs-round{padding:1px 19px}.fs-switch.fs-small.fs-round .fs-toggle{top:0;width:18px;height:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px}.fs-switch.fs-small.fs-round.fs-on .fs-toggle{left:19px}body.fs-loading,body.fs-loading *{cursor:wait !important}#fs_frame{line-height:0;font-size:0}.fs-full-size-wrapper{margin:40px 0 -65px -20px}@media(max-width: 600px){.fs-full-size-wrapper{margin:0 0 -65px -10px}}.fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px !important}.fs-notice.success{color:green}.fs-notice.promotion{border-color:#00a0d2 !important;background-color:#f2fcff !important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-close{cursor:pointer;color:#aaa;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{margin-top:7px;display:inline-block}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,.3);color:#fff;padding:2px 10px;position:absolute;top:100%;bottom:auto;right:auto;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;left:10px;font-size:12px;font-weight:bold;cursor:auto}div.fs-notice.updated,div.fs-notice.success,div.fs-notice.promotion{display:block !important}#fs_connect .fs-error ol,#fs_connect .fs-error .fs-api-request-error-show-details-link,#fs_connect .fs-error .fs-api-request-error-details,.fs-modal .notice-error ol,.fs-modal .notice-error .fs-api-request-error-show-details-link,.fs-modal .notice-error .fs-api-request-error-details,.fs-notice.error ol,.fs-notice.error .fs-api-request-error-show-details-link,.fs-notice.error .fs-api-request-error-details{text-align:left}#fs_connect .fs-error ol,.fs-modal .notice-error ol,.fs-notice.error ol{list-style-type:disc}#fs_connect .fs-error .fs-api-request-error-show-details-link,.fs-modal .notice-error .fs-api-request-error-show-details-link,.fs-notice.error .fs-api-request-error-show-details-link{text-decoration:none;color:#2271b1;box-shadow:none}#fs_connect .fs-error .fs-api-request-error-details,.fs-modal .notice-error .fs-api-request-error-details,.fs-notice.error .fs-api-request-error-details{border:1px solid #ccc;padding:5px;overflow:auto;max-height:150px}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{position:fixed;top:32px;left:160px;right:0;background:#ebfdeb;padding:10px 20px;color:green;z-index:9999;-moz-box-shadow:0 2px 2px rgba(6,113,6,.3);-webkit-box-shadow:0 2px 2px rgba(6,113,6,.3);box-shadow:0 2px 2px rgba(6,113,6,.3);opacity:.95;filter:alpha(opacity=95)}.fs-secure-notice:hover{opacity:1;filter:alpha(opacity=100)}.fs-secure-notice a.fs-security-proof{color:green;text-decoration:none}@media screen and (max-width: 960px){.fs-secure-notice{left:36px}}@media screen and (max-width: 600px){.fs-secure-notice{display:none}}@media screen and (max-width: 1250px){#fs_promo_tab{display:none}}@media screen and (max-width: 782px){.fs-secure-notice{left:0;top:46px;text-align:center}}span.fs-submenu-item.fs-sub:before{content:"↳";padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:"↲"}.fs-submenu-item.pricing.upgrade-mode{color:#adff2f}.fs-submenu-item.pricing.trial-mode{color:#83e2ff}#adminmenu .update-plugins.fs-trial{background-color:#00b9eb}.fs-ajax-spinner{border:0;width:20px;height:20px;margin-right:5px;vertical-align:sub;display:inline-block;background:url("/wp-admin/images/wpspin_light-2x.gif");background-size:contain;margin-bottom:-2px}.wrap.fs-section h2{text-align:left}.plugins p.fs-upgrade-notice{border:0;background-color:#d54e21;padding:10px;color:#f9f9f9;margin-top:10px}
1 label.fs-tag,span.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-switch-label{font-size:20px;line-height:31px;margin:0 5px}#fs_log_book table{font-family:Consolas,Monaco,monospace;font-size:12px}#fs_log_book table th{color:#ccc}#fs_log_book table tr{background:#232525}#fs_log_book table tr.alternate{background:#2b2b2b}#fs_log_book table tr td.fs-col--logger{color:#5a7435}#fs_log_book table tr td.fs-col--type{color:#ffc861}#fs_log_book table tr td.fs-col--function{color:#a7b7b1;font-weight:bold}#fs_log_book table tr td.fs-col--message,#fs_log_book table tr td.fs-col--message a{color:#9a73ac !important}#fs_log_book table tr td.fs-col--file{color:#d07922}#fs_log_book table tr td.fs-col--timestamp{color:#6596be}
1 .fs-notice[data-id^=gdpr_optin_actions] .underlined{text-decoration:underline}.fs-notice[data-id^=gdpr_optin_actions] ul .button,.fs-notice[data-id^=gdpr_optin_actions] ul .action-description{vertical-align:middle}.fs-notice[data-id^=gdpr_optin_actions] ul .action-description{display:inline-block;margin-left:3px}
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
1 .fs-tooltip-trigger{position:relative}.fs-tooltip-trigger:not(a){cursor:help}.fs-tooltip-trigger .dashicons{float:none !important}.fs-tooltip-trigger .fs-tooltip{opacity:0;visibility:hidden;-moz-transition:opacity .3s ease-in-out;-o-transition:opacity .3s ease-in-out;-ms-transition:opacity .3s ease-in-out;-webkit-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;position:absolute;background:rgba(0,0,0,.8);color:#fff !important;font-family:"arial",serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:-17px;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2);line-height:1.3em;font-weight:bold;text-align:left;text-transform:none !important}.rtl .fs-tooltip-trigger .fs-tooltip{text-align:right;left:auto;right:-17px}.fs-tooltip-trigger .fs-tooltip::after{content:" ";display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:rgba(0,0,0,.8) transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl .fs-tooltip-trigger .fs-tooltip::after{right:21px;left:auto}.fs-tooltip-trigger:hover .fs-tooltip{visibility:visible;opacity:1}.fs-permissions .fs-permission.fs-disabled{color:#aaa}.fs-permissions .fs-permission.fs-disabled .fs-permission-description span{color:#aaa}.fs-permissions .fs-permission .fs-switch-feedback{position:absolute;right:15px;top:52px}.fs-permissions ul{height:0;overflow:hidden;margin:0}.fs-permissions ul li{padding:17px 15px;margin:0;position:relative}.fs-permissions ul li>i.dashicons{float:left;font-size:30px;width:30px;height:30px;padding:5px}.fs-permissions ul li .fs-switch{float:right}.fs-permissions ul li .fs-permission-description{margin-left:55px}.fs-permissions ul li .fs-permission-description span{font-size:14px;font-weight:500;color:#23282d}.fs-permissions ul li .fs-permission-description .fs-tooltip{font-size:13px;font-weight:bold}.fs-permissions ul li .fs-permission-description .fs-tooltip-trigger .dashicons{margin:-1px 2px 0 2px}.fs-permissions ul li .fs-permission-description p{margin:2px 0 0 0}.fs-permissions.fs-open{background:#fff}.fs-permissions.fs-open ul{overflow:initial;height:auto;margin:20px 0 10px 0}.fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-right:10px}.fs-permissions .fs-switch-feedback.success{color:#71ae00}.rtl .fs-permissions .fs-switch-feedback{right:auto;left:15px}.rtl .fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-left:10px;margin-right:0}.rtl .fs-permissions ul li .fs-permission-description{margin-right:55px;margin-left:0}.rtl .fs-permissions ul li .fs-switch{float:left}.rtl .fs-permissions ul li i.dashicons{float:right}.fs-modal-opt-out .fs-modal-footer .fs-opt-out-button{line-height:30px;margin-right:10px}.fs-modal-opt-out .fs-permissions{margin-top:0 !important}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-group-opt-out-button{float:right;line-height:1.1em}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-switch-feedback{float:right;line-height:1.1em;margin-right:10px}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-switch-feedback .fs-ajax-spinner{margin:-2px 0 0}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header-title{font-size:1.1em;font-weight:600;text-transform:uppercase;display:block;line-height:1.1em;margin:.5em 0}.fs-modal-opt-out .fs-permissions .fs-permissions-section--desc{margin-top:0}.fs-modal-opt-out .fs-permissions hr{border:0;border-top:#eee solid 1px;margin:25px 0 20px 0}.fs-modal-opt-out .fs-permissions ul{border:1px solid #c3c4c7;border-radius:3px;margin:10px 0 0 0;box-shadow:0 1px 1px rgba(0,0,0,.04)}.fs-modal-opt-out .fs-permissions ul li{border-bottom:1px solid #d7dde1;border-left:4px solid #72aee6}.rtl .fs-modal-opt-out .fs-permissions ul li{border-left:none;border-right:4px solid #72aee6}.fs-modal-opt-out .fs-permissions ul li.fs-disabled{border-left-color:rgba(114,174,230,0)}.fs-modal-opt-out .fs-permissions ul li:last-child{border-bottom:none}
1 label.fs-tag,span.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.wp-list-table.plugins .plugin-title span.fs-tag{display:inline-block;margin-left:5px;line-height:10px}
1 #fs_customizer_upsell .fs-customizer-plan{padding:10px 20px 20px 20px;border-radius:3px;background:#fff}#fs_customizer_upsell .fs-customizer-plan h2{position:relative;margin:0;line-height:2em;text-transform:uppercase}#fs_customizer_upsell .fs-customizer-plan h2 .button-link{top:-2px}#fs_customizer_upsell .fs-feature{position:relative}#fs_customizer_upsell .dashicons-yes{color:#0085ba;font-size:2em;vertical-align:bottom;margin-left:-7px;margin-right:10px}.rtl #fs_customizer_upsell .dashicons-yes{margin-left:10px;margin-right:-7px}#fs_customizer_upsell .dashicons-editor-help{color:#bbb;cursor:help}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{opacity:0;visibility:hidden;-moz-transition:opacity .3s ease-in-out;-o-transition:opacity .3s ease-in-out;-ms-transition:opacity .3s ease-in-out;-webkit-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;position:absolute;background:#000;color:#fff;font-family:"arial",serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:0;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2);line-height:1.3em;font-weight:bold;text-align:left}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{text-align:right}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc::after{content:" ";display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:#000 transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc::after{right:21px;left:auto}#fs_customizer_upsell .dashicons-editor-help:hover .fs-feature-desc{visibility:visible;opacity:1}#fs_customizer_upsell .button-primary{display:block;text-align:center;margin-top:10px}#fs_customizer_support{display:block !important}#fs_customizer_support .button{float:right}#fs_customizer_support .button-group{width:100%;display:block;margin-top:10px}#fs_customizer_support .button-group .button{float:none;width:50%;text-align:center}#customize-theme-controls #accordion-section-freemius_upsell{border-top:1px solid #0085ba !important;border-bottom:1px solid #0085ba !important}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title{color:#fff;background-color:#0085ba;border-left:4px solid #0085ba;transition:.15s background-color ease-in-out,.15s border-color ease-in-out;outline:none;border-bottom:none !important}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title:hover{background-color:#008ec2;border-left-color:#0073aa}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title:after{color:#fff}#customize-theme-controls #accordion-section-freemius_upsell .rtl h3.accordion-section-title{border-left:none;border-right:4px solid #0085ba}#customize-theme-controls #accordion-section-freemius_upsell .rtl h3.accordion-section-title:hover{border-right-color:#0073aa}
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
1 /*!
2 * jQuery postMessage - v0.5 - 9/11/2009
3 * http://benalman.com/projects/jquery-postmessage-plugin/
4 *
5 * Copyright (c) 2009 "Cowboy" Ben Alman
6 * Dual licensed under the MIT and GPL licenses.
7 * http://benalman.com/about/license/
8 *
9 * Non-jQuery fork by Jeff Lee
10 *
11 * This fork consists of the following changes:
12 * 1. Basic code cleanup and restructuring, for legibility.
13 * 2. The `postMessage` and `receiveMessage` functions can be bound arbitrarily,
14 * in terms of both function names and object scope. Scope is specified by
15 * the the "this" context of NoJQueryPostMessageMixin();
16 * 3. I've removed the check for Opera 9.64, which used `$.browser`. There were
17 * at least three different GitHub users requesting the removal of this
18 * "Opera sniff" on the original project's Issues page, so I figured this
19 * would be a relatively safe change.
20 * 4. `postMessage` no longer uses `$.param` to serialize messages that are not
21 * strings. I actually prefer this structure anyway. `receiveMessage` does
22 * not implement a corresponding deserialization step, and as such it seems
23 * cleaner and more symmetric to leave both data serialization and
24 * deserialization to the client.
25 * 5. The use of `$.isFunction` is replaced by a functionally-identical check.
26 * 6. The `$:nomunge` YUI option is no longer necessary.
27 */
28
29 function NoJQueryPostMessageMixin(postBinding, receiveBinding) {
30
31 var setMessageCallback, unsetMessageCallback, currentMsgCallback,
32 intervalId, lastHash, cacheBust = 1;
33
34 if (window.postMessage) {
35
36 if (window.addEventListener) {
37 setMessageCallback = function(callback) {
38 window.addEventListener('message', callback, false);
39 }
40
41 unsetMessageCallback = function(callback) {
42 window.removeEventListener('message', callback, false);
43 }
44 } else {
45 setMessageCallback = function(callback) {
46 window.attachEvent('onmessage', callback);
47 }
48
49 unsetMessageCallback = function(callback) {
50 window.detachEvent('onmessage', callback);
51 }
52 }
53
54 this[postBinding] = function(message, targetUrl, target) {
55 if (!targetUrl) {
56 return;
57 }
58
59 // The browser supports window.postMessage, so call it with a targetOrigin
60 // set appropriately, based on the targetUrl parameter.
61 target.postMessage( message, targetUrl.replace( /([^:]+:\/\/[^\/]+).*/, '$1' ) );
62 }
63
64 // Since the browser supports window.postMessage, the callback will be
65 // bound to the actual event associated with window.postMessage.
66 this[receiveBinding] = function(callback, sourceOrigin, delay) {
67 // Unbind an existing callback if it exists.
68 if (currentMsgCallback) {
69 unsetMessageCallback(currentMsgCallback);
70 currentMsgCallback = null;
71 }
72
73 if (!callback) {
74 return false;
75 }
76
77 // Bind the callback. A reference to the callback is stored for ease of
78 // unbinding.
79 currentMsgCallback = setMessageCallback(function(e) {
80 switch(Object.prototype.toString.call(sourceOrigin)) {
81 case '[object String]':
82 if (sourceOrigin !== e.origin) {
83 return false;
84 }
85 break;
86 case '[object Function]':
87 if (sourceOrigin(e.origin)) {
88 return false;
89 }
90 break;
91 }
92
93 callback(e);
94 });
95 };
96
97 } else {
98
99 this[postBinding] = function(message, targetUrl, target) {
100 if (!targetUrl) {
101 return;
102 }
103
104 // The browser does not support window.postMessage, so set the location
105 // of the target to targetUrl#message. A bit ugly, but it works! A cache
106 // bust parameter is added to ensure that repeat messages trigger the
107 // callback.
108 target.location = targetUrl.replace( /#.*$/, '' ) + '#' + (+new Date) + (cacheBust++) + '&' + message;
109 }
110
111 // Since the browser sucks, a polling loop will be started, and the
112 // callback will be called whenever the location.hash changes.
113 this[receiveBinding] = function(callback, sourceOrigin, delay) {
114 if (intervalId) {
115 clearInterval(intervalId);
116 intervalId = null;
117 }
118
119 if (callback) {
120 delay = typeof sourceOrigin === 'number'
121 ? sourceOrigin
122 : typeof delay === 'number'
123 ? delay
124 : 100;
125
126 intervalId = setInterval(function(){
127 var hash = document.location.hash,
128 re = /^#?\d+&/;
129 if ( hash !== lastHash && re.test( hash ) ) {
130 lastHash = hash;
131 callback({ data: hash.replace( re, '' ) });
132 }
133 }, delay );
134 }
135 };
136
137 }
138
139 return this;
140 }
...\ No newline at end of file ...\ No newline at end of file
1 /*
2 * nojquery-postmessage by Jeff Lee
3 * a non-jQuery fork of:
4 *
5 * jQuery postMessage - v0.5 - 9/11/2009
6 * http://benalman.com/projects/jquery-postmessage-plugin/
7 *
8 * Copyright (c) 2009 "Cowboy" Ben Alman
9 * Dual licensed under the MIT and GPL licenses.
10 * http://benalman.com/about/license/
11 */
12 function NoJQueryPostMessageMixin(g,a){var b,h,e,d,f,c=1;if(window.postMessage){if(window.addEventListener){b=function(i){window.addEventListener("message",i,false)};h=function(i){window.removeEventListener("message",i,false)}}else{b=function(i){window.attachEvent("onmessage",i)};h=function(i){window.detachEvent("onmessage",i)}}this[g]=function(i,k,j){if(!k){return}j.postMessage(i,k.replace(/([^:]+:\/\/[^\/]+).*/,"$1"))};this[a]=function(k,j,i){if(e){h(e);e=null}if(!k){return false}e=b(function(l){switch(Object.prototype.toString.call(j)){case"[object String]":if(j!==l.origin){return false}break;case"[object Function]":if(j(l.origin)){return false}break}k(l)})}}else{this[g]=function(i,k,j){if(!k){return}j.location=k.replace(/#.*$/,"")+"#"+(+new Date)+(c++)+"&"+i};this[a]=function(k,j,i){if(d){clearInterval(d);d=null}if(k){i=typeof j==="number"?j:typeof i==="number"?i:100;d=setInterval(function(){var m=document.location.hash,l=/^#?\d+&/;if(m!==f&&l.test(m)){f=m;k({data:m.replace(l,"")})}},i)}}}return this};
...\ No newline at end of file ...\ No newline at end of file
1 (function ($, undef) {
2 var global = this;
3
4 // Namespace.
5 global.FS = global.FS || {};
6
7 global.FS.PostMessage = function ()
8 {
9 var
10 _is_child = false,
11 _postman = new NoJQueryPostMessageMixin('postMessage', 'receiveMessage'),
12 _callbacks = {},
13 _base_url,
14 _parent_url = decodeURIComponent(document.location.hash.replace(/^#/, '')),
15 _parent_subdomain = _parent_url.substring(0, _parent_url.indexOf('/', ('https://' === _parent_url.substring(0, ('https://').length)) ? 8 : 7)),
16 _init = function () {
17 _postman.receiveMessage(function (e) {
18 var data = JSON.parse(e.data);
19
20 if (_callbacks[data.type]) {
21 for (var i = 0; i < _callbacks[data.type].length; i++) {
22 // Execute type callbacks.
23 _callbacks[data.type][i](data.data);
24 }
25 }
26 }, _base_url);
27 },
28 _hasParent = ('' !== _parent_url),
29 $window = $(window),
30 $html = $('html');
31
32 return {
33 init : function (url, iframes)
34 {
35 _base_url = url;
36 _init();
37
38 // Automatically receive forward messages.
39 FS.PostMessage.receiveOnce('forward', function (data){
40 window.location = data.url;
41 });
42
43 iframes = iframes || [];
44
45 if (iframes.length > 0) {
46 $window.on('scroll', function () {
47 for (var i = 0; i < iframes.length; i++) {
48 FS.PostMessage.postScroll(iframes[i]);
49 }
50 });
51 }
52 },
53 init_child : function ()
54 {
55 this.init(_parent_subdomain);
56
57 _is_child = true;
58
59 // Post height of a child right after window is loaded.
60 $(window).bind('load', function () {
61 FS.PostMessage.postHeight();
62
63 // Post message that window was loaded.
64 FS.PostMessage.post('loaded');
65 });
66 },
67 hasParent : function ()
68 {
69 return _hasParent;
70 },
71 postHeight : function (diff, wrapper) {
72 diff = diff || 0;
73 wrapper = wrapper || '#wrap_section';
74 this.post('height', {
75 height: diff + $(wrapper).outerHeight(true)
76 });
77 },
78 postScroll : function (iframe) {
79 this.post('scroll', {
80 top: $window.scrollTop(),
81 height: ($window.height() - parseFloat($html.css('paddingTop')) - parseFloat($html.css('marginTop')))
82 }, iframe);
83 },
84 post : function (type, data, iframe)
85 {
86 console.debug('PostMessage.post', type);
87
88 if (iframe)
89 {
90 // Post to iframe.
91 _postman.postMessage(JSON.stringify({
92 type: type,
93 data: data
94 }), iframe.src, iframe.contentWindow);
95 }
96 else {
97 // Post to parent.
98 _postman.postMessage(JSON.stringify({
99 type: type,
100 data: data
101 }), _parent_url, window.parent);
102 }
103 },
104 receive: function (type, callback)
105 {
106 console.debug('PostMessage.receive', type);
107
108 if (undef === _callbacks[type])
109 _callbacks[type] = [];
110
111 _callbacks[type].push(callback);
112 },
113 receiveOnce: function (type, callback)
114 {
115 if (this.is_set(type))
116 return;
117
118 this.receive(type, callback);
119 },
120 // Check if any callbacks assigned to a specified message type.
121 is_set: function (type)
122 {
123 return (undef != _callbacks[type]);
124 },
125 parent_url: function ()
126 {
127 return _parent_url;
128 },
129 parent_subdomain: function ()
130 {
131 return _parent_subdomain;
132 }
133 };
134 }();
135 })(jQuery);
...\ No newline at end of file ...\ No newline at end of file
This diff could not be displayed because it is too large.
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 2.5.1
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Class FS_Lock
15 *
16 * @author Vova Feldman (@svovaf)
17 * @since 2.5.1
18 */
19 class FS_Lock {
20 /**
21 * @var int Random ID representing the current PHP thread.
22 */
23 private static $_thread_id;
24 /**
25 * @var string
26 */
27 private $_lock_id;
28
29 /**
30 * @param string $lock_id
31 */
32 function __construct( $lock_id ) {
33 if ( ! fs_starts_with( $lock_id, WP_FS___OPTION_PREFIX ) ) {
34 $lock_id = WP_FS___OPTION_PREFIX . $lock_id;
35 }
36
37 $this->_lock_id = $lock_id;
38
39 if ( ! isset( self::$_thread_id ) ) {
40 self::$_thread_id = mt_rand( 0, 32000 );
41 }
42 }
43
44 /**
45 * Try to acquire lock. If the lock is already set or is being acquired by another locker, don't do anything.
46 *
47 * @param int $expiration
48 *
49 * @return bool TRUE if successfully acquired lock.
50 */
51 function try_lock( $expiration = 0 ) {
52 if ( $this->is_locked() ) {
53 // Already locked.
54 return false;
55 }
56
57 set_site_transient( $this->_lock_id, self::$_thread_id, $expiration );
58
59 if ( $this->has_lock() ) {
60 $this->lock($expiration);
61
62 return true;
63 }
64
65 return false;
66 }
67
68 /**
69 * Acquire lock regardless if it's already acquired by another locker or not.
70 *
71 * @author Vova Feldman (@svovaf)
72 * @since 2.1.0
73 *
74 * @param int $expiration
75 */
76 function lock( $expiration = 0 ) {
77 set_site_transient( $this->_lock_id, true, $expiration );
78 }
79
80 /**
81 * Checks if lock is currently acquired.
82 *
83 * @author Vova Feldman (@svovaf)
84 * @since 2.1.0
85 *
86 * @return bool
87 */
88 function is_locked() {
89 return ( false !== get_site_transient( $this->_lock_id ) );
90 }
91
92 /**
93 * Unlock the lock.
94 *
95 * @author Vova Feldman (@svovaf)
96 * @since 2.1.0
97 */
98 function unlock() {
99 delete_site_transient( $this->_lock_id );
100 }
101
102 /**
103 * Checks if lock is currently acquired by the current locker.
104 *
105 * @return bool
106 */
107 protected function has_lock() {
108 return ( self::$_thread_id == get_site_transient( $this->_lock_id ) );
109 }
110 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.3
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 define( 'WP_FS__SECURITY_PARAMS_PREFIX', 's_' );
14
15 /**
16 * Class FS_Security
17 */
18 class FS_Security {
19 /**
20 * @var FS_Security
21 * @since 1.0.3
22 */
23 private static $_instance;
24 /**
25 * @var FS_Logger
26 * @since 1.0.3
27 */
28 private static $_logger;
29
30 /**
31 * @return \FS_Security
32 */
33 public static function instance() {
34 if ( ! isset( self::$_instance ) ) {
35 self::$_instance = new FS_Security();
36 self::$_logger = FS_Logger::get_logger(
37 WP_FS__SLUG,
38 WP_FS__DEBUG_SDK,
39 WP_FS__ECHO_DEBUG_SDK
40 );
41 }
42
43 return self::$_instance;
44 }
45
46 private function __construct() {
47 }
48
49 /**
50 * @param \FS_Scope_Entity $entity
51 * @param int $timestamp
52 * @param string $action
53 *
54 * @return string
55 */
56 function get_secure_token( FS_Scope_Entity $entity, $timestamp, $action = '' ) {
57 return md5(
58 $timestamp .
59 $entity->id .
60 $entity->secret_key .
61 $entity->public_key .
62 $action
63 );
64 }
65
66 /**
67 * @param \FS_Scope_Entity $entity
68 * @param int|bool $timestamp
69 * @param string $action
70 *
71 * @return array
72 */
73 function get_context_params( FS_Scope_Entity $entity, $timestamp = false, $action = '' ) {
74 if ( false === $timestamp ) {
75 $timestamp = time();
76 }
77
78 return array(
79 's_ctx_type' => $entity->get_type(),
80 's_ctx_id' => $entity->id,
81 's_ctx_ts' => $timestamp,
82 's_ctx_secure' => $this->get_secure_token( $entity, $timestamp, $action ),
83 );
84 }
85 }
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 2.1.0
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 require_once WP_FS__DIR_INCLUDES . '/class-fs-lock.php';
14
15 /**
16 * Class FS_User_Lock
17 */
18 class FS_User_Lock {
19 /**
20 * @var FS_Lock
21 */
22 private $_lock;
23
24 #--------------------------------------------------------------------------------
25 #region Singleton
26 #--------------------------------------------------------------------------------
27
28 /**
29 * @var FS_User_Lock
30 */
31 private static $_instance;
32
33 /**
34 * @author Vova Feldman (@svovaf)
35 * @since 2.1.0
36 *
37 * @return FS_User_Lock
38 */
39 static function instance() {
40 if ( ! isset( self::$_instance ) ) {
41 self::$_instance = new self();
42 }
43
44 return self::$_instance;
45 }
46
47 #endregion
48
49 private function __construct() {
50 $current_user_id = Freemius::get_current_wp_user_id();
51
52 $this->_lock = new FS_Lock( "locked_{$current_user_id}" );
53 }
54
55 /**
56 * Try to acquire lock. If the lock is already set or is being acquired by another locker, don't do anything.
57 *
58 * @author Vova Feldman (@svovaf)
59 * @since 2.1.0
60 *
61 * @param int $expiration
62 *
63 * @return bool TRUE if successfully acquired lock.
64 */
65 function try_lock( $expiration = 0 ) {
66 return $this->_lock->try_lock( $expiration );
67 }
68
69 /**
70 * Acquire lock regardless if it's already acquired by another locker or not.
71 *
72 * @author Vova Feldman (@svovaf)
73 * @since 2.1.0
74 *
75 * @param int $expiration
76 */
77 function lock( $expiration = 0 ) {
78 $this->_lock->lock( $expiration );
79 }
80
81 /**
82 * Unlock the lock.
83 *
84 * @author Vova Feldman (@svovaf)
85 * @since 2.1.0
86 */
87 function unlock() {
88 $this->_lock->unlock();
89 }
90 }
...\ No newline at end of file ...\ No newline at end of file
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.2.2.7
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Class Zerif_Customizer_Theme_Info_Main
15 *
16 * @since 1.0.0
17 * @access public
18 */
19 class FS_Customizer_Support_Section extends WP_Customize_Section {
20
21 function __construct( $manager, $id, $args = array() ) {
22 $manager->register_section_type( 'FS_Customizer_Support_Section' );
23
24 parent::__construct( $manager, $id, $args );
25 }
26
27 /**
28 * The type of customize section being rendered.
29 *
30 * @since 1.0.0
31 * @access public
32 * @var string
33 */
34 public $type = 'freemius-support-section';
35
36 /**
37 * @var Freemius
38 */
39 public $fs = null;
40
41 /**
42 * Add custom parameters to pass to the JS via JSON.
43 *
44 * @since 1.0.0
45 */
46 public function json() {
47 $json = parent::json();
48
49 $is_contact_visible = $this->fs->is_page_visible( 'contact' );
50 $is_support_visible = $this->fs->is_page_visible( 'support' );
51
52 $json['theme_title'] = $this->fs->get_plugin_name();
53
54 if ( $is_contact_visible && $is_support_visible ) {
55 $json['theme_title'] .= ' ' . $this->fs->get_text_inline( 'Support', 'support' );
56 }
57
58 if ( $is_contact_visible ) {
59 $json['contact'] = array(
60 'label' => $this->fs->get_text_inline( 'Contact Us', 'contact-us' ),
61 'url' => $this->fs->contact_url(),
62 );
63 }
64
65 if ( $is_support_visible ) {
66 $json['support'] = array(
67 'label' => $this->fs->get_text_inline( 'Support Forum', 'support-forum' ),
68 'url' => $this->fs->get_support_forum_url()
69 );
70 }
71
72 return $json;
73 }
74
75 /**
76 * Outputs the Underscore.js template.
77 *
78 * @since 1.0.0
79 */
80 protected function render_template() {
81 ?>
82 <li id="fs_customizer_support"
83 class="accordion-section control-section control-section-{{ data.type }} cannot-expand">
84 <h3 class="accordion-section-title">
85 <span>{{ data.theme_title }}</span>
86 <# if ( data.contact && data.support ) { #>
87 <div class="button-group">
88 <# } #>
89 <# if ( data.contact ) { #>
90 <a class="button" href="{{ data.contact.url }}" target="_blank" rel="noopener noreferrer">{{ data.contact.label }} </a>
91 <# } #>
92 <# if ( data.support ) { #>
93 <a class="button" href="{{ data.support.url }}" target="_blank" rel="noopener noreferrer">{{ data.support.label }} </a>
94 <# } #>
95 <# if ( data.contact && data.support ) { #>
96 </div>
97 <# } #>
98 </h3>
99 </li>
100 <?php
101 }
102 }
...\ No newline at end of file ...\ No newline at end of file
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.2.2.7
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Class FS_Customizer_Upsell_Control
15 */
16 class FS_Customizer_Upsell_Control extends WP_Customize_Control {
17
18 /**
19 * Control type
20 *
21 * @var string control type
22 */
23 public $type = 'freemius-upsell-control';
24
25 /**
26 * @var Freemius
27 */
28 public $fs = null;
29
30 /**
31 * @param WP_Customize_Manager $manager the customize manager class.
32 * @param string $id id.
33 * @param array $args customizer manager parameters.
34 */
35 public function __construct( WP_Customize_Manager $manager, $id, array $args ) {
36 $manager->register_control_type( 'FS_Customizer_Upsell_Control' );
37
38 parent::__construct( $manager, $id, $args );
39 }
40
41 /**
42 * Enqueue resources for the control.
43 */
44 public function enqueue() {
45 fs_enqueue_local_style( 'fs_customizer', 'customizer.css' );
46 }
47
48 /**
49 * Json conversion
50 */
51 public function to_json() {
52 $pricing_cta = esc_html( $this->fs->get_pricing_cta_label() ) . '&nbsp;&nbsp;' . ( is_rtl() ? '&#x2190;' : '&#x27a4;' );
53
54 parent::to_json();
55
56 $this->json['button_text'] = $pricing_cta;
57 $this->json['button_url'] = $this->fs->is_in_trial_promotion() ?
58 $this->fs->get_trial_url() :
59 $this->fs->get_upgrade_url();
60
61 $api = FS_Plugin::is_valid_id( $this->fs->get_bundle_id() ) ?
62 $this->fs->get_api_bundle_scope() :
63 $this->fs->get_api_plugin_scope();
64
65 // Load features.
66 $pricing = $api->get( $this->fs->add_show_pending( "pricing.json" ) );
67
68 if ( $this->fs->is_api_result_object( $pricing, 'plans' ) ) {
69 // Add support features.
70 if ( is_array( $pricing->plans ) && 0 < count( $pricing->plans ) ) {
71 $support_features = array(
72 'kb' => 'Help Center',
73 'forum' => 'Support Forum',
74 'email' => 'Priority Email Support',
75 'phone' => 'Phone Support',
76 'skype' => 'Skype Support',
77 'is_success_manager' => 'Personal Success Manager',
78 );
79
80 for ( $i = 0, $len = count( $pricing->plans ); $i < $len; $i ++ ) {
81 if ( 'free' == $pricing->plans[$i]->name ) {
82 continue;
83 }
84
85 if ( ! isset( $pricing->plans[ $i ]->features ) ||
86 ! is_array( $pricing->plans[ $i ]->features ) ) {
87 $pricing->plans[$i]->features = array();
88 }
89
90 foreach ( $support_features as $key => $label ) {
91 $key = ( 'is_success_manager' !== $key ) ?
92 "support_{$key}" :
93 $key;
94
95 if ( ! empty( $pricing->plans[ $i ]->{$key} ) ) {
96
97 $support_feature = new stdClass();
98 $support_feature->title = $label;
99
100 $pricing->plans[ $i ]->features[] = $support_feature;
101 }
102 }
103 }
104
105 $this->json['plans'] = $pricing->plans;
106 }
107 }
108
109 $this->json['strings'] = array(
110 'plan' => $this->fs->get_text_x_inline( 'Plan', 'as product pricing plan', 'plan' ),
111 );
112 }
113
114 /**
115 * Control content
116 */
117 public function content_template() {
118 ?>
119 <div id="fs_customizer_upsell">
120 <# if ( data.plans ) { #>
121 <ul class="fs-customizer-plans">
122 <# for (i in data.plans) { #>
123 <# if ( 'free' != data.plans[i].name && (null != data.plans[i].features && 0 < data.plans[i].features.length) ) { #>
124 <li class="fs-customizer-plan">
125 <div class="fs-accordion-section-open">
126 <h2 class="fs-accordion-section-title menu-item">
127 <span>{{ data.plans[i].title }}</span>
128 <button type="button" class="button-link item-edit" aria-expanded="true">
129 <span class="screen-reader-text">Toggle section: {{ data.plans[i].title }} {{ data.strings.plan }}</span>
130 <span class="toggle-indicator" aria-hidden="true"></span>
131 </button>
132 </h2>
133 <div class="fs-accordion-section-content">
134 <# if ( data.plans[i].description ) { #>
135 <h3>{{ data.plans[i].description }}</h3>
136 <# } #>
137 <# if ( data.plans[i].features ) { #>
138 <ul>
139 <# for ( j in data.plans[i].features ) { #>
140 <li><div class="fs-feature">
141 <span class="dashicons dashicons-yes"></span><span><# if ( data.plans[i].features[j].value ) { #>{{ data.plans[i].features[j].value }} <# } #>{{ data.plans[i].features[j].title }}</span>
142 <# if ( data.plans[i].features[j].description ) { #>
143 <span class="dashicons dashicons-editor-help"><span class="fs-feature-desc">{{ data.plans[i].features[j].description }}</span></span>
144 <# } #>
145 </div></li>
146 <# } #>
147 </ul>
148 <# } #>
149 <# if ( 'free' != data.plans[i].name ) { #>
150 <a href="{{ data.button_url }}" class="button button-primary" target="_blank">{{{ data.button_text }}}</a>
151 <# } #>
152 </div>
153 </div>
154 </li>
155 <# } #>
156 <# } #>
157 </ul>
158 <# } #>
159 </div>
160 <?php }
161 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
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.7.3
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Extends Debug Bar plugin by adding a panel to show all Freemius API requests.
15 *
16 * @author Vova Feldman (@svovaf)
17 * @since 1.1.7.3
18 *
19 * Class Freemius_Debug_Bar_Panel
20 */
21 class Freemius_Debug_Bar_Panel extends Debug_Bar_Panel {
22 function init() {
23 $this->title( 'Freemius' );
24 }
25
26 static function requests_count() {
27 if ( class_exists( 'Freemius_Api_WordPress' ) ) {
28 $logger = Freemius_Api_WordPress::GetLogger();
29 } else {
30 $logger = array();
31 }
32
33 return number_format( count( $logger ) );
34 }
35
36 static function total_time() {
37 if ( class_exists( 'Freemius_Api_WordPress' ) ) {
38 $logger = Freemius_Api_WordPress::GetLogger();
39 } else {
40 $logger = array();
41 }
42
43 $total_time = .0;
44 foreach ( $logger as $l ) {
45 $total_time += $l['total'];
46 }
47
48 return number_format( 100 * $total_time, 2 ) . ' ' . fs_text_x_inline( 'ms', 'milliseconds' );
49 }
50
51 function render() {
52 ?>
53 <div id='debug-bar-php'>
54 <?php fs_require_template( '/debug/api-calls.php' ) ?>
55 <br>
56 <?php fs_require_template( '/debug/scheduled-crons.php' ) ?>
57 <br>
58 <?php fs_require_template( '/debug/plugins-themes-sync.php' ) ?>
59 <br>
60 <?php fs_require_template( '/debug/logger.php' ) ?>
61 </div>
62 <?php
63 }
64 }
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.7.3
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 if ( ! WP_FS__DEBUG_SDK ) {
14 return;
15 }
16
17 /**
18 * Initialize Freemius custom debug panels.
19 *
20 * @param array $panels Debug bar panels objects
21 *
22 * @return array Debug bar panels with your custom panels
23 */
24 function fs_custom_panels_init( $panels ) {
25 if ( class_exists( 'Debug_Bar_Panel' ) ) {
26 if ( FS_API__LOGGER_ON ) {
27 require_once dirname( __FILE__ ) . '/class-fs-debug-bar-panel.php';
28 $panels[] = new Freemius_Debug_Bar_Panel();
29 }
30 }
31
32 return $panels;
33 }
34
35 function fs_custom_status_init( $statuses ) {
36 if ( class_exists( 'Debug_Bar_Panel' ) ) {
37 if ( FS_API__LOGGER_ON ) {
38 require_once dirname( __FILE__ ) . '/class-fs-debug-bar-panel.php';
39 $statuses[] = array(
40 'fs_api_requests',
41 fs_text_inline( 'Freemius API' ),
42 Freemius_Debug_Bar_Panel::requests_count() . ' ' . fs_text_inline( 'Requests' ) .
43 ' (' . Freemius_Debug_Bar_Panel::total_time() . ')'
44 );
45 }
46 }
47
48 return $statuses;
49 }
50
51 add_filter( 'debug_bar_panels', 'fs_custom_panels_init' );
52 add_filter( 'debug_bar_statuses', 'fs_custom_status_init' );
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
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.2.3
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_AffiliateTerms extends FS_Scope_Entity {
14
15 #region Properties
16
17 /**
18 * @var bool
19 */
20 public $is_active;
21 /**
22 * @var string Enum: `affiliation` or `rewards`. Defaults to `affiliation`.
23 */
24 public $type;
25 /**
26 * @var string Enum: `payout` or `credit`. Defaults to `payout`.
27 */
28 public $reward_type;
29 /**
30 * If `first`, the referral will be attributed to the first visited source containing the affiliation link that
31 * was clicked.
32 *
33 * @var string Enum: `first` or `last`. Defaults to `first`.
34 */
35 public $referral_attribution;
36 /**
37 * @var int Defaults to `30`, `0` for session cookie, and `null` for endless cookie (until cookies are cleaned).
38 */
39 public $cookie_days;
40 /**
41 * @var int
42 */
43 public $commission;
44 /**
45 * @var string Enum: `percentage` or `dollar`. Defaults to `percentage`.
46 */
47 public $commission_type;
48 /**
49 * @var null|int Defaults to `0` (affiliate only on first payment). `null` for commission for all renewals. If
50 * greater than `0`, affiliate will get paid for all renewals for `commission_renewals_days` days after
51 * the initial upgrade/purchase.
52 */
53 public $commission_renewals_days;
54 /**
55 * @var int Only cents and no percentage. In US cents, e.g.: 100 = $1.00. Defaults to `null`.
56 */
57 public $install_commission;
58 /**
59 * @var string Required default target link, e.g.: pricing page.
60 */
61 public $default_url;
62 /**
63 * @var string One of the following: 'all', 'new_customer', 'new_user'.
64 * If 'all' - reward for any user type.
65 * If 'new_customer' - reward only for new customers.
66 * If 'new_user' - reward only for new users.
67 */
68 public $reward_customer_type;
69 /**
70 * @var int Defaults to `0` (affiliate only on directly affiliated links). `null` if an affiliate will get
71 * paid for all customers' lifetime payments. If greater than `0`, an affiliate will get paid for all
72 * customer payments for `future_payments_days` days after the initial payment.
73 */
74 public $future_payments_days;
75 /**
76 * @var bool If `true`, allow referrals from social sites.
77 */
78 public $is_social_allowed;
79 /**
80 * @var bool If `true`, allow conversions without HTTP referrer header at all.
81 */
82 public $is_app_allowed;
83 /**
84 * @var bool If `true`, allow referrals from any site.
85 */
86 public $is_any_site_allowed;
87 /**
88 * @var string $plugin_title Title of the plugin. This is used in case we are showing affiliate form for a Bundle instead of the `plugin` in context.
89 */
90 public $plugin_title;
91
92 #endregion Properties
93
94 /**
95 * @author Leo Fajardo (@leorw)
96 *
97 * @return string
98 */
99 function get_formatted_commission()
100 {
101 return ( 'dollar' === $this->commission_type ) ?
102 ( '$' . $this->commission ) :
103 ( $this->commission . '%' );
104 }
105
106 /**
107 * @author Leo Fajardo (@leorw)
108 *
109 * @return bool
110 */
111 function has_lifetime_commission() {
112 return ( 0 !== $this->future_payments_days );
113 }
114
115 /**
116 * @author Leo Fajardo (@leorw)
117 *
118 * @return bool
119 */
120 function is_session_cookie() {
121 return ( 0 == $this->cookie_days );
122 }
123
124 /**
125 * @author Leo Fajardo (@leorw)
126 *
127 * @return bool
128 */
129 function has_renewals_commission() {
130 return ( is_null( $this->commission_renewals_days ) || $this->commission_renewals_days > 0 );
131 }
132 }
...\ No newline at end of file ...\ No newline at end of file
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.2.3
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Affiliate extends FS_Scope_Entity {
14
15 #region Properties
16
17 /**
18 * @var string
19 */
20 public $paypal_email;
21 /**
22 * @var number
23 */
24 public $custom_affiliate_terms_id;
25 /**
26 * @var boolean
27 */
28 public $is_using_custom_terms;
29 /**
30 * @var string status Enum: `pending`, `rejected`, `suspended`, or `active`. Defaults to `pending`.
31 */
32 public $status;
33 /**
34 * @var string
35 */
36 public $domain;
37
38 #endregion Properties
39
40 /**
41 * @author Leo Fajardo
42 *
43 * @return bool
44 */
45 function is_active() {
46 return ( 'active' === $this->status );
47 }
48
49 /**
50 * @author Leo Fajardo
51 *
52 * @return bool
53 */
54 function is_pending() {
55 return ( 'pending' === $this->status );
56 }
57
58 /**
59 * @author Leo Fajardo
60 *
61 * @return bool
62 */
63 function is_suspended() {
64 return ( 'suspended' === $this->status );
65 }
66
67 /**
68 * @author Leo Fajardo
69 *
70 * @return bool
71 */
72 function is_rejected() {
73 return ( 'rejected' === $this->status );
74 }
75
76 /**
77 * @author Leo Fajardo
78 *
79 * @return bool
80 */
81 function is_blocked() {
82 return ( 'blocked' === $this->status );
83 }
84 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius for EDD Add-On
4 * @copyright Copyright (c) 2016, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.0
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Billing extends FS_Entity {
14
15 #region Properties
16
17 /**
18 * @var int
19 */
20 public $entity_id;
21 /**
22 * @var string (Enum) Linked entity type. One of: developer, plugin, user, install
23 */
24 public $entity_type;
25 /**
26 * @var string
27 */
28 public $business_name;
29 /**
30 * @var string
31 */
32 public $first;
33 /**
34 * @var string
35 */
36 public $last;
37 /**
38 * @var string
39 */
40 public $email;
41 /**
42 * @var string
43 */
44 public $phone;
45 /**
46 * @var string
47 */
48 public $website;
49 /**
50 * @var string Tax or VAT ID.
51 */
52 public $tax_id;
53 /**
54 * @var string
55 */
56 public $address_street;
57 /**
58 * @var string
59 */
60 public $address_apt;
61 /**
62 * @var string
63 */
64 public $address_city;
65 /**
66 * @var string
67 */
68 public $address_country;
69 /**
70 * @var string Two chars country code.
71 */
72 public $address_country_code;
73 /**
74 * @var string
75 */
76 public $address_state;
77 /**
78 * @var number Numeric ZIP code (cab be with leading zeros).
79 */
80 public $address_zip;
81
82 #endregion Properties
83
84
85 /**
86 * @param object|bool $event
87 */
88 function __construct( $event = false ) {
89 parent::__construct( $event );
90 }
91
92 static function get_type() {
93 return 'billing';
94 }
95 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.3
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Get object's public variables.
15 *
16 * @author Vova Feldman (@svovaf)
17 * @since 1.0.0
18 *
19 * @param object $object
20 *
21 * @return array
22 */
23 function fs_get_object_public_vars( $object ) {
24 return get_object_vars( $object );
25 }
26
27 class FS_Entity {
28 /**
29 * @var number
30 */
31 public $id;
32 /**
33 * @var string Datetime value in 'YYYY-MM-DD HH:MM:SS' format.
34 */
35 public $updated;
36 /**
37 * @var string Datetime value in 'YYYY-MM-DD HH:MM:SS' format.
38 */
39 public $created;
40
41 /**
42 * @param bool|object $entity
43 */
44 function __construct( $entity = false ) {
45 if ( ! ( $entity instanceof stdClass ) && ! ( $entity instanceof FS_Entity ) ) {
46 return;
47 }
48
49 $props = fs_get_object_public_vars( $this );
50
51 foreach ( $props as $key => $def_value ) {
52 $this->{$key} = isset( $entity->{$key} ) ?
53 $entity->{$key} :
54 $def_value;
55 }
56 }
57
58 static function get_type() {
59 return 'type';
60 }
61
62 /**
63 * @author Vova Feldman (@svovaf)
64 * @since 1.0.6
65 *
66 * @param FS_Entity $entity1
67 * @param FS_Entity $entity2
68 *
69 * @return bool
70 */
71 static function equals( $entity1, $entity2 ) {
72 if ( is_null( $entity1 ) && is_null( $entity2 ) ) {
73 return true;
74 } else if ( is_object( $entity1 ) && is_object( $entity2 ) ) {
75 return ( $entity1->id == $entity2->id );
76 } else if ( is_object( $entity1 ) ) {
77 return is_null( $entity1->id );
78 } else {
79 return is_null( $entity2->id );
80 }
81 }
82
83 private $_is_updated = false;
84
85 /**
86 * Update object property.
87 *
88 * @author Vova Feldman (@svovaf)
89 * @since 1.0.9
90 *
91 * @param string|array[string]mixed $key
92 * @param string|bool $val
93 *
94 * @return bool
95 */
96 function update( $key, $val = false ) {
97 if ( ! is_array( $key ) ) {
98 $key = array( $key => $val );
99 }
100
101 $is_updated = false;
102
103 foreach ( $key as $k => $v ) {
104 if ( $this->{$k} === $v ) {
105 continue;
106 }
107
108 if ( ( is_string( $this->{$k} ) && is_numeric( $v ) ||
109 ( is_numeric( $this->{$k} ) && is_string( $v ) ) ) &&
110 $this->{$k} == $v
111 ) {
112 continue;
113 }
114
115 // Update value.
116 $this->{$k} = $v;
117
118 $is_updated = true;
119 }
120
121 $this->_is_updated = $is_updated;
122
123 return $is_updated;
124 }
125
126 /**
127 * Checks if entity was updated.
128 *
129 * @author Vova Feldman (@svovaf)
130 * @since 1.0.9
131 *
132 * @return bool
133 */
134 function is_updated() {
135 return $this->_is_updated;
136 }
137
138 /**
139 * @param $id
140 *
141 * @author Vova Feldman (@svovaf)
142 * @since 1.1.2
143 *
144 * @return bool
145 */
146 static function is_valid_id($id){
147 return is_numeric($id);
148 }
149
150 /**
151 * @author Leo Fajardo (@leorw)
152 * @since 2.3.1
153 *
154 * @return string
155 */
156 public static function get_class_name() {
157 return get_called_class();
158 }
159 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2016, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.0
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Payment extends FS_Entity {
14
15 #region Properties
16
17 /**
18 * @var number
19 */
20 public $plugin_id;
21 /**
22 * @var number
23 */
24 public $user_id;
25 /**
26 * @var number
27 */
28 public $install_id;
29 /**
30 * @var number
31 */
32 public $subscription_id;
33 /**
34 * @var number
35 */
36 public $plan_id;
37 /**
38 * @var number
39 */
40 public $license_id;
41 /**
42 * @var float
43 */
44 public $gross;
45 /**
46 * @author Leo Fajardo (@leorw)
47 * @since 2.3.0
48 *
49 * @var string One of the following: `usd`, `gbp`, `eur`.
50 */
51 public $currency;
52 /**
53 * @var number
54 */
55 public $bound_payment_id;
56 /**
57 * @var string
58 */
59 public $external_id;
60 /**
61 * @var string
62 */
63 public $gateway;
64 /**
65 * @var string ISO 3166-1 alpha-2 - two-letter country code.
66 *
67 * @link http://www.wikiwand.com/en/ISO_3166-1_alpha-2
68 */
69 public $country_code;
70 /**
71 * @var string
72 */
73 public $vat_id;
74 /**
75 * @var float Actual Tax / VAT in $$$
76 */
77 public $vat;
78 /**
79 * @var int Payment source.
80 */
81 public $source = 0;
82
83 #endregion Properties
84
85 const CURRENCY_USD = 'usd';
86 const CURRENCY_GBP = 'gbp';
87 const CURRENCY_EUR = 'eur';
88
89 /**
90 * @param object|bool $payment
91 */
92 function __construct( $payment = false ) {
93 parent::__construct( $payment );
94 }
95
96 static function get_type() {
97 return 'payment';
98 }
99
100 /**
101 * @author Vova Feldman (@svovaf)
102 * @since 1.0.0
103 *
104 * @return bool
105 */
106 function is_refund() {
107 return ( parent::is_valid_id( $this->bound_payment_id ) && 0 > $this->gross );
108 }
109
110 /**
111 * Checks if the payment was migrated from another platform.
112 *
113 * @author Vova Feldman (@svovaf)
114 * @since 2.0.2
115 *
116 * @return bool
117 */
118 function is_migrated() {
119 return ( 0 != $this->source );
120 }
121
122 /**
123 * Returns the gross in this format:
124 * `{symbol}{amount | 2 decimal digits} {currency | uppercase}`
125 *
126 * Examples: £9.99 GBP, -£9.99 GBP.
127 *
128 * @author Leo Fajardo (@leorw)
129 * @since 2.3.0
130 *
131 * @return string
132 */
133 function formatted_gross()
134 {
135 return (
136 ( $this->gross < 0 ? '-' : '' ) .
137 $this->get_symbol() .
138 number_format( abs( $this->gross ), 2, '.', ',' ) . ' ' .
139 strtoupper( $this->currency )
140 );
141 }
142
143 /**
144 * A map between supported currencies with their symbols.
145 *
146 * @var array<string,string>
147 */
148 static $CURRENCY_2_SYMBOL;
149
150 /**
151 * @author Leo Fajardo (@leorw)
152 * @since 2.3.0
153 *
154 * @return string
155 */
156 private function get_symbol() {
157 if ( ! isset( self::$CURRENCY_2_SYMBOL ) ) {
158 // Lazy load.
159 self::$CURRENCY_2_SYMBOL = array(
160 self::CURRENCY_USD => '$',
161 self::CURRENCY_GBP => '&pound;',
162 self::CURRENCY_EUR => '&euro;',
163 );
164 }
165
166 return self::$CURRENCY_2_SYMBOL[ $this->currency ];
167 }
168 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.3
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Plugin_Info extends FS_Entity {
14 public $plugin_id;
15 public $description;
16 public $short_description;
17 public $banner_url;
18 public $card_banner_url;
19 public $selling_point_0;
20 public $selling_point_1;
21 public $selling_point_2;
22 public $screenshots;
23
24 /**
25 * @param stdClass|bool $plugin_info
26 */
27 function __construct( $plugin_info = false ) {
28 parent::__construct( $plugin_info );
29 }
30
31 static function get_type() {
32 return 'plugin';
33 }
34 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.5
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Class FS_Plugin_License
15 */
16 class FS_Plugin_License extends FS_Entity {
17
18 #region Properties
19
20 /**
21 * @var number
22 */
23 public $plugin_id;
24 /**
25 * @var number
26 */
27 public $user_id;
28 /**
29 * @var number
30 */
31 public $plan_id;
32 /**
33 * @author Leo Fajardo (@leorw)
34 * @since 2.3.0
35 *
36 * @var string
37 */
38 public $parent_plan_name;
39 /**
40 * @author Leo Fajardo (@leorw)
41 * @since 2.3.0
42 *
43 * @var string
44 */
45 public $parent_plan_title;
46 /**
47 * @author Leo Fajardo (@leorw)
48 * @since 2.3.0
49 *
50 * @var number
51 */
52 public $parent_license_id;
53 /**
54 * @author Leo Fajardo (@leorw)
55 * @since 2.4.0
56 *
57 * @var array
58 */
59 public $products;
60 /**
61 * @var number
62 */
63 public $pricing_id;
64 /**
65 * @var int|null
66 */
67 public $quota;
68 /**
69 * @var int
70 */
71 public $activated;
72 /**
73 * @var int
74 */
75 public $activated_local;
76 /**
77 * @var string
78 */
79 public $expiration;
80 /**
81 * @var string
82 */
83 public $secret_key;
84 /**
85 * @var bool
86 */
87 public $is_whitelabeled;
88 /**
89 * @var bool $is_free_localhost Defaults to true. If true, allow unlimited localhost installs with the same
90 * license.
91 */
92 public $is_free_localhost;
93 /**
94 * @var bool $is_block_features Defaults to true. If false, don't block features after license expiry - only
95 * block updates and support.
96 */
97 public $is_block_features;
98 /**
99 * @var bool
100 */
101 public $is_cancelled;
102
103 #endregion Properties
104
105 /**
106 * @param stdClass|bool $license
107 */
108 function __construct( $license = false ) {
109 parent::__construct( $license );
110 }
111
112 /**
113 * Get entity type.
114 *
115 * @return string
116 */
117 static function get_type() {
118 return 'license';
119 }
120
121 /**
122 * Check how many site activations left.
123 *
124 * @author Vova Feldman (@svovaf)
125 * @since 1.0.5
126 *
127 * @return int
128 */
129 function left() {
130 if ( ! $this->is_features_enabled() ) {
131 return 0;
132 }
133
134 if ( $this->is_unlimited() ) {
135 return 999;
136 }
137
138 return ( $this->quota - $this->activated - ( $this->is_free_localhost ? 0 : $this->activated_local ) );
139 }
140
141 /**
142 * Check if single site license.
143 *
144 * @author Vova Feldman (@svovaf)
145 * @since 1.1.8.1
146 *
147 * @return bool
148 */
149 function is_single_site() {
150 return ( is_numeric( $this->quota ) && 1 == $this->quota );
151 }
152
153 /**
154 * @author Vova Feldman (@svovaf)
155 * @since 1.0.5
156 *
157 * @return bool
158 */
159 function is_expired() {
160 return ! $this->is_lifetime() && ( strtotime( $this->expiration ) < WP_FS__SCRIPT_START_TIME );
161 }
162
163 /**
164 * Check if license is not expired.
165 *
166 * @author Vova Feldman (@svovaf)
167 * @since 1.2.1
168 *
169 * @return bool
170 */
171 function is_valid() {
172 return ! $this->is_expired();
173 }
174
175 /**
176 * @author Vova Feldman (@svovaf)
177 * @since 1.0.6
178 *
179 * @return bool
180 */
181 function is_lifetime() {
182 return is_null( $this->expiration );
183 }
184
185 /**
186 * @author Vova Feldman (@svovaf)
187 * @since 1.2.0
188 *
189 * @return bool
190 */
191 function is_unlimited() {
192 return is_null( $this->quota );
193 }
194
195 /**
196 * Check if license is fully utilized.
197 *
198 * @author Vova Feldman (@svovaf)
199 * @since 1.0.6
200 *
201 * @param bool|null $is_localhost
202 *
203 * @return bool
204 */
205 function is_utilized( $is_localhost = null ) {
206 if ( is_null( $is_localhost ) ) {
207 $is_localhost = WP_FS__IS_LOCALHOST_FOR_SERVER;
208 }
209
210 if ( $this->is_unlimited() ) {
211 return false;
212 }
213
214 return ! ( $this->is_free_localhost && $is_localhost ) &&
215 ( $this->quota <= $this->activated + ( $this->is_free_localhost ? 0 : $this->activated_local ) );
216 }
217
218 /**
219 * Check if license can be activated.
220 *
221 * @author Vova Feldman (@svovaf)
222 * @since 2.0.0
223 *
224 * @param bool|null $is_localhost
225 *
226 * @return bool
227 */
228 function can_activate( $is_localhost = null ) {
229 return ! $this->is_utilized( $is_localhost ) && $this->is_features_enabled();
230 }
231
232 /**
233 * Check if license can be activated on a given number of production and localhost sites.
234 *
235 * @author Vova Feldman (@svovaf)
236 * @since 2.0.0
237 *
238 * @param int $production_count
239 * @param int $localhost_count
240 *
241 * @return bool
242 */
243 function can_activate_bulk( $production_count, $localhost_count ) {
244 if ( $this->is_unlimited() ) {
245 return true;
246 }
247
248 /**
249 * For simplicity, the logic will work as following: when given X sites to activate the license on, if it's
250 * possible to activate on ALL of them, do the activation. If it's not possible to activate on ALL of them,
251 * do NOT activate on any of them.
252 */
253 return ( $this->quota >= $this->activated + $production_count + ( $this->is_free_localhost ? 0 : $this->activated_local + $localhost_count ) );
254 }
255
256 /**
257 * @author Vova Feldman (@svovaf)
258 * @since 1.2.1
259 *
260 * @return bool
261 */
262 function is_active() {
263 return ( ! $this->is_cancelled );
264 }
265
266 /**
267 * Check if license's plan features are enabled.
268 *
269 * - Either if plan not expired
270 * - If expired, based on the configuration to block features or not.
271 *
272 * @author Vova Feldman (@svovaf)
273 * @since 1.0.6
274 *
275 * @return bool
276 */
277 function is_features_enabled() {
278 return $this->is_active() && ( ! $this->is_block_features || ! $this->is_expired() );
279 }
280
281 /**
282 * Subscription considered to be new without any payments
283 * if the license expires in less than 24 hours
284 * from the license creation.
285 *
286 * @author Vova Feldman (@svovaf)
287 * @since 1.0.9
288 *
289 * @return bool
290 */
291 function is_first_payment_pending() {
292 return ( WP_FS__TIME_24_HOURS_IN_SEC >= strtotime( $this->expiration ) - strtotime( $this->created ) );
293 }
294
295 /**
296 * @return int
297 */
298 function total_activations() {
299 return ( $this->activated + $this->activated_local );
300 }
301
302 /**
303 * @author Vova Feldman (@svovaf)
304 * @since 2.3.1
305 *
306 * @return string
307 */
308 function get_html_escaped_masked_secret_key() {
309 return self::mask_secret_key_for_html( $this->secret_key );
310 }
311
312 /**
313 * @author Vova Feldman (@svovaf)
314 * @since 2.3.1
315 *
316 * @param string $secret_key
317 *
318 * @return string
319 */
320 static function mask_secret_key_for_html( $secret_key ) {
321 return (
322 // Initial 6 chars - sk_ABC
323 htmlspecialchars( substr( $secret_key, 0, 6 ) ) .
324 // Masking
325 str_pad( '', ( strlen( $secret_key ) - 9 ) * 6, '&bull;' ) .
326 // Last 3 chars.
327 htmlspecialchars( substr( $secret_key, - 3 ) )
328 );
329 }
330 }
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.5
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Class FS_Plugin_Plan
15 *
16 * @property FS_Pricing[] $pricing
17 */
18 class FS_Plugin_Plan extends FS_Entity {
19
20 #region Properties
21
22 /**
23 * @var number
24 */
25 public $plugin_id;
26 /**
27 * @var string
28 */
29 public $name;
30 /**
31 * @var string
32 */
33 public $title;
34 /**
35 * @var string
36 */
37 public $description;
38 /**
39 * @var bool Defaults to true. If true, allow unlimited localhost installs with the same license.
40 */
41 public $is_free_localhost;
42 /**
43 * @var bool Defaults to true. If false, don't block features after license expiry - only block updates and
44 * support.
45 */
46 public $is_block_features;
47 /**
48 * @var int
49 */
50 public $license_type;
51 /**
52 * @var bool
53 */
54 public $is_https_support;
55 /**
56 * @var int Trial days.
57 */
58 public $trial_period;
59 /**
60 * @var string If true, require payment for trial.
61 */
62 public $is_require_subscription;
63 /**
64 * @var string Knowledge Base URL.
65 */
66 public $support_kb;
67 /**
68 * @var string Support Forum URL.
69 */
70 public $support_forum;
71 /**
72 * @var string Support email address.
73 */
74 public $support_email;
75 /**
76 * @var string Support phone.
77 */
78 public $support_phone;
79 /**
80 * @var string Support skype username.
81 */
82 public $support_skype;
83 /**
84 * @var bool Is personal success manager supported with the plan.
85 */
86 public $is_success_manager;
87 /**
88 * @var bool Is featured plan.
89 */
90 public $is_featured;
91
92 #endregion Properties
93
94 /**
95 * @param object|bool $plan
96 */
97 function __construct( $plan = false ) {
98 parent::__construct( $plan );
99
100 if ( is_object( $plan ) ) {
101 $this->name = strtolower( $plan->name );
102 }
103 }
104
105 static function get_type() {
106 return 'plan';
107 }
108
109 /**
110 * @author Vova Feldman (@svovaf)
111 * @since 1.0.9
112 *
113 * @return bool
114 */
115 function is_free() {
116 return ( 'free' === $this->name );
117 }
118
119 /**
120 * Checks if this plan supports "Technical Support".
121 *
122 * @author Leo Fajardo (leorw)
123 * @since 1.2.0
124 *
125 * @return bool
126 */
127 function has_technical_support() {
128 return ( ! empty( $this->support_email ) ||
129 ! empty( $this->support_skype ) ||
130 ! empty( $this->support_phone ) ||
131 ! empty( $this->is_success_manager )
132 );
133 }
134
135 /**
136 * @author Vova Feldman (@svovaf)
137 * @since 1.0.9
138 *
139 * @return bool
140 */
141 function has_trial() {
142 return ! $this->is_free() &&
143 is_numeric( $this->trial_period ) && ( $this->trial_period > 0 );
144 }
145 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2018, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 2.0.0
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Plugin_Tag extends FS_Entity {
14 /**
15 * @var string
16 */
17 public $version;
18 /**
19 * @var string
20 */
21 public $url;
22 /**
23 * @var string
24 */
25 public $requires_platform_version;
26 /**
27 * @var string
28 */
29 public $requires_programming_language_version;
30 /**
31 * @var string
32 */
33 public $tested_up_to_version;
34 /**
35 * @var bool
36 */
37 public $has_free;
38 /**
39 * @var bool
40 */
41 public $has_premium;
42 /**
43 * @var string One of the following: `pending`, `beta`, `unreleased`.
44 */
45 public $release_mode;
46
47 function __construct( $tag = false ) {
48 parent::__construct( $tag );
49 }
50
51 static function get_type() {
52 return 'tag';
53 }
54
55 /**
56 * @author Leo Fajardo (@leorw)
57 * @since 2.3.0
58 *
59 * @return bool
60 */
61 function is_beta() {
62 return ( 'beta' === $this->release_mode );
63 }
64 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.3
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Plugin extends FS_Scope_Entity {
14 /**
15 * @since 1.0.6
16 * @var null|number
17 */
18 public $parent_plugin_id;
19 /**
20 * @var string
21 */
22 public $title;
23 /**
24 * @var string
25 */
26 public $slug;
27 /**
28 * @author Leo Fajardo (@leorw)
29 * @since 2.2.1
30 *
31 * @var string
32 */
33 public $premium_slug;
34 /**
35 * @since 1.2.2
36 *
37 * @var string 'plugin' or 'theme'
38 */
39 public $type;
40 /**
41 * @author Leo Fajardo (@leorw)
42 *
43 * @since 1.2.3
44 *
45 * @var string|false false if the module doesn't have an affiliate program or one of the following: 'selected', 'customers', or 'all'.
46 */
47 public $affiliate_moderation;
48 /**
49 * @var bool Set to true if the free version of the module is hosted on WordPress.org. Defaults to true.
50 */
51 public $is_wp_org_compliant = true;
52 /**
53 * @author Leo Fajardo (@leorw)
54 * @since 2.2.5
55 *
56 * @var int
57 */
58 public $premium_releases_count;
59
60 #region Install Specific Properties
61
62 /**
63 * @var string
64 */
65 public $file;
66 /**
67 * @var string
68 */
69 public $version;
70 /**
71 * @var bool
72 */
73 public $auto_update;
74 /**
75 * @var FS_Plugin_Info
76 */
77 public $info;
78 /**
79 * @since 1.0.9
80 *
81 * @var bool
82 */
83 public $is_premium;
84 /**
85 * @author Leo Fajardo (@leorw)
86 * @since 2.2.1
87 *
88 * @var string
89 */
90 public $premium_suffix;
91 /**
92 * @since 1.0.9
93 *
94 * @var bool
95 */
96 public $is_live;
97 /**
98 * @since 2.2.3
99 * @var null|number
100 */
101 public $bundle_id;
102 /**
103 * @since 2.3.1
104 * @var null|string
105 */
106 public $bundle_public_key;
107 /**
108 * @since 2.5.4
109 * @var null|array
110 */
111 public $opt_in_moderation;
112
113 const AFFILIATE_MODERATION_CUSTOMERS = 'customers';
114
115 #endregion Install Specific Properties
116
117 /**
118 * @param stdClass|bool $plugin
119 */
120 function __construct( $plugin = false ) {
121 parent::__construct( $plugin );
122
123 $this->is_premium = false;
124 $this->is_live = true;
125
126 if ( empty( $this->premium_slug ) && ! empty( $plugin->slug ) ) {
127 $this->premium_slug = "{$this->slug}-premium";
128 }
129
130 if ( empty( $this->premium_suffix ) ) {
131 $this->premium_suffix = '(Premium)';
132 }
133
134 if ( isset( $plugin->info ) && is_object( $plugin->info ) ) {
135 $this->info = new FS_Plugin_Info( $plugin->info );
136 }
137 }
138
139 /**
140 * Check if plugin is an add-on (has parent).
141 *
142 * @author Vova Feldman (@svovaf)
143 * @since 1.0.6
144 *
145 * @return bool
146 */
147 function is_addon() {
148 return isset( $this->parent_plugin_id ) && is_numeric( $this->parent_plugin_id );
149 }
150
151 /**
152 * @author Leo Fajardo (@leorw)
153 * @since 1.2.3
154 *
155 * @return bool
156 */
157 function has_affiliate_program() {
158 return ( ! empty( $this->affiliate_moderation ) );
159 }
160
161 static function get_type() {
162 return 'plugin';
163 }
164 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius for EDD Add-On
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.0
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Pricing extends FS_Entity {
14
15 #region Properties
16
17 /**
18 * @var number
19 */
20 public $plan_id;
21 /**
22 * @var int
23 */
24 public $licenses;
25 /**
26 * @var null|float
27 */
28 public $monthly_price;
29 /**
30 * @var null|float
31 */
32 public $annual_price;
33 /**
34 * @var null|float
35 */
36 public $lifetime_price;
37 /**
38 * @author Leo Fajardo (@leorw)
39 * @since 2.3.1
40 *
41 * @var string One of the following: `usd`, `gbp`, `eur`.
42 */
43 public $currency;
44
45 #endregion Properties
46
47 /**
48 * @param object|bool $pricing
49 */
50 function __construct( $pricing = false ) {
51 parent::__construct( $pricing );
52 }
53
54 static function get_type() {
55 return 'pricing';
56 }
57
58 /**
59 * @author Vova Feldman (@svovaf)
60 * @since 1.1.8
61 *
62 * @return bool
63 */
64 function has_monthly() {
65 return ( is_numeric( $this->monthly_price ) && $this->monthly_price > 0 );
66 }
67
68 /**
69 * @author Vova Feldman (@svovaf)
70 * @since 1.1.8
71 *
72 * @return bool
73 */
74 function has_annual() {
75 return ( is_numeric( $this->annual_price ) && $this->annual_price > 0 );
76 }
77
78 /**
79 * @author Vova Feldman (@svovaf)
80 * @since 1.1.8
81 *
82 * @return bool
83 */
84 function has_lifetime() {
85 return ( is_numeric( $this->lifetime_price ) && $this->lifetime_price > 0 );
86 }
87
88 /**
89 * Check if unlimited licenses pricing.
90 *
91 * @author Vova Feldman (@svovaf)
92 * @since 1.1.8
93 *
94 * @return bool
95 */
96 function is_unlimited() {
97 return is_null( $this->licenses );
98 }
99
100
101 /**
102 * Check if pricing has more than one billing cycle.
103 *
104 * @author Vova Feldman (@svovaf)
105 * @since 1.1.8
106 *
107 * @return bool
108 */
109 function is_multi_cycle() {
110 $cycles = 0;
111 if ( $this->has_monthly() ) {
112 $cycles ++;
113 }
114 if ( $this->has_annual() ) {
115 $cycles ++;
116 }
117 if ( $this->has_lifetime() ) {
118 $cycles ++;
119 }
120
121 return $cycles > 1;
122 }
123
124 /**
125 * Get annual over monthly discount.
126 *
127 * @author Vova Feldman (@svovaf)
128 * @since 1.1.8
129 *
130 * @return int
131 */
132 function annual_discount_percentage() {
133 return floor( $this->annual_savings() / ( $this->monthly_price * 12 * ( $this->is_unlimited() ? 1 : $this->licenses ) ) * 100 );
134 }
135
136 /**
137 * Get annual over monthly savings.
138 *
139 * @author Vova Feldman (@svovaf)
140 * @since 1.1.8
141 *
142 * @return float
143 */
144 function annual_savings() {
145 return ( $this->monthly_price * 12 - $this->annual_price ) * ( $this->is_unlimited() ? 1 : $this->licenses );
146 }
147
148 /**
149 * @author Leo Fajardo (@leorw)
150 * @since 2.3.1
151 *
152 * @return bool
153 */
154 function is_usd() {
155 return ( 'usd' === $this->currency );
156 }
157 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.4
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Scope_Entity extends FS_Entity {
14 /**
15 * @var string
16 */
17 public $public_key;
18 /**
19 * @var string
20 */
21 public $secret_key;
22
23 /**
24 * @param bool|stdClass $scope_entity
25 */
26 function __construct( $scope_entity = false ) {
27 parent::__construct( $scope_entity );
28 }
29 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.3
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * @property int $blog_id
15 */
16 class FS_Site extends FS_Scope_Entity {
17 /**
18 * @var number
19 */
20 public $site_id;
21 /**
22 * @var number
23 */
24 public $plugin_id;
25 /**
26 * @var number
27 */
28 public $user_id;
29 /**
30 * @var string
31 */
32 public $title;
33 /**
34 * @var string
35 */
36 public $url;
37 /**
38 * @var string
39 */
40 public $version;
41 /**
42 * @var string E.g. en-GB
43 */
44 public $language;
45 /**
46 * @var string Platform version (e.g WordPress version).
47 */
48 public $platform_version;
49 /**
50 * Freemius SDK version
51 *
52 * @author Leo Fajardo (@leorw)
53 * @since 1.2.2
54 *
55 * @var string SDK version (e.g.: 1.2.2)
56 */
57 public $sdk_version;
58 /**
59 * @var string Programming language version (e.g PHP version).
60 */
61 public $programming_language_version;
62 /**
63 * @var number|null
64 */
65 public $plan_id;
66 /**
67 * @var number|null
68 */
69 public $license_id;
70 /**
71 * @var number|null
72 */
73 public $trial_plan_id;
74 /**
75 * @var string|null
76 */
77 public $trial_ends;
78 /**
79 * @since 1.0.9
80 *
81 * @var bool
82 */
83 public $is_premium = false;
84 /**
85 * @author Leo Fajardo (@leorw)
86 *
87 * @since 1.2.1.5
88 * @deprecated Since 2.5.1
89 * @todo Remove after a few releases.
90 *
91 * @var bool
92 */
93 public $is_disconnected = false;
94 /**
95 * @since 2.0.0
96 *
97 * @var bool
98 */
99 public $is_active = true;
100 /**
101 * @since 2.0.0
102 *
103 * @var bool
104 */
105 public $is_uninstalled = false;
106 /**
107 * @author Edgar Melkonyan
108 *
109 * @since 2.4.2
110 *
111 * @var bool
112 */
113 public $is_beta;
114
115 /**
116 * @param stdClass|bool $site
117 */
118 function __construct( $site = false ) {
119 parent::__construct( $site );
120
121 if ( is_object( $site ) ) {
122 $this->plan_id = $site->plan_id;
123 }
124
125 if ( ! is_bool( $this->is_disconnected ) ) {
126 $this->is_disconnected = false;
127 }
128 }
129
130 static function get_type() {
131 return 'install';
132 }
133
134 /**
135 * @author Vova Feldman (@svovaf)
136 * @since 2.0.0
137 *
138 * @param string $url
139 *
140 * @return bool
141 */
142 static function is_localhost_by_address( $url ) {
143 if ( false !== strpos( $url, '127.0.0.1' ) ||
144 false !== strpos( $url, 'localhost' )
145 ) {
146 return true;
147 }
148
149 if ( ! fs_starts_with( $url, 'http' ) ) {
150 $url = 'http://' . $url;
151 }
152
153 $url_parts = parse_url( $url );
154
155 $subdomain = $url_parts['host'];
156
157 return (
158 // Starts with.
159 fs_starts_with( $subdomain, 'local.' ) ||
160 fs_starts_with( $subdomain, 'dev.' ) ||
161 fs_starts_with( $subdomain, 'test.' ) ||
162 fs_starts_with( $subdomain, 'stage.' ) ||
163 fs_starts_with( $subdomain, 'staging.' ) ||
164
165 // Ends with.
166 fs_ends_with( $subdomain, '.dev' ) ||
167 fs_ends_with( $subdomain, '.test' ) ||
168 fs_ends_with( $subdomain, '.staging' ) ||
169 fs_ends_with( $subdomain, '.local' ) ||
170 fs_ends_with( $subdomain, '.example' ) ||
171 fs_ends_with( $subdomain, '.invalid' ) ||
172 // GoDaddy test/dev.
173 fs_ends_with( $subdomain, '.myftpupload.com' ) ||
174 // ngrok tunneling.
175 fs_ends_with( $subdomain, '.ngrok.io' ) ||
176 // wpsandbox.
177 fs_ends_with( $subdomain, '.wpsandbox.pro' ) ||
178 // SiteGround staging.
179 fs_starts_with( $subdomain, 'staging' ) ||
180 // WPEngine staging.
181 fs_ends_with( $subdomain, '.staging.wpengine.com' ) ||
182 fs_ends_with( $subdomain, '.dev.wpengine.com' ) ||
183 fs_ends_with( $subdomain, '.wpengine.com' ) ||
184 // Pantheon
185 ( fs_ends_with( $subdomain, 'pantheonsite.io' ) &&
186 ( fs_starts_with( $subdomain, 'test-' ) || fs_starts_with( $subdomain, 'dev-' ) ) ) ||
187 // Cloudways
188 fs_ends_with( $subdomain, '.cloudwaysapps.com' ) ||
189 // Kinsta
190 (
191 ( fs_starts_with( $subdomain, 'staging-' ) || fs_starts_with( $subdomain, 'env-' ) ) &&
192 ( fs_ends_with( $subdomain, '.kinsta.com' ) || fs_ends_with( $subdomain, '.kinsta.cloud' ) )
193 ) ||
194 // DesktopServer
195 fs_ends_with( $subdomain, '.dev.cc' ) ||
196 // Pressable
197 fs_ends_with( $subdomain, '.mystagingwebsite.com' ) ||
198 // WPMU DEV
199 ( fs_ends_with( $subdomain, '.tempurl.host' ) || fs_ends_with( $subdomain, '.wpmudev.host' ) ) ||
200 // Vendasta
201 ( fs_ends_with( $subdomain, '.websitepro-staging.com' ) || fs_ends_with( $subdomain, '.websitepro.hosting' ) ) ||
202 // InstaWP
203 fs_ends_with( $subdomain, '.instawp.xyz' )
204 );
205 }
206
207 function is_localhost() {
208 return ( WP_FS__IS_LOCALHOST_FOR_SERVER || self::is_localhost_by_address( $this->url ) );
209 }
210
211 /**
212 * Check if site in trial.
213 *
214 * @author Vova Feldman (@svovaf)
215 * @since 1.0.9
216 *
217 * @return bool
218 */
219 function is_trial() {
220 return is_numeric( $this->trial_plan_id ) && ( strtotime( $this->trial_ends ) > WP_FS__SCRIPT_START_TIME );
221 }
222
223 /**
224 * Check if user already utilized the trial with the current install.
225 *
226 * @author Vova Feldman (@svovaf)
227 * @since 1.0.9
228 *
229 * @return bool
230 */
231 function is_trial_utilized() {
232 return is_numeric( $this->trial_plan_id );
233 }
234
235 /**
236 * @author Edgar Melkonyan
237 *
238 * @return bool
239 */
240 function is_beta() {
241 return ( isset( $this->is_beta ) && true === $this->is_beta );
242 }
243
244 /**
245 * @author Leo Fajardo (@leorw)
246 * @since 2.5.1
247 *
248 * @param string $site_url
249 *
250 * @return bool
251 */
252 function is_clone( $site_url ) {
253 $clone_install_url = trailingslashit( fs_strip_url_protocol( $this->url ) );
254
255 return ( $clone_install_url !== $site_url );
256 }
257 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.9
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Subscription extends FS_Entity {
14
15 #region Properties
16
17 /**
18 * @var number
19 */
20 public $user_id;
21 /**
22 * @var number
23 */
24 public $install_id;
25 /**
26 * @var number
27 */
28 public $plan_id;
29 /**
30 * @var number
31 */
32 public $license_id;
33 /**
34 * @var float
35 */
36 public $total_gross;
37 /**
38 * @var float
39 */
40 public $amount_per_cycle;
41 /**
42 * @var int # of months
43 */
44 public $billing_cycle;
45 /**
46 * @var float
47 */
48 public $outstanding_balance;
49 /**
50 * @var int
51 */
52 public $failed_payments;
53 /**
54 * @var string
55 */
56 public $gateway;
57 /**
58 * @var string
59 */
60 public $external_id;
61 /**
62 * @var string|null
63 */
64 public $trial_ends;
65 /**
66 * @var string|null Datetime of the next payment, or null if cancelled.
67 */
68 public $next_payment;
69 /**
70 * @since 2.3.1
71 *
72 * @var string|null Datetime of the cancellation.
73 */
74 public $canceled_at;
75 /**
76 * @var string|null
77 */
78 public $vat_id;
79 /**
80 * @var string Two characters country code
81 */
82 public $country_code;
83
84 #endregion Properties
85
86 /**
87 * @param object|bool $subscription
88 */
89 function __construct( $subscription = false ) {
90 parent::__construct( $subscription );
91 }
92
93 static function get_type() {
94 return 'subscription';
95 }
96
97 /**
98 * Check if subscription is active.
99 *
100 * @author Vova Feldman (@svovaf)
101 * @since 1.0.9
102 *
103 * @return bool
104 */
105 function is_active() {
106 if ( $this->is_canceled() ) {
107 return false;
108 }
109
110 return (
111 ! empty( $this->next_payment ) &&
112 strtotime( $this->next_payment ) > WP_FS__SCRIPT_START_TIME
113 );
114 }
115
116 /**
117 * @author Vova Feldman (@svovaf)
118 * @since 2.3.1
119 *
120 * @return bool
121 */
122 function is_canceled() {
123 return ! is_null( $this->canceled_at );
124 }
125
126 /**
127 * Subscription considered to be new without any payments
128 * if the next payment should be made within less than 24 hours
129 * from the subscription creation.
130 *
131 * @author Vova Feldman (@svovaf)
132 * @since 1.0.9
133 *
134 * @return bool
135 */
136 function is_first_payment_pending() {
137 return ( WP_FS__TIME_24_HOURS_IN_SEC >= strtotime( $this->next_payment ) - strtotime( $this->created ) );
138 }
139
140 /**
141 * @author Vova Feldman (@svovaf)
142 * @since 1.1.7
143 */
144 function has_trial() {
145 return ! is_null( $this->trial_ends );
146 }
147 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.3
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_User extends FS_Scope_Entity {
14
15 #region Properties
16
17 /**
18 * @var string
19 */
20 public $email;
21 /**
22 * @var string
23 */
24 public $first;
25 /**
26 * @var string
27 */
28 public $last;
29 /**
30 * @var bool
31 */
32 public $is_verified;
33 /**
34 * @var string|null
35 */
36 public $customer_id;
37 /**
38 * @var float
39 */
40 public $gross;
41
42 #endregion Properties
43
44 /**
45 * @param object|bool $user
46 */
47 function __construct( $user = false ) {
48 parent::__construct( $user );
49 }
50
51 function get_name() {
52 return trim( ucfirst( trim( is_string( $this->first ) ? $this->first : '' ) ) . ' ' . ucfirst( trim( is_string( $this->last ) ? $this->last : '' ) ) );
53 }
54
55 function is_verified() {
56 return ( isset( $this->is_verified ) && true === $this->is_verified );
57 }
58
59 /**
60 * @author Leo Fajardo (@leorw)
61 * @since 2.4.2
62 *
63 * @return bool
64 */
65 function is_beta() {
66 // Return `false` since this is just for backward compatibility.
67 return false;
68 }
69
70 static function get_type() {
71 return 'user';
72 }
73 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
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.2.1.6
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Retrieve the translation of $text.
15 *
16 * @since 1.2.1.6
17 *
18 * @param string $text
19 *
20 * @return string
21 */
22 function _fs_text( $text ) {
23 // Avoid misleading Theme Check warning.
24 $fn = 'translate';
25 return $fn( $text, 'freemius' );
26 }
27
28 /**
29 * Retrieve translated string with gettext context.
30 *
31 * Quite a few times, there will be collisions with similar translatable text
32 * found in more than two places, but with different translated context.
33 *
34 * By including the context in the pot file, translators can translate the two
35 * strings differently.
36 *
37 * @since 1.2.1.6
38 *
39 * @param string $text
40 * @param string $context
41 *
42 * @return string
43 */
44 function _fs_x( $text, $context ) {
45 // Avoid misleading Theme Check warning.
46 $fn = 'translate_with_gettext_context';
47 return $fn( $text, $context, 'freemius' );
48 }
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.6
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Cache_Manager {
14 /**
15 * @var FS_Option_Manager
16 */
17 private $_options;
18 /**
19 * @var FS_Logger
20 */
21 private $_logger;
22
23 /**
24 * @var FS_Cache_Manager[]
25 */
26 private static $_MANAGERS = array();
27
28 /**
29 * @author Vova Feldman (@svovaf)
30 * @since 1.1.3
31 *
32 * @param string $id
33 */
34 private function __construct( $id ) {
35 $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_cach_mngr_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
36
37 $this->_logger->entrance();
38 $this->_logger->log( 'id = ' . $id );
39
40 $this->_options = FS_Option_Manager::get_manager( $id, true, true, false );
41 }
42
43 /**
44 * @author Vova Feldman (@svovaf)
45 * @since 1.1.6
46 *
47 * @param $id
48 *
49 * @return FS_Cache_Manager
50 */
51 static function get_manager( $id ) {
52 $id = strtolower( $id );
53
54 if ( ! isset( self::$_MANAGERS[ $id ] ) ) {
55 self::$_MANAGERS[ $id ] = new FS_Cache_Manager( $id );
56 }
57
58 return self::$_MANAGERS[ $id ];
59 }
60
61 /**
62 * @author Vova Feldman (@svovaf)
63 * @since 1.1.6
64 *
65 * @return bool
66 */
67 function is_empty() {
68 $this->_logger->entrance();
69
70 return $this->_options->is_empty();
71 }
72
73 /**
74 * @author Vova Feldman (@svovaf)
75 * @since 1.1.6
76 */
77 function clear() {
78 $this->_logger->entrance();
79
80 $this->_options->clear( true );
81 }
82
83 /**
84 * Delete cache manager from DB.
85 *
86 * @author Vova Feldman (@svovaf)
87 * @since 1.0.9
88 */
89 function delete() {
90 $this->_options->delete();
91 }
92
93 /**
94 * Check if there's a cached item.
95 *
96 * @author Vova Feldman (@svovaf)
97 * @since 1.1.6
98 *
99 * @param string $key
100 *
101 * @return bool
102 */
103 function has( $key ) {
104 $cache_entry = $this->_options->get_option( $key, false );
105
106 return ( is_object( $cache_entry ) &&
107 isset( $cache_entry->timestamp ) &&
108 is_numeric( $cache_entry->timestamp )
109 );
110 }
111
112 /**
113 * Check if there's a valid cached item.
114 *
115 * @author Vova Feldman (@svovaf)
116 * @since 1.1.6
117 *
118 * @param string $key
119 * @param null|int $expiration Since 1.2.2.7
120 *
121 * @return bool
122 */
123 function has_valid( $key, $expiration = null ) {
124 $cache_entry = $this->_options->get_option( $key, false );
125
126 $is_valid = ( is_object( $cache_entry ) &&
127 isset( $cache_entry->timestamp ) &&
128 is_numeric( $cache_entry->timestamp ) &&
129 $cache_entry->timestamp > WP_FS__SCRIPT_START_TIME
130 );
131
132 if ( $is_valid &&
133 is_numeric( $expiration ) &&
134 isset( $cache_entry->created ) &&
135 is_numeric( $cache_entry->created ) &&
136 $cache_entry->created + $expiration < WP_FS__SCRIPT_START_TIME
137 ) {
138 /**
139 * Even if the cache is still valid, since we are checking for validity
140 * with an explicit expiration period, if the period has past, return
141 * `false` as if the cache is invalid.
142 *
143 * @since 1.2.2.7
144 */
145 $is_valid = false;
146 }
147
148 return $is_valid;
149 }
150
151 /**
152 * @author Vova Feldman (@svovaf)
153 * @since 1.1.6
154 *
155 * @param string $key
156 * @param mixed $default
157 *
158 * @return mixed
159 */
160 function get( $key, $default = null ) {
161 $this->_logger->entrance( 'key = ' . $key );
162
163 $cache_entry = $this->_options->get_option( $key, false );
164
165 if ( is_object( $cache_entry ) &&
166 isset( $cache_entry->timestamp ) &&
167 is_numeric( $cache_entry->timestamp )
168 ) {
169 return $cache_entry->result;
170 }
171
172 return is_object( $default ) ? clone $default : $default;
173 }
174
175 /**
176 * @author Vova Feldman (@svovaf)
177 * @since 1.1.6
178 *
179 * @param string $key
180 * @param mixed $default
181 *
182 * @return mixed
183 */
184 function get_valid( $key, $default = null ) {
185 $this->_logger->entrance( 'key = ' . $key );
186
187 $cache_entry = $this->_options->get_option( $key, false );
188
189 if ( is_object( $cache_entry ) &&
190 isset( $cache_entry->timestamp ) &&
191 is_numeric( $cache_entry->timestamp ) &&
192 $cache_entry->timestamp > WP_FS__SCRIPT_START_TIME
193 ) {
194 return $cache_entry->result;
195 }
196
197 return is_object( $default ) ? clone $default : $default;
198 }
199
200 /**
201 * @author Vova Feldman (@svovaf)
202 * @since 1.1.6
203 *
204 * @param string $key
205 * @param mixed $value
206 * @param int $expiration
207 * @param int $created Since 2.0.0 Cache creation date.
208 */
209 function set( $key, $value, $expiration = WP_FS__TIME_24_HOURS_IN_SEC, $created = WP_FS__SCRIPT_START_TIME ) {
210 $this->_logger->entrance( 'key = ' . $key );
211
212 $cache_entry = new stdClass();
213
214 $cache_entry->result = $value;
215 $cache_entry->created = $created;
216 $cache_entry->timestamp = $created + $expiration;
217 $this->_options->set_option( $key, $cache_entry, true );
218 }
219
220 /**
221 * Get cached record expiration, or false if not cached or expired.
222 *
223 * @author Vova Feldman (@svovaf)
224 * @since 1.1.7.3
225 *
226 * @param string $key
227 *
228 * @return bool|int
229 */
230 function get_record_expiration( $key ) {
231 $this->_logger->entrance( 'key = ' . $key );
232
233 $cache_entry = $this->_options->get_option( $key, false );
234
235 if ( is_object( $cache_entry ) &&
236 isset( $cache_entry->timestamp ) &&
237 is_numeric( $cache_entry->timestamp ) &&
238 $cache_entry->timestamp > WP_FS__SCRIPT_START_TIME
239 ) {
240 return $cache_entry->timestamp;
241 }
242
243 return false;
244 }
245
246 /**
247 * Purge cached item.
248 *
249 * @author Vova Feldman (@svovaf)
250 * @since 1.1.6
251 *
252 * @param string $key
253 */
254 function purge( $key ) {
255 $this->_logger->entrance( 'key = ' . $key );
256
257 $this->_options->unset_option( $key, true );
258 }
259
260 /**
261 * Extend cached item caching period.
262 *
263 * @author Vova Feldman (@svovaf)
264 * @since 2.0.0
265 *
266 * @param string $key
267 * @param int $expiration
268 *
269 * @return bool
270 */
271 function update_expiration( $key, $expiration = WP_FS__TIME_24_HOURS_IN_SEC ) {
272 $this->_logger->entrance( 'key = ' . $key );
273
274 $cache_entry = $this->_options->get_option( $key, false );
275
276 if ( ! is_object( $cache_entry ) ||
277 ! isset( $cache_entry->timestamp ) ||
278 ! is_numeric( $cache_entry->timestamp )
279 ) {
280 return false;
281 }
282
283 $this->set( $key, $cache_entry->result, $expiration, $cache_entry->created );
284
285 return true;
286 }
287
288 /**
289 * Set cached item as expired.
290 *
291 * @author Vova Feldman (@svovaf)
292 * @since 1.2.2.7
293 *
294 * @param string $key
295 */
296 function expire( $key ) {
297 $this->_logger->entrance( 'key = ' . $key );
298
299 $cache_entry = $this->_options->get_option( $key, false );
300
301 if ( is_object( $cache_entry ) &&
302 isset( $cache_entry->timestamp ) &&
303 is_numeric( $cache_entry->timestamp )
304 ) {
305 // Set to expired.
306 $cache_entry->timestamp = WP_FS__SCRIPT_START_TIME;
307 $this->_options->set_option( $key, $cache_entry, true );
308 }
309 }
310
311 #--------------------------------------------------------------------------------
312 #region Migration
313 #--------------------------------------------------------------------------------
314
315 /**
316 * Migrate options from site level.
317 *
318 * @author Vova Feldman (@svovaf)
319 * @since 2.0.0
320 */
321 function migrate_to_network() {
322 $this->_options->migrate_to_network();
323 }
324
325 #endregion
326 }
...\ No newline at end of file ...\ No newline at end of file
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 2.1.0
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_GDPR_Manager {
14 /**
15 * @var FS_Option_Manager
16 */
17 private $_storage;
18 /**
19 * @var array {
20 * @type bool $required Are GDPR rules apply on the current context admin.
21 * @type bool $show_opt_in_notice Should the marketing and offers opt-in message be shown to the admin or not. If not set, defaults to `true`.
22 * @type int $notice_shown_at Last time the special GDPR opt-in message was shown to the current admin.
23 * }
24 */
25 private $_data;
26 /**
27 * @var int
28 */
29 private $_wp_user_id;
30 /**
31 * @var string
32 */
33 private $_option_name;
34 /**
35 * @var FS_Admin_Notices
36 */
37 private $_notices;
38
39 #--------------------------------------------------------------------------------
40 #region Singleton
41 #--------------------------------------------------------------------------------
42
43 /**
44 * @var FS_GDPR_Manager
45 */
46 private static $_instance;
47
48 /**
49 * @return FS_GDPR_Manager
50 */
51 public static function instance() {
52 if ( ! isset( self::$_instance ) ) {
53 self::$_instance = new self();
54 }
55
56 return self::$_instance;
57 }
58
59 #endregion
60
61 private function __construct() {
62 $this->_storage = FS_Option_Manager::get_manager( WP_FS__GDPR_OPTION_NAME, true, true );
63 $this->_wp_user_id = Freemius::get_current_wp_user_id();
64 $this->_option_name = "u{$this->_wp_user_id}";
65 $this->_data = $this->_storage->get_option( $this->_option_name, array() );
66 $this->_notices = FS_Admin_Notices::instance( 'all_admins', '', '', true );
67
68 if ( ! is_array( $this->_data ) ) {
69 $this->_data = array();
70 }
71 }
72
73 /**
74 * Update a GDPR option for the current admin and store it.
75 *
76 * @author Vova Feldman (@svovaf)
77 * @since 2.1.0
78 *
79 * @param string $name
80 * @param mixed $value
81 */
82 private function update_option( $name, $value ) {
83 $this->_data[ $name ] = $value;
84
85 $this->_storage->set_option( $this->_option_name, $this->_data, true );
86 }
87
88 /**
89 * @author Leo Fajardo (@leorw)
90 * @since 2.1.0
91 *
92 * @param bool $is_required
93 */
94 public function store_is_required( $is_required ) {
95 $this->update_option( 'required', $is_required );
96 }
97
98 /**
99 * Checks if the GDPR opt-in sticky notice is currently shown.
100 *
101 * @author Vova Feldman (@svovaf)
102 * @since 2.1.0
103 *
104 * @return bool
105 */
106 public function is_opt_in_notice_shown() {
107 return $this->_notices->has_sticky( "gdpr_optin_actions_{$this->_wp_user_id}", true );
108 }
109
110 /**
111 * Remove the GDPR opt-in sticky notice.
112 *
113 * @author Vova Feldman (@svovaf)
114 * @since 2.1.0
115 */
116 public function remove_opt_in_notice() {
117 $this->_notices->remove_sticky( "gdpr_optin_actions_{$this->_wp_user_id}", true );
118
119 $this->disable_opt_in_notice();
120 }
121
122 /**
123 * Prevents the opt-in message from being added/shown.
124 *
125 * @author Leo Fajardo (@leorw)
126 * @since 2.1.0
127 */
128 public function disable_opt_in_notice() {
129 $this->update_option( 'show_opt_in_notice', false );
130 }
131
132 /**
133 * Checks if a GDPR opt-in message needs to be shown to the current admin.
134 *
135 * @author Vova Feldman (@svovaf)
136 * @since 2.1.0
137 *
138 * @return bool
139 */
140 public function should_show_opt_in_notice() {
141 return (
142 ! isset( $this->_data['show_opt_in_notice'] ) ||
143 true === $this->_data['show_opt_in_notice']
144 );
145 }
146
147 /**
148 * Get the last time the GDPR opt-in notice was shown.
149 *
150 * @author Vova Feldman (@svovaf)
151 * @since 2.1.0
152 *
153 * @return false|int
154 */
155 public function last_time_notice_was_shown() {
156 return isset( $this->_data['notice_shown_at'] ) ?
157 $this->_data['notice_shown_at'] :
158 false;
159 }
160
161 /**
162 * Update the timestamp of the last time the GDPR opt-in message was shown to now.
163 *
164 * @author Vova Feldman (@svovaf)
165 * @since 2.1.0
166 */
167 public function notice_was_just_shown() {
168 $this->update_option( 'notice_shown_at', WP_FS__SCRIPT_START_TIME );
169 }
170
171 /**
172 * @param string $message
173 * @param string|null $plugin_title
174 *
175 * @author Vova Feldman (@svovaf)
176 * @since 2.1.0
177 */
178 public function add_opt_in_sticky_notice( $message, $plugin_title = null ) {
179 $this->_notices->add_sticky(
180 $message,
181 "gdpr_optin_actions_{$this->_wp_user_id}",
182 '',
183 'promotion',
184 true,
185 $this->_wp_user_id,
186 $plugin_title,
187 true
188 );
189 }
190 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.6
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_License_Manager /*extends FS_Abstract_Manager*/
14 {
15 //
16 //
17 // /**
18 // * @var FS_License_Manager[]
19 // */
20 // private static $_instances = array();
21 //
22 // static function instance( Freemius $fs ) {
23 // $slug = strtolower( $fs->get_slug() );
24 //
25 // if ( ! isset( self::$_instances[ $slug ] ) ) {
26 // self::$_instances[ $slug ] = new FS_License_Manager( $slug, $fs );
27 // }
28 //
29 // return self::$_instances[ $slug ];
30 // }
31 //
32 //// private function __construct($slug) {
33 //// parent::__construct($slug);
34 //// }
35 //
36 // function entry_id() {
37 // return 'licenses';
38 // }
39 //
40 // function sync( $id ) {
41 //
42 // }
43 //
44 // /**
45 // * @author Vova Feldman (@svovaf)
46 // * @since 1.0.5
47 // * @uses FS_Api
48 // *
49 // * @param number|bool $plugin_id
50 // *
51 // * @return FS_Plugin_License[]|stdClass Licenses or API error.
52 // */
53 // function api_get_user_plugin_licenses( $plugin_id = false ) {
54 // $api = $this->_fs->get_api_user_scope();
55 //
56 // if ( ! is_numeric( $plugin_id ) ) {
57 // $plugin_id = $this->_fs->get_id();
58 // }
59 //
60 // $result = $api->call( "/plugins/{$plugin_id}/licenses.json" );
61 //
62 // if ( ! isset( $result->error ) ) {
63 // for ( $i = 0, $len = count( $result->licenses ); $i < $len; $i ++ ) {
64 // $result->licenses[ $i ] = new FS_Plugin_License( $result->licenses[ $i ] );
65 // }
66 //
67 // $result = $result->licenses;
68 // }
69 //
70 // return $result;
71 // }
72 //
73 // function api_get_many() {
74 //
75 // }
76 //
77 // function api_activate( $id ) {
78 //
79 // }
80 //
81 // function api_deactivate( $id ) {
82 //
83 // }
84
85 /**
86 * @param FS_Plugin_License[] $licenses
87 *
88 * @return bool
89 */
90 static function has_premium_license( $licenses ) {
91 if ( is_array( $licenses ) ) {
92 foreach ( $licenses as $license ) {
93 /**
94 * @var FS_Plugin_License $license
95 */
96 if ( ! $license->is_utilized() && $license->is_features_enabled() ) {
97 return true;
98 }
99 }
100 }
101
102 return false;
103 }
104 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.6
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Plan_Manager {
14 /**
15 * @var FS_Plan_Manager
16 */
17 private static $_instance;
18
19 /**
20 * @return FS_Plan_Manager
21 */
22 static function instance() {
23 if ( ! isset( self::$_instance ) ) {
24 self::$_instance = new FS_Plan_Manager();
25 }
26
27 return self::$_instance;
28 }
29
30 private function __construct() {
31 }
32
33 /**
34 * @param FS_Plugin_License[] $licenses
35 *
36 * @return bool
37 */
38 function has_premium_license( $licenses ) {
39 if ( is_array( $licenses ) ) {
40 /**
41 * @var FS_Plugin_License[] $licenses
42 */
43 foreach ( $licenses as $license ) {
44 if ( ! $license->is_utilized() && $license->is_features_enabled() ) {
45 return true;
46 }
47 }
48 }
49
50 return false;
51 }
52
53 /**
54 * Check if plugin has any paid plans.
55 *
56 * @author Vova Feldman (@svovaf)
57 * @since 1.0.7
58 *
59 * @param FS_Plugin_Plan[] $plans
60 *
61 * @return bool
62 */
63 function has_paid_plan( $plans ) {
64 if ( ! is_array( $plans ) || 0 === count( $plans ) ) {
65 return false;
66 }
67
68 /**
69 * @var FS_Plugin_Plan[] $plans
70 */
71 for ( $i = 0, $len = count( $plans ); $i < $len; $i ++ ) {
72 if ( ! $plans[ $i ]->is_free() ) {
73 return true;
74 }
75 }
76
77 return false;
78 }
79
80 /**
81 * Check if plugin has any free plan, or is it premium only.
82 *
83 * Note: If no plans configured, assume plugin is free.
84 *
85 * @author Vova Feldman (@svovaf)
86 * @since 1.0.7
87 *
88 * @param FS_Plugin_Plan[] $plans
89 *
90 * @return bool
91 */
92 function has_free_plan( $plans ) {
93 if ( ! is_array( $plans ) || 0 === count( $plans ) ) {
94 return true;
95 }
96
97 /**
98 * @var FS_Plugin_Plan[] $plans
99 */
100 for ( $i = 0, $len = count( $plans ); $i < $len; $i ++ ) {
101 if ( $plans[ $i ]->is_free() ) {
102 return true;
103 }
104 }
105
106 return false;
107 }
108
109 /**
110 * Find all plans that have trial.
111 *
112 * @author Vova Feldman (@svovaf)
113 * @since 1.0.9
114 *
115 * @param FS_Plugin_Plan[] $plans
116 *
117 * @return FS_Plugin_Plan[]
118 */
119 function get_trial_plans( $plans ) {
120 $trial_plans = array();
121
122 if ( is_array( $plans ) && 0 < count( $plans ) ) {
123 /**
124 * @var FS_Plugin_Plan[] $plans
125 */
126 for ( $i = 0, $len = count( $plans ); $i < $len; $i ++ ) {
127 if ( $plans[ $i ]->has_trial() ) {
128 $trial_plans[] = $plans[ $i ];
129 }
130 }
131 }
132
133 return $trial_plans;
134 }
135
136 /**
137 * Check if plugin has any trial plan.
138 *
139 * @author Vova Feldman (@svovaf)
140 * @since 1.0.9
141 *
142 * @param FS_Plugin_Plan[] $plans
143 *
144 * @return bool
145 */
146 function has_trial_plan( $plans ) {
147 if ( ! is_array( $plans ) || 0 === count( $plans ) ) {
148 return true;
149 }
150
151 /**
152 * @var FS_Plugin_Plan[] $plans
153 */
154 for ( $i = 0, $len = count( $plans ); $i < $len; $i ++ ) {
155 if ( $plans[ $i ]->has_trial() ) {
156 return true;
157 }
158 }
159
160 return false;
161 }
162 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.6
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Plugin_Manager {
14 /**
15 * @since 1.2.2
16 *
17 * @var string|number
18 */
19 protected $_module_id;
20 /**
21 * @since 1.2.2
22 *
23 * @var FS_Plugin
24 */
25 protected $_module;
26
27 /**
28 * @var FS_Plugin_Manager[]
29 */
30 private static $_instances = array();
31 /**
32 * @var FS_Logger
33 */
34 protected $_logger;
35
36 /**
37 * Option names
38 *
39 * @author Leo Fajardo (@leorw)
40 * @since 1.2.2
41 */
42 const OPTION_NAME_PLUGINS = 'plugins';
43 const OPTION_NAME_THEMES = 'themes';
44
45 /**
46 * @param string|number $module_id
47 *
48 * @return FS_Plugin_Manager
49 */
50 static function instance( $module_id ) {
51 $key = 'm_' . $module_id;
52
53 if ( ! isset( self::$_instances[ $key ] ) ) {
54 self::$_instances[ $key ] = new FS_Plugin_Manager( $module_id );
55 }
56
57 return self::$_instances[ $key ];
58 }
59
60 /**
61 * @param string|number $module_id
62 */
63 protected function __construct( $module_id ) {
64 $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $module_id . '_' . 'plugins', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
65 $this->_module_id = $module_id;
66
67 $this->load();
68 }
69
70 protected function get_option_manager() {
71 return FS_Option_Manager::get_manager( WP_FS__ACCOUNTS_OPTION_NAME, true, true );
72 }
73
74 /**
75 * @author Leo Fajardo (@leorw)
76 * @since 1.2.2
77 *
78 * @param string|bool $module_type "plugin", "theme", or "false" for all modules.
79 *
80 * @return array
81 */
82 protected function get_all_modules( $module_type = false ) {
83 $option_manager = $this->get_option_manager();
84
85 if ( false !== $module_type ) {
86 return fs_get_entities( $option_manager->get_option( $module_type . 's', array() ), FS_Plugin::get_class_name() );
87 }
88
89 return array(
90 self::OPTION_NAME_PLUGINS => fs_get_entities( $option_manager->get_option( self::OPTION_NAME_PLUGINS, array() ), FS_Plugin::get_class_name() ),
91 self::OPTION_NAME_THEMES => fs_get_entities( $option_manager->get_option( self::OPTION_NAME_THEMES, array() ), FS_Plugin::get_class_name() ),
92 );
93 }
94
95 /**
96 * Load plugin data from local DB.
97 *
98 * @author Vova Feldman (@svovaf)
99 * @since 1.0.6
100 */
101 function load() {
102 $all_modules = $this->get_all_modules();
103
104 if ( ! is_numeric( $this->_module_id ) ) {
105 unset( $all_modules[ self::OPTION_NAME_THEMES ] );
106 }
107
108 foreach ( $all_modules as $modules ) {
109 /**
110 * @since 1.2.2
111 *
112 * @var $modules FS_Plugin[]
113 */
114 foreach ( $modules as $module ) {
115 $found_module = false;
116
117 /**
118 * If module ID is not numeric, it must be a plugin's slug.
119 *
120 * @author Leo Fajardo (@leorw)
121 * @since 1.2.2
122 */
123 if ( ! is_numeric( $this->_module_id ) ) {
124 if ( $this->_module_id === $module->slug ) {
125 $this->_module_id = $module->id;
126 $found_module = true;
127 }
128 } else if ( $this->_module_id == $module->id ) {
129 $found_module = true;
130 }
131
132 if ( $found_module ) {
133 $this->_module = $module;
134 break;
135 }
136 }
137 }
138 }
139
140 /**
141 * Store plugin on local DB.
142 *
143 * @author Vova Feldman (@svovaf)
144 * @since 1.0.6
145 *
146 * @param bool|FS_Plugin $module
147 * @param bool $flush
148 *
149 * @return bool|\FS_Plugin
150 */
151 function store( $module = false, $flush = true ) {
152 if ( false !== $module ) {
153 $this->_module = $module;
154 }
155
156 $all_modules = $this->get_all_modules( $this->_module->type );
157 $all_modules[ $this->_module->slug ] = $this->_module;
158
159 $options_manager = $this->get_option_manager();
160 $options_manager->set_option( $this->_module->type . 's', $all_modules, $flush );
161
162 return $this->_module;
163 }
164
165 /**
166 * Update local plugin data if different.
167 *
168 * @author Vova Feldman (@svovaf)
169 * @since 1.0.6
170 *
171 * @param \FS_Plugin $plugin
172 * @param bool $store
173 *
174 * @return bool True if plugin was updated.
175 */
176 function update( FS_Plugin $plugin, $store = true ) {
177 if ( ! ($this->_module instanceof FS_Plugin ) ||
178 $this->_module->slug != $plugin->slug ||
179 $this->_module->public_key != $plugin->public_key ||
180 $this->_module->secret_key != $plugin->secret_key ||
181 $this->_module->parent_plugin_id != $plugin->parent_plugin_id ||
182 $this->_module->title != $plugin->title
183 ) {
184 $this->store( $plugin, $store );
185
186 return true;
187 }
188
189 return false;
190 }
191
192 /**
193 * @author Vova Feldman (@svovaf)
194 * @since 1.0.6
195 *
196 * @param FS_Plugin $plugin
197 * @param bool $store
198 */
199 function set( FS_Plugin $plugin, $store = false ) {
200 $this->_module = $plugin;
201
202 if ( $store ) {
203 $this->store();
204 }
205 }
206
207 /**
208 * @author Vova Feldman (@svovaf)
209 * @since 1.0.6
210 *
211 * @return bool|\FS_Plugin
212 */
213 function get() {
214 if ( isset( $this->_module ) ) {
215 return $this->_module;
216 }
217
218 if ( empty( $this->_module_id ) ) {
219 return false;
220 }
221
222 /**
223 * Return an FS_Plugin entity that has its `id` and `is_live` properties set (`is_live` is initialized in the FS_Plugin constructor) to avoid triggering an error that is relevant to these properties when the FS_Plugin entity is used before the `parse_settings()` method is called. This can happen when creating a regular WordPress site by cloning a subsite of a multisite network and the data that is stored in the network-level storage is not cloned.
224 *
225 * @author Leo Fajardo (@leorw)
226 * @since 2.5.0
227 */
228 $plugin = new FS_Plugin();
229 $plugin->id = $this->_module_id;
230
231 return $plugin;
232 }
233 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
7 exit;
8 }
9
10 if ( ! class_exists( 'Freemius_ArgumentNotExistException' ) ) {
11 class Freemius_ArgumentNotExistException extends Freemius_InvalidArgumentException {
12 }
13 }
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
7 exit;
8 }
9
10 if ( ! class_exists( 'Freemius_EmptyArgumentException' ) ) {
11 class Freemius_EmptyArgumentException extends Freemius_InvalidArgumentException {
12 }
13 }
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 if ( ! class_exists( 'Freemius_Exception' ) ) {
7 /**
8 * Thrown when an API call returns an exception.
9 *
10 */
11 class Freemius_Exception extends Exception {
12 protected $_result;
13 protected $_type;
14 protected $_code;
15
16 /**
17 * Make a new API Exception with the given result.
18 *
19 * @param array $result The result from the API server.
20 */
21 public function __construct( $result ) {
22 $this->_result = $result;
23
24 $code = 0;
25 $message = 'Unknown error, please check GetResult().';
26 $type = '';
27
28 if ( isset( $result['error'] ) && is_array( $result['error'] ) ) {
29 if ( isset( $result['error']['code'] ) ) {
30 $code = $result['error']['code'];
31 }
32 if ( isset( $result['error']['message'] ) ) {
33 $message = $result['error']['message'];
34 }
35 if ( isset( $result['error']['type'] ) ) {
36 $type = $result['error']['type'];
37 }
38 }
39
40 $this->_type = $type;
41 $this->_code = $code;
42
43 parent::__construct( $message, is_numeric( $code ) ? $code : 0 );
44 }
45
46 /**
47 * Return the associated result object returned by the API server.
48 *
49 * @return array The result from the API server
50 */
51 public function getResult() {
52 return $this->_result;
53 }
54
55 public function getStringCode() {
56 return $this->_code;
57 }
58
59 public function getType() {
60 return $this->_type;
61 }
62
63 /**
64 * To make debugging easier.
65 *
66 * @return string The string representation of the error
67 */
68 public function __toString() {
69 $str = $this->getType() . ': ';
70
71 if ( $this->code != 0 ) {
72 $str .= $this->getStringCode() . ': ';
73 }
74
75 return $str . $this->getMessage();
76 }
77 }
78 }
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 if ( ! class_exists( 'Freemius_Exception' ) ) {
7 exit;
8 }
9
10 if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
11 class Freemius_InvalidArgumentException extends Freemius_Exception { }
12 }
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 if ( ! class_exists( 'Freemius_Exception' ) ) {
7 exit;
8 }
9
10 if ( ! class_exists( 'Freemius_OAuthException' ) ) {
11 class Freemius_OAuthException extends Freemius_Exception {
12 public function __construct( $pResult ) {
13 parent::__construct( $pResult );
14 }
15 }
16 }
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * Copyright 2014 Freemius, Inc.
4 *
5 * Licensed under the GPL v2 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at
8 *
9 * http://choosealicense.com/licenses/gpl-v2/
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations
15 * under the License.
16 */
17
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit;
20 }
21
22 if ( ! defined( 'FS_API__VERSION' ) ) {
23 define( 'FS_API__VERSION', '1' );
24 }
25 if ( ! defined( 'FS_SDK__PATH' ) ) {
26 define( 'FS_SDK__PATH', dirname( __FILE__ ) );
27 }
28 if ( ! defined( 'FS_SDK__EXCEPTIONS_PATH' ) ) {
29 define( 'FS_SDK__EXCEPTIONS_PATH', FS_SDK__PATH . '/Exceptions/' );
30 }
31
32 if ( ! function_exists( 'json_decode' ) ) {
33 throw new Exception( 'Freemius needs the JSON PHP extension.' );
34 }
35
36 // Include all exception files.
37 $exceptions = array(
38 'Exception',
39 'InvalidArgumentException',
40 'ArgumentNotExistException',
41 'EmptyArgumentException',
42 'OAuthException'
43 );
44
45 foreach ( $exceptions as $e ) {
46 require_once FS_SDK__EXCEPTIONS_PATH . $e . '.php';
47 }
48
49 if ( ! class_exists( 'Freemius_Api_Base' ) ) {
50 abstract class Freemius_Api_Base {
51 const VERSION = '1.0.4';
52 const FORMAT = 'json';
53
54 protected $_id;
55 protected $_public;
56 protected $_secret;
57 protected $_scope;
58 protected $_isSandbox;
59
60 /**
61 * @param string $pScope 'app', 'developer', 'plugin', 'user' or 'install'.
62 * @param number $pID Element's id.
63 * @param string $pPublic Public key.
64 * @param string $pSecret Element's secret key.
65 * @param bool $pIsSandbox Whether or not to run API in sandbox mode.
66 */
67 public function Init( $pScope, $pID, $pPublic, $pSecret, $pIsSandbox = false ) {
68 $this->_id = $pID;
69 $this->_public = $pPublic;
70 $this->_secret = $pSecret;
71 $this->_scope = $pScope;
72 $this->_isSandbox = $pIsSandbox;
73 }
74
75 public function IsSandbox() {
76 return $this->_isSandbox;
77 }
78
79 function CanonizePath( $pPath ) {
80 $pPath = trim( $pPath, '/' );
81 $query_pos = strpos( $pPath, '?' );
82 $query = '';
83
84 if ( false !== $query_pos ) {
85 $query = substr( $pPath, $query_pos );
86 $pPath = substr( $pPath, 0, $query_pos );
87 }
88
89 // Trim '.json' suffix.
90 $format_length = strlen( '.' . self::FORMAT );
91 $start = $format_length * ( - 1 ); //negative
92 if ( substr( strtolower( $pPath ), $start ) === ( '.' . self::FORMAT ) ) {
93 $pPath = substr( $pPath, 0, strlen( $pPath ) - $format_length );
94 }
95
96 switch ( $this->_scope ) {
97 case 'app':
98 $base = '/apps/' . $this->_id;
99 break;
100 case 'developer':
101 $base = '/developers/' . $this->_id;
102 break;
103 case 'user':
104 $base = '/users/' . $this->_id;
105 break;
106 case 'plugin':
107 $base = '/plugins/' . $this->_id;
108 break;
109 case 'install':
110 $base = '/installs/' . $this->_id;
111 break;
112 default:
113 throw new Freemius_Exception( 'Scope not implemented.' );
114 }
115
116 return '/v' . FS_API__VERSION . $base .
117 ( ! empty( $pPath ) ? '/' : '' ) . $pPath .
118 ( ( false === strpos( $pPath, '.' ) ) ? '.' . self::FORMAT : '' ) . $query;
119 }
120
121 abstract function MakeRequest( $pCanonizedPath, $pMethod = 'GET', $pParams = array() );
122
123 /**
124 * @param string $pPath
125 * @param string $pMethod
126 * @param array $pParams
127 *
128 * @return object[]|object|null
129 */
130 private function _Api( $pPath, $pMethod = 'GET', $pParams = array() ) {
131 $pMethod = strtoupper( $pMethod );
132
133 try {
134 $result = $this->MakeRequest( $pPath, $pMethod, $pParams );
135 } catch ( Freemius_Exception $e ) {
136 // Map to error object.
137 $result = (object) $e->getResult();
138 } catch ( Exception $e ) {
139 // Map to error object.
140 $result = (object) array(
141 'error' => (object) array(
142 'type' => 'Unknown',
143 'message' => $e->getMessage() . ' (' . $e->getFile() . ': ' . $e->getLine() . ')',
144 'code' => 'unknown',
145 'http' => 402
146 )
147 );
148 }
149
150 return $result;
151 }
152
153 public function Api( $pPath, $pMethod = 'GET', $pParams = array() ) {
154 return $this->_Api( $this->CanonizePath( $pPath ), $pMethod, $pParams );
155 }
156
157 /**
158 * Base64 decoding that does not need to be urldecode()-ed.
159 *
160 * Exactly the same as PHP base64 encode except it uses
161 * `-` instead of `+`
162 * `_` instead of `/`
163 * No padded =
164 *
165 * @param string $input Base64UrlEncoded() string
166 *
167 * @return string
168 */
169 protected static function Base64UrlDecode( $input ) {
170 /**
171 * IMPORTANT NOTE:
172 * This is a hack suggested by @otto42 and @greenshady from
173 * the theme's review team. The usage of base64 for API
174 * signature encoding was approved in a Slack meeting
175 * held on Tue (10/25 2016).
176 *
177 * @todo Remove this hack once the base64 error is removed from the Theme Check.
178 *
179 * @since 1.2.2
180 * @author Vova Feldman (@svovaf)
181 */
182 $fn = 'base64' . '_decode';
183 return $fn( strtr( $input, '-_', '+/' ) );
184 }
185
186 /**
187 * Base64 encoding that does not need to be urlencode()ed.
188 *
189 * Exactly the same as base64 encode except it uses
190 * `-` instead of `+
191 * `_` instead of `/`
192 *
193 * @param string $input string
194 *
195 * @return string Base64 encoded string
196 */
197 protected static function Base64UrlEncode( $input ) {
198 /**
199 * IMPORTANT NOTE:
200 * This is a hack suggested by @otto42 and @greenshady from
201 * the theme's review team. The usage of base64 for API
202 * signature encoding was approved in a Slack meeting
203 * held on Tue (10/25 2016).
204 *
205 * @todo Remove this hack once the base64 error is removed from the Theme Check.
206 *
207 * @since 1.2.2
208 * @author Vova Feldman (@svovaf)
209 */
210 $fn = 'base64' . '_encode';
211 $str = strtr( $fn( $input ), '+/', '-_' );
212 $str = str_replace( '=', '', $str );
213
214 return $str;
215 }
216 }
217 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
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.7
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Find the plugin main file path based on any given file inside the plugin's folder.
15 *
16 * @author Vova Feldman (@svovaf)
17 * @since 1.1.7.1
18 *
19 * @param string $file Absolute path to a file inside a plugin's folder.
20 *
21 * @return string
22 */
23 function fs_find_direct_caller_plugin_file( $file ) {
24 /**
25 * All the code below will be executed once on activation.
26 * If the user changes the main plugin's file name, the file_exists()
27 * will catch it.
28 */
29 $all_plugins = fs_get_plugins( true );
30
31 $file_real_path = fs_normalize_path( realpath( $file ) );
32
33 // Get active plugin's main files real full names (might be symlinks).
34 foreach ( $all_plugins as $relative_path => $data ) {
35 if ( 0 === strpos( $file_real_path, fs_normalize_path( dirname( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) ) . '/' ) ) ) {
36 if ( '.' !== dirname( trailingslashit( $relative_path ) ) ) {
37 return $relative_path;
38 }
39 }
40 }
41
42 return null;
43 }
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 2.2.1
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 if ( ! function_exists( 'fs_get_plugins' ) ) {
14 /**
15 * @author Leo Fajardo (@leorw)
16 * @since 2.2.1
17 *
18 * @param bool $delete_cache
19 *
20 * @return array
21 */
22 function fs_get_plugins( $delete_cache = false ) {
23 $cached_plugins = wp_cache_get( 'plugins', 'plugins' );
24 if ( ! is_array( $cached_plugins ) ) {
25 $cached_plugins = array();
26 }
27
28 $plugin_folder = '';
29 if ( isset( $cached_plugins[ $plugin_folder ] ) ) {
30 $plugins = $cached_plugins[ $plugin_folder ];
31 } else {
32 if ( ! function_exists( 'get_plugins' ) ) {
33 require_once ABSPATH . 'wp-admin/includes/plugin.php';
34 }
35
36 $plugins = get_plugins();
37
38 if ( $delete_cache && is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
39 wp_cache_delete( 'plugins', 'plugins' );
40 }
41 }
42
43 return $plugins;
44 }
45 }
...\ No newline at end of file ...\ No newline at end of file
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 2.5.1
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 if ( ! function_exists( 'fs_migrate_251' ) ) {
14 function fs_migrate_251( Freemius $fs, $install_by_blog_id ) {
15 $permission_manager = FS_Permission_Manager::instance( $fs );
16
17 /**
18 * @var FS_Site $install
19 */
20 foreach ( $install_by_blog_id as $blog_id => $install ) {
21 if ( true === $install->is_disconnected ) {
22 $permission_manager->update_site_tracking(
23 false,
24 ( 0 == $blog_id ) ? null : $blog_id,
25 // Update only if permissions are not yet set.
26 true
27 );
28 }
29 }
30 }
31 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 // Silence is golden.
3 // Hide file structure from users on unprotected servers.
...\ No newline at end of file ...\ No newline at end of file