├── includes ├── assets │ ├── scss │ │ ├── _functions.scss │ │ ├── _start.scss │ │ ├── _load.scss │ │ ├── index.php │ │ ├── admin │ │ │ ├── index.php │ │ │ ├── checkout.scss │ │ │ ├── _license-activation.scss │ │ │ ├── dialog-boxes.scss │ │ │ ├── _themes.scss │ │ │ ├── _auto-install.scss │ │ │ ├── _deactivation-feedback.scss │ │ │ ├── _ajax-loader.scss │ │ │ ├── _license-key-resend.scss │ │ │ ├── affiliation.scss │ │ │ ├── debug.scss │ │ │ ├── _modal-common.scss │ │ │ ├── account.scss │ │ │ └── common.scss │ │ ├── _vars.scss │ │ ├── _colors.scss │ │ └── customizer.scss │ ├── index.php │ ├── js │ │ ├── index.php │ │ ├── nojquery.ba-postmessage.min.js │ │ ├── postmessage.js │ │ └── nojquery.ba-postmessage.js │ ├── css │ │ ├── admin │ │ │ ├── checkout.css │ │ │ ├── index.php │ │ │ ├── license-activation.css │ │ │ ├── deactivation-feedback.css │ │ │ ├── affiliation.css │ │ │ ├── debug.css │ │ │ ├── common.css │ │ │ └── account.css │ │ ├── index.php │ │ └── customizer.css │ └── img │ │ ├── index.php │ │ ├── plugin-icon.png │ │ └── theme-icon.png ├── index.php ├── includes │ ├── index.php │ ├── debug │ │ ├── index.php │ │ ├── debug-bar-start.php │ │ └── class-fs-debug-bar-panel.php │ ├── sdk │ │ ├── index.php │ │ └── Exceptions │ │ │ ├── index.php │ │ │ ├── InvalidArgumentException.php │ │ │ ├── EmptyArgumentException.php │ │ │ ├── ArgumentNotExistException.php │ │ │ ├── OAuthException.php │ │ │ └── Exception.php │ ├── customizer │ │ ├── index.php │ │ ├── class-fs-customizer-support-section.php │ │ └── class-fs-customizer-upsell-control.php │ ├── entities │ │ ├── index.php │ │ ├── class-fs-plugin-tag.php │ │ ├── class-fs-scope-entity.php │ │ ├── class-fs-plugin-info.php │ │ ├── class-fs-user.php │ │ ├── class-fs-billing.php │ │ ├── class-fs-payment.php │ │ ├── class-fs-affiliate.php │ │ ├── class-fs-plugin.php │ │ ├── class-fs-subscription.php │ │ ├── class-fs-pricing.php │ │ ├── class-fs-site.php │ │ ├── class-fs-plugin-plan.php │ │ ├── class-fs-entity.php │ │ ├── class-fs-affiliate-terms.php │ │ └── class-fs-plugin-license.php │ ├── managers │ │ ├── index.php │ │ ├── class-fs-license-manager.php │ │ ├── class-fs-plan-manager.php │ │ └── class-fs-plugin-manager.php │ ├── supplements │ │ ├── index.php │ │ └── fs-essential-functions-1.1.7.1.php │ ├── l10n.php │ └── class-fs-security.php ├── languages │ ├── freemius-en.mo │ ├── index.php │ ├── freemius-da_DK.mo │ ├── freemius-es_ES.mo │ ├── freemius-he_IL.mo │ ├── freemius-it_IT.mo │ └── freemius-ja_JP.mo ├── templates │ ├── index.php │ ├── js │ │ ├── index.php │ │ ├── jquery.content-change.php │ │ └── style-premium-theme.php │ ├── account │ │ ├── index.php │ │ └── payments.php │ ├── debug │ │ ├── index.php │ │ ├── logger.php │ │ ├── plugins-themes-sync.php │ │ ├── scheduled-crons.php │ │ └── api-calls.php │ ├── forms │ │ ├── index.php │ │ └── deactivation │ │ │ ├── index.php │ │ │ ├── contact.php │ │ │ └── retry-skip.php │ ├── plugin-info │ │ ├── index.php │ │ ├── screenshots.php │ │ ├── description.php │ │ └── features.php │ ├── ajax-loader.php │ ├── add-trial-to-pricing.php │ ├── all-admin-notice.php │ ├── secure-https-header.php │ ├── email.php │ ├── sticky-admin-notice-js.php │ ├── admin-notice.php │ ├── tabs-capture-js.php │ ├── firewall-issues-js.php │ ├── powered-by.php │ ├── plugin-icon.php │ ├── contact.php │ └── pricing.php └── require.php ├── img ├── delete.png └── ajax-spinner.gif ├── languages ├── sticky-list.mo └── sticky-list-sv_SE.mo ├── js ├── sticky-list_responsive.js ├── arrive.min.js └── list.pagination.min.js ├── .gitignore ├── css ├── sticky-list_admin_styles.css └── sticky-list_styles.css └── sticky-list.php /includes/assets/scss/_functions.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/13pixlar/sticky-list/HEAD/img/delete.png -------------------------------------------------------------------------------- /img/ajax-spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/13pixlar/sticky-list/HEAD/img/ajax-spinner.gif -------------------------------------------------------------------------------- /languages/sticky-list.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/13pixlar/sticky-list/HEAD/languages/sticky-list.mo -------------------------------------------------------------------------------- /includes/index.php: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /includes/assets/scss/_vars.scss: -------------------------------------------------------------------------------- 1 | $is_production: true; 2 | 3 | $img_common: if($is_production == true, '//img.freemius.com', 'http://img.freemius:8080'); 4 | 5 | $layout_width: 960px; 6 | $admin_mobile_max_width: 782px; -------------------------------------------------------------------------------- /includes/assets/scss/admin/dialog-boxes.scss: -------------------------------------------------------------------------------- 1 | @import "../start"; 2 | @import "modal-common"; 3 | @import "deactivation-feedback"; 4 | @import "license-activation"; 5 | @import "license-key-resend"; 6 | @import "ajax-loader"; 7 | @import "auto-install"; -------------------------------------------------------------------------------- /includes/includes/sdk/Exceptions/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | div, 24 | label, 25 | fieldset 26 | { 27 | width: $max-width; 28 | max-width: 100%; 29 | margin: 0 auto; 30 | display: block; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # ========================= 18 | # Operating System Files 19 | # ========================= 20 | 21 | # OSX 22 | # ========================= 23 | 24 | .DS_Store 25 | .AppleDouble 26 | .LSOverride 27 | 28 | # Icon must end with two \r 29 | Icon 30 | 31 | 32 | # Thumbnails 33 | ._* 34 | 35 | # Files that might appear on external disk 36 | .Spotlight-V100 37 | .Trashes 38 | 39 | # Directories potentially created on remote AFP share 40 | .AppleDB 41 | .AppleDesktop 42 | Network Trash Folder 43 | Temporary Items 44 | .apdisk 45 | .svn/ 46 | sticky-list.sublime-project 47 | sticky-list.sublime-workspace 48 | -------------------------------------------------------------------------------- /includes/includes/entities/class-fs-plugin-info.php: -------------------------------------------------------------------------------- 1 | get_slug(); 18 | 19 | echo fs_text_inline( 'Sorry for the inconvenience and we are here to help if you give us a chance.', 'contact-support-before-deactivation', $slug ) 20 | . sprintf(" %s", 21 | $fs->contact_url( 'technical_support' ), 22 | fs_text_inline( 'Contact Support', 'contact-support', $slug ) 23 | ); 24 | -------------------------------------------------------------------------------- /includes/templates/add-trial-to-pricing.php: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /css/sticky-list_admin_styles.css: -------------------------------------------------------------------------------- 1 | tr + tr { 2 | display: none; 3 | } 4 | .show, 5 | tr:last-child { 6 | display: table-row; 7 | } 8 | #gaddon-setting-row-link_label th:before, 9 | #gaddon-setting-row-enable_view_label th:before, 10 | #gaddon-setting-row-enable_edit_label th:before, 11 | #gaddon-setting-row-update_text th:before, 12 | #gaddon-setting-row-new_entry_id th:before, 13 | #gaddon-setting-row-enable_delete_label th:before, 14 | #gaddon-setting-row-confirm_delete th:before, 15 | #gaddon-setting-row-confirm_delete_text th:before, 16 | #gaddon-setting-row-delete_type th:before, 17 | #gaddon-setting-row-enable_duplicate_label th:before, 18 | #gaddon-setting-row-pdf_label th:before, 19 | #gaddon-setting-row-pdf_id th:before, 20 | #gaddon-setting-row-initial_sort th:before, 21 | #gaddon-setting-row-initial_sort_direction th:before, 22 | #gaddon-setting-row-enable_search th:before, 23 | #gaddon-setting-row-page_entries th:before { 24 | content: "\27a5"; 25 | color: #ddd; 26 | font-size: 18px; 27 | font-weight: bold; 28 | padding-left: 15px !important; 29 | } -------------------------------------------------------------------------------- /includes/templates/plugin-info/screenshots.php: -------------------------------------------------------------------------------- 1 | 22 |
    23 | $url ) : ?> 25 | 30 |
  1. 31 | 32 |
  2. 33 | 34 |
35 | -------------------------------------------------------------------------------- /includes/templates/all-admin-notice.php: -------------------------------------------------------------------------------- 1 | 17 |
32 |

33 | 34 | 35 | 36 | 37 |

