Easy Watermark - Version 0.7.1

Version Description

  • Security fix
Download this release

Release Info

Developer szaleq
Plugin Icon Easy Watermark
Version 0.7.1
Comparing to
See all releases

Code changes from version 0.7.0 to 0.7.1

Files changed (62) hide show
  1. classes/class-ew-plugin-core.php +1 -1
  2. freemius/assets/css/admin/common.css +2 -2
  3. freemius/assets/css/admin/dialog-boxes.css +2 -2
  4. freemius/assets/scss/_colors.scss +11 -0
  5. freemius/assets/scss/admin/_buttons.scss +28 -0
  6. freemius/assets/scss/admin/_plugin-upgrade-notice.scss +8 -0
  7. freemius/assets/scss/admin/_subscription-cancellation.scss +30 -0
  8. freemius/assets/scss/admin/common.scss +4 -2
  9. freemius/assets/scss/admin/dialog-boxes.scss +3 -1
  10. freemius/includes/class-freemius.php +1100 -275
  11. freemius/includes/class-fs-api.php +14 -4
  12. freemius/includes/class-fs-plugin-updater.php +317 -69
  13. freemius/includes/class-fs-storage.php +2 -2
  14. freemius/includes/entities/class-fs-plugin.php +22 -0
  15. freemius/includes/entities/class-fs-site.php +2 -0
  16. freemius/includes/fs-core-functions.php +115 -91
  17. freemius/includes/fs-essential-functions.php +4 -2
  18. freemius/includes/fs-plugin-info-dialog.php +37 -7
  19. freemius/includes/i18n.php +3 -3
  20. freemius/includes/managers/class-fs-admin-menu-manager.php +17 -5
  21. freemius/includes/managers/class-fs-admin-notice-manager.php +74 -0
  22. freemius/includes/supplements/fs-essential-functions-1.1.7.1.php +2 -6
  23. freemius/includes/supplements/fs-essential-functions-2.2.1.php +45 -0
  24. freemius/languages/freemius-da_DK.mo +0 -0
  25. freemius/languages/freemius-da_DK.po +2431 -9
  26. freemius/languages/freemius-en.mo +0 -0
  27. freemius/languages/freemius-en.po +544 -429
  28. freemius/languages/freemius-es_ES.mo +0 -0
  29. freemius/languages/freemius-es_ES.po +620 -486
  30. freemius/languages/freemius-fr_FR.mo +0 -0
  31. freemius/languages/freemius-fr_FR.po +618 -484
  32. freemius/languages/freemius-he_IL.mo +0 -0
  33. freemius/languages/freemius-he_IL.po +616 -482
  34. freemius/languages/freemius-hu_HU.mo +0 -0
  35. freemius/languages/freemius-hu_HU.po +2433 -0
  36. freemius/languages/freemius-it_IT.mo +0 -0
  37. freemius/languages/freemius-it_IT.po +618 -483
  38. freemius/languages/freemius-ja_JP.mo +0 -0
  39. freemius/languages/freemius-ja_JP.po +619 -485
  40. freemius/languages/freemius-nl_NL.mo +0 -0
  41. freemius/languages/freemius-nl_NL.po +643 -508
  42. freemius/languages/freemius-ru_RU.mo +0 -0
  43. freemius/languages/freemius-ru_RU.po +618 -483
  44. freemius/languages/freemius.pot +529 -414
  45. freemius/start.php +20 -9
  46. freemius/templates/account.php +84 -31
  47. freemius/templates/account/partials/addon.php +349 -344
  48. freemius/templates/account/partials/site.php +10 -5
  49. freemius/templates/add-ons.php +1 -1
  50. freemius/templates/admin-notice.php +29 -1
  51. freemius/templates/checkout.php +2 -2
  52. freemius/templates/connect.php +7 -5
  53. freemius/templates/contact.php +3 -3
  54. freemius/templates/debug.php +4 -2
  55. freemius/templates/forms/deactivation/form.php +98 -31
  56. freemius/templates/forms/premium-versions-upgrade-handler.php +27 -5
  57. freemius/templates/forms/premium-versions-upgrade-metadata.php +17 -1
  58. freemius/templates/forms/subscription-cancellation.php +277 -0
  59. freemius/templates/pricing.php +2 -2
  60. freemius/templates/tabs.php +4 -0
  61. index.php +1 -1
  62. readme.txt +4 -1
