Yasr – Yet Another Stars Rating - Version 2.0.8

Version Description

  • NEW FEATURE: Added a bos to the top right, that will allow to select if the post is a review or not. More info here here
  • FIXED: warning that in some rare circumstances may appear in yasr_schema function
Download this release

Release Info

Developer Dudo
Plugin Icon 128x128 Yasr – Yet Another Stars Rating
Version 2.0.8
Comparing to
See all releases

Code changes from version 2.0.7 to 2.0.8

Files changed (67) hide show
  1. css/yasr-admin.css +10 -0
  2. freemius/assets/css/admin/dialog-boxes.css +1 -1
  3. freemius/assets/css/admin/plugins.css +1 -0
  4. freemius/assets/css/customizer.css +1 -1
  5. freemius/includes/class-freemius.php +966 -213
  6. freemius/includes/class-fs-plugin-updater.php +26 -2
  7. freemius/includes/class-fs-storage.php +44 -40
  8. freemius/includes/customizer/class-fs-customizer-upsell-control.php +5 -1
  9. freemius/includes/entities/class-fs-entity.php +10 -0
  10. freemius/includes/entities/class-fs-plugin-license.php +33 -0
  11. freemius/includes/entities/class-fs-plugin.php +5 -0
  12. freemius/includes/entities/class-fs-pricing.php +16 -0
  13. freemius/includes/entities/class-fs-site.php +3 -3
  14. freemius/includes/entities/class-fs-subscription.php +136 -114
  15. freemius/includes/fs-core-functions.php +282 -217
  16. freemius/includes/fs-plugin-info-dialog.php +27 -6
  17. freemius/includes/managers/class-fs-admin-menu-manager.php +53 -32
  18. freemius/includes/managers/class-fs-cache-manager.php +1 -1
  19. freemius/includes/managers/class-fs-option-manager.php +35 -11
  20. freemius/includes/managers/class-fs-plugin-manager.php +3 -3
  21. freemius/languages/freemius-cs_CZ.mo +0 -0
  22. freemius/languages/freemius-cs_CZ.po +2760 -0
  23. freemius/languages/freemius-da_DK.mo +0 -0
  24. freemius/languages/freemius-da_DK.po +592 -804
  25. freemius/languages/freemius-en.mo +0 -0
  26. freemius/languages/freemius-en.po +415 -379
  27. freemius/languages/freemius-es_ES.mo +0 -0
  28. freemius/languages/freemius-es_ES.po +492 -454
  29. freemius/languages/freemius-fr_FR.mo +0 -0
  30. freemius/languages/freemius-fr_FR.po +492 -454
  31. freemius/languages/freemius-he_IL.mo +0 -0
  32. freemius/languages/freemius-he_IL.po +491 -453
  33. freemius/languages/freemius-hu_HU.mo +0 -0
  34. freemius/languages/freemius-hu_HU.po +491 -453
  35. freemius/languages/freemius-it_IT.mo +0 -0
  36. freemius/languages/freemius-it_IT.po +492 -454
  37. freemius/languages/freemius-ja_JP.mo +0 -0
  38. freemius/languages/freemius-ja_JP.po +492 -454
  39. freemius/languages/freemius-nl_NL.mo +0 -0
  40. freemius/languages/freemius-nl_NL.po +492 -454
  41. freemius/languages/freemius-ru_RU.mo +0 -0
  42. freemius/languages/freemius-ru_RU.po +491 -453
  43. freemius/languages/freemius-ta.mo +0 -0
  44. freemius/languages/freemius-ta.po +2548 -0
  45. freemius/languages/freemius.pot +414 -378
  46. freemius/start.php +1 -1
  47. freemius/templates/account.php +187 -116
  48. freemius/templates/account/partials/addon.php +123 -84
  49. freemius/templates/account/partials/site.php +45 -29
  50. freemius/templates/add-ons.php +501 -440
  51. freemius/templates/connect.php +3 -3
  52. freemius/templates/debug.php +759 -726
  53. freemius/templates/debug/scheduled-crons.php +1 -1
  54. freemius/templates/forms/data-debug-mode.php +213 -0
  55. freemius/templates/forms/license-activation.php +12 -14
  56. freemius/templates/forms/optout.php +4 -2
  57. freemius/templates/forms/subscription-cancellation.php +1 -1
  58. freemius/templates/powered-by.php +5 -2
  59. freemius/templates/pricing.php +1 -0
  60. freemius/templates/tabs.php +2 -2
  61. js/src/yasr-guten-panel.js +70 -1
  62. js/yasr-guten-panel.js +99 -11
  63. lib/admin/editor/yasr-metabox-top-right.php +38 -23
  64. lib/yasr-db-functions.php +38 -1
  65. lib/yasr-functions.php +41 -37
  66. readme.txt +8 -2
  67. yet-another-stars-rating.php +3 -3