38 | 39 |
-------------------------------------------------------------------------------- /includes/assets/scss/admin/_deactivation-feedback.scss: -------------------------------------------------------------------------------- 1 | @import "../colors"; 2 | 3 | .fs-modal.fs-modal-deactivation-feedback { 4 | .reason-input, .internal-message { 5 | margin: 3px 0 3px 22px; 6 | 7 | input, textarea { 8 | width: 100%; 9 | } 10 | } 11 | 12 | li.reason { 13 | &.has-internal-message .internal-message { 14 | border: 1px solid lighten($darkest-color, 80%); 15 | padding: 7px; 16 | display: none; 17 | } 18 | 19 | @media (max-width: 650px) { 20 | li.reason { 21 | margin-bottom: 10px; 22 | 23 | .reason-input, .internal-message { 24 | margin-left: 29px; 25 | } 26 | 27 | label { 28 | display: table; 29 | 30 | > span { 31 | display: table-cell; 32 | font-size: 1.3em; 33 | } 34 | } 35 | } 36 | } 37 | } 38 | 39 | .anonymous-feedback-label { 40 | float: left; 41 | } 42 | 43 | .fs-modal-panel { 44 | margin-top: 0 !important; 45 | 46 | h3 { 47 | margin-top: 0; 48 | line-height: 1.5em; 49 | } 50 | } 51 | } 52 | 53 | #the-list .deactivate > .fs-slug { 54 | display: none; 55 | } -------------------------------------------------------------------------------- /includes/templates/secure-https-header.php: -------------------------------------------------------------------------------- 1 | 15 |
16 | 17 | get_text_inline( 'Secure HTTPS %s page, running from an external domain', 'secure-x-page-header' ), 29 | $VARS['page'] 30 | ) ) . 31 | ' - ' . 32 | sprintf( 33 | '%s', 34 | 'https://www.mcafeesecure.com/verify?host=' . WP_FS__ROOT_DOMAIN_PRODUCTION, 35 | 'Freemius Inc. [US]' 36 | ); 37 | } 38 | ?> 39 |
-------------------------------------------------------------------------------- /includes/templates/js/jquery.content-change.php: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /includes/templates/email.php: -------------------------------------------------------------------------------- 1 | 18 | 19 | $section ) { 21 | ?> 22 | 23 | 24 | 25 | 26 | $row ) { 28 | $col_count = count( $row ); 29 | ?> 30 | 31 | 33 | 34 | 36 | 37 | 38 | 41 | 42 | 45 | 46 | 49 |
:
-------------------------------------------------------------------------------- /includes/assets/scss/admin/_ajax-loader.scss: -------------------------------------------------------------------------------- 1 | $color: $wp-selected-color; 2 | $bkg-color: #fff; 3 | $size: 20; 4 | 5 | .fs-ajax-loader 6 | { 7 | position: relative; 8 | width: #{8*$size + 10}px; 9 | height: #{$size}px; 10 | margin: auto; 11 | 12 | .fs-ajax-loader-bar 13 | { 14 | position: absolute; 15 | top: 0; 16 | background-color: $color; 17 | width: #{$size}px; 18 | height: #{$size}px; 19 | @include animation-name(bounce_ajaxLoader); 20 | @include animation-duration(1.5s); 21 | @include animation-iteration-count(infinite); 22 | @include animation-direction(normal); 23 | @include transform(.3); 24 | } 25 | 26 | @for $i from 0 through 7 27 | { 28 | .fs-ajax-loader-bar-#{$i + 1} 29 | { 30 | left: #{$i*($size - 1)}px; 31 | @include animation-delay(#{0.6 + $i*0.15}s); 32 | } 33 | } 34 | } 35 | 36 | @include keyframes(bounce_ajaxLoader) 37 | { 38 | 0% 39 | { 40 | @include transform(scale(1)); 41 | background-color: $color; 42 | } 43 | 44 | 100% 45 | { 46 | @include transform(scale(.3)); 47 | background-color: $bkg-color; 48 | } 49 | } -------------------------------------------------------------------------------- /includes/templates/forms/deactivation/retry-skip.php: -------------------------------------------------------------------------------- 1 | get_slug(); 18 | 19 | $skip_url = fs_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $fs->get_unique_affix() . '_skip_activation' ) ), $fs->get_unique_affix() . '_skip_activation' ); 20 | $skip_text = strtolower( fs_text_x_inline( 'Skip', 'verb', 'skip', $slug ) ); 21 | $use_plugin_anonymously_text = fs_text_inline( 'Click here to use the plugin anonymously', 'click-here-to-use-plugin-anonymously', $slug ); 22 | 23 | echo sprintf( fs_text_inline( "You might have missed it, but you don't have to share any data and can just %s the opt-in.", 'dont-have-to-share-any-data', $slug ), "{$skip_text}" ) 24 | . " {$use_plugin_anonymously_text}"; -------------------------------------------------------------------------------- /includes/templates/sticky-admin-notice-js.php: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /includes/assets/css/admin/license-activation.css: -------------------------------------------------------------------------------- 1 | .fs-modal{position:fixed;overflow:auto;height:100%;width:100%;top:0;z-index:100000;display:none;background:rgba(0,0,0,0.6)}.fs-modal .fs-modal-dialog{background:transparent;position:absolute;left:50%;margin-left:-298px;padding-bottom:30px;top:-100%;z-index:100001;width:596px}@media (max-width: 650px){.fs-modal .fs-modal-dialog{margin-left:-50%;box-sizing:border-box;padding-left:10px;padding-right:10px;width:100%}.fs-modal .fs-modal-dialog .fs-modal-panel>h3>strong{font-size:1.3em}}.fs-modal.active{display:block}.fs-modal.active:before{display:block}.fs-modal.active .fs-modal-dialog{top:10%}.fs-modal .fs-modal-body,.fs-modal .fs-modal-footer{border:0;background:#fefefe;padding:20px}.fs-modal .fs-modal-body{border-bottom:0}.fs-modal .fs-modal-body .license-activation-message{margin:0;display:none}.fs-modal .fs-modal-body input.license_key{width:100%}.fs-modal .fs-modal-body p{font-size:14px}.fs-modal .fs-modal-body h2{font-size:20px}.fs-modal .fs-modal-body>div{margin-top:10px}.fs-modal .fs-modal-body>div h2{font-weight:bold;font-size:20px;margin-top:0}.fs-modal .fs-modal-footer{border-top:#eeeeee solid 1px;text-align:right}.fs-modal .fs-modal-footer>.button{margin:0 7px}.fs-modal .fs-modal-footer>.button:first-child{margin:0}.fs-modal .fs-modal-panel:not(.active){display:none}body.has-fs-modal{overflow:hidden} 2 | -------------------------------------------------------------------------------- /includes/includes/l10n.php: -------------------------------------------------------------------------------- 1 | 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 | static function get_type() { 60 | return 'user'; 61 | } 62 | } -------------------------------------------------------------------------------- /includes/templates/js/style-premium-theme.php: -------------------------------------------------------------------------------- 1 | get_slug(); 21 | 22 | ?> 23 | -------------------------------------------------------------------------------- /includes/assets/scss/admin/_license-key-resend.scss: -------------------------------------------------------------------------------- 1 | .fs-modal.fs-modal-license-key-resend 2 | { 3 | .email-address-container 4 | { 5 | overflow: hidden; 6 | padding-right: 2px; 7 | } 8 | 9 | &.fs-freemium 10 | { 11 | input.email-address 12 | { 13 | width: 300px; 14 | } 15 | 16 | label 17 | { 18 | display: block; 19 | margin-bottom: 10px; 20 | } 21 | } 22 | 23 | &.fs-premium 24 | { 25 | input.email-address 26 | { 27 | width: 100%; 28 | } 29 | 30 | .button-container 31 | { 32 | float: right; 33 | margin-left: 7px; 34 | 35 | @media (max-width: 650px) { 36 | margin-top: 2px; 37 | } 38 | } 39 | } 40 | } 41 | 42 | .rtl 43 | { 44 | .fs-modal.fs-modal-license-key-resend 45 | { 46 | .fs-modal-body 47 | { 48 | .input-container > .email-address-container 49 | { 50 | padding-left: 2px; 51 | padding-right: 0; 52 | } 53 | 54 | .button-container 55 | { 56 | float: left; 57 | margin-right: 7px; 58 | margin-left: 0; 59 | } 60 | } 61 | } 62 | } 63 | 64 | a.show-license-resend-modal 65 | { 66 | margin-top: 4px; 67 | display: inline-block; 68 | } 69 | -------------------------------------------------------------------------------- /includes/includes/debug/debug-bar-start.php: -------------------------------------------------------------------------------- 1 | &$data ) { 39 | if ( 0 === strpos( $file_real_path, fs_normalize_path( dirname( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) ) ) ) ) { 40 | if ( '.' !== dirname( trailingslashit( $relative_path ) ) ) { 41 | return $relative_path; 42 | } 43 | } 44 | } 45 | 46 | return null; 47 | } 48 | -------------------------------------------------------------------------------- /includes/templates/admin-notice.php: -------------------------------------------------------------------------------- 1 | 15 | data-id="" data-manager-id="" 16 | class=" fs-notice"> 37 | 38 | 39 | 40 |
42 |
43 | 44 |
45 | 46 | 47 |
48 | 49 | -------------------------------------------------------------------------------- /includes/includes/debug/class-fs-debug-bar-panel.php: -------------------------------------------------------------------------------- 1 | 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 |
54 | 55 |
56 | 57 |
58 | 59 |
60 | 61 |
62 | h3>strong{font-size:1.3em}.fs-modal .fs-modal-dialog li.reason{margin-bottom:10px}.fs-modal .fs-modal-dialog li.reason .reason-input,.fs-modal .fs-modal-dialog li.reason .internal-message{margin-left:29px}.fs-modal .fs-modal-dialog li.reason label{display:table}.fs-modal .fs-modal-dialog li.reason label>span{display:table-cell;font-size:1.3em}}.fs-modal.active{display:block}.fs-modal.active:before{display:block}.fs-modal.active .fs-modal-dialog{top:10%}.fs-modal .fs-modal-body,.fs-modal .fs-modal-footer{border:0;background:#fefefe;padding:20px}.fs-modal .fs-modal-body{border-bottom:0}.fs-modal .fs-modal-body h2{font-size:20px}.fs-modal .fs-modal-body>div{margin-top:10px}.fs-modal .fs-modal-body>div h2{font-weight:bold;font-size:20px;margin-top:0}.fs-modal .fs-modal-footer{border-top:#eeeeee solid 1px;text-align:right}.fs-modal .fs-modal-footer>.button{margin:0 7px}.fs-modal .fs-modal-footer>.button:first-child{margin:0}.fs-modal .fs-modal-panel:not(.active){display:none}.fs-modal .reason-input,.fs-modal .internal-message{margin:3px 0 3px 22px}.fs-modal .reason-input input,.fs-modal .reason-input textarea,.fs-modal .internal-message input,.fs-modal .internal-message textarea{width:100%}.fs-modal li.reason.has-internal-message .internal-message{border:1px solid #ccc;padding:7px;display:none}body.has-fs-modal{overflow:hidden}#the-list .deactivate>.fs-slug{display:none} 2 | -------------------------------------------------------------------------------- /includes/assets/scss/_colors.scss: -------------------------------------------------------------------------------- 1 | $menu-hover-color: #333; 2 | $darkest-color: #000; 3 | $fms-live-color: #71ae00; 4 | $fms-test-color: #f7941d; 5 | $fms-link-color: #29abe1; 6 | $fms-link-hover-color: darken(#29abe1, 10%); 7 | $body-bkg: #111; 8 | $special-color: #d3135a; 9 | $body-color: #f1f1f1; 10 | $fms-white: #f1f1f1; 11 | $container-bkg: #222; 12 | $container-bkg-odd: #262626; 13 | $container-border-color: #333; 14 | $table-head-bkg: #333; 15 | $table-head-color: #999; 16 | $info-color: #999; 17 | $error-color: #ff0000; 18 | 19 | $fs-logo-blue-color: #29abe1; 20 | $fs-logo-green-color: #71ae00; 21 | $fs-logo-magenta-color: #d3135a; 22 | 23 | // WordPress colors. 24 | $page-header-bkg: #333; 25 | $page-header-color: $fms-white; 26 | $text-dark-color: #333; 27 | $text-light-color: #666; 28 | $text-lightest-color: #999; 29 | 30 | // Notices. 31 | $wp-notice-success-color: #f7fff7; 32 | $wp-notice-success-dark-color: #46b450; 33 | $wp-notice-error-color: #ffeaea; 34 | $wp-notice-error-dark-color: #dc3232; 35 | $wp-notice-warn-color: #fff8e5; 36 | $wp-notice-warn-dark-color: #ffb900; 37 | $fs-notice-promotion-border-color: #00a0d2; 38 | $fs-notice-promotion-bkg: #f2fcff; 39 | 40 | // WP Buttons. 41 | $button-primary-bkg: #6bc406; 42 | $button-primary-color: $fms-white; 43 | $button-secondary-bkg: #333; 44 | $button-secondary-color: $fms-white; 45 | $featured-color: #6bc406; 46 | $wp-selected-color: #0074a3; 47 | 48 | $wordpress_color: #01749A; 49 | $blogger_color: #ff8100; 50 | $wix_color: #fac102; 51 | $shopify_color: #80d100; 52 | $addthis_color: #fe6d4e; 53 | $tumblr_color: #34506b; 54 | $zepo_color: #00baf2; 55 | $jquery_color: #000919; 56 | $javascript_color: #00baf2; 57 | $squarespace_color: #000; 58 | 59 | $blog_color: #ff6600; 60 | $facebook_color: #3b5998; 61 | $twitter_color: #4099ff; 62 | $linkedin_color: #4875b4; 63 | $youtube_color: #ff3333; 64 | $gplus_color: #c63d2d; 65 | 66 | -------------------------------------------------------------------------------- /sticky-list.php: -------------------------------------------------------------------------------- 1 | '1528', 28 | 'slug' => 'gravity-forms-sticky-list', 29 | 'type' => 'plugin', 30 | 'public_key' => 'pk_ab96a4a2bac76862a81de1dde21a9', 31 | 'is_premium' => false, 32 | 'has_addons' => false, 33 | 'has_paid_plans' => false, 34 | 'menu' => array( 35 | 'first-path' => 'plugins.php', 36 | ), 37 | ) ); 38 | } 39 | 40 | return $stickylist_fs; 41 | } 42 | 43 | // Init Freemius. 44 | stickylist_fs(); 45 | // Signal that SDK was initiated. 46 | do_action( 'stickylist_fs_loaded' ); 47 | 48 | add_action( 'gform_loaded', array( 'StickyList_Bootstrap', 'load' ), 5 ); 49 | class StickyList_Bootstrap { 50 | 51 | public static function load() { 52 | if ( ! method_exists( 'GFForms', 'include_addon_framework' ) ) { 53 | return; 54 | } 55 | 56 | require_once( 'class-sticky-list.php' ); 57 | GFAddOn::register( 'StickyList' ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /css/sticky-list_styles.css: -------------------------------------------------------------------------------- 1 | /* sticky-list styles */ 2 | 3 | /* Make the action buttons aligned to the right */ 4 | table.sticky-list th.sticky-action, 5 | table.sticky-list td.sticky-action { 6 | text-align: right; 7 | white-space:nowrap; 8 | } 9 | 10 | /* Do not wrap text in the table header */ 11 | table.sticky-list th, 12 | table.sticky-list .sticky-nowrap { 13 | white-space:nowrap; 14 | } 15 | 16 | /* Make every other row in the list slightly grey */ 17 | table.sticky-list tr:nth-child(2n+2) { 18 | background: #f7f7f7; 19 | } 20 | 21 | table.sticky-list, 22 | table.sticky-list * { 23 | border: none; 24 | } 25 | 26 | table.sticky-list form, 27 | table.sticky-list button, 28 | table.sticky-list form input { 29 | display: inline-block !important; 30 | } 31 | 32 | /* Style the action buttons */ 33 | table.sticky-list button { 34 | background:none!important; 35 | border:none; 36 | padding:0!important; 37 | cursor: pointer; 38 | font-style: normal; 39 | font-weight: normal; 40 | text-transform: none; 41 | font-size: inherit; 42 | color: inherit; 43 | margin-left: 5px; 44 | text-decoration: underline; 45 | } 46 | 47 | /* Pagination styles */ 48 | div[id^="sticky-list-wrapper"] ul.pagination { 49 | list-style: none; 50 | margin: 0; 51 | } 52 | div[id^="sticky-list-wrapper"] ul.pagination li { 53 | display: inline-block; 54 | margin-right: 5px; 55 | } 56 | div[id^="sticky-list-wrapper"] ul.pagination li.active a, 57 | div[id^="sticky-list-wrapper"] ul.pagination li.disabled a { 58 | color: inherit; 59 | text-decoration: none; 60 | cursor: default; 61 | } 62 | 63 | /* Upload field styles */ 64 | div[class^="file_"] .remove-entry { 65 | cursor: pointer; 66 | text-decoration: none; 67 | border-bottom: none; 68 | } 69 | div[class^="file_"] a.remove-entry img { 70 | display: inline-block; 71 | } 72 | div[class^="file_"] + input[type="file"] { 73 | display: none; 74 | } 75 | -------------------------------------------------------------------------------- /includes/includes/entities/class-fs-billing.php: -------------------------------------------------------------------------------- 1 | bound_payment_id ) && 0 > $this->gross ); 93 | } 94 | } -------------------------------------------------------------------------------- /includes/templates/tabs-capture-js.php: -------------------------------------------------------------------------------- 1 | get_slug(); 19 | ?> 20 | -------------------------------------------------------------------------------- /includes/templates/account/payments.php: -------------------------------------------------------------------------------- 1 | get_slug(); 20 | 21 | $payments = $fs->_fetch_payments(); 22 | 23 | $show_payments = ( is_array( $payments ) && 0 < count( $payments ) ); 24 | 25 | if ( $show_payments ) : 26 | ?> 27 |
28 |
29 |

30 | 31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | > 45 | 46 | 47 | 48 | 51 | 52 | 53 | 54 |
id ?>created ) ) ?>$gross ?>
55 |
56 |
57 |
58 | 17 | -------------------------------------------------------------------------------- /includes/includes/sdk/Exceptions/Exception.php: -------------------------------------------------------------------------------- 1 | _result = $result; 19 | 20 | $code = 0; 21 | $message = 'Unknown error, please check GetResult().'; 22 | $type = ''; 23 | 24 | if ( isset( $result['error'] ) && is_array( $result['error'] ) ) { 25 | if ( isset( $result['error']['code'] ) ) { 26 | $code = $result['error']['code']; 27 | } 28 | if ( isset( $result['error']['message'] ) ) { 29 | $message = $result['error']['message']; 30 | } 31 | if ( isset( $result['error']['type'] ) ) { 32 | $type = $result['error']['type']; 33 | } 34 | } 35 | 36 | $this->_type = $type; 37 | $this->_code = $code; 38 | 39 | parent::__construct( $message, is_numeric( $code ) ? $code : 0 ); 40 | } 41 | 42 | /** 43 | * Return the associated result object returned by the API server. 44 | * 45 | * @return array The result from the API server 46 | */ 47 | public function getResult() { 48 | return $this->_result; 49 | } 50 | 51 | public function getStringCode() { 52 | return $this->_code; 53 | } 54 | 55 | public function getType() { 56 | return $this->_type; 57 | } 58 | 59 | /** 60 | * To make debugging easier. 61 | * 62 | * @return string The string representation of the error 63 | */ 64 | public function __toString() { 65 | $str = $this->getType() . ': '; 66 | 67 | if ( $this->code != 0 ) { 68 | $str .= $this->getStringCode() . ': '; 69 | } 70 | 71 | return $str . $this->getMessage(); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /includes/assets/css/admin/affiliation.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";#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{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} 2 | -------------------------------------------------------------------------------- /includes/assets/css/customizer.css: -------------------------------------------------------------------------------- 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 0.3s ease-in-out;-o-transition:opacity 0.3s ease-in-out;-ms-transition:opacity 0.3s ease-in-out;-webkit-transition:opacity 0.3s ease-in-out;transition:opacity 0.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,0.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,0.2);box-shadow:1px 1px 1px rgba(0,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} 2 | -------------------------------------------------------------------------------- /includes/assets/css/admin/debug.css: -------------------------------------------------------------------------------- 1 | .switch{position:relative;display:inline-block;font-size:1.6em;font-weight:bold;color:#ccc;text-shadow:0px 1px 1px rgba(255,255,255,0.8);height:18px;padding:6px 6px 5px 6px;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);border-radius:4px;background:#ececec;box-shadow:0px 0px 4px rgba(0,0,0,0.1),inset 0px 1px 3px 0px rgba(0,0,0,0.1);cursor:pointer}.switch span{display:inline-block;width:35px;text-transform:uppercase}.switch span.on{color:#6bc406}.switch .toggle{position:absolute;top:1px;width:37px;height:25px;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.3);border-radius:4px;background:#fff;background:-moz-linear-gradient(top, #ececec 0%, #fff 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #ececec), color-stop(100%, #fff));background:-webkit-linear-gradient(top, #ececec 0%, #fff 100%);background:-o-linear-gradient(top, #ececec 0%, #fff 100%);background:-ms-linear-gradient(top, #ececec 0%, #fff 100%);background:linear-gradient(top, #ececec 0%, #fff 100%);box-shadow:inset 0px 1px 0px 0px rgba(255,255,255,0.5);z-index:999;-moz-transition:all 0.15s ease-in-out;-o-transition:all 0.15s ease-in-out;-ms-transition:all 0.15s ease-in-out;-webkit-transition:all 0.15s ease-in-out;transition:all 0.15s ease-in-out}.switch.on .toggle{left:2%}.switch.off .toggle{left:54%}.switch.round{padding:0px 20px;border-radius:40px}.switch.round .toggle{border-radius:40px;width:14px;height:14px}.switch.round.on .toggle{left:3%;background:#6bc406}.switch.round.off .toggle{left:58%}.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} 2 | -------------------------------------------------------------------------------- /includes/includes/class-fs-security.php: -------------------------------------------------------------------------------- 1 | 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 | } 86 | -------------------------------------------------------------------------------- /includes/includes/entities/class-fs-affiliate.php: -------------------------------------------------------------------------------- 1 | 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 | } -------------------------------------------------------------------------------- /includes/templates/powered-by.php: -------------------------------------------------------------------------------- 1 | 39 | 40 |
41 | -------------------------------------------------------------------------------- /includes/templates/debug/logger.php: -------------------------------------------------------------------------------- 1 | 15 |

16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 39 | > 42 | 43 | 44 | 45 | 46 | 57 | 62 | 63 | 64 | 65 | 66 |
#
.get_id() ?> 47 | %s', 50 | esc_html( substr( $log['msg'], 0, 32 ) ) . ( 32 < strlen( $log['msg'] ) ? '...' : '' ) 51 | ); 52 | ?> 53 |
54 | 55 |
56 |
get_file() ) . ':' . $log['line']; 60 | } 61 | ?>
-------------------------------------------------------------------------------- /includes/assets/css/admin/common.css: -------------------------------------------------------------------------------- 1 | .theme-browser .theme .fs-premium-theme-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,0.3);-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);font-size:1.1em}#iframe{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}} 2 | .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,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}.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,0.3);-webkit-box-shadow:0 2px 2px rgba(6,113,6,0.3);box-shadow:0 2px 2px rgba(6,113,6,0.3);opacity:0.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: 500px){#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:'\21B3';padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:'\21B2'}.fs-submenu-item.pricing.upgrade-mode{color:greenyellow}.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}.wrap.fs-section h2{text-align:left} 3 | -------------------------------------------------------------------------------- /includes/templates/plugin-info/description.php: -------------------------------------------------------------------------------- 1 | info->selling_point_0 ) || 21 | ! empty( $plugin->info->selling_point_1 ) || 22 | ! empty( $plugin->info->selling_point_2 ) 23 | ) : ?> 24 |
25 | 34 |
35 | 36 |
37 | info->description, array( 39 | 'a' => array( 'href' => array(), 'title' => array(), 'target' => array() ), 40 | 'b' => array(), 41 | 'i' => array(), 42 | 'p' => array(), 43 | 'blockquote' => array(), 44 | 'h2' => array(), 45 | 'h3' => array(), 46 | 'ul' => array(), 47 | 'ol' => array(), 48 | 'li' => array() 49 | ) ); 50 | ?> 51 |
52 | info->screenshots ) ) : ?> 53 | info->screenshots ?> 54 |
55 |