classes/class-ew-plugin-core.php CHANGED
@@ -23,7 +23,7 @@ class EW_Plugin_Core extends EW_Pluggable
23
/**
24
* @var string plugin version
25
*/
26
- protected static $version = '0.7.0';
27
28
/**
29
* @var string plugin class name
23
/**
24
* @var string plugin version
25
*/
26
+ protected static $version = '0.7.1';
27
28
/**
29
* @var string plugin class name
freemius/assets/css/admin/common.css CHANGED
@@ -1,2 +1,2 @@
1
- .theme-browser .theme .fs-premium-theme-badge{position:absolute;top:10px;right:0;background:#71ae00;color:#fff;text-transform:uppercase;padding:5px 10px;-moz-border-radius:3px 0 0 3px;-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;font-weight:bold;border-right:0;-moz-box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);font-size:1.1em}#iframe{line-height:0;font-size:0}.fs-full-size-wrapper{margin:40px 0 -65px -20px}@media (max-width: 600px){.fs-full-size-wrapper{margin:0 0 -65px -10px}}
2
- .fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px !important}.fs-notice.success{color:green}.fs-notice.promotion{border-color:#00a0d2 !important;background-color:#f2fcff !important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-close{cursor:pointer;color:#aaa;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{margin-top:7px;display:inline-block}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,0.3);color:#fff;padding:2px 10px;position:absolute;top:100%;bottom:auto;right:auto;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;left:10px;font-size:12px;font-weight:bold;cursor:auto}div.fs-notice.updated,div.fs-notice.success,div.fs-notice.promotion{display:block !important}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{position:fixed;top:32px;left:160px;right:0;background:#ebfdeb;padding:10px 20px;color:green;z-index:9999;-moz-box-shadow:0 2px 2px rgba(6,113,6,0.3);-webkit-box-shadow:0 2px 2px rgba(6,113,6,0.3);box-shadow:0 2px 2px rgba(6,113,6,0.3);opacity:0.95;filter:alpha(opacity=95)}.fs-secure-notice:hover{opacity:1;filter:alpha(opacity=100)}.fs-secure-notice a.fs-security-proof{color:green;text-decoration:none}@media screen and (max-width: 960px){.fs-secure-notice{left:36px}}@media screen and (max-width: 600px){.fs-secure-notice{display:none}}@media screen and (max-width: 500px){#fs_promo_tab{display:none}}@media screen and (max-width: 782px){.fs-secure-notice{left:0;top:46px;text-align:center}}span.fs-submenu-item.fs-sub:before{content:'\21B3';padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:'\21B2'}.fs-submenu-item.pricing.upgrade-mode{color:greenyellow}.fs-submenu-item.pricing.trial-mode{color:#83e2ff}#adminmenu .update-plugins.fs-trial{background-color:#00b9eb}.fs-ajax-spinner{border:0;width:20px;height:20px;margin-right:5px;vertical-align:sub;display:inline-block;background:url("/wp-admin/images/wpspin_light-2x.gif");background-size:contain}.wrap.fs-section h2{text-align:left}
1
+ .theme-browser .theme .fs-premium-theme-badge{position:absolute;top:10px;right:0;background:#71ae00;color:#fff;text-transform:uppercase;padding:5px 10px;-moz-border-radius:3px 0 0 3px;-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;font-weight:bold;border-right:0;-moz-box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);font-size:1.1em}#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}}
2
+ .fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px !important}.fs-notice.success{color:green}.fs-notice.promotion{border-color:#00a0d2 !important;background-color:#f2fcff !important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-close{cursor:pointer;color:#aaa;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{margin-top:7px;display:inline-block}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,0.3);color:#fff;padding:2px 10px;position:absolute;top:100%;bottom:auto;right:auto;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;left:10px;font-size:12px;font-weight:bold;cursor:auto}div.fs-notice.updated,div.fs-notice.success,div.fs-notice.promotion{display:block !important}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{position:fixed;top:32px;left:160px;right:0;background:#ebfdeb;padding:10px 20px;color:green;z-index:9999;-moz-box-shadow:0 2px 2px rgba(6,113,6,0.3);-webkit-box-shadow:0 2px 2px rgba(6,113,6,0.3);box-shadow:0 2px 2px rgba(6,113,6,0.3);opacity:0.95;filter:alpha(opacity=95)}.fs-secure-notice:hover{opacity:1;filter:alpha(opacity=100)}.fs-secure-notice a.fs-security-proof{color:green;text-decoration:none}@media screen and (max-width: 960px){.fs-secure-notice{left:36px}}@media screen and (max-width: 600px){.fs-secure-notice{display:none}}@media screen and (max-width: 500px){#fs_promo_tab{display:none}}@media screen and (max-width: 782px){.fs-secure-notice{left:0;top:46px;text-align:center}}span.fs-submenu-item.fs-sub:before{content:'\21B3';padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:'\21B2'}.fs-submenu-item.pricing.upgrade-mode{color:greenyellow}.fs-submenu-item.pricing.trial-mode{color:#83e2ff}#adminmenu .update-plugins.fs-trial{background-color:#00b9eb}.fs-ajax-spinner{border:0;width:20px;height:20px;margin-right:5px;vertical-align:sub;display:inline-block;background:url("/wp-admin/images/wpspin_light-2x.gif");background-size:contain}.wrap.fs-section h2{text-align:left}.plugins p.fs-upgrade-notice{border:0;background-color:#d54e21;padding:10px;color:#f9f9f9;margin-top:10px}
freemius/assets/css/admin/dialog-boxes.css CHANGED
@@ -1,2 +1,2 @@
1
- .fs-modal{position:fixed;overflow:auto;height:100%;width:100%;top:0;z-index:100000;display:none;background:rgba(0,0,0,0.6)}.fs-modal .fs-modal-dialog{background:transparent;position:absolute;left:50%;margin-left:-298px;padding-bottom:30px;top:-100%;z-index:100001;width:596px}@media (max-width: 650px){.fs-modal .fs-modal-dialog{margin-left:-50%;box-sizing:border-box;padding-left:10px;padding-right:10px;width:100%}.fs-modal .fs-modal-dialog .fs-modal-panel>h3>strong{font-size:1.3em}}.fs-modal.active{display:block}.fs-modal.active:before{display:block}.fs-modal.active .fs-modal-dialog{top:10%}.fs-modal.fs-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-license-activation .fs-modal-body input.license_key{width:100%}#license_options_container table,#license_options_container table select,#license_options_container table #available_license_key{width:100%}#license_options_container table td:first-child{width:1%}#license_options_container table #other_license_key_container label{position:relative;top:6px;float:left;margin-right:5px}#license_options_container table #other_license_key_container div{overflow:hidden;width:auto;height:30px;display:block;top:2px;position:relative}#license_options_container table #other_license_key_container div input{margin:0}#sites_list_container td{cursor:pointer}#multisite_options_container{margin-top:10px;border:1px solid #ccc;padding:5px}#multisite_options_container a{text-decoration:none}#multisite_options_container a:focus{box-shadow:none}#multisite_options_container a.selected{font-weight:bold}#multisite_options_container.apply-on-all-sites{border:0 none;padding:0}#multisite_options_container.apply-on-all-sites #all_sites_options{border-spacing:0}#multisite_options_container.apply-on-all-sites #all_sites_options td:not(:first-child){display:none}#multisite_options_container #sites_list_container{display:none;overflow:auto}#multisite_options_container #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}
1
+ .fs-modal{position:fixed;overflow:auto;height:100%;width:100%;top:0;z-index:100000;display:none;background:rgba(0,0,0,0.6)}.fs-modal .fs-modal-dialog{background:transparent;position:absolute;left:50%;margin-left:-298px;padding-bottom:30px;top:-100%;z-index:100001;width:596px}@media (max-width: 650px){.fs-modal .fs-modal-dialog{margin-left:-50%;box-sizing:border-box;padding-left:10px;padding-right:10px;width:100%}.fs-modal .fs-modal-dialog .fs-modal-panel>h3>strong{font-size:1.3em}}.fs-modal.active{display:block}.fs-modal.active:before{display:block}.fs-modal.active .fs-modal-dialog{top:10%}.fs-modal.fs-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.license_key{width:100%}#license_options_container table,#license_options_container table select,#license_options_container table #available_license_key{width:100%}#license_options_container table td:first-child{width:1%}#license_options_container table #other_license_key_container label{position:relative;top:6px;float:left;margin-right:5px}#license_options_container table #other_license_key_container div{overflow:hidden;width:auto;height:30px;display:block;top:2px;position:relative}#license_options_container table #other_license_key_container div input{margin:0}#sites_list_container td{cursor:pointer}#multisite_options_container{margin-top:10px;border:1px solid #ccc;padding:5px}#multisite_options_container a{text-decoration:none}#multisite_options_container a:focus{box-shadow:none}#multisite_options_container a.selected{font-weight:bold}#multisite_options_container.apply-on-all-sites{border:0 none;padding:0}#multisite_options_container.apply-on-all-sites #all_sites_options{border-spacing:0}#multisite_options_container.apply-on-all-sites #all_sites_options td:not(:first-child){display:none}#multisite_options_container #sites_list_container{display:none;overflow:auto}#multisite_options_container #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}
freemius/assets/scss/_colors.scss CHANGED
@@ -44,6 +44,17 @@ $button-secondary-bkg: #333;
44
$button-secondary-color: $fms-white;
45
$featured-color: #6bc406;
46
$wp-selected-color: #0074a3;
47
48
$wordpress_color: #01749A;
49
$blogger_color: #ff8100;
44
$button-secondary-color: $fms-white;
45
$featured-color: #6bc406;
46
$wp-selected-color: #0074a3;
47
+ $wp-button-alert-border-color: #d2593c;
48
+ $wp-button-alert-border-top-color: #ec6544;
49
+ $wp-button-alert-shadow-color: #d2593c;
50
+ $wp-button-alert-focused-shadow1-color: #dd6041;
51
+ $wp-button-alert-focused-shadow2-color: #e4a796;
52
+ $wp-button-alert-background-color: #f56a48;
53
+ $wp-button-alert-hovered-background-color: #fd6d4a;
54
+ $wp-button-alert-active-background-color: #dd6041;
55
+ $wp-button-alert-disabled-color: #f5b3a1;
56
+ $wp-button-alert-disabled-background-color: #e76444;
57
+ $wp-button-alert-disabled-border-color: #d85e40;
58
59
$wordpress_color: #01749A;
60
$blogger_color: #ff8100;
freemius/assets/scss/admin/_buttons.scss ADDED
@@ -0,0 +1,28 @@
1
+ .button-primary.warn {
2
+ box-shadow: 0 1px 0 $wp-button-alert-shadow-color;
3
+ text-shadow: 0 -1px 1px $wp-button-alert-shadow-color, 1px 0 1px $wp-button-alert-shadow-color, 0 1px 1px $wp-button-alert-shadow-color, -1px 0 1px $wp-button-alert-shadow-color;
4
+ background: $wp-button-alert-background-color;
5
+ border-color: $wp-button-alert-border-top-color $wp-button-alert-border-color $wp-button-alert-border-color;
6
+
7
+ &:hover {
8
+ background: $wp-button-alert-hovered-background-color;
9
+ border-color: $wp-button-alert-border-color;
10
+ }
11
+
12
+ &:focus {
13
+ box-shadow: 0 1px 0 $wp-button-alert-focused-shadow1-color, 0 0 2px 1px $wp-button-alert-focused-shadow2-color;
14
+ }
15
+
16
+ &:active {
17
+ background: $wp-button-alert-active-background-color;
18
+ border-color: $wp-button-alert-border-color;
19
+ box-shadow: inset 0 2px 0 $wp-button-alert-shadow-color;
20
+ }
21
+
22
+ &.disabled {
23
+ color: $wp-button-alert-disabled-color !important;
24
+ background: $wp-button-alert-disabled-background-color !important;
25
+ border-color: $wp-button-alert-disabled-border-color !important;
26
+ text-shadow: 0 -1px 0 rgba(0,0,0,.1) !important;
27
+ }
28
+ }
freemius/assets/scss/admin/_plugin-upgrade-notice.scss ADDED
@@ -0,0 +1,8 @@
1
+ .plugins p.fs-upgrade-notice
2
+ {
3
+ border: 0;
4
+ background-color: #d54e21;
5
+ padding: 10px;
6
+ color: #f9f9f9;
7
+ margin-top: 10px;
8
+ }
freemius/assets/scss/admin/_subscription-cancellation.scss ADDED
@@ -0,0 +1,30 @@
1
+ .fs-modal.fs-modal-subscription-cancellation {
2
+ .fs-price-increase-warning {
3
+ color: red;
4
+ font-weight: bold;
5
+ padding: 0 25px;
6
+ margin-bottom: 0;
7
+ }
8
+
9
+ ul.subscription-actions label {
10
+ input {
11
+ float: left;
12
+ top: 5px;
13
+ position: relative;
14
+
15
+ .rtl & {
16
+ float: right;
17
+ }
18
+ }
19
+
20
+ span {
21
+ display: block;
22
+ margin-left: 24px;
23
+
24
+ .rtl & {
25
+ margin-left: 0;
26
+ margin-right: 24px;
27
+ }
28
+ }
29
+ }
30
+ }
freemius/assets/scss/admin/common.scss CHANGED
@@ -1,7 +1,7 @@
1
@import "../start";
2
@import "themes";
3
4
- #iframe
5
{
6
line-height: 0;
7
font-size: 0;
@@ -215,4 +215,6 @@ span.fs-submenu-item.fs-sub:before
215
h2 {
216
text-align: left;
217
}
218
- }
1
@import "../start";
2
@import "themes";
3
4
+ #fs_frame
5
{
6
line-height: 0;
7
font-size: 0;
215
h2 {
216
text-align: left;
217
}
218
+ }
219
+
220
+ @import "plugin-upgrade-notice";
freemius/assets/scss/admin/dialog-boxes.scss CHANGED
@@ -1,8 +1,10 @@
1
@import "../start";
2
@import "modal-common";
3
@import "deactivation-feedback";
4
@import "license-activation";
5
@import "multisite-options";
6
@import "license-key-resend";
7
@import "ajax-loader";
8
- @import "auto-install";
1
@import "../start";
2
@import "modal-common";
3
@import "deactivation-feedback";
4
+ @import "subscription-cancellation";
5
@import "license-activation";
6
@import "multisite-options";
7
@import "license-key-resend";
8
@import "ajax-loader";
9
+ @import "auto-install";
10
+ @import "buttons";
freemius/includes/class-freemius.php CHANGED
@@ -33,6 +33,12 @@
33
* @var string
34
*/
35
private $_plugin_basename;
36
/**
37
* @since 1.0.0
38
*
@@ -671,11 +677,12 @@
671
version_compare( $sdk_version, '1.2.3', '>=' )
672
) {
673
/**
674
- * Starting from version 1.2.3, paths are stored as relative paths and not absolute paths; so when upgrading to 1.2.3, make paths relative.
675
*
676
* @author Leo Fajardo (@leorw)
677
*/
678
- $this->make_paths_relative();
679
}
680
681
if ( version_compare( $sdk_prev_version, '1.1.5', '<' ) &&
@@ -699,6 +706,25 @@
699
700
}
701
}
702
}
703
704
/**
@@ -824,30 +850,12 @@
824
}
825
826
/**
827
- * Makes paths relative.
828
*
829
* @author Leo Fajardo (@leorw)
830
* @since 1.2.3
831
*/
832
- private function make_paths_relative() {
833
- $id_slug_type_path_map = self::$_accounts->get_option( 'id_slug_type_path_map', array() );
834
-
835
- if ( isset( $id_slug_type_path_map[ $this->_module_id ]['path'] ) ) {
836
- $id_slug_type_path_map[ $this->_module_id ]['path'] = $this->get_relative_path( $id_slug_type_path_map[ $this->_module_id ]['path'] );
837
-
838
- self::$_accounts->set_option( 'id_slug_type_path_map', $id_slug_type_path_map, true );
839
- }
840
-
841
- if ( isset( $this->_storage->plugin_main_file ) ) {
842
- $plugin_main_file = $this->_storage->plugin_main_file;
843
-
844
- if ( isset( $plugin_main_file->path ) ) {
845
- $this->_storage->plugin_main_file->path = $this->get_relative_path( $this->_storage->plugin_main_file->path );
846
- } else if ( isset( $plugin_main_file->prev_path ) ) {
847
- $this->_storage->plugin_main_file->prev_path = $this->get_relative_path( $this->_storage->plugin_main_file->prev_path );
848
- }
849
- }
850
-
851
// Remove invalid path that is still associated with the current slug if there's any.
852
$file_slug_map = self::$_accounts->get_option( 'file_slug_map', array() );
853
foreach ( $file_slug_map as $plugin_basename => $slug ) {
@@ -1230,6 +1238,22 @@
1230
<?php
1231
}
1232
1233
/**
1234
* @author Vova Feldman (@svovaf)
1235
* @since 1.0.9
@@ -1241,6 +1265,26 @@
1241
add_action( 'plugins_loaded', array( &$this, '_hook_action_links_and_register_account_hooks' ) );
1242
1243
if ( $this->is_plugin() ) {
1244
$plugin_dir = dirname( $this->_plugin_dir_path ) . '/';
1245
1246
/**
@@ -1408,6 +1452,84 @@
1408
}
1409
}
1410
1411
/**
1412
* Keeping the uninstall hook registered for free or premium plugin version may result to a fatal error that
1413
* could happen when a user tries to uninstall either version while one of them is still active. Uninstalling a
@@ -1428,23 +1550,37 @@
1428
1429
/**
1430
* @since 1.2.0 Invalidate module's main file cache, otherwise, FS_Plugin_Updater will not fetch updates.
1431
*/
1432
- private function clear_module_main_file_cache() {
1433
if ( ! isset( $this->_storage->plugin_main_file ) ||
1434
- empty( $this->_storage->plugin_main_file->path )
1435
) {
1436
return;
1437
}
1438
1439
- $plugin_main_file = clone $this->_storage->plugin_main_file;
1440
1441
- // Store cached path (2nd layer cache).
1442
- $plugin_main_file->prev_path = $plugin_main_file->path;
1443
1444
- // Clear cached path.
1445
- unset( $plugin_main_file->path );
1446
1447
- $this->_storage->plugin_main_file = $plugin_main_file;
1448
1449
/**
1450
* Clear global cached path.
@@ -1491,6 +1627,11 @@
1491
array( &$this, '_submit_uninstall_reason_action' )
1492
);
1493
1494
if ( ! $this->is_addon() || $this->is_parent_plugin_installed() ) {
1495
if ( ( $this->is_plugin() && self::is_plugins_page() ) ||
1496
( $this->is_theme() && self::is_themes_page() )
@@ -1615,7 +1756,7 @@
1615
1616
return fs_normalize_path( trailingslashit( $is_plugin ?
1617
WP_PLUGIN_DIR :
1618
- get_theme_root() ) );
1619
}
1620
1621
/**
@@ -1680,11 +1821,11 @@
1680
private function get_caller_main_file_and_type() {
1681
self::require_plugin_essentials();
1682
1683
- $all_plugins = get_plugins();
1684
$all_plugins_paths = array();
1685
1686
// Get active plugin's main files real full names (might be symlinks).
1687
- foreach ( $all_plugins as $relative_path => &$data ) {
1688
if ( false === strpos( fs_normalize_path( $relative_path ), '/' ) ) {
1689
/**
1690
* Ignore plugins that don't have a folder (e.g. Hello Dolly) since they
@@ -1702,7 +1843,7 @@
1702
$caller_file_candidate = false;
1703
$caller_map = array();
1704
$module_type = WP_FS__MODULE_TYPE_PLUGIN;
1705
- $themes_dir = fs_normalize_path( get_theme_root() );
1706
1707
for ( $i = 1, $bt = debug_backtrace(), $len = count( $bt ); $i < $len; $i ++ ) {
1708
if ( empty( $bt[ $i ]['file'] ) ) {
@@ -1722,7 +1863,10 @@
1722
'requir' . 'e_once',
1723
'requir' . 'e',
1724
'includ' . 'e_once',
1725
- 'includ' . 'e'
1726
) )
1727
) {
1728
// Ignore call stack hooks and files inclusion.
@@ -2058,6 +2202,51 @@
2058
exit;
2059
}
2060
2061
/**
2062
* @author Leo Fajardo (@leorw)
2063
* @since 2.0.2
@@ -2134,16 +2323,18 @@
2134
* @since 1.2.2
2135
*
2136
* @param string|number $id_or_slug
2137
*
2138
* @return number|false
2139
*/
2140
- private static function get_module_id( $id_or_slug ) {
2141
if ( is_numeric( $id_or_slug ) ) {
2142
return $id_or_slug;
2143
}
2144
2145
foreach ( self::$_instances as $instance ) {
2146
- if ( $instance->is_plugin() && ( $id_or_slug === $instance->get_slug() ) ) {
2147
return $instance->get_id();
2148
}
2149
}
@@ -2170,15 +2361,16 @@
2170
* @author Vova Feldman (@svovaf)
2171
* @since 1.0.1
2172
*
2173
- * @param $plugin_file
2174
*
2175
* @return false|Freemius
2176
*/
2177
- static function get_instance_by_file( $plugin_file ) {
2178
$slug = self::find_slug_by_basename( $plugin_file );
2179
2180
return ( false !== $slug ) ?
2181
- self::instance( self::get_module_id( $slug ) ) :
2182
false;
2183
}
2184
@@ -2292,10 +2484,13 @@
2292
function is_site_activation_mode( $and_on = true ) {
2293
return (
2294
( $this->is_on() || ! $and_on ) &&
2295
- ( ! $this->is_registered() ||
2296
- ( $this->is_only_premium() && ! $this->has_features_enabled_license() ) ) &&
2297
- ( ! $this->is_enable_anonymous() ||
2298
- ( ! $this->is_anonymous() && ! $this->is_pending_activation() ) )
2299
);
2300
}
2301
@@ -2330,7 +2525,7 @@
2330
return false;
2331
}
2332
2333
- if ( $this->is_network_anonymous() ) {
2334
// Super-admin skipped the connection network wide -> not activation mode.
2335
return false;
2336
}
@@ -2451,7 +2646,7 @@
2451
self::require_plugin_essentials();
2452
2453
$active_plugin = array();
2454
- $all_plugins = get_plugins();
2455
$active_plugins_basenames = self::get_active_plugins_basenames( $blog_id );
2456
2457
foreach ( $active_plugins_basenames as $plugin_basename ) {
@@ -2477,6 +2672,11 @@
2477
get_option( 'active_plugins' );
2478
2479
$active = array();
2480
foreach ( $active_basenames as $basename ) {
2481
$active[ $basename ] = array(
2482
'is_active' => true,
@@ -2501,7 +2701,7 @@
2501
private static function get_all_plugins( $blog_id = 0 ) {
2502
self::require_plugin_essentials();
2503
2504
- $all_plugins = get_plugins();
2505
2506
$active_plugins_basenames = self::get_active_plugins_basenames( $blog_id );
2507
@@ -2533,7 +2733,7 @@
2533
private static function get_network_plugins() {
2534
self::require_plugin_essentials();
2535
2536
- $all_plugins = get_plugins();
2537
2538
$network_active_basenames = is_multisite() ?
2539
get_site_option( 'active_sitewide_plugins' ) :
@@ -2677,6 +2877,8 @@
2677
}
2678
2679
add_action( 'admin_footer', array( 'Freemius', '_enrich_ajax_url' ) );
2680
2681
self::$_statics_loaded = true;
2682
}
@@ -2775,6 +2977,10 @@
2775
* @since 1.1.7.3
2776
*/
2777
static function _toggle_debug_mode() {
2778
$is_on = fs_request_get( 'is_on', false, 'post' );
2779
2780
if ( fs_request_is_post() && in_array( $is_on, array( 0, 1 ) ) ) {
@@ -2806,8 +3012,16 @@
2806
* @since 1.2.1.7
2807
*/
2808
static function _get_db_option() {
2809
$option_name = fs_request_get( 'option_name' );
2810
2811
$value = get_option( $option_name );
2812
2813
$result = array(
@@ -2830,7 +3044,16 @@
2830
* @since 1.2.1.7
2831
*/
2832
static function _set_db_option() {
2833
- $option_name = fs_request_get( 'option_name' );
2834
$option_value = fs_request_get( 'option_value' );
2835
2836
if ( ! empty( $option_value ) ) {
@@ -4068,14 +4291,16 @@
4068
* @author Vova Feldman (@svovaf)
4069
*/
4070
if ( $this->is_user_in_admin() &&
4071
- ! $this->is_addon() &&
4072
- $this->has_addons() &&
4073
- 'plugin-information' === fs_request_get( 'tab', false ) &&
4074
- $this->get_id() == fs_request_get( 'parent_plugin_id', false )
4075
) {
4076
require_once WP_FS__DIR_INCLUDES . '/fs-plugin-info-dialog.php';
4077
4078
- new FS_Plugin_Info_Dialog( $this );
4079
}
4080
4081
// Check if Freemius is on for the current plugin.
@@ -4189,7 +4414,21 @@
4189
* @author Vova Feldman
4190
* @since 1.2.1.6
4191
*/
4192
- if ( $this->is_premium() && $this->has_release_on_freemius() ) {
4193
FS_Plugin_Updater::instance( $this );
4194
}
4195
@@ -4232,6 +4471,26 @@
4232
}
4233
}
4234
4235
/**
4236
* @author Leo Fajardo (@leorw)
4237
*
@@ -4668,16 +4927,20 @@
4668
$this->_plugin :
4669
new FS_Plugin();
4670
4671
$plugin->update( array(
4672
'id' => $id,
4673
'type' => $this->get_option( $plugin_info, 'type', $this->_module_type ),
4674
'public_key' => $public_key,
4675
'slug' => $this->_slug,
4676
'parent_plugin_id' => $parent_id,
4677
'version' => $this->get_plugin_version(),
4678
- 'title' => $this->get_plugin_name(),
4679
'file' => $this->_plugin_basename,
4680
'is_premium' => $this->get_bool_option( $plugin_info, 'is_premium', true ),
4681
'is_live' => $this->get_bool_option( $plugin_info, 'is_live', true ),
4682
'affiliate_moderation' => $this->get_option( $plugin_info, 'has_affiliation' ),
4683
) );
@@ -5058,7 +5321,7 @@
5058
}
5059
5060
$addon = $this->get_addon( $addon_id );
5061
- $premium_basename = "{$addon->slug}-premium/{$addon->slug}.php";
5062
5063
if ( file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $premium_basename ) ) ) {
5064
return $premium_basename;
@@ -5066,9 +5329,9 @@
5066
5067
$all_plugins = $this->get_all_plugins();
5068
5069
- foreach ( $all_plugins as $basename => &$data ) {
5070
if ( $addon->slug === $data['slug'] ||
5071
- $addon->slug . '-premium' === $data['slug']
5072
) {
5073
return $basename;
5074
}
@@ -5308,7 +5571,7 @@
5308
if ( ! isset( $this->_is_anonymous ) ) {
5309
if ( $this->is_network_anonymous() ) {
5310
$this->_is_anonymous = true;
5311
- } else {
5312
if ( ! isset( $this->_storage->is_anonymous ) ) {
5313
// Not skipped.
5314
$this->_is_anonymous = false;
@@ -5499,6 +5762,20 @@
5499
$this->_storage->store( "{$name}_timestamp", time() );
5500
}
5501
5502
/**
5503
* Check if cron was executed in the last $period of seconds.
5504
*
@@ -5513,7 +5790,7 @@
5513
private function is_cron_executed( $name, $period = WP_FS__TIME_24_HOURS_IN_SEC ) {
5514
$this->_logger->entrance( $name );
5515
5516
- $last_execution = $this->set_cron_execution_timestamp( $name );
5517
5518
if ( ! is_numeric( $last_execution ) ) {
5519
return false;
@@ -5774,12 +6051,14 @@
5774
}
5775
}
5776
5777
foreach ( $users_2_blog_ids as $user_id => $blog_ids ) {
5778
if ( 0 < $blog_ids[0] ) {
5779
$this->switch_to_blog( $blog_ids[0] );
5780
}
5781
5782
- call_user_func_array( $callable, array( $blog_ids ) );
5783
5784
foreach ( $blog_ids as $blog_id ) {
5785
$this->do_action( "after_{$name}_cron", $blog_id );
@@ -5787,6 +6066,8 @@
5787
}
5788
5789
if ( is_multisite() ) {
5790
$this->do_action( "after_{$name}_cron_multisite" );
5791
}
5792
}
@@ -5858,13 +6139,16 @@
5858
* @author Vova Feldman (@svovaf)
5859
* @since 2.0.0
5860
*
5861
- * @param int[] $blog_ids
5862
*/
5863
- function _sync_cron_method( array $blog_ids ) {
5864
if ( $this->is_registered() ) {
5865
if ( $this->has_paid_plan() ) {
5866
// Initiate background plan sync.
5867
- $this->_sync_license( true );
5868
5869
if ( $this->is_paying() ) {
5870
// Check for premium plugin updates.
@@ -6079,9 +6363,10 @@
6079
* @author Vova Feldman (@svovaf)
6080
* @since 2.0.0
6081
*
6082
- * @param int[] $blog_ids
6083
*/
6084
- function _sync_install_cron_method( array $blog_ids ) {
6085
if ( $this->is_registered() ) {
6086
if ( 1 < count( $blog_ids ) ) {
6087
$this->sync_installs( array(), true );
@@ -6185,6 +6470,7 @@
6185
if ( ! $this->is_addon() &&
6186
! ( ! $this->_is_network_active && fs_is_network_admin() ) &&
6187
(
6188
// Not registered nor anonymous.
6189
( ! $this->is_registered() && ! $this->is_anonymous() ) ||
6190
// OR, network level and in network upgrade mode.
@@ -6201,14 +6487,18 @@
6201
* @since 1.2.2
6202
*/
6203
if ( $this->is_theme()
6204
- && $this->is_only_premium()
6205
&& ! $this->has_settings_menu()
6206
&& ! isset( $_REQUEST['fs_action'] )
6207
&& $this->can_activate_previous_theme()
6208
) {
6209
- $this->activate_previous_theme();
6210
6211
- return;
6212
}
6213
6214
if ( ! fs_is_network_admin() &&
@@ -6308,7 +6598,7 @@
6308
$this->_module_type,
6309
sprintf( '<b><a href="%s">%s</a></b>',
6310
$this->get_activation_url(),
6311
- sprintf( $this->get_text_inline( 'Opt in to make "%s" Better!', 'optin-x-now' ), $this->get_plugin_name() )
6312
)
6313
),
6314
'connect_account',
@@ -6770,6 +7060,20 @@
6770
}
6771
}
6772
6773
if ( ! isset( $this->_storage->is_plugin_new_install ) ) {
6774
/**
6775
* If no previous version of plugin's version exist, it means that it's either
@@ -7039,7 +7343,7 @@
7039
private function remove_sdk_reference() {
7040
global $fs_active_plugins;
7041
7042
- foreach ( $fs_active_plugins->plugins as $sdk_path => &$data ) {
7043
if ( $this->_plugin_basename == $data->plugin_path ) {
7044
unset( $fs_active_plugins->plugins[ $sdk_path ] );
7045
break;
@@ -7221,6 +7525,23 @@
7221
}
7222
}
7223
7224
/**
7225
* Clears the anonymous mode and redirects to the opt-in screen.
7226
*
@@ -7234,6 +7555,8 @@
7234
7235
$this->reset_anonymous_mode( fs_is_network_admin() );
7236
7237
fs_redirect( $this->get_activation_url() );
7238
}
7239
@@ -7673,39 +7996,43 @@
7673
$include_plugins = true,
7674
$include_themes = true
7675
) {
7676
- /**
7677
- * @since 1.1.8 Also send plugin updates.
7678
- */
7679
- if ( $include_plugins && ! isset( $override['plugins'] ) ) {
7680
- $plugins = $this->get_plugins_data_for_api();
7681
- if ( ! empty( $plugins ) ) {
7682
- $override['plugins'] = $plugins;
7683
}
7684
}
7685
- /**
7686
- * @since 1.1.8 Also send themes updates.
7687
- */
7688
- if ( $include_themes && ! isset( $override['themes'] ) ) {
7689
- $themes = $this->get_themes_data_for_api();
7690
- if ( ! empty( $themes ) ) {
7691
- $override['themes'] = $themes;
7692
}
7693
}
7694
7695
- return array_merge( array(
7696
- 'version' => $this->get_plugin_version(),
7697
- 'is_premium' => $this->is_premium(),
7698
- 'language' => get_bloginfo( 'language' ),
7699
- 'charset' => get_bloginfo( 'charset' ),
7700
- 'platform_version' => get_bloginfo( 'version' ),
7701
- 'sdk_version' => $this->version,
7702
- 'programming_language_version' => phpversion(),
7703
- 'title' => get_bloginfo( 'name' ),
7704
- 'url' => get_site_url(),
7705
// Special params.
7706
- 'is_active' => true,
7707
- 'is_disconnected' => $this->is_tracking_prohibited(),
7708
- 'is_uninstalled' => false,
7709
), $override );
7710
}
7711
@@ -7750,12 +8077,10 @@
7750
// }
7751
7752
// Common properties.
7753
- $common = array_merge( array(
7754
- 'version' => $this->get_plugin_version(),
7755
- 'is_premium' => $this->is_premium(),
7756
- 'sdk_version' => $this->version,
7757
- 'programming_language_version' => phpversion(),
7758
- 'platform_version' => get_bloginfo( 'version' ),
7759
), $override );
7760
7761
@@ -7909,28 +8234,56 @@
7909
$params = $this->get_install_diff_for_api( $check_properties, $this->_site, $override );
7910
}
7911
7912
- if ( 0 < count( $params ) ) {
7913
if ( ! is_multisite() ) {
7914
// Update last install sync timestamp.
7915
$this->set_cron_execution_timestamp( 'install_sync' );
7916
}
7917
7918
$params['uid'] = $this->get_anonymous_id();
7919
7920
- // Send updated values to FS.
7921
- $site = $this->get_api_site_scope()->call( '/', 'put', $params );
7922
7923
- if ( $this->is_api_result_entity( $site ) ) {
7924
- if ( ! is_multisite() ) {
7925
- // I successfully sent install update, clear scheduled sync if exist.
7926
- $this->clear_install_sync_cron();
7927
- }
7928
- }
7929
7930
- return $site;
7931
}
7932
7933
- return false;
7934
}
7935
7936
/**
@@ -7949,24 +8302,70 @@
7949
7950
$installs_data = $this->get_installs_data_for_api( $override, ! $flush );
7951
7952
if ( empty( $installs_data ) ) {
7953
- return false;
7954
}
7955
7956
- // Update last install sync timestamp.
7957
- $this->set_cron_execution_timestamp( 'install_sync' );
7958
7959
// Send updated values to FS.
7960
$result = $this->get_api_user_scope()->call( "/plugins/{$this->_plugin->id}/installs.json", 'put', $installs_data );
7961
7962
- if ( $this->is_api_result_object( $result, 'installs' ) ) {
7963
- // I successfully sent installs update, clear scheduled sync if exist.
7964
$this->clear_install_sync_cron();
7965
}
7966
7967
return $result;
7968
}
7969
7970
/**
7971
* Update install only if changed.
7972
*
@@ -8171,14 +8570,59 @@
8171
// @todo Decide if we want to delete plugin information from db.
8172
}
8173
8174
/**
8175
* @author Vova Feldman (@svovaf)
8176
* @since 1.1.1
8177
*
8178
* @return string
8179
*/
8180
function premium_plugin_basename() {
8181
- return "{$this->_slug}-premium/" . basename( $this->_free_plugin_basename );
8182
}
8183
8184
/**
@@ -8317,13 +8761,29 @@
8317
}
8318
8319
/**
8320
* @author Vova Feldman (@svovaf)
8321
* @since 1.2.1.7
8322
*
8323
* @return string Plugin slug.
8324
*/
8325
function get_target_folder_name() {
8326
- return $this->_slug . ( $this->can_use_premium_code() ? '-premium' : '' );
8327
}
8328
8329
/**
@@ -8394,31 +8854,63 @@
8394
* @author Vova Feldman (@svovaf)
8395
* @since 1.0.9
8396
*
8397
- * @return string
8398
*/
8399
- function get_plugin_name() {
8400
- $this->_logger->entrance();
8401
8402
- if ( ! isset( $this->_plugin_name ) ) {
8403
- $plugin_data = $this->get_plugin_data();
8404
8405
- // Get name.
8406
- $this->_plugin_name = $plugin_data['Name'];
8407
8408
- // Check if plugin name contains "(Premium)" suffix and remove it.
8409
- $suffix = ' (premium)';
8410
- $suffix_len = strlen( $suffix );
8411
8412
- if ( strlen( $plugin_data['Name'] ) > $suffix_len &&
8413
- $suffix === substr( strtolower( $plugin_data['Name'] ), - $suffix_len )
8414
- ) {
8415
- $this->_plugin_name = substr( $plugin_data['Name'], 0, - $suffix_len );
8416
}
8417
-
8418
- $this->_logger->departure( 'Name = ' . $this->_plugin_name );
8419
}
8420
8421
- return $this->_plugin_name;
8422
}
8423
8424
/**
@@ -9124,7 +9616,16 @@
9124
* @return bool
9125
*/
9126
function is_premium() {
9127
- return $this->_plugin->is_premium;
9128
}
9129
9130
/**
@@ -10514,6 +11015,56 @@
10514
fs_require_template( 'forms/resend-key.php', $vars );
10515
}
10516
10517
/**
10518
* @author Leo Fajardo (@leorw)
10519
* @since 2.0.2
@@ -10698,7 +11249,7 @@
10698
'license_key' => $fs->apply_filters( 'license_key', $license_key )
10699
);
10700
10701
- $install = $api->call( '/', 'put', $params );
10702
10703
if ( FS_Api::is_api_error( $install ) ) {
10704
$error = FS_Api::is_api_error_object( $install ) ?
@@ -10791,6 +11342,10 @@
10791
}
10792
}
10793
10794
$result = array(
10795
'success' => ( false === $error )
10796
);
@@ -11045,6 +11600,34 @@
11045
static function get_current_page() {
11046
if ( ! isset( self::$_pagenow ) ) {
11047
global $pagenow;
11048
11049
self::$_pagenow = $pagenow;
11050
@@ -11076,6 +11659,16 @@
11076
return ( 'plugins.php' === self::get_current_page() );
11077
}
11078
11079
/**
11080
* @author Leo Fajardo (@leorw)
11081
* @since 2.0.2
@@ -11343,6 +11936,40 @@
11343
return $this->get_upgrade_url( WP_FS__PERIOD_ANNUALLY, true );
11344
}
11345
11346
/**
11347
* Plugin's pricing URL.
11348
*
@@ -11977,7 +12604,13 @@
11977
* @author Vova Feldman (@svovaf)
11978
*/
11979
$args = array(
11980
- 'public' => 1,
11981
'archived' => 0,
11982
'mature' => 0,
11983
'spam' => 0,
@@ -12173,7 +12806,7 @@
12173
12174
self::$_accounts->set_site_blog_context( $blog_id );
12175
$this->_storage->set_site_blog_context( $blog_id );
12176
- $this->_storage->set_network_active( true, $this->is_delegated_connection( $blog_id ) );
12177
12178
$this->_site = is_object( $install ) ?
12179
$install :
@@ -13122,6 +13755,12 @@
13122
}
13123
}
13124
13125
if ( $this->is_theme() ) {
13126
$this->_register_account_hooks();
13127
}
@@ -13187,6 +13826,30 @@
13187
13188
}
13189
13190
/**
13191
* @author Vova Feldman (@svovaf)
13192
* @since 1.1.7.4
@@ -13208,7 +13871,9 @@
13208
// Return to the module's main page.
13209
$this->get_after_activation_url( 'after_connect_url', array( 'fs_action' => $activation_action ) );
13210
13211
- $params = array(
13212
'user_firstname' => $current_user->user_firstname,
13213
'user_lastname' => $current_user->user_lastname,
13214
'user_nickname' => $current_user->user_nicename,
@@ -13223,13 +13888,10 @@
13223
'account',
13224
array( 'fs_action' => 'sync_user' )
13225
), 'sync_user' ),
13226
- 'platform_version' => get_bloginfo( 'version' ),
13227
- 'sdk_version' => $this->version,
13228
- 'programming_language_version' => phpversion(),
13229
'is_premium' => $this->is_premium(),
13230
'is_active' => true,
13231
'is_uninstalled' => false,
13232
- );
13233
13234
if ( true === $network_level_or_blog_id ) {
13235
if ( ! isset( $override_with['sites'] ) ) {
@@ -13415,7 +14077,7 @@
13415
'timeout' => WP_FS__DEBUG_SDK ? 60 : 30,
13416
);
13417
13418
- $url = WP_FS__ADDRESS . '/action/service/user/install/';
13419
$response = self::safe_remote_post( $url, $request );
13420
13421
if ( is_wp_error( $response ) ) {
@@ -14572,7 +15234,7 @@
14572
14573
$hook = false;
14574
14575
- if ( ! $this->_menu->has_menu() ) {
14576
// Add the opt-in page without a menu item.
14577
$hook = FS_Admin_Menu_Manager::add_subpage(
14578
null,
@@ -14920,15 +15582,25 @@
14920
}
14921
}
14922
14923
- if ( 0 < count( $this->_menu_items ) ) {
14924
- if ( ! $this->_menu->is_top_level() ) {
14925
- fs_enqueue_local_style( 'fs_common', '/admin/common.css' );
14926
14927
- // Append submenu items right after the plugin's submenu item.
14928
- $this->order_sub_submenu_items();
14929
- } else {
14930
- // Append submenu items.
14931
- $this->embed_submenu_items();
14932
}
14933
}
14934
}
@@ -14954,16 +15626,6 @@
14954
14955
foreach ( $this->_menu_items as $priority => $items ) {
14956
foreach ( $items as $item ) {
14957
- if ( $item['show_submenu'] && $is_first_submenu_item ) {
14958
- if ( $this->_is_network_active && ! empty( $this->_dynamically_added_top_level_page_hook_name ) ) {
14959
- $item['menu_slug'] = '';
14960
-
14961
- $this->_menu->override_menu_item( $item['render_function'] );
14962
- }
14963
-
14964
- $is_first_submenu_item = false;
14965
- }
14966
-
14967
$capability = ( ! empty( $item['capability'] ) ? $item['capability'] : $top_level_menu_capability );
14968
14969
$menu_item = sprintf(
@@ -14974,12 +15636,13 @@
14974
$item['menu_title']
14975
);
14976
14977
- $menu_slug = $this->_menu->get_slug( $item['menu_slug'] );
14978
14979
if ( ! isset( $item['url'] ) ) {
14980
$hook = FS_Admin_Menu_Manager::add_subpage(
14981
$item['show_submenu'] ?
14982
- $this->get_top_level_menu_slug() :
14983
null,
14984
$item['page_title'],
14985
$menu_item,
@@ -14994,7 +15657,7 @@
14994
} else {
14995
FS_Admin_Menu_Manager::add_subpage(
14996
$item['show_submenu'] ?
14997
- $this->get_top_level_menu_slug() :
14998
null,
14999
$item['page_title'],
15000
$menu_item,
@@ -15003,6 +15666,24 @@
15003
array( $this, '' )
15004
);
15005
}
15006
}
15007
}
15008
}
@@ -16245,11 +16926,12 @@
16245
* @param bool|number $plugin_id
16246
* @param bool $flush Since 1.1.7.3
16247
* @param int $expiration Since 1.2.2.7
16248
*
16249
* @return object|false New plugin tag info if exist.
16250
*/
16251
- private function _fetch_newer_version( $plugin_id = false, $flush = true, $expiration = WP_FS__TIME_24_HOURS_IN_SEC ) {
16252
- $latest_tag = $this->_fetch_latest_version( $plugin_id, $flush, $expiration );
16253
16254
if ( ! is_object( $latest_tag ) ) {
16255
return false;
@@ -16274,17 +16956,18 @@
16274
* @param bool|number $plugin_id
16275
* @param bool $flush Since 1.1.7.3
16276
* @param int $expiration Since 1.2.2.7
16277
*
16278
* @return bool|FS_Plugin_Tag
16279
*/
16280
- function get_update( $plugin_id = false, $flush = true, $expiration = WP_FS__TIME_24_HOURS_IN_SEC ) {
16281
$this->_logger->entrance();
16282
16283
if ( ! is_numeric( $plugin_id ) ) {
16284
$plugin_id = $this->_plugin->id;
16285
}
16286
16287
- $this->check_updates( true, $plugin_id, $flush, $expiration );
16288
$updates = $this->get_all_updates();
16289
16290
return isset( $updates[ $plugin_id ] ) && is_object( $updates[ $plugin_id ] ) ? $updates[ $plugin_id ] : false;
@@ -16437,8 +17120,11 @@
16437
* the admin.
16438
* @param bool $is_context_single_site @since 2.0.0. This is used when syncing a license for a single install from the
16439
* network-level "Account" page.
16440
*/
16441
- private function _sync_license( $background = false, $is_context_single_site = false ) {
16442
$this->_logger->entrance();
16443
16444
$plugin_id = fs_request_get( 'plugin_id', $this->get_id() );
@@ -16448,7 +17134,7 @@
16448
if ( $is_addon_sync ) {
16449
$this->_sync_addon_license( $plugin_id, $background );
16450
} else {
16451
- $this->_sync_plugin_license( $background, true, $is_context_single_site );
16452
}
16453
16454
$this->do_action( 'after_account_plan_sync', $this->get_plan_name() );
@@ -16538,11 +17224,15 @@
16538
* @param bool $is_context_single_site Since 2.0.0. This is used when sending an update for a single install and
16539
* syncing its license from the network-level "Account" page (e.g.: after
16540
* activating a license only for the single install).
16541
*/
16542
private function _sync_plugin_license(
16543
$background = false,
16544
$send_installs_update = true,
16545
- $is_context_single_site = false
16546
) {
16547
$this->_logger->entrance();
16548
@@ -16559,6 +17249,16 @@
16559
* @todo This line will execute install sync on a daily basis, even if running the free version (for opted-in users). The reason we want to keep it that way is for cases when the user was a paying customer, then there was a failure in subscription payment, and then after some time the payment was successful. This could be heavily optimized. For example, we can skip the $flush if the current install was never associated with a paid version.
16560
*/
16561
if ( $is_site_level_sync ) {
16562
$result = $this->send_install_update( array(), true );
16563
$is_valid = $this->is_api_result_entity( $result );
16564
} else {
@@ -17068,6 +17768,18 @@
17068
$api = $this->get_api_site_scope();
17069
$license = $api->call( "/licenses/{$this->_site->license_id}.json", 'delete' );
17070
17071
if ( isset( $license->error ) ) {
17072
$this->_admin_notices->add(
17073
$this->get_text_inline( 'It looks like the license deactivation failed.', 'license-deactivation-failed-message' ) . '<br> ' .
@@ -17088,7 +17800,7 @@
17088
}
17089
}
17090
17091
- // Updated site plan to default.
17092
$this->_sync_plans();
17093
$this->_site->plan_id = $this->_plans[0]->id;
17094
// Unlink license from site.
@@ -17115,13 +17827,17 @@
17115
* @author Vova Feldman (@svovaf)
17116
* @since 1.0.4
17117
*
17118
* @uses FS_Api
17119
*/
17120
private function _downgrade_site() {
17121
$this->_logger->entrance();
17122
17123
$api = $this->get_api_site_scope();
17124
- $site = $api->call( 'downgrade.json', 'put' );
17125
17126
$plan_downgraded = false;
17127
$plan = false;
@@ -17139,29 +17855,47 @@
17139
( is_object( $subscription ) && ! isset( $subscription->error ) && ! $subscription->is_active() );
17140
} else {
17141
// handle different error cases.
17142
-
17143
}
17144
17145
- if ( $plan_downgraded ) {
17146
- // Remove previous sticky message about upgrade (if exist).
17147
- $this->_admin_notices->remove_sticky( 'plan_upgraded' );
17148
-
17149
- $this->_admin_notices->add(
17150
- sprintf( $this->get_text_inline( 'Your plan was successfully downgraded. Your %s plan license will expire in %s.', 'plan-x-downgraded-message' ),
17151
- $plan->title,
17152
- human_time_diff( time(), strtotime( $this->_license->expiration ) )
17153
)
17154
);
17155
17156
- // Store site updates.
17157
- $this->_store_site();
17158
- } else {
17159
- $this->_admin_notices->add(
17160
- $this->get_text_inline( 'Seems like we are having some temporary issue with your plan downgrade. Please try again in few minutes.', 'plan-downgraded-failure-message' ),
17161
- $this->get_text_x_inline( 'Oops', 'exclamation', 'oops' ) . '...',
17162
- 'error'
17163
- );
17164
}
17165
}
17166
17167
/**
@@ -17268,22 +18002,19 @@
17268
* @author Vova Feldman (@svovaf)
17269
* @since 1.0.9
17270
*
17271
* @uses FS_Api
17272
*/
17273
private function _cancel_trial() {
17274
$this->_logger->entrance();
17275
17276
- // Alias.
17277
- $oops_text = $this->get_text_x_inline( 'Oops', 'exclamation', 'oops' ) . '...';
17278
-
17279
if ( ! $this->is_trial() ) {
17280
- $this->_admin_notices->add(
17281
- $this->get_text_inline( 'It looks like you are not in trial mode anymore so there\'s nothing to cancel :)', 'trial-cancel-no-trial-message' ),
17282
- $oops_text,
17283
- 'error'
17284
);
17285
-
17286
- return;
17287
}
17288
17289
$trial_plan = $this->get_trial_plan();
@@ -17314,31 +18045,33 @@
17314
// @todo handle different error cases.
17315
}
17316
17317
- if ( $trial_cancelled ) {
17318
- // Remove previous sticky messages about upgrade or trial (if exist).
17319
- $this->_admin_notices->remove_sticky( array(
17320
- 'trial_started',
17321
- 'trial_promotion',
17322
- 'plan_upgraded',
17323
- ) );
17324
17325
- // Store site updates.
17326
- $this->_store_site();
17327
17328
- if ( ! $this->is_addon() ||
17329
- ! $this->deactivate_premium_only_addon_without_license( true )
17330
- ) {
17331
- $this->_admin_notices->add(
17332
- sprintf( $this->get_text_inline( 'Your %s free trial was successfully cancelled.', 'trial-cancel-message' ), $trial_plan->title )
17333
- );
17334
- }
17335
- } else {
17336
$this->_admin_notices->add(
17337
- $this->get_text_inline( 'Seems like we are having some temporary issue with your trial cancellation. Please try again in few minutes.', 'trial-cancel-failure-message' ),
17338
- $oops_text,
17339
- 'error'
17340
);
17341
}
17342
}
17343
17344
/**
@@ -17409,15 +18142,19 @@
17409
* @since 1.0.4
17410
*
17411
* @param bool|number $addon_id
17412
- * @param bool $flush Since 1.1.7.3
17413
- * @param int $expiration Since 1.2.2.7
17414
*
17415
* @return object|false Plugin latest tag info.
17416
*/
17417
function _fetch_latest_version(
17418
$addon_id = false,
17419
$flush = true,
17420
- $expiration = WP_FS__TIME_24_HOURS_IN_SEC
17421
) {
17422
$this->_logger->entrance();
17423
@@ -17468,8 +18205,18 @@
17468
$this->switch_to_blog( $switch_to_blog_id );
17469
}
17470
17471
$tag = $this->get_api_site_or_plugin_scope()->get(
17472
- $this->_get_latest_version_endpoint( $addon_id, 'json' ),
17473
$flush,
17474
$expiration
17475
);
@@ -17605,17 +18352,19 @@
17605
* @param bool|number $plugin_id
17606
* @param bool $flush Since 1.1.7.3
17607
* @param int $expiration Since 1.2.2.7
17608
*/
17609
private function check_updates(
17610
$background = false,
17611
$plugin_id = false,
17612
$flush = true,
17613
- $expiration = WP_FS__TIME_24_HOURS_IN_SEC
17614
) {
17615
$this->_logger->entrance();
17616
17617
// Check if there's a newer version for download.
17618
- $new_version = $this->_fetch_newer_version( $plugin_id, $flush, $expiration );
17619
17620
$update = null;
17621
if ( is_object( $new_version ) ) {
@@ -17971,7 +18720,9 @@
17971
*/
17972
function get_after_activation_url( $filter, $params = array(), $network = null ) {
17973
if ( $this->is_free_wp_org_theme() &&
17974
- fs_request_has( 'pending_activation' )
17975
) {
17976
$first_time_path = '';
17977
} else {
@@ -18103,6 +18854,8 @@
18103
$this->_site = null;
18104
$this->_user = null;
18105
18106
fs_redirect( $this->get_activation_url() );
18107
} else {
18108
if ( $this->is_addon_activated( $plugin_id ) ) {
@@ -18122,15 +18875,23 @@
18122
check_admin_referer( $action );
18123
}
18124
18125
- if ( $plugin_id == $this->get_id() ) {
18126
- $this->_downgrade_site();
18127
18128
- if ( is_numeric( $blog_id ) ) {
18129
- $this->switch_to_blog( $this->_storage->network_install_blog_id );
18130
- }
18131
- } else if ( $this->is_addon_activated( $plugin_id ) ) {
18132
- $fs_addon = self::get_instance_by_id( $plugin_id );
18133
- $fs_addon->_downgrade_site();
18134
}
18135
18136
return;
@@ -18162,7 +18923,11 @@
18162
$this->_site = null;
18163
$this->_user = null;
18164
18165
- fs_redirect( $this->get_activation_url() );
18166
}
18167
} else {
18168
if ( $this->is_addon_activated( $plugin_id ) ) {
@@ -18260,13 +19025,13 @@
18260
#region Actions that might be called from external links (e.g. email)
18261
18262
case 'cancel_trial':
18263
- if ( $plugin_id == $this->get_id() ) {
18264
- $this->_cancel_trial();
18265
- } else {
18266
- if ( $this->is_addon_activated( $plugin_id ) ) {
18267
- $fs_addon = self::get_instance_by_id( $plugin_id );
18268
- $fs_addon->_cancel_trial();
18269
- }
18270
}
18271
18272
return;
@@ -19262,11 +20027,23 @@
19262
19263
if ( ! $this->is_addon() || ! $this->has_free_plan() ) {
19264
$first_time_path = $this->_menu->get_first_time_path();
19265
- $url = $this->is_activation_mode() ?
19266
- $this->get_activation_url() :
19267
- ( empty( $first_time_path ) ?
19268
- $this->_get_admin_page_url() :
19269
- $first_time_path );
19270
} else {
19271
$plugin_fs = false;
19272
@@ -19386,6 +20163,21 @@
19386
$this->_admin_notices->add_sticky( $message, $id, $title, $type );
19387
}
19388
19389
/**
19390
* Helper function that returns the final steps for the upgrade completion.
19391
*
@@ -19411,25 +20203,52 @@
19411
$plan_title = $this->get_plan_title();
19412
}
19413
19414
- // @since 1.2.1.5 The free version is auto deactivated.
19415
- $deactivation_step = version_compare( $this->version, '1.2.1.5', '<' ) ?
19416
- ( '<li>' . $this->esc_html_inline( 'Deactivate the free version', 'deactivate-free-version' ) . '.</li>' ) :
19417
- '';
19418
19419
- return sprintf(
19420
- ' %s: <ol><li>%s.</li>%s<li>%s (<a href="%s" target="_blank">%s</a>).</li></ol>',
19421
- $this->get_text_inline( 'Please follow these steps to complete the upgrade', 'follow-steps-to-complete-upgrade' ),
19422
- ( empty( $activate_license_string ) ? '' : $activate_license_string . '</li><li>' ) .
19423
- $this->get_latest_download_link( sprintf(
19424
- /* translators: %s: Plan title */
19425
- $this->get_text_inline( 'Download the latest %s version', 'download-latest-x-version' ),
19426
- $plan_title
19427
- ) ),
19428
- $deactivation_step,
19429
- $this->get_text_inline( 'Upload and activate the downloaded version', 'upload-and-activate' ),
19430
- '//bit.ly/upload-wp-' . $this->_module_type . 's',
19431
- $this->get_text_inline( 'How to upload and activate?', 'howto-upload-activate' )
19432
- );
19433
}
19434
19435
/**
@@ -20212,13 +21031,19 @@
20212
20213
// Locate the main assets folder.
20214
if ( 1 < count( $fs_active_plugins->plugins ) ) {
20215
- $plugin_or_theme_img_dir = ( $this->is_plugin() ? WP_PLUGIN_DIR : get_theme_root() );
20216
20217
foreach ( $fs_active_plugins->plugins as $sdk_path => &$data ) {
20218
if ( $data->plugin_path == $this->get_plugin_basename() ) {
20219
$img_dir = $plugin_or_theme_img_dir
20220
. '/'
20221
- . str_replace( '../themes/', '', $sdk_path )
20222
. '/assets/img';
20223
20224
break;
33
* @var string
34
*/
35
private $_plugin_basename;
36
+ /**
37
+ * @since 2.2.1
38
+ *
39
+ * @var string
40
+ */
41
+ private $_premium_plugin_basename;
42
/**
43
* @since 1.0.0
44
*
677
version_compare( $sdk_version, '1.2.3', '>=' )
678
) {
679
/**
680
+ * Starting from version 1.2.3, paths are stored as relative instead of absolute and some of them can be
681
+ * invalid.
682
*
683
* @author Leo Fajardo (@leorw)
684
*/
685
+ $this->remove_invalid_paths();
686
}
687
688
if ( version_compare( $sdk_prev_version, '1.1.5', '<' ) &&
706
707
}
708
}
709
+
710
+ if (
711
+ version_compare( $sdk_prev_version, '2.2.1', '<' ) &&
712
+ version_compare( $sdk_version, '2.2.1', '>=' )
713
+ ) {
714
+ /**
715
+ * Clear the file cache without storing the previous path since it could be a wrong path. For example,
716
+ * 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
717
+ * as the parent plugin's when the add-on was auto-installed since the relevant method names were not
718
+ * skipped in the logic that determines the right path in the `get_caller_main_file_and_type` method
719
+ * (e.g. `try_activate_plugin`). Since it was an auto-installation, the caller was the parent plugin
720
+ * and so its path was used. In case the stored path is wrong, clearing the cache will resolve issues
721
+ * related to data mix-up between plugins (e.g. titles and versions of an add-on and its parent plugin).
722
+ *
723
+ * @author Leo Fajardo (@leorw)
724
+ * @since 2.2.1
725
+ */
726
+ $this->clear_module_main_file_cache( false );
727
+ }
728
}
729
730
/**
850
}
851
852
/**
853
+ * Remove invalid paths.
854
*
855
* @author Leo Fajardo (@leorw)
856
* @since 1.2.3
857
*/
858
+ private function remove_invalid_paths() {
859
// Remove invalid path that is still associated with the current slug if there's any.
860
$file_slug_map = self::$_accounts->get_option( 'file_slug_map', array() );
861
foreach ( $file_slug_map as $plugin_basename => $slug ) {
1238
<?php
1239
}
1240
1241
+ /**
1242
+ * Opens the support forum subemenu item in a new browser page.
1243
+ *
1244
+ * @author Vova Feldman (@svovaf)
1245
+ * @since 2.1.4
1246
+ */
1247
+ static function _open_support_forum_in_new_page() {
1248
+ ?>
1249
+ <script type="text/javascript">
1250
+ (function ($) {
1251
+ $('.fs-submenu-item.wp-support-forum').parent().attr('target', '_blank');
1252
+ })(jQuery);
1253
+ </script>
1254
+ <?php
1255
+ }
1256
+
1257
/**
1258
* @author Vova Feldman (@svovaf)
1259
* @since 1.0.9
1265
add_action( 'plugins_loaded', array( &$this, '_hook_action_links_and_register_account_hooks' ) );
1266
1267
if ( $this->is_plugin() ) {
1268
+ if ( self::is_plugin_install_page() && true !== fs_request_get_bool( 'fs_allow_updater_and_dialog' ) ) {
1269
+ /**
1270
+ * Unless the `fs_allow_updater_and_dialog` URL param exists and its value is `true`, make
1271
+ * Freemius-related updates unavailable on the "Add Plugins" admin page (/plugin-install.php)
1272
+ * so that they won't interfere with the .org plugins' functionalities on that page (e.g.
1273
+ * updating of a .org plugin).
1274
+ */
1275
+ add_filter( 'site_transient_update_plugins', array( 'Freemius', '_remove_fs_updates_from_plugin_install_page' ), 10, 2 );
1276
+ } else if ( self::is_plugins_page() || self::is_updates_page() ) {
1277
+ /**
1278
+ * On the "Plugins" and "Updates" admin pages, if there are premium or non–org-compliant
1279
+ * plugins, modify their details dialog URLs (add a Freemius-specific param) so that the SDK can
1280
+ * determine if the plugin information dialog should show information from Freemius.
1281
+ *
1282
+ * @author Leo Fajardo (@leorw)
1283
+ * @since 2.2.3
1284
+ */
1285
+ add_action( 'admin_footer', array( 'Freemius', '_prepend_fs_allow_updater_and_dialog_flag_url_param' ) );
1286
+ }
1287
+
1288
$plugin_dir = dirname( $this->_plugin_dir_path ) . '/';
1289
1290
/**
1452
}
1453
}
1454
1455
+ /**
1456
+ * Makes Freemius-related updates unavailable on the "Add Plugins" admin page (/plugin-install.php) so that
1457
+ * they won't interfere with the .org plugins' functionalities on that page (e.g. updating of a .org plugin).
1458
+ *
1459
+ * @author Leo Fajardo (@leorw)
1460
+ * @since 2.2.3
1461
+ *
1462
+ * @param object $updates
1463
+ * @param string|null $transient
1464
+ *
1465
+ * @return object
1466
+ */
1467
+ static function _remove_fs_updates_from_plugin_install_page( $updates, $transient = null ) {
1468
+ if ( is_object( $updates ) && isset( $updates->response ) ) {
1469
+ foreach ( $updates->response as $file => $plugin ) {
1470
+ if ( false !== strpos( $plugin->package, 'api.freemius' ) ) {
1471
+ unset( $updates->response[ $file ] );
1472
+ }
1473
+ }
1474
+ }
1475
+
1476
+ return $updates;
1477
+ }
1478
+
1479
+ /**
1480
+ * Prepends the `fs_allow_updater_and_dialog` param to the plugin information URLs to tell the SDK to handle
1481
+ * the information that is shown on the plugin details dialog that is shown when the relevant link is clicked.
1482
+ *
1483
+ * @author Leo Fajardo (@leorw)
1484
+ * @since 2.2.3
1485
+ *
1486
+ * @return string
1487
+ */
1488
+ static function _prepend_fs_allow_updater_and_dialog_flag_url_param() {
1489
+ $slug_basename_map = array();
1490
+ foreach ( self::$_instances as $instance ) {
1491
+ if ( ! $instance->is_plugin() ) {
1492
+ continue;
1493
+ }
1494
+
1495
+ $slug_basename_map[ $instance->get_slug() ] = $instance->premium_plugin_basename();
1496
+ }
1497
+ ?>
1498
+ <script type="text/javascript">
1499
+ (function( $ ) {
1500
+ var slugBasenameMap = <?php echo json_encode( $slug_basename_map ) ?>;
1501
+ for ( var slug in slugBasenameMap ) {
1502
+ var basename = slugBasenameMap[ slug ];
1503
+
1504
+ // Try to get the plugin rows if on the "Plugins" page.
1505
+ var $pluginRows = $( '.wp-list-table.plugins tr[data-plugin="' + basename + '"]');
1506
+
1507
+ if ( 0 === $pluginRows.length ) {
1508
+ // Try to get the plugin rows if on the "Updates" page.
1509
+ var $pluginCheckbox = $( '#update-plugins-table input[type="checkbox"][value="' + basename + '"]' );
1510
+ if ( 0 !== $pluginCheckbox.length ) {
1511
+ $pluginRows = $pluginCheckbox.parents( 'tr:first' );
1512
+ }
1513
+ }
1514
+
1515
+ if ( 0 === $pluginRows.length ) {
1516
+ // No plugin rows found.
1517
+ continue;
1518
+ }
1519
+
1520
+ // Find the "View details" links and add the `fs_allow_updater_and_dialog` param to the URL.
1521
+ $pluginRows.find( 'a[href*="plugin-install.php?tab=plugin-information"]' ).each(function() {
1522
+ var $this = $( this ),
1523
+ href = $this.attr( 'href' ).replace( '?tab=', '?fs_allow_updater_and_dialog=true&tab=');
1524
+
1525
+ $this.attr( 'href', href );
1526
+ });
1527
+ }
1528
+ })( jQuery );
1529
+ </script>
1530
+ <?php
1531
+ }
1532
+
1533
/**
1534
* Keeping the uninstall hook registered for free or premium plugin version may result to a fatal error that
1535
* could happen when a user tries to uninstall either version while one of them is still active. Uninstalling a
1550
1551
/**
1552
* @since 1.2.0 Invalidate module's main file cache, otherwise, FS_Plugin_Updater will not fetch updates.
1553
+ *
1554
+ * @param bool $store_prev_path
1555
*/
1556
+ private function clear_module_main_file_cache( $store_prev_path = true ) {
1557
if ( ! isset( $this->_storage->plugin_main_file ) ||
1558
+ empty( $this->_storage->plugin_main_file->path )
1559
) {
1560
return;
1561
}
1562
1563
+ if ( ! $store_prev_path ) {
1564
+ /**
1565
+ * Storing the previous path is not needed when clearing the cache after an SDK version update since
1566
+ * the main purpose of the cache clearing in that event is to correct a wrong plugin main file path
1567
+ * which causes data mix-up between plugins (e.g. titles and versions of an add-on and its parent plugin).
1568
+ *
1569
+ * @author Leo Fajardo (@leorw)
1570
+ * @since 2.2.1
1571
+ */
1572
+ unset( $this->_storage->plugin_main_file->path );
1573
+ } else {
1574
+ $plugin_main_file = clone $this->_storage->plugin_main_file;
1575
1576
+ // Store cached path (2nd layer cache).
1577
+ $plugin_main_file->prev_path = $plugin_main_file->path;
1578
1579
+ // Clear cached path.
1580
+ unset( $plugin_main_file->path );
1581
1582
+ $this->_storage->plugin_main_file = $plugin_main_file;
1583
+ }
1584
1585
/**
1586
* Clear global cached path.
1627
array( &$this, '_submit_uninstall_reason_action' )
1628
);
1629
1630
+ $this->add_ajax_action(
1631
+ 'cancel_subscription_or_trial',
1632
+ array( &$this, 'cancel_subscription_or_trial_ajax_action' )
1633
+ );
1634
+
1635
if ( ! $this->is_addon() || $this->is_parent_plugin_installed() ) {
1636
if ( ( $this->is_plugin() && self::is_plugins_page() ) ||
1637
( $this->is_theme() && self::is_themes_page() )
1756
1757
return fs_normalize_path( trailingslashit( $is_plugin ?
1758
WP_PLUGIN_DIR :
1759
+ get_theme_root( get_stylesheet() ) ) );
1760
}
1761
1762
/**
1821
private function get_caller_main_file_and_type() {
1822
self::require_plugin_essentials();
1823
1824
+ $all_plugins = fs_get_plugins( true );
1825
$all_plugins_paths = array();
1826
1827
// Get active plugin's main files real full names (might be symlinks).
1828
+ foreach ( $all_plugins as $relative_path => $data ) {
1829
if ( false === strpos( fs_normalize_path( $relative_path ), '/' ) ) {
1830
/**
1831
* Ignore plugins that don't have a folder (e.g. Hello Dolly) since they
1843
$caller_file_candidate = false;
1844
$caller_map = array();
1845
$module_type = WP_FS__MODULE_TYPE_PLUGIN;
1846
+ $themes_dir = fs_normalize_path( get_theme_root( get_stylesheet() ) );
1847
1848
for ( $i = 1, $bt = debug_backtrace(), $len = count( $bt ); $i < $len; $i ++ ) {
1849
if ( empty( $bt[ $i ]['file'] ) ) {
1863
'requir' . 'e_once',
1864
'requir' . 'e',
1865
'includ' . 'e_once',
1866
+ 'includ' . 'e',
1867
+ 'install_and_activate_plugin',
1868
+ 'try_activate_plugin',
1869
+ 'activate_plugin'
1870
) )
1871
) {
1872
// Ignore call stack hooks and files inclusion.
2202
exit;
2203
}
2204
2205
+ /**
2206
+ * @author Leo Fajardo (@leorw)
2207
+ * @since 2.1.4
2208
+ */
2209
+ function cancel_subscription_or_trial_ajax_action() {
2210
+ $this->_logger->entrance();
2211
+
2212
+ $this->check_ajax_referer( 'cancel_subscription_or_trial' );
2213
+
2214
+ $result = $this->cancel_subscription_or_trial( fs_request_get( 'plugin_id', $this->get_id() ), false );
2215
+
2216
+ if ( $this->is_api_error( $result ) ) {
2217
+ $this->shoot_ajax_failure( $result->error->message );
2218
+ }
2219
+
2220
+ $this->shoot_ajax_success();
2221
+ }
2222
+
2223
+ /**
2224
+ * @author Leo Fajardo (@leorw)
2225
+ * @since 2.1.4
2226
+ *
2227
+ * @param number $plugin_id
2228
+ *
2229
+ * @return object
2230
+ */
2231
+ private function cancel_subscription_or_trial( $plugin_id ) {
2232
+ $fs = null;
2233
+ if ( $plugin_id == $this->get_id() ) {
2234
+ $fs = $this;
2235
+ } else if ( $this->is_addon_activated( $plugin_id ) ) {
2236
+ $fs = self::get_instance_by_id( $plugin_id );
2237
+ }
2238
+
2239
+ $result = null;
2240
+
2241
+ if ( ! is_null( $fs ) ) {
2242
+ $result = $fs->is_paid_trial() ?
2243
+ $fs->_cancel_trial() :
2244
+ $fs->_downgrade_site();
2245
+ }
2246
+
2247
+ return $result;
2248
+ }
2249
+
2250
/**
2251
* @author Leo Fajardo (@leorw)
2252
* @since 2.0.2
2323
* @since 1.2.2
2324
*
2325
* @param string|number $id_or_slug
2326
+ * @param string $module_type
2327
*
2328
* @return number|false
2329
*/
2330
+ private static function get_module_id( $id_or_slug, $module_type = WP_FS__MODULE_TYPE_PLUGIN ) {
2331
if ( is_numeric( $id_or_slug ) ) {
2332
return $id_or_slug;
2333
}
2334
2335
foreach ( self::$_instances as $instance ) {
2336
+ // Also check the module type since there can be a plugin and a theme with the same slug.
2337
+ if ( ( $module_type === $instance->get_module_type() ) && ( $id_or_slug === $instance->get_slug() ) ) {
2338
return $instance->get_id();
2339
}
2340
}
2361
* @author Vova Feldman (@svovaf)
2362
* @since 1.0.1
2363
*
2364
+ * @param string $plugin_file
2365
+ * @param string $module_type
2366
*
2367
* @return false|Freemius
2368
*/
2369
+ static function get_instance_by_file( $plugin_file, $module_type = WP_FS__MODULE_TYPE_PLUGIN ) {
2370
$slug = self::find_slug_by_basename( $plugin_file );
2371
2372
return ( false !== $slug ) ?
2373
+ self::instance( self::get_module_id( $slug, $module_type ) ) :
2374
false;
2375
}
2376
2484
function is_site_activation_mode( $and_on = true ) {
2485
return (
2486
( $this->is_on() || ! $and_on ) &&
2487
+ ( $this->is_premium() && true === $this->_storage->require_license_activation ) ||
2488
+ (
2489
+ ( ! $this->is_registered() ||
2490
+ ( $this->is_only_premium() && ! $this->has_features_enabled_license() ) ) &&
2491
+ ( ! $this->is_enable_anonymous() ||
2492
+ ( ! $this->is_anonymous() && ! $this->is_pending_activation() ) )
2493
+ )
2494
);
2495
}
2496
2525
return false;
2526
}
2527
2528
+ if ( $this->is_network_anonymous() && true !== $this->_storage->require_license_activation ) {
2529
// Super-admin skipped the connection network wide -> not activation mode.
2530
return false;
2531
}
2646
self::require_plugin_essentials();
2647
2648
$active_plugin = array();
2649
+ $all_plugins = fs_get_plugins();
2650
$active_plugins_basenames = self::get_active_plugins_basenames( $blog_id );
2651
2652
foreach ( $active_plugins_basenames as $plugin_basename ) {
2672
get_option( 'active_plugins' );
2673
2674
$active = array();
2675
+
2676
+ if ( ! is_array( $active_basenames ) ) {
2677
+ return $active;
2678
+ }
2679
+
2680
foreach ( $active_basenames as $basename ) {
2681
$active[ $basename ] = array(
2682
'is_active' => true,
2701
private static function get_all_plugins( $blog_id = 0 ) {
2702
self::require_plugin_essentials();
2703
2704
+ $all_plugins = fs_get_plugins();
2705
2706
$active_plugins_basenames = self::get_active_plugins_basenames( $blog_id );
2707
2733
private static function get_network_plugins() {
2734
self::require_plugin_essentials();
2735
2736
+ $all_plugins = fs_get_plugins();
2737
2738
$network_active_basenames = is_multisite() ?
2739
get_site_option( 'active_sitewide_plugins' ) :
2877
}
2878
2879
add_action( 'admin_footer', array( 'Freemius', '_enrich_ajax_url' ) );
2880
+ add_action( 'admin_footer', array( 'Freemius', '_open_support_forum_in_new_page' ) );
2881
+
2882
2883
self::$_statics_loaded = true;
2884
}
2977
* @since 1.1.7.3
2978
*/
2979
static function _toggle_debug_mode() {
2980
+ if ( ! is_super_admin() ) {
2981
+ return;
2982
+ }
2983
+
2984
$is_on = fs_request_get( 'is_on', false, 'post' );
2985
2986
if ( fs_request_is_post() && in_array( $is_on, array( 0, 1 ) ) ) {
3012
* @since 1.2.1.7
3013
*/
3014
static function _get_db_option() {
3015
+ check_admin_referer( 'fs_get_db_option' );
3016
+
3017
$option_name = fs_request_get( 'option_name' );
3018
3019
+ if ( ! is_super_admin() ||
3020
+ ! fs_starts_with( $option_name, 'fs_' )
3021
+ ) {
3022
+ self::shoot_ajax_failure();
3023
+ }
3024
+
3025
$value = get_option( $option_name );
3026
3027
$result = array(
3044
* @since 1.2.1.7
3045
*/
3046
static function _set_db_option() {
3047
+ check_admin_referer( 'fs_set_db_option' );
3048
+
3049
+ $option_name = fs_request_get( 'option_name' );
3050
+
3051
+ if ( ! is_super_admin() ||
3052
+ ! fs_starts_with( $option_name, 'fs_' )
3053
+ ) {
3054
+ self::shoot_ajax_failure();
3055
+ }
3056
+
3057
$option_value = fs_request_get( 'option_value' );
3058
3059
if ( ! empty( $option_value ) ) {
4291
* @author Vova Feldman (@svovaf)
4292
*/
4293
if ( $this->is_user_in_admin() &&
4294
+ 'plugin-information' === fs_request_get( 'tab', false ) &&
4295
+ $this->should_use_freemius_updater_and_dialog() &&
4296
+ (
4297
+ ( $this->is_addon() && $this->get_slug() == fs_request_get( 'plugin', false ) ) ||
4298
+ ( $this->has_addons() && $this->get_id() == fs_request_get( 'parent_plugin_id', false ) )
4299
+ )
4300
) {
4301
require_once WP_FS__DIR_INCLUDES . '/fs-plugin-info-dialog.php';
4302
4303
+ new FS_Plugin_Info_Dialog( $this->is_addon() ? $this->get_parent_instance() : $this );
4304
}
4305
4306
// Check if Freemius is on for the current plugin.
4414
* @author Vova Feldman
4415
* @since 1.2.1.6
4416
*/
4417
+ if (
4418
+ $this->should_use_freemius_updater_and_dialog() &&
4419
+ (
4420
+ $this->is_premium() ||
4421
+ /**
4422
+ * If not premium but the premium version is installed, also instantiate the updater so that the
4423
+ * plugin information dialog of the premium version will have the information from the server.
4424
+ *
4425
+ * @author Leo Fajardo (@leorw)
4426
+ * @since 2.2.3
4427
+ */
4428
+ ( file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $this->premium_plugin_basename() ) ) )
4429
+ ) &&
4430
+ $this->has_release_on_freemius()
4431
+ ) {
4432
FS_Plugin_Updater::instance( $this );
4433
}
4434
4471
}
4472
}
4473
4474
+ /**
4475
+ * @author Leo Fajardo (@leorw)
4476
+ * @since 2.2.3
4477
+ *
4478
+ * @return bool
4479
+ */
4480
+ private function should_use_freemius_updater_and_dialog() {
4481
+ return (
4482
+ /**
4483
+ * Unless the `fs_allow_updater_and_dialog` URL param exists and its value is `true`, disallow updater
4484
+ * and dialog on the "Add Plugins" admin page (/plugin-install.php) so that they won't interfere with
4485
+ * the .org plugins' functionalities on that page (e.g. installation and viewing plugin details from
4486
+ * .org).
4487
+ */
4488
+ ( ! self::is_plugin_install_page() || true === fs_request_get_bool( 'fs_allow_updater_and_dialog' ) ) &&
4489
+ // Disallow updater and dialog when installing a plugin, otherwise .org "add-on" plugins will be affected.
4490
+ ( 'install-plugin' !== fs_request_get( 'action' ) )
4491
+ );
4492
+ }
4493
+
4494
/**
4495
* @author Leo Fajardo (@leorw)
4496
*
4927
$this->_plugin :
4928
new FS_Plugin();
4929
4930
+ $premium_suffix = $this->get_option( $plugin_info, 'premium_suffix', '(Premium)' );
4931
+
4932
$plugin->update( array(
4933
'id' => $id,
4934
'type' => $this->get_option( $plugin_info, 'type', $this->_module_type ),
4935
'public_key' => $public_key,
4936
'slug' => $this->_slug,
4937
+ 'premium_slug' => $this->get_option( $plugin_info, 'premium_slug', "{$this->_slug}-premium" ),
4938
'parent_plugin_id' => $parent_id,
4939
'version' => $this->get_plugin_version(),
4940
+ 'title' => $this->get_plugin_name( $premium_suffix ),
4941
'file' => $this->_plugin_basename,
4942
'is_premium' => $this->get_bool_option( $plugin_info, 'is_premium', true ),
4943
+ 'premium_suffix' => $premium_suffix,
4944
'is_live' => $this->get_bool_option( $plugin_info, 'is_live', true ),
4945
'affiliate_moderation' => $this->get_option( $plugin_info, 'has_affiliation' ),
4946
) );
5321
}
5322
5323
$addon = $this->get_addon( $addon_id );
5324
+ $premium_basename = "{$addon->premium_slug}/{$addon->slug}.php";
5325
5326
if ( file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $premium_basename ) ) ) {
5327
return $premium_basename;
5329
5330
$all_plugins = $this->get_all_plugins();
5331
5332
+ foreach ( $all_plugins as $basename => $data ) {
5333
if ( $addon->slug === $data['slug'] ||
5334
+ $addon->premium_slug === $data['slug']
5335
) {
5336
return $basename;
5337
}
5571
if ( ! isset( $this->_is_anonymous ) ) {
5572
if ( $this->is_network_anonymous() ) {
5573
$this->_is_anonymous = true;
5574
+ } else if ( ! fs_is_network_admin() ) {
5575
if ( ! isset( $this->_storage->is_anonymous ) ) {
5576
// Not skipped.
5577
$this->_is_anonymous = false;
5762
$this->_storage->store( "{$name}_timestamp", time() );
5763
}
5764
5765
+ /**
5766
+ * Sets the keepalive time to now.
5767
+ *
5768
+ * @author Leo Fajardo (@leorw)
5769
+ * @since 2.2.3
5770
+ *
5771
+ * @param bool|null $use_network_level_storage
5772
+ */
5773
+ private function set_keepalive_timestamp( $use_network_level_storage = null ) {
5774
+ $this->_logger->entrance();
5775
+
5776
+ $this->_storage->store( 'keepalive_timestamp', time(), $use_network_level_storage );
5777
+ }
5778
+
5779
/**
5780
* Check if cron was executed in the last $period of seconds.
5781
*
5790
private function is_cron_executed( $name, $period = WP_FS__TIME_24_HOURS_IN_SEC ) {
5791
$this->_logger->entrance( $name );
5792
5793
+ $last_execution = $this->cron_last_execution( $name );
5794
5795
if ( ! is_numeric( $last_execution ) ) {
5796
return false;
6051
}
6052
}
6053
6054
+ $current_blog_id = get_current_blog_id();
6055
+
6056
foreach ( $users_2_blog_ids as $user_id => $blog_ids ) {
6057
if ( 0 < $blog_ids[0] ) {
6058
$this->switch_to_blog( $blog_ids[0] );
6059
}
6060
6061
+ call_user_func_array( $callable, array( $blog_ids, ( is_multisite() ? $current_blog_id : null ) ) );
6062
6063
foreach ( $blog_ids as $blog_id ) {
6064
$this->do_action( "after_{$name}_cron", $blog_id );
6066
}
6067
6068
if ( is_multisite() ) {
6069
+ $this->switch_to_blog( $current_blog_id );
6070
+
6071
$this->do_action( "after_{$name}_cron_multisite" );
6072
}
6073
}
6139
* @author Vova Feldman (@svovaf)
6140
* @since 2.0.0
6141
*
6142
+ * @param int[] $blog_ids
6143
+ * @param int|null $current_blog_id @since 2.2.3. This is passed from the `execute_cron` method and used by the
6144
+ * `_sync_plugin_license` method in order to switch to the previous blog when sending
6145
+ * updates for a single site in case `execute_cron` has switched to a different blog.
6146
*/
6147
+ function _sync_cron_method( array $blog_ids, $current_blog_id = null ) {
6148
if ( $this->is_registered() ) {
6149
if ( $this->has_paid_plan() ) {
6150
// Initiate background plan sync.
6151
+ $this->_sync_license( true, false, $current_blog_id );
6152
6153
if ( $this->is_paying() ) {
6154
// Check for premium plugin updates.
6363
* @author Vova Feldman (@svovaf)
6364
* @since 2.0.0
6365
*
6366
+ * @param int[] $blog_ids
6367
+ * @param int|null $current_blog_id
6368
*/
6369
+ function _sync_install_cron_method( array $blog_ids, $current_blog_id = null ) {
6370
if ( $this->is_registered() ) {
6371
if ( 1 < count( $blog_ids ) ) {
6372
$this->sync_installs( array(), true );
6470
if ( ! $this->is_addon() &&
6471
! ( ! $this->_is_network_active && fs_is_network_admin() ) &&
6472
(
6473
+ ( true === $this->_storage->require_license_activation ) ||
6474
// Not registered nor anonymous.
6475
( ! $this->is_registered() && ! $this->is_anonymous() ) ||
6476
// OR, network level and in network upgrade mode.
6487
* @since 1.2.2
6488
*/
6489
if ( $this->is_theme()
6490
&& ! $this->has_settings_menu()
6491
&& ! isset( $_REQUEST['fs_action'] )
6492
&& $this->can_activate_previous_theme()
6493
) {
6494
+ if ( $this->is_only_premium() ) {
6495
+ $this->activate_previous_theme();
6496
+ return;
6497
+ }
6498
6499
+ if ( true === $this->_storage->require_license_activation ) {
6500
+ $this->_storage->require_license_activation = false;
6501
+ }
6502
}
6503
6504
if ( ! fs_is_network_admin() &&
6598
$this->_module_type,
6599
sprintf( '<b><a href="%s">%s</a></b>',
6600
$this->get_activation_url(),
6601
+ sprintf( $this->get_text_inline( 'Opt in to make "%s" better!', 'optin-x-now' ), $this->get_plugin_name() )
6602
)
6603
),
6604
'connect_account',
7060
}
7061
}
7062
7063
+ if (
7064
+ $is_premium_version_activation &&
7065
+ (
7066
+ ( ! $this->is_registered() && $this->is_anonymous() ) ||
7067
+ (
7068
+ $this->is_registered() &&
7069
+ ! $this->is_trial() &&
7070
+ ! $this->has_features_enabled_license()
7071
+ )
7072
+ )
7073
+ ) {
7074
+ $this->_storage->require_license_activation = true;
7075
+ }
7076
+
7077
if ( ! isset( $this->_storage->is_plugin_new_install ) ) {
7078
/**
7079
* If no previous version of plugin's version exist, it means that it's either
7343
private function remove_sdk_reference() {
7344
global $fs_active_plugins;
7345
7346
+ foreach ( $fs_active_plugins->plugins as $sdk_path => $data ) {
7347
if ( $this->_plugin_basename == $data->plugin_path ) {
7348
unset( $fs_active_plugins->plugins[ $sdk_path ] );
7349
break;
7525
}
7526
}
7527
7528
+ /**
7529
+ * This is used to ensure that before redirecting to the opt-in page after resetting the anonymous mode or
7530
+ * deleting the account in the network level, the URL of the page to redirect to is correct.
7531
+ *
7532
+ * @author Leo Fajardo (@leorw)
7533
+ *
7534
+ * @since 2.1.3
7535
+ */
7536
+ private function maybe_set_slug_and_network_menu_exists_flag() {
7537
+ if ( ! empty( $this->_dynamically_added_top_level_page_hook_name ) ) {
7538
+ $this->_menu->set_slug_and_network_menu_exists_flag( $this->_menu->has_menu() ?
7539
+ $this->_menu->get_slug() :
7540
+ $this->_slug
7541
+ );
7542
+ }
7543
+ }
7544
+
7545
/**
7546
* Clears the anonymous mode and redirects to the opt-in screen.
7547
*
7555
7556
$this->reset_anonymous_mode( fs_is_network_admin() );
7557
7558
+ $this->maybe_set_slug_and_network_menu_exists_flag();
7559
+
7560
fs_redirect( $this->get_activation_url() );
7561
}
7562
7996
$include_plugins = true,
7997
$include_themes = true
7998
) {
7999
+ if ( ! defined( 'WP_FS__TRACK_PLUGINS' ) || false !== WP_FS__TRACK_PLUGINS ) {
8000
+ /**
8001
+ * @since 1.1.8 Also send plugin updates.
8002
+ */
8003
+ if ( $include_plugins && ! isset( $override['plugins'] ) ) {
8004
+ $plugins = $this->get_plugins_data_for_api();
8005
+ if ( ! empty( $plugins ) ) {
8006
+ $override['plugins'] = $plugins;
8007
+ }
8008
}
8009
}
8010
+
8011
+ if ( ! defined( 'WP_FS__TRACK_THEMES' ) || false !== WP_FS__TRACK_THEMES ) {
8012
+ /**
8013
+ * @since 1.1.8 Also send themes updates.
8014
+ */
8015
+ if ( $include_themes && ! isset( $override['themes'] ) ) {
8016
+ $themes = $this->get_themes_data_for_api();
8017
+ if ( ! empty( $themes ) ) {
8018
+ $override['themes'] = $themes;
8019
+ }
8020
}
8021
}
8022
8023
+ $versions = $this->get_versions();
8024
+
8025
+ return array_merge( $versions, array(
8026
+ 'version' => $this->get_plugin_version(),
8027
+ 'is_premium' => $this->is_premium(),
8028
+ 'language' => get_bloginfo( 'language' ),
8029
+ 'charset' => get_bloginfo( 'charset' ),
8030
+ 'title' => get_bloginfo( 'name' ),
8031
+ 'url' => get_site_url(),
8032
// Special params.
8033
+ 'is_active' => true,
8034
+ 'is_disconnected' => $this->is_tracking_prohibited(),
8035
+ 'is_uninstalled' => false,
8036
), $override );
8037
}
8038
8077
// }
8078
8079
// Common properties.
8080
+ $versions = $this->get_versions();
8081
+ $common = array_merge( $versions, array(
8082
+ 'version' => $this->get_plugin_version(),
8083
+ 'is_premium' => $this->is_premium(),
8084
), $override );
8085
8086
8234
$params = $this->get_install_diff_for_api( $check_properties, $this->_site, $override );
8235
}
8236
8237
+ $keepalive_only_update = false;
8238
+ if ( empty( $params ) ) {
8239
+ $keepalive_only_update = $this->should_send_keepalive_update();
8240
+
8241
+ if ( ! $keepalive_only_update ) {
8242
+ /**
8243
+ * There are no updates to send including keepalive.
8244
+ *
8245
+ * @author Leo Fajardo (@leorw)
8246
+ * @since 2.2.3
8247
+ */
8248
+ return false;
8249
+ }
8250
+ }
8251
+
8252
+ if ( ! $keepalive_only_update ) {
8253
+ /**
8254
+ * Do not update the last install sync timestamp after a keepalive-only call since there were no actual
8255
+ * updates sent.
8256
+ *
8257
+ * @author Leo Fajardo (@leorw)
8258
+ * @since 2.2.3
8259
+ */
8260
if ( ! is_multisite() ) {
8261
// Update last install sync timestamp.
8262
$this->set_cron_execution_timestamp( 'install_sync' );
8263
}
8264
8265
$params['uid'] = $this->get_anonymous_id();
8266
+ }
8267
8268
+ $this->set_keepalive_timestamp();
8269
8270
+ // Send updated values to FS.
8271
+ $site = $this->get_api_site_scope()->call( '/', 'put', $params );
8272
8273
+ if ( ! $keepalive_only_update && $this->is_api_result_entity( $site ) ) {
8274
+ /**
8275
+ * Do not clear scheduled sync after a keepalive-only call since there were no actual updates sent.
8276
+ *
8277
+ * @author Leo Fajardo (@leorw)
8278
+ * @since 2.2.3
8279
+ */
8280
+ if ( ! is_multisite() ) {
8281
+ // I successfully sent install update, clear scheduled sync if exist.
8282
+ $this->clear_install_sync_cron();
8283
+ }
8284
}
8285
8286
+ return $site;
8287
}
8288
8289
/**
8302
8303
$installs_data = $this->get_installs_data_for_api( $override, ! $flush );
8304
8305
+ $keepalive_only_update = false;
8306
if ( empty( $installs_data ) ) {
8307
+ /**
8308
+ * Pass `true` to use the network level storage since the update is for many installs.
8309
+ *
8310
+ * @author Leo Fajardo (@leorw)
8311
+ * @since 2.2.3
8312
+ */
8313
+ $keepalive_only_update = $this->should_send_keepalive_update( true );
8314
+
8315
+ if ( ! $keepalive_only_update ) {
8316
+ /**
8317
+ * There are no updates to send including keepalive.
8318
+ *
8319
+ * @author Leo Fajardo (@leorw)
8320
+ * @since 2.2.3
8321
+ */
8322
+ return false;
8323
+ }
8324
+ }
8325
+
8326
+ if ( ! $keepalive_only_update ) {
8327
+ // Update last install sync timestamp if there were actual updates sent (i.e., not a keepalive-only call).
8328
+ $this->set_cron_execution_timestamp( 'install_sync' );
8329
}
8330
8331
+ /**
8332
+ * Pass `true` to use the network level storage since the update is for many installs.
8333
+ *
8334
+ * @author Leo Fajardo (@leorw)
8335
+ * @since 2.2.3
8336
+ */
8337
+ $this->set_keepalive_timestamp( true );
8338
8339
// Send updated values to FS.
8340
$result = $this->get_api_user_scope()->call( "/plugins/{$this->_plugin->id}/installs.json", 'put', $installs_data );
8341
8342
+ if ( ! $keepalive_only_update && $this->is_api_result_object( $result, 'installs' ) ) {
8343
+ // I successfully sent installs update (there was an actual update sent and it's not just a keepalive-only call), clear scheduled sync if exist.
8344
$this->clear_install_sync_cron();
8345
}
8346
8347
return $result;
8348
}
8349
8350
+ /**
8351
+ * @author Leo Fajardo (@leorw)
8352
+ *
8353
+ * @param bool|null $use_network_level_storage
8354
+ *
8355
+ * @return bool
8356
+ */
8357
+ private function should_send_keepalive_update( $use_network_level_storage = null ) {
8358
+ $keepalive_timestamp = $this->_storage->get( 'keepalive_timestamp', 0, $use_network_level_storage );
8359
+
8360
+ if ( $keepalive_timestamp < ( time() - WP_FS__TIME_WEEK_IN_SEC ) ) {
8361
+ // If updated more than 7 days ago, trigger a keepalive and update the time it was triggered.
8362
+ return true;
8363
+ } else {
8364
+ // If updated 7 days ago or less, "flip a coin", if the value is 7 trigger a keepalive and update the last time it was triggered.
8365
+ return ( 7 == rand( 1, 7 ) );
8366
+ }
8367
+ }
8368
+
8369
/**
8370
* Update install only if changed.
8371
*
8570
// @todo Decide if we want to delete plugin information from db.
8571
}
8572
8573
+ /**
8574
+ * Set the basename of the current product and hook _activate_plugin_event_hook() to the activation action.
8575
+ *
8576
+ * @author Vova Feldman (@svovaf)
8577
+ * @since 2.2.1
8578
+ *
8579
+ * @param string $is_premium
8580
+ * @param string $caller
8581
+ *
8582
+ * @return string
8583
+ */
8584
+ function set_basename( $is_premium, $caller ) {
8585
+ $basename = plugin_basename( $caller );
8586
+
8587
+ $current_basename = $is_premium ?
8588
+ $this->_premium_plugin_basename :
8589
+ $this->_free_plugin_basename;
8590
+
8591
+ if ( $current_basename == $basename ) {
8592
+ // Basename value set correctly.
8593
+ return;
8594
+ }
8595
+
8596
+ if ( $is_premium ) {
8597
+ $this->_premium_plugin_basename = $basename;
8598
+ } else {
8599
+ $this->_free_plugin_basename = $basename;
8600
+ }
8601
+
8602
+ $plugin_dir = dirname( $this->_plugin_dir_path ) . '/';
8603
+
8604
+ register_activation_hook(
8605
+ $plugin_dir . $basename,
8606
+ array( &$this, '_activate_plugin_event_hook' )
8607
+ );
8608
+ }
8609
+
8610
/**
8611
* @author Vova Feldman (@svovaf)
8612
* @since 1.1.1
8613
+ * @since 2.2.1 If the context product is in its premium version, use the current module's basename, even if it was renamed.
8614
*
8615
* @return string
8616
*/
8617
function premium_plugin_basename() {
8618
+ if ( ! isset( $this->_premium_plugin_basename ) ) {
8619
+ $this->_premium_plugin_basename = $this->is_premium() ?
8620
+ // The product is premium, so use the current basename.
8621
+ $this->_plugin_basename :
8622
+ $this->get_premium_slug() . '/' . basename( $this->_free_plugin_basename );
8623
+ }
8624
+
8625
+ return $this->_premium_plugin_basename;
8626
}
8627
8628
/**
8761
}
8762
8763
/**
8764
+ * @author Leo Fajardo (@leorw)
8765
+ * @since 2.2.1
8766
+ *
8767
+ * @return string
8768
+ */
8769
+ function get_premium_slug() {
8770
+ return is_object( $this->_plugin ) ?
8771
+ $this->_plugin->premium_slug :
8772
+ "{$this->_slug}-premium";
8773
+ }
8774
+
8775
+ /**
8776
+ * Retrieve the desired folder name for the product.
8777
+ *
8778
* @author Vova Feldman (@svovaf)
8779
* @since 1.2.1.7
8780
*
8781
* @return string Plugin slug.
8782
*/
8783
function get_target_folder_name() {
8784
+ return $this->can_use_premium_code() ?
8785
+ $this->_plugin->premium_slug :
8786
+ $this->_slug;
8787
}
8788
8789
/**
8854
* @author Vova Feldman (@svovaf)
8855
* @since 1.0.9
8856
*
8857
+ * @param string|bool $premium_suffix
8858
+ *
8859
+ * @return string
8860
+ */
8861
+ function get_plugin_name( $premium_suffix = false ) {
8862
+ $this->_logger->entrance();
8863
+
8864
+ /**
8865
+ * This `if-else` can be squeezed into a single `if` but I intentionally split it for code readability.
8866
+ *
8867
+ * @author Vova Feldman
8868
+ */
8869
+ if ( ! isset( $this->_plugin_name ) ) {<