css/yasr-admin.css CHANGED
@@ -70,6 +70,16 @@
70
text-align: left;
71
}
72
73
/*** End metabox overall rating ***/
74
75
#multi_rating_table {
70
text-align: left;
71
}
72
73
+ #yasr-switcher-post-is-review {
74
+ margin: 0 auto;
75
+ text-align: left;
76
+ }
77
+
78
+ .rich-snippet-title {
79
+ font-weight: bold;
80
+ margin-bottom: 5px;
81
+ }
82
+
83
/*** End metabox overall rating ***/
84
85
#multi_rating_table {
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-subscription-cancellation .fs-price-increase-warning{color:red;font-weight:bold;padding:0 25px;margin-bottom:0}.fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label input{float:left;top:5px;position:relative}.rtl .fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label input{float:right}.fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label span{display:block;margin-left:24px}.rtl .fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label span{margin-left:0;margin-right:24px}.fs-modal.fs-modal-license-activation .fs-modal-body input.fs-license-key{width:100%}.fs-license-options-container table,.fs-license-options-container table select,.fs-license-options-container table .fs-available-license-key{width:100%}.fs-license-options-container table td:first-child{width:1%}.fs-license-options-container table .fs-other-license-key-container label{position:relative;top:6px;float:left;margin-right:5px}.fs-license-options-container table .fs-other-license-key-container div{overflow:hidden;width:auto;height:30px;display:block;top:2px;position:relative}.fs-license-options-container table .fs-other-license-key-container div input{margin:0}.fs-sites-list-container td{cursor:pointer}.fs-multisite-options-container{margin-top:10px;border:1px solid #ccc;padding:5px}.fs-multisite-options-container a{text-decoration:none}.fs-multisite-options-container a:focus{box-shadow:none}.fs-multisite-options-container a.selected{font-weight:bold}.fs-multisite-options-container.fs-apply-on-all-sites{border:0 none;padding:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options{border-spacing:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options td:not(:first-child){display:none}.fs-multisite-options-container .fs-sites-list-container{display:none;overflow:auto}.fs-multisite-options-container .fs-sites-list-container table td{border-top:1px solid #ccc;padding:4px 2px}.fs-modal.fs-modal-license-key-resend .email-address-container{overflow:hidden;padding-right:2px}.fs-modal.fs-modal-license-key-resend.fs-freemium input.email-address{width:300px}.fs-modal.fs-modal-license-key-resend.fs-freemium label{display:block;margin-bottom:10px}.fs-modal.fs-modal-license-key-resend.fs-premium input.email-address{width:100%}.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{float:right;margin-left:7px}@media (max-width: 650px){.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{margin-top:2px}}
2
.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .input-container>.email-address-container{padding-left:2px;padding-right:0}.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .button-container{float:left;margin-right:7px;margin-left:0}a.show-license-resend-modal{margin-top:4px;display:inline-block}.fs-ajax-loader{position:relative;width:170px;height:20px;margin:auto}.fs-ajax-loader .fs-ajax-loader-bar{position:absolute;top:0;background-color:#0074a3;width:20px;height:20px;-webkit-animation-name:bounce_ajaxLoader;-moz-animation-name:bounce_ajaxLoader;-ms-animation-name:bounce_ajaxLoader;-o-animation-name:bounce_ajaxLoader;animation-name:bounce_ajaxLoader;-webkit-animation-duration:1.5s;-moz-animation-duration:1.5s;-ms-animation-duration:1.5s;-o-animation-duration:1.5s;animation-duration:1.5s;animation-iteration-count:infinite;-o-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;-webkit-animation-iteration-count:infinite;-moz-animation-iteration-count:infinite;-webkit-animation-direction:normal;-moz-animation-direction:normal;-ms-animation-direction:normal;-o-animation-direction:normal;animation-direction:normal;-moz-transform:0.3;-o-transform:0.3;-ms-transform:0.3;-webkit-transform:0.3;transform:0.3}.fs-ajax-loader .fs-ajax-loader-bar-1{left:0px;animation-delay:0.6s;-o-animation-delay:0.6s;-ms-animation-delay:0.6s;-webkit-animation-delay:0.6s;-moz-animation-delay:0.6s}.fs-ajax-loader .fs-ajax-loader-bar-2{left:19px;animation-delay:0.75s;-o-animation-delay:0.75s;-ms-animation-delay:0.75s;-webkit-animation-delay:0.75s;-moz-animation-delay:0.75s}.fs-ajax-loader .fs-ajax-loader-bar-3{left:38px;animation-delay:0.9s;-o-animation-delay:0.9s;-ms-animation-delay:0.9s;-webkit-animation-delay:0.9s;-moz-animation-delay:0.9s}.fs-ajax-loader .fs-ajax-loader-bar-4{left:57px;animation-delay:1.05s;-o-animation-delay:1.05s;-ms-animation-delay:1.05s;-webkit-animation-delay:1.05s;-moz-animation-delay:1.05s}.fs-ajax-loader .fs-ajax-loader-bar-5{left:76px;animation-delay:1.2s;-o-animation-delay:1.2s;-ms-animation-delay:1.2s;-webkit-animation-delay:1.2s;-moz-animation-delay:1.2s}.fs-ajax-loader .fs-ajax-loader-bar-6{left:95px;animation-delay:1.35s;-o-animation-delay:1.35s;-ms-animation-delay:1.35s;-webkit-animation-delay:1.35s;-moz-animation-delay:1.35s}.fs-ajax-loader .fs-ajax-loader-bar-7{left:114px;animation-delay:1.5s;-o-animation-delay:1.5s;-ms-animation-delay:1.5s;-webkit-animation-delay:1.5s;-moz-animation-delay:1.5s}.fs-ajax-loader .fs-ajax-loader-bar-8{left:133px;animation-delay:1.65s;-o-animation-delay:1.65s;-ms-animation-delay:1.65s;-webkit-animation-delay:1.65s;-moz-animation-delay:1.65s}@-moz-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-ms-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-o-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-webkit-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}.fs-modal-auto-install #request-filesystem-credentials-form h2,.fs-modal-auto-install #request-filesystem-credentials-form .request-filesystem-credentials-action-buttons{display:none}.fs-modal-auto-install #request-filesystem-credentials-form input[type=password],.fs-modal-auto-install #request-filesystem-credentials-form input[type=email],.fs-modal-auto-install #request-filesystem-credentials-form input[type=text]{-webkit-appearance:none;padding:10px 10px 5px 10px;width:300px;max-width:100%}.fs-modal-auto-install #request-filesystem-credentials-form>div,.fs-modal-auto-install #request-filesystem-credentials-form label,.fs-modal-auto-install #request-filesystem-credentials-form fieldset{width:300px;max-width:100%;margin:0 auto;display:block}.button-primary.warn{box-shadow:0 1px 0 #d2593c;text-shadow:0 -1px 1px #d2593c,1px 0 1px #d2593c,0 1px 1px #d2593c,-1px 0 1px #d2593c;background:#f56a48;border-color:#ec6544 #d2593c #d2593c}.button-primary.warn:hover{background:#fd6d4a;border-color:#d2593c}.button-primary.warn:focus{box-shadow:0 1px 0 #dd6041,0 0 2px 1px #e4a796}.button-primary.warn:active{background:#dd6041;border-color:#d2593c;box-shadow:inset 0 2px 0 #d2593c}.button-primary.warn.disabled{color:#f5b3a1 !important;background:#e76444 !important;border-color:#d85e40 !important;text-shadow:0 -1px 0 rgba(0,0,0,0.1) !important}
1
+ .fs-modal{position:fixed;overflow:auto;height:100%;width:100%;top:0;z-index:100000;display:none;background:rgba(0,0,0,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.fs-license-key{width:100%}.fs-license-options-container table,.fs-license-options-container table select,.fs-license-options-container table .fs-available-license-key{width:100%}.fs-license-options-container table td:first-child{width:1%}.fs-license-options-container table .fs-other-license-key-container label{position:relative;top:6px;float:left;margin-right:5px}.fs-license-options-container table .fs-other-license-key-container div{overflow:hidden;width:auto;height:30px;display:block;top:2px;position:relative}.fs-license-options-container table .fs-other-license-key-container div input{margin:0}.fs-sites-list-container td{cursor:pointer}.fs-modal.fs-modal-developer-license-debug-mode .fs-modal-body input.fs-license-or-user-key{width:100%}.fs-multisite-options-container{margin-top:10px;border:1px solid #ccc;padding:5px}.fs-multisite-options-container a{text-decoration:none}.fs-multisite-options-container a:focus{box-shadow:none}.fs-multisite-options-container a.selected{font-weight:bold}.fs-multisite-options-container.fs-apply-on-all-sites{border:0 none;padding:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options{border-spacing:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options td:not(:first-child){display:none}.fs-multisite-options-container .fs-sites-list-container{display:none;overflow:auto}.fs-multisite-options-container .fs-sites-list-container table td{border-top:1px solid #ccc;padding:4px 2px}.fs-modal.fs-modal-license-key-resend .email-address-container{overflow:hidden;padding-right:2px}.fs-modal.fs-modal-license-key-resend.fs-freemium input.email-address{width:300px}.fs-modal.fs-modal-license-key-resend.fs-freemium label{display:block;margin-bottom:10px}.fs-modal.fs-modal-license-key-resend.fs-premium input.email-address{width:100%}.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{float:right;margin-left:7px}@media (max-width: 650px){.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{margin-top:2px}}
2
.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .input-container>.email-address-container{padding-left:2px;padding-right:0}.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .button-container{float:left;margin-right:7px;margin-left:0}a.show-license-resend-modal{margin-top:4px;display:inline-block}.fs-ajax-loader{position:relative;width:170px;height:20px;margin:auto}.fs-ajax-loader .fs-ajax-loader-bar{position:absolute;top:0;background-color:#0074a3;width:20px;height:20px;-webkit-animation-name:bounce_ajaxLoader;-moz-animation-name:bounce_ajaxLoader;-ms-animation-name:bounce_ajaxLoader;-o-animation-name:bounce_ajaxLoader;animation-name:bounce_ajaxLoader;-webkit-animation-duration:1.5s;-moz-animation-duration:1.5s;-ms-animation-duration:1.5s;-o-animation-duration:1.5s;animation-duration:1.5s;animation-iteration-count:infinite;-o-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;-webkit-animation-iteration-count:infinite;-moz-animation-iteration-count:infinite;-webkit-animation-direction:normal;-moz-animation-direction:normal;-ms-animation-direction:normal;-o-animation-direction:normal;animation-direction:normal;-moz-transform:0.3;-o-transform:0.3;-ms-transform:0.3;-webkit-transform:0.3;transform:0.3}.fs-ajax-loader .fs-ajax-loader-bar-1{left:0px;animation-delay:0.6s;-o-animation-delay:0.6s;-ms-animation-delay:0.6s;-webkit-animation-delay:0.6s;-moz-animation-delay:0.6s}.fs-ajax-loader .fs-ajax-loader-bar-2{left:19px;animation-delay:0.75s;-o-animation-delay:0.75s;-ms-animation-delay:0.75s;-webkit-animation-delay:0.75s;-moz-animation-delay:0.75s}.fs-ajax-loader .fs-ajax-loader-bar-3{left:38px;animation-delay:0.9s;-o-animation-delay:0.9s;-ms-animation-delay:0.9s;-webkit-animation-delay:0.9s;-moz-animation-delay:0.9s}.fs-ajax-loader .fs-ajax-loader-bar-4{left:57px;animation-delay:1.05s;-o-animation-delay:1.05s;-ms-animation-delay:1.05s;-webkit-animation-delay:1.05s;-moz-animation-delay:1.05s}.fs-ajax-loader .fs-ajax-loader-bar-5{left:76px;animation-delay:1.2s;-o-animation-delay:1.2s;-ms-animation-delay:1.2s;-webkit-animation-delay:1.2s;-moz-animation-delay:1.2s}.fs-ajax-loader .fs-ajax-loader-bar-6{left:95px;animation-delay:1.35s;-o-animation-delay:1.35s;-ms-animation-delay:1.35s;-webkit-animation-delay:1.35s;-moz-animation-delay:1.35s}.fs-ajax-loader .fs-ajax-loader-bar-7{left:114px;animation-delay:1.5s;-o-animation-delay:1.5s;-ms-animation-delay:1.5s;-webkit-animation-delay:1.5s;-moz-animation-delay:1.5s}.fs-ajax-loader .fs-ajax-loader-bar-8{left:133px;animation-delay:1.65s;-o-animation-delay:1.65s;-ms-animation-delay:1.65s;-webkit-animation-delay:1.65s;-moz-animation-delay:1.65s}@-moz-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-ms-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-o-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-webkit-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}.fs-modal-auto-install #request-filesystem-credentials-form h2,.fs-modal-auto-install #request-filesystem-credentials-form .request-filesystem-credentials-action-buttons{display:none}.fs-modal-auto-install #request-filesystem-credentials-form input[type=password],.fs-modal-auto-install #request-filesystem-credentials-form input[type=email],.fs-modal-auto-install #request-filesystem-credentials-form input[type=text]{-webkit-appearance:none;padding:10px 10px 5px 10px;width:300px;max-width:100%}.fs-modal-auto-install #request-filesystem-credentials-form>div,.fs-modal-auto-install #request-filesystem-credentials-form label,.fs-modal-auto-install #request-filesystem-credentials-form fieldset{width:300px;max-width:100%;margin:0 auto;display:block}.button-primary.warn{box-shadow:0 1px 0 #d2593c;text-shadow:0 -1px 1px #d2593c,1px 0 1px #d2593c,0 1px 1px #d2593c,-1px 0 1px #d2593c;background:#f56a48;border-color:#ec6544 #d2593c #d2593c}.button-primary.warn:hover{background:#fd6d4a;border-color:#d2593c}.button-primary.warn:focus{box-shadow:0 1px 0 #dd6041,0 0 2px 1px #e4a796}.button-primary.warn:active{background:#dd6041;border-color:#d2593c;box-shadow:inset 0 2px 0 #d2593c}.button-primary.warn.disabled{color:#f5b3a1 !important;background:#e76444 !important;border-color:#d85e40 !important;text-shadow:0 -1px 0 rgba(0,0,0,0.1) !important}
freemius/assets/css/admin/plugins.css ADDED
@@ -0,0 +1 @@
1
+ label.fs-tag,span.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.wp-list-table.plugins .plugin-title span.fs-tag{display:inline-block;margin-left:5px;line-height:10px}
freemius/assets/css/customizer.css CHANGED
@@ -1 +1 @@
1
- #fs_customizer_upsell .fs-customizer-plan{padding:10px 20px 20px 20px;border-radius:3px;background:#fff}#fs_customizer_upsell .fs-customizer-plan h2{position:relative;margin:0;line-height:2em;text-transform:uppercase}#fs_customizer_upsell .fs-customizer-plan h2 .button-link{top:-2px}#fs_customizer_upsell .fs-feature{position:relative}#fs_customizer_upsell .dashicons-yes{color:#0085ba;font-size:2em;vertical-align:bottom;margin-left:-7px;margin-right:10px}.rtl #fs_customizer_upsell .dashicons-yes{margin-left:10px;margin-right:-7px}#fs_customizer_upsell .dashicons-editor-help{color:#bbb;cursor:help}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{opacity:0;visibility:hidden;-moz-transition:opacity 0.3s ease-in-out;-o-transition:opacity 0.3s ease-in-out;-ms-transition:opacity 0.3s ease-in-out;-webkit-transition:opacity 0.3s ease-in-out;transition:opacity 0.3s ease-in-out;position:absolute;background:#000;color:#fff;font-family:'arial', serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:0;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,0.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,0.2);box-shadow:1px 1px 1px rgba(0,0,0,0.2);line-height:1.3em;font-weight:bold;text-align:left}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{text-align:right}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc::after{content:' ';display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:#000 transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc::after{right:21px;left:auto}#fs_customizer_upsell .dashicons-editor-help:hover .fs-feature-desc{visibility:visible;opacity:1}#fs_customizer_upsell .button-primary{display:block;text-align:center;margin-top:10px}#fs_customizer_support{display:block !important}#fs_customizer_support .button{float:right}#fs_customizer_support .button-group{width:100%;display:block;margin-top:10px}#fs_customizer_support .button-group .button{float:none;width:50%;text-align:center}
1
+ #fs_customizer_upsell .fs-customizer-plan{padding:10px 20px 20px 20px;border-radius:3px;background:#fff}#fs_customizer_upsell .fs-customizer-plan h2{position:relative;margin:0;line-height:2em;text-transform:uppercase}#fs_customizer_upsell .fs-customizer-plan h2 .button-link{top:-2px}#fs_customizer_upsell .fs-feature{position:relative}#fs_customizer_upsell .dashicons-yes{color:#0085ba;font-size:2em;vertical-align:bottom;margin-left:-7px;margin-right:10px}.rtl #fs_customizer_upsell .dashicons-yes{margin-left:10px;margin-right:-7px}#fs_customizer_upsell .dashicons-editor-help{color:#bbb;cursor:help}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{opacity:0;visibility:hidden;-moz-transition:opacity 0.3s ease-in-out;-o-transition:opacity 0.3s ease-in-out;-ms-transition:opacity 0.3s ease-in-out;-webkit-transition:opacity 0.3s ease-in-out;transition:opacity 0.3s ease-in-out;position:absolute;background:#000;color:#fff;font-family:'arial', serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:0;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,0.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,0.2);box-shadow:1px 1px 1px rgba(0,0,0,0.2);line-height:1.3em;font-weight:bold;text-align:left}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{text-align:right}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc::after{content:' ';display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:#000 transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc::after{right:21px;left:auto}#fs_customizer_upsell .dashicons-editor-help:hover .fs-feature-desc{visibility:visible;opacity:1}#fs_customizer_upsell .button-primary{display:block;text-align:center;margin-top:10px}#fs_customizer_support{display:block !important}#fs_customizer_support .button{float:right}#fs_customizer_support .button-group{width:100%;display:block;margin-top:10px}#fs_customizer_support .button-group .button{float:none;width:50%;text-align:center}#customize-theme-controls #accordion-section-freemius_upsell{border-top:1px solid #0085ba !important;border-bottom:1px solid #0085ba !important}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title{color:#fff;background-color:#0085ba;border-left:4px solid #0085ba;transition:.15s background-color ease-in-out, .15s border-color ease-in-out;outline:none;border-bottom:none !important}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title:hover{background-color:#008ec2;border-left-color:#0073aa}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title:after{color:#fff}#customize-theme-controls #accordion-section-freemius_upsell .rtl h3.accordion-section-title{border-left:none;border-right:4px solid #0085ba}#customize-theme-controls #accordion-section-freemius_upsell .rtl h3.accordion-section-title:hover{border-right-color:#0073aa}
freemius/includes/class-freemius.php CHANGED
@@ -164,6 +164,15 @@
164
*/
165
private $_has_addons;
166
167
/**
168
* @since 1.1.6
169
* @var string[]bool.
@@ -334,6 +343,14 @@
334
*/
335
private $_dynamically_added_top_level_page_hook_name = '';
336
337
#region Uninstall Reasons IDs
338
339
const REASON_NO_LONGER_NEEDED = 1;
@@ -484,13 +501,13 @@
484
);
485
486
if ( 'true' === fs_request_get( 'fs_clear_api_cache' ) ||
487
- 'true' === fs_request_is_action( 'restart_freemius' )
488
) {
489
FS_Api::clear_cache();
490
$this->_cache->clear();
491
}
492
493
- $this->_register_hooks();
494
495
/**
496
* Starting from version 2.0.0, `FS_Site` entities no longer have the `plan` property and have `plan_id`
@@ -702,6 +719,52 @@
702
$this->_menu->has_menu();
703
}
704
705
/**
706
* Check if the context module is free wp.org theme.
707
*
@@ -734,12 +797,11 @@
734
* @since 1.2.2.7 Even if the menu item was specified to be hidden, when it is the context page, then show the submenu item so the user will have the right context page.
735
*
736
* @param string $slug
737
- * @param bool $ignore_free_wp_org_theme_context This is used to decide if the associated tab should be shown
738
- * or hidden.
739
*
740
* @return bool
741
*/
742
- function is_submenu_item_visible( $slug, $ignore_free_wp_org_theme_context = false ) {
743
if ( $this->is_admin_page( $slug ) ) {
744
/**
745
* It is the current context page, so show the submenu item
@@ -754,7 +816,7 @@
754
return false;
755
}
756
757
- if ( ! $ignore_free_wp_org_theme_context && $this->is_free_wp_org_theme() ) {
758
/**
759
* wp.org themes are limited to a single submenu item, and
760
* sub-submenu items are most likely not allowed (never verified).
@@ -980,7 +1042,7 @@
980
}
981
982
if ( isset( $this->_storage->subscription ) && is_object( $this->_storage->subscription ) ) {
983
- $this->_storage->subscriptions = array( $this->_storage->subscription );
984
}
985
}
986
@@ -1453,11 +1515,11 @@
1453
* @author Vova Feldman (@svovaf)
1454
* @since 1.0.9
1455
*/
1456
- private function _register_hooks() {
1457
$this->_logger->entrance();
1458
1459
if ( is_admin() ) {
1460
- add_action( 'plugins_loaded', array( &$this, '_hook_action_links_and_register_account_hooks' ) );
1461
1462
if ( $this->is_plugin() ) {
1463
if ( self::is_plugin_install_page() && true !== fs_request_get_bool( 'fs_allow_updater_and_dialog' ) ) {
@@ -1498,34 +1560,6 @@
1498
} else {
1499
add_action( 'after_switch_theme', array( &$this, '_activate_theme_event_hook' ), 10, 2 );
1500
1501
- /**
1502
- * Include the required hooks to capture the theme settings' page tabs
1503
- * and cache them.
1504
- *
1505
- * @author Vova Feldman (@svovaf)
1506
- * @since 1.2.2.7
1507
- */
1508
- if ( ! $this->_cache->has_valid( 'tabs' ) ) {
1509
- add_action( 'admin_footer', array( &$this, '_tabs_capture' ) );
1510
- // Add license activation AJAX callback.
1511
- $this->add_ajax_action( 'store_tabs', array( &$this, '_store_tabs_ajax_action' ) );
1512
-
1513
- add_action( 'admin_enqueue_scripts', array( &$this, '_store_tabs_styles' ), 9999999 );
1514
- }
1515
-
1516
- add_action(
1517
- 'admin_footer',
1518
- array( &$this, '_add_freemius_tabs' ),
1519
- /**
1520
- * The tabs JS code must be executed after the tabs capture logic (_tabs_capture()).
1521
- * That's why the priority is 11 while the tabs capture logic is added
1522
- * with priority 10.
1523
- *
1524
- * @author Vova Feldman (@svovaf)
1525
- */
1526
- 11
1527
- );
1528
-
1529
add_action( 'admin_footer', array( &$this, '_style_premium_theme' ) );
1530
}
1531
@@ -1545,7 +1579,10 @@
1545
*
1546
* @author Vova Feldman (@svovaf)
1547
*/
1548
- if ( $this->is_plugin() && $this->is_activation_mode( false ) ) {
1549
add_action( 'plugins_loaded', array( &$this, '_plugins_loaded' ) );
1550
} else {
1551
// If was activated before, then it was already loaded before.
@@ -1605,6 +1642,7 @@
1605
1606
$this->add_ajax_action( 'update_billing', array( &$this, '_update_billing_ajax_action' ) );
1607
$this->add_ajax_action( 'start_trial', array( &$this, '_start_trial_ajax_action' ) );
1608
1609
if ( $this->_is_network_active && fs_is_network_admin() ) {
1610
$this->add_ajax_action( 'network_activate', array( &$this, '_network_activate_ajax_action' ) );
@@ -1646,6 +1684,65 @@
1646
}
1647
}
1648
1649
/**
1650
* Makes Freemius-related updates unavailable on the "Add Plugins" admin page (/plugin-install.php) so that
1651
* they won't interfere with the .org plugins' functionalities on that page (e.g. updating of a .org plugin).
@@ -1908,7 +2005,7 @@
1908
* @since 2.0.0
1909
*/
1910
function _hook_action_links_and_register_account_hooks() {
1911
- add_action( 'admin_init', array( &$this, '_add_tracking_links' ) );
1912
1913
if ( self::is_plugins_page() && $this->is_plugin() ) {
1914
$this->hook_plugin_action_links();
@@ -2250,6 +2347,10 @@
2250
2251
if ( ! isset( $caller_map[ $caller_file_hash ] ) ) {
2252
foreach ( $all_plugins_paths as $plugin_path ) {
2253
if ( false !== strpos( $caller_file_path, fs_normalize_path( dirname( $plugin_path ) . '/' ) ) ) {
2254
$caller_map[ $caller_file_hash ] = fs_normalize_path( $plugin_path );
2255
break;
@@ -2928,7 +3029,7 @@
2928
* @return bool
2929
*/
2930
function is_activation_page() {
2931
- if ( $this->_menu->is_main_settings_page() ) {
2932
return true;
2933
}
2934
@@ -4630,22 +4731,7 @@
4630
4631
$this->parse_settings( $plugin_info );
4632
4633
- if ( is_admin() && $this->is_theme() && $this->is_premium() && ! $this->has_active_valid_license() ) {
4634
- $this->add_ajax_action(
4635
- 'delete_theme_update_data',
4636
- array( &$this, '_delete_theme_update_data_action' )
4637
- );
4638
- }
4639
-
4640
- if ( ! self::is_ajax() ) {
4641
- if ( ! $this->is_addon() || $this->is_only_premium() ) {
4642
- add_action(
4643
- ( $this->_is_network_active && fs_is_network_admin() ? 'network_' : '' ) . 'admin_menu',
4644
- array( &$this, '_prepare_admin_menu' ),
4645
- WP_FS__LOWEST_PRIORITY
4646
- );
4647
- }
4648
- }
4649
4650
if ( $this->should_stop_execution() ) {
4651
return;
@@ -4803,6 +4889,7 @@
4803
if (
4804
$this->_parent->is_registered() &&
4805
! $this->is_registered() &&
4806
/**
4807
* If not registered for add-on and the following conditions for the add-on are met, activate add-on account.
4808
* * Network active and in network admin - network activate add-on account.
@@ -5396,6 +5483,7 @@
5396
'is_live' => $this->get_bool_option( $plugin_info, 'is_live', true ),
5397
'affiliate_moderation' => $this->get_option( $plugin_info, 'has_affiliation' ),
5398
'bundle_id' => $this->get_option( $plugin_info, 'bundle_id', null ),
5399
) );
5400
5401
if ( $plugin->is_updated() ) {
@@ -5467,6 +5555,14 @@
5467
5468
$this->_is_trial_require_payment = $this->get_bool_option( $plugin_info['trial'], 'is_require_payment', false );
5469
}
5470
}
5471
5472
/**
@@ -6937,8 +7033,7 @@
6937
6938
$this->_add_upgrade_action_link();
6939
6940
- if ( ! $this->is_addon() &&
6941
- ! ( ! $this->_is_network_active && fs_is_network_admin() ) &&
6942
(
6943
( true === $this->_storage->require_license_activation ) ||
6944
// Not registered nor anonymous.
@@ -6948,7 +7043,7 @@
6948
)
6949
) {
6950
if ( ! $this->is_pending_activation() ) {
6951
- if ( ! $this->_menu->is_main_settings_page() ) {
6952
/**
6953
* If a user visits any other admin page before activating the premium-only theme with a valid
6954
* license, reactivate the previous theme.
@@ -7015,8 +7110,8 @@
7015
}
7016
}
7017
7018
- if ( $this->is_theme() &&
7019
- $this->_menu->is_main_settings_page()
7020
) {
7021
$this->_show_theme_activation_optin_dialog();
7022
}
@@ -7781,7 +7876,7 @@
7781
*
7782
* @return array
7783
*/
7784
- private function get_sites_for_network_level_optin() {
7785
$sites = array();
7786
$all_sites = self::get_sites();
7787
@@ -9397,10 +9492,12 @@
9397
* @author Vova Feldman (@svovaf)
9398
* @since 1.0.1
9399
*
9400
* @return array
9401
*/
9402
- function get_plugin_data() {
9403
- if ( ! isset( $this->_plugin_data ) ) {
9404
self::require_plugin_essentials();
9405
9406
if ( $this->is_plugin() ) {
@@ -9505,6 +9602,18 @@
9505
null;
9506
}
9507
9508
/**
9509
* @author Vova Feldman (@svovaf)
9510
* @since 1.2.1.5
@@ -9527,6 +9636,32 @@
9527
$this->_plugin->id;
9528
}
9529
9530
/**
9531
* @author Vova Feldman (@svovaf)
9532
* @since 1.0.1
@@ -9626,12 +9761,14 @@
9626
* @author Vova Feldman (@svovaf)
9627
* @since 1.0.0
9628
*
9629
* @return string
9630
*/
9631
- function get_plugin_version() {
9632
$this->_logger->entrance();
9633
9634
- $plugin_data = $this->get_plugin_data();
9635
9636
$this->_logger->departure( 'Version = ' . $plugin_data['Version'] );
9637
@@ -9756,7 +9893,7 @@
9756
* @return array[number]FS_User
9757
*/
9758
static function get_all_users() {
9759
- $users = self::$_accounts->get_option( 'users', array() );
9760
9761
if ( ! is_array( $users ) ) {
9762
$users = array();
@@ -9800,7 +9937,7 @@
9800
$option_name = $module_type . '_' . $option_name;
9801
}
9802
9803
- return self::$_accounts->get_option( $option_name, array(), $network_level_or_blog_id );
9804
}
9805
9806
/**
@@ -9848,6 +9985,54 @@
9848
self::$_accounts->set_option( $option_name, $option_value, $store, $network_level_or_blog_id );
9849
}
9850
9851
/**
9852
* @author Vova Feldman (@svovaf)
9853
* @since 1.0.6
@@ -10031,7 +10216,7 @@
10031
* @return FS_Plugin_Tag[]
10032
*/
10033
private static function get_all_updates() {
10034
- $updates = self::$_accounts->get_option( 'updates', array() );
10035
10036
if ( ! is_array( $updates ) ) {
10037
$updates = array();
@@ -10047,7 +10232,7 @@
10047
* @return array<number,FS_Plugin[]>|false
10048
*/
10049
private static function get_all_addons() {
10050
- $addons = self::$_accounts->get_option( 'addons', array() );
10051
10052
if ( ! is_array( $addons ) ) {
10053
$addons = array();
@@ -10060,7 +10245,7 @@
10060
* @author Vova Feldman (@svovaf)
10061
* @since 1.0.6
10062
*
10063
- * @return FS_Plugin[]|false
10064
*/
10065
private static function get_all_account_addons() {
10066
$addons = self::$_accounts->get_option( 'account_addons', array() );
@@ -10161,7 +10346,7 @@
10161
* @author Vova Feldman (@svovaf)
10162
* @since 1.0.6
10163
*
10164
- * @return FS_Plugin[]|false
10165
*/
10166
function get_account_addons() {
10167
$this->_logger->entrance();
@@ -10305,7 +10490,7 @@
10305
10306
if ( ! fs_is_network_admin() ) {
10307
// Get blog-level activated installations.
10308
- $sites = self::$_accounts->get_option( 'sites', array() );
10309
} else {
10310
$sites = null;
10311
@@ -10314,7 +10499,7 @@
10314
) {
10315
if ( FS_Site::is_valid_id( $addon_storage->network_install_blog_id ) ) {
10316
// Get network-level activated installations.
10317
- $sites = self::$_accounts->get_option(
10318
'sites',
10319
array(),
10320
$addon_storage->network_install_blog_id
@@ -10324,9 +10509,10 @@
10324
}
10325
10326
$addon_info = array(
10327
- 'is_connected' => false,
10328
- 'slug' => $slug,
10329
- 'title' => $addon->title
10330
);
10331
10332
if ( ! $is_installed ) {
@@ -10372,14 +10558,14 @@
10372
10373
$addon_info['site'] = $site;
10374
10375
- $plugins_data = self::$_accounts->get_option( WP_FS__MODULE_TYPE_PLUGIN . 's', array() );
10376
if ( isset( $plugins_data[ $slug ] ) ) {
10377
$plugin_data = $plugins_data[ $slug ];
10378
10379
$addon_info['version'] = $plugin_data->version;
10380
}
10381
10382
- $all_plans = self::$_accounts->get_option( 'plans', array() );
10383
if ( isset( $all_plans[ $slug ] ) ) {
10384
$plans = $all_plans[ $slug ];
10385
@@ -10392,7 +10578,7 @@
10392
}
10393
}
10394
10395
- $licenses = self::$_accounts->get_option( 'all_licenses', array() );
10396
if ( is_array( $licenses ) && isset( $licenses[ $addon_id ] ) ) {
10397
foreach ( $licenses[ $addon_id ] as $license ) {
10398
if ( $license->id == $site->license_id ) {
@@ -10406,7 +10592,9 @@
10406
if ( isset( $addon_storage->subscriptions ) &&
10407
! empty( $addon_storage->subscriptions )
10408
) {
10409
- foreach ( $addon_storage->subscriptions as $subscription ) {
10410
if ( $subscription->license_id == $site->license_id ) {
10411
$addon_info['subscription'] = $subscription;
10412
break;
@@ -10497,7 +10685,7 @@
10497
function is_premium() {
10498
/**
10499
* `$this->_plugin` will be `false` when `is_activation_mode` calls this method directly from the
10500
- * `_register_hooks` method.
10501
*
10502
* @author Leo Fajardo (@leorw)
10503
* @since 2.2.3
@@ -10594,7 +10782,20 @@
10594
return false;
10595
}
10596
10597
- return $this->has_active_valid_license() && ( $this->_site->trial_plan_id == $this->_license->plan_id );
10598
}
10599
10600
/**
@@ -10729,10 +10930,26 @@
10729
* @author Vova Feldman (@svovaf)
10730
* @since 1.1.7.3
10731
*
10732
* @return bool
10733
*/
10734
- function has_any_license() {
10735
- return is_array( $this->_licenses ) && ( 0 < count( $this->_licenses ) );
10736
}
10737
10738
/**
@@ -10878,7 +11095,9 @@
10878
10879
if ( $license instanceof FS_Plugin_License ) {
10880
$this->_licenses[] = $license;
10881
- $this->_license = $license;
10882
$this->_store_licenses();
10883
10884
return $license;
@@ -11103,7 +11322,7 @@
11103
11104
// Update current license.
11105
if ( is_object( $this->_license ) ) {
11106
- $this->_license = $this->_get_license_by_id( $this->_license->id );
11107
}
11108
11109
return $this->_licenses;
@@ -11443,6 +11662,21 @@
11443
return true;
11444
}
11445
11446
/**
11447
* Activate a given license on a collection of blogs/sites that are not yet opted-in.
11448
*
@@ -11458,7 +11692,7 @@
11458
private function activate_license_on_many_sites(
11459
FS_User $user,
11460
$license_key,
11461
- array $site_ids
11462
) {
11463
$sites = array();
11464
foreach ( $site_ids as $site_id ) {
@@ -11482,30 +11716,43 @@
11482
}
11483
11484
$installs = array();
11485
- foreach ( $result->installs as $install ) {
11486
- $installs[] = new FS_Site( $install );
11487
- }
11488
11489
- // Map site addresses to their blog IDs.
11490
- $address_to_blog_map = $this->get_address_to_blog_map();
11491
11492
- $first_blog_id = null;
11493
11494
- foreach ( $installs as $install ) {
11495
- $address = trailingslashit( fs_strip_url_protocol( $install->url ) );
11496
- $blog_id = $address_to_blog_map[ $address ];
11497
11498
- $this->_store_site( true, $blog_id, $install );
11499
11500
- $this->reset_anonymous_mode( $blog_id );
11501
11502
- if ( is_null( $first_blog_id ) ) {
11503
- $first_blog_id = $blog_id;
11504
}
11505
- }
11506
11507
- if ( ! FS_Site::is_valid_id( $this->_storage->network_install_blog_id ) ) {
11508
- $this->_storage->network_install_blog_id = $first_blog_id;
11509
}
11510
11511
return true;
@@ -11524,7 +11771,7 @@
11524
function _update_site_license( $new_license ) {
11525
$this->_logger->entrance();
11526
11527
- $this->_license = $new_license;
11528
11529
if ( ! is_object( $new_license ) ) {
11530
$this->_site->license_id = null;
@@ -11560,21 +11807,256 @@
11560
}
11561
11562
/**
11563
- * Sync site's subscription.
11564
- *
11565
* @author Vova Feldman (@svovaf)
11566
- * @since 1.0.9
11567
*
11568
- * @param FS_Plugin_License|null $license
11569
*
11570
- * @return bool|\FS_Subscription
11571
*/
11572
- private function _sync_site_subscription( $license ) {
11573
- if ( ! is_object( $license ) ) {
11574
- $this->delete_unused_subscriptions();
11575
11576
- return false;
11577
- }
11578
11579
// Load subscription details if not lifetime.
11580
$subscription = $license->is_lifetime() ?
@@ -11616,7 +12098,7 @@
11616
return null;
11617
}
11618
11619
- foreach ( $this->_storage->subscriptions as $subscription ) {
11620
if ( $subscription->license_id == $license_id ) {
11621
return $subscription;
11622
}
@@ -11642,7 +12124,7 @@
11642
return;
11643
}
11644
11645
- $subscriptions = $this->_storage->subscriptions;
11646
11647
$updated_subscription = false;
11648
foreach ( $subscriptions as $key => $existing_subscription ) {
@@ -11755,9 +12237,11 @@
11755
* @author Vova Feldman (@svovaf)
11756
* @since 1.2.1.7
11757
*
11758
* @return bool
11759
*/
11760
- function is_single_plan() {
11761
$this->_logger->entrance();
11762
11763
if ( ! $this->is_registered() ||
@@ -11767,7 +12251,18 @@
11767
return true;
11768
}
11769
11770
- return ( 1 === ( count( $this->_plans ) - ( $this->has_free_plan() ? 1 : 0 ) ) );
11771
}
11772
11773
/**
@@ -11881,6 +12376,18 @@
11881
fs_require_template( 'forms/resend-key.php', $vars );
11882
}
11883
11884
/**
11885
* Displays a subscription cancellation dialog box when the user clicks on the "Deactivate License"
11886
* link on the "Account" page or deactivates a plugin and there's an active subscription that is
@@ -11899,6 +12406,10 @@
11899
// Subscription cancellation dialog box is currently not supported for multisite networks.
11900
return array();
11901
}
11902
11903
$license = $this->_get_license();
11904
@@ -11986,8 +12497,8 @@
11986
return;
11987
}
11988
11989
- if ( ! $this->is_premium() ) {
11990
- // Only add license activation logic to the premium version.
11991
return;
11992
}
11993
@@ -12149,7 +12660,9 @@
12149
$is_marketing_allowed = null,
12150
$plugin_id = null
12151
) {
12152
- return $this->activate_license(
12153
$license_key,
12154
$this->is_network_active() ?
12155
$this->get_sites_for_network_level_optin() :
@@ -12158,6 +12671,11 @@
12158
null,
12159
$plugin_id
12160
);
12161
}
12162
12163
/**
@@ -12203,7 +12721,20 @@
12203
12204
$has_valid_blog_id = is_numeric( $blog_id );
12205
12206
- if ( $fs->is_registered() ) {
12207
if ( fs_is_network_admin() && ! $has_valid_blog_id ) {
12208
// If no specific blog ID was provided, activate the license for all sites in the network.
12209
$blog_2_install_map = array();
@@ -12214,7 +12745,7 @@
12214
continue;
12215
}
12216
12217
- $install = $this->get_install_by_blog_id( $site['blog_id'] );
12218
12219
if ( is_object( $install ) ) {
12220
$blog_2_install_map[ $site['blog_id'] ] = $install;
@@ -12223,10 +12754,8 @@
12223
}
12224
}
12225
12226
- $user = $this->get_current_or_network_user();
12227
-
12228
if ( ! empty( $blog_2_install_map ) ) {
12229
- $result = $this->activate_license_on_many_installs( $user, $license_key, $blog_2_install_map );
12230
12231
if ( true !== $result ) {
12232
$error = FS_Api::is_api_error_object( $result ) ?
@@ -12236,7 +12765,7 @@
12236
}
12237
12238
if ( empty( $error ) && ! empty( $site_ids ) ) {
12239
- $result = $this->activate_license_on_many_sites( $user, $license_key, $site_ids );
12240
12241
if ( true !== $result ) {
12242
$error = FS_Api::is_api_error_object( $result ) ?
@@ -12252,28 +12781,38 @@
12252
*
12253
* @author Leo Fajardo (@leorw)
12254
*/
12255
- $this->switch_to_blog( $blog_id );
12256
}
12257
12258
- $api = $fs->get_api_site_scope();
12259
12260
- $params = array(
12261
- 'license_key' => $fs->apply_filters( 'license_key', $license_key )
12262
- );
12263
12264
- $install = $api->call( $fs->add_show_pending( '/' ), 'put', $params );
12265
12266
- if ( FS_Api::is_api_error( $install ) ) {
12267
- $error = FS_Api::is_api_error_object( $install ) ?
12268
- $install->error->message :
12269
- var_export( $install->error, true );
12270
- } else {
12271
- $fs->reconnect_locally( $has_valid_blog_id );
12272
}
12273
}
12274
12275
if ( empty( $error ) ) {
12276
- $this->network_upgrade_mode_completed();
12277
12278
$fs->_sync_license( true, $has_valid_blog_id );
12279
@@ -12325,17 +12864,17 @@
12325
continue;
12326
}
12327
12328
- if ( $this->is_installed_on_site( $blog_id ) ) {
12329
// Site was already connected before.
12330
continue;
12331
}
12332
12333
- if ( $this->is_site_delegated_connection( $blog_id ) ) {
12334
// Site's connection was delegated.
12335
continue;
12336
}
12337
12338
- if ( $this->is_anonymous_site( $blog_id ) ) {
12339
// Site connection was already skipped.
12340
continue;
12341
}
@@ -12344,18 +12883,18 @@
12344
}
12345
12346
if ( ! empty( $pending_sites ) ) {
12347
- if ( $this->is_freemium() && $this->is_enable_anonymous() ) {
12348
- $this->skip_connection( $pending_sites );
12349
} else {
12350
- $this->delegate_connection( $pending_sites );
12351
}
12352
}
12353
}
12354
}
12355
}
12356
12357
- if ( false === $error && true === $this->_storage->require_license_activation ) {
12358
- $this->_storage->require_license_activation = false;
12359
}
12360
12361
$result = array(
@@ -12363,9 +12902,9 @@
12363
);
12364
12365
if ( false !== $error ) {
12366
- $result['error'] = $this->apply_filters( 'opt_in_error_message', $error );
12367
} else {
12368
- if ( $this->is_addon() || $this->has_addons() ) {
12369
/**
12370
* Purge the valid user licenses cache so that when the "Account" or the "Add-Ons" page is loaded,
12371
* an updated valid user licenses collection will be fetched from the server which is used to also
@@ -12374,7 +12913,7 @@
12374
* @author Leo Fajardo (@leorw)
12375
* @since 2.2.4
12376
*/
12377
- $this->purge_valid_user_licenses_cache();
12378
}
12379
12380
$result['next_page'] = $next_page;
@@ -13409,9 +13948,8 @@
13409
$page_param = $this->_menu->get_slug( $page );
13410
13411
if ( empty( $page ) &&
13412
- $this->is_theme() &&
13413
// Show the opt-in as an overlay for free wp.org themes or themes without any settings page.
13414
- ( $this->is_free_wp_org_theme() || ! $this->has_settings_menu() )
13415
) {
13416
$params[ $this->get_unique_affix() . '_show_optin' ] = 'true';
13417
@@ -13841,10 +14379,12 @@
13841
*
13842
* @param int $blog_id
13843
* @param FS_Site $install
13844
*/
13845
function switch_to_blog( $blog_id, FS_Site $install = null ) {
13846
if ( $blog_id == $this->_context_is_network_or_blog_id ) {
13847
- return;
13848
}
13849
13850
switch_to_blog( $blog_id );
@@ -13858,9 +14398,10 @@
13858
$install :
13859
$this->get_install_by_blog_id( $blog_id );
13860
13861
- $this->_user = false;
13862
- $this->_licenses = false;
13863
- $this->_license = null;
13864
13865
if ( is_object( $this->_site ) ) {
13866
// Try to fetch user from install.
@@ -13905,6 +14446,8 @@
13905
13906
unset( $this->_site_api );
13907
unset( $this->_user_api );
13908
}
13909
13910
/**
@@ -14350,6 +14893,18 @@
14350
return ( $this->_menu->get_slug( $page ) === fs_request_get( 'page', '', 'get' ) );
14351
}
14352
14353
/**
14354
* Get module's main admin setting page URL.
14355
*
@@ -14370,8 +14925,22 @@
14370
* @since 1.2.2.7
14371
*
14372
* @return bool
14373
*/
14374
function is_theme_settings_page() {
14375
return fs_starts_with(
14376
fs_request_get( 'page', '', 'get' ),
14377
$this->_menu->get_slug()
@@ -14993,6 +15562,13 @@
14993
'is_uninstalled' => false,
14994
) );
14995
14996
if ( true === $network_level_or_blog_id ) {
14997
if ( ! isset( $override_with['sites'] ) ) {
14998
$params['sites'] = $this->get_sites_for_network_level_optin();
@@ -15088,9 +15664,12 @@
15088
if ( ! $is_uninstall ) {
15089
$fs_user = Freemius::_get_user_by_email( $email );
15090
if ( is_object( $fs_user ) && ! $this->is_pending_activation() ) {
15091
- return $this->install_with_current_user(
15092
false,
15093
$trial_plan_id,
15094
$sites
15095
);
15096
}
@@ -15361,7 +15940,7 @@
15361
);
15362
15363
if ( is_numeric( $first_install->license_id ) ) {
15364
- $this->_license = $this->_get_license_by_id( $first_install->license_id );
15365
}
15366
15367
$this->_admin_notices->remove_sticky( 'connect_account' );
@@ -15852,7 +16431,7 @@
15852
*
15853
* @return \FS_Site|object|string If redirect is `false`, returns the next page the user should be redirected to, or the API error object if failed to install. If $setup_account is set to `false`, return the newly created install.
15854
*/
15855
- private function install_with_user(
15856
FS_User $user,
15857
$license_key = false,
15858
$trial_plan_id = false,
@@ -15941,6 +16520,10 @@
15941
15942
if ( ! empty( $license_key ) ) {
15943
$extra_install_params['license_key'] = $this->apply_filters( 'license_key', $license_key );
15944
} else if ( FS_Plugin_Plan::is_valid_id( $trial_plan_id ) ) {
15945
$extra_install_params['trial_plan_id'] = $trial_plan_id;
15946
}
@@ -15962,7 +16545,7 @@
15962
! $this->is_api_result_object( $result, 'installs' )
15963
) {
15964
if ( ! empty( $args['license_key'] ) ) {
15965
- // Pass full the fully entered license key to the failure handler.
15966
$args['license_key'] = $license_key;
15967
}
15968
@@ -16339,7 +16922,7 @@
16339
*/
16340
private function add_menu_action() {
16341
if ( $this->is_activation_mode() ) {
16342
- if ( $this->is_plugin() || ( $this->has_settings_menu() && ! $this->is_free_wp_org_theme() ) ) {
16343
$this->override_plugin_menu_with_activation();
16344
} else {
16345
/**
@@ -16361,7 +16944,7 @@
16361
}
16362
} else if (
16363
fs_request_is_action( 'sync_user' ) &&
16364
- ( ! $this->has_settings_menu() || $this->is_free_wp_org_theme() )
16365
) {
16366
$this->_handle_account_user_sync();
16367
}
@@ -16609,7 +17192,7 @@
16609
// Didn't ask to hide the pricing page.
16610
$this->is_page_visible( 'pricing' ) &&
16611
// Don't have a valid active license or has more than one plan.
16612
- ( ! $this->is_paying() || ! $this->is_single_plan() )
16613
);
16614
}
16615
@@ -16627,12 +17210,13 @@
16627
return false;
16628
}
16629
16630
- if ( $this->is_free_wp_org_theme() && ! fs_is_network_admin() ) {
16631
- // Also add action links or submenu items when running in a free .org theme so the tabs will be visible.
16632
- return true;
16633
- }
16634
-
16635
- if ( $is_activation_mode && ! $this->is_free_wp_org_theme() ) {
16636
return false;
16637
}
16638
@@ -16712,17 +17296,19 @@
16712
}
16713
16714
if ( $add_submenu_items ) {
16715
- // Add contact page.
16716
- $this->add_submenu_item(
16717
- $this->get_text_inline( 'Contact Us', 'contact-us' ),
16718
- array( &$this, '_contact_page_render' ),
16719
- $this->get_plugin_name() . ' &ndash; ' . $this->get_text_inline( 'Contact Us', 'contact-us' ),
16720
- 'manage_options',
16721
- 'contact',
16722
- 'Freemius::_clean_admin_content_section',
16723
- WP_FS__DEFAULT_PRIORITY,
16724
- $this->is_submenu_item_visible( 'contact' )
16725
- );
16726
16727
if ( $this->has_addons() ) {
16728
$this->add_submenu_item(
@@ -16741,7 +17327,7 @@
16741
if ( $add_submenu_items ||
16742
( $is_activation_mode && $this->is_only_premium() && $this->is_admin_page( 'pricing' ) )
16743
) {
16744
- if ( ! WP_FS__DEMO_MODE ) {
16745
$show_pricing = (
16746
$this->is_submenu_item_visible( 'pricing' ) &&
16747
$this->is_pricing_page_visible()
@@ -17106,6 +17692,24 @@
17106
17107
#endregion ------------------------------------------------------------------
17108
17109
17110
#--------------------------------------------------------------------------------
17111
#region Actions / Hooks / Filters
@@ -17482,21 +18086,24 @@
17482
private function _store_site( $store = true, $network_level_or_blog_id = null, FS_Site $site = null ) {
17483
$this->_logger->entrance();
17484
17485
- if ( empty( $this->_site->id ) ) {
17486
$this->_logger->error( "Empty install ID, can't store site." );
17487
17488
return;
17489
}
17490
17491
- $site_clone = is_object( $site ) ? $site : $this->_site;
17492
- $encrypted_site = clone $site_clone;
17493
17494
$sites = self::get_all_sites( $this->_module_type, $network_level_or_blog_id );
17495
17496
$prev_stored_user_id = $this->_storage->get( 'prev_user_id', false, $network_level_or_blog_id );
17497
17498
if ( empty( $prev_stored_user_id ) &&
17499
- $this->_user->id != $this->_site->user_id
17500
) {
17501
/**
17502
* Store the current user ID as the previous user ID so that the previous user can be used
@@ -17512,7 +18119,7 @@
17512
$this->_storage->store( 'prev_user_id', $sites[ $this->_slug ]->user_id, $network_level_or_blog_id );
17513
}
17514
17515
- $sites[ $this->_slug ] = $encrypted_site;
17516
17517
$this->set_account_option( 'sites', $sites, $store, $network_level_or_blog_id );
17518
}
@@ -17722,6 +18329,10 @@
17722
* @since 2.2.4
17723
*/
17724
private function purge_valid_user_licenses_cache() {
17725
$this->get_api_user_scope()->purge_cache( $this->get_valid_user_licenses_endpoint() );
17726
}
17727
@@ -18380,6 +18991,88 @@
18380
return self::is_active_valid_license( $this->_license );
18381
}
18382
18383
/**
18384
* Check if a given license is active & valid (not expired).
18385
*
@@ -18694,7 +19387,7 @@
18694
} else {
18695
// Authentication params are broken.
18696
$this->_admin_notices->add(
18697
- $this->get_text_inline( 'It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again.', 'wrong-authentication-param-message' ),
18698
$this->get_text_x_inline( 'Oops', 'exclamation', 'oops' ) . '...',
18699
'error'
18700
);
@@ -18861,12 +19554,32 @@
18861
$this->get_network_install_blog_id()
18862
);
18863
} else {
18864
- if ( is_object( $this->_license ) && $this->_license->is_expired() ) {
18865
- if ( ! $this->has_features_enabled_license() ) {
18866
- $this->_deactivate_license();
18867
- $plan_change = 'downgraded';
18868
- } else {
18869
- $plan_change = 'expired';
18870
}
18871
}
18872
@@ -18890,7 +19603,7 @@
18890
18891
$hmm_text = $this->get_text_x_inline( 'Hmm', 'something somebody says when they are thinking about what you have just said.', 'hmm' ) . '...';
18892
18893
- if ( $this->has_paid_plan() ) {
18894
switch ( $plan_change ) {
18895
case 'none':
18896
if ( ! $background && is_admin() ) {
@@ -18983,6 +19696,9 @@
18983
'license_expired',
18984
$hmm_text
18985
);
18986
$this->_admin_notices->remove_sticky( 'plan_upgraded' );
18987
break;
18988
case 'trial_started':
@@ -19037,7 +19753,8 @@
19037
* @author Vova Feldman (@svovaf)
19038
* @since 1.0.5
19039
*
19040
- * @param bool $background
19041
*/
19042
protected function _activate_license( $background = false, $premium_license = null ) {
19043
$this->_logger->entrance();
@@ -19844,7 +20561,7 @@
19844
19845
$api = $this->get_api_site_or_plugin_scope();
19846
19847
- $path = $this->add_show_pending( '/addons.json?enriched=true' );
19848
19849
/**
19850
* @since 1.2.1
@@ -20151,7 +20868,7 @@
20151
* @return string
20152
*/
20153
function get_after_activation_url( $filter, $params = array(), $network = null ) {
20154
- if ( $this->is_free_wp_org_theme() &&
20155
( fs_request_has( 'pending_activation' ) ||
20156
// For cases when the first time path is set, even though it's a WP.org theme.
20157
fs_request_get_bool( $this->get_unique_affix() . '_show_optin' ) )
@@ -20894,6 +21611,26 @@
20894
return $this->_plugin_api;
20895
}
20896
20897
/**
20898
* Get site API scope object (fallback to public plugin scope when not registered).
20899
*
@@ -21227,7 +21964,7 @@
21227
function _show_theme_activation_optin_dialog() {
21228
fs_enqueue_local_style( 'fs_connect', '/admin/connect.css' );
21229
21230
- add_action( 'admin_footer-themes.php', array( &$this, '_add_fs_theme_activation_dialog' ) );
21231
}
21232
21233
/**
@@ -21235,6 +21972,12 @@
21235
* @since 1.2.2
21236
*/
21237
function _add_fs_theme_activation_dialog() {
21238
$vars = array( 'id' => $this->_module_id );
21239
fs_require_once_template( 'connect.php', $vars );
21240
}
@@ -21322,7 +22065,7 @@
21322
$add_upgrade_link = (
21323
$add_action_links ||
21324
( $is_activation_mode && $this->is_only_premium() )
21325
- ) && ! WP_FS__DEMO_MODE;
21326
21327
$add_addons_link = ( $add_action_links && $this->has_addons() );
21328
@@ -21411,6 +22154,11 @@
21411
21412
$this->_logger->entrance();
21413
21414
if ( fs_is_network_admin() ) {
21415
if ( ! $this->_is_network_active ) {
21416
// Don't add tracking links when browsing the network WP Admin and the plugin is not network active.
@@ -21470,8 +22218,6 @@
21470
} else {
21471
$link_text_id = $this->get_text_inline( 'Opt In', 'opt-in' );
21472
}
21473
-
21474
- add_action( 'admin_footer', array( &$this, '_add_optout_dialog' ) );
21475
} else if ( $this->is_anonymous() || $this->is_activation_mode() ) {
21476
/**
21477
* Show opt-in link only if skipped or in activation mode.
@@ -21488,6 +22234,8 @@
21488
$url = $this->get_activation_url( $params );
21489
}
21490
21491
if ( ! empty( $link_text_id ) && $this->is_plugin() && self::is_plugins_page() ) {
21492
$this->add_plugin_action_link(
21493
$link_text_id,
@@ -22177,7 +22925,7 @@
22177
function _tabs_capture() {
22178
$this->_logger->entrance();
22179
22180
- if ( ! $this->is_theme_settings_page() ||
22181
! $this->is_matching_url( $this->main_menu_url() )
22182
) {
22183
return;
@@ -22232,7 +22980,7 @@
22232
function _store_tabs_styles() {
22233
$this->_logger->entrance();
22234
22235
- if ( ! $this->is_theme_settings_page() ||
22236
! $this->is_matching_url( $this->main_menu_url() )
22237
) {
22238
return;
@@ -22306,18 +23054,23 @@
22306
return false;
22307
}
22308
22309
- if ( ! $this->is_theme() ) {
22310
// Only add tabs to themes for now.
22311
return false;
22312
}
22313
22314
- if ( ! $this->has_paid_plan() && ! $this->has_addons() ) {
22315
// Only add tabs to monetizing themes.
22316
return false;
22317
}
22318
22319
- if ( ! $this->is_theme_settings_page() ) {
22320
- // Only add tabs if browsing one of the theme's setting pages.
22321
return false;
22322
}
22323
@@ -23004,8 +23757,8 @@
23004
}
23005
23006
$modules = array_merge(
23007
- array_values( self::$_accounts->get_option( 'plugins', array() ) ),
23008
- array_values( self::$_accounts->get_option( 'themes', array() ) )
23009
);
23010
23011
foreach ( $modules as $module ) {
@@ -23149,8 +23902,8 @@
23149
}
23150
23151
$modules = array_merge(
23152
- array_values( self::$_accounts->get_option( 'plugins', array() ) ),
23153
- array_values( self::$_accounts->get_option( 'themes', array() ) )
23154
);
23155
23156
foreach ( $modules as $key => $module ) {
164
*/
165
private $_has_addons;
166
167
+ /**
168
+ * @since 2.4.5
169
+ * @var string Navigation type: 'menu' or 'tabs'.
170
+ */
171
+ private $_navigation;
172
+
173
+ const NAVIGATION_MENU = 'menu';
174
+ const NAVIGATION_TABS = 'tabs';
175
+
176
/**
177
* @since 1.1.6
178
* @var string[]bool.
343
*/
344
private $_dynamically_added_top_level_page_hook_name = '';
345
346
+ /**
347
+ * @author Leo Fajardo (@leorw)
348
+ * @since 2.3.1
349
+ *
350
+ * @var bool
351
+ */
352
+ private $is_whitelabeled;
353
+
354
#region Uninstall Reasons IDs
355
356
const REASON_NO_LONGER_NEEDED = 1;
501
);
502
503
if ( 'true' === fs_request_get( 'fs_clear_api_cache' ) ||
504
+ fs_request_is_action( 'restart_freemius' )
505
) {
506
FS_Api::clear_cache();
507
$this->_cache->clear();
508
}
509
510
+ $this->register_constructor_hooks();
511
512
/**
513
* Starting from version 2.0.0, `FS_Site` entities no longer have the `plan` property and have `plan_id`
719
$this->_menu->has_menu();
720
}
721
722
+ /**
723
+ * If `true` the opt-in should be shown as a modal dialog box on the themes.php page. WordPress.org themes guidelines prohibit from redirecting the user from the themes.php page after activating a theme.
724
+ *
725
+ * @author Vova Feldman (@svovaf)
726
+ * @since 2.4.5
727
+ *
728
+ * @return bool
729
+ */
730
+ function show_opt_in_on_themes_page() {
731
+ if ( ! $this->is_free_wp_org_theme() ) {
732
+ return false;
733
+ }
734
+
735
+ if ( ! $this->has_settings_menu() ) {
736
+ return true;
737
+ }
738
+
739
+ return $this->show_settings_with_tabs();
740
+ }
741
+
742
+ /**
743
+ * If `true` the opt-in should be shown on the product's main setting page.
744
+ *
745
+ * @author Vova Feldman (@svovaf)
746
+ * @since 2.4.5
747
+ *
748
+ * @return bool
749
+ *
750
+ * @uses show_opt_in_on_themes_page();
751
+ */
752
+ function show_opt_in_on_setting_page() {
753
+ return ! $this->show_opt_in_on_themes_page();
754
+ }
755
+
756
+ /**
757
+ * If `true` the settings should be shown using tabs.
758
+ *
759
+ * @author Vova Feldman (@svovaf)
760
+ * @since 2.4.5
761
+ *
762
+ * @return bool
763
+ */
764
+ function show_settings_with_tabs() {
765
+ return ( self::NAVIGATION_TABS === $this->_navigation );
766
+ }
767
+
768
/**
769
* Check if the context module is free wp.org theme.
770
*
797
* @since 1.2.2.7 Even if the menu item was specified to be hidden, when it is the context page, then show the submenu item so the user will have the right context page.
798
*
799
* @param string $slug
800
+ * @param bool $is_tabs_visibility_check This is used to decide if the associated tab should be shown or hidden.
801
*
802
* @return bool
803
*/
804
+ function is_submenu_item_visible( $slug, $is_tabs_visibility_check = false ) {
805
if ( $this->is_admin_page( $slug ) ) {
806
/**
807
* It is the current context page, so show the submenu item
816
return false;
817
}
818
819
+ if ( ! $is_tabs_visibility_check && $this->show_settings_with_tabs() ) {
820
/**
821
* wp.org themes are limited to a single submenu item, and
822
* sub-submenu items are most likely not allowed (never verified).
1042
}
1043
1044
if ( isset( $this->_storage->subscription ) && is_object( $this->_storage->subscription ) ) {
1045
+ $this->_storage->subscriptions = array( fs_get_entity( $this->_storage->subscription, FS_Subscription::get_class_name() ) );
1046
}
1047
}
1048
1515
* @author Vova Feldman (@svovaf)
1516
* @since 1.0.9
1517
*/
1518
+ private function register_constructor_hooks() {
1519
$this->_logger->entrance();
1520
1521
if ( is_admin() ) {
1522
+ add_action( 'admin_init', array( &$this, '_hook_action_links_and_register_account_hooks' ) );
1523
1524
if ( $this->is_plugin() ) {
1525
if ( self::is_plugin_install_page() && true !== fs_request_get_bool( 'fs_allow_updater_and_dialog' ) ) {
1560
} else {
1561
add_action( 'after_switch_theme', array( &$this, '_activate_theme_event_hook' ), 10, 2 );
1562
1563
add_action( 'admin_footer', array( &$this, '_style_premium_theme' ) );
1564
}
1565
1579
*
1580
* @author Vova Feldman (@svovaf)
1581
*/
1582
+ if ( $this->is_plugin() &&
1583
+ $this->is_activation_mode( false ) &&
1584
+ 0 == did_action( 'plugins_loaded' )
1585
+ ) {
1586
add_action( 'plugins_loaded', array( &$this, '_plugins_loaded' ) );
1587
} else {
1588
// If was activated before, then it was already loaded before.
1642
1643
$this->add_ajax_action( 'update_billing', array( &$this, '_update_billing_ajax_action' ) );
1644
$this->add_ajax_action( 'start_trial', array( &$this, '_start_trial_ajax_action' ) );
1645
+ $this->add_ajax_action( 'set_data_debug_mode', array( &$this, '_set_data_debug_mode' ) );
1646
1647
if ( $this->_is_network_active && fs_is_network_admin() ) {
1648
$this->add_ajax_action( 'network_activate', array( &$this, '_network_activate_ajax_action' ) );
1684
}
1685
}
1686
1687
+ /**
1688
+ * Register the required hooks right after the settings parse is completed.
1689
+ *
1690
+ * @author Vova Feldman (@svovaf)
1691
+ * @since 2.3.1
1692
+ */
1693
+ private function register_after_settings_parse_hooks() {
1694
+ if ( is_admin() &&
1695
+ $this->is_theme() &&
1696
+ $this->is_premium() &&
1697
+ ! $this->has_active_valid_license()
1698
+ ) {
1699
+ $this->add_ajax_action(
1700
+ 'delete_theme_update_data',
1701
+ array( &$this, '_delete_theme_update_data_action' )
1702
+ );
1703
+ }
1704
+
1705
+ if ( $this->show_settings_with_tabs() ) {
1706
+ /**
1707
+ * Include the required hooks to capture the theme settings' page tabs
1708
+ * and cache them.
1709
+ *
1710
+ * @author Vova Feldman (@svovaf)
1711
+ * @since 1.2.2.7
1712
+ */
1713
+ if ( ! $this->_cache->has_valid( 'tabs' ) ) {
1714
+ add_action( 'admin_footer', array( &$this, '_tabs_capture' ) );
1715
+ // Add license activation AJAX callback.
1716
+ $this->add_ajax_action( 'store_tabs', array( &$this, '_store_tabs_ajax_action' ) );
1717
+
1718
+ add_action( 'admin_enqueue_scripts', array( &$this, '_store_tabs_styles' ), 9999999 );
1719
+ }
1720
+
1721
+ add_action(
1722
+ 'admin_footer',
1723
+ array( &$this, '_add_freemius_tabs' ),
1724
+ /**
1725
+ * The tabs JS code must be executed after the tabs capture logic (_tabs_capture()).
1726
+ * That's why the priority is 11 while the tabs capture logic is added
1727
+ * with priority 10.
1728
+ *
1729
+ * @author Vova Feldman (@svovaf)
1730
+ */
1731
+ 11
1732
+ );
1733
+ }
1734
+
1735
+ if ( ! self::is_ajax() ) {
1736
+ if ( ! $this->is_addon() || $this->is_only_premium() ) {
1737
+ add_action(
1738
+ ( $this->_is_network_active && fs_is_network_admin() ? 'network_' : '' ) . 'admin_menu',
1739
+ array( &$this, '_prepare_admin_menu' ),
1740
+ WP_FS__LOWEST_PRIORITY
1741
+ );
1742
+ }
1743
+ }
1744
+ }
1745
+
1746
/**
1747
* Makes Freemius-related updates unavailable on the "Add Plugins" admin page (/plugin-install.php) so that
1748
* they won't interfere with the .org plugins' functionalities on that page (e.g. updating of a .org plugin).
2005
* @since 2.0.0
2006
*/
2007
function _hook_action_links_and_register_account_hooks() {
2008
+ $this->_add_tracking_links();
2009
2010
if ( self::is_plugins_page() && $this->is_plugin() ) {
2011
$this->hook_plugin_action_links();
2347
2348
if ( ! isset( $caller_map[ $caller_file_hash ] ) ) {
2349
foreach ( $all_plugins_paths as $plugin_path ) {
2350
+ if ( empty( $plugin_path ) ) {
2351
+ continue;
2352
+ }
2353
+
2354
if ( false !== strpos( $caller_file_path, fs_normalize_path( dirname( $plugin_path ) . '/' ) ) ) {
2355
$caller_map[ $caller_file_hash ] = fs_normalize_path( $plugin_path );
2356
break;
3029
* @return bool
3030
*/
3031
function is_activation_page() {
3032
+ if ( $this->_menu->is_activation_page( $this->show_opt_in_on_themes_page() ) ) {
3033
return true;
3034
}
3035
4731
4732
$this->parse_settings( $plugin_info );
4733
4734
+ $this->register_after_settings_parse_hooks();
4735
4736
if ( $this->should_stop_execution() ) {
4737
return;
4889
if (
4890
$this->_parent->is_registered() &&
4891
! $this->is_registered() &&
4892
+ $this->has_free_plan() &&
4893
/**
4894
* If not registered for add-on and the following conditions for the add-on are met, activate add-on account.
4895
* * Network active and in network admin - network activate add-on account.
5483
'is_live' => $this->get_bool_option( $plugin_info, 'is_live', true ),
5484
'affiliate_moderation' => $this->get_option( $plugin_info, 'has_affiliation' ),
5485
'bundle_id' => $this->get_option( $plugin_info, 'bundle_id', null ),
5486
+ 'bundle_public_key' => $this->get_option( $plugin_info, 'bundle_public_key', null ),
5487
) );
5488
5489
if ( $plugin->is_updated() ) {
5555
5556
$this->_is_trial_require_payment = $this->get_bool_option( $plugin_info['trial'], 'is_require_payment', false );
5557
}
5558
+
5559
+ $this->_navigation = $this->get_option(
5560
+ $plugin_info,
5561
+ 'navigation',
5562
+ $this->is_free_wp_org_theme() ?
5563
+ self::NAVIGATION_TABS :
5564
+ self::NAVIGATION_MENU
5565
+ );
5566
}
5567
5568
/**
7033
7034
$this->_add_upgrade_action_link();
7035
7036
+ if ( ! ( ! $this->_is_network_active && fs_is_network_admin() ) &&
7037
(
7038
( true === $this->_storage->require_license_activation ) ||
7039
// Not registered nor anonymous.
7043
)
7044
) {
7045
if ( ! $this->is_pending_activation() ) {
7046
+ if ( ! $this->_menu->is_activation_page( $this->show_opt_in_on_themes_page() ) ) {
7047
/**
7048
* If a user visits any other admin page before activating the premium-only theme with a valid
7049
* license, reactivate the previous theme.
7110
}
7111
}
7112
7113
+ if ( $this->show_opt_in_on_themes_page() &&
7114
+ $this->is_activation_page()
7115
) {
7116
$this->_show_theme_activation_optin_dialog();
7117
}
7876
*
7877
* @return array
7878
*/
7879
+ function get_sites_for_network_level_optin() {
7880
$sites = array();
7881
$all_sites = self::get_sites();
7882
9492
* @author Vova Feldman (@svovaf)
9493
* @since 1.0.1
9494
*
9495
+ * @param bool $reparse_plugin_metadata
9496
+ *
9497
* @return array
9498
*/
9499
+ function get_plugin_data( $reparse_plugin_metadata = false ) {
9500
+ if ( ! isset( $this->_plugin_data ) || $reparse_plugin_metadata ) {
9501
self::require_plugin_essentials();
9502
9503
if ( $this->is_plugin() ) {
9602
null;
9603
}
9604
9605
+ /**
9606
+ * @author Vova Feldman (@svovaf)
9607
+ * @since 2.3.1
9608
+ *
9609
+ * @return string|null Bundle public key.
9610
+ */
9611
+ function get_bundle_public_key() {
9612
+ return isset( $this->_plugin->bundle_public_key ) ?
9613
+ $this->_plugin->bundle_public_key :
9614
+ null;
9615
+ }
9616
+
9617
/**
9618
* @author Vova Feldman (@svovaf)
9619
* @since 1.2.1.5
9636
$this->_plugin->id;
9637
}
9638
9639
+ /**
9640
+ * @author Vova Feldman (@svovaf)
9641
+ * @since 2.3.1
9642
+ *
9643
+ * @return string
9644
+ */
9645
+ function get_usage_tracking_terms_url() {
9646
+ return $this->apply_filters(
9647
+ 'usage_tracking_terms_url',
9648
+ "https://freemius.com/wordpress/usage-tracking/{$this->_plugin->id}/{$this->_slug}/"
9649
+ );
9650
+ }
9651
+
9652
+ /**
9653
+ * @author Vova Feldman (@svovaf)
9654
+ * @since 2.3.1
9655
+ *
9656
+ * @return string
9657
+ */
9658
+ function get_eula_url() {
9659
+ return $this->apply_filters(
9660
+ 'eula_url',
9661
+ "https://freemius.com/terms/{$this->_plugin->id}/{$this->_slug}/"
9662
+ );
9663
+ }
9664
+
9665
/**
9666
* @author Vova Feldman (@svovaf)
9667
* @since 1.0.1
9761
* @author Vova Feldman (@svovaf)
9762
* @since 1.0.0
9763
*
9764
+ * @param bool $reparse_plugin_metadata
9765
+ *
9766
* @return string
9767
*/
9768
+ function get_plugin_version( $reparse_plugin_metadata = false ) {
9769
$this->_logger->entrance();
9770
9771
+ $plugin_data = $this->get_plugin_data( $reparse_plugin_metadata );
9772
9773
$this->_logger->departure( 'Version = ' . $plugin_data['Version'] );
9774
9893
* @return array[number]FS_User
9894
*/
9895
static function get_all_users() {
9896
+ $users = self::maybe_get_entities_account_option( 'users', array() );
9897
9898
if ( ! is_array( $users ) ) {
9899
$users = array();
9937
$option_name = $module_type . '_' . $option_name;
9938
}
9939
9940
+ return self::maybe_get_entities_account_option( $option_name, array(), $network_level_or_blog_id );
9941
}
9942
9943
/**
9985
self::$_accounts->set_option( $option_name, $option_value, $store, $network_level_or_blog_id );
9986
}
9987
9988
+ /**
9989
+ * This method can also return non-entity or non-entities collection option like the `user_id_license_ids_map` option.
9990
+ *
9991
+ * @author Leo Fajardo (@leorw)
9992
+ * @since 2.3.1
9993
+ *
9994
+ * @param string $option_name
9995
+ * @param mixed $default
9996
+ * @param null|bool|int $network_level_or_blog_id When an integer, use the given blog storage. When `true` use the multisite storage (if there's a network). When `false`, use the current context blog storage. When `null`, the decision which storage to use (MS vs. Current S) will be handled internally and determined based on the $option (based on self::$_SITE_LEVEL_PARAMS).
9997
+ *
9998
+ * @return mixed|FS_Plugin[]|FS_User[]|FS_Site[]|FS_Plugin_License[]|FS_Plugin_Plan[]|FS_Plugin_Tag[]
9999
+ */
10000
+ private static function maybe_get_entities_account_option( $option_name, $default = null, $network_level_or_blog_id = null ) {
10001
+ $option = self::$_accounts->get_option( $option_name, $default, $network_level_or_blog_id );
10002
+
10003
+ $class_name = '';
10004
+
10005
+ switch ( $option_name ) {
10006
+ case 'plugins':
10007
+ case 'themes':
10008
+ case 'addons':
10009
+ $class_name = FS_Plugin::get_class_name();
10010
+ break;
10011
+ case 'users':
10012
+ $class_name = FS_User::get_class_name();
10013
+ break;
10014
+ case 'sites':
10015
+ $class_name = FS_Site::get_class_name();
10016
+ break;
10017
+ case 'licenses':
10018
+ case 'all_licenses':
10019
+ $class_name = FS_Plugin_License::get_class_name();
10020
+ break;
10021
+ case 'plans':
10022
+ $class_name = FS_Plugin_Plan::get_class_name();
10023
+ break;
10024
+ case 'updates':
10025
+ $class_name = FS_Plugin_Tag::get_class_name();
10026
+ break;
10027
+ }
10028
+
10029
+ if ( empty( $class_name ) ) {
10030
+ return $option;
10031
+ }
10032
+
10033
+ return fs_get_entities( $option, $class_name );
10034
+ }
10035
+
10036
/**
10037
* @author Vova Feldman (@svovaf)
10038
* @since 1.0.6
10216
* @return FS_Plugin_Tag[]
10217
*/
10218
private static function get_all_updates() {
10219
+ $updates = self::maybe_get_entities_account_option( 'updates', array() );
10220
10221
if ( ! is_array( $updates ) ) {
10222
$updates = array();
10232
* @return array<number,FS_Plugin[]>|false
10233
*/
10234
private static function get_all_addons() {
10235
+ $addons = self::maybe_get_entities_account_option( 'addons', array() );
10236
10237
if ( ! is_array( $addons ) ) {
10238
$addons = array();
10245
* @author Vova Feldman (@svovaf)
10246
* @since 1.0.6
10247
*
10248
+ * @return number[]|false
10249
*/
10250
private static function get_all_account_addons() {
10251
$addons = self::$_accounts->get_option( 'account_addons', array() );
10346
* @author Vova Feldman (@svovaf)
10347
* @since 1.0.6
10348
*
10349
+ * @return number[]|false
10350
*/
10351
function get_account_addons() {
10352
$this->_logger->entrance();
10490
10491
if ( ! fs_is_network_admin() ) {
10492
// Get blog-level activated installations.
10493
+ $sites = self::maybe_get_entities_account_option( 'sites', array() );
10494
} else {
10495
$sites = null;
10496
10499
) {
10500
if ( FS_Site::is_valid_id( $addon_storage->network_install_blog_id ) ) {
10501
// Get network-level activated installations.
10502
+ $sites = self::maybe_get_entities_account_option(
10503
'sites',
10504
array(),
10505
$addon_storage->network_install_blog_id
10509
}
10510
10511
$addon_info = array(
10512
+ 'is_connected' => false,
10513
+ 'slug' => $slug,
10514
+ 'title' => $addon->title,
10515
+ 'is_whitelabeled' => $addon_storage->is_whitelabeled
10516
);
10517
10518
if ( ! $is_installed ) {
10558
10559
$addon_info['site'] = $site;
10560
10561
+ $plugins_data = self::maybe_get_entities_account_option( WP_FS__MODULE_TYPE_PLUGIN . 's', array() );
10562
if ( isset( $plugins_data[ $slug ] ) ) {
10563
$plugin_data = $plugins_data[ $slug ];
10564
10565
$addon_info['version'] = $plugin_data->version;
10566
}
10567
10568
+ $all_plans = self::maybe_get_entities_account_option( 'plans', array() );
10569
if ( isset( $all_plans[ $slug ] ) ) {
10570
$plans = $all_plans[ $slug ];
10571
10578
}
10579
}
10580
10581
+ $licenses = self::maybe_get_entities_account_option( 'all_licenses', array() );
10582
if ( is_array( $licenses ) && isset( $licenses[ $addon_id ] ) ) {
10583
foreach ( $licenses[ $addon_id ] as $license ) {
10584
if ( $license->id == $site->license_id ) {
10592
if ( isset( $addon_storage->subscriptions ) &&
10593
! empty( $addon_storage->subscriptions )
10594
) {
10595
+ $addon_subscriptions = fs_get_entities( $addon_storage->subscriptions, FS_Subscription::get_class_name() );
10596
+
10597
+ foreach ( $addon_subscriptions as $subscription ) {
10598
if ( $subscription->license_id == $site->license_id ) {
10599
$addon_info['subscription'] = $subscription;
10600
break;
10685
function is_premium() {
10686
/**
10687
* `$this->_plugin` will be `false` when `is_activation_mode` calls this method directly from the
10688
+ * `register_constructor_hooks` method.
10689
*
10690
* @author Leo Fajardo (@leorw)
10691
* @since 2.2.3
10782
return false;
10783
}
10784
10785
+ if ( ! $this->has_active_valid_license() ) {
10786
+ return false;
10787
+ }
10788
+
10789
+ if ( $this->_site->trial_plan_id != $this->_license->plan_id ) {
10790
+ return false;
10791
+ }
10792
+
10793
+ /**
10794
+ * @var FS_Subscription $subscription
10795
+ */
10796
+ $subscription = $this->_get_subscription( $this->_license->id );
10797
+
10798
+ return ( is_object( $subscription ) && $subscription->is_active() );
10799
}
10800
10801
/**
10930
* @author Vova Feldman (@svovaf)
10931
* @since 1.1.7.3
10932
*
10933
+ * @param bool $including_foreign
10934
+ *
10935
* @return bool
10936
*/
10937
+ function has_any_license( $including_foreign = true ) {
10938
+ if ( ! is_array( $this->_licenses ) || 0 === count( $this->_licenses ) ) {
10939
+ return false;
10940
+ }
10941
+
10942
+ if ( $including_foreign ) {
10943
+ return true;
10944
+ }
10945
+
10946
+ foreach ( $this->_licenses as $license ) {
10947
+ if ( $this->_user->id == $license->user_id ) {
10948
+ return true;
10949
+ }
10950
+ }
10951
+
10952
+ return false;
10953
}
10954
10955
/**
11095
11096
if ( $license instanceof FS_Plugin_License ) {
11097
$this->_licenses[] = $license;
11098
+
11099
+ $this->set_license( $license );
11100
+
11101
$this->_store_licenses();
11102
11103
return $license;
11322
11323
// Update current license.
11324
if ( is_object( $this->_license ) ) {
11325
+ $this->set_license( $this->_get_license_by_id( $this->_license->id ) );
11326
}
11327
11328
return $this->_licenses;
11662
return true;
11663
}
11664
11665
+ /**
11666
+ * Activate a given license on a collection of blogs/sites that are not yet opted-in.
11667
+ *
11668
+ * @author Vova Feldman (@svovaf)
11669
+ * @since 2.3.1
11670
+ *
11671
+ * @param \FS_User $user
11672
+ * @param string $license_key
11673
+ *
11674
+ * @return true|mixed True if successful, otherwise, the API result.
11675
+ */
11676
+ private function activate_license_on_site( FS_User $user, $license_key ) {
11677
+ return $this->activate_license_on_many_sites( $user, $license_key );
11678
+ }
11679
+
11680
/**
11681
* Activate a given license on a collection of blogs/sites that are not yet opted-in.
11682
*
11692
private function activate_license_on_many_sites(
11693
FS_User $user,
11694
$license_key,
11695
+ array $site_ids = array()
11696
) {
11697
$sites = array();
11698
foreach ( $site_ids as $site_id ) {
11716
}
11717
11718
$installs = array();
11719
11720
+ if ( $this->is_api_result_entity( $result ) ) {
11721
+ $install = new FS_Site( $result );
11722
11723
+ $this->_user = $user;
11724
11725
+ $this->_store_site( true, null, $install );
11726
11727
+ $this->_site = $install;
11728
+
11729
+ $this->reset_anonymous_mode();
11730
+ } else {
11731
+ foreach ( $result->installs as $install ) {
11732
+ $installs[] = new FS_Site( $install );
11733
+ }
11734
+
11735
+ // Map site addresses to their blog IDs.
11736
+ $address_to_blog_map = $this->get_address_to_blog_map();
11737
+
11738
+ $first_blog_id = null;
11739
+
11740
+ foreach ( $installs as $install ) {
11741
+ $address = trailingslashit( fs_strip_url_protocol( $install->url ) );
11742
+ $blog_id = $address_to_blog_map[ $address ];
11743
+
11744
+ $this->_store_site( true, $blog_id, $install );
11745
11746
+ $this->reset_anonymous_mode( $blog_id );
11747
11748
+ if ( is_null( $first_blog_id ) ) {
11749
+ $first_blog_id = $blog_id;
11750
+ }
11751
}
11752
11753
+ if ( ! FS_Site::is_valid_id( $this->_storage->network_install_blog_id ) ) {
11754
+ $this->_storage->network_install_blog_id = $first_blog_id;
11755
+ }
11756
}
11757
11758
return true;
11771
function _update_site_license( $new_license ) {
11772
$this->_logger->entrance();
11773
11774
+ $this->set_license( $new_license );
11775
11776
if ( ! is_object( $new_license ) ) {
11777
$this->_site->license_id = null;
11807
}
11808
11809
/**
11810
* @author Vova Feldman (@svovaf)
11811
+ * @since 2.3.1
11812
*
11813
+ * @param \FS_Plugin_License $license
11814
+ */
11815
+ private function set_license( FS_Plugin_License $license = null ) {
11816
+ $this->_license = $license;
11817
+
11818
+ $this->maybe_update_whitelabel_flag( $license );
11819
+ }
11820
+
11821
+ /**
11822
+ * @author Leo Fajardo (@leorw)
11823
+ * @since 2.3.1
11824
*
11825
+ * @param FS_Plugin_License $license
11826
*/
11827
+ private function maybe_update_whitelabel_flag( $license ) {
11828
+ $is_whitelabeled = isset( $this->_storage->is_whitelabeled ) ?
11829
+ $this->_storage->is_whitelabeled :
11830
+ false;
11831
11832
+ if ( is_object( $license ) ) {
11833
+ $license_user = self::_get_user_by_id( $license->user_id );
11834
+
11835
+ if ( ! is_object( $license_user ) ) {
11836
+ // If foreign license, do not update the `is_whitelabeled` flag.
11837
+ return;
11838
+ }
11839
+
11840
+ if ( $this->is_addon() ) {
11841
+ /**
11842
+ * Store the last license data to the parent's storage since it's needed only when showing the
11843
+ * "Start Debug" dialog which is triggered from the "Account" page. This way, there's no need to
11844
+ * iterate over the add-ons just to get the last license data.
11845
+ */
11846
+ $this->get_parent_instance()->store_last_activated_license_data( $license, $license_user );
11847
+ } else {
11848
+ $this->store_last_activated_license_data( $license );
11849
+ }
11850
+
11851
+ if ( $license->is_whitelabeled ) {
11852
+ // Activated a developer license, data should be hidden.
11853
+ $is_whitelabeled = true;
11854
+ } else if ( $this->is_registered() && $this->_user->id == $license->user_id ) {
11855
+ // The account owner activated a regular license key, no need to hide the data.
11856
+ $is_whitelabeled = false;
11857
+ }
11858
+ }
11859
+
11860
+ $this->_storage->is_whitelabeled = $is_whitelabeled;
11861
+
11862
+ // Reset the whitelabeled status after update.
11863
+ $this->is_whitelabeled = null;
11864
+ if ( $this->is_addon() ) {
11865
+ $parent_fs = $this->get_parent_instance();
11866
+
11867
+ if ( is_object( $parent_fs ) ) {
11868
+ $parent_fs->is_whitelabeled = null;
11869
+ }
11870
+ }
11871
+ }
11872
+
11873
+ /**
11874
+ * @author Leo Fajardo (@leorw)
11875
+ * @since 2.3.1
11876
+ *
11877
+ * @param FS_Plugin_License $license
11878
+ * @param FS_User $license_user
11879
+ */
11880
+ private function store_last_activated_license_data( FS_Plugin_License $license, $license_user = null ) {
11881
+ if ( ! is_object( $license_user ) ) {
11882
+ $this->_storage->last_license_key = md5( $license->secret_key );
11883
+ $this->_storage->last_license_user_id = null;
11884
+ } else {
11885
+ $this->_storage->last_license_user_key = md5( $license_user->secret_key );
11886
+ $this->_storage->last_license_user_id = $license_user->id;
11887
+ }
11888
+ }
11889
+
11890
+ /**
11891
+ * @author Leo Fajardo (@leorw)
11892
+ * @since 2.3.1
11893
+ *
11894
+ * @param bool $ignore_data_debug_mode
11895
+ *
11896
+ * @return bool
11897
+ */
11898
+ function is_whitelabeled_by_flag( $ignore_data_debug_mode = false ) {
11899
+ if ( true !== $this->_storage->is_whitelabeled ) {
11900
+ return false;
11901
+ } else if ( $ignore_data_debug_mode ) {
11902
+ return true;
11903
+ }
11904
+
11905
+ $fs = $this->is_addon() ?
11906
+ $this->get_parent_instance() :
11907
+ $this;
11908
+
11909
+ return ! $fs->is_data_debug_mode();
11910
+ }
11911
+
11912
+ /**
11913
+ * @author Leo Fajardo (@leorw)
11914
+ * @since 2.3.1
11915
+ *
11916
+ * @return number
11917
+ */
11918
+ function get_last_license_user_id() {
11919
+ return ( FS_User::is_valid_id( $this->_storage->last_license_user_id ) ) ?
11920
+ $this->_storage->last_license_user_id :
11921
+ null;
11922
+ }
11923
+
11924
+ /**
11925
+ * @author Leo Fajardo (@leorw)
11926
+ * @since 2.3.1
11927
+ *
11928
+ * @param int $blog_id
11929
+ * @param bool $ignore_data_debug_mode
11930
+ *
11931
+ * @return bool
11932
+ */
11933
+ function is_whitelabeled( $ignore_data_debug_mode = false, $blog_id = null ) {
11934
+ if ( ! is_null( $blog_id ) ) {
11935
+ $this->switch_to_blog( $blog_id );
11936
+ }
11937
+
11938
+ if ( ! is_null( $this->is_whitelabeled ) ) {
11939
+ $is_whitelabeled = $this->is_whitelabeled;
11940
+ } else {
11941
+ $is_whitelabeled = false;
11942
+
11943
+ $is_whitelabeled_flag = $this->is_whitelabeled_by_flag( true );
11944
+
11945
+ if ( ! $this->has_addons() ) {
11946
+ $is_whitelabeled = $is_whitelabeled_flag;
11947
+ } else if ( $is_whitelabeled_flag ) {
11948
+ $is_whitelabeled = true;
11949
+ } else {
11950
+ $addon_ids = $this->get_updated_account_addons();
11951
+ $installed_addons = $this->get_installed_addons();
11952
+ foreach ( $installed_addons as $fs_addon ) {
11953
+ $addon_ids[] = $fs_addon->get_id();
11954
+ }
11955
+
11956
+ if ( ! empty( $addon_ids ) ) {
11957
+ $addon_ids = array_unique( $addon_ids );
11958
+
11959
+ $is_network_level = (
11960
+ fs_is_network_admin() &&
11961
+ $this->is_network_active()
11962
+ );
11963
+
11964
+ foreach ( $addon_ids as $addon_id ) {
11965
+ $addon = $this->get_addon( $addon_id );
11966
+
11967
+ if ( ! is_object( $addon ) ) {
11968
+ continue;
11969
+ }
11970
+
11971
+ $addon_storage = FS_Storage::instance( WP_FS__MODULE_TYPE_PLUGIN, $addon->slug );
11972
+ $fs_addon = $this->is_addon_activated( $addon_id ) ?
11973
+ self::get_addon_instance( $addon_id ) :
11974
+ null;
11975
+
11976
+ $was_addon_network_activated = false;
11977
+
11978
+ if ( is_object( $fs_addon ) ) {
11979
+ $was_addon_network_activated = $fs_addon->is_network_active();
11980
+ } else if ( $is_network_level ) {
11981
+ $was_addon_network_activated = $addon_storage->get( 'was_plugin_loaded', false, true );
11982
+ }
11983
+
11984
+ $network_delegated_connection = (
11985
+ $was_addon_network_activated &&
11986
+ $addon_storage->get( 'is_delegated_connection', false, true )
11987
+ );
11988
+
11989
+ if (
11990
+ $is_network_level &&
11991
+ ( ! $was_addon_network_activated || $network_delegated_connection )
11992
+ ) {
11993
+ $sites = self::get_sites();
11994
+
11995
+ /**
11996
+ * If in network admin area and the add-on was not network-activated or network-activated
11997
+ * and network-delegated, find any add-on whose is_whitelabeled flag is true.
11998
+ */
11999
+ foreach ( $sites as $site ) {
12000
+ $site_info = $this->get_site_info( $site );
12001
+
12002
+ if ( $addon_storage->get( 'is_whitelabeled', false, $site_info['blog_id'] ) ) {
12003
+ $is_whitelabeled = true;
12004
+ break;
12005
+ }
12006
+ }
12007
+
12008
+ if ( $is_whitelabeled ) {
12009
+ break;
12010
+ }
12011
+ } else {
12012
+ /**
12013
+ * This will be executed when any of the following is met:
12014
+ * 1. Add-on was network-activated, not network-delegated, and in network admin area.
12015
+ * 2. Add-on was network-activated, network-delegated, and in site admin area.
12016
+ * 3. Add-on was not network-activated and in site admin area.
12017
+ */
12018
+ if ( true === $addon_storage->is_whitelabeled ) {
12019
+ $is_whitelabeled = true;
12020
+ break;
12021
+ }
12022
+ }
12023
+ }
12024
+ }
12025
+ }
12026
+
12027
+ $this->is_whitelabeled = $is_whitelabeled;
12028
+
12029
+ if ( ! $is_whitelabeled || ! $this->is_data_debug_mode() ) {
12030
+ $this->_admin_notices->remove_sticky( 'data_debug_mode_enabled' );
12031
+ }
12032
+
12033
+ if ( ! is_null( $blog_id ) ) {
12034
+ $this->restore_current_blog();
12035
+ }
12036
+ }
12037
+
12038
+ return (
12039
+ $is_whitelabeled &&
12040
+ ( $ignore_data_debug_mode || ! $this->is_data_debug_mode() )
12041
+ );
12042
+ }
12043
+
12044
+ /**
12045
+ * Sync site's subscription.
12046
+ *
12047
+ * @author Vova Feldman (@svovaf)
12048
+ * @since 1.0.9
12049
+ *
12050
+ * @param FS_Plugin_License|null $license
12051
+ *
12052
+ * @return bool|\FS_Subscription
12053
+ */
12054
+ private function _sync_site_subscription( $license ) {
12055
+ if ( ! is_object( $license ) ) {
12056
+ $this->delete_unused_subscriptions();
12057
+
12058
+ return false;
12059
+ }
12060
12061
// Load subscription details if not lifetime.
12062
$subscription = $license->is_lifetime() ?
12098
return null;
12099
}
12100
12101
+ foreach ( fs_get_entities( $this->_storage->subscriptions, FS_Subscription::get_class_name() ) as $subscription ) {
12102
if ( $subscription->license_id == $license_id ) {
12103
return $subscription;
12104
}
12124
return;
12125
}
12126
12127
+ $subscriptions = fs_get_entities( $this->_storage->subscriptions, FS_Subscription::get_class_name() );
12128
12129
$updated_subscription = false;
12130
foreach ( $subscriptions as $key => $existing_subscription ) {
12237
* @author Vova Feldman (@svovaf)
12238
* @since 1.2.1.7
12239
*
12240
+ * @param bool $double_check In some cases developers prefer to release their paid offering as premium-only, even though there is a free version. For those cases, looking at the 'is_premium_only' value isn't enough because the result will return false even when the product has only signle paid plan.
12241
+ *
12242
* @return bool
12243
*/
12244
+ function is_single_plan( $double_check = false ) {
12245
$this->_logger->entrance();
12246
12247
if ( ! $this->is_registered() ||
12251
return true;
12252
}
12253
12254
+ $has_free_plan = $this->has_free_plan();
12255
+
12256
+ if ( ! $has_free_plan && $double_check ) {
12257
+ foreach ( $this->_plans as $plan ) {
12258
+ if ( $plan->is_free() ) {
12259
+ $has_free_plan = true;
12260
+ break;
12261
+ }
12262
+ }
12263
+ }
12264
+
12265
+ return ( 1 === ( count( $this->_plans ) - ( $has_free_plan ? 1 : 0 ) ) );
12266
}
12267
12268
/**
12376
fs_require_template( 'forms/resend-key.php', $vars );
12377
}
12378
12379
+ /**
12380
+ * @author Leo Fajardo (@leorw)
12381
+ * @since 2.3.1
12382
+ */
12383
+ function _add_data_debug_mode_dialog_box() {
12384
+ $vars = array(
12385
+ 'id' => $this->_module_id,
12386
+ );
12387
+
12388
+ fs_require_template( 'forms/data-debug-mode.php', $vars );
12389
+ }
12390
+
12391
/**
12392
* Displays a subscription cancellation dialog box when the user clicks on the "Deactivate License"
12393
* link on the "Account" page or deactivates a plugin and there's an active subscription that is
12406
// Subscription cancellation dialog box is currently not supported for multisite networks.
12407
return array();
12408
}
12409
+
12410
+ if ( $this->is_whitelabeled() ) {
12411
+ return array();
12412
+ }
12413
12414
$license = $this->_get_license();
12415
12497
return;
12498
}
12499
12500
+ if ( $this->has_premium_version() && ! $this->is_premium() ) {
12501
+ // Only add license activation logic to the premium version, or in case of a serviceware plugin, also in the free version.
12502
return;
12503
}
12504
12660
$is_marketing_allowed = null,
12661
$plugin_id = null
12662
) {
12663
+ $this->_logger->entrance();
12664
+
12665
+ $result = $this->activate_license(
12666
$license_key,
12667
$this->is_network_active() ?
12668
$this->get_sites_for_network_level_optin() :
12671
null,
12672
$plugin_id
12673
);
12674
+
12675
+ // No need to show the sticky after license activation notice after migrating a license.
12676
+ $this->_admin_notices->remove_sticky( 'plan_upgraded' );
12677
+
12678
+ return $result;
12679
}
12680
12681
/**
12721
12722
$has_valid_blog_id = is_numeric( $blog_id );
12723
12724
+ $user = null;
12725
+
12726
+ if ( $fs->is_addon() && $fs->get_parent_instance()->is_registered() ) {
12727
+ /**
12728
+ * When activating an add-on's license and the parent is opted-in, activate the license with the parent's opted-in user context.
12729
+ *
12730
+ * @author Vova Feldman (@svovaf)
12731
+ */
12732
+ $user = $fs->get_parent_instance()->get_current_or_network_user();
12733
+ } else if ( $fs->is_registered() ) {
12734
+ $user = $fs->get_current_or_network_user();
12735
+ }
12736
+
12737
+ if ( is_object( $user ) ) {
12738
if ( fs_is_network_admin() && ! $has_valid_blog_id ) {
12739
// If no specific blog ID was provided, activate the license for all sites in the network.
12740
$blog_2_install_map = array();
12745
continue;
12746
}
12747
12748
+ $install = $fs->get_install_by_blog_id( $site['blog_id'] );
12749
12750
if ( is_object( $install ) ) {
12751
$blog_2_install_map[ $site['blog_id'] ] = $install;
12754
}
12755
}
12756
12757
if ( ! empty( $blog_2_install_map ) ) {
12758
+ $result = $fs->activate_license_on_many_installs( $user, $license_key, $blog_2_install_map );
12759
12760
if ( true !== $result ) {
12761
$error = FS_Api::is_api_error_object( $result ) ?
12765
}
12766
12767
if ( empty( $error ) && ! empty( $site_ids ) ) {
12768
+ $result = $fs->activate_license_on_many_sites( $user, $license_key, $site_ids );
12769
12770
if ( true !== $result ) {
12771
$error = FS_Api::is_api_error_object( $result ) ?
12781
*
12782
* @author Leo Fajardo (@leorw)
12783
*/
12784
+ $fs->switch_to_blog( $blog_id );
12785
}
12786
12787
+ if ( $fs->is_registered() ) {
12788
+ $params = array(
12789
+ 'license_key' => $fs->apply_filters( 'license_key', $license_key )
12790
+ );
12791
12792
+ $api = $fs->get_api_site_scope();
12793
12794
+ $install = $api->call( $fs->add_show_pending( '/' ), 'put', $params );
12795
12796
+ if ( FS_Api::is_api_error( $install ) ) {
12797
+ $error = FS_Api::is_api_error_object( $install ) ?
12798
+ $install->error->message :
12799
+ var_export( $install->error, true );
12800
+ } else {
12801
+ $fs->reconnect_locally( $has_valid_blog_id );
12802
+ }
12803
+ } else /* ( $fs->is_addon() && $fs->get_parent_instance()->is_registered() ) */ {
12804
+ $result = $fs->activate_license_on_site( $user, $license_key );
12805
+
12806
+ if ( true !== $result ) {
12807
+ $error = FS_Api::is_api_error_object( $result ) ?
12808
+ $result->error->message :
12809
+ var_export( $result, true );
12810
+ }
12811
}
12812
}
12813
12814
if ( empty( $error ) ) {
12815
+ $fs->network_upgrade_mode_completed();
12816
12817
$fs->_sync_license( true, $has_valid_blog_id );
12818
12864
continue;
12865
}
12866
12867
+ if ( $fs->is_installed_on_site( $blog_id ) ) {
12868
// Site was already connected before.
12869
continue;
12870
}
12871
12872
+ if ( $fs->is_site_delegated_connection( $blog_id ) ) {
12873
// Site's connection was delegated.
12874
continue;
12875
}
12876
12877
+ if ( $fs->is_anonymous_site( $blog_id ) ) {
12878
// Site connection was already skipped.
12879
continue;
12880
}
12883
}
12884
12885
if ( ! empty( $pending_sites ) ) {
12886
+ if ( $fs->is_freemium() && $fs->is_enable_anonymous() ) {
12887
+ $fs->skip_connection( $pending_sites );
12888
} else {
12889
+ $fs->delegate_connection( $pending_sites );
12890
}
12891
}
12892
}
12893
}
12894
}
12895
12896
+ if ( false === $error && true === $fs->_storage->require_license_activation ) {
12897
+ $fs->_storage->require_license_activation = false;
12898
}
12899
12900
$result = array(
12902
);
12903
12904
if ( false !== $error ) {
12905
+ $result['error'] = $fs->apply_filters( 'opt_in_error_message', $error );
12906
} else {
12907
+ if ( $fs->is_addon() || $fs->has_addons() ) {
12908
/**
12909
* Purge the valid user licenses cache so that when the "Account" or the "Add-Ons" page is loaded,
12910
* an updated valid user licenses collection will be fetched from the server which is used to also
12913
* @author Leo Fajardo (@leorw)
12914
* @since 2.2.4
12915
*/
12916
+ $fs->purge_valid_user_licenses_cache();
12917
}
12918
12919
$result['next_page'] = $next_page;
13948
$page_param = $this->_menu->get_slug( $page );
13949
13950
if ( empty( $page ) &&
13951
// Show the opt-in as an overlay for free wp.org themes or themes without any settings page.
13952
+ $this->show_opt_in_on_themes_page()
13953
) {
13954
$params[ $this->get_unique_affix() . '_show_optin' ] = 'true';
13955
14379
*
14380
* @param int $blog_id
14381
* @param FS_Site $install
14382
+ *
14383
+ * @return bool Since 2.3.1 returns if a switch was made.
14384
*/
14385
function switch_to_blog( $blog_id, FS_Site $install = null ) {
14386
if ( $blog_id == $this->_context_is_network_or_blog_id ) {
14387
+ return false;
14388
}
14389
14390
switch_to_blog( $blog_id );
14398
$install :
14399
$this->get_install_by_blog_id( $blog_id );
14400
14401
+ $this->_user = false;
14402
+ $this->_licenses = false;
14403
+ $this->_license = null;
14404
+ $this->is_whitelabeled = null;
14405
14406
if ( is_object( $this->_site ) ) {
14407
// Try to fetch user from install.
14446
14447
unset( $this->_site_api );
14448
unset( $this->_user_api );
14449
+
14450
+ return false;
14451
}
14452
14453
/**
14893
return ( $this->_menu->get_slug( $page ) === fs_request_get( 'page', '', 'get' ) );
14894
}
14895
14896
+ /**
14897
+ * Check if currently in the product's main admin page.
14898
+ *
14899
+ * @author Vova Feldman (@svovaf)
14900
+ * @since 2.3.1
14901
+ *
14902
+ * @return bool
14903
+ */
14904
+ function is_main_admin_page() {
14905
+ return $this->is_admin_page( '' );
14906
+ }
14907
+
14908
/**
14909
* Get module's main admin setting page URL.
14910
*
14925
* @since 1.2.2.7
14926
*
14927
* @return bool
14928
+ *
14929
+ * @deprecated Please use is_product_settings_page() instead;
14930
*/
14931
function is_theme_settings_page() {
14932
+ return $this->is_product_settings_page();
14933
+ }
14934
+
14935
+ /**
14936
+ * Check if currently on the product's main setting page or on any of the Freemius added pages (via tabs).
14937
+ *