slug ) ?>

56 | 77 |
78 | -------------------------------------------------------------------------------- /includes/includes/managers/class-fs-license-manager.php: -------------------------------------------------------------------------------- 1 | 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 | } -------------------------------------------------------------------------------- /includes/require.php: -------------------------------------------------------------------------------- 1 | is_premium = false; 85 | $this->is_live = true; 86 | 87 | if ( isset( $plugin->info ) && is_object( $plugin->info ) ) { 88 | $this->info = new FS_Plugin_Info( $plugin->info ); 89 | } 90 | } 91 | 92 | /** 93 | * Check if plugin is an add-on (has parent). 94 | * 95 | * @author Vova Feldman (@svovaf) 96 | * @since 1.0.6 97 | * 98 | * @return bool 99 | */ 100 | function is_addon() { 101 | return isset( $this->parent_plugin_id ) && is_numeric( $this->parent_plugin_id ); 102 | } 103 | 104 | /** 105 | * @author Leo Fajardo (@leorw) 106 | * @since 1.2.3 107 | * 108 | * @return bool 109 | */ 110 | function has_affiliate_program() { 111 | return ( ! empty( $this->affiliate_moderation ) ); 112 | } 113 | 114 | static function get_type() { 115 | return 'plugin'; 116 | } 117 | } -------------------------------------------------------------------------------- /includes/includes/entities/class-fs-subscription.php: -------------------------------------------------------------------------------- 1 | next_payment ) && 101 | ( strtotime( $this->next_payment ) > WP_FS__SCRIPT_START_TIME ); 102 | } 103 | 104 | /** 105 | * Subscription considered to be new without any payments 106 | * if the next payment should be made within less than 24 hours 107 | * from the subscription creation. 108 | * 109 | * @author Vova Feldman (@svovaf) 110 | * @since 1.0.9 111 | * 112 | * @return bool 113 | */ 114 | function is_first_payment_pending() { 115 | return ( WP_FS__TIME_24_HOURS_IN_SEC >= strtotime( $this->next_payment ) - strtotime( $this->created ) ); 116 | } 117 | 118 | /** 119 | * @author Vova Feldman (@svovaf) 120 | * @since 1.1.7 121 | */ 122 | function has_trial() { 123 | return ! is_null( $this->trial_ends ); 124 | } 125 | } -------------------------------------------------------------------------------- /includes/templates/debug/plugins-themes-sync.php: -------------------------------------------------------------------------------- 1 | get_option( 'all_plugins' ); 15 | $all_themes = $fs_options->get_option( 'all_themes' ); 16 | 17 | /* translators: %s: time period (e.g. In "2 hours") */ 18 | $in_x_text = fs_text_inline( 'In %s', 'in-x' ); 19 | /* translators: %s: time period (e.g. "2 hours" ago) */ 20 | $x_ago_text = fs_text_inline( '%s ago', 'x-ago' ); 21 | $sec_text = fs_text_x_inline( 'sec', 'seconds' ); 22 | ?> 23 |

