Version Description
- New! - Possibility to open menus with enter key when got focus
- New! - 3 new filters to replace the logo image, current menu and menu URL
- Fix! - Remove blank space below the header in a specific theme
- Fix! - Display normal logo if retina isn't uploaded and vice versa
- Fix! - Only force autoplay videos on desktop
- Improvment! - Update Freemius SDK
Download this release
Release Info
Developer | takanakui |
Plugin | WP Mobile Menu |
Version | 2.8.3 |
Comparing to | |
See all releases |
Code changes from version 2.8.2.7 to 2.8.3
- freemius/assets/css/admin/account.css +1 -1
- freemius/assets/css/admin/add-ons.css +1 -2
- freemius/assets/css/admin/affiliation.css +1 -1
- freemius/assets/css/admin/clone-resolution.css +1 -0
- freemius/assets/css/admin/common.css +1 -2
- freemius/assets/css/admin/connect.css +1 -1
- freemius/assets/css/admin/debug.css +1 -1
- freemius/assets/css/admin/dialog-boxes.css +1 -2
- freemius/assets/css/admin/gdpr-optin-notice.css +1 -1
- freemius/assets/css/admin/optout.css +1 -0
- freemius/assets/css/customizer.css +1 -1
- freemius/config.php +5 -5
- freemius/includes/class-freemius-abstract.php +4 -63
- freemius/includes/class-freemius.php +2232 -1056
- freemius/includes/class-fs-admin-notices.php +56 -24
- freemius/includes/class-fs-api.php +27 -3
- freemius/includes/class-fs-lock.php +110 -0
- freemius/includes/class-fs-logger.php +2 -1
- freemius/includes/class-fs-plugin-updater.php +41 -18
- freemius/includes/class-fs-storage.php +106 -80
- freemius/includes/class-fs-user-lock.php +10 -46
- freemius/includes/customizer/class-fs-customizer-upsell-control.php +2 -2
- freemius/includes/entities/class-fs-affiliate-terms.php +4 -0
- freemius/includes/entities/class-fs-plugin-tag.php +4 -0
- freemius/includes/entities/class-fs-site.php +22 -21
- freemius/includes/entities/class-fs-user.php +12 -1
- freemius/includes/fs-core-functions.php +10 -22
- freemius/includes/fs-essential-functions.php +7 -97
- freemius/includes/fs-plugin-info-dialog.php +55 -4
- freemius/includes/i18n.php +0 -605
- freemius/includes/managers/class-fs-admin-notice-manager.php +75 -20
- freemius/includes/managers/class-fs-clone-manager.php +1660 -0
- freemius/includes/managers/class-fs-key-value-storage.php +10 -0
- freemius/includes/managers/class-fs-option-manager.php +35 -80
- freemius/includes/managers/class-fs-permission-manager.php +698 -0
- freemius/includes/managers/class-fs-plugin-manager.php +18 -5
- freemius/includes/sdk/FreemiusBase.php +169 -171
- freemius/includes/sdk/FreemiusWordPress.php +715 -715
- freemius/includes/supplements/fs-migration-2.5.1.php +31 -0
- freemius/languages/freemius-cs_CZ.mo +0 -0
- freemius/languages/freemius-da_DK.mo +0 -0
- freemius/languages/freemius-de_DE.mo +0 -0
- freemius/languages/freemius-en.mo +0 -0
- freemius/languages/freemius-es_ES.mo +0 -0
- freemius/languages/freemius-fr_FR.mo +0 -0
- freemius/languages/freemius-he_IL.mo +0 -0
- freemius/languages/freemius-hu_HU.mo +0 -0
- freemius/languages/freemius-it_IT.mo +0 -0
- freemius/languages/freemius-ja.mo +0 -0
- freemius/languages/freemius-nl_NL.mo +0 -0
- freemius/languages/freemius-ru_RU.mo +0 -0
- freemius/languages/freemius-ta.mo +0 -0
- freemius/languages/freemius-zh_CN.mo +0 -0
- freemius/languages/freemius.pot +868 -630
- freemius/require.php +2 -0
- freemius/start.php +6 -2
- freemius/templates/account.php +65 -30
- freemius/templates/account/billing.php +1 -1
- freemius/templates/account/partials/disconnect-button.php +104 -0
- freemius/templates/account/partials/site.php +8 -6
- freemius/templates/account/payments.php +10 -11
- freemius/templates/admin-notice.php +4 -1
- freemius/templates/auto-installation.php +1 -1
- freemius/templates/clone-resolution-js.php +79 -0
- freemius/templates/connect.php +153 -144
- freemius/templates/connect/index.php +3 -0
- freemius/templates/connect/permission.php +43 -0
- freemius/templates/connect/permissions-group.php +72 -0
- freemius/templates/contact.php +1 -1
- freemius/templates/debug.php +78 -16
- freemius/templates/firewall-issues-js.php +1 -2
- freemius/templates/forms/affiliation.php +6 -6
- freemius/templates/forms/data-debug-mode.php +1 -1
- freemius/templates/forms/deactivation/form.php +174 -51
- freemius/templates/forms/email-address-update.php +347 -0
- freemius/templates/forms/license-activation.php +38 -18
- freemius/templates/forms/optout.php +147 -301
- freemius/templates/forms/resend-key.php +5 -2
- freemius/templates/forms/trial-start.php +1 -1
- freemius/templates/forms/user-change.php +1 -1
- freemius/templates/gdpr-optin-js.php +1 -1
- freemius/templates/js/permissions.php +546 -0
- freemius/templates/partials/network-activation.php +1 -1
- freemius/templates/plugin-icon.php +3 -1
- freemius/templates/plugin-info/description.php +1 -1
- freemius/templates/plugin-info/features.php +1 -1
- freemius/templates/powered-by.php +7 -7
- freemius/templates/pricing.php +12 -11
- freemius/templates/sticky-admin-notice-js.php +1 -2
- freemius/templates/tabs-capture-js.php +1 -1
- includes/class-wp-mobile-menu-core.php +15 -21
- includes/css/mobmenu.css +6 -2
- includes/dynamic-style.php +2 -2
- includes/js/mobmenu.js +10 -7
- includes/widgets/mobile-menu.php +0 -150
- mobmenu.php +4 -5
- readme.txt +10 -2
freemius/assets/css/admin/account.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
label.fs-tag,span.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-notice[data-id=
|
1 |
+
label.fs-tag,span.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-notice[data-id=license_not_whitelabeled].success,.fs-notice[data-id=license_whitelabeled].success{color:inherit;border-left-color:#00a0d2}.fs-notice[data-id=license_not_whitelabeled].success label.fs-plugin-title,.fs-notice[data-id=license_whitelabeled].success label.fs-plugin-title{display:none}#fs_account .postbox,#fs_account .widefat{max-width:800px}#fs_account h3{font-size:1.3em;padding:12px 15px;margin:0 0 12px 0;line-height:1.4;border-bottom:1px solid #f1f1f1}#fs_account h3 .dashicons{width:26px;height:26px;font-size:1.3em}#fs_account i.dashicons{font-size:1.2em;height:1.2em;width:1.2em}#fs_account .dashicons{vertical-align:middle}#fs_account .fs-header-actions{position:absolute;top:17px;right:15px;font-size:.9em}#fs_account .fs-header-actions ul{margin:0}#fs_account .fs-header-actions li{float:left}#fs_account .fs-header-actions li form{display:inline-block}#fs_account .fs-header-actions li a{text-decoration:none}#fs_account_details .button-group{float:right}.rtl #fs_account .fs-header-actions{left:15px;right:auto}.fs-key-value-table{width:100%}.fs-key-value-table form{display:inline-block}.fs-key-value-table tr td:first-child{text-align:right}.fs-key-value-table tr td:first-child nobr{font-weight:bold}.fs-key-value-table tr td:first-child form{display:block}.fs-key-value-table tr td.fs-right{text-align:right}.fs-key-value-table tr.fs-odd{background:#ebebeb}.fs-key-value-table td,.fs-key-value-table th{padding:10px}.fs-key-value-table code{line-height:28px}.fs-key-value-table var,.fs-key-value-table code,.fs-key-value-table input[type=text]{color:#0073aa;font-size:16px;background:none}.fs-key-value-table input[type=text]{width:100%;font-weight:bold}.fs-field-beta_program label{margin-left:7px}label.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error{background:#dc3232}#fs_sites .fs-scrollable-table .fs-table-body{max-height:200px;overflow:auto;border:1px solid #e5e5e5}#fs_sites .fs-scrollable-table .fs-table-body>table.widefat{border:none !important}#fs_sites .fs-scrollable-table .fs-main-column{width:100%}#fs_sites .fs-scrollable-table .fs-site-details td:first-of-type{text-align:right;color:gray;width:1px}#fs_sites .fs-scrollable-table .fs-site-details td:last-of-type{text-align:right}#fs_sites .fs-scrollable-table .fs-install-details table tr td{width:1px;white-space:nowrap}#fs_sites .fs-scrollable-table .fs-install-details table tr td:last-of-type{width:auto}#fs_addons h3{border:none;margin-bottom:0;padding:4px 5px}#fs_addons td{vertical-align:middle}#fs_addons thead{white-space:nowrap}#fs_addons td:first-child,#fs_addons th:first-child{text-align:left;font-weight:bold}#fs_addons td:last-child,#fs_addons th:last-child{text-align:right}#fs_addons th{font-weight:bold}#fs_billing_address{width:100%}#fs_billing_address tr td{width:50%;padding:5px}#fs_billing_address tr:first-of-type td{padding-top:0}#fs_billing_address span{font-weight:bold}#fs_billing_address input,#fs_billing_address select{display:block;width:100%;margin-top:5px}#fs_billing_address input::-moz-placeholder,#fs_billing_address select::-moz-placeholder{color:transparent;opacity:1}#fs_billing_address input:-ms-input-placeholder,#fs_billing_address select:-ms-input-placeholder{color:transparent}#fs_billing_address input::-webkit-input-placeholder,#fs_billing_address select::-webkit-input-placeholder{color:transparent}#fs_billing_address input.fs-read-mode,#fs_billing_address select.fs-read-mode{border-color:transparent;color:#777;border-bottom:1px dashed #ccc;padding-left:0;background:none}#fs_billing_address.fs-read-mode td span{display:none}#fs_billing_address.fs-read-mode input,#fs_billing_address.fs-read-mode select{border-color:transparent;color:#777;border-bottom:1px dashed #ccc;padding-left:0;background:none}#fs_billing_address.fs-read-mode input::-moz-placeholder,#fs_billing_address.fs-read-mode select::-moz-placeholder{color:#ccc;opacity:1}#fs_billing_address.fs-read-mode input:-ms-input-placeholder,#fs_billing_address.fs-read-mode select:-ms-input-placeholder{color:#ccc}#fs_billing_address.fs-read-mode input::-webkit-input-placeholder,#fs_billing_address.fs-read-mode select::-webkit-input-placeholder{color:#ccc}#fs_billing_address button{display:block;width:100%}@media screen and (max-width: 639px){#fs_account .fs-header-actions{position:static;padding:0 15px 12px 15px;margin:0 0 12px 0}#fs_account .fs-header-actions li{float:none;display:inline-block}#fs_account #fs_account_details{display:block}#fs_account #fs_account_details tbody,#fs_account #fs_account_details tr,#fs_account #fs_account_details td,#fs_account #fs_account_details th{display:block}#fs_account #fs_account_details tr td:first-child{text-align:left}#fs_account #fs_account_details tr td:nth-child(2){padding:0 12px}#fs_account #fs_account_details tr td:nth-child(2) code{margin:0;padding:0}#fs_account #fs_account_details tr td:nth-child(2) label{margin-left:0}#fs_account #fs_account_details tr td:nth-child(3){text-align:left}#fs_account #fs_account_details tr.fs-field-plan td:nth-child(2) .button-group{float:none;margin:12px 0}}
|
freemius/assets/css/admin/add-ons.css
CHANGED
@@ -1,2 +1 @@
|
|
1 |
-
.fs-badge{position:absolute;top:10px;right:0;background:#71ae00;color:white;text-transform:uppercase;padding:5px 10px;-moz-border-radius:3px 0 0 3px;-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;font-weight:bold;border-right:0;-moz-box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);box-shadow:0 2px 1px -1px rgba(0,0,0,0.3)}#fs_addons .fs-cards-list{list-style:none}#fs_addons .fs-cards-list .fs-card{float:left;height:152px;width:310px;padding:0;margin:0 0 30px 30px;font-size:14px;list-style:none;border:1px solid #ddd;cursor:pointer;position:relative}#fs_addons .fs-cards-list .fs-card .fs-overlay{position:absolute;left:0;right:0;bottom:0;top:0;z-index:9}#fs_addons .fs-cards-list .fs-card .fs-inner{background-color:#fff;overflow:hidden;height:100%;position:relative}#fs_addons .fs-cards-list .fs-card .fs-inner>ul{-moz-transition:all,0.15s;-o-transition:all,0.15s;-ms-transition:all,0.15s;-webkit-transition:all,0.15s;transition:all,0.15s;left:0;right:0;top:0;position:absolute}#fs_addons .fs-cards-list .fs-card .fs-inner>ul>li{list-style:none;line-height:18px;padding:0 15px;width:100%;display:block;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-card-banner{padding:0;margin:0;line-height:0;display:block;height:100px;background-repeat:repeat-x;background-size:100% 100%;-moz-transition:all,0.15s;-o-transition:all,0.15s;-ms-transition:all,0.15s;-webkit-transition:all,0.15s;transition:all,0.15s}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-card-banner .fs-badge.fs-installed-addon-badge{font-size:1.02em;line-height:1.3em}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-title{margin:10px 0 0 0;height:18px;overflow:hidden;color:#000;white-space:nowrap;text-overflow:ellipsis;font-weight:bold}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-offer{font-size:0.9em}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-description{background-color:#f9f9f9;padding:10px 15px 100px 15px;border-top:1px solid #eee;margin:0 0 10px 0;color:#777}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-tag{position:absolute;top:10px;right:0px;background:greenyellow;display:block;padding:2px 10px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,0.3);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,0.3);box-shadow:1px 1px 1px rgba(0,0,0,0.3);text-transform:uppercase;font-size:0.9em;font-weight:bold}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-cta .button,#fs_addons .fs-cards-list .fs-card .fs-inner .fs-cta .button-group{position:absolute;top:112px;right:10px}@media screen and (min-width: 960px){#fs_addons .fs-cards-list .fs-card:hover .fs-overlay{border:2px solid #29abe1;margin-left:-1px;margin-top:-1px}#fs_addons .fs-cards-list .fs-card:hover .fs-inner ul{top:-100px}#fs_addons .fs-cards-list .fs-card:hover .fs-inner .fs-title,#fs_addons .fs-cards-list .fs-card:hover .fs-inner .fs-offer{color:#29abe1}}
|
2 |
-
#TB_window,#TB_window iframe{width:821px !important}#plugin-information .fyi{width:266px !important}#plugin-information #section-holder{margin-right:299px}#plugin-information #section-description h2,#plugin-information #section-description h3,#plugin-information #section-description p,#plugin-information #section-description b,#plugin-information #section-description i,#plugin-information #section-description blockquote,#plugin-information #section-description li,#plugin-information #section-description ul,#plugin-information #section-description ol{clear:none}#plugin-information #section-description iframe{max-width:100%}#plugin-information #section-description .fs-selling-points{padding-bottom:10px;border-bottom:1px solid #ddd}#plugin-information #section-description .fs-selling-points ul{margin:0}#plugin-information #section-description .fs-selling-points ul li{padding:0;list-style:none outside none}#plugin-information #section-description .fs-selling-points ul li i.dashicons{color:#71ae00;font-size:3em;vertical-align:middle;line-height:30px;float:left;margin:0 0 0 -15px}#plugin-information #section-description .fs-selling-points ul li h3{margin:1em 30px !important}#plugin-information #section-description .fs-screenshots:after{content:"";display:table;clear:both}#plugin-information #section-description .fs-screenshots ul{list-style:none;margin:0}#plugin-information #section-description .fs-screenshots ul li{width:225px;height:225px;float:left;margin-bottom:20px;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}#plugin-information #section-description .fs-screenshots ul li a{display:block;width:100%;height:100%;border:1px solid;-moz-box-shadow:1px 1px 1px rgba(0,0,0,0.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,0.2);box-shadow:1px 1px 1px rgba(0,0,0,0.2);background-size:cover}#plugin-information #section-description .fs-screenshots ul li.odd{margin-right:20px}#plugin-information .plugin-information-pricing{margin:-16px;border-bottom:1px solid #ddd}#plugin-information .plugin-information-pricing .fs-plan h3{margin-top:0;padding:20px;font-size:16px}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper{border-bottom:1px solid #ddd}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab{cursor:pointer;position:relative;padding:0 10px;font-size:0.9em}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab label{text-transform:uppercase;color:green;background:greenyellow;position:absolute;left:-1px;right:-1px;bottom:100%;border:1px solid darkgreen;padding:2px;text-align:center;font-size:0.9em;line-height:1em}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab.nav-tab-active{cursor:default;background:#fffeec;border-bottom-color:#fffeec}#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle h3{background:#fffeec;margin:0;padding-bottom:0;color:#0073aa}#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle .nav-tab-wrapper,#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle .fs-billing-frequency{display:none}#plugin-information .plugin-information-pricing .fs-plan .fs-pricing-body{background:#fffeec;padding:20px}#plugin-information .plugin-information-pricing .fs-plan .button{width:100%;text-align:center;font-weight:bold;text-transform:uppercase;font-size:1.1em}#plugin-information .plugin-information-pricing .fs-plan label{white-space:nowrap}#plugin-information .plugin-information-pricing .fs-plan var{font-style:normal}#plugin-information .plugin-information-pricing .fs-plan .fs-billing-frequency,#plugin-information .plugin-information-pricing .fs-plan .fs-annual-discount{text-align:center;display:block;font-weight:bold;margin-bottom:10px;text-transform:uppercase;background:#F3F3F3;padding:2px;border:1px solid #ccc}#plugin-information .plugin-information-pricing .fs-plan .fs-annual-discount{text-transform:none;color:green;background:greenyellow}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms{font-size:0.9em}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms i{float:left;margin:0 0 0 -15px}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms li{margin:10px 0 0 0}#plugin-information #section-features .fs-features{margin:-20px -26px}#plugin-information #section-features table{width:100%;border-spacing:0;border-collapse:separate}#plugin-information #section-features table thead th{padding:10px 0}#plugin-information #section-features table thead .fs-price{color:#71ae00;font-weight:normal;display:block;text-align:center}#plugin-information #section-features table tbody td{border-top:1px solid #ccc;padding:10px 0;text-align:center;width:100px;color:#71ae00}#plugin-information #section-features table tbody td:first-child{text-align:left;width:auto;color:inherit;padding-left:26px}#plugin-information #section-features table tbody tr.fs-odd td{background:#fefefe}#plugin-information #section-features .dashicons-yes{width:30px;height:30px;font-size:30px}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .button-group .button,#plugin-information .fs-dropdown .button-group .button{position:relative;width:auto;top:0;right:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .button-group .button:focus,#plugin-information .fs-dropdown .button-group .button:focus{z-index:10}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .button-group .fs-dropdown-arrow,#plugin-information .fs-dropdown .button-group .fs-dropdown-arrow{border-top:6px solid white;border-right:4px solid transparent;border-left:4px solid transparent;top:12px;position:relative}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active:not(.up) .button:not(.fs-dropdown-arrow-button),#plugin-information .fs-dropdown.active:not(.up) .button:not(.fs-dropdown-arrow-button){border-bottom-left-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active:not(.up) .fs-dropdown-arrow-button,#plugin-information .fs-dropdown.active:not(.up) .fs-dropdown-arrow-button{border-bottom-right-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active.up .button:not(.fs-dropdown-arrow-button),#plugin-information .fs-dropdown.active.up .button:not(.fs-dropdown-arrow-button){border-top-left-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active.up .fs-dropdown-arrow-button,#plugin-information .fs-dropdown.active.up .fs-dropdown-arrow-button{border-top-right-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list,#plugin-information .fs-dropdown .fs-dropdown-list{position:absolute;right:-1px;top:100%;margin-left:auto;padding:3px 0;border:1px solid #bfbfbf;background-color:#fff;z-index:1;width:230px;text-align:left;-moz-box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12);-webkit-box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12);box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li,#plugin-information .fs-dropdown .fs-dropdown-list li{margin:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li a,#plugin-information .fs-dropdown .fs-dropdown-list li a{display:block;padding:5px 10px;text-decoration:none;text-shadow:none}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li:hover,#plugin-information .fs-dropdown .fs-dropdown-list li:hover{background-color:#0074a3;color:#fff}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li:hover a,#plugin-information .fs-dropdown .fs-dropdown-list li:hover a{color:#fff}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown:not(.up) .fs-dropdown-list,#plugin-information .fs-dropdown:not(.up) .fs-dropdown-list{-moz-border-radius:3px 0 3px 3px;-webkit-border-radius:3px 0 3px 3px;border-radius:3px 0 3px 3px}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.up .fs-dropdown-list,#plugin-information .fs-dropdown.up .fs-dropdown-list{-moz-border-radius:3px 3px 0 3px;-webkit-border-radius:3px 3px 0 3px;border-radius:3px 3px 0 3px}#plugin-information .fs-dropdown .button-group{width:100%}#plugin-information .fs-dropdown .button-group .button{float:none;font-size:14px;font-weight:normal;text-transform:none}#plugin-information .fs-dropdown .fs-dropdown-list{margin-top:1px}#plugin-information .fs-dropdown.up .fs-dropdown-list{top:auto;bottom:100%;margin-bottom:2px}#plugin-information.wp-core-ui .fs-pricing-body .fs-dropdown .button-group{text-align:center;display:table}#plugin-information.wp-core-ui .fs-pricing-body .fs-dropdown .button-group .button{display:table-cell}#plugin-information.wp-core-ui .fs-pricing-body .fs-dropdown .button-group .button:not(.fs-dropdown-arrow-button){left:1px;width:100%}#plugin-information-footer>.button,#plugin-information-footer .fs-dropdown{position:relative;top:3px}#plugin-information-footer>.button.left,#plugin-information-footer .fs-dropdown.left{float:left}#plugin-information-footer>.right,#plugin-information-footer .fs-dropdown{float:right}@media screen and (max-width: 961px){#fs_addons .fs-cards-list .fs-card{height:265px}}
|
1 |
+
.fs-badge{position:absolute;top:10px;right:0;background:#71ae00;color:#fff;text-transform:uppercase;padding:5px 10px;-moz-border-radius:3px 0 0 3px;-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;font-weight:bold;border-right:0;-moz-box-shadow:0 2px 1px -1px rgba(0,0,0,.3);-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,.3);box-shadow:0 2px 1px -1px rgba(0,0,0,.3)}#fs_addons .fs-cards-list{list-style:none}#fs_addons .fs-cards-list .fs-card{float:left;height:152px;width:310px;padding:0;margin:0 0 30px 30px;font-size:14px;list-style:none;border:1px solid #ddd;cursor:pointer;position:relative}#fs_addons .fs-cards-list .fs-card .fs-overlay{position:absolute;left:0;right:0;bottom:0;top:0;z-index:9}#fs_addons .fs-cards-list .fs-card .fs-inner{background-color:#fff;overflow:hidden;height:100%;position:relative}#fs_addons .fs-cards-list .fs-card .fs-inner>ul{-moz-transition:all,.15s;-o-transition:all,.15s;-ms-transition:all,.15s;-webkit-transition:all,.15s;transition:all,.15s;left:0;right:0;top:0;position:absolute}#fs_addons .fs-cards-list .fs-card .fs-inner>ul>li{list-style:none;line-height:18px;padding:0 15px;width:100%;display:block;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-card-banner{padding:0;margin:0;line-height:0;display:block;height:100px;background-repeat:repeat-x;background-size:100% 100%;-moz-transition:all,.15s;-o-transition:all,.15s;-ms-transition:all,.15s;-webkit-transition:all,.15s;transition:all,.15s}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-card-banner .fs-badge.fs-installed-addon-badge{font-size:1.02em;line-height:1.3em}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-title{margin:10px 0 0 0;height:18px;overflow:hidden;color:#000;white-space:nowrap;text-overflow:ellipsis;font-weight:bold}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-offer{font-size:.9em}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-description{background-color:#f9f9f9;padding:10px 15px 100px 15px;border-top:1px solid #eee;margin:0 0 10px 0;color:#777}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-tag{position:absolute;top:10px;right:0px;background:#adff2f;display:block;padding:2px 10px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.3);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.3);box-shadow:1px 1px 1px rgba(0,0,0,.3);text-transform:uppercase;font-size:.9em;font-weight:bold}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-cta .button,#fs_addons .fs-cards-list .fs-card .fs-inner .fs-cta .button-group{position:absolute;top:112px;right:10px}@media screen and (min-width: 960px){#fs_addons .fs-cards-list .fs-card:hover .fs-overlay{border:2px solid #29abe1;margin-left:-1px;margin-top:-1px}#fs_addons .fs-cards-list .fs-card:hover .fs-inner ul{top:-100px}#fs_addons .fs-cards-list .fs-card:hover .fs-inner .fs-title,#fs_addons .fs-cards-list .fs-card:hover .fs-inner .fs-offer{color:#29abe1}}#TB_window,#TB_window iframe{width:821px !important}#plugin-information .fyi{width:266px !important}#plugin-information #section-holder{margin-right:299px;clear:none}#plugin-information #section-description h2,#plugin-information #section-description h3,#plugin-information #section-description p,#plugin-information #section-description b,#plugin-information #section-description i,#plugin-information #section-description blockquote,#plugin-information #section-description li,#plugin-information #section-description ul,#plugin-information #section-description ol{clear:none}#plugin-information #section-description iframe{max-width:100%}#plugin-information #section-description .fs-selling-points{padding-bottom:10px;border-bottom:1px solid #ddd}#plugin-information #section-description .fs-selling-points ul{margin:0}#plugin-information #section-description .fs-selling-points ul li{padding:0;list-style:none outside none}#plugin-information #section-description .fs-selling-points ul li i.dashicons{color:#71ae00;font-size:3em;vertical-align:middle;line-height:30px;float:left;margin:0 0 0 -15px}#plugin-information #section-description .fs-selling-points ul li h3{margin:1em 30px !important}#plugin-information #section-description .fs-screenshots:after{content:"";display:table;clear:both}#plugin-information #section-description .fs-screenshots ul{list-style:none;margin:0}#plugin-information #section-description .fs-screenshots ul li{width:225px;height:225px;float:left;margin-bottom:20px;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}#plugin-information #section-description .fs-screenshots ul li a{display:block;width:100%;height:100%;border:1px solid;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2);background-size:cover}#plugin-information #section-description .fs-screenshots ul li.odd{margin-right:20px}#plugin-information .plugin-information-pricing{margin:-16px;border-bottom:1px solid #ddd}#plugin-information .plugin-information-pricing .fs-plan h3{margin-top:0;padding:20px;font-size:16px}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper{border-bottom:1px solid #ddd}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab{cursor:pointer;position:relative;padding:0 10px;font-size:.9em}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab label{text-transform:uppercase;color:green;background:#adff2f;position:absolute;left:-1px;right:-1px;bottom:100%;border:1px solid #006400;padding:2px;text-align:center;font-size:.9em;line-height:1em}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab.nav-tab-active{cursor:default;background:#fffeec;border-bottom-color:#fffeec}#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle h3{background:#fffeec;margin:0;padding-bottom:0;color:#0073aa}#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle .nav-tab-wrapper,#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle .fs-billing-frequency{display:none}#plugin-information .plugin-information-pricing .fs-plan .fs-pricing-body{background:#fffeec;padding:20px}#plugin-information .plugin-information-pricing .fs-plan .button{width:100%;text-align:center;font-weight:bold;text-transform:uppercase;font-size:1.1em}#plugin-information .plugin-information-pricing .fs-plan label{white-space:nowrap}#plugin-information .plugin-information-pricing .fs-plan var{font-style:normal}#plugin-information .plugin-information-pricing .fs-plan .fs-billing-frequency,#plugin-information .plugin-information-pricing .fs-plan .fs-annual-discount{text-align:center;display:block;font-weight:bold;margin-bottom:10px;text-transform:uppercase;background:#f3f3f3;padding:2px;border:1px solid #ccc}#plugin-information .plugin-information-pricing .fs-plan .fs-annual-discount{text-transform:none;color:green;background:#adff2f}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms{font-size:.9em}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms i{float:left;margin:0 0 0 -15px}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms li{margin:10px 0 0 0}#plugin-information #section-features .fs-features{margin:-20px -26px}#plugin-information #section-features table{width:100%;border-spacing:0;border-collapse:separate}#plugin-information #section-features table thead th{padding:10px 0}#plugin-information #section-features table thead .fs-price{color:#71ae00;font-weight:normal;display:block;text-align:center}#plugin-information #section-features table tbody td{border-top:1px solid #ccc;padding:10px 0;text-align:center;width:100px;color:#71ae00}#plugin-information #section-features table tbody td:first-child{text-align:left;width:auto;color:inherit;padding-left:26px}#plugin-information #section-features table tbody tr.fs-odd td{background:#fefefe}#plugin-information #section-features .dashicons-yes{width:30px;height:30px;font-size:30px}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .button-group .button,#plugin-information .fs-dropdown .button-group .button{position:relative;width:auto;top:0;right:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .button-group .button:focus,#plugin-information .fs-dropdown .button-group .button:focus{z-index:10}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .button-group .fs-dropdown-arrow,#plugin-information .fs-dropdown .button-group .fs-dropdown-arrow{border-top:6px solid #fff;border-right:4px solid transparent;border-left:4px solid transparent;top:12px;position:relative}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active:not(.up) .button:not(.fs-dropdown-arrow-button),#plugin-information .fs-dropdown.active:not(.up) .button:not(.fs-dropdown-arrow-button){border-bottom-left-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active:not(.up) .fs-dropdown-arrow-button,#plugin-information .fs-dropdown.active:not(.up) .fs-dropdown-arrow-button{border-bottom-right-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active.up .button:not(.fs-dropdown-arrow-button),#plugin-information .fs-dropdown.active.up .button:not(.fs-dropdown-arrow-button){border-top-left-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active.up .fs-dropdown-arrow-button,#plugin-information .fs-dropdown.active.up .fs-dropdown-arrow-button{border-top-right-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list,#plugin-information .fs-dropdown .fs-dropdown-list{position:absolute;right:-1px;top:100%;margin-left:auto;padding:3px 0;border:1px solid #bfbfbf;background-color:#fff;z-index:1;width:230px;text-align:left;-moz-box-shadow:0px 2px 4px -1px rgba(0,0,0,.2),0px 4px 5px 0px rgba(0,0,0,.14),0px 1px 10px 0px rgba(0,0,0,.12);-webkit-box-shadow:0px 2px 4px -1px rgba(0,0,0,.2),0px 4px 5px 0px rgba(0,0,0,.14),0px 1px 10px 0px rgba(0,0,0,.12);box-shadow:0px 2px 4px -1px rgba(0,0,0,.2),0px 4px 5px 0px rgba(0,0,0,.14),0px 1px 10px 0px rgba(0,0,0,.12)}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li,#plugin-information .fs-dropdown .fs-dropdown-list li{margin:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li a,#plugin-information .fs-dropdown .fs-dropdown-list li a{display:block;padding:5px 10px;text-decoration:none;text-shadow:none}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li:hover,#plugin-information .fs-dropdown .fs-dropdown-list li:hover{background-color:#0074a3;color:#fff}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li:hover a,#plugin-information .fs-dropdown .fs-dropdown-list li:hover a{color:#fff}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown:not(.up) .fs-dropdown-list,#plugin-information .fs-dropdown:not(.up) .fs-dropdown-list{-moz-border-radius:3px 0 3px 3px;-webkit-border-radius:3px 0 3px 3px;border-radius:3px 0 3px 3px}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.up .fs-dropdown-list,#plugin-information .fs-dropdown.up .fs-dropdown-list{-moz-border-radius:3px 3px 0 3px;-webkit-border-radius:3px 3px 0 3px;border-radius:3px 3px 0 3px}#plugin-information .fs-dropdown .button-group{width:100%}#plugin-information .fs-dropdown .button-group .button{float:none;font-size:14px;font-weight:normal;text-transform:none}#plugin-information .fs-dropdown .fs-dropdown-list{margin-top:1px}#plugin-information .fs-dropdown.up .fs-dropdown-list{top:auto;bottom:100%;margin-bottom:2px}#plugin-information.wp-core-ui .fs-pricing-body .fs-dropdown .button-group{text-align:center;display:table}#plugin-information.wp-core-ui .fs-pricing-body .fs-dropdown .button-group .button{display:table-cell}#plugin-information.wp-core-ui .fs-pricing-body .fs-dropdown .button-group .button:not(.fs-dropdown-arrow-button){left:1px;width:100%}#plugin-information-footer>.button,#plugin-information-footer .fs-dropdown{position:relative;top:3px}#plugin-information-footer>.button.left,#plugin-information-footer .fs-dropdown.left{float:left}#plugin-information-footer>.right,#plugin-information-footer .fs-dropdown{float:right}@media screen and (max-width: 961px){#fs_addons .fs-cards-list .fs-card{height:265px}}
|
|
freemius/assets/css/admin/affiliation.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
|
1 |
+
#fs_affiliation_content_wrapper #messages{margin-top:25px}#fs_affiliation_content_wrapper h3{font-size:24px;padding:0;margin-left:0}#fs_affiliation_content_wrapper ul li{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;list-style-type:none}#fs_affiliation_content_wrapper ul li:before{content:"✓";margin-right:10px;font-weight:bold}#fs_affiliation_content_wrapper p:not(.description),#fs_affiliation_content_wrapper li,#fs_affiliation_content_wrapper label{font-size:16px !important;line-height:26px !important}#fs_affiliation_content_wrapper .button{margin-top:20px;margin-bottom:7px;line-height:35px;height:40px;font-size:16px}#fs_affiliation_content_wrapper .button#cancel_button{margin-right:5px}#fs_affiliation_content_wrapper form .input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form .input-container .input-label{font-weight:bold;display:block;width:100%}#fs_affiliation_content_wrapper form .input-container.input-container-text label,#fs_affiliation_content_wrapper form .input-container.input-container-text input,#fs_affiliation_content_wrapper form .input-container.input-container-text textarea{display:block}#fs_affiliation_content_wrapper form .input-container #add_domain,#fs_affiliation_content_wrapper form .input-container .remove-domain{text-decoration:none;display:inline-block;margin-top:3px}#fs_affiliation_content_wrapper form .input-container #add_domain:focus,#fs_affiliation_content_wrapper form .input-container .remove-domain:focus{box-shadow:none}#fs_affiliation_content_wrapper form .input-container #add_domain.disabled,#fs_affiliation_content_wrapper form .input-container .remove-domain.disabled{color:#aaa;cursor:default}#fs_affiliation_content_wrapper form #extra_domains_container .description{margin-top:0;position:relative;top:-4px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain{display:inline-block;margin-right:5px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain:last-of-type{margin-bottom:0}
|
freemius/assets/css/admin/clone-resolution.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.fs-notice[data-id^=clone_resolution_options_notice]{padding:0;color:inherit !important}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-body{padding:0;margin-bottom:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-header{padding:5px 10px}.fs-notice[data-id^=clone_resolution_options_notice] ol{margin-top:0;margin-bottom:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{display:flex;flex-direction:row;padding:0 10px 10px}@media(max-width: 750px){.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{flex-direction:column}}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option{border:1px solid #ccc;padding:10px 10px 15px 10px;flex:auto;margin:5px}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:first-child{margin-left:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:last-child{margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option strong{font-size:1.2em;padding:2px;line-height:1.5em}.fs-notice[data-id^=clone_resolution_options_notice] a{text-decoration:none}.fs-notice[data-id^=clone_resolution_options_notice] .button{margin-right:10px}.rtl .fs-notice[data-id^=clone_resolution_options_notice] .button{margin-right:0;margin-left:10px}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-documentation-container{padding:0 10px 15px}.fs-notice[data-id=temporary_duplicate_notice] #fs_clone_resolution_error_message{border:1px solid #d3135a;background:#fee;color:#d3135a;padding:10px}.fs-notice[data-id=temporary_duplicate_notice] ol{margin-top:0}
|
freemius/assets/css/admin/common.css
CHANGED
@@ -1,2 +1 @@
|
|
1 |
-
.fs-badge{position:absolute;top:10px;right:0;background:#71ae00;color
|
2 |
-
.fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px !important}.fs-notice.success{color:green}.fs-notice.promotion{border-color:#00a0d2 !important;background-color:#f2fcff !important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-close{cursor:pointer;color:#aaa;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{margin-top:7px;display:inline-block}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,0.3);color:#fff;padding:2px 10px;position:absolute;top:100%;bottom:auto;right:auto;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;left:10px;font-size:12px;font-weight:bold;cursor:auto}div.fs-notice.updated,div.fs-notice.success,div.fs-notice.promotion{display:block !important}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{position:fixed;top:32px;left:160px;right:0;background:#ebfdeb;padding:10px 20px;color:green;z-index:9999;-moz-box-shadow:0 2px 2px rgba(6,113,6,0.3);-webkit-box-shadow:0 2px 2px rgba(6,113,6,0.3);box-shadow:0 2px 2px rgba(6,113,6,0.3);opacity:0.95;filter:alpha(opacity=95)}.fs-secure-notice:hover{opacity:1;filter:alpha(opacity=100)}.fs-secure-notice a.fs-security-proof{color:green;text-decoration:none}@media screen and (max-width: 960px){.fs-secure-notice{left:36px}}@media screen and (max-width: 600px){.fs-secure-notice{display:none}}@media screen and (max-width: 1250px){#fs_promo_tab{display:none}}@media screen and (max-width: 782px){.fs-secure-notice{left:0;top:46px;text-align:center}}span.fs-submenu-item.fs-sub:before{content:'\21B3';padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:'\21B2'}.fs-submenu-item.pricing.upgrade-mode{color:greenyellow}.fs-submenu-item.pricing.trial-mode{color:#83e2ff}#adminmenu .update-plugins.fs-trial{background-color:#00b9eb}.fs-ajax-spinner{border:0;width:20px;height:20px;margin-right:5px;vertical-align:sub;display:inline-block;background:url("/wp-admin/images/wpspin_light-2x.gif");background-size:contain;margin-bottom:-2px}.wrap.fs-section h2{text-align:left}.plugins p.fs-upgrade-notice{border:0;background-color:#d54e21;padding:10px;color:#f9f9f9;margin-top:10px}
|
1 |
+
.fs-badge{position:absolute;top:10px;right:0;background:#71ae00;color:#fff;text-transform:uppercase;padding:5px 10px;-moz-border-radius:3px 0 0 3px;-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;font-weight:bold;border-right:0;-moz-box-shadow:0 2px 1px -1px rgba(0,0,0,.3);-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,.3);box-shadow:0 2px 1px -1px rgba(0,0,0,.3)}.theme-browser .theme .fs-premium-theme-badge-container{position:absolute;right:0;top:0}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge{position:relative;top:0;margin-top:10px;text-align:center}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-premium-theme-badge{font-size:1.1em}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-beta-theme-badge{background:#00a0d2}.fs-switch{position:relative;display:inline-block;color:#ccc;text-shadow:0 1px 1px rgba(255,255,255,.8);height:18px;padding:6px 6px 5px 6px;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);background:#ececec;box-shadow:0 0 4px rgba(0,0,0,.1),inset 0 1px 3px 0 rgba(0,0,0,.1);cursor:pointer}.fs-switch span{display:inline-block;width:35px;text-transform:uppercase}.fs-switch .fs-toggle{position:absolute;top:1px;width:37px;height:25px;border:1px solid #ccc;border:1px solid rgba(0,0,0,.3);border-radius:4px;background:#fff;background-color:#fff;background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #ececec), color-stop(1, #fff));background-image:-webkit-linear-gradient(top, #ececec, #fff);background-image:-moz-linear-gradient(top, #ececec, #fff);background-image:-ms-linear-gradient(top, #ececec, #fff);background-image:-o-linear-gradient(top, #ececec, #fff);background-image:linear-gradient(top, bottom, #ececec, #fff);box-shadow:inset 0 1px 0 0 rgba(255,255,255,.5);z-index:999;-moz-transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1);-o-transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1);-ms-transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1);-webkit-transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1);transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1)}.fs-switch.fs-off .fs-toggle{left:2%}.fs-switch.fs-on .fs-toggle{left:54%}.fs-switch.fs-round{top:8px;padding:4px 25px;-moz-border-radius:24px;-webkit-border-radius:24px;border-radius:24px}.fs-switch.fs-round .fs-toggle{top:0;width:24px;height:24px;-moz-border-radius:24px;-webkit-border-radius:24px;border-radius:24px}.fs-switch.fs-round.fs-off .fs-toggle{left:-1px}.fs-switch.fs-round.fs-on{background:#0085ba}.fs-switch.fs-round.fs-on .fs-toggle{left:25px}.fs-switch.fs-small.fs-round{padding:1px 19px}.fs-switch.fs-small.fs-round .fs-toggle{top:0;width:18px;height:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px}.fs-switch.fs-small.fs-round.fs-on .fs-toggle{left:19px}body.fs-loading,body.fs-loading *{cursor:wait !important}#fs_frame{line-height:0;font-size:0}.fs-full-size-wrapper{margin:40px 0 -65px -20px}@media(max-width: 600px){.fs-full-size-wrapper{margin:0 0 -65px -10px}}.fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px !important}.fs-notice.success{color:green}.fs-notice.promotion{border-color:#00a0d2 !important;background-color:#f2fcff !important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-close{cursor:pointer;color:#aaa;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{margin-top:7px;display:inline-block}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,.3);color:#fff;padding:2px 10px;position:absolute;top:100%;bottom:auto;right:auto;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;left:10px;font-size:12px;font-weight:bold;cursor:auto}div.fs-notice.updated,div.fs-notice.success,div.fs-notice.promotion{display:block !important}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{position:fixed;top:32px;left:160px;right:0;background:#ebfdeb;padding:10px 20px;color:green;z-index:9999;-moz-box-shadow:0 2px 2px rgba(6,113,6,.3);-webkit-box-shadow:0 2px 2px rgba(6,113,6,.3);box-shadow:0 2px 2px rgba(6,113,6,.3);opacity:.95;filter:alpha(opacity=95)}.fs-secure-notice:hover{opacity:1;filter:alpha(opacity=100)}.fs-secure-notice a.fs-security-proof{color:green;text-decoration:none}@media screen and (max-width: 960px){.fs-secure-notice{left:36px}}@media screen and (max-width: 600px){.fs-secure-notice{display:none}}@media screen and (max-width: 1250px){#fs_promo_tab{display:none}}@media screen and (max-width: 782px){.fs-secure-notice{left:0;top:46px;text-align:center}}span.fs-submenu-item.fs-sub:before{content:"↳";padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:"↲"}.fs-submenu-item.pricing.upgrade-mode{color:#adff2f}.fs-submenu-item.pricing.trial-mode{color:#83e2ff}#adminmenu .update-plugins.fs-trial{background-color:#00b9eb}.fs-ajax-spinner{border:0;width:20px;height:20px;margin-right:5px;vertical-align:sub;display:inline-block;background:url("/wp-admin/images/wpspin_light-2x.gif");background-size:contain;margin-bottom:-2px}.wrap.fs-section h2{text-align:left}.plugins p.fs-upgrade-notice{border:0;background-color:#d54e21;padding:10px;color:#f9f9f9;margin-top:10px}
|
|
freemius/assets/css/admin/connect.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
#fs_connect{width:480px;-moz-box-shadow:0px 1px 2px rgba(0,0,0,0.3);-webkit-box-shadow:0px 1px 2px rgba(0,0,0,0.3);box-shadow:0px 1px 2px rgba(0,0,0,0.3);margin:20px 0}@media screen and (max-width: 479px){#fs_connect{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none;width:auto;margin:0 0 0 -10px}}#fs_connect .fs-content{background:#fff;padding:15px 20px}#fs_connect .fs-content .fs-error{background:snow;color:#d3135a;border:1px solid #d3135a;-moz-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);text-align:center;padding:5px;margin-bottom:10px}#fs_connect .fs-content p{margin:0;padding:0;font-size:1.2em}#fs_connect .fs-license-key-container{position:relative;width:280px;margin:10px auto 0 auto}#fs_connect .fs-license-key-container input{width:100%}#fs_connect .fs-license-key-container .dashicons{position:absolute;top:5px;right:5px}#fs_connect.require-license-key .fs-sites-list-container td{cursor:pointer}#fs_connect #delegate_to_site_admins{margin-right:15px;float:right;height:26px;vertical-align:middle;line-height:37px;font-weight:bold;border-bottom:1px dashed;text-decoration:none}#fs_connect #delegate_to_site_admins.rtl{margin-left:15px;margin-right:0}#fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}#fs_connect .fs-actions .button{padding:0 10px 1px;line-height:35px;height:37px;font-size:16px;margin-bottom:0}#fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}#fs_connect .fs-actions .button.button-primary{padding-right:15px;padding-left:15px}#fs_connect .fs-actions .button.button-primary:after{content:' \279C'}#fs_connect .fs-actions .button.button-primary.fs-loading:after{content:''}#fs_connect .fs-actions .button.button-secondary{float:right}#fs_connect.fs-anonymous-disabled .fs-actions .button.button-primary{width:100%}#fs_connect .fs-permissions{padding:10px 20px;background:#FEFEFE;-moz-transition:background 0.5s ease;-o-transition:background 0.5s ease;-ms-transition:background 0.5s ease;-webkit-transition:background 0.5s ease;transition:background 0.5s ease}#fs_connect .fs-permissions .fs-license-sync-disclaimer{text-align:center;margin-top:0}#fs_connect .fs-permissions>.fs-trigger{font-size:0.9em;text-decoration:none;text-align:center;display:block}#fs_connect .fs-permissions ul{height:0;overflow:hidden;margin:0}#fs_connect .fs-permissions ul li{margin-bottom:12px}#fs_connect .fs-permissions ul li:last-child{margin-bottom:0}#fs_connect .fs-permissions ul li>i.dashicons{float:left;font-size:40px;width:40px;height:40px}#fs_connect .fs-permissions ul li .fs-switch{float:right}#fs_connect .fs-permissions ul li .fs-permission-description{margin-left:55px}#fs_connect .fs-permissions ul li .fs-permission-description span{font-weight:bold;text-transform:uppercase;color:#23282d}#fs_connect .fs-permissions ul li .fs-permission-description p{margin:2px 0 0 0}#fs_connect .fs-permissions.fs-open{background:#fff}#fs_connect .fs-permissions.fs-open ul{overflow:initial;height:auto;margin:20px 20px 10px 20px}@media screen and (max-width: 479px){#fs_connect .fs-permissions{background:#fff}#fs_connect .fs-permissions .fs-trigger{display:none}#fs_connect .fs-permissions ul{height:auto;margin:20px}}#fs_connect .fs-freemium-licensing{padding:8px;background:#777;color:#fff}#fs_connect .fs-freemium-licensing p{text-align:center;display:block;margin:0;padding:0}#fs_connect .fs-freemium-licensing a{color:#C2EEFF;text-decoration:underline}#fs_connect .fs-visual{padding:12px;line-height:0;background:#fafafa;height:80px;position:relative}#fs_connect .fs-visual .fs-site-icon{position:absolute;left:20px;top:10px}#fs_connect .fs-visual .fs-connect-logo{position:absolute;right:20px;top:10px}#fs_connect .fs-visual .fs-plugin-icon{position:absolute;top:10px;left:50%;margin-left:-40px}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-site-icon,#fs_connect .fs-visual img,#fs_connect .fs-visual object{width:80px;height:80px}#fs_connect .fs-visual .dashicons-wordpress{font-size:64px;background:#01749a;color:#fff;width:64px;height:64px;padding:8px}#fs_connect .fs-visual .dashicons-plus{position:absolute;top:50%;font-size:30px;margin-top:-10px;color:#bbb}#fs_connect .fs-visual .dashicons-plus.fs-first{left:28%}#fs_connect .fs-visual .dashicons-plus.fs-second{left:65%}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-connect-logo,#fs_connect .fs-visual .fs-site-icon{border:1px solid #ccc;padding:1px;background:#fff}#fs_connect .fs-terms{text-align:center;font-size:0.85em;padding:5px;background:rgba(0,0,0,0.05)}#fs_connect .fs-terms,#fs_connect .fs-terms a{color:#999}#fs_connect .fs-terms a{text-decoration:none}.fs-multisite-options-container{margin-top:10px;border:1px solid #ccc;padding:5px}.fs-multisite-options-container a{text-decoration:none}.fs-multisite-options-container a:focus{box-shadow:none}.fs-multisite-options-container a.selected{font-weight:bold}.fs-multisite-options-container.fs-apply-on-all-sites{border:0 none;padding:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options{border-spacing:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options td:not(:first-child){display:none}.fs-multisite-options-container .fs-sites-list-container{display:none;overflow:auto}.fs-multisite-options-container .fs-sites-list-container table td{border-top:1px solid #ccc;padding:4px 2px}.fs-tooltip-trigger{position:relative}.fs-tooltip-trigger:not(a){cursor:help}.fs-tooltip-trigger .fs-tooltip{opacity:0;visibility:hidden;-moz-transition:opacity 0.3s ease-in-out;-o-transition:opacity 0.3s ease-in-out;-ms-transition:opacity 0.3s ease-in-out;-webkit-transition:opacity 0.3s ease-in-out;transition:opacity 0.3s ease-in-out;position:absolute;background:rgba(0,0,0,0.8);color:#fff !important;font-family:'arial', serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:-17px;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,0.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,0.2);box-shadow:1px 1px 1px rgba(0,0,0,0.2);line-height:1.3em;font-weight:bold;text-align:left;text-transform:none !important}.rtl .fs-tooltip-trigger .fs-tooltip{text-align:right;left:auto;right:-17px}.fs-tooltip-trigger .fs-tooltip::after{content:' ';display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:rgba(0,0,0,0.8) transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl .fs-tooltip-trigger .fs-tooltip::after{right:21px;left:auto}.fs-tooltip-trigger:hover .fs-tooltip{visibility:visible;opacity:1}#fs_marketing_optin{display:none;margin-top:10px;border:1px solid #ccc;padding:10px;line-height:1.5em}#fs_marketing_optin .fs-message{display:block;margin-bottom:5px;font-size:1.05em;font-weight:600}#fs_marketing_optin.error{border:1px solid #d3135a;background:#fee}#fs_marketing_optin.error .fs-message{color:#d3135a}#fs_marketing_optin .fs-input-container{margin-top:5px}#fs_marketing_optin .fs-input-container label{margin-top:5px;display:block}#fs_marketing_optin .fs-input-container label input{float:left;margin:1px 0 0 0}#fs_marketing_optin .fs-input-container label:first-child{display:block;margin-bottom:2px}#fs_marketing_optin .fs-input-label{display:block;margin-left:20px}#fs_marketing_optin .fs-input-label .underlined{text-decoration:underline}.rtl #fs_marketing_optin .fs-input-container label input{float:right}.rtl #fs_marketing_optin .fs-input-label{margin-left:0;margin-right:20px}.rtl #fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}.rtl #fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}.rtl #fs_connect .fs-actions .button.button-primary:after{content:' \000bb'}.rtl #fs_connect .fs-actions .button.button-primary.fs-loading:after{content:''}.rtl #fs_connect .fs-actions .button.button-secondary{float:left}.rtl #fs_connect .fs-permissions ul li .fs-permission-description{margin-right:55px;margin-left:0}.rtl #fs_connect .fs-permissions ul li .fs-switch{float:left}.rtl #fs_connect .fs-permissions ul li i.dashicons{float:right}.rtl #fs_connect .fs-visual .fs-site-icon{right:20px;left:auto}.rtl #fs_connect .fs-visual .fs-connect-logo{right:auto;left:20px}#fs_theme_connect_wrapper{position:fixed;top:0;height:100%;width:100%;z-index:99990;background:rgba(0,0,0,0.75);text-align:center;overflow-y:auto}#fs_theme_connect_wrapper:before{content:"";display:inline-block;vertical-align:middle;height:100%}#fs_theme_connect_wrapper>button.close{color:white;cursor:pointer;height:40px;width:40px;position:absolute;right:0;border:0;background-color:transparent;top:32px}#fs_theme_connect_wrapper #fs_connect{top:0;text-align:left;display:inline-block;vertical-align:middle;margin-top:52px;margin-bottom:20px}#fs_theme_connect_wrapper #fs_connect .fs-terms{background:rgba(140,140,140,0.64)}#fs_theme_connect_wrapper #fs_connect .fs-terms,#fs_theme_connect_wrapper #fs_connect .fs-terms a{color:#c5c5c5}.wp-pointer-content #fs_connect{margin:0;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.fs-opt-in-pointer .wp-pointer-content{padding:0}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow{border-bottom-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#fafafa}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow{border-top-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow-inner{border-top-color:#fafafa}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow{border-right-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow-inner{border-right-color:#fafafa}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow{border-left-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow-inner{border-left-color:#fafafa}#license_issues_link{display:block;text-align:center;font-size:0.9em;margin-top:10px}
|
1 |
+
.fs-tooltip-trigger{position:relative}.fs-tooltip-trigger:not(a){cursor:help}.fs-tooltip-trigger .dashicons{float:none !important}.fs-tooltip-trigger .fs-tooltip{opacity:0;visibility:hidden;-moz-transition:opacity .3s ease-in-out;-o-transition:opacity .3s ease-in-out;-ms-transition:opacity .3s ease-in-out;-webkit-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;position:absolute;background:rgba(0,0,0,.8);color:#fff !important;font-family:"arial",serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:-17px;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2);line-height:1.3em;font-weight:bold;text-align:left;text-transform:none !important}.rtl .fs-tooltip-trigger .fs-tooltip{text-align:right;left:auto;right:-17px}.fs-tooltip-trigger .fs-tooltip::after{content:" ";display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:rgba(0,0,0,.8) transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl .fs-tooltip-trigger .fs-tooltip::after{right:21px;left:auto}.fs-tooltip-trigger:hover .fs-tooltip{visibility:visible;opacity:1}#fs_connect{width:484px;margin:60px auto 20px auto}#fs_connect a{color:inherit}#fs_connect a:not(.button){text-decoration:underline}#fs_connect .fs-box-container{box-shadow:0 1px 2px rgba(0,0,0,.3);border-radius:3px;overflow:hidden;padding-top:40px;background:#f0f0f1}@media screen and (max-width: 483px){#fs_connect{width:auto;margin:30px 0 0 -10px}#fs_connect .fs-box-container{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}}#fs_connect .fs-content{background:#fff;padding:30px 20px}#fs_connect .fs-content .fs-error{background:snow;color:#d3135a;border:1px solid #d3135a;-moz-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);text-align:center;padding:5px;margin-bottom:10px}#fs_connect .fs-content h2{line-height:1.5em}#fs_connect .fs-content p{margin:0;padding:0;font-size:1.2em}#fs_connect .fs-license-key-container{position:relative;width:280px;margin:10px auto 0 auto}#fs_connect .fs-license-key-container input{width:100%}#fs_connect .fs-license-key-container .dashicons{position:absolute;top:5px;right:5px}#fs_connect.require-license-key .fs-content{padding-bottom:10px}#fs_connect.require-license-key .fs-actions{border-top:none}#fs_connect.require-license-key .fs-sites-list-container td{cursor:pointer}#fs_connect #delegate_to_site_admins{margin-right:15px;float:right;height:26px;vertical-align:middle;line-height:37px;font-weight:bold;border-bottom:1px dashed;text-decoration:none}#fs_connect #delegate_to_site_admins.rtl{margin-left:15px;margin-right:0}#fs_connect .fs-actions{padding:10px 20px;background:#fff;border-width:1px 0;border-style:solid;border-color:#f1f1f1}#fs_connect .fs-actions .button{padding:0 10px 1px;line-height:35px;height:37px;font-size:16px;margin-bottom:0}#fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}#fs_connect .fs-actions .button.button-primary{padding-right:15px;padding-left:15px}#fs_connect .fs-actions .button.button-primary:after{content:" ➜"}#fs_connect .fs-actions .button.button-primary.fs-loading:after{content:""}#fs_connect .fs-actions .button.button-secondary{float:right}#fs_connect.fs-anonymous-disabled .fs-actions .button.button-primary{width:100%}#fs_connect .fs-permissions{padding:10px 20px;background:#fff;-moz-transition:background .5s ease;-o-transition:background .5s ease;-ms-transition:background .5s ease;-webkit-transition:background .5s ease;transition:background .5s ease}#fs_connect .fs-permissions .fs-license-sync-disclaimer{text-align:center;margin-top:0}#fs_connect .fs-permissions>.fs-trigger{font-size:.9em;text-decoration:none;text-align:center;display:block}#fs_connect .fs-permissions>.fs-trigger .fs-arrow::after{content:"→";width:20px;display:inline-block}#fs_connect .fs-permissions.fs-open>.fs-trigger .fs-arrow::after{content:"↓" !important}#fs_connect .fs-permissions ul li{padding-left:0;padding-right:0}@media screen and (max-width: 483px){#fs_connect .fs-permissions ul{height:auto;margin:20px}}#fs_connect .fs-freemium-licensing{padding:8px;background:#777;color:#fff}#fs_connect .fs-freemium-licensing p{text-align:center;display:block;margin:0;padding:0}#fs_connect .fs-freemium-licensing a{color:inherit;text-decoration:underline}#fs_connect .fs-header{padding:0;line-height:0;height:0;position:relative}#fs_connect .fs-header .fs-site-icon,#fs_connect .fs-header .fs-connect-logo{position:absolute;top:-8px;border-radius:50%}#fs_connect .fs-header .fs-site-icon{left:152px}#fs_connect .fs-header .fs-connect-logo{right:152px}#fs_connect .fs-header .fs-site-icon,#fs_connect .fs-header img,#fs_connect .fs-header object{width:50px;height:50px;border-radius:50%}#fs_connect .fs-header .fs-plugin-icon{position:absolute;overflow:hidden;top:-23px;left:50%;margin-left:-44px;border-radius:50%;z-index:1}#fs_connect .fs-header .fs-plugin-icon,#fs_connect .fs-header .fs-plugin-icon img{width:80px;height:80px}#fs_connect .fs-header .dashicons-wordpress-alt{font-size:40px;background:#01749a;color:#fff;width:40px;height:40px;padding:5px;border-radius:50%}#fs_connect .fs-header .dashicons-plus{position:absolute;top:50%;font-size:30px;margin-top:-10px;color:#bbb}#fs_connect .fs-header .dashicons-plus.fs-first{left:28%}#fs_connect .fs-header .dashicons-plus.fs-second{left:65%}#fs_connect .fs-header .fs-plugin-icon,#fs_connect .fs-header .fs-connect-logo,#fs_connect .fs-header .fs-site-icon{border:1px solid #efefef;padding:3px;background:#fff}#fs_connect .fs-terms{text-align:center;font-size:.85em;padding:10px 5px}#fs_connect .fs-terms,#fs_connect .fs-terms a{color:#999}#fs_connect .fs-terms a{text-decoration:none}.fs-multisite-options-container{margin-top:20px;border:1px solid #ccc;padding:5px}.fs-multisite-options-container a{text-decoration:none}.fs-multisite-options-container a:focus{box-shadow:none}.fs-multisite-options-container a.selected{font-weight:bold}.fs-multisite-options-container.fs-apply-on-all-sites{border:0 none;padding:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options{border-spacing:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options td:not(:first-child){display:none}.fs-multisite-options-container .fs-sites-list-container{display:none;overflow:auto}.fs-multisite-options-container .fs-sites-list-container table td{border-top:1px solid #ccc;padding:4px 2px}#fs_marketing_optin{display:none;margin-top:10px;border:1px solid #ccc;padding:10px;line-height:1.5em}#fs_marketing_optin .fs-message{display:block;margin-bottom:5px;font-size:1.05em;font-weight:600}#fs_marketing_optin.error{border:1px solid #d3135a;background:#fee}#fs_marketing_optin.error .fs-message{color:#d3135a}#fs_marketing_optin .fs-input-container{margin-top:5px}#fs_marketing_optin .fs-input-container label{margin-top:5px;display:block}#fs_marketing_optin .fs-input-container label input{float:left;margin:1px 0 0 0}#fs_marketing_optin .fs-input-container label:first-child{display:block;margin-bottom:2px}#fs_marketing_optin .fs-input-label{display:block;margin-left:20px}#fs_marketing_optin .fs-input-label .underlined{text-decoration:underline}.rtl #fs_marketing_optin .fs-input-container label input{float:right}.rtl #fs_marketing_optin .fs-input-label{margin-left:0;margin-right:20px}.rtl #fs_connect{border-radius:3px}.rtl #fs_connect .fs-actions{padding:10px 20px;background:#c0c7ca}.rtl #fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}.rtl #fs_connect .fs-actions .button.button-primary:after{content:" »"}.rtl #fs_connect .fs-actions .button.button-primary.fs-loading:after{content:""}.rtl #fs_connect .fs-actions .button.button-secondary{float:left}.rtl #fs_connect .fs-header .fs-site-icon{right:20px;left:auto}.rtl #fs_connect .fs-header .fs-connect-logo{right:auto;left:20px}.rtl #fs_connect .fs-permissions>.fs-trigger .fs-arrow::after{content:"←"}#fs_theme_connect_wrapper{position:fixed;top:0;height:100%;width:100%;z-index:99990;background:rgba(0,0,0,.75);text-align:center;overflow-y:auto}#fs_theme_connect_wrapper:before{content:"";display:inline-block;vertical-align:middle;height:100%}#fs_theme_connect_wrapper>button.close{color:#fff;cursor:pointer;height:40px;width:40px;position:absolute;right:0;border:0;background-color:transparent;top:32px}#fs_theme_connect_wrapper #fs_connect{top:0;text-align:left;display:inline-block;vertical-align:middle;margin-top:0;margin-bottom:20px}#fs_theme_connect_wrapper #fs_connect .fs-terms,#fs_theme_connect_wrapper #fs_connect .fs-terms a{color:#c5c5c5}.wp-pointer-content #fs_connect{margin:0;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.fs-opt-in-pointer .wp-pointer-content{padding:0}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow{border-bottom-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#fafafa}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow{border-top-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow-inner{border-top-color:#fafafa}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow{border-right-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow-inner{border-right-color:#fafafa}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow{border-left-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow-inner{border-left-color:#fafafa}#license_issues_link{display:block;text-align:center;font-size:.9em;margin-top:10px}.fs-tooltip-trigger{position:relative}.fs-tooltip-trigger:not(a){cursor:help}.fs-tooltip-trigger .dashicons{float:none !important}.fs-tooltip-trigger .fs-tooltip{opacity:0;visibility:hidden;-moz-transition:opacity .3s ease-in-out;-o-transition:opacity .3s ease-in-out;-ms-transition:opacity .3s ease-in-out;-webkit-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;position:absolute;background:rgba(0,0,0,.8);color:#fff !important;font-family:"arial",serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:-17px;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2);line-height:1.3em;font-weight:bold;text-align:left;text-transform:none !important}.rtl .fs-tooltip-trigger .fs-tooltip{text-align:right;left:auto;right:-17px}.fs-tooltip-trigger .fs-tooltip::after{content:" ";display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:rgba(0,0,0,.8) transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl .fs-tooltip-trigger .fs-tooltip::after{right:21px;left:auto}.fs-tooltip-trigger:hover .fs-tooltip{visibility:visible;opacity:1}.fs-permissions .fs-permission.fs-disabled{color:#aaa}.fs-permissions .fs-permission.fs-disabled .fs-permission-description span{color:#aaa}.fs-permissions .fs-permission .fs-switch-feedback{position:absolute;right:15px;top:52px}.fs-permissions ul{height:0;overflow:hidden;margin:0}.fs-permissions ul li{padding:17px 15px;margin:0;position:relative}.fs-permissions ul li>i.dashicons{float:left;font-size:30px;width:30px;height:30px;padding:5px}.fs-permissions ul li .fs-switch{float:right}.fs-permissions ul li .fs-permission-description{margin-left:55px}.fs-permissions ul li .fs-permission-description span{font-size:14px;font-weight:500;color:#23282d}.fs-permissions ul li .fs-permission-description .fs-tooltip{font-size:13px;font-weight:bold}.fs-permissions ul li .fs-permission-description .fs-tooltip-trigger .dashicons{margin:-1px 2px 0 2px}.fs-permissions ul li .fs-permission-description p{margin:2px 0 0 0}.fs-permissions.fs-open{background:#fff}.fs-permissions.fs-open ul{overflow:initial;height:auto;margin:20px 0 10px 0}.fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-right:10px}.fs-permissions .fs-switch-feedback.success{color:#71ae00}.rtl .fs-permissions .fs-switch-feedback{right:auto;left:15px}.rtl .fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-left:10px;margin-right:0}.rtl .fs-permissions ul li .fs-permission-description{margin-right:55px;margin-left:0}.rtl .fs-permissions ul li .fs-switch{float:left}.rtl .fs-permissions ul li i.dashicons{float:right}
|
freemius/assets/css/admin/debug.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.fs-switch-label{font-size:20px;line-height:31px;margin:0 5px}#fs_log_book table{font-family:Consolas,Monaco,monospace;font-size:12px}#fs_log_book table th{color:#ccc}#fs_log_book table tr{background:#232525}#fs_log_book table tr.alternate{background:#2b2b2b}#fs_log_book table tr td.fs-col--logger{color:#5a7435}#fs_log_book table tr td.fs-col--type{color:#ffc861}#fs_log_book table tr td.fs-col--function{color:#a7b7b1;font-weight:bold}#fs_log_book table tr td.fs-col--message,#fs_log_book table tr td.fs-col--message a{color:#9a73ac !important}#fs_log_book table tr td.fs-col--file{color:#d07922}#fs_log_book table tr td.fs-col--timestamp{color:#6596be}
|
1 |
+
label.fs-tag,span.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-switch-label{font-size:20px;line-height:31px;margin:0 5px}#fs_log_book table{font-family:Consolas,Monaco,monospace;font-size:12px}#fs_log_book table th{color:#ccc}#fs_log_book table tr{background:#232525}#fs_log_book table tr.alternate{background:#2b2b2b}#fs_log_book table tr td.fs-col--logger{color:#5a7435}#fs_log_book table tr td.fs-col--type{color:#ffc861}#fs_log_book table tr td.fs-col--function{color:#a7b7b1;font-weight:bold}#fs_log_book table tr td.fs-col--message,#fs_log_book table tr td.fs-col--message a{color:#9a73ac !important}#fs_log_book table tr td.fs-col--file{color:#d07922}#fs_log_book table tr td.fs-col--timestamp{color:#6596be}
|
freemius/assets/css/admin/dialog-boxes.css
CHANGED
@@ -1,2 +1 @@
|
|
1 |
-
.fs-modal{position:fixed;overflow:auto;height:100%;width:100%;top:0;z-index:100000;display:none;background:rgba(0,0,0,0.6)}.fs-modal .dashicons{vertical-align:middle}.fs-modal .fs-modal-dialog{background:transparent;position:absolute;left:50%;margin-left:-298px;padding-bottom:30px;top:-100%;z-index:100001;width:596px}@media (max-width: 650px){.fs-modal .fs-modal-dialog{margin-left:-50%;box-sizing:border-box;padding-left:10px;padding-right:10px;width:100%}.fs-modal .fs-modal-dialog .fs-modal-panel>h3>strong{font-size:1.3em}}.fs-modal.active{display:block}.fs-modal.active:before{display:block}.fs-modal.active .fs-modal-dialog{top:10%}.fs-modal.fs-success .fs-modal-header{border-bottom-color:#46b450}.fs-modal.fs-success .fs-modal-body{background-color:#f7fff7}.fs-modal.fs-warn .fs-modal-header{border-bottom-color:#ffb900}.fs-modal.fs-warn .fs-modal-body{background-color:#fff8e5}.fs-modal.fs-error .fs-modal-header{border-bottom-color:#dc3232}.fs-modal.fs-error .fs-modal-body{background-color:#ffeaea}.fs-modal .fs-modal-body,.fs-modal .fs-modal-footer{border:0;background:#fefefe;padding:20px}.fs-modal .fs-modal-header{border-bottom:#eeeeee solid 1px;background:#fbfbfb;padding:15px 20px;position:relative;margin-bottom:-10px}.fs-modal .fs-modal-header h4{margin:0;padding:0;text-transform:uppercase;font-size:1.2em;font-weight:bold;color:#cacaca;text-shadow:1px 1px 1px #fff;letter-spacing:0.6px;-webkit-font-smoothing:antialiased}.fs-modal .fs-modal-header .fs-close{position:absolute;right:10px;top:12px;cursor:pointer;color:#bbb;-moz-border-radius:20px;-webkit-border-radius:20px;border-radius:20px;padding:3px;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;-ms-transition:all 0.2s ease-in-out;-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.fs-modal .fs-modal-header .fs-close:hover{color:#fff;background:#aaa}.fs-modal .fs-modal-header .fs-close .dashicons,.fs-modal .fs-modal-header .fs-close:hover .dashicons{text-decoration:none}.fs-modal .fs-modal-body{border-bottom:0}.fs-modal .fs-modal-body p{font-size:14px}.fs-modal .fs-modal-body h2{font-size:20px;line-height:1.5em}.fs-modal .fs-modal-body>div{margin-top:10px}.fs-modal .fs-modal-body>div h2{font-weight:bold;font-size:20px;margin-top:0}.fs-modal .fs-modal-footer{border-top:#eeeeee solid 1px;text-align:right}.fs-modal .fs-modal-footer>.button{margin:0 7px}.fs-modal .fs-modal-footer>.button:first-child{margin:0}.fs-modal .fs-modal-panel>.notice.inline{margin:0;display:none}.fs-modal .fs-modal-panel:not(.active){display:none}.rtl .fs-modal .fs-modal-header .fs-close{right:auto;left:20px}body.has-fs-modal{overflow:hidden}.fs-modal.fs-modal-deactivation-feedback .reason-input,.fs-modal.fs-modal-deactivation-feedback .internal-message{margin:3px 0 3px 22px}.fs-modal.fs-modal-deactivation-feedback .reason-input input,.fs-modal.fs-modal-deactivation-feedback .reason-input textarea,.fs-modal.fs-modal-deactivation-feedback .internal-message input,.fs-modal.fs-modal-deactivation-feedback .internal-message textarea{width:100%}.fs-modal.fs-modal-deactivation-feedback li.reason.has-internal-message .internal-message{border:1px solid #ccc;padding:7px;display:none}@media (max-width: 650px){.fs-modal.fs-modal-deactivation-feedback li.reason li.reason{margin-bottom:10px}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason .reason-input,.fs-modal.fs-modal-deactivation-feedback li.reason li.reason .internal-message{margin-left:29px}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason label{display:table}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason label>span{display:table-cell;font-size:1.3em}}.fs-modal.fs-modal-deactivation-feedback .anonymous-feedback-label{float:left}.fs-modal.fs-modal-deactivation-feedback .fs-modal-panel{margin-top:0 !important}.fs-modal.fs-modal-deactivation-feedback .fs-modal-panel h3{margin-top:0;line-height:1.5em}#the-list .deactivate>.fs-slug{display:none}.fs-modal.fs-modal-subscription-cancellation .fs-price-increase-warning{color:red;font-weight:bold;padding:0 25px;margin-bottom:0}.fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label input{float:left;top:5px;position:relative}.rtl .fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label input{float:right}.fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label span{display:block;margin-left:24px}.rtl .fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label span{margin-left:0;margin-right:24px}.fs-modal.fs-modal-license-activation .fs-modal-body input.fs-license-key{width:100%}.fs-license-options-container table,.fs-license-options-container table select,.fs-license-options-container table .fs-available-license-key{width:100%}.fs-license-options-container table td:first-child{width:1%}.fs-license-options-container table .fs-other-license-key-container label{position:relative;top:6px;float:left;margin-right:5px}.fs-license-options-container table .fs-other-license-key-container div{overflow:hidden;width:auto;height:30px;display:block;top:2px;position:relative}.fs-license-options-container table .fs-other-license-key-container div input{margin:0}.fs-sites-list-container td{cursor:pointer}.fs-modal.fs-modal-user-change .fs-modal-body input#fs_other_email_address{width:100%}.fs-user-change-options-container table{width:100%;border-collapse:collapse}.fs-user-change-options-container table tr{display:block;margin-bottom:2px}.fs-user-change-options-container table .fs-email-address-container td{display:inline-block}.fs-user-change-options-container table .fs-email-address-container input[type="radio"]{margin-bottom:0;margin-top:0}.fs-user-change-options-container table .fs-other-email-address-container{width:100%}.fs-user-change-options-container table .fs-other-email-address-container>div{display:table;width:100%}.fs-user-change-options-container table .fs-other-email-address-container>div label,.fs-user-change-options-container table .fs-other-email-address-container>div>div{display:table-cell}.fs-user-change-options-container table .fs-other-email-address-container>div label{width:1%;padding-left:3px;padding-right:3px}.fs-user-change-options-container table .fs-other-email-address-container>div>div{width:auto}.fs-user-change-options-container table .fs-other-email-address-container>div>div input{width:100%}.fs-modal.fs-modal-developer-license-debug-mode .fs-modal-body input.fs-license-or-user-key{width:100%}.fs-multisite-options-container{margin-top:10px;border:1px solid #ccc;padding:5px}.fs-multisite-options-container a{text-decoration:none}.fs-multisite-options-container a:focus{box-shadow:none}.fs-multisite-options-container a.selected{font-weight:bold}.fs-multisite-options-container.fs-apply-on-all-sites{border:0 none;padding:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options{border-spacing:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options td:not(:first-child){display:none}.fs-multisite-options-container .fs-sites-list-container{display:none;overflow:auto}.fs-multisite-options-container .fs-sites-list-container table td{border-top:1px solid #ccc;padding:4px 2px}.fs-modal.fs-modal-license-key-resend .email-address-container{overflow:hidden;padding-right:2px}.fs-modal.fs-modal-license-key-resend.fs-freemium input.email-address{width:300px}.fs-modal.fs-modal-license-key-resend.fs-freemium label{display:block;margin-bottom:10px}.fs-modal.fs-modal-license-key-resend.fs-premium input.email-address{width:100%}.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{float:right;margin-left:7px}@media (max-width: 650px){.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{margin-top:2px}}
|
2 |
-
.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .input-container>.email-address-container{padding-left:2px;padding-right:0}.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .button-container{float:left;margin-right:7px;margin-left:0}a.show-license-resend-modal{margin-top:4px;display:inline-block}.fs-ajax-loader{position:relative;width:170px;height:20px;margin:auto}.fs-ajax-loader .fs-ajax-loader-bar{position:absolute;top:0;background-color:#0074a3;width:20px;height:20px;-webkit-animation-name:bounce_ajaxLoader;-moz-animation-name:bounce_ajaxLoader;-ms-animation-name:bounce_ajaxLoader;-o-animation-name:bounce_ajaxLoader;animation-name:bounce_ajaxLoader;-webkit-animation-duration:1.5s;-moz-animation-duration:1.5s;-ms-animation-duration:1.5s;-o-animation-duration:1.5s;animation-duration:1.5s;animation-iteration-count:infinite;-o-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;-webkit-animation-iteration-count:infinite;-moz-animation-iteration-count:infinite;-webkit-animation-direction:normal;-moz-animation-direction:normal;-ms-animation-direction:normal;-o-animation-direction:normal;animation-direction:normal;-moz-transform:0.3;-o-transform:0.3;-ms-transform:0.3;-webkit-transform:0.3;transform:0.3}.fs-ajax-loader .fs-ajax-loader-bar-1{left:0px;animation-delay:0.6s;-o-animation-delay:0.6s;-ms-animation-delay:0.6s;-webkit-animation-delay:0.6s;-moz-animation-delay:0.6s}.fs-ajax-loader .fs-ajax-loader-bar-2{left:19px;animation-delay:0.75s;-o-animation-delay:0.75s;-ms-animation-delay:0.75s;-webkit-animation-delay:0.75s;-moz-animation-delay:0.75s}.fs-ajax-loader .fs-ajax-loader-bar-3{left:38px;animation-delay:0.9s;-o-animation-delay:0.9s;-ms-animation-delay:0.9s;-webkit-animation-delay:0.9s;-moz-animation-delay:0.9s}.fs-ajax-loader .fs-ajax-loader-bar-4{left:57px;animation-delay:1.05s;-o-animation-delay:1.05s;-ms-animation-delay:1.05s;-webkit-animation-delay:1.05s;-moz-animation-delay:1.05s}.fs-ajax-loader .fs-ajax-loader-bar-5{left:76px;animation-delay:1.2s;-o-animation-delay:1.2s;-ms-animation-delay:1.2s;-webkit-animation-delay:1.2s;-moz-animation-delay:1.2s}.fs-ajax-loader .fs-ajax-loader-bar-6{left:95px;animation-delay:1.35s;-o-animation-delay:1.35s;-ms-animation-delay:1.35s;-webkit-animation-delay:1.35s;-moz-animation-delay:1.35s}.fs-ajax-loader .fs-ajax-loader-bar-7{left:114px;animation-delay:1.5s;-o-animation-delay:1.5s;-ms-animation-delay:1.5s;-webkit-animation-delay:1.5s;-moz-animation-delay:1.5s}.fs-ajax-loader .fs-ajax-loader-bar-8{left:133px;animation-delay:1.65s;-o-animation-delay:1.65s;-ms-animation-delay:1.65s;-webkit-animation-delay:1.65s;-moz-animation-delay:1.65s}@-moz-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-ms-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-o-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-webkit-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}.fs-modal-auto-install #request-filesystem-credentials-form h2,.fs-modal-auto-install #request-filesystem-credentials-form .request-filesystem-credentials-action-buttons{display:none}.fs-modal-auto-install #request-filesystem-credentials-form input[type=password],.fs-modal-auto-install #request-filesystem-credentials-form input[type=email],.fs-modal-auto-install #request-filesystem-credentials-form input[type=text]{-webkit-appearance:none;padding:10px 10px 5px 10px;width:300px;max-width:100%}.fs-modal-auto-install #request-filesystem-credentials-form>div,.fs-modal-auto-install #request-filesystem-credentials-form label,.fs-modal-auto-install #request-filesystem-credentials-form fieldset{width:300px;max-width:100%;margin:0 auto;display:block}.button-primary.warn{box-shadow:0 1px 0 #d2593c;text-shadow:0 -1px 1px #d2593c,1px 0 1px #d2593c,0 1px 1px #d2593c,-1px 0 1px #d2593c;background:#f56a48;border-color:#ec6544 #d2593c #d2593c}.button-primary.warn:hover{background:#fd6d4a;border-color:#d2593c}.button-primary.warn:focus{box-shadow:0 1px 0 #dd6041,0 0 2px 1px #e4a796}.button-primary.warn:active{background:#dd6041;border-color:#d2593c;box-shadow:inset 0 2px 0 #d2593c}.button-primary.warn.disabled{color:#f5b3a1 !important;background:#e76444 !important;border-color:#d85e40 !important;text-shadow:0 -1px 0 rgba(0,0,0,0.1) !important}
|
1 |
+
.fs-modal{position:fixed;overflow:auto;height:100%;width:100%;top:0;z-index:100000;display:none;background:rgba(0,0,0,.6)}@media(min-width: 961px){.fs-modal{padding-left:160px}.rtl .fs-modal{padding-left:0;padding-right:160px}}.fs-modal .dashicons{vertical-align:middle}.fs-modal .fs-modal-dialog{background:transparent;position:absolute;left:50%;margin-left:-298px;padding-bottom:30px;top:-100%;z-index:100001;width:596px}@media(max-width: 650px){.fs-modal .fs-modal-dialog{margin-left:-50%;box-sizing:border-box;padding-left:10px;padding-right:10px;width:100%}.fs-modal .fs-modal-dialog .fs-modal-panel>h3>strong{font-size:1.3em}}.fs-modal.active{display:block}.fs-modal.active:before{display:block}.fs-modal.active .fs-modal-dialog{top:10%}.fs-modal.fs-success .fs-modal-header{border-bottom-color:#46b450}.fs-modal.fs-success .fs-modal-body{background-color:#f7fff7}.fs-modal.fs-warn .fs-modal-header{border-bottom-color:#ffb900}.fs-modal.fs-warn .fs-modal-body{background-color:#fff8e5}.fs-modal.fs-error .fs-modal-header{border-bottom-color:#dc3232}.fs-modal.fs-error .fs-modal-body{background-color:#ffeaea}.fs-modal .fs-modal-body,.fs-modal .fs-modal-footer{border:0;background:#fefefe;padding:20px}.fs-modal .fs-modal-header{border-bottom:#eee solid 1px;background:#fbfbfb;padding:15px 20px;position:relative;margin-bottom:-10px}.fs-modal .fs-modal-header h4{margin:0;padding:0;text-transform:uppercase;font-size:1.2em;font-weight:bold;color:#cacaca;text-shadow:1px 1px 1px #fff;letter-spacing:.6px;-webkit-font-smoothing:antialiased}.fs-modal .fs-modal-header .fs-close{position:absolute;right:10px;top:12px;cursor:pointer;color:#bbb;-moz-border-radius:20px;-webkit-border-radius:20px;border-radius:20px;padding:3px;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.fs-modal .fs-modal-header .fs-close:hover{color:#fff;background:#aaa}.fs-modal .fs-modal-header .fs-close .dashicons,.fs-modal .fs-modal-header .fs-close:hover .dashicons{text-decoration:none}.fs-modal .fs-modal-body{border-bottom:0}.fs-modal .fs-modal-body p{font-size:14px}.fs-modal .fs-modal-body h2{font-size:20px;line-height:1.5em}.fs-modal .fs-modal-body>div{margin-top:10px}.fs-modal .fs-modal-body>div h2{font-weight:bold;font-size:20px;margin-top:0}.fs-modal .fs-modal-footer{border-top:#eee solid 1px;text-align:right}.fs-modal .fs-modal-footer>.button{margin:0 7px}.fs-modal .fs-modal-footer>.button:last-of-type{margin:0}.fs-modal .fs-modal-panel>.notice.inline{margin:0;display:none}.fs-modal .fs-modal-panel:not(.active){display:none}.rtl .fs-modal .fs-modal-header .fs-close{right:auto;left:20px}.rtl .fs-modal .fs-modal-footer{text-align:left}body.has-fs-modal{overflow:hidden}.fs-modal.fs-modal-deactivation-feedback .reason-input,.fs-modal.fs-modal-deactivation-feedback .internal-message{margin:3px 0 3px 22px}.fs-modal.fs-modal-deactivation-feedback .reason-input input,.fs-modal.fs-modal-deactivation-feedback .reason-input textarea,.fs-modal.fs-modal-deactivation-feedback .internal-message input,.fs-modal.fs-modal-deactivation-feedback .internal-message textarea{width:100%}.fs-modal.fs-modal-deactivation-feedback li.reason.has-internal-message .internal-message{border:1px solid #ccc;padding:7px;display:none}@media(max-width: 650px){.fs-modal.fs-modal-deactivation-feedback li.reason li.reason{margin-bottom:10px}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason .reason-input,.fs-modal.fs-modal-deactivation-feedback li.reason li.reason .internal-message{margin-left:29px}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason label{display:table}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason label>span{display:table-cell;font-size:1.3em}}.fs-modal.fs-modal-deactivation-feedback .anonymous-feedback-label,.fs-modal.fs-modal-deactivation-feedback .feedback-from-snooze-label{float:left;line-height:30px}.rtl .fs-modal.fs-modal-deactivation-feedback .anonymous-feedback-label,.rtl .fs-modal.fs-modal-deactivation-feedback .feedback-from-snooze-label{float:right}.fs-modal.fs-modal-deactivation-feedback .fs-modal-panel{margin-top:0 !important}.fs-modal.fs-modal-deactivation-feedback .fs-modal-panel h3{margin-top:0;line-height:1.5em}#the-list .deactivate>.fs-slug{display:none}.fs-modal.fs-modal-subscription-cancellation .fs-price-increase-warning{color:red;font-weight:bold;padding:0 25px;margin-bottom:0}.fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label input{float:left;top:5px;position:relative}.rtl .fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label input{float:right}.fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label span{display:block;margin-left:24px}.rtl .fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label span{margin-left:0;margin-right:24px}.fs-modal.fs-modal-license-activation .fs-modal-body input.fs-license-key{width:100%}.fs-license-options-container table,.fs-license-options-container table select,.fs-license-options-container table .fs-available-license-key{width:100%}.fs-license-options-container table td:first-child{width:1%}.fs-license-options-container table .fs-other-license-key-container label{position:relative;top:6px;float:left;margin-right:5px}.fs-license-options-container table .fs-other-license-key-container div{overflow:hidden;width:auto;height:30px;display:block;top:2px;position:relative}.fs-license-options-container table .fs-other-license-key-container div input{margin:0}.fs-sites-list-container td{cursor:pointer}.fs-modal.fs-modal-user-change .fs-modal-body input#fs_other_email_address{width:100%}.fs-user-change-options-container table{width:100%;border-collapse:collapse}.fs-user-change-options-container table tr{display:block;margin-bottom:2px}.fs-user-change-options-container table .fs-email-address-container td{display:inline-block}.fs-user-change-options-container table .fs-email-address-container input[type=radio]{margin-bottom:0;margin-top:0}.fs-user-change-options-container table .fs-other-email-address-container{width:100%}.fs-user-change-options-container table .fs-other-email-address-container>div{display:table;width:100%}.fs-user-change-options-container table .fs-other-email-address-container>div label,.fs-user-change-options-container table .fs-other-email-address-container>div>div{display:table-cell}.fs-user-change-options-container table .fs-other-email-address-container>div label{width:1%;padding-left:3px;padding-right:3px}.fs-user-change-options-container table .fs-other-email-address-container>div>div{width:auto}.fs-user-change-options-container table .fs-other-email-address-container>div>div input{width:100%}.fs-modal.fs-modal-developer-license-debug-mode .fs-modal-body input.fs-license-or-user-key{width:100%}.fs-multisite-options-container{margin-top:20px;border:1px solid #ccc;padding:5px}.fs-multisite-options-container a{text-decoration:none}.fs-multisite-options-container a:focus{box-shadow:none}.fs-multisite-options-container a.selected{font-weight:bold}.fs-multisite-options-container.fs-apply-on-all-sites{border:0 none;padding:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options{border-spacing:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options td:not(:first-child){display:none}.fs-multisite-options-container .fs-sites-list-container{display:none;overflow:auto}.fs-multisite-options-container .fs-sites-list-container table td{border-top:1px solid #ccc;padding:4px 2px}.fs-modal.fs-modal-license-key-resend .email-address-container{overflow:hidden;padding-right:2px}.fs-modal.fs-modal-license-key-resend.fs-freemium input.email-address{width:300px}.fs-modal.fs-modal-license-key-resend.fs-freemium label{display:block;margin-bottom:10px}.fs-modal.fs-modal-license-key-resend.fs-premium input.email-address{width:100%}.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{float:right;margin-left:7px}@media(max-width: 650px){.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{margin-top:2px}}.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .input-container>.email-address-container{padding-left:2px;padding-right:0}.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .button-container{float:left;margin-right:7px;margin-left:0}a.show-license-resend-modal{margin-top:4px;display:inline-block}.fs-modal.fs-modal-email-address-update .fs-modal-body input[type=text]{width:100%}.fs-modal.fs-modal-email-address-update p{margin-bottom:0}.fs-modal.fs-modal-email-address-update ul{margin:1em .5em}.fs-modal.fs-modal-email-address-update ul li label span{float:left;margin-top:0}.fs-modal.fs-modal-email-address-update ul li label span:last-child{display:block;float:none;margin-left:20px}.fs-ajax-loader{position:relative;width:170px;height:20px;margin:auto}.fs-ajax-loader .fs-ajax-loader-bar{position:absolute;top:0;background-color:#0074a3;width:20px;height:20px;-webkit-animation-name:bounce_ajaxLoader;-moz-animation-name:bounce_ajaxLoader;-ms-animation-name:bounce_ajaxLoader;-o-animation-name:bounce_ajaxLoader;animation-name:bounce_ajaxLoader;-webkit-animation-duration:1.5s;-moz-animation-duration:1.5s;-ms-animation-duration:1.5s;-o-animation-duration:1.5s;animation-duration:1.5s;animation-iteration-count:infinite;-o-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;-webkit-animation-iteration-count:infinite;-moz-animation-iteration-count:infinite;-webkit-animation-direction:normal;-moz-animation-direction:normal;-ms-animation-direction:normal;-o-animation-direction:normal;animation-direction:normal;-moz-transform:.3;-o-transform:.3;-ms-transform:.3;-webkit-transform:.3;transform:.3}.fs-ajax-loader .fs-ajax-loader-bar-1{left:0px;animation-delay:0.6s;-o-animation-delay:0.6s;-ms-animation-delay:0.6s;-webkit-animation-delay:0.6s;-moz-animation-delay:0.6s}.fs-ajax-loader .fs-ajax-loader-bar-2{left:19px;animation-delay:0.75s;-o-animation-delay:0.75s;-ms-animation-delay:0.75s;-webkit-animation-delay:0.75s;-moz-animation-delay:0.75s}.fs-ajax-loader .fs-ajax-loader-bar-3{left:38px;animation-delay:0.9s;-o-animation-delay:0.9s;-ms-animation-delay:0.9s;-webkit-animation-delay:0.9s;-moz-animation-delay:0.9s}.fs-ajax-loader .fs-ajax-loader-bar-4{left:57px;animation-delay:1.05s;-o-animation-delay:1.05s;-ms-animation-delay:1.05s;-webkit-animation-delay:1.05s;-moz-animation-delay:1.05s}.fs-ajax-loader .fs-ajax-loader-bar-5{left:76px;animation-delay:1.2s;-o-animation-delay:1.2s;-ms-animation-delay:1.2s;-webkit-animation-delay:1.2s;-moz-animation-delay:1.2s}.fs-ajax-loader .fs-ajax-loader-bar-6{left:95px;animation-delay:1.35s;-o-animation-delay:1.35s;-ms-animation-delay:1.35s;-webkit-animation-delay:1.35s;-moz-animation-delay:1.35s}.fs-ajax-loader .fs-ajax-loader-bar-7{left:114px;animation-delay:1.5s;-o-animation-delay:1.5s;-ms-animation-delay:1.5s;-webkit-animation-delay:1.5s;-moz-animation-delay:1.5s}.fs-ajax-loader .fs-ajax-loader-bar-8{left:133px;animation-delay:1.65s;-o-animation-delay:1.65s;-ms-animation-delay:1.65s;-webkit-animation-delay:1.65s;-moz-animation-delay:1.65s}@-moz-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-ms-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-o-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-webkit-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}.fs-modal-auto-install #request-filesystem-credentials-form h2,.fs-modal-auto-install #request-filesystem-credentials-form .request-filesystem-credentials-action-buttons{display:none}.fs-modal-auto-install #request-filesystem-credentials-form input[type=password],.fs-modal-auto-install #request-filesystem-credentials-form input[type=email],.fs-modal-auto-install #request-filesystem-credentials-form input[type=text]{-webkit-appearance:none;padding:10px 10px 5px 10px;width:300px;max-width:100%}.fs-modal-auto-install #request-filesystem-credentials-form>div,.fs-modal-auto-install #request-filesystem-credentials-form label,.fs-modal-auto-install #request-filesystem-credentials-form fieldset{width:300px;max-width:100%;margin:0 auto;display:block}.button-primary.warn{box-shadow:0 1px 0 #d2593c;text-shadow:0 -1px 1px #d2593c,1px 0 1px #d2593c,0 1px 1px #d2593c,-1px 0 1px #d2593c;background:#f56a48;border-color:#ec6544 #d2593c #d2593c}.button-primary.warn:hover{background:#fd6d4a;border-color:#d2593c}.button-primary.warn:focus{box-shadow:0 1px 0 #dd6041,0 0 2px 1px #e4a796}.button-primary.warn:active{background:#dd6041;border-color:#d2593c;box-shadow:inset 0 2px 0 #d2593c}.button-primary.warn.disabled{color:#f5b3a1 !important;background:#e76444 !important;border-color:#d85e40 !important;text-shadow:0 -1px 0 rgba(0,0,0,.1) !important}
|
|
freemius/assets/css/admin/gdpr-optin-notice.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.fs-notice[data-id^=
|
1 |
+
.fs-notice[data-id^=gdpr_optin_actions] .underlined{text-decoration:underline}.fs-notice[data-id^=gdpr_optin_actions] ul .button,.fs-notice[data-id^=gdpr_optin_actions] ul .action-description{vertical-align:middle}.fs-notice[data-id^=gdpr_optin_actions] ul .action-description{display:inline-block;margin-left:3px}
|
freemius/assets/css/admin/optout.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.fs-tooltip-trigger{position:relative}.fs-tooltip-trigger:not(a){cursor:help}.fs-tooltip-trigger .dashicons{float:none !important}.fs-tooltip-trigger .fs-tooltip{opacity:0;visibility:hidden;-moz-transition:opacity .3s ease-in-out;-o-transition:opacity .3s ease-in-out;-ms-transition:opacity .3s ease-in-out;-webkit-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;position:absolute;background:rgba(0,0,0,.8);color:#fff !important;font-family:"arial",serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:-17px;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2);line-height:1.3em;font-weight:bold;text-align:left;text-transform:none !important}.rtl .fs-tooltip-trigger .fs-tooltip{text-align:right;left:auto;right:-17px}.fs-tooltip-trigger .fs-tooltip::after{content:" ";display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:rgba(0,0,0,.8) transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl .fs-tooltip-trigger .fs-tooltip::after{right:21px;left:auto}.fs-tooltip-trigger:hover .fs-tooltip{visibility:visible;opacity:1}.fs-permissions .fs-permission.fs-disabled{color:#aaa}.fs-permissions .fs-permission.fs-disabled .fs-permission-description span{color:#aaa}.fs-permissions .fs-permission .fs-switch-feedback{position:absolute;right:15px;top:52px}.fs-permissions ul{height:0;overflow:hidden;margin:0}.fs-permissions ul li{padding:17px 15px;margin:0;position:relative}.fs-permissions ul li>i.dashicons{float:left;font-size:30px;width:30px;height:30px;padding:5px}.fs-permissions ul li .fs-switch{float:right}.fs-permissions ul li .fs-permission-description{margin-left:55px}.fs-permissions ul li .fs-permission-description span{font-size:14px;font-weight:500;color:#23282d}.fs-permissions ul li .fs-permission-description .fs-tooltip{font-size:13px;font-weight:bold}.fs-permissions ul li .fs-permission-description .fs-tooltip-trigger .dashicons{margin:-1px 2px 0 2px}.fs-permissions ul li .fs-permission-description p{margin:2px 0 0 0}.fs-permissions.fs-open{background:#fff}.fs-permissions.fs-open ul{overflow:initial;height:auto;margin:20px 0 10px 0}.fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-right:10px}.fs-permissions .fs-switch-feedback.success{color:#71ae00}.rtl .fs-permissions .fs-switch-feedback{right:auto;left:15px}.rtl .fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-left:10px;margin-right:0}.rtl .fs-permissions ul li .fs-permission-description{margin-right:55px;margin-left:0}.rtl .fs-permissions ul li .fs-switch{float:left}.rtl .fs-permissions ul li i.dashicons{float:right}.fs-modal-opt-out .fs-modal-footer .fs-opt-out-button{line-height:30px;margin-right:10px}.fs-modal-opt-out .fs-permissions{margin-top:0 !important}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-group-opt-out-button{float:right;line-height:1.1em}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-switch-feedback{float:right;line-height:1.1em;margin-right:10px}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-switch-feedback .fs-ajax-spinner{margin:-2px 0 0}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header-title{font-size:1.1em;font-weight:600;text-transform:uppercase;display:block;line-height:1.1em;margin:.5em 0}.fs-modal-opt-out .fs-permissions .fs-permissions-section--desc{margin-top:0}.fs-modal-opt-out .fs-permissions hr{border:0;border-top:#eee solid 1px;margin:25px 0 20px 0}.fs-modal-opt-out .fs-permissions ul{border:1px solid #c3c4c7;border-radius:3px;margin:10px 0 0 0;box-shadow:0 1px 1px rgba(0,0,0,.04)}.fs-modal-opt-out .fs-permissions ul li{border-bottom:1px solid #d7dde1;border-left:4px solid #72aee6}.rtl .fs-modal-opt-out .fs-permissions ul li{border-left:none;border-right:4px solid #72aee6}.fs-modal-opt-out .fs-permissions ul li.fs-disabled{border-left-color:rgba(114,174,230,0)}.fs-modal-opt-out .fs-permissions ul li:last-child{border-bottom:none}
|
freemius/assets/css/customizer.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
#fs_customizer_upsell .fs-customizer-plan{padding:10px 20px 20px 20px;border-radius:3px;background:#fff}#fs_customizer_upsell .fs-customizer-plan h2{position:relative;margin:0;line-height:2em;text-transform:uppercase}#fs_customizer_upsell .fs-customizer-plan h2 .button-link{top:-2px}#fs_customizer_upsell .fs-feature{position:relative}#fs_customizer_upsell .dashicons-yes{color:#0085ba;font-size:2em;vertical-align:bottom;margin-left:-7px;margin-right:10px}.rtl #fs_customizer_upsell .dashicons-yes{margin-left:10px;margin-right:-7px}#fs_customizer_upsell .dashicons-editor-help{color:#bbb;cursor:help}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{opacity:0;visibility:hidden;-moz-transition:opacity
|
1 |
+
#fs_customizer_upsell .fs-customizer-plan{padding:10px 20px 20px 20px;border-radius:3px;background:#fff}#fs_customizer_upsell .fs-customizer-plan h2{position:relative;margin:0;line-height:2em;text-transform:uppercase}#fs_customizer_upsell .fs-customizer-plan h2 .button-link{top:-2px}#fs_customizer_upsell .fs-feature{position:relative}#fs_customizer_upsell .dashicons-yes{color:#0085ba;font-size:2em;vertical-align:bottom;margin-left:-7px;margin-right:10px}.rtl #fs_customizer_upsell .dashicons-yes{margin-left:10px;margin-right:-7px}#fs_customizer_upsell .dashicons-editor-help{color:#bbb;cursor:help}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{opacity:0;visibility:hidden;-moz-transition:opacity .3s ease-in-out;-o-transition:opacity .3s ease-in-out;-ms-transition:opacity .3s ease-in-out;-webkit-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;position:absolute;background:#000;color:#fff;font-family:"arial",serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:0;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2);line-height:1.3em;font-weight:bold;text-align:left}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{text-align:right}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc::after{content:" ";display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:#000 transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc::after{right:21px;left:auto}#fs_customizer_upsell .dashicons-editor-help:hover .fs-feature-desc{visibility:visible;opacity:1}#fs_customizer_upsell .button-primary{display:block;text-align:center;margin-top:10px}#fs_customizer_support{display:block !important}#fs_customizer_support .button{float:right}#fs_customizer_support .button-group{width:100%;display:block;margin-top:10px}#fs_customizer_support .button-group .button{float:none;width:50%;text-align:center}#customize-theme-controls #accordion-section-freemius_upsell{border-top:1px solid #0085ba !important;border-bottom:1px solid #0085ba !important}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title{color:#fff;background-color:#0085ba;border-left:4px solid #0085ba;transition:.15s background-color ease-in-out,.15s border-color ease-in-out;outline:none;border-bottom:none !important}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title:hover{background-color:#008ec2;border-left-color:#0073aa}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title:after{color:#fff}#customize-theme-controls #accordion-section-freemius_upsell .rtl h3.accordion-section-title{border-left:none;border-right:4px solid #0085ba}#customize-theme-controls #accordion-section-freemius_upsell .rtl h3.accordion-section-title:hover{border-right-color:#0073aa}
|
freemius/config.php
CHANGED
@@ -354,7 +354,7 @@
|
|
354 |
is_multisite() &&
|
355 |
( is_network_admin() ||
|
356 |
( ( defined( 'DOING_AJAX' ) && DOING_AJAX &&
|
357 |
-
( isset( $_REQUEST['_fs_network_admin'] ) /*||
|
358 |
( ! empty( $_REQUEST['action'] ) && 'delete-plugin' === $_REQUEST['action'] )*/ )
|
359 |
) ||
|
360 |
// Plugin uninstall.
|
@@ -385,7 +385,7 @@
|
|
385 |
|
386 |
if ( ! defined( 'WP_FS__DEMO_MODE' ) ) {
|
387 |
define( 'WP_FS__DEMO_MODE', false );
|
388 |
-
}
|
389 |
-
if ( ! defined( 'FS_SDK__SSLVERIFY' ) ) {
|
390 |
-
define( 'FS_SDK__SSLVERIFY', false );
|
391 |
-
}
|
354 |
is_multisite() &&
|
355 |
( is_network_admin() ||
|
356 |
( ( defined( 'DOING_AJAX' ) && DOING_AJAX &&
|
357 |
+
( isset( $_REQUEST['_fs_network_admin'] ) && 'true' === $_REQUEST['_fs_network_admin'] /*||
|
358 |
( ! empty( $_REQUEST['action'] ) && 'delete-plugin' === $_REQUEST['action'] )*/ )
|
359 |
) ||
|
360 |
// Plugin uninstall.
|
385 |
|
386 |
if ( ! defined( 'WP_FS__DEMO_MODE' ) ) {
|
387 |
define( 'WP_FS__DEMO_MODE', false );
|
388 |
+
}
|
389 |
+
if ( ! defined( 'FS_SDK__SSLVERIFY' ) ) {
|
390 |
+
define( 'FS_SDK__SSLVERIFY', false );
|
391 |
+
}
|
freemius/includes/class-freemius-abstract.php
CHANGED
@@ -37,9 +37,12 @@
|
|
37 |
* `$fs->is_registered() && $fs->is_tracking_allowed()`
|
38 |
*
|
39 |
* @since 1.0.1
|
|
|
|
|
|
|
40 |
* @return bool
|
41 |
*/
|
42 |
-
abstract function is_registered();
|
43 |
|
44 |
/**
|
45 |
* Check if the user skipped connecting the account with Freemius.
|
@@ -61,68 +64,6 @@
|
|
61 |
|
62 |
#endregion
|
63 |
|
64 |
-
#----------------------------------------------------------------------------------
|
65 |
-
#region Usage Tracking
|
66 |
-
#----------------------------------------------------------------------------------
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Returns TRUE if the user opted-in and didn't disconnect (opt-out).
|
70 |
-
*
|
71 |
-
* @author Leo Fajardo (@leorw)
|
72 |
-
* @since 1.2.1.5
|
73 |
-
*
|
74 |
-
* @return bool
|
75 |
-
*/
|
76 |
-
abstract function is_tracking_allowed();
|
77 |
-
|
78 |
-
/**
|
79 |
-
* Returns TRUE if the user never opted-in or manually opted-out.
|
80 |
-
*
|
81 |
-
* @author Vova Feldman (@svovaf)
|
82 |
-
* @since 1.2.1.5
|
83 |
-
*
|
84 |
-
* @return bool
|
85 |
-
*/
|
86 |
-
function is_tracking_prohibited() {
|
87 |
-
return ! $this->is_registered() || ! $this->is_tracking_allowed();
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Opt-out from usage tracking.
|
92 |
-
*
|
93 |
-
* Note: This will not delete the account information but will stop all tracking.
|
94 |
-
*
|
95 |
-
* Returns:
|
96 |
-
* 1. FALSE - If the user never opted-in.
|
97 |
-
* 2. TRUE - If successfully opted-out.
|
98 |
-
* 3. object - API Result on failure.
|
99 |
-
*
|
100 |
-
* @author Leo Fajardo (@leorw)
|
101 |
-
* @since 1.2.1.5
|
102 |
-
*
|
103 |
-
* @return bool|object
|
104 |
-
*/
|
105 |
-
abstract function stop_tracking();
|
106 |
-
|
107 |
-
/**
|
108 |
-
* Opt-in back into usage tracking.
|
109 |
-
*
|
110 |
-
* Note: This will only work if the user opted-in previously.
|
111 |
-
*
|
112 |
-
* Returns:
|
113 |
-
* 1. FALSE - If the user never opted-in.
|
114 |
-
* 2. TRUE - If successfully opted-in back to usage tracking.
|
115 |
-
* 3. object - API result on failure.
|
116 |
-
*
|
117 |
-
* @author Leo Fajardo (@leorw)
|
118 |
-
* @since 1.2.1.5
|
119 |
-
*
|
120 |
-
* @return bool|object
|
121 |
-
*/
|
122 |
-
abstract function allow_tracking();
|
123 |
-
|
124 |
-
#endregion
|
125 |
-
|
126 |
#----------------------------------------------------------------------------------
|
127 |
#region Module Type
|
128 |
#----------------------------------------------------------------------------------
|
37 |
* `$fs->is_registered() && $fs->is_tracking_allowed()`
|
38 |
*
|
39 |
* @since 1.0.1
|
40 |
+
*
|
41 |
+
* @param bool $ignore_anonymous_state Since 2.5.1
|
42 |
+
*
|
43 |
* @return bool
|
44 |
*/
|
45 |
+
abstract function is_registered( $ignore_anonymous_state = false );
|
46 |
|
47 |
/**
|
48 |
* Check if the user skipped connecting the account with Freemius.
|
64 |
|
65 |
#endregion
|
66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
#----------------------------------------------------------------------------------
|
68 |
#region Module Type
|
69 |
#----------------------------------------------------------------------------------
|
freemius/includes/class-freemius.php
CHANGED
@@ -377,6 +377,8 @@
|
|
377 |
const REASON_DIDNT_WORK_AS_EXPECTED = 14;
|
378 |
const REASON_TEMPORARY_DEACTIVATION = 15;
|
379 |
|
|
|
|
|
380 |
/**
|
381 |
* @author Leo Fajardo (@leorw)
|
382 |
* @since 2.3.1
|
@@ -392,7 +394,8 @@
|
|
392 |
*/
|
393 |
private $_pricing_js_path = null;
|
394 |
|
395 |
-
|
|
|
396 |
|
397 |
/* Ctor
|
398 |
------------------------------------------------------------------------------------------------------------------*/
|
@@ -408,8 +411,10 @@
|
|
408 |
* @param bool $is_init Since 1.2.1 Is initiation sequence.
|
409 |
*/
|
410 |
private function __construct( $module_id, $slug = false, $is_init = false ) {
|
|
|
|
|
411 |
if ( $is_init && is_numeric( $module_id ) && is_string( $slug ) ) {
|
412 |
-
$this->store_id_slug_type_path_map( $module_id, $slug );
|
413 |
}
|
414 |
|
415 |
$this->_module_id = $module_id;
|
@@ -424,7 +429,7 @@
|
|
424 |
|
425 |
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $this->get_unique_affix(), WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
426 |
|
427 |
-
$this->_plugin_main_file_path = $this->_find_caller_plugin_file( $is_init );
|
428 |
$this->_plugin_dir_path = plugin_dir_path( $this->_plugin_main_file_path );
|
429 |
$this->_plugin_basename = $this->get_plugin_basename();
|
430 |
$this->_free_plugin_basename = str_replace( '-premium/', '/', $this->_plugin_basename );
|
@@ -519,7 +524,10 @@
|
|
519 |
* @author Leo Fajardo (@leorw)
|
520 |
* @since 1.2.2
|
521 |
*/
|
522 |
-
( is_object( $this->_plugin )
|
|
|
|
|
|
|
523 |
$this->get_unique_affix()
|
524 |
);
|
525 |
|
@@ -933,82 +941,27 @@
|
|
933 |
* @param string $sdk_version
|
934 |
*/
|
935 |
function _sdk_version_update( $sdk_prev_version, $sdk_version ) {
|
936 |
-
/**
|
937 |
-
* @since 1.1.7.3 Fixed unwanted connectivity test cleanup.
|
938 |
-
*/
|
939 |
if ( empty( $sdk_prev_version ) ) {
|
940 |
return;
|
941 |
}
|
942 |
|
943 |
-
if (
|
944 |
-
version_compare( $
|
945 |
-
|
946 |
-
$this->_storage->handle_gdpr_admin_notice = true;
|
947 |
-
}
|
948 |
-
|
949 |
-
if ( version_compare( $sdk_prev_version, '2.0.0', '<' ) &&
|
950 |
-
version_compare( $sdk_version, '2.0.0', '>=' )
|
951 |
-
) {
|
952 |
-
$this->migrate_to_subscriptions_collection();
|
953 |
-
|
954 |
-
$this->consolidate_licenses();
|
955 |
-
|
956 |
-
// Clear trial_plan since it's now loaded from the plans collection when needed.
|
957 |
-
$this->_storage->remove( 'trial_plan', true, false );
|
958 |
-
}
|
959 |
-
|
960 |
-
if ( version_compare( $sdk_prev_version, '1.2.3', '<' ) &&
|
961 |
-
version_compare( $sdk_version, '1.2.3', '>=' )
|
962 |
-
) {
|
963 |
-
/**
|
964 |
-
* Starting from version 1.2.3, paths are stored as relative instead of absolute and some of them can be
|
965 |
-
* invalid.
|
966 |
-
*
|
967 |
-
* @author Leo Fajardo (@leorw)
|
968 |
-
*/
|
969 |
-
$this->remove_invalid_paths();
|
970 |
-
}
|
971 |
-
|
972 |
-
if ( version_compare( $sdk_prev_version, '1.1.5', '<' ) &&
|
973 |
-
version_compare( $sdk_version, '1.1.5', '>=' )
|
974 |
) {
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
$connectivity_data = $this->_storage->connectivity_test;
|
981 |
-
$connectivity_data['is_active'] = $this->_storage->is_on['is_active'];
|
982 |
-
$connectivity_data['timestamp'] = $this->_storage->is_on['timestamp'];
|
983 |
-
|
984 |
-
// Override.
|
985 |
-
$this->_storage->connectivity_test = $connectivity_data;
|
986 |
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
|
|
|
991 |
}
|
992 |
}
|
993 |
-
|
994 |
-
if (
|
995 |
-
version_compare( $sdk_prev_version, '2.2.1', '<' ) &&
|
996 |
-
version_compare( $sdk_version, '2.2.1', '>=' )
|
997 |
-
) {
|
998 |
-
/**
|
999 |
-
* Clear the file cache without storing the previous path since it could be a wrong path. For example,
|
1000 |
-
* in the versions of the SDK lower than 2.2.1, it's possible for the path of an add-on to be the same
|
1001 |
-
* as the parent plugin's when the add-on was auto-installed since the relevant method names were not
|
1002 |
-
* skipped in the logic that determines the right path in the `get_caller_main_file_and_type` method
|
1003 |
-
* (e.g. `try_activate_plugin`). Since it was an auto-installation, the caller was the parent plugin
|
1004 |
-
* and so its path was used. In case the stored path is wrong, clearing the cache will resolve issues
|
1005 |
-
* related to data mix-up between plugins (e.g. titles and versions of an add-on and its parent plugin).
|
1006 |
-
*
|
1007 |
-
* @author Leo Fajardo (@leorw)
|
1008 |
-
* @since 2.2.1
|
1009 |
-
*/
|
1010 |
-
$this->clear_module_main_file_cache( false );
|
1011 |
-
}
|
1012 |
}
|
1013 |
|
1014 |
/**
|
@@ -1059,102 +1012,6 @@
|
|
1059 |
}
|
1060 |
}
|
1061 |
|
1062 |
-
/**
|
1063 |
-
* @author Leo Fajardo (@leorw)
|
1064 |
-
* @since 2.0.0
|
1065 |
-
*/
|
1066 |
-
private function migrate_to_subscriptions_collection() {
|
1067 |
-
if ( ! is_object( $this->_site ) ) {
|
1068 |
-
return;
|
1069 |
-
}
|
1070 |
-
|
1071 |
-
if ( isset( $this->_storage->subscription ) && is_object( $this->_storage->subscription ) ) {
|
1072 |
-
$this->_storage->subscriptions = array( fs_get_entity( $this->_storage->subscription, FS_Subscription::get_class_name() ) );
|
1073 |
-
}
|
1074 |
-
}
|
1075 |
-
|
1076 |
-
/**
|
1077 |
-
* @author Leo Fajardo (@leorw)
|
1078 |
-
* @since 2.0.0
|
1079 |
-
*/
|
1080 |
-
private function consolidate_licenses() {
|
1081 |
-
$plugin_licenses = self::get_account_option( 'licenses', WP_FS__MODULE_TYPE_PLUGIN );
|
1082 |
-
if ( isset( $plugin_licenses[ $this->_slug ] ) ) {
|
1083 |
-
$plugin_licenses = $plugin_licenses[ $this->_slug ];
|
1084 |
-
} else {
|
1085 |
-
$plugin_licenses = array();
|
1086 |
-
}
|
1087 |
-
|
1088 |
-
$theme_licenses = self::get_account_option( 'licenses', WP_FS__MODULE_TYPE_THEME );
|
1089 |
-
if ( isset( $theme_licenses[ $this->_slug ] ) ) {
|
1090 |
-
$theme_licenses = $theme_licenses[ $this->_slug ];
|
1091 |
-
} else {
|
1092 |
-
$theme_licenses = array();
|
1093 |
-
}
|
1094 |
-
|
1095 |
-
if ( empty( $plugin_licenses ) && empty( $theme_licenses ) ) {
|
1096 |
-
return;
|
1097 |
-
}
|
1098 |
-
|
1099 |
-
$all_licenses = array();
|
1100 |
-
$user_id_license_ids_map = array();
|
1101 |
-
|
1102 |
-
foreach ( $plugin_licenses as $user_id => $user_licenses ) {
|
1103 |
-
if ( is_array( $user_licenses ) ) {
|
1104 |
-
if ( ! isset( $user_license_ids[ $user_id ] ) ) {
|
1105 |
-
$user_id_license_ids_map[ $user_id ] = array();
|
1106 |
-
}
|
1107 |
-
|
1108 |
-
foreach ( $user_licenses as $user_license ) {
|
1109 |
-
$all_licenses[] = $user_license;
|
1110 |
-
$user_id_license_ids_map[ $user_id ][] = $user_license->id;
|
1111 |
-
}
|
1112 |
-
}
|
1113 |
-
}
|
1114 |
-
|
1115 |
-
foreach ( $theme_licenses as $user_id => $user_licenses ) {
|
1116 |
-
if ( is_array( $user_licenses ) ) {
|
1117 |
-
if ( ! isset( $user_license_ids[ $user_id ] ) ) {
|
1118 |
-
$user_id_license_ids_map[ $user_id ] = array();
|
1119 |
-
}
|
1120 |
-
|
1121 |
-
foreach ( $user_licenses as $user_license ) {
|
1122 |
-
$all_licenses[] = $user_license;
|
1123 |
-
$user_id_license_ids_map[ $user_id ][] = $user_license->id;
|
1124 |
-
}
|
1125 |
-
}
|
1126 |
-
}
|
1127 |
-
|
1128 |
-
self::store_user_id_license_ids_map(
|
1129 |
-
$user_id_license_ids_map,
|
1130 |
-
$this->_module_id
|
1131 |
-
);
|
1132 |
-
|
1133 |
-
$this->_store_licenses( true, $this->_module_id, $all_licenses );
|
1134 |
-
}
|
1135 |
-
|
1136 |
-
/**
|
1137 |
-
* Remove invalid paths.
|
1138 |
-
*
|
1139 |
-
* @author Leo Fajardo (@leorw)
|
1140 |
-
* @since 1.2.3
|
1141 |
-
*/
|
1142 |
-
private function remove_invalid_paths() {
|
1143 |
-
// Remove invalid path that is still associated with the current slug if there's any.
|
1144 |
-
$file_slug_map = self::$_accounts->get_option( 'file_slug_map', array() );
|
1145 |
-
foreach ( $file_slug_map as $plugin_basename => $slug ) {
|
1146 |
-
if ( $slug === $this->_slug &&
|
1147 |
-
$plugin_basename !== $this->_plugin_basename &&
|
1148 |
-
! file_exists( $this->get_absolute_path( $plugin_basename ) )
|
1149 |
-
) {
|
1150 |
-
unset( $file_slug_map[ $plugin_basename ] );
|
1151 |
-
self::$_accounts->set_option( 'file_slug_map', $file_slug_map, true );
|
1152 |
-
|
1153 |
-
break;
|
1154 |
-
}
|
1155 |
-
}
|
1156 |
-
}
|
1157 |
-
|
1158 |
/**
|
1159 |
* @author Vova Feldman (@svovaf)
|
1160 |
* @since 1.2.2.7
|
@@ -1491,46 +1348,6 @@
|
|
1491 |
}
|
1492 |
}
|
1493 |
|
1494 |
-
/**
|
1495 |
-
* Add special parameter to WP admin AJAX calls so when we
|
1496 |
-
* process AJAX calls we can identify its source properly.
|
1497 |
-
*
|
1498 |
-
* @author Leo Fajardo (@leorw)
|
1499 |
-
* @since 2.0.0
|
1500 |
-
*/
|
1501 |
-
static function _enrich_ajax_url() {
|
1502 |
-
$admin_param = is_network_admin() ?
|
1503 |
-
'_fs_network_admin' :
|
1504 |
-
'_fs_blog_admin';
|
1505 |
-
?>
|
1506 |
-
<script type="text/javascript">
|
1507 |
-
(function ($) {
|
1508 |
-
$(document).ajaxSend(function (event, jqxhr, settings) {
|
1509 |
-
if (settings.url &&
|
1510 |
-
-1 < settings.url.indexOf('admin-ajax.php') &&
|
1511 |
-
! ( settings.url.indexOf( '<?php echo $admin_param ?>' ) > 0 )
|
1512 |
-
) {
|
1513 |
-
if (
|
1514 |
-
'string' === typeof settings.data &&
|
1515 |
-
settings.data.indexOf( 'action=heartbeat' ) > 0
|
1516 |
-
) {
|
1517 |
-
return;
|
1518 |
-
}
|
1519 |
-
|
1520 |
-
if (settings.url.indexOf('?') > 0) {
|
1521 |
-
settings.url += '&';
|
1522 |
-
} else {
|
1523 |
-
settings.url += '?';
|
1524 |
-
}
|
1525 |
-
|
1526 |
-
settings.url += '<?php echo $admin_param ?>=true';
|
1527 |
-
}
|
1528 |
-
});
|
1529 |
-
})(jQuery);
|
1530 |
-
</script>
|
1531 |
-
<?php
|
1532 |
-
}
|
1533 |
-
|
1534 |
/**
|
1535 |
* Opens the support forum subemenu item in a new browser page.
|
1536 |
*
|
@@ -1641,8 +1458,10 @@
|
|
1641 |
}
|
1642 |
|
1643 |
if ( $this->is_plugin() ) {
|
1644 |
-
if ( $
|
1645 |
add_action( 'wpmu_new_blog', array( $this, '_after_new_blog_callback' ), 10, 6 );
|
|
|
|
|
1646 |
}
|
1647 |
|
1648 |
register_deactivation_hook( $this->_plugin_main_file_path, array( &$this, '_deactivate_plugin_hook' ) );
|
@@ -1652,7 +1471,12 @@
|
|
1652 |
add_action( 'deactivate_blog', array( &$this, '_after_site_deactivated_callback' ) );
|
1653 |
add_action( 'archive_blog', array( &$this, '_after_site_deactivated_callback' ) );
|
1654 |
add_action( 'make_spam_blog', array( &$this, '_after_site_deactivated_callback' ) );
|
1655 |
-
|
|
|
|
|
|
|
|
|
|
|
1656 |
|
1657 |
add_action( 'activate_blog', array( &$this, '_after_site_reactivated_callback' ) );
|
1658 |
add_action( 'unarchive_blog', array( &$this, '_after_site_reactivated_callback' ) );
|
@@ -1677,6 +1501,7 @@
|
|
1677 |
add_action( 'admin_init', array( &$this, '_add_premium_version_upgrade_selection' ) );
|
1678 |
add_action( 'admin_init', array( &$this, '_add_beta_mode_update_handler' ) );
|
1679 |
add_action( 'admin_init', array( &$this, '_add_user_change_option' ) );
|
|
|
1680 |
|
1681 |
$this->add_ajax_action( 'update_billing', array( &$this, '_update_billing_ajax_action' ) );
|
1682 |
$this->add_ajax_action( 'start_trial', array( &$this, '_start_trial_ajax_action' ) );
|
@@ -2048,7 +1873,13 @@
|
|
2048 |
return;
|
2049 |
}
|
2050 |
|
2051 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2052 |
|
2053 |
if ( self::is_plugins_page() && $this->is_plugin() ) {
|
2054 |
$this->hook_plugin_action_links();
|
@@ -2094,20 +1925,27 @@
|
|
2094 |
/**
|
2095 |
* Leverage backtrace to find caller plugin file path.
|
2096 |
*
|
2097 |
-
* @
|
2098 |
-
* @
|
2099 |
-
*
|
2100 |
-
* @param bool $is_init Is initiation sequence.
|
2101 |
*
|
2102 |
* @return string
|
|
|
|
|
|
|
2103 |
*/
|
2104 |
-
private function _find_caller_plugin_file( $is_init = false ) {
|
2105 |
// Try to load the cached value of the file path.
|
2106 |
if ( isset( $this->_storage->plugin_main_file ) ) {
|
2107 |
$plugin_main_file = $this->_storage->plugin_main_file;
|
2108 |
if ( ! empty( $plugin_main_file->path ) ) {
|
2109 |
$absolute_path = $this->get_absolute_path( $plugin_main_file->path );
|
2110 |
if ( file_exists( $absolute_path ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
2111 |
return $absolute_path;
|
2112 |
}
|
2113 |
}
|
@@ -2148,12 +1986,11 @@
|
|
2148 |
* Only the original instantiator that calls dynamic_init can modify the module's path.
|
2149 |
*/
|
2150 |
// Find caller module.
|
2151 |
-
$id_slug_type_path_map = self::$_accounts->get_option( 'id_slug_type_path_map', array() );
|
2152 |
$this->_storage->plugin_main_file = (object) array(
|
2153 |
-
'path' => $
|
2154 |
);
|
2155 |
|
2156 |
-
return $this->get_absolute_path( $
|
2157 |
}
|
2158 |
|
2159 |
/**
|
@@ -2215,6 +2052,8 @@
|
|
2215 |
* @param number $module_id
|
2216 |
* @param string $slug
|
2217 |
*
|
|
|
|
|
2218 |
* @since 1.2.2
|
2219 |
*/
|
2220 |
private function store_id_slug_type_path_map( $module_id, $slug ) {
|
@@ -2236,20 +2075,52 @@
|
|
2236 |
$store_option = true;
|
2237 |
}
|
2238 |
|
2239 |
-
|
2240 |
-
|
2241 |
-
|
2242 |
-
|
2243 |
-
|
2244 |
-
|
2245 |
-
|
2246 |
-
|
2247 |
-
|
2248 |
-
|
2249 |
-
|
2250 |
-
|
2251 |
-
|
2252 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2253 |
|
2254 |
$id_slug_type_path_map[ $module_id ]['type'] = $caller_main_file_and_type->module_type;
|
2255 |
$id_slug_type_path_map[ $module_id ]['path'] = $caller_main_file_and_type->path;
|
@@ -2260,6 +2131,8 @@
|
|
2260 |
if ( $store_option ) {
|
2261 |
self::$_accounts->set_option( 'id_slug_type_path_map', $id_slug_type_path_map, true );
|
2262 |
}
|
|
|
|
|
2263 |
}
|
2264 |
|
2265 |
/**
|
@@ -2273,8 +2146,10 @@
|
|
2273 |
* add-ons are relying on loading the SDK from the parent module, and also allows themes including the
|
2274 |
* SDK an internal file instead of directly from functions.php.
|
2275 |
* @since 1.2.1.7 Knows how to handle cases when an add-on includes the parent module logic.
|
|
|
|
|
2276 |
*/
|
2277 |
-
private function get_caller_main_file_and_type() {
|
2278 |
self::require_plugin_essentials();
|
2279 |
|
2280 |
$all_plugins = fs_get_plugins( true );
|
@@ -2413,10 +2288,12 @@
|
|
2413 |
}
|
2414 |
}
|
2415 |
|
2416 |
-
|
2417 |
'module_type' => $module_type,
|
2418 |
'path' => $caller_file_candidate
|
2419 |
);
|
|
|
|
|
2420 |
}
|
2421 |
|
2422 |
#----------------------------------------------------------------------------------
|
@@ -2433,6 +2310,13 @@
|
|
2433 |
* @since 1.1.2
|
2434 |
*/
|
2435 |
function _add_deactivation_feedback_dialog_box() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2436 |
$subscription_cancellation_dialog_box_template_params = $this->apply_filters( 'show_deactivation_subscription_cancellation', true ) ?
|
2437 |
$this->_get_subscription_cancellation_dialog_box_template_params() :
|
2438 |
array();
|
@@ -2440,7 +2324,7 @@
|
|
2440 |
/**
|
2441 |
* @since 2.3.0 Developers can optionally hide the deactivation feedback form using the 'show_deactivation_feedback_form' filter.
|
2442 |
*/
|
2443 |
-
$show_deactivation_feedback_form =
|
2444 |
if ( $this->has_filter( 'show_deactivation_feedback_form' ) ) {
|
2445 |
$show_deactivation_feedback_form = $this->apply_filters( 'show_deactivation_feedback_form', true );
|
2446 |
} else if ( $this->is_addon() ) {
|
@@ -2545,7 +2429,7 @@
|
|
2545 |
$reason_temporary_deactivation = array(
|
2546 |
'id' => self::REASON_TEMPORARY_DEACTIVATION,
|
2547 |
'text' => sprintf(
|
2548 |
-
$this->get_text_inline( "It's a temporary %s
|
2549 |
strtolower( $this->is_plugin() ?
|
2550 |
$this->get_text_inline( 'Deactivation', 'deactivation' ) :
|
2551 |
$this->get_text_inline( 'Theme Switch', 'theme-switch' )
|
@@ -2710,6 +2594,14 @@
|
|
2710 |
|
2711 |
$this->_storage->store( 'uninstall_reason', $reason );
|
2712 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2713 |
/**
|
2714 |
* If the module type is "theme", trigger the uninstall event here (on theme deactivation) since themes do
|
2715 |
* not support uninstall hook.
|
@@ -2731,6 +2623,73 @@
|
|
2731 |
exit;
|
2732 |
}
|
2733 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2734 |
/**
|
2735 |
* @author Leo Fajardo (@leorw)
|
2736 |
* @since 2.1.4
|
@@ -2927,6 +2886,13 @@
|
|
2927 |
return self::instance( $addon_id );
|
2928 |
}
|
2929 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2930 |
#endregion ------------------------------------------------------------------
|
2931 |
|
2932 |
/**
|
@@ -3437,7 +3403,9 @@
|
|
3437 |
add_action( 'plugins_loaded', array( 'Freemius', '_load_textdomain' ), 1 );
|
3438 |
}
|
3439 |
|
3440 |
-
|
|
|
|
|
3441 |
add_action( 'admin_footer', array( 'Freemius', '_open_support_forum_in_new_page' ) );
|
3442 |
|
3443 |
if ( self::is_plugins_page() || self::is_themes_page() ) {
|
@@ -3456,48 +3424,197 @@
|
|
3456 |
self::$_statics_loaded = true;
|
3457 |
}
|
3458 |
|
|
|
|
|
|
|
|
|
3459 |
/**
|
3460 |
* @author Leo Fajardo (@leorw)
|
|
|
3461 |
*
|
3462 |
-
* @
|
|
|
|
|
3463 |
*/
|
3464 |
-
private
|
3465 |
-
|
3466 |
-
|
3467 |
-
|
3468 |
-
$api_network_options = FS_Option_Manager::get_manager( WP_FS__OPTIONS_OPTION_NAME, true, true );
|
3469 |
-
$api_network_options->migrate_to_network();
|
3470 |
-
|
3471 |
-
// Migrate API cache to network level storage.
|
3472 |
-
FS_Cache_Manager::get_manager( WP_FS__API_CACHE_OPTION_NAME )->migrate_to_network();
|
3473 |
|
3474 |
-
|
3475 |
}
|
3476 |
|
3477 |
-
#----------------------------------------------------------------------------------
|
3478 |
-
#region Localization
|
3479 |
-
#----------------------------------------------------------------------------------
|
3480 |
-
|
3481 |
/**
|
3482 |
-
*
|
|
|
3483 |
*
|
3484 |
-
* @
|
3485 |
-
* @since 1.2.1
|
3486 |
*/
|
3487 |
-
|
3488 |
-
if ( !
|
3489 |
-
return;
|
3490 |
}
|
3491 |
|
3492 |
-
|
3493 |
|
3494 |
-
|
3495 |
-
|
3496 |
-
|
3497 |
-
|
3498 |
-
|
3499 |
-
|
3500 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3501 |
|
3502 |
#endregion
|
3503 |
|
@@ -3531,7 +3648,7 @@
|
|
3531 |
} else {
|
3532 |
// Add hidden debug page.
|
3533 |
$hook = FS_Admin_Menu_Manager::add_subpage(
|
3534 |
-
|
3535 |
$title,
|
3536 |
$title,
|
3537 |
'manage_options',
|
@@ -3692,6 +3809,10 @@
|
|
3692 |
|
3693 |
switch_to_blog( $current_blog_id );
|
3694 |
}
|
|
|
|
|
|
|
|
|
3695 |
} else if ( fs_request_is_action( 'simulate_trial' ) ) {
|
3696 |
check_admin_referer( 'simulate_trial' );
|
3697 |
|
@@ -3740,55 +3861,69 @@
|
|
3740 |
}
|
3741 |
|
3742 |
/**
|
3743 |
-
* @author
|
3744 |
-
* @since
|
|
|
|
|
3745 |
*/
|
3746 |
-
static function
|
3747 |
self::$_static_logger->entrance();
|
3748 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3749 |
if ( ! is_multisite() ) {
|
3750 |
-
$
|
3751 |
-
|
|
|
|
|
|
|
|
|
|
|
3752 |
} else {
|
3753 |
$sites = self::get_sites();
|
3754 |
|
3755 |
-
$all_plugins_installs = array();
|
3756 |
-
$all_themes_installs = array();
|
3757 |
-
|
3758 |
foreach ( $sites as $site ) {
|
3759 |
$blog_id = self::get_site_blog_id( $site );
|
3760 |
|
3761 |
-
|
3762 |
-
|
3763 |
-
foreach ( $plugins_installs as $slug => $install ) {
|
3764 |
-
if ( ! isset( $all_plugins_installs[ $slug ] ) ) {
|
3765 |
-
$all_plugins_installs[ $slug ] = array();
|
3766 |
-
}
|
3767 |
-
|
3768 |
-
$install->blog_id = $blog_id;
|
3769 |
|
3770 |
-
$
|
3771 |
-
|
|
|
|
|
3772 |
|
3773 |
-
|
3774 |
|
3775 |
-
|
3776 |
-
if ( ! isset( $all_themes_installs[ $slug ] ) ) {
|
3777 |
-
$all_themes_installs[ $slug ] = array();
|
3778 |
}
|
3779 |
|
3780 |
-
$install->blog_id = $blog_id;
|
3781 |
-
|
3782 |
-
$all_themes_installs[ $slug ][] = $install;
|
3783 |
}
|
3784 |
}
|
3785 |
}
|
3786 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3787 |
$licenses_by_module_type = self::get_all_licenses_by_module_type();
|
3788 |
|
3789 |
$vars = array(
|
3790 |
-
'plugin_sites' => $
|
3791 |
-
'theme_sites' => $
|
3792 |
'users' => self::get_all_users(),
|
3793 |
'addons' => self::get_all_addons(),
|
3794 |
'account_addons' => self::get_all_account_addons(),
|
@@ -3820,6 +3955,10 @@
|
|
3820 |
function is_on() {
|
3821 |
self::$_static_logger->entrance();
|
3822 |
|
|
|
|
|
|
|
|
|
3823 |
if ( isset( $this->_is_on ) ) {
|
3824 |
return $this->_is_on;
|
3825 |
}
|
@@ -3908,18 +4047,24 @@
|
|
3908 |
|
3909 |
$is_update = $this->apply_filters( 'is_plugin_update', $this->is_plugin_update() );
|
3910 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3911 |
return $this->get_api_plugin_scope()->ping(
|
3912 |
$this->get_anonymous_id( $blog_id ),
|
3913 |
-
|
3914 |
-
'is_update' => json_encode( $is_update ),
|
3915 |
-
'version' => $version,
|
3916 |
-
'sdk' => $this->version,
|
3917 |
-
'is_admin' => json_encode( is_admin() ),
|
3918 |
-
'is_ajax' => json_encode( self::is_ajax() ),
|
3919 |
-
'is_cron' => json_encode( self::is_cron() ),
|
3920 |
-
'is_gdpr_test' => $is_gdpr_test,
|
3921 |
-
'is_http' => json_encode( WP_FS__IS_HTTP_REQUEST ),
|
3922 |
-
)
|
3923 |
);
|
3924 |
}
|
3925 |
|
@@ -4056,9 +4201,9 @@
|
|
4056 |
$unique_id = self::$_accounts->get_option( 'unique_id', null, $blog_id );
|
4057 |
|
4058 |
if ( empty( $unique_id ) || ! is_string( $unique_id ) ) {
|
4059 |
-
$key =
|
4060 |
|
4061 |
-
$secure_auth = SECURE_AUTH_KEY;
|
4062 |
if ( empty( $secure_auth ) ||
|
4063 |
false !== strpos( $secure_auth, ' ' ) ||
|
4064 |
'put your unique phrase here' === $secure_auth
|
@@ -4085,6 +4230,17 @@
|
|
4085 |
return $unique_id;
|
4086 |
}
|
4087 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4088 |
/**
|
4089 |
* @author Vova Feldman (@svovaf)
|
4090 |
* @since 1.1.7.4
|
@@ -4233,11 +4389,16 @@
|
|
4233 |
$install_previous_desc = $this->esc_html_inline( 'Uninstall this version and install the previous one.', 'install-previous-desc' );
|
4234 |
$fix_issue_title = $this->esc_html_inline( 'Yes - I\'m giving you a chance to fix it', 'fix-issue-title' );
|
4235 |
$fix_issue_desc = $this->esc_html_inline( 'We will do our best to whitelist your server and resolve this issue ASAP. You will get a follow-up email to %s once we have an update.', 'fix-issue-desc' );
|
4236 |
-
/* translators: %s: product title (e.g. "Awesome Plugin" requires
|
4237 |
-
$x_requires_access_to_api = $this->esc_html_inline( '%s requires
|
4238 |
$sysadmin_title = $this->esc_html_inline( 'I\'m a system administrator', 'sysadmin-title' );
|
4239 |
$happy_to_resolve_issue_asap = $this->esc_html_inline( 'We are sure it\'s an issue on our side and more than happy to resolve it for you ASAP if you give us a chance.', 'happy-to-resolve-issue-asap' );
|
4240 |
|
|
|
|
|
|
|
|
|
|
|
4241 |
$message = false;
|
4242 |
if ( is_object( $api_result ) &&
|
4243 |
isset( $api_result->error ) &&
|
@@ -4869,7 +5030,7 @@
|
|
4869 |
|
4870 |
/**
|
4871 |
* This should be executed even if Freemius is off for the core module,
|
4872 |
-
* otherwise, the add-ons
|
4873 |
* relevant when the developer decided to turn FS off for existing users.
|
4874 |
*
|
4875 |
* @author Vova Feldman (@svovaf)
|
@@ -4907,22 +5068,25 @@
|
|
4907 |
* @since 1.1.7.3
|
4908 |
*
|
4909 |
*/
|
4910 |
-
if ( $this->is_registered() ) {
|
4911 |
-
|
4912 |
-
$this->schedule_sync_cron();
|
4913 |
-
}
|
4914 |
}
|
4915 |
|
4916 |
/**
|
4917 |
* Check if requested for manual blocking background sync.
|
4918 |
*/
|
4919 |
if ( fs_request_has( 'background_sync' ) ) {
|
|
|
|
|
|
|
4920 |
$this->run_manual_sync();
|
4921 |
}
|
4922 |
}
|
4923 |
}
|
4924 |
|
4925 |
if ( $this->is_registered() ) {
|
|
|
|
|
4926 |
$this->hook_callback_to_install_sync();
|
4927 |
}
|
4928 |
|
@@ -4937,6 +5101,28 @@
|
|
4937 |
}
|
4938 |
|
4939 |
if ( $this->is_user_in_admin() ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4940 |
if ( $this->is_addon() ) {
|
4941 |
if ( ! $this->is_parent_plugin_installed() ) {
|
4942 |
$parent_name = $this->get_option( $plugin_info, 'parent_name', null );
|
@@ -5041,7 +5227,7 @@
|
|
5041 |
* because the updater has some logic that needs to be executed
|
5042 |
* during AJAX calls.
|
5043 |
*
|
5044 |
-
* Currently we need to hook to the `http_request_host_is_external` filter.
|
5045 |
* In the future, there might be additional logic added.
|
5046 |
*
|
5047 |
* @author Vova Feldman
|
@@ -5060,7 +5246,8 @@
|
|
5060 |
*/
|
5061 |
( file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $this->premium_plugin_basename() ) ) )
|
5062 |
) &&
|
5063 |
-
$this->has_release_on_freemius()
|
|
|
5064 |
) {
|
5065 |
FS_Plugin_Updater::instance( $this );
|
5066 |
}
|
@@ -5129,150 +5316,70 @@
|
|
5129 |
}
|
5130 |
|
5131 |
/**
|
5132 |
-
* @
|
|
|
|
|
5133 |
*
|
5134 |
-
* @
|
5135 |
*/
|
5136 |
-
function
|
5137 |
$this->_logger->entrance();
|
5138 |
|
5139 |
-
$
|
5140 |
-
|
5141 |
-
|
5142 |
-
|
5143 |
-
if ( true === $result ) {
|
5144 |
-
self::shoot_ajax_success();
|
5145 |
-
}
|
5146 |
-
|
5147 |
-
$this->_logger->api_error( $result );
|
5148 |
-
|
5149 |
-
self::shoot_ajax_failure(
|
5150 |
-
sprintf( $this->get_text_inline( 'Unexpected API error. Please contact the %s\'s author with the following error.', 'unexpected-api-error' ), $this->_module_type ) .
|
5151 |
-
( $this->is_api_error( $result ) && isset( $result->error ) ?
|
5152 |
-
$result->error->message :
|
5153 |
-
var_export( $result, true ) )
|
5154 |
);
|
5155 |
-
}
|
5156 |
-
|
5157 |
-
/**
|
5158 |
-
* @author Leo Fajardo (@leorw)
|
5159 |
-
* @since 1.2.1.5
|
5160 |
-
*/
|
5161 |
-
function _allow_tracking_callback() {
|
5162 |
-
$this->_logger->entrance();
|
5163 |
-
|
5164 |
-
$this->check_ajax_referer( 'allow_tracking' );
|
5165 |
-
|
5166 |
-
$result = $this->allow_tracking( fs_is_network_admin() );
|
5167 |
|
5168 |
-
|
5169 |
-
|
|
|
|
|
5170 |
}
|
5171 |
|
5172 |
-
$this->
|
5173 |
-
|
5174 |
-
self::shoot_ajax_failure(
|
5175 |
-
sprintf( $this->get_text_inline( 'Unexpected API error. Please contact the %s\'s author with the following error.', 'unexpected-api-error' ), $this->_module_type ) .
|
5176 |
-
( $this->is_api_error( $result ) && isset( $result->error ) ?
|
5177 |
-
$result->error->message :
|
5178 |
-
var_export( $result, true ) )
|
5179 |
-
);
|
5180 |
-
}
|
5181 |
-
|
5182 |
-
/**
|
5183 |
-
* Opt-out from usage tracking.
|
5184 |
-
*
|
5185 |
-
* Note: This will not delete the account information but will stop all tracking.
|
5186 |
-
*
|
5187 |
-
* Returns:
|
5188 |
-
* 1. FALSE - If the user never opted-in.
|
5189 |
-
* 2. TRUE - If successfully opted-out.
|
5190 |
-
* 3. object - API result on failure.
|
5191 |
-
*
|
5192 |
-
* @author Leo Fajardo (@leorw)
|
5193 |
-
* @since 1.2.1.5
|
5194 |
-
*
|
5195 |
-
* @return bool|object
|
5196 |
-
*/
|
5197 |
-
function stop_site_tracking() {
|
5198 |
-
$this->_logger->entrance();
|
5199 |
-
|
5200 |
-
if ( ! $this->is_registered() ) {
|
5201 |
-
// User never opted-in.
|
5202 |
-
return false;
|
5203 |
-
}
|
5204 |
|
5205 |
-
if ( $
|
5206 |
-
|
5207 |
-
return true;
|
5208 |
}
|
5209 |
|
5210 |
-
|
5211 |
-
|
5212 |
-
|
5213 |
-
) );
|
5214 |
-
|
5215 |
-
if ( ! $this->is_api_result_entity( $result ) ||
|
5216 |
-
! isset( $result->is_disconnected ) ||
|
5217 |
-
! $result->is_disconnected
|
5218 |
) {
|
5219 |
$this->_logger->api_error( $result );
|
5220 |
|
5221 |
return $result;
|
5222 |
}
|
5223 |
|
5224 |
-
$this->_site->is_disconnected = $result->is_disconnected;
|
5225 |
-
$this->_store_site();
|
5226 |
-
|
5227 |
-
$this->clear_sync_cron();
|
5228 |
-
|
5229 |
-
// Successfully disconnected.
|
5230 |
return true;
|
5231 |
}
|
5232 |
|
5233 |
/**
|
5234 |
-
*
|
5235 |
-
*
|
5236 |
-
*
|
5237 |
*
|
5238 |
-
*
|
5239 |
-
* 1. FALSE - If the user never opted-in.
|
5240 |
-
* 2. TRUE - If successfully opted-out.
|
5241 |
-
* 3. object - API result on failure.
|
5242 |
-
*
|
5243 |
-
* @author Leo Fajardo (@leorw)
|
5244 |
-
* @since 1.2.1.5
|
5245 |
-
*
|
5246 |
-
* @return bool|object
|
5247 |
*/
|
5248 |
-
function
|
|
|
|
|
|
|
|
|
5249 |
$this->_logger->entrance();
|
5250 |
|
5251 |
-
if ( ! $this->is_registered() ) {
|
5252 |
-
// User never opted-in.
|
5253 |
-
return false;
|
5254 |
-
}
|
5255 |
-
|
5256 |
$install_id_2_blog_id = array();
|
5257 |
-
$
|
5258 |
|
5259 |
-
$
|
5260 |
-
|
5261 |
-
$params = array();
|
5262 |
-
foreach ( $installs_map as $blog_id => $install ) {
|
5263 |
-
if ( $install->is_tracking_prohibited() ) {
|
5264 |
-
// Already opted-out.
|
5265 |
-
continue;
|
5266 |
-
}
|
5267 |
|
|
|
5268 |
if ( $this->is_site_delegated_connection( $blog_id ) ) {
|
5269 |
-
//
|
5270 |
-
$
|
5271 |
continue;
|
5272 |
}
|
5273 |
|
5274 |
-
$params[] = array( 'id' => $install->id );
|
5275 |
-
|
5276 |
$install_id_2_blog_id[ $install->id ] = $blog_id;
|
5277 |
}
|
5278 |
|
@@ -5280,171 +5387,188 @@
|
|
5280 |
return true;
|
5281 |
}
|
5282 |
|
5283 |
-
$params
|
|
|
|
|
|
|
|
|
5284 |
|
5285 |
// Send update to FS.
|
5286 |
-
$result = $this->get_current_or_network_user_api_scope()->call(
|
|
|
|
|
|
|
|
|
5287 |
|
5288 |
-
if ( ! $this->is_api_result_object( $result, '
|
5289 |
$this->_logger->api_error( $result );
|
5290 |
|
5291 |
return $result;
|
5292 |
}
|
5293 |
|
5294 |
-
foreach ( $result->installs as $r_install ) {
|
5295 |
-
$blog_id = $install_id_2_blog_id[ $r_install->id ];
|
5296 |
-
$install = $installs_map[ $blog_id ];
|
5297 |
-
$install->is_disconnected = $r_install->is_disconnected;
|
5298 |
-
$this->_store_site( true, $blog_id, $install );
|
5299 |
-
}
|
5300 |
-
|
5301 |
-
$this->clear_sync_cron( $opt_out_all );
|
5302 |
-
|
5303 |
-
// Successfully disconnected.
|
5304 |
return true;
|
5305 |
}
|
5306 |
|
5307 |
/**
|
5308 |
-
*
|
5309 |
-
*
|
5310 |
-
* Note: This will not delete the account information but will stop all tracking.
|
5311 |
-
*
|
5312 |
-
* Returns:
|
5313 |
-
* 1. FALSE - If the user never opted-in.
|
5314 |
-
* 2. TRUE - If successfully opted-out.
|
5315 |
-
* 3. object - API result on failure.
|
5316 |
-
*
|
5317 |
-
* @author Leo Fajardo (@leorw)
|
5318 |
-
* @since 1.2.1.5
|
5319 |
-
*
|
5320 |
-
* @param bool $is_network_action
|
5321 |
*
|
5322 |
-
* @return
|
5323 |
*/
|
5324 |
-
function
|
5325 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5326 |
|
5327 |
-
return $
|
5328 |
-
$this->stop_network_tracking() :
|
5329 |
-
$this->stop_site_tracking();
|
5330 |
}
|
5331 |
|
5332 |
/**
|
5333 |
-
*
|
5334 |
-
*
|
5335 |
-
* Note: This will only work if the user opted-in previously.
|
5336 |
-
*
|
5337 |
-
* Returns:
|
5338 |
-
* 1. FALSE - If the user never opted-in.
|
5339 |
-
* 2. TRUE - If successfully opted-in back to usage tracking.
|
5340 |
-
* 3. object - API result on failure.
|
5341 |
-
*
|
5342 |
-
* @author Leo Fajardo (@leorw)
|
5343 |
-
* @since 1.2.1.5
|
5344 |
-
*
|
5345 |
-
* @return bool|object
|
5346 |
*/
|
5347 |
-
function
|
5348 |
$this->_logger->entrance();
|
5349 |
|
5350 |
-
|
5351 |
-
// User never opted-in.
|
5352 |
-
return false;
|
5353 |
-
}
|
5354 |
|
5355 |
-
if ( $this->
|
5356 |
-
|
5357 |
-
return true;
|
5358 |
}
|
5359 |
|
5360 |
-
$
|
5361 |
-
|
5362 |
-
) );
|
5363 |
-
|
5364 |
-
if ( ! $this->is_api_result_entity( $result ) ||
|
5365 |
-
! isset( $result->is_disconnected ) ||
|
5366 |
-
$result->is_disconnected
|
5367 |
-
) {
|
5368 |
-
$this->_logger->api_error( $result );
|
5369 |
|
5370 |
-
|
|
|
5371 |
}
|
5372 |
|
5373 |
-
$
|
5374 |
-
$this->_store_site();
|
5375 |
|
5376 |
-
$this->
|
5377 |
|
5378 |
-
|
5379 |
-
|
|
|
|
|
|
|
5380 |
}
|
5381 |
|
5382 |
/**
|
5383 |
-
*
|
5384 |
-
*
|
5385 |
-
*
|
5386 |
-
*
|
5387 |
-
* Returns:
|
5388 |
-
* 1. FALSE - If the user never opted-in.
|
5389 |
-
* 2. TRUE - If successfully opted-in back to usage tracking.
|
5390 |
-
* 3. object - API result on failure.
|
5391 |
-
*
|
5392 |
-
* @author Leo Fajardo (@leorw)
|
5393 |
-
* @since 1.2.1.5
|
5394 |
*
|
5395 |
-
* @return bool|
|
5396 |
*/
|
5397 |
-
function
|
5398 |
-
$this->
|
5399 |
-
|
5400 |
-
if ( ! $this->is_registered() ) {
|
5401 |
// User never opted-in.
|
5402 |
return false;
|
5403 |
}
|
5404 |
|
5405 |
-
|
5406 |
-
|
5407 |
-
|
5408 |
-
|
5409 |
-
|
5410 |
-
|
5411 |
-
|
5412 |
-
}
|
5413 |
-
|
5414 |
-
$params[] = array( 'id' => $install->id );
|
5415 |
-
|
5416 |
-
$install_id_2_blog_id[ $install->id ] = $blog_id;
|
5417 |
}
|
5418 |
|
5419 |
-
|
5420 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5421 |
}
|
5422 |
|
5423 |
-
|
|
|
5424 |
|
5425 |
-
|
5426 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5427 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5428 |
|
5429 |
-
|
5430 |
-
|
|
|
5431 |
|
5432 |
-
|
5433 |
-
|
|
|
|
|
|
|
|
|
|
|
5434 |
|
5435 |
-
|
5436 |
-
|
5437 |
-
|
5438 |
-
$install->is_disconnected = $r_install->is_disconnected;
|
5439 |
-
$this->_store_site( true, $blog_id, $install );
|
5440 |
}
|
5441 |
|
5442 |
-
$this->
|
|
|
|
|
|
|
|
|
5443 |
|
5444 |
-
// Successfully reconnected.
|
5445 |
return true;
|
5446 |
}
|
5447 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5448 |
/**
|
5449 |
* Opt-in back into usage tracking.
|
5450 |
*
|
@@ -5458,16 +5582,18 @@
|
|
5458 |
* @author Leo Fajardo (@leorw)
|
5459 |
* @since 1.2.1.5
|
5460 |
*
|
5461 |
-
* @
|
5462 |
*
|
5463 |
* @return bool|object
|
5464 |
*/
|
5465 |
-
function
|
5466 |
$this->_logger->entrance();
|
5467 |
|
5468 |
-
return $
|
5469 |
-
$this->
|
5470 |
-
$
|
|
|
|
|
5471 |
}
|
5472 |
|
5473 |
/**
|
@@ -5488,8 +5614,7 @@
|
|
5488 |
|
5489 |
if ( ! fs_is_network_admin() || $is_context_single_site ) {
|
5490 |
if ( $this->is_tracking_prohibited() ) {
|
5491 |
-
$this->
|
5492 |
-
$this->_store_site();
|
5493 |
}
|
5494 |
} else {
|
5495 |
$installs_map = $this->get_blog_install_map();
|
@@ -5497,73 +5622,69 @@
|
|
5497 |
/**
|
5498 |
* @var FS_Site $install
|
5499 |
*/
|
5500 |
-
if ( $
|
5501 |
-
$
|
5502 |
-
$this->_store_site( true, $blog_id, $install );
|
5503 |
}
|
5504 |
}
|
5505 |
}
|
5506 |
}
|
5507 |
|
5508 |
/**
|
5509 |
-
*
|
5510 |
-
* @since 2.3.2
|
5511 |
*
|
5512 |
-
* @
|
|
|
|
|
|
|
|
|
5513 |
*/
|
5514 |
-
function
|
5515 |
-
|
5516 |
-
|
5517 |
-
$this->_storage->get( 'is_extensions_tracking_allowed', null )
|
5518 |
-
) );
|
5519 |
-
}
|
5520 |
|
5521 |
-
|
5522 |
-
|
5523 |
-
|
5524 |
-
*/
|
5525 |
-
function _update_tracking_permission_callback() {
|
5526 |
-
$this->_logger->entrance();
|
5527 |
|
5528 |
-
|
|
|
|
|
5529 |
|
5530 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5531 |
|
5532 |
-
|
5533 |
-
|
|
|
5534 |
}
|
5535 |
|
5536 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5537 |
|
5538 |
-
|
5539 |
-
case 'extensions':
|
5540 |
-
$this->update_extensions_tracking_flag( $is_enabled );
|
5541 |
-
break;
|
5542 |
-
default:
|
5543 |
$permission = 'no_match';
|
5544 |
-
|
5545 |
|
5546 |
-
|
5547 |
-
self::shoot_ajax_failure();
|
5548 |
}
|
5549 |
|
5550 |
-
|
5551 |
-
'permissions' => array(
|
5552 |
-
$permission => $is_enabled,
|
5553 |
-
)
|
5554 |
-
) );
|
5555 |
-
}
|
5556 |
-
|
5557 |
-
/**
|
5558 |
-
* @author Leo Fajardo (@leorw)
|
5559 |
-
* @since 2.3.2
|
5560 |
-
*
|
5561 |
-
* @param bool|null $is_enabled
|
5562 |
-
*/
|
5563 |
-
function update_extensions_tracking_flag( $is_enabled ) {
|
5564 |
-
if ( is_bool( $is_enabled ) ) {
|
5565 |
-
$this->_storage->store( 'is_extensions_tracking_allowed', $is_enabled );
|
5566 |
-
}
|
5567 |
}
|
5568 |
|
5569 |
/**
|
@@ -5769,8 +5890,7 @@
|
|
5769 |
if ( $this->is_activation_mode() ) {
|
5770 |
if ( ! is_admin() ) {
|
5771 |
/**
|
5772 |
-
* If in activation mode, don't execute Freemius outside
|
5773 |
-
* admin dashboard.
|
5774 |
*
|
5775 |
* @author Vova Feldman (@svovaf)
|
5776 |
* @since 1.1.7.3
|
@@ -6317,7 +6437,25 @@
|
|
6317 |
if ( ! isset( $this->_is_anonymous ) ) {
|
6318 |
if ( $this->is_network_anonymous() ) {
|
6319 |
$this->_is_anonymous = true;
|
6320 |
-
} else if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6321 |
if ( ! isset( $this->_storage->is_anonymous ) ) {
|
6322 |
// Not skipped.
|
6323 |
$this->_is_anonymous = false;
|
@@ -6373,6 +6511,18 @@
|
|
6373 |
return $this->_storage->get( 'is_pending_activation', false );
|
6374 |
}
|
6375 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6376 |
/**
|
6377 |
* Check if plugin must be WordPress.org compliant.
|
6378 |
*
|
@@ -6449,9 +6599,11 @@
|
|
6449 |
private function get_cron_blog_id( $name ) {
|
6450 |
$this->_logger->entrance( $name );
|
6451 |
|
6452 |
-
|
6453 |
-
|
6454 |
-
|
|
|
|
|
6455 |
$cron_data = $this->get_cron_data( $name );
|
6456 |
|
6457 |
return ( is_object( $cron_data ) && is_numeric( $cron_data->blog_id ) ) ?
|
@@ -6562,18 +6714,23 @@
|
|
6562 |
return 0;
|
6563 |
}
|
6564 |
|
6565 |
-
if ( $this->_is_network_active
|
6566 |
-
|
6567 |
-
$except_blog_id != $this->_storage->network_install_blog_id &&
|
6568 |
-
self::is_site_active( $this->_storage->network_install_blog_id )
|
6569 |
-
) {
|
6570 |
-
// Try to run cron from the main network blog.
|
6571 |
-
$install = $this->get_install_by_blog_id( $this->_storage->network_install_blog_id );
|
6572 |
|
6573 |
-
if (
|
6574 |
-
|
|
|
|
|
6575 |
) {
|
6576 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6577 |
}
|
6578 |
}
|
6579 |
|
@@ -6582,7 +6739,7 @@
|
|
6582 |
foreach ( $installs as $blog_id => $install ) {
|
6583 |
if ( $except_blog_id != $blog_id &&
|
6584 |
self::is_site_active( $blog_id ) &&
|
6585 |
-
|
6586 |
) {
|
6587 |
return $blog_id;
|
6588 |
}
|
@@ -6614,7 +6771,7 @@
|
|
6614 |
/**
|
6615 |
* @var FS_Site $install
|
6616 |
*/
|
6617 |
-
if ( $
|
6618 |
$clear_cron = false;
|
6619 |
break;
|
6620 |
}
|
@@ -6625,14 +6782,7 @@
|
|
6625 |
return;
|
6626 |
}
|
6627 |
|
6628 |
-
|
6629 |
-
* @var object $cron_data
|
6630 |
-
*/
|
6631 |
-
$cron_data = $this->get_cron_data( $name );
|
6632 |
-
|
6633 |
-
$cron_blog_id = is_object( $cron_data ) && isset( $cron_data->blog_id ) ?
|
6634 |
-
$cron_data->blog_id :
|
6635 |
-
0;
|
6636 |
|
6637 |
$this->clear_cron_data( $name );
|
6638 |
|
@@ -6669,14 +6819,7 @@
|
|
6669 |
return false;
|
6670 |
}
|
6671 |
|
6672 |
-
|
6673 |
-
* @var object $cron_data
|
6674 |
-
*/
|
6675 |
-
$cron_data = $this->get_cron_data( $name );
|
6676 |
-
|
6677 |
-
$cron_blog_id = is_object( $cron_data ) && isset( $cron_data->blog_id ) ?
|
6678 |
-
$cron_data->blog_id :
|
6679 |
-
0;
|
6680 |
|
6681 |
if ( 0 < $cron_blog_id ) {
|
6682 |
switch_to_blog( $cron_blog_id );
|
@@ -6787,7 +6930,7 @@
|
|
6787 |
} else {
|
6788 |
$installs = $this->get_blog_install_map();
|
6789 |
foreach ( $installs as $blog_id => $install ) {
|
6790 |
-
if ( $this->
|
6791 |
if ( ! isset( $users_2_blog_ids[ $install->user_id ] ) ) {
|
6792 |
$users_2_blog_ids[ $install->user_id ] = array();
|
6793 |
}
|
@@ -6852,8 +6995,6 @@
|
|
6852 |
* @since 1.1.7.3
|
6853 |
*/
|
6854 |
private function run_manual_sync() {
|
6855 |
-
self::require_pluggable_essentials();
|
6856 |
-
|
6857 |
if ( ! $this->is_user_admin() ) {
|
6858 |
return;
|
6859 |
}
|
@@ -6937,6 +7078,24 @@
|
|
6937 |
return $this->is_cron_on( 'sync' );
|
6938 |
}
|
6939 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6940 |
/**
|
6941 |
* @author Vova Feldman (@svovaf)
|
6942 |
* @since 1.1.7.3
|
@@ -7043,6 +7202,10 @@
|
|
7043 |
* @param int $except_blog_id Since 2.0.0 when running in a multisite network environment, the cron execution is consolidated. This param allows excluding excluded specified blog ID from being the cron executor.
|
7044 |
*/
|
7045 |
private function schedule_install_sync( $except_blog_id = 0 ) {
|
|
|
|
|
|
|
|
|
7046 |
$this->schedule_cron( 'install_sync', 'install_sync', 'single', WP_FS__SCRIPT_START_TIME, false, $except_blog_id );
|
7047 |
}
|
7048 |
|
@@ -7131,13 +7294,20 @@
|
|
7131 |
/**
|
7132 |
* Show a notice that activation is currently pending.
|
7133 |
*
|
|
|
|
|
7134 |
* @author Vova Feldman (@svovaf)
|
7135 |
* @since 1.0.7
|
7136 |
*
|
7137 |
* @param bool|string $email
|
7138 |
* @param bool $is_pending_trial Since 1.2.1.5
|
|
|
7139 |
*/
|
7140 |
-
function _add_pending_activation_notice(
|
|
|
|
|
|
|
|
|
7141 |
if ( ! is_string( $email ) ) {
|
7142 |
$current_user = self::_get_current_wp_user();
|
7143 |
$email = $current_user->user_email;
|
@@ -7145,12 +7315,12 @@
|
|
7145 |
|
7146 |
$this->_admin_notices->add_sticky(
|
7147 |
sprintf(
|
7148 |
-
$this->get_text_inline( 'You should receive
|
7149 |
'<b>' . $this->get_plugin_name() . '</b>',
|
7150 |
'<b>' . $email . '</b>',
|
7151 |
( $is_pending_trial ?
|
7152 |
$this->get_text_inline( 'start the trial', 'start-the-trial' ) :
|
7153 |
-
$this->get_text_inline( 'complete the
|
7154 |
),
|
7155 |
'activation_pending',
|
7156 |
'Thanks!'
|
@@ -7193,6 +7363,20 @@
|
|
7193 |
/**
|
7194 |
* Don't redirect if activating multiple plugins at once (bulk activation).
|
7195 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7196 |
} else if ( ! $is_migration ) {
|
7197 |
$this->_redirect_on_activation_hook();
|
7198 |
return;
|
@@ -7206,7 +7390,7 @@
|
|
7206 |
if ( fs_request_is_action( $this->get_unique_affix() . '_skip_activation' ) ) {
|
7207 |
check_admin_referer( $this->get_unique_affix() . '_skip_activation' );
|
7208 |
|
7209 |
-
$this->skip_connection(
|
7210 |
|
7211 |
fs_redirect( $this->get_after_activation_url( 'after_skip_url' ) );
|
7212 |
}
|
@@ -7379,8 +7563,6 @@
|
|
7379 |
|
7380 |
fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
|
7381 |
fs_enqueue_local_script( 'fs-postmessage', 'postmessage.js' );
|
7382 |
-
|
7383 |
-
fs_enqueue_local_style( 'fs_connect', '/admin/connect.css' );
|
7384 |
}
|
7385 |
|
7386 |
/**
|
@@ -7416,14 +7598,14 @@
|
|
7416 |
<?php
|
7417 |
echo $this->apply_filters( 'optin_pointer_execute', "
|
7418 |
|
7419 |
-
|
7420 |
|
7421 |
-
|
7422 |
-
|
7423 |
-
|
7424 |
-
|
7425 |
|
7426 |
-
|
7427 |
}
|
7428 |
}
|
7429 |
});
|
@@ -7439,7 +7621,7 @@
|
|
7439 |
*
|
7440 |
* @return string
|
7441 |
*/
|
7442 |
-
function current_page_url() {
|
7443 |
$url = 'http';
|
7444 |
|
7445 |
if ( isset( $_SERVER["HTTPS"] ) ) {
|
@@ -7471,7 +7653,7 @@
|
|
7471 |
}
|
7472 |
|
7473 |
/* Events
|
7474 |
-
|
7475 |
/**
|
7476 |
* Delete site install from Database.
|
7477 |
*
|
@@ -7637,10 +7819,19 @@
|
|
7637 |
* @author Leo Fajardo (@leorw)
|
7638 |
* @since 1.2.2
|
7639 |
*
|
7640 |
-
* @return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7641 |
*/
|
7642 |
-
private function
|
7643 |
-
$slug = $this->get_previous_theme_slug();
|
7644 |
if ( false !== $slug && current_user_can( 'switch_themes' ) ) {
|
7645 |
$theme_instance = wp_get_theme( $slug );
|
7646 |
|
@@ -7737,6 +7928,10 @@
|
|
7737 |
( current_filter() !== ( 'activate_' . $this->_free_plugin_basename ) ) :
|
7738 |
$this->is_premium();
|
7739 |
|
|
|
|
|
|
|
|
|
7740 |
$this->_logger->info( 'Activating ' . ( $is_premium_version_activation ? 'premium' : 'free' ) . ' plugin version.' );
|
7741 |
|
7742 |
if ( $this->is_plugin() ) {
|
@@ -7803,7 +7998,9 @@
|
|
7803 |
$plugin_version = $this->_storage->is_anonymous_ms['version'];
|
7804 |
$network = true;
|
7805 |
} else {
|
7806 |
-
$plugin_version = $this->_storage->is_anonymous
|
|
|
|
|
7807 |
$network = false;
|
7808 |
}
|
7809 |
|
@@ -7951,7 +8148,7 @@
|
|
7951 |
);
|
7952 |
} else {
|
7953 |
// Activate the license.
|
7954 |
-
$install = $this->
|
7955 |
'/',
|
7956 |
'put',
|
7957 |
array( 'license_key' => $this->apply_filters( 'license_key', $license->secret_key ) )
|
@@ -8610,6 +8807,20 @@
|
|
8610 |
$this->_is_anonymous = $is_anonymous;
|
8611 |
}
|
8612 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8613 |
/**
|
8614 |
* @author Vova Feldman (@svovaf)
|
8615 |
* @since 2.0.0
|
@@ -8626,9 +8837,17 @@
|
|
8626 |
* @uses Freemius::is_network_anonymous() to check if the super-admin network skipped.
|
8627 |
* @uses Freemius::is_network_delegated_connection() to check if the super-admin network delegated the connection to the site admins.
|
8628 |
*/
|
8629 |
-
function _after_new_blog_callback( $blog_id, $user_id, $domain, $path, $network_id, $meta ) {
|
8630 |
$this->_logger->entrance();
|
8631 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8632 |
if ( $this->is_premium() &&
|
8633 |
$this->is_network_connected() &&
|
8634 |
is_object( $this->_license ) &&
|
@@ -8662,9 +8881,13 @@
|
|
8662 |
}
|
8663 |
}
|
8664 |
|
|
|
|
|
8665 |
$this->switch_to_blog( $current_blog_id );
|
8666 |
|
8667 |
-
if ( is_object( $
|
|
|
|
|
8668 |
// Already connected (with or without a license), so no need to continue.
|
8669 |
return;
|
8670 |
}
|
@@ -8697,6 +8920,8 @@
|
|
8697 |
false
|
8698 |
);
|
8699 |
|
|
|
|
|
8700 |
$this->switch_to_blog( $current_blog_id );
|
8701 |
} else {
|
8702 |
/**
|
@@ -8707,8 +8932,8 @@
|
|
8707 |
$has_delegated_site = false;
|
8708 |
|
8709 |
$sites = self::get_sites();
|
8710 |
-
foreach ( $sites as $
|
8711 |
-
$blog_id = self::get_site_blog_id( $
|
8712 |
|
8713 |
if ( $this->is_site_delegated_connection( $blog_id ) ) {
|
8714 |
$has_delegated_site = true;
|
@@ -8722,19 +8947,74 @@
|
|
8722 |
$this->skip_site_connection( $blog_id );
|
8723 |
}
|
8724 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8725 |
}
|
8726 |
|
8727 |
/**
|
8728 |
* @author Vova Feldman (@svovaf)
|
8729 |
* @since 1.1.3
|
8730 |
*
|
8731 |
-
* @param bool|int $
|
8732 |
*/
|
8733 |
-
private function reset_anonymous_mode( $
|
8734 |
-
if ( true === $
|
8735 |
-
|
8736 |
-
|
8737 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8738 |
}
|
8739 |
|
8740 |
/**
|
@@ -8745,11 +9025,7 @@
|
|
8745 |
* @author Leo Fajardo (@leorw)
|
8746 |
* @since 1.2.2
|
8747 |
*/
|
8748 |
-
if ( ! $this->_is_network_active
|
8749 |
-
0 === $network_or_blog_id ||
|
8750 |
-
get_current_blog_id() == $network_or_blog_id ||
|
8751 |
-
( true === $network_or_blog_id && fs_is_network_admin() )
|
8752 |
-
) {
|
8753 |
$this->_is_anonymous = null;
|
8754 |
}
|
8755 |
}
|
@@ -8795,44 +9071,42 @@
|
|
8795 |
* @author Vova Feldman (@svovaf)
|
8796 |
* @since 1.1.1
|
8797 |
*
|
8798 |
-
* @param
|
8799 |
-
* @param bool $skip_all_network Since 2.0.0. If true, skip connection for all sites.
|
8800 |
*/
|
8801 |
-
function skip_connection( $
|
8802 |
$this->_logger->entrance();
|
8803 |
|
8804 |
$this->_admin_notices->remove_sticky( 'connect_account' );
|
8805 |
|
8806 |
-
if ( $
|
8807 |
$this->set_anonymous_mode( true, true );
|
8808 |
-
}
|
8809 |
|
8810 |
-
|
8811 |
-
|
8812 |
-
|
8813 |
-
$uids = array();
|
8814 |
|
8815 |
-
|
8816 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
8817 |
|
8818 |
-
|
8819 |
-
|
8820 |
-
|
8821 |
-
|
8822 |
-
|
8823 |
-
|
8824 |
-
|
8825 |
-
foreach ( $sites as $site ) {
|
8826 |
-
$uids[] = $site['uid'];
|
8827 |
-
$this->skip_site_connection( $site['blog_id'], false );
|
8828 |
}
|
8829 |
}
|
|
|
8830 |
|
8831 |
-
|
8832 |
-
|
8833 |
-
$this->get_api_plugin_scope()->call( 'skip.json', 'put', array(
|
8834 |
-
'uids' => $uids,
|
8835 |
-
) );
|
8836 |
}
|
8837 |
|
8838 |
$this->network_upgrade_mode_completed();
|
@@ -8847,18 +9121,12 @@
|
|
8847 |
* @param int|null $blog_id
|
8848 |
* @param bool $send_skip
|
8849 |
*/
|
8850 |
-
private function skip_site_connection( $blog_id = null
|
8851 |
$this->_logger->entrance();
|
8852 |
|
8853 |
$this->_admin_notices->remove_sticky( 'connect_account', $blog_id );
|
8854 |
|
8855 |
$this->set_anonymous_mode( true, $blog_id );
|
8856 |
-
|
8857 |
-
if ( $send_skip ) {
|
8858 |
-
$this->get_api_plugin_scope()->call( 'skip.json', 'put', array(
|
8859 |
-
'uids' => array( $this->get_anonymous_id( $blog_id ) ),
|
8860 |
-
) );
|
8861 |
-
}
|
8862 |
}
|
8863 |
|
8864 |
/**
|
@@ -9230,7 +9498,7 @@
|
|
9230 |
* @param string[] $override
|
9231 |
* @param bool $include_plugins Since 1.1.8 by default include plugin changes.
|
9232 |
* @param bool $include_themes Since 1.1.8 by default include plugin changes.
|
9233 |
-
* @param bool $include_blog_data Since 2.3.0 by default include the current blog's data (language,
|
9234 |
*
|
9235 |
* @return array
|
9236 |
*/
|
@@ -9240,7 +9508,10 @@
|
|
9240 |
$include_themes = true,
|
9241 |
$include_blog_data = true
|
9242 |
) {
|
9243 |
-
|
|
|
|
|
|
|
9244 |
if ( ! defined( 'WP_FS__TRACK_PLUGINS' ) || false !== WP_FS__TRACK_PLUGINS ) {
|
9245 |
/**
|
9246 |
* @since 1.1.8 Also send plugin updates.
|
@@ -9268,21 +9539,23 @@
|
|
9268 |
|
9269 |
$versions = $this->get_versions();
|
9270 |
|
9271 |
-
$blog_data =
|
9272 |
-
|
9273 |
-
|
9274 |
-
|
9275 |
-
|
9276 |
-
|
9277 |
-
|
9278 |
-
|
|
|
|
|
|
|
9279 |
|
9280 |
return array_merge( $versions, $blog_data, array(
|
9281 |
'version' => $this->get_plugin_version(),
|
9282 |
'is_premium' => $this->is_premium(),
|
9283 |
// Special params.
|
9284 |
'is_active' => true,
|
9285 |
-
'is_disconnected' => $this->is_tracking_prohibited(),
|
9286 |
'is_uninstalled' => false,
|
9287 |
), $override );
|
9288 |
}
|
@@ -9297,6 +9570,7 @@
|
|
9297 |
*
|
9298 |
* @param string[] string $override
|
9299 |
* @param bool $only_diff
|
|
|
9300 |
* @param bool $include_plugins Since 1.1.8 by default include plugin changes.
|
9301 |
* @param bool $include_themes Since 1.1.8 by default include plugin changes.
|
9302 |
*
|
@@ -9305,6 +9579,7 @@
|
|
9305 |
private function get_installs_data_for_api(
|
9306 |
array $override,
|
9307 |
$only_diff = false,
|
|
|
9308 |
$include_plugins = true,
|
9309 |
$include_themes = true
|
9310 |
) {
|
@@ -9342,6 +9617,10 @@
|
|
9342 |
|
9343 |
$sites = self::get_sites();
|
9344 |
|
|
|
|
|
|
|
|
|
9345 |
foreach ( $sites as $site ) {
|
9346 |
$blog_id = self::get_site_blog_id( $site );
|
9347 |
|
@@ -9353,19 +9632,64 @@
|
|
9353 |
continue;
|
9354 |
}
|
9355 |
|
9356 |
-
if ( ! $this->
|
9357 |
// Don't send updates regarding opted-out installs.
|
9358 |
continue;
|
9359 |
}
|
9360 |
|
9361 |
-
$install_data = $this->get_site_info( $site );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9362 |
|
9363 |
-
|
|
|
|
|
|
|
|
|
|
|
9364 |
|
9365 |
unset( $install_data['blog_id'] );
|
9366 |
unset( $install_data['uid'] );
|
|
|
|
|
9367 |
|
9368 |
-
$install_data['is_disconnected'] = $install->is_disconnected;
|
9369 |
$install_data['is_active'] = $this->is_active_for_site( $blog_id );
|
9370 |
$install_data['is_uninstalled'] = $install->is_uninstalled;
|
9371 |
|
@@ -9388,18 +9712,26 @@
|
|
9388 |
$is_common_diff_for_any_site = $is_common_diff_for_any_site || $is_common_diff;
|
9389 |
}
|
9390 |
|
9391 |
-
if ( ! empty( $install_data ) || $is_common_diff ) {
|
9392 |
// Add install ID and site unique ID.
|
9393 |
$install_data['id'] = $install->id;
|
9394 |
$install_data['uid'] = $uid;
|
|
|
9395 |
|
9396 |
-
$
|
|
|
|
|
9397 |
}
|
9398 |
}
|
9399 |
}
|
9400 |
|
9401 |
restore_current_blog();
|
9402 |
|
|
|
|
|
|
|
|
|
|
|
9403 |
if ( 0 < count( $installs_data ) && ( $is_common_diff_for_any_site || ! $only_diff ) ) {
|
9404 |
if ( ! $only_diff ) {
|
9405 |
$installs_data[] = $common;
|
@@ -9437,8 +9769,12 @@
|
|
9437 |
if ( ( is_bool( $install->{$p} ) || ! empty( $install->{$p} ) ) &&
|
9438 |
$install->{$p} != $v
|
9439 |
) {
|
9440 |
-
$
|
9441 |
-
|
|
|
|
|
|
|
|
|
9442 |
}
|
9443 |
} else {
|
9444 |
$special[ $p ] = $v;
|
@@ -9463,6 +9799,78 @@
|
|
9463 |
return $diff;
|
9464 |
}
|
9465 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9466 |
/**
|
9467 |
* Update install only if changed.
|
9468 |
*
|
@@ -9471,10 +9879,11 @@
|
|
9471 |
*
|
9472 |
* @param string[] string $override
|
9473 |
* @param bool $flush
|
|
|
9474 |
*
|
9475 |
* @return false|object|string
|
9476 |
*/
|
9477 |
-
private function send_install_update( $override = array(), $flush = false ) {
|
9478 |
$this->_logger->entrance();
|
9479 |
|
9480 |
$check_properties = $this->get_install_data_for_api( $override );
|
@@ -9485,7 +9894,6 @@
|
|
9485 |
$params = $this->get_install_diff_for_api( $check_properties, $this->_site, $override );
|
9486 |
}
|
9487 |
|
9488 |
-
$keepalive_only_update = false;
|
9489 |
if ( empty( $params ) ) {
|
9490 |
$keepalive_only_update = $this->should_send_keepalive_update();
|
9491 |
|
@@ -9500,10 +9908,9 @@
|
|
9500 |
}
|
9501 |
}
|
9502 |
|
9503 |
-
if (
|
9504 |
/**
|
9505 |
-
*
|
9506 |
-
* updates sent.
|
9507 |
*
|
9508 |
* @author Leo Fajardo (@leorw)
|
9509 |
* @since 2.2.3
|
@@ -9519,11 +9926,11 @@
|
|
9519 |
$this->set_keepalive_timestamp();
|
9520 |
|
9521 |
// Send updated values to FS.
|
9522 |
-
$site = $this->
|
9523 |
|
9524 |
-
if (
|
9525 |
/**
|
9526 |
-
*
|
9527 |
*
|
9528 |
* @author Leo Fajardo (@leorw)
|
9529 |
* @since 2.2.3
|
@@ -9545,37 +9952,29 @@
|
|
9545 |
*
|
9546 |
* @param string[] string $override
|
9547 |
* @param bool $flush
|
|
|
9548 |
*
|
9549 |
* @return false|object|string
|
9550 |
*/
|
9551 |
-
private function send_installs_update( $override = array(), $flush = false ) {
|
9552 |
$this->_logger->entrance();
|
9553 |
|
9554 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
9555 |
|
9556 |
-
$
|
9557 |
-
if ( empty( $installs_data ) ) {
|
9558 |
-
/**
|
9559 |
-
* Pass `true` to use the network level storage since the update is for many installs.
|
9560 |
-
*
|
9561 |
-
* @author Leo Fajardo (@leorw)
|
9562 |
-
* @since 2.2.3
|
9563 |
-
*/
|
9564 |
-
$keepalive_only_update = $this->should_send_keepalive_update( true );
|
9565 |
|
9566 |
-
|
9567 |
-
|
9568 |
-
* There are no updates to send including keepalive.
|
9569 |
-
*
|
9570 |
-
* @author Leo Fajardo (@leorw)
|
9571 |
-
* @since 2.2.3
|
9572 |
-
*/
|
9573 |
-
return false;
|
9574 |
-
}
|
9575 |
}
|
9576 |
|
9577 |
-
if (
|
9578 |
-
// Update last install sync timestamp
|
9579 |
$this->set_cron_execution_timestamp( 'install_sync' );
|
9580 |
}
|
9581 |
|
@@ -9590,8 +9989,8 @@
|
|
9590 |
// Send updated values to FS.
|
9591 |
$result = $this->get_api_user_scope()->call( "/plugins/{$this->_plugin->id}/installs.json", 'put', $installs_data );
|
9592 |
|
9593 |
-
if (
|
9594 |
-
// I successfully sent
|
9595 |
$this->clear_install_sync_cron();
|
9596 |
}
|
9597 |
|
@@ -9641,10 +10040,10 @@
|
|
9641 |
* @param string[] string $override
|
9642 |
* @param bool $flush
|
9643 |
*/
|
9644 |
-
|
9645 |
$this->_logger->entrance();
|
9646 |
|
9647 |
-
$site = $this->send_install_update( $override, $flush );
|
9648 |
|
9649 |
if ( false === $site ) {
|
9650 |
// No sync required.
|
@@ -9673,7 +10072,7 @@
|
|
9673 |
private function sync_installs( $override = array(), $flush = false ) {
|
9674 |
$this->_logger->entrance();
|
9675 |
|
9676 |
-
$result = $this->send_installs_update( $override, $flush );
|
9677 |
|
9678 |
if ( false === $result ) {
|
9679 |
// No sync required.
|
@@ -9828,8 +10227,8 @@
|
|
9828 |
// Send uninstall event.
|
9829 |
$this->send_installs_update( $params );
|
9830 |
} else {
|
9831 |
-
// Send uninstall event.
|
9832 |
-
$this->
|
9833 |
}
|
9834 |
}
|
9835 |
|
@@ -9926,7 +10325,17 @@
|
|
9926 |
return;
|
9927 |
}
|
9928 |
|
9929 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9930 |
|
9931 |
$fs->do_action( 'after_uninstall' );
|
9932 |
}
|
@@ -10037,7 +10446,7 @@
|
|
10037 |
* @return string
|
10038 |
*/
|
10039 |
function get_premium_slug() {
|
10040 |
-
return is_object( $this->_plugin ) ?
|
10041 |
$this->_plugin->premium_slug :
|
10042 |
"{$this->_slug}-premium";
|
10043 |
}
|
@@ -10090,6 +10499,28 @@
|
|
10090 |
null;
|
10091 |
}
|
10092 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10093 |
/**
|
10094 |
* @author Vova Feldman (@svovaf)
|
10095 |
* @since 1.2.1.5
|
@@ -10134,7 +10565,7 @@
|
|
10134 |
function get_eula_url() {
|
10135 |
return $this->apply_filters(
|
10136 |
'eula_url',
|
10137 |
-
"https://freemius.com/
|
10138 |
);
|
10139 |
}
|
10140 |
|
@@ -10322,7 +10753,7 @@
|
|
10322 |
#endregion ------------------------------------------------------------------
|
10323 |
|
10324 |
/* Account
|
10325 |
-
|
10326 |
|
10327 |
/**
|
10328 |
* Find plugin's slug by plugin's basename.
|
@@ -10386,9 +10817,14 @@
|
|
10386 |
*/
|
10387 |
private static function get_all_sites(
|
10388 |
$module_type = WP_FS__MODULE_TYPE_PLUGIN,
|
10389 |
-
$blog_id = null
|
|
|
10390 |
) {
|
10391 |
-
$sites = self::get_account_option(
|
|
|
|
|
|
|
|
|
10392 |
|
10393 |
if ( ! is_array( $sites ) ) {
|
10394 |
$sites = array();
|
@@ -10748,10 +11184,20 @@
|
|
10748 |
*
|
10749 |
* @author Vova Feldman (@svovaf)
|
10750 |
* @since 1.0.1
|
|
|
|
|
|
|
10751 |
* @return bool
|
10752 |
*/
|
10753 |
-
function is_registered() {
|
10754 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10755 |
}
|
10756 |
|
10757 |
/**
|
@@ -10762,8 +11208,34 @@
|
|
10762 |
*
|
10763 |
* @return bool
|
10764 |
*/
|
10765 |
-
function is_tracking_allowed() {
|
10766 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10767 |
}
|
10768 |
|
10769 |
/**
|
@@ -10799,13 +11271,59 @@
|
|
10799 |
}
|
10800 |
|
10801 |
/**
|
10802 |
-
* @author Vova Feldman (@svovaf)
|
10803 |
-
* @since 1.0.3
|
10804 |
-
*
|
10805 |
-
* @return FS_Site
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10806 |
*/
|
10807 |
-
function
|
10808 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
10809 |
}
|
10810 |
|
10811 |
/**
|
@@ -12089,7 +12607,7 @@
|
|
12089 |
} else {
|
12090 |
$url = is_object( $site ) ?
|
12091 |
$site->siteurl :
|
12092 |
-
|
12093 |
|
12094 |
$disconnected_site_ids[] = $blog_id;
|
12095 |
}
|
@@ -12462,7 +12980,21 @@
|
|
12462 |
} else if ( $is_whitelabeled_flag ) {
|
12463 |
$is_whitelabeled = true;
|
12464 |
} else {
|
12465 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12466 |
$installed_addons = $this->get_installed_addons();
|
12467 |
foreach ( $installed_addons as $fs_addon ) {
|
12468 |
$addon_ids[] = $fs_addon->get_id();
|
@@ -12891,6 +13423,75 @@
|
|
12891 |
fs_require_template( 'forms/resend-key.php', $vars );
|
12892 |
}
|
12893 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12894 |
/**
|
12895 |
* Returns a collection of IDs of installs that are associated with the context product and its add-ons, and activated with foreign licenses.
|
12896 |
*
|
@@ -13098,10 +13699,15 @@
|
|
13098 |
( $is_network_admin && $this->is_network_active() && ! $this->is_network_delegated_connection() ) ||
|
13099 |
( ! $is_network_admin && ( ! $this->is_network_active() || $this->is_delegated_connection() ) )
|
13100 |
) {
|
13101 |
-
|
13102 |
-
|
13103 |
-
|
13104 |
-
|
|
|
|
|
|
|
|
|
|
|
13105 |
}
|
13106 |
}
|
13107 |
|
@@ -13273,7 +13879,7 @@
|
|
13273 |
self::shoot_ajax_failure();
|
13274 |
}
|
13275 |
|
13276 |
-
$site = $this->
|
13277 |
'',
|
13278 |
'put',
|
13279 |
array(
|
@@ -13326,7 +13932,8 @@
|
|
13326 |
fs_request_get( 'blog_id', null ),
|
13327 |
fs_request_get( 'module_id', null, 'post' ),
|
13328 |
fs_request_get( 'user_id', null ),
|
13329 |
-
fs_request_get_bool( 'is_extensions_tracking_allowed', null )
|
|
|
13330 |
);
|
13331 |
|
13332 |
if (
|
@@ -13571,6 +14178,9 @@
|
|
13571 |
* @param null|int $blog_id
|
13572 |
* @param null|number $plugin_id
|
13573 |
* @param null|number $license_owner_id
|
|
|
|
|
|
|
13574 |
*
|
13575 |
* @return array {
|
13576 |
* @var bool $success
|
@@ -13585,7 +14195,8 @@
|
|
13585 |
$blog_id = null,
|
13586 |
$plugin_id = null,
|
13587 |
$license_owner_id = null,
|
13588 |
-
$is_extensions_tracking_allowed = null
|
|
|
13589 |
) {
|
13590 |
$this->_logger->entrance();
|
13591 |
|
@@ -13605,7 +14216,10 @@
|
|
13605 |
$this :
|
13606 |
$this->get_addon_instance( $plugin_id );
|
13607 |
|
13608 |
-
$this->
|
|
|
|
|
|
|
13609 |
|
13610 |
$error = false;
|
13611 |
$next_page = false;
|
@@ -13770,8 +14384,8 @@
|
|
13770 |
}
|
13771 |
}
|
13772 |
|
13773 |
-
$all_sites
|
13774 |
-
$
|
13775 |
|
13776 |
/**
|
13777 |
* Check if there are any sites that are not connected, skipped, nor delegated. For every site that falls into that category, if the product is freemium, skip the connection. If the product is premium only, delegate the connection to the site administrator.
|
@@ -13801,14 +14415,14 @@
|
|
13801 |
continue;
|
13802 |
}
|
13803 |
|
13804 |
-
$
|
13805 |
}
|
13806 |
|
13807 |
-
if ( ! empty( $
|
13808 |
if ( $fs->is_freemium() && $fs->is_enable_anonymous() ) {
|
13809 |
-
$fs->skip_connection( $
|
13810 |
} else {
|
13811 |
-
$fs->delegate_connection( $
|
13812 |
}
|
13813 |
}
|
13814 |
}
|
@@ -13886,7 +14500,7 @@
|
|
13886 |
|
13887 |
$addon_info = $fs->_get_addon_info( $addon_id, $is_installed );
|
13888 |
|
13889 |
-
if ( ! $addon_info['is_connected'] ) {
|
13890 |
// Add-on is not associated with an install entity.
|
13891 |
continue;
|
13892 |
}
|
@@ -13944,11 +14558,11 @@
|
|
13944 |
$this->delegate_connection();
|
13945 |
} else {
|
13946 |
if ( ! empty( $sites_by_action['delegate'] ) ) {
|
13947 |
-
$this->delegate_connection( $sites_by_action['delegate'] );
|
13948 |
}
|
13949 |
|
13950 |
if ( ! empty( $sites_by_action['skip'] ) ) {
|
13951 |
-
$this->skip_connection( $sites_by_action['skip'] );
|
13952 |
}
|
13953 |
|
13954 |
if ( empty( $sites_by_action['allow'] ) ) {
|
@@ -14266,15 +14880,37 @@
|
|
14266 |
return $this->_plugin->has_affiliate_program();
|
14267 |
}
|
14268 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14269 |
/**
|
14270 |
* @author Leo Fajardo (@leorw)
|
14271 |
* @since 1.2.4
|
14272 |
*/
|
14273 |
private function fetch_affiliate_terms() {
|
14274 |
if ( ! is_object( $this->plugin_affiliate_terms ) ) {
|
14275 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
14276 |
$affiliate_terms = $plugins_api->get( '/aff.json?type=affiliation', false );
|
14277 |
|
|
|
|
|
|
|
14278 |
if ( ! $this->is_api_result_entity( $affiliate_terms ) ) {
|
14279 |
return;
|
14280 |
}
|
@@ -14292,8 +14928,10 @@
|
|
14292 |
$application_data = $this->_storage->affiliate_application_data;
|
14293 |
$flush = ( ! isset( $application_data['status'] ) || 'pending' === $application_data['status'] );
|
14294 |
|
|
|
|
|
14295 |
$users_api = $this->get_api_user_scope();
|
14296 |
-
$result = $users_api->get( "/plugins/{$
|
14297 |
if ( $this->is_api_result_object( $result, 'affiliates' ) ) {
|
14298 |
if ( ! empty( $result->affiliates ) ) {
|
14299 |
$affiliate = new FS_Affiliate( $result->affiliates[0] );
|
@@ -14393,15 +15031,17 @@
|
|
14393 |
var_export( $next_page, true )
|
14394 |
);
|
14395 |
} else if ( $this->is_pending_activation() ) {
|
14396 |
-
self::shoot_ajax_failure( $this->get_text_inline( 'Account is pending activation.', 'account-is-pending-activation' ) );
|
14397 |
}
|
14398 |
}
|
14399 |
|
14400 |
$this->fetch_affiliate_terms();
|
14401 |
|
|
|
|
|
14402 |
$api = $this->get_api_user_scope();
|
14403 |
$result = $api->call(
|
14404 |
-
( "/plugins/{$
|
14405 |
'post',
|
14406 |
$affiliate
|
14407 |
);
|
@@ -14863,6 +15503,16 @@
|
|
14863 |
return ( defined( 'DOING_CRON' ) && DOING_CRON );
|
14864 |
}
|
14865 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14866 |
/**
|
14867 |
* Check if a real user is visiting the admin dashboard.
|
14868 |
*
|
@@ -14876,7 +15526,7 @@
|
|
14876 |
is_admin() &&
|
14877 |
! self::is_ajax() &&
|
14878 |
! self::is_cron() &&
|
14879 |
-
|
14880 |
);
|
14881 |
}
|
14882 |
|
@@ -15028,20 +15678,20 @@
|
|
15028 |
* @author Leo Fajardo (@leorw)
|
15029 |
* @since 2.0.0
|
15030 |
*
|
15031 |
-
* @param
|
15032 |
*/
|
15033 |
-
private function delegate_connection( $
|
15034 |
$this->_logger->entrance();
|
15035 |
|
15036 |
$this->_admin_notices->remove_sticky( 'connect_account' );
|
15037 |
|
15038 |
-
if (
|
15039 |
// All sites delegation.
|
15040 |
-
$this->_storage->store( 'is_delegated_connection', true, true
|
15041 |
} else {
|
15042 |
// Specified sites delegation.
|
15043 |
-
foreach ( $
|
15044 |
-
$this->delegate_site_connection( $
|
15045 |
}
|
15046 |
}
|
15047 |
|
@@ -15057,7 +15707,7 @@
|
|
15057 |
* @param int $blog_id
|
15058 |
*/
|
15059 |
private function delegate_site_connection( $blog_id ) {
|
15060 |
-
$this->_storage->store( 'is_delegated_connection', true, $blog_id
|
15061 |
}
|
15062 |
|
15063 |
/**
|
@@ -15097,7 +15747,7 @@
|
|
15097 |
}
|
15098 |
|
15099 |
/**
|
15100 |
-
* Check if delegated the connection. When running within the
|
15101 |
* and haven't specified the blog ID, checks if network level delegated. If running
|
15102 |
* within a site admin or specified a blog ID, check if delegated the connection for
|
15103 |
* the current context site.
|
@@ -15157,12 +15807,17 @@
|
|
15157 |
}
|
15158 |
|
15159 |
/**
|
|
|
|
|
15160 |
* @author Leo Fajardo (@leorw)
|
15161 |
* @since 2.0.0
|
15162 |
*
|
|
|
|
|
|
|
15163 |
* @return array Active & public sites collection.
|
15164 |
*/
|
15165 |
-
static function get_sites() {
|
15166 |
if ( ! is_multisite() ) {
|
15167 |
return array();
|
15168 |
}
|
@@ -15184,27 +15839,11 @@
|
|
15184 |
'mature' => 0,
|
15185 |
'spam' => 0,
|
15186 |
'deleted' => 0,
|
|
|
|
|
15187 |
);
|
15188 |
|
15189 |
-
|
15190 |
-
// For WP 4.6 and above.
|
15191 |
-
return get_sites( $args );
|
15192 |
-
} else if ( function_exists( 'wp_' . 'get_sites' ) ) {
|
15193 |
-
// For WP 3.7 to WP 4.5.
|
15194 |
-
/**
|
15195 |
-
* This is a hack suggested previously proposed by the TRT. Our SDK is compliant with older WP versions and we'd like to keep it that way.
|
15196 |
-
*
|
15197 |
-
* @todo Remove this hack once this false-positive error is removed from the Theme Sniffer.
|
15198 |
-
*
|
15199 |
-
* @since 2.3.3
|
15200 |
-
* @author Vova Feldman (@svovaf)
|
15201 |
-
*/
|
15202 |
-
$fn = 'wp_' . 'get_sites';
|
15203 |
-
return $fn( $args );
|
15204 |
-
} else {
|
15205 |
-
// For WP 3.6 and below.
|
15206 |
-
return get_blog_list( 0, 'all' );
|
15207 |
-
}
|
15208 |
}
|
15209 |
|
15210 |
/**
|
@@ -15253,7 +15892,7 @@
|
|
15253 |
$address_to_blog_map = array();
|
15254 |
foreach ( $sites as $site ) {
|
15255 |
$blog_id = self::get_site_blog_id( $site );
|
15256 |
-
$address =
|
15257 |
$address_to_blog_map[ $address ] = $blog_id;
|
15258 |
}
|
15259 |
|
@@ -15289,6 +15928,42 @@
|
|
15289 |
return $install_map;
|
15290 |
}
|
15291 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15292 |
/**
|
15293 |
* Gets a map of module IDs that the given user has opted-in to.
|
15294 |
*
|
@@ -15373,11 +16048,16 @@
|
|
15373 |
*
|
15374 |
* @param int $blog_id
|
15375 |
* @param FS_Site $install
|
|
|
15376 |
*
|
15377 |
* @return bool Since 2.3.1 returns if a switch was made.
|
15378 |
*/
|
15379 |
-
function switch_to_blog( $blog_id, FS_Site $install = null ) {
|
15380 |
-
if ( ! is_numeric( $blog_id )
|
|
|
|
|
|
|
|
|
15381 |
return false;
|
15382 |
}
|
15383 |
|
@@ -15441,7 +16121,7 @@
|
|
15441 |
unset( $this->_site_api );
|
15442 |
unset( $this->_user_api );
|
15443 |
|
15444 |
-
return
|
15445 |
}
|
15446 |
|
15447 |
/**
|
@@ -15470,21 +16150,41 @@
|
|
15470 |
$site['blog_id'] );
|
15471 |
}
|
15472 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15473 |
/**
|
15474 |
* @author Leo Fajardo (@leorw)
|
15475 |
* @since 2.0.0
|
15476 |
*
|
15477 |
* @param array|WP_Site|null $site
|
|
|
15478 |
*
|
15479 |
* @return array
|
15480 |
*/
|
15481 |
-
function get_site_info( $site = null ) {
|
15482 |
$this->_logger->entrance();
|
15483 |
|
15484 |
$switched = false;
|
15485 |
|
|
|
|
|
15486 |
if ( is_null( $site ) ) {
|
15487 |
-
$url =
|
15488 |
$name = get_bloginfo( 'name' );
|
15489 |
$blog_id = null;
|
15490 |
} else {
|
@@ -15496,26 +16196,44 @@
|
|
15496 |
}
|
15497 |
|
15498 |
if ( $site instanceof WP_Site ) {
|
15499 |
-
$url
|
15500 |
-
$name
|
|
|
15501 |
} else {
|
15502 |
-
$url =
|
15503 |
$name = get_bloginfo( 'name' );
|
15504 |
}
|
15505 |
}
|
15506 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15507 |
$info = array(
|
15508 |
-
'uid'
|
15509 |
-
'url'
|
15510 |
-
'title' => $name,
|
15511 |
-
'language' => get_bloginfo( 'language' ),
|
15512 |
-
'charset' => get_bloginfo( 'charset' ),
|
15513 |
);
|
15514 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15515 |
if ( is_numeric( $blog_id ) ) {
|
15516 |
$info['blog_id'] = $blog_id;
|
15517 |
}
|
15518 |
|
|
|
|
|
|
|
|
|
15519 |
if ( $switched ) {
|
15520 |
restore_current_blog();
|
15521 |
}
|
@@ -15738,6 +16456,10 @@
|
|
15738 |
}
|
15739 |
}
|
15740 |
|
|
|
|
|
|
|
|
|
15741 |
if ( $this->is_sync_cron_scheduled() &&
|
15742 |
$context_blog_id == $this->get_sync_cron_blog_id()
|
15743 |
) {
|
@@ -15771,6 +16493,10 @@
|
|
15771 |
|
15772 |
$this->update_multisite_data_after_site_deactivation( $context_blog_id );
|
15773 |
|
|
|
|
|
|
|
|
|
15774 |
$current_blog_id = get_current_blog_id();
|
15775 |
|
15776 |
$this->switch_to_blog( $context_blog_id );
|
@@ -15804,6 +16530,10 @@
|
|
15804 |
|
15805 |
$this->update_multisite_data_after_site_deactivation( $context_blog_id );
|
15806 |
|
|
|
|
|
|
|
|
|
15807 |
$current_blog_id = get_current_blog_id();
|
15808 |
|
15809 |
$this->switch_to_blog( $context_blog_id );
|
@@ -15821,6 +16551,20 @@
|
|
15821 |
$this->switch_to_blog( $current_blog_id );
|
15822 |
}
|
15823 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15824 |
/**
|
15825 |
* Executed after site re-activation.
|
15826 |
*
|
@@ -15935,9 +16679,17 @@
|
|
15935 |
* @return bool
|
15936 |
*/
|
15937 |
function is_product_settings_page() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15938 |
return fs_starts_with(
|
15939 |
-
|
15940 |
-
$
|
|
|
15941 |
);
|
15942 |
}
|
15943 |
|
@@ -16017,10 +16769,11 @@
|
|
16017 |
*
|
16018 |
* @param bool|string $topic
|
16019 |
* @param bool|string $message
|
|
|
16020 |
*
|
16021 |
* @return string
|
16022 |
*/
|
16023 |
-
function contact_url( $topic = false, $message = false ) {
|
16024 |
$params = array();
|
16025 |
if ( is_string( $topic ) ) {
|
16026 |
$params['topic'] = $topic;
|
@@ -16029,6 +16782,10 @@
|
|
16029 |
$params['message'] = $message;
|
16030 |
}
|
16031 |
|
|
|
|
|
|
|
|
|
16032 |
if ( $this->is_addon() ) {
|
16033 |
$params['addon_id'] = $this->get_id();
|
16034 |
|
@@ -16067,7 +16824,7 @@
|
|
16067 |
}
|
16068 |
|
16069 |
/* Logger
|
16070 |
-
|
16071 |
/**
|
16072 |
* @param string $id
|
16073 |
* @param bool $prefix_slug
|
@@ -16092,7 +16849,7 @@
|
|
16092 |
}
|
16093 |
|
16094 |
/* Security
|
16095 |
-
|
16096 |
private static function _encrypt( $str ) {
|
16097 |
if ( is_null( $str ) ) {
|
16098 |
return null;
|
@@ -16312,20 +17069,6 @@
|
|
16312 |
) {
|
16313 |
// Load site.
|
16314 |
$this->_site = $site;
|
16315 |
-
|
16316 |
-
// Load plans.
|
16317 |
-
$this->_plans = $plans[ $this->_slug ];
|
16318 |
-
if ( ! is_array( $this->_plans ) || empty( $this->_plans ) ) {
|
16319 |
-
$this->_sync_plans();
|
16320 |
-
} else {
|
16321 |
-
for ( $i = 0, $len = count( $this->_plans ); $i < $len; $i ++ ) {
|
16322 |
-
if ( $this->_plans[ $i ] instanceof FS_Plugin_Plan ) {
|
16323 |
-
$this->_plans[ $i ] = self::decrypt_entity( $this->_plans[ $i ] );
|
16324 |
-
} else {
|
16325 |
-
unset( $this->_plans[ $i ] );
|
16326 |
-
}
|
16327 |
-
}
|
16328 |
-
}
|
16329 |
}
|
16330 |
|
16331 |
$user = null;
|
@@ -16354,7 +17097,30 @@
|
|
16354 |
/**
|
16355 |
* This is a special fault tolerance mechanism to handle a scenario that the user data is missing.
|
16356 |
*/
|
16357 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16358 |
}
|
16359 |
|
16360 |
$this->_user = ( $user instanceof FS_User ) ?
|
@@ -16368,6 +17134,23 @@
|
|
16368 |
}
|
16369 |
|
16370 |
if ( is_object( $this->_site ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16371 |
$this->_license = $this->_get_license_by_id( $this->_site->license_id );
|
16372 |
|
16373 |
if ( $this->_site->version != $this->get_plugin_version() ) {
|
@@ -16386,6 +17169,15 @@
|
|
16386 |
if ( $this->is_theme() ) {
|
16387 |
$this->_register_account_hooks();
|
16388 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16389 |
}
|
16390 |
|
16391 |
/**
|
@@ -16465,17 +17257,129 @@
|
|
16465 |
*/
|
16466 |
private function get_versions() {
|
16467 |
$versions = array();
|
16468 |
-
$versions['
|
16469 |
-
|
16470 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16471 |
|
16472 |
-
|
16473 |
-
|
16474 |
-
|
16475 |
-
}
|
16476 |
}
|
16477 |
|
16478 |
-
return $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16479 |
}
|
16480 |
|
16481 |
/**
|
@@ -16530,23 +17434,22 @@
|
|
16530 |
$versions = $this->get_versions();
|
16531 |
|
16532 |
$params = array_merge( $versions, array(
|
16533 |
-
'user_firstname'
|
16534 |
-
'user_lastname'
|
16535 |
-
'
|
16536 |
-
'
|
16537 |
-
'
|
16538 |
-
'
|
16539 |
-
'
|
16540 |
-
'
|
16541 |
-
'
|
16542 |
-
'return_url' => fs_nonce_url( $return_url, $activation_action ),
|
16543 |
-
'account_url' => fs_nonce_url( $this->_get_admin_page_url(
|
16544 |
'account',
|
16545 |
array( 'fs_action' => 'sync_user' )
|
16546 |
), 'sync_user' ),
|
16547 |
-
'is_premium'
|
16548 |
-
'is_active'
|
16549 |
-
'is_uninstalled'
|
|
|
16550 |
) );
|
16551 |
|
16552 |
if ( $this->is_addon() ) {
|
@@ -16567,12 +17470,17 @@
|
|
16567 |
|
16568 |
$site = $this->get_site_info( $site );
|
16569 |
|
16570 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16571 |
'site_uid' => $site['uid'],
|
16572 |
'site_url' => $site['url'],
|
16573 |
-
'site_name' => $site['title'],
|
16574 |
-
'language' => $site['language'],
|
16575 |
-
'charset' => $site['charset'],
|
16576 |
) );
|
16577 |
}
|
16578 |
|
@@ -16597,6 +17505,10 @@
|
|
16597 |
);
|
16598 |
}
|
16599 |
|
|
|
|
|
|
|
|
|
16600 |
return array_merge( $params, $override_with );
|
16601 |
}
|
16602 |
|
@@ -16615,9 +17527,10 @@
|
|
16615 |
* In this case, the user and site info will be sent to the server but no
|
16616 |
* data will be saved to the WP installation's database.
|
16617 |
* @param number|bool $trial_plan_id
|
16618 |
-
* @param bool $is_disconnected Whether
|
16619 |
* @param null|bool $is_marketing_allowed
|
16620 |
* @param array $sites If network-level opt-in, an array of containing details of sites.
|
|
|
16621 |
*
|
16622 |
* @return string|object
|
16623 |
* @use WP_Error
|
@@ -16631,7 +17544,8 @@
|
|
16631 |
$trial_plan_id = false,
|
16632 |
$is_disconnected = false,
|
16633 |
$is_marketing_allowed = null,
|
16634 |
-
$sites = array()
|
|
|
16635 |
) {
|
16636 |
$this->_logger->entrance();
|
16637 |
|
@@ -16655,7 +17569,7 @@
|
|
16655 |
$fs_user,
|
16656 |
false,
|
16657 |
$trial_plan_id,
|
16658 |
-
|
16659 |
true,
|
16660 |
$sites
|
16661 |
);
|
@@ -16723,13 +17637,15 @@
|
|
16723 |
$params['is_marketing_allowed'] = $is_marketing_allowed;
|
16724 |
}
|
16725 |
|
16726 |
-
$params['is_disconnected']
|
16727 |
-
$params['format']
|
|
|
|
|
16728 |
|
16729 |
$request = array(
|
16730 |
'method' => 'POST',
|
16731 |
'body' => $params,
|
16732 |
-
'timeout' =>
|
16733 |
);
|
16734 |
|
16735 |
$url = $this->add_show_pending( WP_FS__ADDRESS . '/action/service/user/install/' );
|
@@ -16815,7 +17731,8 @@
|
|
16815 |
true ),
|
16816 |
false,
|
16817 |
$filtered_license_key,
|
16818 |
-
! empty( $params['trial_plan_id'] )
|
|
|
16819 |
);
|
16820 |
} else if ( isset( $decoded->install_secret_key ) ) {
|
16821 |
return $this->install_with_new_user(
|
@@ -16828,6 +17745,9 @@
|
|
16828 |
( isset( $decoded->is_extensions_tracking_allowed ) && ! is_null( $decoded->is_extensions_tracking_allowed ) ?
|
16829 |
$decoded->is_extensions_tracking_allowed :
|
16830 |
null ),
|
|
|
|
|
|
|
16831 |
$decoded->install_id,
|
16832 |
$decoded->install_public_key,
|
16833 |
$decoded->install_secret_key,
|
@@ -16844,6 +17764,9 @@
|
|
16844 |
( isset( $decoded->is_extensions_tracking_allowed ) && ! is_null( $decoded->is_extensions_tracking_allowed ) ?
|
16845 |
$decoded->is_extensions_tracking_allowed :
|
16846 |
null ),
|
|
|
|
|
|
|
16847 |
$decoded->installs,
|
16848 |
false
|
16849 |
);
|
@@ -16941,15 +17864,11 @@
|
|
16941 |
$this->_admin_notices->remove_sticky( 'connect_account' );
|
16942 |
|
16943 |
if ( $this->is_pending_activation() || ! $this->has_settings_menu() ) {
|
16944 |
-
|
16945 |
-
$this->_admin_notices->remove_sticky( 'activation_pending' );
|
16946 |
-
|
16947 |
-
// Remove plugin from pending activation mode.
|
16948 |
-
unset( $this->_storage->is_pending_activation );
|
16949 |
|
16950 |
if ( ! $this->is_paying_or_trial() ) {
|
16951 |
$this->_admin_notices->add_sticky(
|
16952 |
-
sprintf( $this->get_text_inline( '%s
|
16953 |
'activation_complete'
|
16954 |
);
|
16955 |
}
|
@@ -17071,6 +17990,7 @@
|
|
17071 |
fs_request_get( 'user_secret_key' ),
|
17072 |
fs_request_get_bool( 'is_marketing_allowed', null ),
|
17073 |
fs_request_get_bool( 'is_extensions_tracking_allowed', null ),
|
|
|
17074 |
$pending_sites_info['blog_ids'],
|
17075 |
$pending_sites_info['license_key'],
|
17076 |
$pending_sites_info['trial_plan_id']
|
@@ -17082,6 +18002,7 @@
|
|
17082 |
fs_request_get( 'user_secret_key' ),
|
17083 |
fs_request_get_bool( 'is_marketing_allowed', null ),
|
17084 |
fs_request_get_bool( 'is_extensions_tracking_allowed', null ),
|
|
|
17085 |
fs_request_get( 'install_id' ),
|
17086 |
fs_request_get( 'install_public_key' ),
|
17087 |
fs_request_get( 'install_secret_key' ),
|
@@ -17090,7 +18011,13 @@
|
|
17090 |
);
|
17091 |
}
|
17092 |
} else if ( fs_request_has( 'pending_activation' ) ) {
|
17093 |
-
$this->set_pending_confirmation(
|
|
|
|
|
|
|
|
|
|
|
|
|
17094 |
}
|
17095 |
}
|
17096 |
}
|
@@ -17138,6 +18065,7 @@
|
|
17138 |
* @param string $user_secret_key
|
17139 |
* @param bool|null $is_marketing_allowed
|
17140 |
* @param bool|null $is_extensions_tracking_allowed Since 2.3.2
|
|
|
17141 |
* @param number $install_id
|
17142 |
* @param string $install_public_key
|
17143 |
* @param string $install_secret_key
|
@@ -17152,6 +18080,7 @@
|
|
17152 |
$user_secret_key,
|
17153 |
$is_marketing_allowed,
|
17154 |
$is_extensions_tracking_allowed,
|
|
|
17155 |
$install_id,
|
17156 |
$install_public_key,
|
17157 |
$install_secret_key,
|
@@ -17185,7 +18114,7 @@
|
|
17185 |
$site->secret_key = $install_secret_key;
|
17186 |
|
17187 |
$this->_site = $site;
|
17188 |
-
$site_result = $this->get_api_site_scope()->get();
|
17189 |
$site = new FS_Site( $site_result );
|
17190 |
$this->_site = $site;
|
17191 |
|
@@ -17193,7 +18122,10 @@
|
|
17193 |
$this->disable_opt_in_notice_and_lock_user();
|
17194 |
}
|
17195 |
|
17196 |
-
$this->
|
|
|
|
|
|
|
17197 |
|
17198 |
return $this->setup_account(
|
17199 |
$this->_user,
|
@@ -17214,6 +18146,7 @@
|
|
17214 |
* @param string $user_secret_key
|
17215 |
* @param bool|null $is_marketing_allowed
|
17216 |
* @param bool|null $is_extensions_tracking_allowed Since 2.3.2
|
|
|
17217 |
* @param array $site_ids
|
17218 |
* @param bool $license_key
|
17219 |
* @param bool $trial_plan_id
|
@@ -17227,6 +18160,7 @@
|
|
17227 |
$user_secret_key,
|
17228 |
$is_marketing_allowed,
|
17229 |
$is_extensions_tracking_allowed,
|
|
|
17230 |
$site_ids,
|
17231 |
$license_key = false,
|
17232 |
$trial_plan_id = false,
|
@@ -17238,7 +18172,10 @@
|
|
17238 |
$this->disable_opt_in_notice_and_lock_user();
|
17239 |
}
|
17240 |
|
17241 |
-
$this->
|
|
|
|
|
|
|
17242 |
|
17243 |
$sites = array();
|
17244 |
foreach ( $site_ids as $site_id ) {
|
@@ -17259,6 +18196,7 @@
|
|
17259 |
* @param string $user_secret_key
|
17260 |
* @param bool|null $is_marketing_allowed
|
17261 |
* @param bool|null $is_extensions_tracking_allowed Since 2.3.2
|
|
|
17262 |
* @param object[] $installs
|
17263 |
* @param bool $redirect
|
17264 |
* @param bool $auto_install Since 1.2.1.7 If `true` and setting up an account with a valid license, will redirect (or return a URL) to the account page with a special parameter to trigger the auto installation processes.
|
@@ -17271,6 +18209,7 @@
|
|
17271 |
$user_secret_key,
|
17272 |
$is_marketing_allowed,
|
17273 |
$is_extensions_tracking_allowed,
|
|
|
17274 |
array $installs,
|
17275 |
$redirect = true,
|
17276 |
$auto_install = false
|
@@ -17281,7 +18220,10 @@
|
|
17281 |
$this->disable_opt_in_notice_and_lock_user();
|
17282 |
}
|
17283 |
|
17284 |
-
$this->
|
|
|
|
|
|
|
17285 |
|
17286 |
$install_ids = array();
|
17287 |
|
@@ -17289,12 +18231,13 @@
|
|
17289 |
$install_ids[] = $install->id;
|
17290 |
}
|
17291 |
|
17292 |
-
$
|
17293 |
-
$
|
|
|
17294 |
|
17295 |
$installs = array();
|
17296 |
while ( $left > 0 ) {
|
17297 |
-
$result = $this->get_api_user_scope()->get( "/plugins/{$this->_module_id}/installs.json?ids=" . implode( ',', array_slice( $install_ids, $offset,
|
17298 |
|
17299 |
if ( ! $this->is_api_result_object( $result, 'installs' ) ) {
|
17300 |
// @todo Handle API error.
|
@@ -17302,7 +18245,8 @@
|
|
17302 |
|
17303 |
$installs = array_merge( $installs, $result->installs );
|
17304 |
|
17305 |
-
$left
|
|
|
17306 |
}
|
17307 |
|
17308 |
foreach ( $installs as &$install ) {
|
@@ -17332,7 +18276,8 @@
|
|
17332 |
$email = false,
|
17333 |
$redirect = true,
|
17334 |
$license_key = false,
|
17335 |
-
$is_pending_trial = false
|
|
|
17336 |
) {
|
17337 |
if ( $this->_ignore_pending_mode ) {
|
17338 |
/**
|
@@ -17342,12 +18287,12 @@
|
|
17342 |
* @author Vova Feldman
|
17343 |
* @since 1.2.1.6
|
17344 |
*/
|
17345 |
-
$this->skip_connection(
|
17346 |
} else {
|
17347 |
// Install must be activated via email since
|
17348 |
// user with the same email already exist.
|
17349 |
$this->_storage->is_pending_activation = true;
|
17350 |
-
$this->_add_pending_activation_notice( $email, $is_pending_trial );
|
17351 |
}
|
17352 |
|
17353 |
if ( ! empty( $license_key ) ) {
|
@@ -17362,8 +18307,8 @@
|
|
17362 |
|
17363 |
$next_page = $this->get_after_activation_url( 'after_pending_connect_url' );
|
17364 |
|
17365 |
-
// Reload the page with with pending activation message.
|
17366 |
if ( $redirect ) {
|
|
|
17367 |
fs_redirect( $next_page );
|
17368 |
}
|
17369 |
|
@@ -17392,7 +18337,10 @@
|
|
17392 |
*/
|
17393 |
$license_key = fs_request_get( 'license_secret_key' );
|
17394 |
|
17395 |
-
$this->
|
|
|
|
|
|
|
17396 |
|
17397 |
$this->install_with_current_user( $license_key );
|
17398 |
}
|
@@ -17410,7 +18358,7 @@
|
|
17410 |
*
|
17411 |
* @return object|string If redirect is `false`, returns the next page the user should be redirected to, or the API error object if failed to install.
|
17412 |
*/
|
17413 |
-
|
17414 |
$license_key = false,
|
17415 |
$trial_plan_id = false,
|
17416 |
$sites = array(),
|
@@ -17793,9 +18741,6 @@
|
|
17793 |
$this->send_installs_update();
|
17794 |
}
|
17795 |
|
17796 |
-
// Switch install context back to the first install.
|
17797 |
-
$this->_site = $first_install;
|
17798 |
-
|
17799 |
$current_blog = get_current_blog_id();
|
17800 |
|
17801 |
foreach ( $blog_2_install_map as $blog_id => $install ) {
|
@@ -17804,7 +18749,12 @@
|
|
17804 |
$this->do_action( 'after_account_connection', $this->_user, $install );
|
17805 |
}
|
17806 |
|
17807 |
-
|
|
|
|
|
|
|
|
|
|
|
17808 |
|
17809 |
$this->do_action( 'after_network_account_connection', $this->_user, $blog_2_install_map );
|
17810 |
}
|
@@ -17852,9 +18802,7 @@
|
|
17852 |
$parent_fs->_admin_notices->remove_sticky( 'connect_account' );
|
17853 |
|
17854 |
if ( $parent_fs->is_pending_activation() ) {
|
17855 |
-
$parent_fs->
|
17856 |
-
|
17857 |
-
unset( $parent_fs->_storage->is_pending_activation );
|
17858 |
}
|
17859 |
|
17860 |
// Get user information based on parent's plugin.
|
@@ -17908,6 +18856,10 @@
|
|
17908 |
// return;
|
17909 |
// }
|
17910 |
|
|
|
|
|
|
|
|
|
17911 |
/**
|
17912 |
* When running from a site admin with a network activated module and the connection
|
17913 |
* was NOT delegated and the user still haven't skipped or opted-in, then hide the
|
@@ -18023,7 +18975,7 @@
|
|
18023 |
if ( ! $this->has_settings_menu() ) {
|
18024 |
// Add the opt-in page without a menu item.
|
18025 |
$hook = FS_Admin_Menu_Manager::add_subpage(
|
18026 |
-
|
18027 |
$this->get_plugin_name(),
|
18028 |
$this->get_plugin_name(),
|
18029 |
'manage_options',
|
@@ -18455,7 +19407,7 @@
|
|
18455 |
$hook = FS_Admin_Menu_Manager::add_subpage(
|
18456 |
$item['show_submenu'] ?
|
18457 |
$top_level_menu_slug :
|
18458 |
-
|
18459 |
$item['page_title'],
|
18460 |
$menu_item,
|
18461 |
$capability,
|
@@ -18470,7 +19422,7 @@
|
|
18470 |
FS_Admin_Menu_Manager::add_subpage(
|
18471 |
$item['show_submenu'] ?
|
18472 |
$top_level_menu_slug :
|
18473 |
-
|
18474 |
$item['page_title'],
|
18475 |
$menu_item,
|
18476 |
$capability,
|
@@ -18862,7 +19814,7 @@
|
|
18862 |
*
|
18863 |
* @return string
|
18864 |
*/
|
18865 |
-
|
18866 |
$action = "fs_{$tag}";
|
18867 |
|
18868 |
if ( ! empty( $module_id ) ) {
|
@@ -18885,10 +19837,10 @@
|
|
18885 |
* @uses do_action()
|
18886 |
*/
|
18887 |
function do_action( $tag, $arg = '' ) {
|
18888 |
-
$this->_logger->entrance( $tag );
|
18889 |
-
|
18890 |
$args = func_get_args();
|
18891 |
|
|
|
|
|
18892 |
call_user_func_array( 'do_action', array_merge(
|
18893 |
array( $this->get_action_tag( $tag ) ),
|
18894 |
array_slice( $args, 1 ) )
|
@@ -19028,6 +19980,30 @@
|
|
19028 |
wp_send_json( $result );
|
19029 |
}
|
19030 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19031 |
/**
|
19032 |
* Apply filter, specific for the current context plugin.
|
19033 |
*
|
@@ -19042,9 +20018,10 @@
|
|
19042 |
* @uses apply_filters()
|
19043 |
*/
|
19044 |
function apply_filters( $tag, $value ) {
|
|
|
|
|
19045 |
$this->_logger->entrance( $tag );
|
19046 |
|
19047 |
-
$args = func_get_args();
|
19048 |
array_unshift( $args, $this->get_unique_affix() );
|
19049 |
|
19050 |
return call_user_func_array( 'fs_apply_filter', $args );
|
@@ -19105,7 +20082,7 @@
|
|
19105 |
}
|
19106 |
|
19107 |
/* Account Page
|
19108 |
-
|
19109 |
/**
|
19110 |
* Update site information.
|
19111 |
*
|
@@ -19116,7 +20093,7 @@
|
|
19116 |
* @param null|int $network_level_or_blog_id Since 2.0.0
|
19117 |
* @param \FS_Site $site Since 2.0.0
|
19118 |
*/
|
19119 |
-
private function _store_site( $store = true, $network_level_or_blog_id = null, FS_Site $site = null ) {
|
19120 |
$this->_logger->entrance();
|
19121 |
|
19122 |
if ( is_null( $site ) ) {
|
@@ -19131,9 +20108,12 @@
|
|
19131 |
|
19132 |
$site_clone = clone $site;
|
19133 |
|
19134 |
-
$sites = self::get_all_sites( $this->_module_type, $network_level_or_blog_id );
|
19135 |
|
19136 |
-
if (
|
|
|
|
|
|
|
19137 |
$this->sync_user_by_current_install( $site->user_id );
|
19138 |
|
19139 |
$prev_stored_user_id = $this->_storage->get( 'prev_user_id', false, $network_level_or_blog_id );
|
@@ -19158,7 +20138,26 @@
|
|
19158 |
|
19159 |
$sites[ $this->_slug ] = $site_clone;
|
19160 |
|
19161 |
-
$this->set_account_option(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19162 |
}
|
19163 |
|
19164 |
/**
|
@@ -20399,10 +21398,10 @@
|
|
20399 |
$this->switch_to_blog( $current_blog_id );
|
20400 |
}
|
20401 |
|
20402 |
-
$result = $this->send_install_update( array(), true );
|
20403 |
$is_valid = $this->is_api_result_entity( $result );
|
20404 |
} else {
|
20405 |
-
$result = $this->send_installs_update( array(), true );
|
20406 |
$is_valid = $this->is_api_result_object( $result, 'installs' );
|
20407 |
}
|
20408 |
|
@@ -20412,7 +21411,7 @@
|
|
20412 |
$this->switch_to_blog( $this->_storage->network_install_blog_id );
|
20413 |
}
|
20414 |
|
20415 |
-
// Show API
|
20416 |
if ( ! $background || $this->is_paying() ) {
|
20417 |
// Try to ping API to see if not blocked.
|
20418 |
if ( ! FS_Api::test() ) {
|
@@ -20422,25 +21421,49 @@
|
|
20422 |
* @author Vova Feldman (@svovaf)
|
20423 |
* @since 1.1.6 Only show message related to one of the Freemius powered plugins. Once it will be resolved it will fix the issue for all plugins anyways. There's no point to scare users with multiple error messages.
|
20424 |
*/
|
20425 |
-
$api = $this->get_api_site_scope();
|
20426 |
|
20427 |
if ( ! self::$_global_admin_notices->has_sticky( 'api_blocked' ) ) {
|
20428 |
-
|
20429 |
-
|
20430 |
-
|
20431 |
-
|
20432 |
-
|
20433 |
-
|
20434 |
-
|
20435 |
-
|
20436 |
-
|
20437 |
-
|
20438 |
-
|
20439 |
-
|
20440 |
-
|
20441 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20442 |
}
|
20443 |
-
} else {
|
20444 |
// Authentication params are broken.
|
20445 |
$this->_admin_notices->add(
|
20446 |
$this->get_text_inline( 'It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again.', 'wrong-authentication-param-message' ) . '<br> ' . $this->get_text_inline( 'Error received from the server:', 'server-error-message' ) . var_export( $result->error, true ),
|
@@ -20454,6 +21477,9 @@
|
|
20454 |
return;
|
20455 |
}
|
20456 |
|
|
|
|
|
|
|
20457 |
if ( $is_site_level_sync ) {
|
20458 |
$site = new FS_Site( $result );
|
20459 |
} else {
|
@@ -20645,7 +21671,7 @@
|
|
20645 |
}
|
20646 |
|
20647 |
if ( ! $this->is_addon() &&
|
20648 |
-
$this->_site->is_beta() !== $site->is_beta
|
20649 |
) {
|
20650 |
// Beta flag updated.
|
20651 |
$this->_site = $site;
|
@@ -21200,8 +22226,7 @@
|
|
21200 |
if ( ! $this->is_api_result_entity( $plan ) ) {
|
21201 |
// Some API error while trying to start the trial.
|
21202 |
$this->_admin_notices->add(
|
21203 |
-
|
21204 |
-
. ' ' . var_export( $plan, true ),
|
21205 |
$oops_text,
|
21206 |
'error'
|
21207 |
);
|
@@ -21379,13 +22404,18 @@
|
|
21379 |
) {
|
21380 |
$this->_logger->entrance();
|
21381 |
|
|
|
|
|
|
|
|
|
21382 |
$switch_to_blog_id = null;
|
21383 |
|
21384 |
/**
|
21385 |
* @since 1.1.7.3 Check for plugin updates from Freemius only if opted-in.
|
21386 |
* @since 1.1.7.4 Also check updates for add-ons.
|
21387 |
*/
|
21388 |
-
if (
|
|
|
21389 |
! $this->_is_addon_id( $addon_id )
|
21390 |
) {
|
21391 |
if ( ! is_multisite() ) {
|
@@ -21395,6 +22425,10 @@
|
|
21395 |
$installs_map = $this->get_blog_install_map();
|
21396 |
|
21397 |
foreach ( $installs_map as $blog_id => $install ) {
|
|
|
|
|
|
|
|
|
21398 |
/**
|
21399 |
* @var FS_Site $install
|
21400 |
*/
|
@@ -21491,9 +22525,11 @@
|
|
21491 |
private function get_latest_download_api_url( $plugin_id = false ) {
|
21492 |
$this->_logger->entrance();
|
21493 |
|
21494 |
-
|
21495 |
$this->_get_latest_version_endpoint( $plugin_id, 'zip' )
|
21496 |
);
|
|
|
|
|
21497 |
}
|
21498 |
|
21499 |
/**
|
@@ -21688,7 +22724,6 @@
|
|
21688 |
private function update_email( $new_email ) {
|
21689 |
$this->_logger->entrance();
|
21690 |
|
21691 |
-
|
21692 |
$api = $this->get_api_user_scope();
|
21693 |
$user = $api->call( "?plugin_id={$this->_plugin->id}&fields=id,email,is_verified", 'put', array(
|
21694 |
'email' => $new_email,
|
@@ -21704,7 +22739,6 @@
|
|
21704 |
$this->_store_user();
|
21705 |
} else {
|
21706 |
// handle different error cases.
|
21707 |
-
|
21708 |
}
|
21709 |
|
21710 |
return $user;
|
@@ -21780,15 +22814,32 @@
|
|
21780 |
* @uses FS_Api
|
21781 |
*
|
21782 |
* @param string $candidate_email
|
|
|
21783 |
*
|
21784 |
* @return bool Is ownership change successfully initiated.
|
21785 |
*/
|
21786 |
-
private function init_change_owner( $candidate_email ) {
|
21787 |
$this->_logger->entrance();
|
21788 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21789 |
$api = $this->get_api_site_scope();
|
21790 |
$result = $api->call( "/users/{$this->_user->id}.json", 'put', array(
|
21791 |
'email' => $candidate_email,
|
|
|
|
|
21792 |
'after_confirm_url' => $this->_get_admin_page_url(
|
21793 |
'account',
|
21794 |
array( 'fs_action' => 'change_owner' )
|
@@ -21810,28 +22861,113 @@
|
|
21810 |
private function complete_change_owner() {
|
21811 |
$this->_logger->entrance();
|
21812 |
|
21813 |
-
$
|
21814 |
-
|
21815 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21816 |
|
21817 |
-
$
|
21818 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21819 |
|
21820 |
// Validate install's user and given user.
|
21821 |
if ( $user->id != $this->_site->user_id ) {
|
|
|
|
|
21822 |
return false;
|
21823 |
}
|
21824 |
|
21825 |
-
$
|
21826 |
-
$user->secret_key = fs_request_get( 'user_secret_key' );
|
21827 |
|
21828 |
// Fetch new user information.
|
21829 |
-
$this->_user = $user;
|
21830 |
$user_result = $this->get_api_user_scope( true )->get();
|
21831 |
$user = new FS_User( $user_result );
|
21832 |
$this->_user = $user;
|
21833 |
|
21834 |
-
$this->_set_account( $user, $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21835 |
|
21836 |
return true;
|
21837 |
}
|
@@ -22076,26 +23212,23 @@
|
|
22076 |
|
22077 |
if ( $is_parent_plugin_action ) {
|
22078 |
if ( $is_network_action && ! empty( $blog_id ) ) {
|
22079 |
-
if ( $this->is_registered() ) {
|
22080 |
-
if ( $this->is_tracking_prohibited() ) {
|
22081 |
-
if ( $this->
|
22082 |
$this->_admin_notices->add(
|
22083 |
-
sprintf( $this->get_text_inline( '
|
22084 |
$this->get_text_inline( 'Thank you!', 'thank-you' )
|
22085 |
);
|
22086 |
}
|
22087 |
} else {
|
22088 |
-
if ( $this->
|
|
|
|
|
22089 |
$this->_admin_notices->add(
|
22090 |
sprintf(
|
22091 |
-
$this->get_text_inline( '
|
22092 |
-
$
|
22093 |
-
|
22094 |
-
sprintf(
|
22095 |
-
'<a href="%s" target="_blank" rel="noopener">%s</a>',
|
22096 |
-
'https://freemius.com',
|
22097 |
-
'freemius.com'
|
22098 |
-
)
|
22099 |
)
|
22100 |
);
|
22101 |
}
|
@@ -22243,10 +23376,15 @@
|
|
22243 |
$state = fs_request_get( 'state', 'init' );
|
22244 |
switch ( $state ) {
|
22245 |
case 'init':
|
22246 |
-
$candidate_email = fs_request_get( 'candidate_email'
|
|
|
22247 |
|
22248 |
-
if ( $this->init_change_owner( $candidate_email ) ) {
|
22249 |
-
|
|
|
|
|
|
|
|
|
22250 |
}
|
22251 |
break;
|
22252 |
case 'owner_confirmed':
|
@@ -22269,37 +23407,6 @@
|
|
22269 |
|
22270 |
return;
|
22271 |
|
22272 |
-
case 'update_email':
|
22273 |
-
check_admin_referer( 'update_email' );
|
22274 |
-
|
22275 |
-
$new_email = fs_request_get( 'fs_email_' . $this->get_unique_affix(), '' );
|
22276 |
-
$result = $this->update_email( $new_email );
|
22277 |
-
|
22278 |
-
if ( isset( $result->error ) ) {
|
22279 |
-
switch ( $result->error->code ) {
|
22280 |
-
case 'user_exist':
|
22281 |
-
$this->_admin_notices->add(
|
22282 |
-
$this->get_text_inline( 'Sorry, we could not complete the email update. Another user with the same email is already registered.', 'user-exist-message' ) . ' ' .
|
22283 |
-
sprintf( $this->get_text_inline( 'If you would like to give up the ownership of the %s\'s account to %s click the Change Ownership button.', 'user-exist-message_ownership' ), $this->_module_type, '<b>' . $new_email . '</b>' ) .
|
22284 |
-
sprintf(
|
22285 |
-
'<a style="margin-left: 10px;" href="%s"><button class="button button-primary">%s ➜</button></a>',
|
22286 |
-
$this->get_account_url( 'change_owner', array(
|
22287 |
-
'state' => 'init',
|
22288 |
-
'candidate_email' => $new_email
|
22289 |
-
) ),
|
22290 |
-
$this->get_text_inline( 'Change Ownership', 'change-ownership' )
|
22291 |
-
),
|
22292 |
-
$oops_text,
|
22293 |
-
'error'
|
22294 |
-
);
|
22295 |
-
break;
|
22296 |
-
}
|
22297 |
-
} else {
|
22298 |
-
$this->_admin_notices->add( $this->get_text_inline( 'Your email was successfully updated. You should receive an email with confirmation instructions in few moments.', 'email-updated-message' ) );
|
22299 |
-
}
|
22300 |
-
|
22301 |
-
return;
|
22302 |
-
|
22303 |
case 'update_user_name':
|
22304 |
check_admin_referer( 'update_user_name' );
|
22305 |
|
@@ -22461,7 +23568,26 @@
|
|
22461 |
|
22462 |
fs_enqueue_local_style( 'fs_affiliation', '/admin/affiliation.css' );
|
22463 |
|
22464 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22465 |
echo $this->apply_filters( "/forms/affiliation.php", fs_get_template( '/forms/affiliation.php', $vars ) );
|
22466 |
}
|
22467 |
|
@@ -22562,7 +23688,7 @@
|
|
22562 |
}
|
22563 |
|
22564 |
/* Pricing & Upgrade
|
22565 |
-
|
22566 |
/**
|
22567 |
* Render pricing page.
|
22568 |
*
|
@@ -22704,7 +23830,17 @@
|
|
22704 |
}
|
22705 |
|
22706 |
static function _clean_admin_content_section_hook() {
|
22707 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22708 |
|
22709 |
// Hide footer.
|
22710 |
echo '<style>#wpfooter { display: none !important; }</style>';
|
@@ -22721,17 +23857,17 @@
|
|
22721 |
}
|
22722 |
|
22723 |
/* CSS & JavaScript
|
22724 |
-
|
22725 |
/* function _enqueue_script($handle, $src) {
|
22726 |
-
|
22727 |
|
22728 |
-
|
22729 |
|
22730 |
-
|
22731 |
-
|
22732 |
|
22733 |
/* SDK
|
22734 |
-
|
22735 |
private $_user_api;
|
22736 |
|
22737 |
/**
|
@@ -22743,7 +23879,7 @@
|
|
22743 |
*
|
22744 |
* @return FS_Api
|
22745 |
*/
|
22746 |
-
|
22747 |
if ( ! isset( $this->_user_api ) || $flush ) {
|
22748 |
$this->_user_api = $this->get_api_user_scope_by_user( $this->_user );
|
22749 |
}
|
@@ -22822,13 +23958,56 @@
|
|
22822 |
$this->_site->public_key,
|
22823 |
! $this->is_live(),
|
22824 |
$this->_site->secret_key,
|
22825 |
-
$this->get_sdk_version()
|
|
|
22826 |
);
|
22827 |
}
|
22828 |
|
22829 |
return $this->_site_api;
|
22830 |
}
|
22831 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22832 |
private $_plugin_api;
|
22833 |
|
22834 |
/**
|
@@ -23264,7 +24443,7 @@
|
|
23264 |
}
|
23265 |
|
23266 |
/* Action Links
|
23267 |
-
|
23268 |
private $_action_links_hooked = false;
|
23269 |
private $_action_links = array();
|
23270 |
|
@@ -23435,15 +24614,6 @@
|
|
23435 |
|
23436 |
$this->_logger->entrance();
|
23437 |
|
23438 |
-
/**
|
23439 |
-
* @author Vova Feldman (@svovaf)
|
23440 |
-
* @since 2.3.2 Allow opting out from usage-tracking for paid products too by giving the appropriate warning letting the user know the automatic updates mechanism cannot function without an ongoing connection to the licensing and updates engine.
|
23441 |
-
*/
|
23442 |
-
/*if ( $this->is_premium() ) {
|
23443 |
-
// Don't add opt-in/out for premium code base.
|
23444 |
-
return;
|
23445 |
-
}*/
|
23446 |
-
|
23447 |
if ( $this->is_only_premium() && $this->is_free_plan() ) {
|
23448 |
// Don't add tracking links for premium-only products that were opted-in by relation (add-on or a parent product) before activating any license.
|
23449 |
return;
|
@@ -23451,10 +24621,13 @@
|
|
23451 |
|
23452 |
if (
|
23453 |
$this->is_addon() &&
|
23454 |
-
! $this->is_only_premium()
|
23455 |
-
$this->_parent->is_anonymous()
|
23456 |
) {
|
23457 |
-
|
|
|
|
|
|
|
|
|
23458 |
}
|
23459 |
|
23460 |
if ( fs_is_network_admin() ) {
|
@@ -23503,23 +24676,15 @@
|
|
23503 |
}
|
23504 |
}
|
23505 |
|
23506 |
-
if ( $this->add_ajax_action( '
|
23507 |
-
return;
|
23508 |
-
}
|
23509 |
-
|
23510 |
-
if ( $this->add_ajax_action( 'allow_tracking', array( &$this, '_allow_tracking_callback' ) ) ) {
|
23511 |
-
return;
|
23512 |
-
}
|
23513 |
-
|
23514 |
-
if ( $this->add_ajax_action( 'update_tracking_permission', array( &$this, '_update_tracking_permission_callback' ) ) ) {
|
23515 |
return;
|
23516 |
}
|
23517 |
|
23518 |
$link_text_id = '';
|
23519 |
$url = '#';
|
23520 |
|
23521 |
-
if ( $this->is_registered() ) {
|
23522 |
-
if ( $this->is_tracking_allowed() ) {
|
23523 |
$link_text_id = $this->get_text_inline( 'Opt Out', 'opt-out' );
|
23524 |
} else {
|
23525 |
$link_text_id = $this->get_text_inline( 'Opt In', 'opt-in' );
|
@@ -23716,9 +24881,12 @@
|
|
23716 |
*/
|
23717 |
private function is_premium_version_installed() {
|
23718 |
$premium_plugin_basename = $this->premium_plugin_basename();
|
23719 |
-
$premium_plugin = get_plugins( '/' . dirname( $premium_plugin_basename ) );
|
23720 |
|
23721 |
-
|
|
|
|
|
|
|
|
|
23722 |
}
|
23723 |
|
23724 |
/**
|
@@ -23754,7 +24922,9 @@
|
|
23754 |
* @author Leo Fajardo (@leorw)
|
23755 |
* @since 2.2.1
|
23756 |
*/
|
23757 |
-
$
|
|
|
|
|
23758 |
|
23759 |
return sprintf(
|
23760 |
/* translators: %1$s: Product title; %2$s: Plan title */
|
@@ -23763,7 +24933,9 @@
|
|
23763 |
$plan_title,
|
23764 |
sprintf(
|
23765 |
'<a style="margin-left: 10px;" href="%s"><button class="button button-primary">%s</button></a>',
|
23766 |
-
|
|
|
|
|
23767 |
esc_html( sprintf(
|
23768 |
/* translators: %s: Plan title */
|
23769 |
$this->get_text_inline( 'Activate %s features', 'activate-x-features' ),
|
@@ -23788,7 +24960,7 @@
|
|
23788 |
) ),
|
23789 |
$deactivation_step,
|
23790 |
$this->get_text_inline( 'Upload and activate the downloaded version', 'upload-and-activate' ),
|
23791 |
-
$this->apply_filters( 'upload_and_install_video_url', '//bit.ly/
|
23792 |
$this->get_text_inline( 'How to upload and activate?', 'howto-upload-activate' )
|
23793 |
);
|
23794 |
}
|
@@ -24241,8 +25413,10 @@
|
|
24241 |
function _tabs_capture() {
|
24242 |
$this->_logger->entrance();
|
24243 |
|
24244 |
-
if (
|
24245 |
-
|
|
|
|
|
24246 |
) {
|
24247 |
return;
|
24248 |
}
|
@@ -24296,8 +25470,10 @@
|
|
24296 |
function _store_tabs_styles() {
|
24297 |
$this->_logger->entrance();
|
24298 |
|
24299 |
-
if (
|
24300 |
-
|
|
|
|
|
24301 |
) {
|
24302 |
return;
|
24303 |
}
|
377 |
const REASON_DIDNT_WORK_AS_EXPECTED = 14;
|
378 |
const REASON_TEMPORARY_DEACTIVATION = 15;
|
379 |
|
380 |
+
#endregion
|
381 |
+
|
382 |
/**
|
383 |
* @author Leo Fajardo (@leorw)
|
384 |
* @since 2.3.1
|
394 |
*/
|
395 |
private $_pricing_js_path = null;
|
396 |
|
397 |
+
const VERSION_MAX_CHARS = 16;
|
398 |
+
const LANGUAGE_MAX_CHARS = 8;
|
399 |
|
400 |
/* Ctor
|
401 |
------------------------------------------------------------------------------------------------------------------*/
|
411 |
* @param bool $is_init Since 1.2.1 Is initiation sequence.
|
412 |
*/
|
413 |
private function __construct( $module_id, $slug = false, $is_init = false ) {
|
414 |
+
$main_file = false;
|
415 |
+
|
416 |
if ( $is_init && is_numeric( $module_id ) && is_string( $slug ) ) {
|
417 |
+
$main_file = $this->store_id_slug_type_path_map( $module_id, $slug );
|
418 |
}
|
419 |
|
420 |
$this->_module_id = $module_id;
|
429 |
|
430 |
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $this->get_unique_affix(), WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
431 |
|
432 |
+
$this->_plugin_main_file_path = $this->_find_caller_plugin_file( $is_init, $main_file );
|
433 |
$this->_plugin_dir_path = plugin_dir_path( $this->_plugin_main_file_path );
|
434 |
$this->_plugin_basename = $this->get_plugin_basename();
|
435 |
$this->_free_plugin_basename = str_replace( '-premium/', '/', $this->_plugin_basename );
|
524 |
* @author Leo Fajardo (@leorw)
|
525 |
* @since 1.2.2
|
526 |
*/
|
527 |
+
( is_object( $this->_plugin ) && isset( $this->_plugin->title ) ?
|
528 |
+
$this->_plugin->title :
|
529 |
+
$this->get_plugin_name()
|
530 |
+
),
|
531 |
$this->get_unique_affix()
|
532 |
);
|
533 |
|
941 |
* @param string $sdk_version
|
942 |
*/
|
943 |
function _sdk_version_update( $sdk_prev_version, $sdk_version ) {
|
|
|
|
|
|
|
944 |
if ( empty( $sdk_prev_version ) ) {
|
945 |
return;
|
946 |
}
|
947 |
|
948 |
+
if (
|
949 |
+
version_compare( $sdk_prev_version, '2.5.1', '<' ) &&
|
950 |
+
version_compare( $sdk_version, '2.5.1', '>=' )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
951 |
) {
|
952 |
+
if ( $this->is_registered( true ) ) {
|
953 |
+
/**
|
954 |
+
* Migrate to new permissions layer.
|
955 |
+
*/
|
956 |
+
require_once WP_FS__DIR_INCLUDES . '/supplements/fs-migration-2.5.1.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
957 |
|
958 |
+
$install_by_blog_id = is_multisite() ?
|
959 |
+
$this->get_blog_install_map() :
|
960 |
+
array( 0 => $this->_site );
|
961 |
|
962 |
+
fs_migrate_251( $this, $install_by_blog_id );
|
963 |
}
|
964 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
965 |
}
|
966 |
|
967 |
/**
|
1012 |
}
|
1013 |
}
|
1014 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1015 |
/**
|
1016 |
* @author Vova Feldman (@svovaf)
|
1017 |
* @since 1.2.2.7
|
1348 |
}
|
1349 |
}
|
1350 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1351 |
/**
|
1352 |
* Opens the support forum subemenu item in a new browser page.
|
1353 |
*
|
1458 |
}
|
1459 |
|
1460 |
if ( $this->is_plugin() ) {
|
1461 |
+
if ( version_compare( $GLOBALS['wp_version'], '5.1', '<' ) ) {
|
1462 |
add_action( 'wpmu_new_blog', array( $this, '_after_new_blog_callback' ), 10, 6 );
|
1463 |
+
} else {
|
1464 |
+
add_action( 'wp_initialize_site', array( $this, '_after_wp_initialize_site_callback' ), 11, 2 );
|
1465 |
}
|
1466 |
|
1467 |
register_deactivation_hook( $this->_plugin_main_file_path, array( &$this, '_deactivate_plugin_hook' ) );
|
1471 |
add_action( 'deactivate_blog', array( &$this, '_after_site_deactivated_callback' ) );
|
1472 |
add_action( 'archive_blog', array( &$this, '_after_site_deactivated_callback' ) );
|
1473 |
add_action( 'make_spam_blog', array( &$this, '_after_site_deactivated_callback' ) );
|
1474 |
+
|
1475 |
+
if ( version_compare( $GLOBALS['wp_version'], '5.1', '<' ) ) {
|
1476 |
+
add_action( 'deleted_blog', array( $this, '_after_site_deleted_callback' ), 10, 2 );
|
1477 |
+
} else {
|
1478 |
+
add_action( 'wp_delete_site', array( $this, '_after_wpsite_deleted_callback' ) );
|
1479 |
+
}
|
1480 |
|
1481 |
add_action( 'activate_blog', array( &$this, '_after_site_reactivated_callback' ) );
|
1482 |
add_action( 'unarchive_blog', array( &$this, '_after_site_reactivated_callback' ) );
|
1501 |
add_action( 'admin_init', array( &$this, '_add_premium_version_upgrade_selection' ) );
|
1502 |
add_action( 'admin_init', array( &$this, '_add_beta_mode_update_handler' ) );
|
1503 |
add_action( 'admin_init', array( &$this, '_add_user_change_option' ) );
|
1504 |
+
add_action( 'admin_init', array( &$this, '_add_email_address_update_option' ) );
|
1505 |
|
1506 |
$this->add_ajax_action( 'update_billing', array( &$this, '_update_billing_ajax_action' ) );
|
1507 |
$this->add_ajax_action( 'start_trial', array( &$this, '_start_trial_ajax_action' ) );
|
1873 |
return;
|
1874 |
}
|
1875 |
|
1876 |
+
if (
|
1877 |
+
( self::is_plugins_page() && $this->is_plugin() ) ||
|
1878 |
+
( self::is_themes_page() && $this->is_theme() ) ||
|
1879 |
+
fs_request_is_action_secure( $this->get_unique_affix() . '_reconnect' )
|
1880 |
+
) {
|
1881 |
+
$this->_add_tracking_links();
|
1882 |
+
}
|
1883 |
|
1884 |
if ( self::is_plugins_page() && $this->is_plugin() ) {
|
1885 |
$this->hook_plugin_action_links();
|
1925 |
/**
|
1926 |
* Leverage backtrace to find caller plugin file path.
|
1927 |
*
|
1928 |
+
* @param bool $is_init Is initiation sequence.
|
1929 |
+
* @param string $main_file Since 2.5.0 expects the module's main file path to potentially purge the cached path.
|
|
|
|
|
1930 |
*
|
1931 |
* @return string
|
1932 |
+
* @since 1.0.6
|
1933 |
+
*
|
1934 |
+
* @author Vova Feldman (@svovaf)
|
1935 |
*/
|
1936 |
+
private function _find_caller_plugin_file( $is_init = false, $main_file = '' ) {
|
1937 |
// Try to load the cached value of the file path.
|
1938 |
if ( isset( $this->_storage->plugin_main_file ) ) {
|
1939 |
$plugin_main_file = $this->_storage->plugin_main_file;
|
1940 |
if ( ! empty( $plugin_main_file->path ) ) {
|
1941 |
$absolute_path = $this->get_absolute_path( $plugin_main_file->path );
|
1942 |
if ( file_exists( $absolute_path ) ) {
|
1943 |
+
if ( $is_init && $absolute_path !== $this->get_absolute_path( $main_file ) ) {
|
1944 |
+
// Update cached path if not matching the actual path.
|
1945 |
+
$plugin_main_file->path = $main_file;
|
1946 |
+
$this->_storage->plugin_main_file = $plugin_main_file;
|
1947 |
+
}
|
1948 |
+
|
1949 |
return $absolute_path;
|
1950 |
}
|
1951 |
}
|
1986 |
* Only the original instantiator that calls dynamic_init can modify the module's path.
|
1987 |
*/
|
1988 |
// Find caller module.
|
|
|
1989 |
$this->_storage->plugin_main_file = (object) array(
|
1990 |
+
'path' => $main_file,
|
1991 |
);
|
1992 |
|
1993 |
+
return $this->get_absolute_path( $main_file );
|
1994 |
}
|
1995 |
|
1996 |
/**
|
2052 |
* @param number $module_id
|
2053 |
* @param string $slug
|
2054 |
*
|
2055 |
+
* @return string Since 2.5.0 return the module's main file path.
|
2056 |
+
*
|
2057 |
* @since 1.2.2
|
2058 |
*/
|
2059 |
private function store_id_slug_type_path_map( $module_id, $slug ) {
|
2075 |
$store_option = true;
|
2076 |
}
|
2077 |
|
2078 |
+
$find_caller = empty( $id_slug_type_path_map[ $module_id ]['path'] );
|
2079 |
+
|
2080 |
+
if ( ! $find_caller ) {
|
2081 |
+
/**
|
2082 |
+
* This verification is for cases when suddenly the same module
|
2083 |
+
* is installed but with a different folder name.
|
2084 |
+
*
|
2085 |
+
* @author Vova Feldman (@svovaf)
|
2086 |
+
* @since 1.2.3
|
2087 |
+
*/
|
2088 |
+
$find_caller = ! file_exists( $this->get_absolute_path(
|
2089 |
+
$id_slug_type_path_map[ $module_id ]['path'],
|
2090 |
+
$id_slug_type_path_map[ $module_id ]['type']
|
2091 |
+
) );
|
2092 |
+
}
|
2093 |
+
|
2094 |
+
foreach ( $id_slug_type_path_map as $id => $data ) {
|
2095 |
+
if ( empty( $id ) ) {
|
2096 |
+
// Remove maps with empty module ID.
|
2097 |
+
unset( $id_slug_type_path_map[ $id ] );
|
2098 |
+
$store_option = true;
|
2099 |
+
continue;
|
2100 |
+
}
|
2101 |
+
|
2102 |
+
/**
|
2103 |
+
* If the module's main file path is identical to the main file path of another module then it means that the cached path of the current module or the other one with the same path is wrong, and therefore, we need to recalculate those paths.
|
2104 |
+
*
|
2105 |
+
* @author Vova Feldman (@svovaf)
|
2106 |
+
* @since 2.5.0
|
2107 |
+
*/
|
2108 |
+
if ( ! $find_caller ) {
|
2109 |
+
if ( $id == $module_id ) {
|
2110 |
+
continue;
|
2111 |
+
}
|
2112 |
+
|
2113 |
+
if (
|
2114 |
+
isset( $data['path'] ) &&
|
2115 |
+
$data['path'] === $id_slug_type_path_map[ $module_id ]['path']
|
2116 |
+
) {
|
2117 |
+
$find_caller = true;
|
2118 |
+
}
|
2119 |
+
}
|
2120 |
+
}
|
2121 |
+
|
2122 |
+
if ( $find_caller ) {
|
2123 |
+
$caller_main_file_and_type = $this->get_caller_main_file_and_type( $module_id );
|
2124 |
|
2125 |
$id_slug_type_path_map[ $module_id ]['type'] = $caller_main_file_and_type->module_type;
|
2126 |
$id_slug_type_path_map[ $module_id ]['path'] = $caller_main_file_and_type->path;
|
2131 |
if ( $store_option ) {
|
2132 |
self::$_accounts->set_option( 'id_slug_type_path_map', $id_slug_type_path_map, true );
|
2133 |
}
|
2134 |
+
|
2135 |
+
return $id_slug_type_path_map[ $module_id ]['path'];
|
2136 |
}
|
2137 |
|
2138 |
/**
|
2146 |
* add-ons are relying on loading the SDK from the parent module, and also allows themes including the
|
2147 |
* SDK an internal file instead of directly from functions.php.
|
2148 |
* @since 1.2.1.7 Knows how to handle cases when an add-on includes the parent module logic.
|
2149 |
+
*
|
2150 |
+
* @param number $module_id @since 2.5.0
|
2151 |
*/
|
2152 |
+
private function get_caller_main_file_and_type( $module_id ) {
|
2153 |
self::require_plugin_essentials();
|
2154 |
|
2155 |
$all_plugins = fs_get_plugins( true );
|
2288 |
}
|
2289 |
}
|
2290 |
|
2291 |
+
$caller_main_file_and_type = (object) array(
|
2292 |
'module_type' => $module_type,
|
2293 |
'path' => $caller_file_candidate
|
2294 |
);
|
2295 |
+
|
2296 |
+
return apply_filters( "fs_{$module_id}_caller_main_file_and_type", $caller_main_file_and_type );
|
2297 |
}
|
2298 |
|
2299 |
#----------------------------------------------------------------------------------
|
2310 |
* @since 1.1.2
|
2311 |
*/
|
2312 |
function _add_deactivation_feedback_dialog_box() {
|
2313 |
+
if (
|
2314 |
+
$this->is_clone() ||
|
2315 |
+
( is_object( $this->_site ) && ! $this->is_registered() )
|
2316 |
+
) {
|
2317 |
+
return;
|
2318 |
+
}
|
2319 |
+
|
2320 |
$subscription_cancellation_dialog_box_template_params = $this->apply_filters( 'show_deactivation_subscription_cancellation', true ) ?
|
2321 |
$this->_get_subscription_cancellation_dialog_box_template_params() :
|
2322 |
array();
|
2324 |
/**
|
2325 |
* @since 2.3.0 Developers can optionally hide the deactivation feedback form using the 'show_deactivation_feedback_form' filter.
|
2326 |
*/
|
2327 |
+
$show_deactivation_feedback_form = ! self::is_deactivation_snoozed();
|
2328 |
if ( $this->has_filter( 'show_deactivation_feedback_form' ) ) {
|
2329 |
$show_deactivation_feedback_form = $this->apply_filters( 'show_deactivation_feedback_form', true );
|
2330 |
} else if ( $this->is_addon() ) {
|
2429 |
$reason_temporary_deactivation = array(
|
2430 |
'id' => self::REASON_TEMPORARY_DEACTIVATION,
|
2431 |
'text' => sprintf(
|
2432 |
+
$this->get_text_inline( "It's a temporary %s - I'm troubleshooting an issue", 'reason-temporary-x' ),
|
2433 |
strtolower( $this->is_plugin() ?
|
2434 |
$this->get_text_inline( 'Deactivation', 'deactivation' ) :
|
2435 |
$this->get_text_inline( 'Theme Switch', 'theme-switch' )
|
2594 |
|
2595 |
$this->_storage->store( 'uninstall_reason', $reason );
|
2596 |
|
2597 |
+
if ( self::REASON_TEMPORARY_DEACTIVATION == $reason->id ) {
|
2598 |
+
$snooze_period = fs_request_get( 'snooze_period' );
|
2599 |
+
|
2600 |
+
if ( is_numeric( $snooze_period ) && 0 < $snooze_period ) {
|
2601 |
+
self::snooze_deactivation_form( (int) $snooze_period );
|
2602 |
+
}
|
2603 |
+
}
|
2604 |
+
|
2605 |
/**
|
2606 |
* If the module type is "theme", trigger the uninstall event here (on theme deactivation) since themes do
|
2607 |
* not support uninstall hook.
|
2623 |
exit;
|
2624 |
}
|
2625 |
|
2626 |
+
#--------------------------------------------------------------------------------
|
2627 |
+
#region Deactivation Feedback Snoozing
|
2628 |
+
#--------------------------------------------------------------------------------
|
2629 |
+
|
2630 |
+
/**
|
2631 |
+
* @author Vova Feldman (@svovaf)
|
2632 |
+
* @since 2.4.3
|
2633 |
+
*
|
2634 |
+
* @param int $period
|
2635 |
+
*
|
2636 |
+
* @return bool True if the value was set, false otherwise.
|
2637 |
+
*/
|
2638 |
+
private static function snooze_deactivation_form( $period ) {
|
2639 |
+
return ( 0 < $period && self::reset_deactivation_snoozing( $period ) );
|
2640 |
+
}
|
2641 |
+
|
2642 |
+
/**
|
2643 |
+
* Check if deactivation feedback form is snoozed.
|
2644 |
+
*
|
2645 |
+
* @author Vova Feldman (@svovaf)
|
2646 |
+
* @since 2.4.3
|
2647 |
+
*
|
2648 |
+
* @return bool
|
2649 |
+
*/
|
2650 |
+
static function is_deactivation_snoozed() {
|
2651 |
+
$is_snoozed = ( ! is_multisite() || fs_is_network_admin() ) ?
|
2652 |
+
get_transient( 'fs_snooze_period' ) :
|
2653 |
+
get_site_transient( 'fs_snooze_period' );
|
2654 |
+
|
2655 |
+
|
2656 |
+
return ( 'true' === $is_snoozed );
|
2657 |
+
}
|
2658 |
+
|
2659 |
+
/**
|
2660 |
+
* Reset deactivation snoozing. When `$period` is `0` will stop deactivation snoozing by deleting the transients. Otherwise, will set the transients for the selected period.
|
2661 |
+
*
|
2662 |
+
* @param int $period Period in seconds.
|
2663 |
+
*
|
2664 |
+
* @author Vova Feldman (@svovaf)
|
2665 |
+
* @since 2.4.3
|
2666 |
+
*/
|
2667 |
+
private static function reset_deactivation_snoozing( $period = 0 ) {
|
2668 |
+
$value = ( 0 === $period ) ? null : 'true';
|
2669 |
+
|
2670 |
+
if ( ! is_multisite() || fs_is_network_admin() ) {
|
2671 |
+
return set_transient( 'fs_snooze_period', $value, $period );
|
2672 |
+
} else {
|
2673 |
+
return set_site_transient( 'fs_snooze_period', $value, $period );
|
2674 |
+
}
|
2675 |
+
}
|
2676 |
+
|
2677 |
+
/**
|
2678 |
+
* The deactivation snooze expiration UNIX timestamp (in sec).
|
2679 |
+
*
|
2680 |
+
* @author Vova Feldman (@svovaf)
|
2681 |
+
* @since 2.4.3
|
2682 |
+
*
|
2683 |
+
* @return int
|
2684 |
+
*/
|
2685 |
+
static function deactivation_snooze_expires_at() {
|
2686 |
+
return ( ! is_multisite() || fs_is_network_admin() ) ?
|
2687 |
+
(int) get_option( '_transient_timeout_fs_snooze_period' ) :
|
2688 |
+
(int) get_site_option( '_site_transient_timeout_fs_snooze_period' );
|
2689 |
+
}
|
2690 |
+
|
2691 |
+
#endregion
|
2692 |
+
|
2693 |
/**
|
2694 |
* @author Leo Fajardo (@leorw)
|
2695 |
* @since 2.1.4
|
2886 |
return self::instance( $addon_id );
|
2887 |
}
|
2888 |
|
2889 |
+
/**
|
2890 |
+
* @return Freemius[]
|
2891 |
+
*/
|
2892 |
+
static function _get_all_instances() {
|
2893 |
+
return self::$_instances;
|
2894 |
+
}
|
2895 |
+
|
2896 |
#endregion ------------------------------------------------------------------
|
2897 |
|
2898 |
/**
|
3403 |
add_action( 'plugins_loaded', array( 'Freemius', '_load_textdomain' ), 1 );
|
3404 |
}
|
3405 |
|
3406 |
+
$clone_manager = FS_Clone_Manager::instance();
|
3407 |
+
add_action( 'init', array( $clone_manager, '_init' ) );
|
3408 |
+
|
3409 |
add_action( 'admin_footer', array( 'Freemius', '_open_support_forum_in_new_page' ) );
|
3410 |
|
3411 |
if ( self::is_plugins_page() || self::is_themes_page() ) {
|
3424 |
self::$_statics_loaded = true;
|
3425 |
}
|
3426 |
|
3427 |
+
#--------------------------------------------------------------------------------
|
3428 |
+
#region Clone
|
3429 |
+
#--------------------------------------------------------------------------------
|
3430 |
+
|
3431 |
/**
|
3432 |
* @author Leo Fajardo (@leorw)
|
3433 |
+
* @since 2.5.0
|
3434 |
*
|
3435 |
+
* @param bool $only_if_manual_resolution_is_not_hidden
|
3436 |
+
*
|
3437 |
+
* @return bool
|
3438 |
*/
|
3439 |
+
private function is_unresolved_clone( $only_if_manual_resolution_is_not_hidden = false ) {
|
3440 |
+
if ( ! $this->is_clone( $only_if_manual_resolution_is_not_hidden ) ) {
|
3441 |
+
return false;
|
3442 |
+
}
|
|
|
|
|
|
|
|
|
|
|
3443 |
|
3444 |
+
return FS_Clone_Manager::instance()->has_temporary_duplicate_mode_expired();
|
3445 |
}
|
3446 |
|
|
|
|
|
|
|
|
|
3447 |
/**
|
3448 |
+
* @author Leo Fajardo (@leorw)
|
3449 |
+
* @since 2.5.0
|
3450 |
*
|
3451 |
+
* @param bool $only_if_manual_resolution_is_not_hidden
|
|
|
3452 |
*/
|
3453 |
+
function is_clone( $only_if_manual_resolution_is_not_hidden = false ) {
|
3454 |
+
if ( ! is_object( $this->_site ) ) {
|
3455 |
+
return false;
|
3456 |
}
|
3457 |
|
3458 |
+
$blog_id = null;
|
3459 |
|
3460 |
+
if (
|
3461 |
+
fs_is_network_admin() &&
|
3462 |
+
FS_Site::is_valid_id( $this->_storage->network_install_blog_id )
|
3463 |
+
) {
|
3464 |
+
// Ensure that we're comparing the network install's URL with the relevant subsite's URL.
|
3465 |
+
$blog_id = $this->_storage->network_install_blog_id;
|
3466 |
+
}
|
3467 |
+
|
3468 |
+
$site_url = Freemius::get_unfiltered_site_url( $blog_id, true, true );
|
3469 |
+
|
3470 |
+
if ( ! $this->_site->is_clone( $site_url ) ) {
|
3471 |
+
return false;
|
3472 |
+
}
|
3473 |
+
|
3474 |
+
return (
|
3475 |
+
! $only_if_manual_resolution_is_not_hidden ||
|
3476 |
+
! FS_Clone_Manager::instance()->should_hide_manual_resolution()
|
3477 |
+
);
|
3478 |
+
}
|
3479 |
+
|
3480 |
+
/**
|
3481 |
+
* @author Leo Fajardo (@leorw)
|
3482 |
+
* @since 2.5.0
|
3483 |
+
*
|
3484 |
+
* @param int|null $blog_id
|
3485 |
+
* @param bool $strip_protocol
|
3486 |
+
* @param bool $add_trailing_slash
|
3487 |
+
*
|
3488 |
+
* @return string
|
3489 |
+
*/
|
3490 |
+
static function get_unfiltered_site_url( $blog_id = null, $strip_protocol = false, $add_trailing_slash = false ) {
|
3491 |
+
global $wp_filter;
|
3492 |
+
|
3493 |
+
$site_url_filters = array(
|
3494 |
+
'site_url' => null,
|
3495 |
+
'pre_option_siteurl' => null,
|
3496 |
+
'default_option_siteurl' => null,
|
3497 |
+
'option_siteurl' => null,
|
3498 |
+
);
|
3499 |
+
|
3500 |
+
// Detach all URL-related filters to get the actual site's URL (stripped of potential manipulations by multilingual plugins).
|
3501 |
+
foreach ( $site_url_filters as $hook_name => $site_url_filter ) {
|
3502 |
+
if ( ! empty( $wp_filter[ $hook_name ] ) ) {
|
3503 |
+
$site_url_filters[ $hook_name ] = $wp_filter[ $hook_name ];
|
3504 |
+
unset( $wp_filter[ $hook_name ] );
|
3505 |
+
}
|
3506 |
+
}
|
3507 |
+
|
3508 |
+
$url = get_site_url( $blog_id );
|
3509 |
+
|
3510 |
+
// Re-attach the filters back.
|
3511 |
+
foreach ( $site_url_filters as $hook_name => $site_url_filter ) {
|
3512 |
+
if ( ! empty( $site_url_filter ) ) {
|
3513 |
+
$wp_filter[ $hook_name ] = $site_url_filter;
|
3514 |
+
}
|
3515 |
+
}
|
3516 |
+
|
3517 |
+
if ( $strip_protocol ) {
|
3518 |
+
$url = fs_strip_url_protocol( $url );
|
3519 |
+
}
|
3520 |
+
|
3521 |
+
if ( $add_trailing_slash ) {
|
3522 |
+
$url = trailingslashit( $url );
|
3523 |
+
}
|
3524 |
+
|
3525 |
+
return $url;
|
3526 |
+
}
|
3527 |
+
|
3528 |
+
/**
|
3529 |
+
* @author Leo Fajardo (@leorw)
|
3530 |
+
* @since 2.5.0
|
3531 |
+
*
|
3532 |
+
* @param number $site_id
|
3533 |
+
*/
|
3534 |
+
function fetch_install_by_id( $site_id ) {
|
3535 |
+
return $this->get_current_or_network_user_api_scope()->get( "/installs/{$site_id}.json" );
|
3536 |
+
}
|
3537 |
+
|
3538 |
+
/**
|
3539 |
+
* @author Leo Fajardo (@leorw)
|
3540 |
+
* @since 2.5.0
|
3541 |
+
*
|
3542 |
+
* @return string|object|bool
|
3543 |
+
*/
|
3544 |
+
function _handle_long_term_duplicate() {
|
3545 |
+
$this->_logger->entrance();
|
3546 |
+
|
3547 |
+
$this->delete_current_install( false );
|
3548 |
+
|
3549 |
+
$license_key = false;
|
3550 |
+
|
3551 |
+
if (
|
3552 |
+
is_object( $this->_license ) &&
|
3553 |
+
! $this->_license->is_utilized(
|
3554 |
+
( WP_FS__IS_LOCALHOST_FOR_SERVER || FS_Site::is_localhost_by_address( self::get_unfiltered_site_url() ) )
|
3555 |
+
)
|
3556 |
+
) {
|
3557 |
+
$license_key = $this->_license->secret_key;
|
3558 |
+
}
|
3559 |
+
|
3560 |
+
return $this->opt_in(
|
3561 |
+
false,
|
3562 |
+
false,
|
3563 |
+
false,
|
3564 |
+
$license_key,
|
3565 |
+
false,
|
3566 |
+
false,
|
3567 |
+
false,
|
3568 |
+
null,
|
3569 |
+
array(),
|
3570 |
+
false
|
3571 |
+
);
|
3572 |
+
}
|
3573 |
+
|
3574 |
+
#endregion
|
3575 |
+
|
3576 |
+
/**
|
3577 |
+
* @author Leo Fajardo (@leorw)
|
3578 |
+
*
|
3579 |
+
* @since 2.1.3
|
3580 |
+
*/
|
3581 |
+
private static function migrate_options_to_network() {
|
3582 |
+
self::migrate_accounts_to_network();
|
3583 |
+
|
3584 |
+
// Migrate API options from site level to network level.
|
3585 |
+
$api_network_options = FS_Option_Manager::get_manager( WP_FS__OPTIONS_OPTION_NAME, true, true );
|
3586 |
+
$api_network_options->migrate_to_network();
|
3587 |
+
|
3588 |
+
// Migrate API cache to network level storage.
|
3589 |
+
FS_Cache_Manager::get_manager( WP_FS__API_CACHE_OPTION_NAME )->migrate_to_network();
|
3590 |
+
|
3591 |
+
self::$_accounts->set_option( 'ms_migration_complete', true, true );
|
3592 |
+
}
|
3593 |
+
|
3594 |
+
#----------------------------------------------------------------------------------
|
3595 |
+
#region Localization
|
3596 |
+
#----------------------------------------------------------------------------------
|
3597 |
+
|
3598 |
+
/**
|
3599 |
+
* Load framework's text domain.
|
3600 |
+
*
|
3601 |
+
* @author Vova Feldman (@svovaf)
|
3602 |
+
* @since 1.2.1
|
3603 |
+
*/
|
3604 |
+
static function _load_textdomain() {
|
3605 |
+
if ( ! is_admin() ) {
|
3606 |
+
return;
|
3607 |
+
}
|
3608 |
+
|
3609 |
+
global $fs_active_plugins;
|
3610 |
+
|
3611 |
+
// Works both for plugins and themes.
|
3612 |
+
load_plugin_textdomain(
|
3613 |
+
'freemius',
|
3614 |
+
false,
|
3615 |
+
$fs_active_plugins->newest->sdk_path . '/languages/'
|
3616 |
+
);
|
3617 |
+
}
|
3618 |
|
3619 |
#endregion
|
3620 |
|
3648 |
} else {
|
3649 |
// Add hidden debug page.
|
3650 |
$hook = FS_Admin_Menu_Manager::add_subpage(
|
3651 |
+
'',
|
3652 |
$title,
|
3653 |
$title,
|
3654 |
'manage_options',
|
3809 |
|
3810 |
switch_to_blog( $current_blog_id );
|
3811 |
}
|
3812 |
+
} else if ( fs_request_is_action( 'reset_deactivation_snoozing' ) ) {
|
3813 |
+
check_admin_referer( 'reset_deactivation_snoozing' );
|
3814 |
+
|
3815 |
+
self::reset_deactivation_snoozing();
|
3816 |
} else if ( fs_request_is_action( 'simulate_trial' ) ) {
|
3817 |
check_admin_referer( 'simulate_trial' );
|
3818 |
|
3861 |
}
|
3862 |
|
3863 |
/**
|
3864 |
+
* @author Leo Fajardo (@leorw)
|
3865 |
+
* @since 2.5.0
|
3866 |
+
*
|
3867 |
+
* @return array
|
3868 |
*/
|
3869 |
+
static function get_all_modules_sites() {
|
3870 |
self::$_static_logger->entrance();
|
3871 |
|
3872 |
+
$sites_by_type = array(
|
3873 |
+
WP_FS__MODULE_TYPE_PLUGIN => array(),
|
3874 |
+
WP_FS__MODULE_TYPE_THEME => array(),
|
3875 |
+
);
|
3876 |
+
|
3877 |
+
$module_types = array_keys( $sites_by_type );
|
3878 |
+
|
3879 |
if ( ! is_multisite() ) {
|
3880 |
+
foreach ( $module_types as $type ) {
|
3881 |
+
$sites_by_type[ $type ] = self::get_all_sites( $type );
|
3882 |
+
|
3883 |
+
foreach ( $sites_by_type[ $type ] as $slug => $install ) {
|
3884 |
+
$sites_by_type[ $type ][ $slug ] = array( $install );
|
3885 |
+
}
|
3886 |
+
}
|
3887 |
} else {
|
3888 |
$sites = self::get_sites();
|
3889 |
|
|
|
|
|
|
|
3890 |
foreach ( $sites as $site ) {
|
3891 |
$blog_id = self::get_site_blog_id( $site );
|
3892 |
|
3893 |
+
foreach ( $module_types as $type ) {
|
3894 |
+
$installs = self::get_all_sites( $type, $blog_id );
|
|
|
|
|
|
|
|
|
|
|
|
|
3895 |
|
3896 |
+
foreach ( $installs as $slug => $install ) {
|
3897 |
+
if ( ! isset( $sites_by_type[ $type ][ $slug ] ) ) {
|
3898 |
+
$sites_by_type[ $type ][ $slug ] = array();
|
3899 |
+
}
|
3900 |
|
3901 |
+
$install->blog_id = $blog_id;
|
3902 |
|
3903 |
+
$sites_by_type[ $type ][ $slug ][] = $install;
|
|
|
|
|
3904 |
}
|
3905 |
|
|
|
|
|
|
|
3906 |
}
|
3907 |
}
|
3908 |
}
|
3909 |
|
3910 |
+
return $sites_by_type;
|
3911 |
+
}
|
3912 |
+
|
3913 |
+
/**
|
3914 |
+
* @author Vova Feldman (@svovaf)
|
3915 |
+
* @since 1.0.8
|
3916 |
+
*/
|
3917 |
+
static function _debug_page_render() {
|
3918 |
+
self::$_static_logger->entrance();
|
3919 |
+
|
3920 |
+
$all_modules_sites = self::get_all_modules_sites();
|
3921 |
+
|
3922 |
$licenses_by_module_type = self::get_all_licenses_by_module_type();
|
3923 |
|
3924 |
$vars = array(
|
3925 |
+
'plugin_sites' => $all_modules_sites[ WP_FS__MODULE_TYPE_PLUGIN ],
|
3926 |
+
'theme_sites' => $all_modules_sites[ WP_FS__MODULE_TYPE_THEME ],
|
3927 |
'users' => self::get_all_users(),
|
3928 |
'addons' => self::get_all_addons(),
|
3929 |
'account_addons' => self::get_all_account_addons(),
|
3955 |
function is_on() {
|
3956 |
self::$_static_logger->entrance();
|
3957 |
|
3958 |
+
if ( is_object( $this->_site ) && ! $this->is_registered() ) {
|
3959 |
+
return false;
|
3960 |
+
}
|
3961 |
+
|
3962 |
if ( isset( $this->_is_on ) ) {
|
3963 |
return $this->_is_on;
|
3964 |
}
|
4047 |
|
4048 |
$is_update = $this->apply_filters( 'is_plugin_update', $this->is_plugin_update() );
|
4049 |
|
4050 |
+
$params = array(
|
4051 |
+
'is_update' => json_encode( $is_update ),
|
4052 |
+
'version' => $version,
|
4053 |
+
'sdk' => $this->version,
|
4054 |
+
'is_admin' => json_encode( is_admin() ),
|
4055 |
+
'is_ajax' => json_encode( self::is_ajax() ),
|
4056 |
+
'is_cron' => json_encode( self::is_cron() ),
|
4057 |
+
'is_gdpr_test' => $is_gdpr_test,
|
4058 |
+
'is_http' => json_encode( WP_FS__IS_HTTP_REQUEST ),
|
4059 |
+
);
|
4060 |
+
|
4061 |
+
if ( is_multisite() && function_exists( 'get_network' ) ) {
|
4062 |
+
$params['network_uid'] = $this->get_anonymous_network_id();
|
4063 |
+
}
|
4064 |
+
|
4065 |
return $this->get_api_plugin_scope()->ping(
|
4066 |
$this->get_anonymous_id( $blog_id ),
|
4067 |
+
$params
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4068 |
);
|
4069 |
}
|
4070 |
|
4201 |
$unique_id = self::$_accounts->get_option( 'unique_id', null, $blog_id );
|
4202 |
|
4203 |
if ( empty( $unique_id ) || ! is_string( $unique_id ) ) {
|
4204 |
+
$key = self::get_unfiltered_site_url( $blog_id, true );
|
4205 |
|
4206 |
+
$secure_auth = defined( 'SECURE_AUTH_KEY' ) ? SECURE_AUTH_KEY : '';
|
4207 |
if ( empty( $secure_auth ) ||
|
4208 |
false !== strpos( $secure_auth, ' ' ) ||
|
4209 |
'put your unique phrase here' === $secure_auth
|
4230 |
return $unique_id;
|
4231 |
}
|
4232 |
|
4233 |
+
/**
|
4234 |
+
* Returns anonymous network ID.
|
4235 |
+
*
|
4236 |
+
* @since 2.4.3
|
4237 |
+
*
|
4238 |
+
* @return string
|
4239 |
+
*/
|
4240 |
+
function get_anonymous_network_id() {
|
4241 |
+
return $this->get_anonymous_id( get_network()->site_id );
|
4242 |
+
}
|
4243 |
+
|
4244 |
/**
|
4245 |
* @author Vova Feldman (@svovaf)
|
4246 |
* @since 1.1.7.4
|
4389 |
$install_previous_desc = $this->esc_html_inline( 'Uninstall this version and install the previous one.', 'install-previous-desc' );
|
4390 |
$fix_issue_title = $this->esc_html_inline( 'Yes - I\'m giving you a chance to fix it', 'fix-issue-title' );
|
4391 |
$fix_issue_desc = $this->esc_html_inline( 'We will do our best to whitelist your server and resolve this issue ASAP. You will get a follow-up email to %s once we have an update.', 'fix-issue-desc' );
|
4392 |
+
/* translators: %s: product title (e.g. "Awesome Plugin" requires access to...) */
|
4393 |
+
$x_requires_access_to_api = $this->esc_html_inline( '%s requires access to our API.', 'x-requires-access-to-api' );
|
4394 |
$sysadmin_title = $this->esc_html_inline( 'I\'m a system administrator', 'sysadmin-title' );
|
4395 |
$happy_to_resolve_issue_asap = $this->esc_html_inline( 'We are sure it\'s an issue on our side and more than happy to resolve it for you ASAP if you give us a chance.', 'happy-to-resolve-issue-asap' );
|
4396 |
|
4397 |
+
if ( $this->is_premium() ) {
|
4398 |
+
/* translators: This string is optionally prepended to 'plugin requires access to our API.' */
|
4399 |
+
$x_requires_access_to_api = $this->esc_html_inline( 'For automatic delivery of security & feature updates,', 'requires-api-for' ) . ' ' . $x_requires_access_to_api;
|
4400 |
+
}
|
4401 |
+
|
4402 |
$message = false;
|
4403 |
if ( is_object( $api_result ) &&
|
4404 |
isset( $api_result->error ) &&
|
5030 |
|
5031 |
/**
|
5032 |
* This should be executed even if Freemius is off for the core module,
|
5033 |
+
* otherwise, the add-ons dialog box won't work properly. This is especially
|
5034 |
* relevant when the developer decided to turn FS off for existing users.
|
5035 |
*
|
5036 |
* @author Vova Feldman (@svovaf)
|
5068 |
* @since 1.1.7.3
|
5069 |
*
|
5070 |
*/
|
5071 |
+
if ( $this->is_registered() && $this->is_tracking_allowed() ) {
|
5072 |
+
$this->maybe_schedule_sync_cron();
|
|
|
|
|
5073 |
}
|
5074 |
|
5075 |
/**
|
5076 |
* Check if requested for manual blocking background sync.
|
5077 |
*/
|
5078 |
if ( fs_request_has( 'background_sync' ) ) {
|
5079 |
+
self::require_pluggable_essentials();
|
5080 |
+
self::wp_cookie_constants();
|
5081 |
+
|
5082 |
$this->run_manual_sync();
|
5083 |
}
|
5084 |
}
|
5085 |
}
|
5086 |
|
5087 |
if ( $this->is_registered() ) {
|
5088 |
+
FS_Clone_Manager::instance()->maybe_resolve_new_subsite_install_automatically( $this );
|
5089 |
+
|
5090 |
$this->hook_callback_to_install_sync();
|
5091 |
}
|
5092 |
|
5101 |
}
|
5102 |
|
5103 |
if ( $this->is_user_in_admin() ) {
|
5104 |
+
if ( $this->is_registered() && fs_request_has( 'purchase_completed' ) ) {
|
5105 |
+
$this->_admin_notices->add_sticky(
|
5106 |
+
sprintf(
|
5107 |
+
/* translators: %s: License type (e.g. you have a professional license) */
|
5108 |
+
$this->get_text_inline( 'You have purchased a %s license.', 'you-have-x-license' ),
|
5109 |
+
fs_request_get( 'purchased_plan' )
|
5110 |
+
) .
|
5111 |
+
sprintf(
|
5112 |
+
$this->get_text_inline(" The %s's %sdownload link%s, license key, and installation instructions have been sent to %s. If you can't find the email after 5 min, please check your spam box.", 'post-purchase-email-sent-message' ),
|
5113 |
+
$this->get_module_label( true ),
|
5114 |
+
( FS_Plugin::is_valid_id( $this->get_bundle_id() ) ? "products' " : '' ),
|
5115 |
+
( FS_Plugin::is_valid_id( $this->get_bundle_id() ) ? 's' : '' ),
|
5116 |
+
sprintf(
|
5117 |
+
'<strong>%s</strong>',
|
5118 |
+
fs_request_get( 'purchase_email' )
|
5119 |
+
)
|
5120 |
+
),
|
5121 |
+
'plan_purchased',
|
5122 |
+
$this->get_text_x_inline( 'Yee-haw', 'interjection expressing joy or exuberance', 'yee-haw' ) . '!'
|
5123 |
+
);
|
5124 |
+
}
|
5125 |
+
|
5126 |
if ( $this->is_addon() ) {
|
5127 |
if ( ! $this->is_parent_plugin_installed() ) {
|
5128 |
$parent_name = $this->get_option( $plugin_info, 'parent_name', null );
|
5227 |
* because the updater has some logic that needs to be executed
|
5228 |
* during AJAX calls.
|
5229 |
*
|
5230 |
+
* Currently, we need to hook to the `http_request_host_is_external` filter.
|
5231 |
* In the future, there might be additional logic added.
|
5232 |
*
|
5233 |
* @author Vova Feldman
|
5246 |
*/
|
5247 |
( file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $this->premium_plugin_basename() ) ) )
|
5248 |
) &&
|
5249 |
+
$this->has_release_on_freemius() &&
|
5250 |
+
( ! $this->is_unresolved_clone( true ) )
|
5251 |
) {
|
5252 |
FS_Plugin_Updater::instance( $this );
|
5253 |
}
|
5316 |
}
|
5317 |
|
5318 |
/**
|
5319 |
+
* @param string[] $permissions
|
5320 |
+
* @param bool $is_enabled
|
5321 |
+
* @param int|null $blog_id
|
5322 |
*
|
5323 |
+
* @return true|object `true` on success, API error object on failure.
|
5324 |
*/
|
5325 |
+
private function update_site_permissions( array $permissions, $is_enabled, $blog_id = null ) {
|
5326 |
$this->_logger->entrance();
|
5327 |
|
5328 |
+
$params = array(
|
5329 |
+
'permissions' => implode( ',', $permissions ),
|
5330 |
+
'is_enabled' => $is_enabled,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5331 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5332 |
|
5333 |
+
$current_blog_id = get_current_blog_id();
|
5334 |
+
$is_blog_switched = false;
|
5335 |
+
if ( is_numeric( $blog_id ) && $current_blog_id != $blog_id ) {
|
5336 |
+
$is_blog_switched = $this->switch_to_blog( $blog_id );
|
5337 |
}
|
5338 |
|
5339 |
+
$result = $this->api_site_call( '/permissions.json', 'put', $params );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5340 |
|
5341 |
+
if ( $is_blog_switched ) {
|
5342 |
+
$this->switch_to_blog( $current_blog_id );
|
|
|
5343 |
}
|
5344 |
|
5345 |
+
if (
|
5346 |
+
! $this->is_api_result_object( $result ) ||
|
5347 |
+
! isset( $result->install_id )
|
|
|
|
|
|
|
|
|
|
|
5348 |
) {
|
5349 |
$this->_logger->api_error( $result );
|
5350 |
|
5351 |
return $result;
|
5352 |
}
|
5353 |
|
|
|
|
|
|
|
|
|
|
|
|
|
5354 |
return true;
|
5355 |
}
|
5356 |
|
5357 |
/**
|
5358 |
+
* @param string[] $permissions
|
5359 |
+
* @param bool $is_enabled
|
5360 |
+
* @param bool $has_site_delegated_connection
|
5361 |
*
|
5362 |
+
* @return true|object `true` on success, API error object on failure.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5363 |
*/
|
5364 |
+
private function update_network_permissions(
|
5365 |
+
array $permissions,
|
5366 |
+
$is_enabled,
|
5367 |
+
&$has_site_delegated_connection
|
5368 |
+
) {
|
5369 |
$this->_logger->entrance();
|
5370 |
|
|
|
|
|
|
|
|
|
|
|
5371 |
$install_id_2_blog_id = array();
|
5372 |
+
$install_by_blog_id = $this->get_blog_install_map();
|
5373 |
|
5374 |
+
$has_site_delegated_connection = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5375 |
|
5376 |
+
foreach ( $install_by_blog_id as $blog_id => $install ) {
|
5377 |
if ( $this->is_site_delegated_connection( $blog_id ) ) {
|
5378 |
+
// Only update permissions of non-delegated installs.
|
5379 |
+
$has_site_delegated_connection = true;
|
5380 |
continue;
|
5381 |
}
|
5382 |
|
|
|
|
|
5383 |
$install_id_2_blog_id[ $install->id ] = $blog_id;
|
5384 |
}
|
5385 |
|
5387 |
return true;
|
5388 |
}
|
5389 |
|
5390 |
+
$params = array(
|
5391 |
+
'permissions' => implode( ',', $permissions ),
|
5392 |
+
'is_enabled' => $is_enabled,
|
5393 |
+
'install_ids' => implode( ',', array_keys( $install_id_2_blog_id ) ),
|
5394 |
+
);
|
5395 |
|
5396 |
// Send update to FS.
|
5397 |
+
$result = $this->get_current_or_network_user_api_scope()->call(
|
5398 |
+
"/plugins/{$this->_module_id}/installs/permissions.json",
|
5399 |
+
'put',
|
5400 |
+
$params
|
5401 |
+
);
|
5402 |
|
5403 |
+
if ( ! $this->is_api_result_object( $result, 'installs_metadata' ) ) {
|
5404 |
$this->_logger->api_error( $result );
|
5405 |
|
5406 |
return $result;
|
5407 |
}
|
5408 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5409 |
return true;
|
5410 |
}
|
5411 |
|
5412 |
/**
|
5413 |
+
* @param mixed $result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5414 |
*
|
5415 |
+
* @return string
|
5416 |
*/
|
5417 |
+
private function get_api_error_message( $result ) {
|
5418 |
+
$error_message = sprintf( $this->get_text_inline( 'There was an unexpected API error while processing your request. Please try again in a few minutes and if it still doesn\'t work, contact the %s\'s author with the following:',
|
5419 |
+
'unexpected-api-error' ), $this->_module_type ) . ' ';
|
5420 |
+
|
5421 |
+
if (
|
5422 |
+
$this->is_api_error( $result ) &&
|
5423 |
+
isset( $result->error )
|
5424 |
+
) {
|
5425 |
+
$code = empty( $result->error->code ) ? '' : " Code: {$result->error->code}";
|
5426 |
+
|
5427 |
+
$error_message .= "<b>{$result->error->message}{$code}</b>";
|
5428 |
+
} else {
|
5429 |
+
$error_message .= var_export( $result, true );
|
5430 |
+
}
|
5431 |
|
5432 |
+
return $error_message;
|
|
|
|
|
5433 |
}
|
5434 |
|
5435 |
/**
|
5436 |
+
* @author Vova Feldman (@svovaf)
|
5437 |
+
* @since 2.5.1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5438 |
*/
|
5439 |
+
function _toggle_permission_tracking_callback() {
|
5440 |
$this->_logger->entrance();
|
5441 |
|
5442 |
+
$this->check_ajax_referer( 'toggle_permission_tracking' );
|
|
|
|
|
|
|
5443 |
|
5444 |
+
if ( ! $this->is_registered( true ) ) {
|
5445 |
+
self::shoot_ajax_failure( 'User never opted-in.' );
|
|
|
5446 |
}
|
5447 |
|
5448 |
+
$is_enabled = fs_request_get_bool( 'is_enabled' );
|
5449 |
+
$permissions = fs_request_get( 'permissions' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5450 |
|
5451 |
+
if ( ! is_string( $permissions ) ) {
|
5452 |
+
self::shoot_ajax_failure( 'The permissions param must be a string.' );
|
5453 |
}
|
5454 |
|
5455 |
+
$permissions = explode( ',', $permissions );
|
|
|
5456 |
|
5457 |
+
$result = $this->toggle_permission_tracking( $permissions, $is_enabled );
|
5458 |
|
5459 |
+
if ( true !== $result ) {
|
5460 |
+
self::shoot_ajax_failure( $this->get_api_error_message( $result ) );
|
5461 |
+
}
|
5462 |
+
|
5463 |
+
self::shoot_ajax_success();
|
5464 |
}
|
5465 |
|
5466 |
/**
|
5467 |
+
* @param string[] $permissions
|
5468 |
+
* @param bool $is_enabled
|
5469 |
+
* @param int|null $blog_id
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5470 |
*
|
5471 |
+
* @return bool|mixed `true` if updated successfully or no update is needed.
|
5472 |
*/
|
5473 |
+
private function toggle_permission_tracking( $permissions, $is_enabled, $blog_id = null ) {
|
5474 |
+
if ( ! $this->is_registered( true ) ) {
|
|
|
|
|
5475 |
// User never opted-in.
|
5476 |
return false;
|
5477 |
}
|
5478 |
|
5479 |
+
// Check if permissions are already set as needed.
|
5480 |
+
if ( FS_Permission_Manager::instance( $this )->are_permissions( $permissions, $is_enabled, $blog_id ) ) {
|
5481 |
+
/**
|
5482 |
+
* Note:
|
5483 |
+
* When running on the network admin, there's no need to iterate through all the installs individually since network opt-in permissions are managed for ALL non-delegated installs through a single option (per permission) on the network-level storage.
|
5484 |
+
*/
|
5485 |
+
return true;
|
|
|
|
|
|
|
|
|
|
|
5486 |
}
|
5487 |
|
5488 |
+
$api_managed_permissions = array_intersect(
|
5489 |
+
$permissions,
|
5490 |
+
FS_Permission_Manager::get_api_managed_permission_ids()
|
5491 |
+
);
|
5492 |
+
|
5493 |
+
if (
|
5494 |
+
in_array( FS_Permission_Manager::PERMISSION_ESSENTIALS, $permissions ) &&
|
5495 |
+
! in_array( FS_Permission_Manager::PERMISSION_SITE, $permissions )
|
5496 |
+
) {
|
5497 |
+
$api_managed_permissions[] = FS_Permission_Manager::PERMISSION_SITE;
|
5498 |
}
|
5499 |
|
5500 |
+
if ( ! empty( $api_managed_permissions ) ) {
|
5501 |
+
$has_site_delegated_connection = false;
|
5502 |
|
5503 |
+
if (
|
5504 |
+
! $is_enabled &&
|
5505 |
+
! in_array( FS_Permission_Manager::PERMISSION_EXTENSIONS, $api_managed_permissions ) &&
|
5506 |
+
false === FS_Permission_Manager::instance( $this )->is_extensions_tracking_allowed( $blog_id )
|
5507 |
+
) {
|
5508 |
+
/**
|
5509 |
+
* If we are turning off a permission and the extensions permission is off too, enrich the permissions update request to also turn off extensions tracking, as currently when opting in with extensions tracking disabled the extensions tracking is off but the API isn't aware of it.
|
5510 |
+
*
|
5511 |
+
* @todo Remove this entire `if` after implementing granular opt-in that also sends the permissions to the API when opting in.
|
5512 |
+
*/
|
5513 |
+
$api_managed_permissions[] = FS_Permission_Manager::PERMISSION_EXTENSIONS;
|
5514 |
+
}
|
5515 |
|
5516 |
+
if ( is_null( $blog_id ) && fs_is_network_admin() ) {
|
5517 |
+
$result = $this->update_network_permissions(
|
5518 |
+
$api_managed_permissions,
|
5519 |
+
$is_enabled,
|
5520 |
+
$has_site_delegated_connection
|
5521 |
+
);
|
5522 |
+
} else {
|
5523 |
+
$result = $this->update_site_permissions(
|
5524 |
+
$api_managed_permissions,
|
5525 |
+
$is_enabled,
|
5526 |
+
$blog_id
|
5527 |
+
);
|
5528 |
+
}
|
5529 |
|
5530 |
+
if ( true !== $result ) {
|
5531 |
+
return $result;
|
5532 |
+
}
|
5533 |
|
5534 |
+
if ( in_array( FS_Permission_Manager::PERMISSION_SITE, $api_managed_permissions ) ) {
|
5535 |
+
if ( $is_enabled ) {
|
5536 |
+
$this->schedule_sync_cron();
|
5537 |
+
} else {
|
5538 |
+
$this->clear_sync_cron( ! $has_site_delegated_connection );
|
5539 |
+
}
|
5540 |
+
}
|
5541 |
|
5542 |
+
if ( in_array( FS_Permission_Manager::PERMISSION_USER, $api_managed_permissions ) ) {
|
5543 |
+
$this->toggle_user_permission( $is_enabled, $blog_id );
|
5544 |
+
}
|
|
|
|
|
5545 |
}
|
5546 |
|
5547 |
+
$this->update_tracking_permissions(
|
5548 |
+
$permissions,
|
5549 |
+
$is_enabled,
|
5550 |
+
$blog_id
|
5551 |
+
);
|
5552 |
|
|
|
5553 |
return true;
|
5554 |
}
|
5555 |
|
5556 |
+
/**
|
5557 |
+
* @param bool $is_enabled
|
5558 |
+
* @param int|null $blog_id
|
5559 |
+
*/
|
5560 |
+
private function toggle_user_permission( $is_enabled, $blog_id = null ) {
|
5561 |
+
$network_or_blog_ids = is_numeric( $blog_id ) ?
|
5562 |
+
$blog_id :
|
5563 |
+
fs_is_network_admin();
|
5564 |
+
|
5565 |
+
if ( $is_enabled ) {
|
5566 |
+
$this->reset_anonymous_mode( $network_or_blog_ids );
|
5567 |
+
} else {
|
5568 |
+
$this->skip_connection( $network_or_blog_ids );
|
5569 |
+
}
|
5570 |
+
}
|
5571 |
+
|
5572 |
/**
|
5573 |
* Opt-in back into usage tracking.
|
5574 |
*
|
5582 |
* @author Leo Fajardo (@leorw)
|
5583 |
* @since 1.2.1.5
|
5584 |
*
|
5585 |
+
* @bool $is_enabled
|
5586 |
*
|
5587 |
* @return bool|object
|
5588 |
*/
|
5589 |
+
private function toggle_site_tracking( $is_enabled, $blog_id = null ) {
|
5590 |
$this->_logger->entrance();
|
5591 |
|
5592 |
+
return $this->toggle_permission_tracking(
|
5593 |
+
FS_Permission_Manager::instance( $this )->get_site_tracking_permission_names(),
|
5594 |
+
$is_enabled,
|
5595 |
+
$blog_id
|
5596 |
+
);
|
5597 |
}
|
5598 |
|
5599 |
/**
|
5614 |
|
5615 |
if ( ! fs_is_network_admin() || $is_context_single_site ) {
|
5616 |
if ( $this->is_tracking_prohibited() ) {
|
5617 |
+
FS_Permission_Manager::instance( $this )->update_site_tracking( true );
|
|
|
5618 |
}
|
5619 |
} else {
|
5620 |
$installs_map = $this->get_blog_install_map();
|
5622 |
/**
|
5623 |
* @var FS_Site $install
|
5624 |
*/
|
5625 |
+
if ( ! $this->is_tracking_allowed( $blog_id, $install ) ) {
|
5626 |
+
FS_Permission_Manager::instance( $this )->update_site_tracking( true, $blog_id );
|
|
|
5627 |
}
|
5628 |
}
|
5629 |
}
|
5630 |
}
|
5631 |
|
5632 |
/**
|
5633 |
+
* Update permission tracking flags. When updating in a network context, in addition to updating the network-level flags, also update the permissions on the site-level for all non-delegated sites.
|
|
|
5634 |
*
|
5635 |
+
* @param string[] $permissions
|
5636 |
+
* @param bool $is_enabled
|
5637 |
+
* @param int|null $blog_id
|
5638 |
+
*
|
5639 |
+
* @return array
|
5640 |
*/
|
5641 |
+
private function update_tracking_permissions( $permissions, $is_enabled, $blog_id = null ) {
|
5642 |
+
// Alias.
|
5643 |
+
$permission_manager = FS_Permission_Manager::instance( $this );
|
|
|
|
|
|
|
5644 |
|
5645 |
+
$network_or_blog_ids = is_numeric( $blog_id ) ?
|
5646 |
+
$blog_id :
|
5647 |
+
fs_is_network_admin();
|
|
|
|
|
|
|
5648 |
|
5649 |
+
if ( true === $network_or_blog_ids ) {
|
5650 |
+
// Update the permission for all non-delegated sub-sites.
|
5651 |
+
$blog_ids = $this->get_non_delegated_blog_ids();
|
5652 |
|
5653 |
+
// Add the network-level to the array, to update the permission on the network-level storage.
|
5654 |
+
array_unshift( $blog_ids, null );
|
5655 |
+
}
|
5656 |
+
else
|
5657 |
+
{
|
5658 |
+
if ( false === $network_or_blog_ids ) {
|
5659 |
+
$network_or_blog_ids = null;
|
5660 |
+
}
|
5661 |
|
5662 |
+
$blog_ids = is_array( $network_or_blog_ids ) ?
|
5663 |
+
$network_or_blog_ids :
|
5664 |
+
array( $network_or_blog_ids );
|
5665 |
}
|
5666 |
|
5667 |
+
$result = array();
|
5668 |
+
foreach ( $permissions as $permission ) {
|
5669 |
+
$permission = trim( $permission );
|
5670 |
+
$is_permission_supported = true;
|
5671 |
+
|
5672 |
+
foreach ( $blog_ids as $id ) {
|
5673 |
+
$is_permission_supported = $permission_manager->update_permission_tracking_flag(
|
5674 |
+
$permission,
|
5675 |
+
$is_enabled,
|
5676 |
+
$id
|
5677 |
+
);
|
5678 |
+
}
|
5679 |
|
5680 |
+
if ( ! $is_permission_supported ) {
|
|
|
|
|
|
|
|
|
5681 |
$permission = 'no_match';
|
5682 |
+
}
|
5683 |
|
5684 |
+
$result[ $permission ] = $is_enabled;
|
|
|
5685 |
}
|
5686 |
|
5687 |
+
return $result;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5688 |
}
|
5689 |
|
5690 |
/**
|
5890 |
if ( $this->is_activation_mode() ) {
|
5891 |
if ( ! is_admin() ) {
|
5892 |
/**
|
5893 |
+
* If in activation mode, don't execute Freemius outside the admin dashboard.
|
|
|
5894 |
*
|
5895 |
* @author Vova Feldman (@svovaf)
|
5896 |
* @since 1.1.7.3
|
6437 |
if ( ! isset( $this->_is_anonymous ) ) {
|
6438 |
if ( $this->is_network_anonymous() ) {
|
6439 |
$this->_is_anonymous = true;
|
6440 |
+
} else if ( fs_is_network_admin() ) {
|
6441 |
+
/**
|
6442 |
+
* When not-network-anonymous, yet, running in the network admin, consider as anonymous only when ALL non-delegated sites are set to anonymous.
|
6443 |
+
*/
|
6444 |
+
$non_delegated_sites = $this->get_non_delegated_blog_ids();
|
6445 |
+
|
6446 |
+
foreach ( $non_delegated_sites as $blog_id ) {
|
6447 |
+
$is_anonymous = $this->_storage->get( 'is_anonymous', false, $blog_id );
|
6448 |
+
|
6449 |
+
if ( empty( $is_anonymous ) || false === $is_anonymous[ 'is' ] ) {
|
6450 |
+
$this->_is_anonymous = false;
|
6451 |
+
break;
|
6452 |
+
}
|
6453 |
+
}
|
6454 |
+
|
6455 |
+
if ( false !== $this->_is_anonymous ) {
|
6456 |
+
$this->_is_anonymous = true;
|
6457 |
+
}
|
6458 |
+
} else {
|
6459 |
if ( ! isset( $this->_storage->is_anonymous ) ) {
|
6460 |
// Not skipped.
|
6461 |
$this->_is_anonymous = false;
|
6511 |
return $this->_storage->get( 'is_pending_activation', false );
|
6512 |
}
|
6513 |
|
6514 |
+
/**
|
6515 |
+
* @author Leo Fajardo (@leorw)
|
6516 |
+
* @since 2.5.0
|
6517 |
+
*/
|
6518 |
+
private function clear_pending_activation_mode() {
|
6519 |
+
// Remove the pending activation sticky notice (if it still exists).
|
6520 |
+
$this->_admin_notices->remove_sticky( 'activation_pending' );
|
6521 |
+
|
6522 |
+
// Clear the plugin's pending activation mode.
|
6523 |
+
unset( $this->_storage->is_pending_activation );
|
6524 |
+
}
|
6525 |
+
|
6526 |
/**
|
6527 |
* Check if plugin must be WordPress.org compliant.
|
6528 |
*
|
6599 |
private function get_cron_blog_id( $name ) {
|
6600 |
$this->_logger->entrance( $name );
|
6601 |
|
6602 |
+
if ( ! is_multisite() ) {
|
6603 |
+
// Not a multisite.
|
6604 |
+
return 0;
|
6605 |
+
}
|
6606 |
+
|
6607 |
$cron_data = $this->get_cron_data( $name );
|
6608 |
|
6609 |
return ( is_object( $cron_data ) && is_numeric( $cron_data->blog_id ) ) ?
|
6714 |
return 0;
|
6715 |
}
|
6716 |
|
6717 |
+
if ( $this->_is_network_active ) {
|
6718 |
+
$network_install_blog_id = $this->_storage->network_install_blog_id;
|
|
|
|
|
|
|
|
|
|
|
6719 |
|
6720 |
+
if (
|
6721 |
+
is_numeric( $network_install_blog_id ) &&
|
6722 |
+
$except_blog_id != $network_install_blog_id &&
|
6723 |
+
self::is_site_active( $network_install_blog_id )
|
6724 |
) {
|
6725 |
+
// Try to run cron from the main network blog.
|
6726 |
+
$install = $this->get_install_by_blog_id( $network_install_blog_id );
|
6727 |
+
|
6728 |
+
if (
|
6729 |
+
is_object( $install ) &&
|
6730 |
+
$this->is_tracking_allowed( $network_install_blog_id, $install )
|
6731 |
+
) {
|
6732 |
+
return $network_install_blog_id;
|
6733 |
+
}
|
6734 |
}
|
6735 |
}
|
6736 |
|
6739 |
foreach ( $installs as $blog_id => $install ) {
|
6740 |
if ( $except_blog_id != $blog_id &&
|
6741 |
self::is_site_active( $blog_id ) &&
|
6742 |
+
$this->is_tracking_allowed( $blog_id, $install )
|
6743 |
) {
|
6744 |
return $blog_id;
|
6745 |
}
|
6771 |
/**
|
6772 |
* @var FS_Site $install
|
6773 |
*/
|
6774 |
+
if ( $this->is_tracking_allowed( $blog_id, $install ) ) {
|
6775 |
$clear_cron = false;
|
6776 |
break;
|
6777 |
}
|
6782 |
return;
|
6783 |
}
|
6784 |
|
6785 |
+
$cron_blog_id = $this->get_cron_blog_id( $name );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6786 |
|
6787 |
$this->clear_cron_data( $name );
|
6788 |
|
6819 |
return false;
|
6820 |
}
|
6821 |
|
6822 |
+
$cron_blog_id = $this->get_cron_blog_id( $name );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6823 |
|
6824 |
if ( 0 < $cron_blog_id ) {
|
6825 |
switch_to_blog( $cron_blog_id );
|
6930 |
} else {
|
6931 |
$installs = $this->get_blog_install_map();
|
6932 |
foreach ( $installs as $blog_id => $install ) {
|
6933 |
+
if ( $this->is_tracking_allowed( $blog_id, $install ) ) {
|
6934 |
if ( ! isset( $users_2_blog_ids[ $install->user_id ] ) ) {
|
6935 |
$users_2_blog_ids[ $install->user_id ] = array();
|
6936 |
}
|
6995 |
* @since 1.1.7.3
|
6996 |
*/
|
6997 |
private function run_manual_sync() {
|
|
|
|
|
6998 |
if ( ! $this->is_user_admin() ) {
|
6999 |
return;
|
7000 |
}
|
7078 |
return $this->is_cron_on( 'sync' );
|
7079 |
}
|
7080 |
|
7081 |
+
/**
|
7082 |
+
* @author Leo Fajardo (@leorw)
|
7083 |
+
* @since 2.5.0
|
7084 |
+
*/
|
7085 |
+
private function maybe_schedule_sync_cron() {
|
7086 |
+
$next_schedule = $this->next_sync_cron();
|
7087 |
+
|
7088 |
+
// The event is properly scheduled, so no need to reschedule it.
|
7089 |
+
if (
|
7090 |
+
is_numeric( $next_schedule ) &&
|
7091 |
+
$next_schedule > time()
|
7092 |
+
) {
|
7093 |
+
return;
|
7094 |
+
}
|
7095 |
+
|
7096 |
+
$this->schedule_sync_cron();
|
7097 |
+
}
|
7098 |
+
|
7099 |
/**
|
7100 |
* @author Vova Feldman (@svovaf)
|
7101 |
* @since 1.1.7.3
|
7202 |
* @param int $except_blog_id Since 2.0.0 when running in a multisite network environment, the cron execution is consolidated. This param allows excluding excluded specified blog ID from being the cron executor.
|
7203 |
*/
|
7204 |
private function schedule_install_sync( $except_blog_id = 0 ) {
|
7205 |
+
if ( $this->is_clone() ) {
|
7206 |
+
return;
|
7207 |
+
}
|
7208 |
+
|
7209 |
$this->schedule_cron( 'install_sync', 'install_sync', 'single', WP_FS__SCRIPT_START_TIME, false, $except_blog_id );
|
7210 |
}
|
7211 |
|
7294 |
/**
|
7295 |
* Show a notice that activation is currently pending.
|
7296 |
*
|
7297 |
+
* @todo Add some sort of mechanism to allow users to update the email address they would like to opt-in with when $is_suspicious_email is true.
|
7298 |
+
*
|
7299 |
* @author Vova Feldman (@svovaf)
|
7300 |
* @since 1.0.7
|
7301 |
*
|
7302 |
* @param bool|string $email
|
7303 |
* @param bool $is_pending_trial Since 1.2.1.5
|
7304 |
+
* @param bool $is_suspicious_email Since 2.5.0 Set to true when there's an indication that email address the user opted in with is fake/dummy/placeholder.
|
7305 |
*/
|
7306 |
+
function _add_pending_activation_notice(
|
7307 |
+
$email = false,
|
7308 |
+
$is_pending_trial = false,
|
7309 |
+
$is_suspicious_email = false
|
7310 |
+
) {
|
7311 |
if ( ! is_string( $email ) ) {
|
7312 |
$current_user = self::_get_current_wp_user();
|
7313 |
$email = $current_user->user_email;
|
7315 |
|
7316 |
$this->_admin_notices->add_sticky(
|
7317 |
sprintf(
|
7318 |
+
$this->get_text_inline( 'You should receive a confirmation email for %s to your mailbox at %s. Please make sure you click the button in that email to %s.', 'pending-activation-message' ),
|
7319 |
'<b>' . $this->get_plugin_name() . '</b>',
|
7320 |
'<b>' . $email . '</b>',
|
7321 |
( $is_pending_trial ?
|
7322 |
$this->get_text_inline( 'start the trial', 'start-the-trial' ) :
|
7323 |
+
$this->get_text_inline( 'complete the opt-in', 'complete-the-opt-in' ) )
|
7324 |
),
|
7325 |
'activation_pending',
|
7326 |
'Thanks!'
|
7363 |
/**
|
7364 |
* Don't redirect if activating multiple plugins at once (bulk activation).
|
7365 |
*/
|
7366 |
+
} else if (
|
7367 |
+
self::is_deactivation_snoozed() &&
|
7368 |
+
(
|
7369 |
+
// Either running the free code base.
|
7370 |
+
! $this->is_premium() ||
|
7371 |
+
// Or if has a free version.
|
7372 |
+
! $this->is_only_premium() ||
|
7373 |
+
// If premium only, don't redirect if license is activated.
|
7374 |
+
( $this->is_registered() && ! $this->can_use_premium_code() )
|
7375 |
+
)
|
7376 |
+
) {
|
7377 |
+
/**
|
7378 |
+
* Don't redirect if activating during the deactivation snooze period (aka troubleshooting), unless activating a paid product version that the admin didn't enter its license key yet.
|
7379 |
+
*/
|
7380 |
} else if ( ! $is_migration ) {
|
7381 |
$this->_redirect_on_activation_hook();
|
7382 |
return;
|
7390 |
if ( fs_request_is_action( $this->get_unique_affix() . '_skip_activation' ) ) {
|
7391 |
check_admin_referer( $this->get_unique_affix() . '_skip_activation' );
|
7392 |
|
7393 |
+
$this->skip_connection( fs_is_network_admin() );
|
7394 |
|
7395 |
fs_redirect( $this->get_after_activation_url( 'after_skip_url' ) );
|
7396 |
}
|
7563 |
|
7564 |
fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
|
7565 |
fs_enqueue_local_script( 'fs-postmessage', 'postmessage.js' );
|
|
|
|
|
7566 |
}
|
7567 |
|
7568 |
/**
|
7598 |
<?php
|
7599 |
echo $this->apply_filters( 'optin_pointer_execute', "
|
7600 |
|
7601 |
+
optin.pointer('open');
|
7602 |
|
7603 |
+
// Tag the opt-in pointer with custom class.
|
7604 |
+
$('.wp-pointer #fs_connect')
|
7605 |
+
.parents('.wp-pointer.wp-pointer-top')
|
7606 |
+
.addClass('fs-opt-in-pointer');
|
7607 |
|
7608 |
+
", 'element', 'optin' ) ?>
|
7609 |
}
|
7610 |
}
|
7611 |
});
|
7621 |
*
|
7622 |
* @return string
|
7623 |
*/
|
7624 |
+
static function current_page_url() {
|
7625 |
$url = 'http';
|
7626 |
|
7627 |
if ( isset( $_SERVER["HTTPS"] ) ) {
|
7653 |
}
|
7654 |
|
7655 |
/* Events
|
7656 |
+
------------------------------------------------------------------------------------------------------------------*/
|
7657 |
/**
|
7658 |
* Delete site install from Database.
|
7659 |
*
|
7819 |
* @author Leo Fajardo (@leorw)
|
7820 |
* @since 1.2.2
|
7821 |
*
|
7822 |
+
* @return bool
|
7823 |
+
*/
|
7824 |
+
private function can_activate_previous_theme() {
|
7825 |
+
return $this->can_activate_theme( $this->get_previous_theme_slug() );
|
7826 |
+
}
|
7827 |
+
|
7828 |
+
/**
|
7829 |
+
* @author Leo Fajardo (@leorw)
|
7830 |
+
* @since 2.5.0
|
7831 |
+
*
|
7832 |
+
* @return bool
|
7833 |
*/
|
7834 |
+
private function can_activate_theme( $slug ) {
|
|
|
7835 |
if ( false !== $slug && current_user_can( 'switch_themes' ) ) {
|
7836 |
$theme_instance = wp_get_theme( $slug );
|
7837 |
|
7928 |
( current_filter() !== ( 'activate_' . $this->_free_plugin_basename ) ) :
|
7929 |
$this->is_premium();
|
7930 |
|
7931 |
+
if ( $is_premium_version_activation && $this->is_pending_activation() ) {
|
7932 |
+
$this->clear_pending_activation_mode();
|
7933 |
+
}
|
7934 |
+
|
7935 |
$this->_logger->info( 'Activating ' . ( $is_premium_version_activation ? 'premium' : 'free' ) . ' plugin version.' );
|
7936 |
|
7937 |
if ( $this->is_plugin() ) {
|
7998 |
$plugin_version = $this->_storage->is_anonymous_ms['version'];
|
7999 |
$network = true;
|
8000 |
} else {
|
8001 |
+
$plugin_version = isset( $this->_storage->is_anonymous ) ?
|
8002 |
+
$this->_storage->is_anonymous['version'] :
|
8003 |
+
null;
|
8004 |
$network = false;
|
8005 |
}
|
8006 |
|
8148 |
);
|
8149 |
} else {
|
8150 |
// Activate the license.
|
8151 |
+
$install = $this->api_site_call(
|
8152 |
'/',
|
8153 |
'put',
|
8154 |
array( 'license_key' => $this->apply_filters( 'license_key', $license->secret_key ) )
|
8807 |
$this->_is_anonymous = $is_anonymous;
|
8808 |
}
|
8809 |
|
8810 |
+
/**
|
8811 |
+
* @author Vova Feldman (@svovaf)
|
8812 |
+
* @since 2.5.1
|
8813 |
+
*
|
8814 |
+
* @param bool|int $network_or_blog_id
|
8815 |
+
*/
|
8816 |
+
private function unset_anonymous_mode( $network_or_blog_id = 0 ) {
|
8817 |
+
if ( true === $network_or_blog_id ) {
|
8818 |
+
unset( $this->_storage->is_anonymous_ms );
|
8819 |
+
} else {
|
8820 |
+
$this->_storage->remove( 'is_anonymous', true, $network_or_blog_id );
|
8821 |
+
}
|
8822 |
+
}
|
8823 |
+
|
8824 |
/**
|
8825 |
* @author Vova Feldman (@svovaf)
|
8826 |
* @since 2.0.0
|
8837 |
* @uses Freemius::is_network_anonymous() to check if the super-admin network skipped.
|
8838 |
* @uses Freemius::is_network_delegated_connection() to check if the super-admin network delegated the connection to the site admins.
|
8839 |
*/
|
8840 |
+
public function _after_new_blog_callback( $blog_id, $user_id, $domain, $path, $network_id, $meta ) {
|
8841 |
$this->_logger->entrance();
|
8842 |
|
8843 |
+
if ( ! $this->_is_network_active ) {
|
8844 |
+
FS_Clone_Manager::instance()->store_blog_install_info( $blog_id );
|
8845 |
+
return;
|
8846 |
+
}
|
8847 |
+
|
8848 |
+
$site = null;
|
8849 |
+
$new_blog_id = $blog_id;
|
8850 |
+
|
8851 |
if ( $this->is_premium() &&
|
8852 |
$this->is_network_connected() &&
|
8853 |
is_object( $this->_license ) &&
|
8881 |
}
|
8882 |
}
|
8883 |
|
8884 |
+
$site = $this->_site;
|
8885 |
+
|
8886 |
$this->switch_to_blog( $current_blog_id );
|
8887 |
|
8888 |
+
if ( is_object( $site ) ) {
|
8889 |
+
FS_Clone_Manager::instance()->store_blog_install_info( $blog_id, $site );
|
8890 |
+
|
8891 |
// Already connected (with or without a license), so no need to continue.
|
8892 |
return;
|
8893 |
}
|
8920 |
false
|
8921 |
);
|
8922 |
|
8923 |
+
$site = $this->_site;
|
8924 |
+
|
8925 |
$this->switch_to_blog( $current_blog_id );
|
8926 |
} else {
|
8927 |
/**
|
8932 |
$has_delegated_site = false;
|
8933 |
|
8934 |
$sites = self::get_sites();
|
8935 |
+
foreach ( $sites as $wp_site ) {
|
8936 |
+
$blog_id = self::get_site_blog_id( $wp_site );
|
8937 |
|
8938 |
if ( $this->is_site_delegated_connection( $blog_id ) ) {
|
8939 |
$has_delegated_site = true;
|
8947 |
$this->skip_site_connection( $blog_id );
|
8948 |
}
|
8949 |
}
|
8950 |
+
|
8951 |
+
/**
|
8952 |
+
* Store the new blog's information even if there's no install so that when a clone install is stored in the new blog's storage, we can try to resolve it automatically.
|
8953 |
+
*
|
8954 |
+
* @author Leo Fajardo (@leorw)
|
8955 |
+
* @since 2.5.0
|
8956 |
+
*/
|
8957 |
+
FS_Clone_Manager::instance()->store_blog_install_info( $new_blog_id, $site );
|
8958 |
+
}
|
8959 |
+
|
8960 |
+
/**
|
8961 |
+
* @author Vova Feldman (@svovaf)
|
8962 |
+
* @since 2.5.0
|
8963 |
+
*
|
8964 |
+
* @param \WP_Site $new_site
|
8965 |
+
* @param array $args
|
8966 |
+
*/
|
8967 |
+
public function _after_wp_initialize_site_callback( WP_Site $new_site, $args ) {
|
8968 |
+
$this->_logger->entrance();
|
8969 |
+
|
8970 |
+
$this->_after_new_blog_callback(
|
8971 |
+
$new_site->id,
|
8972 |
+
// Dummy user ID (not in use).
|
8973 |
+
0,
|
8974 |
+
$new_site->domain,
|
8975 |
+
$new_site->path,
|
8976 |
+
$new_site->network_id,
|
8977 |
+
// Dummy meta, not in use.
|
8978 |
+
array()
|
8979 |
+
);
|
8980 |
}
|
8981 |
|
8982 |
/**
|
8983 |
* @author Vova Feldman (@svovaf)
|
8984 |
* @since 1.1.3
|
8985 |
*
|
8986 |
+
* @param bool|int|int[] $network_or_blog_ids Since 2.0.0.
|
8987 |
*/
|
8988 |
+
private function reset_anonymous_mode( $network_or_blog_ids = false ) {
|
8989 |
+
if ( true === $network_or_blog_ids ) {
|
8990 |
+
$this->unset_anonymous_mode( true );
|
8991 |
+
|
8992 |
+
if ( fs_is_network_admin() ) {
|
8993 |
+
$this->_is_anonymous = null;
|
8994 |
+
}
|
8995 |
+
|
8996 |
+
// Rest anonymous mode for all non-delegated sub-sites.
|
8997 |
+
$blog_ids = $this->get_non_delegated_blog_ids();
|
8998 |
+
}
|
8999 |
+
else
|
9000 |
+
{
|
9001 |
+
if ( false === $network_or_blog_ids ) {
|
9002 |
+
$network_or_blog_ids = 0;
|
9003 |
+
}
|
9004 |
+
|
9005 |
+
$blog_ids = is_array( $network_or_blog_ids ) ?
|
9006 |
+
$network_or_blog_ids :
|
9007 |
+
array( $network_or_blog_ids );
|
9008 |
+
|
9009 |
+
foreach ( $blog_ids as $blog_id ) {
|
9010 |
+
if ( 0 === $blog_id || get_current_blog_id() == $blog_id ) {
|
9011 |
+
$this->_is_anonymous = null;
|
9012 |
+
}
|
9013 |
+
}
|
9014 |
+
}
|
9015 |
+
|
9016 |
+
foreach ( $blog_ids as $blog_id ) {
|
9017 |
+
$this->unset_anonymous_mode( $blog_id );
|
9018 |
}
|
9019 |
|
9020 |
/**
|
9025 |
* @author Leo Fajardo (@leorw)
|
9026 |
* @since 1.2.2
|
9027 |
*/
|
9028 |
+
if ( ! $this->_is_network_active ) {
|
|
|
|
|
|
|
|
|
9029 |
$this->_is_anonymous = null;
|
9030 |
}
|
9031 |
}
|
9071 |
* @author Vova Feldman (@svovaf)
|
9072 |
* @since 1.1.1
|
9073 |
*
|
9074 |
+
* @param bool|int|int[] $network_or_blog_ids Since 2.5.1
|
|
|
9075 |
*/
|
9076 |
+
function skip_connection( $network_or_blog_ids = false ) {
|
9077 |
$this->_logger->entrance();
|
9078 |
|
9079 |
$this->_admin_notices->remove_sticky( 'connect_account' );
|
9080 |
|
9081 |
+
if ( true === $network_or_blog_ids ) {
|
9082 |
$this->set_anonymous_mode( true, true );
|
|
|
9083 |
|
9084 |
+
if ( fs_is_network_admin() ) {
|
9085 |
+
$this->_is_anonymous = null;
|
9086 |
+
}
|
|
|
9087 |
|
9088 |
+
// Rest anonymous mode for all non-delegated sub-sites.
|
9089 |
+
$blog_ids = $this->get_non_delegated_blog_ids();
|
9090 |
+
}
|
9091 |
+
else
|
9092 |
+
{
|
9093 |
+
if ( false === $network_or_blog_ids ) {
|
9094 |
+
$network_or_blog_ids = 0;
|
9095 |
+
}
|
9096 |
|
9097 |
+
$blog_ids = is_array( $network_or_blog_ids ) ?
|
9098 |
+
$network_or_blog_ids :
|
9099 |
+
array( $network_or_blog_ids );
|
9100 |
+
|
9101 |
+
foreach ( $blog_ids as $blog_id ) {
|
9102 |
+
if ( 0 === $blog_id || get_current_blog_id() == $blog_id ) {
|
9103 |
+
$this->_is_anonymous = null;
|
|
|
|
|
|
|
9104 |
}
|
9105 |
}
|
9106 |
+
}
|
9107 |
|
9108 |
+
foreach ( $blog_ids as $blog_id ) {
|
9109 |
+
$this->skip_site_connection( $blog_id );
|
|
|
|
|
|
|
9110 |
}
|
9111 |
|
9112 |
$this->network_upgrade_mode_completed();
|
9121 |
* @param int|null $blog_id
|
9122 |
* @param bool $send_skip
|
9123 |
*/
|
9124 |
+
private function skip_site_connection( $blog_id = null ) {
|
9125 |
$this->_logger->entrance();
|
9126 |
|
9127 |
$this->_admin_notices->remove_sticky( 'connect_account', $blog_id );
|
9128 |
|
9129 |
$this->set_anonymous_mode( true, $blog_id );
|
|
|
|
|
|
|
|
|
|
|
|
|
9130 |
}
|
9131 |
|
9132 |
/**
|
9498 |
* @param string[] $override
|
9499 |
* @param bool $include_plugins Since 1.1.8 by default include plugin changes.
|
9500 |
* @param bool $include_themes Since 1.1.8 by default include plugin changes.
|
9501 |
+
* @param bool $include_blog_data Since 2.3.0 by default include the current blog's data (language, title, and URL).
|
9502 |
*
|
9503 |
* @return array
|
9504 |
*/
|
9508 |
$include_themes = true,
|
9509 |
$include_blog_data = true
|
9510 |
) {
|
9511 |
+
// Alias.
|
9512 |
+
$permissions = FS_Permission_Manager::instance( $this );
|
9513 |
+
|
9514 |
+
if ( $permissions->is_extensions_tracking_allowed() ) {
|
9515 |
if ( ! defined( 'WP_FS__TRACK_PLUGINS' ) || false !== WP_FS__TRACK_PLUGINS ) {
|
9516 |
/**
|
9517 |
* @since 1.1.8 Also send plugin updates.
|
9539 |
|
9540 |
$versions = $this->get_versions();
|
9541 |
|
9542 |
+
$blog_data = array();
|
9543 |
+
if ( $include_blog_data ) {
|
9544 |
+
$blog_data['url'] = self::get_unfiltered_site_url();
|
9545 |
+
|
9546 |
+
if ( $permissions->is_diagnostic_tracking_allowed() ) {
|
9547 |
+
$blog_data = array_merge( $blog_data, array(
|
9548 |
+
'language' => self::get_sanitized_language(),
|
9549 |
+
'title' => get_bloginfo( 'name' ),
|
9550 |
+
) );
|
9551 |
+
}
|
9552 |
+
}
|
9553 |
|
9554 |
return array_merge( $versions, $blog_data, array(
|
9555 |
'version' => $this->get_plugin_version(),
|
9556 |
'is_premium' => $this->is_premium(),
|
9557 |
// Special params.
|
9558 |
'is_active' => true,
|
|
|
9559 |
'is_uninstalled' => false,
|
9560 |
), $override );
|
9561 |
}
|
9570 |
*
|
9571 |
* @param string[] string $override
|
9572 |
* @param bool $only_diff
|
9573 |
+
* @param bool $is_keepalive
|
9574 |
* @param bool $include_plugins Since 1.1.8 by default include plugin changes.
|
9575 |
* @param bool $include_themes Since 1.1.8 by default include plugin changes.
|
9576 |
*
|
9579 |
private function get_installs_data_for_api(
|
9580 |
array $override,
|
9581 |
$only_diff = false,
|
9582 |
+
$is_keepalive = false,
|
9583 |
$include_plugins = true,
|
9584 |
$include_themes = true
|
9585 |
) {
|
9617 |
|
9618 |
$sites = self::get_sites();
|
9619 |
|
9620 |
+
$subsite_data_for_api_by_install_id = array();
|
9621 |
+
$install_url_by_install_id = array();
|
9622 |
+
$subsite_registration_date_by_install_id = array();
|
9623 |
+
|
9624 |
foreach ( $sites as $site ) {
|
9625 |
$blog_id = self::get_site_blog_id( $site );
|
9626 |
|
9632 |
continue;
|
9633 |
}
|
9634 |
|
9635 |
+
if ( ! $this->is_tracking_allowed( $blog_id, $install ) ) {
|
9636 |
// Don't send updates regarding opted-out installs.
|
9637 |
continue;
|
9638 |
}
|
9639 |
|
9640 |
+
$install_data = $this->get_site_info( $site, true );
|
9641 |
+
|
9642 |
+
if ( FS_Clone_Manager::instance()->is_temporary_duplicate_by_blog_id( $install_data['blog_id'] ) ) {
|
9643 |
+
continue;
|
9644 |
+
}
|
9645 |
+
|
9646 |
+
$uid = $install_data['uid'];
|
9647 |
+
$url = $install_data['url'];
|
9648 |
+
$registration_date = $install_data['registration_date'];
|
9649 |
+
|
9650 |
+
if ( isset( $subsite_data_for_api_by_install_id[ $install->id ] ) ) {
|
9651 |
+
$clone_subsite_data = $subsite_data_for_api_by_install_id[ $install->id ];
|
9652 |
+
$clone_install_url = $install_url_by_install_id[ $install->id ];
|
9653 |
+
$clone_subsite_registration_date = $subsite_registration_date_by_install_id[ $install->id ];
|
9654 |
+
|
9655 |
+
$skip = false;
|
9656 |
+
|
9657 |
+
if (
|
9658 |
+
! empty( $install_data['registration_date'] ) &&
|
9659 |
+
! empty( $clone_subsite_registration_date )
|
9660 |
+
) {
|
9661 |
+
/**
|
9662 |
+
* If the current subsite was created after the other subsite that is also linked to the same install ID, we assume that it's a clone (not the original), and therefore, would skip its processing.
|
9663 |
+
*
|
9664 |
+
* @author Leo Fajardo (@leorw)
|
9665 |
+
* @since 2.5.1
|
9666 |
+
*/
|
9667 |
+
$skip = ( strtotime( $install_data['registration_date'] ) > strtotime( $clone_subsite_registration_date ) );
|
9668 |
+
} else if (
|
9669 |
+
/**
|
9670 |
+
* If we already have an install with the same URL as the subsite it's stored in, skip the current subsite. Otherwise, replace the existing install's data with the current subsite's install's data if the URLs match.
|
9671 |
+
*
|
9672 |
+
* @author Leo Fajardo (@leorw)
|
9673 |
+
* @since 2.5.0
|
9674 |
+
*/
|
9675 |
+
fs_strip_url_protocol( untrailingslashit( $clone_install_url ) ) === fs_strip_url_protocol( untrailingslashit( $clone_subsite_data['url'] ) ) ||
|
9676 |
+
fs_strip_url_protocol( untrailingslashit( $install->url ) ) !== fs_strip_url_protocol( untrailingslashit( $url ) )
|
9677 |
+
) {
|
9678 |
+
$skip = true;
|
9679 |
+
}
|
9680 |
|
9681 |
+
if ( $skip ) {
|
9682 |
+
// Store the skipped subsite's ID so that the clone resolution manager can try to resolve the clone install that is stored in that subsite later on.
|
9683 |
+
FS_Clone_Manager::instance()->store_blog_install_info( $blog_id );
|
9684 |
+
continue;
|
9685 |
+
}
|
9686 |
+
}
|
9687 |
|
9688 |
unset( $install_data['blog_id'] );
|
9689 |
unset( $install_data['uid'] );
|
9690 |
+
unset( $install_data['url'] );
|
9691 |
+
unset( $install_data['registration_date'] );
|
9692 |
|
|
|
9693 |
$install_data['is_active'] = $this->is_active_for_site( $blog_id );
|
9694 |
$install_data['is_uninstalled'] = $install->is_uninstalled;
|
9695 |
|
9712 |
$is_common_diff_for_any_site = $is_common_diff_for_any_site || $is_common_diff;
|
9713 |
}
|
9714 |
|
9715 |
+
if ( ! empty( $install_data ) || $is_common_diff || $is_keepalive ) {
|
9716 |
// Add install ID and site unique ID.
|
9717 |
$install_data['id'] = $install->id;
|
9718 |
$install_data['uid'] = $uid;
|
9719 |
+
$install_data['url'] = $url;
|
9720 |
|
9721 |
+
$subsite_data_for_api_by_install_id[ $install->id ] = $install_data;
|
9722 |
+
$install_url_by_install_id[ $install->id ] = $install->url;
|
9723 |
+
$subsite_registration_date_by_install_id[ $install->id ] = $registration_date;
|
9724 |
}
|
9725 |
}
|
9726 |
}
|
9727 |
|
9728 |
restore_current_blog();
|
9729 |
|
9730 |
+
$installs_data = array_merge(
|
9731 |
+
$installs_data,
|
9732 |
+
array_values( $subsite_data_for_api_by_install_id )
|
9733 |
+
);
|
9734 |
+
|
9735 |
if ( 0 < count( $installs_data ) && ( $is_common_diff_for_any_site || ! $only_diff ) ) {
|
9736 |
if ( ! $only_diff ) {
|
9737 |
$installs_data[] = $common;
|
9769 |
if ( ( is_bool( $install->{$p} ) || ! empty( $install->{$p} ) ) &&
|
9770 |
$install->{$p} != $v
|
9771 |
) {
|
9772 |
+
$val = self::get_api_sanitized_property( $p, $v );
|
9773 |
+
|
9774 |
+
if ( $install->{$p} != $val ) {
|
9775 |
+
$install->{$p} = $val;
|
9776 |
+
$diff[ $p ] = $val;
|
9777 |
+
}
|
9778 |
}
|
9779 |
} else {
|
9780 |
$special[ $p ] = $v;
|
9799 |
return $diff;
|
9800 |
}
|
9801 |
|
9802 |
+
/**
|
9803 |
+
* @author Leo Fajardo (@leorw)
|
9804 |
+
* @since 2.5.1
|
9805 |
+
*/
|
9806 |
+
private function send_pending_clone_update_once() {
|
9807 |
+
$this->_logger->entrance();
|
9808 |
+
|
9809 |
+
if ( ! empty( $this->_storage->clone_id ) ) {
|
9810 |
+
return;
|
9811 |
+
}
|
9812 |
+
|
9813 |
+
$install_clone = $this->get_api_site_scope()->call(
|
9814 |
+
'/clones',
|
9815 |
+
'post',
|
9816 |
+
array( 'site_url' => self::get_unfiltered_site_url() )
|
9817 |
+
);
|
9818 |
+
|
9819 |
+
if ( $this->is_api_result_entity( $install_clone ) ) {
|
9820 |
+
$this->_storage->clone_id = $install_clone->id;
|
9821 |
+
}
|
9822 |
+
}
|
9823 |
+
|
9824 |
+
/**
|
9825 |
+
* @author Leo Fajardo (@leorw)
|
9826 |
+
* @since 2.5.1
|
9827 |
+
*
|
9828 |
+
* @param string $resolution_type
|
9829 |
+
* @param FS_Site $clone_context_install
|
9830 |
+
*/
|
9831 |
+
function send_clone_resolution_update( $resolution_type, $clone_context_install ) {
|
9832 |
+
$this->_logger->entrance();
|
9833 |
+
|
9834 |
+
if ( empty( $this->_storage->clone_id ) ) {
|
9835 |
+
return;
|
9836 |
+
}
|
9837 |
+
|
9838 |
+
$new_install_id = null;
|
9839 |
+
$current_site = null;
|
9840 |
+
|
9841 |
+
$flush = false;
|
9842 |
+
|
9843 |
+
/**
|
9844 |
+
* If the current site is now different from the context install before the clone resolution, we need to override `$this->_site` so that the API call below will be made with the right install scope entity.
|
9845 |
+
*/
|
9846 |
+
if ( $clone_context_install->id != $this->_site->id ) {
|
9847 |
+
$new_install_id = $this->_site->id;
|
9848 |
+
$current_site = $this->_site;
|
9849 |
+
$this->_site = $clone_context_install;
|
9850 |
+
|
9851 |
+
$flush = true;
|
9852 |
+
}
|
9853 |
+
|
9854 |
+
$this->get_api_site_scope( $flush )->call(
|
9855 |
+
"/clones/{$this->_storage->clone_id}",
|
9856 |
+
'put',
|
9857 |
+
array(
|
9858 |
+
'resolution' => $resolution_type,
|
9859 |
+
'new_install_id' => $new_install_id,
|
9860 |
+
)
|
9861 |
+
);
|
9862 |
+
|
9863 |
+
if ( is_object( $current_site ) ) {
|
9864 |
+
/**
|
9865 |
+
* Ensure that the install scope entity is updated back to the previous install entity.
|
9866 |
+
*/
|
9867 |
+
$this->_site = $current_site;
|
9868 |
+
|
9869 |
+
// Restore the previous install scope entity of the API.
|
9870 |
+
$this->get_api_site_scope( true );
|
9871 |
+
}
|
9872 |
+
}
|
9873 |
+
|
9874 |
/**
|
9875 |
* Update install only if changed.
|
9876 |
*
|
9879 |
*
|
9880 |
* @param string[] string $override
|
9881 |
* @param bool $flush
|
9882 |
+
* @param bool $is_two_way_sync @since 2.5.0 If true and there's a successful API request, the install sync cron will be cleared.
|
9883 |
*
|
9884 |
* @return false|object|string
|
9885 |
*/
|
9886 |
+
private function send_install_update( $override = array(), $flush = false, $is_two_way_sync = false ) {
|
9887 |
$this->_logger->entrance();
|
9888 |
|
9889 |
$check_properties = $this->get_install_data_for_api( $override );
|
9894 |
$params = $this->get_install_diff_for_api( $check_properties, $this->_site, $override );
|
9895 |
}
|
9896 |
|
|
|
9897 |
if ( empty( $params ) ) {
|
9898 |
$keepalive_only_update = $this->should_send_keepalive_update();
|
9899 |
|
9908 |
}
|
9909 |
}
|
9910 |
|
9911 |
+
if ( $is_two_way_sync ) {
|
9912 |
/**
|
9913 |
+
* Update last install sync timestamp during a two-way sync call as we expect that updates are sent during this call.
|
|
|
9914 |
*
|
9915 |
* @author Leo Fajardo (@leorw)
|
9916 |
* @since 2.2.3
|
9926 |
$this->set_keepalive_timestamp();
|
9927 |
|
9928 |
// Send updated values to FS.
|
9929 |
+
$site = $this->api_site_call( '/', 'put', $params, true );
|
9930 |
|
9931 |
+
if ( $is_two_way_sync && $this->is_api_result_entity( $site ) ) {
|
9932 |
/**
|
9933 |
+
* Clear scheduled install sync after a two-way sync call.
|
9934 |
*
|
9935 |
* @author Leo Fajardo (@leorw)
|
9936 |
* @since 2.2.3
|
9952 |
*
|
9953 |
* @param string[] string $override
|
9954 |
* @param bool $flush
|
9955 |
+
* @param bool $is_two_way_sync @since 2.5.0 If true and there's a successful API request, the install sync cron will be cleared.
|
9956 |
*
|
9957 |
* @return false|object|string
|
9958 |
*/
|
9959 |
+
private function send_installs_update( $override = array(), $flush = false, $is_two_way_sync = false ) {
|
9960 |
$this->_logger->entrance();
|
9961 |
|
9962 |
+
/**
|
9963 |
+
* Pass `true` to use the network level storage since the update is for many installs.
|
9964 |
+
*
|
9965 |
+
* @author Leo Fajardo (@leorw)
|
9966 |
+
* @since 2.2.3
|
9967 |
+
*/
|
9968 |
+
$should_send_keepalive = $this->should_send_keepalive_update( true );
|
9969 |
|
9970 |
+
$installs_data = $this->get_installs_data_for_api( $override, ! $flush, $should_send_keepalive );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9971 |
|
9972 |
+
if ( empty( $installs_data ) ) {
|
9973 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9974 |
}
|
9975 |
|
9976 |
+
if ( $is_two_way_sync ) {
|
9977 |
+
// Update last install sync timestamp during a two-way sync call as we expect that updates are sent during this call.
|
9978 |
$this->set_cron_execution_timestamp( 'install_sync' );
|
9979 |
}
|
9980 |
|
9989 |
// Send updated values to FS.
|
9990 |
$result = $this->get_api_user_scope()->call( "/plugins/{$this->_plugin->id}/installs.json", 'put', $installs_data );
|
9991 |
|
9992 |
+
if ( $is_two_way_sync && $this->is_api_result_object( $result, 'installs' ) ) {
|
9993 |
+
// I successfully sent a two-way installs update, clear the scheduled install sync if it exists.
|
9994 |
$this->clear_install_sync_cron();
|
9995 |
}
|
9996 |
|
10040 |
* @param string[] string $override
|
10041 |
* @param bool $flush
|
10042 |
*/
|
10043 |
+
function sync_install( $override = array(), $flush = false ) {
|
10044 |
$this->_logger->entrance();
|
10045 |
|
10046 |
+
$site = $this->send_install_update( $override, $flush, true );
|
10047 |
|
10048 |
if ( false === $site ) {
|
10049 |
// No sync required.
|
10072 |
private function sync_installs( $override = array(), $flush = false ) {
|
10073 |
$this->_logger->entrance();
|
10074 |
|
10075 |
+
$result = $this->send_installs_update( $override, $flush, true );
|
10076 |
|
10077 |
if ( false === $result ) {
|
10078 |
// No sync required.
|
10227 |
// Send uninstall event.
|
10228 |
$this->send_installs_update( $params );
|
10229 |
} else {
|
10230 |
+
// Send uninstall event and handle the result.
|
10231 |
+
$this->sync_install( $params );
|
10232 |
}
|
10233 |
}
|
10234 |
|
10325 |
return;
|
10326 |
}
|
10327 |
|
10328 |
+
if (
|
10329 |
+
! $fs->is_clone() &&
|
10330 |
+
/**
|
10331 |
+
* If there's a context install, run this method only when there's also a context user (e.g., when cloning a subsite of a multisite network into a single-site installation, it's possible for an install to be associated with a non-existing user entity; we want Freemius to be off in this case, while we are trying to recover the user).
|
10332 |
+
*
|
10333 |
+
* @author Leo Fajardo
|
10334 |
+
*/
|
10335 |
+
( ! is_object( $fs->_site ) || $fs->is_registered() )
|
10336 |
+
) {
|
10337 |
+
$fs->_uninstall_plugin_event();
|
10338 |
+
}
|
10339 |
|
10340 |
$fs->do_action( 'after_uninstall' );
|
10341 |
}
|
10446 |
* @return string
|
10447 |
*/
|
10448 |
function get_premium_slug() {
|
10449 |
+
return ( is_object( $this->_plugin ) && ! empty( $this->_plugin->premium_slug ) ) ?
|
10450 |
$this->_plugin->premium_slug :
|
10451 |
"{$this->_slug}-premium";
|
10452 |
}
|
10499 |
null;
|
10500 |
}
|
10501 |
|
10502 |
+
/**
|
10503 |
+
* Get whether the SDK has been initiated in the context of a Bundle.
|
10504 |
+
*
|
10505 |
+
* This will return true, if `bundle_id` is present in the SDK init parameters.
|
10506 |
+
*
|
10507 |
+
* ```php
|
10508 |
+
* $my_fs = fs_dynamic_init( array(
|
10509 |
+
* // ...
|
10510 |
+
* 'bundle_id' => 'XXXX', // Will return true since we have bundle id.
|
10511 |
+
* 'bundle_public_key' => 'pk_XXXX',
|
10512 |
+
* ) );
|
10513 |
+
* ```
|
10514 |
+
*
|
10515 |
+
* @author Swashata Ghosh (@swashata)
|
10516 |
+
* @since 2.5.0
|
10517 |
+
*
|
10518 |
+
* @return bool True if we are running in bundle context, false otherwise.
|
10519 |
+
*/
|
10520 |
+
private function has_bundle_context() {
|
10521 |
+
return ! is_null( $this->get_bundle_id() );
|
10522 |
+
}
|
10523 |
+
|
10524 |
/**
|
10525 |
* @author Vova Feldman (@svovaf)
|
10526 |
* @since 1.2.1.5
|
10565 |
function get_eula_url() {
|
10566 |
return $this->apply_filters(
|
10567 |
'eula_url',
|
10568 |
+
"https://freemius.com/product/{$this->_plugin->id}/{$this->_slug}/legal/eula/"
|
10569 |
);
|
10570 |
}
|
10571 |
|
10753 |
#endregion ------------------------------------------------------------------
|
10754 |
|
10755 |
/* Account
|
10756 |
+
------------------------------------------------------------------------------------------------------------------*/
|
10757 |
|
10758 |
/**
|
10759 |
* Find plugin's slug by plugin's basename.
|
10817 |
*/
|
10818 |
private static function get_all_sites(
|
10819 |
$module_type = WP_FS__MODULE_TYPE_PLUGIN,
|
10820 |
+
$blog_id = null,
|
10821 |
+
$is_backup = false
|
10822 |
) {
|
10823 |
+
$sites = self::get_account_option(
|
10824 |
+
( $is_backup ? 'prev_' : '' ) . 'sites',
|
10825 |
+
$module_type,
|
10826 |
+
$blog_id
|
10827 |
+
);
|
10828 |
|
10829 |
if ( ! is_array( $sites ) ) {
|
10830 |
$sites = array();
|
11184 |
*
|
11185 |
* @author Vova Feldman (@svovaf)
|
11186 |
* @since 1.0.1
|
11187 |
+
*
|
11188 |
+
* @param bool $ignore_anonymous_state Since 2.5.1
|
11189 |
+
*
|
11190 |
* @return bool
|
11191 |
*/
|
11192 |
+
function is_registered( $ignore_anonymous_state = false ) {
|
11193 |
+
return (
|
11194 |
+
is_object( $this->_user ) &&
|
11195 |
+
(
|
11196 |
+
$this->is_premium() ||
|
11197 |
+
$ignore_anonymous_state ||
|
11198 |
+
! $this->is_anonymous()
|
11199 |
+
)
|
11200 |
+
);
|
11201 |
}
|
11202 |
|
11203 |
/**
|
11208 |
*
|
11209 |
* @return bool
|
11210 |
*/
|
11211 |
+
function is_tracking_allowed( $blog_id = null, $install = null ) {
|
11212 |
+
if ( is_null( $install ) ) {
|
11213 |
+
$install = is_null( $blog_id ) ?
|
11214 |
+
$this->_site :
|
11215 |
+
$this->get_install_by_blog_id( $blog_id );
|
11216 |
+
}
|
11217 |
+
|
11218 |
+
return (
|
11219 |
+
is_object( $install ) &&
|
11220 |
+
FS_Permission_Manager::instance( $this )->is_homepage_url_tracking_allowed( $blog_id )
|
11221 |
+
);
|
11222 |
+
}
|
11223 |
+
|
11224 |
+
/**
|
11225 |
+
* Returns TRUE if the user never opted-in or manually opted-out.
|
11226 |
+
*
|
11227 |
+
* @author Vova Feldman (@svovaf)
|
11228 |
+
* @since 1.2.1.5
|
11229 |
+
*
|
11230 |
+
* @param int|null $blog_id
|
11231 |
+
*
|
11232 |
+
* @return bool
|
11233 |
+
*/
|
11234 |
+
function is_tracking_prohibited( $blog_id = null ) {
|
11235 |
+
return (
|
11236 |
+
! $this->is_registered( true ) ||
|
11237 |
+
! $this->is_tracking_allowed( $blog_id )
|
11238 |
+
);
|
11239 |
}
|
11240 |
|
11241 |
/**
|
11271 |
}
|
11272 |
|
11273 |
/**
|
11274 |
+
* @author Vova Feldman (@svovaf)
|
11275 |
+
* @since 1.0.3
|
11276 |
+
*
|
11277 |
+
* @return FS_Site
|
11278 |
+
*/
|
11279 |
+
function get_site() {
|
11280 |
+
return $this->_site;
|
11281 |
+
}
|
11282 |
+
|
11283 |
+
/**
|
11284 |
+
* @author Leo Fajardo (@leorw)
|
11285 |
+
* @since 2.5.0
|
11286 |
+
*/
|
11287 |
+
function store_site( $site ) {
|
11288 |
+
$this->_site = $site;
|
11289 |
+
$this->_store_site( true );
|
11290 |
+
}
|
11291 |
+
|
11292 |
+
/**
|
11293 |
+
* Deletes the current install with an option to back it up in case restoration will be needed (e.g., if the automatic clone resolution attempt fails).
|
11294 |
+
*
|
11295 |
+
* @author Leo Fajardo (@leorw)
|
11296 |
+
* @since 2.5.0
|
11297 |
+
*/
|
11298 |
+
function delete_current_install( $back_up ) {
|
11299 |
+
// Back up and delete the unique ID.
|
11300 |
+
if ( $back_up ) {
|
11301 |
+
self::$_accounts->set_option( 'prev_unique_id', $this->get_anonymous_id() );
|
11302 |
+
}
|
11303 |
+
|
11304 |
+
self::$_accounts->set_option( 'unique_id', null );
|
11305 |
+
|
11306 |
+
if ( $back_up ) {
|
11307 |
+
// Back up the install before deleting it so that it can be restored later on if necessary (e.g., if the automatic clone resolution attempt fails).
|
11308 |
+
$this->back_up_site();
|
11309 |
+
}
|
11310 |
+
|
11311 |
+
$this->_delete_site();
|
11312 |
+
$this->_site = null;
|
11313 |
+
}
|
11314 |
+
|
11315 |
+
/**
|
11316 |
+
* @author Leo Fajardo (@leorw)
|
11317 |
+
* @since 2.5.0
|
11318 |
*/
|
11319 |
+
function restore_backup_site() {
|
11320 |
+
self::$_accounts->set_option(
|
11321 |
+
'unique_id',
|
11322 |
+
self::$_accounts->get_option( 'prev_unique_id' )
|
11323 |
+
);
|
11324 |
+
|
11325 |
+
$sites = self::get_all_sites( $this->_module_type, null, true );
|
11326 |
+
$this->store_site( clone $sites[ $this->_slug ] );
|
11327 |
}
|
11328 |
|
11329 |
/**
|
12607 |
} else {
|
12608 |
$url = is_object( $site ) ?
|
12609 |
$site->siteurl :
|
12610 |
+
self::get_unfiltered_site_url( $blog_id );
|
12611 |
|
12612 |
$disconnected_site_ids[] = $blog_id;
|
12613 |
}
|
12980 |
} else if ( $is_whitelabeled_flag ) {
|
12981 |
$is_whitelabeled = true;
|
12982 |
} else {
|
12983 |
+
if ( $this->is_registered() || $this->is_premium() ) {
|
12984 |
+
$addon_ids = $this->get_updated_account_addons();
|
12985 |
+
} else {
|
12986 |
+
$addons = self::get_all_addons();
|
12987 |
+
|
12988 |
+
$plugin_addons = isset( $addons[ $this->_plugin->id ] ) ?
|
12989 |
+
$addons[ $this->_plugin->id ] :
|
12990 |
+
array();
|
12991 |
+
|
12992 |
+
$addon_ids = array();
|
12993 |
+
foreach ( $plugin_addons as $addon ) {
|
12994 |
+
$addon_ids[] = $addon->id;
|
12995 |
+
}
|
12996 |
+
}
|
12997 |
+
|
12998 |
$installed_addons = $this->get_installed_addons();
|
12999 |
foreach ( $installed_addons as $fs_addon ) {
|
13000 |
$addon_ids[] = $fs_addon->get_id();
|
13423 |
fs_require_template( 'forms/resend-key.php', $vars );
|
13424 |
}
|
13425 |
|
13426 |
+
/**
|
13427 |
+
* Displays an email address update dialog box when the user clicks on the email address "Edit" button on the "Account" page.
|
13428 |
+
*
|
13429 |
+
* @author Leo Fajardo (@leorw)
|
13430 |
+
* @since 2.5.0
|
13431 |
+
*/
|
13432 |
+
function _add_email_address_update_dialog_box() {
|
13433 |
+
$vars = array( 'id' => $this->_module_id );
|
13434 |
+
|
13435 |
+
fs_require_template( 'forms/email-address-update.php', $vars );
|
13436 |
+
}
|
13437 |
+
|
13438 |
+
/**
|
13439 |
+
* @author Leo Fajardo (@leorw)
|
13440 |
+
* @since 2.5.0
|
13441 |
+
*/
|
13442 |
+
function _add_email_address_update_option() {
|
13443 |
+
if ( ! $this->should_handle_user_change() ) {
|
13444 |
+
return;
|
13445 |
+
}
|
13446 |
+
|
13447 |
+
// Add email address update AJAX handler.
|
13448 |
+
$this->add_ajax_action( 'update_email_address', array( &$this, '_email_address_update_ajax_handler' ) );
|
13449 |
+
}
|
13450 |
+
|
13451 |
+
/**
|
13452 |
+
* @author Leo Fajardo (@leorw)
|
13453 |
+
* @since 2.5.0
|
13454 |
+
*/
|
13455 |
+
function _email_address_update_ajax_handler() {
|
13456 |
+
$this->check_ajax_referer( 'update_email_address' );
|
13457 |
+
|
13458 |
+
$new_email_address = fs_request_get( 'email_address' );
|
13459 |
+
$transfer_type = fs_request_get( 'transfer_type' );
|
13460 |
+
|
13461 |
+
$result = $this->update_email( $new_email_address );
|
13462 |
+
|
13463 |
+
if ( ! FS_Api::is_api_error( $result ) ) {
|
13464 |
+
self::shoot_ajax_success();
|
13465 |
+
}
|
13466 |
+
|
13467 |
+
$error = '';
|
13468 |
+
|
13469 |
+
if ( FS_Api::is_api_error_object( $result ) ) {
|
13470 |
+
switch ( $result->error->code ) {
|
13471 |
+
case 'user_exist':
|
13472 |
+
case 'account_verification_required':
|
13473 |
+
$error = array(
|
13474 |
+
'code' => 'change_ownership',
|
13475 |
+
'url' => $this->get_account_url( 'change_owner', array(
|
13476 |
+
'state' => 'init',
|
13477 |
+
'candidate_email' => $new_email_address,
|
13478 |
+
'transfer_type' => $transfer_type,
|
13479 |
+
) ),
|
13480 |
+
);
|
13481 |
+
|
13482 |
+
break;
|
13483 |
+
}
|
13484 |
+
}
|
13485 |
+
|
13486 |
+
if ( empty( $error ) ) {
|
13487 |
+
$error = is_object( $result ) ?
|
13488 |
+
var_export( $result->error, true ) :
|
13489 |
+
$result;
|
13490 |
+
}
|
13491 |
+
|
13492 |
+
self::shoot_ajax_failure( $error );
|
13493 |
+
}
|
13494 |
+
|
13495 |
/**
|
13496 |
* Returns a collection of IDs of installs that are associated with the context product and its add-ons, and activated with foreign licenses.
|
13497 |
*
|
13699 |
( $is_network_admin && $this->is_network_active() && ! $this->is_network_delegated_connection() ) ||
|
13700 |
( ! $is_network_admin && ( ! $this->is_network_active() || $this->is_delegated_connection() ) )
|
13701 |
) {
|
13702 |
+
if (
|
13703 |
+
$this->is_premium() ||
|
13704 |
+
( $this->has_paid_plan() && ! $this->has_premium_version() )
|
13705 |
+
) {
|
13706 |
+
/**
|
13707 |
+
* @since 1.2.0 Add license action link only on plugins page.
|
13708 |
+
*/
|
13709 |
+
$this->_add_license_action_link();
|
13710 |
+
}
|
13711 |
}
|
13712 |
}
|
13713 |
|
13879 |
self::shoot_ajax_failure();
|
13880 |
}
|
13881 |
|
13882 |
+
$site = $this->api_site_call(
|
13883 |
'',
|
13884 |
'put',
|
13885 |
array(
|
13932 |
fs_request_get( 'blog_id', null ),
|
13933 |
fs_request_get( 'module_id', null, 'post' ),
|
13934 |
fs_request_get( 'user_id', null ),
|
13935 |
+
fs_request_get_bool( 'is_extensions_tracking_allowed', null ),
|
13936 |
+
fs_request_get_bool( 'is_diagnostic_tracking_allowed', null )
|
13937 |
);
|
13938 |
|
13939 |
if (
|
14178 |
* @param null|int $blog_id
|
14179 |
* @param null|number $plugin_id
|
14180 |
* @param null|number $license_owner_id
|
14181 |
+
* @param bool|null $is_extensions_tracking_allowed
|
14182 |
+
* @param bool|null $is_diagnostic_tracking_allowed Since 2.5.0.2 to allow license activation with minimal data footprint.
|
14183 |
+
*
|
14184 |
*
|
14185 |
* @return array {
|
14186 |
* @var bool $success
|
14195 |
$blog_id = null,
|
14196 |
$plugin_id = null,
|
14197 |
$license_owner_id = null,
|
14198 |
+
$is_extensions_tracking_allowed = null,
|
14199 |
+
$is_diagnostic_tracking_allowed = null
|
14200 |
) {
|
14201 |
$this->_logger->entrance();
|
14202 |
|
14216 |
$this :
|
14217 |
$this->get_addon_instance( $plugin_id );
|
14218 |
|
14219 |
+
FS_Permission_Manager::instance( $this )->update_permissions_tracking_flag( array(
|
14220 |
+
FS_Permission_Manager::PERMISSION_DIAGNOSTIC => $is_diagnostic_tracking_allowed,
|
14221 |
+
FS_Permission_Manager::PERMISSION_EXTENSIONS => $is_extensions_tracking_allowed,
|
14222 |
+
) );
|
14223 |
|
14224 |
$error = false;
|
14225 |
$next_page = false;
|
14384 |
}
|
14385 |
}
|
14386 |
|
14387 |
+
$all_sites = self::get_sites();
|
14388 |
+
$pending_blog_ids = array();
|
14389 |
|
14390 |
/**
|
14391 |
* Check if there are any sites that are not connected, skipped, nor delegated. For every site that falls into that category, if the product is freemium, skip the connection. If the product is premium only, delegate the connection to the site administrator.
|
14415 |
continue;
|
14416 |
}
|
14417 |
|
14418 |
+
$pending_blog_ids[] = $blog_id;
|
14419 |
}
|
14420 |
|
14421 |
+
if ( ! empty( $pending_blog_ids ) ) {
|
14422 |
if ( $fs->is_freemium() && $fs->is_enable_anonymous() ) {
|
14423 |
+
$fs->skip_connection( $pending_blog_ids );
|
14424 |
} else {
|
14425 |
+
$fs->delegate_connection( $pending_blog_ids );
|
14426 |
}
|
14427 |
}
|
14428 |
}
|
14500 |
|
14501 |
$addon_info = $fs->_get_addon_info( $addon_id, $is_installed );
|
14502 |
|
14503 |
+
if ( ! isset( $addon_info['is_connected'] ) || ! $addon_info['is_connected'] ) {
|
14504 |
// Add-on is not associated with an install entity.
|
14505 |
continue;
|
14506 |
}
|
14558 |
$this->delegate_connection();
|
14559 |
} else {
|
14560 |
if ( ! empty( $sites_by_action['delegate'] ) ) {
|
14561 |
+
$this->delegate_connection( self::get_sites_blog_ids( $sites_by_action['delegate'] ) );
|
14562 |
}
|
14563 |
|
14564 |
if ( ! empty( $sites_by_action['skip'] ) ) {
|
14565 |
+
$this->skip_connection( self::get_sites_blog_ids( $sites_by_action['skip'] ) );
|
14566 |
}
|
14567 |
|
14568 |
if ( empty( $sites_by_action['allow'] ) ) {
|
14880 |
return $this->_plugin->has_affiliate_program();
|
14881 |
}
|
14882 |
|
14883 |
+
/**
|
14884 |
+
* Get Plugin ID under which we will track affiliate application.
|
14885 |
+
*
|
14886 |
+
* This could either be the Bundle ID or the main plugin ID.
|
14887 |
+
*
|
14888 |
+
* @return number Bundle ID if developer has provided one, else the main plugin ID.
|
14889 |
+
*/
|
14890 |
+
private function get_plugin_id_for_affiliate_terms() {
|
14891 |
+
return $this->has_bundle_context() ?
|
14892 |
+
$this->get_bundle_id() :
|
14893 |
+
$this->_plugin_id;
|
14894 |
+
}
|
14895 |
+
|
14896 |
/**
|
14897 |
* @author Leo Fajardo (@leorw)
|
14898 |
* @since 1.2.4
|
14899 |
*/
|
14900 |
private function fetch_affiliate_terms() {
|
14901 |
if ( ! is_object( $this->plugin_affiliate_terms ) ) {
|
14902 |
+
/**
|
14903 |
+
* In case we have a bundle set in SDK configuration, we would like to use that for affiliates, not the main plugin.
|
14904 |
+
*/
|
14905 |
+
$plugins_api = $this->has_bundle_context() ?
|
14906 |
+
$this->get_api_bundle_scope() :
|
14907 |
+
$this->get_api_plugin_scope();
|
14908 |
+
|
14909 |
$affiliate_terms = $plugins_api->get( '/aff.json?type=affiliation', false );
|
14910 |
|
14911 |
+
/**
|
14912 |
+
* At this point, we intentionally don't fallback to the main plugin, because the developer has chosen to use bundle. So it makes sense the affiliate program should be in context to the bundle too.
|
14913 |
+
*/
|
14914 |
if ( ! $this->is_api_result_entity( $affiliate_terms ) ) {
|
14915 |
return;
|
14916 |
}
|
14928 |
$application_data = $this->_storage->affiliate_application_data;
|
14929 |
$flush = ( ! isset( $application_data['status'] ) || 'pending' === $application_data['status'] );
|
14930 |
|
14931 |
+
$plugin_id_for_affiliate = $this->get_plugin_id_for_affiliate_terms();
|
14932 |
+
|
14933 |
$users_api = $this->get_api_user_scope();
|
14934 |
+
$result = $users_api->get( "/plugins/{$plugin_id_for_affiliate}/aff/{$this->plugin_affiliate_terms->id}/affiliates.json", $flush );
|
14935 |
if ( $this->is_api_result_object( $result, 'affiliates' ) ) {
|
14936 |
if ( ! empty( $result->affiliates ) ) {
|
14937 |
$affiliate = new FS_Affiliate( $result->affiliates[0] );
|
15031 |
var_export( $next_page, true )
|
15032 |
);
|
15033 |
} else if ( $this->is_pending_activation() ) {
|
15034 |
+
self::shoot_ajax_failure( $this->get_text_inline( 'Account is pending activation. Please check your email and click the link to activate your account and then submit the affiliate form again.', 'account-is-pending-activation' ) );
|
15035 |
}
|
15036 |
}
|
15037 |
|
15038 |
$this->fetch_affiliate_terms();
|
15039 |
|
15040 |
+
$plugin_id_for_affiliate = $this->get_plugin_id_for_affiliate_terms();
|
15041 |
+
|
15042 |
$api = $this->get_api_user_scope();
|
15043 |
$result = $api->call(
|
15044 |
+
( "/plugins/{$plugin_id_for_affiliate}/aff/{$this->plugin_affiliate_terms->id}/affiliates.json" ),
|
15045 |
'post',
|
15046 |
$affiliate
|
15047 |
);
|
15503 |
return ( defined( 'DOING_CRON' ) && DOING_CRON );
|
15504 |
}
|
15505 |
|
15506 |
+
/**
|
15507 |
+
* @author Leo Fajardo (@leorw)
|
15508 |
+
* @since 2.5.0
|
15509 |
+
*
|
15510 |
+
* @return bool
|
15511 |
+
*/
|
15512 |
+
static function is_admin_post() {
|
15513 |
+
return ( 'admin-post.php' === self::get_current_page() );
|
15514 |
+
}
|
15515 |
+
|
15516 |
/**
|
15517 |
* Check if a real user is visiting the admin dashboard.
|
15518 |
*
|
15526 |
is_admin() &&
|
15527 |
! self::is_ajax() &&
|
15528 |
! self::is_cron() &&
|
15529 |
+
! self::is_admin_post()
|
15530 |
);
|
15531 |
}
|
15532 |
|
15678 |
* @author Leo Fajardo (@leorw)
|
15679 |
* @since 2.0.0
|
15680 |
*
|
15681 |
+
* @param bool|int[] $all_or_blog_ids
|
15682 |
*/
|
15683 |
+
private function delegate_connection( $all_or_blog_ids = true ) {
|
15684 |
$this->_logger->entrance();
|
15685 |
|
15686 |
$this->_admin_notices->remove_sticky( 'connect_account' );
|
15687 |
|
15688 |
+
if ( true === $all_or_blog_ids ) {
|
15689 |
// All sites delegation.
|
15690 |
+
$this->_storage->store( 'is_delegated_connection', true, true );
|
15691 |
} else {
|
15692 |
// Specified sites delegation.
|
15693 |
+
foreach ( $all_or_blog_ids as $blog_id ) {
|
15694 |
+
$this->delegate_site_connection( $blog_id );
|
15695 |
}
|
15696 |
}
|
15697 |
|
15707 |
* @param int $blog_id
|
15708 |
*/
|
15709 |
private function delegate_site_connection( $blog_id ) {
|
15710 |
+
$this->_storage->store( 'is_delegated_connection', true, $blog_id );
|
15711 |
}
|
15712 |
|
15713 |
/**
|
15747 |
}
|
15748 |
|
15749 |
/**
|
15750 |
+
* Check if delegated the connection. When running within the network admin,
|
15751 |
* and haven't specified the blog ID, checks if network level delegated. If running
|
15752 |
* within a site admin or specified a blog ID, check if delegated the connection for
|
15753 |
* the current context site.
|
15807 |
}
|
15808 |
|
15809 |
/**
|
15810 |
+
* @todo Implement pagination when accessing the subsites collection.
|
15811 |
+
*
|
15812 |
* @author Leo Fajardo (@leorw)
|
15813 |
* @since 2.0.0
|
15814 |
*
|
15815 |
+
* @param int $limit Default to 1,000
|
15816 |
+
* @param int $offset Default to 0
|
15817 |
+
*
|
15818 |
* @return array Active & public sites collection.
|
15819 |
*/
|
15820 |
+
static function get_sites( $limit = 1000, $offset = 0 ) {
|
15821 |
if ( ! is_multisite() ) {
|
15822 |
return array();
|
15823 |
}
|
15839 |
'mature' => 0,
|
15840 |
'spam' => 0,
|
15841 |
'deleted' => 0,
|
15842 |
+
'number' => $limit,
|
15843 |
+
'offset' => $offset,
|
15844 |
);
|
15845 |
|
15846 |
+
return get_sites( $args );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15847 |
}
|
15848 |
|
15849 |
/**
|
15892 |
$address_to_blog_map = array();
|
15893 |
foreach ( $sites as $site ) {
|
15894 |
$blog_id = self::get_site_blog_id( $site );
|
15895 |
+
$address = self::get_unfiltered_site_url( $blog_id, true, true );
|
15896 |
$address_to_blog_map[ $address ] = $blog_id;
|
15897 |
}
|
15898 |
|
15928 |
return $install_map;
|
15929 |
}
|
15930 |
|
15931 |
+
/**
|
15932 |
+
* @author Vova Feldman (@svovaf)
|
15933 |
+
* @since 2.5.1
|
15934 |
+
*
|
15935 |
+
* @param bool|null $is_delegated When `true`, returns only connection delegated blog IDs. When `false`, only non-delegated blog IDs.
|
15936 |
+
*
|
15937 |
+
* @return int[]
|
15938 |
+
*/
|
15939 |
+
private function get_blog_ids( $is_delegated = null ) {
|
15940 |
+
$blog_ids = array();
|
15941 |
+
|
15942 |
+
$sites = self::get_sites();
|
15943 |
+
foreach ( $sites as $site ) {
|
15944 |
+
$blog_id = self::get_site_blog_id( $site );
|
15945 |
+
|
15946 |
+
if (
|
15947 |
+
is_null( $is_delegated ) ||
|
15948 |
+
$is_delegated === $this->is_site_delegated_connection( $blog_id )
|
15949 |
+
) {
|
15950 |
+
$blog_ids[] = $blog_id;
|
15951 |
+
}
|
15952 |
+
}
|
15953 |
+
|
15954 |
+
return $blog_ids;
|
15955 |
+
}
|
15956 |
+
|
15957 |
+
/**
|
15958 |
+
* @author Vova Feldman (@svovaf)
|
15959 |
+
* @since 2.5.1
|
15960 |
+
*
|
15961 |
+
* @return int[]
|
15962 |
+
*/
|
15963 |
+
private function get_non_delegated_blog_ids() {
|
15964 |
+
return $this->get_blog_ids( false );
|
15965 |
+
}
|
15966 |
+
|
15967 |
/**
|
15968 |
* Gets a map of module IDs that the given user has opted-in to.
|
15969 |
*
|
16048 |
*
|
16049 |
* @param int $blog_id
|
16050 |
* @param FS_Site $install
|
16051 |
+
* @param bool $flush
|
16052 |
*
|
16053 |
* @return bool Since 2.3.1 returns if a switch was made.
|
16054 |
*/
|
16055 |
+
function switch_to_blog( $blog_id, FS_Site $install = null, $flush = false ) {
|
16056 |
+
if ( ! is_numeric( $blog_id ) ) {
|
16057 |
+
return false;
|
16058 |
+
}
|
16059 |
+
|
16060 |
+
if ( ! $flush && $blog_id == $this->_context_is_network_or_blog_id ) {
|
16061 |
return false;
|
16062 |
}
|
16063 |
|
16121 |
unset( $this->_site_api );
|
16122 |
unset( $this->_user_api );
|
16123 |
|
16124 |
+
return true;
|
16125 |
}
|
16126 |
|
16127 |
/**
|
16150 |
$site['blog_id'] );
|
16151 |
}
|
16152 |
|
16153 |
+
/**
|
16154 |
+
* @author Vova Feldman (@svovaf)
|
16155 |
+
* @since 2.5.1
|
16156 |
+
*
|
16157 |
+
* @param WP_Site[]|array[] $sites
|
16158 |
+
*
|
16159 |
+
* @return int[]
|
16160 |
+
*/
|
16161 |
+
static function get_sites_blog_ids( $sites ) {
|
16162 |
+
$blog_ids = array();
|
16163 |
+
foreach ( $sites as $site ) {
|
16164 |
+
$blog_ids[] = self::get_site_blog_id( $site );
|
16165 |
+
}
|
16166 |
+
|
16167 |
+
return $blog_ids;
|
16168 |
+
}
|
16169 |
+
|
16170 |
/**
|
16171 |
* @author Leo Fajardo (@leorw)
|
16172 |
* @since 2.0.0
|
16173 |
*
|
16174 |
* @param array|WP_Site|null $site
|
16175 |
+
* @param bool $load_registration Since 2.5.1 When set to `true` the method will attempt to return the subsite's registration date, regardless of the `$site` type and value. In most calls, the registration date will be returned anyway, even when the value is `false`. This param is purely for performance optimization.
|
16176 |
*
|
16177 |
* @return array
|
16178 |
*/
|
16179 |
+
function get_site_info( $site = null, $load_registration = false ) {
|
16180 |
$this->_logger->entrance();
|
16181 |
|
16182 |
$switched = false;
|
16183 |
|
16184 |
+
$registration_date = null;
|
16185 |
+
|
16186 |
if ( is_null( $site ) ) {
|
16187 |
+
$url = self::get_unfiltered_site_url();
|
16188 |
$name = get_bloginfo( 'name' );
|
16189 |
$blog_id = null;
|
16190 |
} else {
|
16196 |
}
|
16197 |
|
16198 |
if ( $site instanceof WP_Site ) {
|
16199 |
+
$url = $site->siteurl;
|
16200 |
+
$name = $site->blogname;
|
16201 |
+
$registration_date = $site->registered;
|
16202 |
} else {
|
16203 |
+
$url = self::get_unfiltered_site_url( $blog_id );
|
16204 |
$name = get_bloginfo( 'name' );
|
16205 |
}
|
16206 |
}
|
16207 |
|
16208 |
+
if ( empty( $registration_date ) && $load_registration ) {
|
16209 |
+
$blog_details = get_blog_details( $blog_id, false );
|
16210 |
+
|
16211 |
+
if ( is_object( $blog_details ) && isset( $blog_details->registered ) ) {
|
16212 |
+
$registration_date = $blog_details->registered;
|
16213 |
+
}
|
16214 |
+
}
|
16215 |
+
|
16216 |
$info = array(
|
16217 |
+
'uid' => $this->get_anonymous_id( $blog_id ),
|
16218 |
+
'url' => $url,
|
|
|
|
|
|
|
16219 |
);
|
16220 |
|
16221 |
+
// Add these diagnostic information only if user allowed to track.
|
16222 |
+
if ( FS_Permission_Manager::instance( $this )->is_diagnostic_tracking_allowed() ) {
|
16223 |
+
$info = array_merge( $info, array(
|
16224 |
+
'title' => $name,
|
16225 |
+
'language' => self::get_sanitized_language(),
|
16226 |
+
) );
|
16227 |
+
}
|
16228 |
+
|
16229 |
if ( is_numeric( $blog_id ) ) {
|
16230 |
$info['blog_id'] = $blog_id;
|
16231 |
}
|
16232 |
|
16233 |
+
if ( ! empty( $registration_date ) ) {
|
16234 |
+
$info[ 'registration_date' ] = $registration_date;
|
16235 |
+
}
|
16236 |
+
|
16237 |
if ( $switched ) {
|
16238 |
restore_current_blog();
|
16239 |
}
|
16456 |
}
|
16457 |
}
|
16458 |
|
16459 |
+
if ( ! $this->is_registered() ) {
|
16460 |
+
return;
|
16461 |
+
}
|
16462 |
+
|
16463 |
if ( $this->is_sync_cron_scheduled() &&
|
16464 |
$context_blog_id == $this->get_sync_cron_blog_id()
|
16465 |
) {
|
16493 |
|
16494 |
$this->update_multisite_data_after_site_deactivation( $context_blog_id );
|
16495 |
|
16496 |
+
if ( ! $this->is_registered() ) {
|
16497 |
+
return;
|
16498 |
+
}
|
16499 |
+
|
16500 |
$current_blog_id = get_current_blog_id();
|
16501 |
|
16502 |
$this->switch_to_blog( $context_blog_id );
|
16530 |
|
16531 |
$this->update_multisite_data_after_site_deactivation( $context_blog_id );
|
16532 |
|
16533 |
+
if ( ! $this->is_registered() ) {
|
16534 |
+
return;
|
16535 |
+
}
|
16536 |
+
|
16537 |
$current_blog_id = get_current_blog_id();
|
16538 |
|
16539 |
$this->switch_to_blog( $context_blog_id );
|
16551 |
$this->switch_to_blog( $current_blog_id );
|
16552 |
}
|
16553 |
|
16554 |
+
/**
|
16555 |
+
* Executed after site deletion, called from wp_delete_site
|
16556 |
+
*
|
16557 |
+
* @author Dario Curvino (@dudo)
|
16558 |
+
* @since 2.5.0
|
16559 |
+
*
|
16560 |
+
* @param WP_Site $old_site
|
16561 |
+
*/
|
16562 |
+
public function _after_wpsite_deleted_callback( WP_Site $old_site ) {
|
16563 |
+
$this->_logger->entrance();
|
16564 |
+
|
16565 |
+
$this->_after_site_deleted_callback( $old_site->blog_id, true );
|
16566 |
+
}
|
16567 |
+
|
16568 |
/**
|
16569 |
* Executed after site re-activation.
|
16570 |
*
|
16679 |
* @return bool
|
16680 |
*/
|
16681 |
function is_product_settings_page() {
|
16682 |
+
$page = fs_request_get( 'page', '', 'get' );
|
16683 |
+
$menu_slug = $this->_menu->get_slug();
|
16684 |
+
|
16685 |
+
if ( $page === $menu_slug ) {
|
16686 |
+
return true;
|
16687 |
+
}
|
16688 |
+
|
16689 |
return fs_starts_with(
|
16690 |
+
// e.g., {$menu_slug}-account, {$menu_slug}-affiliation, etc.
|
16691 |
+
$page,
|
16692 |
+
( $menu_slug . '-' )
|
16693 |
);
|
16694 |
}
|
16695 |
|
16769 |
*
|
16770 |
* @param bool|string $topic
|
16771 |
* @param bool|string $message
|
16772 |
+
* @param bool|string $summary Since 2.5.1.
|
16773 |
*
|
16774 |
* @return string
|
16775 |
*/
|
16776 |
+
function contact_url( $topic = false, $message = false, $summary = false ) {
|
16777 |
$params = array();
|
16778 |
if ( is_string( $topic ) ) {
|
16779 |
$params['topic'] = $topic;
|
16782 |
$params['message'] = $message;
|
16783 |
}
|
16784 |
|
16785 |
+
if ( is_string( $summary ) ) {
|
16786 |
+
$params['summary'] = $summary;
|
16787 |
+
}
|
16788 |
+
|
16789 |
if ( $this->is_addon() ) {
|
16790 |
$params['addon_id'] = $this->get_id();
|
16791 |
|
16824 |
}
|
16825 |
|
16826 |
/* Logger
|
16827 |
+
------------------------------------------------------------------------------------------------------------------*/
|
16828 |
/**
|
16829 |
* @param string $id
|
16830 |
* @param bool $prefix_slug
|
16849 |
}
|
16850 |
|
16851 |
/* Security
|
16852 |
+
------------------------------------------------------------------------------------------------------------------*/
|
16853 |
private static function _encrypt( $str ) {
|
16854 |
if ( is_null( $str ) ) {
|
16855 |
return null;
|
17069 |
) {
|
17070 |
// Load site.
|
17071 |
$this->_site = $site;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17072 |
}
|
17073 |
|
17074 |
$user = null;
|
17097 |
/**
|
17098 |
* This is a special fault tolerance mechanism to handle a scenario that the user data is missing.
|
17099 |
*/
|
17100 |
+
if (
|
17101 |
+
! isset( $this->_storage->user_recovery_from_install_last_attempt_timestamp ) ||
|
17102 |
+
time() > ( $this->_storage->user_recovery_from_install_last_attempt_timestamp + FS_Clone_Manager::CLONE_RESOLUTION_MAX_EXECUTION_TIME )
|
17103 |
+
) {
|
17104 |
+
$user = $this->sync_user_by_current_install();
|
17105 |
+
} else {
|
17106 |
+
return;
|
17107 |
+
}
|
17108 |
+
|
17109 |
+
if ( is_object( $user ) ) {
|
17110 |
+
$this->_storage->user_was_recovered_from_install = true;
|
17111 |
+
} else {
|
17112 |
+
$this->_storage->user_recovery_from_install_attempts = isset( $this->_storage->user_recovery_from_install_attempts ) ?
|
17113 |
+
( $this->_storage->user_recovery_from_install_attempts + 1 ) :
|
17114 |
+
1;
|
17115 |
+
|
17116 |
+
if ( $this->_storage->user_recovery_from_install_attempts >= 3 ) {
|
17117 |
+
$this->delete_current_install( false );
|
17118 |
+
} else {
|
17119 |
+
$this->_storage->user_recovery_from_install_last_attempt_timestamp = time();
|
17120 |
+
|
17121 |
+
return;
|
17122 |
+
}
|
17123 |
+
}
|
17124 |
}
|
17125 |
|
17126 |
$this->_user = ( $user instanceof FS_User ) ?
|
17134 |
}
|
17135 |
|
17136 |
if ( is_object( $this->_site ) ) {
|
17137 |
+
// Load plans.
|
17138 |
+
$this->_plans = isset( $plans[ $this->_slug ] ) ?
|
17139 |
+
$plans[ $this->_slug ] :
|
17140 |
+
array();
|
17141 |
+
|
17142 |
+
if ( ! is_array( $this->_plans ) || empty( $this->_plans ) ) {
|
17143 |
+
$this->_sync_plans();
|
17144 |
+
} else {
|
17145 |
+
for ( $i = 0, $len = count( $this->_plans ); $i < $len; $i ++ ) {
|
17146 |
+
if ( $this->_plans[ $i ] instanceof FS_Plugin_Plan ) {
|
17147 |
+
$this->_plans[ $i ] = self::decrypt_entity( $this->_plans[ $i ] );
|
17148 |
+
} else {
|
17149 |
+
unset( $this->_plans[ $i ] );
|
17150 |
+
}
|
17151 |
+
}
|
17152 |
+
}
|
17153 |
+
|
17154 |
$this->_license = $this->_get_license_by_id( $this->_site->license_id );
|
17155 |
|
17156 |
if ( $this->_site->version != $this->get_plugin_version() ) {
|
17169 |
if ( $this->is_theme() ) {
|
17170 |
$this->_register_account_hooks();
|
17171 |
}
|
17172 |
+
|
17173 |
+
if ( $this->is_user_in_admin() && $this->is_clone() ) {
|
17174 |
+
if ( empty( FS_Clone_Manager::instance()->get_clone_identification_timestamp() ) ) {
|
17175 |
+
FS_Clone_Manager::instance()->store_clone_identification_timestamp();
|
17176 |
+
}
|
17177 |
+
|
17178 |
+
FS_Clone_Manager::instance()->maybe_update_clone_resolution_support_flag( $this->_storage->sdk_last_version );
|
17179 |
+
$this->send_pending_clone_update_once();
|
17180 |
+
}
|
17181 |
}
|
17182 |
|
17183 |
/**
|
17257 |
*/
|
17258 |
private function get_versions() {
|
17259 |
$versions = array();
|
17260 |
+
$versions['sdk_version'] = $this->version;
|
17261 |
+
|
17262 |
+
// Collect these diagnostic information only if it's allowed.
|
17263 |
+
if ( FS_Permission_Manager::instance( $this )->is_diagnostic_tracking_allowed() ) {
|
17264 |
+
$versions['platform_version'] = get_bloginfo( 'version' );
|
17265 |
+
$versions['programming_language_version'] = phpversion();
|
17266 |
+
}
|
17267 |
+
|
17268 |
+
foreach ( $versions as $k => $version ) {
|
17269 |
+
$versions[ $k ] = self::get_api_sanitized_property( $k, $version );
|
17270 |
+
}
|
17271 |
+
|
17272 |
+
return $versions;
|
17273 |
+
}
|
17274 |
+
|
17275 |
+
/**
|
17276 |
+
* Get sanitized site language.
|
17277 |
+
*
|
17278 |
+
* @param string $language
|
17279 |
+
* @param int $max_len
|
17280 |
+
*
|
17281 |
+
* @since 2.5.1
|
17282 |
+
* @author Vova Feldman (@svovaf)
|
17283 |
+
*
|
17284 |
+
* @return string
|
17285 |
+
*/
|
17286 |
+
private static function get_sanitized_language( $language = '', $max_len = self::LANGUAGE_MAX_CHARS ) {
|
17287 |
+
if ( empty( $language ) ) {
|
17288 |
+
$language = get_bloginfo( 'language' );
|
17289 |
+
}
|
17290 |
+
|
17291 |
+
return substr( $language, 0, $max_len );
|
17292 |
+
}
|
17293 |
+
|
17294 |
+
/**
|
17295 |
+
* Get core version stripped from pre-release and build.
|
17296 |
+
*
|
17297 |
+
* @since 2.5.1
|
17298 |
+
* @author Vova Feldman (@svovaf)
|
17299 |
+
*
|
17300 |
+
* @param string $version
|
17301 |
+
* @param int $parts
|
17302 |
+
* @param int $max_len
|
17303 |
+
* @param bool $include_pre_release
|
17304 |
+
*
|
17305 |
+
* @return string
|
17306 |
+
*/
|
17307 |
+
private static function get_core_version(
|
17308 |
+
$version,
|
17309 |
+
$parts = 3,
|
17310 |
+
$max_len = self::VERSION_MAX_CHARS,
|
17311 |
+
$include_pre_release = false
|
17312 |
+
) {
|
17313 |
+
if ( empty( $version ) ) {
|
17314 |
+
// Version is empty.
|
17315 |
+
return '';
|
17316 |
+
}
|
17317 |
+
|
17318 |
+
if ( is_numeric( $version ) ) {
|
17319 |
+
$is_float_version = is_float( $version );
|
17320 |
+
|
17321 |
+
$version = (string) $version;
|
17322 |
+
|
17323 |
+
/**
|
17324 |
+
* Casting a whole float number to a string cuts the decimal point. This part make sure to add the missing decimal part to the version.
|
17325 |
+
*/
|
17326 |
+
if ( $is_float_version && false === strpos( $version, '.' ) ) {
|
17327 |
+
$version .= '.0';
|
17328 |
+
}
|
17329 |
+
}
|
17330 |
+
|
17331 |
+
if ( ! is_string( $version ) ) {
|
17332 |
+
return '';
|
17333 |
+
}
|
17334 |
+
|
17335 |
+
if ( $parts < 1 ) {
|
17336 |
+
return '';
|
17337 |
+
}
|
17338 |
+
|
17339 |
+
$pre_release_regex = $include_pre_release ?
|
17340 |
+
'(\-(alpha|beta|RC)([0-9]+)?)?' :
|
17341 |
+
'';
|
17342 |
|
17343 |
+
if ( 0 === preg_match( '/^([0-9]+(\.[0-9]+){0,' . ( $parts - 1 ) . '}' . $pre_release_regex . ')/i', $version, $matches ) ) {
|
17344 |
+
// Version is not starting with a digit.
|
17345 |
+
return '';
|
|
|
17346 |
}
|
17347 |
|
17348 |
+
return substr( $matches[1], 0, $max_len );
|
17349 |
+
}
|
17350 |
+
|
17351 |
+
/**
|
17352 |
+
* @param string $prop
|
17353 |
+
* @param mixed $val
|
17354 |
+
*
|
17355 |
+
* @return mixed
|
17356 |
+
*@author Vova Feldman (@svovaf)
|
17357 |
+
*
|
17358 |
+
* @since 2.5.1
|
17359 |
+
*/
|
17360 |
+
private static function get_api_sanitized_property( $prop, $val ) {
|
17361 |
+
if ( ! is_string( $val ) || empty( $val ) ) {
|
17362 |
+
return $val;
|
17363 |
+
}
|
17364 |
+
|
17365 |
+
switch ( $prop ) {
|
17366 |
+
case 'programming_language_version':
|
17367 |
+
// Get core PHP version, which can have up to 3 parts (ignore pre-releases).
|
17368 |
+
return self::get_core_version( $val );
|
17369 |
+
case 'platform_version':
|
17370 |
+
// Get the exact WordPress version, which can have up to 3 parts (including pre-releases).
|
17371 |
+
return self::get_core_version( $val, 3, self::VERSION_MAX_CHARS, true );
|
17372 |
+
case 'sdk_version':
|
17373 |
+
// Get the exact SDK version, which can have up to 4 parts.
|
17374 |
+
return self::get_core_version( $val, 4 );
|
17375 |
+
case 'version':
|
17376 |
+
// Get the entire version but just limited in length.
|
17377 |
+
return substr( $val, 0, self::VERSION_MAX_CHARS );
|
17378 |
+
case 'language':
|
17379 |
+
return self::get_sanitized_language( $val );
|
17380 |
+
default:
|
17381 |
+
return $val;
|
17382 |
+
}
|
17383 |
}
|
17384 |
|
17385 |
/**
|
17434 |
$versions = $this->get_versions();
|
17435 |
|
17436 |
$params = array_merge( $versions, array(
|
17437 |
+
'user_firstname' => $current_user->user_firstname,
|
17438 |
+
'user_lastname' => $current_user->user_lastname,
|
17439 |
+
'user_email' => $current_user->user_email,
|
17440 |
+
'plugin_slug' => $this->_slug,
|
17441 |
+
'plugin_id' => $this->get_id(),
|
17442 |
+
'plugin_public_key' => $this->get_public_key(),
|
17443 |
+
'plugin_version' => $this->get_plugin_version(),
|
17444 |
+
'return_url' => fs_nonce_url( $return_url, $activation_action ),
|
17445 |
+
'account_url' => fs_nonce_url( $this->_get_admin_page_url(
|
|
|
|
|
17446 |
'account',
|
17447 |
array( 'fs_action' => 'sync_user' )
|
17448 |
), 'sync_user' ),
|
17449 |
+
'is_premium' => $this->is_premium(),
|
17450 |
+
'is_active' => true,
|
17451 |
+
'is_uninstalled' => false,
|
17452 |
+
'is_localhost' => WP_FS__IS_LOCALHOST,
|
17453 |
) );
|
17454 |
|
17455 |
if ( $this->is_addon() ) {
|
17470 |
|
17471 |
$site = $this->get_site_info( $site );
|
17472 |
|
17473 |
+
$diagnostic_info = array();
|
17474 |
+
if ( FS_Permission_Manager::instance( $this )->is_diagnostic_tracking_allowed() ) {
|
17475 |
+
$diagnostic_info = array(
|
17476 |
+
'site_name' => $site['title'],
|
17477 |
+
'language' => self::get_sanitized_language( $site['language'] ),
|
17478 |
+
);
|
17479 |
+
}
|
17480 |
+
|
17481 |
+
$params = array_merge( $params, $diagnostic_info, array(
|
17482 |
'site_uid' => $site['uid'],
|
17483 |
'site_url' => $site['url'],
|
|
|
|
|
|
|
17484 |
) );
|
17485 |
}
|
17486 |
|
17505 |
);
|
17506 |
}
|
17507 |
|
17508 |
+
if ( is_multisite() && function_exists( 'get_network' ) ) {
|
17509 |
+
$params['network_uid'] = $this->get_anonymous_network_id();
|
17510 |
+
}
|
17511 |
+
|
17512 |
return array_merge( $params, $override_with );
|
17513 |
}
|
17514 |
|
17527 |
* In this case, the user and site info will be sent to the server but no
|
17528 |
* data will be saved to the WP installation's database.
|
17529 |
* @param number|bool $trial_plan_id
|
17530 |
+
* @param bool $is_disconnected Whether to opt in without tracking.
|
17531 |
* @param null|bool $is_marketing_allowed
|
17532 |
* @param array $sites If network-level opt-in, an array of containing details of sites.
|
17533 |
+
* @param bool $redirect
|
17534 |
*
|
17535 |
* @return string|object
|
17536 |
* @use WP_Error
|
17544 |
$trial_plan_id = false,
|
17545 |
$is_disconnected = false,
|
17546 |
$is_marketing_allowed = null,
|
17547 |
+
$sites = array(),
|
17548 |
+
$redirect = true
|
17549 |
) {
|
17550 |
$this->_logger->entrance();
|
17551 |
|
17569 |
$fs_user,
|
17570 |
false,
|
17571 |
$trial_plan_id,
|
17572 |
+
$redirect,
|
17573 |
true,
|
17574 |
$sites
|
17575 |
);
|
17637 |
$params['is_marketing_allowed'] = $is_marketing_allowed;
|
17638 |
}
|
17639 |
|
17640 |
+
$params['is_disconnected'] = $is_disconnected;
|
17641 |
+
$params['format'] = 'json';
|
17642 |
+
$params['is_extensions_tracking_allowed'] = FS_Permission_Manager::instance( $this )->is_extensions_tracking_allowed();
|
17643 |
+
$params['is_diagnostic_tracking_allowed'] = FS_Permission_Manager::instance( $this )->is_diagnostic_tracking_allowed();
|
17644 |
|
17645 |
$request = array(
|
17646 |
'method' => 'POST',
|
17647 |
'body' => $params,
|
17648 |
+
'timeout' => 60,
|
17649 |
);
|
17650 |
|
17651 |
$url = $this->add_show_pending( WP_FS__ADDRESS . '/action/service/user/install/' );
|
17731 |
true ),
|
17732 |
false,
|
17733 |
$filtered_license_key,
|
17734 |
+
! empty( $params['trial_plan_id'] ),
|
17735 |
+
isset( $decoded->is_suspicious_email ) && $decoded->is_suspicious_email
|
17736 |
);
|
17737 |
} else if ( isset( $decoded->install_secret_key ) ) {
|
17738 |
return $this->install_with_new_user(
|
17745 |
( isset( $decoded->is_extensions_tracking_allowed ) && ! is_null( $decoded->is_extensions_tracking_allowed ) ?
|
17746 |
$decoded->is_extensions_tracking_allowed :
|
17747 |
null ),
|
17748 |
+
( isset( $decoded->is_diagnostic_tracking_allowed ) && ! is_null( $decoded->is_diagnostic_tracking_allowed ) ?
|
17749 |
+
$decoded->is_diagnostic_tracking_allowed :
|
17750 |
+
null ),
|
17751 |
$decoded->install_id,
|
17752 |
$decoded->install_public_key,
|
17753 |
$decoded->install_secret_key,
|
17764 |
( isset( $decoded->is_extensions_tracking_allowed ) && ! is_null( $decoded->is_extensions_tracking_allowed ) ?
|
17765 |
$decoded->is_extensions_tracking_allowed :
|
17766 |
null ),
|
17767 |
+
( isset( $decoded->is_diagnostic_tracking_allowed ) && ! is_null( $decoded->is_diagnostic_tracking_allowed ) ?
|
17768 |
+
$decoded->is_diagnostic_tracking_allowed :
|
17769 |
+
null ),
|
17770 |
$decoded->installs,
|
17771 |
false
|
17772 |
);
|
17864 |
$this->_admin_notices->remove_sticky( 'connect_account' );
|
17865 |
|
17866 |
if ( $this->is_pending_activation() || ! $this->has_settings_menu() ) {
|
17867 |
+
$this->clear_pending_activation_mode();
|
|
|
|
|
|
|
|
|
17868 |
|
17869 |
if ( ! $this->is_paying_or_trial() ) {
|
17870 |
$this->_admin_notices->add_sticky(
|
17871 |
+
sprintf( $this->get_text_inline( '%s opt-in was successfully completed.', 'plugin-x-activation-message' ), '<b>' . $this->get_plugin_name() . '</b>' ),
|
17872 |
'activation_complete'
|
17873 |
);
|
17874 |
}
|
17990 |
fs_request_get( 'user_secret_key' ),
|
17991 |
fs_request_get_bool( 'is_marketing_allowed', null ),
|
17992 |
fs_request_get_bool( 'is_extensions_tracking_allowed', null ),
|
17993 |
+
fs_request_get_bool( 'is_diagnostic_tracking_allowed', null ),
|
17994 |
$pending_sites_info['blog_ids'],
|
17995 |
$pending_sites_info['license_key'],
|
17996 |
$pending_sites_info['trial_plan_id']
|
18002 |
fs_request_get( 'user_secret_key' ),
|
18003 |
fs_request_get_bool( 'is_marketing_allowed', null ),
|
18004 |
fs_request_get_bool( 'is_extensions_tracking_allowed', null ),
|
18005 |
+
fs_request_get_bool( 'is_diagnostic_tracking_allowed', null ),
|
18006 |
fs_request_get( 'install_id' ),
|
18007 |
fs_request_get( 'install_public_key' ),
|
18008 |
fs_request_get( 'install_secret_key' ),
|
18011 |
);
|
18012 |
}
|
18013 |
} else if ( fs_request_has( 'pending_activation' ) ) {
|
18014 |
+
$this->set_pending_confirmation(
|
18015 |
+
fs_request_get( 'user_email' ),
|
18016 |
+
true,
|
18017 |
+
false,
|
18018 |
+
false,
|
18019 |
+
fs_request_get_bool( 'is_suspicious_email' )
|
18020 |
+
);
|
18021 |
}
|
18022 |
}
|
18023 |
}
|
18065 |
* @param string $user_secret_key
|
18066 |
* @param bool|null $is_marketing_allowed
|
18067 |
* @param bool|null $is_extensions_tracking_allowed Since 2.3.2
|
18068 |
+
* @param bool|null $is_diagnostic_tracking_allowed Since 2.5.0.2
|
18069 |
* @param number $install_id
|
18070 |
* @param string $install_public_key
|
18071 |
* @param string $install_secret_key
|
18080 |
$user_secret_key,
|
18081 |
$is_marketing_allowed,
|
18082 |
$is_extensions_tracking_allowed,
|
18083 |
+
$is_diagnostic_tracking_allowed,
|
18084 |
$install_id,
|
18085 |
$install_public_key,
|
18086 |
$install_secret_key,
|
18114 |
$site->secret_key = $install_secret_key;
|
18115 |
|
18116 |
$this->_site = $site;
|
18117 |
+
$site_result = $this->get_api_site_scope( true )->get();
|
18118 |
$site = new FS_Site( $site_result );
|
18119 |
$this->_site = $site;
|
18120 |
|
18122 |
$this->disable_opt_in_notice_and_lock_user();
|
18123 |
}
|
18124 |
|
18125 |
+
FS_Permission_Manager::instance( $this )->update_permissions_tracking_flag( array(
|
18126 |
+
FS_Permission_Manager::PERMISSION_DIAGNOSTIC => $is_diagnostic_tracking_allowed,
|
18127 |
+
FS_Permission_Manager::PERMISSION_EXTENSIONS => $is_extensions_tracking_allowed,
|
18128 |
+
) );
|
18129 |
|
18130 |
return $this->setup_account(
|
18131 |
$this->_user,
|
18146 |
* @param string $user_secret_key
|
18147 |
* @param bool|null $is_marketing_allowed
|
18148 |
* @param bool|null $is_extensions_tracking_allowed Since 2.3.2
|
18149 |
+
* @param bool|null $is_diagnostic_tracking_allowed Since 2.5.0.2
|
18150 |
* @param array $site_ids
|
18151 |
* @param bool $license_key
|
18152 |
* @param bool $trial_plan_id
|
18160 |
$user_secret_key,
|
18161 |
$is_marketing_allowed,
|
18162 |
$is_extensions_tracking_allowed,
|
18163 |
+
$is_diagnostic_tracking_allowed,
|
18164 |
$site_ids,
|
18165 |
$license_key = false,
|
18166 |
$trial_plan_id = false,
|
18172 |
$this->disable_opt_in_notice_and_lock_user();
|
18173 |
}
|
18174 |
|
18175 |
+
FS_Permission_Manager::instance( $this )->update_permissions_tracking_flag( array(
|
18176 |
+
FS_Permission_Manager::PERMISSION_DIAGNOSTIC => $is_diagnostic_tracking_allowed,
|
18177 |
+
FS_Permission_Manager::PERMISSION_EXTENSIONS => $is_extensions_tracking_allowed,
|
18178 |
+
) );
|
18179 |
|
18180 |
$sites = array();
|
18181 |
foreach ( $site_ids as $site_id ) {
|
18196 |
* @param string $user_secret_key
|
18197 |
* @param bool|null $is_marketing_allowed
|
18198 |
* @param bool|null $is_extensions_tracking_allowed Since 2.3.2
|
18199 |
+
* @param bool|null $is_diagnostic_tracking_allowed Since 2.5.0.2
|
18200 |
* @param object[] $installs
|
18201 |
* @param bool $redirect
|
18202 |
* @param bool $auto_install Since 1.2.1.7 If `true` and setting up an account with a valid license, will redirect (or return a URL) to the account page with a special parameter to trigger the auto installation processes.
|
18209 |
$user_secret_key,
|
18210 |
$is_marketing_allowed,
|
18211 |
$is_extensions_tracking_allowed,
|
18212 |
+
$is_diagnostic_tracking_allowed,
|
18213 |
array $installs,
|
18214 |
$redirect = true,
|
18215 |
$auto_install = false
|
18220 |
$this->disable_opt_in_notice_and_lock_user();
|
18221 |
}
|
18222 |
|
18223 |
+
FS_Permission_Manager::instance( $this )->update_permissions_tracking_flag( array(
|
18224 |
+
FS_Permission_Manager::PERMISSION_DIAGNOSTIC => $is_diagnostic_tracking_allowed,
|
18225 |
+
FS_Permission_Manager::PERMISSION_EXTENSIONS => $is_extensions_tracking_allowed,
|
18226 |
+
) );
|
18227 |
|
18228 |
$install_ids = array();
|
18229 |
|
18231 |
$install_ids[] = $install->id;
|
18232 |
}
|
18233 |
|
18234 |
+
$items_per_request = 25;
|
18235 |
+
$left = count( $install_ids );
|
18236 |
+
$offset = 0;
|
18237 |
|
18238 |
$installs = array();
|
18239 |
while ( $left > 0 ) {
|
18240 |
+
$result = $this->get_api_user_scope()->get( "/plugins/{$this->_module_id}/installs.json?ids=" . implode( ',', array_slice( $install_ids, $offset, $items_per_request ) ) );
|
18241 |
|
18242 |
if ( ! $this->is_api_result_object( $result, 'installs' ) ) {
|
18243 |
// @todo Handle API error.
|
18245 |
|
18246 |
$installs = array_merge( $installs, $result->installs );
|
18247 |
|
18248 |
+
$left -= $items_per_request;
|
18249 |
+
$offset += $items_per_request;
|
18250 |
}
|
18251 |
|
18252 |
foreach ( $installs as &$install ) {
|
18276 |
$email = false,
|
18277 |
$redirect = true,
|
18278 |
$license_key = false,
|
18279 |
+
$is_pending_trial = false,
|
18280 |
+
$is_suspicious_email = false
|
18281 |
) {
|
18282 |
if ( $this->_ignore_pending_mode ) {
|
18283 |
/**
|
18287 |
* @author Vova Feldman
|
18288 |
* @since 1.2.1.6
|
18289 |
*/
|
18290 |
+
$this->skip_connection( fs_is_network_admin() );
|
18291 |
} else {
|
18292 |
// Install must be activated via email since
|
18293 |
// user with the same email already exist.
|
18294 |
$this->_storage->is_pending_activation = true;
|
18295 |
+
$this->_add_pending_activation_notice( $email, $is_pending_trial, $is_suspicious_email );
|
18296 |
}
|
18297 |
|
18298 |
if ( ! empty( $license_key ) ) {
|
18307 |
|
18308 |
$next_page = $this->get_after_activation_url( 'after_pending_connect_url' );
|
18309 |
|
|
|
18310 |
if ( $redirect ) {
|
18311 |
+
// Reload the page with a pending activation message.
|
18312 |
fs_redirect( $next_page );
|
18313 |
}
|
18314 |
|
18337 |
*/
|
18338 |
$license_key = fs_request_get( 'license_secret_key' );
|
18339 |
|
18340 |
+
FS_Permission_Manager::instance( $this )->update_permissions_tracking_flag( array(
|
18341 |
+
FS_Permission_Manager::PERMISSION_DIAGNOSTIC => fs_request_get_bool( 'is_diagnostic_tracking_allowed', null ),
|
18342 |
+
FS_Permission_Manager::PERMISSION_EXTENSIONS => fs_request_get_bool( 'is_extensions_tracking_allowed', null ),
|
18343 |
+
) );
|
18344 |
|
18345 |
$this->install_with_current_user( $license_key );
|
18346 |
}
|
18358 |
*
|
18359 |
* @return object|string If redirect is `false`, returns the next page the user should be redirected to, or the API error object if failed to install.
|
18360 |
*/
|
18361 |
+
function install_with_current_user(
|
18362 |
$license_key = false,
|
18363 |
$trial_plan_id = false,
|
18364 |
$sites = array(),
|
18741 |
$this->send_installs_update();
|
18742 |
}
|
18743 |
|
|
|
|
|
|
|
18744 |
$current_blog = get_current_blog_id();
|
18745 |
|
18746 |
foreach ( $blog_2_install_map as $blog_id => $install ) {
|
18749 |
$this->do_action( 'after_account_connection', $this->_user, $install );
|
18750 |
}
|
18751 |
|
18752 |
+
// Switch install context back to the first install.
|
18753 |
+
$this->switch_to_blog(
|
18754 |
+
$current_blog,
|
18755 |
+
$first_install,
|
18756 |
+
( $this->_site->id != $first_install->id )
|
18757 |
+
);
|
18758 |
|
18759 |
$this->do_action( 'after_network_account_connection', $this->_user, $blog_2_install_map );
|
18760 |
}
|
18802 |
$parent_fs->_admin_notices->remove_sticky( 'connect_account' );
|
18803 |
|
18804 |
if ( $parent_fs->is_pending_activation() ) {
|
18805 |
+
$parent_fs->clear_pending_activation_mode();
|
|
|
|
|
18806 |
}
|
18807 |
|
18808 |
// Get user information based on parent's plugin.
|
18856 |
// return;
|
18857 |
// }
|
18858 |
|
18859 |
+
if ( is_object( $this->_site ) && ! $this->is_registered() ) {
|
18860 |
+
return;
|
18861 |
+
}
|
18862 |
+
|
18863 |
/**
|
18864 |
* When running from a site admin with a network activated module and the connection
|
18865 |
* was NOT delegated and the user still haven't skipped or opted-in, then hide the
|
18975 |
if ( ! $this->has_settings_menu() ) {
|
18976 |
// Add the opt-in page without a menu item.
|
18977 |
$hook = FS_Admin_Menu_Manager::add_subpage(
|
18978 |
+
'',
|
18979 |
$this->get_plugin_name(),
|
18980 |
$this->get_plugin_name(),
|
18981 |
'manage_options',
|
19407 |
$hook = FS_Admin_Menu_Manager::add_subpage(
|
19408 |
$item['show_submenu'] ?
|
19409 |
$top_level_menu_slug :
|
19410 |
+
'',
|
19411 |
$item['page_title'],
|
19412 |
$menu_item,
|
19413 |
$capability,
|
19422 |
FS_Admin_Menu_Manager::add_subpage(
|
19423 |
$item['show_submenu'] ?
|
19424 |
$top_level_menu_slug :
|
19425 |
+
'',
|
19426 |
$item['page_title'],
|
19427 |
$menu_item,
|
19428 |
$capability,
|
19814 |
*
|
19815 |
* @return string
|
19816 |
*/
|
19817 |
+
static function get_ajax_action_static( $tag, $module_id = null ) {
|
19818 |
$action = "fs_{$tag}";
|
19819 |
|
19820 |
if ( ! empty( $module_id ) ) {
|
19837 |
* @uses do_action()
|
19838 |
*/
|
19839 |
function do_action( $tag, $arg = '' ) {
|
|
|
|
|
19840 |
$args = func_get_args();
|
19841 |
|
19842 |
+
$this->_logger->entrance( $tag );
|
19843 |
+
|
19844 |
call_user_func_array( 'do_action', array_merge(
|
19845 |
array( $this->get_action_tag( $tag ) ),
|
19846 |
array_slice( $args, 1 ) )
|
19980 |
wp_send_json( $result );
|
19981 |
}
|
19982 |
|
19983 |
+
/**
|
19984 |
+
* Returns an AJAX URL with a special extra param to indicate whether the request was triggered from the network admin or blog admin.
|
19985 |
+
*
|
19986 |
+
* @author Vova Feldman (@svovaf)
|
19987 |
+
* @since 2.5.1
|
19988 |
+
*
|
19989 |
+
* @param string $wrap_with By default, returns the AJAX URL wrapped with single quotes.
|
19990 |
+
*
|
19991 |
+
* @return string
|
19992 |
+
*/
|
19993 |
+
static function ajax_url( $wrap_with = "'") {
|
19994 |
+
if ( fs_is_network_admin() ) {
|
19995 |
+
$param_name = '_fs_network_admin';
|
19996 |
+
} else {
|
19997 |
+
$param_name = '_fs_blog_admin';
|
19998 |
+
}
|
19999 |
+
|
20000 |
+
$url = admin_url( 'admin-ajax.php', 'relative' );
|
20001 |
+
$url .= ( false === strpos( $url, '?' ) ) ? '?' : '&';
|
20002 |
+
$url .= "{$param_name}=true";
|
20003 |
+
|
20004 |
+
return "{$wrap_with}{$url}{$wrap_with}";
|
20005 |
+
}
|
20006 |
+
|
20007 |
/**
|
20008 |
* Apply filter, specific for the current context plugin.
|
20009 |
*
|
20018 |
* @uses apply_filters()
|
20019 |
*/
|
20020 |
function apply_filters( $tag, $value ) {
|
20021 |
+
$args = func_get_args();
|
20022 |
+
|
20023 |
$this->_logger->entrance( $tag );
|
20024 |
|
|
|
20025 |
array_unshift( $args, $this->get_unique_affix() );
|
20026 |
|
20027 |
return call_user_func_array( 'fs_apply_filter', $args );
|
20082 |
}
|
20083 |
|
20084 |
/* Account Page
|
20085 |
+
------------------------------------------------------------------------------------------------------------------*/
|
20086 |
/**
|
20087 |
* Update site information.
|
20088 |
*
|
20093 |
* @param null|int $network_level_or_blog_id Since 2.0.0
|
20094 |
* @param \FS_Site $site Since 2.0.0
|
20095 |
*/
|
20096 |
+
private function _store_site( $store = true, $network_level_or_blog_id = null, FS_Site $site = null, $is_backup = false ) {
|
20097 |
$this->_logger->entrance();
|
20098 |
|
20099 |
if ( is_null( $site ) ) {
|
20108 |
|
20109 |
$site_clone = clone $site;
|
20110 |
|
20111 |
+
$sites = self::get_all_sites( $this->_module_type, $network_level_or_blog_id, $is_backup );
|
20112 |
|
20113 |
+
if (
|
20114 |
+
! $is_backup &&
|
20115 |
+
is_object( $this->_user ) && $this->_user->id != $site->user_id
|
20116 |
+
) {
|
20117 |
$this->sync_user_by_current_install( $site->user_id );
|
20118 |
|
20119 |
$prev_stored_user_id = $this->_storage->get( 'prev_user_id', false, $network_level_or_blog_id );
|
20138 |
|
20139 |
$sites[ $this->_slug ] = $site_clone;
|
20140 |
|
20141 |
+
$this->set_account_option(
|
20142 |
+
( $is_backup ? 'prev_' : '' ) . 'sites',
|
20143 |
+
$sites,
|
20144 |
+
$store,
|
20145 |
+
$network_level_or_blog_id
|
20146 |
+
);
|
20147 |
+
}
|
20148 |
+
|
20149 |
+
/**
|
20150 |
+
* Stores the context site in the sites backup storage. This logic is used before deleting the site info so that it can be restored later on if necessary (e.g., if the automatic clone resolution attempt fails).
|
20151 |
+
*
|
20152 |
+
* @author Leo Fajardo (@leorw)
|
20153 |
+
* @since 2.5.0
|
20154 |
+
*/
|
20155 |
+
private function back_up_site() {
|
20156 |
+
$this->_logger->entrance();
|
20157 |
+
|
20158 |
+
$site_clone = clone $this->_site;
|
20159 |
+
|
20160 |
+
$this->_store_site( true, null, $site_clone, true );
|
20161 |
}
|
20162 |
|
20163 |
/**
|
21398 |
$this->switch_to_blog( $current_blog_id );
|
21399 |
}
|
21400 |
|
21401 |
+
$result = $this->send_install_update( array(), true, true );
|
21402 |
$is_valid = $this->is_api_result_entity( $result );
|
21403 |
} else {
|
21404 |
+
$result = $this->send_installs_update( array(), true, true );
|
21405 |
$is_valid = $this->is_api_result_object( $result, 'installs' );
|
21406 |
}
|
21407 |
|
21411 |
$this->switch_to_blog( $this->_storage->network_install_blog_id );
|
21412 |
}
|
21413 |
|
21414 |
+
// Show API message only if not background sync or if paying customer.
|
21415 |
if ( ! $background || $this->is_paying() ) {
|
21416 |
// Try to ping API to see if not blocked.
|
21417 |
if ( ! FS_Api::test() ) {
|
21421 |
* @author Vova Feldman (@svovaf)
|
21422 |
* @since 1.1.6 Only show message related to one of the Freemius powered plugins. Once it will be resolved it will fix the issue for all plugins anyways. There's no point to scare users with multiple error messages.
|
21423 |
*/
|
|
|
21424 |
|
21425 |
if ( ! self::$_global_admin_notices->has_sticky( 'api_blocked' ) ) {
|
21426 |
+
// Add notice immediately if not a background sync.
|
21427 |
+
$add_notice = ( ! $background );
|
21428 |
+
|
21429 |
+
if ( ! $add_notice ) {
|
21430 |
+
$counter = (int) get_transient( '_fs_api_connection_retry_counter' );
|
21431 |
+
|
21432 |
+
// We only want to add the notice after 3 consecutive failures.
|
21433 |
+
$add_notice = ( 3 <= $counter );
|
21434 |
+
|
21435 |
+
if ( ! $add_notice ) {
|
21436 |
+
/**
|
21437 |
+
* Update counter transient only if notice shouldn't be added. If it is added the transient will be reset anyway, because the retries mechanism should only start counting if the admin isn't aware of the connectivity issue.
|
21438 |
+
*
|
21439 |
+
* Also, since the background sync happens once a day, setting the transient expiration for a week should be enough to count 3 failures, if there's an actual connectivity issue.
|
21440 |
+
*/
|
21441 |
+
set_transient( '_fs_api_connection_retry_counter', $counter + 1, WP_FS__TIME_WEEK_IN_SEC );
|
21442 |
+
}
|
21443 |
+
}
|
21444 |
+
|
21445 |
+
// Add notice instantly for not-background sync and only after 3 failed attempts for background sync.
|
21446 |
+
if ( $add_notice ) {
|
21447 |
+
self::$_global_admin_notices->add(
|
21448 |
+
sprintf(
|
21449 |
+
$this->get_text_inline( 'Your server is blocking the access to Freemius\' API, which is crucial for %1$s synchronization. Please contact your host to whitelist %2$s', 'server-blocking-access' ),
|
21450 |
+
$this->get_plugin_name(),
|
21451 |
+
'<b>' . implode( ', ', $this->apply_filters( 'api_domains', array(
|
21452 |
+
'api.freemius.com',
|
21453 |
+
'wp.freemius.com'
|
21454 |
+
) ) ) . '</b>'
|
21455 |
+
) . '<br> ' . $this->get_text_inline( 'Error received from the server:', 'server-error-message' ) . var_export( $result->error, true ),
|
21456 |
+
$this->get_text_x_inline( 'Oops', 'exclamation', 'oops' ) . '...',
|
21457 |
+
'error',
|
21458 |
+
$background,
|
21459 |
+
'api_blocked'
|
21460 |
+
);
|
21461 |
+
|
21462 |
+
// Notice was just shown, reset connectivity counter.
|
21463 |
+
delete_transient( '_fs_api_connection_retry_counter' );
|
21464 |
+
}
|
21465 |
}
|
21466 |
+
} else if ( is_object( $result ) ) {
|
21467 |
// Authentication params are broken.
|
21468 |
$this->_admin_notices->add(
|
21469 |
$this->get_text_inline( 'It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again.', 'wrong-authentication-param-message' ) . '<br> ' . $this->get_text_inline( 'Error received from the server:', 'server-error-message' ) . var_export( $result->error, true ),
|
21477 |
return;
|
21478 |
}
|
21479 |
|
21480 |
+
// API is working now. Delete the transient and start afresh.
|
21481 |
+
delete_transient('_fs_api_connection_retry_counter');
|
21482 |
+
|
21483 |
if ( $is_site_level_sync ) {
|
21484 |
$site = new FS_Site( $result );
|
21485 |
} else {
|
21671 |
}
|
21672 |
|
21673 |
if ( ! $this->is_addon() &&
|
21674 |
+
$this->_site->is_beta() !== $site->is_beta()
|
21675 |
) {
|
21676 |
// Beta flag updated.
|
21677 |
$this->_site = $site;
|
22226 |
if ( ! $this->is_api_result_entity( $plan ) ) {
|
22227 |
// Some API error while trying to start the trial.
|
22228 |
$this->_admin_notices->add(
|
22229 |
+
$this->get_api_error_message( $plan ),
|
|
|
22230 |
$oops_text,
|
22231 |
'error'
|
22232 |
);
|
22404 |
) {
|
22405 |
$this->_logger->entrance();
|
22406 |
|
22407 |
+
if ( $this->is_unresolved_clone( true ) ) {
|
22408 |
+
return false;
|
22409 |
+
}
|
22410 |
+
|
22411 |
$switch_to_blog_id = null;
|
22412 |
|
22413 |
/**
|
22414 |
* @since 1.1.7.3 Check for plugin updates from Freemius only if opted-in.
|
22415 |
* @since 1.1.7.4 Also check updates for add-ons.
|
22416 |
*/
|
22417 |
+
if (
|
22418 |
+
( ! $this->is_registered() || ! FS_Permission_Manager::instance( $this )->is_essentials_tracking_allowed() ) &&
|
22419 |
! $this->_is_addon_id( $addon_id )
|
22420 |
) {
|
22421 |
if ( ! is_multisite() ) {
|
22425 |
$installs_map = $this->get_blog_install_map();
|
22426 |
|
22427 |
foreach ( $installs_map as $blog_id => $install ) {
|
22428 |
+
if ( ! FS_Permission_Manager::instance( $this )->is_essentials_tracking_allowed( $blog_id ) ) {
|
22429 |
+
continue;
|
22430 |
+
}
|
22431 |
+
|
22432 |
/**
|
22433 |
* @var FS_Site $install
|
22434 |
*/
|
22525 |
private function get_latest_download_api_url( $plugin_id = false ) {
|
22526 |
$this->_logger->entrance();
|
22527 |
|
22528 |
+
$download_api_url = $this->get_api_site_scope()->get_signed_url(
|
22529 |
$this->_get_latest_version_endpoint( $plugin_id, 'zip' )
|
22530 |
);
|
22531 |
+
|
22532 |
+
return str_replace( 'http:', 'https:', $download_api_url );
|
22533 |
}
|
22534 |
|
22535 |
/**
|
22724 |
private function update_email( $new_email ) {
|
22725 |
$this->_logger->entrance();
|
22726 |
|
|
|
22727 |
$api = $this->get_api_user_scope();
|
22728 |
$user = $api->call( "?plugin_id={$this->_plugin->id}&fields=id,email,is_verified", 'put', array(
|
22729 |
'email' => $new_email,
|
22739 |
$this->_store_user();
|
22740 |
} else {
|
22741 |
// handle different error cases.
|
|
|
22742 |
}
|
22743 |
|
22744 |
return $user;
|
22814 |
* @uses FS_Api
|
22815 |
*
|
22816 |
* @param string $candidate_email
|
22817 |
+
* @param string $transfer_type
|
22818 |
*
|
22819 |
* @return bool Is ownership change successfully initiated.
|
22820 |
*/
|
22821 |
+
private function init_change_owner( $candidate_email, $transfer_type ) {
|
22822 |
$this->_logger->entrance();
|
22823 |
|
22824 |
+
$installs_info_by_slug_map = $this->get_parent_and_addons_installs_info();
|
22825 |
+
$install_ids = array();
|
22826 |
+
|
22827 |
+
foreach ( $installs_info_by_slug_map as $slug => $install_info ) {
|
22828 |
+
$install = $install_info['install'];
|
22829 |
+
|
22830 |
+
if ( $this->_user->id != $install->user_id ) {
|
22831 |
+
// Skip add-on installs that are not owned by the parent product's install's owner.
|
22832 |
+
continue;
|
22833 |
+
}
|
22834 |
+
|
22835 |
+
$install_ids[ $slug ] = $install->id;
|
22836 |
+
}
|
22837 |
+
|
22838 |
$api = $this->get_api_site_scope();
|
22839 |
$result = $api->call( "/users/{$this->_user->id}.json", 'put', array(
|
22840 |
'email' => $candidate_email,
|
22841 |
+
'transfer_type' => $transfer_type,
|
22842 |
+
'install_ids' => implode( ',', array_values( $install_ids ) ),
|
22843 |
'after_confirm_url' => $this->_get_admin_page_url(
|
22844 |
'account',
|
22845 |
array( 'fs_action' => 'change_owner' )
|
22861 |
private function complete_change_owner() {
|
22862 |
$this->_logger->entrance();
|
22863 |
|
22864 |
+
$install_ids = fs_request_get( 'install_ids' );
|
22865 |
+
|
22866 |
+
if ( ! empty( $install_ids ) ) {
|
22867 |
+
$install_ids = explode( ',', $install_ids );
|
22868 |
+
|
22869 |
+
foreach ( $install_ids as $key => $install_id ) {
|
22870 |
+
if ( ! FS_Site::is_valid_id( $install_id ) ) {
|
22871 |
+
unset( $install_ids[ $key ] );
|
22872 |
+
}
|
22873 |
+
}
|
22874 |
+
}
|
22875 |
+
|
22876 |
+
if ( ! is_array( $install_ids ) ) {
|
22877 |
+
$install_ids = array();
|
22878 |
+
}
|
22879 |
+
|
22880 |
+
$user = new FS_User();
|
22881 |
+
$user->id = fs_request_get( 'user_id' );
|
22882 |
+
$user->public_key = fs_request_get( 'user_public_key' );
|
22883 |
+
$user->secret_key = fs_request_get( 'user_secret_key' );
|
22884 |
|
22885 |
+
$prev_user = $this->_user;
|
22886 |
+
$this->_user = $user;
|
22887 |
+
|
22888 |
+
$result = $this->get_api_user_scope( true )->get(
|
22889 |
+
"/installs.json?install_ids=" . implode( ',', $install_ids )
|
22890 |
+
);
|
22891 |
+
|
22892 |
+
$current_blog_sites = self::get_all_sites( $this->get_module_type() );
|
22893 |
+
|
22894 |
+
if ( $this->is_api_result_object( $result, 'installs' ) ) {
|
22895 |
+
$site_id_slug_map = array();
|
22896 |
+
|
22897 |
+
foreach ( $current_blog_sites as $slug => $site ) {
|
22898 |
+
$site_id_slug_map[ $site->id ] = $slug;
|
22899 |
+
}
|
22900 |
+
|
22901 |
+
foreach ( $result->installs as $install ) {
|
22902 |
+
$site = new FS_Site( $install );
|
22903 |
+
|
22904 |
+
if ( ! isset( $site_id_slug_map[ $install->id ] ) ) {
|
22905 |
+
continue;
|
22906 |
+
}
|
22907 |
+
|
22908 |
+
$current_blog_sites[ $site_id_slug_map[ $install->id ] ] = clone $site;
|
22909 |
+
|
22910 |
+
if ( $this->_site->id == $site->id ) {
|
22911 |
+
$this->_site = $site;
|
22912 |
+
}
|
22913 |
+
}
|
22914 |
+
}
|
22915 |
|
22916 |
// Validate install's user and given user.
|
22917 |
if ( $user->id != $this->_site->user_id ) {
|
22918 |
+
$this->_user = $prev_user;
|
22919 |
+
|
22920 |
return false;
|
22921 |
}
|
22922 |
|
22923 |
+
$this->set_account_option( 'sites', $current_blog_sites, true );
|
|
|
22924 |
|
22925 |
// Fetch new user information.
|
|
|
22926 |
$user_result = $this->get_api_user_scope( true )->get();
|
22927 |
$user = new FS_User( $user_result );
|
22928 |
$this->_user = $user;
|
22929 |
|
22930 |
+
$this->_set_account( $user, $this->_site );
|
22931 |
+
|
22932 |
+
$remove_user = true;
|
22933 |
+
$all_modules_sites = self::get_all_modules_sites();
|
22934 |
+
|
22935 |
+
foreach ( $all_modules_sites as $sites_by_module_type ) {
|
22936 |
+
foreach ( $sites_by_module_type as $sites_by_slug ) {
|
22937 |
+
foreach ( $sites_by_slug as $site ) {
|
22938 |
+
if ( $prev_user->id == $site->user_id ) {
|
22939 |
+
$remove_user = false;
|
22940 |
+
break;
|
22941 |
+
}
|
22942 |
+
}
|
22943 |
+
|
22944 |
+
if ( ! $remove_user ) {
|
22945 |
+
break;
|
22946 |
+
}
|
22947 |
+
}
|
22948 |
+
|
22949 |
+
if ( ! $remove_user ) {
|
22950 |
+
break;
|
22951 |
+
}
|
22952 |
+
}
|
22953 |
+
|
22954 |
+
if ( $remove_user ) {
|
22955 |
+
$users = self::get_all_users();
|
22956 |
+
|
22957 |
+
if ( isset( $users[ $prev_user->id ] ) ) {
|
22958 |
+
unset( $users[ $prev_user->id ] );
|
22959 |
+
} else {
|
22960 |
+
// If the prev user wasn't found by the key, iterate over the users collection.
|
22961 |
+
foreach ( $users as $key => $user ) {
|
22962 |
+
if ( $user->id == $prev_user->id ) {
|
22963 |
+
unset( $users[ $key ] );
|
22964 |
+
break;
|
22965 |
+
}
|
22966 |
+
}
|
22967 |
+
}
|
22968 |
+
|
22969 |
+
$this->set_account_option( 'users', $users, true );
|
22970 |
+
}
|
22971 |
|
22972 |
return true;
|
22973 |
}
|
23212 |
|
23213 |
if ( $is_parent_plugin_action ) {
|
23214 |
if ( $is_network_action && ! empty( $blog_id ) ) {
|
23215 |
+
if ( $this->is_registered( true ) ) {
|
23216 |
+
if ( $this->is_tracking_prohibited( $blog_id ) ) {
|
23217 |
+
if ( $this->toggle_site_tracking( true, $blog_id ) ) {
|
23218 |
$this->_admin_notices->add(
|
23219 |
+
sprintf( $this->get_text_inline( 'Sharing diagnostic data with %s helps to provide functionality that\'s more relevant to your website, avoid WordPress or PHP version incompatibilities that can break your website, and recognize which languages & regions the plugin should be translated and tailored to.', 'opt-out-message-appreciation' ), "<b>{$this->get_plugin_title()}</b>" ),
|
23220 |
$this->get_text_inline( 'Thank you!', 'thank-you' )
|
23221 |
);
|
23222 |
}
|
23223 |
} else {
|
23224 |
+
if ( $this->toggle_site_tracking( false, $blog_id ) ) {
|
23225 |
+
$install = $this->get_install_by_blog_id( $blog_id );
|
23226 |
+
|
23227 |
$this->_admin_notices->add(
|
23228 |
sprintf(
|
23229 |
+
$this->get_text_inline( 'Diagnostic data will no longer be sent from %s to %s.', 'opted-out-successfully' ),
|
23230 |
+
self::get_unfiltered_site_url( $blog_id, true ),
|
23231 |
+
"<b>{$this->get_plugin_title()}</b>"
|
|
|
|
|
|
|
|
|
|
|
23232 |
)
|
23233 |
);
|
23234 |
}
|
23376 |
$state = fs_request_get( 'state', 'init' );
|
23377 |
switch ( $state ) {
|
23378 |
case 'init':
|
23379 |
+
$candidate_email = fs_request_get( 'candidate_email' );
|
23380 |
+
$transfer_type = fs_request_get( 'transfer_type' );
|
23381 |
|
23382 |
+
if ( $this->init_change_owner( $candidate_email, $transfer_type ) ) {
|
23383 |
+
if ( 'transfer' === $transfer_type ) {
|
23384 |
+
$this->_admin_notices->add( sprintf( $this->get_text_inline( 'A confirmation email was just sent to %s. The email owner must confirm the update within the next 4 hours.', 'change-owner-request-sent-x-transfer' ), '<b>' . $this->_user->email . '</b>' ) );
|
23385 |
+
} else {
|
23386 |
+
$this->_admin_notices->add( sprintf( $this->get_text_inline( 'A confirmation email was just sent to %s. You must confirm the update within the next 4 hours. If you cannot find the email, please check your spam folder.', 'change-owner-request-sent-x' ), '<b>' . $this->_user->email . '</b>' ) );
|
23387 |
+
}
|
23388 |
}
|
23389 |
break;
|
23390 |
case 'owner_confirmed':
|
23407 |
|
23408 |
return;
|
23409 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23410 |
case 'update_user_name':
|
23411 |
check_admin_referer( 'update_user_name' );
|
23412 |
|
23568 |
|
23569 |
fs_enqueue_local_style( 'fs_affiliation', '/admin/affiliation.css' );
|
23570 |
|
23571 |
+
$is_bundle_context = $this->has_bundle_context();
|
23572 |
+
|
23573 |
+
$plugin_title = $this->get_plugin_title();
|
23574 |
+
|
23575 |
+
if ( $is_bundle_context ) {
|
23576 |
+
$plugin_title = $this->plugin_affiliate_terms->plugin_title;
|
23577 |
+
|
23578 |
+
// Add the suffix "Bundle" only if the word is not present in the title itself.
|
23579 |
+
if ( false === mb_stripos( $plugin_title, fs_text_inline( 'Bundle', 'bundle' ) ) ) {
|
23580 |
+
$plugin_title = $this->apply_filters(
|
23581 |
+
'formatted_bundle_title',
|
23582 |
+
$plugin_title . ' ' . fs_text_inline( 'Bundle', 'bundle' )
|
23583 |
+
);
|
23584 |
+
}
|
23585 |
+
}
|
23586 |
+
|
23587 |
+
$vars = array(
|
23588 |
+
'id' => $this->_module_id,
|
23589 |
+
'plugin_title' => $plugin_title,
|
23590 |
+
);
|
23591 |
echo $this->apply_filters( "/forms/affiliation.php", fs_get_template( '/forms/affiliation.php', $vars ) );
|
23592 |
}
|
23593 |
|
23688 |
}
|
23689 |
|
23690 |
/* Pricing & Upgrade
|
23691 |
+
------------------------------------------------------------------------------------------------------------------*/
|
23692 |
/**
|
23693 |
* Render pricing page.
|
23694 |
*
|
23830 |
}
|
23831 |
|
23832 |
static function _clean_admin_content_section_hook() {
|
23833 |
+
$hide_admin_notices = true;
|
23834 |
+
|
23835 |
+
if ( fs_request_is_action( 'allow_clone_resolution_notice' ) ) {
|
23836 |
+
check_admin_referer( 'fs_allow_clone_resolution_notice' );
|
23837 |
+
|
23838 |
+
$hide_admin_notices = false;
|
23839 |
+
}
|
23840 |
+
|
23841 |
+
if ( $hide_admin_notices ) {
|
23842 |
+
self::_hide_admin_notices();
|
23843 |
+
}
|
23844 |
|
23845 |
// Hide footer.
|
23846 |
echo '<style>#wpfooter { display: none !important; }</style>';
|
23857 |
}
|
23858 |
|
23859 |
/* CSS & JavaScript
|
23860 |
+
------------------------------------------------------------------------------------------------------------------*/
|
23861 |
/* function _enqueue_script($handle, $src) {
|
23862 |
+
$url = plugins_url( substr( WP_FS__DIR_JS, strlen( $this->_plugin_dir_path ) ) . '/assets/js/' . $src );
|
23863 |
|
23864 |
+
$this->_logger->entrance( 'script = ' . $url );
|
23865 |
|
23866 |
+
wp_enqueue_script( $handle, $url );
|
23867 |
+
}*/
|
23868 |
|
23869 |
/* SDK
|
23870 |
+
------------------------------------------------------------------------------------------------------------------*/
|
23871 |
private $_user_api;
|
23872 |
|
23873 |
/**
|
23879 |
*
|
23880 |
* @return FS_Api
|
23881 |
*/
|
23882 |
+
function get_api_user_scope( $flush = false ) {
|
23883 |
if ( ! isset( $this->_user_api ) || $flush ) {
|
23884 |
$this->_user_api = $this->get_api_user_scope_by_user( $this->_user );
|
23885 |
}
|
23958 |
$this->_site->public_key,
|
23959 |
! $this->is_live(),
|
23960 |
$this->_site->secret_key,
|
23961 |
+
$this->get_sdk_version(),
|
23962 |
+
self::get_unfiltered_site_url()
|
23963 |
);
|
23964 |
}
|
23965 |
|
23966 |
return $this->_site_api;
|
23967 |
}
|
23968 |
|
23969 |
+
/**
|
23970 |
+
* @author Leo Fajardo (@leorw)
|
23971 |
+
* @since 2.5.0
|
23972 |
+
*
|
23973 |
+
* @param string $path
|
23974 |
+
* @param string $method
|
23975 |
+
* @param array $params
|
23976 |
+
* @param bool $flush_instance
|
23977 |
+
*
|
23978 |
+
* @return array|mixed|string|void
|
23979 |
+
* @throws Freemius_Exception
|
23980 |
+
*/
|
23981 |
+
private function api_site_call( $path, $method = 'GET', $params = array(), $flush_instance = false ) {
|
23982 |
+
$result = $this->get_api_site_scope( $flush_instance )->call( $path, $method, $params );
|
23983 |
+
|
23984 |
+
/**
|
23985 |
+
* Checks if the local install's URL is different from the remote install's URL, update the local install if necessary, and then run the clone handler if the install's URL is different from the URL of the site.
|
23986 |
+
*
|
23987 |
+
* @author Leo Fajardo (@leorw)
|
23988 |
+
* @since 2.5.0
|
23989 |
+
*/
|
23990 |
+
if (
|
23991 |
+
$this->is_registered() &&
|
23992 |
+
FS_Api::is_api_result_entity( $result ) &&
|
23993 |
+
isset( $result->url )
|
23994 |
+
) {
|
23995 |
+
$stored_local_url = trailingslashit( $this->_site->url );
|
23996 |
+
$stored_remote_url = trailingslashit( $result->url );
|
23997 |
+
|
23998 |
+
if ( $stored_local_url !== $stored_remote_url ) {
|
23999 |
+
$this->_site->url = $result->url;
|
24000 |
+
$this->_store_site();
|
24001 |
+
}
|
24002 |
+
|
24003 |
+
if ( fs_strip_url_protocol( $stored_remote_url ) !== self::get_unfiltered_site_url( null, true, true ) ) {
|
24004 |
+
FS_Clone_Manager::instance()->maybe_run_clone_resolution();
|
24005 |
+
}
|
24006 |
+
}
|
24007 |
+
|
24008 |
+
return $result;
|
24009 |
+
}
|
24010 |
+
|
24011 |
private $_plugin_api;
|
24012 |
|
24013 |
/**
|
24443 |
}
|
24444 |
|
24445 |
/* Action Links
|
24446 |
+
------------------------------------------------------------------------------------------------------------------*/
|
24447 |
private $_action_links_hooked = false;
|
24448 |
private $_action_links = array();
|
24449 |
|
24614 |
|
24615 |
$this->_logger->entrance();
|
24616 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24617 |
if ( $this->is_only_premium() && $this->is_free_plan() ) {
|
24618 |
// Don't add tracking links for premium-only products that were opted-in by relation (add-on or a parent product) before activating any license.
|
24619 |
return;
|
24621 |
|
24622 |
if (
|
24623 |
$this->is_addon() &&
|
24624 |
+
! $this->is_only_premium()
|
|
|
24625 |
) {
|
24626 |
+
$parent = $this->get_parent_instance();
|
24627 |
+
|
24628 |
+
if ( is_object( $parent ) && $parent->is_anonymous() ) {
|
24629 |
+
return;
|
24630 |
+
}
|
24631 |
}
|
24632 |
|
24633 |
if ( fs_is_network_admin() ) {
|
24676 |
}
|
24677 |
}
|
24678 |
|
24679 |
+
if ( $this->add_ajax_action( 'toggle_permission_tracking', array( &$this, '_toggle_permission_tracking_callback' ) ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24680 |
return;
|
24681 |
}
|
24682 |
|
24683 |
$link_text_id = '';
|
24684 |
$url = '#';
|
24685 |
|
24686 |
+
if ( $this->is_registered( true ) ) {
|
24687 |
+
if ( $this->is_registered() && $this->is_tracking_allowed() ) {
|
24688 |
$link_text_id = $this->get_text_inline( 'Opt Out', 'opt-out' );
|
24689 |
} else {
|
24690 |
$link_text_id = $this->get_text_inline( 'Opt In', 'opt-in' );
|
24881 |
*/
|
24882 |
private function is_premium_version_installed() {
|
24883 |
$premium_plugin_basename = $this->premium_plugin_basename();
|
|
|
24884 |
|
24885 |
+
if ( $this->is_theme() ) {
|
24886 |
+
return $this->can_activate_theme( $this->get_premium_slug() );
|
24887 |
+
}
|
24888 |
+
|
24889 |
+
return file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $premium_plugin_basename ) );
|
24890 |
}
|
24891 |
|
24892 |
/**
|
24922 |
* @author Leo Fajardo (@leorw)
|
24923 |
* @since 2.2.1
|
24924 |
*/
|
24925 |
+
$premium_theme_slug_or_plugin_basename = $this->is_theme() ?
|
24926 |
+
$this->get_premium_slug() :
|
24927 |
+
$this->premium_plugin_basename();
|
24928 |
|
24929 |
return sprintf(
|
24930 |
/* translators: %1$s: Product title; %2$s: Plan title */
|
24933 |
$plan_title,
|
24934 |
sprintf(
|
24935 |
'<a style="margin-left: 10px;" href="%s"><button class="button button-primary">%s</button></a>',
|
24936 |
+
( $this->is_theme() ?
|
24937 |
+
wp_nonce_url( 'themes.php?action=activate&stylesheet=' . $premium_theme_slug_or_plugin_basename, 'switch-theme_' . $premium_theme_slug_or_plugin_basename ) :
|
24938 |
+
wp_nonce_url( 'plugins.php?action=activate&plugin=' . $premium_theme_slug_or_plugin_basename, 'activate-plugin_' . $premium_theme_slug_or_plugin_basename ) ),
|
24939 |
esc_html( sprintf(
|
24940 |
/* translators: %s: Plan title */
|
24941 |
$this->get_text_inline( 'Activate %s features', 'activate-x-features' ),
|
24960 |
) ),
|
24961 |
$deactivation_step,
|
24962 |
$this->get_text_inline( 'Upload and activate the downloaded version', 'upload-and-activate' ),
|
24963 |
+
$this->apply_filters( 'upload_and_install_video_url', '//bit.ly/wp-' . $this->_module_type . '-upload' ),
|
24964 |
$this->get_text_inline( 'How to upload and activate?', 'howto-upload-activate' )
|
24965 |
);
|
24966 |
}
|
25413 |
function _tabs_capture() {
|
25414 |
$this->_logger->entrance();
|
25415 |
|
25416 |
+
if (
|
25417 |
+
! $this->is_product_settings_page() ||
|
25418 |
+
! $this->should_page_include_tabs() ||
|
25419 |
+
! $this->is_matching_url( $this->main_menu_url() )
|
25420 |
) {
|
25421 |
return;
|
25422 |
}
|
25470 |
function _store_tabs_styles() {
|
25471 |
$this->_logger->entrance();
|
25472 |
|
25473 |
+
if (
|
25474 |
+
! $this->is_product_settings_page() ||
|
25475 |
+
! $this->should_page_include_tabs() ||
|
25476 |
+
! $this->is_matching_url( $this->main_menu_url() )
|
25477 |
) {
|
25478 |
return;
|
25479 |
}
|
freemius/includes/class-fs-admin-notices.php
CHANGED
@@ -125,13 +125,10 @@
|
|
125 |
$is_sticky = false,
|
126 |
$id = '',
|
127 |
$store_if_sticky = true,
|
128 |
-
$network_level_or_blog_id = null
|
|
|
129 |
) {
|
130 |
-
|
131 |
-
$notices = $this->_network_notices;
|
132 |
-
} else {
|
133 |
-
$notices = $this->get_site_notices( $network_level_or_blog_id );
|
134 |
-
}
|
135 |
|
136 |
$notices->add(
|
137 |
$message,
|
@@ -139,7 +136,11 @@
|
|
139 |
$type,
|
140 |
$is_sticky,
|
141 |
$id,
|
142 |
-
$store_if_sticky
|
|
|
|
|
|
|
|
|
143 |
);
|
144 |
}
|
145 |
|
@@ -149,8 +150,9 @@
|
|
149 |
*
|
150 |
* @param string|string[] $ids
|
151 |
* @param int|null $network_level_or_blog_id
|
|
|
152 |
*/
|
153 |
-
function remove_sticky( $ids, $network_level_or_blog_id = null ) {
|
154 |
if ( ! is_array( $ids ) ) {
|
155 |
$ids = array( $ids );
|
156 |
}
|
@@ -161,7 +163,7 @@
|
|
161 |
$notices = $this->get_site_notices( $network_level_or_blog_id );
|
162 |
}
|
163 |
|
164 |
-
return $notices->remove_sticky( $ids );
|
165 |
}
|
166 |
|
167 |
/**
|
@@ -176,11 +178,7 @@
|
|
176 |
* @return bool
|
177 |
*/
|
178 |
function has_sticky( $id, $network_level_or_blog_id = null ) {
|
179 |
-
|
180 |
-
$notices = $this->_network_notices;
|
181 |
-
} else {
|
182 |
-
$notices = $this->get_site_notices( $network_level_or_blog_id );
|
183 |
-
}
|
184 |
|
185 |
return $notices->has_sticky( $id );
|
186 |
}
|
@@ -200,6 +198,7 @@
|
|
200 |
* @param string|null $plugin_title
|
201 |
* @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network and
|
202 |
* blog admin pages.
|
|
|
203 |
*/
|
204 |
function add_sticky(
|
205 |
$message,
|
@@ -209,15 +208,30 @@
|
|
209 |
$network_level_or_blog_id = null,
|
210 |
$wp_user_id = null,
|
211 |
$plugin_title = null,
|
212 |
-
$is_network_and_blog_admins = false
|
|
|
|
|
213 |
) {
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
|
220 |
-
$notices->
|
221 |
}
|
222 |
|
223 |
/**
|
@@ -227,21 +241,22 @@
|
|
227 |
* @since 2.0.0
|
228 |
*
|
229 |
* @param int|null $network_level_or_blog_id
|
|
|
230 |
*/
|
231 |
-
function clear_all_sticky( $network_level_or_blog_id = null ) {
|
232 |
if ( ! $this->_is_multisite ||
|
233 |
false === $network_level_or_blog_id ||
|
234 |
0 == $network_level_or_blog_id ||
|
235 |
is_null( $network_level_or_blog_id )
|
236 |
) {
|
237 |
$notices = $this->get_site_notices( $network_level_or_blog_id );
|
238 |
-
$notices->clear_all_sticky();
|
239 |
}
|
240 |
|
241 |
if ( $this->_is_multisite &&
|
242 |
( true === $network_level_or_blog_id || is_null( $network_level_or_blog_id ) )
|
243 |
) {
|
244 |
-
$this->_network_notices->clear_all_sticky();
|
245 |
}
|
246 |
}
|
247 |
|
@@ -317,5 +332,22 @@
|
|
317 |
return fs_is_network_admin();
|
318 |
}
|
319 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
320 |
#endregion
|
321 |
}
|
125 |
$is_sticky = false,
|
126 |
$id = '',
|
127 |
$store_if_sticky = true,
|
128 |
+
$network_level_or_blog_id = null,
|
129 |
+
$is_dimissible = null
|
130 |
) {
|
131 |
+
$notices = $this->get_site_or_network_notices( $id, $network_level_or_blog_id );
|
|
|
|
|
|
|
|
|
132 |
|
133 |
$notices->add(
|
134 |
$message,
|
136 |
$type,
|
137 |
$is_sticky,
|
138 |
$id,
|
139 |
+
$store_if_sticky,
|
140 |
+
null,
|
141 |
+
null,
|
142 |
+
false,
|
143 |
+
$is_dimissible
|
144 |
);
|
145 |
}
|
146 |
|
150 |
*
|
151 |
* @param string|string[] $ids
|
152 |
* @param int|null $network_level_or_blog_id
|
153 |
+
* @param bool $store
|
154 |
*/
|
155 |
+
function remove_sticky( $ids, $network_level_or_blog_id = null, $store = true ) {
|
156 |
if ( ! is_array( $ids ) ) {
|
157 |
$ids = array( $ids );
|
158 |
}
|
163 |
$notices = $this->get_site_notices( $network_level_or_blog_id );
|
164 |
}
|
165 |
|
166 |
+
return $notices->remove_sticky( $ids, $store );
|
167 |
}
|
168 |
|
169 |
/**
|
178 |
* @return bool
|
179 |
*/
|
180 |
function has_sticky( $id, $network_level_or_blog_id = null ) {
|
181 |
+
$notices = $this->get_site_or_network_notices( $id, $network_level_or_blog_id );
|
|
|
|
|
|
|
|
|
182 |
|
183 |
return $notices->has_sticky( $id );
|
184 |
}
|
198 |
* @param string|null $plugin_title
|
199 |
* @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network and
|
200 |
* blog admin pages.
|
201 |
+
* @param bool $is_dismissible
|
202 |
*/
|
203 |
function add_sticky(
|
204 |
$message,
|
208 |
$network_level_or_blog_id = null,
|
209 |
$wp_user_id = null,
|
210 |
$plugin_title = null,
|
211 |
+
$is_network_and_blog_admins = false,
|
212 |
+
$is_dismissible = true,
|
213 |
+
$data = array()
|
214 |
) {
|
215 |
+
$notices = $this->get_site_or_network_notices( $id, $network_level_or_blog_id );
|
216 |
+
|
217 |
+
$notices->add_sticky( $message, $id, $title, $type, $wp_user_id, $plugin_title, $is_network_and_blog_admins, $is_dismissible, $data );
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Retrieves the data of a sticky notice.
|
222 |
+
*
|
223 |
+
* @author Leo Fajardo (@leorw)
|
224 |
+
* @since 2.4.3
|
225 |
+
*
|
226 |
+
* @param string $id
|
227 |
+
* @param int|null $network_level_or_blog_id
|
228 |
+
*
|
229 |
+
* @return array|null
|
230 |
+
*/
|
231 |
+
function get_sticky( $id, $network_level_or_blog_id ) {
|
232 |
+
$notices = $this->get_site_or_network_notices( $id, $network_level_or_blog_id );
|
233 |
|
234 |
+
return $notices->get_sticky( $id );
|
235 |
}
|
236 |
|
237 |
/**
|
241 |
* @since 2.0.0
|
242 |
*
|
243 |
* @param int|null $network_level_or_blog_id
|
244 |
+
* @param bool $is_temporary
|
245 |
*/
|
246 |
+
function clear_all_sticky( $network_level_or_blog_id = null, $is_temporary = false ) {
|
247 |
if ( ! $this->_is_multisite ||
|
248 |
false === $network_level_or_blog_id ||
|
249 |
0 == $network_level_or_blog_id ||
|
250 |
is_null( $network_level_or_blog_id )
|
251 |
) {
|
252 |
$notices = $this->get_site_notices( $network_level_or_blog_id );
|
253 |
+
$notices->clear_all_sticky( $is_temporary );
|
254 |
}
|
255 |
|
256 |
if ( $this->_is_multisite &&
|
257 |
( true === $network_level_or_blog_id || is_null( $network_level_or_blog_id ) )
|
258 |
) {
|
259 |
+
$this->_network_notices->clear_all_sticky( $is_temporary );
|
260 |
}
|
261 |
}
|
262 |
|
332 |
return fs_is_network_admin();
|
333 |
}
|
334 |
|
335 |
+
/**
|
336 |
+
* Retrieves an instance of FS_Admin_Notice_Manager.
|
337 |
+
*
|
338 |
+
* @author Leo Fajardo (@leorw)
|
339 |
+
* @since 2.5.0
|
340 |
+
*
|
341 |
+
* @param string $id
|
342 |
+
* @param int|null $network_level_or_blog_id
|
343 |
+
*
|
344 |
+
* @return FS_Admin_Notice_Manager
|
345 |
+
*/
|
346 |
+
private function get_site_or_network_notices( $id, $network_level_or_blog_id ) {
|
347 |
+
return $this->should_use_network_notices( $id, $network_level_or_blog_id ) ?
|
348 |
+
$this->_network_notices :
|
349 |
+
$this->get_site_notices( $network_level_or_blog_id );
|
350 |
+
}
|
351 |
+
|
352 |
#endregion
|
353 |
}
|
freemius/includes/class-fs-api.php
CHANGED
@@ -64,6 +64,14 @@
|
|
64 |
*/
|
65 |
private $_sdk_version;
|
66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
/**
|
68 |
* @param string $slug
|
69 |
* @param string $scope 'app', 'developer', 'user' or 'install'.
|
@@ -72,6 +80,7 @@
|
|
72 |
* @param bool $is_sandbox
|
73 |
* @param bool|string $secret_key Element's secret key.
|
74 |
* @param null|string $sdk_version
|
|
|
75 |
*
|
76 |
* @return FS_Api
|
77 |
*/
|
@@ -82,14 +91,15 @@
|
|
82 |
$public_key,
|
83 |
$is_sandbox,
|
84 |
$secret_key = false,
|
85 |
-
$sdk_version = null
|
|
|
86 |
) {
|
87 |
$identifier = md5( $slug . $scope . $id . $public_key . ( is_string( $secret_key ) ? $secret_key : '' ) . json_encode( $is_sandbox ) );
|
88 |
|
89 |
if ( ! isset( self::$_instances[ $identifier ] ) ) {
|
90 |
self::_init();
|
91 |
|
92 |
-
self::$_instances[ $identifier ] = new FS_Api( $slug, $scope, $id, $public_key, $secret_key, $is_sandbox, $sdk_version );
|
93 |
}
|
94 |
|
95 |
return self::$_instances[ $identifier ];
|
@@ -123,6 +133,7 @@
|
|
123 |
* @param bool|string $secret_key Element's secret key.
|
124 |
* @param bool $is_sandbox
|
125 |
* @param null|string $sdk_version
|
|
|
126 |
*/
|
127 |
private function __construct(
|
128 |
$slug,
|
@@ -131,12 +142,14 @@
|
|
131 |
$public_key,
|
132 |
$secret_key,
|
133 |
$is_sandbox,
|
134 |
-
$sdk_version
|
|
|
135 |
) {
|
136 |
$this->_api = new Freemius_Api_WordPress( $scope, $id, $public_key, $secret_key, $is_sandbox );
|
137 |
|
138 |
$this->_slug = $slug;
|
139 |
$this->_sdk_version = $sdk_version;
|
|
|
140 |
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $slug . '_api', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
141 |
}
|
142 |
|
@@ -198,6 +211,17 @@
|
|
198 |
}
|
199 |
}
|
200 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
$result = $this->_api->Api( $path, $method, $params );
|
202 |
|
203 |
if ( null !== $result &&
|
64 |
*/
|
65 |
private $_sdk_version;
|
66 |
|
67 |
+
/**
|
68 |
+
* @author Leo Fajardo (@leorw)
|
69 |
+
* @since 2.5.0
|
70 |
+
*
|
71 |
+
* @var string
|
72 |
+
*/
|
73 |
+
private $_url;
|
74 |
+
|
75 |
/**
|
76 |
* @param string $slug
|
77 |
* @param string $scope 'app', 'developer', 'user' or 'install'.
|
80 |
* @param bool $is_sandbox
|
81 |
* @param bool|string $secret_key Element's secret key.
|
82 |
* @param null|string $sdk_version
|
83 |
+
* @param null|string $url
|
84 |
*
|
85 |
* @return FS_Api
|
86 |
*/
|
91 |
$public_key,
|
92 |
$is_sandbox,
|
93 |
$secret_key = false,
|
94 |
+
$sdk_version = null,
|
95 |
+
$url = null
|
96 |
) {
|
97 |
$identifier = md5( $slug . $scope . $id . $public_key . ( is_string( $secret_key ) ? $secret_key : '' ) . json_encode( $is_sandbox ) );
|
98 |
|
99 |
if ( ! isset( self::$_instances[ $identifier ] ) ) {
|
100 |
self::_init();
|
101 |
|
102 |
+
self::$_instances[ $identifier ] = new FS_Api( $slug, $scope, $id, $public_key, $secret_key, $is_sandbox, $sdk_version, $url );
|
103 |
}
|
104 |
|
105 |
return self::$_instances[ $identifier ];
|
133 |
* @param bool|string $secret_key Element's secret key.
|
134 |
* @param bool $is_sandbox
|
135 |
* @param null|string $sdk_version
|
136 |
+
* @param null|string $url
|
137 |
*/
|
138 |
private function __construct(
|
139 |
$slug,
|
142 |
$public_key,
|
143 |
$secret_key,
|
144 |
$is_sandbox,
|
145 |
+
$sdk_version,
|
146 |
+
$url
|
147 |
) {
|
148 |
$this->_api = new Freemius_Api_WordPress( $scope, $id, $public_key, $secret_key, $is_sandbox );
|
149 |
|
150 |
$this->_slug = $slug;
|
151 |
$this->_sdk_version = $sdk_version;
|
152 |
+
$this->_url = $url;
|
153 |
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $slug . '_api', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
154 |
}
|
155 |
|
211 |
}
|
212 |
}
|
213 |
|
214 |
+
/**
|
215 |
+
* @since 2.5.0 Include the site's URL, if available, in all API requests that are going through the API manager.
|
216 |
+
*/
|
217 |
+
if ( ! empty( $this->_url ) ) {
|
218 |
+
if ( false === strpos( $path, 'url=' ) &&
|
219 |
+
! isset( $params['url'] )
|
220 |
+
) {
|
221 |
+
$path = add_query_arg( 'url', $this->_url, $path );
|
222 |
+
}
|
223 |
+
}
|
224 |
+
|
225 |
$result = $this->_api->Api( $path, $method, $params );
|
226 |
|
227 |
if ( null !== $result &&
|
freemius/includes/class-fs-lock.php
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 2.5.1
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class FS_Lock
|
15 |
+
*
|
16 |
+
* @author Vova Feldman (@svovaf)
|
17 |
+
* @since 2.5.1
|
18 |
+
*/
|
19 |
+
class FS_Lock {
|
20 |
+
/**
|
21 |
+
* @var int Random ID representing the current PHP thread.
|
22 |
+
*/
|
23 |
+
private static $_thread_id;
|
24 |
+
/**
|
25 |
+
* @var string
|
26 |
+
*/
|
27 |
+
private $_lock_id;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @param string $lock_id
|
31 |
+
*/
|
32 |
+
function __construct( $lock_id ) {
|
33 |
+
if ( ! fs_starts_with( $lock_id, WP_FS___OPTION_PREFIX ) ) {
|
34 |
+
$lock_id = WP_FS___OPTION_PREFIX . $lock_id;
|
35 |
+
}
|
36 |
+
|
37 |
+
$this->_lock_id = $lock_id;
|
38 |
+
|
39 |
+
if ( ! isset( self::$_thread_id ) ) {
|
40 |
+
self::$_thread_id = mt_rand( 0, 32000 );
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Try to acquire lock. If the lock is already set or is being acquired by another locker, don't do anything.
|
46 |
+
*
|
47 |
+
* @param int $expiration
|
48 |
+
*
|
49 |
+
* @return bool TRUE if successfully acquired lock.
|
50 |
+
*/
|
51 |
+
function try_lock( $expiration = 0 ) {
|
52 |
+
if ( $this->is_locked() ) {
|
53 |
+
// Already locked.
|
54 |
+
return false;
|
55 |
+
}
|
56 |
+
|
57 |
+
set_site_transient( $this->_lock_id, self::$_thread_id, $expiration );
|
58 |
+
|
59 |
+
if ( $this->has_lock() ) {
|
60 |
+
$this->lock($expiration);
|
61 |
+
|
62 |
+
return true;
|
63 |
+
}
|
64 |
+
|
65 |
+
return false;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Acquire lock regardless if it's already acquired by another locker or not.
|
70 |
+
*
|
71 |
+
* @author Vova Feldman (@svovaf)
|
72 |
+
* @since 2.1.0
|
73 |
+
*
|
74 |
+
* @param int $expiration
|
75 |
+
*/
|
76 |
+
function lock( $expiration = 0 ) {
|
77 |
+
set_site_transient( $this->_lock_id, true, $expiration );
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Checks if lock is currently acquired.
|
82 |
+
*
|
83 |
+
* @author Vova Feldman (@svovaf)
|
84 |
+
* @since 2.1.0
|
85 |
+
*
|
86 |
+
* @return bool
|
87 |
+
*/
|
88 |
+
function is_locked() {
|
89 |
+
return ( false !== get_site_transient( $this->_lock_id ) );
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Unlock the lock.
|
94 |
+
*
|
95 |
+
* @author Vova Feldman (@svovaf)
|
96 |
+
* @since 2.1.0
|
97 |
+
*/
|
98 |
+
function unlock() {
|
99 |
+
delete_site_transient( $this->_lock_id );
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Checks if lock is currently acquired by the current locker.
|
104 |
+
*
|
105 |
+
* @return bool
|
106 |
+
*/
|
107 |
+
protected function has_lock() {
|
108 |
+
return ( self::$_thread_id == get_site_transient( $this->_lock_id ) );
|
109 |
+
}
|
110 |
+
}
|
freemius/includes/class-fs-logger.php
CHANGED
@@ -38,9 +38,10 @@
|
|
38 |
private static $_HOOKED_FOOTER = false;
|
39 |
|
40 |
private function __construct( $id, $on = false, $echo = false ) {
|
|
|
|
|
41 |
$this->_id = $id;
|
42 |
|
43 |
-
$bt = debug_backtrace();
|
44 |
$caller = $bt[2];
|
45 |
|
46 |
if ( false !== strpos( $caller['file'], 'plugins' ) ) {
|
38 |
private static $_HOOKED_FOOTER = false;
|
39 |
|
40 |
private function __construct( $id, $on = false, $echo = false ) {
|
41 |
+
$bt = debug_backtrace();
|
42 |
+
|
43 |
$this->_id = $id;
|
44 |
|
|
|
45 |
$caller = $bt[2];
|
46 |
|
47 |
if ( false !== strpos( $caller['file'], 'plugins' ) ) {
|
freemius/includes/class-fs-plugin-updater.php
CHANGED
@@ -240,7 +240,11 @@
|
|
240 |
* @since 2.0.0
|
241 |
*/
|
242 |
private function add_transient_filters() {
|
243 |
-
if (
|
|
|
|
|
|
|
|
|
244 |
$this->_logger->log( 'Opted out sites cannot receive automatic software updates.' );
|
245 |
|
246 |
return;
|
@@ -413,7 +417,7 @@
|
|
413 |
|
414 |
$themes_update = get_site_transient( 'update_themes' );
|
415 |
if ( ! isset( $themes_update->response[ $theme_basename ] ) ||
|
416 |
-
|
417 |
) {
|
418 |
return $prepared_themes;
|
419 |
}
|
@@ -610,11 +614,9 @@
|
|
610 |
if ( ! isset( $this->_translation_updates ) ) {
|
611 |
$this->_translation_updates = array();
|
612 |
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
$this->_translation_updates = $translation_updates;
|
617 |
-
}
|
618 |
}
|
619 |
}
|
620 |
|
@@ -634,7 +636,7 @@
|
|
634 |
foreach ( $this->_translation_updates as $translation_update ) {
|
635 |
$lang = $translation_update['language'];
|
636 |
if ( ! isset( $current_plugin_translation_updates_map[ $lang ] ) ||
|
637 |
-
|
638 |
) {
|
639 |
$current_plugin_translation_updates_map[ $lang ] = $translation_update;
|
640 |
}
|
@@ -648,7 +650,7 @@
|
|
648 |
}
|
649 |
|
650 |
/**
|
651 |
-
* Get module's required data for the updates mechanism.
|
652 |
*
|
653 |
* @author Vova Feldman (@svovaf)
|
654 |
* @since 2.0.0
|
@@ -658,13 +660,14 @@
|
|
658 |
* @return object
|
659 |
*/
|
660 |
function get_update_details( FS_Plugin_Tag $new_version ) {
|
661 |
-
$update
|
662 |
-
$update->slug
|
663 |
-
$update->new_version
|
664 |
-
$update->url
|
665 |
-
$update->package
|
666 |
-
$update->tested
|
667 |
-
$update->requires
|
|
|
668 |
|
669 |
$icon = $this->_fs->get_local_icon_url();
|
670 |
|
@@ -806,9 +809,9 @@
|
|
806 |
$basename = $this->_fs->get_plugin_basename();
|
807 |
|
808 |
if ( ! is_object( $transient_data ) ||
|
809 |
-
|
810 |
! is_array( $transient_data->response ) ||
|
811 |
-
|
812 |
) {
|
813 |
return;
|
814 |
}
|
@@ -1093,6 +1096,7 @@ if ( !isset($info->error) ) {
|
|
1093 |
if ( ! $plugin_in_repo ) {
|
1094 |
$data->last_updated = ! is_null( $new_version->updated ) ? $new_version->updated : $new_version->created;
|
1095 |
$data->requires = $new_version->requires_platform_version;
|
|
|
1096 |
$data->tested = $new_version->tested_up_to_version;
|
1097 |
}
|
1098 |
|
@@ -1146,9 +1150,28 @@ if ( !isset($info->error) ) {
|
|
1146 |
}
|
1147 |
}
|
1148 |
|
|
|
|
|
|
|
|
|
1149 |
return $data;
|
1150 |
}
|
1151 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1152 |
/**
|
1153 |
* @author Vova Feldman (@svovaf)
|
1154 |
* @since 1.2.1.7
|
240 |
* @since 2.0.0
|
241 |
*/
|
242 |
private function add_transient_filters() {
|
243 |
+
if (
|
244 |
+
$this->_fs->is_premium() &&
|
245 |
+
$this->_fs->is_registered() &&
|
246 |
+
! FS_Permission_Manager::instance( $this->_fs )->is_essentials_tracking_allowed()
|
247 |
+
) {
|
248 |
$this->_logger->log( 'Opted out sites cannot receive automatic software updates.' );
|
249 |
|
250 |
return;
|
417 |
|
418 |
$themes_update = get_site_transient( 'update_themes' );
|
419 |
if ( ! isset( $themes_update->response[ $theme_basename ] ) ||
|
420 |
+
empty( $themes_update->response[ $theme_basename ]['package'] )
|
421 |
) {
|
422 |
return $prepared_themes;
|
423 |
}
|
614 |
if ( ! isset( $this->_translation_updates ) ) {
|
615 |
$this->_translation_updates = array();
|
616 |
|
617 |
+
$translation_updates = $this->fetch_wp_org_module_translation_updates( $module_type, $slug );
|
618 |
+
if ( ! empty( $translation_updates ) ) {
|
619 |
+
$this->_translation_updates = $translation_updates;
|
|
|
|
|
620 |
}
|
621 |
}
|
622 |
|
636 |
foreach ( $this->_translation_updates as $translation_update ) {
|
637 |
$lang = $translation_update['language'];
|
638 |
if ( ! isset( $current_plugin_translation_updates_map[ $lang ] ) ||
|
639 |
+
version_compare( $translation_update['version'], $current_plugin_translation_updates_map[ $lang ]['version'], '>' )
|
640 |
) {
|
641 |
$current_plugin_translation_updates_map[ $lang ] = $translation_update;
|
642 |
}
|
650 |
}
|
651 |
|
652 |
/**
|
653 |
+
* Get module's required data for the updates' mechanism.
|
654 |
*
|
655 |
* @author Vova Feldman (@svovaf)
|
656 |
* @since 2.0.0
|
660 |
* @return object
|
661 |
*/
|
662 |
function get_update_details( FS_Plugin_Tag $new_version ) {
|
663 |
+
$update = new stdClass();
|
664 |
+
$update->slug = $this->_fs->get_slug();
|
665 |
+
$update->new_version = $new_version->version;
|
666 |
+
$update->url = WP_FS__ADDRESS;
|
667 |
+
$update->package = $new_version->url;
|
668 |
+
$update->tested = self::get_tested_wp_version( $new_version->tested_up_to_version );
|
669 |
+
$update->requires = $new_version->requires_platform_version;
|
670 |
+
$update->requires_php = $new_version->requires_programming_language_version;
|
671 |
|
672 |
$icon = $this->_fs->get_local_icon_url();
|
673 |
|
809 |
$basename = $this->_fs->get_plugin_basename();
|
810 |
|
811 |
if ( ! is_object( $transient_data ) ||
|
812 |
+
! isset( $transient_data->response ) ||
|
813 |
! is_array( $transient_data->response ) ||
|
814 |
+
empty( $transient_data->response[ $basename ] )
|
815 |
) {
|
816 |
return;
|
817 |
}
|
1096 |
if ( ! $plugin_in_repo ) {
|
1097 |
$data->last_updated = ! is_null( $new_version->updated ) ? $new_version->updated : $new_version->created;
|
1098 |
$data->requires = $new_version->requires_platform_version;
|
1099 |
+
$data->requires_php = $new_version->requires_programming_language_version;
|
1100 |
$data->tested = $new_version->tested_up_to_version;
|
1101 |
}
|
1102 |
|
1150 |
}
|
1151 |
}
|
1152 |
|
1153 |
+
if ( ! empty( $data->tested ) ) {
|
1154 |
+
$data->tested = self::get_tested_wp_version( $data->tested );
|
1155 |
+
}
|
1156 |
+
|
1157 |
return $data;
|
1158 |
}
|
1159 |
|
1160 |
+
/**
|
1161 |
+
* @since 2.5.3 If the current WordPress version is a patch of the tested version (e.g., 6.1.2 is a patch of 6.1), then override the tested version with the patch so developers won't need to release a new version just to bump the latest supported WP version.
|
1162 |
+
*
|
1163 |
+
* @param string|null $tested_up_to
|
1164 |
+
*
|
1165 |
+
* @return string|null
|
1166 |
+
*/
|
1167 |
+
private static function get_tested_wp_version( $tested_up_to ) {
|
1168 |
+
$current_wp_version = get_bloginfo( 'version' );
|
1169 |
+
|
1170 |
+
return ( ! empty($tested_up_to) && fs_starts_with( $current_wp_version, $tested_up_to . '.' ) ) ?
|
1171 |
+
$current_wp_version :
|
1172 |
+
$tested_up_to;
|
1173 |
+
}
|
1174 |
+
|
1175 |
/**
|
1176 |
* @author Vova Feldman (@svovaf)
|
1177 |
* @since 1.2.1.7
|
freemius/includes/class-fs-storage.php
CHANGED
@@ -15,9 +15,11 @@
|
|
15 |
*
|
16 |
* A wrapper class for handling network level and single site level storage.
|
17 |
*
|
18 |
-
* @property bool
|
19 |
-
* @property int
|
20 |
-
* @property
|
|
|
|
|
21 |
*/
|
22 |
class FS_Storage {
|
23 |
/**
|
@@ -72,6 +74,16 @@
|
|
72 |
*/
|
73 |
private static $_NETWORK_OPTIONS_MAP;
|
74 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
/**
|
76 |
* @author Leo Fajardo (@leorw)
|
77 |
*
|
@@ -142,10 +154,17 @@
|
|
142 |
* @param string $key
|
143 |
* @param mixed $value
|
144 |
* @param null|bool|int $network_level_or_blog_id When an integer, use the given blog storage. When `true` use the multisite storage (if there's a network). When `false`, use the current context blog storage. When `null`, the decision which storage to use (MS vs. Current S) will be handled internally and determined based on the $option (based on self::$_BINARY_MAP).
|
|
|
145 |
* @param bool $flush
|
146 |
*/
|
147 |
-
function store(
|
148 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
$this->_network_storage->store( $key, $value, $flush );
|
150 |
} else {
|
151 |
$storage = $this->get_site_storage( $network_level_or_blog_id );
|
@@ -199,11 +218,17 @@
|
|
199 |
* @param string $key
|
200 |
* @param mixed $default
|
201 |
* @param null|bool|int $network_level_or_blog_id When an integer, use the given blog storage. When `true` use the multisite storage (if there's a network). When `false`, use the current context blog storage. When `null`, the decision which storage to use (MS vs. Current S) will be handled internally and determined based on the $option (based on self::$_BINARY_MAP).
|
|
|
202 |
*
|
203 |
* @return mixed
|
204 |
*/
|
205 |
-
function get(
|
206 |
-
|
|
|
|
|
|
|
|
|
|
|
207 |
return $this->_network_storage->get( $key, $default );
|
208 |
} else {
|
209 |
$storage = $this->get_site_storage( $network_level_or_blog_id );
|
@@ -289,19 +314,6 @@
|
|
289 |
// Migrate option to the network storage.
|
290 |
$this->_network_storage->store( $option, $this->_storage->{$option}, false );
|
291 |
|
292 |
-
/**
|
293 |
-
* Remove the option from site level storage.
|
294 |
-
*
|
295 |
-
* IMPORTANT:
|
296 |
-
* The line below is intentionally commented since we want to preserve the option
|
297 |
-
* on the site storage level for "downgrade compatibility". Basically, if the user
|
298 |
-
* will downgrade to an older version of the plugin with the prev storage structure,
|
299 |
-
* it will continue working.
|
300 |
-
*
|
301 |
-
* @todo After a few releases we can remove this.
|
302 |
-
*/
|
303 |
-
// $this->_storage->remove($option, false);
|
304 |
-
|
305 |
$updated = true;
|
306 |
}
|
307 |
}
|
@@ -336,63 +348,61 @@
|
|
336 |
private static function load_network_options_map() {
|
337 |
self::$_NETWORK_OPTIONS_MAP = array(
|
338 |
// Network level options.
|
339 |
-
'affiliate_application_data' =>
|
340 |
-
'beta_data' =>
|
341 |
-
'connectivity_test' =>
|
342 |
-
'handle_gdpr_admin_notice' =>
|
343 |
-
'has_trial_plan' =>
|
344 |
-
'install_sync_timestamp' =>
|
345 |
-
'install_sync_cron' =>
|
346 |
-
'is_anonymous_ms' =>
|
347 |
-
'is_network_activated' =>
|
348 |
-
'is_on' =>
|
349 |
-
'is_plugin_new_install' =>
|
350 |
-
'network_install_blog_id' =>
|
351 |
-
'pending_sites_info' =>
|
352 |
-
'plugin_last_version' =>
|
353 |
-
'plugin_main_file' =>
|
354 |
-
'plugin_version' =>
|
355 |
-
'sdk_downgrade_mode' =>
|
356 |
-
'sdk_last_version' =>
|
357 |
-
'sdk_upgrade_mode' =>
|
358 |
-
'sdk_version' =>
|
359 |
-
'sticky_optin_added_ms' =>
|
360 |
-
'subscriptions' =>
|
361 |
-
'sync_timestamp' =>
|
362 |
-
'sync_cron' =>
|
363 |
-
'was_plugin_loaded' =>
|
364 |
-
'network_user_id' =>
|
365 |
-
'plugin_upgrade_mode' =>
|
366 |
-
'plugin_downgrade_mode' =>
|
367 |
-
'is_network_connected' =>
|
368 |
/**
|
369 |
-
* Special flag that is used when a super-admin upgrades to the new version of the SDK that
|
370 |
-
* supports network level integration, when the connection decision wasn't made for all of the
|
371 |
-
* sites in the network.
|
372 |
*/
|
373 |
-
'is_network_activation' =>
|
374 |
-
'license_migration' =>
|
375 |
|
376 |
// When network activated, then network level.
|
377 |
-
'install_timestamp' =>
|
378 |
-
'prev_is_premium' =>
|
379 |
-
'require_license_activation' =>
|
380 |
|
381 |
// If not network activated OR delegated, then site level.
|
382 |
-
'activation_timestamp'
|
383 |
-
'expired_license_notice_shown'
|
384 |
-
'is_whitelabeled'
|
385 |
-
'last_license_key'
|
386 |
-
'last_license_user_id'
|
387 |
-
'prev_user_id'
|
388 |
-
'sticky_optin_added'
|
389 |
-
'uninstall_reason'
|
390 |
-
'is_pending_activation'
|
391 |
-
'pending_license_key'
|
392 |
-
'is_extensions_tracking_allowed' => 2,
|
393 |
|
394 |
// Site level options.
|
395 |
-
'is_anonymous' =>
|
|
|
396 |
);
|
397 |
}
|
398 |
|
@@ -403,25 +413,33 @@
|
|
403 |
* @since 2.0.0
|
404 |
*
|
405 |
* @param string $key
|
|
|
406 |
*
|
407 |
-
* @return bool
|
408 |
*/
|
409 |
-
private function is_multisite_option( $key ) {
|
410 |
if ( ! isset( self::$_NETWORK_OPTIONS_MAP ) ) {
|
411 |
self::load_network_options_map();
|
412 |
}
|
413 |
|
414 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
415 |
// Option not found -> use site level storage.
|
416 |
return false;
|
417 |
}
|
418 |
|
419 |
-
if (
|
420 |
// Option found and set to always use the network level storage on a multisite.
|
421 |
return true;
|
422 |
}
|
423 |
|
424 |
-
if (
|
425 |
// Option found and set to always use the site level storage on a multisite.
|
426 |
return false;
|
427 |
}
|
@@ -430,12 +448,15 @@
|
|
430 |
return false;
|
431 |
}
|
432 |
|
433 |
-
if (
|
434 |
// Network activated.
|
435 |
return true;
|
436 |
}
|
437 |
|
438 |
-
if (
|
|
|
|
|
|
|
439 |
// Network activated and not delegated.
|
440 |
return true;
|
441 |
}
|
@@ -448,10 +469,15 @@
|
|
448 |
*
|
449 |
* @param string $key
|
450 |
* @param null|bool|int $network_level_or_blog_id When an integer, use the given blog storage. When `true` use the multisite storage (if there's a network). When `false`, use the current context blog storage. When `null`, the decision which storage to use (MS vs. Current S) will be handled internally and determined based on the $option (based on self::$_BINARY_MAP).
|
|
|
451 |
*
|
452 |
* @return bool
|
453 |
*/
|
454 |
-
private function should_use_network_storage(
|
|
|
|
|
|
|
|
|
455 |
if ( ! $this->_is_multisite ) {
|
456 |
// Not a multisite environment.
|
457 |
return false;
|
@@ -463,12 +489,12 @@
|
|
463 |
}
|
464 |
|
465 |
if ( is_bool( $network_level_or_blog_id ) ) {
|
466 |
-
// Explicitly specified whether should use the network or blog level storage.
|
467 |
return $network_level_or_blog_id;
|
468 |
}
|
469 |
|
470 |
// Determine which storage to use based on the option.
|
471 |
-
return $this->is_multisite_option( $key );
|
472 |
}
|
473 |
|
474 |
/**
|
@@ -529,4 +555,4 @@
|
|
529 |
}
|
530 |
|
531 |
#endregion
|
532 |
-
}
|
15 |
*
|
16 |
* A wrapper class for handling network level and single site level storage.
|
17 |
*
|
18 |
+
* @property bool $is_network_activation
|
19 |
+
* @property int $network_install_blog_id
|
20 |
+
* @property bool|null $is_extensions_tracking_allowed
|
21 |
+
* @property bool|null $is_diagnostic_tracking_allowed
|
22 |
+
* @property object $sync_cron
|
23 |
*/
|
24 |
class FS_Storage {
|
25 |
/**
|
74 |
*/
|
75 |
private static $_NETWORK_OPTIONS_MAP;
|
76 |
|
77 |
+
const OPTION_LEVEL_UNDEFINED = -1;
|
78 |
+
// The option should be stored on the network level.
|
79 |
+
const OPTION_LEVEL_NETWORK = 0;
|
80 |
+
// The option should be stored on the network level when the plugin is network-activated.
|
81 |
+
const OPTION_LEVEL_NETWORK_ACTIVATED = 1;
|
82 |
+
// The option should be stored on the network level when the plugin is network-activated and the opt-in connection was NOT delegated to the sub-site admin.
|
83 |
+
const OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED = 2;
|
84 |
+
// The option should be stored on the site level.
|
85 |
+
const OPTION_LEVEL_SITE = 3;
|
86 |
+
|
87 |
/**
|
88 |
* @author Leo Fajardo (@leorw)
|
89 |
*
|
154 |
* @param string $key
|
155 |
* @param mixed $value
|
156 |
* @param null|bool|int $network_level_or_blog_id When an integer, use the given blog storage. When `true` use the multisite storage (if there's a network). When `false`, use the current context blog storage. When `null`, the decision which storage to use (MS vs. Current S) will be handled internally and determined based on the $option (based on self::$_BINARY_MAP).
|
157 |
+
* @param int $option_level Since 2.5.1
|
158 |
* @param bool $flush
|
159 |
*/
|
160 |
+
function store(
|
161 |
+
$key,
|
162 |
+
$value,
|
163 |
+
$network_level_or_blog_id = null,
|
164 |
+
$option_level = self::OPTION_LEVEL_UNDEFINED,
|
165 |
+
$flush = true
|
166 |
+
) {
|
167 |
+
if ( $this->should_use_network_storage( $key, $network_level_or_blog_id, $option_level ) ) {
|
168 |
$this->_network_storage->store( $key, $value, $flush );
|
169 |
} else {
|
170 |
$storage = $this->get_site_storage( $network_level_or_blog_id );
|
218 |
* @param string $key
|
219 |
* @param mixed $default
|
220 |
* @param null|bool|int $network_level_or_blog_id When an integer, use the given blog storage. When `true` use the multisite storage (if there's a network). When `false`, use the current context blog storage. When `null`, the decision which storage to use (MS vs. Current S) will be handled internally and determined based on the $option (based on self::$_BINARY_MAP).
|
221 |
+
* @param int $option_level Since 2.5.1
|
222 |
*
|
223 |
* @return mixed
|
224 |
*/
|
225 |
+
function get(
|
226 |
+
$key,
|
227 |
+
$default = false,
|
228 |
+
$network_level_or_blog_id = null,
|
229 |
+
$option_level = self::OPTION_LEVEL_UNDEFINED
|
230 |
+
) {
|
231 |
+
if ( $this->should_use_network_storage( $key, $network_level_or_blog_id, $option_level ) ) {
|
232 |
return $this->_network_storage->get( $key, $default );
|
233 |
} else {
|
234 |
$storage = $this->get_site_storage( $network_level_or_blog_id );
|
314 |
// Migrate option to the network storage.
|
315 |
$this->_network_storage->store( $option, $this->_storage->{$option}, false );
|
316 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
317 |
$updated = true;
|
318 |
}
|
319 |
}
|
348 |
private static function load_network_options_map() {
|
349 |
self::$_NETWORK_OPTIONS_MAP = array(
|
350 |
// Network level options.
|
351 |
+
'affiliate_application_data' => self::OPTION_LEVEL_NETWORK,
|
352 |
+
'beta_data' => self::OPTION_LEVEL_NETWORK,
|
353 |
+
'connectivity_test' => self::OPTION_LEVEL_NETWORK,
|
354 |
+
'handle_gdpr_admin_notice' => self::OPTION_LEVEL_NETWORK,
|
355 |
+
'has_trial_plan' => self::OPTION_LEVEL_NETWORK,
|
356 |
+
'install_sync_timestamp' => self::OPTION_LEVEL_NETWORK,
|
357 |
+
'install_sync_cron' => self::OPTION_LEVEL_NETWORK,
|
358 |
+
'is_anonymous_ms' => self::OPTION_LEVEL_NETWORK,
|
359 |
+
'is_network_activated' => self::OPTION_LEVEL_NETWORK,
|
360 |
+
'is_on' => self::OPTION_LEVEL_NETWORK,
|
361 |
+
'is_plugin_new_install' => self::OPTION_LEVEL_NETWORK,
|
362 |
+
'network_install_blog_id' => self::OPTION_LEVEL_NETWORK,
|
363 |
+
'pending_sites_info' => self::OPTION_LEVEL_NETWORK,
|
364 |
+
'plugin_last_version' => self::OPTION_LEVEL_NETWORK,
|
365 |
+
'plugin_main_file' => self::OPTION_LEVEL_NETWORK,
|
366 |
+
'plugin_version' => self::OPTION_LEVEL_NETWORK,
|
367 |
+
'sdk_downgrade_mode' => self::OPTION_LEVEL_NETWORK,
|
368 |
+
'sdk_last_version' => self::OPTION_LEVEL_NETWORK,
|
369 |
+
'sdk_upgrade_mode' => self::OPTION_LEVEL_NETWORK,
|
370 |
+
'sdk_version' => self::OPTION_LEVEL_NETWORK,
|
371 |
+
'sticky_optin_added_ms' => self::OPTION_LEVEL_NETWORK,
|
372 |
+
'subscriptions' => self::OPTION_LEVEL_NETWORK,
|
373 |
+
'sync_timestamp' => self::OPTION_LEVEL_NETWORK,
|
374 |
+
'sync_cron' => self::OPTION_LEVEL_NETWORK,
|
375 |
+
'was_plugin_loaded' => self::OPTION_LEVEL_NETWORK,
|
376 |
+
'network_user_id' => self::OPTION_LEVEL_NETWORK,
|
377 |
+
'plugin_upgrade_mode' => self::OPTION_LEVEL_NETWORK,
|
378 |
+
'plugin_downgrade_mode' => self::OPTION_LEVEL_NETWORK,
|
379 |
+
'is_network_connected' => self::OPTION_LEVEL_NETWORK,
|
380 |
/**
|
381 |
+
* Special flag that is used when a super-admin upgrades to the new version of the SDK that supports network level integration, when the connection decision wasn't made for all the sites in the network.
|
|
|
|
|
382 |
*/
|
383 |
+
'is_network_activation' => self::OPTION_LEVEL_NETWORK,
|
384 |
+
'license_migration' => self::OPTION_LEVEL_NETWORK,
|
385 |
|
386 |
// When network activated, then network level.
|
387 |
+
'install_timestamp' => self::OPTION_LEVEL_NETWORK_ACTIVATED,
|
388 |
+
'prev_is_premium' => self::OPTION_LEVEL_NETWORK_ACTIVATED,
|
389 |
+
'require_license_activation' => self::OPTION_LEVEL_NETWORK_ACTIVATED,
|
390 |
|
391 |
// If not network activated OR delegated, then site level.
|
392 |
+
'activation_timestamp' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
|
393 |
+
'expired_license_notice_shown' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
|
394 |
+
'is_whitelabeled' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
|
395 |
+
'last_license_key' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
|
396 |
+
'last_license_user_id' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
|
397 |
+
'prev_user_id' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
|
398 |
+
'sticky_optin_added' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
|
399 |
+
'uninstall_reason' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
|
400 |
+
'is_pending_activation' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
|
401 |
+
'pending_license_key' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
|
|
|
402 |
|
403 |
// Site level options.
|
404 |
+
'is_anonymous' => self::OPTION_LEVEL_SITE,
|
405 |
+
'clone_id' => self::OPTION_LEVEL_SITE,
|
406 |
);
|
407 |
}
|
408 |
|
413 |
* @since 2.0.0
|
414 |
*
|
415 |
* @param string $key
|
416 |
+
* @param int $option_level Since 2.5.1
|
417 |
*
|
418 |
+
* @return bool
|
419 |
*/
|
420 |
+
private function is_multisite_option( $key, $option_level = self::OPTION_LEVEL_UNDEFINED ) {
|
421 |
if ( ! isset( self::$_NETWORK_OPTIONS_MAP ) ) {
|
422 |
self::load_network_options_map();
|
423 |
}
|
424 |
|
425 |
+
if (
|
426 |
+
self::OPTION_LEVEL_UNDEFINED === $option_level &&
|
427 |
+
isset( self::$_NETWORK_OPTIONS_MAP[ $key ] )
|
428 |
+
) {
|
429 |
+
$option_level = self::$_NETWORK_OPTIONS_MAP[ $key ];
|
430 |
+
}
|
431 |
+
|
432 |
+
if ( self::OPTION_LEVEL_UNDEFINED === $option_level ) {
|
433 |
// Option not found -> use site level storage.
|
434 |
return false;
|
435 |
}
|
436 |
|
437 |
+
if ( self::OPTION_LEVEL_NETWORK === $option_level ) {
|
438 |
// Option found and set to always use the network level storage on a multisite.
|
439 |
return true;
|
440 |
}
|
441 |
|
442 |
+
if ( self::OPTION_LEVEL_SITE === $option_level ) {
|
443 |
// Option found and set to always use the site level storage on a multisite.
|
444 |
return false;
|
445 |
}
|
448 |
return false;
|
449 |
}
|
450 |
|
451 |
+
if ( self::OPTION_LEVEL_NETWORK_ACTIVATED === $option_level ) {
|
452 |
// Network activated.
|
453 |
return true;
|
454 |
}
|
455 |
|
456 |
+
if (
|
457 |
+
self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED === $option_level &&
|
458 |
+
! $this->_is_delegated_connection
|
459 |
+
) {
|
460 |
// Network activated and not delegated.
|
461 |
return true;
|
462 |
}
|
469 |
*
|
470 |
* @param string $key
|
471 |
* @param null|bool|int $network_level_or_blog_id When an integer, use the given blog storage. When `true` use the multisite storage (if there's a network). When `false`, use the current context blog storage. When `null`, the decision which storage to use (MS vs. Current S) will be handled internally and determined based on the $option (based on self::$_BINARY_MAP).
|
472 |
+
* @param int $option_level Since 2.5.1
|
473 |
*
|
474 |
* @return bool
|
475 |
*/
|
476 |
+
private function should_use_network_storage(
|
477 |
+
$key,
|
478 |
+
$network_level_or_blog_id = null,
|
479 |
+
$option_level = self::OPTION_LEVEL_UNDEFINED
|
480 |
+
) {
|
481 |
if ( ! $this->_is_multisite ) {
|
482 |
// Not a multisite environment.
|
483 |
return false;
|
489 |
}
|
490 |
|
491 |
if ( is_bool( $network_level_or_blog_id ) ) {
|
492 |
+
// Explicitly specified whether it should use the network or blog level storage.
|
493 |
return $network_level_or_blog_id;
|
494 |
}
|
495 |
|
496 |
// Determine which storage to use based on the option.
|
497 |
+
return $this->is_multisite_option( $key, $option_level );
|
498 |
}
|
499 |
|
500 |
/**
|
555 |
}
|
556 |
|
557 |
#endregion
|
558 |
+
}
|
freemius/includes/class-fs-user-lock.php
CHANGED
@@ -10,18 +10,16 @@
|
|
10 |
exit;
|
11 |
}
|
12 |
|
|
|
|
|
13 |
/**
|
14 |
* Class FS_User_Lock
|
15 |
*/
|
16 |
class FS_User_Lock {
|
17 |
/**
|
18 |
-
* @var
|
19 |
-
*/
|
20 |
-
private $_wp_user_id;
|
21 |
-
/**
|
22 |
-
* @var int
|
23 |
*/
|
24 |
-
private $
|
25 |
|
26 |
#--------------------------------------------------------------------------------
|
27 |
#region Singleton
|
@@ -49,10 +47,10 @@
|
|
49 |
#endregion
|
50 |
|
51 |
private function __construct() {
|
52 |
-
$
|
53 |
-
$this->_thread_id = mt_rand( 0, 32000 );
|
54 |
-
}
|
55 |
|
|
|
|
|
56 |
|
57 |
/**
|
58 |
* Try to acquire lock. If the lock is already set or is being acquired by another locker, don't do anything.
|
@@ -65,20 +63,7 @@
|
|
65 |
* @return bool TRUE if successfully acquired lock.
|
66 |
*/
|
67 |
function try_lock( $expiration = 0 ) {
|
68 |
-
|
69 |
-
// Already locked.
|
70 |
-
return false;
|
71 |
-
}
|
72 |
-
|
73 |
-
set_site_transient( "locked_{$this->_wp_user_id}", $this->_thread_id, $expiration );
|
74 |
-
|
75 |
-
if ( $this->has_lock() ) {
|
76 |
-
set_site_transient( "locked_{$this->_wp_user_id}", true, $expiration );
|
77 |
-
|
78 |
-
return true;
|
79 |
-
}
|
80 |
-
|
81 |
-
return false;
|
82 |
}
|
83 |
|
84 |
/**
|
@@ -90,19 +75,7 @@
|
|
90 |
* @param int $expiration
|
91 |
*/
|
92 |
function lock( $expiration = 0 ) {
|
93 |
-
|
94 |
-
}
|
95 |
-
|
96 |
-
/**
|
97 |
-
* Checks if lock is currently acquired.
|
98 |
-
*
|
99 |
-
* @author Vova Feldman (@svovaf)
|
100 |
-
* @since 2.1.0
|
101 |
-
*
|
102 |
-
* @return bool
|
103 |
-
*/
|
104 |
-
function is_locked() {
|
105 |
-
return ( false !== get_site_transient( "locked_{$this->_wp_user_id}" ) );
|
106 |
}
|
107 |
|
108 |
/**
|
@@ -112,15 +85,6 @@
|
|
112 |
* @since 2.1.0
|
113 |
*/
|
114 |
function unlock() {
|
115 |
-
|
116 |
-
}
|
117 |
-
|
118 |
-
/**
|
119 |
-
* Checks if lock is currently acquired by the current locker.
|
120 |
-
*
|
121 |
-
* @return bool
|
122 |
-
*/
|
123 |
-
private function has_lock() {
|
124 |
-
return ( $this->_thread_id == get_site_transient( "locked_{$this->_wp_user_id}" ) );
|
125 |
}
|
126 |
}
|
10 |
exit;
|
11 |
}
|
12 |
|
13 |
+
require_once WP_FS__DIR_INCLUDES . '/class-fs-lock.php';
|
14 |
+
|
15 |
/**
|
16 |
* Class FS_User_Lock
|
17 |
*/
|
18 |
class FS_User_Lock {
|
19 |
/**
|
20 |
+
* @var FS_Lock
|
|
|
|
|
|
|
|
|
21 |
*/
|
22 |
+
private $_lock;
|
23 |
|
24 |
#--------------------------------------------------------------------------------
|
25 |
#region Singleton
|
47 |
#endregion
|
48 |
|
49 |
private function __construct() {
|
50 |
+
$current_user_id = Freemius::get_current_wp_user_id();
|
|
|
|
|
51 |
|
52 |
+
$this->_lock = new FS_Lock( "locked_{$current_user_id}" );
|
53 |
+
}
|
54 |
|
55 |
/**
|
56 |
* Try to acquire lock. If the lock is already set or is being acquired by another locker, don't do anything.
|
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 |
/**
|
75 |
* @param int $expiration
|
76 |
*/
|
77 |
function lock( $expiration = 0 ) {
|
78 |
+
$this->_lock->lock( $expiration );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
80 |
|
81 |
/**
|
85 |
* @since 2.1.0
|
86 |
*/
|
87 |
function unlock() {
|
88 |
+
$this->_lock->unlock();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
}
|
90 |
}
|
freemius/includes/customizer/class-fs-customizer-upsell-control.php
CHANGED
@@ -101,11 +101,11 @@
|
|
101 |
}
|
102 |
}
|
103 |
}
|
|
|
|
|
104 |
}
|
105 |
}
|
106 |
|
107 |
-
$this->json['plans'] = $pricing->plans;
|
108 |
-
|
109 |
$this->json['strings'] = array(
|
110 |
'plan' => $this->fs->get_text_x_inline( 'Plan', 'as product pricing plan', 'plan' ),
|
111 |
);
|
101 |
}
|
102 |
}
|
103 |
}
|
104 |
+
|
105 |
+
$this->json['plans'] = $pricing->plans;
|
106 |
}
|
107 |
}
|
108 |
|
|
|
|
|
109 |
$this->json['strings'] = array(
|
110 |
'plan' => $this->fs->get_text_x_inline( 'Plan', 'as product pricing plan', 'plan' ),
|
111 |
);
|
freemius/includes/entities/class-fs-affiliate-terms.php
CHANGED
@@ -84,6 +84,10 @@
|
|
84 |
* @var bool If `true`, allow referrals from any site.
|
85 |
*/
|
86 |
public $is_any_site_allowed;
|
|
|
|
|
|
|
|
|
87 |
|
88 |
#endregion Properties
|
89 |
|
84 |
* @var bool If `true`, allow referrals from any site.
|
85 |
*/
|
86 |
public $is_any_site_allowed;
|
87 |
+
/**
|
88 |
+
* @var string $plugin_title Title of the plugin. This is used in case we are showing affiliate form for a Bundle instead of the `plugin` in context.
|
89 |
+
*/
|
90 |
+
public $plugin_title;
|
91 |
|
92 |
#endregion Properties
|
93 |
|
freemius/includes/entities/class-fs-plugin-tag.php
CHANGED
@@ -23,6 +23,10 @@
|
|
23 |
* @var string
|
24 |
*/
|
25 |
public $requires_platform_version;
|
|
|
|
|
|
|
|
|
26 |
/**
|
27 |
* @var string
|
28 |
*/
|
23 |
* @var string
|
24 |
*/
|
25 |
public $requires_platform_version;
|
26 |
+
/**
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
public $requires_programming_language_version;
|
30 |
/**
|
31 |
* @var string
|
32 |
*/
|
freemius/includes/entities/class-fs-site.php
CHANGED
@@ -10,6 +10,9 @@
|
|
10 |
exit;
|
11 |
}
|
12 |
|
|
|
|
|
|
|
13 |
class FS_Site extends FS_Scope_Entity {
|
14 |
/**
|
15 |
* @var number
|
@@ -39,10 +42,6 @@
|
|
39 |
* @var string E.g. en-GB
|
40 |
*/
|
41 |
public $language;
|
42 |
-
/**
|
43 |
-
* @var string E.g. UTF-8
|
44 |
-
*/
|
45 |
-
public $charset;
|
46 |
/**
|
47 |
* @var string Platform version (e.g WordPress version).
|
48 |
*/
|
@@ -86,6 +85,8 @@
|
|
86 |
* @author Leo Fajardo (@leorw)
|
87 |
*
|
88 |
* @since 1.2.1.5
|
|
|
|
|
89 |
*
|
90 |
* @var bool
|
91 |
*/
|
@@ -190,7 +191,13 @@
|
|
190 |
// DesktopServer
|
191 |
fs_ends_with( $subdomain, '.dev.cc' ) ||
|
192 |
// Pressable
|
193 |
-
fs_ends_with( $subdomain, '.mystagingwebsite.com' )
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
);
|
195 |
}
|
196 |
|
@@ -223,31 +230,25 @@
|
|
223 |
}
|
224 |
|
225 |
/**
|
226 |
-
* @author
|
227 |
-
* @since 2.0.0
|
228 |
*
|
229 |
* @return bool
|
230 |
*/
|
231 |
-
function
|
232 |
-
return ( true
|
233 |
}
|
234 |
|
235 |
/**
|
236 |
-
* @author
|
237 |
-
* @since
|
238 |
*
|
239 |
-
* @
|
240 |
-
*/
|
241 |
-
function is_tracking_prohibited() {
|
242 |
-
return ! $this->is_tracking_allowed();
|
243 |
-
}
|
244 |
-
|
245 |
-
/**
|
246 |
-
* @author Edgar Melkonyan
|
247 |
*
|
248 |
* @return bool
|
249 |
*/
|
250 |
-
function
|
251 |
-
|
|
|
|
|
252 |
}
|
253 |
}
|
10 |
exit;
|
11 |
}
|
12 |
|
13 |
+
/**
|
14 |
+
* @property int $blog_id
|
15 |
+
*/
|
16 |
class FS_Site extends FS_Scope_Entity {
|
17 |
/**
|
18 |
* @var number
|
42 |
* @var string E.g. en-GB
|
43 |
*/
|
44 |
public $language;
|
|
|
|
|
|
|
|
|
45 |
/**
|
46 |
* @var string Platform version (e.g WordPress version).
|
47 |
*/
|
85 |
* @author Leo Fajardo (@leorw)
|
86 |
*
|
87 |
* @since 1.2.1.5
|
88 |
+
* @deprecated Since 2.5.1
|
89 |
+
* @todo Remove after a few releases.
|
90 |
*
|
91 |
* @var bool
|
92 |
*/
|
191 |
// DesktopServer
|
192 |
fs_ends_with( $subdomain, '.dev.cc' ) ||
|
193 |
// Pressable
|
194 |
+
fs_ends_with( $subdomain, '.mystagingwebsite.com' ) ||
|
195 |
+
// WPMU DEV
|
196 |
+
( fs_ends_with( $subdomain, '.tempurl.host' ) || fs_ends_with( $subdomain, '.wpmudev.host' ) ) ||
|
197 |
+
// Vendasta
|
198 |
+
( fs_ends_with( $subdomain, '.websitepro-staging.com' ) || fs_ends_with( $subdomain, '.websitepro.hosting' ) ) ||
|
199 |
+
// InstaWP
|
200 |
+
fs_ends_with( $subdomain, '.instawp.xyz' )
|
201 |
);
|
202 |
}
|
203 |
|
230 |
}
|
231 |
|
232 |
/**
|
233 |
+
* @author Edgar Melkonyan
|
|
|
234 |
*
|
235 |
* @return bool
|
236 |
*/
|
237 |
+
function is_beta() {
|
238 |
+
return ( isset( $this->is_beta ) && true === $this->is_beta );
|
239 |
}
|
240 |
|
241 |
/**
|
242 |
+
* @author Leo Fajardo (@leorw)
|
243 |
+
* @since 2.5.1
|
244 |
*
|
245 |
+
* @param string $site_url
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
*
|
247 |
* @return bool
|
248 |
*/
|
249 |
+
function is_clone( $site_url ) {
|
250 |
+
$clone_install_url = trailingslashit( fs_strip_url_protocol( $this->url ) );
|
251 |
+
|
252 |
+
return ( $clone_install_url !== $site_url );
|
253 |
}
|
254 |
}
|
freemius/includes/entities/class-fs-user.php
CHANGED
@@ -56,7 +56,18 @@
|
|
56 |
return ( isset( $this->is_verified ) && true === $this->is_verified );
|
57 |
}
|
58 |
|
59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
return 'user';
|
61 |
}
|
62 |
}
|
56 |
return ( isset( $this->is_verified ) && true === $this->is_verified );
|
57 |
}
|
58 |
|
59 |
+
/**
|
60 |
+
* @author Leo Fajardo (@leorw)
|
61 |
+
* @since 2.4.2
|
62 |
+
*
|
63 |
+
* @return bool
|
64 |
+
*/
|
65 |
+
function is_beta() {
|
66 |
+
// Return `false` since this is just for backward compatibility.
|
67 |
+
return false;
|
68 |
+
}
|
69 |
+
|
70 |
+
static function get_type() {
|
71 |
return 'user';
|
72 |
}
|
73 |
}
|
freemius/includes/fs-core-functions.php
CHANGED
@@ -756,7 +756,7 @@
|
|
756 |
} // If b has a priority and a does not, b wins.
|
757 |
elseif ( isset( $a['priority'] ) && ! isset( $b['priority'] ) ) {
|
758 |
return - 1;
|
759 |
-
} // If neither has a priority or both priorities are equal
|
760 |
elseif ( ( ! isset( $a['priority'] ) && ! isset( $b['priority'] ) ) || $a['priority'] === $b['priority'] ) {
|
761 |
return 0;
|
762 |
}
|
@@ -770,6 +770,12 @@
|
|
770 |
#region Localization
|
771 |
#--------------------------------------------------------------------------------
|
772 |
|
|
|
|
|
|
|
|
|
|
|
|
|
773 |
if ( ! function_exists( 'fs_text' ) ) {
|
774 |
/**
|
775 |
* Retrieve a translated text by key.
|
@@ -782,12 +788,10 @@
|
|
782 |
*
|
783 |
* @return string
|
784 |
*
|
785 |
-
* @global $
|
786 |
*/
|
787 |
function fs_text( $key, $slug = 'freemius' ) {
|
788 |
-
global $
|
789 |
-
$fs_module_info_text,
|
790 |
-
$fs_text_overrides;
|
791 |
|
792 |
if ( isset( $fs_text_overrides[ $slug ] ) ) {
|
793 |
if ( isset( $fs_text_overrides[ $slug ][ $key ] ) ) {
|
@@ -800,22 +804,6 @@
|
|
800 |
}
|
801 |
}
|
802 |
|
803 |
-
if ( ! isset( $fs_text ) ) {
|
804 |
-
$dir = defined( 'WP_FS__DIR_INCLUDES' ) ?
|
805 |
-
WP_FS__DIR_INCLUDES :
|
806 |
-
dirname( __FILE__ );
|
807 |
-
|
808 |
-
require_once $dir . '/i18n.php';
|
809 |
-
}
|
810 |
-
|
811 |
-
if ( isset( $fs_text[ $key ] ) ) {
|
812 |
-
return $fs_text[ $key ];
|
813 |
-
}
|
814 |
-
|
815 |
-
if ( isset( $fs_module_info_text[ $key ] ) ) {
|
816 |
-
return $fs_module_info_text[ $key ];
|
817 |
-
}
|
818 |
-
|
819 |
return $key;
|
820 |
}
|
821 |
|
@@ -1349,7 +1337,7 @@
|
|
1349 |
function fs_is_plugin_uninstall() {
|
1350 |
return (
|
1351 |
defined( 'WP_UNINSTALL_PLUGIN' ) ||
|
1352 |
-
( 0 < did_action( '
|
1353 |
);
|
1354 |
}
|
1355 |
}
|
756 |
} // If b has a priority and a does not, b wins.
|
757 |
elseif ( isset( $a['priority'] ) && ! isset( $b['priority'] ) ) {
|
758 |
return - 1;
|
759 |
+
} // If neither has a priority or both priorities are equal it's a tie.
|
760 |
elseif ( ( ! isset( $a['priority'] ) && ! isset( $b['priority'] ) ) || $a['priority'] === $b['priority'] ) {
|
761 |
return 0;
|
762 |
}
|
770 |
#region Localization
|
771 |
#--------------------------------------------------------------------------------
|
772 |
|
773 |
+
global $fs_text_overrides;
|
774 |
+
|
775 |
+
if ( ! isset( $fs_text_overrides ) ) {
|
776 |
+
$fs_text_overrides = array();
|
777 |
+
}
|
778 |
+
|
779 |
if ( ! function_exists( 'fs_text' ) ) {
|
780 |
/**
|
781 |
* Retrieve a translated text by key.
|
788 |
*
|
789 |
* @return string
|
790 |
*
|
791 |
+
* @global $fs_text_overrides
|
792 |
*/
|
793 |
function fs_text( $key, $slug = 'freemius' ) {
|
794 |
+
global $fs_text_overrides;
|
|
|
|
|
795 |
|
796 |
if ( isset( $fs_text_overrides[ $slug ] ) ) {
|
797 |
if ( isset( $fs_text_overrides[ $slug ][ $key ] ) ) {
|
804 |
}
|
805 |
}
|
806 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
807 |
return $key;
|
808 |
}
|
809 |
|
1337 |
function fs_is_plugin_uninstall() {
|
1338 |
return (
|
1339 |
defined( 'WP_UNINSTALL_PLUGIN' ) ||
|
1340 |
+
( 0 < did_action( 'pre_uninstall_plugin' ) )
|
1341 |
);
|
1342 |
}
|
1343 |
}
|
freemius/includes/fs-essential-functions.php
CHANGED
@@ -149,111 +149,21 @@
|
|
149 |
|
150 |
#endregion Core Redirect (copied from BuddyPress) -----------------------------------------
|
151 |
|
152 |
-
if ( ! function_exists( '__fs' ) ) {
|
153 |
-
global $fs_text_overrides;
|
154 |
-
|
155 |
-
if ( ! isset( $fs_text_overrides ) ) {
|
156 |
-
$fs_text_overrides = array();
|
157 |
-
}
|
158 |
-
|
159 |
-
/**
|
160 |
-
* Retrieve a translated text by key.
|
161 |
-
*
|
162 |
-
* @deprecated Use `fs_text()` instead since methods starting with `__` trigger warnings in Php 7.
|
163 |
-
* @todo Remove this method in the future.
|
164 |
-
*
|
165 |
-
* @author Vova Feldman (@svovaf)
|
166 |
-
* @since 1.1.4
|
167 |
-
*
|
168 |
-
* @param string $key
|
169 |
-
* @param string $slug
|
170 |
-
*
|
171 |
-
* @return string
|
172 |
-
*
|
173 |
-
* @global $fs_text, $fs_text_overrides
|
174 |
-
*/
|
175 |
-
function __fs( $key, $slug = 'freemius' ) {
|
176 |
-
_deprecated_function( __FUNCTION__, '2.0.0', 'fs_text()' );
|
177 |
-
|
178 |
-
global $fs_text,
|
179 |
-
$fs_module_info_text,
|
180 |
-
$fs_text_overrides;
|
181 |
-
|
182 |
-
if ( isset( $fs_text_overrides[ $slug ] ) ) {
|
183 |
-
if ( isset( $fs_text_overrides[ $slug ][ $key ] ) ) {
|
184 |
-
return $fs_text_overrides[ $slug ][ $key ];
|
185 |
-
}
|
186 |
-
|
187 |
-
$lower_key = strtolower( $key );
|
188 |
-
if ( isset( $fs_text_overrides[ $slug ][ $lower_key ] ) ) {
|
189 |
-
return $fs_text_overrides[ $slug ][ $lower_key ];
|
190 |
-
}
|
191 |
-
}
|
192 |
-
|
193 |
-
if ( ! isset( $fs_text ) ) {
|
194 |
-
$dir = defined( 'WP_FS__DIR_INCLUDES' ) ?
|
195 |
-
WP_FS__DIR_INCLUDES :
|
196 |
-
dirname( __FILE__ );
|
197 |
-
|
198 |
-
require_once $dir . '/i18n.php';
|
199 |
-
}
|
200 |
-
|
201 |
-
if ( isset( $fs_text[ $key ] ) ) {
|
202 |
-
return $fs_text[ $key ];
|
203 |
-
}
|
204 |
-
|
205 |
-
if ( isset( $fs_module_info_text[ $key ] ) ) {
|
206 |
-
return $fs_module_info_text[ $key ];
|
207 |
-
}
|
208 |
-
|
209 |
-
return $key;
|
210 |
-
}
|
211 |
-
|
212 |
-
/**
|
213 |
-
* Output a translated text by key.
|
214 |
-
*
|
215 |
-
* @deprecated Use `fs_echo()` instead for consistency with `fs_text()`.
|
216 |
-
*
|
217 |
-
* @todo Remove this method in the future.
|
218 |
-
*
|
219 |
-
* @author Vova Feldman (@svovaf)
|
220 |
-
* @since 1.1.4
|
221 |
-
*
|
222 |
-
* @param string $key
|
223 |
-
* @param string $slug
|
224 |
-
*/
|
225 |
-
function _efs( $key, $slug = 'freemius' ) {
|
226 |
-
fs_echo( $key, $slug );
|
227 |
-
}
|
228 |
-
}
|
229 |
-
|
230 |
if ( ! function_exists( 'fs_get_ip' ) ) {
|
231 |
/**
|
232 |
-
* Get
|
233 |
-
|
|
|
|
|
234 |
* @author Vova Feldman (@svovaf)
|
235 |
* @since 1.1.2
|
236 |
*
|
237 |
* @return string|null
|
238 |
*/
|
239 |
function fs_get_ip() {
|
240 |
-
$
|
241 |
-
|
242 |
-
|
243 |
-
'HTTP_X_FORWARDED_FOR',
|
244 |
-
'HTTP_X_FORWARDED',
|
245 |
-
'HTTP_FORWARDED_FOR',
|
246 |
-
'HTTP_FORWARDED',
|
247 |
-
'REMOTE_ADDR',
|
248 |
-
);
|
249 |
-
|
250 |
-
foreach ( $fields as $ip_field ) {
|
251 |
-
if ( ! empty( $_SERVER[ $ip_field ] ) ) {
|
252 |
-
return $_SERVER[ $ip_field ];
|
253 |
-
}
|
254 |
-
}
|
255 |
-
|
256 |
-
return null;
|
257 |
}
|
258 |
}
|
259 |
|
149 |
|
150 |
#endregion Core Redirect (copied from BuddyPress) -----------------------------------------
|
151 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
if ( ! function_exists( 'fs_get_ip' ) ) {
|
153 |
/**
|
154 |
+
* Get server IP.
|
155 |
+
*
|
156 |
+
* @since 2.5.1 This method returns the server IP.
|
157 |
+
*
|
158 |
* @author Vova Feldman (@svovaf)
|
159 |
* @since 1.1.2
|
160 |
*
|
161 |
* @return string|null
|
162 |
*/
|
163 |
function fs_get_ip() {
|
164 |
+
return empty( $_SERVER[ 'SERVER_ADDR' ] ) ?
|
165 |
+
null :
|
166 |
+
$_SERVER[ 'SERVER_ADDR' ];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
}
|
168 |
}
|
169 |
|
freemius/includes/fs-plugin-info-dialog.php
CHANGED
@@ -311,6 +311,7 @@
|
|
311 |
$data->version = $latest->version;
|
312 |
$data->last_updated = $latest->created;
|
313 |
$data->requires = $latest->requires_platform_version;
|
|
|
314 |
$data->tested = $latest->tested_up_to_version;
|
315 |
} else if ( ! empty( $current_addon_version ) ) {
|
316 |
$data->version = $current_addon_version;
|
@@ -1306,8 +1307,8 @@
|
|
1306 |
<?php endif ?>
|
1307 |
</div>
|
1308 |
</div>
|
1309 |
-
</div>
|
1310 |
<?php endforeach ?>
|
|
|
1311 |
<?php endif ?>
|
1312 |
<?php endif ?>
|
1313 |
<div>
|
@@ -1344,7 +1345,10 @@
|
|
1344 |
?>
|
1345 |
<li>
|
1346 |
<strong><?php fs_esc_html_echo_inline( 'Requires WordPress Version', 'requires-wordpress-version', $api->slug ) ?>
|
1347 |
-
:</strong> <?php echo esc_html( sprintf(
|
|
|
|
|
|
|
1348 |
</li>
|
1349 |
<?php
|
1350 |
}
|
@@ -1356,6 +1360,19 @@
|
|
1356 |
</li>
|
1357 |
<?php
|
1358 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1359 |
if ( ! empty( $api->downloaded ) ) {
|
1360 |
?>
|
1361 |
<li>
|
@@ -1485,9 +1502,43 @@
|
|
1485 |
</div>
|
1486 |
<div id="section-holder" class="wrap">
|
1487 |
<?php
|
1488 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1489 |
echo '<div class="notice notice-warning"><p>' . '<strong>' . fs_text_inline( 'Warning', 'warning', $api->slug ) . ':</strong> ' . fs_text_inline( 'This plugin has not been tested with your current version of WordPress.', 'not-tested-warning', $api->slug ) . '</p></div>';
|
1490 |
-
} else if ( !
|
1491 |
echo '<div class="notice notice-warning"><p>' . '<strong>' . fs_text_inline( 'Warning', 'warning', $api->slug ) . ':</strong> ' . fs_text_inline( 'This plugin has not been marked as compatible with your version of WordPress.', 'not-compatible-warning', $api->slug ) . '</p></div>';
|
1492 |
}
|
1493 |
|
311 |
$data->version = $latest->version;
|
312 |
$data->last_updated = $latest->created;
|
313 |
$data->requires = $latest->requires_platform_version;
|
314 |
+
$data->requires_php = $latest->requires_programming_language_version;
|
315 |
$data->tested = $latest->tested_up_to_version;
|
316 |
} else if ( ! empty( $current_addon_version ) ) {
|
317 |
$data->version = $current_addon_version;
|
1307 |
<?php endif ?>
|
1308 |
</div>
|
1309 |
</div>
|
|
|
1310 |
<?php endforeach ?>
|
1311 |
+
</div>
|
1312 |
<?php endif ?>
|
1313 |
<?php endif ?>
|
1314 |
<div>
|
1345 |
?>
|
1346 |
<li>
|
1347 |
<strong><?php fs_esc_html_echo_inline( 'Requires WordPress Version', 'requires-wordpress-version', $api->slug ) ?>
|
1348 |
+
:</strong> <?php echo esc_html( sprintf(
|
1349 |
+
/* translators: %s: Version number. */
|
1350 |
+
fs_text_inline( '%s or higher', 'x-or-higher', $api->slug ), $api->requires )
|
1351 |
+
) ?>
|
1352 |
</li>
|
1353 |
<?php
|
1354 |
}
|
1360 |
</li>
|
1361 |
<?php
|
1362 |
}
|
1363 |
+
if ( ! empty( $api->requires_php ) ) {
|
1364 |
+
?>
|
1365 |
+
<li>
|
1366 |
+
<strong><?php fs_esc_html_echo_inline( 'Requires PHP Version', 'requires-php-version', $api->slug ); ?>:</strong>
|
1367 |
+
<?php
|
1368 |
+
echo esc_html( sprintf(
|
1369 |
+
/* translators: %s: Version number. */
|
1370 |
+
fs_text_inline( '%s or higher', 'x-or-higher', $api->slug ), $api->requires_php )
|
1371 |
+
);
|
1372 |
+
?>
|
1373 |
+
</li>
|
1374 |
+
<?php
|
1375 |
+
}
|
1376 |
if ( ! empty( $api->downloaded ) ) {
|
1377 |
?>
|
1378 |
<li>
|
1502 |
</div>
|
1503 |
<div id="section-holder" class="wrap">
|
1504 |
<?php
|
1505 |
+
$requires_php = isset( $api->requires_php ) ? $api->requires_php : null;
|
1506 |
+
$requires_wp = isset( $api->requires ) ? $api->requires : null;
|
1507 |
+
|
1508 |
+
$compatible_php = empty( $requires_php ) || version_compare( PHP_VERSION, $requires_php, '>=' );
|
1509 |
+
|
1510 |
+
// Strip off any -alpha, -RC, -beta, -src suffixes.
|
1511 |
+
list( $wp_version ) = explode( '-', $GLOBALS['wp_version'] );
|
1512 |
+
|
1513 |
+
$compatible_wp = empty( $requires_wp ) || version_compare( $wp_version, $requires_wp, '>=' );
|
1514 |
+
$tested_wp = ( empty( $api->tested ) || version_compare( $wp_version, $api->tested, '<=' ) );
|
1515 |
+
|
1516 |
+
if ( ! $compatible_php ) {
|
1517 |
+
echo '<div class="notice notice-error notice-alt"><p><strong>' . fs_text_inline( 'Error', 'error', $api->slug ) . ':</strong> ' . fs_text_inline( 'This plugin requires a newer version of PHP.', 'newer-php-required-error', $api->slug );
|
1518 |
+
|
1519 |
+
if ( current_user_can( 'update_php' ) ) {
|
1520 |
+
$wp_get_update_php_url = function_exists( 'wp_get_update_php_url' ) ?
|
1521 |
+
wp_get_update_php_url() :
|
1522 |
+
'https://wordpress.org/support/update-php/';
|
1523 |
+
|
1524 |
+
printf(
|
1525 |
+
/* translators: %s: URL to Update PHP page. */
|
1526 |
+
' ' . fs_text_inline( '<a href="%s" target="_blank">Click here to learn more about updating PHP</a>.', 'php-update-learn-more-link', $api->slug ),
|
1527 |
+
esc_url( $wp_get_update_php_url )
|
1528 |
+
);
|
1529 |
+
|
1530 |
+
if ( function_exists( 'wp_update_php_annotation' ) ) {
|
1531 |
+
wp_update_php_annotation( '</p><p><em>', '</em>' );
|
1532 |
+
}
|
1533 |
+
} else {
|
1534 |
+
echo '</p>';
|
1535 |
+
}
|
1536 |
+
echo '</div>';
|
1537 |
+
}
|
1538 |
+
|
1539 |
+
if ( ! $tested_wp ) {
|
1540 |
echo '<div class="notice notice-warning"><p>' . '<strong>' . fs_text_inline( 'Warning', 'warning', $api->slug ) . ':</strong> ' . fs_text_inline( 'This plugin has not been tested with your current version of WordPress.', 'not-tested-warning', $api->slug ) . '</p></div>';
|
1541 |
+
} else if ( ! $compatible_wp ) {
|
1542 |
echo '<div class="notice notice-warning"><p>' . '<strong>' . fs_text_inline( 'Warning', 'warning', $api->slug ) . ':</strong> ' . fs_text_inline( 'This plugin has not been marked as compatible with your version of WordPress.', 'not-compatible-warning', $api->slug ) . '</p></div>';
|
1543 |
}
|
1544 |
|
freemius/includes/i18n.php
DELETED
@@ -1,605 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.1.4
|
7 |
-
*
|
8 |
-
* @deprecated This file is no longer in use. It's still in the project for backward compatibility.
|
9 |
-
*/
|
10 |
-
|
11 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
-
exit;
|
13 |
-
}
|
14 |
-
|
15 |
-
require_once dirname( __FILE__ ) . '/l10n.php';
|
16 |
-
|
17 |
-
/**
|
18 |
-
* All strings can now be overridden.
|
19 |
-
*
|
20 |
-
* For example, if we want to override:
|
21 |
-
* 'you-are-step-away' => 'You are just one step away - %s',
|
22 |
-
*
|
23 |
-
* We can use the filter:
|
24 |
-
* fs_override_i18n( array(
|
25 |
-
* 'opt-in-connect' => __( "Yes - I'm in!", '{your-text_domain}' ),
|
26 |
-
* 'skip' => __( 'Not today', '{your-text_domain}' ),
|
27 |
-
* ), '{plugin_slug}' );
|
28 |
-
*
|
29 |
-
* Or with the Freemius instance:
|
30 |
-
*
|
31 |
-
* my_freemius->override_i18n( array(
|
32 |
-
* 'opt-in-connect' => __( "Yes - I'm in!", '{your-text_domain}' ),
|
33 |
-
* 'skip' => __( 'Not today', '{your-text_domain}' ),
|
34 |
-
* ) );
|
35 |
-
*/
|
36 |
-
global $fs_text;
|
37 |
-
|
38 |
-
$fs_text = array(
|
39 |
-
'account' => _fs_text( 'Account' ),
|
40 |
-
'addon' => _fs_text( 'Add-On' ),
|
41 |
-
'contact-us' => _fs_text( 'Contact Us' ),
|
42 |
-
'contact-support' => _fs_text( 'Contact Support' ),
|
43 |
-
'change-ownership' => _fs_text( 'Change Ownership' ),
|
44 |
-
'support' => _fs_text( 'Support' ),
|
45 |
-
'support-forum' => _fs_text( 'Support Forum' ),
|
46 |
-
'add-ons' => _fs_text( 'Add-Ons' ),
|
47 |
-
'upgrade' => _fs_x( 'Upgrade', 'verb' ),
|
48 |
-
'awesome' => _fs_text( 'Awesome' ),
|
49 |
-
'pricing' => _fs_x( 'Pricing', 'noun' ),
|
50 |
-
'price' => _fs_x( 'Price', 'noun' ),
|
51 |
-
'unlimited-updates' => _fs_text( 'Unlimited Updates' ),
|
52 |
-
'downgrade' => _fs_x( 'Downgrade', 'verb' ),
|
53 |
-
'cancel-subscription' => _fs_x( 'Cancel Subscription', 'verb' ),
|
54 |
-
'cancel-trial' => _fs_text( 'Cancel Trial' ),
|
55 |
-
'free-trial' => _fs_text( 'Free Trial' ),
|
56 |
-
'start-free-x' => _fs_text( 'Start my free %s' ),
|
57 |
-
'no-commitment-x' => _fs_text( 'No commitment for %s - cancel anytime' ),
|
58 |
-
'after-x-pay-as-little-y' => _fs_text( 'After your free %s, pay as little as %s' ),
|
59 |
-
'details' => _fs_text( 'Details' ),
|
60 |
-
'account-details' => _fs_text( 'Account Details' ),
|
61 |
-
'delete' => _fs_x( 'Delete', 'verb' ),
|
62 |
-
'show' => _fs_x( 'Show', 'verb' ),
|
63 |
-
'hide' => _fs_x( 'Hide', 'verb' ),
|
64 |
-
'edit' => _fs_x( 'Edit', 'verb' ),
|
65 |
-
'update' => _fs_x( 'Update', 'verb' ),
|
66 |
-
'date' => _fs_text( 'Date' ),
|
67 |
-
'amount' => _fs_text( 'Amount' ),
|
68 |
-
'invoice' => _fs_text( 'Invoice' ),
|
69 |
-
'billing' => _fs_text( 'Billing' ),
|
70 |
-
'payments' => _fs_text( 'Payments' ),
|
71 |
-
'delete-account' => _fs_text( 'Delete Account' ),
|
72 |
-
'dismiss' => _fs_x( 'Dismiss', 'as close a window' ),
|
73 |
-
'plan' => _fs_x( 'Plan', 'as product pricing plan' ),
|
74 |
-
'change-plan' => _fs_text( 'Change Plan' ),
|
75 |
-
'download-x-version' => _fs_x( 'Download %s Version', 'as download professional version' ),
|
76 |
-
'download-x-version-now' => _fs_x( 'Download %s version now', 'as download professional version now' ),
|
77 |
-
'download-latest' => _fs_x( 'Download Latest', 'as download latest version' ),
|
78 |
-
'you-have-x-license' => _fs_x( 'You have a %s license.', 'E.g. you have a professional license.' ),
|
79 |
-
'new' => _fs_text( 'New' ),
|
80 |
-
'free' => _fs_text( 'Free' ),
|
81 |
-
'trial' => _fs_x( 'Trial', 'as trial plan' ),
|
82 |
-
'start-trial' => _fs_x( 'Start Trial', 'as starting a trial plan' ),
|
83 |
-
'purchase' => _fs_x( 'Purchase', 'verb' ),
|
84 |
-
'purchase-license' => _fs_text( 'Purchase License' ),
|
85 |
-
'buy' => _fs_x( 'Buy', 'verb' ),
|
86 |
-
'buy-license' => _fs_text( 'Buy License' ),
|
87 |
-
'license-single-site' => _fs_text( 'Single Site License' ),
|
88 |
-
'license-unlimited' => _fs_text( 'Unlimited Licenses' ),
|
89 |
-
'license-x-sites' => _fs_text( 'Up to %s Sites' ),
|
90 |
-
'renew-license-now' => _fs_text( '%sRenew your license now%s to access version %s security & feature updates, and support.' ),
|
91 |
-
'ask-for-upgrade-email-address' => _fs_text( "Enter the email address you've used for the upgrade below and we will resend you the license key." ),
|
92 |
-
'x-plan' => _fs_x( '%s Plan', 'e.g. Professional Plan' ),
|
93 |
-
'you-are-step-away' => _fs_text( 'You are just one step away - %s' ),
|
94 |
-
'activate-x-now' => _fs_x( 'Complete "%s" Activation Now',
|
95 |
-
'%s - plugin name. As complete "Jetpack" activation now' ),
|
96 |
-
'few-plugin-tweaks' => _fs_text( 'We made a few tweaks to the %s, %s' ),
|
97 |
-
'optin-x-now' => _fs_text( 'Opt in to make "%s" better!' ),
|
98 |
-
'error' => _fs_text( 'Error' ),
|
99 |
-
'failed-finding-main-path' => _fs_text( 'Freemius SDK couldn\'t find the plugin\'s main file. Please contact sdk@freemius.com with the current error.' ),
|
100 |
-
'learn-more' => _fs_text( 'Learn more' ),
|
101 |
-
'license_not_whitelabeled' => _fs_text( "Is this your client's site? %s if you wish to hide sensitive info like your billing address and invoices from the WP Admin."),
|
102 |
-
'license_whitelabeled' => _fs_text( 'Your %s license was flagged as white-labeled to hide sensitive information from the WP Admin (e.g. your billing address and invoices). If you ever wish to revert it back, you can easily do it through your %s. If this was a mistake you can also %s.'),
|
103 |
-
|
104 |
-
#region Affiliation
|
105 |
-
'affiliation' => _fs_text( 'Affiliation' ),
|
106 |
-
'affiliate' => _fs_text( 'Affiliate' ),
|
107 |
-
'affiliate-tracking' => _fs_text( '%s tracking cookie after the first visit to maximize earnings potential.' ),
|
108 |
-
'renewals-commission' => _fs_text( 'Get commission for automated subscription renewals.' ),
|
109 |
-
'affiliate-application-accepted' => _fs_text( "Your affiliate application for %s has been accepted! Log in to your affiliate area at: %s." ),
|
110 |
-
'affiliate-application-thank-you' => _fs_text( "Thank you for applying for our affiliate program, we'll review your details during the next 14 days and will get back to you with further information." ),
|
111 |
-
'affiliate-application-rejected' => _fs_text( "Thank you for applying for our affiliate program, unfortunately, we've decided at this point to reject your application. Please try again in 30 days." ),
|
112 |
-
'affiliate-account-suspended' => _fs_text( 'Your affiliation account was temporarily suspended.' ),
|
113 |
-
'affiliate-account-blocked' => _fs_text( 'Due to violation of our affiliation terms, we decided to temporarily block your affiliation account. If you have any questions, please contact support.' ),
|
114 |
-
'become-an-ambassador' => _fs_text( 'Like the %s? Become our ambassador and earn cash ;-)' ),
|
115 |
-
'become-an-ambassador-admin-notice' => _fs_text( 'Hey there, did you know that %s has an affiliate program? If you like the %s you can become our ambassador and earn some cash!' ),
|
116 |
-
'refer-new-customers' => _fs_text( 'Refer new customers to our %s and earn %s commission on each successful sale you refer!' ),
|
117 |
-
'program-summary' => _fs_text( 'Program Summary' ),
|
118 |
-
'commission-on-new-license-purchase' => _fs_text( '%s commission when a customer purchases a new license.' ),
|
119 |
-
'unlimited-commissions' => _fs_text( 'Unlimited commissions.' ),
|
120 |
-
'minimum-payout-amount' => _fs_text( '%s minimum payout amount.' ),
|
121 |
-
'payouts-unit-and-processing' => _fs_text( 'Payouts are in USD and processed monthly via PayPal.' ),
|
122 |
-
'commission-payment' => _fs_text( 'As we reserve 30 days for potential refunds, we only pay commissions that are older than 30 days.' ),
|
123 |
-
'become-an-affiliate' => _fs_text( 'Become an affiliate' ),
|
124 |
-
'apply-to-become-an-affiliate' => _fs_text( 'Apply to become an affiliate' ),
|
125 |
-
'full-name' => _fs_text( 'Full name' ),
|
126 |
-
'paypal-account-email-address' => _fs_text( 'PayPal account email address' ),
|
127 |
-
'promotion-methods' => _fs_text( 'Promotion methods' ),
|
128 |
-
'social-media' => _fs_text( 'Social media (Facebook, Twitter, etc.)' ),
|
129 |
-
'mobile-apps' => _fs_text( 'Mobile apps' ),
|
130 |
-
'statistics-information-field-label' => _fs_text( 'Website, email, and social media statistics (optional)' ),
|
131 |
-
'statistics-information-field-desc' => _fs_text( 'Please feel free to provide any relevant website or social media statistics, e.g. monthly unique site visits, number of email subscribers, followers, etc. (we will keep this information confidential).' ),
|
132 |
-
'promotion-method-desc-field-label' => _fs_text( 'How will you promote us?' ),
|
133 |
-
'promotion-method-desc-field-desc' => _fs_text( 'Please provide details on how you intend to promote %s (please be as specific as possible).' ),
|
134 |
-
'domain-field-label' => _fs_text( 'Where are you going to promote the %s?' ),
|
135 |
-
'domain-field-desc' => _fs_text( 'Enter the domain of your website or other websites from where you plan to promote the %s.' ),
|
136 |
-
'extra-domain-fields-label' => _fs_text( 'Extra Domains' ),
|
137 |
-
'extra-domain-fields-desc' => _fs_text( 'Extra domains where you will be marketing the product from.' ),
|
138 |
-
'add-another-domain' => _fs_text( 'Add another domain' ),
|
139 |
-
'remove' => _fs_x( 'Remove', 'Remove domain' ),
|
140 |
-
'email-address-is-required' => _fs_text( 'Email address is required.' ),
|
141 |
-
'domain-is-required' => _fs_text( 'Domain is required.' ),
|
142 |
-
'invalid-domain' => _fs_text( 'Invalid domain' ),
|
143 |
-
'paypal-email-address-is-required' => _fs_text( 'PayPal email address is required.' ),
|
144 |
-
'processing' => _fs_text( 'Processing...' ),
|
145 |
-
'non-expiring' => _fs_text( 'Non-expiring' ),
|
146 |
-
'account-is-pending-activation' => _fs_text( 'Account is pending activation.' ),
|
147 |
-
#endregion Affiliation
|
148 |
-
|
149 |
-
#region Account
|
150 |
-
'expiration' => _fs_x( 'Expiration', 'as expiration date' ),
|
151 |
-
'license' => _fs_x( 'License', 'as software license' ),
|
152 |
-
'not-verified' => _fs_text( 'not verified' ),
|
153 |
-
'verify-email' => _fs_text( 'Verify Email' ),
|
154 |
-
'expires-in' => _fs_x( 'Expires in %s', 'e.g. expires in 2 months' ),
|
155 |
-
'renews-in' => _fs_x( 'Auto renews in %s', 'e.g. auto renews in 2 months' ),
|
156 |
-
'no-expiration' => _fs_text( 'No expiration' ),
|
157 |
-
'expired' => _fs_text( 'Expired' ),
|
158 |
-
'cancelled' => _fs_text( 'Cancelled' ),
|
159 |
-
'in-x' => _fs_x( 'In %s', 'e.g. In 2 hours' ),
|
160 |
-
'x-ago' => _fs_x( '%s ago', 'e.g. 2 min ago' ),
|
161 |
-
/* translators: %s: Version number (e.g. 4.6 or higher) */
|
162 |
-
'x-or-higher' => _fs_text( '%s or higher' ),
|
163 |
-
'version' => _fs_x( 'Version', 'as plugin version' ),
|
164 |
-
'name' => _fs_text( 'Name' ),
|
165 |
-
'email' => _fs_text( 'Email' ),
|
166 |
-
'email-address' => _fs_text( 'Email address' ),
|
167 |
-
'verified' => _fs_text( 'Verified' ),
|
168 |
-
'module' => _fs_text( 'Module' ),
|
169 |
-
'module-type' => _fs_text( 'Module Type' ),
|
170 |
-
'plugin' => _fs_text( 'Plugin' ),
|
171 |
-
'plugins' => _fs_text( 'Plugins' ),
|
172 |
-
'theme' => _fs_text( 'Theme' ),
|
173 |
-
'themes' => _fs_text( 'Themes' ),
|
174 |
-
'path' => _fs_x( 'Path', 'as file/folder path' ),
|
175 |
-
'title' => _fs_text( 'Title' ),
|
176 |
-
'free-version' => _fs_text( 'Free version' ),
|
177 |
-
'premium-version' => _fs_text( 'Premium version' ),
|
178 |
-
'slug' => _fs_x( 'Slug', 'as WP plugin slug' ),
|
179 |
-
'id' => _fs_text( 'ID' ),
|
180 |
-
'users' => _fs_text( 'Users' ),
|
181 |
-
'module-installs' => _fs_text( '%s Installs' ),
|
182 |
-
'sites' => _fs_x( 'Sites', 'like websites' ),
|
183 |
-
'user-id' => _fs_text( 'User ID' ),
|
184 |
-
'site-id' => _fs_text( 'Site ID' ),
|
185 |
-
'public-key' => _fs_text( 'Public Key' ),
|
186 |
-
'secret-key' => _fs_text( 'Secret Key' ),
|
187 |
-
'no-secret' => _fs_x( 'No Secret', 'as secret encryption key missing' ),
|
188 |
-
'no-id' => _fs_text( 'No ID' ),
|
189 |
-
'sync-license' => _fs_x( 'Sync License', 'as synchronize license' ),
|
190 |
-
'sync' => _fs_x( 'Sync', 'as synchronize' ),
|
191 |
-
'activate-license' => _fs_text( 'Activate License' ),
|
192 |
-
'activate-free-version' => _fs_text( 'Activate Free Version' ),
|
193 |
-
'activate-license-message' => _fs_text( 'Please enter the license key that you received in the email right after the purchase:' ),
|
194 |
-
'activating-license' => _fs_text( 'Activating license...' ),
|
195 |
-
'change-license' => _fs_text( 'Change License' ),
|
196 |
-
'update-license' => _fs_text( 'Update License' ),
|
197 |
-
'deactivate-license' => _fs_text( 'Deactivate License' ),
|
198 |
-
'activate' => _fs_text( 'Activate' ),
|
199 |
-
'deactivate' => _fs_text( 'Deactivate' ),
|
200 |
-
'skip-deactivate' => _fs_text( 'Skip & Deactivate' ),
|
201 |
-
'skip-and-x' => _fs_text( 'Skip & %s' ),
|
202 |
-
'no-deactivate' => _fs_text( 'No - just deactivate' ),
|
203 |
-
'yes-do-your-thing' => _fs_text( 'Yes - do your thing' ),
|
204 |
-
'active' => _fs_x( 'Active', 'active mode' ),
|
205 |
-
'is-active' => _fs_x( 'Is Active', 'is active mode?' ),
|
206 |
-
'install-now' => _fs_text( 'Install Now' ),
|
207 |
-
'install-update-now' => _fs_text( 'Install Update Now' ),
|
208 |
-
'more-information-about-x' => _fs_text( 'More information about %s' ),
|
209 |
-
'localhost' => _fs_text( 'Localhost' ),
|
210 |
-
'activate-x-plan' => _fs_x( 'Activate %s Plan', 'as activate Professional plan' ),
|
211 |
-
'x-left' => _fs_x( '%s left', 'as 5 licenses left' ),
|
212 |
-
'last-license' => _fs_text( 'Last license' ),
|
213 |
-
'what-is-your-x' => _fs_text( 'What is your %s?' ),
|
214 |
-
'activate-this-addon' => _fs_text( 'Activate this add-on' ),
|
215 |
-
'deactivate-license-confirm' => _fs_text( 'Deactivating your license will block all premium features, but will enable you to activate the license on another site. Are you sure you want to proceed?' ),
|
216 |
-
'delete-account-x-confirm' => _fs_text( 'Deleting the account will automatically deactivate your %s plan license so you can use it on other sites. If you want to terminate the recurring payments as well, click the "Cancel" button, and first "Downgrade" your account. Are you sure you would like to continue with the deletion?' ),
|
217 |
-
'delete-account-confirm' => _fs_text( 'Deletion is not temporary. Only delete if you no longer want to use this %s anymore. Are you sure you would like to continue with the deletion?' ),
|
218 |
-
'downgrade-x-confirm' => _fs_text( 'Downgrading your plan will immediately stop all future recurring payments and your %s plan license will expire in %s.' ),
|
219 |
-
'cancel-trial-confirm' => _fs_text( 'Cancelling the trial will immediately block access to all premium features. Are you sure?' ),
|
220 |
-
'after-downgrade-non-blocking' => _fs_text( 'You can still enjoy all %s features but you will not have access to %s security & feature updates, nor support.' ),
|
221 |
-
'after-downgrade-blocking' => _fs_text( 'Once your license expires you can still use the Free version but you will NOT have access to the %s features.' ),
|
222 |
-
'proceed-confirmation' => _fs_text( 'Are you sure you want to proceed?' ),
|
223 |
-
#endregion Account
|
224 |
-
|
225 |
-
'add-ons-for-x' => _fs_text( 'Add Ons for %s' ),
|
226 |
-
'add-ons-missing' => _fs_text( 'We could\'nt load the add-ons list. It\'s probably an issue on our side, please try to come back in few minutes.' ),
|
227 |
-
#region Plugin Deactivation
|
228 |
-
'anonymous-feedback' => _fs_text( 'Anonymous feedback' ),
|
229 |
-
'quick-feedback' => _fs_text( 'Quick feedback' ),
|
230 |
-
'deactivation-share-reason' => _fs_text( 'If you have a moment, please let us know why you are %s' ),
|
231 |
-
'deactivating' => _fs_text( 'deactivating' ),
|
232 |
-
'deactivation' => _fs_text( 'Deactivation' ),
|
233 |
-
'theme-switch' => _fs_text( 'Theme Switch' ),
|
234 |
-
'switching' => _fs_text( 'switching' ),
|
235 |
-
'switch' => _fs_text( 'Switch' ),
|
236 |
-
'activate-x' => _fs_text( 'Activate %s' ),
|
237 |
-
'deactivation-modal-button-confirm' => _fs_text( 'Yes - %s' ),
|
238 |
-
'deactivation-modal-button-submit' => _fs_text( 'Submit & %s' ),
|
239 |
-
'cancel' => _fs_text( 'Cancel' ),
|
240 |
-
'reason-no-longer-needed' => _fs_text( 'I no longer need the %s' ),
|
241 |
-
'reason-found-a-better-plugin' => _fs_text( 'I found a better %s' ),
|
242 |
-
'reason-needed-for-a-short-period' => _fs_text( 'I only needed the %s for a short period' ),
|
243 |
-
'reason-broke-my-site' => _fs_text( 'The %s broke my site' ),
|
244 |
-
'reason-suddenly-stopped-working' => _fs_text( 'The %s suddenly stopped working' ),
|
245 |
-
'reason-cant-pay-anymore' => _fs_text( "I can't pay for it anymore" ),
|
246 |
-
'reason-temporary-deactivation' => _fs_text( "It's a temporary deactivation. I'm just debugging an issue." ),
|
247 |
-
'reason-temporary-x' => _fs_text( "It's a temporary %s. I'm just debugging an issue." ),
|
248 |
-
'reason-other' => _fs_x( 'Other',
|
249 |
-
'the text of the "other" reason for deactivating the module that is shown in the modal box.' ),
|
250 |
-
'ask-for-reason-message' => _fs_text( 'Kindly tell us the reason so we can improve.' ),
|
251 |
-
'placeholder-plugin-name' => _fs_text( "What's the %s's name?" ),
|
252 |
-
'placeholder-comfortable-price' => _fs_text( 'What price would you feel comfortable paying?' ),
|
253 |
-
'reason-couldnt-make-it-work' => _fs_text( "I couldn't understand how to make it work" ),
|
254 |
-
'reason-great-but-need-specific-feature' => _fs_text( "The %s is great, but I need specific feature that you don't support" ),
|
255 |
-
'reason-not-working' => _fs_text( 'The %s is not working' ),
|
256 |
-
'reason-not-what-i-was-looking-for' => _fs_text( "It's not what I was looking for" ),
|
257 |
-
'reason-didnt-work-as-expected' => _fs_text( "The %s didn't work as expected" ),
|
258 |
-
'placeholder-feature' => _fs_text( 'What feature?' ),
|
259 |
-
'placeholder-share-what-didnt-work' => _fs_text( "Kindly share what didn't work so we can fix it for future users..." ),
|
260 |
-
'placeholder-what-youve-been-looking-for' => _fs_text( "What you've been looking for?" ),
|
261 |
-
'placeholder-what-did-you-expect' => _fs_text( "What did you expect?" ),
|
262 |
-
'reason-didnt-work' => _fs_text( "The %s didn't work" ),
|
263 |
-
'reason-dont-like-to-share-my-information' => _fs_text( "I don't like to share my information with you" ),
|
264 |
-
'dont-have-to-share-any-data' => _fs_text( "You might have missed it, but you don't have to share any data and can just %s the opt-in." ),
|
265 |
-
#endregion Plugin Deactivation
|
266 |
-
|
267 |
-
#region Connect
|
268 |
-
'hey-x' => _fs_x( 'Hey %s,', 'greeting' ),
|
269 |
-
'thanks-x' => _fs_x( 'Thanks %s!', 'a greeting. E.g. Thanks John!' ),
|
270 |
-
'connect-message' => _fs_text( 'Never miss an important update - opt in to our security and feature updates notifications, and non-sensitive diagnostic tracking with %4$s.' ),
|
271 |
-
'connect-message_on-update' => _fs_text( 'Please help us improve %1$s! If you opt in, some data about your usage of %1$s will be sent to %4$s. If you skip this, that\'s okay! %1$s will still work just fine.' ),
|
272 |
-
'pending-activation-message' => _fs_text( 'You should receive an activation email for %s to your mailbox at %s. Please make sure you click the activation button in that email to %s.' ),
|
273 |
-
'complete-the-install' => _fs_text( 'complete the install' ),
|
274 |
-
'start-the-trial' => _fs_text( 'start the trial' ),
|
275 |
-
'thanks-for-purchasing' => _fs_text( 'Thanks for purchasing %s! To get started, please enter your license key:' ),
|
276 |
-
'license-sync-disclaimer' => _fs_text( 'The %1$s will be periodically sending data to %2$s to check for security and feature updates, and verify the validity of your license.' ),
|
277 |
-
'what-permissions' => _fs_text( 'What permissions are being granted?' ),
|
278 |
-
'permissions-profile' => _fs_text( 'Your Profile Overview' ),
|
279 |
-
'permissions-profile_desc' => _fs_text( 'Name and email address' ),
|
280 |
-
'permissions-site' => _fs_text( 'Your Site Overview' ),
|
281 |
-
'permissions-site_desc' => _fs_text( 'Site URL, WP version, PHP info, plugins & themes' ),
|
282 |
-
'permissions-events' => _fs_text( 'Current %s Events' ),
|
283 |
-
'permissions-events_desc' => _fs_text( 'Activation, deactivation and uninstall' ),
|
284 |
-
'permissions-plugins_themes' => _fs_text( 'Plugins & Themes' ),
|
285 |
-
'permissions-plugins_themes_desc' => _fs_text( 'Titles, versions and state.' ),
|
286 |
-
'permissions-admin-notices' => _fs_text( 'Admin Notices' ),
|
287 |
-
'permissions-newsletter' => _fs_text( 'Newsletter' ),
|
288 |
-
'permissions-newsletter_desc' => _fs_text( 'Updates, announcements, marketing, no spam' ),
|
289 |
-
'privacy-policy' => _fs_text( 'Privacy Policy' ),
|
290 |
-
'tos' => _fs_text( 'Terms of Service' ),
|
291 |
-
'activating' => _fs_x( 'Activating', 'as activating plugin' ),
|
292 |
-
'sending-email' => _fs_x( 'Sending email', 'as in the process of sending an email' ),
|
293 |
-
'opt-in-connect' => _fs_x( 'Allow & Continue', 'button label' ),
|
294 |
-
'agree-activate-license' => _fs_x( 'Agree & Activate License', 'button label' ),
|
295 |
-
'skip' => _fs_x( 'Skip', 'verb' ),
|
296 |
-
'click-here-to-use-plugin-anonymously' => _fs_text( 'Click here to use the plugin anonymously' ),
|
297 |
-
'resend-activation-email' => _fs_text( 'Re-send activation email' ),
|
298 |
-
'license-key' => _fs_text( 'License key' ),
|
299 |
-
'send-license-key' => _fs_text( 'Send License Key' ),
|
300 |
-
'sending-license-key' => _fs_text( 'Sending license key' ),
|
301 |
-
'have-license-key' => _fs_text( 'Have a license key?' ),
|
302 |
-
'dont-have-license-key' => _fs_text( 'Don\'t have a license key?' ),
|
303 |
-
'cant-find-license-key' => _fs_text( "Can't find your license key?" ),
|
304 |
-
'email-not-found' => _fs_text( "We couldn't find your email address in the system, are you sure it's the right address?" ),
|
305 |
-
'no-active-licenses' => _fs_text( "We can't see any active licenses associated with that email address, are you sure it's the right address?" ),
|
306 |
-
'opt-in' => _fs_text( 'Opt In' ),
|
307 |
-
'opt-out' => _fs_text( 'Opt Out' ),
|
308 |
-
'opt-out-cancel' => _fs_text( 'On second thought - I want to continue helping' ),
|
309 |
-
'opting-out' => _fs_text( 'Opting out...' ),
|
310 |
-
'opting-in' => _fs_text( 'Opting in...' ),
|
311 |
-
'opt-out-message-appreciation' => _fs_text( 'We appreciate your help in making the %s better by letting us track some usage data.' ),
|
312 |
-
'opt-out-message-usage-tracking' => _fs_text( "Usage tracking is done in the name of making %s better. Making a better user experience, prioritizing new features, and more good things. We'd really appreciate if you'll reconsider letting us continue with the tracking." ),
|
313 |
-
'opt-out-message-clicking-opt-out' => _fs_text( 'By clicking "Opt Out", we will no longer be sending any data from %s to %s.' ),
|
314 |
-
'apply-on-all-sites-in-the-network' => _fs_text( 'Apply on all sites in the network.' ),
|
315 |
-
'delegate-to-site-admins' => _fs_text( 'Delegate to Site Admins' ),
|
316 |
-
'delegate-to-site-admins-and-continue' => _fs_text( 'Delegate to Site Admins & Continue' ),
|
317 |
-
'continue' => _fs_text( 'Continue' ),
|
318 |
-
'allow' => _fs_text( 'allow' ),
|
319 |
-
'delegate' => _fs_text( 'delegate' ),
|
320 |
-
#endregion Connect
|
321 |
-
|
322 |
-
#region Screenshots
|
323 |
-
'screenshots' => _fs_text( 'Screenshots' ),
|
324 |
-
'view-full-size-x' => _fs_text( 'Click to view full-size screenshot %d' ),
|
325 |
-
#endregion Screenshots
|
326 |
-
|
327 |
-
#region Debug
|
328 |
-
'freemius-debug' => _fs_text( 'Freemius Debug' ),
|
329 |
-
'on' => _fs_x( 'On', 'as turned on' ),
|
330 |
-
'off' => _fs_x( 'Off', 'as turned off' ),
|
331 |
-
'debugging' => _fs_x( 'Debugging', 'as code debugging' ),
|
332 |
-
'freemius-state' => _fs_text( 'Freemius State' ),
|
333 |
-
'connected' => _fs_x( 'Connected', 'as connection was successful' ),
|
334 |
-
'blocked' => _fs_x( 'Blocked', 'as connection blocked' ),
|
335 |
-
'api' => _fs_x( 'API', 'as application program interface' ),
|
336 |
-
'sdk' => _fs_x( 'SDK', 'as software development kit versions' ),
|
337 |
-
'sdk-versions' => _fs_x( 'SDK Versions', 'as software development kit versions' ),
|
338 |
-
'plugin-path' => _fs_x( 'Plugin Path', 'as plugin folder path' ),
|
339 |
-
'sdk-path' => _fs_x( 'SDK Path', 'as sdk path' ),
|
340 |
-
'addons-of-x' => _fs_text( 'Add Ons of Plugin %s' ),
|
341 |
-
'delete-all-confirm' => _fs_text( 'Are you sure you want to delete all Freemius data?' ),
|
342 |
-
'actions' => _fs_text( 'Actions' ),
|
343 |
-
'delete-all-accounts' => _fs_text( 'Delete All Accounts' ),
|
344 |
-
'start-fresh' => _fs_text( 'Start Fresh' ),
|
345 |
-
'clear-api-cache' => _fs_text( 'Clear API Cache' ),
|
346 |
-
'sync-data-from-server' => _fs_text( 'Sync Data From Server' ),
|
347 |
-
'scheduled-crons' => _fs_text( 'Scheduled Crons' ),
|
348 |
-
'cron-type' => _fs_text( 'Cron Type' ),
|
349 |
-
'plugins-themes-sync' => _fs_text( 'Plugins & Themes Sync' ),
|
350 |
-
'module-licenses' => _fs_text( '%s Licenses' ),
|
351 |
-
'debug-log' => _fs_text( 'Debug Log' ),
|
352 |
-
'all' => _fs_text( 'All' ),
|
353 |
-
'file' => _fs_text( 'File' ),
|
354 |
-
'function' => _fs_text( 'Function' ),
|
355 |
-
'process-id' => _fs_text( 'Process ID' ),
|
356 |
-
'logger' => _fs_text( 'Logger' ),
|
357 |
-
'message' => _fs_text( 'Message' ),
|
358 |
-
'download' => _fs_text( 'Download' ),
|
359 |
-
'filter' => _fs_text( 'Filter' ),
|
360 |
-
'type' => _fs_text( 'Type' ),
|
361 |
-
'all-types' => _fs_text( 'All Types' ),
|
362 |
-
'all-requests' => _fs_text( 'All Requests' ),
|
363 |
-
#endregion Debug
|
364 |
-
|
365 |
-
#region Expressions
|
366 |
-
'congrats' => _fs_x( 'Congrats', 'as congratulations' ),
|
367 |
-
'oops' => _fs_x( 'Oops', 'exclamation' ),
|
368 |
-
'yee-haw' => _fs_x( 'Yee-haw', 'interjection expressing joy or exuberance' ),
|
369 |
-
'woot' => _fs_x( 'W00t',
|
370 |
-
'(especially in electronic communication) used to express elation, enthusiasm, or triumph.' ),
|
371 |
-
'right-on' => _fs_x( 'Right on', 'a positive response' ),
|
372 |
-
'hmm' => _fs_x( 'Hmm',
|
373 |
-
'something somebody says when they are thinking about what you have just said. ' ),
|
374 |
-
'ok' => _fs_text( 'O.K' ),
|
375 |
-
'hey' => _fs_x( 'Hey', 'exclamation' ),
|
376 |
-
'heads-up' => _fs_x( 'Heads up',
|
377 |
-
'advance notice of something that will need attention.' ),
|
378 |
-
#endregion Expressions
|
379 |
-
|
380 |
-
#region Admin Notices
|
381 |
-
'you-have-latest' => _fs_text( 'Seems like you got the latest release.' ),
|
382 |
-
'you-are-good' => _fs_text( 'You are all good!' ),
|
383 |
-
'user-exist-message' => _fs_text( 'Sorry, we could not complete the email update. Another user with the same email is already registered.' ),
|
384 |
-
'user-exist-message_ownership' => _fs_text( 'If you would like to give up the ownership of the %s\'s account to %s click the Change Ownership button.' ),
|
385 |
-
'email-updated-message' => _fs_text( 'Your email was successfully updated. You should receive an email with confirmation instructions in few moments.' ),
|
386 |
-
'name-updated-message' => _fs_text( 'Your name was successfully updated.' ),
|
387 |
-
'x-updated' => _fs_text( 'You have successfully updated your %s.' ),
|
388 |
-
'name-update-failed-message' => _fs_text( 'Please provide your full name.' ),
|
389 |
-
'verification-email-sent-message' => _fs_text( 'Verification mail was just sent to %s. If you can\'t find it after 5 min, please check your spam box.' ),
|
390 |
-
'addons-info-external-message' => _fs_text( 'Just letting you know that the add-ons information of %s is being pulled from an external server.' ),
|
391 |
-
'no-cc-required' => _fs_text( 'No credit card required' ),
|
392 |
-
'premium-activated-message' => _fs_text( 'Premium %s version was successfully activated.' ),
|
393 |
-
'successful-version-upgrade-message' => _fs_text( 'The upgrade of %s was successfully completed.' ),
|
394 |
-
'activation-with-plan-x-message' => _fs_text( 'Your account was successfully activated with the %s plan.' ),
|
395 |
-
'download-latest-x-version-now' => _fs_text( 'Download the latest %s version now' ),
|
396 |
-
'follow-steps-to-complete-upgrade' => _fs_text( 'Please follow these steps to complete the upgrade' ),
|
397 |
-
'download-latest-x-version' => _fs_text( 'Download the latest %s version' ),
|
398 |
-
'download-latest-version' => _fs_text( 'Download the latest version' ),
|
399 |
-
'deactivate-free-version' => _fs_text( 'Deactivate the free version' ),
|
400 |
-
'upload-and-activate' => _fs_text( 'Upload and activate the downloaded version' ),
|
401 |
-
'howto-upload-activate' => _fs_text( 'How to upload and activate?' ),
|
402 |
-
'addon-successfully-purchased-message' => _fs_x( '%s Add-on was successfully purchased.',
|
403 |
-
'%s - product name, e.g. Facebook add-on was successfully...' ),
|
404 |
-
'addon-successfully-upgraded-message' => _fs_text( 'Your %s Add-on plan was successfully upgraded.' ),
|
405 |
-
'email-verified-message' => _fs_text( 'Your email has been successfully verified - you are AWESOME!' ),
|
406 |
-
'plan-upgraded-message' => _fs_text( 'Your plan was successfully upgraded.' ),
|
407 |
-
'plan-changed-to-x-message' => _fs_text( 'Your plan was successfully changed to %s.' ),
|
408 |
-
'license-expired-blocking-message' => _fs_text( 'Your license has expired. You can still continue using the free %s forever.' ),
|
409 |
-
'license-cancelled' => _fs_text( 'Your license has been cancelled. If you think it\'s a mistake, please contact support.' ),
|
410 |
-
'trial-started-message' => _fs_text( 'Your trial has been successfully started.' ),
|
411 |
-
'license-activated-message' => _fs_text( 'Your license was successfully activated.' ),
|
412 |
-
'no-active-license-message' => _fs_text( 'It looks like your site currently doesn\'t have an active license.' ),
|
413 |
-
'license-deactivation-message' => _fs_text( 'Your license was successfully deactivated, you are back to the %s plan.' ),
|
414 |
-
'license-deactivation-failed-message' => _fs_text( 'It looks like the license deactivation failed.' ),
|
415 |
-
'license-activation-failed-message' => _fs_text( 'It looks like the license could not be activated.' ),
|
416 |
-
'server-error-message' => _fs_text( 'Error received from the server:' ),
|
417 |
-
'trial-expired-message' => _fs_text( 'Your trial has expired. You can still continue using all our free features.' ),
|
418 |
-
'plan-x-downgraded-message' => _fs_text( 'Your plan was successfully downgraded. Your %s plan license will expire in %s.' ),
|
419 |
-
'plan-downgraded-failure-message' => _fs_text( 'Seems like we are having some temporary issue with your plan downgrade. Please try again in few minutes.' ),
|
420 |
-
'trial-cancel-no-trial-message' => _fs_text( 'It looks like you are not in trial mode anymore so there\'s nothing to cancel :)' ),
|
421 |
-
'trial-cancel-message' => _fs_text( 'Your %s free trial was successfully cancelled.' ),
|
422 |
-
'version-x-released' => _fs_x( 'Version %s was released.', '%s - numeric version number' ),
|
423 |
-
'please-download-x' => _fs_text( 'Please download %s.' ),
|
424 |
-
'latest-x-version' => _fs_x( 'the latest %s version here',
|
425 |
-
'%s - plan name, as the latest professional version here' ),
|
426 |
-
'trial-x-promotion-message' => _fs_text( 'How do you like %s so far? Test all our %s premium features with a %d-day free trial.' ),
|
427 |
-
'start-free-trial' => _fs_x( 'Start free trial', 'call to action' ),
|
428 |
-
'starting-trial' => _fs_text( 'Starting trial' ),
|
429 |
-
'please-wait' => _fs_text( 'Please wait' ),
|
430 |
-
'trial-cancel-failure-message' => _fs_text( 'Seems like we are having some temporary issue with your trial cancellation. Please try again in few minutes.' ),
|
431 |
-
'trial-utilized' => _fs_text( 'You already utilized a trial before.' ),
|
432 |
-
'in-trial-mode' => _fs_text( 'You are already running the %s in a trial mode.' ),
|
433 |
-
'trial-plan-x-not-exist' => _fs_text( 'Plan %s do not exist, therefore, can\'t start a trial.' ),
|
434 |
-
'plan-x-no-trial' => _fs_text( 'Plan %s does not support a trial period.' ),
|
435 |
-
'no-trials' => _fs_text( 'None of the %s\'s plans supports a trial period.' ),
|
436 |
-
'unexpected-api-error' => _fs_text( 'Unexpected API error. Please contact the %s\'s author with the following error.' ),
|
437 |
-
'no-commitment-for-x-days' => _fs_text( 'No commitment for %s days - cancel anytime!' ),
|
438 |
-
'license-expired-non-blocking-message' => _fs_text( 'Your license has expired. You can still continue using all the %s features, but you\'ll need to renew your license to continue getting updates and support.' ),
|
439 |
-
'could-not-activate-x' => _fs_text( 'Couldn\'t activate %s.' ),
|
440 |
-
'contact-us-with-error-message' => _fs_text( 'Please contact us with the following message:' ),
|
441 |
-
'plan-did-not-change-message' => _fs_text( 'It looks like you are still on the %s plan. If you did upgrade or change your plan, it\'s probably an issue on our side - sorry.' ),
|
442 |
-
'contact-us-here' => _fs_text( 'Please contact us here' ),
|
443 |
-
'plan-did-not-change-email-message' => _fs_text( 'I have upgraded my account but when I try to Sync the License, the plan remains %s.' ),
|
444 |
-
#endregion Admin Notices
|
445 |
-
#region Connectivity Issues
|
446 |
-
'connectivity-test-fails-message' => _fs_text( 'From unknown reason, the API connectivity test failed.' ),
|
447 |
-
'connectivity-test-maybe-temporary' => _fs_text( 'It\'s probably a temporary issue on our end. Just to be sure, with your permission, would it be o.k to run another connectivity test?' ),
|
448 |
-
'curl-missing-message' => _fs_text( 'We use PHP cURL library for the API calls, which is a very common library and usually installed and activated out of the box. Unfortunately, cURL is not activated (or disabled) on your server.' ),
|
449 |
-
'curl-disabled-methods' => _fs_text( 'Disabled method(s):' ),
|
450 |
-
'cloudflare-blocks-connection-message' => _fs_text( 'From unknown reason, CloudFlare, the firewall we use, blocks the connection.' ),
|
451 |
-
'x-requires-access-to-api' => _fs_x( '%s requires an access to our API.',
|
452 |
-
'as pluginX requires an access to our API' ),
|
453 |
-
'squid-blocks-connection-message' => _fs_text( 'It looks like your server is using Squid ACL (access control lists), which blocks the connection.' ),
|
454 |
-
'squid-no-clue-title' => _fs_text( 'I don\'t know what is Squid or ACL, help me!' ),
|
455 |
-
'squid-no-clue-desc' => _fs_text( 'We\'ll make sure to contact your hosting company and resolve the issue. You will get a follow-up email to %s once we have an update.' ),
|
456 |
-
'sysadmin-title' => _fs_text( 'I\'m a system administrator' ),
|
457 |
-
'squid-sysadmin-desc' => _fs_text( 'Great, please whitelist the following domains: %s. Once you are done, deactivate the %s and activate it again.' ),
|
458 |
-
'curl-missing-no-clue-title' => _fs_text( 'I don\'t know what is cURL or how to install it, help me!' ),
|
459 |
-
'curl-missing-no-clue-desc' => _fs_text( 'We\'ll make sure to contact your hosting company and resolve the issue. You will get a follow-up email to %s once we have an update.' ),
|
460 |
-
'curl-missing-sysadmin-desc' => _fs_text( 'Great, please install cURL and enable it in your php.ini file. In addition, search for the \'disable_functions\' directive in your php.ini file and remove any disabled methods starting with \'curl_\'. To make sure it was successfully activated, use \'phpinfo()\'. Once activated, deactivate the %s and reactivate it back again.' ),
|
461 |
-
'happy-to-resolve-issue-asap' => _fs_text( 'We are sure it\'s an issue on our side and more than happy to resolve it for you ASAP if you give us a chance.' ),
|
462 |
-
'contact-support-before-deactivation' => _fs_text( 'Sorry for the inconvenience and we are here to help if you give us a chance.' ),
|
463 |
-
'fix-issue-title' => _fs_text( 'Yes - I\'m giving you a chance to fix it' ),
|
464 |
-
'fix-issue-desc' => _fs_text( 'We will do our best to whitelist your server and resolve this issue ASAP. You will get a follow-up email to %s once we have an update.' ),
|
465 |
-
'install-previous-title' => _fs_text( 'Let\'s try your previous version' ),
|
466 |
-
'install-previous-desc' => _fs_text( 'Uninstall this version and install the previous one.' ),
|
467 |
-
'deactivate-plugin-title' => _fs_text( 'That\'s exhausting, please deactivate' ),
|
468 |
-
'deactivate-plugin-desc' => _fs_text( 'We feel your frustration and sincerely apologize for the inconvenience. Hope to see you again in the future.' ),
|
469 |
-
'fix-request-sent-message' => _fs_text( 'Thank for giving us the chance to fix it! A message was just sent to our technical staff. We will get back to you as soon as we have an update to %s. Appreciate your patience.' ),
|
470 |
-
'server-blocking-access' => _fs_x( 'Your server is blocking the access to Freemius\' API, which is crucial for %1$s synchronization. Please contact your host to whitelist %2$s',
|
471 |
-
'%1$s - plugin title, %2$s - API domain' ),
|
472 |
-
'wrong-authentication-param-message' => _fs_text( 'It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again.' ),
|
473 |
-
#endregion Connectivity Issues
|
474 |
-
#region Change Owner
|
475 |
-
'change-owner-request-sent-x' => _fs_text( 'Please check your mailbox, you should receive an email via %s to confirm the ownership change. From security reasons, you must confirm the change within the next 15 min. If you cannot find the email, please check your spam folder.' ),
|
476 |
-
'change-owner-request_owner-confirmed' => _fs_text( 'Thanks for confirming the ownership change. An email was just sent to %s for final approval.' ),
|
477 |
-
'change-owner-request_candidate-confirmed' => _fs_text( '%s is the new owner of the account.' ),
|
478 |
-
#endregion Change Owner
|
479 |
-
'addon-x-cannot-run-without-y' => _fs_x( '%s cannot run without %s.',
|
480 |
-
'addonX cannot run without pluginY' ),
|
481 |
-
'addon-x-cannot-run-without-parent' => _fs_x( '%s cannot run without the plugin.', 'addonX cannot run...' ),
|
482 |
-
'plugin-x-activation-message' => _fs_x( '%s activation was successfully completed.',
|
483 |
-
'pluginX activation was successfully...' ),
|
484 |
-
'features-and-pricing' => _fs_x( 'Features & Pricing', 'Plugin installer section title' ),
|
485 |
-
'free-addon-not-deployed' => _fs_text( 'Add-on must be deployed to WordPress.org or Freemius.' ),
|
486 |
-
'paid-addon-not-deployed' => _fs_text( 'Paid add-on must be deployed to Freemius.' ),
|
487 |
-
#--------------------------------------------------------------------------------
|
488 |
-
#region Add-On Licensing
|
489 |
-
#--------------------------------------------------------------------------------
|
490 |
-
'addon-no-license-message' => _fs_text( '%s is a premium only add-on. You have to purchase a license first before activating the plugin.' ),
|
491 |
-
'addon-trial-cancelled-message' => _fs_text( '%s free trial was successfully cancelled. Since the add-on is premium only it was automatically deactivated. If you like to use it in the future, you\'ll have to purchase a license.' ),
|
492 |
-
#endregion
|
493 |
-
#--------------------------------------------------------------------------------
|
494 |
-
#region Billing Cycles
|
495 |
-
#--------------------------------------------------------------------------------
|
496 |
-
'monthly' => _fs_x( 'Monthly', 'as every month' ),
|
497 |
-
'mo' => _fs_x( 'mo', 'as monthly period' ),
|
498 |
-
'annual' => _fs_x( 'Annual', 'as once a year' ),
|
499 |
-
'annually' => _fs_x( 'Annually', 'as once a year' ),
|
500 |
-
'once' => _fs_x( 'Once', 'as once a year' ),
|
501 |
-
'year' => _fs_x( 'year', 'as annual period' ),
|
502 |
-
'lifetime' => _fs_text( 'Lifetime' ),
|
503 |
-
'best' => _fs_x( 'Best', 'e.g. the best product' ),
|
504 |
-
'billed-x' => _fs_x( 'Billed %s', 'e.g. billed monthly' ),
|
505 |
-
'save-x' => _fs_x( 'Save %s', 'as a discount of $5 or 10%' ),
|
506 |
-
#endregion Billing Cycles
|
507 |
-
'view-details' => _fs_text( 'View details' ),
|
508 |
-
#--------------------------------------------------------------------------------
|
509 |
-
#region Trial
|
510 |
-
#--------------------------------------------------------------------------------
|
511 |
-
'approve-start-trial' => _fs_x( 'Approve & Start Trial', 'button label' ),
|
512 |
-
/* translators: %1$s: Number of trial days; %2$s: Plan name; */
|
513 |
-
'start-trial-prompt-header' => _fs_text( 'You are 1-click away from starting your %1$s-day free trial of the %2$s plan.' ),
|
514 |
-
/* translators: %s: Link to freemius.com */
|
515 |
-
'start-trial-prompt-message' => _fs_text( 'For compliance with the WordPress.org guidelines, before we start the trial we ask that you opt in with your user and non-sensitive site information, allowing the %s to periodically send data to %s to check for version updates and to validate your trial.' ),
|
516 |
-
|
517 |
-
#endregion
|
518 |
-
#--------------------------------------------------------------------------------
|
519 |
-
#region Billing Details
|
520 |
-
#--------------------------------------------------------------------------------
|
521 |
-
'business-name' => _fs_text( 'Business name' ),
|
522 |
-
'tax-vat-id' => _fs_text( 'Tax / VAT ID' ),
|
523 |
-
'address-line-n' => _fs_text( 'Address Line %d' ),
|
524 |
-
'country' => _fs_text( 'Country' ),
|
525 |
-
'select-country' => _fs_text( 'Select Country' ),
|
526 |
-
'city' => _fs_text( 'City' ),
|
527 |
-
'town' => _fs_text( 'Town' ),
|
528 |
-
'state' => _fs_text( 'State' ),
|
529 |
-
'province' => _fs_text( 'Province' ),
|
530 |
-
'zip-postal-code' => _fs_text( 'ZIP / Postal Code' ),
|
531 |
-
#endregion
|
532 |
-
#--------------------------------------------------------------------------------
|
533 |
-
#region Module Installation
|
534 |
-
#--------------------------------------------------------------------------------
|
535 |
-
'installing-plugin-x' => _fs_text( 'Installing plugin: %s' ),
|
536 |
-
'auto-installation' => _fs_text( 'Automatic Installation' ),
|
537 |
-
/* translators: %s: Number of seconds */
|
538 |
-
'x-sec' => _fs_text( '%s sec' ),
|
539 |
-
'installing-in-n' => _fs_text( 'An automated download and installation of %s (paid version) from %s will start in %s. If you would like to do it manually - click the cancellation button now.' ),
|
540 |
-
'installing-module-x' => _fs_text( 'The installation process has started and may take a few minutes to complete. Please wait until it is done - do not refresh this page.' ),
|
541 |
-
'cancel-installation' => _fs_text( 'Cancel Installation' ),
|
542 |
-
'module-package-rename-failure' => _fs_text( 'The remote plugin package does not contain a folder with the desired slug and renaming did not work.' ),
|
543 |
-
'auto-install-error-invalid-id' => _fs_text( 'Invalid module ID.' ),
|
544 |
-
'auto-install-error-not-opted-in' => _fs_text( 'Auto installation only works for opted-in users.' ),
|
545 |
-
'auto-install-error-premium-activated' => _fs_text( 'Premium version already active.' ),
|
546 |
-
'auto-install-error-premium-addon-activated' => _fs_text( 'Premium add-on version already installed.' ),
|
547 |
-
'auto-install-error-invalid-license' => _fs_text( 'You do not have a valid license to access the premium version.' ),
|
548 |
-
'auto-install-error-serviceware' => _fs_text( 'Plugin is a "Serviceware" which means it does not have a premium code version.' ),
|
549 |
-
#endregion
|
550 |
-
|
551 |
-
/* translators: %s: Page name */
|
552 |
-
'secure-x-page-header' => _fs_text( 'Secure HTTPS %s page, running from an external domain' ),
|
553 |
-
'pci-compliant' => _fs_text( 'PCI compliant' ),
|
554 |
-
'view-paid-features' => _fs_text( 'View paid features' ),
|
555 |
-
);
|
556 |
-
|
557 |
-
/**
|
558 |
-
* Localization of the strings in the plugin/theme info dialog box.
|
559 |
-
*
|
560 |
-
* $fs_module_info_text should ONLY include strings that are not located in $fs_text.
|
561 |
-
*
|
562 |
-
* @author Vova Feldman (@svovaf)
|
563 |
-
* @since 1.2.2
|
564 |
-
*/
|
565 |
-
global $fs_module_info_text;
|
566 |
-
|
567 |
-
$fs_module_info_text = array(
|
568 |
-
'description' => _fs_x( 'Description', 'Plugin installer section title' ),
|
569 |
-
'installation' => _fs_x( 'Installation', 'Plugin installer section title' ),
|
570 |
-
'faq' => _fs_x( 'FAQ', 'Plugin installer section title' ),
|
571 |
-
'changelog' => _fs_x( 'Changelog', 'Plugin installer section title' ),
|
572 |
-
'reviews' => _fs_x( 'Reviews', 'Plugin installer section title' ),
|
573 |
-
'other_notes' => _fs_x( 'Other Notes', 'Plugin installer section title' ),
|
574 |
-
/* translators: %s: 1 or One */
|
575 |
-
'x-star' => _fs_text( '%s star' ),
|
576 |
-
/* translators: %s: Number larger than 1 */
|
577 |
-
'x-stars' => _fs_text( '%s stars' ),
|
578 |
-
/* translators: %s: 1 or One */
|
579 |
-
'x-rating' => _fs_text( '%s rating' ),
|
580 |
-
/* translators: %s: Number larger than 1 */
|
581 |
-
'x-ratings' => _fs_text( '%s ratings' ),
|
582 |
-
/* translators: %s: 1 or One (Number of times downloaded) */
|
583 |
-
'x-time' => _fs_text( '%s time' ),
|
584 |
-
/* translators: %s: Number of times downloaded */
|
585 |
-
'x-times' => _fs_text( '%s times' ),
|
586 |
-
/* translators: %s: # of stars (e.g. 5 stars) */
|
587 |
-
'click-to-reviews' => _fs_text( 'Click to see reviews that provided a rating of %s' ),
|
588 |
-
'last-updated:' => _fs_text( 'Last Updated' ),
|
589 |
-
'requires-wordpress-version:' => _fs_text( 'Requires WordPress Version:' ),
|
590 |
-
'author:' => _fs_x( 'Author:', 'as the plugin author' ),
|
591 |
-
'compatible-up-to:' => _fs_text( 'Compatible up to:' ),
|
592 |
-
'downloaded:' => _fs_text( 'Downloaded:' ),
|
593 |
-
'wp-org-plugin-page' => _fs_text( 'WordPress.org Plugin Page' ),
|
594 |
-
'plugin-homepage' => _fs_text( 'Plugin Homepage' ),
|
595 |
-
'donate-to-plugin' => _fs_text( 'Donate to this plugin' ),
|
596 |
-
'average-rating' => _fs_text( 'Average Rating' ),
|
597 |
-
'based-on-x' => _fs_text( 'based on %s' ),
|
598 |
-
'warning:' => _fs_text( 'Warning:' ),
|
599 |
-
'contributors' => _fs_text( 'Contributors' ),
|
600 |
-
'plugin-install' => _fs_text( 'Plugin Install' ),
|
601 |
-
'not-tested-warning' => _fs_text( 'This plugin has not been tested with your current version of WordPress.' ),
|
602 |
-
'not-compatible-warning' => _fs_text( 'This plugin has not been marked as compatible with your version of WordPress.' ),
|
603 |
-
'newer-installed' => _fs_text( 'Newer Version (%s) Installed' ),
|
604 |
-
'latest-installed' => _fs_text( 'Latest Version Installed' ),
|
605 |
-
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
freemius/includes/managers/class-fs-admin-notice-manager.php
CHANGED
@@ -160,7 +160,10 @@
|
|
160 |
false,
|
161 |
isset( $msg['wp_user_id'] ) ? $msg['wp_user_id'] : null,
|
162 |
! empty( $msg['plugin'] ) ? $msg['plugin'] : null,
|
163 |
-
$is_network_and_blog_admins
|
|
|
|
|
|
|
164 |
);
|
165 |
}
|
166 |
}
|
@@ -224,9 +227,6 @@
|
|
224 |
return;
|
225 |
}
|
226 |
|
227 |
-
|
228 |
-
$show_admin_notices = ( ! $this->is_gutenberg_page() );
|
229 |
-
|
230 |
foreach ( $this->_notices as $id => $msg ) {
|
231 |
if ( isset( $msg['wp_user_id'] ) && is_numeric( $msg['wp_user_id'] ) ) {
|
232 |
if ( get_current_user_id() != $msg['wp_user_id'] ) {
|
@@ -269,7 +269,7 @@
|
|
269 |
$show_notice = call_user_func_array( 'fs_apply_filter', array(
|
270 |
$this->_module_unique_affix,
|
271 |
'show_admin_notice',
|
272 |
-
$show_admin_notices,
|
273 |
$msg
|
274 |
) );
|
275 |
|
@@ -323,6 +323,30 @@
|
|
323 |
return false;
|
324 |
}
|
325 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
326 |
/**
|
327 |
* Add admin message to admin messages queue, and hook to admin_notices / all_admin_notices if not yet hooked.
|
328 |
*
|
@@ -339,6 +363,8 @@
|
|
339 |
* @param string|null $plugin_title
|
340 |
* @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network
|
341 |
* and blog admin pages.
|
|
|
|
|
342 |
*
|
343 |
* @uses add_action()
|
344 |
*/
|
@@ -351,7 +377,9 @@
|
|
351 |
$store_if_sticky = true,
|
352 |
$wp_user_id = null,
|
353 |
$plugin_title = null,
|
354 |
-
$is_network_and_blog_admins = false
|
|
|
|
|
355 |
) {
|
356 |
$notices_type = $this->get_notices_type();
|
357 |
|
@@ -371,14 +399,16 @@
|
|
371 |
}
|
372 |
|
373 |
$message_object = array(
|
374 |
-
'message'
|
375 |
-
'title'
|
376 |
-
'type'
|
377 |
-
'sticky'
|
378 |
-
'id'
|
379 |
-
'manager_id'
|
380 |
-
'plugin'
|
381 |
-
'wp_user_id'
|
|
|
|
|
382 |
);
|
383 |
|
384 |
if ( $is_sticky && $store_if_sticky ) {
|
@@ -393,15 +423,16 @@
|
|
393 |
* @since 1.0.7
|
394 |
*
|
395 |
* @param string|string[] $ids
|
|
|
396 |
*/
|
397 |
-
function remove_sticky( $ids ) {
|
398 |
if ( ! is_array( $ids ) ) {
|
399 |
$ids = array( $ids );
|
400 |
}
|
401 |
|
402 |
foreach ( $ids as $id ) {
|
403 |
// Remove from sticky storage.
|
404 |
-
$this->_sticky_storage->remove( $id );
|
405 |
|
406 |
if ( isset( $this->_notices[ $id ] ) ) {
|
407 |
unset( $this->_notices[ $id ] );
|
@@ -437,14 +468,32 @@
|
|
437 |
* @param string|null $plugin_title
|
438 |
* @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network
|
439 |
* and blog admin pages.
|
|
|
|
|
440 |
*/
|
441 |
-
function add_sticky( $message, $id, $title = '', $type = 'success', $wp_user_id = null, $plugin_title = null, $is_network_and_blog_admins = false ) {
|
442 |
if ( ! empty( $this->_module_unique_affix ) ) {
|
443 |
$message = fs_apply_filter( $this->_module_unique_affix, "sticky_message_{$id}", $message );
|
444 |
$title = fs_apply_filter( $this->_module_unique_affix, "sticky_title_{$id}", $title );
|
445 |
}
|
446 |
|
447 |
-
$this->add( $message, $title, $type, true, $id, true, $wp_user_id, $plugin_title, $is_network_and_blog_admins );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
448 |
}
|
449 |
|
450 |
/**
|
@@ -452,9 +501,15 @@
|
|
452 |
*
|
453 |
* @author Vova Feldman (@svovaf)
|
454 |
* @since 1.0.8
|
|
|
|
|
455 |
*/
|
456 |
-
function clear_all_sticky() {
|
457 |
-
$
|
|
|
|
|
|
|
|
|
458 |
}
|
459 |
|
460 |
#--------------------------------------------------------------------------------
|
160 |
false,
|
161 |
isset( $msg['wp_user_id'] ) ? $msg['wp_user_id'] : null,
|
162 |
! empty( $msg['plugin'] ) ? $msg['plugin'] : null,
|
163 |
+
$is_network_and_blog_admins,
|
164 |
+
isset( $msg['dismissible'] ) ?
|
165 |
+
$msg['dismissible'] :
|
166 |
+
null
|
167 |
);
|
168 |
}
|
169 |
}
|
227 |
return;
|
228 |
}
|
229 |
|
|
|
|
|
|
|
230 |
foreach ( $this->_notices as $id => $msg ) {
|
231 |
if ( isset( $msg['wp_user_id'] ) && is_numeric( $msg['wp_user_id'] ) ) {
|
232 |
if ( get_current_user_id() != $msg['wp_user_id'] ) {
|
269 |
$show_notice = call_user_func_array( 'fs_apply_filter', array(
|
270 |
$this->_module_unique_affix,
|
271 |
'show_admin_notice',
|
272 |
+
$this->show_admin_notices(),
|
273 |
$msg
|
274 |
) );
|
275 |
|
323 |
return false;
|
324 |
}
|
325 |
|
326 |
+
/**
|
327 |
+
* Check if admin notices should be shown on page. E.g., we don't want to show notices in the Visual Editor.
|
328 |
+
*
|
329 |
+
* @author Xiaheng Chen (@xhchen)
|
330 |
+
* @since 2.4.2
|
331 |
+
*
|
332 |
+
* @return bool
|
333 |
+
*/
|
334 |
+
function show_admin_notices() {
|
335 |
+
global $pagenow;
|
336 |
+
|
337 |
+
if ( 'about.php' === $pagenow ) {
|
338 |
+
// Don't show admin notices on the About page.
|
339 |
+
return false;
|
340 |
+
}
|
341 |
+
|
342 |
+
if ( $this->is_gutenberg_page() ) {
|
343 |
+
// Don't show admin notices in Gutenberg (visual editor).
|
344 |
+
return false;
|
345 |
+
}
|
346 |
+
|
347 |
+
return true;
|
348 |
+
}
|
349 |
+
|
350 |
/**
|
351 |
* Add admin message to admin messages queue, and hook to admin_notices / all_admin_notices if not yet hooked.
|
352 |
*
|
363 |
* @param string|null $plugin_title
|
364 |
* @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network
|
365 |
* and blog admin pages.
|
366 |
+
* @param bool|null $is_dismissible
|
367 |
+
* @param array $data
|
368 |
*
|
369 |
* @uses add_action()
|
370 |
*/
|
377 |
$store_if_sticky = true,
|
378 |
$wp_user_id = null,
|
379 |
$plugin_title = null,
|
380 |
+
$is_network_and_blog_admins = false,
|
381 |
+
$is_dismissible = null,
|
382 |
+
$data = array()
|
383 |
) {
|
384 |
$notices_type = $this->get_notices_type();
|
385 |
|
399 |
}
|
400 |
|
401 |
$message_object = array(
|
402 |
+
'message' => $message,
|
403 |
+
'title' => $title,
|
404 |
+
'type' => $type,
|
405 |
+
'sticky' => $is_sticky,
|
406 |
+
'id' => $id,
|
407 |
+
'manager_id' => $this->_id,
|
408 |
+
'plugin' => ( ! is_null( $plugin_title ) ? $plugin_title : $this->_title ),
|
409 |
+
'wp_user_id' => $wp_user_id,
|
410 |
+
'dismissible' => $is_dismissible,
|
411 |
+
'data' => $data
|
412 |
);
|
413 |
|
414 |
if ( $is_sticky && $store_if_sticky ) {
|
423 |
* @since 1.0.7
|
424 |
*
|
425 |
* @param string|string[] $ids
|
426 |
+
* @param bool $store
|
427 |
*/
|
428 |
+
function remove_sticky( $ids, $store = true ) {
|
429 |
if ( ! is_array( $ids ) ) {
|
430 |
$ids = array( $ids );
|
431 |
}
|
432 |
|
433 |
foreach ( $ids as $id ) {
|
434 |
// Remove from sticky storage.
|
435 |
+
$this->_sticky_storage->remove( $id, $store );
|
436 |
|
437 |
if ( isset( $this->_notices[ $id ] ) ) {
|
438 |
unset( $this->_notices[ $id ] );
|
468 |
* @param string|null $plugin_title
|
469 |
* @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network
|
470 |
* and blog admin pages.
|
471 |
+
* @param bool $is_dimissible
|
472 |
+
* @param array $data
|
473 |
*/
|
474 |
+
function add_sticky( $message, $id, $title = '', $type = 'success', $wp_user_id = null, $plugin_title = null, $is_network_and_blog_admins = false, $is_dimissible = true, $data = array() ) {
|
475 |
if ( ! empty( $this->_module_unique_affix ) ) {
|
476 |
$message = fs_apply_filter( $this->_module_unique_affix, "sticky_message_{$id}", $message );
|
477 |
$title = fs_apply_filter( $this->_module_unique_affix, "sticky_title_{$id}", $title );
|
478 |
}
|
479 |
|
480 |
+
$this->add( $message, $title, $type, true, $id, true, $wp_user_id, $plugin_title, $is_network_and_blog_admins, $is_dimissible, $data );
|
481 |
+
}
|
482 |
+
|
483 |
+
/**
|
484 |
+
* Retrieves the data of an sticky notice.
|
485 |
+
*
|
486 |
+
* @author Leo Fajardo (@leorw)
|
487 |
+
* @since 2.4.3
|
488 |
+
*
|
489 |
+
* @param string $id Message ID.
|
490 |
+
*
|
491 |
+
* @return array|null
|
492 |
+
*/
|
493 |
+
function get_sticky( $id ) {
|
494 |
+
return isset( $this->_sticky_storage->{$id} ) ?
|
495 |
+
$this->_sticky_storage->{$id} :
|
496 |
+
null;
|
497 |
}
|
498 |
|
499 |
/**
|
501 |
*
|
502 |
* @author Vova Feldman (@svovaf)
|
503 |
* @since 1.0.8
|
504 |
+
*
|
505 |
+
* @param bool $is_temporary @since 2.5.1
|
506 |
*/
|
507 |
+
function clear_all_sticky( $is_temporary = false ) {
|
508 |
+
if ( $is_temporary ) {
|
509 |
+
$this->_notices = array();
|
510 |
+
} else {
|
511 |
+
$this->_sticky_storage->clear_all();
|
512 |
+
}
|
513 |
}
|
514 |
|
515 |
#--------------------------------------------------------------------------------
|
freemius/includes/managers/class-fs-clone-manager.php
ADDED
@@ -0,0 +1,1660 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @author Leo Fajardo (@leorw)
|
7 |
+
* @since 2.5.0
|
8 |
+
*/
|
9 |
+
|
10 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
11 |
+
exit;
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Manages the detection of clones and provides the logged-in WordPress user with options for manually resolving them.
|
16 |
+
*
|
17 |
+
* @since 2.5.0
|
18 |
+
*
|
19 |
+
* @property int $clone_identification_timestamp
|
20 |
+
* @property int $temporary_duplicate_mode_selection_timestamp
|
21 |
+
* @property int $temporary_duplicate_notice_shown_timestamp
|
22 |
+
* @property string $request_handler_id
|
23 |
+
* @property int $request_handler_timestamp
|
24 |
+
* @property int $request_handler_retries_count
|
25 |
+
* @property bool $hide_manual_resolution
|
26 |
+
* @property array $new_blog_install_map
|
27 |
+
*/
|
28 |
+
class FS_Clone_Manager {
|
29 |
+
/**
|
30 |
+
* @var FS_Option_Manager
|
31 |
+
*/
|
32 |
+
private $_storage;
|
33 |
+
/**
|
34 |
+
* @var FS_Option_Manager
|
35 |
+
*/
|
36 |
+
private $_network_storage;
|
37 |
+
/**
|
38 |
+
* @var FS_Admin_Notices
|
39 |
+
*/
|
40 |
+
private $_notices;
|
41 |
+
/**
|
42 |
+
* @var FS_Logger
|
43 |
+
*/
|
44 |
+
protected $_logger;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @var int 3 minutes
|
48 |
+
*/
|
49 |
+
const CLONE_RESOLUTION_MAX_EXECUTION_TIME = 180;
|
50 |
+
/**
|
51 |
+
* @var int
|
52 |
+
*/
|
53 |
+
const CLONE_RESOLUTION_MAX_RETRIES = 3;
|
54 |
+
/**
|
55 |
+
* @var int
|
56 |
+
*/
|
57 |
+
const TEMPORARY_DUPLICATE_PERIOD = WP_FS__TIME_WEEK_IN_SEC * 2;
|
58 |
+
/**
|
59 |
+
* @var string
|
60 |
+
*/
|
61 |
+
const OPTION_NAME = 'clone_resolution';
|
62 |
+
/**
|
63 |
+
* @var string
|
64 |
+
*/
|
65 |
+
const OPTION_MANAGER_NAME = 'clone_management';
|
66 |
+
/**
|
67 |
+
* @var string
|
68 |
+
*/
|
69 |
+
const OPTION_TEMPORARY_DUPLICATE = 'temporary_duplicate';
|
70 |
+
/**
|
71 |
+
* @var string
|
72 |
+
*/
|
73 |
+
const OPTION_LONG_TERM_DUPLICATE = 'long_term_duplicate';
|
74 |
+
/**
|
75 |
+
* @var string
|
76 |
+
*/
|
77 |
+
const OPTION_NEW_HOME = 'new_home';
|
78 |
+
|
79 |
+
#--------------------------------------------------------------------------------
|
80 |
+
#region Singleton
|
81 |
+
#--------------------------------------------------------------------------------
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @var FS_Clone_Manager
|
85 |
+
*/
|
86 |
+
private static $_instance;
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @return FS_Clone_Manager
|
90 |
+
*/
|
91 |
+
static function instance() {
|
92 |
+
if ( ! isset( self::$_instance ) ) {
|
93 |
+
self::$_instance = new self();
|
94 |
+
}
|
95 |
+
|
96 |
+
return self::$_instance;
|
97 |
+
}
|
98 |
+
|
99 |
+
#endregion
|
100 |
+
|
101 |
+
private function __construct() {
|
102 |
+
$this->_storage = FS_Option_Manager::get_manager( WP_FS___OPTION_PREFIX . self::OPTION_MANAGER_NAME, true );
|
103 |
+
$this->_network_storage = FS_Option_Manager::get_manager( WP_FS___OPTION_PREFIX . self::OPTION_MANAGER_NAME, true, true );
|
104 |
+
|
105 |
+
$this->maybe_migrate_options();
|
106 |
+
|
107 |
+
$this->_notices = FS_Admin_Notices::instance( 'global_clone_resolution_notices', '', '', true );
|
108 |
+
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . '_clone_manager', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Migrate clone resolution options from 2.5.0 array-based structure, to a new flat structure.
|
113 |
+
*
|
114 |
+
* The reason this logic is not in a separate migration script is that we want to be 100% sure data is migrated before any execution of clone logic.
|
115 |
+
*
|
116 |
+
* @todo Delete this one in the future.
|
117 |
+
*/
|
118 |
+
private function maybe_migrate_options() {
|
119 |
+
$storages = array(
|
120 |
+
$this->_storage,
|
121 |
+
$this->_network_storage
|
122 |
+
);
|
123 |
+
|
124 |
+
foreach ( $storages as $storage ) {
|
125 |
+
$clone_data = $storage->get_option( self::OPTION_NAME );
|
126 |
+
if ( is_array( $clone_data ) && ! empty( $clone_data ) ) {
|
127 |
+
foreach ( $clone_data as $key => $val ) {
|
128 |
+
if ( ! is_null( $val ) ) {
|
129 |
+
$storage->set_option( $key, $val );
|
130 |
+
}
|
131 |
+
}
|
132 |
+
|
133 |
+
$storage->unset_option( self::OPTION_NAME, true );
|
134 |
+
}
|
135 |
+
}
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* @author Leo Fajardo (@leorw)
|
140 |
+
* @since 2.5.0
|
141 |
+
*/
|
142 |
+
function _init() {
|
143 |
+
if ( is_admin() ) {
|
144 |
+
if ( Freemius::is_admin_post() ) {
|
145 |
+
add_action( 'admin_post_fs_clone_resolution', array( $this, '_handle_clone_resolution' ) );
|
146 |
+
}
|
147 |
+
|
148 |
+
if ( Freemius::is_ajax() ) {
|
149 |
+
Freemius::add_ajax_action_static( 'handle_clone_resolution', array( $this, '_clone_resolution_action_ajax_handler' ) );
|
150 |
+
} else {
|
151 |
+
if (
|
152 |
+
empty( $this->get_clone_identification_timestamp() ) &&
|
153 |
+
(
|
154 |
+
! fs_is_network_admin() ||
|
155 |
+
! ( $this->is_clone_resolution_options_notice_shown() || $this->is_temporary_duplicate_notice_shown() )
|
156 |
+
)
|
157 |
+
) {
|
158 |
+
$this->hide_clone_admin_notices();
|
159 |
+
} else if ( ! Freemius::is_cron() && ! Freemius::is_admin_post() ) {
|
160 |
+
$this->try_resolve_clone_automatically();
|
161 |
+
$this->maybe_show_clone_admin_notice();
|
162 |
+
|
163 |
+
add_action( 'admin_footer', array( $this, '_add_clone_resolution_javascript' ) );
|
164 |
+
}
|
165 |
+
}
|
166 |
+
}
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Retrieves the timestamp that was stored when a clone was identified.
|
171 |
+
*
|
172 |
+
* @return int|null
|
173 |
+
*/
|
174 |
+
function get_clone_identification_timestamp() {
|
175 |
+
return $this->get_option( 'clone_identification_timestamp', true );
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* @author Leo Fajardo (@leorw)
|
180 |
+
* @since 2.5.1
|
181 |
+
*
|
182 |
+
* @param string $sdk_last_version
|
183 |
+
*/
|
184 |
+
function maybe_update_clone_resolution_support_flag( $sdk_last_version ) {
|
185 |
+
if ( null !== $this->hide_manual_resolution ) {
|
186 |
+
return;
|
187 |
+
}
|
188 |
+
|
189 |
+
$this->hide_manual_resolution = (
|
190 |
+
! empty( $sdk_last_version ) &&
|
191 |
+
version_compare( $sdk_last_version, '2.5.0', '<' )
|
192 |
+
);
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Stores the time when a clone was identified.
|
197 |
+
*/
|
198 |
+
function store_clone_identification_timestamp() {
|
199 |
+
$this->clone_identification_timestamp = time();
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Retrieves the timestamp for the temporary duplicate mode's expiration.
|
204 |
+
*
|
205 |
+
* @return int
|
206 |
+
*/
|
207 |
+
function get_temporary_duplicate_expiration_timestamp() {
|
208 |
+
$temporary_duplicate_mode_start_timestamp = $this->was_temporary_duplicate_mode_selected() ?
|
209 |
+
$this->temporary_duplicate_mode_selection_timestamp :
|
210 |
+
$this->get_clone_identification_timestamp();
|
211 |
+
|
212 |
+
return ( $temporary_duplicate_mode_start_timestamp + self::TEMPORARY_DUPLICATE_PERIOD );
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Determines if the SDK should handle clones. The SDK handles clones only up to 3 times with 3 min interval.
|
217 |
+
*
|
218 |
+
* @return bool
|
219 |
+
*/
|
220 |
+
private function should_handle_clones() {
|
221 |
+
if ( ! isset( $this->request_handler_timestamp ) ) {
|
222 |
+
return true;
|
223 |
+
}
|
224 |
+
|
225 |
+
if ( $this->request_handler_retries_count >= self::CLONE_RESOLUTION_MAX_RETRIES ) {
|
226 |
+
return false;
|
227 |
+
}
|
228 |
+
|
229 |
+
// Give the logic that handles clones enough time to finish (it is given 3 minutes for now).
|
230 |
+
return ( time() > ( $this->request_handler_timestamp + self::CLONE_RESOLUTION_MAX_EXECUTION_TIME ) );
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* @author Leo Fajardo (@leorw)
|
235 |
+
* @since 2.5.1
|
236 |
+
*
|
237 |
+
* @return bool
|
238 |
+
*/
|
239 |
+
function should_hide_manual_resolution() {
|
240 |
+
return ( true === $this->hide_manual_resolution );
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Executes the clones handler logic if it should be executed, i.e., based on the return value of the should_handle_clones() method.
|
245 |
+
*
|
246 |
+
* @author Leo Fajardo (@leorw)
|
247 |
+
* @since 2.5.0
|
248 |
+
*/
|
249 |
+
function maybe_run_clone_resolution() {
|
250 |
+
if ( ! $this->should_handle_clones() ) {
|
251 |
+
return;
|
252 |
+
}
|
253 |
+
|
254 |
+
$this->request_handler_retries_count = isset( $this->request_handler_retries_count ) ?
|
255 |
+
( $this->request_handler_retries_count + 1 ) :
|
256 |
+
1;
|
257 |
+
|
258 |
+
$this->request_handler_timestamp = time();
|
259 |
+
|
260 |
+
$handler_id = ( rand() . microtime() );
|
261 |
+
$this->request_handler_id = $handler_id;
|
262 |
+
|
263 |
+
// Add cookies to trigger request with the same user access permissions.
|
264 |
+
$cookies = array();
|
265 |
+
foreach ( $_COOKIE as $name => $value ) {
|
266 |
+
$cookies[] = new WP_Http_Cookie( array(
|
267 |
+
'name' => $name,
|
268 |
+
'value' => $value,
|
269 |
+
) );
|
270 |
+
}
|
271 |
+
|
272 |
+
wp_remote_post(
|
273 |
+
admin_url( 'admin-post.php' ),
|
274 |
+
array(
|
275 |
+
'method' => 'POST',
|
276 |
+
'body' => array(
|
277 |
+
'action' => 'fs_clone_resolution',
|
278 |
+
'handler_id' => $handler_id,
|
279 |
+
),
|
280 |
+
'timeout' => 0.01,
|
281 |
+
'blocking' => false,
|
282 |
+
'sslverify' => false,
|
283 |
+
'cookies' => $cookies,
|
284 |
+
)
|
285 |
+
);
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Executes the clones handler logic.
|
290 |
+
*
|
291 |
+
* @author Leo Fajardo (@leorw)
|
292 |
+
* @since 2.5.0
|
293 |
+
*/
|
294 |
+
function _handle_clone_resolution() {
|
295 |
+
$handler_id = fs_request_get( 'handler_id' );
|
296 |
+
|
297 |
+
if ( empty( $handler_id ) ) {
|
298 |
+
return;
|
299 |
+
}
|
300 |
+
|
301 |
+
if (
|
302 |
+
! isset( $this->request_handler_id ) ||
|
303 |
+
$this->request_handler_id !== $handler_id
|
304 |
+
) {
|
305 |
+
return;
|
306 |
+
}
|
307 |
+
|
308 |
+
if ( ! $this->try_automatic_resolution() ) {
|
309 |
+
$this->clear_temporary_duplicate_notice_shown_timestamp();
|
310 |
+
}
|
311 |
+
}
|
312 |
+
|
313 |
+
#--------------------------------------------------------------------------------
|
314 |
+
#region Automatic Clone Resolution
|
315 |
+
#--------------------------------------------------------------------------------
|
316 |
+
|
317 |
+
/**
|
318 |
+
* @var array All installs cache.
|
319 |
+
*/
|
320 |
+
private $all_installs;
|
321 |
+
|
322 |
+
/**
|
323 |
+
* Checks if a given instance's install is a clone of another subsite in the network.
|
324 |
+
*
|
325 |
+
* @author Vova Feldman (@svovaf)
|
326 |
+
*
|
327 |
+
* @return FS_Site
|
328 |
+
*/
|
329 |
+
private function find_network_subsite_clone_install( Freemius $instance ) {
|
330 |
+
if ( ! is_multisite() ) {
|
331 |
+
// Not a multi-site network.
|
332 |
+
return null;
|
333 |
+
}
|
334 |
+
|
335 |
+
if ( ! isset( $this->all_installs ) ) {
|
336 |
+
$this->all_installs = Freemius::get_all_modules_sites();
|
337 |
+
}
|
338 |
+
|
339 |
+
// Check if there's another blog that has the same site.
|
340 |
+
$module_type = $instance->get_module_type();
|
341 |
+
$sites_by_module_type = ! empty( $this->all_installs[ $module_type ] ) ?
|
342 |
+
$this->all_installs[ $module_type ] :
|
343 |
+
array();
|
344 |
+
|
345 |
+
$slug = $instance->get_slug();
|
346 |
+
$sites_by_slug = ! empty( $sites_by_module_type[ $slug ] ) ?
|
347 |
+
$sites_by_module_type[ $slug ] :
|
348 |
+
array();
|
349 |
+
|
350 |
+
$current_blog_id = get_current_blog_id();
|
351 |
+
|
352 |
+
$current_install = $instance->get_site();
|
353 |
+
|
354 |
+
foreach ( $sites_by_slug as $site ) {
|
355 |
+
if (
|
356 |
+
$current_install->id == $site->id &&
|
357 |
+
$current_blog_id != $site->blog_id
|
358 |
+
) {
|
359 |
+
// Clone is identical to an install on another subsite in the network.
|
360 |
+
return $site;
|
361 |
+
}
|
362 |
+
}
|
363 |
+
|
364 |
+
return null;
|
365 |
+
}
|
366 |
+
|
367 |
+
/**
|
368 |
+
* Tries to find a different install of the context product that is associated with the current URL and loads it.
|
369 |
+
*
|
370 |
+
* @author Leo Fajardo (@leorw)
|
371 |
+
* @since 2.5.0
|
372 |
+
*
|
373 |
+
* @param Freemius $instance
|
374 |
+
* @param string $url
|
375 |
+
*
|
376 |
+
* @return object
|
377 |
+
*/
|
378 |
+
private function find_other_install_by_url( Freemius $instance, $url ) {
|
379 |
+
$result = $instance->get_api_user_scope()->get( "/plugins/{$instance->get_id()}/installs.json?url=" . urlencode( $url ) . "&all=true", true );
|
380 |
+
|
381 |
+
$current_install = $instance->get_site();
|
382 |
+
|
383 |
+
if ( $instance->is_api_result_object( $result, 'installs' ) ) {
|
384 |
+
foreach ( $result->installs as $install ) {
|
385 |
+
if ( $install->id == $current_install->id ) {
|
386 |
+
continue;
|
387 |
+
}
|
388 |
+
|
389 |
+
if (
|
390 |
+
$instance->is_only_premium() &&
|
391 |
+
! FS_Plugin_License::is_valid_id( $install->license_id )
|
392 |
+
) {
|
393 |
+
continue;
|
394 |
+
}
|
395 |
+
|
396 |
+
// When searching for installs by a URL, the API will first strip any paths and search for any matching installs by the subdomain. Therefore, we need to test if there's a match between the current URL and the install's URL before continuing.
|
397 |
+
if ( $url !== fs_strip_url_protocol( untrailingslashit( $install->url ) ) ) {
|
398 |
+
continue;
|
399 |
+
}
|
400 |
+
|
401 |
+
// Found a different install that is associated with the current URL, load it and replace the current install with it if no updated install is found.
|
402 |
+
return $install;
|
403 |
+
}
|
404 |
+
}
|
405 |
+
|
406 |
+
return null;
|
407 |
+
}
|
408 |
+
|
409 |
+
/**
|
410 |
+
* Delete the current install associated with a given instance and opt-in/activate-license to create a fresh install.
|
411 |
+
*
|
412 |
+
* @author Vova Feldman (@svovaf)
|
413 |
+
* @since 2.5.0
|
414 |
+
*
|
415 |
+
* @param Freemius $instance
|
416 |
+
* @param string|false $license_key
|
417 |
+
*
|
418 |
+
* @return bool TRUE if successfully connected. FALSE if failed and had to restore install from backup.
|
419 |
+
*/
|
420 |
+
private function delete_install_and_connect( Freemius $instance, $license_key = false ) {
|
421 |
+
$user = Freemius::_get_user_by_id( $instance->get_site()->user_id );
|
422 |
+
|
423 |
+
$instance->delete_current_install( true );
|
424 |
+
|
425 |
+
if ( ! is_object( $user ) ) {
|
426 |
+
// Get logged-in WordPress user.
|
427 |
+
$current_user = Freemius::_get_current_wp_user();
|
428 |
+
|
429 |
+
// Find the relevant FS user by email address.
|
430 |
+
$user = Freemius::_get_user_by_email( $current_user->user_email );
|
431 |
+
}
|
432 |
+
|
433 |
+
if ( is_object( $user ) ) {
|
434 |
+
// When a clone is found, we prefer to use the same user of the original install for the opt-in.
|
435 |
+
$instance->install_with_user( $user, $license_key, false, false );
|
436 |
+
} else {
|
437 |
+
// If no user is found, activate with the license.
|
438 |
+
$instance->opt_in(
|
439 |
+
false,
|
440 |
+
false,
|
441 |
+
false,
|
442 |
+
$license_key
|
443 |
+
);
|
444 |
+
}
|
445 |
+
|
446 |
+
if ( is_object( $instance->get_site() ) ) {
|
447 |
+
// Install successfully created.
|
448 |
+
return true;
|
449 |
+
}
|
450 |
+
|
451 |
+
// Restore from backup.
|
452 |
+
$instance->restore_backup_site();
|
453 |
+
|
454 |
+
return false;
|
455 |
+
}
|
456 |
+
|
457 |
+
/**
|
458 |
+
* Try to resolve the clone situation automatically.
|
459 |
+
*
|
460 |
+
* @param Freemius $instance
|
461 |
+
* @param string $current_url
|
462 |
+
* @param bool $is_localhost
|
463 |
+
* @param bool|null $is_clone_of_network_subsite
|
464 |
+
*
|
465 |
+
* @return bool If managed to automatically resolve the clone.
|
466 |
+
*/
|
467 |
+
private function try_resolve_clone_automatically_by_instance(
|
468 |
+
Freemius $instance,
|
469 |
+
$current_url,
|
470 |
+
$is_localhost,
|
471 |
+
$is_clone_of_network_subsite = null
|
472 |
+
) {
|
473 |
+
// Try to find a different install of the context product that is associated with the current URL.
|
474 |
+
$associated_install = $this->find_other_install_by_url( $instance, $current_url );
|
475 |
+
|
476 |
+
if ( is_object( $associated_install ) ) {
|
477 |
+
// Replace the current install with a different install that is associated with the current URL.
|
478 |
+
$instance->store_site( new FS_Site( clone $associated_install ) );
|
479 |
+
$instance->sync_install( array( 'is_new_site' => true ), true );
|
480 |
+
|
481 |
+
return true;
|
482 |
+
}
|
483 |
+
|
484 |
+
if ( ! $instance->is_premium() ) {
|
485 |
+
// For free products, opt-in with the context user to create new install.
|
486 |
+
return $this->delete_install_and_connect( $instance );
|
487 |
+
}
|
488 |
+
|
489 |
+
$license = $instance->_get_license();
|
490 |
+
$can_activate_license = ( is_object( $license ) && ! $license->is_utilized( $is_localhost ) );
|
491 |
+
|
492 |
+
if ( ! $can_activate_license ) {
|
493 |
+
// License can't be activated, therefore, can't be automatically resolved.
|
494 |
+
return false;
|
495 |
+
}
|
496 |
+
|
497 |
+
if ( ! WP_FS__IS_LOCALHOST_FOR_SERVER && ! $is_localhost ) {
|
498 |
+
$is_clone_of_network_subsite = ( ! is_null( $is_clone_of_network_subsite ) ) ?
|
499 |
+
$is_clone_of_network_subsite :
|
500 |
+
is_object( $this->find_network_subsite_clone_install( $instance ) );
|
501 |
+
|
502 |
+
if ( ! $is_clone_of_network_subsite ) {
|
503 |
+
return false;
|
504 |
+
}
|
505 |
+
}
|
506 |
+
|
507 |
+
// If the site is a clone of another subsite in the network, or a localhost one, try to auto activate the license.
|
508 |
+
return $this->delete_install_and_connect( $instance, $license->secret_key );
|
509 |
+
}
|
510 |
+
|
511 |
+
/**
|
512 |
+
* @author Leo Fajardo (@leorw)
|
513 |
+
* @since 2.5.0
|
514 |
+
*/
|
515 |
+
private function try_resolve_clone_automatically() {
|
516 |
+
$clone_action = $this->get_clone_resolution_action_from_config();
|
517 |
+
|
518 |
+
if ( ! empty( $clone_action ) ) {
|
519 |
+
$this->try_resolve_clone_automatically_by_config( $clone_action );
|
520 |
+
return;
|
521 |
+
}
|
522 |
+
|
523 |
+
$this->try_automatic_resolution();
|
524 |
+
}
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Tries to resolve the clone situation automatically based on the config in the wp-config.php file.
|
528 |
+
*
|
529 |
+
* @author Leo Fajardo (@leorw)
|
530 |
+
* @since 2.5.0
|
531 |
+
*
|
532 |
+
* @param string $clone_action
|
533 |
+
*/
|
534 |
+
private function try_resolve_clone_automatically_by_config( $clone_action ) {
|
535 |
+
$fs_instances = array();
|
536 |
+
|
537 |
+
if ( self::OPTION_LONG_TERM_DUPLICATE === $clone_action ) {
|
538 |
+
$instances = Freemius::_get_all_instances();
|
539 |
+
|
540 |
+
foreach ( $instances as $instance ) {
|
541 |
+
if ( ! $instance->is_registered() ) {
|
542 |
+
continue;
|
543 |
+
}
|
544 |
+
|
545 |
+
if ( ! $instance->is_clone() ) {
|
546 |
+
continue;
|
547 |
+
}
|
548 |
+
|
549 |
+
$license = $instance->has_features_enabled_license() ?
|
550 |
+
$instance->_get_license() :
|
551 |
+
null;
|
552 |
+
|
553 |
+
if (
|
554 |
+
is_object( $license ) &&
|
555 |
+
! $license->is_utilized(
|
556 |
+
( WP_FS__IS_LOCALHOST_FOR_SERVER || FS_Site::is_localhost_by_address( Freemius::get_unfiltered_site_url() ) )
|
557 |
+
)
|
558 |
+
) {
|
559 |
+
$fs_instances[] = $instance;
|
560 |
+
}
|
561 |
+
}
|
562 |
+
|
563 |
+
if ( empty( $fs_instances ) ) {
|
564 |
+
return;
|
565 |
+
}
|
566 |
+
}
|
567 |
+
|
568 |
+
$this->resolve_cloned_sites( $clone_action, $fs_instances );
|
569 |
+
}
|
570 |
+
|
571 |
+
/**
|
572 |
+
* @author Leo Fajard (@leorw)
|
573 |
+
* @since 2.5.0
|
574 |
+
*
|
575 |
+
* @return string|null
|
576 |
+
*/
|
577 |
+
private function get_clone_resolution_action_from_config() {
|
578 |
+
if ( ! defined( 'FS__RESOLVE_CLONE_AS' ) ) {
|
579 |
+
return null;
|
580 |
+
}
|
581 |
+
|
582 |
+
if ( ! in_array(
|
583 |
+
FS__RESOLVE_CLONE_AS,
|
584 |
+
array(
|
585 |
+
self::OPTION_NEW_HOME,
|
586 |
+
self::OPTION_TEMPORARY_DUPLICATE,
|
587 |
+
self::OPTION_LONG_TERM_DUPLICATE,
|
588 |
+
)
|
589 |
+
) ) {
|
590 |
+
return null;
|
591 |
+
}
|
592 |
+
|
593 |
+
return FS__RESOLVE_CLONE_AS;
|
594 |
+
}
|
595 |
+
|
596 |
+
/**
|
597 |
+
* Tries to recover the install of a newly created subsite or resolve it if it's a clone.
|
598 |
+
*
|
599 |
+
* @author Leo Fajardo (@leorw)
|
600 |
+
* @since 2.5.0
|
601 |
+
*
|
602 |
+
* @param Freemius $instance
|
603 |
+
*/
|
604 |
+
function maybe_resolve_new_subsite_install_automatically( Freemius $instance ) {
|
605 |
+
if ( ! $instance->is_user_in_admin() ) {
|
606 |
+
// Try to recover an install or resolve a clone only when there's a user in admin to prevent doing it prematurely (e.g., the install can get replaced with clone data again).
|
607 |
+
return;
|
608 |
+
}
|
609 |
+
|
610 |
+
if ( ! is_multisite() ) {
|
611 |
+
return;
|
612 |
+
}
|
613 |
+
|
614 |
+
$new_blog_install_map = $this->new_blog_install_map;
|
615 |
+
|
616 |
+
if ( empty( $new_blog_install_map ) || ! is_array( $new_blog_install_map ) ) {
|
617 |
+
return;
|
618 |
+
}
|
619 |
+
|
620 |
+
$is_network_admin = fs_is_network_admin();
|
621 |
+
|
622 |
+
if ( ! $is_network_admin ) {
|
623 |
+
// If not in network admin, handle the current site.
|
624 |
+
$blog_id = get_current_blog_id();
|
625 |
+
} else {
|
626 |
+
// If in network admin, handle only the first site.
|
627 |
+
$blog_ids = array_keys( $new_blog_install_map );
|
628 |
+
$blog_id = $blog_ids[0];
|
629 |
+
}
|
630 |
+
|
631 |
+
if ( ! isset( $new_blog_install_map[ $blog_id ] ) ) {
|
632 |
+
// There's no site to handle.
|
633 |
+
return;
|
634 |
+
}
|
635 |
+
|
636 |
+
$expected_install_id = $new_blog_install_map[ $blog_id ]['install_id'];
|
637 |
+
|
638 |
+
$current_install = $instance->get_install_by_blog_id( $blog_id );
|
639 |
+
$current_install_id = is_object( $current_install ) ?
|
640 |
+
$current_install->id :
|
641 |
+
null;
|
642 |
+
|
643 |
+
if ( $expected_install_id == $current_install_id ) {
|
644 |
+
// Remove the current site's information from the map to prevent handling it again.
|
645 |
+
$this->remove_new_blog_install_info_from_storage( $blog_id );
|
646 |
+
|
647 |
+
return;
|
648 |
+
}
|
649 |
+
|
650 |
+
require_once WP_FS__DIR_INCLUDES . '/class-fs-lock.php';
|
651 |
+
|
652 |
+
$lock = new FS_Lock( self::OPTION_NAME . '_subsite' );
|
653 |
+
|
654 |
+
if ( ! $lock->try_lock(60) ) {
|
655 |
+
return;
|
656 |
+
}
|
657 |
+
|
658 |
+
$instance->switch_to_blog( $blog_id );
|
659 |
+
|
660 |
+
$current_url = untrailingslashit( Freemius::get_unfiltered_site_url( null, true ) );
|
661 |
+
$current_install_url = is_object( $current_install ) ?
|
662 |
+
fs_strip_url_protocol( untrailingslashit( $current_install->url ) ) :
|
663 |
+
null;
|
664 |
+
|
665 |
+
// This can be `false` even if the install is a clone as the URL can be updated as part of the cloning process.
|
666 |
+
$is_clone = ( ! is_null( $current_install_url ) && $current_url !== $current_install_url );
|
667 |
+
|
668 |
+
if ( ! FS_Site::is_valid_id( $expected_install_id ) ) {
|
669 |
+
$expected_install = null;
|
670 |
+
} else {
|
671 |
+
$expected_install = $instance->fetch_install_by_id( $expected_install_id );
|
672 |
+
}
|
673 |
+
|
674 |
+
if ( FS_Api::is_api_result_entity( $expected_install ) ) {
|
675 |
+
// Replace the current install with the expected install.
|
676 |
+
$instance->store_site( new FS_Site( clone $expected_install ) );
|
677 |
+
$instance->sync_install( array( 'is_new_site' => true ), true );
|
678 |
+
} else {
|
679 |
+
$network_subsite_clone_install = null;
|
680 |
+
|
681 |
+
if ( ! $is_clone ) {
|
682 |
+
// It is possible that `$is_clone` is `false` but the install is actually a clone as the following call checks the install ID and not the URL.
|
683 |
+
$network_subsite_clone_install = $this->find_network_subsite_clone_install( $instance );
|
684 |
+
}
|
685 |
+
|
686 |
+
if ( $is_clone || is_object( $network_subsite_clone_install ) ) {
|
687 |
+
// If there's no expected install (or it couldn't be fetched) and the current install is a clone, try to resolve the clone automatically.
|
688 |
+
$is_localhost = FS_Site::is_localhost_by_address( $current_url );
|
689 |
+
|
690 |
+
$resolved = $this->try_resolve_clone_automatically_by_instance( $instance, $current_url, $is_localhost, is_object( $network_subsite_clone_install ) );
|
691 |
+
|
692 |
+
if ( ! $resolved && is_object( $network_subsite_clone_install ) ) {
|
693 |
+
if ( empty( $this->get_clone_identification_timestamp() ) ) {
|
694 |
+
$this->store_clone_identification_timestamp();
|
695 |
+
}
|
696 |
+
|
697 |
+
// Since the clone couldn't be identified based on the URL, replace the stored install with the cloned install so that the manual clone resolution notice will appear.
|
698 |
+
$instance->store_site( clone $network_subsite_clone_install );
|
699 |
+
}
|
700 |
+
}
|
701 |
+
}
|
702 |
+
|
703 |
+
$instance->restore_current_blog();
|
704 |
+
|
705 |
+
// Remove the current site's information from the map to prevent handling it again.
|
706 |
+
$this->remove_new_blog_install_info_from_storage( $blog_id );
|
707 |
+
|
708 |
+
$lock->unlock();
|
709 |
+
}
|
710 |
+
|
711 |
+
/**
|
712 |
+
* If a new install was created after creating a new subsite, its ID is stored in the blog-install map so that it can be recovered in case it's replaced with a clone install (e.g., when the newly created subsite is a clone). The IDs of the clone subsites that were created while not running this version of the SDK or a higher version will also be stored in the said map so that the clone manager can also try to resolve them later on.
|
713 |
+
*
|
714 |
+
* @author Leo Fajardo (@leorw)
|
715 |
+
* @since 2.5.0
|
716 |
+
*
|
717 |
+
* @param int $blog_id
|
718 |
+
* @param FS_Site $site
|
719 |
+
*/
|
720 |
+
function store_blog_install_info( $blog_id, $site = null ) {
|
721 |
+
$new_blog_install_map = $this->new_blog_install_map;
|
722 |
+
|
723 |
+
if (
|
724 |
+
empty( $new_blog_install_map ) ||
|
725 |
+
! is_array( $new_blog_install_map )
|
726 |
+
) {
|
727 |
+
$new_blog_install_map = array();
|
728 |
+
}
|
729 |
+
|
730 |
+
$install_id = null;
|
731 |
+
|
732 |
+
if ( is_object( $site ) ) {
|
733 |
+
$install_id = $site->id;
|
734 |
+
}
|
735 |
+
|
736 |
+
$new_blog_install_map[ $blog_id ] = array( 'install_id' => $install_id );
|
737 |
+
|
738 |
+
$this->new_blog_install_map = $new_blog_install_map;
|
739 |
+
}
|
740 |
+
|
741 |
+
/**
|
742 |
+
* @author Leo Fajardo (@leorw)
|
743 |
+
* @since 2.5.0
|
744 |
+
*
|
745 |
+
* @param int $blog_id
|
746 |
+
*/
|
747 |
+
private function remove_new_blog_install_info_from_storage( $blog_id ) {
|
748 |
+
$new_blog_install_map = $this->new_blog_install_map;
|
749 |
+
|
750 |
+
unset( $new_blog_install_map[ $blog_id ] );
|
751 |
+
$this->new_blog_install_map = $new_blog_install_map;
|
752 |
+
}
|
753 |
+
|
754 |
+
/**
|
755 |
+
* Tries to resolve all clones automatically.
|
756 |
+
*
|
757 |
+
* @author Leo Fajardo (@leorw)
|
758 |
+
* @since 2.5.0
|
759 |
+
*
|
760 |
+
* @return bool If managed to automatically resolve all clones.
|
761 |
+
*/
|
762 |
+
private function try_automatic_resolution() {
|
763 |
+
$this->_logger->entrance();
|
764 |
+
|
765 |
+
require_once WP_FS__DIR_INCLUDES . '/class-fs-lock.php';
|
766 |
+
|
767 |
+
$lock = new FS_Lock( self::OPTION_NAME );
|
768 |
+
|
769 |
+
/**
|
770 |
+
* Try to acquire lock for the next 60 sec based on the thread ID.
|
771 |
+
*/
|
772 |
+
if ( ! $lock->try_lock( 60 ) ) {
|
773 |
+
return false;
|
774 |
+
}
|
775 |
+
|
776 |
+
$current_url = untrailingslashit( Freemius::get_unfiltered_site_url( null, true ) );
|
777 |
+
$is_localhost = FS_Site::is_localhost_by_address( $current_url );
|
778 |
+
|
779 |
+
$require_manual_resolution = false;
|
780 |
+
|
781 |
+
$instances = Freemius::_get_all_instances();
|
782 |
+
|
783 |
+
foreach ( $instances as $instance ) {
|
784 |
+
if ( ! $instance->is_registered() ) {
|
785 |
+
continue;
|
786 |
+
}
|
787 |
+
|
788 |
+
if ( ! $instance->is_clone() ) {
|
789 |
+
continue;
|
790 |
+
}
|
791 |
+
|
792 |
+
if ( ! $this->try_resolve_clone_automatically_by_instance( $instance, $current_url, $is_localhost ) ) {
|
793 |
+
$require_manual_resolution = true;
|
794 |
+
}
|
795 |
+
}
|
796 |
+
|
797 |
+
// Create a 1-day lock.
|
798 |
+
$lock->lock( WP_FS__TIME_24_HOURS_IN_SEC );
|
799 |
+
|
800 |
+
return ( ! $require_manual_resolution );
|
801 |
+
}
|
802 |
+
|
803 |
+
#endregion
|
804 |
+
|
805 |
+
#--------------------------------------------------------------------------------
|
806 |
+
#region Manual Clone Resolution
|
807 |
+
#--------------------------------------------------------------------------------
|
808 |
+
|
809 |
+
/**
|
810 |
+
* @author Leo Fajardo (@leorw)
|
811 |
+
* @since 2.5.0
|
812 |
+
*/
|
813 |
+
function _add_clone_resolution_javascript() {
|
814 |
+
$vars = array( 'ajax_action' => Freemius::get_ajax_action_static( 'handle_clone_resolution' ) );
|
815 |
+
|
816 |
+
fs_require_once_template( 'clone-resolution-js.php', $vars );
|
817 |
+
}
|
818 |
+
|
819 |
+
/**
|
820 |
+
* @author Leo Fajardo (@leorw)
|
821 |
+
* @since 2.5.0
|
822 |
+
*/
|
823 |
+
function _clone_resolution_action_ajax_handler() {
|
824 |
+
$this->_logger->entrance();
|
825 |
+
|
826 |
+
check_ajax_referer( Freemius::get_ajax_action_static( 'handle_clone_resolution' ), 'security' );
|
827 |
+
|
828 |
+
$clone_action = fs_request_get( 'clone_action' );
|
829 |
+
$blog_id = is_multisite() ?
|
830 |
+
fs_request_get( 'blog_id' ) :
|
831 |
+
0;
|
832 |
+
|
833 |
+
if ( is_multisite() && $blog_id == get_current_blog_id() ) {
|
834 |
+
$blog_id = 0;
|
835 |
+
}
|
836 |
+
|
837 |
+
if ( empty( $clone_action ) ) {
|
838 |
+
Freemius::shoot_ajax_failure( array(
|
839 |
+
'message' => fs_text_inline( 'Invalid clone resolution action.', 'invalid-clone-resolution-action-error' ),
|
840 |
+
'redirect_url' => '',
|
841 |
+
) );
|
842 |
+
}
|
843 |
+
|
844 |
+
$result = $this->resolve_cloned_sites( $clone_action, array(), $blog_id );
|
845 |
+
|
846 |
+
Freemius::shoot_ajax_success( $result );
|
847 |
+
}
|
848 |
+
|
849 |
+
/**
|
850 |
+
* @author Leo Fajardo (@leorw)
|
851 |
+
* @since 2.5.0
|
852 |
+
*
|
853 |
+
* @param string $clone_action
|
854 |
+
* @param Freemius[] $fs_instances
|
855 |
+
* @param int $blog_id
|
856 |
+
*
|
857 |
+
* @return array
|
858 |
+
*/
|
859 |
+
private function resolve_cloned_sites( $clone_action, $fs_instances = array(), $blog_id = 0 ) {
|
860 |
+
$this->_logger->entrance();
|
861 |
+
|
862 |
+
$result = array();
|
863 |
+
|
864 |
+
$instances_with_clone = array();
|
865 |
+
$instances_with_clone_count = 0;
|
866 |
+
$install_by_instance_id = array();
|
867 |
+
|
868 |
+
$instances = ( ! empty( $fs_instances ) ) ?
|
869 |
+
$fs_instances :
|
870 |
+
Freemius::_get_all_instances();
|
871 |
+
|
872 |
+
$should_switch_to_blog = ( $blog_id > 0 );
|
873 |
+
|
874 |
+
foreach ( $instances as $instance ) {
|
875 |
+
if ( $should_switch_to_blog ) {
|
876 |
+
$instance->switch_to_blog( $blog_id );
|
877 |
+
}
|
878 |
+
|
879 |
+
if ( $instance->is_registered() && $instance->is_clone() ) {
|
880 |
+
$instances_with_clone[] = $instance;
|
881 |
+
|
882 |
+
$instances_with_clone_count ++;
|
883 |
+
|
884 |
+
$install_by_instance_id[ $instance->get_id() ] = $instance->get_site();
|
885 |
+
}
|
886 |
+
}
|
887 |
+
|
888 |
+
if ( self::OPTION_TEMPORARY_DUPLICATE === $clone_action ) {
|
889 |
+
$this->store_temporary_duplicate_timestamp();
|
890 |
+
} else {
|
891 |
+
$redirect_url = '';
|
892 |
+
|
893 |
+
foreach ( $instances_with_clone as $instance ) {
|
894 |
+
if ( $should_switch_to_blog ) {
|
895 |
+
$instance->switch_to_blog( $blog_id );
|
896 |
+
}
|
897 |
+
|
898 |
+
$has_error = false;
|
899 |
+
|
900 |
+
if ( self::OPTION_NEW_HOME === $clone_action ) {
|
901 |
+
$instance->sync_install( array( 'is_new_site' => true ), true );
|
902 |
+
|
903 |
+
if ( $instance->is_clone() ) {
|
904 |
+
$has_error = true;
|
905 |
+
}
|
906 |
+
} else {
|
907 |
+
$instance->_handle_long_term_duplicate();
|
908 |
+
|
909 |
+
if ( ! is_object( $instance->get_site() ) ) {
|
910 |
+
$has_error = true;
|
911 |
+
}
|
912 |
+
}
|
913 |
+
|
914 |
+
if ( $has_error && 1 === $instances_with_clone_count ) {
|
915 |
+
$redirect_url = $instance->get_activation_url();
|
916 |
+
}
|
917 |
+
}
|
918 |
+
|
919 |
+
$result = ( array( 'redirect_url' => $redirect_url ) );
|
920 |
+
}
|
921 |
+
|
922 |
+
foreach ( $instances_with_clone as $instance ) {
|
923 |
+
if ( $should_switch_to_blog ) {
|
924 |
+
$instance->switch_to_blog( $blog_id );
|
925 |
+
}
|
926 |
+
|
927 |
+
// No longer a clone, send an update.
|
928 |
+
if ( ! $instance->is_clone() ) {
|
929 |
+
$instance->send_clone_resolution_update(
|
930 |
+
$clone_action,
|
931 |
+
$install_by_instance_id[ $instance->get_id() ]
|
932 |
+
);
|
933 |
+
}
|
934 |
+
}
|
935 |
+
|
936 |
+
if ( 'temporary_duplicate_license_activation' !== $clone_action ) {
|
937 |
+
$this->remove_clone_resolution_options_notice();
|
938 |
+
} else {
|
939 |
+
$this->remove_temporary_duplicate_notice();
|
940 |
+
}
|
941 |
+
|
942 |
+
if ( $should_switch_to_blog ) {
|
943 |
+
foreach ( $instances as $instance ) {
|
944 |
+
$instance->restore_current_blog();
|
945 |
+
}
|
946 |
+
}
|
947 |
+
|
948 |
+
return $result;
|
949 |
+
}
|
950 |
+
|
951 |
+
/**
|
952 |
+
* @author Leo Fajardo (@leorw)
|
953 |
+
* @since 2.5.0
|
954 |
+
*/
|
955 |
+
private function hide_clone_admin_notices() {
|
956 |
+
$this->remove_clone_resolution_options_notice( false );
|
957 |
+
$this->remove_temporary_duplicate_notice( false );
|
958 |
+
}
|
959 |
+
|
960 |
+
/**
|
961 |
+
* @author Leo Fajardo (@leorw)
|
962 |
+
* @since 2.5.0
|
963 |
+
*/
|
964 |
+
function maybe_show_clone_admin_notice() {
|
965 |
+
$this->_logger->entrance();
|
966 |
+
|
967 |
+
if ( fs_is_network_admin() ) {
|
968 |
+
$existing_notice_ids = $this->maybe_remove_notices();
|
969 |
+
|
970 |
+
if ( ! empty( $existing_notice_ids ) ) {
|
971 |
+
fs_enqueue_local_style( 'fs_clone_resolution_notice', '/admin/clone-resolution.css' );
|
972 |
+
}
|
973 |
+
|
974 |
+
return;
|
975 |
+
}
|
976 |
+
|
977 |
+
$first_instance_with_clone = null;
|
978 |
+
|
979 |
+
$site_urls = array();
|
980 |
+
$sites_with_license_urls = array();
|
981 |
+
$sites_with_premium_version_count = 0;
|
982 |
+
$product_ids = array();
|
983 |
+
$product_titles = array();
|
984 |
+
|
985 |
+
$instances = Freemius::_get_all_instances();
|
986 |
+
|
987 |
+
foreach ( $instances as $instance ) {
|
988 |
+
if ( ! $instance->is_registered() ) {
|
989 |
+
continue;
|
990 |
+
}
|
991 |
+
|
992 |
+
if ( ! $instance->is_clone( true ) ) {
|
993 |
+
continue;
|
994 |
+
}
|
995 |
+
|
996 |
+
$install = $instance->get_site();
|
997 |
+
|
998 |
+
$site_urls[] = $install->url;
|
999 |
+
$product_ids[] = $instance->get_id();
|
1000 |
+
$product_titles[] = $instance->get_plugin_title();
|
1001 |
+
|
1002 |
+
if ( is_null( $first_instance_with_clone ) ) {
|
1003 |
+
$first_instance_with_clone = $instance;
|
1004 |
+
}
|
1005 |
+
|
1006 |
+
if ( is_object( $instance->_get_license() ) ) {
|
1007 |
+
$sites_with_license_urls[] = $install->url;
|
1008 |
+
}
|
1009 |
+
|
1010 |
+
if ( $instance->is_premium() ) {
|
1011 |
+
$sites_with_premium_version_count ++;
|
1012 |
+
}
|
1013 |
+
}
|
1014 |
+
|
1015 |
+
if ( empty( $site_urls ) && empty( $sites_with_license_urls ) ) {
|
1016 |
+
$this->hide_clone_admin_notices();
|
1017 |
+
|
1018 |
+
return;
|
1019 |
+
}
|
1020 |
+
|
1021 |
+
$site_urls = array_unique( $site_urls );
|
1022 |
+
$sites_with_license_urls = array_unique( $sites_with_license_urls );
|
1023 |
+
|
1024 |
+
$module_label = fs_text_inline( 'products', 'products' );
|
1025 |
+
$admin_notice_module_title = null;
|
1026 |
+
|
1027 |
+
$has_temporary_duplicate_mode_expired = $this->has_temporary_duplicate_mode_expired();
|
1028 |
+
|
1029 |
+
if (
|
1030 |
+
! $this->was_temporary_duplicate_mode_selected() ||
|
1031 |
+
$has_temporary_duplicate_mode_expired
|
1032 |
+
) {
|
1033 |
+
if ( ! empty( $site_urls ) ) {
|
1034 |
+
fs_enqueue_local_style( 'fs_clone_resolution_notice', '/admin/clone-resolution.css' );
|
1035 |
+
|
1036 |
+
$doc_url = 'https://freemius.com/help/documentation/wordpress-sdk/safe-mode-clone-resolution-duplicate-website/';
|
1037 |
+
|
1038 |
+
if ( 1 === count( $instances ) ) {
|
1039 |
+
$doc_url = fs_apply_filter(
|
1040 |
+
$first_instance_with_clone->get_unique_affix(),
|
1041 |
+
'clone_resolution_documentation_url',
|
1042 |
+
$doc_url
|
1043 |
+
);
|
1044 |
+
}
|
1045 |
+
|
1046 |
+
$this->add_manual_clone_resolution_admin_notice(
|
1047 |
+
$product_ids,
|
1048 |
+
$product_titles,
|
1049 |
+
$site_urls,
|
1050 |
+
Freemius::get_unfiltered_site_url(),
|
1051 |
+
( count( $site_urls ) === count( $sites_with_license_urls ) ),
|
1052 |
+
( count( $site_urls ) === $sites_with_premium_version_count ),
|
1053 |
+
$doc_url
|
1054 |
+
);
|
1055 |
+
}
|
1056 |
+
|
1057 |
+
return;
|
1058 |
+
}
|
1059 |
+
|
1060 |
+
if ( empty( $sites_with_license_urls ) ) {
|
1061 |
+
return;
|
1062 |
+
}
|
1063 |
+
|
1064 |
+
if ( ! $this->is_temporary_duplicate_notice_shown() ) {
|
1065 |
+
$last_time_temporary_duplicate_notice_shown = $this->temporary_duplicate_notice_shown_timestamp;
|
1066 |
+
$was_temporary_duplicate_notice_shown_before = is_numeric( $last_time_temporary_duplicate_notice_shown );
|
1067 |
+
|
1068 |
+
if ( $was_temporary_duplicate_notice_shown_before ) {
|
1069 |
+
$temporary_duplicate_mode_expiration_timestamp = $this->get_temporary_duplicate_expiration_timestamp();
|
1070 |
+
$current_time = time();
|
1071 |
+
|
1072 |
+
if (
|
1073 |
+
$current_time > $temporary_duplicate_mode_expiration_timestamp ||
|
1074 |
+
$current_time < ( $temporary_duplicate_mode_expiration_timestamp - ( 2 * WP_FS__TIME_24_HOURS_IN_SEC ) )
|
1075 |
+
) {
|
1076 |
+
// Do not show the notice if the temporary duplicate mode has already expired or it will expire more than 2 days from now.
|
1077 |
+
return;
|
1078 |
+
}
|
1079 |
+
}
|
1080 |
+
}
|
1081 |
+
|
1082 |
+
if ( 1 === count( $sites_with_license_urls ) ) {
|
1083 |
+
$module_label = $first_instance_with_clone->get_module_label( true );
|
1084 |
+
$admin_notice_module_title = $first_instance_with_clone->get_plugin_title();
|
1085 |
+
}
|
1086 |
+
|
1087 |
+
fs_enqueue_local_style( 'fs_clone_resolution_notice', '/admin/clone-resolution.css' );
|
1088 |
+
|
1089 |
+
$this->add_temporary_duplicate_sticky_notice(
|
1090 |
+
$product_ids,
|
1091 |
+
$this->get_temporary_duplicate_admin_notice_string( $sites_with_license_urls, $product_titles, $module_label ),
|
1092 |
+
$admin_notice_module_title
|
1093 |
+
);
|
1094 |
+
}
|
1095 |
+
|
1096 |
+
/**
|
1097 |
+
* Removes the notices from the storage if the context product is either no longer active on the context subsite or it's active but there's no longer any clone. This prevents the notices from being shown on the network-level admin page when they are no longer relevant.
|
1098 |
+
*
|
1099 |
+
* @author Leo Fajardo (@leorw)
|
1100 |
+
* @since 2.5.1
|
1101 |
+
*
|
1102 |
+
* @return string[]
|
1103 |
+
*/
|
1104 |
+
private function maybe_remove_notices() {
|
1105 |
+
$notices = array(
|
1106 |
+
'clone_resolution_options_notice' => $this->_notices->get_sticky( 'clone_resolution_options_notice', true ),
|
1107 |
+
'temporary_duplicate_notice' => $this->_notices->get_sticky( 'temporary_duplicate_notice', true ),
|
1108 |
+
);
|
1109 |
+
|
1110 |
+
$instances = Freemius::_get_all_instances();
|
1111 |
+
|
1112 |
+
foreach ( $notices as $id => $notice ) {
|
1113 |
+
if ( ! is_array( $notice ) ) {
|
1114 |
+
unset( $notices[ $id ] );
|
1115 |
+
continue;
|
1116 |
+
}
|
1117 |
+
|
1118 |
+
if ( empty( $notice['data'] ) || ! is_array( $notice['data'] ) ) {
|
1119 |
+
continue;
|
1120 |
+
}
|
1121 |
+
|
1122 |
+
if ( empty( $notice['data']['product_ids'] ) || empty( $notice['data']['blog_id'] ) ) {
|
1123 |
+
continue;
|
1124 |
+
}
|
1125 |
+
|
1126 |
+
$product_ids = $notice['data']['product_ids'];
|
1127 |
+
$blog_id = $notice['data']['blog_id'];
|
1128 |
+
$has_clone = false;
|
1129 |
+
|
1130 |
+
if ( ! is_null( get_site( $blog_id ) ) ) {
|
1131 |
+
foreach ( $product_ids as $product_id ) {
|
1132 |
+
if ( ! isset( $instances[ 'm_' . $product_id ] ) ) {
|
1133 |
+
continue;
|
1134 |
+
}
|
1135 |
+
|
1136 |
+
$instance = $instances[ 'm_' . $product_id ];
|
1137 |
+
|
1138 |
+
$plugin_basename = $instance->get_plugin_basename();
|
1139 |
+
|
1140 |
+
$is_plugin_active = is_plugin_active_for_network( $plugin_basename );
|
1141 |
+
|
1142 |
+
if ( ! $is_plugin_active ) {
|
1143 |
+
switch_to_blog( $blog_id );
|
1144 |
+
|
1145 |
+
$is_plugin_active = is_plugin_active( $plugin_basename );
|
1146 |
+
|
1147 |
+
restore_current_blog();
|
1148 |
+
}
|
1149 |
+
|
1150 |
+
if ( ! $is_plugin_active ) {
|
1151 |
+
continue;
|
1152 |
+
}
|
1153 |
+
|
1154 |
+
$install = $instance->get_install_by_blog_id( $blog_id );
|
1155 |
+
|
1156 |
+
if ( ! is_object( $install ) ) {
|
1157 |
+
continue;
|
1158 |
+
}
|
1159 |
+
|
1160 |
+
$subsite_url = Freemius::get_unfiltered_site_url( $blog_id, true, true );
|
1161 |
+
|
1162 |
+
$has_clone = ( fs_strip_url_protocol( trailingslashit( $install->url ) ) !== $subsite_url );
|
1163 |
+
}
|
1164 |
+
}
|
1165 |
+
|
1166 |
+
if ( ! $has_clone ) {
|
1167 |
+
$this->_notices->remove_sticky( $id, true, false );
|
1168 |
+
unset( $notices[ $id ] );
|
1169 |
+
}
|
1170 |
+
}
|
1171 |
+
|
1172 |
+
return array_keys( $notices );
|
1173 |
+
}
|
1174 |
+
|
1175 |
+
/**
|
1176 |
+
* Adds a notice that provides the logged-in WordPress user with manual clone resolution options.
|
1177 |
+
*
|
1178 |
+
* @param number[] $product_ids
|
1179 |
+
* @param string[] $site_urls
|
1180 |
+
* @param string $current_url
|
1181 |
+
* @param bool $has_license
|
1182 |
+
* @param bool $is_premium
|
1183 |
+
* @param string $doc_url
|
1184 |
+
*/
|
1185 |
+
private function add_manual_clone_resolution_admin_notice(
|
1186 |
+
$product_ids,
|
1187 |
+
$product_titles,
|
1188 |
+
$site_urls,
|
1189 |
+
$current_url,
|
1190 |
+
$has_license,
|
1191 |
+
$is_premium,
|
1192 |
+
$doc_url
|
1193 |
+
) {
|
1194 |
+
$this->_logger->entrance();
|
1195 |
+
|
1196 |
+
$total_sites = count( $site_urls );
|
1197 |
+
$sites_list = '';
|
1198 |
+
|
1199 |
+
$total_products = count( $product_titles );
|
1200 |
+
$products_list = '';
|
1201 |
+
|
1202 |
+
if ( 1 === $total_products ) {
|
1203 |
+
$notice_header = sprintf(
|
1204 |
+
'<div class="fs-notice-header"><p>%s</p></div>',
|
1205 |
+
fs_esc_html_inline( '%1$s has been placed into safe mode because we noticed that %2$s is an exact copy of %3$s.', 'single-cloned-site-safe-mode-message' )
|
1206 |
+
);
|
1207 |
+
} else {
|
1208 |
+
$notice_header = sprintf(
|
1209 |
+
'<div class="fs-notice-header"><p>%s</p></div>',
|
1210 |
+
( 1 === $total_sites ) ?
|
1211 |
+
fs_esc_html_inline( 'The products below have been placed into safe mode because we noticed that %2$s is an exact copy of %3$s:%1$s', 'multiple-products-cloned-site-safe-mode-message' ) :
|
1212 |
+
fs_esc_html_inline( 'The products below have been placed into safe mode because we noticed that %2$s is an exact copy of these sites:%3$s%1$s', 'multiple-products-multiple-cloned-sites-safe-mode-message' )
|
1213 |
+
);
|
1214 |
+
|
1215 |
+
foreach ( $product_titles as $product_title ) {
|
1216 |
+
$products_list .= sprintf( '<li>%s</li>', $product_title );
|
1217 |
+
}
|
1218 |
+
|
1219 |
+
$products_list = '<ol>' . $products_list . '</ol>';
|
1220 |
+
|
1221 |
+
foreach ( $site_urls as $site_url ) {
|
1222 |
+
$sites_list .= sprintf(
|
1223 |
+
'<li><a href="%s" target="_blank">%s</a></li>',
|
1224 |
+
$site_url,
|
1225 |
+
fs_strip_url_protocol( $site_url )
|
1226 |
+
);
|
1227 |
+
}
|
1228 |
+
|
1229 |
+
$sites_list = '<ol>' . $sites_list . '</ol>';
|
1230 |
+
}
|
1231 |
+
|
1232 |
+
$remote_site_link = '<b>' . (1 === $total_sites ?
|
1233 |
+
sprintf(
|
1234 |
+
'<a href="%s" target="_blank">%s</a>',
|
1235 |
+
$site_urls[0],
|
1236 |
+
fs_strip_url_protocol( $site_urls[0] )
|
1237 |
+
) :
|
1238 |
+
fs_text_inline( 'the above-mentioned sites', 'above-mentioned-sites' )) . '</b>';
|
1239 |
+
|
1240 |
+
$current_site_link = sprintf(
|
1241 |
+
'<b><a href="%s" target="_blank">%s</a></b>',
|
1242 |
+
$current_url,
|
1243 |
+
fs_strip_url_protocol( $current_url )
|
1244 |
+
);
|
1245 |
+
|
1246 |
+
$button_template = '<button class="button" data-clone-action="%s">%s</button>';
|
1247 |
+
$option_template = '<div class="fs-clone-resolution-option"><strong>%s</strong><p>%s</p><div>%s</div></div>';
|
1248 |
+
|
1249 |
+
$duplicate_option = sprintf(
|
1250 |
+
$option_template,
|
1251 |
+
fs_esc_html_inline( 'Is %2$s a duplicate of %4$s?', 'duplicate-site-confirmation-message' ),
|
1252 |
+
fs_esc_html_inline( 'Yes, %2$s is a duplicate of %4$s for the purpose of testing, staging, or development.', 'duplicate-site-message' ),
|
1253 |
+
( $this->has_temporary_duplicate_mode_expired() ?
|
1254 |
+
sprintf(
|
1255 |
+
$button_template,
|
1256 |
+
'long_term_duplicate',
|
1257 |
+
fs_text_inline( 'Long-Term Duplicate', 'long-term-duplicate' )
|
1258 |
+
) :
|
1259 |
+
sprintf(
|
1260 |
+
$button_template,
|
1261 |
+
'temporary_duplicate',
|
1262 |
+
fs_text_inline( 'Duplicate Website', 'duplicate-site' )
|
1263 |
+
) )
|
1264 |
+
);
|
1265 |
+
|
1266 |
+
$migration_option = sprintf(
|
1267 |
+
$option_template,
|
1268 |
+
fs_esc_html_inline( 'Is %2$s the new home of %4$s?', 'migrate-site-confirmation-message' ),
|
1269 |
+
sprintf(
|
1270 |
+
fs_esc_html_inline( 'Yes, %%2$s is replacing %%4$s. I would like to migrate my %s from %%4$s to %%2$s.', 'migrate-site-message' ),
|
1271 |
+
( $has_license ? fs_text_inline( 'license', 'license' ) : fs_text_inline( 'data', 'data' ) )
|
1272 |
+
),
|
1273 |
+
sprintf(
|
1274 |
+
$button_template,
|
1275 |
+
'new_home',
|
1276 |
+
$has_license ?
|
1277 |
+
fs_text_inline( 'Migrate License', 'migrate-product-license' ) :
|
1278 |
+
fs_text_inline( 'Migrate', 'migrate-product-data' )
|
1279 |
+
)
|
1280 |
+
);
|
1281 |
+
|
1282 |
+
$new_website = sprintf(
|
1283 |
+
$option_template,
|
1284 |
+
fs_esc_html_inline( 'Is %2$s a new website?', 'new-site-confirmation-message' ),
|
1285 |
+
fs_esc_html_inline( 'Yes, %2$s is a new and different website that is separate from %4$s.', 'new-site-message' ) .
|
1286 |
+
($is_premium ?
|
1287 |
+
' ' . fs_text_inline( 'It requires license activation.', 'new-site-requires-license-activation-message' ) :
|
1288 |
+
''
|
1289 |
+
),
|
1290 |
+
sprintf(
|
1291 |
+
$button_template,
|
1292 |
+
'new_website',
|
1293 |
+
( ! $is_premium || ! $has_license ) ?
|
1294 |
+
fs_text_inline( 'New Website', 'new-website' ) :
|
1295 |
+
fs_text_inline( 'Activate License', 'activate-license' )
|
1296 |
+
)
|
1297 |
+
);
|
1298 |
+
|
1299 |
+
$blog_id = get_current_blog_id();
|
1300 |
+
|
1301 |
+
/**
|
1302 |
+
* %1$s - single product's title or product titles list.
|
1303 |
+
* %2$s - site's URL.
|
1304 |
+
* %3$s - single install's URL or install URLs list.
|
1305 |
+
* %4$s - Clone site's link or "the above-mentioned sites" if there are multiple clone sites.
|
1306 |
+
*/
|
1307 |
+
$message = sprintf(
|
1308 |
+
$notice_header .
|
1309 |
+
'<div class="fs-clone-resolution-options-container" data-ajax-url="' . esc_attr( admin_url( 'admin-ajax.php?_fs_network_admin=false', 'relative' ) ) . '" data-blog-id="' . $blog_id . '">' .
|
1310 |
+
$duplicate_option .
|
1311 |
+
$migration_option .
|
1312 |
+
$new_website . '</div>' .
|
1313 |
+
sprintf( '<div class="fs-clone-documentation-container">Unsure what to do? <a href="%s" target="_blank">Read more here</a>.</div>', $doc_url ),
|
1314 |
+
// %1$s
|
1315 |
+
( 1 === $total_products ?
|
1316 |
+
sprintf( '<b>%s</b>', $product_titles[0] ) :
|
1317 |
+
( 1 === $total_sites ?
|
1318 |
+
sprintf( '<div>%s</div>', $products_list ) :
|
1319 |
+
sprintf( '<div><p><strong>%s</strong>:</p>%s</div>', fs_esc_html_x_inline( 'Products', 'Clone resolution admin notice products list label', 'products' ), $products_list ) )
|
1320 |
+
),
|
1321 |
+
// %2$s
|
1322 |
+
$current_site_link,
|
1323 |
+
// %3$s
|
1324 |
+
( 1 === $total_sites ?
|
1325 |
+
$remote_site_link :
|
1326 |
+
$sites_list ),
|
1327 |
+
// %4$s
|
1328 |
+
$remote_site_link
|
1329 |
+
);
|
1330 |
+
|
1331 |
+
$this->_notices->add_sticky(
|
1332 |
+
$message,
|
1333 |
+
'clone_resolution_options_notice',
|
1334 |
+
'',
|
1335 |
+
'warn',
|
1336 |
+
true,
|
1337 |
+
null,
|
1338 |
+
null,
|
1339 |
+
true,
|
1340 |
+
// Intentionally not dismissible.
|
1341 |
+
false,
|
1342 |
+
array(
|
1343 |
+
'product_ids' => $product_ids,
|
1344 |
+
'blog_id' => $blog_id
|
1345 |
+
)
|
1346 |
+
);
|
1347 |
+
}
|
1348 |
+
|
1349 |
+
#endregion
|
1350 |
+
|
1351 |
+
#--------------------------------------------------------------------------------
|
1352 |
+
#region Temporary Duplicate (Short Term)
|
1353 |
+
#--------------------------------------------------------------------------------
|
1354 |
+
|
1355 |
+
/**
|
1356 |
+
* @author Leo Fajardo (@leorw)
|
1357 |
+
* @since 2.5.0
|
1358 |
+
*
|
1359 |
+
* @return string
|
1360 |
+
*/
|
1361 |
+
private function get_temporary_duplicate_admin_notice_string(
|
1362 |
+
$site_urls,
|
1363 |
+
$product_titles,
|
1364 |
+
$module_label
|
1365 |
+
) {
|
1366 |
+
$this->_logger->entrance();
|
1367 |
+
|
1368 |
+
$temporary_duplicate_end_date = $this->get_temporary_duplicate_expiration_timestamp();
|
1369 |
+
$temporary_duplicate_end_date = date( 'M j, Y', $temporary_duplicate_end_date );
|
1370 |
+
|
1371 |
+
$current_url = Freemius::get_unfiltered_site_url();
|
1372 |
+
$current_site_link = sprintf(
|
1373 |
+
'<b><a href="%s" target="_blank">%s</a></b>',
|
1374 |
+
$current_url,
|
1375 |
+
fs_strip_url_protocol( $current_url )
|
1376 |
+
);
|
1377 |
+
|
1378 |
+
$total_sites = count( $site_urls );
|
1379 |
+
$sites_list = '';
|
1380 |
+
|
1381 |
+
$total_products = count( $product_titles );
|
1382 |
+
$products_list = '';
|
1383 |
+
|
1384 |
+
if ( $total_sites > 1 ) {
|
1385 |
+
foreach ( $site_urls as $site_url ) {
|
1386 |
+
$sites_list .= sprintf(
|
1387 |
+
'<li><a href="%s" target="_blank">%s</a></li>',
|
1388 |
+
$site_url,
|
1389 |
+
fs_strip_url_protocol( $site_url )
|
1390 |
+
);
|
1391 |
+
}
|
1392 |
+
|
1393 |
+
$sites_list = '<ol class="fs-sites-list">' . $sites_list . '</ol>';
|
1394 |
+
}
|
1395 |
+
|
1396 |
+
if ( $total_products > 1 ) {
|
1397 |
+
foreach ( $product_titles as $product_title ) {
|
1398 |
+
$products_list .= sprintf( '<li>%s</li>', $product_title );
|
1399 |
+
}
|
1400 |
+
|
1401 |
+
$products_list = '<ol>' . $products_list . '</ol>';
|
1402 |
+
}
|
1403 |
+
|
1404 |
+
return sprintf(
|
1405 |
+
sprintf(
|
1406 |
+
'<div>%s</div>',
|
1407 |
+
( 1 === $total_sites ?
|
1408 |
+
sprintf( '<p>%s</p>', fs_esc_html_inline( 'You marked this website, %s, as a temporary duplicate of %s.', 'temporary-duplicate-message' ) ) :
|
1409 |
+
sprintf( '<p>%s:</p>', fs_esc_html_inline( 'You marked this website, %s, as a temporary duplicate of these sites', 'temporary-duplicate-of-sites-message' ) ) . '%s' )
|
1410 |
+
) . '%s',
|
1411 |
+
$current_site_link,
|
1412 |
+
( 1 === $total_sites ?
|
1413 |
+
sprintf(
|
1414 |
+
'<b><a href="%s" target="_blank">%s</a></b>',
|
1415 |
+
$site_urls[0],
|
1416 |
+
fs_strip_url_protocol( $site_urls[0] )
|
1417 |
+
) :
|
1418 |
+
$sites_list ),
|
1419 |
+
sprintf(
|
1420 |
+
'<div class="fs-clone-resolution-options-container fs-duplicate-site-options" data-ajax-url="%s" data-blog-id="' . get_current_blog_id() . '"><p>%s</p>%s<p>%s</p></div>',
|
1421 |
+
esc_attr( admin_url( 'admin-ajax.php?_fs_network_admin=false', 'relative' ) ),
|
1422 |
+
sprintf(
|
1423 |
+
fs_esc_html_inline( "%s automatic security & feature updates and paid functionality will keep working without interruptions until %s (or when your license expires, whatever comes first).", 'duplicate-site-confirmation-message' ),
|
1424 |
+
( 1 === $total_products ?
|
1425 |
+
sprintf(
|
1426 |
+
fs_esc_html_x_inline( "The %s's", '"The <product_label>", e.g.: "The plugin"', 'the-product-x'),
|
1427 |
+
"<strong>{$module_label}</strong>"
|
1428 |
+
) :
|
1429 |
+
fs_esc_html_inline( "The following products'", 'the-following-products' ) ),
|
1430 |
+
sprintf( '<strong>%s</strong>', $temporary_duplicate_end_date )
|
1431 |
+
),
|
1432 |
+
( 1 === $total_products ?
|
1433 |
+
'' :
|
1434 |
+
sprintf( '<div>%s</div>', $products_list )
|
1435 |
+
),
|
1436 |
+
sprintf(
|
1437 |
+
fs_esc_html_inline( 'If this is a long term duplicate, to keep automatic updates and paid functionality after %s, please %s.', 'duplicate-site-message' ),
|
1438 |
+
sprintf( '<strong>%s</strong>', $temporary_duplicate_end_date),
|
1439 |
+
sprintf( '<a href="#" id="fs_temporary_duplicate_license_activation_link" data-clone-action="temporary_duplicate_license_activation">%s</a>', fs_esc_html_inline( 'activate a license here', 'activate-license-here' ) )
|
1440 |
+
)
|
1441 |
+
)
|
1442 |
+
);
|
1443 |
+
}
|
1444 |
+
|
1445 |
+
/**
|
1446 |
+
* Determines if the temporary duplicate mode has already expired.
|
1447 |
+
*
|
1448 |
+
* @return bool
|
1449 |
+
*/
|
1450 |
+
function has_temporary_duplicate_mode_expired() {
|
1451 |
+
$temporary_duplicate_mode_start_timestamp = $this->was_temporary_duplicate_mode_selected() ?
|
1452 |
+
$this->get_option( 'temporary_duplicate_mode_selection_timestamp', true ) :
|
1453 |
+
$this->get_clone_identification_timestamp();
|
1454 |
+
|
1455 |
+
if ( ! is_numeric( $temporary_duplicate_mode_start_timestamp ) ) {
|
1456 |
+
return false;
|
1457 |
+
}
|
1458 |
+
|
1459 |
+
return ( time() > ( $temporary_duplicate_mode_start_timestamp + self::TEMPORARY_DUPLICATE_PERIOD ) );
|
1460 |
+
}
|
1461 |
+
|
1462 |
+
/**
|
1463 |
+
* Determines if the logged-in WordPress user manually selected the temporary duplicate mode for the site.
|
1464 |
+
*
|
1465 |
+
* @return bool
|
1466 |
+
*/
|
1467 |
+
function was_temporary_duplicate_mode_selected() {
|
1468 |
+
return is_numeric( $this->temporary_duplicate_mode_selection_timestamp );
|
1469 |
+
}
|
1470 |
+
|
1471 |
+
/**
|
1472 |
+
* Stores the time when the logged-in WordPress user selected the temporary duplicate mode for the site.
|
1473 |
+
*/
|
1474 |
+
private function store_temporary_duplicate_timestamp() {
|
1475 |
+
$this->temporary_duplicate_mode_selection_timestamp = time();
|
1476 |
+
}
|
1477 |
+
|
1478 |
+
/**
|
1479 |
+
* Removes the notice that is shown when the logged-in WordPress user has selected the temporary duplicate mode for the site.
|
1480 |
+
*
|
1481 |
+
* @param bool $store
|
1482 |
+
*/
|
1483 |
+
function remove_clone_resolution_options_notice( $store = true ) {
|
1484 |
+
$this->_notices->remove_sticky( 'clone_resolution_options_notice', true, $store );
|
1485 |
+
}
|
1486 |
+
|
1487 |
+
/**
|
1488 |
+
* Removes the notice that is shown when the logged-in WordPress user has selected the temporary duplicate mode for the site.
|
1489 |
+
*
|
1490 |
+
* @param bool $store
|
1491 |
+
*/
|
1492 |
+
function remove_temporary_duplicate_notice( $store = true ) {
|
1493 |
+
$this->_notices->remove_sticky( 'temporary_duplicate_notice', true, $store );
|
1494 |
+
}
|
1495 |
+
|
1496 |
+
/**
|
1497 |
+
* Determines if the manual clone resolution options notice is currently being shown.
|
1498 |
+
*
|
1499 |
+
* @return bool
|
1500 |
+
*/
|
1501 |
+
function is_clone_resolution_options_notice_shown() {
|
1502 |
+
return $this->_notices->has_sticky( 'clone_resolution_options_notice', true );
|
1503 |
+
}
|
1504 |
+
|
1505 |
+
/**
|
1506 |
+
* Determines if the temporary duplicate notice is currently being shown.
|
1507 |
+
*
|
1508 |
+
* @return bool
|
1509 |
+
*/
|
1510 |
+
function is_temporary_duplicate_notice_shown() {
|
1511 |
+
return $this->_notices->has_sticky( 'temporary_duplicate_notice', true );
|
1512 |
+
}
|
1513 |
+
|
1514 |
+
/**
|
1515 |
+
* Determines if a site was marked as a temporary duplicate and if it's still a temporary duplicate.
|
1516 |
+
*
|
1517 |
+
* @return bool
|
1518 |
+
*/
|
1519 |
+
function is_temporary_duplicate_by_blog_id( $blog_id ) {
|
1520 |
+
$timestamp = $this->get_option( 'temporary_duplicate_mode_selection_timestamp', false, $blog_id );
|
1521 |
+
|
1522 |
+
return (
|
1523 |
+
is_numeric( $timestamp ) &&
|
1524 |
+
time() < ( $timestamp + self::TEMPORARY_DUPLICATE_PERIOD )
|
1525 |
+
);
|
1526 |
+
}
|
1527 |
+
|
1528 |
+
/**
|
1529 |
+
* Determines the last time the temporary duplicate notice was shown.
|
1530 |
+
*
|
1531 |
+
* @return int|null
|
1532 |
+
*/
|
1533 |
+
function last_time_temporary_duplicate_notice_was_shown() {
|
1534 |
+
return $this->temporary_duplicate_notice_shown_timestamp;
|
1535 |
+
}
|
1536 |
+
|
1537 |
+
/**
|
1538 |
+
* Clears the time that has been stored when the temporary duplicate notice was shown.
|
1539 |
+
*/
|
1540 |
+
function clear_temporary_duplicate_notice_shown_timestamp() {
|
1541 |
+
unset( $this->temporary_duplicate_notice_shown_timestamp );
|
1542 |
+
}
|
1543 |
+
|
1544 |
+
/**
|
1545 |
+
* Adds a temporary duplicate notice that provides the logged-in WordPress user with an option to activate a license for the site.
|
1546 |
+
*
|
1547 |
+
* @param number[] $product_ids
|
1548 |
+
* @param string $message
|
1549 |
+
* @param string|null $plugin_title
|
1550 |
+
*/
|
1551 |
+
function add_temporary_duplicate_sticky_notice(
|
1552 |
+
$product_ids,
|
1553 |
+
$message,
|
1554 |
+
$plugin_title = null
|
1555 |
+
) {
|
1556 |
+
$this->_logger->entrance();
|
1557 |
+
|
1558 |
+
$this->_notices->add_sticky(
|
1559 |
+
$message,
|
1560 |
+
'temporary_duplicate_notice',
|
1561 |
+
'',
|
1562 |
+
'promotion',
|
1563 |
+
true,
|
1564 |
+
null,
|
1565 |
+
$plugin_title,
|
1566 |
+
true,
|
1567 |
+
true,
|
1568 |
+
array(
|
1569 |
+
'product_ids' => $product_ids,
|
1570 |
+
'blog_id' => get_current_blog_id()
|
1571 |
+
)
|
1572 |
+
);
|
1573 |
+
|
1574 |
+
$this->temporary_duplicate_notice_shown_timestamp = time();
|
1575 |
+
}
|
1576 |
+
|
1577 |
+
#endregion
|
1578 |
+
|
1579 |
+
/**
|
1580 |
+
* @author Leo Fajardo
|
1581 |
+
* @since 2.5.0
|
1582 |
+
*
|
1583 |
+
* @param string $key
|
1584 |
+
*
|
1585 |
+
* @return bool
|
1586 |
+
*/
|
1587 |
+
private function should_use_network_storage( $key ) {
|
1588 |
+
return ( 'new_blog_install_map' === $key );
|
1589 |
+
}
|
1590 |
+
|
1591 |
+
/**
|
1592 |
+
* @param string $key
|
1593 |
+
* @param number|null $blog_id
|
1594 |
+
*
|
1595 |
+
* @return FS_Option_Manager
|
1596 |
+
*/
|
1597 |
+
private function get_storage( $key, $blog_id = null ) {
|
1598 |
+
if ( is_numeric( $blog_id ) ){
|
1599 |
+
return FS_Option_Manager::get_manager( WP_FS___OPTION_PREFIX . self::OPTION_MANAGER_NAME, true, $blog_id );
|
1600 |
+
}
|
1601 |
+
|
1602 |
+
return $this->should_use_network_storage( $key ) ?
|
1603 |
+
$this->_network_storage :
|
1604 |
+
$this->_storage;
|
1605 |
+
}
|
1606 |
+
|
1607 |
+
/**
|
1608 |
+
* @param string $name
|
1609 |
+
* @param bool $flush
|
1610 |
+
* @param number|null $blog_id
|
1611 |
+
*
|
1612 |
+
* @return mixed
|
1613 |
+
*/
|
1614 |
+
private function get_option( $name, $flush = false, $blog_id = null ) {
|
1615 |
+
return $this->get_storage( $name, $blog_id )->get_option( $name, null, $flush );
|
1616 |
+
}
|
1617 |
+
|
1618 |
+
#--------------------------------------------------------------------------------
|
1619 |
+
#region Magic methods
|
1620 |
+
#--------------------------------------------------------------------------------
|
1621 |
+
|
1622 |
+
/**
|
1623 |
+
* @param string $name
|
1624 |
+
* @param int|string $value
|
1625 |
+
*/
|
1626 |
+
function __set( $name, $value ) {
|
1627 |
+
$this->get_storage( $name )->set_option( $name, $value, true );
|
1628 |
+
}
|
1629 |
+
|
1630 |
+
/**
|
1631 |
+
* @param string $name
|
1632 |
+
*
|
1633 |
+
* @return bool
|
1634 |
+
*/
|
1635 |
+
function __isset( $name ) {
|
1636 |
+
return $this->get_storage( $name )->has_option( $name, true );
|
1637 |
+
}
|
1638 |
+
|
1639 |
+
/**
|
1640 |
+
* @param string $name
|
1641 |
+
*/
|
1642 |
+
function __unset( $name ) {
|
1643 |
+
$this->get_storage( $name )->unset_option( $name, true );
|
1644 |
+
}
|
1645 |
+
|
1646 |
+
/**
|
1647 |
+
* @param string $name
|
1648 |
+
*
|
1649 |
+
* @return null|int|string
|
1650 |
+
*/
|
1651 |
+
function __get( $name ) {
|
1652 |
+
return $this->get_option(
|
1653 |
+
$name,
|
1654 |
+
// Reload storage from DB when accessing request_handler_* options to avoid race conditions.
|
1655 |
+
fs_starts_with( $name, 'request_handler' )
|
1656 |
+
);
|
1657 |
+
}
|
1658 |
+
|
1659 |
+
#endregion
|
1660 |
+
}
|
freemius/includes/managers/class-fs-key-value-storage.php
CHANGED
@@ -298,6 +298,7 @@
|
|
298 |
return $this->get( $k, null );
|
299 |
}
|
300 |
|
|
|
301 |
function offsetSet( $k, $v ) {
|
302 |
if ( is_null( $k ) ) {
|
303 |
throw new Exception( 'Can\'t append value to request params.' );
|
@@ -306,14 +307,17 @@
|
|
306 |
}
|
307 |
}
|
308 |
|
|
|
309 |
function offsetExists( $k ) {
|
310 |
return array_key_exists( $k, $this->_data );
|
311 |
}
|
312 |
|
|
|
313 |
function offsetUnset( $k ) {
|
314 |
unset( $this->$k );
|
315 |
}
|
316 |
|
|
|
317 |
function offsetGet( $k ) {
|
318 |
return $this->get( $k, null );
|
319 |
}
|
@@ -325,6 +329,7 @@
|
|
325 |
* @link http://php.net/manual/en/iterator.current.php
|
326 |
* @return mixed Can return any type.
|
327 |
*/
|
|
|
328 |
public function current() {
|
329 |
return current( $this->_data );
|
330 |
}
|
@@ -336,6 +341,7 @@
|
|
336 |
* @link http://php.net/manual/en/iterator.next.php
|
337 |
* @return void Any returned value is ignored.
|
338 |
*/
|
|
|
339 |
public function next() {
|
340 |
next( $this->_data );
|
341 |
}
|
@@ -347,6 +353,7 @@
|
|
347 |
* @link http://php.net/manual/en/iterator.key.php
|
348 |
* @return mixed scalar on success, or null on failure.
|
349 |
*/
|
|
|
350 |
public function key() {
|
351 |
return key( $this->_data );
|
352 |
}
|
@@ -359,6 +366,7 @@
|
|
359 |
* @return boolean The return value will be casted to boolean and then evaluated.
|
360 |
* Returns true on success or false on failure.
|
361 |
*/
|
|
|
362 |
public function valid() {
|
363 |
$key = key( $this->_data );
|
364 |
|
@@ -372,6 +380,7 @@
|
|
372 |
* @link http://php.net/manual/en/iterator.rewind.php
|
373 |
* @return void Any returned value is ignored.
|
374 |
*/
|
|
|
375 |
public function rewind() {
|
376 |
reset( $this->_data );
|
377 |
}
|
@@ -386,6 +395,7 @@
|
|
386 |
* <p>
|
387 |
* The return value is cast to an integer.
|
388 |
*/
|
|
|
389 |
public function count() {
|
390 |
return count( $this->_data );
|
391 |
}
|
298 |
return $this->get( $k, null );
|
299 |
}
|
300 |
|
301 |
+
#[ReturnTypeWillChange]
|
302 |
function offsetSet( $k, $v ) {
|
303 |
if ( is_null( $k ) ) {
|
304 |
throw new Exception( 'Can\'t append value to request params.' );
|
307 |
}
|
308 |
}
|
309 |
|
310 |
+
#[ReturnTypeWillChange]
|
311 |
function offsetExists( $k ) {
|
312 |
return array_key_exists( $k, $this->_data );
|
313 |
}
|
314 |
|
315 |
+
#[ReturnTypeWillChange]
|
316 |
function offsetUnset( $k ) {
|
317 |
unset( $this->$k );
|
318 |
}
|
319 |
|
320 |
+
#[ReturnTypeWillChange]
|
321 |
function offsetGet( $k ) {
|
322 |
return $this->get( $k, null );
|
323 |
}
|
329 |
* @link http://php.net/manual/en/iterator.current.php
|
330 |
* @return mixed Can return any type.
|
331 |
*/
|
332 |
+
#[ReturnTypeWillChange]
|
333 |
public function current() {
|
334 |
return current( $this->_data );
|
335 |
}
|
341 |
* @link http://php.net/manual/en/iterator.next.php
|
342 |
* @return void Any returned value is ignored.
|
343 |
*/
|
344 |
+
#[ReturnTypeWillChange]
|
345 |
public function next() {
|
346 |
next( $this->_data );
|
347 |
}
|
353 |
* @link http://php.net/manual/en/iterator.key.php
|
354 |
* @return mixed scalar on success, or null on failure.
|
355 |
*/
|
356 |
+
#[ReturnTypeWillChange]
|
357 |
public function key() {
|
358 |
return key( $this->_data );
|
359 |
}
|
366 |
* @return boolean The return value will be casted to boolean and then evaluated.
|
367 |
* Returns true on success or false on failure.
|
368 |
*/
|
369 |
+
#[ReturnTypeWillChange]
|
370 |
public function valid() {
|
371 |
$key = key( $this->_data );
|
372 |
|
380 |
* @link http://php.net/manual/en/iterator.rewind.php
|
381 |
* @return void Any returned value is ignored.
|
382 |
*/
|
383 |
+
#[ReturnTypeWillChange]
|
384 |
public function rewind() {
|
385 |
reset( $this->_data );
|
386 |
}
|
395 |
* <p>
|
396 |
* The return value is cast to an integer.
|
397 |
*/
|
398 |
+
#[ReturnTypeWillChange]
|
399 |
public function count() {
|
400 |
return count( $this->_data );
|
401 |
}
|
freemius/includes/managers/class-fs-option-manager.php
CHANGED
@@ -11,14 +11,11 @@
|
|
11 |
}
|
12 |
|
13 |
/**
|
14 |
-
*
|
15 |
-
* layer
|
16 |
-
* layer
|
17 |
-
* layer 1: Database (options table). All options stored as one option record in the DB to reduce number of DB
|
18 |
-
* queries.
|
19 |
*
|
20 |
-
* If load() is not explicitly called, starts as empty manager. Same thing about saving the data - you have to
|
21 |
-
* explicitly call store().
|
22 |
*
|
23 |
* Class Freemius_Option_Manager
|
24 |
*/
|
@@ -157,59 +154,33 @@
|
|
157 |
function load( $flush = false ) {
|
158 |
$this->_logger->entrance();
|
159 |
|
160 |
-
$
|
161 |
-
|
162 |
-
|
163 |
-
if ( isset( $this->_options ) ) {
|
164 |
-
// Clear prev options.
|
165 |
-
$this->clear();
|
166 |
-
}
|
167 |
-
|
168 |
-
$cache_group = $this->get_cache_group();
|
169 |
-
|
170 |
-
if ( WP_FS__DEBUG_SDK ) {
|
171 |
-
|
172 |
-
// Don't use cache layer in DEBUG mode.
|
173 |
-
$load_options = empty( $this->_options );
|
174 |
-
|
175 |
-
} else {
|
176 |
-
|
177 |
-
$this->_options = wp_cache_get(
|
178 |
-
$option_name,
|
179 |
-
$cache_group
|
180 |
-
);
|
181 |
|
182 |
-
|
183 |
-
|
|
|
|
|
184 |
|
185 |
-
|
186 |
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
}
|
195 |
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
|
200 |
// $this->_logger->info('get_option = ' . var_export($this->_options, true));
|
201 |
|
202 |
-
|
203 |
-
|
204 |
-
}
|
205 |
-
|
206 |
-
$cached = false;
|
207 |
-
}
|
208 |
-
|
209 |
-
if ( ! WP_FS__DEBUG_SDK && ! $cached ) {
|
210 |
-
// Set non encoded cache.
|
211 |
-
wp_cache_set( $option_name, $this->_options, $cache_group );
|
212 |
-
}
|
213 |
}
|
214 |
}
|
215 |
|
@@ -272,10 +243,15 @@
|
|
272 |
* @since 1.0.6
|
273 |
*
|
274 |
* @param string $option
|
|
|
275 |
*
|
276 |
* @return bool
|
277 |
*/
|
278 |
-
function has_option( $option ) {
|
|
|
|
|
|
|
|
|
279 |
return array_key_exists( $option, $this->_options );
|
280 |
}
|
281 |
|
@@ -285,14 +261,15 @@
|
|
285 |
*
|
286 |
* @param string $option
|
287 |
* @param mixed $default
|
|
|
288 |
*
|
289 |
* @return mixed
|
290 |
*/
|
291 |
-
function get_option( $option, $default = null ) {
|
292 |
$this->_logger->entrance( 'option = ' . $option );
|
293 |
|
294 |
-
if ( ! $this->is_loaded() ) {
|
295 |
-
$this->load();
|
296 |
}
|
297 |
|
298 |
if ( is_array( $this->_options ) ) {
|
@@ -310,7 +287,7 @@
|
|
310 |
/**
|
311 |
* If it's an object, return a clone of the object, otherwise,
|
312 |
* external changes of the object will actually change the value
|
313 |
-
* of the object in the
|
314 |
* behaviour and data integrity when a store() call is triggered.
|
315 |
*
|
316 |
* Example:
|
@@ -436,10 +413,6 @@
|
|
436 |
} else {
|
437 |
update_option( $option_name, $this->_options, $this->_autoload );
|
438 |
}
|
439 |
-
|
440 |
-
if ( ! WP_FS__DEBUG_SDK ) {
|
441 |
-
wp_cache_set( $option_name, $this->_options, $this->get_cache_group() );
|
442 |
-
}
|
443 |
}
|
444 |
|
445 |
/**
|
@@ -499,23 +472,5 @@
|
|
499 |
return $this->_id;
|
500 |
}
|
501 |
|
502 |
-
/**
|
503 |
-
* @author Vova Feldman (@svovaf)
|
504 |
-
* @since 2.0.0
|
505 |
-
*
|
506 |
-
* @return string
|
507 |
-
*/
|
508 |
-
private function get_cache_group() {
|
509 |
-
$group = WP_FS__SLUG;
|
510 |
-
|
511 |
-
if ( $this->_is_network_storage ) {
|
512 |
-
$group .= '_ms';
|
513 |
-
} else if ( $this->_blog_id > 0 ) {
|
514 |
-
$group .= "_s{$this->_blog_id}";
|
515 |
-
}
|
516 |
-
|
517 |
-
return $group;
|
518 |
-
}
|
519 |
-
|
520 |
#endregion
|
521 |
}
|
11 |
}
|
12 |
|
13 |
/**
|
14 |
+
* 2-layer lazy options manager.
|
15 |
+
* layer 2: Memory
|
16 |
+
* layer 1: Database (options table). All options stored as one option record in the DB to reduce number of DB queries.
|
|
|
|
|
17 |
*
|
18 |
+
* If load() is not explicitly called, starts as empty manager. Same thing about saving the data - you have to explicitly call store().
|
|
|
19 |
*
|
20 |
* Class Freemius_Option_Manager
|
21 |
*/
|
154 |
function load( $flush = false ) {
|
155 |
$this->_logger->entrance();
|
156 |
|
157 |
+
if ( ! $flush && isset( $this->_options ) ) {
|
158 |
+
return;
|
159 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
|
161 |
+
if ( isset( $this->_options ) ) {
|
162 |
+
// Clear prev options.
|
163 |
+
$this->clear();
|
164 |
+
}
|
165 |
|
166 |
+
$option_name = $this->get_option_manager_name();
|
167 |
|
168 |
+
if ( $this->_is_network_storage ) {
|
169 |
+
$this->_options = get_site_option( $option_name );
|
170 |
+
} else if ( $this->_blog_id > 0 ) {
|
171 |
+
$this->_options = get_blog_option( $this->_blog_id, $option_name );
|
172 |
+
} else {
|
173 |
+
$this->_options = get_option( $option_name );
|
174 |
+
}
|
|
|
175 |
|
176 |
+
if ( is_string( $this->_options ) ) {
|
177 |
+
$this->_options = json_decode( $this->_options );
|
178 |
+
}
|
179 |
|
180 |
// $this->_logger->info('get_option = ' . var_export($this->_options, true));
|
181 |
|
182 |
+
if ( false === $this->_options ) {
|
183 |
+
$this->clear();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
}
|
185 |
}
|
186 |
|
243 |
* @since 1.0.6
|
244 |
*
|
245 |
* @param string $option
|
246 |
+
* @param bool $flush
|
247 |
*
|
248 |
* @return bool
|
249 |
*/
|
250 |
+
function has_option( $option, $flush = false ) {
|
251 |
+
if ( ! $this->is_loaded() || $flush ) {
|
252 |
+
$this->load( $flush );
|
253 |
+
}
|
254 |
+
|
255 |
return array_key_exists( $option, $this->_options );
|
256 |
}
|
257 |
|
261 |
*
|
262 |
* @param string $option
|
263 |
* @param mixed $default
|
264 |
+
* @param bool $flush
|
265 |
*
|
266 |
* @return mixed
|
267 |
*/
|
268 |
+
function get_option( $option, $default = null, $flush = false ) {
|
269 |
$this->_logger->entrance( 'option = ' . $option );
|
270 |
|
271 |
+
if ( ! $this->is_loaded() || $flush ) {
|
272 |
+
$this->load( $flush );
|
273 |
}
|
274 |
|
275 |
if ( is_array( $this->_options ) ) {
|
287 |
/**
|
288 |
* If it's an object, return a clone of the object, otherwise,
|
289 |
* external changes of the object will actually change the value
|
290 |
+
* of the object in the option manager which may lead to an unexpected
|
291 |
* behaviour and data integrity when a store() call is triggered.
|
292 |
*
|
293 |
* Example:
|
413 |
} else {
|
414 |
update_option( $option_name, $this->_options, $this->_autoload );
|
415 |
}
|
|
|
|
|
|
|
|
|
416 |
}
|
417 |
|
418 |
/**
|
472 |
return $this->_id;
|
473 |
}
|
474 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
475 |
#endregion
|
476 |
}
|
freemius/includes/managers/class-fs-permission-manager.php
ADDED
@@ -0,0 +1,698 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2022, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 2.5.1
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* This class is responsible for managing the user permissions.
|
15 |
+
*
|
16 |
+
* @author Vova Feldman (@svovaf)
|
17 |
+
* @since 2.5.1
|
18 |
+
*/
|
19 |
+
class FS_Permission_Manager {
|
20 |
+
/**
|
21 |
+
* @var Freemius
|
22 |
+
*/
|
23 |
+
private $_fs;
|
24 |
+
/**
|
25 |
+
* @var FS_Storage
|
26 |
+
*/
|
27 |
+
private $_storage;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @var array<number,self>
|
31 |
+
*/
|
32 |
+
private static $_instances = array();
|
33 |
+
|
34 |
+
const PERMISSION_USER = 'user';
|
35 |
+
const PERMISSION_SITE = 'site';
|
36 |
+
const PERMISSION_EVENTS = 'events';
|
37 |
+
const PERMISSION_ESSENTIALS = 'essentials';
|
38 |
+
const PERMISSION_DIAGNOSTIC = 'diagnostic';
|
39 |
+
const PERMISSION_EXTENSIONS = 'extensions';
|
40 |
+
const PERMISSION_NEWSLETTER = 'newsletter';
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @param Freemius $fs
|
44 |
+
*
|
45 |
+
* @return self
|
46 |
+
*/
|
47 |
+
static function instance( Freemius $fs ) {
|
48 |
+
$id = $fs->get_id();
|
49 |
+
|
50 |
+
if ( ! isset( self::$_instances[ $id ] ) ) {
|
51 |
+
self::$_instances[ $id ] = new self( $fs );
|
52 |
+
}
|
53 |
+
|
54 |
+
return self::$_instances[ $id ];
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @param Freemius $fs
|
59 |
+
*/
|
60 |
+
protected function __construct( Freemius $fs ) {
|
61 |
+
$this->_fs = $fs;
|
62 |
+
$this->_storage = FS_Storage::instance( $fs->get_module_type(), $fs->get_slug() );
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* @return string[]
|
67 |
+
*/
|
68 |
+
static function get_all_permission_ids() {
|
69 |
+
return array(
|
70 |
+
self::PERMISSION_USER,
|
71 |
+
self::PERMISSION_SITE,
|
72 |
+
self::PERMISSION_EVENTS,
|
73 |
+
self::PERMISSION_ESSENTIALS,
|
74 |
+
self::PERMISSION_DIAGNOSTIC,
|
75 |
+
self::PERMISSION_EXTENSIONS,
|
76 |
+
self::PERMISSION_NEWSLETTER,
|
77 |
+
);
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @return string[]
|
82 |
+
*/
|
83 |
+
static function get_api_managed_permission_ids() {
|
84 |
+
return array(
|
85 |
+
self::PERMISSION_USER,
|
86 |
+
self::PERMISSION_SITE,
|
87 |
+
self::PERMISSION_EXTENSIONS,
|
88 |
+
);
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @param string $permission
|
93 |
+
*
|
94 |
+
* @return bool
|
95 |
+
*/
|
96 |
+
static function is_supported_permission( $permission ) {
|
97 |
+
return in_array( $permission, self::get_all_permission_ids() );
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* @param bool $is_license_activation
|
102 |
+
* @param array[] $extra_permissions
|
103 |
+
*
|
104 |
+
* @return array[]
|
105 |
+
*/
|
106 |
+
function get_permissions( $is_license_activation, array $extra_permissions = array() ) {
|
107 |
+
return $is_license_activation ?
|
108 |
+
$this->get_license_activation_permissions( $extra_permissions ) :
|
109 |
+
$this->get_opt_in_permissions( $extra_permissions );
|
110 |
+
}
|
111 |
+
|
112 |
+
#--------------------------------------------------------------------------------
|
113 |
+
#region Opt-In Permissions
|
114 |
+
#--------------------------------------------------------------------------------
|
115 |
+
|
116 |
+
/**
|
117 |
+
* @param array[] $extra_permissions
|
118 |
+
*
|
119 |
+
* @return array[]
|
120 |
+
*/
|
121 |
+
function get_opt_in_permissions(
|
122 |
+
array $extra_permissions = array(),
|
123 |
+
$load_default_from_storage = false,
|
124 |
+
$is_optional = false
|
125 |
+
) {
|
126 |
+
$permissions = array_merge(
|
127 |
+
$this->get_opt_in_required_permissions( $load_default_from_storage ),
|
128 |
+
$this->get_opt_in_optional_permissions( $load_default_from_storage, $is_optional ),
|
129 |
+
$extra_permissions
|
130 |
+
);
|
131 |
+
|
132 |
+
return $this->get_sorted_permissions_by_priority( $permissions );
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* @param bool $load_default_from_storage
|
137 |
+
*
|
138 |
+
* @return array[]
|
139 |
+
*/
|
140 |
+
function get_opt_in_required_permissions( $load_default_from_storage = false ) {
|
141 |
+
return array( $this->get_user_permission( $load_default_from_storage ) );
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* @param bool $load_default_from_storage
|
146 |
+
* @param bool $is_optional
|
147 |
+
*
|
148 |
+
* @return array[]
|
149 |
+
*/
|
150 |
+
function get_opt_in_optional_permissions(
|
151 |
+
$load_default_from_storage = false,
|
152 |
+
$is_optional = false
|
153 |
+
) {
|
154 |
+
return array_merge(
|
155 |
+
$this->get_opt_in_diagnostic_permissions( $load_default_from_storage, $is_optional ),
|
156 |
+
array( $this->get_extensions_permission(
|
157 |
+
false,
|
158 |
+
false,
|
159 |
+
$load_default_from_storage
|
160 |
+
) )
|
161 |
+
);
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @param bool $load_default_from_storage
|
166 |
+
* @param bool $is_optional
|
167 |
+
*
|
168 |
+
* @return array[]
|
169 |
+
*/
|
170 |
+
function get_opt_in_diagnostic_permissions(
|
171 |
+
$load_default_from_storage = false,
|
172 |
+
$is_optional = false
|
173 |
+
) {
|
174 |
+
// Alias.
|
175 |
+
$fs = $this->_fs;
|
176 |
+
|
177 |
+
$permissions = array();
|
178 |
+
|
179 |
+
$permissions[] = $this->get_permission(
|
180 |
+
self::PERMISSION_SITE,
|
181 |
+
'admin-links',
|
182 |
+
$fs->get_text_inline( 'View Basic Website Info', 'permissions-site' ),
|
183 |
+
$fs->get_text_inline( 'Homepage URL & title, WP & PHP versions, and site language', 'permissions-site_desc' ),
|
184 |
+
sprintf(
|
185 |
+
/* translators: %s: 'Plugin' or 'Theme' */
|
186 |
+
$fs->get_text_inline( 'To provide additional functionality that\'s relevant to your website, avoid WordPress or PHP version incompatibilities that can break your website, and recognize which languages & regions the %s should be translated and tailored to.', 'permissions-site_tooltip' ),
|
187 |
+
$fs->get_module_label( true )
|
188 |
+
),
|
189 |
+
10,
|
190 |
+
$is_optional,
|
191 |
+
true,
|
192 |
+
$load_default_from_storage
|
193 |
+
);
|
194 |
+
|
195 |
+
$permissions[] = $this->get_permission(
|
196 |
+
self::PERMISSION_EVENTS,
|
197 |
+
'admin-' . ( $fs->is_plugin() ? 'plugins' : 'appearance' ),
|
198 |
+
sprintf( $fs->get_text_inline( 'View Basic %s Info', 'permissions-events' ), $fs->get_module_label() ),
|
199 |
+
sprintf(
|
200 |
+
/* translators: %s: 'Plugin' or 'Theme' */
|
201 |
+
$fs->get_text_inline( 'Current %s & SDK versions, and if active or uninstalled', 'permissions-events_desc' ),
|
202 |
+
$fs->get_module_label( true )
|
203 |
+
),
|
204 |
+
'',
|
205 |
+
20,
|
206 |
+
$is_optional,
|
207 |
+
true,
|
208 |
+
$load_default_from_storage
|
209 |
+
);
|
210 |
+
|
211 |
+
return $permissions;
|
212 |
+
}
|
213 |
+
|
214 |
+
#endregion
|
215 |
+
|
216 |
+
#--------------------------------------------------------------------------------
|
217 |
+
#region License Activation Permissions
|
218 |
+
#--------------------------------------------------------------------------------
|
219 |
+
|
220 |
+
/**
|
221 |
+
* @param array[] $extra_permissions
|
222 |
+
*
|
223 |
+
* @return array[]
|
224 |
+
*/
|
225 |
+
function get_license_activation_permissions(
|
226 |
+
array $extra_permissions = array(),
|
227 |
+
$include_optional_label = true
|
228 |
+
) {
|
229 |
+
$permissions = array_merge(
|
230 |
+
$this->get_license_required_permissions(),
|
231 |
+
$this->get_license_optional_permissions( $include_optional_label ),
|
232 |
+
$extra_permissions
|
233 |
+
);
|
234 |
+
|
235 |
+
return $this->get_sorted_permissions_by_priority( $permissions );
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* @param bool $load_default_from_storage
|
240 |
+
*
|
241 |
+
* @return array[]
|
242 |
+
*/
|
243 |
+
function get_license_required_permissions( $load_default_from_storage = false ) {
|
244 |
+
// Alias.
|
245 |
+
$fs = $this->_fs;
|
246 |
+
|
247 |
+
$permissions = array();
|
248 |
+
|
249 |
+
$permissions[] = $this->get_permission(
|
250 |
+
self::PERMISSION_ESSENTIALS,
|
251 |
+
'admin-links',
|
252 |
+
$fs->get_text_inline( 'View License Essentials', 'permissions-essentials' ),
|
253 |
+
$fs->get_text_inline(
|
254 |
+
sprintf(
|
255 |
+
/* translators: %s: 'Plugin' or 'Theme' */
|
256 |
+
'Homepage URL, %s version, SDK version',
|
257 |
+
$fs->get_module_label()
|
258 |
+
),
|
259 |
+
'permissions-essentials_desc'
|
260 |
+
),
|
261 |
+
sprintf(
|
262 |
+
/* translators: %s: 'Plugin' or 'Theme' */
|
263 |
+
$fs->get_text_inline( 'To let you manage & control where the license is activated and ensure %s security & feature updates are only delivered to websites you authorize.', 'permissions-essentials_tooltip' ),
|
264 |
+
$fs->get_module_label( true )
|
265 |
+
),
|
266 |
+
10,
|
267 |
+
false,
|
268 |
+
true,
|
269 |
+
$load_default_from_storage
|
270 |
+
);
|
271 |
+
|
272 |
+
$permissions[] = $this->get_permission(
|
273 |
+
self::PERMISSION_EVENTS,
|
274 |
+
'admin-' . ( $fs->is_plugin() ? 'plugins' : 'appearance' ),
|
275 |
+
sprintf( $fs->get_text_inline( 'View %s State', 'permissions-events' ), $fs->get_module_label() ),
|
276 |
+
sprintf(
|
277 |
+
/* translators: %s: 'Plugin' or 'Theme' */
|
278 |
+
$fs->get_text_inline( 'Is active, deactivated, or uninstalled', 'permissions-events_desc-paid' ),
|
279 |
+
$fs->get_module_label( true )
|
280 |
+
),
|
281 |
+
sprintf( $fs->get_text_inline( 'So you can reuse the license when the %s is no longer active.', 'permissions-events_tooltip' ), $fs->get_module_label( true ) ),
|
282 |
+
20,
|
283 |
+
false,
|
284 |
+
true,
|
285 |
+
$load_default_from_storage
|
286 |
+
);
|
287 |
+
|
288 |
+
return $permissions;
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* @return array[]
|
293 |
+
*/
|
294 |
+
function get_license_optional_permissions(
|
295 |
+
$include_optional_label = false,
|
296 |
+
$load_default_from_storage = false
|
297 |
+
) {
|
298 |
+
return array(
|
299 |
+
$this->get_diagnostic_permission( $include_optional_label, $load_default_from_storage ),
|
300 |
+
$this->get_extensions_permission( true, $include_optional_label, $load_default_from_storage ),
|
301 |
+
);
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* @param bool $include_optional_label
|
306 |
+
* @param bool $load_default_from_storage
|
307 |
+
*
|
308 |
+
* @return array
|
309 |
+
*/
|
310 |
+
function get_diagnostic_permission(
|
311 |
+
$include_optional_label = false,
|
312 |
+
$load_default_from_storage = false
|
313 |
+
) {
|
314 |
+
return $this->get_permission(
|
315 |
+
self::PERMISSION_DIAGNOSTIC,
|
316 |
+
'wordpress-alt',
|
317 |
+
$this->_fs->get_text_inline( 'View Diagnostic Info', 'permissions-diagnostic' ) . ( $include_optional_label ? ' (' . $this->_fs->get_text_inline( 'optional' ) . ')' : '' ),
|
318 |
+
$this->_fs->get_text_inline( 'WordPress & PHP versions, site language & title', 'permissions-diagnostic_desc' ),
|
319 |
+
sprintf(
|
320 |
+
/* translators: %s: 'Plugin' or 'Theme' */
|
321 |
+
$this->_fs->get_text_inline( 'To avoid breaking your website due to WordPress or PHP version incompatibilities, and recognize which languages & regions the %s should be translated and tailored to.', 'permissions-diagnostic_tooltip' ),
|
322 |
+
$this->_fs->get_module_label( true )
|
323 |
+
),
|
324 |
+
25,
|
325 |
+
true,
|
326 |
+
true,
|
327 |
+
$load_default_from_storage
|
328 |
+
);
|
329 |
+
}
|
330 |
+
|
331 |
+
#endregion
|
332 |
+
|
333 |
+
#--------------------------------------------------------------------------------
|
334 |
+
#region Common Permissions
|
335 |
+
#--------------------------------------------------------------------------------
|
336 |
+
|
337 |
+
/**
|
338 |
+
* @param bool $is_license_activation
|
339 |
+
* @param bool $include_optional_label
|
340 |
+
* @param bool $load_default_from_storage
|
341 |
+
*
|
342 |
+
* @return array
|
343 |
+
*/
|
344 |
+
function get_extensions_permission(
|
345 |
+
$is_license_activation,
|
346 |
+
$include_optional_label = false,
|
347 |
+
$load_default_from_storage = false
|
348 |
+
) {
|
349 |
+
$is_on_by_default = ! $is_license_activation;
|
350 |
+
|
351 |
+
return $this->get_permission(
|
352 |
+
self::PERMISSION_EXTENSIONS,
|
353 |
+
'block-default',
|
354 |
+
$this->_fs->get_text_inline( 'View Plugins & Themes List', 'permissions-extensions' ) . ( $is_license_activation ? ( $include_optional_label ? ' (' . $this->_fs->get_text_inline( 'optional' ) . ')' : '' ) : '' ),
|
355 |
+
$this->_fs->get_text_inline( 'Names, slugs, versions, and if active or not', 'permissions-extensions_desc' ),
|
356 |
+
$this->_fs->get_text_inline( 'To ensure compatibility and avoid conflicts with your installed plugins and themes.', 'permissions-events_tooltip' ),
|
357 |
+
25,
|
358 |
+
true,
|
359 |
+
$is_on_by_default,
|
360 |
+
$load_default_from_storage
|
361 |
+
);
|
362 |
+
}
|
363 |
+
|
364 |
+
/**
|
365 |
+
* @param bool $load_default_from_storage
|
366 |
+
*
|
367 |
+
* @return array
|
368 |
+
*/
|
369 |
+
function get_user_permission( $load_default_from_storage = false ) {
|
370 |
+
return $this->get_permission(
|
371 |
+
self::PERMISSION_USER,
|
372 |
+
'admin-users',
|
373 |
+
$this->_fs->get_text_inline( 'View Basic Profile Info', 'permissions-profile' ),
|
374 |
+
$this->_fs->get_text_inline( 'Your WordPress user\'s: first & last name, and email address', 'permissions-profile_desc' ),
|
375 |
+
$this->_fs->get_text_inline( 'Never miss important updates, get security warnings before they become public knowledge, and receive notifications about special offers and awesome new features.', 'permissions-profile_tooltip' ),
|
376 |
+
5,
|
377 |
+
false,
|
378 |
+
true,
|
379 |
+
$load_default_from_storage
|
380 |
+
);
|
381 |
+
}
|
382 |
+
|
383 |
+
#endregion
|
384 |
+
|
385 |
+
#--------------------------------------------------------------------------------
|
386 |
+
#region Optional Permissions
|
387 |
+
#--------------------------------------------------------------------------------
|
388 |
+
|
389 |
+
/**
|
390 |
+
* @return array[]
|
391 |
+
*/
|
392 |
+
function get_newsletter_permission() {
|
393 |
+
return $this->get_permission(
|
394 |
+
self::PERMISSION_NEWSLETTER,
|
395 |
+
'email-alt',
|
396 |
+
$this->_fs->get_text_inline( 'Newsletter', 'permissions-newsletter' ),
|
397 |
+
$this->_fs->get_text_inline( 'Updates, announcements, marketing, no spam', 'permissions-newsletter_desc' ),
|
398 |
+
'',
|
399 |
+
15
|
400 |
+
);
|
401 |
+
}
|
402 |
+
|
403 |
+
#endregion
|
404 |
+
|
405 |
+
#--------------------------------------------------------------------------------
|
406 |
+
#region Permissions Storage
|
407 |
+
#--------------------------------------------------------------------------------
|
408 |
+
|
409 |
+
/**
|
410 |
+
* @param int|null $blog_id
|
411 |
+
*
|
412 |
+
* @return bool
|
413 |
+
*/
|
414 |
+
function is_extensions_tracking_allowed( $blog_id = null ) {
|
415 |
+
return $this->is_permission_allowed( self::PERMISSION_EXTENSIONS, ! $this->_fs->is_premium(), $blog_id );
|
416 |
+
}
|
417 |
+
|
418 |
+
/**
|
419 |
+
* @param int|null $blog_id
|
420 |
+
*
|
421 |
+
* @return bool
|
422 |
+
*/
|
423 |
+
function is_essentials_tracking_allowed( $blog_id = null ) {
|
424 |
+
return $this->is_permission_allowed( self::PERMISSION_ESSENTIALS, true, $blog_id );
|
425 |
+
}
|
426 |
+
|
427 |
+
/**
|
428 |
+
* @param bool $default
|
429 |
+
*
|
430 |
+
* @return bool
|
431 |
+
*/
|
432 |
+
function is_diagnostic_tracking_allowed( $default = true ) {
|
433 |
+
return $this->_fs->is_premium() ?
|
434 |
+
$this->is_permission_allowed( self::PERMISSION_DIAGNOSTIC, $default ) :
|
435 |
+
$this->is_permission_allowed( self::PERMISSION_SITE, $default );
|
436 |
+
}
|
437 |
+
|
438 |
+
/**
|
439 |
+
* @param int|null $blog_id
|
440 |
+
*
|
441 |
+
* @return bool
|
442 |
+
*/
|
443 |
+
function is_homepage_url_tracking_allowed( $blog_id = null ) {
|
444 |
+
return $this->is_permission_allowed( $this->get_site_permission_name(), true, $blog_id );
|
445 |
+
}
|
446 |
+
|
447 |
+
/**
|
448 |
+
* @param int|null $blog_id
|
449 |
+
*
|
450 |
+
* @return bool
|
451 |
+
*/
|
452 |
+
function update_site_tracking( $is_enabled, $blog_id = null, $only_if_not_set = false ) {
|
453 |
+
$permissions = $this->get_site_tracking_permission_names();
|
454 |
+
|
455 |
+
$result = true;
|
456 |
+
foreach ( $permissions as $permission ) {
|
457 |
+
if ( ! $only_if_not_set || ! $this->is_permission_set( $permission, $blog_id ) ) {
|
458 |
+
$result = ( $result && $this->update_permission_tracking_flag( $permission, $is_enabled, $blog_id ) );
|
459 |
+
}
|
460 |
+
}
|
461 |
+
|
462 |
+
return $result;
|
463 |
+
}
|
464 |
+
|
465 |
+
/**
|
466 |
+
* @param string $permission
|
467 |
+
* @param bool $default
|
468 |
+
* @param int|null $blog_id
|
469 |
+
*
|
470 |
+
* @return bool
|
471 |
+
*/
|
472 |
+
function is_permission_allowed( $permission, $default = false, $blog_id = null ) {
|
473 |
+
if ( ! self::is_supported_permission( $permission ) ) {
|
474 |
+
return $default;
|
475 |
+
}
|
476 |
+
|
477 |
+
return $this->is_permission( $permission, true, $blog_id );
|
478 |
+
}
|
479 |
+
|
480 |
+
/**
|
481 |
+
* @param string $permission
|
482 |
+
* @param bool $is_allowed
|
483 |
+
* @param int|null $blog_id
|
484 |
+
*
|
485 |
+
* @return bool
|
486 |
+
*/
|
487 |
+
function is_permission( $permission, $is_allowed, $blog_id = null ) {
|
488 |
+
if ( ! self::is_supported_permission( $permission ) ) {
|
489 |
+
return false;
|
490 |
+
}
|
491 |
+
|
492 |
+
$tag = "is_{$permission}_tracking_allowed";
|
493 |
+
|
494 |
+
return ( $is_allowed === $this->_fs->apply_filters(
|
495 |
+
$tag,
|
496 |
+
$this->_storage->get(
|
497 |
+
$tag,
|
498 |
+
$this->get_permission_default( $permission ),
|
499 |
+
$blog_id,
|
500 |
+
FS_Storage::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED
|
501 |
+
)
|
502 |
+
) );
|
503 |
+
}
|
504 |
+
|
505 |
+
/**
|
506 |
+
* @param string $permission
|
507 |
+
* @param int|null $blog_id
|
508 |
+
*
|
509 |
+
* @return bool
|
510 |
+
*/
|
511 |
+
function is_permission_set( $permission, $blog_id = null ) {
|
512 |
+
$tag = "is_{$permission}_tracking_allowed";
|
513 |
+
|
514 |
+
$permission = $this->_storage->get(
|
515 |
+
$tag,
|
516 |
+
null,
|
517 |
+
$blog_id,
|
518 |
+
FS_Storage::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED
|
519 |
+
);
|
520 |
+
|
521 |
+
return is_bool( $permission );
|
522 |
+
}
|
523 |
+
|
524 |
+
/**
|
525 |
+
* @param string[] $permissions
|
526 |
+
* @param bool $is_allowed
|
527 |
+
*
|
528 |
+
* @return bool `true` if all given permissions are in sync with `$is_allowed`.
|
529 |
+
*/
|
530 |
+
function are_permissions( $permissions, $is_allowed, $blog_id = null ) {
|
531 |
+
foreach ( $permissions as $permission ) {
|
532 |
+
if ( ! $this->is_permission( $permission, $is_allowed, $blog_id ) ) {
|
533 |
+
return false;
|
534 |
+
}
|
535 |
+
}
|
536 |
+
|
537 |
+
return true;
|
538 |
+
}
|
539 |
+
|
540 |
+
/**
|
541 |
+
* @param string $permission
|
542 |
+
* @param bool $is_enabled
|
543 |
+
* @param int|null $blog_id
|
544 |
+
*
|
545 |
+
* @return bool `false` if permission not supported or `$is_enabled` is not a boolean.
|
546 |
+
*/
|
547 |
+
function update_permission_tracking_flag( $permission, $is_enabled, $blog_id = null ) {
|
548 |
+
if ( is_bool( $is_enabled ) && self::is_supported_permission( $permission ) ) {
|
549 |
+
$this->_storage->store(
|
550 |
+
"is_{$permission}_tracking_allowed",
|
551 |
+
$is_enabled,
|
552 |
+
$blog_id,
|
553 |
+
FS_Storage::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED
|
554 |
+
);
|
555 |
+
|
556 |
+
return true;
|
557 |
+
}
|
558 |
+
|
559 |
+
return false;
|
560 |
+
}
|
561 |
+
|
562 |
+
/**
|
563 |
+
* @param array<string,bool> $permissions
|
564 |
+
*/
|
565 |
+
function update_permissions_tracking_flag( $permissions ) {
|
566 |
+
foreach ( $permissions as $permission => $is_enabled ) {
|
567 |
+
$this->update_permission_tracking_flag( $permission, $is_enabled );
|
568 |
+
}
|
569 |
+
}
|
570 |
+
|
571 |
+
#endregion
|
572 |
+
|
573 |
+
|
574 |
+
/**
|
575 |
+
* @param string $permission
|
576 |
+
*
|
577 |
+
* @return bool
|
578 |
+
*/
|
579 |
+
function get_permission_default( $permission ) {
|
580 |
+
if (
|
581 |
+
$this->_fs->is_premium() &&
|
582 |
+
self::PERMISSION_EXTENSIONS === $permission
|
583 |
+
) {
|
584 |
+
return false;
|
585 |
+
}
|
586 |
+
|
587 |
+
// All permissions except for the extensions in paid version are on by default when the user opts in to usage tracking.
|
588 |
+
return true;
|
589 |
+
}
|
590 |
+
|
591 |
+
/**
|
592 |
+
* @return string
|
593 |
+
*/
|
594 |
+
function get_site_permission_name() {
|
595 |
+
return $this->_fs->is_premium() ?
|
596 |
+
self::PERMISSION_ESSENTIALS :
|
597 |
+
self::PERMISSION_SITE;
|
598 |
+
}
|
599 |
+
|
600 |
+
/**
|
601 |
+
* @return string[]
|
602 |
+
*/
|
603 |
+
function get_site_tracking_permission_names() {
|
604 |
+
return $this->_fs->is_premium() ?
|
605 |
+
array(
|
606 |
+
FS_Permission_Manager::PERMISSION_ESSENTIALS,
|
607 |
+
FS_Permission_Manager::PERMISSION_EVENTS,
|
608 |
+
) :
|
609 |
+
array( FS_Permission_Manager::PERMISSION_SITE );
|
610 |
+
}
|
611 |
+
|
612 |
+
#--------------------------------------------------------------------------------
|
613 |
+
#region Rendering
|
614 |
+
#--------------------------------------------------------------------------------
|
615 |
+
|
616 |
+
/**
|
617 |
+
* @param array $permission
|
618 |
+
*/
|
619 |
+
function render_permission( array $permission ) {
|
620 |
+
fs_require_template( 'connect/permission.php', $permission );
|
621 |
+
}
|
622 |
+
|
623 |
+
/**
|
624 |
+
* @param array $permissions_group
|
625 |
+
*/
|
626 |
+
function render_permissions_group( array $permissions_group ) {
|
627 |
+
$permissions_group[ 'fs' ] = $this->_fs;
|
628 |
+
|
629 |
+
fs_require_template( 'connect/permissions-group.php', $permissions_group );
|
630 |
+
}
|
631 |
+
|
632 |
+
function require_permissions_js() {
|
633 |
+
fs_require_once_template( 'js/permissions.php', $params );
|
634 |
+
}
|
635 |
+
|
636 |
+
#endregion
|
637 |
+
|
638 |
+
#--------------------------------------------------------------------------------
|
639 |
+
#region Helper Methods
|
640 |
+
#--------------------------------------------------------------------------------
|
641 |
+
|
642 |
+
/**
|
643 |
+
* @param string $id
|
644 |
+
* @param string $dashicon
|
645 |
+
* @param string $label
|
646 |
+
* @param string $desc
|
647 |
+
* @param string $tooltip
|
648 |
+
* @param int $priority
|
649 |
+
* @param bool $is_optional
|
650 |
+
* @param bool $is_on_by_default
|
651 |
+
* @param bool $load_from_storage
|
652 |
+
*
|
653 |
+
* @return array
|
654 |
+
*/
|
655 |
+
private function get_permission(
|
656 |
+
$id,
|
657 |
+
$dashicon,
|
658 |
+
$label,
|
659 |
+
$desc,
|
660 |
+
$tooltip = '',
|
661 |
+
$priority = 10,
|
662 |
+
$is_optional = false,
|
663 |
+
$is_on_by_default = true,
|
664 |
+
$load_from_storage = false
|
665 |
+
) {
|
666 |
+
$is_on = $load_from_storage ?
|
667 |
+
$this->is_permission_allowed( $id, $is_on_by_default ) :
|
668 |
+
$is_on_by_default;
|
669 |
+
|
670 |
+
return array(
|
671 |
+
'id' => $id,
|
672 |
+
'icon-class' => $this->_fs->apply_filters( "permission_{$id}_icon", "dashicons dashicons-{$dashicon}" ),
|
673 |
+
'label' => $this->_fs->apply_filters( "permission_{$id}_label", $label ),
|
674 |
+
'tooltip' => $this->_fs->apply_filters( "permission_{$id}_tooltip", $tooltip ),
|
675 |
+
'desc' => $this->_fs->apply_filters( "permission_{$id}_desc", $desc ),
|
676 |
+
'priority' => $this->_fs->apply_filters( "permission_{$id}_priority", $priority ),
|
677 |
+
'optional' => $is_optional,
|
678 |
+
'default' => $this->_fs->apply_filters( "permission_{$id}_default", $is_on ),
|
679 |
+
);
|
680 |
+
}
|
681 |
+
|
682 |
+
/**
|
683 |
+
* @param array $permissions
|
684 |
+
*
|
685 |
+
* @return array[]
|
686 |
+
*/
|
687 |
+
private function get_sorted_permissions_by_priority( array $permissions ) {
|
688 |
+
// Allow filtering of the permissions list.
|
689 |
+
$permissions = $this->_fs->apply_filters( 'permission_list', $permissions );
|
690 |
+
|
691 |
+
// Sort by priority.
|
692 |
+
uasort( $permissions, 'fs_sort_by_priority' );
|
693 |
+
|
694 |
+
return $permissions;
|
695 |
+
}
|
696 |
+
|
697 |
+
#endregion
|
698 |
+
}
|
freemius/includes/managers/class-fs-plugin-manager.php
CHANGED
@@ -211,10 +211,23 @@
|
|
211 |
* @return bool|\FS_Plugin
|
212 |
*/
|
213 |
function get() {
|
214 |
-
|
215 |
-
|
216 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
}
|
218 |
-
|
219 |
-
|
220 |
}
|
211 |
* @return bool|\FS_Plugin
|
212 |
*/
|
213 |
function get() {
|
214 |
+
if ( isset( $this->_module ) ) {
|
215 |
+
return $this->_module;
|
216 |
+
}
|
217 |
+
|
218 |
+
if ( empty( $this->_module_id ) ) {
|
219 |
+
return false;
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Return an FS_Plugin entity that has its `id` and `is_live` properties set (`is_live` is initialized in the FS_Plugin constructor) to avoid triggering an error that is relevant to these properties when the FS_Plugin entity is used before the `parse_settings()` method is called. This can happen when creating a regular WordPress site by cloning a subsite of a multisite network and the data that is stored in the network-level storage is not cloned.
|
224 |
+
*
|
225 |
+
* @author Leo Fajardo (@leorw)
|
226 |
+
* @since 2.5.0
|
227 |
+
*/
|
228 |
+
$plugin = new FS_Plugin();
|
229 |
+
$plugin->id = $this->_module_id;
|
230 |
+
|
231 |
+
return $plugin;
|
232 |
}
|
|
|
|
|
233 |
}
|
freemius/includes/sdk/FreemiusBase.php
CHANGED
@@ -46,174 +46,172 @@
|
|
46 |
require_once FS_SDK__EXCEPTIONS_PATH . $e . '.php';
|
47 |
}
|
48 |
|
49 |
-
if ( class_exists( 'Freemius_Api_Base' ) ) {
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
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 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
}
|
219 |
-
}
|
46 |
require_once FS_SDK__EXCEPTIONS_PATH . $e . '.php';
|
47 |
}
|
48 |
|
49 |
+
if ( ! class_exists( 'Freemius_Api_Base' ) ) {
|
50 |
+
abstract class Freemius_Api_Base {
|
51 |
+
const VERSION = '1.0.4';
|
52 |
+
const FORMAT = 'json';
|
53 |
+
|
54 |
+
protected $_id;
|
55 |
+
protected $_public;
|
56 |
+
protected $_secret;
|
57 |
+
protected $_scope;
|
58 |
+
protected $_isSandbox;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @param string $pScope 'app', 'developer', 'plugin', 'user' or 'install'.
|
62 |
+
* @param number $pID Element's id.
|
63 |
+
* @param string $pPublic Public key.
|
64 |
+
* @param string $pSecret Element's secret key.
|
65 |
+
* @param bool $pIsSandbox Whether or not to run API in sandbox mode.
|
66 |
+
*/
|
67 |
+
public function Init( $pScope, $pID, $pPublic, $pSecret, $pIsSandbox = false ) {
|
68 |
+
$this->_id = $pID;
|
69 |
+
$this->_public = $pPublic;
|
70 |
+
$this->_secret = $pSecret;
|
71 |
+
$this->_scope = $pScope;
|
72 |
+
$this->_isSandbox = $pIsSandbox;
|
73 |
+
}
|
74 |
+
|
75 |
+
public function IsSandbox() {
|
76 |
+
return $this->_isSandbox;
|
77 |
+
}
|
78 |
+
|
79 |
+
function CanonizePath( $pPath ) {
|
80 |
+
$pPath = trim( $pPath, '/' );
|
81 |
+
$query_pos = strpos( $pPath, '?' );
|
82 |
+
$query = '';
|
83 |
+
|
84 |
+
if ( false !== $query_pos ) {
|
85 |
+
$query = substr( $pPath, $query_pos );
|
86 |
+
$pPath = substr( $pPath, 0, $query_pos );
|
87 |
+
}
|
88 |
+
|
89 |
+
// Trim '.json' suffix.
|
90 |
+
$format_length = strlen( '.' . self::FORMAT );
|
91 |
+
$start = $format_length * ( - 1 ); //negative
|
92 |
+
if ( substr( strtolower( $pPath ), $start ) === ( '.' . self::FORMAT ) ) {
|
93 |
+
$pPath = substr( $pPath, 0, strlen( $pPath ) - $format_length );
|
94 |
+
}
|
95 |
+
|
96 |
+
switch ( $this->_scope ) {
|
97 |
+
case 'app':
|
98 |
+
$base = '/apps/' . $this->_id;
|
99 |
+
break;
|
100 |
+
case 'developer':
|
101 |
+
$base = '/developers/' . $this->_id;
|
102 |
+
break;
|
103 |
+
case 'user':
|
104 |
+
$base = '/users/' . $this->_id;
|
105 |
+
break;
|
106 |
+
case 'plugin':
|
107 |
+
$base = '/plugins/' . $this->_id;
|
108 |
+
break;
|
109 |
+
case 'install':
|
110 |
+
$base = '/installs/' . $this->_id;
|
111 |
+
break;
|
112 |
+
default:
|
113 |
+
throw new Freemius_Exception( 'Scope not implemented.' );
|
114 |
+
}
|
115 |
+
|
116 |
+
return '/v' . FS_API__VERSION . $base .
|
117 |
+
( ! empty( $pPath ) ? '/' : '' ) . $pPath .
|
118 |
+
( ( false === strpos( $pPath, '.' ) ) ? '.' . self::FORMAT : '' ) . $query;
|
119 |
+
}
|
120 |
+
|
121 |
+
abstract function MakeRequest( $pCanonizedPath, $pMethod = 'GET', $pParams = array() );
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @param string $pPath
|
125 |
+
* @param string $pMethod
|
126 |
+
* @param array $pParams
|
127 |
+
*
|
128 |
+
* @return object[]|object|null
|
129 |
+
*/
|
130 |
+
private function _Api( $pPath, $pMethod = 'GET', $pParams = array() ) {
|
131 |
+
$pMethod = strtoupper( $pMethod );
|
132 |
+
|
133 |
+
try {
|
134 |
+
$result = $this->MakeRequest( $pPath, $pMethod, $pParams );
|
135 |
+
} catch ( Freemius_Exception $e ) {
|
136 |
+
// Map to error object.
|
137 |
+
$result = (object) $e->getResult();
|
138 |
+
} catch ( Exception $e ) {
|
139 |
+
// Map to error object.
|
140 |
+
$result = (object) array(
|
141 |
+
'error' => (object) array(
|
142 |
+
'type' => 'Unknown',
|
143 |
+
'message' => $e->getMessage() . ' (' . $e->getFile() . ': ' . $e->getLine() . ')',
|
144 |
+
'code' => 'unknown',
|
145 |
+
'http' => 402
|
146 |
+
)
|
147 |
+
);
|
148 |
+
}
|
149 |
+
|
150 |
+
return $result;
|
151 |
+
}
|
152 |
+
|
153 |
+
public function Api( $pPath, $pMethod = 'GET', $pParams = array() ) {
|
154 |
+
return $this->_Api( $this->CanonizePath( $pPath ), $pMethod, $pParams );
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Base64 decoding that does not need to be urldecode()-ed.
|
159 |
+
*
|
160 |
+
* Exactly the same as PHP base64 encode except it uses
|
161 |
+
* `-` instead of `+`
|
162 |
+
* `_` instead of `/`
|
163 |
+
* No padded =
|
164 |
+
*
|
165 |
+
* @param string $input Base64UrlEncoded() string
|
166 |
+
*
|
167 |
+
* @return string
|
168 |
+
*/
|
169 |
+
protected static function Base64UrlDecode( $input ) {
|
170 |
+
/**
|
171 |
+
* IMPORTANT NOTE:
|
172 |
+
* This is a hack suggested by @otto42 and @greenshady from
|
173 |
+
* the theme's review team. The usage of base64 for API
|
174 |
+
* signature encoding was approved in a Slack meeting
|
175 |
+
* held on Tue (10/25 2016).
|
176 |
+
*
|
177 |
+
* @todo Remove this hack once the base64 error is removed from the Theme Check.
|
178 |
+
*
|
179 |
+
* @since 1.2.2
|
180 |
+
* @author Vova Feldman (@svovaf)
|
181 |
+
*/
|
182 |
+
$fn = 'base64' . '_decode';
|
183 |
+
return $fn( strtr( $input, '-_', '+/' ) );
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* Base64 encoding that does not need to be urlencode()ed.
|
188 |
+
*
|
189 |
+
* Exactly the same as base64 encode except it uses
|
190 |
+
* `-` instead of `+
|
191 |
+
* `_` instead of `/`
|
192 |
+
*
|
193 |
+
* @param string $input string
|
194 |
+
*
|
195 |
+
* @return string Base64 encoded string
|
196 |
+
*/
|
197 |
+
protected static function Base64UrlEncode( $input ) {
|
198 |
+
/**
|
199 |
+
* IMPORTANT NOTE:
|
200 |
+
* This is a hack suggested by @otto42 and @greenshady from
|
201 |
+
* the theme's review team. The usage of base64 for API
|
202 |
+
* signature encoding was approved in a Slack meeting
|
203 |
+
* held on Tue (10/25 2016).
|
204 |
+
*
|
205 |
+
* @todo Remove this hack once the base64 error is removed from the Theme Check.
|
206 |
+
*
|
207 |
+
* @since 1.2.2
|
208 |
+
* @author Vova Feldman (@svovaf)
|
209 |
+
*/
|
210 |
+
$fn = 'base64' . '_encode';
|
211 |
+
$str = strtr( $fn( $input ), '+/', '-_' );
|
212 |
+
$str = str_replace( '=', '', $str );
|
213 |
+
|
214 |
+
return $str;
|
215 |
+
}
|
216 |
+
}
|
217 |
+
}
|
|
|
|
freemius/includes/sdk/FreemiusWordPress.php
CHANGED
@@ -1,715 +1,715 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Copyright 2016 Freemius, Inc.
|
4 |
-
*
|
5 |
-
* Licensed under the GPL v2 (the "License"); you may
|
6 |
-
* not use this file except in compliance with the License. You may obtain
|
7 |
-
* a copy of the License at
|
8 |
-
*
|
9 |
-
* http://choosealicense.com/licenses/gpl-v2/
|
10 |
-
*
|
11 |
-
* Unless required by applicable law or agreed to in writing, software
|
12 |
-
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
13 |
-
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
14 |
-
* License for the specific language governing permissions and limitations
|
15 |
-
* under the License.
|
16 |
-
*/
|
17 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
18 |
-
exit;
|
19 |
-
}
|
20 |
-
|
21 |
-
require_once dirname( __FILE__ ) . '/FreemiusBase.php';
|
22 |
-
|
23 |
-
if ( ! defined( 'FS_SDK__USER_AGENT' ) ) {
|
24 |
-
define( 'FS_SDK__USER_AGENT', 'fs-php-' . Freemius_Api_Base::VERSION );
|
25 |
-
}
|
26 |
-
|
27 |
-
if ( ! defined( 'FS_SDK__SIMULATE_NO_CURL' ) ) {
|
28 |
-
define( 'FS_SDK__SIMULATE_NO_CURL', false );
|
29 |
-
}
|
30 |
-
|
31 |
-
if ( ! defined( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE' ) ) {
|
32 |
-
define( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE', false );
|
33 |
-
}
|
34 |
-
|
35 |
-
if ( ! defined( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL' ) ) {
|
36 |
-
define( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL', false );
|
37 |
-
}
|
38 |
-
|
39 |
-
if ( ! defined( 'FS_SDK__HAS_CURL' ) ) {
|
40 |
-
if ( FS_SDK__SIMULATE_NO_CURL ) {
|
41 |
-
define( 'FS_SDK__HAS_CURL', false );
|
42 |
-
} else {
|
43 |
-
$curl_required_methods = array(
|
44 |
-
'curl_version',
|
45 |
-
'curl_exec',
|
46 |
-
'curl_init',
|
47 |
-
'curl_close',
|
48 |
-
'curl_setopt',
|
49 |
-
'curl_setopt_array',
|
50 |
-
'curl_error',
|
51 |
-
);
|
52 |
-
|
53 |
-
$has_curl = true;
|
54 |
-
foreach ( $curl_required_methods as $m ) {
|
55 |
-
if ( ! function_exists( $m ) ) {
|
56 |
-
$has_curl = false;
|
57 |
-
break;
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
-
define( 'FS_SDK__HAS_CURL', $has_curl );
|
62 |
-
}
|
63 |
-
}
|
64 |
-
|
65 |
-
if ( ! defined( 'FS_SDK__SSLVERIFY' ) ) {
|
66 |
-
define( 'FS_SDK__SSLVERIFY', false );
|
67 |
-
}
|
68 |
-
|
69 |
-
$curl_version = FS_SDK__HAS_CURL ?
|
70 |
-
curl_version() :
|
71 |
-
array( 'version' => '7.37' );
|
72 |
-
|
73 |
-
if ( ! defined( 'FS_API__PROTOCOL' ) ) {
|
74 |
-
define( 'FS_API__PROTOCOL', version_compare( $curl_version['version'], '7.37', '>=' ) ? 'https' : 'http' );
|
75 |
-
}
|
76 |
-
|
77 |
-
if ( ! defined( 'FS_API__LOGGER_ON' ) ) {
|
78 |
-
define( 'FS_API__LOGGER_ON', false );
|
79 |
-
}
|
80 |
-
|
81 |
-
if ( ! defined( 'FS_API__ADDRESS' ) ) {
|
82 |
-
define( 'FS_API__ADDRESS', '://api.freemius.com' );
|
83 |
-
}
|
84 |
-
if ( ! defined( 'FS_API__SANDBOX_ADDRESS' ) ) {
|
85 |
-
define( 'FS_API__SANDBOX_ADDRESS', '://sandbox-api.freemius.com' );
|
86 |
-
}
|
87 |
-
|
88 |
-
if ( class_exists( 'Freemius_Api_WordPress' ) ) {
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
* @param string
|
97 |
-
* @param
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
*
|
132 |
-
*
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
*
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
$time
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
*
|
181 |
-
*
|
182 |
-
*
|
183 |
-
*
|
184 |
-
*
|
185 |
-
*
|
186 |
-
* @
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
*
|
210 |
-
*
|
211 |
-
*
|
212 |
-
*
|
213 |
-
*
|
214 |
-
*
|
215 |
-
*
|
216 |
-
* @
|
217 |
-
*
|
218 |
-
*
|
219 |
-
* @
|
220 |
-
* @
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
$pMethod =
|
228 |
-
|
229 |
-
|
230 |
-
$
|
231 |
-
|
232 |
-
$
|
233 |
-
$
|
234 |
-
|
235 |
-
$
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
$
|
248 |
-
$
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
*
|
276 |
-
|
277 |
-
|
278 |
-
*
|
279 |
-
*
|
280 |
-
*
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
$
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
* @
|
301 |
-
*
|
302 |
-
* @
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
$
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
'
|
320 |
-
'
|
321 |
-
'
|
322 |
-
'
|
323 |
-
'
|
324 |
-
'
|
325 |
-
'
|
326 |
-
|
327 |
-
$response
|
328 |
-
|
329 |
-
'
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
* @param string $
|
346 |
-
* @param
|
347 |
-
* @param array
|
348 |
-
* @param
|
349 |
-
* @param
|
350 |
-
*
|
351 |
-
*
|
352 |
-
*
|
353 |
-
*
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
$
|
358 |
-
$
|
359 |
-
$
|
360 |
-
$
|
361 |
-
$
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
'
|
377 |
-
'
|
378 |
-
'
|
379 |
-
'
|
380 |
-
'
|
381 |
-
'
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
//
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
*
|
429 |
-
*
|
430 |
-
*
|
431 |
-
*
|
432 |
-
|
433 |
-
|
434 |
-
$
|
435 |
-
$regex
|
436 |
-
|
437 |
-
|
438 |
-
*
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
//
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
'
|
480 |
-
'
|
481 |
-
'
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
*
|
494 |
-
*
|
495 |
-
*
|
496 |
-
*
|
497 |
-
* @param string $
|
498 |
-
* @param
|
499 |
-
* @param array
|
500 |
-
*
|
501 |
-
*
|
502 |
-
*
|
503 |
-
*
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
$
|
508 |
-
$
|
509 |
-
$
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
$
|
519 |
-
$
|
520 |
-
$
|
521 |
-
$
|
522 |
-
$this
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
*
|
529 |
-
*
|
530 |
-
*
|
531 |
-
*
|
532 |
-
*
|
533 |
-
*
|
534 |
-
*
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
*
|
549 |
-
*
|
550 |
-
*
|
551 |
-
*
|
552 |
-
*
|
553 |
-
*
|
554 |
-
*
|
555 |
-
*
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
*
|
572 |
-
*
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
'
|
586 |
-
'
|
587 |
-
'
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
*
|
604 |
-
*
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
*
|
615 |
-
*
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
'
|
626 |
-
'
|
627 |
-
'
|
628 |
-
'
|
629 |
-
'
|
630 |
-
'
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
$
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
'
|
646 |
-
'
|
647 |
-
'
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
$
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
'
|
665 |
-
'
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
'
|
673 |
-
'
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
*
|
684 |
-
*
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
'
|
691 |
-
'
|
692 |
-
'
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
*
|
700 |
-
*
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
'
|
707 |
-
'
|
708 |
-
'
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright 2016 Freemius, Inc.
|
4 |
+
*
|
5 |
+
* Licensed under the GPL v2 (the "License"); you may
|
6 |
+
* not use this file except in compliance with the License. You may obtain
|
7 |
+
* a copy of the License at
|
8 |
+
*
|
9 |
+
* http://choosealicense.com/licenses/gpl-v2/
|
10 |
+
*
|
11 |
+
* Unless required by applicable law or agreed to in writing, software
|
12 |
+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
13 |
+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
14 |
+
* License for the specific language governing permissions and limitations
|
15 |
+
* under the License.
|
16 |
+
*/
|
17 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
18 |
+
exit;
|
19 |
+
}
|
20 |
+
|
21 |
+
require_once dirname( __FILE__ ) . '/FreemiusBase.php';
|
22 |
+
|
23 |
+
if ( ! defined( 'FS_SDK__USER_AGENT' ) ) {
|
24 |
+
define( 'FS_SDK__USER_AGENT', 'fs-php-' . Freemius_Api_Base::VERSION );
|
25 |
+
}
|
26 |
+
|
27 |
+
if ( ! defined( 'FS_SDK__SIMULATE_NO_CURL' ) ) {
|
28 |
+
define( 'FS_SDK__SIMULATE_NO_CURL', false );
|
29 |
+
}
|
30 |
+
|
31 |
+
if ( ! defined( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE' ) ) {
|
32 |
+
define( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE', false );
|
33 |
+
}
|
34 |
+
|
35 |
+
if ( ! defined( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL' ) ) {
|
36 |
+
define( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL', false );
|
37 |
+
}
|
38 |
+
|
39 |
+
if ( ! defined( 'FS_SDK__HAS_CURL' ) ) {
|
40 |
+
if ( FS_SDK__SIMULATE_NO_CURL ) {
|
41 |
+
define( 'FS_SDK__HAS_CURL', false );
|
42 |
+
} else {
|
43 |
+
$curl_required_methods = array(
|
44 |
+
'curl_version',
|
45 |
+
'curl_exec',
|
46 |
+
'curl_init',
|
47 |
+
'curl_close',
|
48 |
+
'curl_setopt',
|
49 |
+
'curl_setopt_array',
|
50 |
+
'curl_error',
|
51 |
+
);
|
52 |
+
|
53 |
+
$has_curl = true;
|
54 |
+
foreach ( $curl_required_methods as $m ) {
|
55 |
+
if ( ! function_exists( $m ) ) {
|
56 |
+
$has_curl = false;
|
57 |
+
break;
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
define( 'FS_SDK__HAS_CURL', $has_curl );
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
if ( ! defined( 'FS_SDK__SSLVERIFY' ) ) {
|
66 |
+
define( 'FS_SDK__SSLVERIFY', false );
|
67 |
+
}
|
68 |
+
|
69 |
+
$curl_version = FS_SDK__HAS_CURL ?
|
70 |
+
curl_version() :
|
71 |
+
array( 'version' => '7.37' );
|
72 |
+
|
73 |
+
if ( ! defined( 'FS_API__PROTOCOL' ) ) {
|
74 |
+
define( 'FS_API__PROTOCOL', version_compare( $curl_version['version'], '7.37', '>=' ) ? 'https' : 'http' );
|
75 |
+
}
|
76 |
+
|
77 |
+
if ( ! defined( 'FS_API__LOGGER_ON' ) ) {
|
78 |
+
define( 'FS_API__LOGGER_ON', false );
|
79 |
+
}
|
80 |
+
|
81 |
+
if ( ! defined( 'FS_API__ADDRESS' ) ) {
|
82 |
+
define( 'FS_API__ADDRESS', '://api.freemius.com' );
|
83 |
+
}
|
84 |
+
if ( ! defined( 'FS_API__SANDBOX_ADDRESS' ) ) {
|
85 |
+
define( 'FS_API__SANDBOX_ADDRESS', '://sandbox-api.freemius.com' );
|
86 |
+
}
|
87 |
+
|
88 |
+
if ( ! class_exists( 'Freemius_Api_WordPress' ) ) {
|
89 |
+
class Freemius_Api_WordPress extends Freemius_Api_Base {
|
90 |
+
private static $_logger = array();
|
91 |
+
|
92 |
+
/**
|
93 |
+
* @param string $pScope 'app', 'developer', 'user' or 'install'.
|
94 |
+
* @param number $pID Element's id.
|
95 |
+
* @param string $pPublic Public key.
|
96 |
+
* @param string|bool $pSecret Element's secret key.
|
97 |
+
* @param bool $pSandbox Whether or not to run API in sandbox mode.
|
98 |
+
*/
|
99 |
+
public function __construct( $pScope, $pID, $pPublic, $pSecret = false, $pSandbox = false ) {
|
100 |
+
// If secret key not provided, use public key encryption.
|
101 |
+
if ( is_bool( $pSecret ) ) {
|
102 |
+
$pSecret = $pPublic;
|
103 |
+
}
|
104 |
+
|
105 |
+
parent::Init( $pScope, $pID, $pPublic, $pSecret, $pSandbox );
|
106 |
+
}
|
107 |
+
|
108 |
+
public static function GetUrl( $pCanonizedPath = '', $pIsSandbox = false ) {
|
109 |
+
$address = ( $pIsSandbox ? FS_API__SANDBOX_ADDRESS : FS_API__ADDRESS );
|
110 |
+
|
111 |
+
if ( ':' === $address[0] ) {
|
112 |
+
$address = self::$_protocol . $address;
|
113 |
+
}
|
114 |
+
|
115 |
+
return $address . $pCanonizedPath;
|
116 |
+
}
|
117 |
+
|
118 |
+
#----------------------------------------------------------------------------------
|
119 |
+
#region Servers Clock Diff
|
120 |
+
#----------------------------------------------------------------------------------
|
121 |
+
|
122 |
+
/**
|
123 |
+
* @var int Clock diff in seconds between current server to API server.
|
124 |
+
*/
|
125 |
+
private static $_clock_diff = 0;
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Set clock diff for all API calls.
|
129 |
+
*
|
130 |
+
* @since 1.0.3
|
131 |
+
*
|
132 |
+
* @param $pSeconds
|
133 |
+
*/
|
134 |
+
public static function SetClockDiff( $pSeconds ) {
|
135 |
+
self::$_clock_diff = $pSeconds;
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Find clock diff between current server to API server.
|
140 |
+
*
|
141 |
+
* @since 1.0.2
|
142 |
+
* @return int Clock diff in seconds.
|
143 |
+
*/
|
144 |
+
public static function FindClockDiff() {
|
145 |
+
$time = time();
|
146 |
+
$pong = self::Ping();
|
147 |
+
|
148 |
+
return ( $time - strtotime( $pong->timestamp ) );
|
149 |
+
}
|
150 |
+
|
151 |
+
#endregion
|
152 |
+
|
153 |
+
/**
|
154 |
+
* @var string http or https
|
155 |
+
*/
|
156 |
+
private static $_protocol = FS_API__PROTOCOL;
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Set API connection protocol.
|
160 |
+
*
|
161 |
+
* @since 1.0.4
|
162 |
+
*/
|
163 |
+
public static function SetHttp() {
|
164 |
+
self::$_protocol = 'http';
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* @since 1.0.4
|
169 |
+
*
|
170 |
+
* @return bool
|
171 |
+
*/
|
172 |
+
public static function IsHttps() {
|
173 |
+
return ( 'https' === self::$_protocol );
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Sign request with the following HTTP headers:
|
178 |
+
* Content-MD5: MD5(HTTP Request body)
|
179 |
+
* Date: Current date (i.e Sat, 14 Feb 2016 20:24:46 +0000)
|
180 |
+
* Authorization: FS {scope_entity_id}:{scope_entity_public_key}:base64encode(sha256(string_to_sign,
|
181 |
+
* {scope_entity_secret_key}))
|
182 |
+
*
|
183 |
+
* @param string $pResourceUrl
|
184 |
+
* @param array $pWPRemoteArgs
|
185 |
+
*
|
186 |
+
* @return array
|
187 |
+
*/
|
188 |
+
function SignRequest( $pResourceUrl, $pWPRemoteArgs ) {
|
189 |
+
$auth = $this->GenerateAuthorizationParams(
|
190 |
+
$pResourceUrl,
|
191 |
+
$pWPRemoteArgs['method'],
|
192 |
+
! empty( $pWPRemoteArgs['body'] ) ? $pWPRemoteArgs['body'] : ''
|
193 |
+
);
|
194 |
+
|
195 |
+
$pWPRemoteArgs['headers']['Date'] = $auth['date'];
|
196 |
+
$pWPRemoteArgs['headers']['Authorization'] = $auth['authorization'];
|
197 |
+
|
198 |
+
if ( ! empty( $auth['content_md5'] ) ) {
|
199 |
+
$pWPRemoteArgs['headers']['Content-MD5'] = $auth['content_md5'];
|
200 |
+
}
|
201 |
+
|
202 |
+
return $pWPRemoteArgs;
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Generate Authorization request headers:
|
207 |
+
*
|
208 |
+
* Content-MD5: MD5(HTTP Request body)
|
209 |
+
* Date: Current date (i.e Sat, 14 Feb 2016 20:24:46 +0000)
|
210 |
+
* Authorization: FS {scope_entity_id}:{scope_entity_public_key}:base64encode(sha256(string_to_sign,
|
211 |
+
* {scope_entity_secret_key}))
|
212 |
+
*
|
213 |
+
* @author Vova Feldman
|
214 |
+
*
|
215 |
+
* @param string $pResourceUrl
|
216 |
+
* @param string $pMethod
|
217 |
+
* @param string $pPostParams
|
218 |
+
*
|
219 |
+
* @return array
|
220 |
+
* @throws Freemius_Exception
|
221 |
+
*/
|
222 |
+
function GenerateAuthorizationParams(
|
223 |
+
$pResourceUrl,
|
224 |
+
$pMethod = 'GET',
|
225 |
+
$pPostParams = ''
|
226 |
+
) {
|
227 |
+
$pMethod = strtoupper( $pMethod );
|
228 |
+
|
229 |
+
$eol = "\n";
|
230 |
+
$content_md5 = '';
|
231 |
+
$content_type = '';
|
232 |
+
$now = ( time() - self::$_clock_diff );
|
233 |
+
$date = date( 'r', $now );
|
234 |
+
|
235 |
+
if ( in_array( $pMethod, array( 'POST', 'PUT' ) ) ) {
|
236 |
+
$content_type = 'application/json';
|
237 |
+
|
238 |
+
if ( ! empty( $pPostParams ) ) {
|
239 |
+
$content_md5 = md5( $pPostParams );
|
240 |
+
}
|
241 |
+
}
|
242 |
+
|
243 |
+
$string_to_sign = implode( $eol, array(
|
244 |
+
$pMethod,
|
245 |
+
$content_md5,
|
246 |
+
$content_type,
|
247 |
+
$date,
|
248 |
+
$pResourceUrl
|
249 |
+
) );
|
250 |
+
|
251 |
+
// If secret and public keys are identical, it means that
|
252 |
+
// the signature uses public key hash encoding.
|
253 |
+
$auth_type = ( $this->_secret !== $this->_public ) ? 'FS' : 'FSP';
|
254 |
+
|
255 |
+
$auth = array(
|
256 |
+
'date' => $date,
|
257 |
+
'authorization' => $auth_type . ' ' . $this->_id . ':' .
|
258 |
+
$this->_public . ':' .
|
259 |
+
self::Base64UrlEncode( hash_hmac(
|
260 |
+
'sha256', $string_to_sign, $this->_secret
|
261 |
+
) )
|
262 |
+
);
|
263 |
+
|
264 |
+
if ( ! empty( $content_md5 ) ) {
|
265 |
+
$auth['content_md5'] = $content_md5;
|
266 |
+
}
|
267 |
+
|
268 |
+
return $auth;
|
269 |
+
}
|
270 |
+
|
271 |
+
/**
|
272 |
+
* Get API request URL signed via query string.
|
273 |
+
*
|
274 |
+
* @since 1.2.3 Stopped using http_build_query(). Instead, use urlencode(). In some environments the encoding of http_build_query() can generate a URL that once used with a redirect, the `&` querystring separator is escaped to `&` which breaks the URL (Added by @svovaf).
|
275 |
+
*
|
276 |
+
* @param string $pPath
|
277 |
+
*
|
278 |
+
* @throws Freemius_Exception
|
279 |
+
*
|
280 |
+
* @return string
|
281 |
+
*/
|
282 |
+
function GetSignedUrl( $pPath ) {
|
283 |
+
$resource = explode( '?', $this->CanonizePath( $pPath ) );
|
284 |
+
$pResourceUrl = $resource[0];
|
285 |
+
|
286 |
+
$auth = $this->GenerateAuthorizationParams( $pResourceUrl );
|
287 |
+
|
288 |
+
return Freemius_Api_WordPress::GetUrl(
|
289 |
+
$pResourceUrl . '?' .
|
290 |
+
( 1 < count( $resource ) && ! empty( $resource[1] ) ? $resource[1] . '&' : '' ) .
|
291 |
+
'authorization=' . urlencode( $auth['authorization'] ) .
|
292 |
+
'&auth_date=' . urlencode( $auth['date'] )
|
293 |
+
, $this->_isSandbox );
|
294 |
+
}
|
295 |
+
|
296 |
+
/**
|
297 |
+
* @author Vova Feldman
|
298 |
+
*
|
299 |
+
* @param string $pUrl
|
300 |
+
* @param array $pWPRemoteArgs
|
301 |
+
*
|
302 |
+
* @return mixed
|
303 |
+
*/
|
304 |
+
private static function ExecuteRequest( $pUrl, &$pWPRemoteArgs ) {
|
305 |
+
$bt = debug_backtrace();
|
306 |
+
|
307 |
+
$start = microtime( true );
|
308 |
+
|
309 |
+
$response = wp_remote_request( $pUrl, $pWPRemoteArgs );
|
310 |
+
|
311 |
+
if ( FS_API__LOGGER_ON ) {
|
312 |
+
$end = microtime( true );
|
313 |
+
|
314 |
+
$has_body = ( isset( $pWPRemoteArgs['body'] ) && ! empty( $pWPRemoteArgs['body'] ) );
|
315 |
+
$is_http_error = is_wp_error( $response );
|
316 |
+
|
317 |
+
self::$_logger[] = array(
|
318 |
+
'id' => count( self::$_logger ),
|
319 |
+
'start' => $start,
|
320 |
+
'end' => $end,
|
321 |
+
'total' => ( $end - $start ),
|
322 |
+
'method' => $pWPRemoteArgs['method'],
|
323 |
+
'path' => $pUrl,
|
324 |
+
'body' => $has_body ? $pWPRemoteArgs['body'] : null,
|
325 |
+
'result' => ! $is_http_error ?
|
326 |
+
$response['body'] :
|
327 |
+
json_encode( $response->get_error_messages() ),
|
328 |
+
'code' => ! $is_http_error ? $response['response']['code'] : null,
|
329 |
+
'backtrace' => $bt,
|
330 |
+
);
|
331 |
+
}
|
332 |
+
|
333 |
+
return $response;
|
334 |
+
}
|
335 |
+
|
336 |
+
/**
|
337 |
+
* @return array
|
338 |
+
*/
|
339 |
+
static function GetLogger() {
|
340 |
+
return self::$_logger;
|
341 |
+
}
|
342 |
+
|
343 |
+
/**
|
344 |
+
* @param string $pCanonizedPath
|
345 |
+
* @param string $pMethod
|
346 |
+
* @param array $pParams
|
347 |
+
* @param null|array $pWPRemoteArgs
|
348 |
+
* @param bool $pIsSandbox
|
349 |
+
* @param null|callable $pBeforeExecutionFunction
|
350 |
+
*
|
351 |
+
* @return object[]|object|null
|
352 |
+
*
|
353 |
+
* @throws \Freemius_Exception
|
354 |
+
*/
|
355 |
+
private static function MakeStaticRequest(
|
356 |
+
$pCanonizedPath,
|
357 |
+
$pMethod = 'GET',
|
358 |
+
$pParams = array(),
|
359 |
+
$pWPRemoteArgs = null,
|
360 |
+
$pIsSandbox = false,
|
361 |
+
$pBeforeExecutionFunction = null
|
362 |
+
) {
|
363 |
+
// Connectivity errors simulation.
|
364 |
+
if ( FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE ) {
|
365 |
+
self::ThrowCloudFlareDDoSException();
|
366 |
+
} else if ( FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL ) {
|
367 |
+
self::ThrowSquidAclException();
|
368 |
+
}
|
369 |
+
|
370 |
+
if ( empty( $pWPRemoteArgs ) ) {
|
371 |
+
$user_agent = 'Freemius/WordPress-SDK/' . Freemius_Api_Base::VERSION . '; ' .
|
372 |
+
home_url();
|
373 |
+
|
374 |
+
$pWPRemoteArgs = array(
|
375 |
+
'method' => strtoupper( $pMethod ),
|
376 |
+
'connect_timeout' => 10,
|
377 |
+
'timeout' => 60,
|
378 |
+
'follow_redirects' => true,
|
379 |
+
'redirection' => 5,
|
380 |
+
'user-agent' => $user_agent,
|
381 |
+
'blocking' => true,
|
382 |
+
);
|
383 |
+
}
|
384 |
+
|
385 |
+
if ( ! isset( $pWPRemoteArgs['headers'] ) ||
|
386 |
+
! is_array( $pWPRemoteArgs['headers'] )
|
387 |
+
) {
|
388 |
+
$pWPRemoteArgs['headers'] = array();
|
389 |
+
}
|
390 |
+
|
391 |
+
if ( in_array( $pMethod, array( 'POST', 'PUT' ) ) ) {
|
392 |
+
$pWPRemoteArgs['headers']['Content-type'] = 'application/json';
|
393 |
+
|
394 |
+
if ( is_array( $pParams ) && 0 < count( $pParams ) ) {
|
395 |
+
$pWPRemoteArgs['body'] = json_encode( $pParams );
|
396 |
+
}
|
397 |
+
}
|
398 |
+
|
399 |
+
$request_url = self::GetUrl( $pCanonizedPath, $pIsSandbox );
|
400 |
+
|
401 |
+
$resource = explode( '?', $pCanonizedPath );
|
402 |
+
|
403 |
+
if ( FS_SDK__HAS_CURL ) {
|
404 |
+
// Disable the 'Expect: 100-continue' behaviour. This causes cURL to wait
|
405 |
+
// for 2 seconds if the server does not support this header.
|
406 |
+
$pWPRemoteArgs['headers']['Expect'] = '';
|
407 |
+
}
|
408 |
+
|
409 |
+
if ( 'https' === substr( strtolower( $request_url ), 0, 5 ) ) {
|
410 |
+
$pWPRemoteArgs['sslverify'] = FS_SDK__SSLVERIFY;
|
411 |
+
}
|
412 |
+
|
413 |
+
if ( false !== $pBeforeExecutionFunction &&
|
414 |
+
is_callable( $pBeforeExecutionFunction )
|
415 |
+
) {
|
416 |
+
$pWPRemoteArgs = call_user_func( $pBeforeExecutionFunction, $resource[0], $pWPRemoteArgs );
|
417 |
+
}
|
418 |
+
|
419 |
+
$result = self::ExecuteRequest( $request_url, $pWPRemoteArgs );
|
420 |
+
|
421 |
+
if ( is_wp_error( $result ) ) {
|
422 |
+
/**
|
423 |
+
* @var WP_Error $result
|
424 |
+
*/
|
425 |
+
if ( self::IsCurlError( $result ) ) {
|
426 |
+
/**
|
427 |
+
* With dual stacked DNS responses, it's possible for a server to
|
428 |
+
* have IPv6 enabled but not have IPv6 connectivity. If this is
|
429 |
+
* the case, cURL will try IPv4 first and if that fails, then it will
|
430 |
+
* fall back to IPv6 and the error EHOSTUNREACH is returned by the
|
431 |
+
* operating system.
|
432 |
+
*/
|
433 |
+
$matches = array();
|
434 |
+
$regex = '/Failed to connect to ([^:].*): Network is unreachable/';
|
435 |
+
if ( preg_match( $regex, $result->get_error_message( 'http_request_failed' ), $matches ) ) {
|
436 |
+
/**
|
437 |
+
* Validate IP before calling `inet_pton()` to avoid PHP un-catchable warning.
|
438 |
+
* @author Vova Feldman (@svovaf)
|
439 |
+
*/
|
440 |
+
if ( filter_var( $matches[1], FILTER_VALIDATE_IP ) ) {
|
441 |
+
if ( strlen( inet_pton( $matches[1] ) ) === 16 ) {
|
442 |
+
// error_log('Invalid IPv6 configuration on server, Please disable or get native IPv6 on your server.');
|
443 |
+
// Hook to an action triggered just before cURL is executed to resolve the IP version to v4.
|
444 |
+
add_action( 'http_api_curl', 'Freemius_Api_WordPress::CurlResolveToIPv4', 10, 1 );
|
445 |
+
|
446 |
+
// Re-run request.
|
447 |
+
$result = self::ExecuteRequest( $request_url, $pWPRemoteArgs );
|
448 |
+
}
|
449 |
+
}
|
450 |
+
}
|
451 |
+
}
|
452 |
+
|
453 |
+
if ( is_wp_error( $result ) ) {
|
454 |
+
self::ThrowWPRemoteException( $result );
|
455 |
+
}
|
456 |
+
}
|
457 |
+
|
458 |
+
$response_body = $result['body'];
|
459 |
+
|
460 |
+
if ( empty( $response_body ) ) {
|
461 |
+
return null;
|
462 |
+
}
|
463 |
+
|
464 |
+
$decoded = json_decode( $response_body );
|
465 |
+
|
466 |
+
if ( is_null( $decoded ) ) {
|
467 |
+
if ( preg_match( '/Please turn JavaScript on/i', $response_body ) &&
|
468 |
+
preg_match( '/text\/javascript/', $response_body )
|
469 |
+
) {
|
470 |
+
self::ThrowCloudFlareDDoSException( $response_body );
|
471 |
+
} else if ( preg_match( '/Access control configuration prevents your request from being allowed at this time. Please contact your service provider if you feel this is incorrect./', $response_body ) &&
|
472 |
+
preg_match( '/squid/', $response_body )
|
473 |
+
) {
|
474 |
+
self::ThrowSquidAclException( $response_body );
|
475 |
+
} else {
|
476 |
+
$decoded = (object) array(
|
477 |
+
'error' => (object) array(
|
478 |
+
'type' => 'Unknown',
|
479 |
+
'message' => $response_body,
|
480 |
+
'code' => 'unknown',
|
481 |
+
'http' => 402
|
482 |
+
)
|
483 |
+
);
|
484 |
+
}
|
485 |
+
}
|
486 |
+
|
487 |
+
return $decoded;
|
488 |
+
}
|
489 |
+
|
490 |
+
|
491 |
+
/**
|
492 |
+
* Makes an HTTP request. This method can be overridden by subclasses if
|
493 |
+
* developers want to do fancier things or use something other than wp_remote_request()
|
494 |
+
* to make the request.
|
495 |
+
*
|
496 |
+
* @param string $pCanonizedPath The URL to make the request to
|
497 |
+
* @param string $pMethod HTTP method
|
498 |
+
* @param array $pParams The parameters to use for the POST body
|
499 |
+
* @param null|array $pWPRemoteArgs wp_remote_request options.
|
500 |
+
*
|
501 |
+
* @return object[]|object|null
|
502 |
+
*
|
503 |
+
* @throws Freemius_Exception
|
504 |
+
*/
|
505 |
+
public function MakeRequest(
|
506 |
+
$pCanonizedPath,
|
507 |
+
$pMethod = 'GET',
|
508 |
+
$pParams = array(),
|
509 |
+
$pWPRemoteArgs = null
|
510 |
+
) {
|
511 |
+
$resource = explode( '?', $pCanonizedPath );
|
512 |
+
|
513 |
+
// Only sign request if not ping.json connectivity test.
|
514 |
+
$sign_request = ( '/v1/ping.json' !== strtolower( substr( $resource[0], - strlen( '/v1/ping.json' ) ) ) );
|
515 |
+
|
516 |
+
return self::MakeStaticRequest(
|
517 |
+
$pCanonizedPath,
|
518 |
+
$pMethod,
|
519 |
+
$pParams,
|
520 |
+
$pWPRemoteArgs,
|
521 |
+
$this->_isSandbox,
|
522 |
+
$sign_request ? array( &$this, 'SignRequest' ) : null
|
523 |
+
);
|
524 |
+
}
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Sets CURLOPT_IPRESOLVE to CURL_IPRESOLVE_V4 for cURL-Handle provided as parameter
|
528 |
+
*
|
529 |
+
* @param resource $handle A cURL handle returned by curl_init()
|
530 |
+
*
|
531 |
+
* @return resource $handle A cURL handle returned by curl_init() with CURLOPT_IPRESOLVE set to
|
532 |
+
* CURL_IPRESOLVE_V4
|
533 |
+
*
|
534 |
+
* @link https://gist.github.com/golderweb/3a2aaec2d56125cc004e
|
535 |
+
*/
|
536 |
+
static function CurlResolveToIPv4( $handle ) {
|
537 |
+
curl_setopt( $handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
|
538 |
+
|
539 |
+
return $handle;
|
540 |
+
}
|
541 |
+
|
542 |
+
#----------------------------------------------------------------------------------
|
543 |
+
#region Connectivity Test
|
544 |
+
#----------------------------------------------------------------------------------
|
545 |
+
|
546 |
+
/**
|
547 |
+
* If successful connectivity to the API endpoint using ping.json endpoint.
|
548 |
+
*
|
549 |
+
* - OR -
|
550 |
+
*
|
551 |
+
* Validate if ping result object is valid.
|
552 |
+
*
|
553 |
+
* @param mixed $pPong
|
554 |
+
*
|
555 |
+
* @return bool
|
556 |
+
*/
|
557 |
+
public static function Test( $pPong = null ) {
|
558 |
+
$pong = is_null( $pPong ) ?
|
559 |
+
self::Ping() :
|
560 |
+
$pPong;
|
561 |
+
|
562 |
+
return (
|
563 |
+
is_object( $pong ) &&
|
564 |
+
isset( $pong->api ) &&
|
565 |
+
'pong' === $pong->api
|
566 |
+
);
|
567 |
+
}
|
568 |
+
|
569 |
+
/**
|
570 |
+
* Ping API to test connectivity.
|
571 |
+
*
|
572 |
+
* @return object
|
573 |
+
*/
|
574 |
+
public static function Ping() {
|
575 |
+
try {
|
576 |
+
$result = self::MakeStaticRequest( '/v' . FS_API__VERSION . '/ping.json' );
|
577 |
+
} catch ( Freemius_Exception $e ) {
|
578 |
+
// Map to error object.
|
579 |
+
$result = (object) $e->getResult();
|
580 |
+
} catch ( Exception $e ) {
|
581 |
+
// Map to error object.
|
582 |
+
$result = (object) array(
|
583 |
+
'error' => (object) array(
|
584 |
+
'type' => 'Unknown',
|
585 |
+
'message' => $e->getMessage() . ' (' . $e->getFile() . ': ' . $e->getLine() . ')',
|
586 |
+
'code' => 'unknown',
|
587 |
+
'http' => 402
|
588 |
+
)
|
589 |
+
);
|
590 |
+
}
|
591 |
+
|
592 |
+
return $result;
|
593 |
+
}
|
594 |
+
|
595 |
+
#endregion
|
596 |
+
|
597 |
+
#----------------------------------------------------------------------------------
|
598 |
+
#region Connectivity Exceptions
|
599 |
+
#----------------------------------------------------------------------------------
|
600 |
+
|
601 |
+
/**
|
602 |
+
* @param \WP_Error $pError
|
603 |
+
*
|
604 |
+
* @return bool
|
605 |
+
*/
|
606 |
+
private static function IsCurlError( WP_Error $pError ) {
|
607 |
+
$message = $pError->get_error_message( 'http_request_failed' );
|
608 |
+
|
609 |
+
return ( 0 === strpos( $message, 'cURL' ) );
|
610 |
+
}
|
611 |
+
|
612 |
+
/**
|
613 |
+
* @param WP_Error $pError
|
614 |
+
*
|
615 |
+
* @throws Freemius_Exception
|
616 |
+
*/
|
617 |
+
private static function ThrowWPRemoteException( WP_Error $pError ) {
|
618 |
+
if ( self::IsCurlError( $pError ) ) {
|
619 |
+
$message = $pError->get_error_message( 'http_request_failed' );
|
620 |
+
|
621 |
+
#region Check if there are any missing cURL methods.
|
622 |
+
|
623 |
+
$curl_required_methods = array(
|
624 |
+
'curl_version',
|
625 |
+
'curl_exec',
|
626 |
+
'curl_init',
|
627 |
+
'curl_close',
|
628 |
+
'curl_setopt',
|
629 |
+
'curl_setopt_array',
|
630 |
+
'curl_error',
|
631 |
+
);
|
632 |
+
|
633 |
+
// Find all missing methods.
|
634 |
+
$missing_methods = array();
|
635 |
+
foreach ( $curl_required_methods as $m ) {
|
636 |
+
if ( ! function_exists( $m ) ) {
|
637 |
+
$missing_methods[] = $m;
|
638 |
+
}
|
639 |
+
}
|
640 |
+
|
641 |
+
if ( ! empty( $missing_methods ) ) {
|
642 |
+
throw new Freemius_Exception( array(
|
643 |
+
'error' => (object) array(
|
644 |
+
'type' => 'cUrlMissing',
|
645 |
+
'message' => $message,
|
646 |
+
'code' => 'curl_missing',
|
647 |
+
'http' => 402
|
648 |
+
),
|
649 |
+
'missing_methods' => $missing_methods,
|
650 |
+
) );
|
651 |
+
}
|
652 |
+
|
653 |
+
#endregion
|
654 |
+
|
655 |
+
// cURL error - "cURL error {{errno}}: {{error}}".
|
656 |
+
$parts = explode( ':', substr( $message, strlen( 'cURL error ' ) ), 2 );
|
657 |
+
|
658 |
+
$code = ( 0 < count( $parts ) ) ? $parts[0] : 'http_request_failed';
|
659 |
+
$message = ( 1 < count( $parts ) ) ? $parts[1] : $message;
|
660 |
+
|
661 |
+
$e = new Freemius_Exception( array(
|
662 |
+
'error' => (object) array(
|
663 |
+
'code' => $code,
|
664 |
+
'message' => $message,
|
665 |
+
'type' => 'CurlException',
|
666 |
+
),
|
667 |
+
) );
|
668 |
+
} else {
|
669 |
+
$e = new Freemius_Exception( array(
|
670 |
+
'error' => (object) array(
|
671 |
+
'code' => $pError->get_error_code(),
|
672 |
+
'message' => $pError->get_error_message(),
|
673 |
+
'type' => 'WPRemoteException',
|
674 |
+
),
|
675 |
+
) );
|
676 |
+
}
|
677 |
+
|
678 |
+
throw $e;
|
679 |
+
}
|
680 |
+
|
681 |
+
/**
|
682 |
+
* @param string $pResult
|
683 |
+
*
|
684 |
+
* @throws Freemius_Exception
|
685 |
+
*/
|
686 |
+
private static function ThrowCloudFlareDDoSException( $pResult = '' ) {
|
687 |
+
throw new Freemius_Exception( array(
|
688 |
+
'error' => (object) array(
|
689 |
+
'type' => 'CloudFlareDDoSProtection',
|
690 |
+
'message' => $pResult,
|
691 |
+
'code' => 'cloudflare_ddos_protection',
|
692 |
+
'http' => 402
|
693 |
+
)
|
694 |
+
) );
|
695 |
+
}
|
696 |
+
|
697 |
+
/**
|
698 |
+
* @param string $pResult
|
699 |
+
*
|
700 |
+
* @throws Freemius_Exception
|
701 |
+
*/
|
702 |
+
private static function ThrowSquidAclException( $pResult = '' ) {
|
703 |
+
throw new Freemius_Exception( array(
|
704 |
+
'error' => (object) array(
|
705 |
+
'type' => 'SquidCacheBlock',
|
706 |
+
'message' => $pResult,
|
707 |
+
'code' => 'squid_cache_block',
|
708 |
+
'http' => 402
|
709 |
+
)
|
710 |
+
) );
|
711 |
+
}
|
712 |
+
|
713 |
+
#endregion
|
714 |
+
}
|
715 |
+
}
|
freemius/includes/supplements/fs-migration-2.5.1.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 2.5.1
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
if ( ! function_exists( 'fs_migrate_251' ) ) {
|
14 |
+
function fs_migrate_251( Freemius $fs, $install_by_blog_id ) {
|
15 |
+
$permission_manager = FS_Permission_Manager::instance( $fs );
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var FS_Site $install
|
19 |
+
*/
|
20 |
+
foreach ( $install_by_blog_id as $blog_id => $install ) {
|
21 |
+
if ( true === $install->is_disconnected ) {
|
22 |
+
$permission_manager->update_site_tracking(
|
23 |
+
false,
|
24 |
+
( 0 == $blog_id ) ? null : $blog_id,
|
25 |
+
// Update only if permissions are not yet set.
|
26 |
+
true
|
27 |
+
);
|
28 |
+
}
|
29 |
+
}
|
30 |
+
}
|
31 |
+
}
|
freemius/languages/freemius-cs_CZ.mo
CHANGED
Binary file
|
freemius/languages/freemius-da_DK.mo
CHANGED
Binary file
|
freemius/languages/freemius-de_DE.mo
ADDED
Binary file
|
freemius/languages/freemius-en.mo
CHANGED
Binary file
|
freemius/languages/freemius-es_ES.mo
CHANGED
Binary file
|
freemius/languages/freemius-fr_FR.mo
CHANGED
Binary file
|
freemius/languages/freemius-he_IL.mo
CHANGED
Binary file
|
freemius/languages/freemius-hu_HU.mo
CHANGED
Binary file
|
freemius/languages/freemius-it_IT.mo
CHANGED
Binary file
|
freemius/languages/freemius-ja.mo
CHANGED
Binary file
|
freemius/languages/freemius-nl_NL.mo
CHANGED
Binary file
|
freemius/languages/freemius-ru_RU.mo
CHANGED
Binary file
|
freemius/languages/freemius-ta.mo
CHANGED
Binary file
|
freemius/languages/freemius-zh_CN.mo
CHANGED
Binary file
|
freemius/languages/freemius.pot
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
# Copyright (C)
|
2 |
# This file is distributed under the same license as the freemius package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
@@ -16,795 +16,807 @@ msgstr ""
|
|
16 |
"X-Poedit-SourceCharset: UTF-8\n"
|
17 |
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
18 |
|
19 |
-
#: includes/class-freemius.php:
|
20 |
msgid "An update to a Beta version will replace your installed version of %s with the latest Beta release - use with caution, and not on production sites. You have been warned."
|
21 |
msgstr ""
|
22 |
|
23 |
-
#: includes/class-freemius.php:
|
24 |
msgid "Would you like to proceed with the update?"
|
25 |
msgstr ""
|
26 |
|
27 |
-
#: includes/class-freemius.php:
|
28 |
msgid "Freemius SDK couldn't find the plugin's main file. Please contact sdk@freemius.com with the current error."
|
29 |
msgstr ""
|
30 |
|
31 |
-
#: includes/class-freemius.php:
|
32 |
msgid "Error"
|
33 |
msgstr ""
|
34 |
|
35 |
-
#: includes/class-freemius.php:
|
36 |
msgid "I found a better %s"
|
37 |
msgstr ""
|
38 |
|
39 |
-
#: includes/class-freemius.php:
|
40 |
msgid "What's the %s's name?"
|
41 |
msgstr ""
|
42 |
|
43 |
-
#: includes/class-freemius.php:
|
44 |
-
msgid "It's a temporary %s
|
45 |
msgstr ""
|
46 |
|
47 |
-
#: includes/class-freemius.php:
|
48 |
msgid "Deactivation"
|
49 |
msgstr ""
|
50 |
|
51 |
-
#: includes/class-freemius.php:
|
52 |
msgid "Theme Switch"
|
53 |
msgstr ""
|
54 |
|
55 |
-
#: includes/class-freemius.php:
|
56 |
msgid "Other"
|
57 |
msgstr ""
|
58 |
|
59 |
-
#: includes/class-freemius.php:
|
60 |
msgid "I no longer need the %s"
|
61 |
msgstr ""
|
62 |
|
63 |
-
#: includes/class-freemius.php:
|
64 |
msgid "I only needed the %s for a short period"
|
65 |
msgstr ""
|
66 |
|
67 |
-
#: includes/class-freemius.php:
|
68 |
msgid "The %s broke my site"
|
69 |
msgstr ""
|
70 |
|
71 |
-
#: includes/class-freemius.php:
|
72 |
msgid "The %s suddenly stopped working"
|
73 |
msgstr ""
|
74 |
|
75 |
-
#: includes/class-freemius.php:
|
76 |
msgid "I can't pay for it anymore"
|
77 |
msgstr ""
|
78 |
|
79 |
-
#: includes/class-freemius.php:
|
80 |
msgid "What price would you feel comfortable paying?"
|
81 |
msgstr ""
|
82 |
|
83 |
-
#: includes/class-freemius.php:
|
84 |
msgid "I don't like to share my information with you"
|
85 |
msgstr ""
|
86 |
|
87 |
-
#: includes/class-freemius.php:
|
88 |
msgid "The %s didn't work"
|
89 |
msgstr ""
|
90 |
|
91 |
-
#: includes/class-freemius.php:
|
92 |
msgid "I couldn't understand how to make it work"
|
93 |
msgstr ""
|
94 |
|
95 |
-
#: includes/class-freemius.php:
|
96 |
msgid "The %s is great, but I need specific feature that you don't support"
|
97 |
msgstr ""
|
98 |
|
99 |
-
#: includes/class-freemius.php:
|
100 |
msgid "What feature?"
|
101 |
msgstr ""
|
102 |
|
103 |
-
#: includes/class-freemius.php:
|
104 |
msgid "The %s is not working"
|
105 |
msgstr ""
|
106 |
|
107 |
-
#: includes/class-freemius.php:
|
108 |
msgid "Kindly share what didn't work so we can fix it for future users..."
|
109 |
msgstr ""
|
110 |
|
111 |
-
#: includes/class-freemius.php:
|
112 |
msgid "It's not what I was looking for"
|
113 |
msgstr ""
|
114 |
|
115 |
-
#: includes/class-freemius.php:
|
116 |
msgid "What you've been looking for?"
|
117 |
msgstr ""
|
118 |
|
119 |
-
#: includes/class-freemius.php:
|
120 |
msgid "The %s didn't work as expected"
|
121 |
msgstr ""
|
122 |
|
123 |
-
#: includes/class-freemius.php:
|
124 |
msgid "What did you expect?"
|
125 |
msgstr ""
|
126 |
|
127 |
-
#: includes/class-freemius.php:
|
128 |
msgid "Freemius Debug"
|
129 |
msgstr ""
|
130 |
|
131 |
-
#: includes/class-freemius.php:
|
132 |
msgid "I don't know what is cURL or how to install it, help me!"
|
133 |
msgstr ""
|
134 |
|
135 |
-
#: includes/class-freemius.php:
|
136 |
msgid "We'll make sure to contact your hosting company and resolve the issue. You will get a follow-up email to %s once we have an update."
|
137 |
msgstr ""
|
138 |
|
139 |
-
#: includes/class-freemius.php:
|
140 |
msgid "Great, please install cURL and enable it in your php.ini file. In addition, search for the 'disable_functions' directive in your php.ini file and remove any disabled methods starting with 'curl_'. To make sure it was successfully activated, use 'phpinfo()'. Once activated, deactivate the %s and reactivate it back again."
|
141 |
msgstr ""
|
142 |
|
143 |
-
#: includes/class-freemius.php:
|
144 |
msgid "Yes - do your thing"
|
145 |
msgstr ""
|
146 |
|
147 |
-
#: includes/class-freemius.php:
|
148 |
msgid "No - just deactivate"
|
149 |
msgstr ""
|
150 |
|
151 |
-
#: includes/class-freemius.php:
|
152 |
msgctxt "exclamation"
|
153 |
msgid "Oops"
|
154 |
msgstr ""
|
155 |
|
156 |
-
#: includes/class-freemius.php:
|
157 |
msgid "Thank for giving us the chance to fix it! A message was just sent to our technical staff. We will get back to you as soon as we have an update to %s. Appreciate your patience."
|
158 |
msgstr ""
|
159 |
|
160 |
-
#: includes/class-freemius.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
msgctxt "addonX cannot run without pluginY"
|
162 |
msgid "%s cannot run without %s."
|
163 |
msgstr ""
|
164 |
|
165 |
-
#: includes/class-freemius.php:
|
166 |
msgctxt "addonX cannot run..."
|
167 |
msgid "%s cannot run without the plugin."
|
168 |
msgstr ""
|
169 |
|
170 |
-
#: includes/class-freemius.php:
|
171 |
-
msgid "
|
172 |
msgstr ""
|
173 |
|
174 |
-
#: includes/class-freemius.php:
|
175 |
msgid "Premium %s version was successfully activated."
|
176 |
msgstr ""
|
177 |
|
178 |
-
#: includes/class-freemius.php:
|
179 |
msgctxt "Used to express elation, enthusiasm, or triumph (especially in electronic communication)."
|
180 |
msgid "W00t"
|
181 |
msgstr ""
|
182 |
|
183 |
-
#: includes/class-freemius.php:
|
184 |
msgid "You have a %s license."
|
185 |
msgstr ""
|
186 |
|
187 |
-
#: includes/class-freemius.php:
|
188 |
-
msgctxt "interjection expressing joy or exuberance"
|
189 |
-
msgid "Yee-haw"
|
190 |
-
msgstr ""
|
191 |
-
|
192 |
-
#: includes/class-freemius.php:6174
|
193 |
msgid "%s free trial was successfully cancelled. Since the add-on is premium only it was automatically deactivated. If you like to use it in the future, you'll have to purchase a license."
|
194 |
msgstr ""
|
195 |
|
196 |
-
#: includes/class-freemius.php:
|
197 |
msgid "%s is a premium only add-on. You have to purchase a license first before activating the plugin."
|
198 |
msgstr ""
|
199 |
|
200 |
-
#: includes/class-freemius.php:
|
201 |
msgid "More information about %s"
|
202 |
msgstr ""
|
203 |
|
204 |
-
#: includes/class-freemius.php:
|
205 |
msgid "Purchase License"
|
206 |
msgstr ""
|
207 |
|
208 |
-
#: includes/class-freemius.php:
|
209 |
-
msgid "You should receive
|
210 |
msgstr ""
|
211 |
|
212 |
-
#: includes/class-freemius.php:
|
213 |
msgid "start the trial"
|
214 |
msgstr ""
|
215 |
|
216 |
-
#: includes/class-freemius.php:
|
217 |
-
msgid "complete the
|
218 |
msgstr ""
|
219 |
|
220 |
-
#: includes/class-freemius.php:
|
221 |
msgid "You are just one step away - %s"
|
222 |
msgstr ""
|
223 |
|
224 |
-
#: includes/class-freemius.php:
|
225 |
msgctxt "%s - plugin name. As complete \"PluginX\" activation now"
|
226 |
msgid "Complete \"%s\" Activation Now"
|
227 |
msgstr ""
|
228 |
|
229 |
-
#: includes/class-freemius.php:
|
230 |
msgid "We made a few tweaks to the %s, %s"
|
231 |
msgstr ""
|
232 |
|
233 |
-
#: includes/class-freemius.php:
|
234 |
msgid "Opt in to make \"%s\" better!"
|
235 |
msgstr ""
|
236 |
|
237 |
-
#: includes/class-freemius.php:
|
238 |
msgid "The upgrade of %s was successfully completed."
|
239 |
msgstr ""
|
240 |
|
241 |
-
#: includes/class-freemius.php:
|
242 |
msgid "Add-On"
|
243 |
msgstr ""
|
244 |
|
245 |
-
#: includes/class-freemius.php:
|
246 |
msgid "Plugin"
|
247 |
msgstr ""
|
248 |
|
249 |
-
#: includes/class-freemius.php:
|
250 |
msgid "Theme"
|
251 |
msgstr ""
|
252 |
|
253 |
-
#: includes/class-freemius.php:
|
254 |
msgid "An unknown error has occurred while trying to toggle the license's white-label mode."
|
255 |
msgstr ""
|
256 |
|
257 |
-
#: includes/class-freemius.php:
|
258 |
msgid "Your %s license was flagged as white-labeled to hide sensitive information from the WP Admin (e.g. your email, license key, prices, billing address & invoices). If you ever wish to revert it back, you can easily do it through your %s. If this was a mistake you can also %s."
|
259 |
msgstr ""
|
260 |
|
261 |
-
#: includes/class-freemius.php:
|
262 |
msgid "User Dashboard"
|
263 |
msgstr ""
|
264 |
|
265 |
-
#: includes/class-freemius.php:
|
266 |
msgid "revert it now"
|
267 |
msgstr ""
|
268 |
|
269 |
-
#: includes/class-freemius.php:
|
270 |
msgid "An unknown error has occurred while trying to set the user's beta mode."
|
271 |
msgstr ""
|
272 |
|
273 |
-
#: includes/class-freemius.php:
|
274 |
msgid "Invalid new user ID or email address."
|
275 |
msgstr ""
|
276 |
|
277 |
-
#: includes/class-freemius.php:
|
278 |
msgid "Sorry, we could not complete the email update. Another user with the same email is already registered."
|
279 |
msgstr ""
|
280 |
|
281 |
-
#: includes/class-freemius.php:
|
282 |
msgid "If you would like to give up the ownership of the %s's account to %s click the Change Ownership button."
|
283 |
msgstr ""
|
284 |
|
285 |
-
#: includes/class-freemius.php:
|
286 |
msgid "Change Ownership"
|
287 |
msgstr ""
|
288 |
|
289 |
-
#: includes/class-freemius.php:
|
290 |
msgid "Invalid site details collection."
|
291 |
msgstr ""
|
292 |
|
293 |
-
#: includes/class-freemius.php:
|
294 |
msgid "We couldn't find your email address in the system, are you sure it's the right address?"
|
295 |
msgstr ""
|
296 |
|
297 |
-
#: includes/class-freemius.php:
|
298 |
msgid "We can't see any active licenses associated with that email address, are you sure it's the right address?"
|
299 |
msgstr ""
|
300 |
|
301 |
-
#: includes/class-freemius.php:
|
302 |
-
msgid "Account is pending activation."
|
303 |
msgstr ""
|
304 |
|
305 |
-
#: includes/class-freemius.php:
|
306 |
msgid "Buy a license now"
|
307 |
msgstr ""
|
308 |
|
309 |
-
#: includes/class-freemius.php:
|
310 |
msgid "Renew your license now"
|
311 |
msgstr ""
|
312 |
|
313 |
-
#: includes/class-freemius.php:
|
314 |
msgid "%s to access version %s security & feature updates, and support."
|
315 |
msgstr ""
|
316 |
|
317 |
-
#: includes/class-freemius.php:
|
318 |
-
msgid "%s
|
319 |
msgstr ""
|
320 |
|
321 |
-
#: includes/class-freemius.php:
|
322 |
msgid "Your account was successfully activated with the %s plan."
|
323 |
msgstr ""
|
324 |
|
325 |
-
#: includes/class-freemius.php:
|
326 |
msgid "Your trial has been successfully started."
|
327 |
msgstr ""
|
328 |
|
329 |
-
#: includes/class-freemius.php:
|
330 |
msgid "Couldn't activate %s."
|
331 |
msgstr ""
|
332 |
|
333 |
-
#: includes/class-freemius.php:
|
334 |
msgid "Please contact us with the following message:"
|
335 |
msgstr ""
|
336 |
|
337 |
-
#: includes/class-freemius.php:
|
338 |
msgid "An unknown error has occurred."
|
339 |
msgstr ""
|
340 |
|
341 |
-
#: includes/class-freemius.php:
|
342 |
msgid "Upgrade"
|
343 |
msgstr ""
|
344 |
|
345 |
-
#: includes/class-freemius.php:
|
346 |
msgid "Start Trial"
|
347 |
msgstr ""
|
348 |
|
349 |
-
#: includes/class-freemius.php:
|
350 |
msgid "Pricing"
|
351 |
msgstr ""
|
352 |
|
353 |
-
#: includes/class-freemius.php:
|
354 |
msgid "Affiliation"
|
355 |
msgstr ""
|
356 |
|
357 |
-
#: includes/class-freemius.php:
|
358 |
msgid "Account"
|
359 |
msgstr ""
|
360 |
|
361 |
-
#: includes/class-freemius.php:
|
362 |
msgid "Contact Us"
|
363 |
msgstr ""
|
364 |
|
365 |
-
#: includes/class-freemius.php:
|
366 |
msgid "Add-Ons"
|
367 |
msgstr ""
|
368 |
|
369 |
-
#: includes/class-freemius.php:
|
370 |
msgctxt "ASCII arrow left icon"
|
371 |
msgid "←"
|
372 |
msgstr ""
|
373 |
|
374 |
-
#: includes/class-freemius.php:
|
375 |
msgctxt "ASCII arrow right icon"
|
376 |
msgid "➤"
|
377 |
msgstr ""
|
378 |
|
379 |
-
#: includes/class-freemius.php:
|
380 |
msgctxt "noun"
|
381 |
msgid "Pricing"
|
382 |
msgstr ""
|
383 |
|
384 |
-
#: includes/class-freemius.php:
|
385 |
msgid "Support Forum"
|
386 |
msgstr ""
|
387 |
|
388 |
-
#: includes/class-freemius.php:
|
389 |
msgid "Your email has been successfully verified - you are AWESOME!"
|
390 |
msgstr ""
|
391 |
|
392 |
-
#: includes/class-freemius.php:
|
393 |
msgctxt "a positive response"
|
394 |
msgid "Right on"
|
395 |
msgstr ""
|
396 |
|
397 |
-
#: includes/class-freemius.php:
|
398 |
msgid "seems like the key you entered doesn't match our records."
|
399 |
msgstr ""
|
400 |
|
401 |
-
#: includes/class-freemius.php:
|
402 |
msgid "Debug mode was successfully enabled and will be automatically disabled in 60 min. You can also disable it earlier by clicking the \"Stop Debug\" link."
|
403 |
msgstr ""
|
404 |
|
405 |
-
#: includes/class-freemius.php:
|
406 |
msgid "Your %s Add-on plan was successfully upgraded."
|
407 |
msgstr ""
|
408 |
|
409 |
-
#: includes/class-freemius.php:
|
410 |
msgid "%s Add-on was successfully purchased."
|
411 |
msgstr ""
|
412 |
|
413 |
-
#: includes/class-freemius.php:
|
414 |
msgid "Download the latest version"
|
415 |
msgstr ""
|
416 |
|
417 |
-
#: includes/class-freemius.php:
|
418 |
msgid "Your server is blocking the access to Freemius' API, which is crucial for %1$s synchronization. Please contact your host to whitelist %2$s"
|
419 |
msgstr ""
|
420 |
|
421 |
-
#: includes/class-freemius.php:
|
422 |
msgid "Error received from the server:"
|
423 |
msgstr ""
|
424 |
|
425 |
-
#: includes/class-freemius.php:
|
426 |
msgid "It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again."
|
427 |
msgstr ""
|
428 |
|
429 |
-
#: includes/class-freemius.php:
|
430 |
msgctxt "something somebody says when they are thinking about what you have just said."
|
431 |
msgid "Hmm"
|
432 |
msgstr ""
|
433 |
|
434 |
-
#: includes/class-freemius.php:
|
435 |
msgid "It looks like you are still on the %s plan. If you did upgrade or change your plan, it's probably an issue on our side - sorry."
|
436 |
msgstr ""
|
437 |
|
438 |
-
#: includes/class-freemius.php:
|
439 |
msgctxt "trial period"
|
440 |
msgid "Trial"
|
441 |
msgstr ""
|
442 |
|
443 |
-
#: includes/class-freemius.php:
|
444 |
msgid "I have upgraded my account but when I try to Sync the License, the plan remains %s."
|
445 |
msgstr ""
|
446 |
|
447 |
-
#: includes/class-freemius.php:
|
448 |
msgid "Please contact us here"
|
449 |
msgstr ""
|
450 |
|
451 |
-
#: includes/class-freemius.php:
|
452 |
msgid "Your plan was successfully activated."
|
453 |
msgstr ""
|
454 |
|
455 |
-
#: includes/class-freemius.php:
|
456 |
msgid "Your plan was successfully upgraded."
|
457 |
msgstr ""
|
458 |
|
459 |
-
#: includes/class-freemius.php:
|
460 |
msgid "Your plan was successfully changed to %s."
|
461 |
msgstr ""
|
462 |
|
463 |
-
#: includes/class-freemius.php:
|
464 |
msgid "Your license has expired. You can still continue using the free %s forever."
|
465 |
msgstr ""
|
466 |
|
467 |
-
#: includes/class-freemius.php:
|
468 |
msgid "Your license has expired. %1$sUpgrade now%2$s to continue using the %3$s without interruptions."
|
469 |
msgstr ""
|
470 |
|
471 |
-
#: includes/class-freemius.php:
|
472 |
msgid "Your license has been cancelled. If you think it's a mistake, please contact support."
|
473 |
msgstr ""
|
474 |
|
475 |
-
#: includes/class-freemius.php:
|
476 |
msgid "Your license has expired. You can still continue using all the %s features, but you'll need to renew your license to continue getting updates and support."
|
477 |
msgstr ""
|
478 |
|
479 |
-
#: includes/class-freemius.php:
|
480 |
msgid "Your free trial has expired. You can still continue using all our free features."
|
481 |
msgstr ""
|
482 |
|
483 |
-
#: includes/class-freemius.php:
|
484 |
msgid "Your free trial has expired. %1$sUpgrade now%2$s to continue using the %3$s without interruptions."
|
485 |
msgstr ""
|
486 |
|
487 |
-
#: includes/class-freemius.php:
|
488 |
msgid "It looks like the license could not be activated."
|
489 |
msgstr ""
|
490 |
|
491 |
-
#: includes/class-freemius.php:
|
492 |
msgid "Your license was successfully activated."
|
493 |
msgstr ""
|
494 |
|
495 |
-
#: includes/class-freemius.php:
|
496 |
msgid "It looks like your site currently doesn't have an active license."
|
497 |
msgstr ""
|
498 |
|
499 |
-
#: includes/class-freemius.php:
|
500 |
msgid "It looks like the license deactivation failed."
|
501 |
msgstr ""
|
502 |
|
503 |
-
#: includes/class-freemius.php:
|
504 |
msgid "Your %s license was successfully deactivated."
|
505 |
msgstr ""
|
506 |
|
507 |
-
#: includes/class-freemius.php:
|
508 |
msgid "Your license was successfully deactivated, you are back to the %s plan."
|
509 |
msgstr ""
|
510 |
|
511 |
-
#: includes/class-freemius.php:
|
512 |
msgid "O.K"
|
513 |
msgstr ""
|
514 |
|
515 |
-
#: includes/class-freemius.php:
|
516 |
msgid "Seems like we are having some temporary issue with your subscription cancellation. Please try again in few minutes."
|
517 |
msgstr ""
|
518 |
|
519 |
-
#: includes/class-freemius.php:
|
520 |
msgid "Your subscription was successfully cancelled. Your %s plan license will expire in %s."
|
521 |
msgstr ""
|
522 |
|
523 |
-
#: includes/class-freemius.php:
|
524 |
msgid "You are already running the %s in a trial mode."
|
525 |
msgstr ""
|
526 |
|
527 |
-
#: includes/class-freemius.php:
|
528 |
msgid "You already utilized a trial before."
|
529 |
msgstr ""
|
530 |
|
531 |
-
#: includes/class-freemius.php:
|
532 |
msgid "Plan %s do not exist, therefore, can't start a trial."
|
533 |
msgstr ""
|
534 |
|
535 |
-
#: includes/class-freemius.php:
|
536 |
msgid "Plan %s does not support a trial period."
|
537 |
msgstr ""
|
538 |
|
539 |
-
#: includes/class-freemius.php:
|
540 |
msgid "None of the %s's plans supports a trial period."
|
541 |
msgstr ""
|
542 |
|
543 |
-
#: includes/class-freemius.php:
|
544 |
msgid "It looks like you are not in trial mode anymore so there's nothing to cancel :)"
|
545 |
msgstr ""
|
546 |
|
547 |
-
#: includes/class-freemius.php:
|
548 |
msgid "Seems like we are having some temporary issue with your trial cancellation. Please try again in few minutes."
|
549 |
msgstr ""
|
550 |
|
551 |
-
#: includes/class-freemius.php:
|
552 |
msgid "Your %s free trial was successfully cancelled."
|
553 |
msgstr ""
|
554 |
|
555 |
-
#: includes/class-freemius.php:
|
556 |
msgid "Version %s was released."
|
557 |
msgstr ""
|
558 |
|
559 |
-
#: includes/class-freemius.php:
|
560 |
msgid "Please download %s."
|
561 |
msgstr ""
|
562 |
|
563 |
-
#: includes/class-freemius.php:
|
564 |
msgid "the latest %s version here"
|
565 |
msgstr ""
|
566 |
|
567 |
-
#: includes/class-freemius.php:
|
568 |
msgid "New"
|
569 |
msgstr ""
|
570 |
|
571 |
-
#: includes/class-freemius.php:
|
572 |
msgid "Seems like you got the latest release."
|
573 |
msgstr ""
|
574 |
|
575 |
-
#: includes/class-freemius.php:
|
576 |
msgid "You are all good!"
|
577 |
msgstr ""
|
578 |
|
579 |
-
#: includes/class-freemius.php:
|
580 |
msgid "Verification mail was just sent to %s. If you can't find it after 5 min, please check your spam box."
|
581 |
msgstr ""
|
582 |
|
583 |
-
#: includes/class-freemius.php:
|
584 |
msgid "Site successfully opted in."
|
585 |
msgstr ""
|
586 |
|
587 |
-
#: includes/class-freemius.php:
|
588 |
msgid "Awesome"
|
589 |
msgstr ""
|
590 |
|
591 |
-
#: includes/class-freemius.php:
|
592 |
-
msgid "
|
593 |
msgstr ""
|
594 |
|
595 |
-
#: includes/class-freemius.php:
|
596 |
msgid "Thank you!"
|
597 |
msgstr ""
|
598 |
|
599 |
-
#: includes/class-freemius.php:
|
600 |
-
msgid "
|
601 |
msgstr ""
|
602 |
|
603 |
-
#: includes/class-freemius.php:
|
604 |
-
msgid "
|
605 |
msgstr ""
|
606 |
|
607 |
-
#: includes/class-freemius.php:
|
|
|
|
|
|
|
|
|
608 |
msgid "Thanks for confirming the ownership change. An email was just sent to %s for final approval."
|
609 |
msgstr ""
|
610 |
|
611 |
-
#: includes/class-freemius.php:
|
612 |
msgid "%s is the new owner of the account."
|
613 |
msgstr ""
|
614 |
|
615 |
-
#: includes/class-freemius.php:
|
616 |
msgctxt "as congratulations"
|
617 |
msgid "Congrats"
|
618 |
msgstr ""
|
619 |
|
620 |
-
#: includes/class-freemius.php:
|
621 |
-
msgid "Your email was successfully updated. You should receive an email with confirmation instructions in few moments."
|
622 |
-
msgstr ""
|
623 |
-
|
624 |
-
#: includes/class-freemius.php:22287
|
625 |
msgid "Please provide your full name."
|
626 |
msgstr ""
|
627 |
|
628 |
-
#: includes/class-freemius.php:
|
629 |
msgid "Your name was successfully updated."
|
630 |
msgstr ""
|
631 |
|
632 |
-
#: includes/class-freemius.php:
|
633 |
msgid "You have successfully updated your %s."
|
634 |
msgstr ""
|
635 |
|
636 |
-
#: includes/class-freemius.php:
|
637 |
msgid "Is this your client's site? %s if you wish to hide sensitive info like your email, license key, prices, billing address & invoices from the WP Admin."
|
638 |
msgstr ""
|
639 |
|
640 |
-
#: includes/class-freemius.php:
|
641 |
msgid "Click here"
|
642 |
msgstr ""
|
643 |
|
644 |
-
#: includes/class-freemius.php:
|
|
|
|
|
|
|
|
|
645 |
msgid "Just letting you know that the add-ons information of %s is being pulled from an external server."
|
646 |
msgstr ""
|
647 |
|
648 |
-
#: includes/class-freemius.php:
|
649 |
msgctxt "advance notice of something that will need attention."
|
650 |
msgid "Heads up"
|
651 |
msgstr ""
|
652 |
|
653 |
-
#: includes/class-freemius.php:
|
654 |
msgctxt "exclamation"
|
655 |
msgid "Hey"
|
656 |
msgstr ""
|
657 |
|
658 |
-
#: includes/class-freemius.php:
|
659 |
msgid "How do you like %s so far? Test all our %s premium features with a %d-day free trial."
|
660 |
msgstr ""
|
661 |
|
662 |
-
#: includes/class-freemius.php:
|
663 |
msgid "No commitment for %s days - cancel anytime!"
|
664 |
msgstr ""
|
665 |
|
666 |
-
#: includes/class-freemius.php:
|
667 |
msgid "No credit card required"
|
668 |
msgstr ""
|
669 |
|
670 |
-
#: includes/class-freemius.php:
|
671 |
msgctxt "call to action"
|
672 |
msgid "Start free trial"
|
673 |
msgstr ""
|
674 |
|
675 |
-
#: includes/class-freemius.php:
|
676 |
msgid "Hey there, did you know that %s has an affiliate program? If you like the %s you can become our ambassador and earn some cash!"
|
677 |
msgstr ""
|
678 |
|
679 |
-
#: includes/class-freemius.php:
|
680 |
msgid "Learn more"
|
681 |
msgstr ""
|
682 |
|
683 |
-
#: includes/class-freemius.php:
|
684 |
msgid "Activate License"
|
685 |
msgstr ""
|
686 |
|
687 |
-
#: includes/class-freemius.php:
|
688 |
msgid "Change License"
|
689 |
msgstr ""
|
690 |
|
691 |
-
#: includes/class-freemius.php:
|
692 |
msgid "Opt Out"
|
693 |
msgstr ""
|
694 |
|
695 |
-
#: includes/class-freemius.php:
|
696 |
msgid "Opt In"
|
697 |
msgstr ""
|
698 |
|
699 |
-
#: includes/class-freemius.php:
|
700 |
msgid " The paid version of %1$s is already installed. Please activate it to start benefiting the %2$s features. %3$s"
|
701 |
msgstr ""
|
702 |
|
703 |
-
#: includes/class-freemius.php:
|
704 |
msgid "Activate %s features"
|
705 |
msgstr ""
|
706 |
|
707 |
-
#: includes/class-freemius.php:
|
708 |
msgid "Please follow these steps to complete the upgrade"
|
709 |
msgstr ""
|
710 |
|
711 |
-
#: includes/class-freemius.php:
|
712 |
msgid "Download the latest %s version"
|
713 |
msgstr ""
|
714 |
|
715 |
-
#: includes/class-freemius.php:
|
716 |
msgid "Upload and activate the downloaded version"
|
717 |
msgstr ""
|
718 |
|
719 |
-
#: includes/class-freemius.php:
|
720 |
msgid "How to upload and activate?"
|
721 |
msgstr ""
|
722 |
|
723 |
-
#: includes/class-freemius.php:
|
724 |
msgid "%sClick here%s to choose the sites where you'd like to activate the license on."
|
725 |
msgstr ""
|
726 |
|
727 |
-
#: includes/class-freemius.php:
|
728 |
msgid "Auto installation only works for opted-in users."
|
729 |
msgstr ""
|
730 |
|
731 |
-
#: includes/class-freemius.php:
|
732 |
msgid "Invalid module ID."
|
733 |
msgstr ""
|
734 |
|
735 |
-
#: includes/class-freemius.php:
|
736 |
msgid "Premium version already active."
|
737 |
msgstr ""
|
738 |
|
739 |
-
#: includes/class-freemius.php:
|
740 |
msgid "You do not have a valid license to access the premium version."
|
741 |
msgstr ""
|
742 |
|
743 |
-
#: includes/class-freemius.php:
|
744 |
msgid "Plugin is a \"Serviceware\" which means it does not have a premium code version."
|
745 |
msgstr ""
|
746 |
|
747 |
-
#: includes/class-freemius.php:
|
748 |
msgid "Premium add-on version already installed."
|
749 |
msgstr ""
|
750 |
|
751 |
-
#: includes/class-freemius.php:
|
752 |
msgid "View paid features"
|
753 |
msgstr ""
|
754 |
|
755 |
-
#: includes/class-freemius.php:
|
756 |
msgid "Thank you so much for using %s and its add-ons!"
|
757 |
msgstr ""
|
758 |
|
759 |
-
#: includes/class-freemius.php:
|
760 |
msgid "Thank you so much for using %s!"
|
761 |
msgstr ""
|
762 |
|
763 |
-
#: includes/class-freemius.php:
|
764 |
msgid "You've already opted-in to our usage-tracking, which helps us keep improving the %s."
|
765 |
msgstr ""
|
766 |
|
767 |
-
#: includes/class-freemius.php:
|
768 |
msgid "Thank you so much for using our products!"
|
769 |
msgstr ""
|
770 |
|
771 |
-
#: includes/class-freemius.php:
|
772 |
msgid "You've already opted-in to our usage-tracking, which helps us keep improving them."
|
773 |
msgstr ""
|
774 |
|
775 |
-
#: includes/class-freemius.php:
|
776 |
msgid "%s and its add-ons"
|
777 |
msgstr ""
|
778 |
|
779 |
-
#: includes/class-freemius.php:
|
780 |
msgid "Products"
|
781 |
msgstr ""
|
782 |
|
783 |
-
#: includes/class-freemius.php:
|
784 |
msgid "Yes"
|
785 |
msgstr ""
|
786 |
|
787 |
-
#: includes/class-freemius.php:
|
788 |
msgid "send me security & feature updates, educational content and offers."
|
789 |
msgstr ""
|
790 |
|
791 |
-
#: includes/class-freemius.php:
|
792 |
msgid "No"
|
793 |
msgstr ""
|
794 |
|
795 |
-
#: includes/class-freemius.php:
|
796 |
msgid "do %sNOT%s send me security & feature updates, educational content and offers."
|
797 |
msgstr ""
|
798 |
|
799 |
-
#: includes/class-freemius.php:
|
800 |
msgid "Due to the new %sEU General Data Protection Regulation (GDPR)%s compliance requirements it is required that you provide your explicit consent, again, confirming that you are onboard :-)"
|
801 |
msgstr ""
|
802 |
|
803 |
-
#: includes/class-freemius.php:
|
804 |
msgid "Please let us know if you'd like us to contact you for security & feature updates, educational content, and occasional offers:"
|
805 |
msgstr ""
|
806 |
|
807 |
-
#: includes/class-freemius.php:
|
808 |
msgid "License key is empty."
|
809 |
msgstr ""
|
810 |
|
@@ -816,620 +828,620 @@ msgstr ""
|
|
816 |
msgid "Buy license"
|
817 |
msgstr ""
|
818 |
|
819 |
-
#: includes/class-fs-plugin-updater.php:
|
820 |
msgid "There is a %s of %s available."
|
821 |
msgstr ""
|
822 |
|
823 |
-
#: includes/class-fs-plugin-updater.php:
|
824 |
msgid "new Beta version"
|
825 |
msgstr ""
|
826 |
|
827 |
-
#: includes/class-fs-plugin-updater.php:
|
828 |
msgid "new version"
|
829 |
msgstr ""
|
830 |
|
831 |
-
#: includes/class-fs-plugin-updater.php:
|
832 |
msgid "Important Upgrade Notice:"
|
833 |
msgstr ""
|
834 |
|
835 |
-
#: includes/class-fs-plugin-updater.php:
|
836 |
msgid "Installing plugin: %s"
|
837 |
msgstr ""
|
838 |
|
839 |
-
#: includes/class-fs-plugin-updater.php:
|
840 |
msgid "Unable to connect to the filesystem. Please confirm your credentials."
|
841 |
msgstr ""
|
842 |
|
843 |
-
#: includes/class-fs-plugin-updater.php:
|
844 |
msgid "The remote plugin package does not contain a folder with the desired slug and renaming did not work."
|
845 |
msgstr ""
|
846 |
|
847 |
-
#: includes/fs-plugin-info-dialog.php:
|
848 |
msgid "Purchase More"
|
849 |
msgstr ""
|
850 |
|
851 |
-
#: includes/fs-plugin-info-dialog.php:
|
852 |
msgctxt "verb"
|
853 |
msgid "Purchase"
|
854 |
msgstr ""
|
855 |
|
856 |
-
#: includes/fs-plugin-info-dialog.php:
|
857 |
msgid "Start my free %s"
|
858 |
msgstr ""
|
859 |
|
860 |
-
#: includes/fs-plugin-info-dialog.php:
|
861 |
msgid "Install Free Version Update Now"
|
862 |
msgstr ""
|
863 |
|
864 |
-
#: includes/fs-plugin-info-dialog.php:
|
865 |
msgid "Install Update Now"
|
866 |
msgstr ""
|
867 |
|
868 |
-
#: includes/fs-plugin-info-dialog.php:
|
869 |
msgid "Install Free Version Now"
|
870 |
msgstr ""
|
871 |
|
872 |
-
#: includes/fs-plugin-info-dialog.php:
|
873 |
msgid "Install Now"
|
874 |
msgstr ""
|
875 |
|
876 |
-
#: includes/fs-plugin-info-dialog.php:
|
877 |
msgctxt "as download latest version"
|
878 |
msgid "Download Latest Free Version"
|
879 |
msgstr ""
|
880 |
|
881 |
-
#: includes/fs-plugin-info-dialog.php:
|
882 |
msgctxt "as download latest version"
|
883 |
msgid "Download Latest"
|
884 |
msgstr ""
|
885 |
|
886 |
-
#: includes/fs-plugin-info-dialog.php:
|
887 |
msgid "Activate this add-on"
|
888 |
msgstr ""
|
889 |
|
890 |
-
#: includes/fs-plugin-info-dialog.php:
|
891 |
msgid "Activate Free Version"
|
892 |
msgstr ""
|
893 |
|
894 |
-
#: includes/fs-plugin-info-dialog.php:
|
895 |
msgid "Activate"
|
896 |
msgstr ""
|
897 |
|
898 |
-
#: includes/fs-plugin-info-dialog.php:
|
899 |
msgctxt "Plugin installer section title"
|
900 |
msgid "Description"
|
901 |
msgstr ""
|
902 |
|
903 |
-
#: includes/fs-plugin-info-dialog.php:
|
904 |
msgctxt "Plugin installer section title"
|
905 |
msgid "Installation"
|
906 |
msgstr ""
|
907 |
|
908 |
-
#: includes/fs-plugin-info-dialog.php:
|
909 |
msgctxt "Plugin installer section title"
|
910 |
msgid "FAQ"
|
911 |
msgstr ""
|
912 |
|
913 |
-
#: includes/fs-plugin-info-dialog.php:
|
914 |
msgid "Screenshots"
|
915 |
msgstr ""
|
916 |
|
917 |
-
#: includes/fs-plugin-info-dialog.php:
|
918 |
msgctxt "Plugin installer section title"
|
919 |
msgid "Changelog"
|
920 |
msgstr ""
|
921 |
|
922 |
-
#: includes/fs-plugin-info-dialog.php:
|
923 |
msgctxt "Plugin installer section title"
|
924 |
msgid "Reviews"
|
925 |
msgstr ""
|
926 |
|
927 |
-
#: includes/fs-plugin-info-dialog.php:
|
928 |
msgctxt "Plugin installer section title"
|
929 |
msgid "Other Notes"
|
930 |
msgstr ""
|
931 |
|
932 |
-
#: includes/fs-plugin-info-dialog.php:
|
933 |
msgctxt "Plugin installer section title"
|
934 |
msgid "Features & Pricing"
|
935 |
msgstr ""
|
936 |
|
937 |
-
#: includes/fs-plugin-info-dialog.php:
|
938 |
msgid "Plugin Install"
|
939 |
msgstr ""
|
940 |
|
941 |
-
#: includes/fs-plugin-info-dialog.php:
|
942 |
msgctxt "e.g. Professional Plan"
|
943 |
msgid "%s Plan"
|
944 |
msgstr ""
|
945 |
|
946 |
-
#: includes/fs-plugin-info-dialog.php:
|
947 |
msgctxt "e.g. the best product"
|
948 |
msgid "Best"
|
949 |
msgstr ""
|
950 |
|
951 |
-
#: includes/fs-plugin-info-dialog.php:
|
952 |
msgctxt "as every month"
|
953 |
msgid "Monthly"
|
954 |
msgstr ""
|
955 |
|
956 |
-
#: includes/fs-plugin-info-dialog.php:
|
957 |
msgctxt "as once a year"
|
958 |
msgid "Annual"
|
959 |
msgstr ""
|
960 |
|
961 |
-
#: includes/fs-plugin-info-dialog.php:
|
962 |
msgid "Lifetime"
|
963 |
msgstr ""
|
964 |
|
965 |
-
#: includes/fs-plugin-info-dialog.php:
|
966 |
msgctxt "e.g. billed monthly"
|
967 |
msgid "Billed %s"
|
968 |
msgstr ""
|
969 |
|
970 |
-
#: includes/fs-plugin-info-dialog.php:
|
971 |
msgctxt "as once a year"
|
972 |
msgid "Annually"
|
973 |
msgstr ""
|
974 |
|
975 |
-
#: includes/fs-plugin-info-dialog.php:
|
976 |
msgctxt "as once a year"
|
977 |
msgid "Once"
|
978 |
msgstr ""
|
979 |
|
980 |
-
#: includes/fs-plugin-info-dialog.php:
|
981 |
msgid "Single Site License"
|
982 |
msgstr ""
|
983 |
|
984 |
-
#: includes/fs-plugin-info-dialog.php:
|
985 |
msgid "Unlimited Licenses"
|
986 |
msgstr ""
|
987 |
|
988 |
-
#: includes/fs-plugin-info-dialog.php:
|
989 |
msgid "Up to %s Sites"
|
990 |
msgstr ""
|
991 |
|
992 |
-
#: includes/fs-plugin-info-dialog.php:
|
993 |
msgctxt "as monthly period"
|
994 |
msgid "mo"
|
995 |
msgstr ""
|
996 |
|
997 |
-
#: includes/fs-plugin-info-dialog.php:
|
998 |
msgctxt "as annual period"
|
999 |
msgid "year"
|
1000 |
msgstr ""
|
1001 |
|
1002 |
-
#: includes/fs-plugin-info-dialog.php:
|
1003 |
msgctxt "noun"
|
1004 |
msgid "Price"
|
1005 |
msgstr ""
|
1006 |
|
1007 |
-
#: includes/fs-plugin-info-dialog.php:
|
1008 |
msgid "Save %s"
|
1009 |
msgstr ""
|
1010 |
|
1011 |
-
#: includes/fs-plugin-info-dialog.php:
|
1012 |
msgid "No commitment for %s - cancel anytime"
|
1013 |
msgstr ""
|
1014 |
|
1015 |
-
#: includes/fs-plugin-info-dialog.php:
|
1016 |
msgid "After your free %s, pay as little as %s"
|
1017 |
msgstr ""
|
1018 |
|
1019 |
-
#: includes/fs-plugin-info-dialog.php:
|
1020 |
msgid "Details"
|
1021 |
msgstr ""
|
1022 |
|
1023 |
-
#: includes/fs-plugin-info-dialog.php:
|
1024 |
msgctxt "product version"
|
1025 |
msgid "Version"
|
1026 |
msgstr ""
|
1027 |
|
1028 |
-
#: includes/fs-plugin-info-dialog.php:
|
1029 |
msgctxt "as the plugin author"
|
1030 |
msgid "Author"
|
1031 |
msgstr ""
|
1032 |
|
1033 |
-
#: includes/fs-plugin-info-dialog.php:
|
1034 |
msgid "Last Updated"
|
1035 |
msgstr ""
|
1036 |
|
1037 |
-
#: includes/fs-plugin-info-dialog.php:
|
1038 |
msgctxt "x-ago"
|
1039 |
msgid "%s ago"
|
1040 |
msgstr ""
|
1041 |
|
1042 |
-
#: includes/fs-plugin-info-dialog.php:
|
1043 |
msgid "Requires WordPress Version"
|
1044 |
msgstr ""
|
1045 |
|
1046 |
-
#: includes/fs-plugin-info-dialog.php:
|
1047 |
msgid "%s or higher"
|
1048 |
msgstr ""
|
1049 |
|
1050 |
-
#: includes/fs-plugin-info-dialog.php:
|
1051 |
msgid "Compatible up to"
|
1052 |
msgstr ""
|
1053 |
|
1054 |
-
#: includes/fs-plugin-info-dialog.php:
|
|
|
|
|
|
|
|
|
1055 |
msgid "Downloaded"
|
1056 |
msgstr ""
|
1057 |
|
1058 |
-
#: includes/fs-plugin-info-dialog.php:
|
1059 |
msgid "%s time"
|
1060 |
msgstr ""
|
1061 |
|
1062 |
-
#: includes/fs-plugin-info-dialog.php:
|
1063 |
msgid "%s times"
|
1064 |
msgstr ""
|
1065 |
|
1066 |
-
#: includes/fs-plugin-info-dialog.php:
|
1067 |
msgid "WordPress.org Plugin Page"
|
1068 |
msgstr ""
|
1069 |
|
1070 |
-
#: includes/fs-plugin-info-dialog.php:
|
1071 |
msgid "Plugin Homepage"
|
1072 |
msgstr ""
|
1073 |
|
1074 |
-
#: includes/fs-plugin-info-dialog.php:
|
1075 |
msgid "Donate to this plugin"
|
1076 |
msgstr ""
|
1077 |
|
1078 |
-
#: includes/fs-plugin-info-dialog.php:
|
1079 |
msgid "Average Rating"
|
1080 |
msgstr ""
|
1081 |
|
1082 |
-
#: includes/fs-plugin-info-dialog.php:
|
1083 |
msgid "based on %s"
|
1084 |
msgstr ""
|
1085 |
|
1086 |
-
#: includes/fs-plugin-info-dialog.php:
|
1087 |
msgid "%s rating"
|
1088 |
msgstr ""
|
1089 |
|
1090 |
-
#: includes/fs-plugin-info-dialog.php:
|
1091 |
msgid "%s ratings"
|
1092 |
msgstr ""
|
1093 |
|
1094 |
-
#: includes/fs-plugin-info-dialog.php:
|
1095 |
msgid "%s star"
|
1096 |
msgstr ""
|
1097 |
|
1098 |
-
#: includes/fs-plugin-info-dialog.php:
|
1099 |
msgid "%s stars"
|
1100 |
msgstr ""
|
1101 |
|
1102 |
-
#: includes/fs-plugin-info-dialog.php:
|
1103 |
msgid "Click to see reviews that provided a rating of %s"
|
1104 |
msgstr ""
|
1105 |
|
1106 |
-
#: includes/fs-plugin-info-dialog.php:
|
1107 |
msgid "Contributors"
|
1108 |
msgstr ""
|
1109 |
|
1110 |
-
#: includes/fs-plugin-info-dialog.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1111 |
msgid "Warning"
|
1112 |
msgstr ""
|
1113 |
|
1114 |
-
#: includes/fs-plugin-info-dialog.php:
|
1115 |
msgid "This plugin has not been tested with your current version of WordPress."
|
1116 |
msgstr ""
|
1117 |
|
1118 |
-
#: includes/fs-plugin-info-dialog.php:
|
1119 |
msgid "This plugin has not been marked as compatible with your version of WordPress."
|
1120 |
msgstr ""
|
1121 |
|
1122 |
-
#: includes/fs-plugin-info-dialog.php:
|
1123 |
msgid "Paid add-on must be deployed to Freemius."
|
1124 |
msgstr ""
|
1125 |
|
1126 |
-
#: includes/fs-plugin-info-dialog.php:
|
1127 |
msgid "Add-on must be deployed to WordPress.org or Freemius."
|
1128 |
msgstr ""
|
1129 |
|
1130 |
-
#: includes/fs-plugin-info-dialog.php:
|
1131 |
msgid "Newer Version (%s) Installed"
|
1132 |
msgstr ""
|
1133 |
|
1134 |
-
#: includes/fs-plugin-info-dialog.php:
|
1135 |
msgid "Newer Free Version (%s) Installed"
|
1136 |
msgstr ""
|
1137 |
|
1138 |
-
#: includes/fs-plugin-info-dialog.php:
|
1139 |
msgid "Latest Version Installed"
|
1140 |
msgstr ""
|
1141 |
|
1142 |
-
#: includes/fs-plugin-info-dialog.php:
|
1143 |
msgid "Latest Free Version Installed"
|
1144 |
msgstr ""
|
1145 |
|
1146 |
-
#: templates/account.php:
|
1147 |
msgid "Downgrading your plan"
|
1148 |
msgstr ""
|
1149 |
|
1150 |
-
#: templates/account.php:
|
1151 |
msgid "Cancelling the subscription"
|
1152 |
msgstr ""
|
1153 |
|
1154 |
#. translators: %1$s: Either 'Downgrading your plan' or 'Cancelling the subscription'
|
1155 |
-
#: templates/account.php:
|
1156 |
msgid "%1$s will immediately stop all future recurring payments and your %2$s plan license will expire in %3$s."
|
1157 |
msgstr ""
|
1158 |
|
1159 |
-
#: templates/account.php:
|
1160 |
msgid "Please note that we will not be able to grandfather outdated pricing for renewals/new subscriptions after a cancellation. If you choose to renew the subscription manually in the future, after a price increase, which typically occurs once a year, you will be charged the updated price."
|
1161 |
msgstr ""
|
1162 |
|
1163 |
-
#: templates/account.php:
|
1164 |
msgid "Cancelling the trial will immediately block access to all premium features. Are you sure?"
|
1165 |
msgstr ""
|
1166 |
|
1167 |
-
#: templates/account.php:
|
1168 |
msgid "You can still enjoy all %s features but you will not have access to %s security & feature updates, nor support."
|
1169 |
msgstr ""
|
1170 |
|
1171 |
-
#: templates/account.php:
|
1172 |
msgid "Once your license expires you can still use the Free version but you will NOT have access to the %s features."
|
1173 |
msgstr ""
|
1174 |
|
1175 |
#. translators: %s: Plan title (e.g. "Professional")
|
1176 |
-
#: templates/account.php:
|
1177 |
msgid "Activate %s Plan"
|
1178 |
msgstr ""
|
1179 |
|
1180 |
#. translators: %s: Time period (e.g. Auto renews in "2 months")
|
1181 |
-
#: templates/account.php:
|
1182 |
msgid "Auto renews in %s"
|
1183 |
msgstr ""
|
1184 |
|
1185 |
#. translators: %s: Time period (e.g. Expires in "2 months")
|
1186 |
-
#: templates/account.php:
|
1187 |
msgid "Expires in %s"
|
1188 |
msgstr ""
|
1189 |
|
1190 |
-
#: templates/account.php:
|
1191 |
msgctxt "as synchronize license"
|
1192 |
msgid "Sync License"
|
1193 |
msgstr ""
|
1194 |
|
1195 |
-
#: templates/account.php:
|
1196 |
msgid "Cancel Trial"
|
1197 |
msgstr ""
|
1198 |
|
1199 |
-
#: templates/account.php:
|
1200 |
msgid "Change Plan"
|
1201 |
msgstr ""
|
1202 |
|
1203 |
-
#: templates/account.php:
|
1204 |
msgctxt "verb"
|
1205 |
msgid "Upgrade"
|
1206 |
msgstr ""
|
1207 |
|
1208 |
-
#: templates/account.php:
|
1209 |
msgctxt "verb"
|
1210 |
msgid "Downgrade"
|
1211 |
msgstr ""
|
1212 |
|
1213 |
-
#: templates/account.php:
|
1214 |
msgid "Free"
|
1215 |
msgstr ""
|
1216 |
|
1217 |
-
#: templates/account.php:
|
1218 |
msgctxt "as product pricing plan"
|
1219 |
msgid "Plan"
|
1220 |
msgstr ""
|
1221 |
|
1222 |
-
#: templates/account.php:
|
1223 |
msgid "Bundle Plan"
|
1224 |
msgstr ""
|
1225 |
|
1226 |
-
#: templates/account.php:
|
1227 |
msgid "Free Trial"
|
1228 |
msgstr ""
|
1229 |
|
1230 |
-
#: templates/account.php:
|
1231 |
msgid "Account Details"
|
1232 |
msgstr ""
|
1233 |
|
1234 |
-
#: templates/account.php:
|
1235 |
msgid "Start Debug"
|
1236 |
msgstr ""
|
1237 |
|
1238 |
-
#: templates/account.php:
|
1239 |
msgid "Stop Debug"
|
1240 |
msgstr ""
|
1241 |
|
1242 |
-
#: templates/account.php:
|
1243 |
msgid "Billing & Invoices"
|
1244 |
msgstr ""
|
1245 |
|
1246 |
-
#: templates/account.php:
|
1247 |
-
msgid "Deleting the account will automatically deactivate your %s plan license so you can use it on other sites. If you want to terminate the recurring payments as well, click the \"Cancel\" button, and first \"Downgrade\" your account. Are you sure you would like to continue with the deletion?"
|
1248 |
-
msgstr ""
|
1249 |
-
|
1250 |
-
#: templates/account.php:290
|
1251 |
-
msgid "Deletion is not temporary. Only delete if you no longer want to use this %s anymore. Are you sure you would like to continue with the deletion?"
|
1252 |
-
msgstr ""
|
1253 |
-
|
1254 |
-
#: templates/account.php:293
|
1255 |
-
msgid "Delete Account"
|
1256 |
-
msgstr ""
|
1257 |
-
|
1258 |
-
#: templates/account.php:305, templates/account/partials/addon.php:231, templates/account/partials/deactivate-license-button.php:35
|
1259 |
msgid "Deactivate License"
|
1260 |
msgstr ""
|
1261 |
|
1262 |
-
#: templates/account.php:
|
1263 |
msgid "Are you sure you want to proceed?"
|
1264 |
msgstr ""
|
1265 |
|
1266 |
-
#: templates/account.php:
|
1267 |
msgid "Cancel Subscription"
|
1268 |
msgstr ""
|
1269 |
|
1270 |
-
#: templates/account.php:
|
1271 |
msgctxt "as synchronize"
|
1272 |
msgid "Sync"
|
1273 |
msgstr ""
|
1274 |
|
1275 |
-
#: templates/account.php:
|
1276 |
msgid "Name"
|
1277 |
msgstr ""
|
1278 |
|
1279 |
-
#: templates/account.php:
|
1280 |
msgid "Email"
|
1281 |
msgstr ""
|
1282 |
|
1283 |
-
#: templates/account.php:
|
1284 |
msgid "User ID"
|
1285 |
msgstr ""
|
1286 |
|
1287 |
-
#: templates/account.php:
|
1288 |
msgid "ID"
|
1289 |
msgstr ""
|
1290 |
|
1291 |
-
#: templates/account.php:
|
1292 |
msgid "Site ID"
|
1293 |
msgstr ""
|
1294 |
|
1295 |
-
#: templates/account.php:
|
1296 |
msgid "No ID"
|
1297 |
msgstr ""
|
1298 |
|
1299 |
-
#: templates/account.php:
|
1300 |
msgid "Public Key"
|
1301 |
msgstr ""
|
1302 |
|
1303 |
-
#: templates/account.php:
|
1304 |
msgid "Secret Key"
|
1305 |
msgstr ""
|
1306 |
|
1307 |
-
#: templates/account.php:
|
1308 |
msgctxt "as secret encryption key missing"
|
1309 |
msgid "No Secret"
|
1310 |
msgstr ""
|
1311 |
|
1312 |
-
#: templates/account.php:
|
1313 |
msgid "Trial"
|
1314 |
msgstr ""
|
1315 |
|
1316 |
-
#: templates/account.php:
|
1317 |
msgid "License Key"
|
1318 |
msgstr ""
|
1319 |
|
1320 |
-
#: templates/account.php:
|
1321 |
msgid "Join the Beta program"
|
1322 |
msgstr ""
|
1323 |
|
1324 |
-
#: templates/account.php:
|
1325 |
msgid "not verified"
|
1326 |
msgstr ""
|
1327 |
|
1328 |
-
#: templates/account.php:
|
1329 |
msgid "Expired"
|
1330 |
msgstr ""
|
1331 |
|
1332 |
-
#: templates/account.php:
|
1333 |
msgid "Premium version"
|
1334 |
msgstr ""
|
1335 |
|
1336 |
-
#: templates/account.php:
|
1337 |
msgid "Free version"
|
1338 |
msgstr ""
|
1339 |
|
1340 |
-
#: templates/account.php:
|
1341 |
msgid "Verify Email"
|
1342 |
msgstr ""
|
1343 |
|
1344 |
-
#: templates/account.php:
|
1345 |
msgid "Download %s Version"
|
1346 |
msgstr ""
|
1347 |
|
1348 |
-
#: templates/account.php:
|
1349 |
msgid "Download Paid Version"
|
1350 |
msgstr ""
|
1351 |
|
1352 |
-
#: templates/account.php:
|
1353 |
msgctxt "verb"
|
1354 |
msgid "Show"
|
1355 |
msgstr ""
|
1356 |
|
1357 |
-
#: templates/account.php:
|
1358 |
msgid "What is your %s?"
|
1359 |
msgstr ""
|
1360 |
|
1361 |
-
#: templates/account.php:
|
1362 |
msgctxt "verb"
|
1363 |
msgid "Edit"
|
1364 |
msgstr ""
|
1365 |
|
1366 |
-
#: templates/account.php:
|
1367 |
msgid "Change User"
|
1368 |
msgstr ""
|
1369 |
|
1370 |
-
#: templates/account.php:
|
1371 |
msgid "Sites"
|
1372 |
msgstr ""
|
1373 |
|
1374 |
-
#: templates/account.php:
|
1375 |
msgid "Search by address"
|
1376 |
msgstr ""
|
1377 |
|
1378 |
-
#: templates/account.php:
|
1379 |
msgid "Address"
|
1380 |
msgstr ""
|
1381 |
|
1382 |
-
#: templates/account.php:
|
1383 |
msgid "License"
|
1384 |
msgstr ""
|
1385 |
|
1386 |
-
#: templates/account.php:
|
1387 |
msgid "Plan"
|
1388 |
msgstr ""
|
1389 |
|
1390 |
-
#: templates/account.php:
|
1391 |
msgctxt "as software license"
|
1392 |
msgid "License"
|
1393 |
msgstr ""
|
1394 |
|
1395 |
-
#: templates/account.php:
|
1396 |
msgctxt "verb"
|
1397 |
msgid "Hide"
|
1398 |
msgstr ""
|
1399 |
|
1400 |
-
#: templates/account.php:
|
1401 |
msgid "Processing"
|
1402 |
msgstr ""
|
1403 |
|
1404 |
-
#: templates/account.php:
|
1405 |
msgid "Get updates for bleeding edge Beta versions of %s."
|
1406 |
msgstr ""
|
1407 |
|
1408 |
-
#: templates/account.php:
|
1409 |
msgid "Cancelling %s"
|
1410 |
msgstr ""
|
1411 |
|
1412 |
-
#: templates/account.php:
|
1413 |
msgid "trial"
|
1414 |
msgstr ""
|
1415 |
|
1416 |
-
#: templates/account.php:
|
1417 |
msgid "Cancelling %s..."
|
1418 |
msgstr ""
|
1419 |
|
1420 |
-
#: templates/account.php:
|
1421 |
msgid "subscription"
|
1422 |
msgstr ""
|
1423 |
|
1424 |
-
#: templates/account.php:
|
1425 |
msgid "Deactivating your license will block all premium features, but will enable activating the license on another site. Are you sure you want to proceed?"
|
1426 |
msgstr ""
|
1427 |
|
1428 |
-
#: templates/account.php:
|
1429 |
msgid "Disabling white-label mode"
|
1430 |
msgstr ""
|
1431 |
|
1432 |
-
#: templates/account.php:
|
1433 |
msgid "Enabling white-label mode"
|
1434 |
msgstr ""
|
1435 |
|
@@ -1455,7 +1467,7 @@ msgctxt "installed add-on"
|
|
1455 |
msgid "Installed"
|
1456 |
msgstr ""
|
1457 |
|
1458 |
-
#: templates/admin-notice.php:13, templates/forms/license-activation.php:
|
1459 |
msgctxt "as close a window"
|
1460 |
msgid "Dismiss"
|
1461 |
msgstr ""
|
@@ -1489,198 +1501,147 @@ msgid "PCI compliant"
|
|
1489 |
msgstr ""
|
1490 |
|
1491 |
#. translators: %s: name (e.g. Hey John,)
|
1492 |
-
#: templates/connect.php:
|
1493 |
msgctxt "greeting"
|
1494 |
msgid "Hey %s,"
|
1495 |
msgstr ""
|
1496 |
|
1497 |
-
#: templates/connect.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1498 |
msgid "Allow & Continue"
|
1499 |
msgstr ""
|
1500 |
|
1501 |
-
#: templates/connect.php:
|
1502 |
msgid "Re-send activation email"
|
1503 |
msgstr ""
|
1504 |
|
1505 |
-
#: templates/connect.php:
|
1506 |
msgid "Thanks %s!"
|
1507 |
msgstr ""
|
1508 |
|
1509 |
-
#: templates/connect.php:
|
1510 |
-
msgid "
|
1511 |
msgstr ""
|
1512 |
|
1513 |
-
#: templates/connect.php:
|
1514 |
-
msgid "
|
1515 |
msgstr ""
|
1516 |
|
1517 |
-
#: templates/connect.php:
|
1518 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
1519 |
msgstr ""
|
1520 |
|
1521 |
-
#: templates/connect.php:
|
1522 |
-
msgid "
|
1523 |
msgstr ""
|
1524 |
|
1525 |
-
#: templates/connect.php:
|
1526 |
-
msgid "
|
1527 |
msgstr ""
|
1528 |
|
1529 |
-
#: templates/connect.php:
|
1530 |
-
msgid "
|
1531 |
msgstr ""
|
1532 |
|
1533 |
-
#: templates/connect.php:
|
1534 |
msgid "We're excited to introduce the Freemius network-level integration."
|
1535 |
msgstr ""
|
1536 |
|
1537 |
-
#: templates/connect.php:
|
1538 |
msgid "During the update process we detected %d site(s) that are still pending license activation."
|
1539 |
msgstr ""
|
1540 |
|
1541 |
-
#: templates/connect.php:
|
1542 |
msgid "If you'd like to use the %s on those sites, please enter your license key below and click the activation button."
|
1543 |
msgstr ""
|
1544 |
|
1545 |
-
#: templates/connect.php:
|
1546 |
msgid "%s's paid features"
|
1547 |
msgstr ""
|
1548 |
|
1549 |
-
#: templates/connect.php:
|
1550 |
msgid "Alternatively, you can skip it for now and activate the license later, in your %s's network-level Account page."
|
1551 |
msgstr ""
|
1552 |
|
1553 |
-
#: templates/connect.php:
|
1554 |
msgid "During the update process we detected %s site(s) in the network that are still pending your attention."
|
1555 |
msgstr ""
|
1556 |
|
1557 |
-
#: templates/connect.php:
|
1558 |
msgid "License key"
|
1559 |
msgstr ""
|
1560 |
|
1561 |
-
#: templates/connect.php:
|
1562 |
msgid "Can't find your license key?"
|
1563 |
msgstr ""
|
1564 |
|
1565 |
-
#: templates/connect.php:
|
1566 |
msgctxt "verb"
|
1567 |
msgid "Skip"
|
1568 |
msgstr ""
|
1569 |
|
1570 |
-
#: templates/connect.php:
|
1571 |
msgid "Delegate to Site Admins"
|
1572 |
msgstr ""
|
1573 |
|
1574 |
-
#: templates/connect.php:
|
1575 |
msgid "If you click it, this decision will be delegated to the sites administrators."
|
1576 |
msgstr ""
|
1577 |
|
1578 |
-
#: templates/connect.php:
|
1579 |
msgid "License issues?"
|
1580 |
msgstr ""
|
1581 |
|
1582 |
-
#: templates/connect.php:
|
1583 |
-
msgid "
|
1584 |
-
msgstr ""
|
1585 |
-
|
1586 |
-
#: templates/connect.php:363
|
1587 |
-
msgid "Name and email address"
|
1588 |
-
msgstr ""
|
1589 |
-
|
1590 |
-
#: templates/connect.php:370
|
1591 |
-
msgid "So you can manage and control your license remotely from the User Dashboard."
|
1592 |
-
msgstr ""
|
1593 |
-
|
1594 |
-
#: templates/connect.php:371
|
1595 |
-
msgid "Your Site Overview"
|
1596 |
-
msgstr ""
|
1597 |
-
|
1598 |
-
#: templates/connect.php:372
|
1599 |
-
msgid "Site URL, WP version, PHP info"
|
1600 |
-
msgstr ""
|
1601 |
-
|
1602 |
-
#: templates/connect.php:379
|
1603 |
-
msgid "Admin Notices"
|
1604 |
-
msgstr ""
|
1605 |
-
|
1606 |
-
#: templates/connect.php:380, templates/connect.php:398
|
1607 |
-
msgid "Updates, announcements, marketing, no spam"
|
1608 |
-
msgstr ""
|
1609 |
-
|
1610 |
-
#: templates/connect.php:387
|
1611 |
-
msgid "So you can reuse the license when the %s is no longer active."
|
1612 |
-
msgstr ""
|
1613 |
-
|
1614 |
-
#: templates/connect.php:388
|
1615 |
-
msgid "Current %s Status"
|
1616 |
-
msgstr ""
|
1617 |
-
|
1618 |
-
#: templates/connect.php:389
|
1619 |
-
msgid "Active, deactivated, or uninstalled"
|
1620 |
-
msgstr ""
|
1621 |
-
|
1622 |
-
#: templates/connect.php:397
|
1623 |
-
msgid "Newsletter"
|
1624 |
-
msgstr ""
|
1625 |
-
|
1626 |
-
#: templates/connect.php:405
|
1627 |
-
msgid "Plugins & Themes"
|
1628 |
-
msgstr ""
|
1629 |
-
|
1630 |
-
#: templates/connect.php:405
|
1631 |
-
msgid "optional"
|
1632 |
-
msgstr ""
|
1633 |
-
|
1634 |
-
#: templates/connect.php:406
|
1635 |
-
msgid "To help us troubleshoot any potential issues that may arise from other plugin or theme conflicts."
|
1636 |
-
msgstr ""
|
1637 |
-
|
1638 |
-
#: templates/connect.php:407
|
1639 |
-
msgid "Title, slug, version, and is active"
|
1640 |
-
msgstr ""
|
1641 |
-
|
1642 |
-
#: templates/connect.php:424
|
1643 |
-
msgid "The %1$s will periodically send %2$s to %3$s for security & feature updates delivery, and license management."
|
1644 |
-
msgstr ""
|
1645 |
-
|
1646 |
-
#: templates/connect.php:426
|
1647 |
-
msgid "diagnostic data"
|
1648 |
-
msgstr ""
|
1649 |
-
|
1650 |
-
#: templates/connect.php:427
|
1651 |
-
msgid "Freemius is our licensing and software updates engine"
|
1652 |
msgstr ""
|
1653 |
|
1654 |
#: templates/connect.php:430
|
1655 |
-
msgid "
|
1656 |
msgstr ""
|
1657 |
|
1658 |
-
#: templates/connect.php:
|
1659 |
msgid "Don't have a license key?"
|
1660 |
msgstr ""
|
1661 |
|
1662 |
-
#: templates/connect.php:
|
1663 |
msgid "Have a license key?"
|
1664 |
msgstr ""
|
1665 |
|
1666 |
-
#: templates/connect.php:
|
|
|
|
|
|
|
|
|
1667 |
msgid "Privacy Policy"
|
1668 |
msgstr ""
|
1669 |
|
1670 |
-
#: templates/connect.php:
|
1671 |
msgid "License Agreement"
|
1672 |
msgstr ""
|
1673 |
|
1674 |
-
#: templates/connect.php:
|
1675 |
msgid "Terms of Service"
|
1676 |
msgstr ""
|
1677 |
|
1678 |
-
#: templates/connect.php:
|
1679 |
msgctxt "as in the process of sending an email"
|
1680 |
msgid "Sending email"
|
1681 |
msgstr ""
|
1682 |
|
1683 |
-
#: templates/connect.php:
|
1684 |
msgctxt "as activating plugin"
|
1685 |
msgid "Activating"
|
1686 |
msgstr ""
|
@@ -1699,235 +1660,239 @@ msgctxt "as turned on"
|
|
1699 |
msgid "On"
|
1700 |
msgstr ""
|
1701 |
|
1702 |
-
#: templates/debug.php:
|
1703 |
msgid "SDK"
|
1704 |
msgstr ""
|
1705 |
|
1706 |
-
#: templates/debug.php:
|
1707 |
msgctxt "as code debugging"
|
1708 |
msgid "Debugging"
|
1709 |
msgstr ""
|
1710 |
|
1711 |
-
#: templates/debug.php:
|
1712 |
msgid "Actions"
|
1713 |
msgstr ""
|
1714 |
|
1715 |
-
#: templates/debug.php:
|
1716 |
msgid "Are you sure you want to delete all Freemius data?"
|
1717 |
msgstr ""
|
1718 |
|
1719 |
-
#: templates/debug.php:
|
1720 |
msgid "Delete All Accounts"
|
1721 |
msgstr ""
|
1722 |
|
1723 |
-
#: templates/debug.php:
|
1724 |
msgid "Clear API Cache"
|
1725 |
msgstr ""
|
1726 |
|
1727 |
-
#: templates/debug.php:
|
1728 |
msgid "Clear Updates Transients"
|
1729 |
msgstr ""
|
1730 |
|
1731 |
-
#: templates/debug.php:
|
|
|
|
|
|
|
|
|
1732 |
msgid "Sync Data From Server"
|
1733 |
msgstr ""
|
1734 |
|
1735 |
-
#: templates/debug.php:
|
1736 |
msgid "Migrate Options to Network"
|
1737 |
msgstr ""
|
1738 |
|
1739 |
-
#: templates/debug.php:
|
1740 |
msgid "Load DB Option"
|
1741 |
msgstr ""
|
1742 |
|
1743 |
-
#: templates/debug.php:
|
1744 |
msgid "Set DB Option"
|
1745 |
msgstr ""
|
1746 |
|
1747 |
-
#: templates/debug.php:
|
1748 |
msgid "Key"
|
1749 |
msgstr ""
|
1750 |
|
1751 |
-
#: templates/debug.php:
|
1752 |
msgid "Value"
|
1753 |
msgstr ""
|
1754 |
|
1755 |
-
#: templates/debug.php:
|
1756 |
msgctxt "as software development kit versions"
|
1757 |
msgid "SDK Versions"
|
1758 |
msgstr ""
|
1759 |
|
1760 |
-
#: templates/debug.php:
|
1761 |
msgid "SDK Path"
|
1762 |
msgstr ""
|
1763 |
|
1764 |
-
#: templates/debug.php:
|
1765 |
msgid "Module Path"
|
1766 |
msgstr ""
|
1767 |
|
1768 |
-
#: templates/debug.php:
|
1769 |
msgid "Is Active"
|
1770 |
msgstr ""
|
1771 |
|
1772 |
-
#: templates/debug.php:
|
1773 |
msgid "Plugins"
|
1774 |
msgstr ""
|
1775 |
|
1776 |
-
#: templates/debug.php:
|
1777 |
msgid "Themes"
|
1778 |
msgstr ""
|
1779 |
|
1780 |
-
#: templates/debug.php:
|
1781 |
msgid "Slug"
|
1782 |
msgstr ""
|
1783 |
|
1784 |
-
#: templates/debug.php:
|
1785 |
msgid "Title"
|
1786 |
msgstr ""
|
1787 |
|
1788 |
-
#: templates/debug.php:
|
1789 |
msgctxt "as application program interface"
|
1790 |
msgid "API"
|
1791 |
msgstr ""
|
1792 |
|
1793 |
-
#: templates/debug.php:
|
1794 |
msgid "Freemius State"
|
1795 |
msgstr ""
|
1796 |
|
1797 |
-
#: templates/debug.php:
|
1798 |
msgid "Network Blog"
|
1799 |
msgstr ""
|
1800 |
|
1801 |
-
#: templates/debug.php:
|
1802 |
msgid "Network User"
|
1803 |
msgstr ""
|
1804 |
|
1805 |
-
#: templates/debug.php:
|
1806 |
msgctxt "as connection was successful"
|
1807 |
msgid "Connected"
|
1808 |
msgstr ""
|
1809 |
|
1810 |
-
#: templates/debug.php:
|
1811 |
msgctxt "as connection blocked"
|
1812 |
msgid "Blocked"
|
1813 |
msgstr ""
|
1814 |
|
1815 |
-
#: templates/debug.php:
|
1816 |
msgid "Simulate Trial Promotion"
|
1817 |
msgstr ""
|
1818 |
|
1819 |
-
#: templates/debug.php:
|
1820 |
msgid "Simulate Network Upgrade"
|
1821 |
msgstr ""
|
1822 |
|
1823 |
-
#: templates/debug.php:
|
1824 |
msgid "%s Installs"
|
1825 |
msgstr ""
|
1826 |
|
1827 |
-
#: templates/debug.php:
|
1828 |
msgctxt "like websites"
|
1829 |
msgid "Sites"
|
1830 |
msgstr ""
|
1831 |
|
1832 |
-
#: templates/debug.php:
|
1833 |
msgid "Blog ID"
|
1834 |
msgstr ""
|
1835 |
|
1836 |
-
#: templates/debug.php:
|
1837 |
msgid "License ID"
|
1838 |
msgstr ""
|
1839 |
|
1840 |
-
#: templates/debug.php:
|
1841 |
msgctxt "verb"
|
1842 |
msgid "Delete"
|
1843 |
msgstr ""
|
1844 |
|
1845 |
-
#: templates/debug.php:
|
1846 |
msgid "Add Ons of module %s"
|
1847 |
msgstr ""
|
1848 |
|
1849 |
-
#: templates/debug.php:
|
1850 |
msgid "Users"
|
1851 |
msgstr ""
|
1852 |
|
1853 |
-
#: templates/debug.php:
|
1854 |
msgid "Verified"
|
1855 |
msgstr ""
|
1856 |
|
1857 |
-
#: templates/debug.php:
|
1858 |
msgid "%s Licenses"
|
1859 |
msgstr ""
|
1860 |
|
1861 |
-
#: templates/debug.php:
|
1862 |
msgid "Plugin ID"
|
1863 |
msgstr ""
|
1864 |
|
1865 |
-
#: templates/debug.php:
|
1866 |
msgid "Plan ID"
|
1867 |
msgstr ""
|
1868 |
|
1869 |
-
#: templates/debug.php:
|
1870 |
msgid "Quota"
|
1871 |
msgstr ""
|
1872 |
|
1873 |
-
#: templates/debug.php:
|
1874 |
msgid "Activated"
|
1875 |
msgstr ""
|
1876 |
|
1877 |
-
#: templates/debug.php:
|
1878 |
msgid "Blocking"
|
1879 |
msgstr ""
|
1880 |
|
1881 |
-
#: templates/debug.php:
|
1882 |
msgid "Type"
|
1883 |
msgstr ""
|
1884 |
|
1885 |
-
#: templates/debug.php:
|
1886 |
msgctxt "as expiration date"
|
1887 |
msgid "Expiration"
|
1888 |
msgstr ""
|
1889 |
|
1890 |
-
#: templates/debug.php:
|
1891 |
msgid "Debug Log"
|
1892 |
msgstr ""
|
1893 |
|
1894 |
-
#: templates/debug.php:
|
1895 |
msgid "All Types"
|
1896 |
msgstr ""
|
1897 |
|
1898 |
-
#: templates/debug.php:
|
1899 |
msgid "All Requests"
|
1900 |
msgstr ""
|
1901 |
|
1902 |
-
#: templates/debug.php:
|
1903 |
msgid "File"
|
1904 |
msgstr ""
|
1905 |
|
1906 |
-
#: templates/debug.php:
|
1907 |
msgid "Function"
|
1908 |
msgstr ""
|
1909 |
|
1910 |
-
#: templates/debug.php:
|
1911 |
msgid "Process ID"
|
1912 |
msgstr ""
|
1913 |
|
1914 |
-
#: templates/debug.php:
|
1915 |
msgid "Logger"
|
1916 |
msgstr ""
|
1917 |
|
1918 |
-
#: templates/debug.php:
|
1919 |
msgid "Message"
|
1920 |
msgstr ""
|
1921 |
|
1922 |
-
#: templates/debug.php:
|
1923 |
msgid "Filter"
|
1924 |
msgstr ""
|
1925 |
|
1926 |
-
#: templates/debug.php:
|
1927 |
msgid "Download"
|
1928 |
msgstr ""
|
1929 |
|
1930 |
-
#: templates/debug.php:
|
1931 |
msgid "Timestamp"
|
1932 |
msgstr ""
|
1933 |
|
@@ -1952,6 +1917,211 @@ msgstr ""
|
|
1952 |
msgid "Requests"
|
1953 |
msgstr ""
|
1954 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1955 |
#: templates/account/billing.php:22
|
1956 |
msgctxt "verb"
|
1957 |
msgid "Update"
|
@@ -2017,6 +2187,16 @@ msgstr ""
|
|
2017 |
msgid "Invoice"
|
2018 |
msgstr ""
|
2019 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020 |
#: templates/debug/api-calls.php:56
|
2021 |
msgid "API"
|
2022 |
msgstr ""
|
@@ -2105,143 +2285,143 @@ msgstr ""
|
|
2105 |
msgid "Next"
|
2106 |
msgstr ""
|
2107 |
|
2108 |
-
#: templates/forms/affiliation.php:
|
2109 |
msgid "Non-expiring"
|
2110 |
msgstr ""
|
2111 |
|
2112 |
-
#: templates/forms/affiliation.php:
|
2113 |
msgid "Apply to become an affiliate"
|
2114 |
msgstr ""
|
2115 |
|
2116 |
-
#: templates/forms/affiliation.php:
|
2117 |
msgid "Your affiliate application for %s has been accepted! Log in to your affiliate area at: %s."
|
2118 |
msgstr ""
|
2119 |
|
2120 |
-
#: templates/forms/affiliation.php:
|
2121 |
msgid "Thank you for applying for our affiliate program, we'll review your details during the next 14 days and will get back to you with further information."
|
2122 |
msgstr ""
|
2123 |
|
2124 |
-
#: templates/forms/affiliation.php:
|
2125 |
msgid "Your affiliation account was temporarily suspended."
|
2126 |
msgstr ""
|
2127 |
|
2128 |
-
#: templates/forms/affiliation.php:
|
2129 |
msgid "Thank you for applying for our affiliate program, unfortunately, we've decided at this point to reject your application. Please try again in 30 days."
|
2130 |
msgstr ""
|
2131 |
|
2132 |
-
#: templates/forms/affiliation.php:
|
2133 |
msgid "Due to violation of our affiliation terms, we decided to temporarily block your affiliation account. If you have any questions, please contact support."
|
2134 |
msgstr ""
|
2135 |
|
2136 |
-
#: templates/forms/affiliation.php:
|
2137 |
msgid "Like the %s? Become our ambassador and earn cash ;-)"
|
2138 |
msgstr ""
|
2139 |
|
2140 |
-
#: templates/forms/affiliation.php:
|
2141 |
msgid "Refer new customers to our %s and earn %s commission on each successful sale you refer!"
|
2142 |
msgstr ""
|
2143 |
|
2144 |
-
#: templates/forms/affiliation.php:
|
2145 |
msgid "Program Summary"
|
2146 |
msgstr ""
|
2147 |
|
2148 |
-
#: templates/forms/affiliation.php:
|
2149 |
msgid "%s commission when a customer purchases a new license."
|
2150 |
msgstr ""
|
2151 |
|
2152 |
-
#: templates/forms/affiliation.php:
|
2153 |
msgid "Get commission for automated subscription renewals."
|
2154 |
msgstr ""
|
2155 |
|
2156 |
-
#: templates/forms/affiliation.php:
|
2157 |
msgid "%s tracking cookie after the first visit to maximize earnings potential."
|
2158 |
msgstr ""
|
2159 |
|
2160 |
-
#: templates/forms/affiliation.php:
|
2161 |
msgid "Unlimited commissions."
|
2162 |
msgstr ""
|
2163 |
|
2164 |
-
#: templates/forms/affiliation.php:
|
2165 |
msgid "%s minimum payout amount."
|
2166 |
msgstr ""
|
2167 |
|
2168 |
-
#: templates/forms/affiliation.php:
|
2169 |
msgid "Payouts are in USD and processed monthly via PayPal."
|
2170 |
msgstr ""
|
2171 |
|
2172 |
-
#: templates/forms/affiliation.php:
|
2173 |
msgid "As we reserve 30 days for potential refunds, we only pay commissions that are older than 30 days."
|
2174 |
msgstr ""
|
2175 |
|
2176 |
-
#: templates/forms/affiliation.php:
|
2177 |
msgid "Affiliate"
|
2178 |
msgstr ""
|
2179 |
|
2180 |
-
#: templates/forms/affiliation.php:
|
2181 |
msgid "Email address"
|
2182 |
msgstr ""
|
2183 |
|
2184 |
-
#: templates/forms/affiliation.php:
|
2185 |
msgid "Full name"
|
2186 |
msgstr ""
|
2187 |
|
2188 |
-
#: templates/forms/affiliation.php:
|
2189 |
msgid "PayPal account email address"
|
2190 |
msgstr ""
|
2191 |
|
2192 |
-
#: templates/forms/affiliation.php:
|
2193 |
msgid "Where are you going to promote the %s?"
|
2194 |
msgstr ""
|
2195 |
|
2196 |
-
#: templates/forms/affiliation.php:
|
2197 |
msgid "Enter the domain of your website or other websites from where you plan to promote the %s."
|
2198 |
msgstr ""
|
2199 |
|
2200 |
-
#: templates/forms/affiliation.php:
|
2201 |
msgid "Add another domain"
|
2202 |
msgstr ""
|
2203 |
|
2204 |
-
#: templates/forms/affiliation.php:
|
2205 |
msgid "Extra Domains"
|
2206 |
msgstr ""
|
2207 |
|
2208 |
-
#: templates/forms/affiliation.php:
|
2209 |
msgid "Extra domains where you will be marketing the product from."
|
2210 |
msgstr ""
|
2211 |
|
2212 |
-
#: templates/forms/affiliation.php:
|
2213 |
msgid "Promotion methods"
|
2214 |
msgstr ""
|
2215 |
|
2216 |
-
#: templates/forms/affiliation.php:
|
2217 |
msgid "Social media (Facebook, Twitter, etc.)"
|
2218 |
msgstr ""
|
2219 |
|
2220 |
-
#: templates/forms/affiliation.php:
|
2221 |
msgid "Mobile apps"
|
2222 |
msgstr ""
|
2223 |
|
2224 |
-
#: templates/forms/affiliation.php:
|
2225 |
msgid "Website, email, and social media statistics (optional)"
|
2226 |
msgstr ""
|
2227 |
|
2228 |
-
#: templates/forms/affiliation.php:
|
2229 |
msgid "Please feel free to provide any relevant website or social media statistics, e.g. monthly unique site visits, number of email subscribers, followers, etc. (we will keep this information confidential)."
|
2230 |
msgstr ""
|
2231 |
|
2232 |
-
#: templates/forms/affiliation.php:
|
2233 |
msgid "How will you promote us?"
|
2234 |
msgstr ""
|
2235 |
|
2236 |
-
#: templates/forms/affiliation.php:
|
2237 |
msgid "Please provide details on how you intend to promote %s (please be as specific as possible)."
|
2238 |
msgstr ""
|
2239 |
|
2240 |
-
#: templates/forms/affiliation.php:
|
2241 |
msgid "Cancel"
|
2242 |
msgstr ""
|
2243 |
|
2244 |
-
#: templates/forms/affiliation.php:
|
2245 |
msgid "Become an affiliate"
|
2246 |
msgstr ""
|
2247 |
|
@@ -2261,66 +2441,93 @@ msgstr ""
|
|
2261 |
msgid "User key"
|
2262 |
msgstr ""
|
2263 |
|
2264 |
-
#: templates/forms/
|
2265 |
-
msgid "
|
2266 |
msgstr ""
|
2267 |
|
2268 |
-
#: templates/forms/
|
2269 |
-
|
|
|
2270 |
msgstr ""
|
2271 |
|
2272 |
-
#: templates/forms/
|
2273 |
-
msgid "
|
2274 |
msgstr ""
|
2275 |
|
2276 |
-
#: templates/forms/
|
2277 |
-
msgid "
|
2278 |
msgstr ""
|
2279 |
|
2280 |
-
#: templates/forms/
|
2281 |
-
|
2282 |
-
msgid "Opt Out"
|
2283 |
msgstr ""
|
2284 |
|
2285 |
-
#: templates/forms/
|
2286 |
-
|
2287 |
-
|
|
|
|
|
|
|
2288 |
msgstr ""
|
2289 |
|
2290 |
-
#: templates/forms/
|
2291 |
-
msgid "
|
2292 |
msgstr ""
|
2293 |
|
2294 |
-
#: templates/forms/
|
2295 |
-
msgid "
|
2296 |
msgstr ""
|
2297 |
|
2298 |
-
#: templates/forms/
|
2299 |
-
msgid "
|
2300 |
msgstr ""
|
2301 |
|
2302 |
-
#: templates/forms/
|
2303 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2304 |
msgstr ""
|
2305 |
|
2306 |
#: templates/forms/optout.php:44
|
2307 |
-
msgid "
|
2308 |
msgstr ""
|
2309 |
|
2310 |
-
#: templates/forms/optout.php:
|
2311 |
-
msgid "
|
2312 |
msgstr ""
|
2313 |
|
2314 |
-
#: templates/forms/optout.php:
|
2315 |
-
msgid "
|
2316 |
msgstr ""
|
2317 |
|
2318 |
-
#: templates/forms/optout.php:
|
2319 |
-
msgid "
|
2320 |
msgstr ""
|
2321 |
|
2322 |
-
#: templates/forms/optout.php:
|
2323 |
-
msgid "
|
|
|
|
|
|
|
|
|
2324 |
msgstr ""
|
2325 |
|
2326 |
#: templates/forms/premium-versions-upgrade-handler.php:40
|
@@ -2344,7 +2551,11 @@ msgstr ""
|
|
2344 |
msgid "Send License Key"
|
2345 |
msgstr ""
|
2346 |
|
2347 |
-
#: templates/forms/resend-key.php:
|
|
|
|
|
|
|
|
|
2348 |
msgid "Enter the email address you've used for the upgrade below and we will resend you the license key."
|
2349 |
msgstr ""
|
2350 |
|
@@ -2356,10 +2567,6 @@ msgstr ""
|
|
2356 |
msgid "In case you are NOT planning on using this %s on this site (or any other site) - would you like to cancel the %s as well?"
|
2357 |
msgstr ""
|
2358 |
|
2359 |
-
#: templates/forms/subscription-cancellation.php:52
|
2360 |
-
msgid "license"
|
2361 |
-
msgstr ""
|
2362 |
-
|
2363 |
#: templates/forms/subscription-cancellation.php:57
|
2364 |
msgid "Cancel %s - I no longer need any security & feature updates, nor support for %s because I'm not planning to use the %s on this, or any other site."
|
2365 |
msgstr ""
|
@@ -2380,7 +2587,7 @@ msgstr ""
|
|
2380 |
msgid "Proceed"
|
2381 |
msgstr ""
|
2382 |
|
2383 |
-
#: templates/forms/subscription-cancellation.php:191, templates/forms/deactivation/form.php:
|
2384 |
msgid "Cancel %s & Proceed"
|
2385 |
msgstr ""
|
2386 |
|
@@ -2404,9 +2611,8 @@ msgstr ""
|
|
2404 |
msgid "Enter email address"
|
2405 |
msgstr ""
|
2406 |
|
2407 |
-
#: templates/
|
2408 |
-
|
2409 |
-
msgid "Dismiss"
|
2410 |
msgstr ""
|
2411 |
|
2412 |
#: templates/js/style-premium-theme.php:39
|
@@ -2417,31 +2623,31 @@ msgstr ""
|
|
2417 |
msgid "Beta"
|
2418 |
msgstr ""
|
2419 |
|
2420 |
-
#: templates/partials/network-activation.php:
|
2421 |
msgid "Activate license on all sites in the network."
|
2422 |
msgstr ""
|
2423 |
|
2424 |
-
#: templates/partials/network-activation.php:
|
2425 |
msgid "Apply on all sites in the network."
|
2426 |
msgstr ""
|
2427 |
|
2428 |
-
#: templates/partials/network-activation.php:
|
2429 |
msgid "Activate license on all pending sites."
|
2430 |
msgstr ""
|
2431 |
|
2432 |
-
#: templates/partials/network-activation.php:
|
2433 |
msgid "Apply on all pending sites."
|
2434 |
msgstr ""
|
2435 |
|
2436 |
-
#: templates/partials/network-activation.php:
|
2437 |
msgid "allow"
|
2438 |
msgstr ""
|
2439 |
|
2440 |
-
#: templates/partials/network-activation.php:
|
2441 |
msgid "delegate"
|
2442 |
msgstr ""
|
2443 |
|
2444 |
-
#: templates/partials/network-activation.php:
|
2445 |
msgid "skip"
|
2446 |
msgstr ""
|
2447 |
|
@@ -2467,31 +2673,47 @@ msgid "Last license"
|
|
2467 |
msgstr ""
|
2468 |
|
2469 |
#. translators: %1$s: Either 'Downgrading your plan' or 'Cancelling the subscription'
|
2470 |
-
#: templates/account/partials/addon.php:
|
2471 |
msgid "%1$s will immediately stop all future recurring payments and your %s plan license will expire in %s."
|
2472 |
msgstr ""
|
2473 |
|
2474 |
-
#: templates/account/partials/addon.php:
|
2475 |
msgid "Cancelled"
|
2476 |
msgstr ""
|
2477 |
|
2478 |
-
#: templates/account/partials/addon.php:
|
2479 |
msgid "No expiration"
|
2480 |
msgstr ""
|
2481 |
|
2482 |
-
#: templates/account/partials/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2483 |
msgid "Owner Name"
|
2484 |
msgstr ""
|
2485 |
|
2486 |
-
#: templates/account/partials/site.php:
|
2487 |
msgid "Owner Email"
|
2488 |
msgstr ""
|
2489 |
|
2490 |
-
#: templates/account/partials/site.php:
|
2491 |
msgid "Owner ID"
|
2492 |
msgstr ""
|
2493 |
|
2494 |
-
#: templates/account/partials/site.php:
|
2495 |
msgid "Subscription"
|
2496 |
msgstr ""
|
2497 |
|
@@ -2503,47 +2725,63 @@ msgstr ""
|
|
2503 |
msgid "Contact Support"
|
2504 |
msgstr ""
|
2505 |
|
2506 |
-
#: templates/forms/deactivation/form.php:
|
2507 |
msgid "Anonymous feedback"
|
2508 |
msgstr ""
|
2509 |
|
2510 |
-
#: templates/forms/deactivation/form.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2511 |
msgid "Deactivate"
|
2512 |
msgstr ""
|
2513 |
|
2514 |
-
#: templates/forms/deactivation/form.php:
|
2515 |
msgid "Activate %s"
|
2516 |
msgstr ""
|
2517 |
|
2518 |
-
#: templates/forms/deactivation/form.php:
|
|
|
|
|
|
|
|
|
2519 |
msgid "Quick Feedback"
|
2520 |
msgstr ""
|
2521 |
|
2522 |
-
#: templates/forms/deactivation/form.php:
|
2523 |
msgid "If you have a moment, please let us know why you are %s"
|
2524 |
msgstr ""
|
2525 |
|
2526 |
-
#: templates/forms/deactivation/form.php:
|
2527 |
msgid "deactivating"
|
2528 |
msgstr ""
|
2529 |
|
2530 |
-
#: templates/forms/deactivation/form.php:
|
2531 |
msgid "switching"
|
2532 |
msgstr ""
|
2533 |
|
2534 |
-
#: templates/forms/deactivation/form.php:
|
2535 |
-
msgid "
|
2536 |
msgstr ""
|
2537 |
|
2538 |
-
#: templates/forms/deactivation/form.php:
|
2539 |
-
msgid "
|
2540 |
msgstr ""
|
2541 |
|
2542 |
-
#: templates/forms/deactivation/form.php:
|
2543 |
msgid "Yes - %s"
|
2544 |
msgstr ""
|
2545 |
|
2546 |
-
#: templates/forms/deactivation/form.php:
|
2547 |
msgid "Skip & %s"
|
2548 |
msgstr ""
|
2549 |
|
1 |
+
# Copyright (C) 2022 freemius
|
2 |
# This file is distributed under the same license as the freemius package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
16 |
"X-Poedit-SourceCharset: UTF-8\n"
|
17 |
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
18 |
|
19 |
+
#: includes/class-freemius.php:1744, templates/account.php:947
|
20 |
msgid "An update to a Beta version will replace your installed version of %s with the latest Beta release - use with caution, and not on production sites. You have been warned."
|
21 |
msgstr ""
|
22 |
|
23 |
+
#: includes/class-freemius.php:1751
|
24 |
msgid "Would you like to proceed with the update?"
|
25 |
msgstr ""
|
26 |
|
27 |
+
#: includes/class-freemius.php:1976
|
28 |
msgid "Freemius SDK couldn't find the plugin's main file. Please contact sdk@freemius.com with the current error."
|
29 |
msgstr ""
|
30 |
|
31 |
+
#: includes/class-freemius.php:1978, includes/fs-plugin-info-dialog.php:1517
|
32 |
msgid "Error"
|
33 |
msgstr ""
|
34 |
|
35 |
+
#: includes/class-freemius.php:2424
|
36 |
msgid "I found a better %s"
|
37 |
msgstr ""
|
38 |
|
39 |
+
#: includes/class-freemius.php:2426
|
40 |
msgid "What's the %s's name?"
|
41 |
msgstr ""
|
42 |
|
43 |
+
#: includes/class-freemius.php:2432
|
44 |
+
msgid "It's a temporary %s - I'm troubleshooting an issue"
|
45 |
msgstr ""
|
46 |
|
47 |
+
#: includes/class-freemius.php:2434
|
48 |
msgid "Deactivation"
|
49 |
msgstr ""
|
50 |
|
51 |
+
#: includes/class-freemius.php:2435
|
52 |
msgid "Theme Switch"
|
53 |
msgstr ""
|
54 |
|
55 |
+
#: includes/class-freemius.php:2444, templates/forms/resend-key.php:24, templates/forms/user-change.php:29
|
56 |
msgid "Other"
|
57 |
msgstr ""
|
58 |
|
59 |
+
#: includes/class-freemius.php:2452
|
60 |
msgid "I no longer need the %s"
|
61 |
msgstr ""
|
62 |
|
63 |
+
#: includes/class-freemius.php:2459
|
64 |
msgid "I only needed the %s for a short period"
|
65 |
msgstr ""
|
66 |
|
67 |
+
#: includes/class-freemius.php:2465
|
68 |
msgid "The %s broke my site"
|
69 |
msgstr ""
|
70 |
|
71 |
+
#: includes/class-freemius.php:2472
|
72 |
msgid "The %s suddenly stopped working"
|
73 |
msgstr ""
|
74 |
|
75 |
+
#: includes/class-freemius.php:2482
|
76 |
msgid "I can't pay for it anymore"
|
77 |
msgstr ""
|
78 |
|
79 |
+
#: includes/class-freemius.php:2484
|
80 |
msgid "What price would you feel comfortable paying?"
|
81 |
msgstr ""
|
82 |
|
83 |
+
#: includes/class-freemius.php:2490
|
84 |
msgid "I don't like to share my information with you"
|
85 |
msgstr ""
|
86 |
|
87 |
+
#: includes/class-freemius.php:2511
|
88 |
msgid "The %s didn't work"
|
89 |
msgstr ""
|
90 |
|
91 |
+
#: includes/class-freemius.php:2521
|
92 |
msgid "I couldn't understand how to make it work"
|
93 |
msgstr ""
|
94 |
|
95 |
+
#: includes/class-freemius.php:2529
|
96 |
msgid "The %s is great, but I need specific feature that you don't support"
|
97 |
msgstr ""
|
98 |
|
99 |
+
#: includes/class-freemius.php:2531
|
100 |
msgid "What feature?"
|
101 |
msgstr ""
|
102 |
|
103 |
+
#: includes/class-freemius.php:2535
|
104 |
msgid "The %s is not working"
|
105 |
msgstr ""
|
106 |
|
107 |
+
#: includes/class-freemius.php:2537
|
108 |
msgid "Kindly share what didn't work so we can fix it for future users..."
|
109 |
msgstr ""
|
110 |
|
111 |
+
#: includes/class-freemius.php:2541
|
112 |
msgid "It's not what I was looking for"
|
113 |
msgstr ""
|
114 |
|
115 |
+
#: includes/class-freemius.php:2543
|
116 |
msgid "What you've been looking for?"
|
117 |
msgstr ""
|
118 |
|
119 |
+
#: includes/class-freemius.php:2547
|
120 |
msgid "The %s didn't work as expected"
|
121 |
msgstr ""
|
122 |
|
123 |
+
#: includes/class-freemius.php:2549
|
124 |
msgid "What did you expect?"
|
125 |
msgstr ""
|
126 |
|
127 |
+
#: includes/class-freemius.php:3637, templates/debug.php:24
|
128 |
msgid "Freemius Debug"
|
129 |
msgstr ""
|
130 |
|
131 |
+
#: includes/class-freemius.php:4444
|
132 |
msgid "I don't know what is cURL or how to install it, help me!"
|
133 |
msgstr ""
|
134 |
|
135 |
+
#: includes/class-freemius.php:4446
|
136 |
msgid "We'll make sure to contact your hosting company and resolve the issue. You will get a follow-up email to %s once we have an update."
|
137 |
msgstr ""
|
138 |
|
139 |
+
#: includes/class-freemius.php:4453
|
140 |
msgid "Great, please install cURL and enable it in your php.ini file. In addition, search for the 'disable_functions' directive in your php.ini file and remove any disabled methods starting with 'curl_'. To make sure it was successfully activated, use 'phpinfo()'. Once activated, deactivate the %s and reactivate it back again."
|
141 |
msgstr ""
|
142 |
|
143 |
+
#: includes/class-freemius.php:4558
|
144 |
msgid "Yes - do your thing"
|
145 |
msgstr ""
|
146 |
|
147 |
+
#: includes/class-freemius.php:4563
|
148 |
msgid "No - just deactivate"
|
149 |
msgstr ""
|
150 |
|
151 |
+
#: includes/class-freemius.php:4608, includes/class-freemius.php:5139, includes/class-freemius.php:6334, includes/class-freemius.php:13998, includes/class-freemius.php:14747, includes/class-freemius.php:18513, includes/class-freemius.php:18618, includes/class-freemius.php:18795, includes/class-freemius.php:21078, includes/class-freemius.php:21456, includes/class-freemius.php:21470, includes/class-freemius.php:22158, includes/class-freemius.php:23174, includes/class-freemius.php:23304, includes/class-freemius.php:23434, templates/add-ons.php:57
|
152 |
msgctxt "exclamation"
|
153 |
msgid "Oops"
|
154 |
msgstr ""
|
155 |
|
156 |
+
#: includes/class-freemius.php:4683
|
157 |
msgid "Thank for giving us the chance to fix it! A message was just sent to our technical staff. We will get back to you as soon as we have an update to %s. Appreciate your patience."
|
158 |
msgstr ""
|
159 |
|
160 |
+
#: includes/class-freemius.php:5108
|
161 |
+
msgid "You have purchased a %s license."
|
162 |
+
msgstr ""
|
163 |
+
|
164 |
+
#: includes/class-freemius.php:5112
|
165 |
+
msgid " The %s's %sdownload link%s, license key, and installation instructions have been sent to %s. If you can't find the email after 5 min, please check your spam box."
|
166 |
+
msgstr ""
|
167 |
+
|
168 |
+
#: includes/class-freemius.php:5122, includes/class-freemius.php:6031, includes/class-freemius.php:17889, includes/class-freemius.php:17900, includes/class-freemius.php:21347, includes/class-freemius.php:21738, includes/class-freemius.php:21807, includes/class-freemius.php:21979
|
169 |
+
msgctxt "interjection expressing joy or exuberance"
|
170 |
+
msgid "Yee-haw"
|
171 |
+
msgstr ""
|
172 |
+
|
173 |
+
#: includes/class-freemius.php:5136
|
174 |
msgctxt "addonX cannot run without pluginY"
|
175 |
msgid "%s cannot run without %s."
|
176 |
msgstr ""
|
177 |
|
178 |
+
#: includes/class-freemius.php:5137
|
179 |
msgctxt "addonX cannot run..."
|
180 |
msgid "%s cannot run without the plugin."
|
181 |
msgstr ""
|
182 |
|
183 |
+
#: includes/class-freemius.php:5418
|
184 |
+
msgid "There was an unexpected API error while processing your request. Please try again in a few minutes and if it still doesn't work, contact the %s's author with the following:"
|
185 |
msgstr ""
|
186 |
|
187 |
+
#: includes/class-freemius.php:6000
|
188 |
msgid "Premium %s version was successfully activated."
|
189 |
msgstr ""
|
190 |
|
191 |
+
#: includes/class-freemius.php:6012, includes/class-freemius.php:7992
|
192 |
msgctxt "Used to express elation, enthusiasm, or triumph (especially in electronic communication)."
|
193 |
msgid "W00t"
|
194 |
msgstr ""
|
195 |
|
196 |
+
#: includes/class-freemius.php:6027
|
197 |
msgid "You have a %s license."
|
198 |
msgstr ""
|
199 |
|
200 |
+
#: includes/class-freemius.php:6317
|
|
|
|
|
|
|
|
|
|
|
201 |
msgid "%s free trial was successfully cancelled. Since the add-on is premium only it was automatically deactivated. If you like to use it in the future, you'll have to purchase a license."
|
202 |
msgstr ""
|
203 |
|
204 |
+
#: includes/class-freemius.php:6321
|
205 |
msgid "%s is a premium only add-on. You have to purchase a license first before activating the plugin."
|
206 |
msgstr ""
|
207 |
|
208 |
+
#: includes/class-freemius.php:6330, templates/add-ons.php:186, templates/account/partials/addon.php:386
|
209 |
msgid "More information about %s"
|
210 |
msgstr ""
|
211 |
|
212 |
+
#: includes/class-freemius.php:6331
|
213 |
msgid "Purchase License"
|
214 |
msgstr ""
|
215 |
|
216 |
+
#: includes/class-freemius.php:7318, templates/connect.php:216
|
217 |
+
msgid "You should receive a confirmation email for %s to your mailbox at %s. Please make sure you click the button in that email to %s."
|
218 |
msgstr ""
|
219 |
|
220 |
+
#: includes/class-freemius.php:7322
|
221 |
msgid "start the trial"
|
222 |
msgstr ""
|
223 |
|
224 |
+
#: includes/class-freemius.php:7323, templates/connect.php:220
|
225 |
+
msgid "complete the opt-in"
|
226 |
msgstr ""
|
227 |
|
228 |
+
#: includes/class-freemius.php:7456
|
229 |
msgid "You are just one step away - %s"
|
230 |
msgstr ""
|
231 |
|
232 |
+
#: includes/class-freemius.php:7459
|
233 |
msgctxt "%s - plugin name. As complete \"PluginX\" activation now"
|
234 |
msgid "Complete \"%s\" Activation Now"
|
235 |
msgstr ""
|
236 |
|
237 |
+
#: includes/class-freemius.php:7541
|
238 |
msgid "We made a few tweaks to the %s, %s"
|
239 |
msgstr ""
|
240 |
|
241 |
+
#: includes/class-freemius.php:7545
|
242 |
msgid "Opt in to make \"%s\" better!"
|
243 |
msgstr ""
|
244 |
|
245 |
+
#: includes/class-freemius.php:7991
|
246 |
msgid "The upgrade of %s was successfully completed."
|
247 |
msgstr ""
|
248 |
|
249 |
+
#: includes/class-freemius.php:10709, includes/class-fs-plugin-updater.php:1090, includes/class-fs-plugin-updater.php:1305, includes/class-fs-plugin-updater.php:1312, templates/auto-installation.php:32
|
250 |
msgid "Add-On"
|
251 |
msgstr ""
|
252 |
|
253 |
+
#: includes/class-freemius.php:10711, templates/account.php:411, templates/account.php:419, templates/debug.php:395, templates/debug.php:615
|
254 |
msgid "Plugin"
|
255 |
msgstr ""
|
256 |
|
257 |
+
#: includes/class-freemius.php:10712, templates/account.php:412, templates/account.php:420, templates/debug.php:395, templates/debug.php:615, templates/forms/deactivation/form.php:107
|
258 |
msgid "Theme"
|
259 |
msgstr ""
|
260 |
|
261 |
+
#: includes/class-freemius.php:13817
|
262 |
msgid "An unknown error has occurred while trying to toggle the license's white-label mode."
|
263 |
msgstr ""
|
264 |
|
265 |
+
#: includes/class-freemius.php:13831
|
266 |
msgid "Your %s license was flagged as white-labeled to hide sensitive information from the WP Admin (e.g. your email, license key, prices, billing address & invoices). If you ever wish to revert it back, you can easily do it through your %s. If this was a mistake you can also %s."
|
267 |
msgstr ""
|
268 |
|
269 |
+
#: includes/class-freemius.php:13836, templates/account/partials/disconnect-button.php:84
|
270 |
msgid "User Dashboard"
|
271 |
msgstr ""
|
272 |
|
273 |
+
#: includes/class-freemius.php:13837
|
274 |
msgid "revert it now"
|
275 |
msgstr ""
|
276 |
|
277 |
+
#: includes/class-freemius.php:13895
|
278 |
msgid "An unknown error has occurred while trying to set the user's beta mode."
|
279 |
msgstr ""
|
280 |
|
281 |
+
#: includes/class-freemius.php:13969
|
282 |
msgid "Invalid new user ID or email address."
|
283 |
msgstr ""
|
284 |
|
285 |
+
#: includes/class-freemius.php:13999
|
286 |
msgid "Sorry, we could not complete the email update. Another user with the same email is already registered."
|
287 |
msgstr ""
|
288 |
|
289 |
+
#: includes/class-freemius.php:14000
|
290 |
msgid "If you would like to give up the ownership of the %s's account to %s click the Change Ownership button."
|
291 |
msgstr ""
|
292 |
|
293 |
+
#: includes/class-freemius.php:14007
|
294 |
msgid "Change Ownership"
|
295 |
msgstr ""
|
296 |
|
297 |
+
#: includes/class-freemius.php:14614
|
298 |
msgid "Invalid site details collection."
|
299 |
msgstr ""
|
300 |
|
301 |
+
#: includes/class-freemius.php:14734
|
302 |
msgid "We couldn't find your email address in the system, are you sure it's the right address?"
|
303 |
msgstr ""
|
304 |
|
305 |
+
#: includes/class-freemius.php:14736
|
306 |
msgid "We can't see any active licenses associated with that email address, are you sure it's the right address?"
|
307 |
msgstr ""
|
308 |
|
309 |
+
#: includes/class-freemius.php:15034
|
310 |
+
msgid "Account is pending activation. Please check your email and click the link to activate your account and then submit the affiliate form again."
|
311 |
msgstr ""
|
312 |
|
313 |
+
#: includes/class-freemius.php:15148, templates/forms/premium-versions-upgrade-handler.php:47
|
314 |
msgid "Buy a license now"
|
315 |
msgstr ""
|
316 |
|
317 |
+
#: includes/class-freemius.php:15160, templates/forms/premium-versions-upgrade-handler.php:46
|
318 |
msgid "Renew your license now"
|
319 |
msgstr ""
|
320 |
|
321 |
+
#: includes/class-freemius.php:15164
|
322 |
msgid "%s to access version %s security & feature updates, and support."
|
323 |
msgstr ""
|
324 |
|
325 |
+
#: includes/class-freemius.php:17871
|
326 |
+
msgid "%s opt-in was successfully completed."
|
327 |
msgstr ""
|
328 |
|
329 |
+
#: includes/class-freemius.php:17885
|
330 |
msgid "Your account was successfully activated with the %s plan."
|
331 |
msgstr ""
|
332 |
|
333 |
+
#: includes/class-freemius.php:17896, includes/class-freemius.php:21803
|
334 |
msgid "Your trial has been successfully started."
|
335 |
msgstr ""
|
336 |
|
337 |
+
#: includes/class-freemius.php:18511, includes/class-freemius.php:18616, includes/class-freemius.php:18793
|
338 |
msgid "Couldn't activate %s."
|
339 |
msgstr ""
|
340 |
|
341 |
+
#: includes/class-freemius.php:18512, includes/class-freemius.php:18617, includes/class-freemius.php:18794
|
342 |
msgid "Please contact us with the following message:"
|
343 |
msgstr ""
|
344 |
|
345 |
+
#: includes/class-freemius.php:18613, templates/forms/data-debug-mode.php:162
|
346 |
msgid "An unknown error has occurred."
|
347 |
msgstr ""
|
348 |
|
349 |
+
#: includes/class-freemius.php:19153, includes/class-freemius.php:24542
|
350 |
msgid "Upgrade"
|
351 |
msgstr ""
|
352 |
|
353 |
+
#: includes/class-freemius.php:19159
|
354 |
msgid "Start Trial"
|
355 |
msgstr ""
|
356 |
|
357 |
+
#: includes/class-freemius.php:19161
|
358 |
msgid "Pricing"
|
359 |
msgstr ""
|
360 |
|
361 |
+
#: includes/class-freemius.php:19241, includes/class-freemius.php:19243
|
362 |
msgid "Affiliation"
|
363 |
msgstr ""
|
364 |
|
365 |
+
#: includes/class-freemius.php:19271, includes/class-freemius.php:19273, templates/account.php:264, templates/debug.php:362
|
366 |
msgid "Account"
|
367 |
msgstr ""
|
368 |
|
369 |
+
#: includes/class-freemius.php:19287, includes/class-freemius.php:19289, includes/customizer/class-fs-customizer-support-section.php:60
|
370 |
msgid "Contact Us"
|
371 |
msgstr ""
|
372 |
|
373 |
+
#: includes/class-freemius.php:19300, includes/class-freemius.php:19302, includes/class-freemius.php:24556, templates/account.php:134, templates/account/partials/addon.php:49
|
374 |
msgid "Add-Ons"
|
375 |
msgstr ""
|
376 |
|
377 |
+
#: includes/class-freemius.php:19336
|
378 |
msgctxt "ASCII arrow left icon"
|
379 |
msgid "←"
|
380 |
msgstr ""
|
381 |
|
382 |
+
#: includes/class-freemius.php:19336
|
383 |
msgctxt "ASCII arrow right icon"
|
384 |
msgid "➤"
|
385 |
msgstr ""
|
386 |
|
387 |
+
#: includes/class-freemius.php:19338, templates/pricing.php:110
|
388 |
msgctxt "noun"
|
389 |
msgid "Pricing"
|
390 |
msgstr ""
|
391 |
|
392 |
+
#: includes/class-freemius.php:19551, includes/customizer/class-fs-customizer-support-section.php:67
|
393 |
msgid "Support Forum"
|
394 |
msgstr ""
|
395 |
|
396 |
+
#: includes/class-freemius.php:20572
|
397 |
msgid "Your email has been successfully verified - you are AWESOME!"
|
398 |
msgstr ""
|
399 |
|
400 |
+
#: includes/class-freemius.php:20573
|
401 |
msgctxt "a positive response"
|
402 |
msgid "Right on"
|
403 |
msgstr ""
|
404 |
|
405 |
+
#: includes/class-freemius.php:21079
|
406 |
msgid "seems like the key you entered doesn't match our records."
|
407 |
msgstr ""
|
408 |
|
409 |
+
#: includes/class-freemius.php:21103
|
410 |
msgid "Debug mode was successfully enabled and will be automatically disabled in 60 min. You can also disable it earlier by clicking the \"Stop Debug\" link."
|
411 |
msgstr ""
|
412 |
|
413 |
+
#: includes/class-freemius.php:21338
|
414 |
msgid "Your %s Add-on plan was successfully upgraded."
|
415 |
msgstr ""
|
416 |
|
417 |
+
#: includes/class-freemius.php:21340
|
418 |
msgid "%s Add-on was successfully purchased."
|
419 |
msgstr ""
|
420 |
|
421 |
+
#: includes/class-freemius.php:21343
|
422 |
msgid "Download the latest version"
|
423 |
msgstr ""
|
424 |
|
425 |
+
#: includes/class-freemius.php:21449
|
426 |
msgid "Your server is blocking the access to Freemius' API, which is crucial for %1$s synchronization. Please contact your host to whitelist %2$s"
|
427 |
msgstr ""
|
428 |
|
429 |
+
#: includes/class-freemius.php:21455, includes/class-freemius.php:21469, includes/class-freemius.php:21938, includes/class-freemius.php:22027
|
430 |
msgid "Error received from the server:"
|
431 |
msgstr ""
|
432 |
|
433 |
+
#: includes/class-freemius.php:21469
|
434 |
msgid "It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again."
|
435 |
msgstr ""
|
436 |
|
437 |
+
#: includes/class-freemius.php:21700, includes/class-freemius.php:21943, includes/class-freemius.php:21998, includes/class-freemius.php:22105
|
438 |
msgctxt "something somebody says when they are thinking about what you have just said."
|
439 |
msgid "Hmm"
|
440 |
msgstr ""
|
441 |
|
442 |
+
#: includes/class-freemius.php:21713
|
443 |
msgid "It looks like you are still on the %s plan. If you did upgrade or change your plan, it's probably an issue on our side - sorry."
|
444 |
msgstr ""
|
445 |
|
446 |
+
#: includes/class-freemius.php:21714, templates/account.php:136, templates/add-ons.php:250, templates/account/partials/addon.php:51
|
447 |
msgctxt "trial period"
|
448 |
msgid "Trial"
|
449 |
msgstr ""
|
450 |
|
451 |
+
#: includes/class-freemius.php:21719
|
452 |
msgid "I have upgraded my account but when I try to Sync the License, the plan remains %s."
|
453 |
msgstr ""
|
454 |
|
455 |
+
#: includes/class-freemius.php:21723, includes/class-freemius.php:21782
|
456 |
msgid "Please contact us here"
|
457 |
msgstr ""
|
458 |
|
459 |
+
#: includes/class-freemius.php:21734
|
460 |
msgid "Your plan was successfully activated."
|
461 |
msgstr ""
|
462 |
|
463 |
+
#: includes/class-freemius.php:21735
|
464 |
msgid "Your plan was successfully upgraded."
|
465 |
msgstr ""
|
466 |
|
467 |
+
#: includes/class-freemius.php:21752
|
468 |
msgid "Your plan was successfully changed to %s."
|
469 |
msgstr ""
|
470 |
|
471 |
+
#: includes/class-freemius.php:21768
|
472 |
msgid "Your license has expired. You can still continue using the free %s forever."
|
473 |
msgstr ""
|
474 |
|
475 |
+
#: includes/class-freemius.php:21770
|
476 |
msgid "Your license has expired. %1$sUpgrade now%2$s to continue using the %3$s without interruptions."
|
477 |
msgstr ""
|
478 |
|
479 |
+
#: includes/class-freemius.php:21778
|
480 |
msgid "Your license has been cancelled. If you think it's a mistake, please contact support."
|
481 |
msgstr ""
|
482 |
|
483 |
+
#: includes/class-freemius.php:21791
|
484 |
msgid "Your license has expired. You can still continue using all the %s features, but you'll need to renew your license to continue getting updates and support."
|
485 |
msgstr ""
|
486 |
|
487 |
+
#: includes/class-freemius.php:21817
|
488 |
msgid "Your free trial has expired. You can still continue using all our free features."
|
489 |
msgstr ""
|
490 |
|
491 |
+
#: includes/class-freemius.php:21819
|
492 |
msgid "Your free trial has expired. %1$sUpgrade now%2$s to continue using the %3$s without interruptions."
|
493 |
msgstr ""
|
494 |
|
495 |
+
#: includes/class-freemius.php:21934
|
496 |
msgid "It looks like the license could not be activated."
|
497 |
msgstr ""
|
498 |
|
499 |
+
#: includes/class-freemius.php:21976
|
500 |
msgid "Your license was successfully activated."
|
501 |
msgstr ""
|
502 |
|
503 |
+
#: includes/class-freemius.php:22002
|
504 |
msgid "It looks like your site currently doesn't have an active license."
|
505 |
msgstr ""
|
506 |
|
507 |
+
#: includes/class-freemius.php:22026
|
508 |
msgid "It looks like the license deactivation failed."
|
509 |
msgstr ""
|
510 |
|
511 |
+
#: includes/class-freemius.php:22055
|
512 |
msgid "Your %s license was successfully deactivated."
|
513 |
msgstr ""
|
514 |
|
515 |
+
#: includes/class-freemius.php:22056
|
516 |
msgid "Your license was successfully deactivated, you are back to the %s plan."
|
517 |
msgstr ""
|
518 |
|
519 |
+
#: includes/class-freemius.php:22059
|
520 |
msgid "O.K"
|
521 |
msgstr ""
|
522 |
|
523 |
+
#: includes/class-freemius.php:22112
|
524 |
msgid "Seems like we are having some temporary issue with your subscription cancellation. Please try again in few minutes."
|
525 |
msgstr ""
|
526 |
|
527 |
+
#: includes/class-freemius.php:22121
|
528 |
msgid "Your subscription was successfully cancelled. Your %s plan license will expire in %s."
|
529 |
msgstr ""
|
530 |
|
531 |
+
#: includes/class-freemius.php:22163
|
532 |
msgid "You are already running the %s in a trial mode."
|
533 |
msgstr ""
|
534 |
|
535 |
+
#: includes/class-freemius.php:22174
|
536 |
msgid "You already utilized a trial before."
|
537 |
msgstr ""
|
538 |
|
539 |
+
#: includes/class-freemius.php:22188
|
540 |
msgid "Plan %s do not exist, therefore, can't start a trial."
|
541 |
msgstr ""
|
542 |
|
543 |
+
#: includes/class-freemius.php:22199
|
544 |
msgid "Plan %s does not support a trial period."
|
545 |
msgstr ""
|
546 |
|
547 |
+
#: includes/class-freemius.php:22210
|
548 |
msgid "None of the %s's plans supports a trial period."
|
549 |
msgstr ""
|
550 |
|
551 |
+
#: includes/class-freemius.php:22259
|
552 |
msgid "It looks like you are not in trial mode anymore so there's nothing to cancel :)"
|
553 |
msgstr ""
|
554 |
|
555 |
+
#: includes/class-freemius.php:22295
|
556 |
msgid "Seems like we are having some temporary issue with your trial cancellation. Please try again in few minutes."
|
557 |
msgstr ""
|
558 |
|
559 |
+
#: includes/class-freemius.php:22314
|
560 |
msgid "Your %s free trial was successfully cancelled."
|
561 |
msgstr ""
|
562 |
|
563 |
+
#: includes/class-freemius.php:22641
|
564 |
msgid "Version %s was released."
|
565 |
msgstr ""
|
566 |
|
567 |
+
#: includes/class-freemius.php:22641
|
568 |
msgid "Please download %s."
|
569 |
msgstr ""
|
570 |
|
571 |
+
#: includes/class-freemius.php:22648
|
572 |
msgid "the latest %s version here"
|
573 |
msgstr ""
|
574 |
|
575 |
+
#: includes/class-freemius.php:22653
|
576 |
msgid "New"
|
577 |
msgstr ""
|
578 |
|
579 |
+
#: includes/class-freemius.php:22658
|
580 |
msgid "Seems like you got the latest release."
|
581 |
msgstr ""
|
582 |
|
583 |
+
#: includes/class-freemius.php:22659
|
584 |
msgid "You are all good!"
|
585 |
msgstr ""
|
586 |
|
587 |
+
#: includes/class-freemius.php:23062
|
588 |
msgid "Verification mail was just sent to %s. If you can't find it after 5 min, please check your spam box."
|
589 |
msgstr ""
|
590 |
|
591 |
+
#: includes/class-freemius.php:23202
|
592 |
msgid "Site successfully opted in."
|
593 |
msgstr ""
|
594 |
|
595 |
+
#: includes/class-freemius.php:23203, includes/class-freemius.php:24252
|
596 |
msgid "Awesome"
|
597 |
msgstr ""
|
598 |
|
599 |
+
#: includes/class-freemius.php:23219
|
600 |
+
msgid "Sharing diagnostic data with %s helps to provide functionality that's more relevant to your website, avoid WordPress or PHP version incompatibilities that can break your website, and recognize which languages & regions the plugin should be translated and tailored to."
|
601 |
msgstr ""
|
602 |
|
603 |
+
#: includes/class-freemius.php:23220
|
604 |
msgid "Thank you!"
|
605 |
msgstr ""
|
606 |
|
607 |
+
#: includes/class-freemius.php:23229
|
608 |
+
msgid "Diagnostic data will no longer be sent from %s to %s."
|
609 |
msgstr ""
|
610 |
|
611 |
+
#: includes/class-freemius.php:23384
|
612 |
+
msgid "A confirmation email was just sent to %s. The email owner must confirm the update within the next 4 hours."
|
613 |
msgstr ""
|
614 |
|
615 |
+
#: includes/class-freemius.php:23386
|
616 |
+
msgid "A confirmation email was just sent to %s. You must confirm the update within the next 4 hours. If you cannot find the email, please check your spam folder."
|
617 |
+
msgstr ""
|
618 |
+
|
619 |
+
#: includes/class-freemius.php:23393
|
620 |
msgid "Thanks for confirming the ownership change. An email was just sent to %s for final approval."
|
621 |
msgstr ""
|
622 |
|
623 |
+
#: includes/class-freemius.php:23398
|
624 |
msgid "%s is the new owner of the account."
|
625 |
msgstr ""
|
626 |
|
627 |
+
#: includes/class-freemius.php:23400
|
628 |
msgctxt "as congratulations"
|
629 |
msgid "Congrats"
|
630 |
msgstr ""
|
631 |
|
632 |
+
#: includes/class-freemius.php:23417
|
|
|
|
|
|
|
|
|
633 |
msgid "Please provide your full name."
|
634 |
msgstr ""
|
635 |
|
636 |
+
#: includes/class-freemius.php:23422
|
637 |
msgid "Your name was successfully updated."
|
638 |
msgstr ""
|
639 |
|
640 |
+
#: includes/class-freemius.php:23483
|
641 |
msgid "You have successfully updated your %s."
|
642 |
msgstr ""
|
643 |
|
644 |
+
#: includes/class-freemius.php:23542
|
645 |
msgid "Is this your client's site? %s if you wish to hide sensitive info like your email, license key, prices, billing address & invoices from the WP Admin."
|
646 |
msgstr ""
|
647 |
|
648 |
+
#: includes/class-freemius.php:23545
|
649 |
msgid "Click here"
|
650 |
msgstr ""
|
651 |
|
652 |
+
#: includes/class-freemius.php:23582, includes/class-freemius.php:23579
|
653 |
+
msgid "Bundle"
|
654 |
+
msgstr ""
|
655 |
+
|
656 |
+
#: includes/class-freemius.php:23662
|
657 |
msgid "Just letting you know that the add-ons information of %s is being pulled from an external server."
|
658 |
msgstr ""
|
659 |
|
660 |
+
#: includes/class-freemius.php:23663
|
661 |
msgctxt "advance notice of something that will need attention."
|
662 |
msgid "Heads up"
|
663 |
msgstr ""
|
664 |
|
665 |
+
#: includes/class-freemius.php:24292
|
666 |
msgctxt "exclamation"
|
667 |
msgid "Hey"
|
668 |
msgstr ""
|
669 |
|
670 |
+
#: includes/class-freemius.php:24292
|
671 |
msgid "How do you like %s so far? Test all our %s premium features with a %d-day free trial."
|
672 |
msgstr ""
|
673 |
|
674 |
+
#: includes/class-freemius.php:24300
|
675 |
msgid "No commitment for %s days - cancel anytime!"
|
676 |
msgstr ""
|
677 |
|
678 |
+
#: includes/class-freemius.php:24301
|
679 |
msgid "No credit card required"
|
680 |
msgstr ""
|
681 |
|
682 |
+
#: includes/class-freemius.php:24308, templates/forms/trial-start.php:53
|
683 |
msgctxt "call to action"
|
684 |
msgid "Start free trial"
|
685 |
msgstr ""
|
686 |
|
687 |
+
#: includes/class-freemius.php:24385
|
688 |
msgid "Hey there, did you know that %s has an affiliate program? If you like the %s you can become our ambassador and earn some cash!"
|
689 |
msgstr ""
|
690 |
|
691 |
+
#: includes/class-freemius.php:24394
|
692 |
msgid "Learn more"
|
693 |
msgstr ""
|
694 |
|
695 |
+
#: includes/class-freemius.php:24580, templates/account.php:573, templates/account.php:725, templates/connect.php:223, templates/connect.php:449, includes/managers/class-fs-clone-manager.php:1295, templates/forms/license-activation.php:27, templates/account/partials/addon.php:326
|
696 |
msgid "Activate License"
|
697 |
msgstr ""
|
698 |
|
699 |
+
#: includes/class-freemius.php:24581, templates/account.php:667, templates/account.php:724, templates/account/partials/addon.php:327, templates/account/partials/site.php:273
|
700 |
msgid "Change License"
|
701 |
msgstr ""
|
702 |
|
703 |
+
#: includes/class-freemius.php:24688, templates/account/partials/site.php:170
|
704 |
msgid "Opt Out"
|
705 |
msgstr ""
|
706 |
|
707 |
+
#: includes/class-freemius.php:24690, includes/class-freemius.php:24696, templates/account/partials/site.php:49, templates/account/partials/site.php:170
|
708 |
msgid "Opt In"
|
709 |
msgstr ""
|
710 |
|
711 |
+
#: includes/class-freemius.php:24931
|
712 |
msgid " The paid version of %1$s is already installed. Please activate it to start benefiting the %2$s features. %3$s"
|
713 |
msgstr ""
|
714 |
|
715 |
+
#: includes/class-freemius.php:24941
|
716 |
msgid "Activate %s features"
|
717 |
msgstr ""
|
718 |
|
719 |
+
#: includes/class-freemius.php:24954
|
720 |
msgid "Please follow these steps to complete the upgrade"
|
721 |
msgstr ""
|
722 |
|
723 |
+
#: includes/class-freemius.php:24958
|
724 |
msgid "Download the latest %s version"
|
725 |
msgstr ""
|
726 |
|
727 |
+
#: includes/class-freemius.php:24962
|
728 |
msgid "Upload and activate the downloaded version"
|
729 |
msgstr ""
|
730 |
|
731 |
+
#: includes/class-freemius.php:24964
|
732 |
msgid "How to upload and activate?"
|
733 |
msgstr ""
|
734 |
|
735 |
+
#: includes/class-freemius.php:25098
|
736 |
msgid "%sClick here%s to choose the sites where you'd like to activate the license on."
|
737 |
msgstr ""
|
738 |
|
739 |
+
#: includes/class-freemius.php:25267
|
740 |
msgid "Auto installation only works for opted-in users."
|
741 |
msgstr ""
|
742 |
|
743 |
+
#: includes/class-freemius.php:25277, includes/class-freemius.php:25310, includes/class-fs-plugin-updater.php:1284, includes/class-fs-plugin-updater.php:1298
|
744 |
msgid "Invalid module ID."
|
745 |
msgstr ""
|
746 |
|
747 |
+
#: includes/class-freemius.php:25286, includes/class-fs-plugin-updater.php:1320
|
748 |
msgid "Premium version already active."
|
749 |
msgstr ""
|
750 |
|
751 |
+
#: includes/class-freemius.php:25293
|
752 |
msgid "You do not have a valid license to access the premium version."
|
753 |
msgstr ""
|
754 |
|
755 |
+
#: includes/class-freemius.php:25300
|
756 |
msgid "Plugin is a \"Serviceware\" which means it does not have a premium code version."
|
757 |
msgstr ""
|
758 |
|
759 |
+
#: includes/class-freemius.php:25318, includes/class-fs-plugin-updater.php:1319
|
760 |
msgid "Premium add-on version already installed."
|
761 |
msgstr ""
|
762 |
|
763 |
+
#: includes/class-freemius.php:25672
|
764 |
msgid "View paid features"
|
765 |
msgstr ""
|
766 |
|
767 |
+
#: includes/class-freemius.php:25994
|
768 |
msgid "Thank you so much for using %s and its add-ons!"
|
769 |
msgstr ""
|
770 |
|
771 |
+
#: includes/class-freemius.php:25995
|
772 |
msgid "Thank you so much for using %s!"
|
773 |
msgstr ""
|
774 |
|
775 |
+
#: includes/class-freemius.php:26001
|
776 |
msgid "You've already opted-in to our usage-tracking, which helps us keep improving the %s."
|
777 |
msgstr ""
|
778 |
|
779 |
+
#: includes/class-freemius.php:26005
|
780 |
msgid "Thank you so much for using our products!"
|
781 |
msgstr ""
|
782 |
|
783 |
+
#: includes/class-freemius.php:26006
|
784 |
msgid "You've already opted-in to our usage-tracking, which helps us keep improving them."
|
785 |
msgstr ""
|
786 |
|
787 |
+
#: includes/class-freemius.php:26025
|
788 |
msgid "%s and its add-ons"
|
789 |
msgstr ""
|
790 |
|
791 |
+
#: includes/class-freemius.php:26034
|
792 |
msgid "Products"
|
793 |
msgstr ""
|
794 |
|
795 |
+
#: includes/class-freemius.php:26041, templates/connect.php:324
|
796 |
msgid "Yes"
|
797 |
msgstr ""
|
798 |
|
799 |
+
#: includes/class-freemius.php:26042, templates/connect.php:325
|
800 |
msgid "send me security & feature updates, educational content and offers."
|
801 |
msgstr ""
|
802 |
|
803 |
+
#: includes/class-freemius.php:26043, templates/connect.php:330
|
804 |
msgid "No"
|
805 |
msgstr ""
|
806 |
|
807 |
+
#: includes/class-freemius.php:26045, templates/connect.php:332
|
808 |
msgid "do %sNOT%s send me security & feature updates, educational content and offers."
|
809 |
msgstr ""
|
810 |
|
811 |
+
#: includes/class-freemius.php:26055
|
812 |
msgid "Due to the new %sEU General Data Protection Regulation (GDPR)%s compliance requirements it is required that you provide your explicit consent, again, confirming that you are onboard :-)"
|
813 |
msgstr ""
|
814 |
|
815 |
+
#: includes/class-freemius.php:26057, templates/connect.php:339
|
816 |
msgid "Please let us know if you'd like us to contact you for security & feature updates, educational content, and occasional offers:"
|
817 |
msgstr ""
|
818 |
|
819 |
+
#: includes/class-freemius.php:26339
|
820 |
msgid "License key is empty."
|
821 |
msgstr ""
|
822 |
|
828 |
msgid "Buy license"
|
829 |
msgstr ""
|
830 |
|
831 |
+
#: includes/class-fs-plugin-updater.php:331, includes/class-fs-plugin-updater.php:364
|
832 |
msgid "There is a %s of %s available."
|
833 |
msgstr ""
|
834 |
|
835 |
+
#: includes/class-fs-plugin-updater.php:333, includes/class-fs-plugin-updater.php:369
|
836 |
msgid "new Beta version"
|
837 |
msgstr ""
|
838 |
|
839 |
+
#: includes/class-fs-plugin-updater.php:334, includes/class-fs-plugin-updater.php:370
|
840 |
msgid "new version"
|
841 |
msgstr ""
|
842 |
|
843 |
+
#: includes/class-fs-plugin-updater.php:393
|
844 |
msgid "Important Upgrade Notice:"
|
845 |
msgstr ""
|
846 |
|
847 |
+
#: includes/class-fs-plugin-updater.php:1349
|
848 |
msgid "Installing plugin: %s"
|
849 |
msgstr ""
|
850 |
|
851 |
+
#: includes/class-fs-plugin-updater.php:1390
|
852 |
msgid "Unable to connect to the filesystem. Please confirm your credentials."
|
853 |
msgstr ""
|
854 |
|
855 |
+
#: includes/class-fs-plugin-updater.php:1572
|
856 |
msgid "The remote plugin package does not contain a folder with the desired slug and renaming did not work."
|
857 |
msgstr ""
|
858 |
|
859 |
+
#: includes/fs-plugin-info-dialog.php:542
|
860 |
msgid "Purchase More"
|
861 |
msgstr ""
|
862 |
|
863 |
+
#: includes/fs-plugin-info-dialog.php:543, templates/account/partials/addon.php:390
|
864 |
msgctxt "verb"
|
865 |
msgid "Purchase"
|
866 |
msgstr ""
|
867 |
|
868 |
+
#: includes/fs-plugin-info-dialog.php:547
|
869 |
msgid "Start my free %s"
|
870 |
msgstr ""
|
871 |
|
872 |
+
#: includes/fs-plugin-info-dialog.php:745
|
873 |
msgid "Install Free Version Update Now"
|
874 |
msgstr ""
|
875 |
|
876 |
+
#: includes/fs-plugin-info-dialog.php:746, templates/account.php:656
|
877 |
msgid "Install Update Now"
|
878 |
msgstr ""
|
879 |
|
880 |
+
#: includes/fs-plugin-info-dialog.php:755
|
881 |
msgid "Install Free Version Now"
|
882 |
msgstr ""
|
883 |
|
884 |
+
#: includes/fs-plugin-info-dialog.php:756, templates/add-ons.php:323, templates/auto-installation.php:111, templates/account/partials/addon.php:370, templates/account/partials/addon.php:423
|
885 |
msgid "Install Now"
|
886 |
msgstr ""
|
887 |
|
888 |
+
#: includes/fs-plugin-info-dialog.php:772
|
889 |
msgctxt "as download latest version"
|
890 |
msgid "Download Latest Free Version"
|
891 |
msgstr ""
|
892 |
|
893 |
+
#: includes/fs-plugin-info-dialog.php:773, templates/account.php:114, templates/add-ons.php:37, templates/account/partials/addon.php:30
|
894 |
msgctxt "as download latest version"
|
895 |
msgid "Download Latest"
|
896 |
msgstr ""
|
897 |
|
898 |
+
#: includes/fs-plugin-info-dialog.php:788, templates/add-ons.php:329, templates/account/partials/addon.php:361, templates/account/partials/addon.php:417
|
899 |
msgid "Activate this add-on"
|
900 |
msgstr ""
|
901 |
|
902 |
+
#: includes/fs-plugin-info-dialog.php:790, templates/connect.php:446
|
903 |
msgid "Activate Free Version"
|
904 |
msgstr ""
|
905 |
|
906 |
+
#: includes/fs-plugin-info-dialog.php:791, templates/account.php:138, templates/add-ons.php:330, templates/account/partials/addon.php:53
|
907 |
msgid "Activate"
|
908 |
msgstr ""
|
909 |
|
910 |
+
#: includes/fs-plugin-info-dialog.php:1003
|
911 |
msgctxt "Plugin installer section title"
|
912 |
msgid "Description"
|
913 |
msgstr ""
|
914 |
|
915 |
+
#: includes/fs-plugin-info-dialog.php:1004
|
916 |
msgctxt "Plugin installer section title"
|
917 |
msgid "Installation"
|
918 |
msgstr ""
|
919 |
|
920 |
+
#: includes/fs-plugin-info-dialog.php:1005
|
921 |
msgctxt "Plugin installer section title"
|
922 |
msgid "FAQ"
|
923 |
msgstr ""
|
924 |
|
925 |
+
#: includes/fs-plugin-info-dialog.php:1006, templates/plugin-info/description.php:55
|
926 |
msgid "Screenshots"
|
927 |
msgstr ""
|
928 |
|
929 |
+
#: includes/fs-plugin-info-dialog.php:1007
|
930 |
msgctxt "Plugin installer section title"
|
931 |
msgid "Changelog"
|
932 |
msgstr ""
|
933 |
|
934 |
+
#: includes/fs-plugin-info-dialog.php:1008
|
935 |
msgctxt "Plugin installer section title"
|
936 |
msgid "Reviews"
|
937 |
msgstr ""
|
938 |
|
939 |
+
#: includes/fs-plugin-info-dialog.php:1009
|
940 |
msgctxt "Plugin installer section title"
|
941 |
msgid "Other Notes"
|
942 |
msgstr ""
|
943 |
|
944 |
+
#: includes/fs-plugin-info-dialog.php:1024
|
945 |
msgctxt "Plugin installer section title"
|
946 |
msgid "Features & Pricing"
|
947 |
msgstr ""
|
948 |
|
949 |
+
#: includes/fs-plugin-info-dialog.php:1034
|
950 |
msgid "Plugin Install"
|
951 |
msgstr ""
|
952 |
|
953 |
+
#: includes/fs-plugin-info-dialog.php:1106
|
954 |
msgctxt "e.g. Professional Plan"
|
955 |
msgid "%s Plan"
|
956 |
msgstr ""
|
957 |
|
958 |
+
#: includes/fs-plugin-info-dialog.php:1132
|
959 |
msgctxt "e.g. the best product"
|
960 |
msgid "Best"
|
961 |
msgstr ""
|
962 |
|
963 |
+
#: includes/fs-plugin-info-dialog.php:1138, includes/fs-plugin-info-dialog.php:1158
|
964 |
msgctxt "as every month"
|
965 |
msgid "Monthly"
|
966 |
msgstr ""
|
967 |
|
968 |
+
#: includes/fs-plugin-info-dialog.php:1141
|
969 |
msgctxt "as once a year"
|
970 |
msgid "Annual"
|
971 |
msgstr ""
|
972 |
|
973 |
+
#: includes/fs-plugin-info-dialog.php:1144
|
974 |
msgid "Lifetime"
|
975 |
msgstr ""
|
976 |
|
977 |
+
#: includes/fs-plugin-info-dialog.php:1158, includes/fs-plugin-info-dialog.php:1160, includes/fs-plugin-info-dialog.php:1162
|
978 |
msgctxt "e.g. billed monthly"
|
979 |
msgid "Billed %s"
|
980 |
msgstr ""
|
981 |
|
982 |
+
#: includes/fs-plugin-info-dialog.php:1160
|
983 |
msgctxt "as once a year"
|
984 |
msgid "Annually"
|
985 |
msgstr ""
|
986 |
|
987 |
+
#: includes/fs-plugin-info-dialog.php:1162
|
988 |
msgctxt "as once a year"
|
989 |
msgid "Once"
|
990 |
msgstr ""
|
991 |
|
992 |
+
#: includes/fs-plugin-info-dialog.php:1168
|
993 |
msgid "Single Site License"
|
994 |
msgstr ""
|
995 |
|
996 |
+
#: includes/fs-plugin-info-dialog.php:1170
|
997 |
msgid "Unlimited Licenses"
|
998 |
msgstr ""
|
999 |
|
1000 |
+
#: includes/fs-plugin-info-dialog.php:1172
|
1001 |
msgid "Up to %s Sites"
|
1002 |
msgstr ""
|
1003 |
|
1004 |
+
#: includes/fs-plugin-info-dialog.php:1182, templates/plugin-info/features.php:82
|
1005 |
msgctxt "as monthly period"
|
1006 |
msgid "mo"
|
1007 |
msgstr ""
|
1008 |
|
1009 |
+
#: includes/fs-plugin-info-dialog.php:1189, templates/plugin-info/features.php:80
|
1010 |
msgctxt "as annual period"
|
1011 |
msgid "year"
|
1012 |
msgstr ""
|
1013 |
|
1014 |
+
#: includes/fs-plugin-info-dialog.php:1243
|
1015 |
msgctxt "noun"
|
1016 |
msgid "Price"
|
1017 |
msgstr ""
|
1018 |
|
1019 |
+
#: includes/fs-plugin-info-dialog.php:1291
|
1020 |
msgid "Save %s"
|
1021 |
msgstr ""
|
1022 |
|
1023 |
+
#: includes/fs-plugin-info-dialog.php:1301
|
1024 |
msgid "No commitment for %s - cancel anytime"
|
1025 |
msgstr ""
|
1026 |
|
1027 |
+
#: includes/fs-plugin-info-dialog.php:1304
|
1028 |
msgid "After your free %s, pay as little as %s"
|
1029 |
msgstr ""
|
1030 |
|
1031 |
+
#: includes/fs-plugin-info-dialog.php:1315
|
1032 |
msgid "Details"
|
1033 |
msgstr ""
|
1034 |
|
1035 |
+
#: includes/fs-plugin-info-dialog.php:1319, templates/account.php:125, templates/debug.php:232, templates/debug.php:269, templates/debug.php:514, templates/account/partials/addon.php:41
|
1036 |
msgctxt "product version"
|
1037 |
msgid "Version"
|
1038 |
msgstr ""
|
1039 |
|
1040 |
+
#: includes/fs-plugin-info-dialog.php:1326
|
1041 |
msgctxt "as the plugin author"
|
1042 |
msgid "Author"
|
1043 |
msgstr ""
|
1044 |
|
1045 |
+
#: includes/fs-plugin-info-dialog.php:1333
|
1046 |
msgid "Last Updated"
|
1047 |
msgstr ""
|
1048 |
|
1049 |
+
#: includes/fs-plugin-info-dialog.php:1338, templates/account.php:544
|
1050 |
msgctxt "x-ago"
|
1051 |
msgid "%s ago"
|
1052 |
msgstr ""
|
1053 |
|
1054 |
+
#: includes/fs-plugin-info-dialog.php:1347
|
1055 |
msgid "Requires WordPress Version"
|
1056 |
msgstr ""
|
1057 |
|
1058 |
+
#: includes/fs-plugin-info-dialog.php:1350, includes/fs-plugin-info-dialog.php:1370
|
1059 |
msgid "%s or higher"
|
1060 |
msgstr ""
|
1061 |
|
1062 |
+
#: includes/fs-plugin-info-dialog.php:1358
|
1063 |
msgid "Compatible up to"
|
1064 |
msgstr ""
|
1065 |
|
1066 |
+
#: includes/fs-plugin-info-dialog.php:1366
|
1067 |
+
msgid "Requires PHP Version"
|
1068 |
+
msgstr ""
|
1069 |
+
|
1070 |
+
#: includes/fs-plugin-info-dialog.php:1379
|
1071 |
msgid "Downloaded"
|
1072 |
msgstr ""
|
1073 |
|
1074 |
+
#: includes/fs-plugin-info-dialog.php:1383
|
1075 |
msgid "%s time"
|
1076 |
msgstr ""
|
1077 |
|
1078 |
+
#: includes/fs-plugin-info-dialog.php:1385
|
1079 |
msgid "%s times"
|
1080 |
msgstr ""
|
1081 |
|
1082 |
+
#: includes/fs-plugin-info-dialog.php:1396
|
1083 |
msgid "WordPress.org Plugin Page"
|
1084 |
msgstr ""
|
1085 |
|
1086 |
+
#: includes/fs-plugin-info-dialog.php:1405
|
1087 |
msgid "Plugin Homepage"
|
1088 |
msgstr ""
|
1089 |
|
1090 |
+
#: includes/fs-plugin-info-dialog.php:1414, includes/fs-plugin-info-dialog.php:1498
|
1091 |
msgid "Donate to this plugin"
|
1092 |
msgstr ""
|
1093 |
|
1094 |
+
#: includes/fs-plugin-info-dialog.php:1421
|
1095 |
msgid "Average Rating"
|
1096 |
msgstr ""
|
1097 |
|
1098 |
+
#: includes/fs-plugin-info-dialog.php:1428
|
1099 |
msgid "based on %s"
|
1100 |
msgstr ""
|
1101 |
|
1102 |
+
#: includes/fs-plugin-info-dialog.php:1432
|
1103 |
msgid "%s rating"
|
1104 |
msgstr ""
|
1105 |
|
1106 |
+
#: includes/fs-plugin-info-dialog.php:1434
|
1107 |
msgid "%s ratings"
|
1108 |
msgstr ""
|
1109 |
|
1110 |
+
#: includes/fs-plugin-info-dialog.php:1449
|
1111 |
msgid "%s star"
|
1112 |
msgstr ""
|
1113 |
|
1114 |
+
#: includes/fs-plugin-info-dialog.php:1451
|
1115 |
msgid "%s stars"
|
1116 |
msgstr ""
|
1117 |
|
1118 |
+
#: includes/fs-plugin-info-dialog.php:1463
|
1119 |
msgid "Click to see reviews that provided a rating of %s"
|
1120 |
msgstr ""
|
1121 |
|
1122 |
+
#: includes/fs-plugin-info-dialog.php:1476
|
1123 |
msgid "Contributors"
|
1124 |
msgstr ""
|
1125 |
|
1126 |
+
#: includes/fs-plugin-info-dialog.php:1517
|
1127 |
+
msgid "This plugin requires a newer version of PHP."
|
1128 |
+
msgstr ""
|
1129 |
+
|
1130 |
+
#: includes/fs-plugin-info-dialog.php:1526
|
1131 |
+
msgid "<a href=\"%s\" target=\"_blank\">Click here to learn more about updating PHP</a>."
|
1132 |
+
msgstr ""
|
1133 |
+
|
1134 |
+
#: includes/fs-plugin-info-dialog.php:1540, includes/fs-plugin-info-dialog.php:1542
|
1135 |
msgid "Warning"
|
1136 |
msgstr ""
|
1137 |
|
1138 |
+
#: includes/fs-plugin-info-dialog.php:1540
|
1139 |
msgid "This plugin has not been tested with your current version of WordPress."
|
1140 |
msgstr ""
|
1141 |
|
1142 |
+
#: includes/fs-plugin-info-dialog.php:1542
|
1143 |
msgid "This plugin has not been marked as compatible with your version of WordPress."
|
1144 |
msgstr ""
|
1145 |
|
1146 |
+
#: includes/fs-plugin-info-dialog.php:1561
|
1147 |
msgid "Paid add-on must be deployed to Freemius."
|
1148 |
msgstr ""
|
1149 |
|
1150 |
+
#: includes/fs-plugin-info-dialog.php:1562
|
1151 |
msgid "Add-on must be deployed to WordPress.org or Freemius."
|
1152 |
msgstr ""
|
1153 |
|
1154 |
+
#: includes/fs-plugin-info-dialog.php:1583
|
1155 |
msgid "Newer Version (%s) Installed"
|
1156 |
msgstr ""
|
1157 |
|
1158 |
+
#: includes/fs-plugin-info-dialog.php:1584
|
1159 |
msgid "Newer Free Version (%s) Installed"
|
1160 |
msgstr ""
|
1161 |
|
1162 |
+
#: includes/fs-plugin-info-dialog.php:1591
|
1163 |
msgid "Latest Version Installed"
|
1164 |
msgstr ""
|
1165 |
|
1166 |
+
#: includes/fs-plugin-info-dialog.php:1592
|
1167 |
msgid "Latest Free Version Installed"
|
1168 |
msgstr ""
|
1169 |
|
1170 |
+
#: templates/account.php:115, templates/forms/subscription-cancellation.php:96, templates/account/partials/addon.php:31, templates/account/partials/site.php:313
|
1171 |
msgid "Downgrading your plan"
|
1172 |
msgstr ""
|
1173 |
|
1174 |
+
#: templates/account.php:116, templates/forms/subscription-cancellation.php:97, templates/account/partials/addon.php:32, templates/account/partials/site.php:314
|
1175 |
msgid "Cancelling the subscription"
|
1176 |
msgstr ""
|
1177 |
|
1178 |
#. translators: %1$s: Either 'Downgrading your plan' or 'Cancelling the subscription'
|
1179 |
+
#: templates/account.php:118, templates/forms/subscription-cancellation.php:99, templates/account/partials/site.php:316
|
1180 |
msgid "%1$s will immediately stop all future recurring payments and your %2$s plan license will expire in %3$s."
|
1181 |
msgstr ""
|
1182 |
|
1183 |
+
#: templates/account.php:119, templates/forms/subscription-cancellation.php:100, templates/account/partials/addon.php:35, templates/account/partials/site.php:317
|
1184 |
msgid "Please note that we will not be able to grandfather outdated pricing for renewals/new subscriptions after a cancellation. If you choose to renew the subscription manually in the future, after a price increase, which typically occurs once a year, you will be charged the updated price."
|
1185 |
msgstr ""
|
1186 |
|
1187 |
+
#: templates/account.php:120, templates/forms/subscription-cancellation.php:106, templates/account/partials/addon.php:36
|
1188 |
msgid "Cancelling the trial will immediately block access to all premium features. Are you sure?"
|
1189 |
msgstr ""
|
1190 |
|
1191 |
+
#: templates/account.php:121, templates/forms/subscription-cancellation.php:101, templates/account/partials/addon.php:37, templates/account/partials/site.php:318
|
1192 |
msgid "You can still enjoy all %s features but you will not have access to %s security & feature updates, nor support."
|
1193 |
msgstr ""
|
1194 |
|
1195 |
+
#: templates/account.php:122, templates/forms/subscription-cancellation.php:102, templates/account/partials/addon.php:38, templates/account/partials/site.php:319
|
1196 |
msgid "Once your license expires you can still use the Free version but you will NOT have access to the %s features."
|
1197 |
msgstr ""
|
1198 |
|
1199 |
#. translators: %s: Plan title (e.g. "Professional")
|
1200 |
+
#: templates/account.php:124, templates/account/partials/activate-license-button.php:31, templates/account/partials/addon.php:40
|
1201 |
msgid "Activate %s Plan"
|
1202 |
msgstr ""
|
1203 |
|
1204 |
#. translators: %s: Time period (e.g. Auto renews in "2 months")
|
1205 |
+
#: templates/account.php:127, templates/account/partials/addon.php:43, templates/account/partials/site.php:293
|
1206 |
msgid "Auto renews in %s"
|
1207 |
msgstr ""
|
1208 |
|
1209 |
#. translators: %s: Time period (e.g. Expires in "2 months")
|
1210 |
+
#: templates/account.php:129, templates/account/partials/addon.php:45, templates/account/partials/site.php:295
|
1211 |
msgid "Expires in %s"
|
1212 |
msgstr ""
|
1213 |
|
1214 |
+
#: templates/account.php:130
|
1215 |
msgctxt "as synchronize license"
|
1216 |
msgid "Sync License"
|
1217 |
msgstr ""
|
1218 |
|
1219 |
+
#: templates/account.php:131, templates/account/partials/addon.php:46
|
1220 |
msgid "Cancel Trial"
|
1221 |
msgstr ""
|
1222 |
|
1223 |
+
#: templates/account.php:132, templates/account/partials/addon.php:47
|
1224 |
msgid "Change Plan"
|
1225 |
msgstr ""
|
1226 |
|
1227 |
+
#: templates/account.php:133, templates/account/partials/addon.php:48
|
1228 |
msgctxt "verb"
|
1229 |
msgid "Upgrade"
|
1230 |
msgstr ""
|
1231 |
|
1232 |
+
#: templates/account.php:135, templates/account/partials/addon.php:50, templates/account/partials/site.php:320
|
1233 |
msgctxt "verb"
|
1234 |
msgid "Downgrade"
|
1235 |
msgstr ""
|
1236 |
|
1237 |
+
#: templates/account.php:137, templates/add-ons.php:246, templates/plugin-info/features.php:72, templates/account/partials/addon.php:52, templates/account/partials/site.php:33
|
1238 |
msgid "Free"
|
1239 |
msgstr ""
|
1240 |
|
1241 |
+
#: templates/account.php:139, templates/debug.php:408, includes/customizer/class-fs-customizer-upsell-control.php:110, templates/account/partials/addon.php:54
|
1242 |
msgctxt "as product pricing plan"
|
1243 |
msgid "Plan"
|
1244 |
msgstr ""
|
1245 |
|
1246 |
+
#: templates/account.php:140
|
1247 |
msgid "Bundle Plan"
|
1248 |
msgstr ""
|
1249 |
|
1250 |
+
#: templates/account.php:272
|
1251 |
msgid "Free Trial"
|
1252 |
msgstr ""
|
1253 |
|
1254 |
+
#: templates/account.php:283
|
1255 |
msgid "Account Details"
|
1256 |
msgstr ""
|
1257 |
|
1258 |
+
#: templates/account.php:290, templates/forms/data-debug-mode.php:33
|
1259 |
msgid "Start Debug"
|
1260 |
msgstr ""
|
1261 |
|
1262 |
+
#: templates/account.php:292
|
1263 |
msgid "Stop Debug"
|
1264 |
msgstr ""
|
1265 |
|
1266 |
+
#: templates/account.php:299
|
1267 |
msgid "Billing & Invoices"
|
1268 |
msgstr ""
|
1269 |
|
1270 |
+
#: templates/account.php:322, templates/account/partials/addon.php:236, templates/account/partials/deactivate-license-button.php:35
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1271 |
msgid "Deactivate License"
|
1272 |
msgstr ""
|
1273 |
|
1274 |
+
#: templates/account.php:345, templates/forms/subscription-cancellation.php:125
|
1275 |
msgid "Are you sure you want to proceed?"
|
1276 |
msgstr ""
|
1277 |
|
1278 |
+
#: templates/account.php:345, templates/account/partials/addon.php:260
|
1279 |
msgid "Cancel Subscription"
|
1280 |
msgstr ""
|
1281 |
|
1282 |
+
#: templates/account.php:374, templates/account/partials/addon.php:345
|
1283 |
msgctxt "as synchronize"
|
1284 |
msgid "Sync"
|
1285 |
msgstr ""
|
1286 |
|
1287 |
+
#: templates/account.php:389, templates/debug.php:571
|
1288 |
msgid "Name"
|
1289 |
msgstr ""
|
1290 |
|
1291 |
+
#: templates/account.php:395, templates/debug.php:572
|
1292 |
msgid "Email"
|
1293 |
msgstr ""
|
1294 |
|
1295 |
+
#: templates/account.php:402, templates/debug.php:406, templates/debug.php:621
|
1296 |
msgid "User ID"
|
1297 |
msgstr ""
|
1298 |
|
1299 |
+
#: templates/account.php:420, templates/account.php:738, templates/account.php:789, templates/debug.php:267, templates/debug.php:400, templates/debug.php:511, templates/debug.php:570, templates/debug.php:619, templates/debug.php:698, templates/account/payments.php:35, templates/debug/logger.php:21
|
1300 |
msgid "ID"
|
1301 |
msgstr ""
|
1302 |
|
1303 |
+
#: templates/account.php:427
|
1304 |
msgid "Site ID"
|
1305 |
msgstr ""
|
1306 |
|
1307 |
+
#: templates/account.php:430
|
1308 |
msgid "No ID"
|
1309 |
msgstr ""
|
1310 |
|
1311 |
+
#: templates/account.php:435, templates/debug.php:274, templates/debug.php:409, templates/debug.php:515, templates/debug.php:574, templates/account/partials/site.php:228
|
1312 |
msgid "Public Key"
|
1313 |
msgstr ""
|
1314 |
|
1315 |
+
#: templates/account.php:441, templates/debug.php:410, templates/debug.php:516, templates/debug.php:575, templates/account/partials/site.php:241
|
1316 |
msgid "Secret Key"
|
1317 |
msgstr ""
|
1318 |
|
1319 |
+
#: templates/account.php:444
|
1320 |
msgctxt "as secret encryption key missing"
|
1321 |
msgid "No Secret"
|
1322 |
msgstr ""
|
1323 |
|
1324 |
+
#: templates/account.php:471, templates/account/partials/site.php:120, templates/account/partials/site.php:122
|
1325 |
msgid "Trial"
|
1326 |
msgstr ""
|
1327 |
|
1328 |
+
#: templates/account.php:498, templates/debug.php:627, templates/account/partials/site.php:262
|
1329 |
msgid "License Key"
|
1330 |
msgstr ""
|
1331 |
|
1332 |
+
#: templates/account.php:529
|
1333 |
msgid "Join the Beta program"
|
1334 |
msgstr ""
|
1335 |
|
1336 |
+
#: templates/account.php:535
|
1337 |
msgid "not verified"
|
1338 |
msgstr ""
|
1339 |
|
1340 |
+
#: templates/account.php:544, templates/account/partials/addon.php:195
|
1341 |
msgid "Expired"
|
1342 |
msgstr ""
|
1343 |
|
1344 |
+
#: templates/account.php:602
|
1345 |
msgid "Premium version"
|
1346 |
msgstr ""
|
1347 |
|
1348 |
+
#: templates/account.php:604
|
1349 |
msgid "Free version"
|
1350 |
msgstr ""
|
1351 |
|
1352 |
+
#: templates/account.php:616
|
1353 |
msgid "Verify Email"
|
1354 |
msgstr ""
|
1355 |
|
1356 |
+
#: templates/account.php:630
|
1357 |
msgid "Download %s Version"
|
1358 |
msgstr ""
|
1359 |
|
1360 |
+
#: templates/account.php:646
|
1361 |
msgid "Download Paid Version"
|
1362 |
msgstr ""
|
1363 |
|
1364 |
+
#: templates/account.php:664, templates/account.php:927, templates/account/partials/site.php:250, templates/account/partials/site.php:272
|
1365 |
msgctxt "verb"
|
1366 |
msgid "Show"
|
1367 |
msgstr ""
|
1368 |
|
1369 |
+
#: templates/account.php:680
|
1370 |
msgid "What is your %s?"
|
1371 |
msgstr ""
|
1372 |
|
1373 |
+
#: templates/account.php:688, templates/account/billing.php:21
|
1374 |
msgctxt "verb"
|
1375 |
msgid "Edit"
|
1376 |
msgstr ""
|
1377 |
|
1378 |
+
#: templates/account.php:693, templates/forms/user-change.php:27
|
1379 |
msgid "Change User"
|
1380 |
msgstr ""
|
1381 |
|
1382 |
+
#: templates/account.php:717
|
1383 |
msgid "Sites"
|
1384 |
msgstr ""
|
1385 |
|
1386 |
+
#: templates/account.php:730
|
1387 |
msgid "Search by address"
|
1388 |
msgstr ""
|
1389 |
|
1390 |
+
#: templates/account.php:739, templates/debug.php:403
|
1391 |
msgid "Address"
|
1392 |
msgstr ""
|
1393 |
|
1394 |
+
#: templates/account.php:740
|
1395 |
msgid "License"
|
1396 |
msgstr ""
|
1397 |
|
1398 |
+
#: templates/account.php:741
|
1399 |
msgid "Plan"
|
1400 |
msgstr ""
|
1401 |
|
1402 |
+
#: templates/account.php:792
|
1403 |
msgctxt "as software license"
|
1404 |
msgid "License"
|
1405 |
msgstr ""
|
1406 |
|
1407 |
+
#: templates/account.php:921
|
1408 |
msgctxt "verb"
|
1409 |
msgid "Hide"
|
1410 |
msgstr ""
|
1411 |
|
1412 |
+
#: templates/account.php:943, templates/forms/data-debug-mode.php:31, templates/forms/deactivation/form.php:358, templates/forms/deactivation/form.php:389
|
1413 |
msgid "Processing"
|
1414 |
msgstr ""
|
1415 |
|
1416 |
+
#: templates/account.php:946
|
1417 |
msgid "Get updates for bleeding edge Beta versions of %s."
|
1418 |
msgstr ""
|
1419 |
|
1420 |
+
#: templates/account.php:1004
|
1421 |
msgid "Cancelling %s"
|
1422 |
msgstr ""
|
1423 |
|
1424 |
+
#: templates/account.php:1004, templates/account.php:1021, templates/forms/subscription-cancellation.php:27, templates/forms/deactivation/form.php:178
|
1425 |
msgid "trial"
|
1426 |
msgstr ""
|
1427 |
|
1428 |
+
#: templates/account.php:1019, templates/forms/deactivation/form.php:195
|
1429 |
msgid "Cancelling %s..."
|
1430 |
msgstr ""
|
1431 |
|
1432 |
+
#: templates/account.php:1022, templates/forms/subscription-cancellation.php:28, templates/forms/deactivation/form.php:179
|
1433 |
msgid "subscription"
|
1434 |
msgstr ""
|
1435 |
|
1436 |
+
#: templates/account.php:1036
|
1437 |
msgid "Deactivating your license will block all premium features, but will enable activating the license on another site. Are you sure you want to proceed?"
|
1438 |
msgstr ""
|
1439 |
|
1440 |
+
#: templates/account.php:1110
|
1441 |
msgid "Disabling white-label mode"
|
1442 |
msgstr ""
|
1443 |
|
1444 |
+
#: templates/account.php:1111
|
1445 |
msgid "Enabling white-label mode"
|
1446 |
msgstr ""
|
1447 |
|
1467 |
msgid "Installed"
|
1468 |
msgstr ""
|
1469 |
|
1470 |
+
#: templates/admin-notice.php:13, templates/forms/license-activation.php:243, templates/forms/resend-key.php:80
|
1471 |
msgctxt "as close a window"
|
1472 |
msgid "Dismiss"
|
1473 |
msgstr ""
|
1501 |
msgstr ""
|
1502 |
|
1503 |
#. translators: %s: name (e.g. Hey John,)
|
1504 |
+
#: templates/connect.php:121
|
1505 |
msgctxt "greeting"
|
1506 |
msgid "Hey %s,"
|
1507 |
msgstr ""
|
1508 |
|
1509 |
+
#: templates/connect.php:189
|
1510 |
+
msgid "Never miss an important update"
|
1511 |
+
msgstr ""
|
1512 |
+
|
1513 |
+
#: templates/connect.php:197
|
1514 |
+
msgid "Thank you for updating to %1$s v%2$s!"
|
1515 |
+
msgstr ""
|
1516 |
+
|
1517 |
+
#: templates/connect.php:207
|
1518 |
msgid "Allow & Continue"
|
1519 |
msgstr ""
|
1520 |
|
1521 |
+
#: templates/connect.php:211
|
1522 |
msgid "Re-send activation email"
|
1523 |
msgstr ""
|
1524 |
|
1525 |
+
#: templates/connect.php:215
|
1526 |
msgid "Thanks %s!"
|
1527 |
msgstr ""
|
1528 |
|
1529 |
+
#: templates/connect.php:227
|
1530 |
+
msgid "Welcome to %s! To get started, please enter your license key:"
|
1531 |
msgstr ""
|
1532 |
|
1533 |
+
#: templates/connect.php:237
|
1534 |
+
msgid "Opt in to get email notifications for security & feature updates, educational content, and occasional offers, and to share some basic WordPress environment info. This will help us make the %s more compatible with your site and better at doing what you need it to."
|
1535 |
msgstr ""
|
1536 |
|
1537 |
+
#: templates/connect.php:239
|
1538 |
+
msgid "Opt in to get email notifications for security & feature updates, and to share some basic WordPress environment info. This will help us make the %s more compatible with your site and better at doing what you need it to."
|
1539 |
+
msgstr ""
|
1540 |
+
|
1541 |
+
#. translators: %s: module type (plugin, theme, or add-on)
|
1542 |
+
#: templates/connect.php:245
|
1543 |
+
msgid "We have introduced this opt-in so you never miss an important update and help us make the %s more compatible with your site and better at doing what you need it to."
|
1544 |
msgstr ""
|
1545 |
|
1546 |
+
#: templates/connect.php:248
|
1547 |
+
msgid "Opt in to get email notifications for security & feature updates, educational content, and occasional offers, and to share some basic WordPress environment info."
|
1548 |
msgstr ""
|
1549 |
|
1550 |
+
#: templates/connect.php:249
|
1551 |
+
msgid "Opt in to get email notifications for security & feature updates, and to share some basic WordPress environment info."
|
1552 |
msgstr ""
|
1553 |
|
1554 |
+
#: templates/connect.php:252
|
1555 |
+
msgid "If you skip this, that's okay! %1$s will still work just fine."
|
1556 |
msgstr ""
|
1557 |
|
1558 |
+
#: templates/connect.php:282
|
1559 |
msgid "We're excited to introduce the Freemius network-level integration."
|
1560 |
msgstr ""
|
1561 |
|
1562 |
+
#: templates/connect.php:285
|
1563 |
msgid "During the update process we detected %d site(s) that are still pending license activation."
|
1564 |
msgstr ""
|
1565 |
|
1566 |
+
#: templates/connect.php:287
|
1567 |
msgid "If you'd like to use the %s on those sites, please enter your license key below and click the activation button."
|
1568 |
msgstr ""
|
1569 |
|
1570 |
+
#: templates/connect.php:289
|
1571 |
msgid "%s's paid features"
|
1572 |
msgstr ""
|
1573 |
|
1574 |
+
#: templates/connect.php:294
|
1575 |
msgid "Alternatively, you can skip it for now and activate the license later, in your %s's network-level Account page."
|
1576 |
msgstr ""
|
1577 |
|
1578 |
+
#: templates/connect.php:296
|
1579 |
msgid "During the update process we detected %s site(s) in the network that are still pending your attention."
|
1580 |
msgstr ""
|
1581 |
|
1582 |
+
#: templates/connect.php:305, templates/forms/data-debug-mode.php:35, templates/forms/license-activation.php:42
|
1583 |
msgid "License key"
|
1584 |
msgstr ""
|
1585 |
|
1586 |
+
#: templates/connect.php:308, templates/forms/license-activation.php:22
|
1587 |
msgid "Can't find your license key?"
|
1588 |
msgstr ""
|
1589 |
|
1590 |
+
#: templates/connect.php:371, templates/connect.php:695, templates/forms/deactivation/retry-skip.php:20
|
1591 |
msgctxt "verb"
|
1592 |
msgid "Skip"
|
1593 |
msgstr ""
|
1594 |
|
1595 |
+
#: templates/connect.php:374
|
1596 |
msgid "Delegate to Site Admins"
|
1597 |
msgstr ""
|
1598 |
|
1599 |
+
#: templates/connect.php:374
|
1600 |
msgid "If you click it, this decision will be delegated to the sites administrators."
|
1601 |
msgstr ""
|
1602 |
|
1603 |
+
#: templates/connect.php:401
|
1604 |
msgid "License issues?"
|
1605 |
msgstr ""
|
1606 |
|
1607 |
+
#: templates/connect.php:425
|
1608 |
+
msgid "For delivery of security & feature updates, and license management, %s needs to"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1609 |
msgstr ""
|
1610 |
|
1611 |
#: templates/connect.php:430
|
1612 |
+
msgid "This will allow %s to"
|
1613 |
msgstr ""
|
1614 |
|
1615 |
+
#: templates/connect.php:445
|
1616 |
msgid "Don't have a license key?"
|
1617 |
msgstr ""
|
1618 |
|
1619 |
+
#: templates/connect.php:448
|
1620 |
msgid "Have a license key?"
|
1621 |
msgstr ""
|
1622 |
|
1623 |
+
#: templates/connect.php:456
|
1624 |
+
msgid "Freemius is our licensing and software updates engine"
|
1625 |
+
msgstr ""
|
1626 |
+
|
1627 |
+
#: templates/connect.php:459
|
1628 |
msgid "Privacy Policy"
|
1629 |
msgstr ""
|
1630 |
|
1631 |
+
#: templates/connect.php:461
|
1632 |
msgid "License Agreement"
|
1633 |
msgstr ""
|
1634 |
|
1635 |
+
#: templates/connect.php:461
|
1636 |
msgid "Terms of Service"
|
1637 |
msgstr ""
|
1638 |
|
1639 |
+
#: templates/connect.php:881
|
1640 |
msgctxt "as in the process of sending an email"
|
1641 |
msgid "Sending email"
|
1642 |
msgstr ""
|
1643 |
|
1644 |
+
#: templates/connect.php:882
|
1645 |
msgctxt "as activating plugin"
|
1646 |
msgid "Activating"
|
1647 |
msgstr ""
|
1660 |
msgid "On"
|
1661 |
msgstr ""
|
1662 |
|
1663 |
+
#: templates/debug.php:24
|
1664 |
msgid "SDK"
|
1665 |
msgstr ""
|
1666 |
|
1667 |
+
#: templates/debug.php:28
|
1668 |
msgctxt "as code debugging"
|
1669 |
msgid "Debugging"
|
1670 |
msgstr ""
|
1671 |
|
1672 |
+
#: templates/debug.php:58, templates/debug.php:279, templates/debug.php:411, templates/debug.php:576
|
1673 |
msgid "Actions"
|
1674 |
msgstr ""
|
1675 |
|
1676 |
+
#: templates/debug.php:68
|
1677 |
msgid "Are you sure you want to delete all Freemius data?"
|
1678 |
msgstr ""
|
1679 |
|
1680 |
+
#: templates/debug.php:68
|
1681 |
msgid "Delete All Accounts"
|
1682 |
msgstr ""
|
1683 |
|
1684 |
+
#: templates/debug.php:75
|
1685 |
msgid "Clear API Cache"
|
1686 |
msgstr ""
|
1687 |
|
1688 |
+
#: templates/debug.php:83
|
1689 |
msgid "Clear Updates Transients"
|
1690 |
msgstr ""
|
1691 |
|
1692 |
+
#: templates/debug.php:92
|
1693 |
+
msgid "Reset Deactivation Snoozing"
|
1694 |
+
msgstr ""
|
1695 |
+
|
1696 |
+
#: templates/debug.php:100
|
1697 |
msgid "Sync Data From Server"
|
1698 |
msgstr ""
|
1699 |
|
1700 |
+
#: templates/debug.php:109
|
1701 |
msgid "Migrate Options to Network"
|
1702 |
msgstr ""
|
1703 |
|
1704 |
+
#: templates/debug.php:114
|
1705 |
msgid "Load DB Option"
|
1706 |
msgstr ""
|
1707 |
|
1708 |
+
#: templates/debug.php:117
|
1709 |
msgid "Set DB Option"
|
1710 |
msgstr ""
|
1711 |
|
1712 |
+
#: templates/debug.php:211
|
1713 |
msgid "Key"
|
1714 |
msgstr ""
|
1715 |
|
1716 |
+
#: templates/debug.php:212
|
1717 |
msgid "Value"
|
1718 |
msgstr ""
|
1719 |
|
1720 |
+
#: templates/debug.php:228
|
1721 |
msgctxt "as software development kit versions"
|
1722 |
msgid "SDK Versions"
|
1723 |
msgstr ""
|
1724 |
|
1725 |
+
#: templates/debug.php:233
|
1726 |
msgid "SDK Path"
|
1727 |
msgstr ""
|
1728 |
|
1729 |
+
#: templates/debug.php:234, templates/debug.php:273
|
1730 |
msgid "Module Path"
|
1731 |
msgstr ""
|
1732 |
|
1733 |
+
#: templates/debug.php:235
|
1734 |
msgid "Is Active"
|
1735 |
msgstr ""
|
1736 |
|
1737 |
+
#: templates/debug.php:263, templates/debug/plugins-themes-sync.php:35
|
1738 |
msgid "Plugins"
|
1739 |
msgstr ""
|
1740 |
|
1741 |
+
#: templates/debug.php:263, templates/debug/plugins-themes-sync.php:56
|
1742 |
msgid "Themes"
|
1743 |
msgstr ""
|
1744 |
|
1745 |
+
#: templates/debug.php:268, templates/debug.php:405, templates/debug.php:513, templates/debug/scheduled-crons.php:80
|
1746 |
msgid "Slug"
|
1747 |
msgstr ""
|
1748 |
|
1749 |
+
#: templates/debug.php:270, templates/debug.php:512
|
1750 |
msgid "Title"
|
1751 |
msgstr ""
|
1752 |
|
1753 |
+
#: templates/debug.php:271
|
1754 |
msgctxt "as application program interface"
|
1755 |
msgid "API"
|
1756 |
msgstr ""
|
1757 |
|
1758 |
+
#: templates/debug.php:272
|
1759 |
msgid "Freemius State"
|
1760 |
msgstr ""
|
1761 |
|
1762 |
+
#: templates/debug.php:276
|
1763 |
msgid "Network Blog"
|
1764 |
msgstr ""
|
1765 |
|
1766 |
+
#: templates/debug.php:277
|
1767 |
msgid "Network User"
|
1768 |
msgstr ""
|
1769 |
|
1770 |
+
#: templates/debug.php:321
|
1771 |
msgctxt "as connection was successful"
|
1772 |
msgid "Connected"
|
1773 |
msgstr ""
|
1774 |
|
1775 |
+
#: templates/debug.php:322
|
1776 |
msgctxt "as connection blocked"
|
1777 |
msgid "Blocked"
|
1778 |
msgstr ""
|
1779 |
|
1780 |
+
#: templates/debug.php:358
|
1781 |
msgid "Simulate Trial Promotion"
|
1782 |
msgstr ""
|
1783 |
|
1784 |
+
#: templates/debug.php:370
|
1785 |
msgid "Simulate Network Upgrade"
|
1786 |
msgstr ""
|
1787 |
|
1788 |
+
#: templates/debug.php:394
|
1789 |
msgid "%s Installs"
|
1790 |
msgstr ""
|
1791 |
|
1792 |
+
#: templates/debug.php:396
|
1793 |
msgctxt "like websites"
|
1794 |
msgid "Sites"
|
1795 |
msgstr ""
|
1796 |
|
1797 |
+
#: templates/debug.php:402, templates/account/partials/site.php:156
|
1798 |
msgid "Blog ID"
|
1799 |
msgstr ""
|
1800 |
|
1801 |
+
#: templates/debug.php:407
|
1802 |
msgid "License ID"
|
1803 |
msgstr ""
|
1804 |
|
1805 |
+
#: templates/debug.php:493, templates/debug.php:599, templates/account/partials/addon.php:440
|
1806 |
msgctxt "verb"
|
1807 |
msgid "Delete"
|
1808 |
msgstr ""
|
1809 |
|
1810 |
+
#: templates/debug.php:507
|
1811 |
msgid "Add Ons of module %s"
|
1812 |
msgstr ""
|
1813 |
|
1814 |
+
#: templates/debug.php:566
|
1815 |
msgid "Users"
|
1816 |
msgstr ""
|
1817 |
|
1818 |
+
#: templates/debug.php:573
|
1819 |
msgid "Verified"
|
1820 |
msgstr ""
|
1821 |
|
1822 |
+
#: templates/debug.php:615
|
1823 |
msgid "%s Licenses"
|
1824 |
msgstr ""
|
1825 |
|
1826 |
+
#: templates/debug.php:620
|
1827 |
msgid "Plugin ID"
|
1828 |
msgstr ""
|
1829 |
|
1830 |
+
#: templates/debug.php:622
|
1831 |
msgid "Plan ID"
|
1832 |
msgstr ""
|
1833 |
|
1834 |
+
#: templates/debug.php:623
|
1835 |
msgid "Quota"
|
1836 |
msgstr ""
|
1837 |
|
1838 |
+
#: templates/debug.php:624
|
1839 |
msgid "Activated"
|
1840 |
msgstr ""
|
1841 |
|
1842 |
+
#: templates/debug.php:625
|
1843 |
msgid "Blocking"
|
1844 |
msgstr ""
|
1845 |
|
1846 |
+
#: templates/debug.php:626, templates/debug.php:697, templates/debug/logger.php:22
|
1847 |
msgid "Type"
|
1848 |
msgstr ""
|
1849 |
|
1850 |
+
#: templates/debug.php:628
|
1851 |
msgctxt "as expiration date"
|
1852 |
msgid "Expiration"
|
1853 |
msgstr ""
|
1854 |
|
1855 |
+
#: templates/debug.php:656
|
1856 |
msgid "Debug Log"
|
1857 |
msgstr ""
|
1858 |
|
1859 |
+
#: templates/debug.php:660
|
1860 |
msgid "All Types"
|
1861 |
msgstr ""
|
1862 |
|
1863 |
+
#: templates/debug.php:667
|
1864 |
msgid "All Requests"
|
1865 |
msgstr ""
|
1866 |
|
1867 |
+
#: templates/debug.php:672, templates/debug.php:701, templates/debug/logger.php:25
|
1868 |
msgid "File"
|
1869 |
msgstr ""
|
1870 |
|
1871 |
+
#: templates/debug.php:673, templates/debug.php:699, templates/debug/logger.php:23
|
1872 |
msgid "Function"
|
1873 |
msgstr ""
|
1874 |
|
1875 |
+
#: templates/debug.php:674
|
1876 |
msgid "Process ID"
|
1877 |
msgstr ""
|
1878 |
|
1879 |
+
#: templates/debug.php:675
|
1880 |
msgid "Logger"
|
1881 |
msgstr ""
|
1882 |
|
1883 |
+
#: templates/debug.php:676, templates/debug.php:700, templates/debug/logger.php:24
|
1884 |
msgid "Message"
|
1885 |
msgstr ""
|
1886 |
|
1887 |
+
#: templates/debug.php:678
|
1888 |
msgid "Filter"
|
1889 |
msgstr ""
|
1890 |
|
1891 |
+
#: templates/debug.php:686
|
1892 |
msgid "Download"
|
1893 |
msgstr ""
|
1894 |
|
1895 |
+
#: templates/debug.php:702, templates/debug/logger.php:26
|
1896 |
msgid "Timestamp"
|
1897 |
msgstr ""
|
1898 |
|
1917 |
msgid "Requests"
|
1918 |
msgstr ""
|
1919 |
|
1920 |
+
#: includes/managers/class-fs-clone-manager.php:839
|
1921 |
+
msgid "Invalid clone resolution action."
|
1922 |
+
msgstr ""
|
1923 |
+
|
1924 |
+
#: includes/managers/class-fs-clone-manager.php:1024
|
1925 |
+
msgid "products"
|
1926 |
+
msgstr ""
|
1927 |
+
|
1928 |
+
#: includes/managers/class-fs-clone-manager.php:1205
|
1929 |
+
msgid "%1$s has been placed into safe mode because we noticed that %2$s is an exact copy of %3$s."
|
1930 |
+
msgstr ""
|
1931 |
+
|
1932 |
+
#: includes/managers/class-fs-clone-manager.php:1211
|
1933 |
+
msgid "The products below have been placed into safe mode because we noticed that %2$s is an exact copy of %3$s:%1$s"
|
1934 |
+
msgstr ""
|
1935 |
+
|
1936 |
+
#: includes/managers/class-fs-clone-manager.php:1212
|
1937 |
+
msgid "The products below have been placed into safe mode because we noticed that %2$s is an exact copy of these sites:%3$s%1$s"
|
1938 |
+
msgstr ""
|
1939 |
+
|
1940 |
+
#: includes/managers/class-fs-clone-manager.php:1238
|
1941 |
+
msgid "the above-mentioned sites"
|
1942 |
+
msgstr ""
|
1943 |
+
|
1944 |
+
#: includes/managers/class-fs-clone-manager.php:1251
|
1945 |
+
msgid "Is %2$s a duplicate of %4$s?"
|
1946 |
+
msgstr ""
|
1947 |
+
|
1948 |
+
#: includes/managers/class-fs-clone-manager.php:1252
|
1949 |
+
msgid "Yes, %2$s is a duplicate of %4$s for the purpose of testing, staging, or development."
|
1950 |
+
msgstr ""
|
1951 |
+
|
1952 |
+
#: includes/managers/class-fs-clone-manager.php:1257
|
1953 |
+
msgid "Long-Term Duplicate"
|
1954 |
+
msgstr ""
|
1955 |
+
|
1956 |
+
#: includes/managers/class-fs-clone-manager.php:1262
|
1957 |
+
msgid "Duplicate Website"
|
1958 |
+
msgstr ""
|
1959 |
+
|
1960 |
+
#: includes/managers/class-fs-clone-manager.php:1268
|
1961 |
+
msgid "Is %2$s the new home of %4$s?"
|
1962 |
+
msgstr ""
|
1963 |
+
|
1964 |
+
#: includes/managers/class-fs-clone-manager.php:1270
|
1965 |
+
msgid "Yes, %%2$s is replacing %%4$s. I would like to migrate my %s from %%4$s to %%2$s."
|
1966 |
+
msgstr ""
|
1967 |
+
|
1968 |
+
#: includes/managers/class-fs-clone-manager.php:1271, templates/forms/subscription-cancellation.php:52
|
1969 |
+
msgid "license"
|
1970 |
+
msgstr ""
|
1971 |
+
|
1972 |
+
#: includes/managers/class-fs-clone-manager.php:1271
|
1973 |
+
msgid "data"
|
1974 |
+
msgstr ""
|
1975 |
+
|
1976 |
+
#: includes/managers/class-fs-clone-manager.php:1277
|
1977 |
+
msgid "Migrate License"
|
1978 |
+
msgstr ""
|
1979 |
+
|
1980 |
+
#: includes/managers/class-fs-clone-manager.php:1278
|
1981 |
+
msgid "Migrate"
|
1982 |
+
msgstr ""
|
1983 |
+
|
1984 |
+
#: includes/managers/class-fs-clone-manager.php:1284
|
1985 |
+
msgid "Is %2$s a new website?"
|
1986 |
+
msgstr ""
|
1987 |
+
|
1988 |
+
#: includes/managers/class-fs-clone-manager.php:1285
|
1989 |
+
msgid "Yes, %2$s is a new and different website that is separate from %4$s."
|
1990 |
+
msgstr ""
|
1991 |
+
|
1992 |
+
#: includes/managers/class-fs-clone-manager.php:1287
|
1993 |
+
msgid "It requires license activation."
|
1994 |
+
msgstr ""
|
1995 |
+
|
1996 |
+
#: includes/managers/class-fs-clone-manager.php:1294
|
1997 |
+
msgid "New Website"
|
1998 |
+
msgstr ""
|
1999 |
+
|
2000 |
+
#: includes/managers/class-fs-clone-manager.php:1319
|
2001 |
+
msgctxt "Clone resolution admin notice products list label"
|
2002 |
+
msgid "Products"
|
2003 |
+
msgstr ""
|
2004 |
+
|
2005 |
+
#: includes/managers/class-fs-clone-manager.php:1408
|
2006 |
+
msgid "You marked this website, %s, as a temporary duplicate of %s."
|
2007 |
+
msgstr ""
|
2008 |
+
|
2009 |
+
#: includes/managers/class-fs-clone-manager.php:1409
|
2010 |
+
msgid "You marked this website, %s, as a temporary duplicate of these sites"
|
2011 |
+
msgstr ""
|
2012 |
+
|
2013 |
+
#: includes/managers/class-fs-clone-manager.php:1423
|
2014 |
+
msgid "%s automatic security & feature updates and paid functionality will keep working without interruptions until %s (or when your license expires, whatever comes first)."
|
2015 |
+
msgstr ""
|
2016 |
+
|
2017 |
+
#: includes/managers/class-fs-clone-manager.php:1426
|
2018 |
+
msgctxt "\"The <product_label>\", e.g.: \"The plugin\""
|
2019 |
+
msgid "The %s's"
|
2020 |
+
msgstr ""
|
2021 |
+
|
2022 |
+
#: includes/managers/class-fs-clone-manager.php:1429
|
2023 |
+
msgid "The following products'"
|
2024 |
+
msgstr ""
|
2025 |
+
|
2026 |
+
#: includes/managers/class-fs-clone-manager.php:1437
|
2027 |
+
msgid "If this is a long term duplicate, to keep automatic updates and paid functionality after %s, please %s."
|
2028 |
+
msgstr ""
|
2029 |
+
|
2030 |
+
#: includes/managers/class-fs-clone-manager.php:1439
|
2031 |
+
msgid "activate a license here"
|
2032 |
+
msgstr ""
|
2033 |
+
|
2034 |
+
#: includes/managers/class-fs-permission-manager.php:182
|
2035 |
+
msgid "View Basic Website Info"
|
2036 |
+
msgstr ""
|
2037 |
+
|
2038 |
+
#: includes/managers/class-fs-permission-manager.php:183
|
2039 |
+
msgid "Homepage URL & title, WP & PHP versions, and site language"
|
2040 |
+
msgstr ""
|
2041 |
+
|
2042 |
+
#: includes/managers/class-fs-permission-manager.php:186
|
2043 |
+
msgid "To provide additional functionality that's relevant to your website, avoid WordPress or PHP version incompatibilities that can break your website, and recognize which languages & regions the %s should be translated and tailored to."
|
2044 |
+
msgstr ""
|
2045 |
+
|
2046 |
+
#: includes/managers/class-fs-permission-manager.php:198
|
2047 |
+
msgid "View Basic %s Info"
|
2048 |
+
msgstr ""
|
2049 |
+
|
2050 |
+
#: includes/managers/class-fs-permission-manager.php:201
|
2051 |
+
msgid "Current %s & SDK versions, and if active or uninstalled"
|
2052 |
+
msgstr ""
|
2053 |
+
|
2054 |
+
#: includes/managers/class-fs-permission-manager.php:252
|
2055 |
+
msgid "View License Essentials"
|
2056 |
+
msgstr ""
|
2057 |
+
|
2058 |
+
#: includes/managers/class-fs-permission-manager.php:253
|
2059 |
+
msgstr ""
|
2060 |
+
|
2061 |
+
#: includes/managers/class-fs-permission-manager.php:263
|
2062 |
+
msgid "To let you manage & control where the license is activated and ensure %s security & feature updates are only delivered to websites you authorize."
|
2063 |
+
msgstr ""
|
2064 |
+
|
2065 |
+
#: includes/managers/class-fs-permission-manager.php:275
|
2066 |
+
msgid "View %s State"
|
2067 |
+
msgstr ""
|
2068 |
+
|
2069 |
+
#: includes/managers/class-fs-permission-manager.php:278
|
2070 |
+
msgid "Is active, deactivated, or uninstalled"
|
2071 |
+
msgstr ""
|
2072 |
+
|
2073 |
+
#: includes/managers/class-fs-permission-manager.php:281
|
2074 |
+
msgid "So you can reuse the license when the %s is no longer active."
|
2075 |
+
msgstr ""
|
2076 |
+
|
2077 |
+
#: includes/managers/class-fs-permission-manager.php:317
|
2078 |
+
msgid "View Diagnostic Info"
|
2079 |
+
msgstr ""
|
2080 |
+
|
2081 |
+
#: includes/managers/class-fs-permission-manager.php:317, includes/managers/class-fs-permission-manager.php:354
|
2082 |
+
msgid "optional"
|
2083 |
+
msgstr ""
|
2084 |
+
|
2085 |
+
#: includes/managers/class-fs-permission-manager.php:318
|
2086 |
+
msgid "WordPress & PHP versions, site language & title"
|
2087 |
+
msgstr ""
|
2088 |
+
|
2089 |
+
#: includes/managers/class-fs-permission-manager.php:321
|
2090 |
+
msgid "To avoid breaking your website due to WordPress or PHP version incompatibilities, and recognize which languages & regions the %s should be translated and tailored to."
|
2091 |
+
msgstr ""
|
2092 |
+
|
2093 |
+
#: includes/managers/class-fs-permission-manager.php:354
|
2094 |
+
msgid "View Plugins & Themes List"
|
2095 |
+
msgstr ""
|
2096 |
+
|
2097 |
+
#: includes/managers/class-fs-permission-manager.php:355
|
2098 |
+
msgid "Names, slugs, versions, and if active or not"
|
2099 |
+
msgstr ""
|
2100 |
+
|
2101 |
+
#: includes/managers/class-fs-permission-manager.php:356
|
2102 |
+
msgid "To ensure compatibility and avoid conflicts with your installed plugins and themes."
|
2103 |
+
msgstr ""
|
2104 |
+
|
2105 |
+
#: includes/managers/class-fs-permission-manager.php:373
|
2106 |
+
msgid "View Basic Profile Info"
|
2107 |
+
msgstr ""
|
2108 |
+
|
2109 |
+
#: includes/managers/class-fs-permission-manager.php:374
|
2110 |
+
msgid "Your WordPress user's: first & last name, and email address"
|
2111 |
+
msgstr ""
|
2112 |
+
|
2113 |
+
#: includes/managers/class-fs-permission-manager.php:375
|
2114 |
+
msgid "Never miss important updates, get security warnings before they become public knowledge, and receive notifications about special offers and awesome new features."
|
2115 |
+
msgstr ""
|
2116 |
+
|
2117 |
+
#: includes/managers/class-fs-permission-manager.php:396
|
2118 |
+
msgid "Newsletter"
|
2119 |
+
msgstr ""
|
2120 |
+
|
2121 |
+
#: includes/managers/class-fs-permission-manager.php:397
|
2122 |
+
msgid "Updates, announcements, marketing, no spam"
|
2123 |
+
msgstr ""
|
2124 |
+
|
2125 |
#: templates/account/billing.php:22
|
2126 |
msgctxt "verb"
|
2127 |
msgid "Update"
|
2187 |
msgid "Invoice"
|
2188 |
msgstr ""
|
2189 |
|
2190 |
+
#: templates/connect/permissions-group.php:31, templates/forms/optout.php:26, templates/js/permissions.php:78
|
2191 |
+
msgctxt "verb"
|
2192 |
+
msgid "Opt Out"
|
2193 |
+
msgstr ""
|
2194 |
+
|
2195 |
+
#: templates/connect/permissions-group.php:32, templates/js/permissions.php:77
|
2196 |
+
msgctxt "verb"
|
2197 |
+
msgid "Opt In"
|
2198 |
+
msgstr ""
|
2199 |
+
|
2200 |
#: templates/debug/api-calls.php:56
|
2201 |
msgid "API"
|
2202 |
msgstr ""
|
2285 |
msgid "Next"
|
2286 |
msgstr ""
|
2287 |
|
2288 |
+
#: templates/forms/affiliation.php:83
|
2289 |
msgid "Non-expiring"
|
2290 |
msgstr ""
|
2291 |
|
2292 |
+
#: templates/forms/affiliation.php:86
|
2293 |
msgid "Apply to become an affiliate"
|
2294 |
msgstr ""
|
2295 |
|
2296 |
+
#: templates/forms/affiliation.php:108
|
2297 |
msgid "Your affiliate application for %s has been accepted! Log in to your affiliate area at: %s."
|
2298 |
msgstr ""
|
2299 |
|
2300 |
+
#: templates/forms/affiliation.php:123
|
2301 |
msgid "Thank you for applying for our affiliate program, we'll review your details during the next 14 days and will get back to you with further information."
|
2302 |
msgstr ""
|
2303 |
|
2304 |
+
#: templates/forms/affiliation.php:126
|
2305 |
msgid "Your affiliation account was temporarily suspended."
|
2306 |
msgstr ""
|
2307 |
|
2308 |
+
#: templates/forms/affiliation.php:129
|
2309 |
msgid "Thank you for applying for our affiliate program, unfortunately, we've decided at this point to reject your application. Please try again in 30 days."
|
2310 |
msgstr ""
|
2311 |
|
2312 |
+
#: templates/forms/affiliation.php:132
|
2313 |
msgid "Due to violation of our affiliation terms, we decided to temporarily block your affiliation account. If you have any questions, please contact support."
|
2314 |
msgstr ""
|
2315 |
|
2316 |
+
#: templates/forms/affiliation.php:145
|
2317 |
msgid "Like the %s? Become our ambassador and earn cash ;-)"
|
2318 |
msgstr ""
|
2319 |
|
2320 |
+
#: templates/forms/affiliation.php:146
|
2321 |
msgid "Refer new customers to our %s and earn %s commission on each successful sale you refer!"
|
2322 |
msgstr ""
|
2323 |
|
2324 |
+
#: templates/forms/affiliation.php:149
|
2325 |
msgid "Program Summary"
|
2326 |
msgstr ""
|
2327 |
|
2328 |
+
#: templates/forms/affiliation.php:151
|
2329 |
msgid "%s commission when a customer purchases a new license."
|
2330 |
msgstr ""
|
2331 |
|
2332 |
+
#: templates/forms/affiliation.php:153
|
2333 |
msgid "Get commission for automated subscription renewals."
|
2334 |
msgstr ""
|
2335 |
|
2336 |
+
#: templates/forms/affiliation.php:156
|
2337 |
msgid "%s tracking cookie after the first visit to maximize earnings potential."
|
2338 |
msgstr ""
|
2339 |
|
2340 |
+
#: templates/forms/affiliation.php:159
|
2341 |
msgid "Unlimited commissions."
|
2342 |
msgstr ""
|
2343 |
|
2344 |
+
#: templates/forms/affiliation.php:161
|
2345 |
msgid "%s minimum payout amount."
|
2346 |
msgstr ""
|
2347 |
|
2348 |
+
#: templates/forms/affiliation.php:162
|
2349 |
msgid "Payouts are in USD and processed monthly via PayPal."
|
2350 |
msgstr ""
|
2351 |
|
2352 |
+
#: templates/forms/affiliation.php:163
|
2353 |
msgid "As we reserve 30 days for potential refunds, we only pay commissions that are older than 30 days."
|
2354 |
msgstr ""
|
2355 |
|
2356 |
+
#: templates/forms/affiliation.php:166
|
2357 |
msgid "Affiliate"
|
2358 |
msgstr ""
|
2359 |
|
2360 |
+
#: templates/forms/affiliation.php:169, templates/forms/resend-key.php:23
|
2361 |
msgid "Email address"
|
2362 |
msgstr ""
|
2363 |
|
2364 |
+
#: templates/forms/affiliation.php:173
|
2365 |
msgid "Full name"
|
2366 |
msgstr ""
|
2367 |
|
2368 |
+
#: templates/forms/affiliation.php:177
|
2369 |
msgid "PayPal account email address"
|
2370 |
msgstr ""
|
2371 |
|
2372 |
+
#: templates/forms/affiliation.php:181
|
2373 |
msgid "Where are you going to promote the %s?"
|
2374 |
msgstr ""
|
2375 |
|
2376 |
+
#: templates/forms/affiliation.php:183
|
2377 |
msgid "Enter the domain of your website or other websites from where you plan to promote the %s."
|
2378 |
msgstr ""
|
2379 |
|
2380 |
+
#: templates/forms/affiliation.php:185
|
2381 |
msgid "Add another domain"
|
2382 |
msgstr ""
|
2383 |
|
2384 |
+
#: templates/forms/affiliation.php:189
|
2385 |
msgid "Extra Domains"
|
2386 |
msgstr ""
|
2387 |
|
2388 |
+
#: templates/forms/affiliation.php:190
|
2389 |
msgid "Extra domains where you will be marketing the product from."
|
2390 |
msgstr ""
|
2391 |
|
2392 |
+
#: templates/forms/affiliation.php:200
|
2393 |
msgid "Promotion methods"
|
2394 |
msgstr ""
|
2395 |
|
2396 |
+
#: templates/forms/affiliation.php:203
|
2397 |
msgid "Social media (Facebook, Twitter, etc.)"
|
2398 |
msgstr ""
|
2399 |
|
2400 |
+
#: templates/forms/affiliation.php:207
|
2401 |
msgid "Mobile apps"
|
2402 |
msgstr ""
|
2403 |
|
2404 |
+
#: templates/forms/affiliation.php:211
|
2405 |
msgid "Website, email, and social media statistics (optional)"
|
2406 |
msgstr ""
|
2407 |
|
2408 |
+
#: templates/forms/affiliation.php:214
|
2409 |
msgid "Please feel free to provide any relevant website or social media statistics, e.g. monthly unique site visits, number of email subscribers, followers, etc. (we will keep this information confidential)."
|
2410 |
msgstr ""
|
2411 |
|
2412 |
+
#: templates/forms/affiliation.php:218
|
2413 |
msgid "How will you promote us?"
|
2414 |
msgstr ""
|
2415 |
|
2416 |
+
#: templates/forms/affiliation.php:221
|
2417 |
msgid "Please provide details on how you intend to promote %s (please be as specific as possible)."
|
2418 |
msgstr ""
|
2419 |
|
2420 |
+
#: templates/forms/affiliation.php:233, templates/forms/resend-key.php:22, templates/account/partials/disconnect-button.php:92
|
2421 |
msgid "Cancel"
|
2422 |
msgstr ""
|
2423 |
|
2424 |
+
#: templates/forms/affiliation.php:235
|
2425 |
msgid "Become an affiliate"
|
2426 |
msgstr ""
|
2427 |
|
2441 |
msgid "User key"
|
2442 |
msgstr ""
|
2443 |
|
2444 |
+
#: templates/forms/email-address-update.php:32
|
2445 |
+
msgid "Email address update"
|
2446 |
msgstr ""
|
2447 |
|
2448 |
+
#: templates/forms/email-address-update.php:33, templates/forms/user-change.php:81
|
2449 |
+
msgctxt "close window"
|
2450 |
+
msgid "Dismiss"
|
2451 |
msgstr ""
|
2452 |
|
2453 |
+
#: templates/forms/email-address-update.php:38
|
2454 |
+
msgid "Enter the new email address"
|
2455 |
msgstr ""
|
2456 |
|
2457 |
+
#: templates/forms/email-address-update.php:42
|
2458 |
+
msgid "Are both %s and %s your email addresses?"
|
2459 |
msgstr ""
|
2460 |
|
2461 |
+
#: templates/forms/email-address-update.php:50
|
2462 |
+
msgid "Yes - both addresses are mine"
|
|
|
2463 |
msgstr ""
|
2464 |
|
2465 |
+
#: templates/forms/email-address-update.php:57
|
2466 |
+
msgid "%s is my client's email address"
|
2467 |
+
msgstr ""
|
2468 |
+
|
2469 |
+
#: templates/forms/email-address-update.php:66
|
2470 |
+
msgid "%s is my email address"
|
2471 |
msgstr ""
|
2472 |
|
2473 |
+
#: templates/forms/email-address-update.php:75
|
2474 |
+
msgid "Would you like to merge %s into %s?"
|
2475 |
msgstr ""
|
2476 |
|
2477 |
+
#: templates/forms/email-address-update.php:84
|
2478 |
+
msgid "Yes - move all my data and assets from %s to %s"
|
2479 |
msgstr ""
|
2480 |
|
2481 |
+
#: templates/forms/email-address-update.php:94
|
2482 |
+
msgid "No - only move this site's data to %s"
|
2483 |
msgstr ""
|
2484 |
|
2485 |
+
#: templates/forms/email-address-update.php:292, templates/forms/email-address-update.php:298
|
2486 |
+
msgid "Update"
|
2487 |
+
msgstr ""
|
2488 |
+
|
2489 |
+
#: templates/forms/license-activation.php:23
|
2490 |
+
msgid "Please enter the license key that you received in the email right after the purchase:"
|
2491 |
+
msgstr ""
|
2492 |
+
|
2493 |
+
#: templates/forms/license-activation.php:28
|
2494 |
+
msgid "Update License"
|
2495 |
+
msgstr ""
|
2496 |
+
|
2497 |
+
#: templates/forms/license-activation.php:34
|
2498 |
+
msgid "The %1$s will be periodically sending essential license data to %2$s to check for security and feature updates, and verify the validity of your license."
|
2499 |
+
msgstr ""
|
2500 |
+
|
2501 |
+
#: templates/forms/license-activation.php:39
|
2502 |
+
msgid "Agree & Activate License"
|
2503 |
+
msgstr ""
|
2504 |
+
|
2505 |
+
#: templates/forms/license-activation.php:204
|
2506 |
+
msgid "Associate with the license owner's account."
|
2507 |
msgstr ""
|
2508 |
|
2509 |
#: templates/forms/optout.php:44
|
2510 |
+
msgid "Communication"
|
2511 |
msgstr ""
|
2512 |
|
2513 |
+
#: templates/forms/optout.php:56
|
2514 |
+
msgid "Stay Connected"
|
2515 |
msgstr ""
|
2516 |
|
2517 |
+
#: templates/forms/optout.php:61
|
2518 |
+
msgid "Diagnostic Info"
|
2519 |
msgstr ""
|
2520 |
|
2521 |
+
#: templates/forms/optout.php:77
|
2522 |
+
msgid "Keep Sharing"
|
2523 |
msgstr ""
|
2524 |
|
2525 |
+
#: templates/forms/optout.php:82
|
2526 |
+
msgid "Extensions"
|
2527 |
+
msgstr ""
|
2528 |
+
|
2529 |
+
#: templates/forms/optout.php:104
|
2530 |
+
msgid "Keep automatic updates"
|
2531 |
msgstr ""
|
2532 |
|
2533 |
#: templates/forms/premium-versions-upgrade-handler.php:40
|
2551 |
msgid "Send License Key"
|
2552 |
msgstr ""
|
2553 |
|
2554 |
+
#: templates/forms/resend-key.php:58
|
2555 |
+
msgid "Enter the email address you've used during the purchase and we will resend you the license key."
|
2556 |
+
msgstr ""
|
2557 |
+
|
2558 |
+
#: templates/forms/resend-key.php:59
|
2559 |
msgid "Enter the email address you've used for the upgrade below and we will resend you the license key."
|
2560 |
msgstr ""
|
2561 |
|
2567 |
msgid "In case you are NOT planning on using this %s on this site (or any other site) - would you like to cancel the %s as well?"
|
2568 |
msgstr ""
|
2569 |
|
|
|
|
|
|
|
|
|
2570 |
#: templates/forms/subscription-cancellation.php:57
|
2571 |
msgid "Cancel %s - I no longer need any security & feature updates, nor support for %s because I'm not planning to use the %s on this, or any other site."
|
2572 |
msgstr ""
|
2587 |
msgid "Proceed"
|
2588 |
msgstr ""
|
2589 |
|
2590 |
+
#: templates/forms/subscription-cancellation.php:191, templates/forms/deactivation/form.php:216
|
2591 |
msgid "Cancel %s & Proceed"
|
2592 |
msgstr ""
|
2593 |
|
2611 |
msgid "Enter email address"
|
2612 |
msgstr ""
|
2613 |
|
2614 |
+
#: templates/js/permissions.php:337, templates/js/permissions.php:485
|
2615 |
+
msgid "Saved"
|
|
|
2616 |
msgstr ""
|
2617 |
|
2618 |
#: templates/js/style-premium-theme.php:39
|
2623 |
msgid "Beta"
|
2624 |
msgstr ""
|
2625 |
|
2626 |
+
#: templates/partials/network-activation.php:32
|
2627 |
msgid "Activate license on all sites in the network."
|
2628 |
msgstr ""
|
2629 |
|
2630 |
+
#: templates/partials/network-activation.php:33
|
2631 |
msgid "Apply on all sites in the network."
|
2632 |
msgstr ""
|
2633 |
|
2634 |
+
#: templates/partials/network-activation.php:36
|
2635 |
msgid "Activate license on all pending sites."
|
2636 |
msgstr ""
|
2637 |
|
2638 |
+
#: templates/partials/network-activation.php:37
|
2639 |
msgid "Apply on all pending sites."
|
2640 |
msgstr ""
|
2641 |
|
2642 |
+
#: templates/partials/network-activation.php:45, templates/partials/network-activation.php:79
|
2643 |
msgid "allow"
|
2644 |
msgstr ""
|
2645 |
|
2646 |
+
#: templates/partials/network-activation.php:48, templates/partials/network-activation.php:82
|
2647 |
msgid "delegate"
|
2648 |
msgstr ""
|
2649 |
|
2650 |
+
#: templates/partials/network-activation.php:52, templates/partials/network-activation.php:86
|
2651 |
msgid "skip"
|
2652 |
msgstr ""
|
2653 |
|
2673 |
msgstr ""
|
2674 |
|
2675 |
#. translators: %1$s: Either 'Downgrading your plan' or 'Cancelling the subscription'
|
2676 |
+
#: templates/account/partials/addon.php:34
|
2677 |
msgid "%1$s will immediately stop all future recurring payments and your %s plan license will expire in %s."
|
2678 |
msgstr ""
|
2679 |
|
2680 |
+
#: templates/account/partials/addon.php:190
|
2681 |
msgid "Cancelled"
|
2682 |
msgstr ""
|
2683 |
|
2684 |
+
#: templates/account/partials/addon.php:200
|
2685 |
msgid "No expiration"
|
2686 |
msgstr ""
|
2687 |
|
2688 |
+
#: templates/account/partials/disconnect-button.php:74
|
2689 |
+
msgid "By disconnecting the website, previously shared diagnostic data about %1$s will be deleted and no longer visible to %2$s."
|
2690 |
+
msgstr ""
|
2691 |
+
|
2692 |
+
#: templates/account/partials/disconnect-button.php:78
|
2693 |
+
msgid "Disconnecting the website will permanently remove %s from your User Dashboard's account."
|
2694 |
+
msgstr ""
|
2695 |
+
|
2696 |
+
#: templates/account/partials/disconnect-button.php:84
|
2697 |
+
msgid "If you wish to cancel your %1$s plan's subscription instead, please navigate to the %2$s and cancel it there."
|
2698 |
+
msgstr ""
|
2699 |
+
|
2700 |
+
#: templates/account/partials/disconnect-button.php:88
|
2701 |
+
msgid "Are you sure you would like to proceed with the disconnection?"
|
2702 |
+
msgstr ""
|
2703 |
+
|
2704 |
+
#: templates/account/partials/site.php:190
|
2705 |
msgid "Owner Name"
|
2706 |
msgstr ""
|
2707 |
|
2708 |
+
#: templates/account/partials/site.php:202
|
2709 |
msgid "Owner Email"
|
2710 |
msgstr ""
|
2711 |
|
2712 |
+
#: templates/account/partials/site.php:214
|
2713 |
msgid "Owner ID"
|
2714 |
msgstr ""
|
2715 |
|
2716 |
+
#: templates/account/partials/site.php:288
|
2717 |
msgid "Subscription"
|
2718 |
msgstr ""
|
2719 |
|
2725 |
msgid "Contact Support"
|
2726 |
msgstr ""
|
2727 |
|
2728 |
+
#: templates/forms/deactivation/form.php:65
|
2729 |
msgid "Anonymous feedback"
|
2730 |
msgstr ""
|
2731 |
|
2732 |
+
#: templates/forms/deactivation/form.php:71
|
2733 |
+
msgid "hour"
|
2734 |
+
msgstr ""
|
2735 |
+
|
2736 |
+
#: templates/forms/deactivation/form.php:76
|
2737 |
+
msgid "hours"
|
2738 |
+
msgstr ""
|
2739 |
+
|
2740 |
+
#: templates/forms/deactivation/form.php:81, templates/forms/deactivation/form.php:86
|
2741 |
+
msgid "days"
|
2742 |
+
msgstr ""
|
2743 |
+
|
2744 |
+
#: templates/forms/deactivation/form.php:106
|
2745 |
msgid "Deactivate"
|
2746 |
msgstr ""
|
2747 |
|
2748 |
+
#: templates/forms/deactivation/form.php:108
|
2749 |
msgid "Activate %s"
|
2750 |
msgstr ""
|
2751 |
|
2752 |
+
#: templates/forms/deactivation/form.php:111
|
2753 |
+
msgid "Submit & %s"
|
2754 |
+
msgstr ""
|
2755 |
+
|
2756 |
+
#: templates/forms/deactivation/form.php:130
|
2757 |
msgid "Quick Feedback"
|
2758 |
msgstr ""
|
2759 |
|
2760 |
+
#: templates/forms/deactivation/form.php:134
|
2761 |
msgid "If you have a moment, please let us know why you are %s"
|
2762 |
msgstr ""
|
2763 |
|
2764 |
+
#: templates/forms/deactivation/form.php:134
|
2765 |
msgid "deactivating"
|
2766 |
msgstr ""
|
2767 |
|
2768 |
+
#: templates/forms/deactivation/form.php:134
|
2769 |
msgid "switching"
|
2770 |
msgstr ""
|
2771 |
|
2772 |
+
#: templates/forms/deactivation/form.php:448
|
2773 |
+
msgid "Kindly tell us the reason so we can improve."
|
2774 |
msgstr ""
|
2775 |
|
2776 |
+
#: templates/forms/deactivation/form.php:478
|
2777 |
+
msgid "Snooze & %s"
|
2778 |
msgstr ""
|
2779 |
|
2780 |
+
#: templates/forms/deactivation/form.php:638
|
2781 |
msgid "Yes - %s"
|
2782 |
msgstr ""
|
2783 |
|
2784 |
+
#: templates/forms/deactivation/form.php:645
|
2785 |
msgid "Skip & %s"
|
2786 |
msgstr ""
|
2787 |
|
freemius/require.php
CHANGED
@@ -21,6 +21,8 @@
|
|
21 |
// require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-abstract-manager.php';
|
22 |
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-option-manager.php';
|
23 |
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-gdpr-manager.php';
|
|
|
|
|
24 |
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-cache-manager.php';
|
25 |
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-admin-notice-manager.php';
|
26 |
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-admin-menu-manager.php';
|
21 |
// require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-abstract-manager.php';
|
22 |
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-option-manager.php';
|
23 |
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-gdpr-manager.php';
|
24 |
+
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-clone-manager.php';
|
25 |
+
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-permission-manager.php';
|
26 |
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-cache-manager.php';
|
27 |
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-admin-notice-manager.php';
|
28 |
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-admin-menu-manager.php';
|
freemius/start.php
CHANGED
@@ -15,7 +15,7 @@
|
|
15 |
*
|
16 |
* @var string
|
17 |
*/
|
18 |
-
$this_sdk_version = '2.
|
19 |
|
20 |
#region SDK Selection Logic --------------------------------------------------------------------
|
21 |
|
@@ -68,7 +68,11 @@
|
|
68 |
|
69 |
if ( ! isset( $fs_active_plugins ) ) {
|
70 |
// Load all Freemius powered active plugins.
|
71 |
-
$fs_active_plugins = get_option( 'fs_active_plugins'
|
|
|
|
|
|
|
|
|
72 |
|
73 |
if ( ! isset( $fs_active_plugins->plugins ) ) {
|
74 |
$fs_active_plugins->plugins = array();
|
15 |
*
|
16 |
* @var string
|
17 |
*/
|
18 |
+
$this_sdk_version = '2.5.3';
|
19 |
|
20 |
#region SDK Selection Logic --------------------------------------------------------------------
|
21 |
|
68 |
|
69 |
if ( ! isset( $fs_active_plugins ) ) {
|
70 |
// Load all Freemius powered active plugins.
|
71 |
+
$fs_active_plugins = get_option( 'fs_active_plugins' );
|
72 |
+
|
73 |
+
if ( ! is_object( $fs_active_plugins ) ) {
|
74 |
+
$fs_active_plugins = new stdClass();
|
75 |
+
}
|
76 |
|
77 |
if ( ! isset( $fs_active_plugins->plugins ) ) {
|
78 |
$fs_active_plugins->plugins = array();
|
freemius/templates/account.php
CHANGED
@@ -46,6 +46,7 @@
|
|
46 |
$site = $fs->get_site();
|
47 |
$name = $user->get_name();
|
48 |
$license = $fs->_get_license();
|
|
|
49 |
$is_data_debug_mode = $fs->is_data_debug_mode();
|
50 |
$is_whitelabeled = $fs->is_whitelabeled();
|
51 |
$subscription = ( is_object( $license ) ?
|
@@ -58,10 +59,19 @@
|
|
58 |
$show_upgrade = ( ! $is_whitelabeled && $has_paid_plan && ! $is_paying && ! $is_paid_trial );
|
59 |
$trial_plan = $fs->get_trial_plan();
|
60 |
|
|
|
|
|
|
|
|
|
|
|
61 |
if ( $has_paid_plan ) {
|
62 |
$fs->_add_license_activation_dialog_box();
|
63 |
}
|
64 |
|
|
|
|
|
|
|
|
|
65 |
$ids_of_installs_activated_with_foreign_licenses = $fs->should_handle_user_change() ?
|
66 |
$fs->get_installs_ids_with_foreign_licenses() :
|
67 |
array();
|
@@ -86,12 +96,15 @@
|
|
86 |
) );
|
87 |
}
|
88 |
|
89 |
-
|
|
|
|
|
90 |
|
91 |
-
|
|
|
92 |
|
93 |
|
94 |
-
|
95 |
|
96 |
if ( $has_tabs ) {
|
97 |
$query_params['tabs'] = 'true';
|
@@ -140,6 +153,7 @@
|
|
140 |
$install = $fs->get_install_by_blog_id( $site_info['blog_id'] );
|
141 |
$view_params = array(
|
142 |
'freemius' => $fs,
|
|
|
143 |
'license' => $license,
|
144 |
'site' => $site_info,
|
145 |
'install' => $install,
|
@@ -234,6 +248,14 @@
|
|
234 |
$addons_to_show = array_unique( array_merge( $installed_addons_ids, $account_addons ) );
|
235 |
|
236 |
$is_active_bundle_subscription = ( is_object( $bundle_subscription ) && $bundle_subscription->is_active() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
?>
|
238 |
<div class="wrap fs-section">
|
239 |
<?php if ( ! $has_tabs && ! $fs->apply_filters( 'hide_account_tabs', false ) ) : ?>
|
@@ -274,24 +296,19 @@
|
|
274 |
<li> • </li>
|
275 |
<?php endif ?>
|
276 |
<?php if ( $show_billing ) : ?>
|
277 |
-
|
278 |
<li> • </li>
|
279 |
<?php endif ?>
|
280 |
<?php if ( ! $is_whitelabeled ) : ?>
|
281 |
<?php if ( ! $is_paying ) : ?>
|
282 |
<li>
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
echo esc_attr( sprintf( fs_text_inline( 'Deletion is not temporary. Only delete if you no longer want to use this %s anymore. Are you sure you would like to continue with the deletion?', 'delete-account-confirm', $slug ), $fs->get_module_label( true ) ) );
|
291 |
-
}
|
292 |
-
?>')) this.parentNode.submit(); return false;"><i
|
293 |
-
class="dashicons dashicons-no"></i> <?php fs_esc_html_echo_inline( 'Delete Account', 'delete-account', $slug ) ?></a>
|
294 |
-
</form>
|
295 |
</li>
|
296 |
<li> • </li>
|
297 |
<?php endif ?>
|
@@ -330,7 +347,7 @@
|
|
330 |
</li>
|
331 |
<li> • </li>
|
332 |
<?php endif ?>
|
333 |
-
<?php if (
|
334 |
<li>
|
335 |
<a href="<?php echo $fs->get_upgrade_url() ?>"><i
|
336 |
class="dashicons dashicons-grid-view"></i> <?php echo esc_html( $change_plan_text ) ?></a>
|
@@ -366,7 +383,7 @@
|
|
366 |
|
367 |
$profile = array();
|
368 |
|
369 |
-
|
370 |
$profile[] = array(
|
371 |
'id' => 'user_name',
|
372 |
'title' => fs_text_inline( 'Name', 'name', $slug ),
|
@@ -435,7 +452,7 @@
|
|
435 |
'value' => $fs->get_plugin_version()
|
436 |
);
|
437 |
|
438 |
-
if ( ! fs_is_network_admin() && $is_premium
|
439 |
$profile[] = array(
|
440 |
'id' => 'beta_program',
|
441 |
'title' => '',
|
@@ -537,15 +554,13 @@
|
|
537 |
<?php endif ?>
|
538 |
<?php if ( ! $is_whitelabeled ) : ?>
|
539 |
<div class="button-group">
|
540 |
-
<?php $available_license = $fs->is_free_plan() && ! fs_is_network_admin() ? $fs->_get_available_premium_license( $site->is_localhost() ) : false ?>
|
541 |
<?php if ( is_object( $available_license ) ) : ?>
|
542 |
-
<?php $premium_plan = $fs->_get_plan_by_id( $available_license->plan_id ) ?>
|
543 |
<?php
|
544 |
$view_params = array(
|
545 |
'freemius' => $fs,
|
546 |
'slug' => $slug,
|
547 |
'license' => $available_license,
|
548 |
-
'plan' => $
|
549 |
'is_localhost' => $site->is_localhost(),
|
550 |
'install_id' => $site->id,
|
551 |
'class' => 'button-primary',
|
@@ -562,7 +577,7 @@
|
|
562 |
<input type="hidden" name="fs_action"
|
563 |
value="<?php echo $fs->get_unique_affix() ?>_sync_license">
|
564 |
<?php wp_nonce_field( $fs->get_unique_affix() . '_sync_license' ) ?>
|
565 |
-
<?php if ( $show_upgrade ||
|
566 |
<a href="<?php echo $fs->get_upgrade_url() ?>"
|
567 |
class="button<?php
|
568 |
echo $show_upgrade ?
|
@@ -645,7 +660,7 @@
|
|
645 |
<?php endif ?>
|
646 |
<?php
|
647 |
elseif ( in_array( $p['id'], array( 'license_key', 'site_secret_key' ) ) ) : ?>
|
648 |
-
<?php if ( ! $is_whitelabeled ) : ?>
|
649 |
<button class="button button-small fs-toggle-visibility"><?php fs_esc_html_echo_x_inline( 'Show', 'verb', 'show', $slug ) ?></button>
|
650 |
<?php endif ?>
|
651 |
<?php if ('license_key' === $p['id']) : ?>
|
@@ -658,6 +673,7 @@
|
|
658 |
'user_name'
|
659 |
) ) )
|
660 |
) : ?>
|
|
|
661 |
<form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST"
|
662 |
onsubmit="var val = prompt('<?php echo esc_attr( sprintf(
|
663 |
/* translators: %s: User's account property (e.g. name, email) */
|
@@ -668,9 +684,10 @@
|
|
668 |
<input type="hidden" name="fs_<?php echo $p['id'] ?>_<?php echo $fs->get_unique_affix() ?>"
|
669 |
value="">
|
670 |
<?php wp_nonce_field( 'update_' . $p['id'] ) ?>
|
671 |
-
<input type="submit" class="button button-small"
|
672 |
value="<?php echo fs_esc_attr_x_inline( 'Edit', 'verb', 'edit', $slug ) ?>">
|
673 |
</form>
|
|
|
674 |
<?php elseif ( 'user_id' === $p['id'] && ! empty( $ids_of_installs_activated_with_foreign_licenses ) ) : ?>
|
675 |
<input id="fs_change_user" type="submit" class="button button-small"
|
676 |
value="<?php echo fs_esc_attr_inline( 'Change User', 'change-user', $slug ) ?>">
|
@@ -730,12 +747,30 @@
|
|
730 |
<div class="fs-table-body">
|
731 |
<table class="widefat">
|
732 |
<?php
|
|
|
|
|
733 |
foreach ( $site_view_params as $view_params ) {
|
734 |
fs_require_template(
|
735 |
'account/partials/site.php',
|
736 |
$view_params
|
737 |
);
|
738 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
739 |
</table>
|
740 |
</div>
|
741 |
</div>
|
@@ -839,7 +874,7 @@
|
|
839 |
|
840 |
<?php
|
841 |
if ( $show_billing ) {
|
842 |
-
$view_params = array( 'id' => $VARS['id'] );
|
843 |
fs_require_once_template( 'account/billing.php', $view_params );
|
844 |
fs_require_once_template( 'account/payments.php', $view_params );
|
845 |
}
|
@@ -919,7 +954,7 @@
|
|
919 |
|
920 |
if ( ! isChecked || confirm( '<?php echo $confirmation_message ?>' ) ) {
|
921 |
$.ajax( {
|
922 |
-
url :
|
923 |
method: 'POST',
|
924 |
data : {
|
925 |
action : '<?php echo $fs->get_ajax_action( 'set_beta_mode' ) ?>',
|
@@ -1062,7 +1097,7 @@
|
|
1062 |
var $toggleLink = $( this );
|
1063 |
|
1064 |
$.ajax( {
|
1065 |
-
url :
|
1066 |
method: 'POST',
|
1067 |
data : {
|
1068 |
action : '<?php echo $fs->get_ajax_action( 'toggle_whitelabel_mode' ) ?>',
|
@@ -1095,4 +1130,4 @@
|
|
1095 |
'module_slug' => $slug,
|
1096 |
'module_version' => $fs->get_plugin_version(),
|
1097 |
);
|
1098 |
-
|
46 |
$site = $fs->get_site();
|
47 |
$name = $user->get_name();
|
48 |
$license = $fs->_get_license();
|
49 |
+
$is_license_foreign = ( is_object( $license ) && $user->id != $license->user_id );
|
50 |
$is_data_debug_mode = $fs->is_data_debug_mode();
|
51 |
$is_whitelabeled = $fs->is_whitelabeled();
|
52 |
$subscription = ( is_object( $license ) ?
|
59 |
$show_upgrade = ( ! $is_whitelabeled && $has_paid_plan && ! $is_paying && ! $is_paid_trial );
|
60 |
$trial_plan = $fs->get_trial_plan();
|
61 |
|
62 |
+
$is_plan_change_supported = (
|
63 |
+
! $fs->is_single_plan() &&
|
64 |
+
! $fs->apply_filters( 'hide_plan_change', false )
|
65 |
+
);
|
66 |
+
|
67 |
if ( $has_paid_plan ) {
|
68 |
$fs->_add_license_activation_dialog_box();
|
69 |
}
|
70 |
|
71 |
+
if ( $fs->should_handle_user_change() ) {
|
72 |
+
$fs->_add_email_address_update_dialog_box();
|
73 |
+
}
|
74 |
+
|
75 |
$ids_of_installs_activated_with_foreign_licenses = $fs->should_handle_user_change() ?
|
76 |
$fs->get_installs_ids_with_foreign_licenses() :
|
77 |
array();
|
96 |
) );
|
97 |
}
|
98 |
|
99 |
+
$show_billing = ( ! $is_whitelabeled && ! $fs->apply_filters( 'hide_billing_and_payments_info', false ) );
|
100 |
+
if ( $show_billing ) {
|
101 |
+
$payments = $fs->_fetch_payments();
|
102 |
|
103 |
+
$show_billing = ( is_array( $payments ) && 0 < count( $payments ) );
|
104 |
+
}
|
105 |
|
106 |
|
107 |
+
$has_tabs = $fs->_add_tabs_before_content();
|
108 |
|
109 |
if ( $has_tabs ) {
|
110 |
$query_params['tabs'] = 'true';
|
153 |
$install = $fs->get_install_by_blog_id( $site_info['blog_id'] );
|
154 |
$view_params = array(
|
155 |
'freemius' => $fs,
|
156 |
+
'user' => $fs->get_user(),
|
157 |
'license' => $license,
|
158 |
'site' => $site_info,
|
159 |
'install' => $install,
|
248 |
$addons_to_show = array_unique( array_merge( $installed_addons_ids, $account_addons ) );
|
249 |
|
250 |
$is_active_bundle_subscription = ( is_object( $bundle_subscription ) && $bundle_subscription->is_active() );
|
251 |
+
|
252 |
+
$available_license = ( $fs->is_free_plan() && ! fs_is_network_admin() ) ?
|
253 |
+
$fs->_get_available_premium_license( $site->is_localhost() ) :
|
254 |
+
null;
|
255 |
+
|
256 |
+
$available_license_paid_plan = is_object( $available_license ) ?
|
257 |
+
$fs->_get_plan_by_id( $available_license->plan_id ) :
|
258 |
+
null;
|
259 |
?>
|
260 |
<div class="wrap fs-section">
|
261 |
<?php if ( ! $has_tabs && ! $fs->apply_filters( 'hide_account_tabs', false ) ) : ?>
|
296 |
<li> • </li>
|
297 |
<?php endif ?>
|
298 |
<?php if ( $show_billing ) : ?>
|
299 |
+
<li><a href="#fs_billing"><i class="dashicons dashicons-portfolio"></i> <?php fs_esc_html_echo_inline( 'Billing & Invoices', 'billing-invoices', $slug ) ?></a></li>
|
300 |
<li> • </li>
|
301 |
<?php endif ?>
|
302 |
<?php if ( ! $is_whitelabeled ) : ?>
|
303 |
<?php if ( ! $is_paying ) : ?>
|
304 |
<li>
|
305 |
+
<?php
|
306 |
+
$view_params = array(
|
307 |
+
'freemius' => $fs,
|
308 |
+
'license' => $available_license,
|
309 |
+
'license_paid_plan' => $available_license_paid_plan,
|
310 |
+
);
|
311 |
+
fs_require_template( 'account/partials/disconnect-button.php', $view_params ); ?>
|
|
|
|
|
|
|
|
|
|
|
312 |
</li>
|
313 |
<li> • </li>
|
314 |
<?php endif ?>
|
347 |
</li>
|
348 |
<li> • </li>
|
349 |
<?php endif ?>
|
350 |
+
<?php if ( $is_plan_change_supported ) : ?>
|
351 |
<li>
|
352 |
<a href="<?php echo $fs->get_upgrade_url() ?>"><i
|
353 |
class="dashicons dashicons-grid-view"></i> <?php echo esc_html( $change_plan_text ) ?></a>
|
383 |
|
384 |
$profile = array();
|
385 |
|
386 |
+
if ( ! $is_whitelabeled ) {
|
387 |
$profile[] = array(
|
388 |
'id' => 'user_name',
|
389 |
'title' => fs_text_inline( 'Name', 'name', $slug ),
|
452 |
'value' => $fs->get_plugin_version()
|
453 |
);
|
454 |
|
455 |
+
if ( ! fs_is_network_admin() && $is_premium ) {
|
456 |
$profile[] = array(
|
457 |
'id' => 'beta_program',
|
458 |
'title' => '',
|
554 |
<?php endif ?>
|
555 |
<?php if ( ! $is_whitelabeled ) : ?>
|
556 |
<div class="button-group">
|
|
|
557 |
<?php if ( is_object( $available_license ) ) : ?>
|
|
|
558 |
<?php
|
559 |
$view_params = array(
|
560 |
'freemius' => $fs,
|
561 |
'slug' => $slug,
|
562 |
'license' => $available_license,
|
563 |
+
'plan' => $available_license_paid_plan,
|
564 |
'is_localhost' => $site->is_localhost(),
|
565 |
'install_id' => $site->id,
|
566 |
'class' => 'button-primary',
|
577 |
<input type="hidden" name="fs_action"
|
578 |
value="<?php echo $fs->get_unique_affix() ?>_sync_license">
|
579 |
<?php wp_nonce_field( $fs->get_unique_affix() . '_sync_license' ) ?>
|
580 |
+
<?php if ( $show_upgrade || $is_plan_change_supported ) : ?>
|
581 |
<a href="<?php echo $fs->get_upgrade_url() ?>"
|
582 |
class="button<?php
|
583 |
echo $show_upgrade ?
|
660 |
<?php endif ?>
|
661 |
<?php
|
662 |
elseif ( in_array( $p['id'], array( 'license_key', 'site_secret_key' ) ) ) : ?>
|
663 |
+
<?php if ( ! $is_whitelabeled && ( 'site_secret_key' === $p['id'] || ! $is_license_foreign ) ) : ?>
|
664 |
<button class="button button-small fs-toggle-visibility"><?php fs_esc_html_echo_x_inline( 'Show', 'verb', 'show', $slug ) ?></button>
|
665 |
<?php endif ?>
|
666 |
<?php if ('license_key' === $p['id']) : ?>
|
673 |
'user_name'
|
674 |
) ) )
|
675 |
) : ?>
|
676 |
+
<?php if ( 'email' !== $p['id'] || ! fs_is_network_admin() ) : ?>
|
677 |
<form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST"
|
678 |
onsubmit="var val = prompt('<?php echo esc_attr( sprintf(
|
679 |
/* translators: %s: User's account property (e.g. name, email) */
|
684 |
<input type="hidden" name="fs_<?php echo $p['id'] ?>_<?php echo $fs->get_unique_affix() ?>"
|
685 |
value="">
|
686 |
<?php wp_nonce_field( 'update_' . $p['id'] ) ?>
|
687 |
+
<input type="submit" class="button button-small <?php if ( 'email' === $p['id'] ) echo 'button-edit-email-address' ?>"
|
688 |
value="<?php echo fs_esc_attr_x_inline( 'Edit', 'verb', 'edit', $slug ) ?>">
|
689 |
</form>
|
690 |
+
<?php endif ?>
|
691 |
<?php elseif ( 'user_id' === $p['id'] && ! empty( $ids_of_installs_activated_with_foreign_licenses ) ) : ?>
|
692 |
<input id="fs_change_user" type="submit" class="button button-small"
|
693 |
value="<?php echo fs_esc_attr_inline( 'Change User', 'change-user', $slug ) ?>">
|
747 |
<div class="fs-table-body">
|
748 |
<table class="widefat">
|
749 |
<?php
|
750 |
+
$current_blog_id = get_current_blog_id();
|
751 |
+
|
752 |
foreach ( $site_view_params as $view_params ) {
|
753 |
fs_require_template(
|
754 |
'account/partials/site.php',
|
755 |
$view_params
|
756 |
);
|
757 |
+
}
|
758 |
+
|
759 |
+
/**
|
760 |
+
* It's possible for the `Freemius::switch_to_blog()` method to be called within the `site.php` template and this changes the Freemius instance's context, so this check is for restoring the previous context based on the previously retrieved site.
|
761 |
+
*
|
762 |
+
* @author Leo Fajardo (@leorw)
|
763 |
+
* @since 2.5.0
|
764 |
+
*/
|
765 |
+
$current_install = $fs->get_site();
|
766 |
+
|
767 |
+
if (
|
768 |
+
is_object( $site ) &&
|
769 |
+
( ! is_object( $current_install ) || $current_install->id != $site->id )
|
770 |
+
) {
|
771 |
+
$fs->switch_to_blog( $current_blog_id, $site, true );
|
772 |
+
}
|
773 |
+
?>
|
774 |
</table>
|
775 |
</div>
|
776 |
</div>
|
874 |
|
875 |
<?php
|
876 |
if ( $show_billing ) {
|
877 |
+
$view_params = array( 'id' => $VARS['id'], 'payments' => $payments );
|
878 |
fs_require_once_template( 'account/billing.php', $view_params );
|
879 |
fs_require_once_template( 'account/payments.php', $view_params );
|
880 |
}
|
954 |
|
955 |
if ( ! isChecked || confirm( '<?php echo $confirmation_message ?>' ) ) {
|
956 |
$.ajax( {
|
957 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
958 |
method: 'POST',
|
959 |
data : {
|
960 |
action : '<?php echo $fs->get_ajax_action( 'set_beta_mode' ) ?>',
|
1097 |
var $toggleLink = $( this );
|
1098 |
|
1099 |
$.ajax( {
|
1100 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
1101 |
method: 'POST',
|
1102 |
data : {
|
1103 |
action : '<?php echo $fs->get_ajax_action( 'toggle_whitelabel_mode' ) ?>',
|
1130 |
'module_slug' => $slug,
|
1131 |
'module_version' => $fs->get_plugin_version(),
|
1132 |
);
|
1133 |
+
fs_require_template( 'powered-by.php', $params );
|
freemius/templates/account/billing.php
CHANGED
@@ -377,7 +377,7 @@
|
|
377 |
});
|
378 |
|
379 |
$.ajax({
|
380 |
-
url :
|
381 |
method : 'POST',
|
382 |
data : {
|
383 |
action : '<?php echo $fs->get_ajax_action( 'update_billing' ) ?>',
|
377 |
});
|
378 |
|
379 |
$.ajax({
|
380 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
381 |
method : 'POST',
|
382 |
data : {
|
383 |
action : '<?php echo $fs->get_ajax_action( 'update_billing' ) ?>',
|
freemius/templates/account/partials/disconnect-button.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2016, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 2.5.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
* @var Freemius $fs
|
16 |
+
*/
|
17 |
+
$fs = $VARS['freemius'];
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var FS_Plugin_License $license
|
21 |
+
*/
|
22 |
+
$license = $VARS['license'];
|
23 |
+
/**
|
24 |
+
* @var FS_Plugin_Plan $license_paid_plan
|
25 |
+
*/
|
26 |
+
$license_paid_plan = $VARS['license_paid_plan'];
|
27 |
+
|
28 |
+
$license_subscription = ( is_object( $license ) && is_object( $license_paid_plan ) ) ?
|
29 |
+
$fs->_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( '<a href="#" tabindex="-1">%s</a>', fs_strip_url_protocol( untrailingslashit( Freemius::get_unfiltered_site_url() ) ) );
|
40 |
+
?>
|
41 |
+
<script type="text/javascript">
|
42 |
+
// Wrap in a IFFE to prevent leaking global variables.
|
43 |
+
( function( $ ) {
|
44 |
+
$( document ).ready( function() {
|
45 |
+
var $modal = $( '#fs_modal_delete_site' );
|
46 |
+
|
47 |
+
$( '#<?php echo $button_id ?>' ).on( 'click', function( e ) {
|
48 |
+
// Prevent the form being submitted.
|
49 |
+
e.preventDefault();
|
50 |
+
|
51 |
+
$( document.body ).append( $modal );
|
52 |
+
$modal.show();
|
53 |
+
} );
|
54 |
+
|
55 |
+
$modal.on( 'click', '.button-close', function ( evt ) {
|
56 |
+
$modal.hide();
|
57 |
+
} );
|
58 |
+
|
59 |
+
$modal.on( 'click', '.button-primary', function ( evt ) {
|
60 |
+
$( '#<?php echo $button_id ?>' ).closest( 'form' )[0].submit();
|
61 |
+
} );
|
62 |
+
} );
|
63 |
+
} )( jQuery );
|
64 |
+
</script>
|
65 |
+
<div id="fs_modal_delete_site" class="fs-modal active" style="display: none">
|
66 |
+
<div class="fs-modal-dialog">
|
67 |
+
<div class="fs-modal-header">
|
68 |
+
<h4><?php echo $fs->esc_html_inline( 'Disconnect', 'disconnect' ) ?></h4>
|
69 |
+
</div>
|
70 |
+
<div class="fs-modal-body">
|
71 |
+
<?php if ( ! is_object( $license ) ) : ?>
|
72 |
+
<p><?php echo
|
73 |
+
// translators: %1$s is replaced with the website's homepage address, %2$s is replaced with the plugin name.
|
74 |
+
sprintf( esc_html( $fs->get_text_inline( 'By disconnecting the website, previously shared diagnostic data about %1$s will be deleted and no longer visible to %2$s.', 'disconnect-intro-paid' ) ), $website_link, '<b>' . $fs->get_plugin_title() . '</b>' ) ?></p>
|
75 |
+
<?php else : ?>
|
76 |
+
<p><?php echo
|
77 |
+
// translators: %s is replaced with the website's homepage address.
|
78 |
+
sprintf( esc_html( $fs->get_text_inline( 'Disconnecting the website will permanently remove %s from your User Dashboard\'s account.', 'disconnect-intro-paid' ) ), $website_link ) ?></p>
|
79 |
+
<?php endif ?>
|
80 |
+
|
81 |
+
<?php if ( $has_active_subscription ) : ?>
|
82 |
+
<p><?php echo
|
83 |
+
// translators: %1$s is replaced by the paid plan name, %2$s is replaced with an anchor link with the text "User Dashboard".
|
84 |
+
sprintf( esc_html( $fs->get_text_inline( 'If you wish to cancel your %1$s plan\'s subscription instead, please navigate to the %2$s and cancel it there.', 'disconnect-subscription-disclaimer' ) ), $license_paid_plan->title, sprintf( '<a href="https://users.freemius.com" target="_blank" rel="noreferrer noopener nofollow">%s</a>', $fs->get_text_inline( 'User Dashboard', 'user-dashboard' ) )
|
85 |
+
) ?></p>
|
86 |
+
<?php endif ?>
|
87 |
+
|
88 |
+
<p><?php echo esc_html( $fs->get_text_inline( 'Are you sure you would like to proceed with the disconnection?', 'disconnect-confirm' ) ) ?></p>
|
89 |
+
</div>
|
90 |
+
<div class="fs-modal-footer">
|
91 |
+
<button class="button button-primary<?php if ( is_object( $license ) ) : ?> warn<?php endif ?>" tabindex="2"><?php echo $fs->esc_html_inline( 'Yes', 'yes' ) . ' - ' . $fs->esc_html_inline( 'Disconnect', 'disconnect' ) ?></button>
|
92 |
+
<button class="button button-secondary button-close" tabindex="1"><?php echo esc_html( $fs->get_text_inline( 'Cancel', 'cancel' ) ) ?></button>
|
93 |
+
</div>
|
94 |
+
</div>
|
95 |
+
</div>
|
96 |
+
<form action="<?php echo esc_attr( $fs->_get_admin_page_url( 'account' ) ); ?>" method="POST">
|
97 |
+
<input type="hidden" name="fs_action" value="delete_account">
|
98 |
+
<?php wp_nonce_field( 'delete_account' ) ?>
|
99 |
+
|
100 |
+
<a id="<?php echo $button_id ?>" href="#" class="fs-button-inline">
|
101 |
+
<i class="dashicons dashicons-no"></i>
|
102 |
+
<?php echo $fs->esc_html_inline( 'Disconnect', 'disconnect' ) ?>
|
103 |
+
</a>
|
104 |
+
</form>
|
freemius/templates/account/partials/site.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
$is_whitelabeled = $fs->is_whitelabeled();
|
24 |
$has_paid_plan = $fs->has_paid_plan();
|
25 |
$is_premium = $fs->is_premium();
|
26 |
-
$main_user = $
|
27 |
$blog_id = $site['blog_id'];
|
28 |
|
29 |
$install = $VARS['install'];
|
@@ -32,7 +32,7 @@
|
|
32 |
$trial_plan = $fs->get_trial_plan();
|
33 |
$free_text = fs_text_inline( 'Free', 'free', $slug );
|
34 |
|
35 |
-
if ( $is_whitelabeled && $fs->is_delegated_connection( $blog_id ) ) {
|
36 |
$is_whitelabeled = $fs->is_whitelabeled( true, $blog_id );
|
37 |
}
|
38 |
?>
|
@@ -159,14 +159,15 @@
|
|
159 |
<td><?php if ( ! FS_Plugin_License::is_valid_id( $install->license_id ) ) : ?>
|
160 |
<!-- Toggle Usage Tracking -->
|
161 |
<?php $action = 'toggle_tracking' ?>
|
|
|
162 |
<form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST">
|
163 |
<input type="hidden" name="fs_action" value="<?php echo $action ?>">
|
164 |
<?php wp_nonce_field( trim( "{$action}:{$blog_id}:{$install->id}", ':' ) ) ?>
|
165 |
<input type="hidden" name="install_id" value="<?php echo $install->id ?>">
|
166 |
<input type="hidden" name="blog_id" value="<?php echo $blog_id ?>">
|
167 |
-
<button class="fs-toggle-tracking button button-small<?php if ( $
|
168 |
echo ' button-primary';
|
169 |
-
} ?>" data-is-disconnected="<?php echo $
|
170 |
</form>
|
171 |
<!--/ Toggle Usage Tracking -->
|
172 |
<?php endif ?></td>
|
@@ -174,7 +175,7 @@
|
|
174 |
<?php $row_index ++ ?>
|
175 |
<!--/ Blog ID -->
|
176 |
|
177 |
-
<?php if ( $
|
178 |
<?php
|
179 |
/**
|
180 |
* @var FS_User $user
|
@@ -226,7 +227,8 @@
|
|
226 |
<td>
|
227 |
<nobr><?php fs_esc_html_echo_inline( 'Public Key', 'public-key', $slug ) ?>:</nobr>
|
228 |
</td>
|
229 |
-
<td
|
|
|
230 |
</tr>
|
231 |
<?php $row_index ++ ?>
|
232 |
<!--/ Public Key -->
|
23 |
$is_whitelabeled = $fs->is_whitelabeled();
|
24 |
$has_paid_plan = $fs->has_paid_plan();
|
25 |
$is_premium = $fs->is_premium();
|
26 |
+
$main_user = $VARS['user'];
|
27 |
$blog_id = $site['blog_id'];
|
28 |
|
29 |
$install = $VARS['install'];
|
32 |
$trial_plan = $fs->get_trial_plan();
|
33 |
$free_text = fs_text_inline( 'Free', 'free', $slug );
|
34 |
|
35 |
+
if ( $is_whitelabeled && is_object( $install ) && $fs->is_delegated_connection( $blog_id ) ) {
|
36 |
$is_whitelabeled = $fs->is_whitelabeled( true, $blog_id );
|
37 |
}
|
38 |
?>
|
159 |
<td><?php if ( ! FS_Plugin_License::is_valid_id( $install->license_id ) ) : ?>
|
160 |
<!-- Toggle Usage Tracking -->
|
161 |
<?php $action = 'toggle_tracking' ?>
|
162 |
+
<?php $is_disconnected = ! FS_Permission_Manager::instance( $fs )->is_homepage_url_tracking_allowed( $blog_id ) ?>
|
163 |
<form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST">
|
164 |
<input type="hidden" name="fs_action" value="<?php echo $action ?>">
|
165 |
<?php wp_nonce_field( trim( "{$action}:{$blog_id}:{$install->id}", ':' ) ) ?>
|
166 |
<input type="hidden" name="install_id" value="<?php echo $install->id ?>">
|
167 |
<input type="hidden" name="blog_id" value="<?php echo $blog_id ?>">
|
168 |
+
<button class="fs-toggle-tracking button button-small<?php if ( $is_disconnected ) {
|
169 |
echo ' button-primary';
|
170 |
+
} ?>" data-is-disconnected="<?php echo $is_disconnected ? 'true' : 'false' ?>"><?php $is_disconnected ? fs_esc_html_echo_inline( 'Opt In', 'opt-in', $slug ) : fs_esc_html_echo_inline( 'Opt Out', 'opt-out', $slug ) ?></button>
|
171 |
</form>
|
172 |
<!--/ Toggle Usage Tracking -->
|
173 |
<?php endif ?></td>
|
175 |
<?php $row_index ++ ?>
|
176 |
<!--/ Blog ID -->
|
177 |
|
178 |
+
<?php if ( $install->user_id != $main_user->id ) : ?>
|
179 |
<?php
|
180 |
/**
|
181 |
* @var FS_User $user
|
227 |
<td>
|
228 |
<nobr><?php fs_esc_html_echo_inline( 'Public Key', 'public-key', $slug ) ?>:</nobr>
|
229 |
</td>
|
230 |
+
<td><code><?php echo htmlspecialchars( $install->public_key ) ?></code></td>
|
231 |
+
<td></td>
|
232 |
</tr>
|
233 |
<?php $row_index ++ ?>
|
234 |
<!--/ Public Key -->
|
freemius/templates/account/payments.php
CHANGED
@@ -10,19 +10,19 @@
|
|
10 |
exit;
|
11 |
}
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
|
19 |
-
|
|
|
|
|
|
|
20 |
|
21 |
-
$
|
22 |
-
|
23 |
-
$show_payments = ( is_array( $payments ) && 0 < count( $payments ) );
|
24 |
|
25 |
-
if ( $show_payments ) :
|
26 |
?>
|
27 |
<div class="postbox">
|
28 |
<div id="fs_payments">
|
@@ -56,4 +56,3 @@
|
|
56 |
</div>
|
57 |
</div>
|
58 |
<?php
|
59 |
-
endif;
|
10 |
exit;
|
11 |
}
|
12 |
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
* @var Freemius $fs
|
16 |
+
*/
|
17 |
+
$fs = freemius( $VARS['id'] );
|
18 |
|
19 |
+
/**
|
20 |
+
* @var FS_Payment[] $payments
|
21 |
+
*/
|
22 |
+
$payments = $VARS['payments'];
|
23 |
|
24 |
+
$slug = $fs->get_slug();
|
|
|
|
|
25 |
|
|
|
26 |
?>
|
27 |
<div class="postbox">
|
28 |
<div id="fs_payments">
|
56 |
</div>
|
57 |
</div>
|
58 |
<?php
|
|
freemius/templates/admin-notice.php
CHANGED
@@ -45,6 +45,9 @@
|
|
45 |
case 'promotion':
|
46 |
echo 'updated promotion';
|
47 |
break;
|
|
|
|
|
|
|
48 |
case 'update':
|
49 |
// echo 'update-nag update';
|
50 |
// break;
|
@@ -64,7 +67,7 @@
|
|
64 |
} ?>"><?php if ( ! empty( $VARS['plugin'] ) ) : ?>
|
65 |
<label class="fs-plugin-title"><?php echo $VARS['plugin'] ?></label>
|
66 |
<?php endif ?>
|
67 |
-
<?php if ( ! empty( $VARS['sticky'] ) ) : ?>
|
68 |
<div class="fs-close"><i class="dashicons dashicons-no"
|
69 |
title="<?php echo esc_attr( $dismiss_text ) ?>"></i> <span><?php echo esc_html( $dismiss_text ) ?></span>
|
70 |
</div>
|
45 |
case 'promotion':
|
46 |
echo 'updated promotion';
|
47 |
break;
|
48 |
+
case 'warn':
|
49 |
+
echo 'notice notice-warning';
|
50 |
+
break;
|
51 |
case 'update':
|
52 |
// echo 'update-nag update';
|
53 |
// break;
|
67 |
} ?>"><?php if ( ! empty( $VARS['plugin'] ) ) : ?>
|
68 |
<label class="fs-plugin-title"><?php echo $VARS['plugin'] ?></label>
|
69 |
<?php endif ?>
|
70 |
+
<?php if ( ! empty( $VARS['sticky'] ) && ( ! isset( $VARS['dismissible'] ) || false !== $VARS['dismissible'] ) ) : ?>
|
71 |
<div class="fs-close"><i class="dashicons dashicons-no"
|
72 |
title="<?php echo esc_attr( $dismiss_text ) ?>"></i> <span><?php echo esc_html( $dismiss_text ) ?></span>
|
73 |
</div>
|
freemius/templates/auto-installation.php
CHANGED
@@ -164,7 +164,7 @@
|
|
164 |
}
|
165 |
|
166 |
$.ajax({
|
167 |
-
url :
|
168 |
method : 'POST',
|
169 |
data : data,
|
170 |
success: function (resultObj) {
|
164 |
}
|
165 |
|
166 |
$.ajax({
|
167 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
168 |
method : 'POST',
|
169 |
data : data,
|
170 |
success: function (resultObj) {
|
freemius/templates/clone-resolution-js.php
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 2.5.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
?>
|
13 |
+
<script type="text/javascript">
|
14 |
+
( function( $ ) {
|
15 |
+
var $errorMessage = null;
|
16 |
+
|
17 |
+
$( document ).ready( function() {
|
18 |
+
var $cloneResolutionNotice = $( 'div[data-id="clone_resolution_options_notice"], div[data-id="temporary_duplicate_notice"]' );
|
19 |
+
|
20 |
+
if ( 0 === $cloneResolutionNotice.length ) {
|
21 |
+
return;
|
22 |
+
}
|
23 |
+
|
24 |
+
$errorMessage = $cloneResolutionNotice.find( '#fs_clone_resolution_error_message' );
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Triggers an AJAX request when the license activation link or any of the buttons on the clone resolution options notice is clicked. The AJAX request will then handle the action the user has chosen.
|
28 |
+
*/
|
29 |
+
$cloneResolutionNotice.on( 'click', '.button, #fs_temporary_duplicate_license_activation_link', function( evt ) {
|
30 |
+
evt.preventDefault();
|
31 |
+
|
32 |
+
var $this = $( this );
|
33 |
+
|
34 |
+
if ( $this.hasClass( 'disabled' ) ) {
|
35 |
+
return;
|
36 |
+
}
|
37 |
+
|
38 |
+
var $body = $( 'body' ),
|
39 |
+
$optionsContainer = $this.parents( '.fs-clone-resolution-options-container' ),
|
40 |
+
cursor = $body.css( 'cursor' ),
|
41 |
+
beforeUnload = function() {
|
42 |
+
return '<?php fs_esc_js_echo_inline( 'Please wait', 'please-wait' ) ?>';
|
43 |
+
};
|
44 |
+
|
45 |
+
$.ajax( {
|
46 |
+
// Get the parent options container from the child as `$cloneResolutionNotice` can have different AJAX URLs if both the manual clone resolution options and temporary duplicate notices are shown (for different subsites in a multisite network).
|
47 |
+
url : $optionsContainer.data( 'ajax-url' ),
|
48 |
+
method : 'POST',
|
49 |
+
data : {
|
50 |
+
action : '<?php echo $VARS['ajax_action'] ?>',
|
51 |
+
security : '<?php echo wp_create_nonce( $VARS['ajax_action'] ) ?>',
|
52 |
+
clone_action: $this.data( 'clone-action' ),
|
53 |
+
blog_id : $optionsContainer.data( 'blog-id' )
|
54 |
+
},
|
55 |
+
beforeSend: function() {
|
56 |
+
$body.css( { cursor: 'wait' } );
|
57 |
+
|
58 |
+
$cloneResolutionNotice.find( '.button' ).addClass( 'disabled' );
|
59 |
+
|
60 |
+
$( window ).on( 'beforeunload', beforeUnload );
|
61 |
+
},
|
62 |
+
success : function( resultObj ) {
|
63 |
+
$( window ).off( 'beforeunload', beforeUnload );
|
64 |
+
|
65 |
+
if ( resultObj.data.redirect_url && '' !== resultObj.data.redirect_url ) {
|
66 |
+
window.location = resultObj.data.redirect_url;
|
67 |
+
} else {
|
68 |
+
window.location.reload();
|
69 |
+
}
|
70 |
+
},
|
71 |
+
error : function() {
|
72 |
+
$body.css( { cursor: cursor } );
|
73 |
+
$cloneResolutionNotice.find( '.button' ).removeClass( 'disabled' );
|
74 |
+
}
|
75 |
+
} );
|
76 |
+
} );
|
77 |
+
} );
|
78 |
+
} )( jQuery );
|
79 |
+
</script>
|
freemius/templates/connect.php
CHANGED
@@ -25,6 +25,15 @@
|
|
25 |
|
26 |
$fs->_enqueue_connect_essentials();
|
27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
$current_user = Freemius::_get_current_wp_user();
|
29 |
|
30 |
$first_name = $current_user->user_firstname;
|
@@ -32,7 +41,7 @@
|
|
32 |
$first_name = $current_user->nickname;
|
33 |
}
|
34 |
|
35 |
-
$site_url =
|
36 |
$protocol_pos = strpos( $site_url, '://' );
|
37 |
if ( false !== $protocol_pos ) {
|
38 |
$site_url = substr( $site_url, $protocol_pos + 3 );
|
@@ -118,6 +127,14 @@
|
|
118 |
if ( is_null( $is_gdpr_required ) ) {
|
119 |
$is_gdpr_required = $fs->fetch_and_store_current_user_gdpr_anonymously();
|
120 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
?>
|
122 |
<?php
|
123 |
if ( $is_optin_dialog ) { ?>
|
@@ -138,26 +155,54 @@
|
|
138 |
* @author Vova Feldman
|
139 |
* @since 2.3.2
|
140 |
*/
|
141 |
-
$fs->do_action( 'connect/before' );
|
142 |
?>
|
143 |
<div id="fs_connect"
|
144 |
class="wrap<?php if ( ! fs_is_network_admin() && ( ! $fs->is_enable_anonymous() || $is_pending_activation || $require_license_key ) ) {
|
145 |
echo ' fs-anonymous-disabled';
|
146 |
} ?><?php echo $require_license_key ? ' require-license-key' : '' ?>">
|
147 |
-
|
148 |
-
<b class="fs-site-icon"><i class="dashicons dashicons-wordpress"></i></b
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
|
|
|
|
|
|
|
|
157 |
<div class="fs-content">
|
|
|
|
|
158 |
<?php if ( ! empty( $error ) ) : ?>
|
159 |
-
<p class="fs-error"><?php echo esc_html( $error ) ?></p>
|
160 |
<?php endif ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
<p><?php
|
162 |
$button_label = fs_text_inline( 'Allow & Continue', 'opt-in-connect', $slug );
|
163 |
$message = '';
|
@@ -168,16 +213,14 @@
|
|
168 |
$message = $fs->apply_filters( 'pending_activation_message', sprintf(
|
169 |
/* translators: %s: name (e.g. Thanks John!) */
|
170 |
fs_text_inline( 'Thanks %s!', 'thanks-x', $slug ) . '<br>' .
|
171 |
-
fs_text_inline( 'You should receive
|
172 |
$first_name,
|
173 |
'<b>' . $fs->get_plugin_name() . '</b>',
|
174 |
'<b>' . $current_user->user_email . '</b>',
|
175 |
-
fs_text_inline( 'complete the
|
176 |
) );
|
177 |
} else if ( $require_license_key ) {
|
178 |
-
$button_label = $
|
179 |
-
fs_text_inline( 'Activate License', 'agree-activate-license', $slug ) :
|
180 |
-
fs_text_inline( 'Agree & Activate License', 'agree-activate-license', $slug );
|
181 |
|
182 |
$message = $fs->apply_filters(
|
183 |
'connect-message_on-premium',
|
@@ -186,21 +229,32 @@
|
|
186 |
$fs->get_plugin_name()
|
187 |
);
|
188 |
} else {
|
189 |
-
|
190 |
-
$default_optin_message = $is_gdpr_required ?
|
191 |
-
fs_text_inline( 'Never miss an important update - opt in to our security & feature updates notifications, educational content, offers, and non-sensitive diagnostic tracking with %4$s.', 'connect-message', $slug) :
|
192 |
-
fs_text_inline( 'Never miss an important update - opt in to our security and feature updates notifications, and non-sensitive diagnostic tracking with %4$s.', 'connect-message', $slug);
|
193 |
|
194 |
-
if ( $fs->is_plugin_update() ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
195 |
// If Freemius was added on a plugin update, set different
|
196 |
// opt-in message.
|
197 |
-
$default_optin_message = $is_gdpr_required ?
|
198 |
-
fs_text_inline( 'Never miss an important update - opt in to our security & feature updates notifications, educational content, offers, and non-sensitive diagnostic tracking with %4$s. If you skip this, that\'s okay! %1$s will still work just fine.', 'connect-message_on-update', $slug ) :
|
199 |
-
fs_text_inline( 'Never miss an important update - opt in to our security & feature updates notifications, and non-sensitive diagnostic tracking with %4$s. If you skip this, that\'s okay! %1$s will still work just fine.', 'connect-message_on-update', $slug );
|
200 |
|
201 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
// that message. Otherwise, fallback to regular opt-in
|
203 |
-
// custom message if
|
204 |
if ( $fs->has_filter( 'connect_message_on_update' ) ) {
|
205 |
$filter = 'connect_message_on_update';
|
206 |
}
|
@@ -208,17 +262,12 @@
|
|
208 |
|
209 |
$message = $fs->apply_filters(
|
210 |
$filter,
|
211 |
-
($is_network_upgrade_mode ?
|
212 |
-
'' :
|
213 |
-
/* translators: %s: name (e.g. Hey John,) */
|
214 |
-
$hey_x_text . '<br>'
|
215 |
-
) .
|
216 |
sprintf(
|
217 |
-
|
218 |
'<b>' . esc_html( $fs->get_plugin_name() ) . '</b>',
|
219 |
'<b>' . $current_user->user_login . '</b>',
|
220 |
'<a href="' . $site_url . '" target="_blank" rel="noopener noreferrer">' . $site_url . '</a>',
|
221 |
-
|
222 |
),
|
223 |
$first_name,
|
224 |
$fs->get_plugin_name(),
|
@@ -266,7 +315,7 @@
|
|
266 |
* @author Vova Feldman
|
267 |
* @since 2.1.2
|
268 |
*/
|
269 |
-
$fs->do_action( 'connect/after_license_input' );
|
270 |
?>
|
271 |
|
272 |
<?php
|
@@ -311,8 +360,12 @@
|
|
311 |
echo fs_get_template( 'partials/network-activation.php', $vars );
|
312 |
?>
|
313 |
<?php endif ?>
|
|
|
|
|
314 |
</div>
|
315 |
<div class="fs-actions">
|
|
|
|
|
316 |
<?php if ( $fs->is_enable_anonymous() && ! $is_pending_activation && ( ! $require_license_key || $is_network_upgrade_mode ) ) : ?>
|
317 |
<a id="skip_activation" href="<?php echo fs_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $fs->get_unique_affix() . '_skip_activation' ), $is_network_level_activation ), $fs->get_unique_affix() . '_skip_activation' ) ?>"
|
318 |
class="button button-secondary" tabindex="2"><?php fs_esc_html_echo_x_inline( 'Skip', 'verb', 'skip', $slug ) ?></a>
|
@@ -326,6 +379,7 @@
|
|
326 |
value="<?php echo $fs->get_unique_affix() ?>_activate_existing">
|
327 |
<?php wp_nonce_field( 'activate_existing_' . $fs->get_public_key() ) ?>
|
328 |
<input type="hidden" name="is_extensions_tracking_allowed" value="1">
|
|
|
329 |
<button class="button button-primary" tabindex="1"
|
330 |
type="submit"><?php echo esc_html( $button_label ) ?></button>
|
331 |
</form>
|
@@ -336,6 +390,7 @@
|
|
336 |
<input type="hidden" name="<?php echo $name ?>" value="<?php echo esc_attr( $value ) ?>">
|
337 |
<?php endforeach ?>
|
338 |
<input type="hidden" name="is_extensions_tracking_allowed" value="1">
|
|
|
339 |
<button class="button button-primary" tabindex="1"
|
340 |
type="submit"<?php if ( $require_license_key ) {
|
341 |
echo ' disabled="disabled"';
|
@@ -345,109 +400,42 @@
|
|
345 |
<?php if ( $require_license_key ) : ?>
|
346 |
<a id="license_issues_link" href="<?php echo $fs->apply_filters( 'known_license_issues_url', 'https://freemius.com/help/documentation/wordpress-sdk/license-activation-issues/' ) ?>" target="_blank"><?php fs_esc_html_echo_inline( 'License issues?', 'license-issues', $slug ) ?></a>
|
347 |
<?php endif ?>
|
|
|
|
|
348 |
</div><?php
|
|
|
349 |
|
350 |
// Set core permission list items.
|
351 |
$permissions = array();
|
352 |
|
353 |
-
/**
|
354 |
-
* When activating a license key the information of the admin is not collected, we gather the user info from the license.
|
355 |
-
*
|
356 |
-
* @since 2.3.2
|
357 |
-
* @author Vova Feldman
|
358 |
-
*/
|
359 |
-
if ( ! $require_license_key ) {
|
360 |
-
$permissions['profile'] = array(
|
361 |
-
'icon-class' => 'dashicons dashicons-admin-users',
|
362 |
-
'label' => $fs->get_text_inline( 'Your Profile Overview', 'permissions-profile' ),
|
363 |
-
'desc' => $fs->get_text_inline( 'Name and email address', 'permissions-profile_desc' ),
|
364 |
-
'priority' => 5,
|
365 |
-
);
|
366 |
-
}
|
367 |
-
|
368 |
-
$permissions['site'] = array(
|
369 |
-
'icon-class' => 'dashicons dashicons-admin-settings',
|
370 |
-
'tooltip' => ( $require_license_key ? sprintf( $fs->get_text_inline( 'So you can manage and control your license remotely from the User Dashboard.', 'permissions-site_tooltip' ), $fs->get_module_type() ) : '' ),
|
371 |
-
'label' => $fs->get_text_inline( 'Your Site Overview', 'permissions-site' ),
|
372 |
-
'desc' => $fs->get_text_inline( 'Site URL, WP version, PHP info', 'permissions-site_desc' ),
|
373 |
-
'priority' => 10,
|
374 |
-
);
|
375 |
-
|
376 |
-
if ( ! $require_license_key ) {
|
377 |
-
$permissions['notices'] = array(
|
378 |
-
'icon-class' => 'dashicons dashicons-testimonial',
|
379 |
-
'label' => $fs->get_text_inline( 'Admin Notices', 'permissions-admin-notices' ),
|
380 |
-
'desc' => $fs->get_text_inline( 'Updates, announcements, marketing, no spam', 'permissions-newsletter_desc' ),
|
381 |
-
'priority' => 13,
|
382 |
-
);
|
383 |
-
}
|
384 |
-
|
385 |
-
$permissions['events'] = array(
|
386 |
-
'icon-class' => 'dashicons dashicons-admin-' . ( $fs->is_plugin() ? 'plugins' : 'appearance' ),
|
387 |
-
'tooltip' => ( $require_license_key ? sprintf( $fs->get_text_inline( 'So you can reuse the license when the %s is no longer active.', 'permissions-events_tooltip' ), $fs->get_module_type() ) : '' ),
|
388 |
-
'label' => sprintf( $fs->get_text_inline( 'Current %s Status', 'permissions-events' ), ucfirst( $fs->get_module_type() ) ),
|
389 |
-
'desc' => $fs->get_text_inline( 'Active, deactivated, or uninstalled', 'permissions-events_desc' ),
|
390 |
-
'priority' => 20,
|
391 |
-
);
|
392 |
-
|
393 |
// Add newsletter permissions if enabled.
|
394 |
if ( $is_gdpr_required || $fs->is_permission_requested( 'newsletter' ) ) {
|
395 |
-
$permissions[
|
396 |
-
'icon-class' => 'dashicons dashicons-email-alt',
|
397 |
-
'label' => $fs->get_text_inline( 'Newsletter', 'permissions-newsletter' ),
|
398 |
-
'desc' => $fs->get_text_inline( 'Updates, announcements, marketing, no spam', 'permissions-newsletter_desc' ),
|
399 |
-
'priority' => 15,
|
400 |
-
);
|
401 |
}
|
402 |
|
403 |
-
$permissions
|
404 |
-
|
405 |
-
|
406 |
-
'tooltip' => $fs->get_text_inline( 'To help us troubleshoot any potential issues that may arise from other plugin or theme conflicts.', 'permissions-events_tooltip' ),
|
407 |
-
'desc' => $fs->get_text_inline( 'Title, slug, version, and is active', 'permissions-extensions_desc' ),
|
408 |
-
'priority' => 25,
|
409 |
-
'optional' => true,
|
410 |
-
'default' => $fs->apply_filters( 'permission_extensions_default', ! $require_license_key )
|
411 |
);
|
412 |
|
413 |
-
// Allow filtering of the permissions list.
|
414 |
-
$permissions = $fs->apply_filters( 'permission_list', $permissions );
|
415 |
-
|
416 |
-
// Sort by priority.
|
417 |
-
uasort( $permissions, 'fs_sort_by_priority' );
|
418 |
-
|
419 |
if ( ! empty( $permissions ) ) : ?>
|
420 |
<div class="fs-permissions">
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
<?php endif ?>
|
432 |
<ul><?php
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
<?php if ( isset( $permission['optional'] ) && true === $permission['optional'] ) : ?>
|
438 |
-
<div class="fs-switch fs-small fs-round fs-<?php echo (! isset( $permission['default'] ) || true === $permission['default'] ) ? 'on' : 'off' ?>">
|
439 |
-
<div class="fs-toggle"></div>
|
440 |
-
</div>
|
441 |
-
<?php endif ?>
|
442 |
-
|
443 |
-
<div class="fs-permission-description">
|
444 |
-
<span<?php if ( ! empty($permission['tooltip']) ) : ?> class="fs-tooltip-trigger"<?php endif ?>><?php echo esc_html( $permission['label'] ); ?><?php if ( ! empty($permission['tooltip']) ) : ?><i class="dashicons dashicons-editor-help"><span class="fs-tooltip" style="width: 200px"><?php echo $permission['tooltip'] ?></span></i><?php endif ?></span>
|
445 |
-
|
446 |
-
<p><?php echo esc_html( $permission['desc'] ); ?></p>
|
447 |
-
</div>
|
448 |
-
</li>
|
449 |
-
<?php endforeach; ?>
|
450 |
-
</ul>
|
451 |
</div>
|
452 |
<?php endif ?>
|
453 |
<?php if ( $is_premium_code && $is_freemium ) : ?>
|
@@ -463,7 +451,10 @@
|
|
463 |
</p>
|
464 |
</div>
|
465 |
<?php endif ?>
|
|
|
466 |
<div class="fs-terms">
|
|
|
|
|
467 |
<a href="https://freemius.com/privacy/" target="_blank" rel="noopener"
|
468 |
tabindex="1"><?php fs_esc_html_echo_inline( 'Privacy Policy', 'privacy-policy', $slug ) ?></a>
|
469 |
-
|
@@ -477,7 +468,7 @@
|
|
477 |
* @author Vova Feldman
|
478 |
* @since 2.3.2
|
479 |
*/
|
480 |
-
$fs->do_action( 'connect/after' );
|
481 |
|
482 |
if ( $is_optin_dialog ) { ?>
|
483 |
</div>
|
@@ -531,13 +522,12 @@
|
|
531 |
// Reset loading mode.
|
532 |
$primaryCta.html(primaryCtaLabel);
|
533 |
$primaryCta.prop('disabled', false);
|
534 |
-
$(
|
535 |
-
$('.fs-loading').removeClass('fs-loading');
|
536 |
|
537 |
console.log('resetLoadingMode - Primary button was enabled');
|
538 |
},
|
539 |
setLoadingMode = function () {
|
540 |
-
$(document.body).
|
541 |
};
|
542 |
|
543 |
$('.fs-actions .button').on('click', function () {
|
@@ -601,6 +591,11 @@
|
|
601 |
updatePrimaryCtaText( actionType );
|
602 |
});
|
603 |
|
|
|
|
|
|
|
|
|
|
|
604 |
$sitesListContainer.delegate( '.action', 'click', function( evt ) {
|
605 |
var $this = $( evt.target );
|
606 |
if ( $this.hasClass( 'selected' ) ) {
|
@@ -707,15 +702,25 @@
|
|
707 |
var ajaxOptin = ( requireLicenseKey || isNetworkActive );
|
708 |
|
709 |
$form.on('submit', function () {
|
710 |
-
var $extensionsPermission = $('#
|
711 |
-
isExtensionsTrackingAllowed = ($extensionsPermission.length > 0) ?
|
712 |
-
$extensionsPermission.hasClass('fs-on') :
|
713 |
null;
|
714 |
|
715 |
-
|
716 |
-
$
|
|
|
|
|
|
|
|
|
|
|
717 |
} else {
|
718 |
-
$('input[name=is_extensions_tracking_allowed]').val(isExtensionsTrackingAllowed ? 1 : 0);
|
|
|
|
|
|
|
|
|
|
|
719 |
}
|
720 |
|
721 |
/**
|
@@ -772,6 +777,8 @@
|
|
772 |
data.is_marketing_allowed = isMarketingAllowed;
|
773 |
|
774 |
data.is_extensions_tracking_allowed = isExtensionsTrackingAllowed;
|
|
|
|
|
775 |
}
|
776 |
|
777 |
$marketingOptin.removeClass( 'error' );
|
@@ -794,7 +801,6 @@
|
|
794 |
url : $this.find( '.url' ).val(),
|
795 |
title : $this.find( '.title' ).val(),
|
796 |
language: $this.find( '.language' ).val(),
|
797 |
-
charset : $this.find( '.charset' ).val(),
|
798 |
blog_id : $this.find( '.blog-id' ).find( 'span' ).text()
|
799 |
};
|
800 |
|
@@ -822,7 +828,7 @@
|
|
822 |
* @since 1.2.1.5
|
823 |
*/
|
824 |
$.ajax({
|
825 |
-
url :
|
826 |
method : 'POST',
|
827 |
data : data,
|
828 |
success: function (result) {
|
@@ -858,6 +864,15 @@
|
|
858 |
return true;
|
859 |
});
|
860 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
861 |
$primaryCta.on('click', function () {
|
862 |
console.log('Primary button was clicked');
|
863 |
|
@@ -874,12 +889,6 @@
|
|
874 |
return false;
|
875 |
});
|
876 |
|
877 |
-
$( '.fs-switch' ).click( function () {
|
878 |
-
$(this)
|
879 |
-
.toggleClass( 'fs-on' )
|
880 |
-
.toggleClass( 'fs-off' );
|
881 |
-
});
|
882 |
-
|
883 |
if (requireLicenseKey) {
|
884 |
/**
|
885 |
* Submit license key on enter.
|
@@ -1005,7 +1014,7 @@
|
|
1005 |
$primaryCta.html('<?php fs_esc_js_echo_inline( 'Please wait', 'please-wait', $slug ) ?>...');
|
1006 |
|
1007 |
$.ajax({
|
1008 |
-
url :
|
1009 |
method : 'POST',
|
1010 |
data : {
|
1011 |
action : '<?php echo $fs->get_ajax_action( 'fetch_is_marketing_required_flag_value' ) ?>',
|
@@ -1035,4 +1044,4 @@
|
|
1035 |
|
1036 |
//endregion
|
1037 |
})(jQuery);
|
1038 |
-
</script>
|
25 |
|
26 |
$fs->_enqueue_connect_essentials();
|
27 |
|
28 |
+
/**
|
29 |
+
* Enqueueing the styles in `_enqueue_connect_essentials()` is too late, as we need them in the HEADER. Therefore, inject the styles inline to avoid FOUC.
|
30 |
+
*
|
31 |
+
* @author Vova Feldman (@svovaf)
|
32 |
+
*/
|
33 |
+
echo "<style>\n";
|
34 |
+
include WP_FS__DIR_CSS . '/admin/connect.css';
|
35 |
+
echo "</style>\n";
|
36 |
+
|
37 |
$current_user = Freemius::_get_current_wp_user();
|
38 |
|
39 |
$first_name = $current_user->user_firstname;
|
41 |
$first_name = $current_user->nickname;
|
42 |
}
|
43 |
|
44 |
+
$site_url = Freemius::get_unfiltered_site_url();
|
45 |
$protocol_pos = strpos( $site_url, '://' );
|
46 |
if ( false !== $protocol_pos ) {
|
47 |
$site_url = substr( $site_url, $protocol_pos + 3 );
|
127 |
if ( is_null( $is_gdpr_required ) ) {
|
128 |
$is_gdpr_required = $fs->fetch_and_store_current_user_gdpr_anonymously();
|
129 |
}
|
130 |
+
|
131 |
+
$activation_state = array(
|
132 |
+
'is_license_activation' => $require_license_key,
|
133 |
+
'is_pending_activation' => $is_pending_activation,
|
134 |
+
'is_gdpr_required' => $is_gdpr_required,
|
135 |
+
'is_network_level_activation' => $is_network_level_activation,
|
136 |
+
'is_dialog' => $is_optin_dialog,
|
137 |
+
);
|
138 |
?>
|
139 |
<?php
|
140 |
if ( $is_optin_dialog ) { ?>
|
155 |
* @author Vova Feldman
|
156 |
* @since 2.3.2
|
157 |
*/
|
158 |
+
$fs->do_action( 'connect/before', $activation_state );
|
159 |
?>
|
160 |
<div id="fs_connect"
|
161 |
class="wrap<?php if ( ! fs_is_network_admin() && ( ! $fs->is_enable_anonymous() || $is_pending_activation || $require_license_key ) ) {
|
162 |
echo ' fs-anonymous-disabled';
|
163 |
} ?><?php echo $require_license_key ? ' require-license-key' : '' ?>">
|
164 |
+
<div class="fs-header">
|
165 |
+
<!-- <b class="fs-site-icon"><i class="dashicons dashicons-wordpress-alt"></i></b>-->
|
166 |
+
<?php
|
167 |
+
$size = 50;
|
168 |
+
$vars = array(
|
169 |
+
'id' => $fs->get_id(),
|
170 |
+
'size' => $size,
|
171 |
+
);
|
172 |
+
|
173 |
+
fs_require_once_template( 'plugin-icon.php', $vars );
|
174 |
+
?>
|
175 |
+
<!-- <img class="fs-connect-logo" width="--><?php //echo $size ?><!--" height="--><?php //echo $size ?><!--" src="//img.freemius.com/logo/connect.svg"/>-->
|
176 |
+
</div>
|
177 |
+
<div class="fs-box-container">
|
178 |
<div class="fs-content">
|
179 |
+
<?php $fs->do_action( 'connect/before_message', $activation_state ) ?>
|
180 |
+
|
181 |
<?php if ( ! empty( $error ) ) : ?>
|
182 |
+
<p class="fs-error"><?php echo $fs->apply_filters( 'connect_error_esc_html', esc_html( $error ) ) ?></p>
|
183 |
<?php endif ?>
|
184 |
+
<?php
|
185 |
+
if ( ! $is_pending_activation && ! $require_license_key ) {
|
186 |
+
if ( ! $fs->is_plugin_update() ) {
|
187 |
+
echo $fs->apply_filters( 'connect-header', sprintf(
|
188 |
+
'<h2 style="text-align: center">%s</h2>',
|
189 |
+
esc_html( fs_text_inline( 'Never miss an important update', 'connect-header' ) )
|
190 |
+
) );
|
191 |
+
} else {
|
192 |
+
echo $fs->apply_filters( 'connect-header_on-update', sprintf(
|
193 |
+
'<h2>%s</h2>',
|
194 |
+
sprintf(
|
195 |
+
esc_html(
|
196 |
+
/* translators: %1$s: plugin name (e.g., "Awesome Plugin"); %2$s: version (e.g., "1.2.3") */
|
197 |
+
fs_text_inline('Thank you for updating to %1$s v%2$s!', 'connect-header_on-update' )
|
198 |
+
),
|
199 |
+
esc_html( $fs->get_plugin_name() ),
|
200 |
+
$fs->get_plugin_version()
|
201 |
+
)
|
202 |
+
) );
|
203 |
+
}
|
204 |
+
}
|
205 |
+
?>
|
206 |
<p><?php
|
207 |
$button_label = fs_text_inline( 'Allow & Continue', 'opt-in-connect', $slug );
|
208 |
$message = '';
|
213 |
$message = $fs->apply_filters( 'pending_activation_message', sprintf(
|
214 |
/* translators: %s: name (e.g. Thanks John!) */
|
215 |
fs_text_inline( 'Thanks %s!', 'thanks-x', $slug ) . '<br>' .
|
216 |
+
fs_text_inline( 'You should receive a confirmation email for %s to your mailbox at %s. Please make sure you click the button in that email to %s.', 'pending-activation-message', $slug ),
|
217 |
$first_name,
|
218 |
'<b>' . $fs->get_plugin_name() . '</b>',
|
219 |
'<b>' . $current_user->user_email . '</b>',
|
220 |
+
fs_text_inline( 'complete the opt-in', 'complete-the-opt-in', $slug )
|
221 |
) );
|
222 |
} else if ( $require_license_key ) {
|
223 |
+
$button_label = fs_text_inline( 'Activate License', 'activate-license', $slug );
|
|
|
|
|
224 |
|
225 |
$message = $fs->apply_filters(
|
226 |
'connect-message_on-premium',
|
229 |
$fs->get_plugin_name()
|
230 |
);
|
231 |
} else {
|
232 |
+
$filter = 'connect_message';
|
|
|
|
|
|
|
233 |
|
234 |
+
if ( ! $fs->is_plugin_update() ) {
|
235 |
+
$default_optin_message = esc_html( sprintf( ( $is_gdpr_required ?
|
236 |
+
/* translators: %s: module type (plugin, theme, or add-on) */
|
237 |
+
fs_text_inline( 'Opt in to get email notifications for security & feature updates, educational content, and occasional offers, and to share some basic WordPress environment info. This will help us make the %s more compatible with your site and better at doing what you need it to.', 'connect-message', $slug ) :
|
238 |
+
/* translators: %s: module type (plugin, theme, or add-on) */
|
239 |
+
fs_text_inline( 'Opt in to get email notifications for security & feature updates, and to share some basic WordPress environment info. This will help us make the %s more compatible with your site and better at doing what you need it to.', 'connect-message', $slug ) ), $fs->get_module_label( true ) ) );
|
240 |
+
} else {
|
241 |
// If Freemius was added on a plugin update, set different
|
242 |
// opt-in message.
|
|
|
|
|
|
|
243 |
|
244 |
+
/* translators: %s: module type (plugin, theme, or add-on) */
|
245 |
+
$default_optin_message = esc_html( sprintf( fs_text_inline( 'We have introduced this opt-in so you never miss an important update and help us make the %s more compatible with your site and better at doing what you need it to.', 'connect-message_on-update_why' ), $fs->get_module_label( true ) ) );
|
246 |
+
|
247 |
+
$default_optin_message .= '<br><br>' . esc_html( $is_gdpr_required ?
|
248 |
+
fs_text_inline( 'Opt in to get email notifications for security & feature updates, educational content, and occasional offers, and to share some basic WordPress environment info.', 'connect-message_on-update', $slug ) :
|
249 |
+
fs_text_inline( 'Opt in to get email notifications for security & feature updates, and to share some basic WordPress environment info.', 'connect-message_on-update', $slug ) );
|
250 |
+
|
251 |
+
if ( $fs->is_enable_anonymous() ) {
|
252 |
+
$default_optin_message .= ' ' . esc_html( fs_text_inline( 'If you skip this, that\'s okay! %1$s will still work just fine.', 'connect-message_on-update_skip', $slug ) );
|
253 |
+
}
|
254 |
+
|
255 |
+
// If user customized the opt-in message on update, use
|
256 |
// that message. Otherwise, fallback to regular opt-in
|
257 |
+
// custom message if exists.
|
258 |
if ( $fs->has_filter( 'connect_message_on_update' ) ) {
|
259 |
$filter = 'connect_message_on_update';
|
260 |
}
|
262 |
|
263 |
$message = $fs->apply_filters(
|
264 |
$filter,
|
|
|
|
|
|
|
|
|
|
|
265 |
sprintf(
|
266 |
+
$default_optin_message,
|
267 |
'<b>' . esc_html( $fs->get_plugin_name() ) . '</b>',
|
268 |
'<b>' . $current_user->user_login . '</b>',
|
269 |
'<a href="' . $site_url . '" target="_blank" rel="noopener noreferrer">' . $site_url . '</a>',
|
270 |
+
$freemius_link
|
271 |
),
|
272 |
$first_name,
|
273 |
$fs->get_plugin_name(),
|
315 |
* @author Vova Feldman
|
316 |
* @since 2.1.2
|
317 |
*/
|
318 |
+
$fs->do_action( 'connect/after_license_input', $activation_state );
|
319 |
?>
|
320 |
|
321 |
<?php
|
360 |
echo fs_get_template( 'partials/network-activation.php', $vars );
|
361 |
?>
|
362 |
<?php endif ?>
|
363 |
+
|
364 |
+
<?php $fs->do_action( 'connect/after_message', $activation_state ) ?>
|
365 |
</div>
|
366 |
<div class="fs-actions">
|
367 |
+
<?php $fs->do_action( 'connect/before_actions', $activation_state ) ?>
|
368 |
+
|
369 |
<?php if ( $fs->is_enable_anonymous() && ! $is_pending_activation && ( ! $require_license_key || $is_network_upgrade_mode ) ) : ?>
|
370 |
<a id="skip_activation" href="<?php echo fs_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $fs->get_unique_affix() . '_skip_activation' ), $is_network_level_activation ), $fs->get_unique_affix() . '_skip_activation' ) ?>"
|
371 |
class="button button-secondary" tabindex="2"><?php fs_esc_html_echo_x_inline( 'Skip', 'verb', 'skip', $slug ) ?></a>
|
379 |
value="<?php echo $fs->get_unique_affix() ?>_activate_existing">
|
380 |
<?php wp_nonce_field( 'activate_existing_' . $fs->get_public_key() ) ?>
|
381 |
<input type="hidden" name="is_extensions_tracking_allowed" value="1">
|
382 |
+
<input type="hidden" name="is_diagnostic_tracking_allowed" value="1">
|
383 |
<button class="button button-primary" tabindex="1"
|
384 |
type="submit"><?php echo esc_html( $button_label ) ?></button>
|
385 |
</form>
|
390 |
<input type="hidden" name="<?php echo $name ?>" value="<?php echo esc_attr( $value ) ?>">
|
391 |
<?php endforeach ?>
|
392 |
<input type="hidden" name="is_extensions_tracking_allowed" value="1">
|
393 |
+
<input type="hidden" name="is_diagnostic_tracking_allowed" value="1">
|
394 |
<button class="button button-primary" tabindex="1"
|
395 |
type="submit"<?php if ( $require_license_key ) {
|
396 |
echo ' disabled="disabled"';
|
400 |
<?php if ( $require_license_key ) : ?>
|
401 |
<a id="license_issues_link" href="<?php echo $fs->apply_filters( 'known_license_issues_url', 'https://freemius.com/help/documentation/wordpress-sdk/license-activation-issues/' ) ?>" target="_blank"><?php fs_esc_html_echo_inline( 'License issues?', 'license-issues', $slug ) ?></a>
|
402 |
<?php endif ?>
|
403 |
+
|
404 |
+
<?php $fs->do_action( 'connect/after_actions', $activation_state ) ?>
|
405 |
</div><?php
|
406 |
+
$permission_manager = FS_Permission_Manager::instance( $fs );
|
407 |
|
408 |
// Set core permission list items.
|
409 |
$permissions = array();
|
410 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
411 |
// Add newsletter permissions if enabled.
|
412 |
if ( $is_gdpr_required || $fs->is_permission_requested( 'newsletter' ) ) {
|
413 |
+
$permissions[] = $permission_manager->get_newsletter_permission();
|
|
|
|
|
|
|
|
|
|
|
414 |
}
|
415 |
|
416 |
+
$permissions = $permission_manager->get_permissions(
|
417 |
+
$require_license_key,
|
418 |
+
$permissions
|
|
|
|
|
|
|
|
|
|
|
419 |
);
|
420 |
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
if ( ! empty( $permissions ) ) : ?>
|
422 |
<div class="fs-permissions">
|
423 |
+
<?php if ( $require_license_key ) : ?>
|
424 |
+
<a class="fs-trigger wp-core-ui" href="#" tabindex="1" style="color: inherit;"><?php echo sprintf(
|
425 |
+
fs_esc_html_inline( 'For delivery of security & feature updates, and license management, %s needs to', 'license-sync-disclaimer', $slug ) . '<b class="fs-arrow"></b>',
|
426 |
+
sprintf( '<nobr class="button-link" style="color: inherit;">%s</nobr>', $fs->get_plugin_title() )
|
427 |
+
) ?></a>
|
428 |
+
<?php else : ?>
|
429 |
+
<a class="fs-trigger wp-core-ui" href="#" tabindex="1" style="color: inherit;"><?php printf(
|
430 |
+
fs_esc_html_inline( 'This will allow %s to', 'this-will-allow-x', $slug ) . '<b class="fs-arrow"></b>',
|
431 |
+
sprintf( '<nobr class="button-link" style="color: inherit;">%s</nobr>', $fs->get_plugin_title() )
|
432 |
+
) ?></a>
|
433 |
<?php endif ?>
|
434 |
<ul><?php
|
435 |
+
foreach ( $permissions as $permission ) {
|
436 |
+
$permission_manager->render_permission( $permission );
|
437 |
+
}
|
438 |
+
?></ul>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
439 |
</div>
|
440 |
<?php endif ?>
|
441 |
<?php if ( $is_premium_code && $is_freemium ) : ?>
|
451 |
</p>
|
452 |
</div>
|
453 |
<?php endif ?>
|
454 |
+
</div>
|
455 |
<div class="fs-terms">
|
456 |
+
<a class="fs-tooltip-trigger<?php echo is_rtl() ? ' rtl' : '' ?>" href="<?php echo $freemius_site_url ?>" target="_blank" rel="noopener" tabindex="1">Powered by Freemius<?php if ( $require_license_key ) : ?> <span class="fs-tooltip" style="width: 170px"><?php echo $fs->get_text_inline( 'Freemius is our licensing and software updates engine', 'permissions-extensions_desc' ) ?></span><?php endif ?></a>
|
457 |
+
-
|
458 |
<a href="https://freemius.com/privacy/" target="_blank" rel="noopener"
|
459 |
tabindex="1"><?php fs_esc_html_echo_inline( 'Privacy Policy', 'privacy-policy', $slug ) ?></a>
|
460 |
-
|
468 |
* @author Vova Feldman
|
469 |
* @since 2.3.2
|
470 |
*/
|
471 |
+
$fs->do_action( 'connect/after', $activation_state );
|
472 |
|
473 |
if ( $is_optin_dialog ) { ?>
|
474 |
</div>
|
522 |
// Reset loading mode.
|
523 |
$primaryCta.html(primaryCtaLabel);
|
524 |
$primaryCta.prop('disabled', false);
|
525 |
+
$( '.fs-loading' ).removeClass( 'fs-loading' );
|
|
|
526 |
|
527 |
console.log('resetLoadingMode - Primary button was enabled');
|
528 |
},
|
529 |
setLoadingMode = function () {
|
530 |
+
$( document.body ).addClass( 'fs-loading' );
|
531 |
};
|
532 |
|
533 |
$('.fs-actions .button').on('click', function () {
|
591 |
updatePrimaryCtaText( actionType );
|
592 |
});
|
593 |
|
594 |
+
$sitesListContainer.delegate( 'td:not(:first-child)', 'click', function() {
|
595 |
+
// If a site row is clicked, trigger a click on the checkbox.
|
596 |
+
$( this ).parent().find( 'td:first-child input' ).click();
|
597 |
+
} );
|
598 |
+
|
599 |
$sitesListContainer.delegate( '.action', 'click', function( evt ) {
|
600 |
var $this = $( evt.target );
|
601 |
if ( $this.hasClass( 'selected' ) ) {
|
702 |
var ajaxOptin = ( requireLicenseKey || isNetworkActive );
|
703 |
|
704 |
$form.on('submit', function () {
|
705 |
+
var $extensionsPermission = $( '#fs_permission_extensions .fs-switch' ),
|
706 |
+
isExtensionsTrackingAllowed = ( $extensionsPermission.length > 0 ) ?
|
707 |
+
$extensionsPermission.hasClass( 'fs-on' ) :
|
708 |
null;
|
709 |
|
710 |
+
var $diagnosticPermission = $( '#fs_permission_diagnostic .fs-switch' ),
|
711 |
+
isDiagnosticTrackingAllowed = ( $diagnosticPermission.length > 0 ) ?
|
712 |
+
$diagnosticPermission.hasClass( 'fs-on' ) :
|
713 |
+
null;
|
714 |
+
|
715 |
+
if ( null === isExtensionsTrackingAllowed ) {
|
716 |
+
$( 'input[name=is_extensions_tracking_allowed]' ).remove();
|
717 |
} else {
|
718 |
+
$( 'input[name=is_extensions_tracking_allowed]' ).val( isExtensionsTrackingAllowed ? 1 : 0 );
|
719 |
+
}
|
720 |
+
|
721 |
+
// We are not showing switch to enable/disable diagnostic tracking while activating free version. So, don't remove hidden `is_diagnostic_tracking_allowed` element from DOM and change the value only if switch is available.
|
722 |
+
if ( null !== isDiagnosticTrackingAllowed ) {
|
723 |
+
$( 'input[name=is_diagnostic_tracking_allowed]' ).val( isDiagnosticTrackingAllowed ? 1 : 0 );
|
724 |
}
|
725 |
|
726 |
/**
|
777 |
data.is_marketing_allowed = isMarketingAllowed;
|
778 |
|
779 |
data.is_extensions_tracking_allowed = isExtensionsTrackingAllowed;
|
780 |
+
|
781 |
+
data.is_diagnostic_tracking_allowed = isDiagnosticTrackingAllowed;
|
782 |
}
|
783 |
|
784 |
$marketingOptin.removeClass( 'error' );
|
801 |
url : $this.find( '.url' ).val(),
|
802 |
title : $this.find( '.title' ).val(),
|
803 |
language: $this.find( '.language' ).val(),
|
|
|
804 |
blog_id : $this.find( '.blog-id' ).find( 'span' ).text()
|
805 |
};
|
806 |
|
828 |
* @since 1.2.1.5
|
829 |
*/
|
830 |
$.ajax({
|
831 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
832 |
method : 'POST',
|
833 |
data : data,
|
834 |
success: function (result) {
|
864 |
return true;
|
865 |
});
|
866 |
|
867 |
+
$( '#fs_connect .fs-permissions .fs-switch' ).on( 'click', function () {
|
868 |
+
$( this )
|
869 |
+
.toggleClass( 'fs-on' )
|
870 |
+
.toggleClass( 'fs-off' );
|
871 |
+
|
872 |
+
$( this ).closest( '.fs-permission' )
|
873 |
+
.toggleClass( 'fs-disabled' );
|
874 |
+
});
|
875 |
+
|
876 |
$primaryCta.on('click', function () {
|
877 |
console.log('Primary button was clicked');
|
878 |
|
889 |
return false;
|
890 |
});
|
891 |
|
|
|
|
|
|
|
|
|
|
|
|
|
892 |
if (requireLicenseKey) {
|
893 |
/**
|
894 |
* Submit license key on enter.
|
1014 |
$primaryCta.html('<?php fs_esc_js_echo_inline( 'Please wait', 'please-wait', $slug ) ?>...');
|
1015 |
|
1016 |
$.ajax({
|
1017 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
1018 |
method : 'POST',
|
1019 |
data : {
|
1020 |
action : '<?php echo $fs->get_ajax_action( 'fetch_is_marketing_required_flag_value' ) ?>',
|
1044 |
|
1045 |
//endregion
|
1046 |
})(jQuery);
|
1047 |
+
</script>
|
freemius/templates/connect/index.php
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
3 |
+
// Hide file structure from users on unprotected servers.
|
freemius/templates/connect/permission.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2022, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 2.5.1
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
* @var array $permission {
|
16 |
+
* @type string $id
|
17 |
+
* @type bool $default
|
18 |
+
* @type string $icon-class
|
19 |
+
* @type bool $optional
|
20 |
+
* @type string $label
|
21 |
+
* @type string $tooltip
|
22 |
+
* @type string $desc
|
23 |
+
* }
|
24 |
+
*/
|
25 |
+
$permission = $VARS;
|
26 |
+
|
27 |
+
$is_permission_on = ( ! isset( $permission['default'] ) || true === $permission['default'] );
|
28 |
+
?>
|
29 |
+
<li id="fs_permission_<?php echo esc_attr( $permission['id'] ) ?>" data-permission-id="<?php echo esc_attr( $permission['id'] ) ?>"
|
30 |
+
class="fs-permission fs-<?php echo esc_attr( $permission['id'] ); ?><?php echo ( ! $is_permission_on ) ? ' fs-disabled' : ''; ?>">
|
31 |
+
<i class="<?php echo esc_attr( $permission['icon-class'] ); ?>"></i>
|
32 |
+
<?php if ( isset( $permission['optional'] ) && true === $permission['optional'] ) : ?>
|
33 |
+
<div class="fs-switch fs-small fs-round fs-<?php echo $is_permission_on ? 'on' : 'off' ?>">
|
34 |
+
<div class="fs-toggle"></div>
|
35 |
+
</div>
|
36 |
+
<?php endif ?>
|
37 |
+
|
38 |
+
<div class="fs-permission-description">
|
39 |
+
<span<?php if ( ! empty( $permission['tooltip'] ) ) : ?> class="fs-tooltip-trigger"<?php endif ?>><?php echo esc_html( $permission['label'] ); ?><?php if ( ! empty( $permission['tooltip'] ) ) : ?><i class="dashicons dashicons-editor-help"><span class="fs-tooltip" style="width: 200px"><?php echo esc_html( $permission['tooltip'] ) ?></span></i><?php endif ?></span>
|
40 |
+
|
41 |
+
<p><?php echo esc_html( $permission['desc'] ); ?></p>
|
42 |
+
</div>
|
43 |
+
</li>
|
freemius/templates/connect/permissions-group.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2022, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 2.5.1
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
*
|
16 |
+
* @var array $permission_group {
|
17 |
+
* @type Freemius $fs
|
18 |
+
* @type string $id
|
19 |
+
* @type string $desc
|
20 |
+
* @type array $prompt
|
21 |
+
* @type array $permissions
|
22 |
+
* @type bool $is_enabled
|
23 |
+
* }
|
24 |
+
*/
|
25 |
+
$permission_group = $VARS;
|
26 |
+
|
27 |
+
$fs = $permission_group[ 'fs' ];
|
28 |
+
|
29 |
+
$permission_manager = FS_Permission_Manager::instance( $fs );
|
30 |
+
|
31 |
+
$opt_out_text = $fs->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 |
+
<div class="fs-permissions-section fs-<?php echo esc_attr( $permission_group[ 'id' ] ) ?>-permissions">
|
49 |
+
<div>
|
50 |
+
<div class="fs-permissions-section--header">
|
51 |
+
<a class="fs-group-opt-out-button"
|
52 |
+
data-type="<?php echo esc_attr( $permission_group['type'] ) ?>"
|
53 |
+
data-group-id="<?php echo esc_attr( $permission_group[ 'id' ] ) ?>"
|
54 |
+
data-is-enabled="<?php echo $is_enabled ? 'true' : 'false' ?>"
|
55 |
+
href="#"><?php echo esc_html( $is_enabled ? $opt_out_text : $opt_in_text ) ?></a>
|
56 |
+
<span class="fs-permissions-section--header-title"><?php
|
57 |
+
// The title is already HTML-escaped.
|
58 |
+
echo $permission_group[ 'title' ]
|
59 |
+
?></span>
|
60 |
+
</div>
|
61 |
+
<p class="fs-permissions-section--desc"><?php
|
62 |
+
// The description is already HTML-escaped.
|
63 |
+
echo $permission_group['desc']
|
64 |
+
?></p></div>
|
65 |
+
<ul>
|
66 |
+
<?php
|
67 |
+
foreach ( $permission_group['permissions'] as $permission ) {
|
68 |
+
$permission_manager->render_permission( $permission );
|
69 |
+
}
|
70 |
+
?>
|
71 |
+
</ul>
|
72 |
+
</div>
|
freemius/templates/contact.php
CHANGED
@@ -69,7 +69,7 @@
|
|
69 |
$query_params = array_merge( $_GET, array_merge( $context_params, array(
|
70 |
'plugin_version' => $fs->get_plugin_version(),
|
71 |
'wp_login_url' => wp_login_url(),
|
72 |
-
'site_url' =>
|
73 |
// 'wp_admin_css' => get_bloginfo('wpurl') . "/wp-admin/load-styles.php?c=1&load=buttons,wp-admin,dashicons",
|
74 |
) ) );
|
75 |
|
69 |
$query_params = array_merge( $_GET, array_merge( $context_params, array(
|
70 |
'plugin_version' => $fs->get_plugin_version(),
|
71 |
'wp_login_url' => wp_login_url(),
|
72 |
+
'site_url' => Freemius::get_unfiltered_site_url(),
|
73 |
// 'wp_admin_css' => get_bloginfo('wpurl') . "/wp-admin/load-styles.php?c=1&load=buttons,wp-admin,dashicons",
|
74 |
) ) );
|
75 |
|
freemius/templates/debug.php
CHANGED
@@ -16,6 +16,10 @@
|
|
16 |
|
17 |
$off_text = fs_text_x_inline( 'Off', 'as turned off' );
|
18 |
$on_text = fs_text_x_inline( 'On', 'as turned on' );
|
|
|
|
|
|
|
|
|
19 |
?>
|
20 |
<h1><?php echo fs_text_inline( 'Freemius Debug' ) . ' - ' . fs_text_inline( 'SDK' ) . ' v.' . $fs_active_plugins->newest->version ?></h1>
|
21 |
<div>
|
@@ -35,7 +39,7 @@
|
|
35 |
.toggleClass( 'fs-on' )
|
36 |
.toggleClass( 'fs-off' );
|
37 |
|
38 |
-
$.post(
|
39 |
action: 'fs_toggle_debug_mode',
|
40 |
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
41 |
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_toggle_debug_mode' ) ); ?>,
|
@@ -79,6 +83,16 @@
|
|
79 |
<button class="button"><?php fs_esc_html_echo_inline( 'Clear Updates Transients' ) ?></button>
|
80 |
</form>
|
81 |
</td>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
<td>
|
83 |
<!-- Sync Data with Server -->
|
84 |
<form action="" method="POST">
|
@@ -102,6 +116,15 @@
|
|
102 |
<td>
|
103 |
<button id="fs_set_db_option" class="button"><?php fs_esc_html_echo_inline( 'Set DB Option' ) ?></button>
|
104 |
</td>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
</tr>
|
106 |
</tbody>
|
107 |
</table>
|
@@ -111,7 +134,7 @@
|
|
111 |
var optionName = prompt('Please enter the option name:');
|
112 |
|
113 |
if (optionName) {
|
114 |
-
$.post(
|
115 |
action : 'fs_get_db_option',
|
116 |
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
117 |
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_get_db_option' ) ); ?>,
|
@@ -132,7 +155,7 @@
|
|
132 |
var optionValue = prompt('Please enter the option value:');
|
133 |
|
134 |
if (optionValue) {
|
135 |
-
$.post(
|
136 |
action : 'fs_set_db_option',
|
137 |
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
138 |
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_set_db_option' ) ); ?>,
|
@@ -175,6 +198,10 @@
|
|
175 |
'key' => 'WP_FS__DIR',
|
176 |
'val' => WP_FS__DIR,
|
177 |
),
|
|
|
|
|
|
|
|
|
178 |
)
|
179 |
?>
|
180 |
<br>
|
@@ -229,7 +256,7 @@
|
|
229 |
WP_FS__MODULE_TYPE_THEME
|
230 |
);
|
231 |
?>
|
232 |
-
|
233 |
<?php foreach ( $module_types as $module_type ) : ?>
|
234 |
<?php $modules = fs_get_entities( $fs_options->get_option( $module_type . 's' ), FS_Plugin::get_class_name() ) ?>
|
235 |
<?php if ( is_array( $modules ) && count( $modules ) > 0 ) : ?>
|
@@ -245,7 +272,7 @@
|
|
245 |
<th><?php fs_esc_html_echo_inline( 'Freemius State' ) ?></th>
|
246 |
<th><?php fs_esc_html_echo_inline( 'Module Path' ) ?></th>
|
247 |
<th><?php fs_esc_html_echo_inline( 'Public Key' ) ?></th>
|
248 |
-
<?php if ( is_multisite
|
249 |
<th><?php fs_esc_html_echo_inline( 'Network Blog' ) ?></th>
|
250 |
<th><?php fs_esc_html_echo_inline( 'Network User' ) ?></th>
|
251 |
<?php endif ?>
|
@@ -268,7 +295,14 @@
|
|
268 |
}
|
269 |
}
|
270 |
?>
|
271 |
-
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
<tr<?php if ( $is_active ) {
|
273 |
if ( $fs->has_api_connectivity() && $fs->is_on() ) {
|
274 |
echo ' style="background: #E6FFE6; font-weight: bold"';
|
@@ -298,7 +332,7 @@
|
|
298 |
} ?></td>
|
299 |
<td><?php echo $data->file ?></td>
|
300 |
<td><?php echo $data->public_key ?></td>
|
301 |
-
<?php if ( is_multisite
|
302 |
<?php
|
303 |
$network_blog_id = null;
|
304 |
$network_user = null;
|
@@ -352,8 +386,7 @@
|
|
352 |
*/
|
353 |
$sites_map = $VARS[ $module_type . '_sites' ];
|
354 |
|
355 |
-
$
|
356 |
-
$all_plans = false;
|
357 |
?>
|
358 |
<?php if ( is_array( $sites_map ) && count( $sites_map ) > 0 ) : ?>
|
359 |
<h2><?php echo esc_html( sprintf(
|
@@ -379,15 +412,37 @@
|
|
379 |
</tr>
|
380 |
</thead>
|
381 |
<tbody>
|
|
|
382 |
<?php foreach ( $sites_map as $slug => $sites ) : ?>
|
383 |
-
<?php if ( ! is_array( $sites ) ) {
|
384 |
-
$sites = array( $sites );
|
385 |
-
} ?>
|
386 |
<?php foreach ( $sites as $site ) : ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
387 |
<tr>
|
388 |
-
<td
|
|
|
|
|
|
|
|
|
|
|
389 |
<?php if ( $is_multisite ) : ?>
|
390 |
-
<td><?php echo $
|
391 |
<td><?php echo fs_strip_url_protocol( $site->url ) ?></td>
|
392 |
<?php endif ?>
|
393 |
<td><?php echo $slug ?></td>
|
@@ -484,8 +539,15 @@
|
|
484 |
* @var FS_User[] $users
|
485 |
*/
|
486 |
$users = $VARS['users'];
|
|
|
487 |
$users_with_developer_license_by_id = array();
|
488 |
|
|
|
|
|
|
|
|
|
|
|
|
|
489 |
foreach ( $module_types as $module_type ) {
|
490 |
/**
|
491 |
* @var FS_Plugin_License[] $licenses
|
@@ -578,7 +640,7 @@
|
|
578 |
<td><?php echo $license->is_block_features ? 'Blocking' : 'Flexible' ?></td>
|
579 |
<td><?php echo $license->is_whitelabeled ? 'Whitelabeled' : 'Normal' ?></td>
|
580 |
<td><?php
|
581 |
-
echo $license->is_whitelabeled ?
|
582 |
$license->get_html_escaped_masked_secret_key() :
|
583 |
esc_html( $license->secret_key );
|
584 |
?></td>
|
@@ -726,7 +788,7 @@
|
|
726 |
offset = 0;
|
727 |
}
|
728 |
|
729 |
-
$.post(
|
730 |
action : 'fs_get_debug_log',
|
731 |
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
732 |
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_get_debug_log' ) ); ?>,
|
16 |
|
17 |
$off_text = fs_text_x_inline( 'Off', 'as turned off' );
|
18 |
$on_text = fs_text_x_inline( 'On', 'as turned on' );
|
19 |
+
|
20 |
+
$has_any_active_clone = false;
|
21 |
+
|
22 |
+
$is_multisite = is_multisite();
|
23 |
?>
|
24 |
<h1><?php echo fs_text_inline( 'Freemius Debug' ) . ' - ' . fs_text_inline( 'SDK' ) . ' v.' . $fs_active_plugins->newest->version ?></h1>
|
25 |
<div>
|
39 |
.toggleClass( 'fs-on' )
|
40 |
.toggleClass( 'fs-off' );
|
41 |
|
42 |
+
$.post( <?php echo Freemius::ajax_url() ?>, {
|
43 |
action: 'fs_toggle_debug_mode',
|
44 |
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
45 |
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_toggle_debug_mode' ) ); ?>,
|
83 |
<button class="button"><?php fs_esc_html_echo_inline( 'Clear Updates Transients' ) ?></button>
|
84 |
</form>
|
85 |
</td>
|
86 |
+
<?php if ( Freemius::is_deactivation_snoozed() ) : ?>
|
87 |
+
<td>
|
88 |
+
<!-- Reset Deactivation Snoozing -->
|
89 |
+
<form action="" method="POST">
|
90 |
+
<input type="hidden" name="fs_action" value="reset_deactivation_snoozing">
|
91 |
+
<?php wp_nonce_field( 'reset_deactivation_snoozing' ) ?>
|
92 |
+
<button class="button"><?php fs_esc_html_echo_inline( 'Reset Deactivation Snoozing' ) ?> (Expires in <?php echo ( Freemius::deactivation_snooze_expires_at() - time() ) ?> sec)</button>
|
93 |
+
</form>
|
94 |
+
</td>
|
95 |
+
<?php endif ?>
|
96 |
<td>
|
97 |
<!-- Sync Data with Server -->
|
98 |
<form action="" method="POST">
|
116 |
<td>
|
117 |
<button id="fs_set_db_option" class="button"><?php fs_esc_html_echo_inline( 'Set DB Option' ) ?></button>
|
118 |
</td>
|
119 |
+
<td>
|
120 |
+
<?php
|
121 |
+
$fs_debug_page_url = 'admin.php?page=freemius&fs_action=allow_clone_resolution_notice';
|
122 |
+
$fs_debug_page_url = fs_is_network_admin() ?
|
123 |
+
network_admin_url( $fs_debug_page_url ) :
|
124 |
+
admin_url( $fs_debug_page_url );
|
125 |
+
?>
|
126 |
+
<a href="<?php echo wp_nonce_url( $fs_debug_page_url, 'fs_allow_clone_resolution_notice' ) ?>" class="button button-primary">Resolve Clone(s)</a>
|
127 |
+
</td>
|
128 |
</tr>
|
129 |
</tbody>
|
130 |
</table>
|
134 |
var optionName = prompt('Please enter the option name:');
|
135 |
|
136 |
if (optionName) {
|
137 |
+
$.post(<?php echo Freemius::ajax_url() ?>, {
|
138 |
action : 'fs_get_db_option',
|
139 |
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
140 |
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_get_db_option' ) ); ?>,
|
155 |
var optionValue = prompt('Please enter the option value:');
|
156 |
|
157 |
if (optionValue) {
|
158 |
+
$.post(<?php echo Freemius::ajax_url() ?>, {
|
159 |
action : 'fs_set_db_option',
|
160 |
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
161 |
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_set_db_option' ) ); ?>,
|
198 |
'key' => 'WP_FS__DIR',
|
199 |
'val' => WP_FS__DIR,
|
200 |
),
|
201 |
+
array(
|
202 |
+
'key' => 'wp_using_ext_object_cache()',
|
203 |
+
'val' => wp_using_ext_object_cache() ? 'true' : 'false',
|
204 |
+
),
|
205 |
)
|
206 |
?>
|
207 |
<br>
|
256 |
WP_FS__MODULE_TYPE_THEME
|
257 |
);
|
258 |
?>
|
259 |
+
<?php $active_modules_by_id = array() ?>
|
260 |
<?php foreach ( $module_types as $module_type ) : ?>
|
261 |
<?php $modules = fs_get_entities( $fs_options->get_option( $module_type . 's' ), FS_Plugin::get_class_name() ) ?>
|
262 |
<?php if ( is_array( $modules ) && count( $modules ) > 0 ) : ?>
|
272 |
<th><?php fs_esc_html_echo_inline( 'Freemius State' ) ?></th>
|
273 |
<th><?php fs_esc_html_echo_inline( 'Module Path' ) ?></th>
|
274 |
<th><?php fs_esc_html_echo_inline( 'Public Key' ) ?></th>
|
275 |
+
<?php if ( $is_multisite ) : ?>
|
276 |
<th><?php fs_esc_html_echo_inline( 'Network Blog' ) ?></th>
|
277 |
<th><?php fs_esc_html_echo_inline( 'Network User' ) ?></th>
|
278 |
<?php endif ?>
|
295 |
}
|
296 |
}
|
297 |
?>
|
298 |
+
<?php
|
299 |
+
$fs = null;
|
300 |
+
if ( $is_active ) {
|
301 |
+
$fs = freemius( $data->id );
|
302 |
+
|
303 |
+
$active_modules_by_id[ $data->id ] = true;
|
304 |
+
}
|
305 |
+
?>
|
306 |
<tr<?php if ( $is_active ) {
|
307 |
if ( $fs->has_api_connectivity() && $fs->is_on() ) {
|
308 |
echo ' style="background: #E6FFE6; font-weight: bold"';
|
332 |
} ?></td>
|
333 |
<td><?php echo $data->file ?></td>
|
334 |
<td><?php echo $data->public_key ?></td>
|
335 |
+
<?php if ( $is_multisite ) : ?>
|
336 |
<?php
|
337 |
$network_blog_id = null;
|
338 |
$network_user = null;
|
386 |
*/
|
387 |
$sites_map = $VARS[ $module_type . '_sites' ];
|
388 |
|
389 |
+
$all_plans = false;
|
|
|
390 |
?>
|
391 |
<?php if ( is_array( $sites_map ) && count( $sites_map ) > 0 ) : ?>
|
392 |
<h2><?php echo esc_html( sprintf(
|
412 |
</tr>
|
413 |
</thead>
|
414 |
<tbody>
|
415 |
+
<?php $site_url = null ?>
|
416 |
<?php foreach ( $sites_map as $slug => $sites ) : ?>
|
|
|
|
|
|
|
417 |
<?php foreach ( $sites as $site ) : ?>
|
418 |
+
<?php
|
419 |
+
$blog_id = $is_multisite ?
|
420 |
+
$site->blog_id :
|
421 |
+
null;
|
422 |
+
|
423 |
+
if ( is_null( $site_url ) || $is_multisite ) {
|
424 |
+
$site_url = Freemius::get_unfiltered_site_url(
|
425 |
+
$blog_id,
|
426 |
+
true,
|
427 |
+
true
|
428 |
+
);
|
429 |
+
}
|
430 |
+
|
431 |
+
$is_active_clone = ( $site->is_clone( $site_url ) && isset( $active_modules_by_id[ $site->plugin_id ] ) );
|
432 |
+
|
433 |
+
if ( $is_active_clone ) {
|
434 |
+
$has_any_active_clone = true;
|
435 |
+
}
|
436 |
+
?>
|
437 |
<tr>
|
438 |
+
<td>
|
439 |
+
<?php echo $site->id ?>
|
440 |
+
<?php if ( $is_active_clone ) : ?>
|
441 |
+
<label class="fs-tag fs-warn">Clone</label>
|
442 |
+
<?php endif ?>
|
443 |
+
</td>
|
444 |
<?php if ( $is_multisite ) : ?>
|
445 |
+
<td><?php echo $blog_id ?></td>
|
446 |
<td><?php echo fs_strip_url_protocol( $site->url ) ?></td>
|
447 |
<?php endif ?>
|
448 |
<td><?php echo $slug ?></td>
|
539 |
* @var FS_User[] $users
|
540 |
*/
|
541 |
$users = $VARS['users'];
|
542 |
+
$user_ids_map = array();
|
543 |
$users_with_developer_license_by_id = array();
|
544 |
|
545 |
+
if ( is_array( $users ) && ! empty( $users ) ) {
|
546 |
+
foreach ( $users as $user ) {
|
547 |
+
$user_ids_map[ $user->id ] = true;
|
548 |
+
}
|
549 |
+
}
|
550 |
+
|
551 |
foreach ( $module_types as $module_type ) {
|
552 |
/**
|
553 |
* @var FS_Plugin_License[] $licenses
|
640 |
<td><?php echo $license->is_block_features ? 'Blocking' : 'Flexible' ?></td>
|
641 |
<td><?php echo $license->is_whitelabeled ? 'Whitelabeled' : 'Normal' ?></td>
|
642 |
<td><?php
|
643 |
+
echo ( $license->is_whitelabeled || ! isset( $user_ids_map[ $license->user_id ] ) ) ?
|
644 |
$license->get_html_escaped_masked_secret_key() :
|
645 |
esc_html( $license->secret_key );
|
646 |
?></td>
|
788 |
offset = 0;
|
789 |
}
|
790 |
|
791 |
+
$.post(<?php echo Freemius::ajax_url() ?>, {
|
792 |
action : 'fs_get_debug_log',
|
793 |
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
794 |
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_get_debug_log' ) ); ?>,
|
freemius/templates/firewall-issues-js.php
CHANGED
@@ -48,8 +48,7 @@
|
|
48 |
|
49 |
$( this ).css({'cursor': 'wait'});
|
50 |
|
51 |
-
|
52 |
-
$.post( ajaxurl, data, function( response ) {
|
53 |
if ( 1 == response ) {
|
54 |
// Refresh page on success.
|
55 |
location.reload();
|
48 |
|
49 |
$( this ).css({'cursor': 'wait'});
|
50 |
|
51 |
+
$.post( <?php echo Freemius::ajax_url() ?>, data, function( response ) {
|
|
|
52 |
if ( 1 == response ) {
|
53 |
// Refresh page on success.
|
54 |
location.reload();
|
freemius/templates/forms/affiliation.php
CHANGED
@@ -13,8 +13,10 @@
|
|
13 |
/**
|
14 |
* @var array $VARS
|
15 |
* @var Freemius $fs
|
|
|
16 |
*/
|
17 |
-
$fs
|
|
|
18 |
|
19 |
$slug = $fs->get_slug();
|
20 |
|
@@ -22,7 +24,6 @@
|
|
22 |
$affiliate = $fs->get_affiliate();
|
23 |
$affiliate_terms = $fs->get_affiliate_terms();
|
24 |
|
25 |
-
$plugin_title = $fs->get_plugin_title();
|
26 |
$module_type = $fs->is_plugin() ?
|
27 |
WP_FS__MODULE_TYPE_PLUGIN :
|
28 |
WP_FS__MODULE_TYPE_THEME;
|
@@ -45,7 +46,7 @@
|
|
45 |
$promotion_method_mobile_apps = false;
|
46 |
$statistics_information = false;
|
47 |
$promotion_method_description = false;
|
48 |
-
$members_dashboard_login_url = 'https://
|
49 |
|
50 |
$affiliate_application_data = $fs->get_affiliate_application_data();
|
51 |
|
@@ -71,7 +72,7 @@
|
|
71 |
$current_user = Freemius::_get_current_wp_user();
|
72 |
$full_name = trim( $current_user->user_firstname . ' ' . $current_user->user_lastname );
|
73 |
$email_address = $current_user->user_email;
|
74 |
-
$domain =
|
75 |
}
|
76 |
|
77 |
$affiliate_tracking = 30;
|
@@ -365,7 +366,7 @@
|
|
365 |
}
|
366 |
|
367 |
$.ajax({
|
368 |
-
url :
|
369 |
method : 'POST',
|
370 |
data : {
|
371 |
action : '<?php echo $fs->get_ajax_action( 'submit_affiliate_application' ) ?>',
|
@@ -506,4 +507,3 @@
|
|
506 |
'module_version' => $fs->get_plugin_version(),
|
507 |
);
|
508 |
fs_require_template( 'powered-by.php', $params );
|
509 |
-
?>
|
13 |
/**
|
14 |
* @var array $VARS
|
15 |
* @var Freemius $fs
|
16 |
+
* @var string $plugin_title
|
17 |
*/
|
18 |
+
$fs = freemius( $VARS['id'] );
|
19 |
+
$plugin_title = $VARS['plugin_title'];
|
20 |
|
21 |
$slug = $fs->get_slug();
|
22 |
|
24 |
$affiliate = $fs->get_affiliate();
|
25 |
$affiliate_terms = $fs->get_affiliate_terms();
|
26 |
|
|
|
27 |
$module_type = $fs->is_plugin() ?
|
28 |
WP_FS__MODULE_TYPE_PLUGIN :
|
29 |
WP_FS__MODULE_TYPE_THEME;
|
46 |
$promotion_method_mobile_apps = false;
|
47 |
$statistics_information = false;
|
48 |
$promotion_method_description = false;
|
49 |
+
$members_dashboard_login_url = 'https://users.freemius.com/login';
|
50 |
|
51 |
$affiliate_application_data = $fs->get_affiliate_application_data();
|
52 |
|
72 |
$current_user = Freemius::_get_current_wp_user();
|
73 |
$full_name = trim( $current_user->user_firstname . ' ' . $current_user->user_lastname );
|
74 |
$email_address = $current_user->user_email;
|
75 |
+
$domain = Freemius::get_unfiltered_site_url( null, true );
|
76 |
}
|
77 |
|
78 |
$affiliate_tracking = 30;
|
366 |
}
|
367 |
|
368 |
$.ajax({
|
369 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
370 |
method : 'POST',
|
371 |
data : {
|
372 |
action : '<?php echo $fs->get_ajax_action( 'submit_affiliate_application' ) ?>',
|
507 |
'module_version' => $fs->get_plugin_version(),
|
508 |
);
|
509 |
fs_require_template( 'powered-by.php', $params );
|
|
freemius/templates/forms/data-debug-mode.php
CHANGED
@@ -140,7 +140,7 @@ HTML;
|
|
140 |
};
|
141 |
|
142 |
$.ajax( {
|
143 |
-
url :
|
144 |
method : 'POST',
|
145 |
data : data,
|
146 |
beforeSend: function () {
|
140 |
};
|
141 |
|
142 |
$.ajax( {
|
143 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
144 |
method : 'POST',
|
145 |
data : data,
|
146 |
beforeSend: function () {
|
freemius/templates/forms/deactivation/form.php
CHANGED
@@ -24,6 +24,7 @@
|
|
24 |
$anonymous_feedback_checkbox_html = '';
|
25 |
|
26 |
$reasons_list_items_html = '';
|
|
|
27 |
|
28 |
if ( $show_deactivation_feedback_form ) {
|
29 |
$reasons = $VARS['reasons'];
|
@@ -64,6 +65,41 @@ HTML;
|
|
64 |
fs_esc_html_inline( 'Anonymous feedback', 'anonymous-feedback', $slug )
|
65 |
);
|
66 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
}
|
68 |
|
69 |
// Aliases.
|
@@ -71,6 +107,13 @@ HTML;
|
|
71 |
$theme_text = fs_text_inline( 'Theme', 'theme', $slug );
|
72 |
$activate_x_text = fs_text_inline( 'Activate %s', 'activate-x', $slug );
|
73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
75 |
|
76 |
if ( ! empty( $subscription_cancellation_dialog_box_template_params ) ) {
|
@@ -92,6 +135,7 @@ HTML;
|
|
92 |
+ ' </div>'
|
93 |
+ ' <div class="fs-modal-footer">'
|
94 |
+ ' <?php echo $anonymous_feedback_checkbox_html ?>'
|
|
|
95 |
+ ' <a href="#" class="button button-secondary button-deactivate"></a>'
|
96 |
+ ' <a href="#" class="button button-secondary button-close"><?php fs_esc_js_echo_inline( 'Cancel', 'cancel', $slug ) ?></a>'
|
97 |
+ ' </div>'
|
@@ -101,6 +145,7 @@ HTML;
|
|
101 |
selectedReasonID = false,
|
102 |
redirectLink = '',
|
103 |
$anonymousFeedback = $modal.find( '.anonymous-feedback-label' ),
|
|
|
104 |
isAnonymous = <?php echo ( $is_anonymous ? 'true' : 'false' ); ?>,
|
105 |
otherReasonID = <?php echo Freemius::REASON_OTHER; ?>,
|
106 |
dontShareDataReasonID = <?php echo Freemius::REASON_DONT_LIKE_TO_SHARE_MY_INFORMATION; ?>,
|
@@ -135,7 +180,7 @@ HTML;
|
|
135 |
?>
|
136 |
|
137 |
$.ajax({
|
138 |
-
url :
|
139 |
method : 'POST',
|
140 |
data : {
|
141 |
action : '<?php echo $fs->get_ajax_action( 'cancel_subscription_or_trial' ) ?>',
|
@@ -230,10 +275,6 @@ HTML;
|
|
230 |
} ?>
|
231 |
|
232 |
$modal.on('input propertychange', '.reason-input input', function () {
|
233 |
-
if (!isOtherReasonSelected()) {
|
234 |
-
return;
|
235 |
-
}
|
236 |
-
|
237 |
var reason = $(this).val().trim();
|
238 |
|
239 |
/**
|
@@ -241,9 +282,12 @@ HTML;
|
|
241 |
* to change the message color back to default.
|
242 |
*/
|
243 |
if (reason.length > 0) {
|
244 |
-
|
245 |
-
|
246 |
-
|
|
|
|
|
|
|
247 |
});
|
248 |
|
249 |
$modal.on('blur', '.reason-input input', function () {
|
@@ -260,8 +304,8 @@ HTML;
|
|
260 |
*/
|
261 |
if (0 === $userReason.val().trim().length) {
|
262 |
$('.message').addClass('error-message');
|
263 |
-
|
264 |
-
|
265 |
}, 150);
|
266 |
});
|
267 |
|
@@ -276,15 +320,34 @@ HTML;
|
|
276 |
var _this = $(this);
|
277 |
|
278 |
if (_this.hasClass('allow-deactivate')) {
|
279 |
-
var
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
280 |
|
281 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
282 |
if ( ! deleteThemeUpdateData ) {
|
283 |
// If no selected reason, just deactivate the plugin.
|
284 |
window.location.href = redirectLink;
|
285 |
} else {
|
286 |
$.ajax({
|
287 |
-
url :
|
288 |
method : 'POST',
|
289 |
data : {
|
290 |
action : '<?php echo $fs->get_ajax_action( 'delete_theme_update_data' ) ?>',
|
@@ -292,8 +355,7 @@ HTML;
|
|
292 |
module_id: '<?php echo $fs->get_id() ?>'
|
293 |
},
|
294 |
beforeSend: function() {
|
295 |
-
_parent.find( '.fs-modal-footer .button' ).
|
296 |
-
_parent.find( '.fs-modal-footer .button-secondary' ).text( 'Processing...' );
|
297 |
},
|
298 |
complete : function() {
|
299 |
window.location.href = redirectLink;
|
@@ -304,28 +366,27 @@ HTML;
|
|
304 |
return;
|
305 |
}
|
306 |
|
307 |
-
|
308 |
-
|
309 |
-
userReason = ( 0 !== $input.length ) ? $input.val().trim() : '';
|
310 |
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
|
315 |
$.ajax({
|
316 |
-
url :
|
317 |
method : 'POST',
|
318 |
data : {
|
319 |
-
action
|
320 |
-
security
|
321 |
-
module_id
|
322 |
-
reason_id
|
323 |
-
reason_info
|
324 |
-
is_anonymous: isAnonymousFeedback()
|
|
|
325 |
},
|
326 |
beforeSend: function () {
|
327 |
-
_parent.find('.fs-modal-footer .button').
|
328 |
-
_parent.find('.fs-modal-footer .button-secondary').text('Processing...');
|
329 |
},
|
330 |
complete : function () {
|
331 |
// Do not show the dialog box, deactivate the plugin.
|
@@ -365,20 +426,17 @@ HTML;
|
|
365 |
|
366 |
$modal.find('.reason-input').remove();
|
367 |
$modal.find( '.internal-message' ).hide();
|
368 |
-
$modal.find('.button-deactivate').html('<?php echo esc_js(
|
369 |
-
fs_text_inline( 'Submit & %s', 'deactivation-modal-button-submit' , $slug ),
|
370 |
-
$fs->is_plugin() ?
|
371 |
-
$deactivate_text :
|
372 |
-
sprintf( $activate_x_text, $theme_text )
|
373 |
-
) ) ?>');
|
374 |
-
|
375 |
-
enableDeactivateButton();
|
376 |
|
377 |
if ( _parent.hasClass( 'has-internal-message' ) ) {
|
378 |
_parent.find( '.internal-message' ).show();
|
379 |
}
|
380 |
|
381 |
-
if (_parent.hasClass('has-input')) {
|
|
|
|
|
|
|
|
|
382 |
var inputType = _parent.data('input-type'),
|
383 |
inputPlaceholder = _parent.data('input-placeholder'),
|
384 |
reasonInputHtml = '<div class="reason-input"><span class="message"></span>' + ( ( 'textfield' === inputType ) ? '<input type="text" maxlength="128" />' : '<textarea rows="5" maxlength="128"></textarea>' ) + '</div>';
|
@@ -388,11 +446,60 @@ HTML;
|
|
388 |
|
389 |
if (isOtherReasonSelected()) {
|
390 |
showMessage('<?php echo esc_js( fs_text_inline( 'Kindly tell us the reason so we can improve.', 'ask-for-reason-message' , $slug ) ); ?>');
|
391 |
-
|
392 |
-
|
393 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
394 |
});
|
395 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
396 |
// If the user has clicked outside the window, cancel it.
|
397 |
$modal.on('click', function (evt) {
|
398 |
var $target = $(evt.target);
|
@@ -453,8 +560,6 @@ HTML;
|
|
453 |
function resetModal() {
|
454 |
selectedReasonID = false;
|
455 |
|
456 |
-
enableDeactivateButton();
|
457 |
-
|
458 |
// Uncheck all radio buttons.
|
459 |
$modal.find('input[type="radio"]').prop('checked', false);
|
460 |
|
@@ -463,8 +568,8 @@ HTML;
|
|
463 |
|
464 |
$modal.find('.message').hide();
|
465 |
|
466 |
-
|
467 |
-
$anonymousFeedback.find( 'input' ).prop( 'checked', false );
|
468 |
|
469 |
// Hide, since by default there is no selected reason.
|
470 |
$anonymousFeedback.hide();
|
@@ -491,13 +596,31 @@ HTML;
|
|
491 |
$modal.find('.message').text(message).show();
|
492 |
}
|
493 |
|
494 |
-
|
495 |
-
|
496 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
497 |
|
498 |
-
|
499 |
-
|
500 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
501 |
|
502 |
function showPanel(panelType) {
|
503 |
$modal.find( '.fs-modal-panel' ).removeClass( 'active' );
|
24 |
$anonymous_feedback_checkbox_html = '';
|
25 |
|
26 |
$reasons_list_items_html = '';
|
27 |
+
$snooze_select_html = '';
|
28 |
|
29 |
if ( $show_deactivation_feedback_form ) {
|
30 |
$reasons = $VARS['reasons'];
|
65 |
fs_esc_html_inline( 'Anonymous feedback', 'anonymous-feedback', $slug )
|
66 |
);
|
67 |
}
|
68 |
+
|
69 |
+
$snooze_periods = array(
|
70 |
+
array(
|
71 |
+
'increment' => fs_text_inline( 'hour', $slug ),
|
72 |
+
'quantity' => number_format_i18n(1),
|
73 |
+
'value' => 6 * WP_FS__TIME_10_MIN_IN_SEC,
|
74 |
+
),
|
75 |
+
array(
|
76 |
+
'increment' => fs_text_inline( 'hours', $slug ),
|
77 |
+
'quantity' => number_format_i18n(24),
|
78 |
+
'value' => WP_FS__TIME_24_HOURS_IN_SEC,
|
79 |
+
),
|
80 |
+
array(
|
81 |
+
'increment' => fs_text_inline( 'days', $slug ),
|
82 |
+
'quantity' => number_format_i18n(7),
|
83 |
+
'value' => WP_FS__TIME_WEEK_IN_SEC,
|
84 |
+
),
|
85 |
+
array(
|
86 |
+
'increment' => fs_text_inline( 'days', $slug ),
|
87 |
+
'quantity' => number_format_i18n(30),
|
88 |
+
'value' => 30 * WP_FS__TIME_24_HOURS_IN_SEC,
|
89 |
+
),
|
90 |
+
);
|
91 |
+
|
92 |
+
$snooze_select_html = '<select>';
|
93 |
+
foreach ($snooze_periods as $period) {
|
94 |
+
$snooze_select_html .= sprintf(
|
95 |
+
'<option value="%s">%s %s</option>',
|
96 |
+
$period['value'],
|
97 |
+
$period['quantity'],
|
98 |
+
$period['increment']
|
99 |
+
);
|
100 |
+
}
|
101 |
+
|
102 |
+
$snooze_select_html .= '</select>';
|
103 |
}
|
104 |
|
105 |
// Aliases.
|
107 |
$theme_text = fs_text_inline( 'Theme', 'theme', $slug );
|
108 |
$activate_x_text = fs_text_inline( 'Activate %s', 'activate-x', $slug );
|
109 |
|
110 |
+
$submit_deactivate_text = sprintf(
|
111 |
+
fs_text_inline( 'Submit & %s', 'deactivation-modal-button-submit', $slug ),
|
112 |
+
$fs->is_plugin() ?
|
113 |
+
$deactivate_text :
|
114 |
+
sprintf( $activate_x_text, $theme_text )
|
115 |
+
);
|
116 |
+
|
117 |
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
118 |
|
119 |
if ( ! empty( $subscription_cancellation_dialog_box_template_params ) ) {
|
135 |
+ ' </div>'
|
136 |
+ ' <div class="fs-modal-footer">'
|
137 |
+ ' <?php echo $anonymous_feedback_checkbox_html ?>'
|
138 |
+
+ ' <label style="display: none" class="feedback-from-snooze-label"><input type="checkbox" class="feedback-from-snooze-checkbox"> <span><?php fs_esc_js_echo_inline( 'Snooze this panel during troubleshooting', 'snooze-panel-during-troubleshooting', $slug ) ?></span><span style="display: none"><?php fs_esc_js_echo_inline( 'Snooze this panel for', 'snooze-panel-for', $slug ) ?> <?php echo $snooze_select_html ?></span></label>'
|
139 |
+ ' <a href="#" class="button button-secondary button-deactivate"></a>'
|
140 |
+ ' <a href="#" class="button button-secondary button-close"><?php fs_esc_js_echo_inline( 'Cancel', 'cancel', $slug ) ?></a>'
|
141 |
+ ' </div>'
|
145 |
selectedReasonID = false,
|
146 |
redirectLink = '',
|
147 |
$anonymousFeedback = $modal.find( '.anonymous-feedback-label' ),
|
148 |
+
$feedbackSnooze = $modal.find( '.feedback-from-snooze-label' ),
|
149 |
isAnonymous = <?php echo ( $is_anonymous ? 'true' : 'false' ); ?>,
|
150 |
otherReasonID = <?php echo Freemius::REASON_OTHER; ?>,
|
151 |
dontShareDataReasonID = <?php echo Freemius::REASON_DONT_LIKE_TO_SHARE_MY_INFORMATION; ?>,
|
180 |
?>
|
181 |
|
182 |
$.ajax({
|
183 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
184 |
method : 'POST',
|
185 |
data : {
|
186 |
action : '<?php echo $fs->get_ajax_action( 'cancel_subscription_or_trial' ) ?>',
|
275 |
} ?>
|
276 |
|
277 |
$modal.on('input propertychange', '.reason-input input', function () {
|
|
|
|
|
|
|
|
|
278 |
var reason = $(this).val().trim();
|
279 |
|
280 |
/**
|
282 |
* to change the message color back to default.
|
283 |
*/
|
284 |
if (reason.length > 0) {
|
285 |
+
$('.message').removeClass('error-message');
|
286 |
+
}
|
287 |
+
|
288 |
+
toggleDeactivationButtonPrimary( reason.length > 0 );
|
289 |
+
|
290 |
+
changeDeactivateButtonText();
|
291 |
});
|
292 |
|
293 |
$modal.on('blur', '.reason-input input', function () {
|
304 |
*/
|
305 |
if (0 === $userReason.val().trim().length) {
|
306 |
$('.message').addClass('error-message');
|
307 |
+
changeDeactivateButtonText();
|
308 |
+
}
|
309 |
}, 150);
|
310 |
});
|
311 |
|
320 |
var _this = $(this);
|
321 |
|
322 |
if (_this.hasClass('allow-deactivate')) {
|
323 |
+
var
|
324 |
+
$radio = $modal.find('input[type="radio"]:checked'),
|
325 |
+
isReasonSelected = (0 < $radio.length),
|
326 |
+
userReason = '';
|
327 |
+
|
328 |
+
if ( isReasonSelected ) {
|
329 |
+
var $selectedReason = $radio.parents('li:first'),
|
330 |
+
$reasonInput = $selectedReason.find('textarea, input[type="text"]');
|
331 |
|
332 |
+
if ( 0 < $reasonInput.length ) {
|
333 |
+
userReason = $reasonInput.val().trim();
|
334 |
+
}
|
335 |
+
}
|
336 |
+
|
337 |
+
if ( otherReasonID == selectedReasonID && '' === userReason ) {
|
338 |
+
// If the 'Other' is selected and a reason is not provided (aka it's empty), treat it as if a reason wasn't selected at all.
|
339 |
+
isReasonSelected = false;
|
340 |
+
}
|
341 |
+
|
342 |
+
_parent.find( '.fs-modal-footer .button' ).addClass( 'disabled' );
|
343 |
+
|
344 |
+
if ( ! isReasonSelected ) {
|
345 |
if ( ! deleteThemeUpdateData ) {
|
346 |
// If no selected reason, just deactivate the plugin.
|
347 |
window.location.href = redirectLink;
|
348 |
} else {
|
349 |
$.ajax({
|
350 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
351 |
method : 'POST',
|
352 |
data : {
|
353 |
action : '<?php echo $fs->get_ajax_action( 'delete_theme_update_data' ) ?>',
|
355 |
module_id: '<?php echo $fs->get_id() ?>'
|
356 |
},
|
357 |
beforeSend: function() {
|
358 |
+
_parent.find( '.fs-modal-footer .button-deactivate' ).text( '<?php echo esc_js( fs_text_inline( 'Processing', 'processing', $slug ) ) ?>...' );
|
|
|
359 |
},
|
360 |
complete : function() {
|
361 |
window.location.href = redirectLink;
|
366 |
return;
|
367 |
}
|
368 |
|
369 |
+
var snoozePeriod = 0,
|
370 |
+
shouldSnooze = $feedbackSnooze.find( '.feedback-from-snooze-checkbox' ).is( ':checked' );
|
|
|
371 |
|
372 |
+
if ( shouldSnooze && <?php echo Freemius::REASON_TEMPORARY_DEACTIVATION ?> == selectedReasonID ) {
|
373 |
+
snoozePeriod = parseInt($feedbackSnooze.find('select').val(), 10);
|
374 |
+
}
|
375 |
|
376 |
$.ajax({
|
377 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
378 |
method : 'POST',
|
379 |
data : {
|
380 |
+
action : '<?php echo $fs->get_ajax_action( 'submit_uninstall_reason' ) ?>',
|
381 |
+
security : '<?php echo $fs->get_ajax_security( 'submit_uninstall_reason' ) ?>',
|
382 |
+
module_id : '<?php echo $fs->get_id() ?>',
|
383 |
+
reason_id : $radio.val(),
|
384 |
+
reason_info : userReason,
|
385 |
+
is_anonymous : isAnonymousFeedback(),
|
386 |
+
snooze_period: snoozePeriod
|
387 |
},
|
388 |
beforeSend: function () {
|
389 |
+
_parent.find('.fs-modal-footer .button-deactivate').text('<?php echo esc_js( fs_text_inline( 'Processing', 'processing', $slug ) ) ?>...');
|
|
|
390 |
},
|
391 |
complete : function () {
|
392 |
// Do not show the dialog box, deactivate the plugin.
|
426 |
|
427 |
$modal.find('.reason-input').remove();
|
428 |
$modal.find( '.internal-message' ).hide();
|
429 |
+
$modal.find('.button-deactivate').html('<?php echo esc_js( $submit_deactivate_text ) ?>');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
430 |
|
431 |
if ( _parent.hasClass( 'has-internal-message' ) ) {
|
432 |
_parent.find( '.internal-message' ).show();
|
433 |
}
|
434 |
|
435 |
+
if ( ! _parent.hasClass('has-input') ) {
|
436 |
+
toggleDeactivationButtonPrimary( true );
|
437 |
+
} else {
|
438 |
+
toggleDeactivationButtonPrimary( false );
|
439 |
+
|
440 |
var inputType = _parent.data('input-type'),
|
441 |
inputPlaceholder = _parent.data('input-placeholder'),
|
442 |
reasonInputHtml = '<div class="reason-input"><span class="message"></span>' + ( ( 'textfield' === inputType ) ? '<input type="text" maxlength="128" />' : '<textarea rows="5" maxlength="128"></textarea>' ) + '</div>';
|
446 |
|
447 |
if (isOtherReasonSelected()) {
|
448 |
showMessage('<?php echo esc_js( fs_text_inline( 'Kindly tell us the reason so we can improve.', 'ask-for-reason-message' , $slug ) ); ?>');
|
449 |
+
changeDeactivateButtonText();
|
450 |
+
}
|
451 |
}
|
452 |
+
|
453 |
+
$anonymousFeedback.toggle( <?php echo Freemius::REASON_TEMPORARY_DEACTIVATION ?> != selectedReasonID );
|
454 |
+
$feedbackSnooze.toggle( <?php echo Freemius::REASON_TEMPORARY_DEACTIVATION ?> == selectedReasonID );
|
455 |
+
|
456 |
+
if ( <?php echo Freemius::REASON_TEMPORARY_DEACTIVATION ?> == selectedReasonID ) {
|
457 |
+
updateDeactivationButtonOnTrouble();
|
458 |
+
}
|
459 |
});
|
460 |
|
461 |
+
var toggleDeactivationButtonPrimary = function ( isPrimary ) {
|
462 |
+
if ( isPrimary ) {
|
463 |
+
$modal.find('.button-deactivate')
|
464 |
+
.removeClass( 'button-secondary' )
|
465 |
+
.addClass( 'button-primary' );
|
466 |
+
} else {
|
467 |
+
$modal.find('.button-deactivate')
|
468 |
+
.addClass( 'button-secondary' )
|
469 |
+
.removeClass( 'button-primary' );
|
470 |
+
}
|
471 |
+
};
|
472 |
+
|
473 |
+
var snooze = false;
|
474 |
+
|
475 |
+
var updateDeactivationButtonOnTrouble = function () {
|
476 |
+
if ( snooze ) {
|
477 |
+
$modal.find('.button-deactivate').html('<?php echo esc_js( sprintf(
|
478 |
+
fs_text_inline( 'Snooze & %s', 'snooze-modal-button-submit' , $slug ),
|
479 |
+
$fs->is_plugin() ?
|
480 |
+
$deactivate_text :
|
481 |
+
sprintf( $activate_x_text, $theme_text )
|
482 |
+
) ) ?>');
|
483 |
+
} else {
|
484 |
+
$modal.find('.button-deactivate').html('<?php echo esc_js(
|
485 |
+
$fs->is_plugin() ?
|
486 |
+
$deactivate_text :
|
487 |
+
sprintf( $activate_x_text, $theme_text )
|
488 |
+
) ?>');
|
489 |
+
}
|
490 |
+
};
|
491 |
+
|
492 |
+
$feedbackSnooze.on( 'click', 'input', function () {
|
493 |
+
var $spans = $feedbackSnooze.find( 'span' );
|
494 |
+
|
495 |
+
snooze = ( ! snooze );
|
496 |
+
|
497 |
+
$( $spans[0] ).toggle();
|
498 |
+
$( $spans[1] ).toggle();
|
499 |
+
|
500 |
+
updateDeactivationButtonOnTrouble();
|
501 |
+
});
|
502 |
+
|
503 |
// If the user has clicked outside the window, cancel it.
|
504 |
$modal.on('click', function (evt) {
|
505 |
var $target = $(evt.target);
|
560 |
function resetModal() {
|
561 |
selectedReasonID = false;
|
562 |
|
|
|
|
|
563 |
// Uncheck all radio buttons.
|
564 |
$modal.find('input[type="radio"]').prop('checked', false);
|
565 |
|
568 |
|
569 |
$modal.find('.message').hide();
|
570 |
|
571 |
+
if ( isAnonymous ) {
|
572 |
+
$anonymousFeedback.find( 'input' ).prop( 'checked', <?php echo $fs->apply_filters( 'default_to_anonymous_feedback', false ) ? 'true' : 'false' ?> );
|
573 |
|
574 |
// Hide, since by default there is no selected reason.
|
575 |
$anonymousFeedback.hide();
|
596 |
$modal.find('.message').text(message).show();
|
597 |
}
|
598 |
|
599 |
+
/**
|
600 |
+
* @author Xiaheng Chen (@xhchen)
|
601 |
+
*
|
602 |
+
* @since 2.4.2
|
603 |
+
*/
|
604 |
+
function changeDeactivateButtonText() {
|
605 |
+
if ( ! isOtherReasonSelected()) {
|
606 |
+
return;
|
607 |
+
}
|
608 |
|
609 |
+
var
|
610 |
+
$userReason = $modal.find('.reason-input input'),
|
611 |
+
$deactivateButton = $modal.find('.button-deactivate');
|
612 |
+
|
613 |
+
if (0 === $userReason.val().trim().length) {
|
614 |
+
// If the reason is empty, just change the text to 'Deactivate' (plugin) or 'Activate themeX' (theme).
|
615 |
+
$deactivateButton.html('<?php echo
|
616 |
+
$fs->is_plugin() ?
|
617 |
+
$deactivate_text :
|
618 |
+
sprintf( $activate_x_text, $theme_text )
|
619 |
+
?>');
|
620 |
+
} else {
|
621 |
+
$deactivateButton.html('<?php echo esc_js( $submit_deactivate_text ) ?>');
|
622 |
+
}
|
623 |
+
}
|
624 |
|
625 |
function showPanel(panelType) {
|
626 |
$modal.find( '.fs-modal-panel' ).removeClass( 'active' );
|
freemius/templates/forms/email-address-update.php
ADDED
@@ -0,0 +1,347 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
*
|
7 |
+
* @author Leo Fajardo (@leorw)
|
8 |
+
* @since 2.5.0
|
9 |
+
*/
|
10 |
+
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var array $VARS
|
17 |
+
*/
|
18 |
+
$fs = freemius( $VARS['id'] );
|
19 |
+
$slug = $fs->get_slug();
|
20 |
+
|
21 |
+
$user = $fs->get_user();
|
22 |
+
$current_email_address = $user->email;
|
23 |
+
|
24 |
+
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
25 |
+
?>
|
26 |
+
<script type="text/javascript">
|
27 |
+
( function ( $ ) {
|
28 |
+
var modalHtml =
|
29 |
+
'<div class="fs-modal fs-modal-email-address-update">'
|
30 |
+
+ ' <div class="fs-modal-dialog">'
|
31 |
+
+ ' <div class="fs-modal-header">'
|
32 |
+
+ ' <h4><?php fs_esc_attr_echo_inline( 'Email address update', 'email-address-update', $slug ) ?></h4>'
|
33 |
+
+ ' <a href="!#" class="fs-close"><i class="dashicons dashicons-no" title="<?php echo esc_js( fs_text_x_inline( 'Dismiss', 'close window', 'dismiss', $slug ) ) ?>"></i></a>'
|
34 |
+
+ ' </div>'
|
35 |
+
+ ' <div class="fs-modal-body">'
|
36 |
+
+ ' <div class="fs-modal-panel active">'
|
37 |
+
+ ' <div class="notice notice-error inline fs-update-error-message"><p></p></div>'
|
38 |
+
+ ' <p><?php fs_echo_inline( 'Enter the new email address', 'enter-new-email-address' , $slug ) ?>:</p>'
|
39 |
+
+ ' <input type="text" class="fs-new-email-address-input" />'
|
40 |
+
+ ' <div class="fs-email-addresses-ownership-options" style="display: none">'
|
41 |
+
+ ' <p><?php echo sprintf(
|
42 |
+
fs_esc_html_inline( 'Are both %s and %s your email addresses?', 'email-addresses-ownership-confirmation' , $slug ),
|
43 |
+
sprintf( '<strong>%s</strong>', $current_email_address ),
|
44 |
+
'<strong class="fs-new-email-address"></strong>'
|
45 |
+
) ?></p>'
|
46 |
+
+ ' <ul>'
|
47 |
+
+ ' <li>'
|
48 |
+
+ ' <label>'
|
49 |
+
+ ' <span><input type="radio" name="email-addresses-ownership" value="both"/></span>'
|
50 |
+
+ ' <span><?php fs_echo_inline( 'Yes - both addresses are mine', 'both-addresses-are-mine', $slug ); ?></span>'
|
51 |
+
+ ' </label>'
|
52 |
+
+ ' </li>'
|
53 |
+
+ ' <li>'
|
54 |
+
+ ' <label>'
|
55 |
+
+ ' <span><input type="radio" name="email-addresses-ownership" value="current"/></span>'
|
56 |
+
+ ' <div><?php echo sprintf(
|
57 |
+
fs_esc_html_inline( "%s is my client's email address", 'client-email-address-confirmation', $slug ),
|
58 |
+
'<strong class="fs-new-email-address"></strong>'
|
59 |
+
) ?></span>'
|
60 |
+
+ ' </label>'
|
61 |
+
+ ' </li>'
|
62 |
+
+ ' <li>'
|
63 |
+
+ ' <label>'
|
64 |
+
+ ' <span><input type="radio" name="email-addresses-ownership" value="new"/></span>'
|
65 |
+
+ ' <div><?php echo sprintf(
|
66 |
+
fs_esc_html_inline( "%s is my email address", 'email-address-ownership-confirmation', $slug ),
|
67 |
+
'<strong class="fs-new-email-address"></strong>'
|
68 |
+
) ?></span>'
|
69 |
+
+ ' </label>'
|
70 |
+
+ ' </li>'
|
71 |
+
+ ' </ul>'
|
72 |
+
+ ' </div>'
|
73 |
+
+ ' <div class="fs-assets-transfership-options" style="display: none">'
|
74 |
+
+ ' <p><?php echo sprintf(
|
75 |
+
fs_esc_html_inline( 'Would you like to merge %s into %s?', 'accounts-merge-confirmation' , $slug ),
|
76 |
+
sprintf( '<strong>%s</strong>', $current_email_address ),
|
77 |
+
'<strong class="fs-new-email-address"></strong>'
|
78 |
+
) ?></p>'
|
79 |
+
+ ' <ul>'
|
80 |
+
+ ' <li>'
|
81 |
+
+ ' <label>'
|
82 |
+
+ ' <span><input type="radio" name="assets-transfer-type" value="all" /></span>'
|
83 |
+
+ ' <span><?php echo sprintf(
|
84 |
+
fs_esc_html_inline( 'Yes - move all my data and assets from %s to %s', 'move-all-data-and-assets-into-new-account', $slug ),
|
85 |
+
sprintf( '<strong>%s</strong>', $current_email_address ),
|
86 |
+
'<strong class="fs-new-email-address"></strong>'
|
87 |
+
) ?></span>'
|
88 |
+
+ ' </label>'
|
89 |
+
+ ' </li>'
|
90 |
+
+ ' <li>'
|
91 |
+
+ ' <label>'
|
92 |
+
+ ' <span><input type="radio" name="assets-transfer-type" value="plugin" /></span>'
|
93 |
+
+ ' <span><?php echo sprintf(
|
94 |
+
fs_esc_html_inline( "No - only move this site's data to %s", 'move-only-plugin-data-into-new-account', $slug ),
|
95 |
+
'<strong class="fs-new-email-address"></strong>'
|
96 |
+
) ?></span>'
|
97 |
+
+ ' </label>'
|
98 |
+
+ ' </li>'
|
99 |
+
+ ' </ul>'
|
100 |
+
+ ' </div>'
|
101 |
+
+ ' </div>'
|
102 |
+
+ ' </div>'
|
103 |
+
+ ' <div class="fs-modal-footer">'
|
104 |
+
+ ' <button class="button button-primary button-update" disabled><?php fs_esc_js_echo_inline( 'Update', 'update-email-address', $slug ) ?></button>'
|
105 |
+
+ ' <button class="button button-secondary button-close"><?php fs_esc_js_echo_inline( 'Cancel', 'cancel', $slug ) ?></button>'
|
106 |
+
+ ' </div>'
|
107 |
+
+ ' </div>'
|
108 |
+
+ '</div>',
|
109 |
+
$modal = $( modalHtml ),
|
110 |
+
$updateButton = $modal.find( '.button-update' ),
|
111 |
+
$updateResultMessage = $modal.find( '.fs-update-error-message' ),
|
112 |
+
selectedEmailAddressesOwnershipOption = null,
|
113 |
+
selectedAssetsTransfershipOption = null,
|
114 |
+
previousEmailAddress = '',
|
115 |
+
$body = $( 'body' );
|
116 |
+
|
117 |
+
$modal.appendTo( $body );
|
118 |
+
|
119 |
+
registerEventHandlers();
|
120 |
+
|
121 |
+
function registerEventHandlers() {
|
122 |
+
$body.on( 'click', '#fs_account_details .button-edit-email-address', function ( evt ) {
|
123 |
+
evt.preventDefault();
|
124 |
+
|
125 |
+
showModal( evt );
|
126 |
+
} );
|
127 |
+
|
128 |
+
$modal.on( 'input propertychange keyup paste delete cut', '.fs-new-email-address-input', function () {
|
129 |
+
var emailAddress = $( this ).val().trim();
|
130 |
+
|
131 |
+
if ( emailAddress === previousEmailAddress ) {
|
132 |
+
return;
|
133 |
+
}
|
134 |
+
|
135 |
+
var isValidEmailAddressInput = isValidEmailAddress( emailAddress );
|
136 |
+
|
137 |
+
toggleOptions( isValidEmailAddressInput );
|
138 |
+
|
139 |
+
if ( ! isValidEmailAddressInput ) {
|
140 |
+
disableUpdateButton();
|
141 |
+
} else {
|
142 |
+
$modal.find( '.fs-new-email-address').text( emailAddress );
|
143 |
+
|
144 |
+
maybeEnableUpdateButton();
|
145 |
+
}
|
146 |
+
|
147 |
+
previousEmailAddress = emailAddress;
|
148 |
+
} );
|
149 |
+
|
150 |
+
$modal.on( 'blur', '.fs-new-email-address-input', function() {
|
151 |
+
var emailAddress = $( this ).val().trim(),
|
152 |
+
isValidEmailAddressInput = isValidEmailAddress( emailAddress );
|
153 |
+
|
154 |
+
toggleOptions( isValidEmailAddressInput );
|
155 |
+
|
156 |
+
if ( ! isValidEmailAddressInput ) {
|
157 |
+
disableUpdateButton();
|
158 |
+
}
|
159 |
+
} );
|
160 |
+
|
161 |
+
$modal.on( 'click', '.fs-close, .button-secondary', function () {
|
162 |
+
closeModal();
|
163 |
+
return false;
|
164 |
+
} );
|
165 |
+
|
166 |
+
$modal.on( 'click', '.fs-modal-footer .button-update', function ( evt ) {
|
167 |
+
if ( ! isValidEmailAddress( previousEmailAddress ) ) {
|
168 |
+
return;
|
169 |
+
}
|
170 |
+
|
171 |
+
if ( previousEmailAddress === '<?php echo $current_email_address ?>' ) {
|
172 |
+
closeModal();
|
173 |
+
return;
|
174 |
+
}
|
175 |
+
|
176 |
+
var transferType = 'transfer';
|
177 |
+
|
178 |
+
if ( 'current' === selectedEmailAddressesOwnershipOption ) {
|
179 |
+
transferType = 'transfer_to_client';
|
180 |
+
} else if (
|
181 |
+
'both' === selectedEmailAddressesOwnershipOption &&
|
182 |
+
'all' === selectedAssetsTransfershipOption
|
183 |
+
) {
|
184 |
+
transferType = 'merge';
|
185 |
+
}
|
186 |
+
|
187 |
+
$.ajax( {
|
188 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
189 |
+
method : 'POST',
|
190 |
+
data : {
|
191 |
+
action : '<?php echo $fs->get_ajax_action( 'update_email_address' ) ?>',
|
192 |
+
security : '<?php echo $fs->get_ajax_security( 'update_email_address' ) ?>',
|
193 |
+
module_id : '<?php echo $fs->get_id() ?>',
|
194 |
+
transfer_type: transferType,
|
195 |
+
email_address: previousEmailAddress
|
196 |
+
},
|
197 |
+
beforeSend: function () {
|
198 |
+
disableUpdateButton();
|
199 |
+
|
200 |
+
$updateButton.find( '.fs-modal-footer .button' ).prop( 'disabled', true );
|
201 |
+
$updateButton.text( 'Processing...' );
|
202 |
+
},
|
203 |
+
success : function( result ) {
|
204 |
+
if ( result.success ) {
|
205 |
+
// Redirect to the "Account" page.
|
206 |
+
window.location.reload();
|
207 |
+
} else {
|
208 |
+
if ('change_ownership' === result.error.code) {
|
209 |
+
window.location = result.error.url;
|
210 |
+
} else {
|
211 |
+
showError(result.error.message ? result.error.message : result.error);
|
212 |
+
resetUpdateButton();
|
213 |
+
}
|
214 |
+
}
|
215 |
+
},
|
216 |
+
error : function () {
|
217 |
+
showError( '<?php fs_esc_js_echo_inline( 'Unexpected error, try again in 5 minutes. If the error persists, please contact support.', 'unexpected-error', $slug ) ?>' );
|
218 |
+
|
219 |
+
resetUpdateButton();
|
220 |
+
}
|
221 |
+
} );
|
222 |
+
} );
|
223 |
+
|
224 |
+
$modal.on( 'click', 'input[type="radio"]', function () {
|
225 |
+
var $selectedOption = $( this ),
|
226 |
+
selectedOptionValue = $selectedOption.val();
|
227 |
+
|
228 |
+
// If the selection has not changed, do not proceed.
|
229 |
+
if (
|
230 |
+
selectedEmailAddressesOwnershipOption === selectedOptionValue ||
|
231 |
+
selectedAssetsTransfershipOption === selectedOptionValue
|
232 |
+
) {
|
233 |
+
return;
|
234 |
+
}
|
235 |
+
|
236 |
+
if ( 'assets-transfer-type' === $selectedOption.attr( 'name' ) ) {
|
237 |
+
selectedAssetsTransfershipOption = selectedOptionValue;
|
238 |
+
} else {
|
239 |
+
selectedEmailAddressesOwnershipOption = selectedOptionValue;
|
240 |
+
|
241 |
+
if ( 'both' !== selectedEmailAddressesOwnershipOption ) {
|
242 |
+
$modal.find( '.fs-assets-transfership-options' ).hide();
|
243 |
+
} else {
|
244 |
+
$modal.find( '.fs-assets-transfership-options' ).show();
|
245 |
+
$modal.find( '.fs-assets-transfership-options input[type="radio"]' ).prop('checked', false);
|
246 |
+
|
247 |
+
selectedAssetsTransfershipOption = null;
|
248 |
+
|
249 |
+
disableUpdateButton();
|
250 |
+
}
|
251 |
+
}
|
252 |
+
|
253 |
+
if ( isValidEmailAddress( $( '.fs-new-email-address-input' ).val().trim() ) ) {
|
254 |
+
maybeEnableUpdateButton();
|
255 |
+
}
|
256 |
+
});
|
257 |
+
}
|
258 |
+
|
259 |
+
function showModal() {
|
260 |
+
resetModal();
|
261 |
+
|
262 |
+
// Display the dialog box.
|
263 |
+
$modal.addClass( 'active' );
|
264 |
+
$modal.find( '.fs-new-email-address-input' ).focus();
|
265 |
+
|
266 |
+
$( 'body' ).addClass( 'has-fs-modal' );
|
267 |
+
}
|
268 |
+
|
269 |
+
function closeModal() {
|
270 |
+
selectedEmailAddressesOwnershipOption = null;
|
271 |
+
|
272 |
+
disableUpdateButton();
|
273 |
+
|
274 |
+
$modal.removeClass( 'active' );
|
275 |
+
|
276 |
+
$( 'body' ).removeClass( 'has-fs-modal' );
|
277 |
+
}
|
278 |
+
|
279 |
+
function resetModal() {
|
280 |
+
hideError();
|
281 |
+
|
282 |
+
// Deselect all radio buttons.
|
283 |
+
$modal.find( 'input[type="radio"]' ).prop( 'checked', false );
|
284 |
+
|
285 |
+
// Clear the value of the email address text field.
|
286 |
+
$modal.find( 'input[type="text"]' ).val( '' );
|
287 |
+
|
288 |
+
toggleOptions( false );
|
289 |
+
|
290 |
+
disableUpdateButton();
|
291 |
+
|
292 |
+
$updateButton.text( <?php echo json_encode( fs_text_inline( 'Update', 'update-email-address', $slug ) ) ?> );
|
293 |
+
}
|
294 |
+
|
295 |
+
function resetUpdateButton() {
|
296 |
+
maybeEnableUpdateButton();
|
297 |
+
|
298 |
+
$updateButton.text( <?php echo json_encode( fs_text_inline( 'Update', 'update-email-address', $slug ) ) ?> );
|
299 |
+
}
|
300 |
+
|
301 |
+
function maybeEnableUpdateButton() {
|
302 |
+
if ( null === selectedEmailAddressesOwnershipOption ) {
|
303 |
+
return;
|
304 |
+
}
|
305 |
+
|
306 |
+
if (
|
307 |
+
'both' === selectedEmailAddressesOwnershipOption &&
|
308 |
+
null === selectedAssetsTransfershipOption
|
309 |
+
) {
|
310 |
+
return;
|
311 |
+
}
|
312 |
+
|
313 |
+
$updateButton.prop( 'disabled', false );
|
314 |
+
}
|
315 |
+
|
316 |
+
function disableUpdateButton() {
|
317 |
+
$updateButton.prop( 'disabled', true );
|
318 |
+
}
|
319 |
+
|
320 |
+
function hideError() {
|
321 |
+
$updateResultMessage.hide();
|
322 |
+
}
|
323 |
+
|
324 |
+
function showError( msg ) {
|
325 |
+
$updateResultMessage.find( ' > p' ).html( msg );
|
326 |
+
$updateResultMessage.show();
|
327 |
+
}
|
328 |
+
|
329 |
+
function isValidEmailAddress( emailAddress ) {
|
330 |
+
if ( '' === emailAddress ) {
|
331 |
+
return false;
|
332 |
+
}
|
333 |
+
|
334 |
+
return /[0-9a-zA-Z][a-zA-Z\+0-9\.\_\-]*@[0-9a-zA-Z\-]+(\.[a-zA-Z]{2,24}){1,3}/.test( emailAddress );
|
335 |
+
}
|
336 |
+
|
337 |
+
function toggleOptions( show ) {
|
338 |
+
$modal.find( '.fs-email-addresses-ownership-options' ).toggle( show );
|
339 |
+
|
340 |
+
if ( ! show ) {
|
341 |
+
$modal.find( '.fs-assets-transfership-options' ).hide();
|
342 |
+
} else if ( 'both' === selectedEmailAddressesOwnershipOption ) {
|
343 |
+
$modal.find( '.fs-assets-transfership-options' ).show();
|
344 |
+
}
|
345 |
+
}
|
346 |
+
} )( jQuery );
|
347 |
+
</script>
|
freemius/templates/forms/license-activation.php
CHANGED
@@ -30,17 +30,10 @@
|
|
30 |
if ( $fs->is_registered() ) {
|
31 |
$activate_button_text = $header_title;
|
32 |
} else {
|
33 |
-
$freemius_site_url = $fs->has_paid_plan() ?
|
34 |
-
'https://freemius.com/' :
|
35 |
-
// Insights platform information.
|
36 |
-
$fs->get_usage_tracking_terms_url();
|
37 |
-
|
38 |
-
$freemius_link = '<a href="' . $freemius_site_url . '" target="_blank" rel="noopener" tabindex="0">freemius.com</a>';
|
39 |
-
|
40 |
$message_below_input_field = sprintf(
|
41 |
-
fs_text_inline( 'The %1$s will be periodically sending data to %2$s to check for security and feature updates, and verify the validity of your license.', 'license-sync-disclaimer', $slug ),
|
42 |
$fs->get_module_label( true ),
|
43 |
-
$
|
44 |
);
|
45 |
|
46 |
$activate_button_text = fs_text_inline( 'Agree & Activate License', 'agree-activate-license', $slug );
|
@@ -59,23 +52,51 @@
|
|
59 |
if ( $is_network_activation ) {
|
60 |
$all_sites = Freemius::get_sites();
|
61 |
|
|
|
|
|
|
|
62 |
foreach ( $all_sites as $site ) {
|
63 |
$site_details = $fs->get_site_info( $site );
|
64 |
|
|
|
|
|
|
|
|
|
65 |
$blog_id = Freemius::get_site_blog_id( $site );
|
66 |
$install = $fs->get_install_by_blog_id($blog_id);
|
67 |
|
68 |
-
if ( is_object( $install )
|
69 |
-
$
|
70 |
-
|
|
|
71 |
|
72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
|
75 |
if ( $is_network_activation ) {
|
76 |
$vars = array(
|
77 |
'id' => $fs->get_id(),
|
78 |
-
'sites' => $
|
79 |
'require_license_key' => true
|
80 |
);
|
81 |
|
@@ -341,7 +362,7 @@ HTML;
|
|
341 |
$activateLicenseButton.html( '<?php fs_esc_js_echo_inline( 'Please wait', 'please-wait', $slug ) ?>...' );
|
342 |
|
343 |
$.ajax( {
|
344 |
-
url :
|
345 |
method : 'POST',
|
346 |
data : {
|
347 |
action : '<?php echo $fs->get_ajax_action( 'fetch_is_marketing_required_flag_value' ) ?>',
|
@@ -589,7 +610,6 @@ HTML;
|
|
589 |
url : $this.find( '.url' ).val(),
|
590 |
title : $this.find( '.title' ).val(),
|
591 |
language: $this.find( '.language' ).val(),
|
592 |
-
charset : $this.find( '.charset' ).val(),
|
593 |
blog_id : $this.find( '.blog-id' ).find( 'span' ).text()
|
594 |
};
|
595 |
|
@@ -607,7 +627,7 @@ HTML;
|
|
607 |
}
|
608 |
|
609 |
$.ajax({
|
610 |
-
url:
|
611 |
method: 'POST',
|
612 |
data: data,
|
613 |
beforeSend: function () {
|
@@ -867,4 +887,4 @@ HTML;
|
|
867 |
}
|
868 |
});
|
869 |
})( jQuery );
|
870 |
-
</script>
|
30 |
if ( $fs->is_registered() ) {
|
31 |
$activate_button_text = $header_title;
|
32 |
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
$message_below_input_field = sprintf(
|
34 |
+
fs_text_inline( 'The %1$s will be periodically sending essential license data to %2$s to check for security and feature updates, and verify the validity of your license.', 'license-sync-disclaimer', $slug ),
|
35 |
$fs->get_module_label( true ),
|
36 |
+
"<b>{$fs->get_plugin_title()}</b>"
|
37 |
);
|
38 |
|
39 |
$activate_button_text = fs_text_inline( 'Agree & Activate License', 'agree-activate-license', $slug );
|
52 |
if ( $is_network_activation ) {
|
53 |
$all_sites = Freemius::get_sites();
|
54 |
|
55 |
+
$subsite_data_by_install_id = array();
|
56 |
+
$install_url_by_install_id = array();
|
57 |
+
|
58 |
foreach ( $all_sites as $site ) {
|
59 |
$site_details = $fs->get_site_info( $site );
|
60 |
|
61 |
+
if ( FS_Clone_Manager::instance()->is_temporary_duplicate_by_blog_id( $site_details['blog_id'] ) ) {
|
62 |
+
continue;
|
63 |
+
}
|
64 |
+
|
65 |
$blog_id = Freemius::get_site_blog_id( $site );
|
66 |
$install = $fs->get_install_by_blog_id($blog_id);
|
67 |
|
68 |
+
if ( is_object( $install ) ) {
|
69 |
+
if ( isset( $subsite_data_by_install_id[ $install->id ] ) ) {
|
70 |
+
$clone_subsite_data = $subsite_data_by_install_id[ $install->id ];
|
71 |
+
$clone_install_url = $install_url_by_install_id[ $install->id ];
|
72 |
|
73 |
+
if (
|
74 |
+
/**
|
75 |
+
* If we already have an install with the same URL as the subsite it's stored in, skip the current subsite. Otherwise, replace the existing install's data with the current subsite's install's data if the URLs match.
|
76 |
+
*
|
77 |
+
* @author Leo Fajardo (@leorw)
|
78 |
+
* @since 2.5.0
|
79 |
+
*/
|
80 |
+
fs_strip_url_protocol( untrailingslashit( $clone_install_url ) ) === fs_strip_url_protocol( untrailingslashit( $clone_subsite_data['url'] ) ) ||
|
81 |
+
fs_strip_url_protocol( untrailingslashit( $install->url ) ) !== fs_strip_url_protocol( untrailingslashit( $site_details['url'] ) )
|
82 |
+
) {
|
83 |
+
continue;
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
if ( FS_Plugin_License::is_valid_id( $install->license_id ) ) {
|
88 |
+
$site_details['license_id'] = $install->license_id;
|
89 |
+
}
|
90 |
+
|
91 |
+
$subsite_data_by_install_id[ $install->id ] = $site_details;
|
92 |
+
$install_url_by_install_id[ $install->id ] = $install->url;
|
93 |
+
}
|
94 |
}
|
95 |
|
96 |
if ( $is_network_activation ) {
|
97 |
$vars = array(
|
98 |
'id' => $fs->get_id(),
|
99 |
+
'sites' => array_values( $subsite_data_by_install_id ),
|
100 |
'require_license_key' => true
|
101 |
);
|
102 |
|
362 |
$activateLicenseButton.html( '<?php fs_esc_js_echo_inline( 'Please wait', 'please-wait', $slug ) ?>...' );
|
363 |
|
364 |
$.ajax( {
|
365 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
366 |
method : 'POST',
|
367 |
data : {
|
368 |
action : '<?php echo $fs->get_ajax_action( 'fetch_is_marketing_required_flag_value' ) ?>',
|
610 |
url : $this.find( '.url' ).val(),
|
611 |
title : $this.find( '.title' ).val(),
|
612 |
language: $this.find( '.language' ).val(),
|
|
|
613 |
blog_id : $this.find( '.blog-id' ).find( 'span' ).text()
|
614 |
};
|
615 |
|
627 |
}
|
628 |
|
629 |
$.ajax({
|
630 |
+
url: <?php echo Freemius::ajax_url() ?>,
|
631 |
method: 'POST',
|
632 |
data: data,
|
633 |
beforeSend: function () {
|
887 |
}
|
888 |
});
|
889 |
})( jQuery );
|
890 |
+
</script>
|
freemius/templates/forms/optout.php
CHANGED
@@ -17,320 +17,166 @@
|
|
17 |
$fs = freemius( $VARS['id'] );
|
18 |
$slug = $fs->get_slug();
|
19 |
|
20 |
-
$action = $fs->is_tracking_allowed() ?
|
21 |
-
'stop_tracking' :
|
22 |
-
'allow_tracking';
|
23 |
-
|
24 |
$reconnect_url = $fs->get_activation_url( array(
|
25 |
'nonce' => wp_create_nonce( $fs->get_unique_affix() . '_reconnect' ),
|
26 |
'fs_action' => ( $fs->get_unique_affix() . '_reconnect' ),
|
27 |
) );
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
$opt_in_text = fs_text_x_inline( 'Opt In', 'verb', 'opt-in', $slug );
|
32 |
-
|
33 |
-
if ( $fs->is_premium() ) {
|
34 |
-
$opt_in_message_appreciation = fs_text_inline( 'Connectivity to the licensing engine was successfully re-established. Automatic security & feature updates are now available through the WP Admin Dashboard.', 'premium-opt-in-message-appreciation', $slug );
|
35 |
-
|
36 |
-
$opt_out_message_subtitle = sprintf( fs_text_inline( 'Warning: Opting out will block automatic updates', 'premium-opt-out-message-appreciation', $slug ), $fs->get_module_type() );
|
37 |
-
$opt_out_message_usage_tracking = sprintf( fs_text_inline( 'Ongoing connectivity with the licensing engine is essential for receiving automatic security & feature updates of the paid product. To receive these updates, data like your license key, %1$s version, and WordPress version, is periodically sent to the server to check for updates. By opting out, you understand that your site won\'t receive automatic updates for %2$s from within the WP Admin Dashboard. This can put your site at risk, and we highly recommend to keep this connection active. If you do choose to opt-out, you\'ll need to check for %1$s updates and install them manually.', 'premium-opt-out-message-usage-tracking', $slug ), $fs->get_module_type(), $plugin_title );
|
38 |
-
|
39 |
-
$primary_cta_label = fs_text_inline( 'I\'d like to keep automatic updates', 'premium-opt-out-cancel', $slug );
|
40 |
-
} else {
|
41 |
-
$opt_in_message_appreciation = sprintf( fs_text_inline( 'We appreciate your help in making the %s better by letting us track some usage data.', 'opt-in-message-appreciation', $slug ), $fs->get_module_type() );
|
42 |
-
|
43 |
-
$opt_out_message_subtitle = $opt_in_message_appreciation;
|
44 |
-
$opt_out_message_usage_tracking = sprintf( fs_text_inline( "Usage tracking is done in the name of making %s better. Making a better user experience, prioritizing new features, and more good things. We'd really appreciate if you'll reconsider letting us continue with the tracking.", 'opt-out-message-usage-tracking', $slug ), $plugin_title );
|
45 |
-
$primary_cta_label = fs_text_inline( 'On second thought - I want to continue helping', 'opt-out-cancel', $slug );
|
46 |
-
}
|
47 |
-
|
48 |
-
$opt_out_message_clicking_opt_out = sprintf(
|
49 |
-
fs_text_inline( 'By clicking "Opt Out", we will no longer be sending any data from %s to %s.', 'opt-out-message-clicking-opt-out', $slug ),
|
50 |
-
$plugin_title,
|
51 |
-
sprintf(
|
52 |
-
'<a href="%s" target="_blank" rel="noopener">%s</a>',
|
53 |
-
'https://freemius.com',
|
54 |
-
'freemius.com'
|
55 |
-
)
|
56 |
-
);
|
57 |
|
58 |
-
|
59 |
-
'id' => '',
|
60 |
-
'slug' => $fs->get_id(),
|
61 |
-
'type' => 'success',
|
62 |
-
'sticky' => false,
|
63 |
-
'plugin' => $fs->get_plugin()->title,
|
64 |
-
'message' => $opt_in_message_appreciation
|
65 |
-
);
|
66 |
-
|
67 |
-
$admin_notice_html = fs_get_template( 'admin-notice.php', $admin_notice_params );
|
68 |
-
|
69 |
-
$modal_content_html = "
|
70 |
-
<h2" . ( $fs->is_premium() ? ' style="color: red"' : '' ) . ">{$opt_out_message_subtitle}</h2>
|
71 |
-
<div class=\"notice notice-error inline opt-out-error-message\"><p></p></div>
|
72 |
-
<p>{$opt_out_message_usage_tracking}</p>
|
73 |
-
<p>{$opt_out_message_clicking_opt_out}</p>
|
74 |
-
<label class=\"fs-permission-extensions\"><div class=\"fs-switch fs-small fs-round fs-" . ( $fs->is_extensions_tracking_allowed() ? 'on' : 'off' ) . "\"><div class=\"fs-toggle\"></div></div> " . fs_text_inline( 'Plugins & themes tracking' ) . " <span class=\"fs-switch-feedback success\"></span></label>";
|
75 |
|
76 |
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
|
|
77 |
fs_enqueue_local_style( 'fs_common', '/admin/common.css' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
<script type="text/javascript">
|
80 |
(function( $ ) {
|
81 |
$( document ).ready(function() {
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
+ ' <div class="fs-modal-panel active">' + modalContentHtml + '</div>'
|
91 |
-
+ ' </div>'
|
92 |
-
+ ' <div class="fs-modal-footer">'
|
93 |
-
+ ' <button class="button <?php echo $fs->is_premium() ? 'button-primary warn' : 'button-secondary' ?> button-opt-out" tabindex="1"><?php echo esc_js( $opt_out_text ) ?></button>'
|
94 |
-
+ ' <button class="button <?php echo $fs->is_premium() ? 'button-secondary' : 'button-primary' ?> button-close" tabindex="2"><?php echo esc_js( $primary_cta_label ) ?></button>'
|
95 |
-
+ ' </div>'
|
96 |
-
+ ' </div>'
|
97 |
-
+ '</div>',
|
98 |
-
$modal = $(modalHtml),
|
99 |
-
$adminNotice = $( <?php echo json_encode( $admin_notice_html ) ?> ),
|
100 |
-
action = '<?php echo $action ?>',
|
101 |
-
actionLinkSelector = 'span.opt-in-or-opt-out.<?php echo $slug ?> a',
|
102 |
-
$optOutButton = $modal.find( '.button-opt-out' ),
|
103 |
-
$optOutErrorMessage = $modal.find( '.opt-out-error-message' ),
|
104 |
-
$extensionsTracking = $modal.find( '.fs-permission-extensions' ),
|
105 |
-
$body = $( 'body' ),
|
106 |
-
moduleID = '<?php echo $fs->get_id() ?>';
|
107 |
-
|
108 |
-
$modal.data( 'action', action );
|
109 |
-
$modal.appendTo( $body );
|
110 |
-
|
111 |
-
function registerActionLinkClick() {
|
112 |
-
$body.on( 'click', actionLinkSelector, function( evt ) {
|
113 |
-
evt.preventDefault();
|
114 |
-
|
115 |
-
if ( 'stop_tracking' == $modal.data( 'action' ) ) {
|
116 |
-
showModal();
|
117 |
-
} else {
|
118 |
-
optIn();
|
119 |
-
}
|
120 |
-
|
121 |
-
return false;
|
122 |
-
});
|
123 |
-
}
|
124 |
-
|
125 |
-
function registerEventHandlers() {
|
126 |
-
registerActionLinkClick();
|
127 |
-
|
128 |
-
$modal.on( 'click', '.button-opt-out', function( evt ) {
|
129 |
-
evt.preventDefault();
|
130 |
-
|
131 |
-
if ( $( this ).hasClass( 'disabled' ) ) {
|
132 |
-
return;
|
133 |
-
}
|
134 |
-
|
135 |
-
disableOptOutButton();
|
136 |
-
optOut();
|
137 |
-
});
|
138 |
-
|
139 |
-
// If the user has clicked outside the window, close the modal.
|
140 |
-
$modal.on( 'click', '.fs-close, .button-close', function() {
|
141 |
-
closeModal();
|
142 |
-
return false;
|
143 |
-
});
|
144 |
-
}
|
145 |
-
|
146 |
-
<?php if ( $fs->is_registered() ) : ?>
|
147 |
-
registerEventHandlers();
|
148 |
-
<?php endif ?>
|
149 |
-
|
150 |
-
function showModal() {
|
151 |
-
resetModal();
|
152 |
-
|
153 |
-
// Display the dialog box.
|
154 |
-
$modal.addClass( 'active' );
|
155 |
-
$body.addClass( 'has-fs-modal' );
|
156 |
-
}
|
157 |
-
|
158 |
-
function closeModal() {
|
159 |
-
$modal.removeClass( 'active' );
|
160 |
-
$body.removeClass( 'has-fs-modal' );
|
161 |
-
}
|
162 |
-
|
163 |
-
function resetOptOutButton() {
|
164 |
-
enableOptOutButton();
|
165 |
-
$optOutButton.text( <?php echo json_encode( $opt_out_text ) ?> );
|
166 |
-
}
|
167 |
-
|
168 |
-
function resetModal() {
|
169 |
-
hideError();
|
170 |
-
resetOptOutButton();
|
171 |
-
}
|
172 |
-
|
173 |
-
function optIn() {
|
174 |
-
sendRequest();
|
175 |
-
}
|
176 |
-
|
177 |
-
function optOut() {
|
178 |
-
sendRequest();
|
179 |
-
}
|
180 |
-
|
181 |
-
function sendRequest() {
|
182 |
-
var $actionLink = $( actionLinkSelector );
|
183 |
-
|
184 |
-
$.ajax({
|
185 |
-
url: ajaxurl,
|
186 |
-
method: 'POST',
|
187 |
-
data: {
|
188 |
-
action : ( 'stop_tracking' == action ?
|
189 |
-
'<?php echo $fs->get_ajax_action( 'stop_tracking' ) ?>' :
|
190 |
-
'<?php echo $fs->get_ajax_action( 'allow_tracking' ) ?>'
|
191 |
-
),
|
192 |
-
security : ( 'stop_tracking' == action ?
|
193 |
-
'<?php echo $fs->get_ajax_security( 'stop_tracking' ) ?>' :
|
194 |
-
'<?php echo $fs->get_ajax_security( 'allow_tracking' ) ?>'
|
195 |
-
),
|
196 |
-
module_id: moduleID,
|
197 |
-
_wp_http_referer: '<?php echo $fs->current_page_url() ?>'
|
198 |
-
},
|
199 |
-
beforeSend: function() {
|
200 |
-
if ( 'allow_tracking' == action ) {
|
201 |
-
$actionLink.text( '<?php fs_esc_js_echo_inline( 'Opting in', 'opting-in', $slug ) ?>...' );
|
202 |
-
} else {
|
203 |
-
$optOutButton.text( '<?php fs_esc_js_echo_inline( 'Opting out', 'opting-out', $slug ) ?>...' );
|
204 |
-
}
|
205 |
-
},
|
206 |
-
success: function( resultObj ) {
|
207 |
-
if ( resultObj.success ) {
|
208 |
-
if ( 'allow_tracking' == action ) {
|
209 |
-
action = 'stop_tracking';
|
210 |
-
$actionLink.text( '<?php echo esc_js( $opt_out_text ) ?>' );
|
211 |
-
showOptInAppreciationMessageAndScrollToTop();
|
212 |
-
} else {
|
213 |
-
action = 'allow_tracking';
|
214 |
-
$actionLink.text( '<?php echo esc_js( $opt_in_text ) ?>' );
|
215 |
-
closeModal();
|
216 |
-
|
217 |
-
if ( $adminNotice.length > 0 ) {
|
218 |
-
$adminNotice.remove();
|
219 |
-
}
|
220 |
-
}
|
221 |
-
|
222 |
-
$modal.data( 'action', action );
|
223 |
-
} else {
|
224 |
-
showError( resultObj.error );
|
225 |
-
resetOptOutButton();
|
226 |
-
}
|
227 |
-
}
|
228 |
-
});
|
229 |
-
}
|
230 |
-
|
231 |
-
var isUpdatingPermission = false;
|
232 |
-
$extensionsTracking.on('click', function() {
|
233 |
-
if (isUpdatingPermission) {
|
234 |
-
return false;
|
235 |
-
}
|
236 |
-
|
237 |
-
isUpdatingPermission = true;
|
238 |
-
|
239 |
-
var $switch = $extensionsTracking.find( '.fs-switch' ),
|
240 |
-
$switchFeedback = $extensionsTracking.find( '.fs-switch-feedback' );
|
241 |
-
|
242 |
-
$switch
|
243 |
-
.toggleClass( 'fs-on' )
|
244 |
-
.toggleClass( 'fs-off' );
|
245 |
-
|
246 |
-
$switchFeedback.html( '<i class="fs-ajax-spinner"></i>' );
|
247 |
-
|
248 |
-
$.ajax({
|
249 |
-
url: ajaxurl,
|
250 |
-
method: 'POST',
|
251 |
-
data: {
|
252 |
-
action : '<?php echo $fs->get_ajax_action( 'update_tracking_permission' ) ?>',
|
253 |
-
security : '<?php echo $fs->get_ajax_security( 'update_tracking_permission' ) ?>',
|
254 |
-
module_id : moduleID,
|
255 |
-
_wp_http_referer: '<?php echo $fs->current_page_url() ?>',
|
256 |
-
permission: 'extensions',
|
257 |
-
is_enabled: $switch.hasClass('fs-on')
|
258 |
-
},
|
259 |
-
success: function( resultObj ) {
|
260 |
-
if ( resultObj.success ) {
|
261 |
-
$switchFeedback.html( '<i class="dashicons dashicons-yes"></i> <?php echo esc_js( fs_text_inline( 'Saved', 'saved', $slug ) ) ?>' )
|
262 |
-
} else {
|
263 |
-
$switch
|
264 |
-
.toggleClass( 'fs-on' )
|
265 |
-
.toggleClass( 'fs-off' );
|
266 |
-
}
|
267 |
-
|
268 |
-
isUpdatingPermission = false;
|
269 |
-
}
|
270 |
-
});
|
271 |
-
});
|
272 |
-
|
273 |
-
function enableOptOutButton() {
|
274 |
-
$optOutButton.removeClass( 'disabled' );
|
275 |
-
}
|
276 |
-
|
277 |
-
function disableOptOutButton() {
|
278 |
-
$optOutButton.addClass( 'disabled' );
|
279 |
-
}
|
280 |
-
|
281 |
-
function hideError() {
|
282 |
-
$optOutErrorMessage.hide();
|
283 |
-
}
|
284 |
-
|
285 |
-
function showOptInAppreciationMessageAndScrollToTop() {
|
286 |
-
$adminNotice.insertAfter( $( '#wpbody-content' ).find( ' > .wrap > h1' ) );
|
287 |
-
window.scrollTo(0, 0);
|
288 |
-
}
|
289 |
-
|
290 |
-
function showError( msg ) {
|
291 |
-
$optOutErrorMessage.find( ' > p' ).html( msg );
|
292 |
-
$optOutErrorMessage.show();
|
293 |
-
}
|
294 |
-
|
295 |
-
<?php if ( $fs->is_theme() ) : ?>
|
296 |
-
/**
|
297 |
-
* Add opt-in/out button to the active theme's buttons collection
|
298 |
-
* in the theme's extended details overlay.
|
299 |
-
*
|
300 |
-
* @author Vova Feldman (@svovaf)
|
301 |
-
* @since 1.2.2.7
|
302 |
-
*/
|
303 |
-
$('.theme-overlay').contentChange(function () {
|
304 |
-
if (0 === $('.theme-overlay.active').length) {
|
305 |
-
// Add opt-in/out button only to the currently active theme.
|
306 |
-
return;
|
307 |
-
}
|
308 |
-
|
309 |
-
if ($('#fs_theme_opt_in_out').length > 0){
|
310 |
-
// Button already there.
|
311 |
-
return;
|
312 |
-
}
|
313 |
-
|
314 |
-
var label = (('stop_tracking' == action) ?
|
315 |
-
'<?php echo esc_js( $opt_out_text ) ?>' :
|
316 |
-
'<?php echo esc_js( $opt_in_text ) ?>'),
|
317 |
-
href = (('stop_tracking' != action) ?
|
318 |
-
'<?php echo ( $fs->is_registered() ? '' : esc_js( $reconnect_url ) ) ?>' :
|
319 |
-
'');
|
320 |
-
|
321 |
-
var $actionLink = $('<a id="fs_theme_opt_in_out" href="' + encodeURI(href) + '" class="button">' + label + '</a>');
|
322 |
-
|
323 |
-
actionLinkSelector = '#fs_theme_opt_in_out';
|
324 |
-
|
325 |
-
$modal.data( 'action', action );
|
326 |
-
|
327 |
-
$('.theme-wrap .theme-actions .active-theme').append($actionLink);
|
328 |
-
|
329 |
-
if ('' === href) {
|
330 |
-
registerActionLinkClick();
|
331 |
-
}
|
332 |
-
});
|
333 |
-
<?php endif ?>
|
334 |
});
|
335 |
})( jQuery );
|
336 |
</script>
|
17 |
$fs = freemius( $VARS['id'] );
|
18 |
$slug = $fs->get_slug();
|
19 |
|
|
|
|
|
|
|
|
|
20 |
$reconnect_url = $fs->get_activation_url( array(
|
21 |
'nonce' => wp_create_nonce( $fs->get_unique_affix() . '_reconnect' ),
|
22 |
'fs_action' => ( $fs->get_unique_affix() . '_reconnect' ),
|
23 |
) );
|
24 |
|
25 |
+
$plugin_title = "<strong>" . esc_html( $fs->get_plugin()->title ) . "</strong>";
|
26 |
+
$opt_out_text = fs_text_x_inline( 'Opt Out', 'verb', 'opt-out', $slug );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
+
$permission_manager = FS_Permission_Manager::instance( $fs );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
31 |
+
fs_enqueue_local_style( 'fs_optout', '/admin/optout.css' );
|
32 |
fs_enqueue_local_style( 'fs_common', '/admin/common.css' );
|
33 |
+
|
34 |
+
if ( ! $fs->is_premium() ) {
|
35 |
+
$optional_permissions = array( $permission_manager->get_extensions_permission( false,
|
36 |
+
false,
|
37 |
+
true
|
38 |
+
) );
|
39 |
+
|
40 |
+
$permission_groups = array(
|
41 |
+
array(
|
42 |
+
'id' => 'communication',
|
43 |
+
'type' => 'required',
|
44 |
+
'title' => $fs->get_text_inline( 'Communication', 'communication' ),
|
45 |
+
'desc' => '',
|
46 |
+
'permissions' => $permission_manager->get_opt_in_required_permissions( true ),
|
47 |
+
'is_enabled' => $fs->is_registered(),
|
48 |
+
'prompt' => array(
|
49 |
+
$fs->esc_html_inline( "Sharing your name and email allows us to keep you in the loop about new features and important updates, warn you about security issues before they become public knowledge, and send you special offers.", 'opt-out-message_user' ),
|
50 |
+
sprintf(
|
51 |
+
$fs->esc_html_inline( 'By clicking "Opt Out", %s will no longer be able to view your name and email.',
|
52 |
+
'opt-out-message-clicking-opt-out' ),
|
53 |
+
$plugin_title
|
54 |
+
),
|
55 |
+
),
|
56 |
+
'prompt_cancel_label' => $fs->get_text_inline( 'Stay Connected', 'stay-connected' )
|
57 |
+
),
|
58 |
+
array(
|
59 |
+
'id' => 'diagnostic',
|
60 |
+
'type' => 'required',
|
61 |
+
'title' => $fs->get_text_inline( 'Diagnostic Info', 'diagnostic-info' ),
|
62 |
+
'desc' => '',
|
63 |
+
'permissions' => $permission_manager->get_opt_in_diagnostic_permissions( true ),
|
64 |
+
'is_enabled' => $fs->is_tracking_allowed(),
|
65 |
+
'prompt' => array(
|
66 |
+
sprintf(
|
67 |
+
$fs->esc_html_inline( 'Sharing diagnostic data helps to provide additional functionality that\'s relevant to your website, avoid WordPress or PHP version incompatibilities that can break the website, and recognize which languages & regions the %s should be translated and tailored to.',
|
68 |
+
'opt-out-message-clicking-opt-out' ),
|
69 |
+
$fs->get_module_type()
|
70 |
+
),
|
71 |
+
sprintf(
|
72 |
+
$fs->esc_html_inline( 'By clicking "Opt Out", diagnostic data will no longer be sent to %s.',
|
73 |
+
'opt-out-message-clicking-opt-out' ),
|
74 |
+
$plugin_title
|
75 |
+
),
|
76 |
+
),
|
77 |
+
'prompt_cancel_label' => $fs->get_text_inline( 'Keep Sharing', 'keep-sharing' )
|
78 |
+
),
|
79 |
+
array(
|
80 |
+
'id' => 'extensions',
|
81 |
+
'type' => 'optional',
|
82 |
+
'title' => $fs->get_text_inline( 'Extensions', 'extensions' ),
|
83 |
+
'desc' => '',
|
84 |
+
'permissions' => $optional_permissions,
|
85 |
+
),
|
86 |
+
);
|
87 |
+
} else {
|
88 |
+
$optional_permissions = $permission_manager->get_license_optional_permissions( false, true );
|
89 |
+
|
90 |
+
$permission_groups = array(
|
91 |
+
array(
|
92 |
+
'id' => 'essentials',
|
93 |
+
'type' => 'required',
|
94 |
+
'title' => $fs->esc_html_inline( 'Required', 'required' ),
|
95 |
+
'desc' => sprintf( $fs->esc_html_inline( 'For automatic delivery of security & feature updates, and license management & protection, %s needs to:',
|
96 |
+
'license-sync-disclaimer' ),
|
97 |
+
'<b>' . esc_html( $fs->get_plugin_title() ) . '</b>' ),
|
98 |
+
'permissions' => $permission_manager->get_license_required_permissions( true ),
|
99 |
+
'is_enabled' => $permission_manager->is_essentials_tracking_allowed(),
|
100 |
+
'prompt' => array(
|
101 |
+
sprintf( $fs->esc_html_inline( 'To ensure that security & feature updates are automatically delivered directly to your WordPress Admin Dashboard while protecting your license from unauthorized abuse, %2$s needs to view the website’s homepage URL, %1$s version, SDK version, and whether the %1$s is active.', 'premium-opt-out-message-usage-tracking' ), $fs->get_module_type(), $plugin_title ),
|
102 |
+
sprintf( $fs->esc_html_inline( 'By opting out from sharing this information with the updates server, you’ll have to check for new %1$s releases and manually download & install them. Not just a hassle, but missing an update can put your site at risk and cause undue compatibility issues, so we highly recommend keeping these essential permissions on.', 'opt-out-message-clicking-opt-out' ), $fs->get_module_type(), $plugin_title ),
|
103 |
+
),
|
104 |
+
'prompt_cancel_label' => $fs->get_text_inline( 'Keep automatic updates', 'premium-opt-out-cancel' )
|
105 |
+
),
|
106 |
+
array(
|
107 |
+
'id' => 'optional',
|
108 |
+
'type' => 'optional',
|
109 |
+
'title' => $fs->esc_html_inline( 'Optional', 'optional' ),
|
110 |
+
'desc' => sprintf( $fs->esc_html_inline( 'For ongoing compatibility with your website, you can optionally allow %s to:',
|
111 |
+
'optional-permissions-disclaimer' ), $plugin_title ),
|
112 |
+
'permissions' => $optional_permissions,
|
113 |
+
),
|
114 |
+
);
|
115 |
+
}
|
116 |
+
|
117 |
+
$ajax_action = 'toggle_permission_tracking';
|
118 |
+
|
119 |
+
$form_id = "fs_opt_out_{$fs->get_id()}";
|
120 |
?>
|
121 |
+
<div id="<?php echo $form_id ?>"
|
122 |
+
class="fs-modal fs-modal-opt-out"
|
123 |
+
data-plugin-id="<?php echo $fs->get_id() ?>"
|
124 |
+
data-action="<?php echo $fs->get_ajax_action( $ajax_action ) ?>"
|
125 |
+
data-security="<?php echo $fs->get_ajax_security( $ajax_action ) ?>"
|
126 |
+
style="display: none">
|
127 |
+
<div class="fs-modal-dialog">
|
128 |
+
<div class="fs-modal-header">
|
129 |
+
<h4><?php echo esc_html( $opt_out_text ) ?></h4>
|
130 |
+
<a href="!#" class="fs-close"><i class="dashicons dashicons-no" title="Dismiss"></i></a>
|
131 |
+
</div>
|
132 |
+
<div class="fs-opt-out-permissions">
|
133 |
+
<div class="fs-modal-body">
|
134 |
+
<div class="notice notice-error inline opt-out-error-message"><p></p></div>
|
135 |
+
<div class="fs-permissions fs-open">
|
136 |
+
<?php foreach ( $permission_groups as $i => $permission_group ) : ?>
|
137 |
+
<?php $permission_manager->render_permissions_group( $permission_group ) ?>
|
138 |
+
<?php if ( $i < count( $permission_groups ) - 1 ) : ?><hr><?php endif ?>
|
139 |
+
<?php endforeach ?>
|
140 |
+
</div>
|
141 |
+
</div>
|
142 |
+
<div class="fs-modal-footer">
|
143 |
+
<button class="button button-primary button-close" tabindex="1"><?php echo $fs->esc_html_inline( 'Done', 'done' ) ?></button>
|
144 |
+
</div>
|
145 |
+
</div>
|
146 |
+
<?php foreach ( $permission_groups as $i => $permission_group ) : ?>
|
147 |
+
<?php if ( ! empty( $permission_group[ 'prompt' ] ) ) : ?>
|
148 |
+
<div class="fs-<?php echo $permission_group[ 'id' ] ?>-opt-out fs-opt-out-disclaimer" data-group-id="<?php echo $permission_group[ 'id' ] ?>" style="display: none">
|
149 |
+
<div class="fs-modal-body">
|
150 |
+
<div class="fs-modal-panel active">
|
151 |
+
<div class="notice notice-error inline opt-out-error-message"><p></p></div>
|
152 |
+
<?php foreach ( $permission_group[ 'prompt' ] as $p ) : ?>
|
153 |
+
<p><?php echo $p ?></p>
|
154 |
+
<?php endforeach ?>
|
155 |
+
</div>
|
156 |
+
</div>
|
157 |
+
<div class="fs-modal-footer">
|
158 |
+
<a class="fs-opt-out-button" tabindex="2" href="#"><?php echo esc_html( $opt_out_text ) ?></a>
|
159 |
+
<button class="button button-primary fs-opt-out-cancel-button" tabindex="1"><?php echo esc_html( $permission_group[ 'prompt_cancel_label' ] ) ?></button>
|
160 |
+
</div>
|
161 |
+
</div>
|
162 |
+
<?php endif ?>
|
163 |
+
<?php endforeach ?>
|
164 |
+
</div>
|
165 |
+
</div>
|
166 |
+
|
167 |
+
<?php $permission_manager->require_permissions_js( false ) ?>
|
168 |
+
|
169 |
<script type="text/javascript">
|
170 |
(function( $ ) {
|
171 |
$( document ).ready(function() {
|
172 |
+
FS.OptOut(
|
173 |
+
'<?php echo $fs->get_id() ?>',
|
174 |
+
'<?php echo $slug ?>',
|
175 |
+
'<?php echo $fs->get_module_type() ?>',
|
176 |
+
<?php echo $fs->is_registered( true ) ? 'true' : 'false' ?>,
|
177 |
+
<?php echo $fs->is_tracking_allowed() ? 'true' : 'false' ?>,
|
178 |
+
'<?php echo esc_js( $reconnect_url ) ?>'
|
179 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
});
|
181 |
})( jQuery );
|
182 |
</script>
|
freemius/templates/forms/resend-key.php
CHANGED
@@ -54,7 +54,10 @@ HTML;
|
|
54 |
HTML;
|
55 |
}
|
56 |
|
57 |
-
|
|
|
|
|
|
|
58 |
$modal_content_html = <<< HTML
|
59 |
<div class="notice notice-error inline license-resend-message"><p></p></div>
|
60 |
<p>{$message_above_input_field}</p>
|
@@ -142,7 +145,7 @@ HTML;
|
|
142 |
}
|
143 |
|
144 |
$.ajax({
|
145 |
-
url :
|
146 |
method : 'POST',
|
147 |
data : {
|
148 |
action : '<?php echo $fs->get_ajax_action( 'resend_license_key' ) ?>',
|
54 |
HTML;
|
55 |
}
|
56 |
|
57 |
+
$message_above_input_field = $fs->is_only_premium() ?
|
58 |
+
fs_esc_html_inline( "Enter the email address you've used during the purchase and we will resend you the license key.", 'ask-for-upgrade-email-address-premium-only', $slug ) :
|
59 |
+
fs_esc_html_inline( "Enter the email address you've used for the upgrade below and we will resend you the license key.", 'ask-for-upgrade-email-address', $slug );
|
60 |
+
|
61 |
$modal_content_html = <<< HTML
|
62 |
<div class="notice notice-error inline license-resend-message"><p></p></div>
|
63 |
<p>{$message_above_input_field}</p>
|
145 |
}
|
146 |
|
147 |
$.ajax({
|
148 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
149 |
method : 'POST',
|
150 |
data : {
|
151 |
action : '<?php echo $fs->get_ajax_action( 'resend_license_key' ) ?>',
|
freemius/templates/forms/trial-start.php
CHANGED
@@ -80,7 +80,7 @@ HTML;
|
|
80 |
var $button = $(this);
|
81 |
|
82 |
$.ajax({
|
83 |
-
url :
|
84 |
method : 'POST',
|
85 |
data : {
|
86 |
action : '<?php echo $fs->get_ajax_action( 'start_trial' ) ?>',
|
80 |
var $button = $(this);
|
81 |
|
82 |
$.ajax({
|
83 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
84 |
method : 'POST',
|
85 |
data : {
|
86 |
action : '<?php echo $fs->get_ajax_action( 'start_trial' ) ?>',
|
freemius/templates/forms/user-change.php
CHANGED
@@ -194,7 +194,7 @@ HTML;
|
|
194 |
disableUserChangeButton();
|
195 |
|
196 |
$.ajax( {
|
197 |
-
url :
|
198 |
method : 'POST',
|
199 |
data : {
|
200 |
action : '<?php echo $fs->get_ajax_action( 'change_user' ) ?>',
|
194 |
disableUserChangeButton();
|
195 |
|
196 |
$.ajax( {
|
197 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
198 |
method : 'POST',
|
199 |
data : {
|
200 |
action : '<?php echo $fs->get_ajax_action( 'change_user' ) ?>',
|
freemius/templates/gdpr-optin-js.php
CHANGED
@@ -38,7 +38,7 @@
|
|
38 |
}
|
39 |
|
40 |
$.ajax({
|
41 |
-
url :
|
42 |
action : '<?php echo $fs->get_ajax_action( 'gdpr_optin_action' ) ?>',
|
43 |
security : '<?php echo $fs->get_ajax_security( 'gdpr_optin_action' ) ?>',
|
44 |
module_id: '<?php echo $fs->get_id() ?>'
|
38 |
}
|
39 |
|
40 |
$.ajax({
|
41 |
+
url : <?php echo Freemius::ajax_url() ?> + '?' + $.param({
|
42 |
action : '<?php echo $fs->get_ajax_action( 'gdpr_optin_action' ) ?>',
|
43 |
security : '<?php echo $fs->get_ajax_security( 'gdpr_optin_action' ) ?>',
|
44 |
module_id: '<?php echo $fs->get_id() ?>'
|
freemius/templates/js/permissions.php
ADDED
@@ -0,0 +1,546 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 2.5.1
|
7 |
+
*/
|
8 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
9 |
+
exit;
|
10 |
+
}
|
11 |
+
?>
|
12 |
+
<script type="text/javascript">
|
13 |
+
( function ( $ ) {
|
14 |
+
var global = this;
|
15 |
+
|
16 |
+
// Namespace.
|
17 |
+
global.FS = global.FS || {};
|
18 |
+
|
19 |
+
//region Switches
|
20 |
+
|
21 |
+
function toggleSwitches( $switches, isOn ) {
|
22 |
+
$switches
|
23 |
+
.toggleClass( 'fs-on', ( null != isOn ? ( true === isOn ) : isOn ) )
|
24 |
+
.toggleClass( 'fs-off', ( null != isOn ? ( false === isOn ) : isOn ) );
|
25 |
+
}
|
26 |
+
|
27 |
+
function isSwitch( $switch, isOn ) {
|
28 |
+
return $switch.hasClass( isOn ? 'fs-on' : 'fs-off' );
|
29 |
+
}
|
30 |
+
|
31 |
+
function getSwitchesStates( $switches, isEnabled ) {
|
32 |
+
var switchStates = [];
|
33 |
+
for ( var i = 0; i < $switches.length; i++ ) {
|
34 |
+
switchStates.push( isSwitch( $( $switches[ i ] ), isEnabled ) );
|
35 |
+
}
|
36 |
+
|
37 |
+
return switchStates;
|
38 |
+
}
|
39 |
+
|
40 |
+
//endregion
|
41 |
+
|
42 |
+
function toggleGroupOptOut( $button, isEnabled ) {
|
43 |
+
setOptInLabel( $button, ! isEnabled );
|
44 |
+
|
45 |
+
$button.data( 'is-enabled', isEnabled );
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @param {object} $permissionsSection
|
50 |
+
*
|
51 |
+
* @returns {string[]}
|
52 |
+
*/
|
53 |
+
function getGroupPermissionIDs( $permissionsSection ) {
|
54 |
+
var permissions = [];
|
55 |
+
$permissionsSection.find( 'ul li').each( function() {
|
56 |
+
permissions.push( $( this ).data( 'permission-id' ) );
|
57 |
+
});
|
58 |
+
|
59 |
+
return permissions;
|
60 |
+
}
|
61 |
+
|
62 |
+
function getGroupOptOutButton( $section ) {
|
63 |
+
return $section.find( '.fs-group-opt-out-button' );
|
64 |
+
}
|
65 |
+
|
66 |
+
//region Opt-in/out Labels
|
67 |
+
|
68 |
+
function setUpdatingLabel( $button, isEnabled ) {
|
69 |
+
$button.text( isEnabled ?
|
70 |
+
'<?php fs_esc_js_echo_inline( 'Opting in', 'opting-in' ) ?>...' :
|
71 |
+
'<?php fs_esc_js_echo_inline( 'Opting out', 'opting-out' ) ?>...'
|
72 |
+
);
|
73 |
+
}
|
74 |
+
|
75 |
+
function getOptInLabel( isEnabled ) {
|
76 |
+
return isEnabled ?
|
77 |
+
'<?php echo esc_js( fs_text_x_inline( 'Opt In', 'verb', 'opt-in' ) ) ?>' :
|
78 |
+
'<?php echo esc_js( fs_text_x_inline( 'Opt Out', 'verb', 'opt-out' ) ) ?>';
|
79 |
+
}
|
80 |
+
|
81 |
+
function setOptInLabel( $button, isEnabled ) {
|
82 |
+
$button.text( getOptInLabel( isEnabled ) );
|
83 |
+
}
|
84 |
+
|
85 |
+
//endregion
|
86 |
+
|
87 |
+
global.FS.Permissions = function () {
|
88 |
+
var isUpdating = false;
|
89 |
+
|
90 |
+
function updateStarted() {
|
91 |
+
isUpdating = true;
|
92 |
+
$body.addClass( 'fs-loading' );
|
93 |
+
}
|
94 |
+
|
95 |
+
function updateCompleted() {
|
96 |
+
isUpdating = false;
|
97 |
+
$body.removeClass( 'fs-loading' );
|
98 |
+
}
|
99 |
+
|
100 |
+
return {
|
101 |
+
isUpdating: function() {
|
102 |
+
return isUpdating;
|
103 |
+
},
|
104 |
+
/**
|
105 |
+
* @param {Number} pluginID
|
106 |
+
* @param {Array} permissions
|
107 |
+
* @param {Boolean} isEnabled
|
108 |
+
* @param {Callback} [success]
|
109 |
+
* @param {Callback} [failure]
|
110 |
+
* @param {Callback} [complete]
|
111 |
+
*/
|
112 |
+
updatePermissions: function(
|
113 |
+
pluginID,
|
114 |
+
permissions,
|
115 |
+
isEnabled,
|
116 |
+
success,
|
117 |
+
failure,
|
118 |
+
complete
|
119 |
+
) {
|
120 |
+
if ( isUpdating ) {
|
121 |
+
return;
|
122 |
+
}
|
123 |
+
|
124 |
+
updateStarted();
|
125 |
+
|
126 |
+
var
|
127 |
+
$permissionsContainer = $( '#fs_opt_out_' + pluginID );
|
128 |
+
|
129 |
+
$.ajax( {
|
130 |
+
url : <?php echo Freemius::ajax_url() ?>,
|
131 |
+
method : 'POST',
|
132 |
+
data : {
|
133 |
+
action : $permissionsContainer.data( 'action' ),
|
134 |
+
security : $permissionsContainer.data( 'security' ),
|
135 |
+
module_id : pluginID,
|
136 |
+
_wp_http_referer: '<?php echo Freemius::current_page_url() ?>',
|
137 |
+
permissions : permissions.join( ',' ),
|
138 |
+
is_enabled : isEnabled
|
139 |
+
},
|
140 |
+
success : function ( resultObj ) {
|
141 |
+
if ( resultObj.success ) {
|
142 |
+
if ( success ) {
|
143 |
+
success( resultObj );
|
144 |
+
}
|
145 |
+
} else {
|
146 |
+
if ( failure ) {
|
147 |
+
failure( resultObj );
|
148 |
+
}
|
149 |
+
}
|
150 |
+
},
|
151 |
+
error : failure,
|
152 |
+
complete: function () {
|
153 |
+
if ( complete ) {
|
154 |
+
complete();
|
155 |
+
}
|
156 |
+
|
157 |
+
updateCompleted();
|
158 |
+
}
|
159 |
+
});
|
160 |
+
},
|
161 |
+
updateGroupPermissions: function(
|
162 |
+
pluginID,
|
163 |
+
groupID,
|
164 |
+
isEnabled,
|
165 |
+
success,
|
166 |
+
failure,
|
167 |
+
complete
|
168 |
+
) {
|
169 |
+
if ( isUpdating ) {
|
170 |
+
return;
|
171 |
+
}
|
172 |
+
|
173 |
+
var
|
174 |
+
$modal = $( '#fs_opt_out_' + pluginID ),
|
175 |
+
$permissionsSection = $modal.find( '.fs-permissions-section.fs-' + groupID + '-permissions' ),
|
176 |
+
$optOutButton = getGroupOptOutButton( $permissionsSection ),
|
177 |
+
$permissions = $permissionsSection.find( 'ul li'),
|
178 |
+
permissions = [];
|
179 |
+
|
180 |
+
$permissions.each( function() {
|
181 |
+
permissions.push( $( this ).data( 'permission-id' ) );
|
182 |
+
});
|
183 |
+
|
184 |
+
setUpdatingLabel( $optOutButton, isEnabled );
|
185 |
+
|
186 |
+
this.updatePermissions(
|
187 |
+
pluginID,
|
188 |
+
permissions,
|
189 |
+
isEnabled,
|
190 |
+
function( resultObj ) {
|
191 |
+
if ( resultObj.success ) {
|
192 |
+
toggleGroupOptOut( $optOutButton, isEnabled );
|
193 |
+
|
194 |
+
// Update permissions state.
|
195 |
+
$permissions.toggleClass( 'fs-disabled', ! isEnabled );
|
196 |
+
|
197 |
+
// Update switches state, if there are any.
|
198 |
+
toggleSwitches( $permissions.find( '.fs-switch' ), isEnabled );
|
199 |
+
|
200 |
+
if ( success ) {
|
201 |
+
success();
|
202 |
+
}
|
203 |
+
}
|
204 |
+
},
|
205 |
+
function ( resultObj ) {
|
206 |
+
setOptInLabel( $optOutButton, isEnabled );
|
207 |
+
|
208 |
+
if ( failure ) {
|
209 |
+
failure( resultObj );
|
210 |
+
}
|
211 |
+
},
|
212 |
+
complete
|
213 |
+
);
|
214 |
+
}
|
215 |
+
};
|
216 |
+
}();
|
217 |
+
|
218 |
+
var $body = $( 'body' )
|
219 |
+
|
220 |
+
global.FS.OptOut = function (
|
221 |
+
pluginID,
|
222 |
+
slug,
|
223 |
+
type,
|
224 |
+
isRegistered,
|
225 |
+
isTrackingAllowed,
|
226 |
+
reconnectUrl
|
227 |
+
) {
|
228 |
+
var $modal = $( '#fs_opt_out_' + pluginID ),
|
229 |
+
actionLinkSelector = ('theme' === type ? '#fs_theme_opt_in_out' : 'span.opt-in-or-opt-out.' + slug + ' a' );
|
230 |
+
|
231 |
+
//region Error Handling
|
232 |
+
|
233 |
+
function hideError( $optOutErrorMessage ) {
|
234 |
+
$optOutErrorMessage = $optOutErrorMessage || $modal.find( '.opt-out-error-message' );
|
235 |
+
$optOutErrorMessage.hide();
|
236 |
+
}
|
237 |
+
|
238 |
+
function showError( $optOutErrorMessage, msg ) {
|
239 |
+
$optOutErrorMessage.find( ' > p' ).html( msg );
|
240 |
+
$optOutErrorMessage.show();
|
241 |
+
}
|
242 |
+
|
243 |
+
//endregion
|
244 |
+
|
245 |
+
function backToPermissionsList() {
|
246 |
+
$modal.find( '.fs-opt-out-disclaimer' )
|
247 |
+
.hide();
|
248 |
+
|
249 |
+
$modal.find( '.fs-opt-out-permissions' )
|
250 |
+
.show();
|
251 |
+
}
|
252 |
+
|
253 |
+
function removeFeedbackIndicators() {
|
254 |
+
$modal.find( '.fs-switch-feedback' )
|
255 |
+
.remove();
|
256 |
+
}
|
257 |
+
|
258 |
+
//region Modal Dialog
|
259 |
+
|
260 |
+
function closeModal() {
|
261 |
+
$modal.removeClass( 'active' );
|
262 |
+
$body.removeClass( 'has-fs-modal' );
|
263 |
+
$modal.hide();
|
264 |
+
}
|
265 |
+
|
266 |
+
function resetModal() {
|
267 |
+
hideError();
|
268 |
+
removeFeedbackIndicators();
|
269 |
+
backToPermissionsList();
|
270 |
+
}
|
271 |
+
|
272 |
+
function showModal() {
|
273 |
+
resetModal();
|
274 |
+
|
275 |
+
// Display the dialog box.
|
276 |
+
$modal.show();
|
277 |
+
$modal.addClass( 'active' );
|
278 |
+
$body.addClass( 'has-fs-modal' );
|
279 |
+
}
|
280 |
+
|
281 |
+
//endregion
|
282 |
+
|
283 |
+
function registerActionLinkClick() {
|
284 |
+
$body.on( 'click', actionLinkSelector, function( evt ) {
|
285 |
+
evt.preventDefault();
|
286 |
+
|
287 |
+
showModal();
|
288 |
+
|
289 |
+
return false;
|
290 |
+
});
|
291 |
+
}
|
292 |
+
|
293 |
+
function registerEventHandlers() {
|
294 |
+
// If the user has clicked outside the window, close the modal.
|
295 |
+
$modal.on( 'click', '.fs-close, .button-close', function() {
|
296 |
+
closeModal();
|
297 |
+
return false;
|
298 |
+
} );
|
299 |
+
|
300 |
+
$modal.on( 'click', '.fs-permissions .fs-switch', function () {
|
301 |
+
if ( FS.Permissions.isUpdating() ) {
|
302 |
+
return false;
|
303 |
+
}
|
304 |
+
|
305 |
+
var $switch = $( this ),
|
306 |
+
$permission = $switch.closest( '.fs-permission' );
|
307 |
+
|
308 |
+
toggleSwitches( $switch );
|
309 |
+
|
310 |
+
$permission.toggleClass( 'fs-disabled' );
|
311 |
+
|
312 |
+
var $optOutContainer = $switch.closest( '.fs-modal-opt-out' );
|
313 |
+
|
314 |
+
if ( 0 === $optOutContainer.length ) {
|
315 |
+
return;
|
316 |
+
}
|
317 |
+
|
318 |
+
// Remove previously added feedback element.
|
319 |
+
$switch.closest( '.fs-modal-dialog' )
|
320 |
+
.find( '.fs-switch-feedback' )
|
321 |
+
.remove();
|
322 |
+
|
323 |
+
var $switchFeedback = $( '<span class="fs-switch-feedback"><i class="fs-ajax-spinner"></i></span>' );
|
324 |
+
|
325 |
+
$switch.after( $switchFeedback )
|
326 |
+
|
327 |
+
var
|
328 |
+
permissionID = $permission.data( 'permission-id' ),
|
329 |
+
isEnabled = isSwitch( $switch, true );
|
330 |
+
|
331 |
+
FS.Permissions.updatePermissions(
|
332 |
+
$optOutContainer.data( 'plugin-id' ),
|
333 |
+
[ permissionID ],
|
334 |
+
isEnabled,
|
335 |
+
function () {
|
336 |
+
$switchFeedback.addClass( 'success' );
|
337 |
+
$switchFeedback.html( '<i class="dashicons dashicons-yes"></i> <?php echo esc_js( fs_text_inline( 'Saved', 'saved' ) ) ?>' );
|
338 |
+
|
339 |
+
var
|
340 |
+
$permissionsGroup = $switch.closest( '.fs-permissions-section' ),
|
341 |
+
$groupPermissions = $permissionsGroup.find( 'ul li' );
|
342 |
+
|
343 |
+
var allGroupPermissionsUseSameValue = false;
|
344 |
+
|
345 |
+
if (
|
346 |
+
isEnabled &&
|
347 |
+
0 === $groupPermissions.filter( '.fs-disabled' ).length )
|
348 |
+
{
|
349 |
+
allGroupPermissionsUseSameValue = true;
|
350 |
+
} else if (
|
351 |
+
! isEnabled &&
|
352 |
+
$groupPermissions.length === $groupPermissions.filter( '.fs-disabled' ).length
|
353 |
+
) {
|
354 |
+
allGroupPermissionsUseSameValue = true;
|
355 |
+
}
|
356 |
+
|
357 |
+
if ( allGroupPermissionsUseSameValue ) {
|
358 |
+
toggleGroupOptOut( getGroupOptOutButton( $permissionsGroup ), isEnabled );
|
359 |
+
}
|
360 |
+
},
|
361 |
+
function () {
|
362 |
+
// Revert switch.
|
363 |
+
toggleSwitches( $switch );
|
364 |
+
|
365 |
+
$switchFeedback.remove();
|
366 |
+
}
|
367 |
+
)
|
368 |
+
});
|
369 |
+
|
370 |
+
// Move back to the permissions list if cancelling opt-out.
|
371 |
+
$modal.on( 'click', '.fs-opt-out-disclaimer .fs-opt-out-cancel-button', function ( evt ) {
|
372 |
+
backToPermissionsList();
|
373 |
+
});
|
374 |
+
|
375 |
+
$modal.on( 'click', '.fs-opt-out-disclaimer .fs-modal-footer .fs-opt-out-button', function ( evt ) {
|
376 |
+
var
|
377 |
+
$optOutButton = $( this ),
|
378 |
+
$actionLink = $( actionLinkSelector ),
|
379 |
+
isEnabled = true,
|
380 |
+
$optOutDisclaimer = $( $optOutButton.closest( '.fs-opt-out-disclaimer' )[ 0 ] ),
|
381 |
+
groupID = $optOutDisclaimer.data( 'group-id' ),
|
382 |
+
$errorMessage = $optOutDisclaimer.find( '.opt-out-error-message' );
|
383 |
+
|
384 |
+
setUpdatingLabel( $optOutButton, ! isEnabled );
|
385 |
+
|
386 |
+
$optOutDisclaimer.find( '.button-primary' ).prop( 'disabled', true );
|
387 |
+
|
388 |
+
hideError( $errorMessage );
|
389 |
+
|
390 |
+
FS.Permissions.updateGroupPermissions(
|
391 |
+
pluginID,
|
392 |
+
groupID,
|
393 |
+
! isEnabled,
|
394 |
+
function () {
|
395 |
+
if ( 'communication' === groupID ) {
|
396 |
+
window.location.reload();
|
397 |
+
} else {
|
398 |
+
setOptInLabel( $actionLink, ! isEnabled );
|
399 |
+
|
400 |
+
backToPermissionsList();
|
401 |
+
}
|
402 |
+
},
|
403 |
+
function ( resultObj ) {
|
404 |
+
setOptInLabel( $optOutButton, false );
|
405 |
+
|
406 |
+
showError( $errorMessage, resultObj.error );
|
407 |
+
},
|
408 |
+
function () {
|
409 |
+
if ( 'communication' !== groupID ) {
|
410 |
+
setOptInLabel( $optOutButton, false );
|
411 |
+
}
|
412 |
+
|
413 |
+
$optOutDisclaimer.find( '.button-primary' ).prop( 'disabled', false );
|
414 |
+
}
|
415 |
+
);
|
416 |
+
} );
|
417 |
+
|
418 |
+
$modal.on( 'click', '.fs-group-opt-out-button', function ( evt ) {
|
419 |
+
evt.preventDefault();
|
420 |
+
|
421 |
+
if ( FS.Permissions.isUpdating() ) {
|
422 |
+
return;
|
423 |
+
}
|
424 |
+
|
425 |
+
var
|
426 |
+
$optOutButton = $( this ),
|
427 |
+
groupID = $optOutButton.data( 'group-id' ),
|
428 |
+
isEnabled = $optOutButton.data( 'is-enabled' ),
|
429 |
+
$optOutDisclaimer = $modal.find( '.fs-' + groupID + '-opt-out' ),
|
430 |
+
isConfirmRequired = ( 0 < $optOutDisclaimer.length ),
|
431 |
+
$errorMessage = $modal.find( '.fs-opt-out-permissions .opt-out-error-message' );
|
432 |
+
|
433 |
+
$errorMessage.hide();
|
434 |
+
|
435 |
+
if ( isConfirmRequired ) {
|
436 |
+
if ( isEnabled ) {
|
437 |
+
// Move to disclaimer window.
|
438 |
+
$modal.find( '.fs-opt-out-permissions' )
|
439 |
+
.hide();
|
440 |
+
|
441 |
+
$optOutDisclaimer.show();
|
442 |
+
} else {
|
443 |
+
// Opt-in.
|
444 |
+
FS.Permissions.updateGroupPermissions(
|
445 |
+
pluginID,
|
446 |
+
groupID,
|
447 |
+
! isEnabled,
|
448 |
+
( 'communication' !== groupID ) ?
|
449 |
+
null :
|
450 |
+
function () {
|
451 |
+
window.location.reload();
|
452 |
+
},
|
453 |
+
function ( resultObj ) {
|
454 |
+
showError( $errorMessage, resultObj.error );
|
455 |
+
}
|
456 |
+
);
|
457 |
+
}
|
458 |
+
} else {
|
459 |
+
// Remove previously added feedback element.
|
460 |
+
$modal.find( '.fs-switch-feedback' )
|
461 |
+
.remove();
|
462 |
+
|
463 |
+
var $switches = $optOutButton.closest( '.fs-permissions-section' )
|
464 |
+
.find( '.fs-permission .fs-switch' );
|
465 |
+
|
466 |
+
var switchStates = getSwitchesStates( $switches, isEnabled );
|
467 |
+
|
468 |
+
toggleSwitches( $switches, ! isEnabled );
|
469 |
+
|
470 |
+
$switches.closest( '.fs-permission' )
|
471 |
+
.toggleClass( 'fs-disabled', isEnabled );
|
472 |
+
|
473 |
+
var $switchFeedback = $( '<span class="fs-switch-feedback"><i class="fs-ajax-spinner"></i></span>' );
|
474 |
+
|
475 |
+
$optOutButton.after( $switchFeedback )
|
476 |
+
|
477 |
+
setUpdatingLabel( $optOutButton, ! isEnabled );
|
478 |
+
|
479 |
+
FS.Permissions.updatePermissions(
|
480 |
+
pluginID,
|
481 |
+
getGroupPermissionIDs( $modal.find( '.fs-permissions-section.fs-' + groupID + '-permissions' ) ),
|
482 |
+
! isEnabled,
|
483 |
+
function () {
|
484 |
+
$switchFeedback.addClass( 'success' );
|
485 |
+
$switchFeedback.html( '<i class="dashicons dashicons-yes"></i> <?php echo esc_js( fs_text_inline( 'Saved', 'saved' ) ) ?>' );
|
486 |
+
|
487 |
+
toggleGroupOptOut( $optOutButton, ! isEnabled );
|
488 |
+
},
|
489 |
+
function () {
|
490 |
+
// Revert switches to their previous state.
|
491 |
+
for ( var i = 0; i < switchStates.length; i++ ) {
|
492 |
+
if ( switchStates[ i ] ) {
|
493 |
+
toggleSwitches( $( $switches[ i ] ), isEnabled );
|
494 |
+
$( $switches[ i ] ).removeClass( 'fs-disabled' );
|
495 |
+
}
|
496 |
+
}
|
497 |
+
|
498 |
+
toggleGroupOptOut( $optOutButton, isEnabled );
|
499 |
+
}
|
500 |
+
)
|
501 |
+
}
|
502 |
+
});
|
503 |
+
}
|
504 |
+
|
505 |
+
if ( 'theme' === type ) {
|
506 |
+
/**
|
507 |
+
* Add opt-in/out button to the active theme's buttons collection
|
508 |
+
* in the theme's extended details overlay.
|
509 |
+
*
|
510 |
+
* @author Vova Feldman (@svovaf)
|
511 |
+
* @since 1.2.2.7
|
512 |
+
*/
|
513 |
+
$( '.theme-overlay' ).contentChange( function () {
|
514 |
+
if ( 0 === $( '.theme-overlay.active' ).length ) {
|
515 |
+
// Add opt-in/out button only to the currently active theme.
|
516 |
+
return;
|
517 |
+
}
|
518 |
+
|
519 |
+
if ( $( '#fs_theme_opt_in_out' ).length > 0 ) {
|
520 |
+
// Button already there.
|
521 |
+
return;
|
522 |
+
}
|
523 |
+
|
524 |
+
var label = getOptInLabel( ! isTrackingAllowed ),
|
525 |
+
href = ( isTrackingAllowed || isRegistered ) ? '' : reconnectUrl,
|
526 |
+
$actionLink = $( '<a id="fs_theme_opt_in_out" href="' + encodeURI( href ) + '" class="button">' + label + '</a>' );
|
527 |
+
|
528 |
+
$( '.theme-wrap .theme-actions .active-theme' ).append( $actionLink );
|
529 |
+
|
530 |
+
if ( isRegistered && '' === href ) {
|
531 |
+
registerActionLinkClick();
|
532 |
+
}
|
533 |
+
});
|
534 |
+
}
|
535 |
+
|
536 |
+
if ( isRegistered ) {
|
537 |
+
if ( 'theme' !== type ) {
|
538 |
+
registerActionLinkClick();
|
539 |
+
}
|
540 |
+
|
541 |
+
registerEventHandlers();
|
542 |
+
}
|
543 |
+
|
544 |
+
};
|
545 |
+
} )( jQuery );
|
546 |
+
</script>
|
freemius/templates/partials/network-activation.php
CHANGED
@@ -58,7 +58,7 @@
|
|
58 |
<div class="fs-sites-list-container">
|
59 |
<table cellspacing="0">
|
60 |
<tbody>
|
61 |
-
<?php $site_props = array('uid', 'url', 'title', '
|
62 |
<?php foreach ( $sites as $site ) : ?>
|
63 |
<tr<?php if ( ! empty( $site['license_id'] ) ) {
|
64 |
echo ' data-license-id="' . $site['license_id'] . '"';
|
58 |
<div class="fs-sites-list-container">
|
59 |
<table cellspacing="0">
|
60 |
<tbody>
|
61 |
+
<?php $site_props = array('uid', 'url', 'title', 'language') ?>
|
62 |
<?php foreach ( $sites as $site ) : ?>
|
63 |
<tr<?php if ( ! empty( $site['license_id'] ) ) {
|
64 |
echo ' data-license-id="' . $site['license_id'] . '"';
|
freemius/templates/plugin-icon.php
CHANGED
@@ -14,7 +14,9 @@
|
|
14 |
* @var array $VARS
|
15 |
*/
|
16 |
$fs = freemius( $VARS['id'] );
|
|
|
|
|
17 |
?>
|
18 |
<div class="fs-plugin-icon">
|
19 |
-
<img src="<?php echo $fs->get_local_icon_url() ?>" width="
|
20 |
</div>
|
14 |
* @var array $VARS
|
15 |
*/
|
16 |
$fs = freemius( $VARS['id'] );
|
17 |
+
|
18 |
+
$size = isset( $VARS['size'] ) ? $VARS['size'] : 80;
|
19 |
?>
|
20 |
<div class="fs-plugin-icon">
|
21 |
+
<img src="<?php echo $fs->get_local_icon_url() ?>" width="<?php echo $size ?>" height="<?php echo $size ?>" />
|
22 |
</div>
|
freemius/templates/plugin-info/description.php
CHANGED
@@ -52,7 +52,7 @@
|
|
52 |
<?php if ( ! empty( $plugin->info->screenshots ) ) : ?>
|
53 |
<?php $screenshots = $plugin->info->screenshots ?>
|
54 |
<div class="fs-screenshots clearfix">
|
55 |
-
<
|
56 |
<ul>
|
57 |
<?php $i = 0;
|
58 |
foreach ( $screenshots as $s => $url ) : ?>
|
52 |
<?php if ( ! empty( $plugin->info->screenshots ) ) : ?>
|
53 |
<?php $screenshots = $plugin->info->screenshots ?>
|
54 |
<div class="fs-screenshots clearfix">
|
55 |
+
<h3><?php fs_esc_html_echo_inline( 'Screenshots', 'screenshots', $plugin->slug ) ?></h3>
|
56 |
<ul>
|
57 |
<?php $i = 0;
|
58 |
foreach ( $screenshots as $s => $url ) : ?>
|
freemius/templates/plugin-info/features.php
CHANGED
@@ -43,7 +43,7 @@
|
|
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 |
-
|
47 |
}
|
48 |
|
49 |
$features_plan_map[ $support_feature->id ]['plans'][ $plan->id ] = $support_feature;
|
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;
|
freemius/templates/powered-by.php
CHANGED
@@ -33,12 +33,12 @@
|
|
33 |
|
34 |
$fs = freemius( $VARS['module_id'] );
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
<div id="pframe"></div>
|
43 |
<script type="text/javascript">
|
44 |
(function ($) {
|
@@ -58,4 +58,4 @@
|
|
58 |
});
|
59 |
})(jQuery);
|
60 |
</script>
|
61 |
-
<?php
|
33 |
|
34 |
$fs = freemius( $VARS['module_id'] );
|
35 |
|
36 |
+
if ( ! $fs->is_whitelabeled() && ! $fs->apply_filters( 'hide_freemius_powered_by', false ) ) {
|
37 |
+
wp_enqueue_script( 'jquery' );
|
38 |
+
wp_enqueue_script( 'json2' );
|
39 |
+
fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
|
40 |
+
fs_enqueue_local_script( 'fs-postmessage', 'postmessage.js' );
|
41 |
+
?>
|
42 |
<div id="pframe"></div>
|
43 |
<script type="text/javascript">
|
44 |
(function ($) {
|
58 |
});
|
59 |
})(jQuery);
|
60 |
</script>
|
61 |
+
<?php } ?>
|
freemius/templates/pricing.php
CHANGED
@@ -88,7 +88,8 @@
|
|
88 |
// Billing cycle.
|
89 |
'billing_cycle' => fs_request_get( 'billing_cycle', WP_FS__PERIOD_ANNUALLY ),
|
90 |
'is_network_admin' => fs_is_network_admin() ? 'true' : 'false',
|
91 |
-
|
|
|
92 |
) );
|
93 |
|
94 |
$use_external_pricing = $fs->should_use_external_pricing();
|
@@ -122,21 +123,21 @@
|
|
122 |
<div id="fs_pricing_wrapper" data-public-url="<?php echo trailingslashit( dirname( $pricing_js_url ) ) ?>"></div>
|
123 |
<?php
|
124 |
$pricing_config = array_merge( array(
|
125 |
-
'contact_url'
|
126 |
-
'
|
127 |
-
'
|
128 |
-
'
|
129 |
-
'
|
130 |
-
'
|
131 |
-
'request_handler_url' => admin_url(
|
132 |
'admin-ajax.php?' . http_build_query( array(
|
133 |
'module_id' => $fs->get_id(),
|
134 |
'action' => $fs->get_ajax_action( 'pricing_ajax_action' ),
|
135 |
'security' => $fs->get_ajax_security( 'pricing_ajax_action' )
|
136 |
) )
|
137 |
),
|
138 |
-
'selector'
|
139 |
-
'unique_affix'
|
|
|
140 |
), $query_params );
|
141 |
|
142 |
wp_add_inline_script( 'freemius-pricing', 'Freemius.pricing.new( ' . json_encode( $pricing_config ) . ' )' );
|
@@ -206,4 +207,4 @@
|
|
206 |
'module_slug' => $slug,
|
207 |
'module_version' => $fs->get_plugin_version(),
|
208 |
);
|
209 |
-
fs_require_template( 'powered-by.php', $params );
|
88 |
// Billing cycle.
|
89 |
'billing_cycle' => fs_request_get( 'billing_cycle', WP_FS__PERIOD_ANNUALLY ),
|
90 |
'is_network_admin' => fs_is_network_admin() ? 'true' : 'false',
|
91 |
+
'currency' => $fs->apply_filters( 'default_currency', 'usd' ),
|
92 |
+
'discounts_model' => $fs->apply_filters( 'pricing/discounts_model', 'absolute' ),
|
93 |
) );
|
94 |
|
95 |
$use_external_pricing = $fs->should_use_external_pricing();
|
123 |
<div id="fs_pricing_wrapper" data-public-url="<?php echo trailingslashit( dirname( $pricing_js_url ) ) ?>"></div>
|
124 |
<?php
|
125 |
$pricing_config = array_merge( array(
|
126 |
+
'contact_url' => $fs->contact_url(),
|
127 |
+
'is_production' => ( defined( 'WP_FS__IS_PRODUCTION_MODE' ) ? WP_FS__IS_PRODUCTION_MODE : null ),
|
128 |
+
'menu_slug' => $fs->get_menu_slug(),
|
129 |
+
'mode' => 'dashboard',
|
130 |
+
'fs_wp_endpoint_url' => WP_FS__ADDRESS,
|
131 |
+
'request_handler_url' => admin_url(
|
|
|
132 |
'admin-ajax.php?' . http_build_query( array(
|
133 |
'module_id' => $fs->get_id(),
|
134 |
'action' => $fs->get_ajax_action( 'pricing_ajax_action' ),
|
135 |
'security' => $fs->get_ajax_security( 'pricing_ajax_action' )
|
136 |
) )
|
137 |
),
|
138 |
+
'selector' => '#fs_pricing_wrapper',
|
139 |
+
'unique_affix' => $fs->get_unique_affix(),
|
140 |
+
'show_annual_in_monthly' => $fs->apply_filters( 'pricing/show_annual_in_monthly', true ),
|
141 |
), $query_params );
|
142 |
|
143 |
wp_add_inline_script( 'freemius-pricing', 'Freemius.pricing.new( ' . json_encode( $pricing_config ) . ' )' );
|
207 |
'module_slug' => $slug,
|
208 |
'module_version' => $fs->get_plugin_version(),
|
209 |
);
|
210 |
+
fs_require_template( 'powered-by.php', $params );
|
freemius/templates/sticky-admin-notice-js.php
CHANGED
@@ -29,8 +29,7 @@
|
|
29 |
message_id: id
|
30 |
};
|
31 |
|
32 |
-
|
33 |
-
$.post( ajaxurl, data, function( response ) {
|
34 |
|
35 |
});
|
36 |
|
29 |
message_id: id
|
30 |
};
|
31 |
|
32 |
+
$.post( <?php echo Freemius::ajax_url() ?>, data, function( response ) {
|
|
|
33 |
|
34 |
});
|
35 |
|
freemius/templates/tabs-capture-js.php
CHANGED
@@ -45,7 +45,7 @@
|
|
45 |
var tabsHtml = $('.wrap .nav-tab-wrapper').clone().wrap('<div>').parent().html();
|
46 |
|
47 |
$.ajax({
|
48 |
-
url :
|
49 |
action : '<?php echo $fs->get_ajax_action( 'store_tabs' ) ?>',
|
50 |
security : '<?php echo $fs->get_ajax_security( 'store_tabs' ) ?>',
|
51 |
module_id: '<?php echo $fs->get_id() ?>'
|
45 |
var tabsHtml = $('.wrap .nav-tab-wrapper').clone().wrap('<div>').parent().html();
|
46 |
|
47 |
$.ajax({
|
48 |
+
url : <?php echo Freemius::ajax_url() ?> + '?' + $.param({
|
49 |
action : '<?php echo $fs->get_ajax_action( 'store_tabs' ) ?>',
|
50 |
security : '<?php echo $fs->get_ajax_security( 'store_tabs' ) ?>',
|
51 |
module_id: '<?php echo $fs->get_id() ?>'
|
includes/class-wp-mobile-menu-core.php
CHANGED
@@ -593,10 +593,11 @@ class WP_Mobile_Menu_Core
|
|
593 |
// Only build the menu it there is a menu assigned to it.
|
594 |
|
595 |
if ( '' !== $current_menu ) {
|
|
|
596 |
// Display the menu.
|
597 |
$output = wp_nav_menu( array(
|
598 |
$menu_param => $current_menu,
|
599 |
-
'items_wrap' => '<ul id="mobmenu' . $menu . '" role="menubar" aria-label="' . __( 'Main navigation for mobile devices', 'mobile-menu' ) . '">%3$s</ul>',
|
600 |
'fallback_cb' => false,
|
601 |
'depth' => $this->mobmenu_depth,
|
602 |
'walker' => new WP_Mobile_Menu_Walker_Nav_Menu( $menu, '' ),
|
@@ -632,7 +633,7 @@ class WP_Mobile_Menu_Core
|
|
632 |
$current_menu = $this->plugin_settings->getOption( $menu . '_menu_tab_1' );
|
633 |
$output .= wp_nav_menu( array(
|
634 |
'menu' => $current_menu,
|
635 |
-
'items_wrap' => '<ul id="mobmenu' . $menu . '" role="menubar" aria-label="' . __( 'Main navigation for mobile devices', 'mobile-menu' ) . '">%3$s</ul>',
|
636 |
'fallback_cb' => false,
|
637 |
'depth' => $this->mobmenu_depth,
|
638 |
'walker' => new WP_Mobile_Menu_Walker_Nav_Menu( $menu, '' ),
|
@@ -642,7 +643,7 @@ class WP_Mobile_Menu_Core
|
|
642 |
$output .= '</div><div class="mobmenu-tab mobmenu-tab-2">';
|
643 |
$output .= wp_nav_menu( array(
|
644 |
'menu' => $current_menu,
|
645 |
-
'items_wrap' => '<ul id="mobmenu' . $menu . '" role="menubar" aria-label="' . __( 'Main navigation for mobile devices', 'mobile-menu' ) . '">%3$s</ul>',
|
646 |
'fallback_cb' => false,
|
647 |
'depth' => $this->mobmenu_depth,
|
648 |
'walker' => new WP_Mobile_Menu_Walker_Nav_Menu( $menu, '' ),
|
@@ -669,7 +670,7 @@ class WP_Mobile_Menu_Core
|
|
669 |
// Display the menu.
|
670 |
$output = wp_nav_menu( array(
|
671 |
$menu_param => $current_menu,
|
672 |
-
'items_wrap' => '<ul id="mobmenu' . $menu . '" role="menubar" aria-label="' . __( 'Main navigation for mobile devices', 'mobile-menu' ) . '">%3$s</ul>',
|
673 |
'fallback_cb' => false,
|
674 |
'depth' => $this->mobmenu_depth,
|
675 |
'walker' => new WP_Mobile_Menu_Walker_Nav_Menu( $menu, '' ),
|
@@ -707,19 +708,6 @@ class WP_Mobile_Menu_Core
|
|
707 |
|
708 |
}
|
709 |
|
710 |
-
/**
|
711 |
-
*
|
712 |
-
* Register Pay With Stripe Elementor Widget.
|
713 |
-
*
|
714 |
-
* @since 1.0.1
|
715 |
-
*/
|
716 |
-
public function mobmenu_el_init_widgets()
|
717 |
-
{
|
718 |
-
// Include Widget files
|
719 |
-
require_once __DIR__ . '/widgets/mobile-menu.php';
|
720 |
-
// Register widget
|
721 |
-
\Elementor\Plugin::instance()->widgets_manager->register_widget_type( new \Mobile_Menu_El_Menu_Widget() );
|
722 |
-
}
|
723 |
|
724 |
/**
|
725 |
* Register the Mobile Menus.
|
@@ -767,6 +755,7 @@ class WP_Mobile_Menu_Core
|
|
767 |
$logo_img = $logo_img[0];
|
768 |
}
|
769 |
|
|
|
770 |
$logo_output = '';
|
771 |
$logo_url = '';
|
772 |
$logo_url_end = '';
|
@@ -776,13 +765,17 @@ class WP_Mobile_Menu_Core
|
|
776 |
if ( $plugin_settings->getOption( 'logo_img_retina' ) ) {
|
777 |
$logo_img_retina = wp_get_attachment_image_src( $plugin_settings->getOption( 'logo_img_retina' ), 'full' );
|
778 |
|
779 |
-
if ( $logo_img_retina == null ) {
|
780 |
-
$logo_img_retina =
|
781 |
} else {
|
782 |
$logo_img_retina = $logo_img_retina[0];
|
|
|
|
|
|
|
|
|
|
|
783 |
}
|
784 |
-
|
785 |
-
$logo_img_retina_metadata = wp_get_attachment_metadata( $plugin_settings->getOption( 'logo_img_retina' ) );
|
786 |
}
|
787 |
|
788 |
|
@@ -804,6 +797,7 @@ class WP_Mobile_Menu_Core
|
|
804 |
}
|
805 |
|
806 |
$logo_url_end = '</a>';
|
|
|
807 |
$logo_url = '<a href="' . $logo_url . '" class="headertext">';
|
808 |
}
|
809 |
|
593 |
// Only build the menu it there is a menu assigned to it.
|
594 |
|
595 |
if ( '' !== $current_menu ) {
|
596 |
+
$current_menu = apply_filters( 'wp_mobile_menu_current_menu', $current_menu, $menu );
|
597 |
// Display the menu.
|
598 |
$output = wp_nav_menu( array(
|
599 |
$menu_param => $current_menu,
|
600 |
+
'items_wrap' => '<ul id="mobmenu' . $menu . '" class="wp-mobile-menu" role="menubar" aria-label="' . __( 'Main navigation for mobile devices', 'mobile-menu' ) . '">%3$s</ul>',
|
601 |
'fallback_cb' => false,
|
602 |
'depth' => $this->mobmenu_depth,
|
603 |
'walker' => new WP_Mobile_Menu_Walker_Nav_Menu( $menu, '' ),
|
633 |
$current_menu = $this->plugin_settings->getOption( $menu . '_menu_tab_1' );
|
634 |
$output .= wp_nav_menu( array(
|
635 |
'menu' => $current_menu,
|
636 |
+
'items_wrap' => '<ul id="mobmenu' . $menu . '" class="wp-mobile-menu" role="menubar" aria-label="' . __( 'Main navigation for mobile devices', 'mobile-menu' ) . '">%3$s</ul>',
|
637 |
'fallback_cb' => false,
|
638 |
'depth' => $this->mobmenu_depth,
|
639 |
'walker' => new WP_Mobile_Menu_Walker_Nav_Menu( $menu, '' ),
|
643 |
$output .= '</div><div class="mobmenu-tab mobmenu-tab-2">';
|
644 |
$output .= wp_nav_menu( array(
|
645 |
'menu' => $current_menu,
|
646 |
+
'items_wrap' => '<ul id="mobmenu' . $menu . '" class="wp-mobile-menu" role="menubar" aria-label="' . __( 'Main navigation for mobile devices', 'mobile-menu' ) . '">%3$s</ul>',
|
647 |
'fallback_cb' => false,
|
648 |
'depth' => $this->mobmenu_depth,
|
649 |
'walker' => new WP_Mobile_Menu_Walker_Nav_Menu( $menu, '' ),
|
670 |
// Display the menu.
|
671 |
$output = wp_nav_menu( array(
|
672 |
$menu_param => $current_menu,
|
673 |
+
'items_wrap' => '<ul id="mobmenu' . $menu . '" class="wp-mobile-menu" role="menubar" aria-label="' . __( 'Main navigation for mobile devices', 'mobile-menu' ) . '">%3$s</ul>',
|
674 |
'fallback_cb' => false,
|
675 |
'depth' => $this->mobmenu_depth,
|
676 |
'walker' => new WP_Mobile_Menu_Walker_Nav_Menu( $menu, '' ),
|
708 |
|
709 |
}
|
710 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
711 |
|
712 |
/**
|
713 |
* Register the Mobile Menus.
|
755 |
$logo_img = $logo_img[0];
|
756 |
}
|
757 |
|
758 |
+
$logo_img = apply_filters( 'wp_mobile_menu_logo_img', $logo_img );
|
759 |
$logo_output = '';
|
760 |
$logo_url = '';
|
761 |
$logo_url_end = '';
|
765 |
if ( $plugin_settings->getOption( 'logo_img_retina' ) ) {
|
766 |
$logo_img_retina = wp_get_attachment_image_src( $plugin_settings->getOption( 'logo_img_retina' ), 'full' );
|
767 |
|
768 |
+
if ( $logo_img_retina == null || !$logo_img_retina ) {
|
769 |
+
$logo_img_retina = $logo_img;
|
770 |
} else {
|
771 |
$logo_img_retina = $logo_img_retina[0];
|
772 |
+
// Double-check line below
|
773 |
+
$logo_img_retina_metadata = wp_get_attachment_metadata( $plugin_settings->getOption( 'logo_img_retina' ) );
|
774 |
+
if ( $logo_img == "" ) {
|
775 |
+
$logo_img = $logo_img_retina;
|
776 |
+
}
|
777 |
}
|
778 |
+
|
|
|
779 |
}
|
780 |
|
781 |
|
797 |
}
|
798 |
|
799 |
$logo_url_end = '</a>';
|
800 |
+
$logo_url = apply_filters( 'wp_mobile_menu_logo_url', $logo_url );
|
801 |
$logo_url = '<a href="' . $logo_url . '" class="headertext">';
|
802 |
}
|
803 |
|
includes/css/mobmenu.css
CHANGED
@@ -199,7 +199,7 @@ body.admin-bar .mobmenu, body.admin-bar .mobmenu-panel {
|
|
199 |
right: 0px;
|
200 |
color:#000;
|
201 |
display: block;
|
202 |
-
z-index:
|
203 |
}
|
204 |
/* 2nd Level Menu Items Padding */
|
205 |
.mobmenu .sub-menu li > a {
|
@@ -245,7 +245,7 @@ body.admin-bar .mobmenu, body.admin-bar .mobmenu-panel {
|
|
245 |
.show-nav-left .mobmenu-overlay, .show-nav-right .mobmenu-overlay {
|
246 |
width: 100%;
|
247 |
height: 100%;
|
248 |
-
z-index:
|
249 |
left: 0;
|
250 |
top: 0;
|
251 |
opacity: 1;
|
@@ -361,4 +361,8 @@ h4.no-mobile-menu a {
|
|
361 |
background: transparent;
|
362 |
outline: #1dcd1d solid 3px;
|
363 |
color: #000;
|
|
|
|
|
|
|
|
|
364 |
}
|
199 |
right: 0px;
|
200 |
color:#000;
|
201 |
display: block;
|
202 |
+
z-index: 10000;
|
203 |
}
|
204 |
/* 2nd Level Menu Items Padding */
|
205 |
.mobmenu .sub-menu li > a {
|
245 |
.show-nav-left .mobmenu-overlay, .show-nav-right .mobmenu-overlay {
|
246 |
width: 100%;
|
247 |
height: 100%;
|
248 |
+
z-index: 10001;
|
249 |
left: 0;
|
250 |
top: 0;
|
251 |
opacity: 1;
|
361 |
background: transparent;
|
362 |
outline: #1dcd1d solid 3px;
|
363 |
color: #000;
|
364 |
+
}
|
365 |
+
|
366 |
+
.mob-menu-slideout #page-container, .mob-menu-slideout-over #page-container {
|
367 |
+
padding-top: 0px!important;
|
368 |
}
|
includes/dynamic-style.php
CHANGED
@@ -701,13 +701,13 @@ echo $left_menu_height_translate ;
|
|
701 |
-ms-transform: translateY(0px);
|
702 |
-o-transform: translateY(0px);
|
703 |
transform: translateY(0px);
|
704 |
-
z-index:
|
705 |
}
|
706 |
.mob-menu-slideout-over.show-nav-left .mobmenu-left-panel {
|
707 |
overflow: hidden;
|
708 |
}
|
709 |
.show-nav-left .mobmenu-panel.show-panel , .show-nav-right .mobmenu-panel.show-panel {
|
710 |
-
z-index:
|
711 |
}
|
712 |
/* Hides everything pushed outside of it */
|
713 |
.mob-menu-slideout .mobmenu-panel, .mob-menu-slideout-over .mobmenu-panel, .mob-menu-slideout .mobmenu-cart-panel, .mob-menu-slideout-over .mobmenu-cart-panel {
|
701 |
-ms-transform: translateY(0px);
|
702 |
-o-transform: translateY(0px);
|
703 |
transform: translateY(0px);
|
704 |
+
z-index: 3000000;
|
705 |
}
|
706 |
.mob-menu-slideout-over.show-nav-left .mobmenu-left-panel {
|
707 |
overflow: hidden;
|
708 |
}
|
709 |
.show-nav-left .mobmenu-panel.show-panel , .show-nav-right .mobmenu-panel.show-panel {
|
710 |
+
z-index: 3000000;
|
711 |
}
|
712 |
/* Hides everything pushed outside of it */
|
713 |
.mob-menu-slideout .mobmenu-panel, .mob-menu-slideout-over .mobmenu-panel, .mob-menu-slideout .mobmenu-cart-panel, .mob-menu-slideout-over .mobmenu-cart-panel {
|
includes/js/mobmenu.js
CHANGED
@@ -144,11 +144,14 @@
|
|
144 |
$( 'body' ).addClass( menu_display_type );
|
145 |
}
|
146 |
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
|
|
|
|
|
|
152 |
|
153 |
var submenu_open_icon = $( '.mob-menu-header-holder' ).attr( 'data-open-icon' );
|
154 |
var submenu_close_icon = $( '.mob-menu-header-holder' ).attr( 'data-close-icon' );
|
@@ -196,7 +199,7 @@
|
|
196 |
});
|
197 |
|
198 |
$( document ).on( 'keyup', '.mobmenu-left-bt', function(e){
|
199 |
-
if( e.type != 'click' && e.which != 13 || e.which == 9 ) {
|
200 |
return;
|
201 |
}
|
202 |
|
@@ -205,7 +208,7 @@
|
|
205 |
});
|
206 |
|
207 |
$( document ).on( 'keyup', '.mobmenu-right-bt', function(e){
|
208 |
-
if( e.type != 'click' && e.which != 13 || e.which == 9 ) {
|
209 |
return;
|
210 |
}
|
211 |
|
144 |
$( 'body' ).addClass( menu_display_type );
|
145 |
}
|
146 |
|
147 |
+
// Only force autoplay videos in desktop
|
148 |
+
if(! ( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) ){
|
149 |
+
$( 'video' ).each( function(){
|
150 |
+
if( 'autoplay' === $( this ).attr('autoplay') ) {
|
151 |
+
$( this )[0].play();
|
152 |
+
}
|
153 |
+
});
|
154 |
+
}
|
155 |
|
156 |
var submenu_open_icon = $( '.mob-menu-header-holder' ).attr( 'data-open-icon' );
|
157 |
var submenu_close_icon = $( '.mob-menu-header-holder' ).attr( 'data-close-icon' );
|
199 |
});
|
200 |
|
201 |
$( document ).on( 'keyup', '.mobmenu-left-bt', function(e){
|
202 |
+
if( e.type != 'click' && e.which != 13 || e.which == 9 || jQuery(this).hasClass( 'mobmenu-trigger-action' ) ) {
|
203 |
return;
|
204 |
}
|
205 |
|
208 |
});
|
209 |
|
210 |
$( document ).on( 'keyup', '.mobmenu-right-bt', function(e){
|
211 |
+
if( e.type != 'click' && e.which != 13 || e.which == 9 || jQuery(this).hasClass( 'mobmenu-trigger-action' ) ) {
|
212 |
return;
|
213 |
}
|
214 |
|
includes/widgets/mobile-menu.php
DELETED
@@ -1,150 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Elementor Widget.
|
4 |
-
*
|
5 |
-
*
|
6 |
-
* @since 1.0.0
|
7 |
-
*/
|
8 |
-
class Mobile_Menu_El_Menu_Widget extends \Elementor\Widget_Base {
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Get widget name.
|
12 |
-
*
|
13 |
-
* Retrieve the widget name.
|
14 |
-
*
|
15 |
-
* @since 1.0.0
|
16 |
-
* @access public
|
17 |
-
*
|
18 |
-
* @return string Widget name.
|
19 |
-
*/
|
20 |
-
public function get_name() {
|
21 |
-
return 'mobile_menu_left_button';
|
22 |
-
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Get widget title.
|
26 |
-
*
|
27 |
-
* Retrieve the widget title.
|
28 |
-
*
|
29 |
-
* @since 1.0.0
|
30 |
-
* @access public
|
31 |
-
*
|
32 |
-
* @return string Widget title.
|
33 |
-
*/
|
34 |
-
public function get_title() {
|
35 |
-
return __( 'Mobile Left Button', 'mobile-menu' );
|
36 |
-
}
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Get widget icon.
|
40 |
-
*
|
41 |
-
* Retrieve the widget icon.
|
42 |
-
*
|
43 |
-
* @since 1.0.0
|
44 |
-
* @access public
|
45 |
-
*
|
46 |
-
* @return string Widget icon.
|
47 |
-
*/
|
48 |
-
public function get_icon() {
|
49 |
-
return 'eicon-button';
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Get widget categories.
|
54 |
-
*
|
55 |
-
* Retrieve the list of categories the oEmbed widget belongs to.
|
56 |
-
*
|
57 |
-
* @since 1.0.0
|
58 |
-
* @access public
|
59 |
-
*
|
60 |
-
* @return array Widget categories.
|
61 |
-
*/
|
62 |
-
public function get_categories() {
|
63 |
-
return [ 'general, mobile' ];
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Register the widget controls.
|
68 |
-
*
|
69 |
-
* Input fields to allow the user to change and customize the widget settings.
|
70 |
-
*
|
71 |
-
* @since 1.0.0
|
72 |
-
* @access protected
|
73 |
-
*/
|
74 |
-
protected function _register_controls() {
|
75 |
-
|
76 |
-
$this->start_controls_section(
|
77 |
-
'mobile_menu_section',
|
78 |
-
[
|
79 |
-
'label' => __( 'Settings', 'mobile-menu' ),
|
80 |
-
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
|
81 |
-
]
|
82 |
-
);
|
83 |
-
|
84 |
-
|
85 |
-
$this->add_control(
|
86 |
-
'btn_color',
|
87 |
-
[
|
88 |
-
'label' => __( 'Icon Color', 'mobile-menu' ),
|
89 |
-
'type' => \Elementor\Controls_Manager::COLOR,
|
90 |
-
'default' => __( '#0070c9', 'mobile-menu' ),
|
91 |
-
]
|
92 |
-
);
|
93 |
-
|
94 |
-
$this->add_control(
|
95 |
-
|
96 |
-
'btn_size',
|
97 |
-
[
|
98 |
-
'label' => __( 'Font Size', 'mobile-menu' ),
|
99 |
-
'type' => \Elementor\Controls_Manager::NUMBER,
|
100 |
-
'placeholder' => __( '0', 'mobile-menu' ),
|
101 |
-
'default' => '25',
|
102 |
-
]
|
103 |
-
);
|
104 |
-
|
105 |
-
$this->add_control(
|
106 |
-
|
107 |
-
'btn_padding',
|
108 |
-
[
|
109 |
-
'label' => __( 'Padding', 'mobile-menu' ),
|
110 |
-
'type' => \Elementor\Controls_Manager::DIMENSIONS,
|
111 |
-
'size_units' => [ 'px', 'em', '%' ],
|
112 |
-
'default' => array('top' =>'10', 'right' => '25', 'bottom' => '10', 'left' => '25', 'isLinked' => false),
|
113 |
-
'selectors' => [
|
114 |
-
'{{WRAPPER}} .pws-submit' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}',
|
115 |
-
],
|
116 |
-
]
|
117 |
-
);
|
118 |
-
|
119 |
-
$this->end_controls_section();
|
120 |
-
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Render oEmbed widget output on the frontend.
|
125 |
-
*
|
126 |
-
* Written in PHP and used to generate the final HTML.
|
127 |
-
*
|
128 |
-
* @since 1.0.0
|
129 |
-
* @access protected
|
130 |
-
*/
|
131 |
-
protected function render() {
|
132 |
-
|
133 |
-
global $mobile_menu_instance;
|
134 |
-
$plugin_settings = MobileMenuOptions::getInstance( 'mobmenu' );
|
135 |
-
$menu_type = 'left';
|
136 |
-
$menu_text = $plugin_settings->getOption( $menu_type . '_menu_text' );
|
137 |
-
$icon_action = $plugin_settings->getOption( $menu_type . '_menu_icon_action' );
|
138 |
-
$icon_target = $plugin_settings->getOption( $menu_type . '_icon_url_target' );
|
139 |
-
$icon_url = $plugin_settings->getOption( $menu_type . '_icon_url' );
|
140 |
-
$icon_font = $plugin_settings->getOption( $menu_type . '_menu_icon_font' );
|
141 |
-
$icon = $plugin_settings->getOption( $menu_type . '_menu_icon' );
|
142 |
-
$icon_new = $plugin_settings->getOption( $menu_type . '_menu_icon_new' );
|
143 |
-
$animation = $plugin_settings->getOption( $menu_type . '_menu_icon_animation' );
|
144 |
-
$close_icon = $plugin_settings->getOption( 'close_icon_font' );
|
145 |
-
$mobile_menu_instance->mobmenu_core->frontend_enqueue_scripts();
|
146 |
-
echo $mobile_menu_instance->mobmenu_core->load_mobile_menu_html( $menu_type, $menu_text, $icon_action, $icon_target, $icon_url, $icon_font, $icon, $icon_new, $animation, $close_icon);
|
147 |
-
|
148 |
-
}
|
149 |
-
|
150 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mobmenu.php
CHANGED
@@ -3,11 +3,11 @@
|
|
3 |
/**
|
4 |
* Plugin Name: Mobile Menu
|
5 |
* Description: An easy to use WordPress responsive mobile menu. Keep your mobile visitors engaged.
|
6 |
-
* Version: 2.8.
|
7 |
* Plugin URI: https://www.wpmobilemenu.com/
|
8 |
* Author: Freshlight Lab
|
9 |
* Author URI: https://www.freshlightlab.com/
|
10 |
-
* Tested up to:
|
11 |
* Text Domain: mobile-menu
|
12 |
* Domain Path: /languages/
|
13 |
* License: GPLv2
|
@@ -16,7 +16,7 @@
|
|
16 |
if ( !defined( 'ABSPATH' ) ) {
|
17 |
die;
|
18 |
}
|
19 |
-
define( 'WP_MOBILE_MENU_VERSION', '2.8.
|
20 |
define( 'WP_MOBILE_MENU_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
|
21 |
define( 'WP_MOBILE_MENU_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
22 |
if ( !class_exists( 'WP_Mobile_Menu' ) ) {
|
@@ -74,8 +74,7 @@ if ( !class_exists( 'WP_Mobile_Menu' ) ) {
|
|
74 |
10,
|
75 |
2
|
76 |
);
|
77 |
-
|
78 |
-
add_action( 'elementor/widgets/widgets_registered', array( $this->mobmenu_core, 'mobmenu_el_init_widgets' ) );
|
79 |
// Load frontend assets.
|
80 |
if ( !is_admin() ) {
|
81 |
add_action( 'init', array( $this, 'load_frontend_assets' ) );
|
3 |
/**
|
4 |
* Plugin Name: Mobile Menu
|
5 |
* Description: An easy to use WordPress responsive mobile menu. Keep your mobile visitors engaged.
|
6 |
+
* Version: 2.8.3
|
7 |
* Plugin URI: https://www.wpmobilemenu.com/
|
8 |
* Author: Freshlight Lab
|
9 |
* Author URI: https://www.freshlightlab.com/
|
10 |
+
* Tested up to: 6.1
|
11 |
* Text Domain: mobile-menu
|
12 |
* Domain Path: /languages/
|
13 |
* License: GPLv2
|
16 |
if ( !defined( 'ABSPATH' ) ) {
|
17 |
die;
|
18 |
}
|
19 |
+
define( 'WP_MOBILE_MENU_VERSION', '2.8.3' );
|
20 |
define( 'WP_MOBILE_MENU_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
|
21 |
define( 'WP_MOBILE_MENU_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
22 |
if ( !class_exists( 'WP_Mobile_Menu' ) ) {
|
74 |
10,
|
75 |
2
|
76 |
);
|
77 |
+
|
|
|
78 |
// Load frontend assets.
|
79 |
if ( !is_admin() ) {
|
80 |
add_action( 'init', array( $this, 'load_frontend_assets' ) );
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: takanakui, freemius, freslightlab
|
|
3 |
link: http://profiles.wordpress.org/takanakui
|
4 |
Tags: mobile, navigation, responsive, menu, responsive menu, mobile menu, tablet menu, hamburger menu, hamburger, wordpress responsive menu, wordpress mobile menu, canvas menu
|
5 |
Requires at least: 4.4
|
6 |
-
Tested up to: 6.
|
7 |
-
Stable tag: 2.8.
|
8 |
Requires PHP: 5.6
|
9 |
License: GPLv3
|
10 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
@@ -136,6 +136,14 @@ Not available at the moment
|
|
136 |
|
137 |
|
138 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
= 2.8.2.7 =
|
140 |
* Fix! - Fix image upload field
|
141 |
* Improvment! - Remove background gradient from free demo content
|
3 |
link: http://profiles.wordpress.org/takanakui
|
4 |
Tags: mobile, navigation, responsive, menu, responsive menu, mobile menu, tablet menu, hamburger menu, hamburger, wordpress responsive menu, wordpress mobile menu, canvas menu
|
5 |
Requires at least: 4.4
|
6 |
+
Tested up to: 6.1
|
7 |
+
Stable tag: 2.8.3
|
8 |
Requires PHP: 5.6
|
9 |
License: GPLv3
|
10 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
136 |
|
137 |
|
138 |
|
139 |
+
= 2.8.3 =
|
140 |
+
* New! - Possibility to open menus with enter key when got focus
|
141 |
+
* New! - 3 new filters to replace the logo image, current menu and menu URL
|
142 |
+
* Fix! - Remove blank space below the header in a specific theme
|
143 |
+
* Fix! - Display normal logo if retina isn't uploaded and vice versa
|
144 |
+
* Fix! - Only force autoplay videos on desktop
|
145 |
+
* Improvment! - Update Freemius SDK
|
146 |
+
|
147 |
= 2.8.2.7 =
|
148 |
* Fix! - Fix image upload field
|
149 |
* Improvment! - Remove background gradient from free demo content
|