├── LICENSE.txt ├── README.md ├── assets ├── css │ ├── admin │ │ ├── account.css │ │ ├── add-ons.css │ │ ├── affiliation.css │ │ ├── checkout.css │ │ ├── clone-resolution.css │ │ ├── common.css │ │ ├── connect.css │ │ ├── debug.css │ │ ├── dialog-boxes.css │ │ ├── gdpr-optin-notice.css │ │ ├── index.php │ │ ├── optout.css │ │ └── plugins.css │ ├── customizer.css │ └── index.php ├── img │ ├── index.php │ ├── plugin-icon.png │ └── theme-icon.png ├── index.php └── js │ ├── index.php │ ├── jquery.form.js │ ├── nojquery.ba-postmessage.js │ ├── postmessage.js │ └── pricing │ ├── 14fb1bd5b7c41648488b06147f50a0dc.svg │ ├── 178afa6030e76635dbe835e111d2c507.png │ ├── 27b5a722a5553d9de0170325267fccec.png │ ├── 4375c4a3ddc6f637c2ab9a2d7220f91e.png │ ├── 4529cac82a2d1f300d3c4702b7b5e8f3.svg │ ├── 5480ed23b199531a8cbc05924f26952b.png │ ├── b4f3b958f4a019862d81b15f3f8eee3a.svg │ ├── c03f665db27af43971565560adfba594.png │ ├── cb5fc4f6ec7ada72e986f6e7dde365bf.png │ ├── dd89563360f0272635c8f0ab7d7f1402.png │ ├── e366d70661d8ad2493bd6afbd779f125.png │ ├── f18006f6535a1a6e9c6bfbffafe6f18a.svg │ ├── f3aac72a8e63997d6bb888f816457e9b.png │ ├── f928f1be99776af83e8e6be4baf8ffe7.svg │ ├── fde48e4609a6ddc11d639fc2421f2afd.png │ ├── freemius-pricing.js │ └── freemius-pricing.js.LICENSE.txt ├── composer.json ├── config.php ├── includes ├── class-freemius-abstract.php ├── class-freemius.php ├── class-fs-admin-notices.php ├── class-fs-api.php ├── class-fs-garbage-collector.php ├── class-fs-lock.php ├── class-fs-logger.php ├── class-fs-options.php ├── class-fs-plugin-updater.php ├── class-fs-security.php ├── class-fs-storage.php ├── class-fs-user-lock.php ├── customizer │ ├── class-fs-customizer-support-section.php │ ├── class-fs-customizer-upsell-control.php │ └── index.php ├── debug │ ├── class-fs-debug-bar-panel.php │ ├── debug-bar-start.php │ └── index.php ├── entities │ ├── class-fs-affiliate-terms.php │ ├── class-fs-affiliate.php │ ├── class-fs-billing.php │ ├── class-fs-entity.php │ ├── class-fs-payment.php │ ├── class-fs-plugin-info.php │ ├── class-fs-plugin-license.php │ ├── class-fs-plugin-plan.php │ ├── class-fs-plugin-tag.php │ ├── class-fs-plugin.php │ ├── class-fs-pricing.php │ ├── class-fs-scope-entity.php │ ├── class-fs-site.php │ ├── class-fs-subscription.php │ ├── class-fs-user.php │ └── index.php ├── fs-core-functions.php ├── fs-essential-functions.php ├── fs-html-escaping-functions.php ├── fs-plugin-info-dialog.php ├── index.php ├── l10n.php ├── managers │ ├── class-fs-admin-menu-manager.php │ ├── class-fs-admin-notice-manager.php │ ├── class-fs-cache-manager.php │ ├── class-fs-checkout-manager.php │ ├── class-fs-clone-manager.php │ ├── class-fs-contact-form-manager.php │ ├── class-fs-debug-manager.php │ ├── class-fs-gdpr-manager.php │ ├── class-fs-key-value-storage.php │ ├── class-fs-license-manager.php │ ├── class-fs-option-manager.php │ ├── class-fs-permission-manager.php │ ├── class-fs-plan-manager.php │ ├── class-fs-plugin-manager.php │ └── index.php ├── sdk │ ├── Exceptions │ │ ├── ArgumentNotExistException.php │ │ ├── EmptyArgumentException.php │ │ ├── Exception.php │ │ ├── InvalidArgumentException.php │ │ ├── OAuthException.php │ │ └── index.php │ ├── FreemiusBase.php │ ├── FreemiusWordPress.php │ ├── LICENSE.txt │ └── index.php └── supplements │ ├── fs-essential-functions-1.1.7.1.php │ ├── fs-essential-functions-2.2.1.php │ ├── fs-migration-2.5.1.php │ └── index.php ├── index.php ├── languages ├── freemius-cs_CZ.mo ├── freemius-da_DK.mo ├── freemius-de_DE.mo ├── freemius-es_ES.mo ├── freemius-fr_FR.mo ├── freemius-he_IL.mo ├── freemius-hu_HU.mo ├── freemius-it_IT.mo ├── freemius-ja.mo ├── freemius-nl_NL.mo ├── freemius-ru_RU.mo ├── freemius-ta.mo ├── freemius-zh_CN.mo ├── freemius.pot └── index.php ├── require.php ├── start.php └── templates ├── account.php ├── account ├── billing.php ├── index.php ├── partials │ ├── activate-license-button.php │ ├── addon.php │ ├── deactivate-license-button.php │ ├── disconnect-button.php │ ├── index.php │ └── site.php └── payments.php ├── add-ons.php ├── add-trial-to-pricing.php ├── admin-notice.php ├── ajax-loader.php ├── api-connectivity-message-js.php ├── auto-installation.php ├── checkout.php ├── checkout ├── frame.php ├── process-redirect.php └── redirect.php ├── clone-resolution-js.php ├── connect.php ├── connect ├── index.php ├── permission.php └── permissions-group.php ├── contact.php ├── debug.php ├── debug ├── api-calls.php ├── index.php ├── logger.php ├── plugins-themes-sync.php └── scheduled-crons.php ├── email.php ├── forms ├── affiliation.php ├── data-debug-mode.php ├── deactivation │ ├── contact.php │ ├── form.php │ ├── index.php │ └── retry-skip.php ├── email-address-update.php ├── index.php ├── license-activation.php ├── optout.php ├── premium-versions-upgrade-handler.php ├── premium-versions-upgrade-metadata.php ├── resend-key.php ├── subscription-cancellation.php ├── trial-start.php └── user-change.php ├── gdpr-optin-js.php ├── index.php ├── js ├── index.php ├── jquery.content-change.php ├── open-license-activation.php ├── permissions.php └── style-premium-theme.php ├── partials ├── index.php └── network-activation.php ├── plugin-icon.php ├── plugin-info ├── description.php ├── features.php ├── index.php └── screenshots.php ├── pricing.php ├── secure-https-header.php ├── sticky-admin-notice-js.php ├── tabs-capture-js.php └── tabs.php /assets/css/admin/account.css: -------------------------------------------------------------------------------- 1 | label.fs-tag,span.fs-tag{background:#ffba00;border-radius:3px;color:#fff;display:inline-block;font-size:11px;line-height:11px;padding:5px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-notice[data-id=license_not_whitelabeled].success,.fs-notice[data-id=license_whitelabeled].success{border-left-color:#00a0d2;color:inherit}.fs-notice[data-id=license_not_whitelabeled].success label.fs-plugin-title,.fs-notice[data-id=license_whitelabeled].success label.fs-plugin-title{display:none}#fs_account .postbox,#fs_account .widefat{max-width:800px}#fs_account h3{border-bottom:1px solid #f1f1f1;font-size:1.3em;line-height:1.4;margin:0 0 12px;padding:12px 15px}#fs_account h3 .dashicons{font-size:1.3em;height:26px;width:26px}#fs_account i.dashicons{font-size:1.2em;height:1.2em;width:1.2em}#fs_account .dashicons{vertical-align:middle}#fs_account .fs-header-actions{font-size:.9em;position:absolute;right:15px;top:17px}#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:700}.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 code,.fs-key-value-table input[type=text],.fs-key-value-table var{background:none;color:#0073aa;font-size:16px}.fs-key-value-table input[type=text]{font-weight:700;width:100%}.fs-field-beta_program label{margin-left:7px}label.fs-tag{border-radius:3px;color:#fff;display:inline-block;font-size:11px;line-height:11px;padding:5px;vertical-align:baseline}label.fs-tag,label.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error{background:#dc3232}#fs_sites .fs-scrollable-table .fs-table-body{border:1px solid #e5e5e5;max-height:200px;overflow:auto}#fs_sites .fs-scrollable-table .fs-table-body>table.widefat{border:none!important}#fs_sites .fs-scrollable-table .fs-main-column{width:100%}#fs_sites .fs-scrollable-table .fs-site-details td:first-of-type{color:gray;text-align:right;width:1px}#fs_sites .fs-scrollable-table .fs-site-details td:last-of-type{text-align:right}#fs_sites .fs-scrollable-table .fs-install-details table tr td{white-space:nowrap;width:1px}#fs_sites .fs-scrollable-table .fs-install-details table tr td:last-of-type{width:auto}#fs_addons h3{border:none;margin-bottom:0;padding:4px 5px}#fs_addons td{vertical-align:middle}#fs_addons thead{white-space:nowrap}#fs_addons td:first-child,#fs_addons th:first-child{font-weight:700;text-align:left}#fs_addons td:last-child,#fs_addons th:last-child{text-align:right}#fs_addons th{font-weight:700}#fs_billing_address{width:100%}#fs_billing_address tr td{padding:5px;width:50%}#fs_billing_address tr:first-of-type td{padding-top:0}#fs_billing_address span{font-weight:700}#fs_billing_address input,#fs_billing_address select{display:block;margin-top:5px;width:100%}#fs_billing_address input::-moz-placeholder,#fs_billing_address select::-moz-placeholder{color:transparent}#fs_billing_address input::placeholder,#fs_billing_address select::placeholder{color:transparent}#fs_billing_address input.fs-read-mode,#fs_billing_address select.fs-read-mode{background:none;border-color:transparent;border-bottom:1px dashed #ccc;color:#777;padding-left:0}#fs_billing_address.fs-read-mode td span{display:none}#fs_billing_address.fs-read-mode input,#fs_billing_address.fs-read-mode select{background:none;border-color:transparent;border-bottom:1px dashed #ccc;color:#777;padding-left:0}#fs_billing_address.fs-read-mode input::-moz-placeholder,#fs_billing_address.fs-read-mode select::-moz-placeholder{color:#ccc}#fs_billing_address.fs-read-mode input::placeholder,#fs_billing_address.fs-read-mode select::placeholder{color:#ccc}#fs_billing_address button{display:block;width:100%}@media screen and (max-width:639px){#fs_account .fs-header-actions{margin:0 0 12px;padding:0 15px 12px;position:static}#fs_account .fs-header-actions li{display:inline-block;float:none}#fs_account #fs_account_details,#fs_account #fs_account_details tbody,#fs_account #fs_account_details td,#fs_account #fs_account_details th,#fs_account #fs_account_details tr{display:block}#fs_account #fs_account_details tr td:first-child{text-align:left}#fs_account #fs_account_details tr td:nth-child(2){padding:0 12px}#fs_account #fs_account_details tr td:nth-child(2) code{margin:0;padding:0}#fs_account #fs_account_details tr td:nth-child(2) label{margin-left:0}#fs_account #fs_account_details tr td:nth-child(3){text-align:left}#fs_account #fs_account_details tr.fs-field-plan td:nth-child(2) .button-group{float:none;margin:12px 0}} -------------------------------------------------------------------------------- /assets/css/admin/affiliation.css: -------------------------------------------------------------------------------- 1 | #fs_affiliation_content_wrapper #messages{margin-top:25px}#fs_affiliation_content_wrapper h3{font-size:24px;margin-left:0;padding:0}#fs_affiliation_content_wrapper ul li{box-sizing:border-box;list-style-type:none}#fs_affiliation_content_wrapper ul li:before{content:"✓";font-weight:700;margin-right:10px}#fs_affiliation_content_wrapper label,#fs_affiliation_content_wrapper li,#fs_affiliation_content_wrapper p:not(.description){font-size:16px!important;line-height:26px!important}#fs_affiliation_content_wrapper .button{font-size:16px;height:40px;line-height:35px;margin-bottom:7px;margin-top:20px}#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{display:block;font-weight:700;width:100%}#fs_affiliation_content_wrapper form .input-container.input-container-text input,#fs_affiliation_content_wrapper form .input-container.input-container-text label,#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{display:inline-block;margin-top:3px;text-decoration:none}#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} -------------------------------------------------------------------------------- /assets/css/admin/checkout.css: -------------------------------------------------------------------------------- 1 | .fs-ajax-loader{height:20px;margin:auto;position:relative;width:170px}.fs-ajax-loader .fs-ajax-loader-bar{animation-direction:normal;animation-duration:1.5s;animation-iteration-count:infinite;animation-name:bounce_ajaxLoader;background-color:#fff;height:20px;position:absolute;top:0;transform:scale(.3);width:20px}.fs-ajax-loader .fs-ajax-loader-bar-1{animation-delay:.6s;left:0}.fs-ajax-loader .fs-ajax-loader-bar-2{animation-delay:.75s;left:19px}.fs-ajax-loader .fs-ajax-loader-bar-3{animation-delay:.9s;left:38px}.fs-ajax-loader .fs-ajax-loader-bar-4{animation-delay:1.05s;left:57px}.fs-ajax-loader .fs-ajax-loader-bar-5{animation-delay:1.2s;left:76px}.fs-ajax-loader .fs-ajax-loader-bar-6{animation-delay:1.35s;left:95px}.fs-ajax-loader .fs-ajax-loader-bar-7{animation-delay:1.5s;left:114px}.fs-ajax-loader .fs-ajax-loader-bar-8{animation-delay:1.65s;left:133px}@keyframes bounce_ajaxLoader{0%{background-color:#0074a3;transform:scale(1)}to{background-color:#fff;transform:scale(.3)}}@media screen and (max-width:782px){#wpbody-content{padding-bottom:0!important}}.fs-checkout-process-redirect{padding:40px;text-align:center} -------------------------------------------------------------------------------- /assets/css/admin/clone-resolution.css: -------------------------------------------------------------------------------- 1 | .fs-notice[data-id^=clone_resolution_options_notice]{color:inherit!important;padding:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-body{margin-bottom:0;padding:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-header{padding:5px 10px}.fs-notice[data-id^=clone_resolution_options_notice] ol{margin-bottom:0;margin-top:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{display:flex;flex-direction:row;padding:0 10px 10px}@media(max-width:750px){.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{flex-direction:column}}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option{border:1px solid #ccc;flex:auto;margin:5px;padding:10px 10px 15px}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:first-child{margin-left:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:last-child{margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option strong{font-size:1.2em;line-height:1.5em;padding:2px}.fs-notice[data-id^=clone_resolution_options_notice] a{text-decoration:none}.fs-notice[data-id^=clone_resolution_options_notice] .button{margin-right:10px}.rtl .fs-notice[data-id^=clone_resolution_options_notice] .button{margin-left:10px;margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-documentation-container{padding:0 10px 15px}.fs-notice[data-id=temporary_duplicate_notice] #fs_clone_resolution_error_message{background:#fee;border:1px solid #d3135a;color:#d3135a;padding:10px}.fs-notice[data-id=temporary_duplicate_notice] ol{margin-top:0}.fs-notice[data-id=temporary_duplicate_notice] a{position:relative}.fs-notice[data-id=temporary_duplicate_notice] a:focus{box-shadow:none}.fs-notice[data-id=temporary_duplicate_notice] a.disabled{color:gray}.fs-notice[data-id=temporary_duplicate_notice] a .fs-ajax-spinner{bottom:0;left:8px;margin-left:100%;position:absolute;right:0;top:-1px} -------------------------------------------------------------------------------- /assets/css/admin/common.css: -------------------------------------------------------------------------------- 1 | .fs-badge{background:#71ae00;border-radius:3px 0 0 3px;border-right:0;box-shadow:0 2px 1px -1px rgba(0,0,0,.3);color:#fff;font-weight:700;padding:5px 10px;position:absolute;right:0;text-transform:uppercase;top:10px}.theme-browser .theme .fs-premium-theme-badge-container{position:absolute;right:0;top:0}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge{margin-top:10px;position:relative;text-align:center;top:0}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-premium-theme-badge{font-size:1.1em}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-beta-theme-badge{background:#00a0d2}.fs-switch{background:#ececec;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);box-shadow:0 0 4px rgba(0,0,0,.1),inset 0 1px 3px 0 rgba(0,0,0,.1);color:#ccc;cursor:pointer;display:inline-block;height:18px;padding:6px 6px 5px;position:relative;text-shadow:0 1px 1px hsla(0,0%,100%,.8)}.fs-switch span{display:inline-block;text-transform:uppercase;width:35px}.fs-switch .fs-toggle{background-color:#fff;background-image:linear-gradient(180deg,#ececec,#fff);border:1px solid rgba(0,0,0,.3);border-radius:4px;box-shadow:inset 0 1px 0 0 hsla(0,0%,100%,.5);height:25px;position:absolute;top:1px;transition:.4s cubic-bezier(.54,1.6,.5,1);width:37px;z-index:999}.fs-switch.fs-off .fs-toggle{left:2%}.fs-switch.fs-on .fs-toggle{left:54%}.fs-switch.fs-round{border-radius:24px;padding:4px 25px;top:8px}.fs-switch.fs-round .fs-toggle{border-radius:24px;height:24px;top:0;width:24px}.fs-switch.fs-round.fs-off .fs-toggle{left:-1px}.fs-switch.fs-round.fs-on{background:#0085ba}.fs-switch.fs-round.fs-on .fs-toggle{left:25px}.fs-switch.fs-small.fs-round{padding:1px 19px}.fs-switch.fs-small.fs-round .fs-toggle{border-radius:18px;height:18px;top:0;width:18px}.fs-switch.fs-small.fs-round.fs-on .fs-toggle{left:19px}body.fs-loading,body.fs-loading *{cursor:wait!important}#fs_frame{font-size:0;line-height:0}.fs-full-size-wrapper{margin:40px 0 -65px -20px}@media(max-width:600px){.fs-full-size-wrapper{margin:0 0 -65px -10px}}.fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px!important}.fs-notice.success{color:green}.fs-notice.promotion{background-color:#f2fcff!important;border-color:#00a0d2!important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-notice-body .fs-trial-message-container{align-items:center;display:flex;flex-wrap:wrap;gap:5px}.fs-notice .fs-close{color:#aaa;cursor:pointer;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{display:inline-block;margin-top:7px}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,.3);border-radius:0 0 3px 3px;bottom:auto;color:#fff;cursor:auto;font-size:12px;font-weight:700;left:10px;padding:2px 10px;position:absolute;right:auto;top:100%}div.fs-notice.promotion,div.fs-notice.success,div.fs-notice.updated{display:block!important}#fs_connect .fs-error .fs-api-request-error-details,#fs_connect .fs-error .fs-api-request-error-show-details-link,#fs_connect .fs-error ol,.fs-modal .notice-error .fs-api-request-error-details,.fs-modal .notice-error .fs-api-request-error-show-details-link,.fs-modal .notice-error ol,.fs-notice.error .fs-api-request-error-details,.fs-notice.error .fs-api-request-error-show-details-link,.fs-notice.error ol{text-align:left}#fs_connect .fs-error ol,.fs-modal .notice-error ol,.fs-notice.error ol{list-style-type:disc}#fs_connect .fs-error .fs-api-request-error-show-details-link,.fs-modal .notice-error .fs-api-request-error-show-details-link,.fs-notice.error .fs-api-request-error-show-details-link{box-shadow:none;color:#2271b1;text-decoration:none}#fs_connect .fs-error .fs-api-request-error-details,.fs-modal .notice-error .fs-api-request-error-details,.fs-notice.error .fs-api-request-error-details{border:1px solid #ccc;max-height:150px;overflow:auto;padding:5px}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{background:#ebfdeb;box-shadow:0 2px 2px rgba(6,113,6,.3);color:green;left:160px;opacity:.95;padding:10px 20px;position:fixed;right:0;top:32px;z-index:9989}.fs-secure-notice:hover{opacity:1}.fs-secure-notice a.fs-security-proof{color:green;text-decoration:none}@media screen and (max-width:960px){.fs-secure-notice{left:36px}}@media screen and (max-width:600px){.fs-secure-notice{display:none}}@media screen and (max-width:1250px){#fs_promo_tab{display:none}}@media screen and (max-width:782px){.fs-secure-notice{left:0;text-align:center;top:46px}}span.fs-submenu-item.fs-sub:before{content:"↳";padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:"↲"}.fs-submenu-item.pricing.upgrade-mode{color:#adff2f}.fs-submenu-item.pricing.trial-mode{color:#83e2ff}#adminmenu .update-plugins.fs-trial{background-color:#00b9eb}.fs-ajax-spinner{background:url(/wp-admin/images/wpspin_light-2x.gif);background-size:contain;border:0;display:inline-block;height:20px;margin-bottom:-2px;margin-right:5px;vertical-align:sub;width:20px}.wrap.fs-section h2{text-align:left}.plugins p.fs-upgrade-notice{background-color:#d54e21;border:0;color:#f9f9f9;margin-top:10px;padding:10px} -------------------------------------------------------------------------------- /assets/css/admin/debug.css: -------------------------------------------------------------------------------- 1 | label.fs-tag,span.fs-tag{background:#ffba00;border-radius:3px;color:#fff;display:inline-block;font-size:11px;line-height:11px;padding:5px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-switch-label{font-size:20px;line-height:31px;margin:0 5px}.fs-debug-table-toggle-button{background:transparent;border:none;cursor:pointer;font-size:1.2em}.fs-debug-table{overflow:hidden}#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:700}#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} -------------------------------------------------------------------------------- /assets/css/admin/gdpr-optin-notice.css: -------------------------------------------------------------------------------- 1 | .fs-notice[data-id^=gdpr_optin_actions] .underlined{text-decoration:underline}.fs-notice[data-id^=gdpr_optin_actions] ul .action-description,.fs-notice[data-id^=gdpr_optin_actions] ul .button{vertical-align:middle}.fs-notice[data-id^=gdpr_optin_actions] ul .action-description{display:inline-block;margin-left:3px} -------------------------------------------------------------------------------- /assets/css/admin/index.php: -------------------------------------------------------------------------------- 1 | i.dashicons{float:left;font-size:30px;height:30px;padding:5px;width:30px}.fs-permissions ul li .fs-switch{float:right}.fs-permissions ul li .fs-permission-description{margin-left:55px}.fs-permissions ul li .fs-permission-description span{color:#23282d;font-size:14px;font-weight:500}.fs-permissions ul li .fs-permission-description .fs-tooltip{font-size:13px;font-weight:700}.fs-permissions ul li .fs-permission-description .fs-tooltip-trigger .dashicons{margin:-1px 2px 0}.fs-permissions ul li .fs-permission-description p{margin:2px 0 0}.fs-permissions.fs-open{background:#fff}.fs-permissions.fs-open ul{height:auto;margin:20px 0 10px;overflow:initial}.fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-right:10px}.fs-permissions .fs-switch-feedback.success{color:#71ae00}.rtl .fs-permissions .fs-switch-feedback{left:15px;right:auto}.rtl .fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-left:10px;margin-right:0}.rtl .fs-permissions ul li .fs-permission-description{margin-left:0;margin-right:55px}.rtl .fs-permissions ul li .fs-switch{float:left}.rtl .fs-permissions ul li i.dashicons{float:right}.fs-modal-opt-out .fs-modal-footer .fs-opt-out-button{line-height:30px;margin-right:10px}.fs-modal-opt-out .fs-permissions{margin-top:0!important}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-group-opt-out-button{float:right;line-height:1.1em}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-switch-feedback{float:right;line-height:1.1em;margin-right:10px}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-switch-feedback .fs-ajax-spinner{margin:-2px 0 0}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header-title{display:block;font-size:1.1em;font-weight:600;line-height:1.1em;margin:.5em 0;text-transform:uppercase}.fs-modal-opt-out .fs-permissions .fs-permissions-section--desc{margin-top:0}.fs-modal-opt-out .fs-permissions hr{border:0;border-top:1px solid #eee;margin:25px 0 20px}.fs-modal-opt-out .fs-permissions ul{border:1px solid #c3c4c7;border-radius:3px;box-shadow:0 1px 1px rgba(0,0,0,.04);margin:10px 0 0}.fs-modal-opt-out .fs-permissions ul li{border-bottom:1px solid #d7dde1;border-left:4px solid #72aee6}.rtl .fs-modal-opt-out .fs-permissions ul li{border-left:none;border-right:4px solid #72aee6}.fs-modal-opt-out .fs-permissions ul li.fs-disabled{border-left-color:rgba(114,174,230,0)}.fs-modal-opt-out .fs-permissions ul li:last-child{border-bottom:none} -------------------------------------------------------------------------------- /assets/css/admin/plugins.css: -------------------------------------------------------------------------------- 1 | label.fs-tag,span.fs-tag{background:#ffba00;border-radius:3px;color:#fff;display:inline-block;font-size:11px;line-height:11px;padding:5px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.wp-list-table.plugins .plugin-title span.fs-tag{display:inline-block;line-height:10px;margin-left:5px} -------------------------------------------------------------------------------- /assets/css/customizer.css: -------------------------------------------------------------------------------- 1 | #fs_customizer_upsell .fs-customizer-plan{background:#fff;border-radius:3px;padding:10px 20px 20px}#fs_customizer_upsell .fs-customizer-plan h2{line-height:2em;margin:0;position:relative;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;margin-left:-7px;margin-right:10px;vertical-align:bottom}.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{background:#000;border-radius:5px;bottom:100%;box-shadow:1px 1px 1px rgba(0,0,0,.2);color:#fff;font-family:arial,serif;font-size:12px;font-weight:700;left:0;line-height:1.3em;margin-bottom:5px;opacity:0;padding:10px;position:absolute;right:0;text-align:left;transition:opacity .3s ease-in-out;visibility:hidden;z-index:999999}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{text-align:right}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc:after{border-color:#000 transparent transparent;border-style:solid;border-width:5px 5px 0;content:" ";display:block;height:0;left:21px;position:absolute;top:100%;width:0}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc:after{left:auto;right:21px}#fs_customizer_upsell .dashicons-editor-help:hover .fs-feature-desc{opacity:1;visibility:visible}#fs_customizer_upsell .button-primary{display:block;margin-top:10px;text-align:center}#fs_customizer_support{display:block!important}#fs_customizer_support .button{float:right}#fs_customizer_support .button-group{display:block;margin-top:10px;width:100%}#fs_customizer_support .button-group .button{float:none;text-align:center;width:50%}#customize-theme-controls #accordion-section-freemius_upsell{border-bottom:1px solid #0085ba!important;border-top:1px solid #0085ba!important}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title{background-color:#0085ba;border-bottom:none!important;border-left:4px solid #0085ba;color:#fff;outline:none;transition:background-color .15s ease-in-out,border-color .15s ease-in-out}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title:hover{background-color:#008ec2;border-left-color:#0073aa}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title:after{color:#fff}#customize-theme-controls #accordion-section-freemius_upsell .rtl h3.accordion-section-title{border-left:none;border-right:4px solid #0085ba}#customize-theme-controls #accordion-section-freemius_upsell .rtl h3.accordion-section-title:hover{border-right-color:#0073aa} -------------------------------------------------------------------------------- /assets/css/index.php: -------------------------------------------------------------------------------- 1 | ").attr({method:t,action:r}).css({display:"none"}),a=function(r,e){if(n.isArray(e))for(var t=0;t").attr({type:"hidden",name:String(r),value:String(e)}))};for(var i in e)e.hasOwnProperty(i)&&a(i,e[i]);return o.appendTo("body")}})}(jQuery); -------------------------------------------------------------------------------- /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 | function NoJQueryPostMessageMixin(n,e){var t,i,o,s,a,r=1;return window.postMessage?(window.addEventListener?(t=function(n){window.addEventListener("message",n,!1)},i=function(n){window.removeEventListener("message",n,!1)}):(t=function(n){window.attachEvent("onmessage",n)},i=function(n){window.detachEvent("onmessage",n)}),this[n]=function(n,e,t){e&&t.postMessage(n,e.replace(/([^:]+:\/\/[^\/]+).*/,"$1"))},this[e]=function(n,e,s){if(o&&(i(o),o=null),!n)return!1;o=t((function(t){switch(Object.prototype.toString.call(e)){case"[object String]":if(e!==t.origin)return!1;break;case"[object Function]":if(e(t.origin))return!1}n(t)}))}):(this[n]=function(n,e,t){e&&(t.location=e.replace(/#.*$/,"")+"#"+ +new Date+r+++"&"+n)},this[e]=function(n,e,t){s&&(clearInterval(s),s=null),n&&(t="number"==typeof e?e:"number"==typeof t?t:100,s=setInterval((function(){var e=document.location.hash,t=/^#?\d+&/;e!==a&&t.test(e)&&(a=e,n({data:e.replace(t,"")}))}),t))}),this} -------------------------------------------------------------------------------- /assets/js/postmessage.js: -------------------------------------------------------------------------------- 1 | !function(t,e){var s,n,o,i,r,a,c,p,u=this;u.FS=u.FS||{},u.FS.PostMessage=(n=new NoJQueryPostMessageMixin("postMessage","receiveMessage"),o={},i=decodeURIComponent(document.location.hash.replace(/^#/,"")),r=i.substring(0,i.indexOf("/","https://"===i.substring(0,8)?8:7)),a=""!==i,c=t(window),p=t("html"),{init:function(t,e){s=t,n.receiveMessage((function(t){var e=JSON.parse(t.data);if(o[e.type])for(var s=0;s0&&c.on("scroll",(function(){for(var t=0;t 11 | * @license MIT 12 | */ 13 | 14 | /*! 15 | * Font Awesome Free 6.0.0 by @fontawesome - https://fontawesome.com 16 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 17 | * Copyright 2022 Fonticons, Inc. 18 | */ 19 | 20 | /** @license React v0.20.2 21 | * scheduler.production.min.js 22 | * 23 | * Copyright (c) Facebook, Inc. and its affiliates. 24 | * 25 | * This source code is licensed under the MIT license found in the 26 | * LICENSE file in the root directory of this source tree. 27 | */ 28 | 29 | /** @license React v17.0.2 30 | * react-dom.production.min.js 31 | * 32 | * Copyright (c) Facebook, Inc. and its affiliates. 33 | * 34 | * This source code is licensed under the MIT license found in the 35 | * LICENSE file in the root directory of this source tree. 36 | */ 37 | 38 | /** @license React v17.0.2 39 | * react.production.min.js 40 | * 41 | * Copyright (c) Facebook, Inc. and its affiliates. 42 | * 43 | * This source code is licensed under the MIT license found in the 44 | * LICENSE file in the root directory of this source tree. 45 | */ 46 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "freemius/wordpress-sdk", 3 | "description": "Freemius WordPress SDK", 4 | "keywords": ["freemius", "wordpress", "plugin", "wordpress-plugin", "theme", "wordpress-theme", "sdk"], 5 | "homepage": "https://freemius.com", 6 | "license": "GPL-3.0-only", 7 | "scripts": { 8 | "phpcs": ["Composer\\Config::disableProcessTimeout", "phpcs -p -s --colors"], 9 | "phpcs:ci": ["Composer\\Config::disableProcessTimeout", "phpcs --standard=phpcompat.xml -p -s --colors"], 10 | "phpstan": "./vendor/bin/phpstan analyse phpstan.neon --memory-limit 2G", 11 | "phpstan:log": "./vendor/bin/phpstan analyse -c phpstan.neon --memory-limit 2G > error-phpstan.xml" 12 | }, 13 | "require": { 14 | "php": ">=5.6" 15 | }, 16 | "autoload": { 17 | "files": [ 18 | "start.php" 19 | ] 20 | }, 21 | "require-dev": { 22 | "wp-coding-standards/wpcs": "^2.3", 23 | "dealerdirect/phpcodesniffer-composer-installer": "^1.0", 24 | "squizlabs/php_codesniffer": "^3.7", 25 | "phpcompatibility/php-compatibility": "^9.3", 26 | "phpcompatibility/phpcompatibility-wp": "^2.1", 27 | "szepeviktor/phpstan-wordpress": "^1.3", 28 | "phpstan/extension-installer": "^1.3" 29 | }, 30 | "prefer-stable": true, 31 | "config": { 32 | "allow-plugins": { 33 | "dealerdirect/phpcodesniffer-composer-installer": true, 34 | "phpstan/extension-installer": true 35 | }, 36 | "platform": { 37 | "php": "8.0" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /includes/class-fs-lock.php: -------------------------------------------------------------------------------- 1 | _lock_id = $lock_id; 38 | 39 | if ( ! isset( self::$_thread_id ) ) { 40 | self::$_thread_id = mt_rand( 0, 32000 ); 41 | } 42 | } 43 | 44 | /** 45 | * Try to acquire lock. If the lock is already set or is being acquired by another locker, don't do anything. 46 | * 47 | * @param int $expiration 48 | * 49 | * @return bool TRUE if successfully acquired lock. 50 | */ 51 | function try_lock( $expiration = 0 ) { 52 | if ( $this->is_locked() ) { 53 | // Already locked. 54 | return false; 55 | } 56 | 57 | set_site_transient( $this->_lock_id, self::$_thread_id, $expiration ); 58 | 59 | if ( $this->has_lock() ) { 60 | $this->lock($expiration); 61 | 62 | return true; 63 | } 64 | 65 | return false; 66 | } 67 | 68 | /** 69 | * Acquire lock regardless if it's already acquired by another locker or not. 70 | * 71 | * @author Vova Feldman (@svovaf) 72 | * @since 2.1.0 73 | * 74 | * @param int $expiration 75 | */ 76 | function lock( $expiration = 0 ) { 77 | set_site_transient( $this->_lock_id, true, $expiration ); 78 | } 79 | 80 | /** 81 | * Checks if lock is currently acquired. 82 | * 83 | * @author Vova Feldman (@svovaf) 84 | * @since 2.1.0 85 | * 86 | * @return bool 87 | */ 88 | function is_locked() { 89 | return ( false !== get_site_transient( $this->_lock_id ) ); 90 | } 91 | 92 | /** 93 | * Unlock the lock. 94 | * 95 | * @author Vova Feldman (@svovaf) 96 | * @since 2.1.0 97 | */ 98 | function unlock() { 99 | delete_site_transient( $this->_lock_id ); 100 | } 101 | 102 | /** 103 | * Checks if lock is currently acquired by the current locker. 104 | * 105 | * @return bool 106 | */ 107 | protected function has_lock() { 108 | return ( self::$_thread_id == get_site_transient( $this->_lock_id ) ); 109 | } 110 | } -------------------------------------------------------------------------------- /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 | /** 87 | * Gets a sandbox trial token for a given plugin, plan, and trial timestamp. 88 | * 89 | * @param FS_Plugin $plugin 90 | * @param FS_Plugin_Plan $plan 91 | * @param int $trial_timestamp 92 | * 93 | * @return string 94 | */ 95 | function get_trial_token( FS_Plugin $plugin, FS_Plugin_Plan $plan, $trial_timestamp ) { 96 | return md5( 97 | $plugin->secret_key . $plugin->public_key . 98 | $plan->trial_period . 99 | $plan->id . 100 | $trial_timestamp 101 | ); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /includes/class-fs-user-lock.php: -------------------------------------------------------------------------------- 1 | _lock = new FS_Lock( "locked_{$current_user_id}" ); 53 | } 54 | 55 | /** 56 | * Try to acquire lock. If the lock is already set or is being acquired by another locker, don't do anything. 57 | * 58 | * @author Vova Feldman (@svovaf) 59 | * @since 2.1.0 60 | * 61 | * @param int $expiration 62 | * 63 | * @return bool TRUE if successfully acquired lock. 64 | */ 65 | function try_lock( $expiration = 0 ) { 66 | return $this->_lock->try_lock( $expiration ); 67 | } 68 | 69 | /** 70 | * Acquire lock regardless if it's already acquired by another locker or not. 71 | * 72 | * @author Vova Feldman (@svovaf) 73 | * @since 2.1.0 74 | * 75 | * @param int $expiration 76 | */ 77 | function lock( $expiration = 0 ) { 78 | $this->_lock->lock( $expiration ); 79 | } 80 | 81 | /** 82 | * Unlock the lock. 83 | * 84 | * @author Vova Feldman (@svovaf) 85 | * @since 2.1.0 86 | */ 87 | function unlock() { 88 | $this->_lock->unlock(); 89 | } 90 | } -------------------------------------------------------------------------------- /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 | title( 'Freemius' ); // @phpstan-ignore-line 27 | } 28 | 29 | public static function requests_count() { 30 | if ( class_exists( 'Freemius_Api_WordPress' ) ) { 31 | $logger = Freemius_Api_WordPress::GetLogger(); 32 | } else { 33 | $logger = array(); 34 | } 35 | 36 | return number_format( count( $logger ) ); 37 | } 38 | 39 | public static function total_time() { 40 | if ( class_exists( 'Freemius_Api_WordPress' ) ) { 41 | $logger = Freemius_Api_WordPress::GetLogger(); 42 | } else { 43 | $logger = array(); 44 | } 45 | 46 | $total_time = .0; 47 | foreach ( $logger as $l ) { 48 | $total_time += $l['total']; 49 | } 50 | 51 | return number_format( 100 * $total_time, 2 ) . ' ' . fs_text_x_inline( 'ms', 'milliseconds' ); 52 | } 53 | 54 | public function render() { 55 | ?> 56 |
    57 | 58 |
    59 | 60 |
    61 | 62 |
    63 | 64 |
    65 | commission_type ) ? 102 | ( '$' . $this->commission ) : 103 | ( $this->commission . '%' ); 104 | } 105 | 106 | /** 107 | * @author Leo Fajardo (@leorw) 108 | * 109 | * @return bool 110 | */ 111 | function has_lifetime_commission() { 112 | return ( 0 !== $this->future_payments_days ); 113 | } 114 | 115 | /** 116 | * @author Leo Fajardo (@leorw) 117 | * 118 | * @return bool 119 | */ 120 | function is_session_cookie() { 121 | return ( 0 == $this->cookie_days ); 122 | } 123 | 124 | /** 125 | * @author Leo Fajardo (@leorw) 126 | * 127 | * @return bool 128 | */ 129 | function has_renewals_commission() { 130 | return ( is_null( $this->commission_renewals_days ) || $this->commission_renewals_days > 0 ); 131 | } 132 | } -------------------------------------------------------------------------------- /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/entities/class-fs-billing.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 | 150 | /** 151 | * @author Leo Fajardo (@leorw) 152 | * @since 2.3.1 153 | * 154 | * @return string 155 | */ 156 | public static function get_class_name() { 157 | return get_called_class(); 158 | } 159 | } -------------------------------------------------------------------------------- /includes/entities/class-fs-payment.php: -------------------------------------------------------------------------------- 1 | bound_payment_id ) && 0 > $this->gross ); 108 | } 109 | 110 | /** 111 | * Checks if the payment was migrated from another platform. 112 | * 113 | * @author Vova Feldman (@svovaf) 114 | * @since 2.0.2 115 | * 116 | * @return bool 117 | */ 118 | function is_migrated() { 119 | return ( 0 != $this->source ); 120 | } 121 | 122 | /** 123 | * Returns the gross in this format: 124 | * `{symbol}{amount | 2 decimal digits} {currency | uppercase}` 125 | * 126 | * Examples: £9.99 GBP, -£9.99 GBP. 127 | * 128 | * @author Leo Fajardo (@leorw) 129 | * @since 2.3.0 130 | * 131 | * @return string 132 | */ 133 | function formatted_gross() 134 | { 135 | return ( 136 | ( $this->gross < 0 ? '-' : '' ) . 137 | $this->get_symbol() . 138 | number_format( abs( $this->gross ), 2, '.', ',' ) . ' ' . 139 | strtoupper( $this->currency ) 140 | ); 141 | } 142 | 143 | /** 144 | * A map between supported currencies with their symbols. 145 | * 146 | * @var array 147 | */ 148 | static $CURRENCY_2_SYMBOL; 149 | 150 | /** 151 | * @author Leo Fajardo (@leorw) 152 | * @since 2.3.0 153 | * 154 | * @return string 155 | */ 156 | private function get_symbol() { 157 | if ( ! isset( self::$CURRENCY_2_SYMBOL ) ) { 158 | // Lazy load. 159 | self::$CURRENCY_2_SYMBOL = array( 160 | self::CURRENCY_USD => '$', 161 | self::CURRENCY_GBP => '£', 162 | self::CURRENCY_EUR => '€', 163 | ); 164 | } 165 | 166 | return self::$CURRENCY_2_SYMBOL[ $this->currency ]; 167 | } 168 | } -------------------------------------------------------------------------------- /includes/entities/class-fs-plugin-info.php: -------------------------------------------------------------------------------- 1 | name = strtolower( $plan->name ); 113 | } 114 | } 115 | 116 | static function get_type() { 117 | return 'plan'; 118 | } 119 | 120 | /** 121 | * @author Vova Feldman (@svovaf) 122 | * @since 1.0.9 123 | * 124 | * @return bool 125 | */ 126 | function is_free() { 127 | return ( 'free' === $this->name ); 128 | } 129 | 130 | /** 131 | * Checks if this plan supports "Technical Support". 132 | * 133 | * @author Leo Fajardo (leorw) 134 | * @since 1.2.0 135 | * 136 | * @return bool 137 | */ 138 | function has_technical_support() { 139 | return ( ! empty( $this->support_email ) || 140 | ! empty( $this->support_skype ) || 141 | ! empty( $this->support_phone ) || 142 | ! empty( $this->is_success_manager ) 143 | ); 144 | } 145 | 146 | /** 147 | * @author Vova Feldman (@svovaf) 148 | * @since 1.0.9 149 | * 150 | * @return bool 151 | */ 152 | function has_trial() { 153 | return ! $this->is_free() && 154 | is_numeric( $this->trial_period ) && ( $this->trial_period > 0 ); 155 | } 156 | } -------------------------------------------------------------------------------- /includes/entities/class-fs-plugin-tag.php: -------------------------------------------------------------------------------- 1 | release_mode ); 63 | } 64 | } -------------------------------------------------------------------------------- /includes/entities/class-fs-plugin.php: -------------------------------------------------------------------------------- 1 | is_premium = false; 124 | $this->is_live = true; 125 | 126 | if ( empty( $this->premium_slug ) && ! empty( $plugin->slug ) ) { 127 | $this->premium_slug = "{$this->slug}-premium"; 128 | } 129 | 130 | if ( empty( $this->premium_suffix ) ) { 131 | $this->premium_suffix = '(Premium)'; 132 | } 133 | 134 | if ( isset( $plugin->info ) && is_object( $plugin->info ) ) { 135 | $this->info = new FS_Plugin_Info( $plugin->info ); 136 | } 137 | } 138 | 139 | /** 140 | * Check if plugin is an add-on (has parent). 141 | * 142 | * @author Vova Feldman (@svovaf) 143 | * @since 1.0.6 144 | * 145 | * @return bool 146 | */ 147 | function is_addon() { 148 | return isset( $this->parent_plugin_id ) && is_numeric( $this->parent_plugin_id ); 149 | } 150 | 151 | /** 152 | * @author Leo Fajardo (@leorw) 153 | * @since 1.2.3 154 | * 155 | * @return bool 156 | */ 157 | function has_affiliate_program() { 158 | return ( ! empty( $this->affiliate_moderation ) ); 159 | } 160 | 161 | static function get_type() { 162 | return 'plugin'; 163 | } 164 | } -------------------------------------------------------------------------------- /includes/entities/class-fs-pricing.php: -------------------------------------------------------------------------------- 1 | monthly_price ) && $this->monthly_price > 0 ); 66 | } 67 | 68 | /** 69 | * @author Vova Feldman (@svovaf) 70 | * @since 1.1.8 71 | * 72 | * @return bool 73 | */ 74 | function has_annual() { 75 | return ( is_numeric( $this->annual_price ) && $this->annual_price > 0 ); 76 | } 77 | 78 | /** 79 | * @author Vova Feldman (@svovaf) 80 | * @since 1.1.8 81 | * 82 | * @return bool 83 | */ 84 | function has_lifetime() { 85 | return ( is_numeric( $this->lifetime_price ) && $this->lifetime_price > 0 ); 86 | } 87 | 88 | /** 89 | * Check if unlimited licenses pricing. 90 | * 91 | * @author Vova Feldman (@svovaf) 92 | * @since 1.1.8 93 | * 94 | * @return bool 95 | */ 96 | function is_unlimited() { 97 | return is_null( $this->licenses ); 98 | } 99 | 100 | 101 | /** 102 | * Check if pricing has more than one billing cycle. 103 | * 104 | * @author Vova Feldman (@svovaf) 105 | * @since 1.1.8 106 | * 107 | * @return bool 108 | */ 109 | function is_multi_cycle() { 110 | $cycles = 0; 111 | if ( $this->has_monthly() ) { 112 | $cycles ++; 113 | } 114 | if ( $this->has_annual() ) { 115 | $cycles ++; 116 | } 117 | if ( $this->has_lifetime() ) { 118 | $cycles ++; 119 | } 120 | 121 | return $cycles > 1; 122 | } 123 | 124 | /** 125 | * Get annual over monthly discount. 126 | * 127 | * @author Vova Feldman (@svovaf) 128 | * @since 1.1.8 129 | * 130 | * @return int 131 | */ 132 | function annual_discount_percentage() { 133 | return floor( $this->annual_savings() / ( $this->monthly_price * 12 * ( $this->is_unlimited() ? 1 : $this->licenses ) ) * 100 ); 134 | } 135 | 136 | /** 137 | * Get annual over monthly savings. 138 | * 139 | * @author Vova Feldman (@svovaf) 140 | * @since 1.1.8 141 | * 142 | * @return float 143 | */ 144 | function annual_savings() { 145 | return ( $this->monthly_price * 12 - $this->annual_price ) * ( $this->is_unlimited() ? 1 : $this->licenses ); 146 | } 147 | 148 | /** 149 | * @author Leo Fajardo (@leorw) 150 | * @since 2.3.1 151 | * 152 | * @return bool 153 | */ 154 | function is_usd() { 155 | return ( 'usd' === $this->currency ); 156 | } 157 | } -------------------------------------------------------------------------------- /includes/entities/class-fs-scope-entity.php: -------------------------------------------------------------------------------- 1 | is_canceled() ) { 107 | return false; 108 | } 109 | 110 | return ( 111 | ! empty( $this->next_payment ) && 112 | strtotime( $this->next_payment ) > WP_FS__SCRIPT_START_TIME 113 | ); 114 | } 115 | 116 | /** 117 | * @author Vova Feldman (@svovaf) 118 | * @since 2.3.1 119 | * 120 | * @return bool 121 | */ 122 | function is_canceled() { 123 | return ! is_null( $this->canceled_at ); 124 | } 125 | 126 | /** 127 | * Subscription considered to be new without any payments 128 | * if the next payment should be made within less than 24 hours 129 | * from the subscription creation. 130 | * 131 | * @author Vova Feldman (@svovaf) 132 | * @since 1.0.9 133 | * 134 | * @return bool 135 | */ 136 | function is_first_payment_pending() { 137 | return ( WP_FS__TIME_24_HOURS_IN_SEC >= strtotime( $this->next_payment ) - strtotime( $this->created ) ); 138 | } 139 | 140 | /** 141 | * @author Vova Feldman (@svovaf) 142 | * @since 1.1.7 143 | */ 144 | function has_trial() { 145 | return ! is_null( $this->trial_ends ); 146 | } 147 | } -------------------------------------------------------------------------------- /includes/entities/class-fs-user.php: -------------------------------------------------------------------------------- 1 | is_beta ); 61 | } 62 | } 63 | 64 | function get_name() { 65 | return trim( ucfirst( trim( is_string( $this->first ) ? $this->first : '' ) ) . ' ' . ucfirst( trim( is_string( $this->last ) ? $this->last : '' ) ) ); 66 | } 67 | 68 | function is_verified() { 69 | return ( isset( $this->is_verified ) && true === $this->is_verified ); 70 | } 71 | 72 | /** 73 | * @author Leo Fajardo (@leorw) 74 | * @since 2.4.2 75 | * 76 | * @return bool 77 | */ 78 | function is_beta() { 79 | // Return `false` since this is just for backward compatibility. 80 | return false; 81 | } 82 | 83 | static function get_type() { 84 | return 'user'; 85 | } 86 | } -------------------------------------------------------------------------------- /includes/entities/index.php: -------------------------------------------------------------------------------- 1 | true, 21 | 'class' => true, 22 | 'style' => true, 23 | 'data-*' => true, 24 | ); 25 | 26 | return array( 27 | 'a' => array_merge( 28 | $common_attributes, 29 | array( 30 | 'href' => true, 31 | 'title' => true, 32 | 'target' => true, 33 | 'rel' => true, 34 | ) 35 | ), 36 | 'img' => array_merge( 37 | $common_attributes, 38 | array( 39 | 'src' => true, 40 | 'alt' => true, 41 | 'title' => true, 42 | 'width' => true, 43 | 'height' => true, 44 | ) 45 | ), 46 | 'br' => $common_attributes, 47 | 'em' => $common_attributes, 48 | 'small' => $common_attributes, 49 | 'strong' => $common_attributes, 50 | 'u' => $common_attributes, 51 | 'b' => $common_attributes, 52 | 'i' => $common_attributes, 53 | 'hr' => $common_attributes, 54 | 'span' => $common_attributes, 55 | 'p' => $common_attributes, 56 | 'div' => $common_attributes, 57 | 'ul' => $common_attributes, 58 | 'li' => $common_attributes, 59 | 'ol' => $common_attributes, 60 | 'h1' => $common_attributes, 61 | 'h2' => $common_attributes, 62 | 'h3' => $common_attributes, 63 | 'h4' => $common_attributes, 64 | 'h5' => $common_attributes, 65 | 'h6' => $common_attributes, 66 | 'button' => $common_attributes, 67 | 'sup' => $common_attributes, 68 | 'sub' => $common_attributes, 69 | 'nobr' => $common_attributes, 70 | ); 71 | } 72 | } 73 | 74 | if ( ! function_exists( 'fs_html_get_classname' ) ) { 75 | /** 76 | * Gets an HTML class attribute value. 77 | * 78 | * @param string|string[] $classes 79 | * 80 | * @return string 81 | */ 82 | function fs_html_get_classname( $classes ) { 83 | if ( is_array( $classes ) ) { 84 | $classes = implode( ' ', $classes ); 85 | } 86 | 87 | return esc_attr( $classes ); 88 | } 89 | } 90 | 91 | if ( ! function_exists( 'fs_html_get_attributes' ) ) { 92 | /** 93 | * Gets a properly escaped HTML attributes string from an associative array. 94 | * 95 | * @param array $attributes A key/value pair array of attributes. 96 | * 97 | * @return string 98 | */ 99 | function fs_html_get_attributes( $attributes ) { 100 | $attribute_string = ''; 101 | 102 | foreach ( $attributes as $key => $value ) { 103 | $attribute_string .= sprintf( 104 | ' %1$s="%2$s"', 105 | esc_attr( $key ), 106 | esc_attr( $value ) 107 | ); 108 | } 109 | 110 | return $attribute_string; 111 | } 112 | } 113 | 114 | if ( ! function_exists( 'fs_html_get_sanitized_html' ) ) { 115 | /** 116 | * Get sanitized HTML for template files. 117 | * 118 | * @param string $raw_html 119 | * 120 | * @return string 121 | * @since 2.5.10 122 | */ 123 | function fs_html_get_sanitized_html( $raw_html ) { 124 | return wp_kses( $raw_html, fs_html_get_allowed_kses_list() ); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /includes/index.php: -------------------------------------------------------------------------------- 1 | 44 | */ 45 | public function get_query_params( Freemius $fs ) { 46 | $context_params = array( 47 | 'plugin_id' => $fs->get_id(), 48 | 'plugin_public_key' => $fs->get_public_key(), 49 | 'plugin_version' => $fs->get_plugin_version(), 50 | ); 51 | 52 | // Get site context secure params. 53 | if ( $fs->is_registered() ) { 54 | $context_params = array_merge( $context_params, FS_Security::instance()->get_context_params( 55 | $fs->get_site(), 56 | time(), 57 | 'contact' 58 | ) ); 59 | } 60 | 61 | return array_merge( $_GET, array_merge( $context_params, array( 62 | 'plugin_version' => $fs->get_plugin_version(), 63 | 'wp_login_url' => wp_login_url(), 64 | 'site_url' => Freemius::get_unfiltered_site_url(), 65 | // 'wp_admin_css' => get_bloginfo('wpurl') . "/wp-admin/load-styles.php?c=1&load=buttons,wp-admin,dashicons", 66 | ) ) ); 67 | } 68 | 69 | /** 70 | * Retrieves the standalone link to the Freemius Contact Form. 71 | * 72 | * @param Freemius $fs 73 | * 74 | * @return string 75 | */ 76 | public function get_standalone_link( Freemius $fs ) { 77 | $query_params = $this->get_query_params( $fs ); 78 | 79 | $query_params['is_standalone'] = 'true'; 80 | $query_params['parent_url'] = admin_url( add_query_arg( null, null ) ); 81 | 82 | return WP_FS__ADDRESS . '/contact/?' . http_build_query( $query_params ); 83 | } 84 | } -------------------------------------------------------------------------------- /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/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 | * Since 2.6.2 call get_filtered_plan 112 | * 113 | * @author Vova Feldman (@svovaf) 114 | * @since 1.0.9 115 | * 116 | * @param FS_Plugin_Plan[] $plans 117 | * 118 | * @return FS_Plugin_Plan[] 119 | */ 120 | function get_trial_plans( $plans ) { 121 | return $this->get_filtered_plans( $plans, true ); 122 | } 123 | 124 | /** 125 | * Find all plans that are not hidden and have trial. 126 | * 127 | * @author Daniele Alessandra (@danielealessandra) 128 | * 129 | * @param FS_Plugin_Plan[] $plans 130 | * 131 | * @return FS_Plugin_Plan[] 132 | * @since 2.6.3 133 | * 134 | */ 135 | function get_visible_trial_plans( $plans ) { 136 | return $this->get_filtered_plans( $plans, true, true ); 137 | } 138 | 139 | /** 140 | * Find all plans filtered by trial or visibility. 141 | * 142 | * @author Daniele Alessandra (@danielealessandra) 143 | * 144 | * @param FS_Plugin_Plan[] $plans 145 | * @param boolean $should_have_trials 146 | * @param boolean $should_be_visible 147 | * 148 | * @return FS_Plugin_Plan[] 149 | * @since 2.6.3 150 | * 151 | */ 152 | function get_filtered_plans( $plans, $should_have_trials = false, $should_be_visible = false ) { 153 | $filtered_plans = array(); 154 | 155 | if ( is_array( $plans ) && count( $plans ) > 0 ) { 156 | foreach ( $plans as $plan ) { 157 | if ( ( $should_have_trials && ! $plan->has_trial() ) || ( $should_be_visible && $plan->is_hidden ) ) { 158 | continue; 159 | } 160 | $filtered_plans[] = $plan; 161 | } 162 | } 163 | 164 | return $filtered_plans; 165 | } 166 | 167 | /** 168 | * Check if plugin has any trial plan. 169 | * 170 | * @author Vova Feldman (@svovaf) 171 | * @since 1.0.9 172 | * 173 | * @param FS_Plugin_Plan[] $plans 174 | * 175 | * @return bool 176 | */ 177 | function has_trial_plan( $plans ) { 178 | if ( ! is_array( $plans ) || 0 === count( $plans ) ) { 179 | return true; 180 | } 181 | 182 | /** 183 | * @var FS_Plugin_Plan[] $plans 184 | */ 185 | for ( $i = 0, $len = count( $plans ); $i < $len; $i ++ ) { 186 | if ( $plans[ $i ]->has_trial() ) { 187 | return true; 188 | } 189 | } 190 | 191 | return false; 192 | } 193 | } -------------------------------------------------------------------------------- /includes/managers/index.php: -------------------------------------------------------------------------------- 1 | _result = $result; 23 | 24 | $code = 0; 25 | $message = 'Unknown error, please check GetResult().'; 26 | $type = ''; 27 | 28 | if ( isset( $result['error'] ) && is_array( $result['error'] ) ) { 29 | if ( isset( $result['error']['code'] ) ) { 30 | $code = $result['error']['code']; 31 | } 32 | if ( isset( $result['error']['message'] ) ) { 33 | $message = $result['error']['message']; 34 | } 35 | if ( isset( $result['error']['type'] ) ) { 36 | $type = $result['error']['type']; 37 | } 38 | } 39 | 40 | $this->_type = $type; 41 | $this->_code = $code; 42 | 43 | parent::__construct( $message, is_numeric( $code ) ? $code : 0 ); 44 | } 45 | 46 | /** 47 | * Return the associated result object returned by the API server. 48 | * 49 | * @return array The result from the API server 50 | */ 51 | public function getResult() { 52 | return $this->_result; 53 | } 54 | 55 | public function getStringCode() { 56 | return $this->_code; 57 | } 58 | 59 | public function getType() { 60 | return $this->_type; 61 | } 62 | 63 | /** 64 | * To make debugging easier. 65 | * 66 | * @return string The string representation of the error 67 | */ 68 | public function __toString() { 69 | $str = $this->getType() . ': '; 70 | 71 | if ( $this->code != 0 ) { 72 | $str .= $this->getStringCode() . ': '; 73 | } 74 | 75 | return $str . $this->getMessage(); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /includes/sdk/Exceptions/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | $data ) { 35 | if ( 0 === strpos( $file_real_path, fs_normalize_path( dirname( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) ) . '/' ) ) ) { 36 | if ( '.' !== dirname( trailingslashit( $relative_path ) ) ) { 37 | return $relative_path; 38 | } 39 | } 40 | } 41 | 42 | return null; 43 | } 44 | -------------------------------------------------------------------------------- /includes/supplements/fs-essential-functions-2.2.1.php: -------------------------------------------------------------------------------- 1 | $install ) { 21 | if ( true === $install->is_disconnected ) { 22 | $permission_manager->update_site_tracking( 23 | false, 24 | ( 0 == $blog_id ) ? null : $blog_id, 25 | // Update only if permissions are not yet set. 26 | true 27 | ); 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /includes/supplements/index.php: -------------------------------------------------------------------------------- 1 | 35 |
    36 | 37 | 38 | 39 | 40 | 41 | 54 |
    -------------------------------------------------------------------------------- /templates/account/partials/deactivate-license-button.php: -------------------------------------------------------------------------------- 1 | 30 |
    31 | 32 | 33 | 34 | 35 | 36 |
    -------------------------------------------------------------------------------- /templates/account/partials/disconnect-button.php: -------------------------------------------------------------------------------- 1 | _get_subscription( $license->id ) : 30 | null; 31 | 32 | $has_active_subscription = ( 33 | is_object( $license_subscription ) && 34 | $license_subscription->is_active() 35 | ); 36 | 37 | $button_id = "fs_disconnect_button_{$fs->get_id()}"; 38 | 39 | $website_link = sprintf( '%s', fs_strip_url_protocol( untrailingslashit( Freemius::get_unfiltered_site_url() ) ) ); 40 | ?> 41 | 65 | 96 |
    97 | 98 | 99 | 100 | 101 | 102 | esc_html_inline( 'Disconnect', 'disconnect' ) ?> 103 | 104 |
    -------------------------------------------------------------------------------- /templates/account/partials/index.php: -------------------------------------------------------------------------------- 1 | get_slug(); 25 | 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 ) ) ?>formatted_gross() ?>is_migrated() ) : ?>
    55 |
    56 |
    57 |
    58 | 21 | -------------------------------------------------------------------------------- /templates/admin-notice.php: -------------------------------------------------------------------------------- 1 | 91 |
    > 92 | 93 | 96 | 97 | 98 | 99 |
    100 | 101 | 102 |
    103 | 104 | 105 |
    106 | 107 | 108 | 109 | 110 | 111 |
    112 |
    113 | -------------------------------------------------------------------------------- /templates/ajax-loader.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /templates/api-connectivity-message-js.php: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /templates/checkout.php: -------------------------------------------------------------------------------- 1 | is_premium() ) { 23 | fs_require_template( 'checkout/frame.php', $VARS ); 24 | } else { 25 | fs_require_template( 'checkout/redirect.php', $VARS ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /templates/checkout/process-redirect.php: -------------------------------------------------------------------------------- 1 | get_id(); 23 | } 24 | 25 | $fs_checkout->verify_checkout_redirect_nonce( $fs ); 26 | 27 | wp_enqueue_script( 'jquery' ); 28 | wp_enqueue_script( 'json2' ); 29 | fs_enqueue_local_script( 'fs-form', 'jquery.form.js', array( 'jquery' ) ); 30 | 31 | $action = fs_request_get( '_fs_checkout_action' ); 32 | $data = json_decode( fs_request_get_raw( '_fs_checkout_data' ) ); 33 | ?> 34 |
    35 |
    36 | 37 |
    38 | 39 |
    40 |

    41 | 42 |

    43 |
    44 |
    45 | 46 | 130 | -------------------------------------------------------------------------------- /templates/checkout/redirect.php: -------------------------------------------------------------------------------- 1 | get_id(); 23 | } 24 | 25 | $plan_id = fs_request_get( 'plan_id' ); 26 | $licenses = fs_request_get( 'licenses' ); 27 | 28 | $query_params = $fs_checkout->get_query_params( 29 | $fs, 30 | $plugin_id, 31 | $plan_id, 32 | $licenses 33 | ); 34 | 35 | // The return URL is a special page which will process the result. 36 | $return_url = $fs_checkout->get_checkout_redirect_return_url( $fs ); 37 | $query_params['return_url'] = $return_url; 38 | 39 | // Add the cancel URL to the same pricing page the request originated from. 40 | $query_params['cancel_url'] = $fs->pricing_url( 41 | fs_request_get( 'billing_cycle', 'annual' ), 42 | fs_request_get_bool( 'trial' ) 43 | ); 44 | 45 | if ( has_site_icon() ) { 46 | $query_params['cancel_icon'] = get_site_icon_url(); 47 | } 48 | 49 | // If the user didn't connect his account with Freemius, 50 | // once he accepts the Terms of Service and Privacy Policy, 51 | // and then click the purchase button, the context information 52 | // of the user will be shared with Freemius in order to complete the 53 | // purchase workflow and activate the license for the right user. 54 | $install_data = array_merge( 55 | $fs->get_opt_in_params(), 56 | array( 57 | 'activation_url' => fs_nonce_url( 58 | $fs->_get_admin_page_url( 59 | '', 60 | array( 61 | 'fs_action' => $fs->get_unique_affix() . '_activate_new', 62 | 'plugin_id' => $plugin_id, 63 | ) 64 | ), 65 | $fs->get_unique_affix() . '_activate_new' 66 | ), 67 | ) 68 | ); 69 | $query_params['install_data'] = json_encode( $install_data ); 70 | 71 | $query_params['_fs_dashboard_independent'] = true; 72 | 73 | $redirect_url = $fs_checkout->get_full_checkout_url( $query_params ); 74 | 75 | if ( ! fs_redirect( $redirect_url ) ) { 76 | // The Header was sent, so the server redirect failed. Rely on JS instead. 77 | ?> 78 |
    79 |
    80 | 81 |
    82 | 83 |
    84 |

    85 | click here if you\'re stuck...' ), 88 | esc_url( $redirect_url ) 89 | ), 90 | array( 'a' => array( 'href' => true ) ) 91 | ); ?> 92 |

    93 |
    94 |
    95 | 101 | 13 | -------------------------------------------------------------------------------- /templates/connect/index.php: -------------------------------------------------------------------------------- 1 | 29 |
  • 31 | 32 | 33 |
    34 |
    35 |
    36 | 37 | 38 |
    39 | class="fs-tooltip-trigger"> 40 | 41 |

    42 |
    43 |
  • -------------------------------------------------------------------------------- /templates/connect/permissions-group.php: -------------------------------------------------------------------------------- 1 | get_text_x_inline( 'Opt Out', 'verb', 'opt-out' ); 32 | $opt_in_text = $fs->get_text_x_inline( 'Opt In', 'verb', 'opt-in' ); 33 | 34 | if ( empty( $permission_group[ 'prompt' ] ) ) { 35 | $is_enabled = false; 36 | 37 | foreach ( $permission_group[ 'permissions' ] as $permission ) { 38 | if ( true === $permission[ 'default' ] ) { 39 | // Even if one of the permissions is on, treat as if the entire group is on. 40 | $is_enabled = true; 41 | break; 42 | } 43 | } 44 | } else { 45 | $is_enabled = ( isset( $permission_group['is_enabled'] ) && true === $permission_group['is_enabled'] ); 46 | } 47 | ?> 48 |
    49 |
    50 |
    51 | 56 | 60 |
    61 |

    65 |
      66 | render_permission( $permission ); 69 | } 70 | ?> 71 |
    72 |
    -------------------------------------------------------------------------------- /templates/contact.php: -------------------------------------------------------------------------------- 1 | get_slug(); 58 | 59 | $query_params = FS_Contact_Form_Manager::instance()->get_query_params( $fs ); 60 | 61 | $view_params = array( 62 | 'id' => $VARS['id'], 63 | 'page' => strtolower( $fs->get_text_inline( 'Contact', 'contact' ) ), 64 | ); 65 | fs_require_once_template('secure-https-header.php', $view_params); 66 | 67 | $has_tabs = $fs->_add_tabs_before_content(); 68 | 69 | if ( $has_tabs ) { 70 | $query_params['tabs'] = 'true'; 71 | } 72 | ?> 73 |
    74 |
    75 | 100 |
    101 | _add_tabs_after_content(); 104 | } 105 | -------------------------------------------------------------------------------- /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 |
    -------------------------------------------------------------------------------- /templates/debug/index.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 | ?>
    -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /templates/debug/scheduled-crons.php: -------------------------------------------------------------------------------- 1 | get_option( $module_type . 's' ), FS_Plugin::get_class_name() ); 25 | if ( is_array( $modules ) && count( $modules ) > 0 ) { 26 | foreach ( $modules as $slug => $data ) { 27 | if ( WP_FS__MODULE_TYPE_THEME === $module_type ) { 28 | $current_theme = wp_get_theme(); 29 | $is_active = ( $current_theme->stylesheet === $data->file ); 30 | } else { 31 | $is_active = is_plugin_active( $data->file ); 32 | } 33 | 34 | /** 35 | * @author Vova Feldman 36 | * 37 | * @since 1.2.1 Don't load data from inactive modules. 38 | */ 39 | if ( $is_active ) { 40 | $fs = freemius( $data->id ); 41 | 42 | $next_execution = $fs->next_sync_cron(); 43 | $last_execution = $fs->last_sync_cron(); 44 | 45 | if ( false !== $next_execution ) { 46 | $scheduled_crons[ $slug ][] = array( 47 | 'name' => $fs->get_plugin_name(), 48 | 'slug' => $slug, 49 | 'module_type' => $fs->get_module_type(), 50 | 'type' => 'sync_cron', 51 | 'last' => $last_execution, 52 | 'next' => $next_execution, 53 | ); 54 | } 55 | 56 | $next_install_execution = $fs->next_install_sync(); 57 | $last_install_execution = $fs->last_install_sync(); 58 | 59 | if (false !== $next_install_execution || 60 | false !== $last_install_execution 61 | ) { 62 | $scheduled_crons[ $slug ][] = array( 63 | 'name' => $fs->get_plugin_name(), 64 | 'slug' => $slug, 65 | 'module_type' => $fs->get_module_type(), 66 | 'type' => 'install_sync', 67 | 'last' => $last_install_execution, 68 | 'next' => $next_install_execution, 69 | ); 70 | } 71 | } 72 | } 73 | } 74 | } 75 | 76 | $sec_text = fs_text_x_inline( 'sec', 'seconds' ); 77 | ?> 78 | 79 |

    80 | 83 | 84 |

    85 | 86 |

    87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 106 | $crons ) : ?> 107 | 108 | 109 | 110 | 111 | 112 | 113 | 128 | 143 | 144 | 145 | 146 | 147 |
    148 | -------------------------------------------------------------------------------- /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 |
    :
    -------------------------------------------------------------------------------- /templates/forms/deactivation/contact.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 | -------------------------------------------------------------------------------- /templates/forms/deactivation/index.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}"; -------------------------------------------------------------------------------- /templates/forms/index.php: -------------------------------------------------------------------------------- 1 | _get_license(); 19 | 20 | if ( ! is_object( $license ) ) { 21 | $purchase_url = $fs->pricing_url(); 22 | } else { 23 | $subscription = $fs->_get_subscription( $license->id ); 24 | 25 | $purchase_url = $fs->checkout_url( 26 | is_object( $subscription ) ? 27 | ( 1 == $subscription->billing_cycle ? WP_FS__PERIOD_MONTHLY : WP_FS__PERIOD_ANNUALLY ) : 28 | WP_FS__PERIOD_LIFETIME, 29 | false, 30 | array( 'licenses' => $license->quota ) 31 | ); 32 | } 33 | 34 | $plugin_data = $fs->get_plugin_data(); 35 | ?> 36 | -------------------------------------------------------------------------------- /templates/gdpr-optin-js.php: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /templates/index.php: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /templates/js/open-license-activation.php: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /templates/js/style-premium-theme.php: -------------------------------------------------------------------------------- 1 | get_slug(); 21 | 22 | ?> 23 | -------------------------------------------------------------------------------- /templates/partials/index.php: -------------------------------------------------------------------------------- 1 | get_slug(); 14 | 15 | $sites = $VARS['sites']; 16 | $require_license_key = $VARS['require_license_key']; 17 | 18 | $show_delegation_option = $fs->apply_filters( 'show_delegation_option', true ); 19 | $enable_per_site_activation = $fs->apply_filters( 'enable_per_site_activation', true ); 20 | ?> 21 | |' ?> 22 | 95 | -------------------------------------------------------------------------------- /templates/plugin-icon.php: -------------------------------------------------------------------------------- 1 | 20 |
    21 | 22 |
    -------------------------------------------------------------------------------- /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 |
      26 | 27 | info->{'selling_point_' . $i} ) ) : ?> 28 |
    • 29 | 30 |

      info->{'selling_point_' . $i} ) ?>

    • 31 | 32 | 33 |
    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 |
      57 | $url ) : ?> 59 |
    • 60 | 66 | 69 |
    • 70 | 71 |
    72 |
    73 | -------------------------------------------------------------------------------- /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']['feature']; 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 |
    -------------------------------------------------------------------------------- /templates/plugin-info/index.php: -------------------------------------------------------------------------------- 1 | 22 |
      23 | $url ) : ?> 25 |
    1. 26 | 27 |
    2. 28 | 29 |
    30 | -------------------------------------------------------------------------------- /templates/pricing.php: -------------------------------------------------------------------------------- 1 | get_slug(); 25 | $timestamp = time(); 26 | 27 | $context_params = array( 28 | 'plugin_id' => $fs->get_id(), 29 | 'plugin_public_key' => $fs->get_public_key(), 30 | 'plugin_version' => $fs->get_plugin_version(), 31 | ); 32 | 33 | $bundle_id = $fs->get_bundle_id(); 34 | if ( ! is_null( $bundle_id ) ) { 35 | $context_params['bundle_id'] = $bundle_id; 36 | } 37 | 38 | // Get site context secure params. 39 | if ( $fs->is_registered() ) { 40 | $context_params = array_merge( $context_params, FS_Security::instance()->get_context_params( 41 | $fs->get_site(), 42 | $timestamp, 43 | 'upgrade' 44 | ) ); 45 | } else { 46 | $context_params['home_url'] = home_url(); 47 | } 48 | 49 | if ( $fs->is_payments_sandbox() ) // Append plugin secure token for sandbox mode authentication.) 50 | { 51 | $context_params['sandbox'] = FS_Security::instance()->get_secure_token( 52 | $fs->get_plugin(), 53 | $timestamp, 54 | 'checkout' 55 | ); 56 | } 57 | 58 | $query_params = array_merge( $context_params, $_GET, array( 59 | 'next' => $fs->_get_sync_license_url( false, false ), 60 | 'plugin_version' => $fs->get_plugin_version(), 61 | // Billing cycle. 62 | 'billing_cycle' => fs_request_get( 'billing_cycle', WP_FS__PERIOD_ANNUALLY ), 63 | 'is_network_admin' => fs_is_network_admin() ? 'true' : 'false', 64 | 'currency' => $fs->apply_filters( 'default_currency', 'usd' ), 65 | 'discounts_model' => $fs->apply_filters( 'pricing/discounts_model', 'absolute' ), 66 | ) ); 67 | 68 | $pricing_js_url = fs_asset_url( $fs->get_pricing_js_path() ); 69 | 70 | wp_enqueue_script( 'freemius-pricing', $pricing_js_url ); 71 | 72 | $pricing_css_path = $fs->apply_filters( 'pricing/css_path', null ); 73 | if ( is_string( $pricing_css_path ) ) { 74 | wp_enqueue_style( 'freemius-pricing', fs_asset_url( $pricing_css_path ) ); 75 | } 76 | 77 | $has_tabs = $fs->_add_tabs_before_content(); 78 | 79 | if ( $has_tabs ) { 80 | $query_params['tabs'] = 'true'; 81 | } 82 | ?> 83 |
    84 |
    85 | $fs->contact_url(), 88 | 'is_production' => ( defined( 'WP_FS__IS_PRODUCTION_MODE' ) ? WP_FS__IS_PRODUCTION_MODE : null ), 89 | 'menu_slug' => $fs->get_menu_slug(), 90 | 'mode' => 'dashboard', 91 | 'fs_wp_endpoint_url' => WP_FS__ADDRESS, 92 | 'request_handler_url' => admin_url( 93 | 'admin-ajax.php?' . http_build_query( array( 94 | 'module_id' => $fs->get_id(), 95 | 'action' => $fs->get_ajax_action( 'pricing_ajax_action' ), 96 | 'security' => $fs->get_ajax_security( 'pricing_ajax_action' ) 97 | ) ) 98 | ), 99 | 'selector' => '#fs_pricing_wrapper', 100 | 'unique_affix' => $fs->get_unique_affix(), 101 | 'show_annual_in_monthly' => $fs->apply_filters( 'pricing/show_annual_in_monthly', true ), 102 | 'license' => $fs->has_active_valid_license() ? $fs->_get_license() : null, 103 | 'plugin_icon' => $fs->get_local_icon_url(), 104 | 'disable_single_package' => $fs->apply_filters( 'pricing/disable_single_package', false ), 105 | ), $query_params ); 106 | 107 | wp_add_inline_script( 'freemius-pricing', 'Freemius.pricing.new( ' . json_encode( $pricing_config ) . ' )' ); 108 | ?> 109 |
    110 | _add_tabs_after_content(); 113 | } 114 | -------------------------------------------------------------------------------- /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 |
    -------------------------------------------------------------------------------- /templates/sticky-admin-notice-js.php: -------------------------------------------------------------------------------- 1 | 16 | 41 | -------------------------------------------------------------------------------- /templates/tabs-capture-js.php: -------------------------------------------------------------------------------- 1 | get_slug(); 19 | ?> 20 | --------------------------------------------------------------------------------