24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 73 | 74 | 75 | 76 |
plugins ) ?>timestamp ) && is_numeric( $all_plugins->timestamp ) ) { 39 | $diff = abs( WP_FS__SCRIPT_START_TIME - $all_plugins->timestamp ); 40 | $human_diff = ( $diff < MINUTE_IN_SECONDS ) ? 41 | $diff . ' ' . $sec_text : 42 | human_time_diff( WP_FS__SCRIPT_START_TIME, $all_plugins->timestamp ); 43 | 44 | echo esc_html( sprintf( 45 | ( ( WP_FS__SCRIPT_START_TIME < $all_plugins->timestamp ) ? 46 | $in_x_text : 47 | $x_ago_text ), 48 | $human_diff 49 | ) ); 50 | } 51 | ?>
themes ) ?>timestamp ) && is_numeric( $all_themes->timestamp ) ) { 60 | $diff = abs( WP_FS__SCRIPT_START_TIME - $all_themes->timestamp ); 61 | $human_diff = ( $diff < MINUTE_IN_SECONDS ) ? 62 | $diff . ' ' . $sec_text : 63 | human_time_diff( WP_FS__SCRIPT_START_TIME, $all_themes->timestamp ); 64 | 65 | echo esc_html( sprintf( 66 | ( ( WP_FS__SCRIPT_START_TIME < $all_themes->timestamp ) ? 67 | $in_x_text : 68 | $x_ago_text ), 69 | $human_diff 70 | ) ); 71 | } 72 | ?>
77 | -------------------------------------------------------------------------------- /includes/includes/customizer/class-fs-customizer-support-section.php: -------------------------------------------------------------------------------- 1 | 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 |
  • 84 |

    85 | {{ data.theme_title }} 86 | <# if ( data.contact && data.support ) { #> 87 |
    88 | <# } #> 89 | <# if ( data.contact ) { #> 90 | {{ data.contact.label }} 91 | <# } #> 92 | <# if ( data.support ) { #> 93 | {{ data.support.label }} 94 | <# } #> 95 | <# if ( data.contact && data.support ) { #> 96 |
    97 | <# } #> 98 |

    99 |
  • 100 | monthly_price ) && $this->monthly_price > 0 ); 59 | } 60 | 61 | /** 62 | * @author Vova Feldman (@svovaf) 63 | * @since 1.1.8 64 | * 65 | * @return bool 66 | */ 67 | function has_annual() { 68 | return ( is_numeric( $this->annual_price ) && $this->annual_price > 0 ); 69 | } 70 | 71 | /** 72 | * @author Vova Feldman (@svovaf) 73 | * @since 1.1.8 74 | * 75 | * @return bool 76 | */ 77 | function has_lifetime() { 78 | return ( is_numeric( $this->lifetime_price ) && $this->lifetime_price > 0 ); 79 | } 80 | 81 | /** 82 | * Check if unlimited licenses pricing. 83 | * 84 | * @author Vova Feldman (@svovaf) 85 | * @since 1.1.8 86 | * 87 | * @return bool 88 | */ 89 | function is_unlimited() { 90 | return is_null( $this->licenses ); 91 | } 92 | 93 | 94 | /** 95 | * Check if pricing has more than one billing cycle. 96 | * 97 | * @author Vova Feldman (@svovaf) 98 | * @since 1.1.8 99 | * 100 | * @return bool 101 | */ 102 | function is_multi_cycle() { 103 | $cycles = 0; 104 | if ( $this->has_monthly() ) { 105 | $cycles ++; 106 | } 107 | if ( $this->has_annual() ) { 108 | $cycles ++; 109 | } 110 | if ( $this->has_lifetime() ) { 111 | $cycles ++; 112 | } 113 | 114 | return $cycles > 1; 115 | } 116 | 117 | /** 118 | * Get annual over monthly discount. 119 | * 120 | * @author Vova Feldman (@svovaf) 121 | * @since 1.1.8 122 | * 123 | * @return int 124 | */ 125 | function annual_discount_percentage() { 126 | return floor( $this->annual_savings() / ( $this->monthly_price * 12 * ( $this->is_unlimited() ? 1 : $this->licenses ) ) * 100 ); 127 | } 128 | 129 | /** 130 | * Get annual over monthly savings. 131 | * 132 | * @author Vova Feldman (@svovaf) 133 | * @since 1.1.8 134 | * 135 | * @return float 136 | */ 137 | function annual_savings() { 138 | return ( $this->monthly_price * 12 - $this->annual_price ) * ( $this->is_unlimited() ? 1 : $this->licenses ); 139 | } 140 | 141 | } -------------------------------------------------------------------------------- /includes/assets/css/admin/account.css: -------------------------------------------------------------------------------- 1 | #fs_account .postbox,#fs_account .widefat{max-width:700px}#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 .button i.dashicons{vertical-align:middle}#fs_account .fs-header-actions{position:absolute;top:17px;right:15px;font-size:0.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}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_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%} 2 | -------------------------------------------------------------------------------- /includes/includes/entities/class-fs-site.php: -------------------------------------------------------------------------------- 1 | plan = new FS_Plugin_Plan(); 103 | 104 | parent::__construct( $site ); 105 | 106 | if ( is_object( $site ) ) { 107 | $this->plan->id = $site->plan_id; 108 | } 109 | 110 | if ( ! is_bool( $this->is_disconnected ) ) { 111 | $this->is_disconnected = false; 112 | } 113 | } 114 | 115 | static function get_type() { 116 | return 'install'; 117 | } 118 | 119 | function is_localhost() { 120 | // The server has no way to verify if localhost unless localhost appears in domain. 121 | return WP_FS__IS_LOCALHOST_FOR_SERVER; 122 | // return (substr($_SERVER['REMOTE_ADDR'], 0, 4) == '127.' || $_SERVER['REMOTE_ADDR'] == '::1'); 123 | } 124 | 125 | /** 126 | * Check if site in trial. 127 | * 128 | * @author Vova Feldman (@svovaf) 129 | * @since 1.0.9 130 | * 131 | * @return bool 132 | */ 133 | function is_trial() { 134 | return is_numeric( $this->trial_plan_id ) && ( strtotime( $this->trial_ends ) > WP_FS__SCRIPT_START_TIME ); 135 | } 136 | 137 | /** 138 | * Check if user already utilized the trial with the current install. 139 | * 140 | * @author Vova Feldman (@svovaf) 141 | * @since 1.0.9 142 | * 143 | * @return bool 144 | */ 145 | function is_trial_utilized() { 146 | return is_numeric( $this->trial_plan_id ); 147 | } 148 | } -------------------------------------------------------------------------------- /includes/includes/entities/class-fs-plugin-plan.php: -------------------------------------------------------------------------------- 1 | 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 | } -------------------------------------------------------------------------------- /includes/includes/entities/class-fs-entity.php: -------------------------------------------------------------------------------- 1 | $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 | } -------------------------------------------------------------------------------- /includes/assets/scss/admin/debug.scss: -------------------------------------------------------------------------------- 1 | @import "../start"; 2 | 3 | .switch 4 | { 5 | position: relative; 6 | display: inline-block; 7 | font-size: 1.6em; 8 | font-weight: bold; 9 | color: #ccc; 10 | text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.8); 11 | height: 18px; 12 | padding: 6px 6px 5px 6px; 13 | border: 1px solid #ccc; 14 | border: 1px solid rgba(0, 0, 0, 0.2); 15 | border-radius: 4px; 16 | background: #ececec; 17 | box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.1), inset 0px 1px 3px 0px rgba(0, 0, 0, 0.1); 18 | cursor: pointer; 19 | 20 | span 21 | { 22 | display: inline-block; width: 35px; 23 | text-transform: uppercase; 24 | 25 | &.on 26 | { 27 | color: $button-primary-bkg; 28 | } 29 | } 30 | 31 | .toggle 32 | { 33 | position: absolute; 34 | top: 1px; 35 | width: 37px; 36 | height: 25px; 37 | border: 1px solid #ccc; 38 | border: 1px solid rgba(0, 0, 0, 0.3); 39 | border-radius: 4px; 40 | background: #fff; 41 | background: -moz-linear-gradient(top, #ececec 0%, #fff 100%); 42 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ececec), color-stop(100%, #fff)); 43 | background: -webkit-linear-gradient(top, #ececec 0%, #fff 100%); 44 | background: -o-linear-gradient(top, #ececec 0%, #fff 100%); 45 | background: -ms-linear-gradient(top, #ececec 0%, #fff 100%); 46 | background: linear-gradient(top, #ececec 0%, #fff 100%); 47 | box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, 0.5); 48 | z-index: 999; 49 | @include transition(all 0.15s ease-in-out); 50 | } 51 | 52 | &.on .toggle 53 | { 54 | left: 2%; 55 | } 56 | &.off .toggle 57 | { 58 | left: 54%; 59 | } 60 | 61 | /* Round switch */ 62 | &.round 63 | { 64 | padding: 0px 20px; 65 | border-radius: 40px; 66 | 67 | .toggle 68 | { 69 | border-radius: 40px; 70 | width: 14px; 71 | height: 14px; 72 | } 73 | 74 | &.on .toggle 75 | { 76 | left: 3%; 77 | background: $button-primary-bkg; 78 | } 79 | &.off .toggle 80 | { 81 | left: 58%; 82 | } 83 | } 84 | } 85 | 86 | .switch-label 87 | { 88 | font-size: 20px; 89 | line-height: 31px; 90 | margin: 0 5px; 91 | } 92 | 93 | #fs_log_book { 94 | table { 95 | font-family: Consolas,Monaco,monospace; 96 | font-size: 12px; 97 | 98 | th { 99 | color: #ccc; 100 | } 101 | 102 | tr { 103 | background: #232525; 104 | 105 | &.alternate { 106 | background: #2b2b2b; 107 | } 108 | 109 | td { 110 | &.fs-col--logger { 111 | color: #5a7435; 112 | } 113 | &.fs-col--type { 114 | color: #ffc861; 115 | } 116 | &.fs-col--function { 117 | color: #a7b7b1; 118 | font-weight: bold; 119 | } 120 | &.fs-col--message { 121 | &, a 122 | { 123 | color: #9a73ac !important; 124 | } 125 | } 126 | &.fs-col--file { 127 | color: #d07922; 128 | } 129 | &.fs-col--timestamp { 130 | color: #6596be; 131 | } 132 | } 133 | } 134 | } 135 | } -------------------------------------------------------------------------------- /includes/assets/scss/admin/_modal-common.scss: -------------------------------------------------------------------------------- 1 | @import "../colors"; 2 | @import "../mixins"; 3 | 4 | .fs-modal { 5 | position: fixed; 6 | overflow: auto; 7 | height: 100%; 8 | width: 100%; 9 | top: 0; 10 | z-index: 100000; 11 | display: none; 12 | background: rgba(0, 0, 0, 0.6); 13 | 14 | .fs-modal-dialog { 15 | background: transparent; 16 | position: absolute; 17 | left: 50%; 18 | margin-left: -298px; 19 | padding-bottom: 30px; 20 | top: -100%; 21 | z-index: 100001; 22 | width: 596px; 23 | 24 | @media (max-width: 650px) { 25 | margin-left: -50%; 26 | box-sizing: border-box; 27 | padding-left: 10px; 28 | padding-right: 10px; 29 | width: 100%; 30 | 31 | .fs-modal-panel > h3 > strong { 32 | font-size: 1.3em; 33 | } 34 | } 35 | } 36 | 37 | &.active { 38 | display: block; 39 | 40 | &:before { 41 | display: block; 42 | } 43 | 44 | .fs-modal-dialog { 45 | top: 10%; 46 | } 47 | } 48 | 49 | &.fs-success { 50 | .fs-modal-header { 51 | border-bottom-color: $wp-notice-success-dark-color; 52 | } 53 | 54 | .fs-modal-body { 55 | background-color: $wp-notice-success-color; 56 | } 57 | } 58 | 59 | &.fs-warn { 60 | .fs-modal-header { 61 | border-bottom-color: $wp-notice-warn-dark-color; 62 | } 63 | 64 | .fs-modal-body { 65 | background-color: $wp-notice-warn-color; 66 | } 67 | } 68 | 69 | &.fs-error { 70 | .fs-modal-header { 71 | border-bottom-color: $wp-notice-error-dark-color; 72 | } 73 | 74 | .fs-modal-body { 75 | background-color: $wp-notice-error-color; 76 | } 77 | } 78 | 79 | 80 | .fs-modal-body, 81 | .fs-modal-footer { 82 | border: 0; 83 | background: #fefefe; 84 | padding: 20px; 85 | } 86 | 87 | .fs-modal-header { 88 | border-bottom: #eeeeee solid 1px; 89 | background: #fbfbfb; 90 | padding: 15px 20px; 91 | position: relative; 92 | margin-bottom: -10px; 93 | // z-index: 2; 94 | 95 | h4 { 96 | margin: 0; 97 | padding: 0; 98 | text-transform: uppercase; 99 | font-size: 1.2em; 100 | font-weight: bold; 101 | color: #cacaca; 102 | text-shadow: 1px 1px 1px #fff; 103 | letter-spacing: 0.6px; 104 | -webkit-font-smoothing: antialiased; 105 | } 106 | 107 | .fs-close { 108 | position: absolute; 109 | right: 10px; 110 | top: 12px; 111 | cursor: pointer; 112 | color: #bbb; 113 | @include border-radius(20px); 114 | padding: 3px; 115 | @include transition(all 0.2s ease-in-out); 116 | 117 | &:hover { 118 | color: #fff; 119 | background: #aaa; 120 | } 121 | } 122 | } 123 | 124 | .fs-modal-body { 125 | border-bottom: 0; 126 | 127 | p { 128 | font-size: 14px; 129 | } 130 | 131 | h2 { 132 | font-size: 20px; 133 | line-height: 1.5em; 134 | } 135 | 136 | > div { 137 | margin-top: 10px; 138 | 139 | h2 { 140 | font-weight: bold; 141 | font-size: 20px; 142 | margin-top: 0; 143 | } 144 | } 145 | } 146 | 147 | .fs-modal-footer { 148 | border-top: #eeeeee solid 1px; 149 | text-align: right; 150 | 151 | > .button { 152 | margin: 0 7px; 153 | 154 | &:first-child { 155 | margin: 0; 156 | } 157 | } 158 | } 159 | 160 | .fs-modal-panel { 161 | > .notice.inline { 162 | margin: 0; 163 | display: none; 164 | } 165 | 166 | &:not(.active) { 167 | display: none; 168 | } 169 | } 170 | } 171 | 172 | .rtl 173 | { 174 | .fs-modal { 175 | .fs-modal-header { 176 | .fs-close { 177 | right: auto; 178 | left: 20px; 179 | } 180 | } 181 | } 182 | } 183 | 184 | body.has-fs-modal { 185 | overflow: hidden; 186 | } -------------------------------------------------------------------------------- /includes/includes/managers/class-fs-plan-manager.php: -------------------------------------------------------------------------------- 1 | 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 | } -------------------------------------------------------------------------------- /includes/templates/plugin-info/features.php: -------------------------------------------------------------------------------- 1 | features) && is_array($plan->features)) { 25 | foreach ( $plan->features as $feature ) { 26 | if ( ! isset( $features_plan_map[ $feature->id ] ) ) { 27 | $features_plan_map[ $feature->id ] = array( 'feature' => $feature, 'plans' => array() ); 28 | } 29 | 30 | $features_plan_map[ $feature->id ]['plans'][ $plan->id ] = $feature; 31 | } 32 | } 33 | 34 | // Add support as a feature. 35 | if ( ! empty( $plan->support_email ) || 36 | ! empty( $plan->support_skype ) || 37 | ! empty( $plan->support_phone ) || 38 | true === $plan->is_success_manager 39 | ) { 40 | if ( ! isset( $features_plan_map['support'] ) ) { 41 | $support_feature = new stdClass(); 42 | $support_feature->id = 'support'; 43 | $support_feature->title = fs_text_inline( 'Support', $plugin->slug ); 44 | $features_plan_map[ $support_feature->id ] = array( 'feature' => $support_feature, 'plans' => array() ); 45 | } else { 46 | $support_feature = $features_plan_map['support']; 47 | } 48 | 49 | $features_plan_map[ $support_feature->id ]['plans'][ $plan->id ] = $support_feature; 50 | } 51 | } 52 | 53 | // Add updates as a feature for all plans. 54 | $updates_feature = new stdClass(); 55 | $updates_feature->id = 'updates'; 56 | $updates_feature->title = fs_text_inline( 'Unlimited Updates', 'unlimited-updates', $plugin->slug ); 57 | $features_plan_map[ $updates_feature->id ] = array( 'feature' => $updates_feature, 'plans' => array() ); 58 | foreach ( $plans as $plan ) { 59 | $features_plan_map[ $updates_feature->id ]['plans'][ $plan->id ] = $updates_feature; 60 | } 61 | ?> 62 |
    63 | 64 | 65 | 66 | 67 | 68 | 91 | 92 | 93 | 94 | 95 | $data ) : ?> 97 | 98 | 99 | 100 | 109 | 110 | 111 | 112 | 113 |
    69 | title ?> 70 | pricing ) ) { 72 | fs_esc_html_echo_inline( 'Free', 'free', $plugin->slug ); 73 | } else { 74 | foreach ( $plan->pricing as $pricing ) { 75 | /** 76 | * @var FS_Pricing $pricing 77 | */ 78 | if ( 1 == $pricing->licenses ) { 79 | if ( $pricing->has_annual() ) { 80 | echo "\${$pricing->annual_price} / " . fs_esc_html_x_inline( 'year', 'as annual period', 'year', $plugin->slug ); 81 | } else if ( $pricing->has_monthly() ) { 82 | echo "\${$pricing->monthly_price} / " . fs_esc_html_x_inline( 'mo', 'as monthly period', 'mo', $plugin->slug ); 83 | } else { 84 | echo "\${$pricing->lifetime_price}"; 85 | } 86 | } 87 | } 88 | } 89 | ?> 90 |
    title ) ) ?> 101 | id ] ) ) : ?> 102 | id ]->value ) ) : ?> 103 | id ]->value ) ?> 104 | 105 | 106 | 107 | 108 |
    114 |
    -------------------------------------------------------------------------------- /includes/templates/plugin-icon.php: -------------------------------------------------------------------------------- 1 | get_slug(); 15 | 16 | /** 17 | * @since 1.1.7.5 18 | */ 19 | $local_path = $fs->apply_filters( 'plugin_icon', false ); 20 | 21 | if ( is_string( $local_path ) ) { 22 | $icons = array( $local_path ); 23 | } else { 24 | global $fs_active_plugins; 25 | 26 | $img_dir = WP_FS__DIR_IMG; 27 | 28 | if ( 1 < count( $fs_active_plugins->plugins ) ) { 29 | $plugin_or_theme_img_dir = ( $fs->is_plugin() ? WP_PLUGIN_DIR : get_theme_root() ); 30 | 31 | foreach ( $fs_active_plugins->plugins as $sdk_path => &$data ) { 32 | if ( $data->plugin_path == $fs->get_plugin_basename() ) { 33 | $img_dir = $plugin_or_theme_img_dir 34 | . '/' 35 | . str_replace( '../themes/', '', $sdk_path ) 36 | . '/assets/img'; 37 | 38 | break; 39 | } 40 | } 41 | } 42 | 43 | if ( $fs->is_theme() ) { 44 | $icons = array( 45 | fs_normalize_path( $img_dir . '/theme-icon.png' ) 46 | ); 47 | } else { 48 | $icons = glob( fs_normalize_path( $img_dir . '/' . $slug . '.*' ) ); 49 | if ( ! is_array( $icons ) || 0 === count( $icons ) ) { 50 | $icon_found = false; 51 | $local_path = fs_normalize_path( $img_dir . '/' . $slug . '.png' ); 52 | 53 | $have_write_permissions = ( 'direct' === get_filesystem_method( array(), fs_normalize_path( $img_dir ) ) ); 54 | 55 | if ( WP_FS__IS_LOCALHOST && $fs->is_org_repo_compliant() && $have_write_permissions ) { 56 | /** 57 | * IMPORTANT: THIS CODE WILL NEVER RUN AFTER THE PLUGIN IS IN THE REPO. 58 | * 59 | * This code will only be executed once during the testing 60 | * of the plugin in a local environment. The plugin icon file WILL 61 | * already exist in the assets folder when the plugin is deployed to 62 | * the repository. 63 | */ 64 | if ( ! function_exists( 'plugins_api' ) ) { 65 | require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; 66 | } 67 | 68 | $plugin_information = plugins_api( 'plugin_information', array( 69 | 'slug' => $slug, 70 | 'fields' => array( 71 | 'sections' => false, 72 | 'tags' => false, 73 | 'icons' => true 74 | ) 75 | ) ); 76 | 77 | if ( 78 | ! is_wp_error( $plugin_information ) 79 | && isset( $plugin_information->icons ) 80 | && ! empty( $plugin_information->icons ) 81 | ) { 82 | /** 83 | * Get the smallest icon. 84 | * 85 | * @author Leo Fajardo (@leorw) 86 | * @since 1.2.2 87 | */ 88 | $icon = end( $plugin_information->icons ); 89 | 90 | if ( 0 !== strpos( $icon, 'http' ) ) { 91 | $icon = 'http:' . $icon; 92 | } 93 | 94 | /** 95 | * Get a clean file extension, e.g.: "jpg" and not "jpg?rev=1305765". 96 | * 97 | * @author Leo Fajardo (@leorw) 98 | * @since 1.2.2 99 | */ 100 | $ext = pathinfo( strtok( $icon, '?' ), PATHINFO_EXTENSION ); 101 | 102 | $local_path = fs_normalize_path( $img_dir . '/' . $slug . '.' . $ext ); 103 | 104 | // Try to download the icon. 105 | $icon_found = fs_download_image( $icon, $local_path ); 106 | } 107 | } 108 | 109 | if ( ! $icon_found ) { 110 | // No icons found, fallback to default icon. 111 | if ( $have_write_permissions ) { 112 | // If have write permissions, copy default icon. 113 | copy( fs_normalize_path( $img_dir . '/plugin-icon.png' ), $local_path ); 114 | } else { 115 | // If doesn't have write permissions, use default icon path. 116 | $local_path = fs_normalize_path( $img_dir . '/plugin-icon.png' ); 117 | } 118 | } 119 | 120 | $icons = array( $local_path ); 121 | } 122 | } 123 | } 124 | 125 | $icon_dir = dirname( $icons[0] ); 126 | $relative_url = fs_img_url( substr( $icons[0], strlen( $icon_dir ) ), $icon_dir ); 127 | ?> 128 |
    129 | 130 |
    -------------------------------------------------------------------------------- /includes/templates/contact.php: -------------------------------------------------------------------------------- 1 | get_slug(); 48 | 49 | $context_params = array( 50 | 'plugin_id' => $fs->get_id(), 51 | 'plugin_public_key' => $fs->get_public_key(), 52 | 'plugin_version' => $fs->get_plugin_version(), 53 | ); 54 | 55 | 56 | // Get site context secure params. 57 | if ( $fs->is_registered() ) { 58 | $context_params = array_merge( $context_params, FS_Security::instance()->get_context_params( 59 | $fs->get_site(), 60 | time(), 61 | 'contact' 62 | ) ); 63 | } 64 | 65 | $query_params = array_merge( $_GET, array_merge( $context_params, array( 66 | 'plugin_version' => $fs->get_plugin_version(), 67 | 'wp_login_url' => wp_login_url(), 68 | 'site_url' => get_site_url(), 69 | // 'wp_admin_css' => get_bloginfo('wpurl') . "/wp-admin/load-styles.php?c=1&load=buttons,wp-admin,dashicons", 70 | ) ) ); 71 | 72 | $view_params = array( 73 | 'id' => $VARS['id'], 74 | 'page' => strtolower( $fs->get_text_inline( 'Contact', 'contact' ) ), 75 | ); 76 | fs_require_once_template('secure-https-header.php', $view_params); 77 | 78 | $has_tabs = $fs->_add_tabs_before_content(); 79 | 80 | if ( $has_tabs ) { 81 | $query_params['tabs'] = 'true'; 82 | } 83 | ?> 84 |
    85 |
    86 | 111 |
    112 | _add_tabs_after_content(); 115 | } 116 | 117 | $params = array( 118 | 'page' => 'contact', 119 | 'module_id' => $fs->get_id(), 120 | 'module_type' => $fs->get_module_type(), 121 | 'module_slug' => $slug, 122 | 'module_version' => $fs->get_plugin_version(), 123 | ); 124 | fs_require_template( 'powered-by.php', $params ); -------------------------------------------------------------------------------- /includes/includes/entities/class-fs-affiliate-terms.php: -------------------------------------------------------------------------------- 1 | commission_type ) ? 98 | ( '$' . $this->commission ) : 99 | ( $this->commission . '%' ); 100 | } 101 | 102 | /** 103 | * @author Leo Fajardo (@leorw) 104 | * 105 | * @return bool 106 | */ 107 | function has_lifetime_commission() { 108 | return ( 0 !== $this->future_payments_days ); 109 | } 110 | 111 | /** 112 | * @author Leo Fajardo (@leorw) 113 | * 114 | * @return bool 115 | */ 116 | function is_session_cookie() { 117 | return ( 0 == $this->cookie_days ); 118 | } 119 | 120 | /** 121 | * @author Leo Fajardo (@leorw) 122 | * 123 | * @return bool 124 | */ 125 | function has_renewals_commission() { 126 | return ( is_null( $this->commission_renewals_days ) || $this->commission_renewals_days > 0 ); 127 | } 128 | } -------------------------------------------------------------------------------- /includes/templates/debug/scheduled-crons.php: -------------------------------------------------------------------------------- 1 | get_option( 'plugins' ); 15 | $scheduled_crons = array(); 16 | 17 | $module_types = array( 18 | WP_FS__MODULE_TYPE_PLUGIN, 19 | WP_FS__MODULE_TYPE_THEME 20 | ); 21 | 22 | foreach ( $module_types as $module_type ) { 23 | $modules = $fs_options->get_option( $module_type . 's' ); 24 | if ( is_array( $modules ) && count( $modules ) > 0 ) { 25 | foreach ( $modules as $slug => $data ) { 26 | if ( WP_FS__MODULE_TYPE_THEME === $module_type ) { 27 | $current_theme = wp_get_theme(); 28 | $is_active = ( $current_theme->stylesheet === $data->file ); 29 | } else { 30 | $is_active = is_plugin_active( $data->file ); 31 | } 32 | 33 | /** 34 | * @author Vova Feldman 35 | * 36 | * @since 1.2.1 Don't load data from inactive modules. 37 | */ 38 | if ( $is_active ) { 39 | $fs = freemius( $data->id ); 40 | 41 | $next_execution = $fs->next_sync_cron(); 42 | $last_execution = $fs->last_sync_cron(); 43 | 44 | if ( false !== $next_execution ) { 45 | $scheduled_crons[ $slug ][] = array( 46 | 'name' => $fs->get_plugin_name(), 47 | 'slug' => $slug, 48 | 'module_type' => $fs->get_module_type(), 49 | 'type' => 'sync_cron', 50 | 'last' => $last_execution, 51 | 'next' => $next_execution, 52 | ); 53 | } 54 | 55 | $next_install_execution = $fs->next_install_sync(); 56 | $last_install_execution = $fs->last_install_sync(); 57 | 58 | if (false !== $next_install_execution || 59 | false !== $last_install_execution 60 | ) { 61 | $scheduled_crons[ $slug ][] = array( 62 | 'name' => $fs->get_plugin_name(), 63 | 'slug' => $slug, 64 | 'module_type' => $fs->get_module_type(), 65 | 'type' => 'install_sync', 66 | 'last' => $last_install_execution, 67 | 'next' => $next_install_execution, 68 | ); 69 | } 70 | } 71 | } 72 | } 73 | } 74 | 75 | $sec_text = fs_text_x_inline( 'sec', 'seconds' ); 76 | ?> 77 |

    78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 96 | $crons ) : ?> 97 | 98 | 99 | 100 | 101 | 102 | 103 | 118 | 133 | 134 | 135 | 136 | 137 |
    138 | -------------------------------------------------------------------------------- /js/arrive.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * arrive.js 3 | * v2.4.1 4 | * https://github.com/uzairfarooq/arrive 5 | * MIT licensed 6 | * 7 | * Copyright (c) 2014-2017 Uzair Farooq 8 | */ 9 | 10 | var Arrive=function(e,t,n){"use strict";function r(e,t,n){l.addMethod(t,n,e.unbindEvent),l.addMethod(t,n,e.unbindEventWithSelectorOrCallback),l.addMethod(t,n,e.unbindEventWithSelectorAndCallback)}function i(e){e.arrive=f.bindEvent,r(f,e,"unbindArrive"),e.leave=d.bindEvent,r(d,e,"unbindLeave")}if(e.MutationObserver&&"undefined"!=typeof HTMLElement){var o=0,l=function(){var t=HTMLElement.prototype.matches||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector;return{matchesSelector:function(e,n){return e instanceof HTMLElement&&t.call(e,n)},addMethod:function(e,t,r){var i=e[t];e[t]=function(){return r.length==arguments.length?r.apply(this,arguments):"function"==typeof i?i.apply(this,arguments):n}},callCallbacks:function(e,t){t&&t.options.onceOnly&&1==t.firedElems.length&&(e=[e[0]]);for(var n,r=0;n=e[r];r++)n&&n.callback&&n.callback.call(n.elem,n.elem);t&&t.options.onceOnly&&1==t.firedElems.length&&t.me.unbindEventWithSelectorAndCallback.call(t.target,t.selector,t.callback)},checkChildNodesRecursively:function(e,t,n,r){for(var i,o=0;i=e[o];o++)n(i,t,r)&&r.push({callback:t.callback,elem:i}),i.childNodes.length>0&&l.checkChildNodesRecursively(i.childNodes,t,n,r)},mergeArrays:function(e,t){var n,r={};for(n in e)e.hasOwnProperty(n)&&(r[n]=e[n]);for(n in t)t.hasOwnProperty(n)&&(r[n]=t[n]);return r},toElementsArray:function(t){return n===t||"number"==typeof t.length&&t!==e||(t=[t]),t}}}(),c=function(){var e=function(){this._eventsBucket=[],this._beforeAdding=null,this._beforeRemoving=null};return e.prototype.addEvent=function(e,t,n,r){var i={target:e,selector:t,options:n,callback:r,firedElems:[]};return this._beforeAdding&&this._beforeAdding(i),this._eventsBucket.push(i),i},e.prototype.removeEvent=function(e){for(var t,n=this._eventsBucket.length-1;t=this._eventsBucket[n];n--)if(e(t)){this._beforeRemoving&&this._beforeRemoving(t);var r=this._eventsBucket.splice(n,1);r&&r.length&&(r[0].callback=null)}},e.prototype.beforeAdding=function(e){this._beforeAdding=e},e.prototype.beforeRemoving=function(e){this._beforeRemoving=e},e}(),a=function(t,r){var i=new c,o=this,a={fireOnAttributesModification:!1};return i.beforeAdding(function(n){var i,l=n.target;(l===e.document||l===e)&&(l=document.getElementsByTagName("html")[0]),i=new MutationObserver(function(e){r.call(this,e,n)});var c=t(n.options);i.observe(l,c),n.observer=i,n.me=o}),i.beforeRemoving(function(e){e.observer.disconnect()}),this.bindEvent=function(e,t,n){t=l.mergeArrays(a,t);for(var r=l.toElementsArray(this),o=0;o0?l.checkChildNodesRecursively(n,t,r,o):"attributes"===e.type&&r(i,t,o)&&o.push({callback:t.callback,elem:i}),l.callCallbacks(o,t)})}function r(e,t){return l.matchesSelector(e,t.selector)&&(e._id===n&&(e._id=o++),-1==t.firedElems.indexOf(e._id))?(t.firedElems.push(e._id),!0):!1}var i={fireOnAttributesModification:!1,onceOnly:!1,existing:!1};f=new a(e,t);var c=f.bindEvent;return f.bindEvent=function(e,t,r){n===r?(r=t,t=i):t=l.mergeArrays(i,t);var o=l.toElementsArray(this);if(t.existing){for(var a=[],s=0;s0&&l.checkChildNodesRecursively(n,t,r,i),l.callCallbacks(i,t)})}function r(e,t){return l.matchesSelector(e,t.selector)}var i={};d=new a(e,t);var o=d.bindEvent;return d.bindEvent=function(e,t,r){n===r?(r=t,t=i):t=l.mergeArrays(i,t),o.call(this,e,t,r)},d},f=new s,d=new u;t&&i(t.fn),i(HTMLElement.prototype),i(NodeList.prototype),i(HTMLCollection.prototype),i(HTMLDocument.prototype),i(Window.prototype);var h={};return r(f,h,"unbindAllArrive"),r(d,h,"unbindAllLeave"),h}}(window,"undefined"==typeof jQuery?null:jQuery,void 0); -------------------------------------------------------------------------------- /includes/assets/scss/admin/account.scss: -------------------------------------------------------------------------------- 1 | @import "../start"; 2 | 3 | #fs_account 4 | { 5 | .postbox, 6 | .widefat 7 | { 8 | max-width: 700px; 9 | } 10 | 11 | h3 12 | { 13 | font-size: 1.3em; 14 | padding: 12px 15px; 15 | margin: 0 0 12px 0; 16 | line-height: 1.4; 17 | border-bottom: 1px solid #F1F1F1; 18 | 19 | .dashicons { 20 | width: 26px; 21 | height: 26px; 22 | font-size: 1.3em; 23 | } 24 | } 25 | 26 | i.dashicons 27 | { 28 | font-size: 1.2em; 29 | height: 1.2em; 30 | width: 1.2em; 31 | } 32 | 33 | .button 34 | { 35 | i.dashicons 36 | { 37 | vertical-align: middle; 38 | } 39 | } 40 | 41 | .fs-header-actions 42 | { 43 | position: absolute; 44 | top: 17px; 45 | right: 15px; 46 | font-size: 0.9em; 47 | 48 | ul 49 | { 50 | margin: 0; 51 | } 52 | 53 | li 54 | { 55 | form 56 | { 57 | display: inline-block; 58 | } 59 | 60 | float: left; 61 | a 62 | { 63 | text-decoration: none; 64 | } 65 | } 66 | } 67 | } 68 | 69 | #fs_account_details .button-group { 70 | float: right; 71 | } 72 | 73 | .rtl #fs_account .fs-header-actions 74 | { 75 | left: 15px; 76 | right: auto; 77 | } 78 | 79 | .fs-key-value-table 80 | { 81 | width: 100%; 82 | 83 | form 84 | { 85 | display: inline-block; 86 | } 87 | 88 | tr 89 | { 90 | td:first-child 91 | { 92 | nobr 93 | { 94 | font-weight: bold; 95 | } 96 | 97 | text-align: right; 98 | 99 | form 100 | { 101 | display: block; 102 | } 103 | } 104 | 105 | td.fs-right 106 | { 107 | text-align: right; 108 | } 109 | 110 | &.fs-odd 111 | { 112 | background: #ebebeb; 113 | } 114 | } 115 | 116 | td, th 117 | { 118 | padding: 10px; 119 | } 120 | 121 | code { 122 | line-height: 28px; 123 | } 124 | 125 | var, code, input[type="text"] 126 | { 127 | color: #0073AA; 128 | font-size: 16px; 129 | background: none; 130 | } 131 | 132 | input[type="text"] { 133 | width: 100%; 134 | font-weight: bold; 135 | } 136 | } 137 | 138 | label.fs-tag 139 | { 140 | background: #ffba00; 141 | color: #fff; 142 | display: inline-block; 143 | border-radius: 3px; 144 | padding: 5px; 145 | font-size: 11px; 146 | line-height: 11px; 147 | vertical-align: baseline; 148 | 149 | &.fs-warn 150 | { 151 | background: #ffba00; 152 | } 153 | &.fs-success 154 | { 155 | background: #46b450; 156 | } 157 | &.fs-error 158 | { 159 | background: #dc3232; 160 | } 161 | } 162 | 163 | #fs_addons 164 | { 165 | h3 166 | { 167 | border: none; 168 | margin-bottom: 0; 169 | padding: 4px 5px; 170 | } 171 | 172 | td 173 | { 174 | vertical-align: middle; 175 | } 176 | 177 | thead { 178 | white-space: nowrap; 179 | } 180 | 181 | td:first-child, 182 | th:first-child 183 | { 184 | text-align: left; 185 | font-weight: bold; 186 | } 187 | td:last-child, 188 | th:last-child 189 | { 190 | text-align: right; 191 | } 192 | th 193 | { 194 | font-weight: bold; 195 | } 196 | } 197 | 198 | #fs_billing_address { 199 | width: 100%; 200 | 201 | tr { 202 | td { 203 | width: 50%; 204 | padding: 5px; 205 | } 206 | 207 | &:first-of-type { 208 | td { 209 | padding-top: 0; 210 | } 211 | } 212 | } 213 | 214 | @mixin read-mode { 215 | border-color: transparent; 216 | color: #777; 217 | border-bottom: 1px dashed #ccc; 218 | padding-left: 0; 219 | background: none; 220 | } 221 | 222 | span { 223 | font-weight: bold; 224 | } 225 | 226 | input, select { 227 | @include placeholder(transparent); 228 | 229 | display: block; 230 | width: 100%; 231 | margin-top: 5px; 232 | 233 | &.fs-read-mode { 234 | @include read-mode(); 235 | } 236 | } 237 | 238 | 239 | &.fs-read-mode { 240 | td span { 241 | display: none; 242 | } 243 | 244 | input, select 245 | { 246 | @include read-mode(); 247 | @include placeholder(#ccc); 248 | } 249 | } 250 | 251 | 252 | button { 253 | display: block; 254 | width: 100%; 255 | } 256 | } -------------------------------------------------------------------------------- /includes/assets/scss/admin/common.scss: -------------------------------------------------------------------------------- 1 | @import "../start"; 2 | @import "themes"; 3 | 4 | #iframe 5 | { 6 | line-height: 0; 7 | font-size: 0; 8 | } 9 | 10 | .fs-full-size-wrapper 11 | { 12 | margin: 40px 0 -65px -20px; 13 | 14 | @media (max-width: 600px) { 15 | margin: 0 0 -65px -10px; 16 | } 17 | } 18 | 19 | .fs-notice 20 | { 21 | position: relative; 22 | 23 | &.fs-has-title 24 | { 25 | margin-bottom: 30px !important; 26 | } 27 | 28 | &.success 29 | { 30 | color: green; 31 | // font-weight: normal; 32 | } 33 | 34 | &.promotion 35 | { 36 | border-color: $fs-notice-promotion-border-color !important; 37 | background-color: $fs-notice-promotion-bkg !important; 38 | } 39 | 40 | .fs-notice-body 41 | { 42 | margin: .5em 0; 43 | padding: 2px; 44 | } 45 | 46 | .fs-close 47 | { 48 | // position: absolute; 49 | // top: 2px; 50 | // bottom: 2px; 51 | // right: 2px; 52 | // min-width: 100px; 53 | // text-align: center; 54 | // padding-right: 2px; 55 | cursor: pointer; 56 | color: #aaa; 57 | float: right; 58 | 59 | &:hover 60 | { 61 | color: #666; 62 | // background: #A9A9A9; 63 | } 64 | 65 | > * 66 | { 67 | margin-top: 7px; 68 | display: inline-block; 69 | } 70 | } 71 | 72 | label.fs-plugin-title 73 | { 74 | background: rgba(0, 0, 0, 0.3); 75 | color: #fff; 76 | padding: 2px 10px; 77 | position: absolute; 78 | top: 100%; 79 | bottom: auto; 80 | right: auto; 81 | @include border-radius(0 0 3px 3px); 82 | left: 10px; 83 | font-size: 12px; 84 | font-weight: bold; 85 | cursor: auto; 86 | } 87 | } 88 | 89 | div.fs-notice 90 | { 91 | &.updated, 92 | &.success, 93 | &.promotion 94 | { 95 | display: block !important; 96 | } 97 | } 98 | 99 | .rtl .fs-notice 100 | { 101 | .fs-close 102 | { 103 | // left: 2px; 104 | // right: auto; 105 | // padding-right: 0; 106 | // padding-left: 2px; 107 | float: left; 108 | } 109 | } 110 | 111 | .fs-secure-notice 112 | { 113 | position: fixed; 114 | top: 32px; 115 | left: 160px; 116 | right: 0; 117 | background: rgb(235, 253, 235); 118 | padding: 10px 20px; 119 | color: green; 120 | z-index: 9999; 121 | @include box-shadow(0 2px 2px rgba(6, 113, 6, 0.3)); 122 | @include opacity(0.95); 123 | 124 | &:hover 125 | { 126 | @include opacity(1); 127 | } 128 | 129 | a.fs-security-proof 130 | { 131 | color: green; 132 | text-decoration: none; 133 | } 134 | } 135 | 136 | @media screen and (max-width: 960px) { 137 | .fs-secure-notice 138 | { 139 | left: 36px; 140 | } 141 | } 142 | 143 | @media screen and (max-width: 600px) { 144 | .fs-secure-notice 145 | { 146 | display: none; 147 | } 148 | } 149 | 150 | @media screen and (max-width: 500px) { 151 | #fs_promo_tab 152 | { 153 | display: none; 154 | } 155 | } 156 | 157 | @media screen and (max-width: 782px) { 158 | .fs-secure-notice 159 | { 160 | left: 0; 161 | top: 46px; 162 | text-align: center; 163 | } 164 | } 165 | 166 | span.fs-submenu-item.fs-sub:before 167 | { 168 | // Add small arrow. 169 | content: '\21B3'; 170 | padding: 0 5px; 171 | } 172 | 173 | .rtl 174 | { 175 | span.fs-submenu-item.fs-sub:before 176 | { 177 | // Add small RTL arrow. 178 | content: '\21B2'; 179 | } 180 | } 181 | 182 | .fs-submenu-item 183 | { 184 | &.pricing 185 | { 186 | &.upgrade-mode 187 | { 188 | color: greenyellow; 189 | } 190 | 191 | &.trial-mode 192 | { 193 | color: #83e2ff; 194 | } 195 | } 196 | } 197 | 198 | #adminmenu .update-plugins.fs-trial 199 | { 200 | background-color: #00b9eb; 201 | } 202 | .fs-ajax-spinner 203 | { 204 | border: 0; 205 | width: 20px; 206 | height: 20px; 207 | margin-right: 5px; 208 | vertical-align: sub; 209 | display: inline-block; 210 | background: url('../../../../../../../wp-admin/images/wpspin_light-2x.gif'); 211 | background-size: contain; 212 | } 213 | 214 | .wrap.fs-section { 215 | h2 { 216 | text-align: left; 217 | } 218 | } -------------------------------------------------------------------------------- /includes/assets/js/postmessage.js: -------------------------------------------------------------------------------- 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); -------------------------------------------------------------------------------- /js/list.pagination.min.js: -------------------------------------------------------------------------------- 1 | !function(){function a(b,c,d){var e=a.resolve(b);if(null==e){d=d||b,c=c||"root";var f=new Error('Failed to require "'+d+'" from "'+c+'"');throw f.path=d,f.parent=c,f.require=!0,f}var g=a.modules[e];if(!g._resolving&&!g.exports){var h={};h.exports={},h.client=h.component=!0,g._resolving=!0,g.call(this,h.exports,a.relative(e),h),delete g._resolving,g.exports=h.exports}return g.exports}a.modules={},a.aliases={},a.resolve=function(b){"/"===b.charAt(0)&&(b=b.slice(1));for(var c=[b,b+".js",b+".json",b+"/index.js",b+"/index.json"],d=0;d=p;p++){var q=l===p?"active":"";g.number(p,n,o,l,m)?(e=b.add({page:p,dotted:!1})[0],q&&d(e.elm).add(q),h(e.elm,p,j)):g.dotted(p,n,o,l,m,b.size())&&(e=b.add({page:"...",dotted:!0})[0],d(e.elm).add("disabled"))}},g={number:function(a,b,c,d,e){return this.left(a,b)||this.right(a,c)||this.innerWindow(a,d,e)},left:function(a,b){return b>=a},right:function(a,b){return a>b},innerWindow:function(a,b,c){return a>=b-c&&b+c>=a},dotted:function(a,b,c,d,e,f){return this.dottedLeft(a,b,c,d,e)||this.dottedRight(a,b,c,d,e,f)},dottedLeft:function(a,b,c,d,e){return a==b+1&&!this.innerWindow(a,d,e)&&!this.right(a,c)},dottedRight:function(a,c,d,e,f,g){return b.items[g-1].values().dotted?!1:a==d&&!this.innerWindow(a,e,f)&&!this.right(a,d)}},h=function(a,b,d){e.bind(a,"click",function(){c.show((b-1)*d+1,d)})};return{init:function(d){c=d,b=new List(c.listContainer.id,{listClass:a.paginationClass||"pagination",item:"
  • ",valueNames:["page","dotted"],searchClass:"pagination-search-that-is-not-supposed-to-exist",sortClass:"pagination-sort-that-is-not-supposed-to-exist"}),c.on("updated",f),f()},name:a.name||"pagination"}}}),a.alias("component-classes/index.js","list.pagination.js/deps/classes/index.js"),a.alias("component-classes/index.js","classes/index.js"),a.alias("component-indexof/index.js","component-classes/deps/indexof/index.js"),a.alias("component-event/index.js","list.pagination.js/deps/event/index.js"),a.alias("component-event/index.js","event/index.js"),a.alias("component-indexof/index.js","list.pagination.js/deps/indexof/index.js"),a.alias("component-indexof/index.js","indexof/index.js"),a.alias("list.pagination.js/index.js","list.pagination.js/index.js"),"object"==typeof exports?module.exports=a("list.pagination.js"):"function"==typeof define&&define.amd?define(function(){return a("list.pagination.js")}):this.ListPagination=a("list.pagination.js")}(); -------------------------------------------------------------------------------- /includes/assets/js/nojquery.ba-postmessage.js: -------------------------------------------------------------------------------- 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 | } -------------------------------------------------------------------------------- /includes/includes/entities/class-fs-plugin-license.php: -------------------------------------------------------------------------------- 1 | is_active() || $this->is_expired() ) { 99 | return 0; 100 | } 101 | 102 | if ( $this->is_unlimited() ) { 103 | return 999; 104 | } 105 | 106 | return ( $this->quota - $this->activated - ( $this->is_free_localhost ? 0 : $this->activated_local ) ); 107 | } 108 | 109 | /** 110 | * Check if single site license. 111 | * 112 | * @author Vova Feldman (@svovaf) 113 | * @since 1.1.8.1 114 | * 115 | * @return bool 116 | */ 117 | function is_single_site() { 118 | return ( is_numeric( $this->quota ) && 1 == $this->quota ); 119 | } 120 | 121 | /** 122 | * @author Vova Feldman (@svovaf) 123 | * @since 1.0.5 124 | * 125 | * @return bool 126 | */ 127 | function is_expired() { 128 | return ! $this->is_lifetime() && ( strtotime( $this->expiration ) < WP_FS__SCRIPT_START_TIME ); 129 | } 130 | 131 | /** 132 | * Check if license is not expired. 133 | * 134 | * @author Vova Feldman (@svovaf) 135 | * @since 1.2.1 136 | * 137 | * @return bool 138 | */ 139 | function is_valid() { 140 | return ! $this->is_expired(); 141 | } 142 | 143 | /** 144 | * @author Vova Feldman (@svovaf) 145 | * @since 1.0.6 146 | * 147 | * @return bool 148 | */ 149 | function is_lifetime() { 150 | return is_null( $this->expiration ); 151 | } 152 | 153 | /** 154 | * @author Vova Feldman (@svovaf) 155 | * @since 1.2.0 156 | * 157 | * @return bool 158 | */ 159 | function is_unlimited() { 160 | return is_null( $this->quota ); 161 | } 162 | 163 | /** 164 | * Check if license is fully utilized. 165 | * 166 | * @author Vova Feldman (@svovaf) 167 | * @since 1.0.6 168 | * 169 | * @param bool $is_localhost 170 | * 171 | * @return bool 172 | */ 173 | function is_utilized( $is_localhost = null ) { 174 | if ( is_null( $is_localhost ) ) { 175 | $is_localhost = WP_FS__IS_LOCALHOST_FOR_SERVER; 176 | } 177 | 178 | if ( $this->is_unlimited() ) { 179 | return false; 180 | } 181 | 182 | return ! ( $this->is_free_localhost && $is_localhost ) && 183 | ( $this->quota <= $this->activated + ( $this->is_free_localhost ? 0 : $this->activated_local ) ); 184 | } 185 | 186 | /** 187 | * @author Vova Feldman (@svovaf) 188 | * @since 1.2.1 189 | * 190 | * @return bool 191 | */ 192 | function is_active() { 193 | return ( ! $this->is_cancelled ); 194 | } 195 | 196 | /** 197 | * Check if license's plan features are enabled. 198 | * 199 | * - Either if plan not expired 200 | * - If expired, based on the configuration to block features or not. 201 | * 202 | * @author Vova Feldman (@svovaf) 203 | * @since 1.0.6 204 | * 205 | * @return bool 206 | */ 207 | function is_features_enabled() { 208 | return $this->is_active() && ( ! $this->is_block_features || ! $this->is_expired() ); 209 | } 210 | 211 | /** 212 | * Subscription considered to be new without any payments 213 | * if the license expires in less than 24 hours 214 | * from the license creation. 215 | * 216 | * @author Vova Feldman (@svovaf) 217 | * @since 1.0.9 218 | * 219 | * @return bool 220 | */ 221 | function is_first_payment_pending() { 222 | return ( WP_FS__TIME_24_HOURS_IN_SEC >= strtotime( $this->expiration ) - strtotime( $this->created ) ); 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /includes/templates/debug/api-calls.php: -------------------------------------------------------------------------------- 1 | 0, 21 | 'POST' => 0, 22 | 'PUT' => 0, 23 | 'DELETE' => 0 24 | ); 25 | 26 | $show_body = false; 27 | foreach ( $logger as $log ) { 28 | $counters[ $log['method'] ] ++; 29 | 30 | if ( ! is_null( $log['body'] ) ) { 31 | $show_body = true; 32 | } 33 | } 34 | 35 | $pretty_print = $show_body && defined( 'JSON_PRETTY_PRINT' ) && version_compare( phpversion(), '5.3', '>=' ); 36 | 37 | /** 38 | * This template is used for debugging, therefore, when possible 39 | * we'd like to prettify the output of a JSON encoded variable. 40 | * This will only be executed when $pretty_print is `true`, and 41 | * the var is `true` only for PHP 5.3 and higher. Due to the 42 | * limitations of the current Theme Check, it throws an error 43 | * that using the "options" parameter (the 2nd param) is not 44 | * supported in PHP 5.2 and lower. Thus, we added this alias 45 | * variable to work around that false-positive. 46 | * 47 | * @author Vova Feldman (@svovaf) 48 | * @since 1.2.2.7 49 | */ 50 | $encode = 'json_encode'; 51 | 52 | $root_path_len = strlen( ABSPATH ); 53 | 54 | $ms_text = fs_text_x_inline( 'ms', 'milliseconds' ); 55 | ?> 56 |

    57 | 58 |

    Total Time:

    59 | 60 |

    Total Requests:

    61 | $count ) : ?> 62 |

    :

    63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 109 | 110 | 125 | 126 | 150 | 151 | 152 | 153 | 154 | 155 |
    #
    . 88 | %s', 90 | $log['path'] 91 | ); 92 | ?> 93 | 94 | 95 | 96 | 97 | 98 | 101 | 104 | 105 | 106 | 107 | 108 | 111 | 112 | %s', 116 | substr( $body, 0, 32 ) . ( 32 < strlen( $body ) ? '...' : '' ) 117 | ); 118 | if ( $pretty_print ) { 119 | $body = $encode( json_decode( $log['body'] ), JSON_PRETTY_PRINT ); 120 | } 121 | ?> 122 |
    123 | 124 |
    127 | %s', 135 | substr( $result, 0, 32 ) . ( 32 < strlen( $result ) ? '...' : '' ) 136 | ); 137 | } 138 | 139 | if ( $is_not_empty_result && $pretty_print ) { 140 | $decoded = json_decode( $result ); 141 | if ( ! is_null( $decoded ) ) { 142 | $result = $encode( $decoded, JSON_PRETTY_PRINT ); 143 | } 144 | } else { 145 | $result = is_string( $result ) ? $result : json_encode( $result ); 146 | } 147 | ?> 148 | style="display: none"> 149 |
    -------------------------------------------------------------------------------- /includes/includes/customizer/class-fs-customizer-upsell-control.php: -------------------------------------------------------------------------------- 1 | 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() ) . '  ' . ( is_rtl() ? '←' : '➤' ); 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 | // Load features. 62 | $pricing = $this->fs->get_api_plugin_scope()->get( 'pricing.json' ); 63 | 64 | if ( $this->fs->is_api_result_object( $pricing, 'plans' ) ) { 65 | // Add support features. 66 | if ( is_array( $pricing->plans ) && 0 < count( $pricing->plans ) ) { 67 | $support_features = array( 68 | 'kb' => 'Help Center', 69 | 'forum' => 'Support Forum', 70 | 'email' => 'Priority Email Support', 71 | 'phone' => 'Phone Support', 72 | 'skype' => 'Skype Support', 73 | 'is_success_manager' => 'Personal Success Manager', 74 | ); 75 | 76 | for ( $i = 0, $len = count( $pricing->plans ); $i < $len; $i ++ ) { 77 | if ( 'free' == $pricing->plans[$i]->name ) { 78 | continue; 79 | } 80 | 81 | if ( ! isset( $pricing->plans[ $i ]->features ) || 82 | ! is_array( $pricing->plans[ $i ]->features ) ) { 83 | $pricing->plans[$i]->features = array(); 84 | } 85 | 86 | foreach ( $support_features as $key => $label ) { 87 | $key = ( 'is_success_manager' !== $key ) ? 88 | "support_{$key}" : 89 | $key; 90 | 91 | if ( ! empty( $pricing->plans[ $i ]->{$key} ) ) { 92 | 93 | $support_feature = new stdClass(); 94 | $support_feature->title = $label; 95 | 96 | $pricing->plans[ $i ]->features[] = $support_feature; 97 | } 98 | } 99 | } 100 | } 101 | } 102 | 103 | $this->json['plans'] = $pricing->plans; 104 | 105 | $this->json['strings'] = array( 106 | 'plan' => $this->fs->get_text_x_inline( 'Plan', 'as product pricing plan', 'plan' ), 107 | ); 108 | } 109 | 110 | /** 111 | * Control content 112 | */ 113 | public function content_template() { 114 | ?> 115 |
    116 | <# if ( data.plans ) { #> 117 |
      118 | <# for (i in data.plans) { #> 119 | <# if ( 'free' != data.plans[i].name && (null != data.plans[i].features && 0 < data.plans[i].features.length) ) { #> 120 |
    • 121 |
      122 | 129 |
      130 | <# if ( data.plans[i].description ) { #> 131 |

      {{ data.plans[i].description }}

      132 | <# } #> 133 | <# if ( data.plans[i].features ) { #> 134 |
        135 | <# for ( j in data.plans[i].features ) { #> 136 |
      • 137 | <# if ( data.plans[i].features[j].value ) { #>{{ data.plans[i].features[j].value }} <# } #>{{ data.plans[i].features[j].title }} 138 | <# if ( data.plans[i].features[j].description ) { #> 139 | {{ data.plans[i].features[j].description }} 140 | <# } #> 141 |
      • 142 | <# } #> 143 |
      144 | <# } #> 145 | <# if ( 'free' != data.plans[i].name ) { #> 146 | {{{ data.button_text }}} 147 | <# } #> 148 |
      149 |
      150 |
    • 151 | <# } #> 152 | <# } #> 153 |
    154 | <# } #> 155 |
    156 | _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 ); 72 | } 73 | 74 | /** 75 | * @author Leo Fajardo (@leorw) 76 | * @since 1.2.2 77 | * 78 | * @param string|false $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 $option_manager->get_option( $module_type . 's', array() ); 87 | } 88 | 89 | return array( 90 | self::OPTION_NAME_PLUGINS => $option_manager->get_option( self::OPTION_NAME_PLUGINS, array() ), 91 | self::OPTION_NAME_THEMES => $option_manager->get_option( self::OPTION_NAME_THEMES, array() ), 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 | return isset( $this->_module ) ? 215 | $this->_module : 216 | false; 217 | } 218 | 219 | 220 | } -------------------------------------------------------------------------------- /includes/templates/pricing.php: -------------------------------------------------------------------------------- 1 | get_slug(); 47 | $timestamp = time(); 48 | 49 | $context_params = array( 50 | 'plugin_id' => $fs->get_id(), 51 | 'plugin_public_key' => $fs->get_public_key(), 52 | 'plugin_version' => $fs->get_plugin_version(), 53 | ); 54 | 55 | // Get site context secure params. 56 | if ( $fs->is_registered() ) { 57 | $context_params = array_merge( $context_params, FS_Security::instance()->get_context_params( 58 | $fs->get_site(), 59 | $timestamp, 60 | 'upgrade' 61 | ) ); 62 | } else { 63 | $context_params['home_url'] = home_url(); 64 | } 65 | 66 | if ( $fs->is_payments_sandbox() ) // Append plugin secure token for sandbox mode authentication.) 67 | { 68 | $context_params['sandbox'] = FS_Security::instance()->get_secure_token( 69 | $fs->get_plugin(), 70 | $timestamp, 71 | 'checkout' 72 | ); 73 | } 74 | 75 | $query_params = array_merge( $context_params, $_GET, array( 76 | 'next' => $fs->_get_sync_license_url( false, false ), 77 | 'plugin_version' => $fs->get_plugin_version(), 78 | // Billing cycle. 79 | 'billing_cycle' => fs_request_get( 'billing_cycle', WP_FS__PERIOD_ANNUALLY ), 80 | ) ); 81 | 82 | 83 | if ( ! $fs->is_registered() ) { 84 | $template_data = array( 85 | 'id' => $fs->get_id(), 86 | ); 87 | fs_require_template( 'forms/trial-start.php', $template_data); 88 | } 89 | 90 | $view_params = array( 91 | 'id' => $VARS['id'], 92 | 'page' => strtolower( $fs->get_text_x_inline( 'Pricing', 'noun', 'pricing' ) ), 93 | ); 94 | fs_require_once_template('secure-https-header.php', $view_params); 95 | 96 | $has_tabs = $fs->_add_tabs_before_content(); 97 | 98 | if ( $has_tabs ) { 99 | $query_params['tabs'] = 'true'; 100 | } 101 | ?> 102 |
    103 |
    104 |
    105 | 106 | 107 | 108 | 109 | 110 | 111 |
    112 | 113 | 151 |
    152 | _add_tabs_after_content(); 155 | } 156 | 157 | $params = array( 158 | 'page' => 'pricing', 159 | 'module_id' => $fs->get_id(), 160 | 'module_type' => $fs->get_module_type(), 161 | 'module_slug' => $slug, 162 | 'module_version' => $fs->get_plugin_version(), 163 | ); 164 | fs_require_template( 'powered-by.php', $params ); --------------------------------------------------------------------------------