Google Maps Plugin by Intergeo - Version 1.0.6

Version Description

  • improved the usability of the builder, markers are added now in a more intuitive way.
Download this release

Release Info

Developer codeinwp
Plugin Icon 128x128 Google Maps Plugin by Intergeo
Version 1.0.6
Comparing to
See all releases

Code changes from version 1.0.5 to 1.0.6

Files changed (37) hide show
  1. css/editor.css +8 -0
  2. freemius/README.md +5 -0
  3. freemius/assets/css/admin/add-ons.css +2 -2
  4. freemius/assets/css/admin/common.css +1 -1
  5. freemius/assets/css/admin/connect.css +1 -1
  6. freemius/assets/scss/admin/add-ons.scss +218 -102
  7. freemius/assets/scss/admin/common.scss +2 -2
  8. freemius/assets/scss/admin/connect.scss +50 -0
  9. freemius/config.php +11 -1
  10. freemius/includes/class-freemius-abstract.php +50 -0
  11. freemius/includes/class-freemius.php +919 -69
  12. freemius/includes/class-fs-api.php +8 -6
  13. freemius/includes/class-fs-plugin-updater.php +32 -26
  14. freemius/includes/debug/class-fs-debug-bar-panel.php +2 -0
  15. freemius/includes/entities/class-fs-plugin-license.php +13 -1
  16. freemius/includes/entities/class-fs-pricing.php +91 -0
  17. freemius/includes/fs-core-functions.php +13 -1
  18. freemius/includes/fs-plugin-info-dialog.php +303 -173
  19. freemius/includes/i18n.php +43 -2
  20. freemius/includes/managers/class-fs-admin-menu-manager.php +4 -4
  21. freemius/includes/managers/class-fs-admin-notice-manager.php +8 -1
  22. freemius/includes/managers/class-fs-option-manager.php +5 -0
  23. freemius/includes/sdk/Freemius.php +4 -2
  24. freemius/includes/sdk/FreemiusBase.php +1 -1
  25. freemius/start.php +8 -1
  26. freemius/templates/account.php +551 -544
  27. freemius/templates/add-ons.php +29 -10
  28. freemius/templates/connect.php +150 -17
  29. freemius/templates/deactivation-feedback-modal.php +217 -136
  30. freemius/templates/plugin-icon.php +4 -4
  31. index.php +7 -4
  32. js/editor.js +119 -14
  33. js/jquery.ddslick.min.js +1 -0
  34. readme.txt +4 -0
  35. templates/iframe/form.php +3 -3
  36. templates/iframe/overlays.php +18 -21
  37. templates/iframe/popups.php +18 -6
css/editor.css CHANGED
@@ -66,4 +66,12 @@
66
 
67
  .computer-btn{
68
  text-shadow: none !important;
 
 
 
 
 
 
 
 
69
  }
66
 
67
  .computer-btn{
68
  text-shadow: none !important;
69
+ }
70
+
71
+ table.intergeo_tlbr_marker_add input[type="button"] {
72
+ float: right;
73
+ }
74
+
75
+ table.intergeo_tlbr_marker_add input[type="button"]::after {
76
+ clear: both;
77
  }
freemius/README.md CHANGED
@@ -10,6 +10,11 @@ http://bit.ly/freemius-beta
10
 
11
  **Below you'll find the integration instructions for our WordPress SDK.**
12
 
 
 
 
 
 
13
  ## Initializing the SDK
14
 
15
  Copy the code below and paste it into the top of your main plugin's PHP file, right after the plugin's header comment:
10
 
11
  **Below you'll find the integration instructions for our WordPress SDK.**
12
 
13
+ ## Code Documentation
14
+
15
+ You can find the SDK's PHP-Doc documentation here:
16
+ https://codedoc.pub/freemius/wordpress-sdk/master/
17
+
18
  ## Initializing the SDK
19
 
20
  Copy the code below and paste it into the top of your main plugin's PHP file, right after the plugin's header comment:
freemius/assets/css/admin/add-ons.css CHANGED
@@ -1,2 +1,2 @@
1
- #fs_addons .fs-cards-list{list-style:none}#fs_addons .fs-cards-list .fs-card{float:left;height:152px;width:310px;padding:0;margin:0 0 30px 30px;font-size:14px;list-style:none;border:1px solid #ddd;cursor:pointer;position:relative}#fs_addons .fs-cards-list .fs-card .fs-overlay{position:absolute;left:0;right:0;bottom:0;top:0;z-index:9}#fs_addons .fs-cards-list .fs-card .fs-inner{background-color:#fff;overflow:hidden;height:100%;position:relative}#fs_addons .fs-cards-list .fs-card .fs-inner ul{-moz-transition:all,0.15s;-o-transition:all,0.15s;-ms-transition:all,0.15s;-webkit-transition:all,0.15s;transition:all,0.15s;left:0;right:0;top:0;position:absolute}#fs_addons .fs-cards-list .fs-card .fs-inner li{list-style:none;line-height:18px;padding:0 15px;width:100%;display:block;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-card-banner{padding:0;margin:0;line-height:0;display:block;height:100px;background-repeat:repeat-x;background-size:100% 100%;-moz-transition:all,0.15s;-o-transition:all,0.15s;-ms-transition:all,0.15s;-webkit-transition:all,0.15s;transition:all,0.15s}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-title{margin:10px 0 0 0;height:18px;overflow:hidden;color:#000;white-space:nowrap;text-overflow:ellipsis;font-weight:bold}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-offer{font-size:0.9em}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-description{background-color:#f9f9f9;padding:10px 15px 100px 15px;border-top:1px solid #eee;margin:0 0 10px 0;color:#777}@media screen and (min-width: 960px){#fs_addons .fs-cards-list .fs-card:hover .fs-overlay{border:2px solid #29abe1;margin-left:-1px;margin-top:-1px}#fs_addons .fs-cards-list .fs-card:hover .fs-inner ul{top:-100px}#fs_addons .fs-cards-list .fs-card:hover .fs-inner .fs-title,#fs_addons .fs-cards-list .fs-card:hover .fs-inner .fs-offer{color:#29abe1}}
2
- #TB_window,#TB_window iframe{width:772px !important}#plugin-information #section-description h2,#plugin-information #section-description h3,#plugin-information #section-description p,#plugin-information #section-description b,#plugin-information #section-description i,#plugin-information #section-description blockquote,#plugin-information #section-description li,#plugin-information #section-description ul,#plugin-information #section-description ol{clear:none}#plugin-information #section-description .fs-selling-points{padding-bottom:10px;border-bottom:1px solid #ddd}#plugin-information #section-description .fs-selling-points ul{margin:0}#plugin-information #section-description .fs-selling-points ul li{padding:0;list-style:none outside none}#plugin-information #section-description .fs-selling-points ul li i.dashicons{color:#71ae00;font-size:3em;vertical-align:middle;line-height:30px;float:left;margin:0 0 0 -15px}#plugin-information #section-description .fs-selling-points ul li h3{margin:1em 30px !important}#plugin-information #section-description .fs-screenshots:after{content:"";display:table;clear:both}#plugin-information #section-description .fs-screenshots ul{list-style:none;margin:0}#plugin-information #section-description .fs-screenshots ul li{width:225px;height:225px;float:left;margin-bottom:20px;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}#plugin-information #section-description .fs-screenshots ul li a{display:block;width:100%;height:100%;border:1px solid;-moz-box-shadow:1px 1px 1px rgba(0,0,0,0.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,0.2);box-shadow:1px 1px 1px rgba(0,0,0,0.2);background-size:cover}#plugin-information #section-description .fs-screenshots ul li.odd{margin-right:20px}#plugin-information .plugin-information-pricing{background:#FFFEEC;margin:-16px;padding:20px;border-bottom:1px solid #DDD}#plugin-information .plugin-information-pricing h3{margin-top:0}#plugin-information .plugin-information-pricing .button{width:100%;text-align:center;font-weight:bold;text-transform:uppercase;font-size:1.1em}#plugin-information .plugin-information-pricing label{white-space:nowrap}#plugin-information .plugin-information-pricing ul.fs-trial-terms{font-size:0.9em}#plugin-information .plugin-information-pricing ul.fs-trial-terms i{float:left;margin:0 0 0 -15px}#plugin-information .plugin-information-pricing ul.fs-trial-terms li{margin:10px 0 0 0}#plugin-information #section-features .fs-features{margin:-20px -26px}#plugin-information #section-features table{width:100%;border-spacing:0;border-collapse:separate}#plugin-information #section-features table thead th{padding:10px 0}#plugin-information #section-features table thead .fs-price{color:#71ae00;font-weight:normal;display:block;text-align:center}#plugin-information #section-features table tbody td{border-top:1px solid #ccc;padding:10px 0;text-align:center;width:100px;color:#71ae00}#plugin-information #section-features table tbody td:first-child{text-align:left;width:auto;color:inherit;padding-left:26px}#plugin-information #section-features table tbody tr.fs-odd td{background:#fefefe}#plugin-information #section-features .dashicons-yes{width:30px;height:30px;font-size:30px}@media screen and (max-width: 961px){#fs_addons .fs-cards-list .fs-card{height:265px}}
1
+ #fs_addons .fs-cards-list{list-style:none}#fs_addons .fs-cards-list .fs-card{float:left;height:152px;width:310px;padding:0;margin:0 0 30px 30px;font-size:14px;list-style:none;border:1px solid #ddd;cursor:pointer;position:relative}#fs_addons .fs-cards-list .fs-card .fs-overlay{position:absolute;left:0;right:0;bottom:0;top:0;z-index:9}#fs_addons .fs-cards-list .fs-card .fs-inner{background-color:#fff;overflow:hidden;height:100%;position:relative}#fs_addons .fs-cards-list .fs-card .fs-inner ul{-moz-transition:all,0.15s;-o-transition:all,0.15s;-ms-transition:all,0.15s;-webkit-transition:all,0.15s;transition:all,0.15s;left:0;right:0;top:0;position:absolute}#fs_addons .fs-cards-list .fs-card .fs-inner li{list-style:none;line-height:18px;padding:0 15px;width:100%;display:block;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-card-banner{padding:0;margin:0;line-height:0;display:block;height:100px;background-repeat:repeat-x;background-size:100% 100%;-moz-transition:all,0.15s;-o-transition:all,0.15s;-ms-transition:all,0.15s;-webkit-transition:all,0.15s;transition:all,0.15s}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-title{margin:10px 0 0 0;height:18px;overflow:hidden;color:#000;white-space:nowrap;text-overflow:ellipsis;font-weight:bold}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-offer{font-size:0.9em}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-description{background-color:#f9f9f9;padding:10px 15px 100px 15px;border-top:1px solid #eee;margin:0 0 10px 0;color:#777}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-tag{position:absolute;top:10px;right:0px;background:greenyellow;display:block;padding:2px 10px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,0.3);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,0.3);box-shadow:1px 1px 1px rgba(0,0,0,0.3);text-transform:uppercase;font-size:0.9em;font-weight:bold}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-cta .button{position:absolute;top:112px;right:10px}@media screen and (min-width: 960px){#fs_addons .fs-cards-list .fs-card:hover .fs-overlay{border:2px solid #29abe1;margin-left:-1px;margin-top:-1px}#fs_addons .fs-cards-list .fs-card:hover .fs-inner ul{top:-100px}#fs_addons .fs-cards-list .fs-card:hover .fs-inner .fs-title,#fs_addons .fs-cards-list .fs-card:hover .fs-inner .fs-offer{color:#29abe1}}
2
+ #TB_window,#TB_window iframe{width:772px !important}#plugin-information #section-description h2,#plugin-information #section-description h3,#plugin-information #section-description p,#plugin-information #section-description b,#plugin-information #section-description i,#plugin-information #section-description blockquote,#plugin-information #section-description li,#plugin-information #section-description ul,#plugin-information #section-description ol{clear:none}#plugin-information #section-description .fs-selling-points{padding-bottom:10px;border-bottom:1px solid #ddd}#plugin-information #section-description .fs-selling-points ul{margin:0}#plugin-information #section-description .fs-selling-points ul li{padding:0;list-style:none outside none}#plugin-information #section-description .fs-selling-points ul li i.dashicons{color:#71ae00;font-size:3em;vertical-align:middle;line-height:30px;float:left;margin:0 0 0 -15px}#plugin-information #section-description .fs-selling-points ul li h3{margin:1em 30px !important}#plugin-information #section-description .fs-screenshots:after{content:"";display:table;clear:both}#plugin-information #section-description .fs-screenshots ul{list-style:none;margin:0}#plugin-information #section-description .fs-screenshots ul li{width:225px;height:225px;float:left;margin-bottom:20px;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}#plugin-information #section-description .fs-screenshots ul li a{display:block;width:100%;height:100%;border:1px solid;-moz-box-shadow:1px 1px 1px rgba(0,0,0,0.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,0.2);box-shadow:1px 1px 1px rgba(0,0,0,0.2);background-size:cover}#plugin-information #section-description .fs-screenshots ul li.odd{margin-right:20px}#plugin-information .plugin-information-pricing{margin:-16px;border-bottom:1px solid #ddd}#plugin-information .plugin-information-pricing .fs-plan h3{margin-top:0;padding:20px;font-size:16px}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper{border-bottom:1px solid #ddd}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab{cursor:pointer;position:relative;padding:0 10px;font-size:0.9em}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab label{text-transform:uppercase;color:green;background:greenyellow;position:absolute;left:-1px;right:-1px;bottom:100%;border:1px solid darkgreen;padding:2px;text-align:center;font-size:0.9em;line-height:1em}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab.nav-tab-active{cursor:default;background:#fffeec;border-bottom-color:#fffeec}#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle h3{background:#fffeec;margin:0;padding-bottom:0;color:#0073aa}#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle .nav-tab-wrapper,#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle .fs-billing-frequency{display:none}#plugin-information .plugin-information-pricing .fs-plan .fs-pricing-body{background:#fffeec;padding:20px}#plugin-information .plugin-information-pricing .fs-plan .button{width:100%;text-align:center;font-weight:bold;text-transform:uppercase;font-size:1.1em}#plugin-information .plugin-information-pricing .fs-plan label{white-space:nowrap}#plugin-information .plugin-information-pricing .fs-plan var{font-style:normal}#plugin-information .plugin-information-pricing .fs-plan .fs-billing-frequency,#plugin-information .plugin-information-pricing .fs-plan .fs-annual-discount{text-align:center;display:block;font-weight:bold;margin-bottom:10px;text-transform:uppercase;background:#F3F3F3;padding:2px;border:1px solid #ccc}#plugin-information .plugin-information-pricing .fs-plan .fs-annual-discount{text-transform:none;color:green;background:greenyellow}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms{font-size:0.9em}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms i{float:left;margin:0 0 0 -15px}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms li{margin:10px 0 0 0}#plugin-information #section-features .fs-features{margin:-20px -26px}#plugin-information #section-features table{width:100%;border-spacing:0;border-collapse:separate}#plugin-information #section-features table thead th{padding:10px 0}#plugin-information #section-features table thead .fs-price{color:#71ae00;font-weight:normal;display:block;text-align:center}#plugin-information #section-features table tbody td{border-top:1px solid #ccc;padding:10px 0;text-align:center;width:100px;color:#71ae00}#plugin-information #section-features table tbody td:first-child{text-align:left;width:auto;color:inherit;padding-left:26px}#plugin-information #section-features table tbody tr.fs-odd td{background:#fefefe}#plugin-information #section-features .dashicons-yes{width:30px;height:30px;font-size:30px}@media screen and (max-width: 961px){#fs_addons .fs-cards-list .fs-card{height:265px}}
freemius/assets/css/admin/common.css CHANGED
@@ -1 +1 @@
1
- .fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px !important}.fs-notice.success{color:green}.fs-notice.promotion{border-color:#00a0d2 !important;background-color:#f2fcff !important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-close{cursor:pointer;color:#aaa;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{margin-top:7px;display:inline-block}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,0.3);color:#fff;padding:2px 10px;position:absolute;bottom:-22px;top:auto;right:auto;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;left:10px;font-size:12px;font-weight:bold;cursor:auto}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{position:fixed;top:32px;left:160px;right:0;background:#ebfdeb;padding:10px 20px;color:green;z-index:9999;box-shadow:0px 2px 2px rgba(6,113,6,0.3);opacity:0.95;filter:alpha(opacity=95)}.fs-secure-notice:hover{opacity:1;filter:alpha(opacity=100)}@media screen and (max-width: 960px){.fs-secure-notice{left:36px}}@media screen and (max-width: 782px){.fs-secure-notice{left:0;top:46px;text-align:center}}span.fs-submenu-item.fs-sub:before{content:'\21B3';padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:'\21B2'}
1
+ .fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px !important}.fs-notice.success{color:green}.fs-notice.promotion{border-color:#00a0d2 !important;background-color:#f2fcff !important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-close{cursor:pointer;color:#aaa;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{margin-top:7px;display:inline-block}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,0.3);color:#fff;padding:2px 10px;position:absolute;top:100%;bottom:auto;right:auto;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;left:10px;font-size:12px;font-weight:bold;cursor:auto}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{position:fixed;top:32px;left:160px;right:0;background:#ebfdeb;padding:10px 20px;color:green;z-index:9999;box-shadow:0px 2px 2px rgba(6,113,6,0.3);opacity:0.95;filter:alpha(opacity=95)}.fs-secure-notice:hover{opacity:1;filter:alpha(opacity=100)}@media screen and (max-width: 960px){.fs-secure-notice{left:36px}}@media screen and (max-width: 782px){.fs-secure-notice{left:0;top:46px;text-align:center}}span.fs-submenu-item.fs-sub:before{content:'\21B3';padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:'\21B2'}
freemius/assets/css/admin/connect.css CHANGED
@@ -1 +1 @@
1
- #fs_connect{width:480px;-moz-box-shadow:0px 1px 2px rgba(0,0,0,0.3);-webkit-box-shadow:0px 1px 2px rgba(0,0,0,0.3);box-shadow:0px 1px 2px rgba(0,0,0,0.3);margin:20px 0}@media screen and (max-width: 479px){#fs_connect{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none;width:auto;margin:0 0 0 -10px}}#fs_connect .fs-content{background:#fff;padding:15px 20px}#fs_connect .fs-content p{margin:0;padding:0;font-size:1.2em}#fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}#fs_connect .fs-actions .button{padding:0 10px 1px;line-height:35px;height:37px;font-size:16px;margin-bottom:0}#fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}#fs_connect .fs-actions .button.button-primary{padding-right:15px;padding-left:15px}#fs_connect .fs-actions .button.button-primary:after{content:' \279C'}#fs_connect .fs-actions .button.button-primary.fs-loading:after{content:''}#fs_connect .fs-actions .button.button-secondary{float:right}#fs_connect.fs-anonymous-disabled .fs-actions .button.button-primary{width:100%}#fs_connect .fs-permissions{padding:10px 20px;background:#FEFEFE;-moz-transition:background 0.5s ease;-o-transition:background 0.5s ease;-ms-transition:background 0.5s ease;-webkit-transition:background 0.5s ease;transition:background 0.5s ease}#fs_connect .fs-permissions .fs-trigger{font-size:0.9em;text-decoration:none;text-align:center;display:block}#fs_connect .fs-permissions ul{height:0;overflow:hidden;margin:0}#fs_connect .fs-permissions ul li{margin-bottom:12px}#fs_connect .fs-permissions ul li:last-child{margin-bottom:0}#fs_connect .fs-permissions ul li i.dashicons{float:left;font-size:40px;width:40px;height:40px}#fs_connect .fs-permissions ul li div{margin-left:55px}#fs_connect .fs-permissions ul li div span{font-weight:bold;text-transform:uppercase;color:#23282d}#fs_connect .fs-permissions ul li div p{margin:2px 0 0 0}#fs_connect .fs-permissions.fs-open{background:#fff}#fs_connect .fs-permissions.fs-open ul{height:auto;margin:20px 20px 10px 20px}@media screen and (max-width: 479px){#fs_connect .fs-permissions{background:#fff}#fs_connect .fs-permissions .fs-trigger{display:none}#fs_connect .fs-permissions ul{height:auto;margin:20px}}#fs_connect .fs-visual{padding:12px;line-height:0;background:#fafafa;height:80px;position:relative}#fs_connect .fs-visual .fs-site-icon{position:absolute;left:20px;top:10px}#fs_connect .fs-visual .fs-connect-logo{position:absolute;right:20px;top:10px}#fs_connect .fs-visual .fs-plugin-icon{position:absolute;top:10px;left:50%;margin-left:-40px}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-site-icon,#fs_connect .fs-visual img,#fs_connect .fs-visual object{width:80px;height:80px}#fs_connect .fs-visual .dashicons-wordpress{font-size:64px;background:#01749a;color:#fff;width:64px;height:64px;padding:8px}#fs_connect .fs-visual .dashicons-plus{position:absolute;top:50%;font-size:30px;margin-top:-10px;color:#bbb}#fs_connect .fs-visual .dashicons-plus.fs-first{left:28%}#fs_connect .fs-visual .dashicons-plus.fs-second{left:65%}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-connect-logo,#fs_connect .fs-visual .fs-site-icon{border:1px solid #ccc;padding:1px;background:#fff}#fs_connect .fs-terms{text-align:center;font-size:0.85em;padding:5px;background:rgba(0,0,0,0.05)}#fs_connect .fs-terms,#fs_connect .fs-terms a{color:#999}#fs_connect .fs-terms a{text-decoration:none}.rtl #fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}.rtl #fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}.rtl #fs_connect .fs-actions .button.button-primary:after{content:' \000bb'}.rtl #fs_connect .fs-actions .button.button-primary.fs-loading:after{content:''}.rtl #fs_connect .fs-actions .button.button-secondary{float:left}.rtl #fs_connect .fs-permissions ul li div{margin-right:55px;margin-left:0}.rtl #fs_connect .fs-permissions ul li i.dashicons{float:right}.rtl #fs_connect .fs-visual .fs-site-icon{right:20px;left:auto}.rtl #fs_connect .fs-visual .fs-connect-logo{right:auto;left:20px}.wp-pointer-content #fs_connect{margin:0;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.fs-opt-in-pointer .wp-pointer-content{padding:0}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow{border-bottom-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#fafafa}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow{border-top-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow-inner{border-top-color:#fafafa}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow{border-right-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow-inner{border-right-color:#fafafa}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow{border-left-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow-inner{border-left-color:#fafafa}
1
+ #fs_connect{width:480px;-moz-box-shadow:0px 1px 2px rgba(0,0,0,0.3);-webkit-box-shadow:0px 1px 2px rgba(0,0,0,0.3);box-shadow:0px 1px 2px rgba(0,0,0,0.3);margin:20px 0}@media screen and (max-width: 479px){#fs_connect{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none;width:auto;margin:0 0 0 -10px}}#fs_connect .fs-content{background:#fff;padding:15px 20px}#fs_connect .fs-content .fs-error{background:snow;color:#d3135a;border:1px solid #d3135a;-moz-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);text-align:center;padding:5px;margin-bottom:10px}#fs_connect .fs-content p{margin:0;padding:0;font-size:1.2em}#fs_connect .fs-license-key-container{position:relative;width:280px;margin:10px auto 0 auto}#fs_connect .fs-license-key-container input{width:100%}#fs_connect .fs-license-key-container .dashicons{position:absolute;top:5px;right:5px}#fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}#fs_connect .fs-actions .button{padding:0 10px 1px;line-height:35px;height:37px;font-size:16px;margin-bottom:0}#fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}#fs_connect .fs-actions .button.button-primary{padding-right:15px;padding-left:15px}#fs_connect .fs-actions .button.button-primary:after{content:' \279C'}#fs_connect .fs-actions .button.button-primary.fs-loading:after{content:''}#fs_connect .fs-actions .button.button-secondary{float:right}#fs_connect.fs-anonymous-disabled .fs-actions .button.button-primary{width:100%}#fs_connect .fs-permissions{padding:10px 20px;background:#FEFEFE;-moz-transition:background 0.5s ease;-o-transition:background 0.5s ease;-ms-transition:background 0.5s ease;-webkit-transition:background 0.5s ease;transition:background 0.5s ease}#fs_connect .fs-permissions .fs-license-sync-disclaimer{text-align:center;margin-top:0}#fs_connect .fs-permissions .fs-trigger{font-size:0.9em;text-decoration:none;text-align:center;display:block}#fs_connect .fs-permissions ul{height:0;overflow:hidden;margin:0}#fs_connect .fs-permissions ul li{margin-bottom:12px}#fs_connect .fs-permissions ul li:last-child{margin-bottom:0}#fs_connect .fs-permissions ul li i.dashicons{float:left;font-size:40px;width:40px;height:40px}#fs_connect .fs-permissions ul li div{margin-left:55px}#fs_connect .fs-permissions ul li div span{font-weight:bold;text-transform:uppercase;color:#23282d}#fs_connect .fs-permissions ul li div p{margin:2px 0 0 0}#fs_connect .fs-permissions.fs-open{background:#fff}#fs_connect .fs-permissions.fs-open ul{height:auto;margin:20px 20px 10px 20px}@media screen and (max-width: 479px){#fs_connect .fs-permissions{background:#fff}#fs_connect .fs-permissions .fs-trigger{display:none}#fs_connect .fs-permissions ul{height:auto;margin:20px}}#fs_connect .fs-freemium-licensing{padding:8px;background:#777;color:#fff}#fs_connect .fs-freemium-licensing p{text-align:center;display:block;margin:0;padding:0}#fs_connect .fs-freemium-licensing a{color:#C2EEFF;text-decoration:underline}#fs_connect .fs-visual{padding:12px;line-height:0;background:#fafafa;height:80px;position:relative}#fs_connect .fs-visual .fs-site-icon{position:absolute;left:20px;top:10px}#fs_connect .fs-visual .fs-connect-logo{position:absolute;right:20px;top:10px}#fs_connect .fs-visual .fs-plugin-icon{position:absolute;top:10px;left:50%;margin-left:-40px}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-site-icon,#fs_connect .fs-visual img,#fs_connect .fs-visual object{width:80px;height:80px}#fs_connect .fs-visual .dashicons-wordpress{font-size:64px;background:#01749a;color:#fff;width:64px;height:64px;padding:8px}#fs_connect .fs-visual .dashicons-plus{position:absolute;top:50%;font-size:30px;margin-top:-10px;color:#bbb}#fs_connect .fs-visual .dashicons-plus.fs-first{left:28%}#fs_connect .fs-visual .dashicons-plus.fs-second{left:65%}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-connect-logo,#fs_connect .fs-visual .fs-site-icon{border:1px solid #ccc;padding:1px;background:#fff}#fs_connect .fs-terms{text-align:center;font-size:0.85em;padding:5px;background:rgba(0,0,0,0.05)}#fs_connect .fs-terms,#fs_connect .fs-terms a{color:#999}#fs_connect .fs-terms a{text-decoration:none}.rtl #fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}.rtl #fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}.rtl #fs_connect .fs-actions .button.button-primary:after{content:' \000bb'}.rtl #fs_connect .fs-actions .button.button-primary.fs-loading:after{content:''}.rtl #fs_connect .fs-actions .button.button-secondary{float:left}.rtl #fs_connect .fs-permissions ul li div{margin-right:55px;margin-left:0}.rtl #fs_connect .fs-permissions ul li i.dashicons{float:right}.rtl #fs_connect .fs-visual .fs-site-icon{right:20px;left:auto}.rtl #fs_connect .fs-visual .fs-connect-logo{right:auto;left:20px}.wp-pointer-content #fs_connect{margin:0;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.fs-opt-in-pointer .wp-pointer-content{padding:0}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow{border-bottom-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#fafafa}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow{border-top-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow-inner{border-top-color:#fafafa}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow{border-right-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow-inner{border-right-color:#fafafa}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow{border-left-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow-inner{border-left-color:#fafafa}
freemius/assets/scss/admin/add-ons.scss CHANGED
@@ -8,76 +8,75 @@
8
 
9
  .fs-card
10
  {
11
- float: left;
12
- // height: 185px; // With reviews/ratings
13
- height: 152px;
14
- width: 310px;
15
- padding: 0;
16
- margin: 0 0 30px 30px;
17
- font-size: 14px;
18
  list-style: none;
19
- border: 1px solid #ddd;
20
- cursor: pointer;
21
- position: relative;
22
 
23
  .fs-overlay
24
  {
25
  position: absolute;
26
- left: 0;
27
- right: 0;
28
- bottom: 0;
29
- top: 0;
30
- z-index: 9;
31
  }
32
 
33
  .fs-inner
34
  {
35
  background-color: #fff;
36
- overflow: hidden;
37
- height: 100%;
38
- position: relative;
39
 
40
  ul
41
  {
42
  @include transition(all, 0.15s);
43
- left: 0;
44
- right: 0;
45
- top: 0;
46
  position: absolute;
47
-
48
  }
49
 
50
  li
51
  {
52
- list-style: none;
53
  line-height: 18px;
54
- padding: 0 15px;
55
- width: 100%;
56
- display: block;
57
  @include box-sizing(border-box);
58
  }
59
 
60
  .fs-card-banner
61
  {
62
- padding: 0;
63
- margin: 0;
64
- line-height: 0;
65
- display: block;
66
- height: 100px;
67
  background-repeat: repeat-x;
68
- background-size: 100% 100%;
69
  @include transition(all, 0.15s);
70
  }
71
 
72
  .fs-title
73
  {
74
- margin: 10px 0 0 0;
75
- height: 18px;
76
- overflow: hidden;
77
- color: #000;
78
- white-space: nowrap;
79
  text-overflow: ellipsis;
80
- font-weight: bold;
81
  }
82
 
83
  .fs-offer
@@ -88,10 +87,34 @@
88
  .fs-description
89
  {
90
  background-color: #f9f9f9;
91
- padding: 10px 15px 100px 15px;
92
- border-top: 1px solid #eee;
93
- margin: 0 0 10px 0;
94
- color: #777;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  }
96
  }
97
 
@@ -149,7 +172,7 @@
149
  .fs-selling-points
150
  {
151
  padding-bottom: 10px;
152
- border-bottom: 1px solid #ddd;
153
 
154
  ul
155
  {
@@ -157,17 +180,17 @@
157
 
158
  li
159
  {
160
- padding: 0;
161
  list-style: none outside none;
162
 
163
  i.dashicons
164
  {
165
- color: $fs-logo-green-color;
166
- font-size: 3em;
167
  vertical-align: middle;
168
- line-height: 30px;
169
- float: left;
170
- margin: 0 0 0 -15px;
171
  }
172
 
173
  h3
@@ -184,23 +207,23 @@
184
  ul
185
  {
186
  list-style: none;
187
- margin: 0;
188
 
189
  li
190
  {
191
- width: 225px;
192
- height: 225px;
193
- float: left;
194
  margin-bottom: 20px;
195
  @include box-sizing(content-box);
196
 
197
  a
198
  {
199
- display: block;
200
- width: 100%;
201
- height: 100%;
202
- border: 1px solid;
203
- @include box-shadow(1px 1px 1px rgba(0,0,0,0.2));
204
  background-size: cover;
205
  }
206
 
@@ -215,41 +238,133 @@
215
 
216
  .plugin-information-pricing
217
  {
218
- background: #FFFEEC;
219
- margin: -16px;
220
- padding: 20px;
221
- border-bottom: 1px solid #DDD;
 
222
 
223
- h3
224
  {
225
- margin-top: 0;
226
- }
227
 
228
- .button
229
- {
230
- width: 100%;
231
- text-align: center;
232
- font-weight: bold;
233
- text-transform: uppercase;
234
- font-size: 1.1em;
235
- }
236
 
237
- label
238
- {
239
- white-space: nowrap;
240
- }
241
 
242
- ul.fs-trial-terms
243
- {
244
- font-size: 0.9em;
 
 
 
245
 
246
- i {
247
- float: left;
248
- margin: 0 0 0 -15px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  }
250
 
251
- li {
252
- margin: 10px 0 0 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  }
254
  }
255
  }
@@ -261,12 +376,14 @@
261
  margin: -20px -26px;
262
  }
263
 
264
- table {
265
- width: 100%;
266
- border-spacing: 0;
 
267
  border-collapse: separate;
268
 
269
- thead {
 
270
  th
271
  {
272
  padding: 10px 0;
@@ -274,10 +391,10 @@
274
 
275
  .fs-price
276
  {
277
- color: $fs-logo-green-color;
278
  font-weight: normal;
279
- display: block;
280
- text-align: center;
281
  }
282
  }
283
 
@@ -286,16 +403,16 @@
286
  td
287
  {
288
  border-top: 1px solid #ccc;
289
- padding: 10px 0;
290
  text-align: center;
291
- width: 100px;
292
- color: $fs-logo-green-color;
293
 
294
  &:first-child
295
  {
296
- text-align: left;
297
- width: auto;
298
- color: inherit;
299
  padding-left: 26px;
300
  }
301
  }
@@ -311,15 +428,14 @@
311
 
312
  .dashicons-yes
313
  {
314
- width: 30px;
315
- height: 30px;
316
  font-size: 30px;
317
  }
318
  }
319
  }
320
 
321
- @media screen and (max-width: 961px)
322
- {
323
  #fs_addons
324
  {
325
  .fs-cards-list
8
 
9
  .fs-card
10
  {
11
+ float: left;
12
+ // height: 185px; // With reviews/ratings
13
+ height: 152px;
14
+ width: 310px;
15
+ padding: 0;
16
+ margin: 0 0 30px 30px;
17
+ font-size: 14px;
18
  list-style: none;
19
+ border: 1px solid #ddd;
20
+ cursor: pointer;
21
+ position: relative;
22
 
23
  .fs-overlay
24
  {
25
  position: absolute;
26
+ left: 0;
27
+ right: 0;
28
+ bottom: 0;
29
+ top: 0;
30
+ z-index: 9;
31
  }
32
 
33
  .fs-inner
34
  {
35
  background-color: #fff;
36
+ overflow: hidden;
37
+ height: 100%;
38
+ position: relative;
39
 
40
  ul
41
  {
42
  @include transition(all, 0.15s);
43
+ left: 0;
44
+ right: 0;
45
+ top: 0;
46
  position: absolute;
 
47
  }
48
 
49
  li
50
  {
51
+ list-style: none;
52
  line-height: 18px;
53
+ padding: 0 15px;
54
+ width: 100%;
55
+ display: block;
56
  @include box-sizing(border-box);
57
  }
58
 
59
  .fs-card-banner
60
  {
61
+ padding: 0;
62
+ margin: 0;
63
+ line-height: 0;
64
+ display: block;
65
+ height: 100px;
66
  background-repeat: repeat-x;
67
+ background-size: 100% 100%;
68
  @include transition(all, 0.15s);
69
  }
70
 
71
  .fs-title
72
  {
73
+ margin: 10px 0 0 0;
74
+ height: 18px;
75
+ overflow: hidden;
76
+ color: #000;
77
+ white-space: nowrap;
78
  text-overflow: ellipsis;
79
+ font-weight: bold;
80
  }
81
 
82
  .fs-offer
87
  .fs-description
88
  {
89
  background-color: #f9f9f9;
90
+ padding: 10px 15px 100px 15px;
91
+ border-top: 1px solid #eee;
92
+ margin: 0 0 10px 0;
93
+ color: #777;
94
+ }
95
+
96
+ .fs-tag
97
+ {
98
+ position: absolute;
99
+ top: 10px;
100
+ right: 0px;
101
+ background: greenyellow;
102
+ display: block;
103
+ padding: 2px 10px;
104
+ @include box-shadow(1px 1px 1px rgba(0,0,0,0.3));
105
+ text-transform: uppercase;
106
+ font-size: 0.9em;
107
+ font-weight: bold;
108
+ }
109
+
110
+ .fs-cta
111
+ {
112
+ .button
113
+ {
114
+ position: absolute;
115
+ top: 112px;
116
+ right: 10px;
117
+ }
118
  }
119
  }
120
 
172
  .fs-selling-points
173
  {
174
  padding-bottom: 10px;
175
+ border-bottom: 1px solid #ddd;
176
 
177
  ul
178
  {
180
 
181
  li
182
  {
183
+ padding: 0;
184
  list-style: none outside none;
185
 
186
  i.dashicons
187
  {
188
+ color: $fs-logo-green-color;
189
+ font-size: 3em;
190
  vertical-align: middle;
191
+ line-height: 30px;
192
+ float: left;
193
+ margin: 0 0 0 -15px;
194
  }
195
 
196
  h3
207
  ul
208
  {
209
  list-style: none;
210
+ margin: 0;
211
 
212
  li
213
  {
214
+ width: 225px;
215
+ height: 225px;
216
+ float: left;
217
  margin-bottom: 20px;
218
  @include box-sizing(content-box);
219
 
220
  a
221
  {
222
+ display: block;
223
+ width: 100%;
224
+ height: 100%;
225
+ border: 1px solid;
226
+ @include box-shadow(1px 1px 1px rgba(0, 0, 0, 0.2));
227
  background-size: cover;
228
  }
229
 
238
 
239
  .plugin-information-pricing
240
  {
241
+ $pricing_color: #FFFEEC;
242
+ $borders_color: #DDD;
243
+ margin: -16px;
244
+ // padding: 20px;
245
+ border-bottom: 1px solid $borders_color;
246
 
247
+ .fs-plan
248
  {
 
 
249
 
250
+ h3
251
+ {
252
+ margin-top: 0;
253
+ padding: 20px;
254
+ font-size: 16px;
255
+ }
 
 
256
 
257
+ .nav-tab-wrapper
258
+ {
259
+ border-bottom: 1px solid $borders_color;
 
260
 
261
+ .nav-tab
262
+ {
263
+ cursor: pointer;
264
+ position: relative;
265
+ padding: 0 10px;
266
+ font-size: 0.9em;
267
 
268
+ label
269
+ {
270
+ text-transform: uppercase;
271
+ color: green;
272
+ background: greenyellow;
273
+ position: absolute;
274
+ left: -1px;
275
+ right: -1px;
276
+ bottom: 100%;
277
+ border: 1px solid darkgreen;
278
+ padding: 2px;
279
+ text-align: center;
280
+ font-size: 0.9em;
281
+ line-height: 1em;
282
+ }
283
+
284
+ &.nav-tab-active
285
+ {
286
+ cursor: default;
287
+ background: $pricing_color;
288
+ border-bottom-color: $pricing_color;
289
+ }
290
+ }
291
  }
292
 
293
+ &.fs-single-cycle
294
+ {
295
+ h3
296
+ {
297
+ background: $pricing_color;
298
+ margin: 0;
299
+ padding-bottom: 0;
300
+ color: #0073aa;
301
+ }
302
+
303
+ .nav-tab-wrapper,
304
+ .fs-billing-frequency
305
+ {
306
+ display: none;
307
+ }
308
+ }
309
+
310
+ .fs-pricing-body
311
+ {
312
+ background: $pricing_color;
313
+ padding: 20px;
314
+ }
315
+
316
+ .button
317
+ {
318
+ width: 100%;
319
+ text-align: center;
320
+ font-weight: bold;
321
+ text-transform: uppercase;
322
+ font-size: 1.1em;
323
+ }
324
+
325
+ label
326
+ {
327
+ white-space: nowrap;
328
+ }
329
+
330
+ var {
331
+ font-style: normal;
332
+ }
333
+
334
+ .fs-billing-frequency,
335
+ .fs-annual-discount
336
+ {
337
+ text-align: center;
338
+ display: block;
339
+ font-weight: bold;
340
+ margin-bottom: 10px;
341
+ text-transform: uppercase;
342
+ background: #F3F3F3;
343
+ padding: 2px;
344
+ border: 1px solid #ccc;
345
+ }
346
+
347
+ .fs-annual-discount
348
+ {
349
+ text-transform: none;
350
+ color: green;
351
+ background: greenyellow;
352
+ }
353
+
354
+ ul.fs-trial-terms
355
+ {
356
+ font-size: 0.9em;
357
+
358
+ i
359
+ {
360
+ float: left;
361
+ margin: 0 0 0 -15px;
362
+ }
363
+
364
+ li
365
+ {
366
+ margin: 10px 0 0 0;
367
+ }
368
  }
369
  }
370
  }
376
  margin: -20px -26px;
377
  }
378
 
379
+ table
380
+ {
381
+ width: 100%;
382
+ border-spacing: 0;
383
  border-collapse: separate;
384
 
385
+ thead
386
+ {
387
  th
388
  {
389
  padding: 10px 0;
391
 
392
  .fs-price
393
  {
394
+ color: $fs-logo-green-color;
395
  font-weight: normal;
396
+ display: block;
397
+ text-align: center;
398
  }
399
  }
400
 
403
  td
404
  {
405
  border-top: 1px solid #ccc;
406
+ padding: 10px 0;
407
  text-align: center;
408
+ width: 100px;
409
+ color: $fs-logo-green-color;
410
 
411
  &:first-child
412
  {
413
+ text-align: left;
414
+ width: auto;
415
+ color: inherit;
416
  padding-left: 26px;
417
  }
418
  }
428
 
429
  .dashicons-yes
430
  {
431
+ width: 30px;
432
+ height: 30px;
433
  font-size: 30px;
434
  }
435
  }
436
  }
437
 
438
+ @media screen and (max-width: 961px) {
 
439
  #fs_addons
440
  {
441
  .fs-cards-list
freemius/assets/scss/admin/common.scss CHANGED
@@ -59,8 +59,8 @@
59
  color: #fff;
60
  padding: 2px 10px;
61
  position: absolute;
62
- bottom: -22px;
63
- top: auto;
64
  right: auto;
65
  @include border-radius(0 0 3px 3px);
66
  left: 10px;
59
  color: #fff;
60
  padding: 2px 10px;
61
  position: absolute;
62
+ top: 100%;
63
+ bottom: auto;
64
  right: auto;
65
  @include border-radius(0 0 3px 3px);
66
  left: 10px;
freemius/assets/scss/admin/connect.scss CHANGED
@@ -19,6 +19,16 @@ $form_width: 480px;
19
  background: #fff;
20
  padding: 15px 20px;
21
 
 
 
 
 
 
 
 
 
 
 
22
  p
23
  {
24
  margin: 0;
@@ -27,6 +37,22 @@ $form_width: 480px;
27
  }
28
  }
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  .fs-actions
31
  {
32
  padding: 10px 20px;
@@ -99,6 +125,11 @@ $form_width: 480px;
99
  // background: #F1F1F1;
100
  @include transition(background 0.5s ease);
101
 
 
 
 
 
 
102
  .fs-trigger
103
  {
104
  font-size: 0.9em;
@@ -176,6 +207,25 @@ $form_width: 480px;
176
  }
177
  }
178
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  $icon_size: 80px;
180
  $wp_logo_padding: $icon_size / 10;
181
  $icons_top: 10px;
19
  background: #fff;
20
  padding: 15px 20px;
21
 
22
+ .fs-error {
23
+ background: snow;
24
+ color: $fs-logo-magenta-color;
25
+ border: 1px solid $fs-logo-magenta-color;
26
+ @include box-shadow(0 1px 1px 0 rgba(0,0,0,.1));
27
+ text-align: center;
28
+ padding: 5px;
29
+ margin-bottom: 10px;
30
+ }
31
+
32
  p
33
  {
34
  margin: 0;
37
  }
38
  }
39
 
40
+ .fs-license-key-container {
41
+ position: relative;
42
+ width: 280px;
43
+ margin: 10px auto 0 auto;
44
+
45
+ input {
46
+ width: 100%;
47
+ }
48
+
49
+ .dashicons {
50
+ position: absolute;
51
+ top: 5px;
52
+ right: 5px;
53
+ }
54
+ }
55
+
56
  .fs-actions
57
  {
58
  padding: 10px 20px;
125
  // background: #F1F1F1;
126
  @include transition(background 0.5s ease);
127
 
128
+ .fs-license-sync-disclaimer {
129
+ text-align: center;
130
+ margin-top: 0;
131
+ }
132
+
133
  .fs-trigger
134
  {
135
  font-size: 0.9em;
207
  }
208
  }
209
 
210
+ .fs-freemium-licensing {
211
+ padding: 8px;
212
+ // background: #0085BA;
213
+ background: #777;
214
+ color: #fff;
215
+
216
+ p {
217
+ text-align: center;
218
+ display: block;
219
+ margin: 0;
220
+ padding: 0;
221
+ }
222
+
223
+ a {
224
+ color: #C2EEFF;
225
+ text-decoration: underline;
226
+ }
227
+ }
228
+
229
  $icon_size: 80px;
230
  $wp_logo_padding: $icon_size / 10;
231
  $icons_top: 10px;
freemius/config.php CHANGED
@@ -40,6 +40,10 @@
40
  define( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL', true );
41
  }
42
 
 
 
 
 
43
  if ( ! defined( 'WP_FS__PING_API_ON_IP_OR_HOST_CHANGES' ) ) {
44
  /**
45
  * @since 1.1.7.3
@@ -196,7 +200,13 @@
196
  * Debugging
197
  */
198
  if ( ! defined( 'WP_FS__DEBUG_SDK' ) ) {
199
- $debug_mode = get_option( 'fs_debug_mode' );
 
 
 
 
 
 
200
  define( 'WP_FS__DEBUG_SDK', is_numeric( $debug_mode ) ? ( 0 < $debug_mode ) : WP_FS__DEV_MODE );
201
  }
202
 
40
  define( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL', true );
41
  }
42
 
43
+ if ( ! defined( 'WP_FS__SIMULATE_FREEMIUS_OFF' ) ) {
44
+ define( 'WP_FS__SIMULATE_FREEMIUS_OFF', false );
45
+ }
46
+
47
  if ( ! defined( 'WP_FS__PING_API_ON_IP_OR_HOST_CHANGES' ) ) {
48
  /**
49
  * @since 1.1.7.3
200
  * Debugging
201
  */
202
  if ( ! defined( 'WP_FS__DEBUG_SDK' ) ) {
203
+ $debug_mode = get_option( 'fs_debug_mode', null );
204
+
205
+ if ( $debug_mode === null ) {
206
+ $debug_mode = false;
207
+ add_option( 'fs_debug_mode', $debug_mode );
208
+ }
209
+
210
  define( 'WP_FS__DEBUG_SDK', is_numeric( $debug_mode ) ? ( 0 < $debug_mode ) : WP_FS__DEV_MODE );
211
  }
212
 
freemius/includes/class-freemius-abstract.php CHANGED
@@ -109,6 +109,16 @@
109
  return ( $this->is_paying() || $this->is_trial() );
110
  }
111
 
 
 
 
 
 
 
 
 
 
 
112
  #region Premium Only ------------------------------------------------------------------
113
 
114
  /**
@@ -201,6 +211,20 @@
201
  return $this->is_paying__premium_only();
202
  }
203
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  #endregion Premium Only ------------------------------------------------------------------
205
 
206
  #region Trial ------------------------------------------------------------------
@@ -295,6 +319,32 @@
295
  */
296
  abstract function has_free_plan();
297
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  #endregion Plans ------------------------------------------------------------------
299
 
300
  /**
109
  return ( $this->is_paying() || $this->is_trial() );
110
  }
111
 
112
+ /**
113
+ * Check if user in a trial or have feature enabled license.
114
+ *
115
+ * @author Vova Feldman (@svovaf)
116
+ * @since 1.1.7
117
+ *
118
+ * @return bool
119
+ */
120
+ abstract function can_use_premium_code();
121
+
122
  #region Premium Only ------------------------------------------------------------------
123
 
124
  /**
211
  return $this->is_paying__premium_only();
212
  }
213
 
214
+ /**
215
+ * Check if user in a trial or have feature enabled license.
216
+ *
217
+ * All code wrapped in this statement will be only included in the premium code.
218
+ *
219
+ * @author Vova Feldman (@svovaf)
220
+ * @since 1.1.9
221
+ *
222
+ * @return bool
223
+ */
224
+ function can_use_premium_code__premium_only() {
225
+ return $this->is_premium() && $this->can_use_premium_code();
226
+ }
227
+
228
  #endregion Premium Only ------------------------------------------------------------------
229
 
230
  #region Trial ------------------------------------------------------------------
319
  */
320
  abstract function has_free_plan();
321
 
322
+ /**
323
+ * Check if plugin is premium only (no free plans).
324
+ *
325
+ * NOTE: is__premium_only() is very different method, don't get confused.
326
+ *
327
+ * @author Vova Feldman (@svovaf)
328
+ * @since 1.1.9
329
+ *
330
+ * @return bool
331
+ */
332
+ abstract function is_only_premium();
333
+
334
+ /**
335
+ * Checks if it's a freemium plugin.
336
+ *
337
+ * @author Vova Feldman (@svovaf)
338
+ * @since 1.1.9
339
+ *
340
+ * @return bool
341
+ */
342
+ function is_freemium() {
343
+ return ! $this->is_only_premium() &&
344
+ $this->has_paid_plan() &&
345
+ $this->has_free_plan();
346
+ }
347
+
348
  #endregion Plans ------------------------------------------------------------------
349
 
350
  /**
freemius/includes/class-freemius.php CHANGED
@@ -102,6 +102,12 @@
102
  */
103
  private $_anonymous_mode;
104
 
 
 
 
 
 
 
105
  /**
106
  * @since 1.0.8
107
  * @var bool Hints the SDK if the plugin has any paid plans.
@@ -146,7 +152,7 @@
146
  /**
147
  * @since 1.0.4
148
  *
149
- * @var FS_Plugin
150
  */
151
  private $_parent_plugin = false;
152
  /**
@@ -363,6 +369,54 @@
363
  }
364
  }
365
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
  /**
367
  * @author Vova Feldman (@svovaf)
368
  * @since 1.0.9
@@ -375,6 +429,21 @@
375
  '_activate_plugin_event_hook'
376
  ) );
377
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
  // Hook to plugin uninstall.
379
  register_uninstall_hook( $this->_plugin_main_file_path, array( 'Freemius', '_uninstall_plugin_hook' ) );
380
 
@@ -402,7 +471,7 @@
402
  private function _register_account_hooks() {
403
  if ( is_admin() ) {
404
  if ( ! $this->is_ajax() ) {
405
- if ( $this->has_trial_plan() ) {
406
  $last_time_trial_promotion_shown = $this->_storage->get( 'trial_promotion_shown', false );
407
  if ( ! $this->_site->is_trial_utilized() &&
408
  (
@@ -532,6 +601,13 @@
532
  'input_placeholder' => __fs( 'placeholder-plugin-name', $this->_slug )
533
  );
534
 
 
 
 
 
 
 
 
535
  $reason_other = array(
536
  'id' => 7,
537
  'text' => __fs( 'reason-other', $this->_slug ),
@@ -576,6 +652,7 @@
576
  );
577
  }
578
 
 
579
  $long_term_user_reasons[] = $reason_other;
580
 
581
  $uninstall_reasons = array(
@@ -594,6 +671,7 @@
594
  'input_placeholder' => ''
595
  ),
596
  $reason_found_better_plugin,
 
597
  $reason_other
598
  ),
599
  'short-term' => array(
@@ -628,6 +706,7 @@
628
  'input_type' => 'textarea',
629
  'input_placeholder' => __fs( 'placeholder-what-did-you-expect', $this->_slug )
630
  ),
 
631
  $reason_other
632
  )
633
  );
@@ -798,12 +877,15 @@
798
  * @author Vova Feldman (@svovaf)
799
  * @since 1.0.7
800
  *
 
 
801
  * @return bool
802
  */
803
- function is_activation_mode() {
804
  return (
 
805
  ! $this->is_registered() &&
806
- ( ! $this->enable_anonymous() ||
807
  ( ! $this->is_anonymous() && ! $this->is_pending_activation() ) )
808
  );
809
  }
@@ -816,7 +898,7 @@
816
  *
817
  * @return array[string]array
818
  */
819
- private function get_active_plugins() {
820
  self::require_plugin_essentials();
821
 
822
  $active_plugin = array();
@@ -830,6 +912,92 @@
830
  return $active_plugin;
831
  }
832
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
833
  private static $_statics_loaded = false;
834
 
835
  /**
@@ -878,7 +1046,7 @@
878
 
879
  if ( WP_FS__DEV_MODE ) {
880
  // Add top-level debug menu item.
881
- $hook = add_object_page(
882
  $title,
883
  $title,
884
  'manage_options',
@@ -1102,7 +1270,7 @@
1102
  * @since 1.1.6 During dev mode, if there's connectivity - turn Freemius on regardless the configuration.
1103
  */
1104
  $this->_is_on = $this->_storage->connectivity_test['is_active'] ||
1105
- ( WP_FS__DEV_MODE && $this->_has_api_connection );
1106
 
1107
  return $this->_has_api_connection;
1108
  }
@@ -1132,10 +1300,15 @@
1132
 
1133
  $version = $this->get_plugin_version();
1134
 
 
 
 
 
 
 
1135
  $is_active = $this->apply_filters(
1136
  'is_on',
1137
- ( ! $is_connected ) ? false :
1138
- ( isset( $pong->is_active ) && true == $pong->is_active ),
1139
  $this->is_plugin_update(),
1140
  $version
1141
  );
@@ -1151,7 +1324,32 @@
1151
  );
1152
 
1153
  $this->_has_api_connection = $is_connected;
1154
- $this->_is_on = $is_active || ( WP_FS__DEV_MODE && $is_connected );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1155
  }
1156
 
1157
  /**
@@ -1163,18 +1361,27 @@
1163
  * @return string
1164
  */
1165
  function get_anonymous_id() {
1166
- if ( ! self::$_accounts->has_option( 'unique_id' ) ) {
 
 
1167
  $key = get_site_url();
1168
 
1169
  // If localhost, assign microtime instead of domain.
1170
- if ( WP_FS__IS_LOCALHOST || false !== strpos( $key, 'localhost' ) ) {
 
 
 
1171
  $key = microtime();
1172
  }
1173
 
1174
- self::$_accounts->set_option( 'unique_id', md5( $key ), true );
 
 
1175
  }
1176
 
1177
- return self::$_accounts->get_option( 'unique_id' );
 
 
1178
  }
1179
 
1180
  /**
@@ -1448,6 +1655,17 @@
1448
  )
1449
  );
1450
 
 
 
 
 
 
 
 
 
 
 
 
1451
  // Send email with technical details to resolve CloudFlare's firewall unnecessary protection.
1452
  $this->send_email(
1453
  'api@freemius.com', // recipient
@@ -1585,7 +1803,7 @@
1585
  // Retrieve the cURL version information so that we can get the version number below.
1586
  $curl_version_information = curl_version();
1587
 
1588
- $active_plugin = $this->get_active_plugins();
1589
 
1590
  // Generate the list of active plugins separated by new line.
1591
  $active_plugin_string = '';
@@ -1619,6 +1837,7 @@
1619
  'site' => array(
1620
  'title' => 'Site',
1621
  'rows' => array(
 
1622
  'address' => array( 'Address', site_url() ),
1623
  'host' => array(
1624
  'HTTP_HOST',
@@ -1823,7 +2042,10 @@
1823
  // @todo This should be only executed on activation. It should be migrated to register_activation_hook() together with other activation related logic.
1824
  if ( $this->is_premium() ) {
1825
  // Remove add-on download admin-notice.
1826
- $this->_parent->_admin_notices->remove_sticky( 'addon_plan_upgraded_' . $this->_slug );
 
 
 
1827
  }
1828
 
1829
  $this->deactivate_premium_only_addon_without_license();
@@ -1888,6 +2110,18 @@
1888
  $this->do_action( 'after_init_addon_pending_activations' );
1889
  }
1890
  }
 
 
 
 
 
 
 
 
 
 
 
 
1891
  }
1892
 
1893
  /**
@@ -1909,6 +2143,14 @@
1909
  $parent_id = $this->get_numeric_option( $plugin_info, 'parent_id', null );
1910
  $parent_name = $this->get_option( $plugin_info, 'parent_name', null );
1911
 
 
 
 
 
 
 
 
 
1912
  if ( isset( $plugin_info['parent'] ) ) {
1913
  $parent_id = $this->get_numeric_option( $plugin_info['parent'], 'id', null );
1914
  // $parent_slug = $this->get_option( $plugin_info['parent'], 'slug', null );
@@ -1962,9 +2204,16 @@
1962
  $this->_has_addons = $this->get_bool_option( $plugin_info, 'has_addons', false );
1963
  $this->_has_paid_plans = $this->get_bool_option( $plugin_info, 'has_paid_plans', true );
1964
  $this->_is_org_compliant = $this->get_bool_option( $plugin_info, 'is_org_compliant', true );
1965
- $this->_enable_anonymous = $this->get_bool_option( $plugin_info, 'enable_anonymous', true );
1966
- $this->_anonymous_mode = $this->get_bool_option( $plugin_info, 'anonymous_mode', false );
1967
- $this->_permissions = $this->get_option( $plugin_info, 'permissions', array() );
 
 
 
 
 
 
 
1968
  }
1969
 
1970
  /**
@@ -1995,6 +2244,19 @@
1995
  * @return bool
1996
  */
1997
  private function should_stop_execution() {
 
 
 
 
 
 
 
 
 
 
 
 
 
1998
  if ( $this->is_activation_mode() ) {
1999
  if ( ! is_admin() ) {
2000
  /**
@@ -2271,28 +2533,51 @@
2271
  ! $this->has_features_enabled_license() &&
2272
  ! $this->_has_premium_license()
2273
  ) {
2274
- deactivate_plugins( array( $this->_plugin_basename ), true );
 
 
 
 
 
 
 
 
 
 
 
2275
 
2276
- $this->_parent->_admin_notices->add_sticky(
2277
- sprintf(
2278
- __fs( ( $is_after_trial_cancel ?
2279
- 'addon-trial-cancelled-message' :
2280
- 'addon-no-license-message' ),
2281
- $this->_parent->_slug
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2282
  ),
2283
- '<b>' . $this->_plugin->title . '</b>'
2284
- ) . ' ' . sprintf(
2285
- '<a href="%s" aria-label="%s" class="button button-primary" style="margin-left: 10px; vertical-align: middle;">%s &nbsp;&#10140;</a>',
2286
- $this->_parent->addon_url( $this->_slug ),
2287
- esc_attr( sprintf( __fs( 'more-information-about-x', $this->_parent->_slug ), $this->_plugin->title ) ),
2288
- __fs( 'purchase-license', $this->_parent->_slug )
2289
- ),
2290
- 'no_addon_license',
2291
- ( $is_after_trial_cancel ? '' : __fs( 'oops', $this->_parent->_slug ) . '...' ),
2292
- ( $is_after_trial_cancel ? 'success' : 'error' )
2293
- );
2294
 
2295
- return true;
 
2296
  }
2297
 
2298
  return false;
@@ -2772,7 +3057,7 @@
2772
  if ( ! $this->is_addon() && ! $this->is_registered() && ! $this->is_anonymous() ) {
2773
  if ( ! $this->is_pending_activation() ) {
2774
  if ( ! $this->_menu->is_activation_page() ) {
2775
- if ( $this->is_plugin_new_install() ) {
2776
  // Show notice for new plugin installations.
2777
  $this->_admin_notices->add(
2778
  sprintf(
@@ -3072,6 +3357,16 @@
3072
  // Store hint that the plugin was just activated to enable auto-redirection to settings.
3073
  add_option( "fs_{$this->_slug}_activated", true );
3074
  }
 
 
 
 
 
 
 
 
 
 
3075
  }
3076
 
3077
  /**
@@ -3270,17 +3565,285 @@
3270
  // $this->sync_install( array(), true );
3271
  }
3272
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3273
  /**
3274
  * Update install details.
3275
  *
3276
  * @author Vova Feldman (@svovaf)
3277
  * @since 1.1.2
3278
  *
3279
- * @param string[] string $override
 
 
3280
  *
3281
  * @return array
3282
  */
3283
- private function get_install_data_for_api( $override = array() ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3284
  return array_merge( array(
3285
  'version' => $this->get_plugin_version(),
3286
  'is_premium' => $this->is_premium(),
@@ -3330,7 +3893,10 @@
3330
  } else {
3331
  $special[ $p ] = $v;
3332
 
3333
- if ( isset( $override[ $p ] ) ) {
 
 
 
3334
  $special_override = true;
3335
  }
3336
  }
@@ -3339,7 +3905,7 @@
3339
  if ( $special_override || 0 < count( $params ) ) {
3340
  // Add special params only if has at least one
3341
  // standard param, or if explicitly requested to
3342
- // override a special param or a pram which is not exist
3343
  // in the install object.
3344
  $params = array_merge( $params, $special );
3345
  }
@@ -3349,6 +3915,8 @@
3349
  // Update last install sync timestamp.
3350
  $this->_storage->install_sync_timestamp = time();
3351
 
 
 
3352
  // Send updated values to FS.
3353
  $site = $this->get_api_site_scope()->call( '/', 'put', $params );
3354
 
@@ -4227,6 +4795,30 @@
4227
  return false;
4228
  }
4229
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4230
  /**
4231
  * Sync local plugin plans with remote server.
4232
  *
@@ -4497,7 +5089,55 @@
4497
  * @return bool
4498
  */
4499
  function has_free_plan() {
4500
- return FS_Plan_Manager::instance()->has_free_plan( $this->_plans );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4501
  }
4502
 
4503
  #region URL Generators
@@ -4641,15 +5281,41 @@
4641
  /**
4642
  * Check if plugin can work in anonymous mode.
4643
  *
4644
- * @author Vova Feldman (@svovaf)
4645
- * @since 1.0.9
4646
  *
4647
  * @return bool
 
 
4648
  */
4649
  function enable_anonymous() {
4650
  return $this->_enable_anonymous;
4651
  }
4652
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4653
  /**
4654
  * Check if feature supported with current site's plan.
4655
  *
@@ -5155,10 +5821,11 @@
5155
  * @param string|bool $email
5156
  * @param string|bool $first
5157
  * @param string|bool $last
 
5158
  *
5159
  * @return bool Is successful opt-in (or set to pending).
5160
  */
5161
- function opt_in( $email = false, $first = false, $last = false ) {
5162
  $this->_logger->entrance();
5163
 
5164
  if ( false === $email ) {
@@ -5184,7 +5851,12 @@
5184
  $user_info['user_lastname'] = $last;
5185
  }
5186
 
5187
- $params = $this->get_opt_in_params( $user_info );
 
 
 
 
 
5188
  $params['format'] = 'json';
5189
 
5190
  $url = WP_FS__ADDRESS . '/action/service/user/install/';
@@ -5215,8 +5887,8 @@
5215
  }
5216
 
5217
  if ( $response instanceof WP_Error ) {
5218
- return false;
5219
- }
5220
  }
5221
 
5222
  if ( is_wp_error( $response ) ) {
@@ -5280,6 +5952,9 @@
5280
  $this->_enrich_site_trial_plan( true );
5281
  }
5282
 
 
 
 
5283
  $this->do_action( 'after_account_connection', $user, $site );
5284
 
5285
  if ( is_numeric( $site->license_id ) ) {
@@ -5338,6 +6013,14 @@
5338
 
5339
  }
5340
  } else {
 
 
 
 
 
 
 
 
5341
  // Reload the page with the keys.
5342
  if ( $redirect && fs_redirect( $this->get_after_activation_url( 'after_connect_url' ) ) ) {
5343
  exit();
@@ -5482,13 +6165,25 @@
5482
  // We have to set the user before getting user scope API handler.
5483
  $this->_user = $user;
5484
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5485
  // Install the plugin.
5486
  $install = $this->get_api_user_scope()->call(
5487
  "/plugins/{$this->get_id()}/installs.json",
5488
  'post',
5489
- $this->get_install_data_for_api( array(
5490
- 'uid' => $this->get_anonymous_id(),
5491
- ) )
5492
  );
5493
 
5494
  if ( isset( $install->error ) ) {
@@ -5532,7 +6227,7 @@
5532
  'post',
5533
  $this->get_install_data_for_api( array(
5534
  'uid' => $this->get_anonymous_id(),
5535
- ) )
5536
  );
5537
 
5538
  if ( isset( $addon_install->error ) ) {
@@ -5589,15 +6284,15 @@
5589
  * @since 1.0.9
5590
  */
5591
  function _prepare_admin_menu() {
5592
- if ( ! $this->is_on() ) {
5593
- return;
5594
- }
5595
 
5596
- if ( ! $this->has_api_connectivity() && ! $this->enable_anonymous() ) {
5597
  $this->_menu->remove_menu_item();
5598
  } else {
5599
- $this->add_submenu_items();
5600
  $this->add_menu_action();
 
5601
  }
5602
  }
5603
 
@@ -5639,7 +6334,7 @@
5639
  foreach ( $this->_menu_items as $priority => $items ) {
5640
  foreach ( $items as $item ) {
5641
  if ( isset( $item['url'] ) ) {
5642
- if ( $page === $item['menu_slug'] ) {
5643
  $this->_logger->log( 'Redirecting to ' . $item['url'] );
5644
 
5645
  fs_redirect( $item['url'] );
@@ -5882,14 +6577,18 @@
5882
  private function order_sub_submenu_items() {
5883
  global $submenu;
5884
 
5885
- $top_level_menu = &$submenu[ $this->_menu->get_top_level_menu_slug() ];
 
 
 
 
 
 
5886
 
5887
  $all_submenu_items_after = array();
5888
 
5889
  $found_submenu_item = false;
5890
 
5891
- if (empty($top_level_menu)) return;
5892
-
5893
  foreach ( $top_level_menu as $submenu_id => $meta ) {
5894
  if ( $found_submenu_item ) {
5895
  // Remove all submenu items after the plugin's submenu item.
@@ -5937,7 +6636,7 @@
5937
  return;
5938
  }
5939
 
5940
- if ( $this->is_registered() || $this->is_anonymous() ) {
5941
  if ( $this->_menu->is_submenu_item_visible( 'support' ) ) {
5942
  $this->add_submenu_link_item(
5943
  $this->apply_filters( 'support_forum_submenu', __fs( 'support-forum', $this->_slug ) ),
@@ -6967,9 +7666,19 @@
6967
  $is_free = $this->is_free_plan();
6968
 
6969
  // Make sure license exist and not expired.
6970
- $new_license = is_null( $site->license_id ) ? null : $this->_get_license_by_id( $site->license_id );
 
 
6971
 
6972
- if ( $is_free && ( ( ! is_object( $new_license ) || $new_license->is_expired() ) ) ) {
 
 
 
 
 
 
 
 
6973
  // The license is expired, so ignore upgrade method.
6974
  } else {
6975
  // License changed.
@@ -7025,10 +7734,9 @@
7025
  ),
7026
  __fs( 'contact-us-here', $this->_slug )
7027
  ),
7028
- '<i>' . $plan->title . ( $this->is_trial() ? ' ' . __fs( 'trial', $this->_slug ) : '' ) . '</i>'
7029
  ),
7030
- __fs( 'hmm', $this->_slug ) . '...',
7031
- 'error'
7032
  );
7033
  }
7034
  break;
@@ -7077,6 +7785,19 @@
7077
  );
7078
  $this->_admin_notices->remove_sticky( 'plan_upgraded' );
7079
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
7080
  case 'expired':
7081
  $this->_admin_notices->add_sticky(
7082
  sprintf( __fs( 'license-expired-non-blocking-message', $this->_slug ), $this->_site->plan->title ),
@@ -7146,6 +7867,21 @@
7146
  return;
7147
  }
7148
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7149
  $api = $this->get_api_site_scope();
7150
  $license = $api->call( "/licenses/{$premium_license->id}.json", 'put' );
7151
 
@@ -7308,6 +8044,100 @@
7308
  }
7309
  }
7310
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7311
  /**
7312
  * Cancel site trial.
7313
  *
@@ -8592,6 +9422,26 @@
8592
  }
8593
  }
8594
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8595
  /**
8596
  * Get the URL of the page that should be loaded right after the plugin activation.
8597
  *
102
  */
103
  private $_anonymous_mode;
104
 
105
+ /**
106
+ * @since 1.1.9
107
+ * @var bool Hints the SDK if plugin have any free plans.
108
+ */
109
+ private $_is_premium_only;
110
+
111
  /**
112
  * @since 1.0.8
113
  * @var bool Hints the SDK if the plugin has any paid plans.
152
  /**
153
  * @since 1.0.4
154
  *
155
+ * @var FS_Plugin|false
156
  */
157
  private $_parent_plugin = false;
158
  /**
369
  }
370
  }
371
 
372
+ /**
373
+ * This action is connected to the 'plugins_loaded' hook and helps to determine
374
+ * if this is a new plugin installation or a plugin update.
375
+ *
376
+ * There are 3 different use-cases:
377
+ * 1) New plugin installation right with Freemius:
378
+ * 1.1 _activate_plugin_event_hook() will be executed first
379
+ * 1.2 Since $this->_storage->is_plugin_new_install is not set,
380
+ * and $this->_storage->plugin_last_version is not set,
381
+ * $this->_storage->is_plugin_new_install will be set to TRUE.
382
+ * 1.3 When _plugins_loaded() will be executed, $this->_storage->is_plugin_new_install will
383
+ * be already set to TRUE.
384
+ *
385
+ * 2) Plugin update, didn't have Freemius before, and now have the SDK:
386
+ * 2.1 _activate_plugin_event_hook() will not be executed, because
387
+ * the activation hook do NOT fires on updates since WP 3.1.
388
+ * 2.2 When _plugins_loaded() will be executed, $this->_storage->is_plugin_new_install will
389
+ * be empty, therefore, it will be set to FALSE.
390
+ *
391
+ * 3) Plugin update, had Freemius in prev version as well:
392
+ * 3.1 _version_updates_handler() will be executed 1st, since FS was installed
393
+ * before, $this->_storage->plugin_last_version will NOT be empty,
394
+ * therefore, $this->_storage->is_plugin_new_install will be set to FALSE.
395
+ * 3.2 When _plugins_loaded() will be executed, $this->_storage->is_plugin_new_install is
396
+ * already set, therefore, it will not be modified.
397
+ *
398
+ * Use-case #3 is backward compatible, #3.1 will be executed since 1.0.9.
399
+ *
400
+ * NOTE:
401
+ * The only fallback of this mechanism is if an admin updates a plugin based on use-case #2,
402
+ * and then, the next immediate PageView is the plugin's main settings page, it will not
403
+ * show the opt-in right away. The reason it will happen is because Freemius execution
404
+ * will be turned off till the plugin is fully loaded at least once
405
+ * (till $this->_storage->was_plugin_loaded is TRUE).
406
+ *
407
+ * @author Vova Feldman (@svovaf)
408
+ * @since 1.1.9
409
+ *
410
+ */
411
+ function _plugins_loaded() {
412
+ // Update flag that plugin was loaded with Freemius at least once.
413
+ $this->_storage->was_plugin_loaded = true;
414
+
415
+ if ( ! isset( $this->_storage->is_plugin_new_install ) ) {
416
+ $this->_storage->is_plugin_new_install = false;
417
+ }
418
+ }
419
+
420
  /**
421
  * @author Vova Feldman (@svovaf)
422
  * @since 1.0.9
429
  '_activate_plugin_event_hook'
430
  ) );
431
 
432
+ /**
433
+ * Part of the mechanism to identify new plugin install vs. plugin update.
434
+ *
435
+ * @author Vova Feldman (@svovaf)
436
+ * @since 1.1.9
437
+ */
438
+ if ( empty( $this->_storage->was_plugin_loaded ) ) {
439
+ if ( $this->is_activation_mode( false ) ) {
440
+ add_action( 'plugins_loaded', array( &$this, '_plugins_loaded' ) );
441
+ } else {
442
+ // If was activated before, then it was already loaded before.
443
+ $this->_plugins_loaded();
444
+ }
445
+ }
446
+
447
  // Hook to plugin uninstall.
448
  register_uninstall_hook( $this->_plugin_main_file_path, array( 'Freemius', '_uninstall_plugin_hook' ) );
449
 
471
  private function _register_account_hooks() {
472
  if ( is_admin() ) {
473
  if ( ! $this->is_ajax() ) {
474
+ if ( $this->apply_filters( 'show_trial', true ) && $this->has_trial_plan() ) {
475
  $last_time_trial_promotion_shown = $this->_storage->get( 'trial_promotion_shown', false );
476
  if ( ! $this->_site->is_trial_utilized() &&
477
  (
601
  'input_placeholder' => __fs( 'placeholder-plugin-name', $this->_slug )
602
  );
603
 
604
+ $reason_temporary_deactivation = array(
605
+ 'id' => 15,
606
+ 'text' => __fs( 'reason-temporary-deactivation', $this->_slug ),
607
+ 'input_type' => '',
608
+ 'input_placeholder' => ''
609
+ );
610
+
611
  $reason_other = array(
612
  'id' => 7,
613
  'text' => __fs( 'reason-other', $this->_slug ),
652
  );
653
  }
654
 
655
+ $long_term_user_reasons[] = $reason_temporary_deactivation;
656
  $long_term_user_reasons[] = $reason_other;
657
 
658
  $uninstall_reasons = array(
671
  'input_placeholder' => ''
672
  ),
673
  $reason_found_better_plugin,
674
+ $reason_temporary_deactivation,
675
  $reason_other
676
  ),
677
  'short-term' => array(
706
  'input_type' => 'textarea',
707
  'input_placeholder' => __fs( 'placeholder-what-did-you-expect', $this->_slug )
708
  ),
709
+ $reason_temporary_deactivation,
710
  $reason_other
711
  )
712
  );
877
  * @author Vova Feldman (@svovaf)
878
  * @since 1.0.7
879
  *
880
+ * @param bool $and_on
881
+ *
882
  * @return bool
883
  */
884
+ function is_activation_mode( $and_on = true ) {
885
  return (
886
+ ( $this->is_on() || ! $and_on ) &&
887
  ! $this->is_registered() &&
888
+ ( ! $this->is_enable_anonymous() ||
889
  ( ! $this->is_anonymous() && ! $this->is_pending_activation() ) )
890
  );
891
  }
898
  *
899
  * @return array[string]array
900
  */
901
+ private static function get_active_plugins() {
902
  self::require_plugin_essentials();
903
 
904
  $active_plugin = array();
912
  return $active_plugin;
913
  }
914
 
915
+ /**
916
+ * Get collection of all plugins.
917
+ *
918
+ * @author Vova Feldman (@svovaf)
919
+ * @since 1.1.8
920
+ *
921
+ * @return array Key is the plugin file path and the value is an array of the plugin data.
922
+ */
923
+ private static function get_all_plugins() {
924
+ self::require_plugin_essentials();
925
+
926
+ $all_plugins = get_plugins();
927
+ $active_plugins_basenames = get_option( 'active_plugins' );
928
+
929
+ foreach ( $all_plugins as $basename => &$data ) {
930
+ // By default set to inactive (next foreach update the active plugins).
931
+ $data['is_active'] = false;
932
+ // Enrich with plugin slug.
933
+ $data['slug'] = self::get_plugin_slug( $basename );
934
+ }
935
+
936
+ // Flag active plugins.
937
+ foreach ( $active_plugins_basenames as $basename ) {
938
+ if ( isset( $all_plugins[ $basename ] ) ) {
939
+ $all_plugins[ $basename ]['is_active'] = true;
940
+ }
941
+ }
942
+
943
+ return $all_plugins;
944
+ }
945
+
946
+
947
+ /**
948
+ * Cached result of get_site_transient( 'update_plugins' )
949
+ *
950
+ * @author Vova Feldman (@svovaf)
951
+ * @since 1.1.8
952
+ *
953
+ * @var object
954
+ */
955
+ private static $_plugins_info;
956
+
957
+ /**
958
+ * Helper function to get specified plugin's slug.
959
+ *
960
+ * @author Vova Feldman (@svovaf)
961
+ * @since 1.1.8
962
+ *
963
+ * @param $basename
964
+ *
965
+ * @return string
966
+ */
967
+ private static function get_plugin_slug( $basename ) {
968
+ if ( ! isset( self::$_plugins_info ) ) {
969
+ self::$_plugins_info = get_site_transient( 'update_plugins' );
970
+ }
971
+
972
+ $slug = '';
973
+
974
+ if ( is_object( self::$_plugins_info ) ) {
975
+ if ( isset( self::$_plugins_info->no_update ) &&
976
+ isset( self::$_plugins_info->no_update[ $basename ] ) &&
977
+ ! empty( self::$_plugins_info->no_update[ $basename ]->slug )
978
+ ) {
979
+ $slug = self::$_plugins_info->no_update[ $basename ]->slug;
980
+ } else if ( isset( self::$_plugins_info->response ) &&
981
+ isset( self::$_plugins_info->response[ $basename ] ) &&
982
+ ! empty( self::$_plugins_info->response[ $basename ]->slug )
983
+ ) {
984
+ $slug = self::$_plugins_info->response[ $basename ]->slug;
985
+ }
986
+ }
987
+
988
+ if ( empty( $slug ) ) {
989
+ // Try to find slug from FS data.
990
+ $slug = self::find_slug_by_basename( $basename );
991
+ }
992
+
993
+ if ( empty( $slug ) ) {
994
+ // Fallback to plugin's folder name.
995
+ $slug = dirname( $basename );
996
+ }
997
+
998
+ return $slug;
999
+ }
1000
+
1001
  private static $_statics_loaded = false;
1002
 
1003
  /**
1046
 
1047
  if ( WP_FS__DEV_MODE ) {
1048
  // Add top-level debug menu item.
1049
+ $hook = add_menu_page(
1050
  $title,
1051
  $title,
1052
  'manage_options',
1270
  * @since 1.1.6 During dev mode, if there's connectivity - turn Freemius on regardless the configuration.
1271
  */
1272
  $this->_is_on = $this->_storage->connectivity_test['is_active'] ||
1273
+ ( WP_FS__DEV_MODE && $this->_has_api_connection && ! WP_FS__SIMULATE_FREEMIUS_OFF );
1274
 
1275
  return $this->_has_api_connection;
1276
  }
1300
 
1301
  $version = $this->get_plugin_version();
1302
 
1303
+ if ( ! $is_connected || WP_FS__SIMULATE_FREEMIUS_OFF ) {
1304
+ $is_active = false;
1305
+ } else {
1306
+ $is_active = ( isset( $pong->is_active ) && true == $pong->is_active );
1307
+ }
1308
+
1309
  $is_active = $this->apply_filters(
1310
  'is_on',
1311
+ $is_active,
 
1312
  $this->is_plugin_update(),
1313
  $version
1314
  );
1324
  );
1325
 
1326
  $this->_has_api_connection = $is_connected;
1327
+ $this->_is_on = $is_active || ( WP_FS__DEV_MODE && $is_connected && ! WP_FS__SIMULATE_FREEMIUS_OFF );
1328
+ }
1329
+
1330
+ /**
1331
+ * Force turning Freemius on.
1332
+ *
1333
+ * @author Vova Feldman (@svovaf)
1334
+ * @since 1.1.8.1
1335
+ *
1336
+ * @return bool TRUE if successfully turned on.
1337
+ */
1338
+ private function turn_on() {
1339
+ $this->_logger->entrance();
1340
+
1341
+ if ( $this->is_on() || ! isset( $this->_storage->connectivity_test['is_active'] ) ) {
1342
+ return false;
1343
+ }
1344
+
1345
+ $updated_connectivity = $this->_storage->connectivity_test;
1346
+ $updated_connectivity['is_active'] = true;
1347
+ $updated_connectivity['timestamp'] = WP_FS__SCRIPT_START_TIME;
1348
+ $this->_storage->connectivity_test = $updated_connectivity;
1349
+
1350
+ $this->_is_on = true;
1351
+
1352
+ return true;
1353
  }
1354
 
1355
  /**
1361
  * @return string
1362
  */
1363
  function get_anonymous_id() {
1364
+ $unique_id = self::$_accounts->get_option( 'unique_id' );
1365
+
1366
+ if ( empty( $unique_id ) || ! is_string( $unique_id ) ) {
1367
  $key = get_site_url();
1368
 
1369
  // If localhost, assign microtime instead of domain.
1370
+ if ( WP_FS__IS_LOCALHOST ||
1371
+ false !== strpos( $key, 'localhost' ) ||
1372
+ false === strpos( $key, '.' )
1373
+ ) {
1374
  $key = microtime();
1375
  }
1376
 
1377
+ $unique_id = md5( $key );
1378
+
1379
+ self::$_accounts->set_option( 'unique_id', $unique_id, true );
1380
  }
1381
 
1382
+ $this->_logger->departure( $unique_id );
1383
+
1384
+ return $unique_id;
1385
  }
1386
 
1387
  /**
1655
  )
1656
  );
1657
 
1658
+ // Add PHP info for deeper investigation.
1659
+ ob_start();
1660
+ phpinfo();
1661
+ $php_info = ob_get_clean();
1662
+ $custom_email_sections['php_info'] = array(
1663
+ 'title' => 'PHP Info',
1664
+ 'rows' => array(
1665
+ 'info' => array( $php_info )
1666
+ )
1667
+ );
1668
+
1669
  // Send email with technical details to resolve CloudFlare's firewall unnecessary protection.
1670
  $this->send_email(
1671
  'api@freemius.com', // recipient
1803
  // Retrieve the cURL version information so that we can get the version number below.
1804
  $curl_version_information = curl_version();
1805
 
1806
+ $active_plugin = self::get_active_plugins();
1807
 
1808
  // Generate the list of active plugins separated by new line.
1809
  $active_plugin_string = '';
1837
  'site' => array(
1838
  'title' => 'Site',
1839
  'rows' => array(
1840
+ 'unique_id' => array( 'Address', $this->get_anonymous_id() ),
1841
  'address' => array( 'Address', site_url() ),
1842
  'host' => array(
1843
  'HTTP_HOST',
2042
  // @todo This should be only executed on activation. It should be migrated to register_activation_hook() together with other activation related logic.
2043
  if ( $this->is_premium() ) {
2044
  // Remove add-on download admin-notice.
2045
+ $this->_parent->_admin_notices->remove_sticky( array(
2046
+ 'addon_plan_upgraded_' . $this->_slug,
2047
+ 'no_addon_license_' . $this->_slug,
2048
+ ) );
2049
  }
2050
 
2051
  $this->deactivate_premium_only_addon_without_license();
2110
  $this->do_action( 'after_init_addon_pending_activations' );
2111
  }
2112
  }
2113
+
2114
+ // Add license activation link and AJAX request handler.
2115
+ if ( $this->has_paid_plan() ) {
2116
+ $this->_add_license_action_link();
2117
+
2118
+ global $pagenow;
2119
+ if ( 'plugins.php' === $pagenow ) {
2120
+ add_action( 'admin_footer', array( &$this, '_add_license_activation_dialog_box' ) );
2121
+ }
2122
+
2123
+ add_action( 'wp_ajax_activate-license', array( &$this, '_activate_license_ajax_action' ) );
2124
+ }
2125
  }
2126
 
2127
  /**
2143
  $parent_id = $this->get_numeric_option( $plugin_info, 'parent_id', null );
2144
  $parent_name = $this->get_option( $plugin_info, 'parent_name', null );
2145
 
2146
+ /**
2147
+ * @author Vova Feldman (@svovaf)
2148
+ * @since 1.1.9 Try to pull secret key from external config.
2149
+ */
2150
+ if ( is_null( $secret_key ) && defined( "WP_FS__{$this->_slug}_SECRET_KEY" ) ) {
2151
+ $secret_key = constant( "WP_FS__{$this->_slug}_SECRET_KEY" );
2152
+ }
2153
+
2154
  if ( isset( $plugin_info['parent'] ) ) {
2155
  $parent_id = $this->get_numeric_option( $plugin_info['parent'], 'id', null );
2156
  // $parent_slug = $this->get_option( $plugin_info['parent'], 'slug', null );
2204
  $this->_has_addons = $this->get_bool_option( $plugin_info, 'has_addons', false );
2205
  $this->_has_paid_plans = $this->get_bool_option( $plugin_info, 'has_paid_plans', true );
2206
  $this->_is_org_compliant = $this->get_bool_option( $plugin_info, 'is_org_compliant', true );
2207
+ $this->_is_premium_only = $this->get_bool_option( $plugin_info, 'is_premium_only', false );
2208
+ if ( $this->_is_premium_only ) {
2209
+ // If premium only plugin, disable anonymous mode.
2210
+ $this->_enable_anonymous = false;
2211
+ $this->_anonymous_mode = false;
2212
+ } else {
2213
+ $this->_enable_anonymous = $this->get_bool_option( $plugin_info, 'enable_anonymous', true );
2214
+ $this->_anonymous_mode = $this->get_bool_option( $plugin_info, 'anonymous_mode', false );
2215
+ }
2216
+ $this->_permissions = $this->get_option( $plugin_info, 'permissions', array() );
2217
  }
2218
 
2219
  /**
2244
  * @return bool
2245
  */
2246
  private function should_stop_execution() {
2247
+ if ( empty( $this->_storage->was_plugin_loaded ) ) {
2248
+ /**
2249
+ * Don't execute Freemius until plugin was fully loaded at least once,
2250
+ * to give the opportunity for the activation hook to run before pinging
2251
+ * the API for connectivity test. This logic is relevant for the
2252
+ * identification of new plugin install vs. plugin update.
2253
+ *
2254
+ * @author Vova Feldman (@svovaf)
2255
+ * @since 1.1.9
2256
+ */
2257
+ return true;
2258
+ }
2259
+
2260
  if ( $this->is_activation_mode() ) {
2261
  if ( ! is_admin() ) {
2262
  /**
2533
  ! $this->has_features_enabled_license() &&
2534
  ! $this->_has_premium_license()
2535
  ) {
2536
+ // IF wrapper is turned off because activation_timestamp is currently only stored for plugins (not addons).
2537
+ // if (empty($this->_storage->activation_timestamp) ||
2538
+ // (WP_FS__SCRIPT_START_TIME - $this->_storage->activation_timestamp) > 30
2539
+ // ) {
2540
+ /**
2541
+ * @todo When it's first fail, there's no reason to try and re-sync because the licenses were just synced after initial activation.
2542
+ *
2543
+ * Retry syncing the user add-on licenses.
2544
+ */
2545
+ // Sync licenses.
2546
+ $this->_sync_licenses();
2547
+ // }
2548
 
2549
+ // Try to activate premium license.
2550
+ $this->_activate_license( true );
2551
+
2552
+ if ( ! $this->has_free_plan() &&
2553
+ ! $this->has_features_enabled_license() &&
2554
+ ! $this->_has_premium_license()
2555
+ ) {
2556
+ // @todo Check if deactivate plugins also call the deactivation hook.
2557
+
2558
+ deactivate_plugins( array( $this->_plugin_basename ), true );
2559
+
2560
+ $this->_parent->_admin_notices->add_sticky(
2561
+ sprintf(
2562
+ __fs( ( $is_after_trial_cancel ?
2563
+ 'addon-trial-cancelled-message' :
2564
+ 'addon-no-license-message' ),
2565
+ $this->_parent->_slug
2566
+ ),
2567
+ '<b>' . $this->_plugin->title . '</b>'
2568
+ ) . ' ' . sprintf(
2569
+ '<a href="%s" aria-label="%s" class="button button-primary" style="margin-left: 10px; vertical-align: middle;">%s &nbsp;&#10140;</a>',
2570
+ $this->_parent->addon_url( $this->_slug ),
2571
+ esc_attr( sprintf( __fs( 'more-information-about-x', $this->_parent->_slug ), $this->_plugin->title ) ),
2572
+ __fs( 'purchase-license', $this->_parent->_slug )
2573
  ),
2574
+ 'no_addon_license_' . $this->_slug,
2575
+ ( $is_after_trial_cancel ? '' : __fs( 'oops', $this->_parent->_slug ) . '...' ),
2576
+ ( $is_after_trial_cancel ? 'success' : 'error' )
2577
+ );
 
 
 
 
 
 
 
2578
 
2579
+ return true;
2580
+ }
2581
  }
2582
 
2583
  return false;
3057
  if ( ! $this->is_addon() && ! $this->is_registered() && ! $this->is_anonymous() ) {
3058
  if ( ! $this->is_pending_activation() ) {
3059
  if ( ! $this->_menu->is_activation_page() ) {
3060
+ if ( $this->is_plugin_new_install() || $this->is_only_premium() ) {
3061
  // Show notice for new plugin installations.
3062
  $this->_admin_notices->add(
3063
  sprintf(
3357
  // Store hint that the plugin was just activated to enable auto-redirection to settings.
3358
  add_option( "fs_{$this->_slug}_activated", true );
3359
  }
3360
+
3361
+ /**
3362
+ * Activation hook is executed after the plugin's main file is loaded, therefore,
3363
+ * after the plugin was loaded. The logic is located at activate_plugin()
3364
+ * ./wp-admin/includes/plugin.php.
3365
+ *
3366
+ * @author Vova Feldman (@svovaf)
3367
+ * @since 1.1.9
3368
+ */
3369
+ $this->_storage->was_plugin_loaded = true;
3370
  }
3371
 
3372
  /**
3565
  // $this->sync_install( array(), true );
3566
  }
3567
 
3568
+ /**
3569
+ * Return a list of modified plugins since the last sync.
3570
+ *
3571
+ * Note:
3572
+ * There's no point to store a plugins counter since even if the number of
3573
+ * plugins didn't change, we still need to check if the versions are all the
3574
+ * same and the activity state is similar.
3575
+ *
3576
+ * @author Vova Feldman (@svovaf)
3577
+ * @since 1.1.8
3578
+ *
3579
+ * @return array|false
3580
+ */
3581
+ private function get_plugins_data_for_api() {
3582
+ // Alias.
3583
+ $option_name = 'all_plugins';
3584
+
3585
+ $all_cached_plugins = self::$_accounts->get_option( $option_name );
3586
+
3587
+ if ( ! is_object( $all_cached_plugins ) ) {
3588
+ $all_cached_plugins = (object) array(
3589
+ 'timestamp' => '',
3590
+ 'md5' => '',
3591
+ 'plugins' => array(),
3592
+ );
3593
+ }
3594
+
3595
+ $time = time();
3596
+
3597
+ if ( ! empty( $all_cached_plugins->timestamp ) &&
3598
+ ( $time - $all_cached_plugins->timestamp ) < WP_FS__TIME_5_MIN_IN_SEC
3599
+ ) {
3600
+ // Don't send plugin updates if last update was in the past 5 min.
3601
+ return false;
3602
+ }
3603
+
3604
+ // Write timestamp to lock the logic.
3605
+ $all_cached_plugins->timestamp = $time;
3606
+ self::$_accounts->set_option( $option_name, $all_cached_plugins, true );
3607
+
3608
+ // Reload options from DB.
3609
+ self::$_accounts->load( true );
3610
+ $all_cached_plugins = self::$_accounts->get_option( $option_name );
3611
+
3612
+ if ( $time != $all_cached_plugins->timestamp ) {
3613
+ // If timestamp is different, then another thread captured the lock.
3614
+ return false;
3615
+ }
3616
+
3617
+ // Check if there's a change in plugins.
3618
+ $all_plugins = self::get_all_plugins();
3619
+
3620
+ // Check if plugins changed.
3621
+ ksort( $all_plugins );
3622
+
3623
+ $plugins_signature = '';
3624
+ foreach ( $all_plugins as $basename => $data ) {
3625
+ $plugins_signature .= $data['slug'] . ',' .
3626
+ $data['Version'] . ',' .
3627
+ ( $data['is_active'] ? '1' : '0' ) . ';';
3628
+ }
3629
+
3630
+ // Check if plugins status changed (version or active/inactive).
3631
+ $plugins_changed = ( $all_cached_plugins->md5 !== md5( $plugins_signature ) );
3632
+
3633
+ $plugins_update_data = array();
3634
+
3635
+ if ( $plugins_changed ) {
3636
+ // Change in plugins, report changes.
3637
+
3638
+ // Update existing plugins info.
3639
+ foreach ( $all_cached_plugins->plugins as $basename => $data ) {
3640
+ if ( ! isset( $all_plugins[ $basename ] ) ) {
3641
+ // Plugin uninstalled.
3642
+ $uninstalled_plugin_data = $data;
3643
+ $uninstalled_plugin_data['is_active'] = false;
3644
+ $uninstalled_plugin_data['is_uninstalled'] = true;
3645
+ $plugins_update_data[] = $uninstalled_plugin_data;
3646
+
3647
+ unset( $all_plugins[ $basename ] );
3648
+ unset( $all_cached_plugins->plugins[ $basename ] );
3649
+ } else if ( $data['is_active'] !== $all_plugins[ $basename ]['is_active'] ||
3650
+ $data['version'] !== $all_plugins[ $basename ]['Version']
3651
+ ) {
3652
+ // Plugin activated or deactivated, or version changed.
3653
+ $all_cached_plugins->plugins[ $basename ]['is_active'] = $all_plugins[ $basename ]['is_active'];
3654
+ $all_cached_plugins->plugins[ $basename ]['version'] = $all_plugins[ $basename ]['Version'];
3655
+
3656
+ $plugins_update_data[] = $all_cached_plugins->plugins[ $basename ];
3657
+ }
3658
+ }
3659
+
3660
+ // Find new plugins that weren't yet seen before.
3661
+ foreach ( $all_plugins as $basename => $data ) {
3662
+ if ( ! isset( $all_cached_plugins->plugins[ $basename ] ) ) {
3663
+ // New plugin.
3664
+ $new_plugin = array(
3665
+ 'slug' => $data['slug'],
3666
+ 'version' => $data['Version'],
3667
+ 'title' => $data['Name'],
3668
+ 'is_active' => $data['is_active'],
3669
+ 'is_uninstalled' => false,
3670
+ );
3671
+
3672
+ $plugins_update_data[] = $new_plugin;
3673
+ $all_cached_plugins->plugins[ $basename ] = $new_plugin;
3674
+ }
3675
+ }
3676
+
3677
+ $all_cached_plugins->md5 = md5( $plugins_signature );
3678
+ $all_cached_plugins->timestamp = $time;
3679
+ self::$_accounts->set_option( $option_name, $all_cached_plugins, true );
3680
+ }
3681
+
3682
+ return $plugins_update_data;
3683
+ }
3684
+
3685
+ /**
3686
+ * Return a list of modified themes since the last sync.
3687
+ *
3688
+ * Note:
3689
+ * There's no point to store a themes counter since even if the number of
3690
+ * themes didn't change, we still need to check if the versions are all the
3691
+ * same and the activity state is similar.
3692
+ *
3693
+ * @author Vova Feldman (@svovaf)
3694
+ * @since 1.1.8
3695
+ *
3696
+ * @return array|false
3697
+ */
3698
+ private function get_themes_data_for_api() {
3699
+ // Alias.
3700
+ $option_name = 'all_themes';
3701
+
3702
+ $all_cached_themes = self::$_accounts->get_option( $option_name );
3703
+
3704
+ if ( ! is_object( $all_cached_themes ) ) {
3705
+ $all_cached_themes = (object) array(
3706
+ 'timestamp' => '',
3707
+ 'md5' => '',
3708
+ 'themes' => array(),
3709
+ );
3710
+ }
3711
+
3712
+ $time = time();
3713
+
3714
+ if ( ! empty( $all_cached_themes->timestamp ) &&
3715
+ ( $time - $all_cached_themes->timestamp ) < WP_FS__TIME_5_MIN_IN_SEC
3716
+ ) {
3717
+ // Don't send theme updates if last update was in the past 5 min.
3718
+ return false;
3719
+ }
3720
+
3721
+ // Write timestamp to lock the logic.
3722
+ $all_cached_themes->timestamp = $time;
3723
+ self::$_accounts->set_option( $option_name, $all_cached_themes, true );
3724
+
3725
+ // Reload options from DB.
3726
+ self::$_accounts->load( true );
3727
+ $all_cached_themes = self::$_accounts->get_option( $option_name );
3728
+
3729
+ if ( $time != $all_cached_themes->timestamp ) {
3730
+ // If timestamp is different, then another thread captured the lock.
3731
+ return false;
3732
+ }
3733
+
3734
+ // Get active theme.
3735
+ $active_theme = wp_get_theme();
3736
+
3737
+ // Check if there's a change in themes.
3738
+ $all_themes = wp_get_themes();
3739
+
3740
+ // Check if themes changed.
3741
+ ksort( $all_themes );
3742
+
3743
+ $themes_signature = '';
3744
+ foreach ( $all_themes as $slug => $data ) {
3745
+ $is_active = ( $slug === $active_theme->stylesheet );
3746
+ $themes_signature .= $slug . ',' .
3747
+ $data->version . ',' .
3748
+ ( $is_active ? '1' : '0' ) . ';';
3749
+ }
3750
+
3751
+ // Check if themes status changed (version or active/inactive).
3752
+ $themes_changed = ( $all_cached_themes->md5 !== md5( $themes_signature ) );
3753
+
3754
+ $themes_update_data = array();
3755
+
3756
+ if ( $themes_changed ) {
3757
+ // Change in themes, report changes.
3758
+
3759
+ // Update existing themes info.
3760
+ foreach ( $all_cached_themes->themes as $slug => $data ) {
3761
+ $is_active = ( $slug === $active_theme->stylesheet );
3762
+
3763
+ if ( ! isset( $all_themes[ $slug ] ) ) {
3764
+ // Plugin uninstalled.
3765
+ $uninstalled_theme_data = $data;
3766
+ $uninstalled_theme_data['is_active'] = false;
3767
+ $uninstalled_theme_data['is_uninstalled'] = true;
3768
+ $themes_update_data[] = $uninstalled_theme_data;
3769
+
3770
+ unset( $all_themes[ $slug ] );
3771
+ unset( $all_cached_themes->themes[ $slug ] );
3772
+ } else if ( $data['is_active'] !== $is_active ||
3773
+ $data['version'] !== $all_themes[ $slug ]->version
3774
+ ) {
3775
+ // Plugin activated or deactivated, or version changed.
3776
+
3777
+ $all_cached_themes->themes[ $slug ]['is_active'] = $is_active;
3778
+ $all_cached_themes->themes[ $slug ]['version'] = $all_themes[ $slug ]->version;
3779
+
3780
+ $themes_update_data[] = $all_cached_themes->themes[ $slug ];
3781
+ }
3782
+ }
3783
+
3784
+ // Find new themes that weren't yet seen before.
3785
+ foreach ( $all_themes as $slug => $data ) {
3786
+ if ( ! isset( $all_cached_themes->themes[ $slug ] ) ) {
3787
+ $is_active = ( $slug === $active_theme->stylesheet );
3788
+
3789
+ // New plugin.
3790
+ $new_plugin = array(
3791
+ 'slug' => $slug,
3792
+ 'version' => $data->version,
3793
+ 'title' => $data->name,
3794
+ 'is_active' => $is_active,
3795
+ 'is_uninstalled' => false,
3796
+ );
3797
+
3798
+ $themes_update_data[] = $new_plugin;
3799
+ $all_cached_themes->themes[ $slug ] = $new_plugin;
3800
+ }
3801
+ }
3802
+
3803
+ $all_cached_themes->md5 = md5( $themes_signature );
3804
+ $all_cached_themes->timestamp = time();
3805
+ self::$_accounts->set_option( $option_name, $all_cached_themes, true );
3806
+ }
3807
+
3808
+ return $themes_update_data;
3809
+ }
3810
+
3811
  /**
3812
  * Update install details.
3813
  *
3814
  * @author Vova Feldman (@svovaf)
3815
  * @since 1.1.2
3816
  *
3817
+ * @param string[] string $override
3818
+ * @param bool $include_plugins Since 1.1.8 by default include plugin changes.
3819
+ * @param bool $include_themes Since 1.1.8 by default include plugin changes.
3820
  *
3821
  * @return array
3822
  */
3823
+ private function get_install_data_for_api(
3824
+ array $override,
3825
+ $include_plugins = true,
3826
+ $include_themes = true
3827
+ ) {
3828
+ /**
3829
+ * @since 1.1.8 Also send plugin updates.
3830
+ */
3831
+ if ( $include_plugins && ! isset( $override['plugins'] ) ) {
3832
+ $plugins = $this->get_plugins_data_for_api();
3833
+ if ( ! empty( $plugins ) ) {
3834
+ $override['plugins'] = $plugins;
3835
+ }
3836
+ }
3837
+ /**
3838
+ * @since 1.1.8 Also send themes updates.
3839
+ */
3840
+ if ( $include_themes && ! isset( $override['themes'] ) ) {
3841
+ $themes = $this->get_themes_data_for_api();
3842
+ if ( ! empty( $themes ) ) {
3843
+ $override['themes'] = $themes;
3844
+ }
3845
+ }
3846
+
3847
  return array_merge( array(
3848
  'version' => $this->get_plugin_version(),
3849
  'is_premium' => $this->is_premium(),
3893
  } else {
3894
  $special[ $p ] = $v;
3895
 
3896
+ if ( isset( $override[ $p ] ) ||
3897
+ 'plugins' === $p ||
3898
+ 'themes' === $p
3899
+ ) {
3900
  $special_override = true;
3901
  }
3902
  }
3905
  if ( $special_override || 0 < count( $params ) ) {
3906
  // Add special params only if has at least one
3907
  // standard param, or if explicitly requested to
3908
+ // override a special param or a param which is not exist
3909
  // in the install object.
3910
  $params = array_merge( $params, $special );
3911
  }
3915
  // Update last install sync timestamp.
3916
  $this->_storage->install_sync_timestamp = time();
3917
 
3918
+ $params['uid'] = $this->get_anonymous_id();
3919
+
3920
  // Send updated values to FS.
3921
  $site = $this->get_api_site_scope()->call( '/', 'put', $params );
3922
 
4795
  return false;
4796
  }
4797
 
4798
+ /**
4799
+ * @author Vova Feldman (@svovaf)
4800
+ * @since 1.1.8.1
4801
+ *
4802
+ * @param string $name
4803
+ *
4804
+ * @return FS_Plugin_Plan|false
4805
+ */
4806
+ private function get_plan_by_name( $name ) {
4807
+ $this->_logger->entrance();
4808
+
4809
+ if ( ! is_array( $this->_plans ) || 0 === count( $this->_plans ) ) {
4810
+ $this->_sync_plans();
4811
+ }
4812
+
4813
+ foreach ( $this->_plans as $plan ) {
4814
+ if ( $name == $plan->name ) {
4815
+ return $plan;
4816
+ }
4817
+ }
4818
+
4819
+ return false;
4820
+ }
4821
+
4822
  /**
4823
  * Sync local plugin plans with remote server.
4824
  *
5089
  * @return bool
5090
  */
5091
  function has_free_plan() {
5092
+ return ! $this->is_only_premium() && FS_Plan_Manager::instance()->has_free_plan( $this->_plans );
5093
+ }
5094
+
5095
+ /**
5096
+ * Displays a license activation dialog box when the user clicks on the "Activate License"
5097
+ * or "Change License" link on the plugins
5098
+ * page.
5099
+ *
5100
+ * @author Leo Fajardo (@leorw)
5101
+ * @since 1.1.9
5102
+ */
5103
+ function _add_license_activation_dialog_box() {
5104
+ fs_enqueue_local_style( 'fs_license_action', '/admin/license-activation.css' );
5105
+
5106
+ $vars = array(
5107
+ 'slug' => $this->_slug
5108
+ );
5109
+
5110
+ fs_require_template( 'license-activation-modal.php', $vars );
5111
+ }
5112
+
5113
+ /**
5114
+ * @author Leo Fajardo (@leorw)
5115
+ * @since 1.1.9
5116
+ */
5117
+ function _activate_license_ajax_action() {
5118
+ if ( ! isset( $_POST['license-key'] ) ) {
5119
+ exit;
5120
+ }
5121
+
5122
+ $license_key = trim( $_POST['license-key'] );
5123
+ if ( empty( $license_key ) ) {
5124
+ exit;
5125
+ }
5126
+
5127
+ if ( $this->is_registered() ) {
5128
+ $api = $this->get_api_site_scope();
5129
+ $api->call( '/', 'put',
5130
+ array(
5131
+ 'license_key' => $license_key
5132
+ )
5133
+ );
5134
+ } else {
5135
+ $this->opt_in( false, false, false, $license_key );
5136
+ }
5137
+
5138
+ // Print '1' for successful operation.
5139
+ echo 1;
5140
+ exit;
5141
  }
5142
 
5143
  #region URL Generators
5281
  /**
5282
  * Check if plugin can work in anonymous mode.
5283
  *
5284
+ * @author Vova Feldman (@svovaf)
5285
+ * @since 1.0.9
5286
  *
5287
  * @return bool
5288
+ *
5289
+ * @deprecated Please use is_enable_anonymous() instead
5290
  */
5291
  function enable_anonymous() {
5292
  return $this->_enable_anonymous;
5293
  }
5294
 
5295
+ /**
5296
+ * Check if plugin can work in anonymous mode.
5297
+ *
5298
+ * @author Vova Feldman (@svovaf)
5299
+ * @since 1.1.9
5300
+ *
5301
+ * @return bool
5302
+ */
5303
+ function is_enable_anonymous() {
5304
+ return $this->_enable_anonymous;
5305
+ }
5306
+
5307
+ /**
5308
+ * Check if plugin is premium only (no free plans).
5309
+ *
5310
+ * @author Vova Feldman (@svovaf)
5311
+ * @since 1.1.9
5312
+ *
5313
+ * @return bool
5314
+ */
5315
+ function is_only_premium() {
5316
+ return $this->_is_premium_only;
5317
+ }
5318
+
5319
  /**
5320
  * Check if feature supported with current site's plan.
5321
  *
5821
  * @param string|bool $email
5822
  * @param string|bool $first
5823
  * @param string|bool $last
5824
+ * @param string|bool $license_key
5825
  *
5826
  * @return bool Is successful opt-in (or set to pending).
5827
  */
5828
+ function opt_in( $email = false, $first = false, $last = false, $license_secret_key = false ) {
5829
  $this->_logger->entrance();
5830
 
5831
  if ( false === $email ) {
5851
  $user_info['user_lastname'] = $last;
5852
  }
5853
 
5854
+ $params = $this->get_opt_in_params( $user_info );
5855
+
5856
+ if ( is_string( $license_secret_key ) ) {
5857
+ $params['license_secret_key'] = $license_secret_key;
5858
+ }
5859
+
5860
  $params['format'] = 'json';
5861
 
5862
  $url = WP_FS__ADDRESS . '/action/service/user/install/';
5887
  }
5888
 
5889
  if ( $response instanceof WP_Error ) {
5890
+ return false;
5891
+ }
5892
  }
5893
 
5894
  if ( is_wp_error( $response ) ) {
5952
  $this->_enrich_site_trial_plan( true );
5953
  }
5954
 
5955
+ // If Freemius was OFF before, turn it on.
5956
+ $this->turn_on();
5957
+
5958
  $this->do_action( 'after_account_connection', $user, $site );
5959
 
5960
  if ( is_numeric( $site->license_id ) ) {
6013
 
6014
  }
6015
  } else {
6016
+ /**
6017
+ * @author Vova Feldman (@svovaf)
6018
+ * @since 1.1.9 If site installed with a valid license, sync license.
6019
+ */
6020
+ if ( $this->is_paying() ) {
6021
+ $this->_sync_plugin_license( true );
6022
+ }
6023
+
6024
  // Reload the page with the keys.
6025
  if ( $redirect && fs_redirect( $this->get_after_activation_url( 'after_connect_url' ) ) ) {
6026
  exit();
6165
  // We have to set the user before getting user scope API handler.
6166
  $this->_user = $user;
6167
 
6168
+ $extra_install_params = array(
6169
+ 'uid' => $this->get_anonymous_id(),
6170
+ );
6171
+
6172
+ /**
6173
+ * @author Vova Feldman (@svovaf)
6174
+ * @since 1.1.9 Add license key if given.
6175
+ */
6176
+ $license_key = fs_request_get( 'license_secret_key' );
6177
+
6178
+ if ( ! empty( $license_key ) ) {
6179
+ $extra_install_params['license_secret_key'] = $license_key;
6180
+ }
6181
+
6182
  // Install the plugin.
6183
  $install = $this->get_api_user_scope()->call(
6184
  "/plugins/{$this->get_id()}/installs.json",
6185
  'post',
6186
+ $this->get_install_data_for_api( $extra_install_params, false, false )
 
 
6187
  );
6188
 
6189
  if ( isset( $install->error ) ) {
6227
  'post',
6228
  $this->get_install_data_for_api( array(
6229
  'uid' => $this->get_anonymous_id(),
6230
+ ), false, false )
6231
  );
6232
 
6233
  if ( isset( $addon_install->error ) ) {
6284
  * @since 1.0.9
6285
  */
6286
  function _prepare_admin_menu() {
6287
+ // if ( ! $this->is_on() ) {
6288
+ // return;
6289
+ // }
6290
 
6291
+ if ( ! $this->has_api_connectivity() && ! $this->is_enable_anonymous() ) {
6292
  $this->_menu->remove_menu_item();
6293
  } else {
 
6294
  $this->add_menu_action();
6295
+ $this->add_submenu_items();
6296
  }
6297
  }
6298
 
6334
  foreach ( $this->_menu_items as $priority => $items ) {
6335
  foreach ( $items as $item ) {
6336
  if ( isset( $item['url'] ) ) {
6337
+ if ( $page === strtolower( $item['menu_slug'] ) ) {
6338
  $this->_logger->log( 'Redirecting to ' . $item['url'] );
6339
 
6340
  fs_redirect( $item['url'] );
6577
  private function order_sub_submenu_items() {
6578
  global $submenu;
6579
 
6580
+ $menu_slug = $this->_menu->get_top_level_menu_slug();
6581
+
6582
+ if ( empty( $submenu[ $menu_slug ] ) ) {
6583
+ return;
6584
+ }
6585
+
6586
+ $top_level_menu = &$submenu[ $menu_slug ];
6587
 
6588
  $all_submenu_items_after = array();
6589
 
6590
  $found_submenu_item = false;
6591
 
 
 
6592
  foreach ( $top_level_menu as $submenu_id => $meta ) {
6593
  if ( $found_submenu_item ) {
6594
  // Remove all submenu items after the plugin's submenu item.
6636
  return;
6637
  }
6638
 
6639
+ if ( ! $this->is_activation_mode() ) {
6640
  if ( $this->_menu->is_submenu_item_visible( 'support' ) ) {
6641
  $this->add_submenu_link_item(
6642
  $this->apply_filters( 'support_forum_submenu', __fs( 'support-forum', $this->_slug ) ),
7666
  $is_free = $this->is_free_plan();
7667
 
7668
  // Make sure license exist and not expired.
7669
+ $new_license = is_null( $site->license_id ) ?
7670
+ null :
7671
+ $this->_get_license_by_id( $site->license_id );
7672
 
7673
+ if ( $is_free && is_null( $new_license ) && $this->has_license() && $this->_license->is_cancelled ) {
7674
+ // License cancelled.
7675
+ $this->_site = $site;
7676
+ $this->_update_site_license( $new_license );
7677
+ $this->_store_licenses();
7678
+ $this->_enrich_site_plan( true );
7679
+
7680
+ $plan_change = 'cancelled';
7681
+ } else if ( $is_free && ( ( ! is_object( $new_license ) || $new_license->is_expired() ) ) ) {
7682
  // The license is expired, so ignore upgrade method.
7683
  } else {
7684
  // License changed.
7734
  ),
7735
  __fs( 'contact-us-here', $this->_slug )
7736
  ),
7737
+ '<i><b>' . $plan->title . ( $this->is_trial() ? ' ' . __fs( 'trial', $this->_slug ) : '' ) . '</b></i>'
7738
  ),
7739
+ __fs( 'hmm', $this->_slug ) . '...'
 
7740
  );
7741
  }
7742
  break;
7785
  );
7786
  $this->_admin_notices->remove_sticky( 'plan_upgraded' );
7787
  break;
7788
+ case 'cancelled':
7789
+ $this->_admin_notices->add(
7790
+ __fs( 'license-cancelled', $this->_slug ) . ' ' .
7791
+ sprintf(
7792
+ '<a href="%s">%s</a>',
7793
+ $this->contact_url( 'bug' ),
7794
+ __fs( 'contact-us-here', $this->_slug )
7795
+ ),
7796
+ __fs( 'hmm', $this->_slug ) . '...',
7797
+ 'error'
7798
+ );
7799
+ $this->_admin_notices->remove_sticky( 'plan_upgraded' );
7800
+ break;
7801
  case 'expired':
7802
  $this->_admin_notices->add_sticky(
7803
  sprintf( __fs( 'license-expired-non-blocking-message', $this->_slug ), $this->_site->plan->title ),
7867
  return;
7868
  }
7869
 
7870
+ /**
7871
+ * If the premium license is already associated with the install, just
7872
+ * update the license reference (activation is not required).
7873
+ *
7874
+ * @since 1.1.9
7875
+ */
7876
+ if ( $premium_license->id == $this->_site->license_id ) {
7877
+ // License is already activated.
7878
+ $this->_update_site_license( $premium_license );
7879
+ $this->_enrich_site_plan( false );
7880
+ $this->_store_account();
7881
+
7882
+ return;
7883
+ }
7884
+
7885
  $api = $this->get_api_site_scope();
7886
  $license = $api->call( "/licenses/{$premium_license->id}.json", 'put' );
7887
 
8044
  }
8045
  }
8046
 
8047
+ /**
8048
+ * @author Vova Feldman (@svovaf)
8049
+ * @since 1.1.8.1
8050
+ *
8051
+ * @param bool|string $plan_name
8052
+ *
8053
+ * @return bool If trial was successfully started.
8054
+ */
8055
+ function start_trial( $plan_name = false ) {
8056
+ $this->_logger->entrance();
8057
+
8058
+ if ( $this->is_trial() ) {
8059
+ // Already in trial mode.
8060
+ $this->_admin_notices->add(
8061
+ __fs( 'in-trial-mode', $this->_slug ),
8062
+ __fs( 'oops', $this->_slug ) . '...',
8063
+ 'error'
8064
+ );
8065
+
8066
+ return false;
8067
+ }
8068
+
8069
+ if ( $this->_site->is_trial_utilized() ) {
8070
+ // Trial was already utilized.
8071
+ $this->_admin_notices->add(
8072
+ __fs( 'trial-utilized', $this->_slug ),
8073
+ __fs( 'oops', $this->_slug ) . '...',
8074
+ 'error'
8075
+ );
8076
+
8077
+ return false;
8078
+ }
8079
+
8080
+ if ( false !== $plan_name ) {
8081
+ $plan = $this->get_plan_by_name( $plan_name );
8082
+
8083
+ if ( false === $plan ) {
8084
+ // Plan doesn't exist.
8085
+ $this->_admin_notices->add(
8086
+ sprintf( __fs( 'trial-plan-x-not-exist', $this->_slug ), $plan_name ),
8087
+ __fs( 'oops', $this->_slug ) . '...',
8088
+ 'error'
8089
+ );
8090
+
8091
+ return false;
8092
+ }
8093
+
8094
+ if ( ! $plan->has_trial() ) {
8095
+ // Plan doesn't exist.
8096
+ $this->_admin_notices->add(
8097
+ sprintf( __fs( 'plan-x-no-trial', $this->_slug ), $plan_name ),
8098
+ __fs( 'oops', $this->_slug ) . '...',
8099
+ 'error'
8100
+ );
8101
+
8102
+ return false;
8103
+ }
8104
+ } else {
8105
+ if ( ! $this->has_trial_plan() ) {
8106
+ // None of the plans have a trial.
8107
+ $this->_admin_notices->add(
8108
+ __fs( 'no-trials', $this->_slug ),
8109
+ __fs( 'oops', $this->_slug ) . '...',
8110
+ 'error'
8111
+ );
8112
+
8113
+ return false;
8114
+ }
8115
+
8116
+ $plans_with_trial = FS_Plan_Manager::instance()->get_trial_plans( $this->_plans );
8117
+
8118
+ $plan = $plans_with_trial[0];
8119
+ }
8120
+
8121
+ $api = $this->get_api_site_scope();
8122
+ $plan = $api->call( "plans/{$plan->id}/trials.json", 'post' );
8123
+
8124
+ if ( $this->is_api_error( $plan ) ) {
8125
+ // Some API error while trying to start the trial.
8126
+ $this->_admin_notices->add(
8127
+ __fs( 'unexpected-api-error', $this->_slug ) . ' ' . var_export( $plan, true ),
8128
+ __fs( 'oops', $this->_slug ) . '...',
8129
+ 'error'
8130
+ );
8131
+
8132
+ return false;
8133
+ }
8134
+
8135
+ // Sync license.
8136
+ $this->_sync_license();
8137
+
8138
+ return $this->is_trial();
8139
+ }
8140
+
8141
  /**
8142
  * Cancel site trial.
8143
  *
9422
  }
9423
  }
9424
 
9425
+ /**
9426
+ * Adds "Activate License" or "Change License" link to the main Plugins page link actions collection.
9427
+ *
9428
+ * @author Leo Fajardo (@leorw)
9429
+ * @since 1.1.9
9430
+ */
9431
+ function _add_license_action_link() {
9432
+ $this->_logger->entrance();
9433
+
9434
+ $link_text = __fs( $this->is_free_plan() ? 'activate-license' : 'change-license', $this->_slug );
9435
+
9436
+ $this->add_plugin_action_link(
9437
+ $link_text,
9438
+ '#',
9439
+ false,
9440
+ 11,
9441
+ ( 'activate-license ' . $this->_slug )
9442
+ );
9443
+ }
9444
+
9445
  /**
9446
  * Get the URL of the page that should be loaded right after the plugin activation.
9447
  *
freemius/includes/class-fs-api.php CHANGED
@@ -363,9 +363,10 @@
363
 
364
  $pong = is_null( $unique_anonymous_id ) ?
365
  Freemius_Api::Ping() :
366
- $this->_call( 'ping.json?' . http_build_query( array_merge( $params, array(
367
- 'uid' => $unique_anonymous_id,
368
- ) ) ) );
 
369
 
370
  if ( $this->is_valid_ping( $pong ) ) {
371
  return $pong;
@@ -379,9 +380,10 @@
379
 
380
  $pong = is_null( $unique_anonymous_id ) ?
381
  Freemius_Api::Ping() :
382
- $this->_call( 'ping.json?' . http_build_query( array_merge( $params, array(
383
- 'uid' => $unique_anonymous_id,
384
- ) ) ) );
 
385
 
386
  if ( ! $this->is_valid_ping( $pong ) ) {
387
  self::$_options->set_option( 'api_force_http', false, true );
363
 
364
  $pong = is_null( $unique_anonymous_id ) ?
365
  Freemius_Api::Ping() :
366
+ $this->_call( 'ping.json?' . http_build_query( array_merge(
367
+ array( 'uid' => $unique_anonymous_id ),
368
+ $params
369
+ ) ) );
370
 
371
  if ( $this->is_valid_ping( $pong ) ) {
372
  return $pong;
380
 
381
  $pong = is_null( $unique_anonymous_id ) ?
382
  Freemius_Api::Ping() :
383
+ $this->_call( 'ping.json?' . http_build_query( array_merge(
384
+ array( 'uid' => $unique_anonymous_id ),
385
+ $params
386
+ ) ) );
387
 
388
  if ( ! $this->is_valid_ping( $pong ) ) {
389
  self::$_options->set_option( 'api_force_http', false, true );
freemius/includes/class-fs-plugin-updater.php CHANGED
@@ -28,10 +28,10 @@
28
  */
29
  private $_logger;
30
  /**
31
- * @var bool
32
- * @since 1.1.7
33
  */
34
- private $_update_checked = false;
35
 
36
  function __construct( Freemius $freemius ) {
37
  $this->_fs = $freemius;
@@ -167,35 +167,41 @@
167
  $this->_logger->entrance();
168
 
169
  if ( empty( $transient_data ) ||
170
- defined( 'WP_FS__UNINSTALL_MODE' ) ||
171
- /**
172
- * From some reason 'pre_set_site_transient_update_plugins' filter
173
- * is called four times in a row.
174
- *
175
- * @since 1.1.7.3
176
- */
177
- $this->_update_checked
178
  ) {
179
  return $transient_data;
180
  }
181
 
182
- // Get plugin's newest update.
183
- $new_version = $this->_fs->get_update(false, false);
184
-
185
- $this->_update_checked = true;
186
-
187
- if ( is_object( $new_version ) ) {
188
- $this->_logger->log( 'Found newer plugin version ' . $new_version->version );
189
-
190
- $plugin_details = new stdClass();
191
- $plugin_details->slug = $this->_fs->get_slug();
192
- $plugin_details->new_version = $new_version->version;
193
- $plugin_details->url = WP_FS__ADDRESS;
194
- $plugin_details->package = $new_version->url;
195
- $plugin_details->plugin = $this->_fs->get_plugin_basename();
 
 
 
 
 
 
 
 
 
 
 
 
196
 
 
197
  // Add plugin to transient data.
198
- $transient_data->response[ $this->_fs->get_plugin_basename() ] = $plugin_details;
199
  }
200
 
201
  return $transient_data;
28
  */
29
  private $_logger;
30
  /**
31
+ * @var object
32
+ * @since 1.1.8.1
33
  */
34
+ private $_update_details;
35
 
36
  function __construct( Freemius $freemius ) {
37
  $this->_fs = $freemius;
167
  $this->_logger->entrance();
168
 
169
  if ( empty( $transient_data ) ||
170
+ defined( 'WP_FS__UNINSTALL_MODE' )
 
 
 
 
 
 
 
171
  ) {
172
  return $transient_data;
173
  }
174
 
175
+ if ( ! isset( $this->_update_details ) ) {
176
+ // Get plugin's newest update.
177
+ $new_version = $this->_fs->get_update( false, false );
178
+
179
+ $this->_update_details = false;
180
+
181
+ if ( is_object( $new_version ) ) {
182
+ $this->_logger->log( 'Found newer plugin version ' . $new_version->version );
183
+
184
+ $plugin_details = new stdClass();
185
+ $plugin_details->slug = $this->_fs->get_slug();
186
+ $plugin_details->new_version = $new_version->version;
187
+ $plugin_details->url = WP_FS__ADDRESS;
188
+ $plugin_details->package = $new_version->url;
189
+ $plugin_details->plugin = $this->_fs->get_plugin_basename();
190
+
191
+ /**
192
+ * Cache plugin details locally since set_site_transient( 'update_plugins' )
193
+ * called multiple times and the non wp.org plugins are filtered after the
194
+ * call to .org.
195
+ *
196
+ * @since 1.1.8.1
197
+ */
198
+ $this->_update_details = $plugin_details;
199
+ }
200
+ }
201
 
202
+ if ( is_object( $this->_update_details ) ) {
203
  // Add plugin to transient data.
204
+ $transient_data->response[ $this->_fs->get_plugin_basename() ] = $this->_update_details;
205
  }
206
 
207
  return $transient_data;
freemius/includes/debug/class-fs-debug-bar-panel.php CHANGED
@@ -55,6 +55,8 @@
55
  <br>
56
  <?php fs_require_template( '/debug/scheduled-crons.php' ) ?>
57
  <br>
 
 
58
  <?php fs_require_template( '/debug/logger.php' ) ?>
59
  </div>
60
  <?php
55
  <br>
56
  <?php fs_require_template( '/debug/scheduled-crons.php' ) ?>
57
  <br>
58
+ <?php fs_require_template( '/debug/plugins-themes-sync.php' ) ?>
59
+ <br>
60
  <?php fs_require_template( '/debug/logger.php' ) ?>
61
  </div>
62
  <?php
freemius/includes/entities/class-fs-plugin-license.php CHANGED
@@ -31,7 +31,7 @@
31
  */
32
  public $pricing_id;
33
  /**
34
- * @var int
35
  */
36
  public $quota;
37
  /**
@@ -90,6 +90,18 @@
90
  return ( $this->quota - $this->activated - ( $this->is_free_localhost ? 0 : $this->activated_local ) );
91
  }
92
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  /**
94
  * @author Vova Feldman (@svovaf)
95
  * @since 1.0.5
31
  */
32
  public $pricing_id;
33
  /**
34
+ * @var int|null
35
  */
36
  public $quota;
37
  /**
90
  return ( $this->quota - $this->activated - ( $this->is_free_localhost ? 0 : $this->activated_local ) );
91
  }
92
 
93
+ /**
94
+ * Check if single site license.
95
+ *
96
+ * @author Vova Feldman (@svovaf)
97
+ * @since 1.1.8.1
98
+ *
99
+ * @return bool
100
+ */
101
+ function is_single_site() {
102
+ return ( is_numeric( $this->quota ) && 1 == $this->quota );
103
+ }
104
+
105
  /**
106
  * @author Vova Feldman (@svovaf)
107
  * @since 1.0.5
freemius/includes/entities/class-fs-pricing.php CHANGED
@@ -47,4 +47,95 @@
47
  static function get_type() {
48
  return 'pricing';
49
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
47
  static function get_type() {
48
  return 'pricing';
49
  }
50
+
51
+ /**
52
+ * @author Vova Feldman (@svovaf)
53
+ * @since 1.1.8
54
+ *
55
+ * @return bool
56
+ */
57
+ function has_monthly() {
58
+ return ( is_numeric( $this->monthly_price ) && $this->monthly_price > 0 );
59
+ }
60
+
61
+ /**
62
+ * @author Vova Feldman (@svovaf)
63
+ * @since 1.1.8
64
+ *
65
+ * @return bool
66
+ */
67
+ function has_annual() {
68
+ return ( is_numeric( $this->annual_price ) && $this->annual_price > 0 );
69
+ }
70
+
71
+ /**
72
+ * @author Vova Feldman (@svovaf)
73
+ * @since 1.1.8
74
+ *
75
+ * @return bool
76
+ */
77
+ function has_lifetime() {
78
+ return ( is_numeric( $this->lifetime_price ) && $this->lifetime_price > 0 );
79
+ }
80
+
81
+ /**
82
+ * Check if unlimited licenses pricing.
83
+ *
84
+ * @author Vova Feldman (@svovaf)
85
+ * @since 1.1.8
86
+ *
87
+ * @return bool
88
+ */
89
+ function is_unlimited() {
90
+ return is_null( $this->licenses );
91
+ }
92
+
93
+
94
+ /**
95
+ * Check if pricing has more than one billing cycle.
96
+ *
97
+ * @author Vova Feldman (@svovaf)
98
+ * @since 1.1.8
99
+ *
100
+ * @return bool
101
+ */
102
+ function is_multi_cycle() {
103
+ $cycles = 0;
104
+ if ( $this->has_monthly() ) {
105
+ $cycles ++;
106
+ }
107
+ if ( $this->has_annual() ) {
108
+ $cycles ++;
109
+ }
110
+ if ( $this->has_lifetime() ) {
111
+ $cycles ++;
112
+ }
113
+
114
+ return $cycles > 1;
115
+ }
116
+
117
+ /**
118
+ * Get annual over monthly discount.
119
+ *
120
+ * @author Vova Feldman (@svovaf)
121
+ * @since 1.1.8
122
+ *
123
+ * @return int
124
+ */
125
+ function annual_discount_percentage() {
126
+ return floor( $this->annual_savings() / ( $this->monthly_price * 12 * ( $this->is_unlimited() ? 1 : $this->licenses ) ) * 100 );
127
+ }
128
+
129
+ /**
130
+ * Get annual over monthly savings.
131
+ *
132
+ * @author Vova Feldman (@svovaf)
133
+ * @since 1.1.8
134
+ *
135
+ * @return float
136
+ */
137
+ function annual_savings() {
138
+ return ( $this->monthly_price * 12 - $this->annual_price ) * ( $this->is_unlimited() ? 1 : $this->licenses );
139
+ }
140
+
141
  }
freemius/includes/fs-core-functions.php CHANGED
@@ -107,7 +107,19 @@
107
  }
108
 
109
  function fs_request_get_bool( $key, $def = false ) {
110
- return ( isset( $_REQUEST[ $key ] ) && ( 1 == $_REQUEST[ $key ] || 'true' === strtolower( $_REQUEST[ $key ] ) ) ) ? true : $def;
 
 
 
 
 
 
 
 
 
 
 
 
111
  }
112
 
113
  function fs_request_is_post() {
107
  }
108
 
109
  function fs_request_get_bool( $key, $def = false ) {
110
+ if ( ! isset( $_REQUEST[ $key ] ) ) {
111
+ return $def;
112
+ }
113
+
114
+ if ( 1 == $_REQUEST[ $key ] || 'true' === strtolower( $_REQUEST[ $key ] ) ) {
115
+ return true;
116
+ }
117
+
118
+ if ( 0 == $_REQUEST[ $key ] || 'false' === strtolower( $_REQUEST[ $key ] ) ) {
119
+ return false;
120
+ }
121
+
122
+ return $def;
123
  }
124
 
125
  function fs_request_is_post() {
freemius/includes/fs-plugin-info-dialog.php CHANGED
@@ -288,8 +288,8 @@
288
  * @author Vova Feldman (@svovaf)
289
  * @since 1.1.7
290
  *
291
- * @param \FS_Plugin_Plan $plan
292
- * @param \FS_Pricing $pricing
293
  *
294
  * @return float|null|string
295
  */
@@ -566,161 +566,291 @@
566
  ?>
567
  <div id="<?php echo $_tab; ?>-content" class='<?php echo $_with_banner; ?>'>
568
  <div class="fyi">
 
569
  <?php if ( isset( $api->plans ) ) : ?>
570
  <div class="plugin-information-pricing">
571
- <?php foreach ($api->plans as $plan) : ?>
572
  <?php
573
- /**
574
- * @var FS_Plugin_Plan $plan
575
- */
576
  ?>
577
- <h3 data-plan="<?php echo $plan->id ?>"><?php printf( __fs( 'x-plan', $api->slug ), $plan->title ) ?></h3>
578
- <?php if ( $api->is_paid ) : ?>
579
- <ul>
580
- <?php if ( 1 === count( $plan->pricing ) && 1 == $plan->pricing[0]->licenses ) : ?>
581
- <?php $pricing = $plan->pricing[0] ?>
582
- <li><label><?php _efs( 'price', $api->slug ) ?>
583
- : <?php echo $this->get_price_tag( $plan, $pricing ) ?></label></li>
584
- <?php else : ?>
585
- <?php $first = true;
586
- foreach ( $plan->pricing as $pricing ) : ?>
587
- <li><label><input name="pricing-<?php echo $plan->id ?>" type="radio"
588
- value="<?php echo $pricing->id ?>"<?php checked( $first, true ) ?>><?php
589
- switch ( $pricing->licenses ) {
590
- case '1':
591
- _efs( 'license-single-site', $api->slug );
592
- break;
593
- case null:
594
- _efs( 'license-unlimited', $api->slug );
595
- break;
596
- default:
597
- printf( __fs( 'license-x-sites', $api->slug ), $pricing->licenses );
598
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
599
  }
600
- ?> - <?php echo $this->get_price_tag( $plan, $pricing ) ?></label></li>
601
- <?php $first = false; endforeach ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
602
  <?php endif ?>
603
- </ul>
604
- <?php endif ?>
605
- <?php echo $this->get_plugin_cta( $api, $plan ) ?>
606
- <div style="clear:both"></div>
607
- <?php if ( $api->is_paid ) : ?>
608
- <?php if ( $plan->has_trial() ) : ?>
609
- <?php $trial_period = $this->get_trial_period( $plan ) ?>
610
- <ul class="fs-trial-terms">
611
- <li>
612
- <i class="dashicons dashicons-yes"></i><?php printf( __fs( 'no-commitment-x', $api->slug ), $trial_period ) ?>
613
- </li>
614
- <li>
615
- <i class="dashicons dashicons-yes"></i><?php printf( __fs( 'after-x-pay-as-little-y', $api->slug ), $trial_period, $this->get_price_tag( $plan, $plan->pricing[0] ) ) ?>
616
- </li>
617
  </ul>
618
- <?php endif ?>
619
- <?php endif ?>
620
- </div>
621
- <?php endforeach ?>
622
- <?php if ($api->is_paid) : ?>
623
- <?php $plan = $api->plans[0] ?>
624
- <?php $billing_cycle = $this->get_billing_cycle( $plan ) ?>
625
-
626
- <?php wp_enqueue_script( 'jquery' ); ?>
627
- <script type="text/javascript">
628
- (function ($) {
629
- $('.plugin-information-pricing input[type=radio]').click(function () {
630
- var checkout_url = '<?php echo esc_url_raw(add_query_arg(array(
631
- 'plugin_id' => $plan->plugin_id,
632
- 'billing_cycle' => $billing_cycle,
633
- ), $api->checkout_link)) ?>&plan_id=' +
634
- $(this).parents('.plugin-information-pricing').find('h3').attr('data-plan') +
635
- '&pricing_id=' + $(this).val();
636
-
637
- $('.plugin-information-pricing .button, #plugin-information-footer .button').attr('href', checkout_url);
638
- });
639
- })(jQuery);
640
- </script>
641
- <?php endif ?>
642
  <?php endif ?>
643
- <div>
644
- <h3><?php _efs( 'details', $api->slug ) ?></h3>
645
- <ul>
646
- <?php if ( ! empty( $api->version ) ) { ?>
647
- <li><strong><?php _e( 'Version:' ); ?></strong> <?php echo $api->version; ?></li>
 
 
 
 
 
 
 
 
648
  <?php
649
  }
650
- if ( ! empty( $api->author ) ) {
651
- ?>
652
- <li>
653
- <strong><?php _e( 'Author:' ); ?></strong> <?php echo links_add_target( $api->author, '_blank' ); ?>
654
- </li>
655
- <?php
656
- }
657
- if ( ! empty( $api->last_updated ) ) {
658
- ?>
659
- <li><strong><?php _e( 'Last Updated:' ); ?></strong> <span
660
- title="<?php echo $api->last_updated; ?>">
661
  <?php printf( __( '%s ago' ), human_time_diff( strtotime( $api->last_updated ) ) ); ?>
662
  </span></li>
663
- <?php
664
- }
665
- if ( ! empty( $api->requires ) ) {
666
- ?>
667
- <li>
668
- <strong><?php _e( 'Requires WordPress Version:' ); ?></strong> <?php printf( __( '%s or higher' ), $api->requires ); ?>
669
- </li>
670
- <?php
671
- }
672
- if ( ! empty( $api->tested ) ) {
673
- ?>
674
- <li><strong><?php _e( 'Compatible up to:' ); ?></strong> <?php echo $api->tested; ?>
675
- </li>
676
- <?php
677
- }
678
- if ( ! empty( $api->downloaded ) ) {
679
- ?>
680
- <li>
681
- <strong><?php _e( 'Downloaded:' ); ?></strong> <?php printf( _n( '%s time', '%s times', $api->downloaded ), number_format_i18n( $api->downloaded ) ); ?>
682
- </li>
683
- <?php
684
- }
685
- if ( ! empty( $api->slug ) && empty( $api->external ) ) {
686
- ?>
687
- <li><a target="_blank"
688
- href="https://wordpress.org/plugins/<?php echo $api->slug; ?>/"><?php _e( 'WordPress.org Plugin Page &#187;' ); ?></a>
689
- </li>
690
- <?php
691
- }
692
- if ( ! empty( $api->homepage ) ) {
693
- ?>
694
- <li><a target="_blank"
695
- href="<?php echo esc_url( $api->homepage ); ?>"><?php _e( 'Plugin Homepage &#187;' ); ?></a>
696
- </li>
697
- <?php
698
- }
699
- if ( ! empty( $api->donate_link ) && empty( $api->contributors ) ) {
700
- ?>
701
- <li><a target="_blank"
702
- href="<?php echo esc_url( $api->donate_link ); ?>"><?php _e( 'Donate to this plugin &#187;' ); ?></a>
703
- </li>
704
- <?php } ?>
705
- </ul>
706
- </div>
707
- <?php if ( ! empty( $api->rating ) ) { ?>
708
- <h3><?php _e( 'Average Rating' ); ?></h3>
709
- <?php wp_star_rating( array(
710
- 'rating' => $api->rating,
711
- 'type' => 'percent',
712
- 'number' => $api->num_ratings
713
- ) ); ?>
714
- <small><?php printf( _n( '(based on %s rating)', '(based on %s ratings)', $api->num_ratings ), number_format_i18n( $api->num_ratings ) ); ?></small>
715
- <?php
716
- }
717
-
718
- if ( ! empty( $api->ratings ) && array_sum( (array) $api->ratings ) > 0 ) {
719
- foreach ( $api->ratings as $key => $ratecount ) {
720
- // Avoid div-by-zero.
721
- $_rating = $api->num_ratings ? ( $ratecount / $api->num_ratings ) : 0;
722
  ?>
723
- <div class="counter-container">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
724
  <span class="counter-label"><a
725
  href="https://wordpress.org/support/view/plugin-reviews/<?php echo $api->slug; ?>?filter=<?php echo $key; ?>"
726
  target="_blank"
@@ -728,37 +858,37 @@
728
  <span class="counter-back">
729
  <span class="counter-bar" style="width: <?php echo 92 * $_rating; ?>px;"></span>
730
  </span>
731
- <span class="counter-count"><?php echo number_format_i18n( $ratecount ); ?></span>
732
- </div>
733
- <?php
734
- }
735
  }
736
- if ( ! empty( $api->contributors ) ) {
737
- ?>
738
- <h3><?php _e( 'Contributors' ); ?></h3>
739
- <ul class="contributors">
740
- <?php
741
- foreach ( (array) $api->contributors as $contrib_username => $contrib_profile ) {
742
- if ( empty( $contrib_username ) && empty( $contrib_profile ) ) {
743
- continue;
744
- }
745
- if ( empty( $contrib_username ) ) {
746
- $contrib_username = preg_replace( '/^.+\/(.+)\/?$/', '\1', $contrib_profile );
747
- }
748
- $contrib_username = sanitize_user( $contrib_username );
749
- if ( empty( $contrib_profile ) ) {
750
- echo "<li><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&amp;s=36' width='18' height='18' />{$contrib_username}</li>";
751
- } else {
752
- echo "<li><a href='{$contrib_profile}' target='_blank'><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&amp;s=36' width='18' height='18' />{$contrib_username}</a></li>";
753
- }
754
  }
755
- ?>
756
- </ul>
757
- <?php if ( ! empty( $api->donate_link ) ) { ?>
758
- <a target="_blank"
759
- href="<?php echo esc_url( $api->donate_link ); ?>"><?php _e( 'Donate to this plugin &#187;' ); ?></a>
760
- <?php } ?>
 
 
 
 
 
 
 
 
 
761
  <?php } ?>
 
762
  </div>
763
  <div id="section-holder" class="wrap">
764
  <?php
@@ -783,7 +913,7 @@
783
  $missing_notice = array(
784
  'type' => 'error',
785
  'id' => md5( microtime() ),
786
- 'message' => __fs( ($api->is_paid ? 'paid-addon-not-deployed' : 'free-addon-not-deployed'), $api->slug ),
787
  );
788
  fs_require_template( 'admin-notice.php', $missing_notice );
789
  }
288
  * @author Vova Feldman (@svovaf)
289
  * @since 1.1.7
290
  *
291
+ * @param FS_Plugin_Plan $plan
292
+ * @param FS_Pricing $pricing
293
  *
294
  * @return float|null|string
295
  */
566
  ?>
567
  <div id="<?php echo $_tab; ?>-content" class='<?php echo $_with_banner; ?>'>
568
  <div class="fyi">
569
+ <?php if ( $api->is_paid ) : ?>
570
  <?php if ( isset( $api->plans ) ) : ?>
571
  <div class="plugin-information-pricing">
572
+ <?php foreach ( $api->plans as $plan ) : ?>
573
  <?php
574
+ /**
575
+ * @var FS_Plugin_Plan $plan
576
+ */
577
  ?>
578
+ <?php $first_pricing = $plan->pricing[0] ?>
579
+ <?php $is_multi_cycle = $first_pricing->is_multi_cycle() ?>
580
+ <div class="fs-plan<?php if ( ! $is_multi_cycle ) {
581
+ echo ' fs-single-cycle';
582
+ } ?>" data-plan-id="<?php echo $plan->id ?>">
583
+ <h3 data-plan="<?php echo $plan->id ?>"><?php printf( __fs( 'x-plan', $api->slug ), $plan->title ) ?></h3>
584
+ <?php $has_annual = $first_pricing->has_annual() ?>
585
+ <?php $has_monthly = $first_pricing->has_monthly() ?>
586
+ <div class="nav-tab-wrapper">
587
+ <?php $billing_cycles = array( 'monthly', 'annual', 'lifetime' ) ?>
588
+ <?php $i = 0;
589
+ foreach ( $billing_cycles as $cycle ) : ?>
590
+ <?php $prop = "{$cycle}_price";
591
+ if ( isset( $first_pricing->{$prop} ) ) : ?>
592
+ <?php $is_featured = ( 'annual' === $cycle && $is_multi_cycle ) ?>
593
+ <?php
594
+ $prices = array();
595
+ foreach ( $plan->pricing as $pricing ) {
596
+ if ( isset( $pricing->{$prop} ) ) {
597
+ $prices[] = array(
598
+ 'id' => $pricing->id,
599
+ 'licenses' => $pricing->licenses,
600
+ 'price' => $pricing->{$prop}
601
+ );
602
+ }
603
+ }
604
+ ?>
605
+ <a class="nav-tab" data-billing-cycle="<?php echo $cycle ?>"
606
+ data-pricing="<?php esc_attr_e( json_encode( $prices ) ) ?>">
607
+ <?php if ( $is_featured ) : ?>
608
+ <label>&#9733; <?php _efs( 'best', $api->slug ) ?> &#9733;</label>
609
+ <?php endif ?>
610
+ <?php _efs( $cycle, $api->slug ) ?>
611
+ </a>
612
+ <?php endif ?>
613
+ <?php $i ++; endforeach ?>
614
+ <?php wp_enqueue_script( 'jquery' ) ?>
615
+ <script type="text/javascript">
616
+ (function ($, undef) {
617
+ var
618
+ _formatBillingFrequency = function (cycle) {
619
+ switch (cycle) {
620
+ case 'monthly':
621
+ return '<?php printf(__fs('billed-x', $api->slug), __fs('monthly', $api->slug)) ?>';
622
+ case 'annual':
623
+ return '<?php printf(__fs('billed-x', $api->slug), __fs('annually', $api->slug)) ?>';
624
+ case 'lifetime':
625
+ return '<?php printf(__fs('billed-x', $api->slug), __fs('once', $api->slug)) ?>';
626
+ }
627
+ },
628
+ _formatLicensesTitle = function (pricing) {
629
+ switch (pricing.licenses) {
630
+ case 1:
631
+ return '<?php _efs( 'license-single-site', $api->slug ) ?>';
632
+ case null:
633
+ return '<?php _efs( 'license-unlimited', $api->slug ) ?>';
634
+ default:
635
+ return '<?php _efs( 'license-x-sites', $api->slug ) ?>'.replace('%s', pricing.licenses);
636
+ }
637
+ },
638
+ _formatPrice = function (pricing, cycle, multipleLicenses) {
639
+ if (undef === multipleLicenses)
640
+ multipleLicenses = true;
641
+
642
+ var priceCycle;
643
+ switch (cycle) {
644
+ case 'monthly':
645
+ priceCycle = ' / <?php _efs('mo', $api->slug) ?>';
646
+ break;
647
+ case 'lifetime':
648
+ priceCycle = '';
649
+ break;
650
+ case 'annual':
651
+ default:
652
+ priceCycle = ' / <?php _efs('year', $api->slug) ?>';
653
+ break;
654
+ }
655
+
656
+ if (!multipleLicenses && 1 == pricing.licenses) {
657
+ return '$' + pricing.price + priceCycle;
658
+ }
659
+
660
+ return _formatLicensesTitle(pricing) + ' - <var class="fs-price">$' + pricing.price + priceCycle + '</var>';
661
+ },
662
+ _checkoutUrl = function (plan, pricing, cycle) {
663
+ return '<?php echo esc_url_raw(remove_query_arg('billing_cycle', add_query_arg(array('plugin_id' => $plan->plugin_id), $api->checkout_link))) ?>' +
664
+ '&plan_id=' + plan +
665
+ '&pricing_id=' + pricing +
666
+ '&billing_cycle=' + cycle<?php if ($plan->has_trial()) { echo " + '&trial=true'"; }?>;
667
+ },
668
+ _updateCtaUrl = function (plan, pricing, cycle) {
669
+ $('.plugin-information-pricing .button, #plugin-information-footer .button').attr('href', _checkoutUrl(plan, pricing, cycle));
670
+ };
671
+
672
+ $(document).ready(function () {
673
+ var $plan = $('.plugin-information-pricing .fs-plan[data-plan-id=<?php echo $plan->id ?>]');
674
+ $plan.find('input[type=radio]').live('click', function () {
675
+ _updateCtaUrl(
676
+ $plan.attr('data-plan-id'),
677
+ $(this).val(),
678
+ $plan.find('.nav-tab-active').attr('data-billing-cycle')
679
+ );
680
+
681
+ $plan.find('.fs-trial-terms .fs-price').html(
682
+ $(this).parents('label').find('.fs-price').html()
683
+ );
684
+ });
685
+
686
+ $plan.find('.nav-tab').click(function () {
687
+ if ($(this).hasClass('nav-tab-active'))
688
+ return;
689
+
690
+ var $this = $(this),
691
+ billingCycle = $this.attr('data-billing-cycle'),
692
+ pricing = JSON.parse($this.attr('data-pricing')),
693
+ $pricesList = $this.parents('.fs-plan').find('.fs-pricing-body .fs-licenses'),
694
+ html = '';
695
+
696
+ // Un-select previously selected tab.
697
+ $plan.find('.nav-tab').removeClass('nav-tab-active');
698
+
699
+ // Select current tab.
700
+ $this.addClass('nav-tab-active');
701
+
702
+ // Render licenses prices.
703
+ if (1 == pricing.length) {
704
+ html = '<li><label><?php _efs( 'price', $api->slug ) ?>: ' + _formatPrice(pricing[0], billingCycle, false) + '</label></li>';
705
+ } else {
706
+ for (var i = 0; i < pricing.length; i++) {
707
+ html += '<li><label><input name="pricing-<?php echo $plan->id ?>" type="radio" value="' + pricing[i].id + '">' + _formatPrice(pricing[i], billingCycle) + '</label></li>';
708
  }
709
+ }
710
+ $pricesList.html(html);
711
+
712
+ if (1 < pricing.length) {
713
+ // Select first license option.
714
+ $pricesList.find('li:first input').click();
715
+ }
716
+ else {
717
+ _updateCtaUrl(
718
+ $plan.attr('data-plan-id'),
719
+ pricing[0].id,
720
+ billingCycle
721
+ );
722
+ }
723
+
724
+ // Update billing frequency.
725
+ $plan.find('.fs-billing-frequency').html(_formatBillingFrequency(billingCycle));
726
+
727
+ if ('annual' === billingCycle) {
728
+ $plan.find('.fs-annual-discount').show();
729
+ } else {
730
+ $plan.find('.fs-annual-discount').hide();
731
+ }
732
+ });
733
+
734
+ <?php if ( $has_annual ) : ?>
735
+ // Select annual by default.
736
+ $plan.find('.nav-tab[data-billing-cycle=annual]').click();
737
+ <?php else : ?>
738
+ // Select first tab.
739
+ $plan.find('.nav-tab:first').click();
740
+ <?php endif ?>
741
+ });
742
+ }(jQuery));
743
+ </script>
744
+ </div>
745
+ <div class="fs-pricing-body">
746
+ <span class="fs-billing-frequency"></span>
747
+ <?php $annual_discount = ( $has_annual && $has_monthly ) ? $plan->pricing[0]->annual_discount_percentage() : 0 ?>
748
+ <?php if ( $annual_discount > 0 ) : ?>
749
+ <span
750
+ class="fs-annual-discount"><?php printf( __fs( 'save-x', $api->slug ), $annual_discount . '%' ) ?></span>
751
  <?php endif ?>
752
+ <ul class="fs-licenses">
 
 
 
 
 
 
 
 
 
 
 
 
 
753
  </ul>
754
+ <?php echo $this->get_plugin_cta( $api, $plan ) ?>
755
+ <div style="clear:both"></div>
756
+ <?php if ( $plan->has_trial() ) : ?>
757
+ <?php $trial_period = $this->get_trial_period( $plan ) ?>
758
+ <ul class="fs-trial-terms">
759
+ <li>
760
+ <i class="dashicons dashicons-yes"></i><?php printf( __fs( 'no-commitment-x', $api->slug ), $trial_period ) ?>
761
+ </li>
762
+ <li>
763
+ <i class="dashicons dashicons-yes"></i><?php printf( __fs( 'after-x-pay-as-little-y', $api->slug ), $trial_period, '<var class="fs-price">' . $this->get_price_tag( $plan, $plan->pricing[0] ) . '</var>' ) ?>
764
+ </li>
765
+ </ul>
766
+ <?php endif ?>
767
+ </div>
768
+ </div>
769
+ </div>
770
+ <?php endforeach ?>
 
 
 
 
 
 
 
771
  <?php endif ?>
772
+ <?php endif ?>
773
+ <div>
774
+ <h3><?php _efs( 'details', $api->slug ) ?></h3>
775
+ <ul>
776
+ <?php if ( ! empty( $api->version ) ) { ?>
777
+ <li><strong><?php _e( 'Version:' ); ?></strong> <?php echo $api->version; ?></li>
778
+ <?php
779
+ }
780
+ if ( ! empty( $api->author ) ) {
781
+ ?>
782
+ <li>
783
+ <strong><?php _e( 'Author:' ); ?></strong> <?php echo links_add_target( $api->author, '_blank' ); ?>
784
+ </li>
785
  <?php
786
  }
787
+ if ( ! empty( $api->last_updated ) ) {
788
+ ?>
789
+ <li><strong><?php _e( 'Last Updated:' ); ?></strong> <span
790
+ title="<?php echo $api->last_updated; ?>">
 
 
 
 
 
 
 
791
  <?php printf( __( '%s ago' ), human_time_diff( strtotime( $api->last_updated ) ) ); ?>
792
  </span></li>
793
+ <?php
794
+ }
795
+ if ( ! empty( $api->requires ) ) {
796
+ ?>
797
+ <li>
798
+ <strong><?php _e( 'Requires WordPress Version:' ); ?></strong> <?php printf( __( '%s or higher' ), $api->requires ); ?>
799
+ </li>
800
+ <?php
801
+ }
802
+ if ( ! empty( $api->tested ) ) {
803
+ ?>
804
+ <li><strong><?php _e( 'Compatible up to:' ); ?></strong> <?php echo $api->tested; ?>
805
+ </li>
806
+ <?php
807
+ }
808
+ if ( ! empty( $api->downloaded ) ) {
809
+ ?>
810
+ <li>
811
+ <strong><?php _e( 'Downloaded:' ); ?></strong> <?php printf( _n( '%s time', '%s times', $api->downloaded ), number_format_i18n( $api->downloaded ) ); ?>
812
+ </li>
813
+ <?php
814
+ }
815
+ if ( ! empty( $api->slug ) && empty( $api->external ) ) {
816
+ ?>
817
+ <li><a target="_blank"
818
+ href="https://wordpress.org/plugins/<?php echo $api->slug; ?>/"><?php _e( 'WordPress.org Plugin Page &#187;' ); ?></a>
819
+ </li>
820
+ <?php
821
+ }
822
+ if ( ! empty( $api->homepage ) ) {
823
+ ?>
824
+ <li><a target="_blank"
825
+ href="<?php echo esc_url( $api->homepage ); ?>"><?php _e( 'Plugin Homepage &#187;' ); ?></a>
826
+ </li>
827
+ <?php
828
+ }
829
+ if ( ! empty( $api->donate_link ) && empty( $api->contributors ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
830
  ?>
831
+ <li><a target="_blank"
832
+ href="<?php echo esc_url( $api->donate_link ); ?>"><?php _e( 'Donate to this plugin &#187;' ); ?></a>
833
+ </li>
834
+ <?php } ?>
835
+ </ul>
836
+ </div>
837
+ <?php if ( ! empty( $api->rating ) ) { ?>
838
+ <h3><?php _e( 'Average Rating' ); ?></h3>
839
+ <?php wp_star_rating( array(
840
+ 'rating' => $api->rating,
841
+ 'type' => 'percent',
842
+ 'number' => $api->num_ratings
843
+ ) ); ?>
844
+ <small><?php printf( _n( '(based on %s rating)', '(based on %s ratings)', $api->num_ratings ), number_format_i18n( $api->num_ratings ) ); ?></small>
845
+ <?php
846
+ }
847
+
848
+ if ( ! empty( $api->ratings ) && array_sum( (array) $api->ratings ) > 0 ) {
849
+ foreach ( $api->ratings as $key => $ratecount ) {
850
+ // Avoid div-by-zero.
851
+ $_rating = $api->num_ratings ? ( $ratecount / $api->num_ratings ) : 0;
852
+ ?>
853
+ <div class="counter-container">
854
  <span class="counter-label"><a
855
  href="https://wordpress.org/support/view/plugin-reviews/<?php echo $api->slug; ?>?filter=<?php echo $key; ?>"
856
  target="_blank"
858
  <span class="counter-back">
859
  <span class="counter-bar" style="width: <?php echo 92 * $_rating; ?>px;"></span>
860
  </span>
861
+ <span class="counter-count"><?php echo number_format_i18n( $ratecount ); ?></span>
862
+ </div>
863
+ <?php
 
864
  }
865
+ }
866
+ if ( ! empty( $api->contributors ) ) {
867
+ ?>
868
+ <h3><?php _e( 'Contributors' ); ?></h3>
869
+ <ul class="contributors">
870
+ <?php
871
+ foreach ( (array) $api->contributors as $contrib_username => $contrib_profile ) {
872
+ if ( empty( $contrib_username ) && empty( $contrib_profile ) ) {
873
+ continue;
 
 
 
 
 
 
 
 
 
874
  }
875
+ if ( empty( $contrib_username ) ) {
876
+ $contrib_username = preg_replace( '/^.+\/(.+)\/?$/', '\1', $contrib_profile );
877
+ }
878
+ $contrib_username = sanitize_user( $contrib_username );
879
+ if ( empty( $contrib_profile ) ) {
880
+ echo "<li><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&amp;s=36' width='18' height='18' />{$contrib_username}</li>";
881
+ } else {
882
+ echo "<li><a href='{$contrib_profile}' target='_blank'><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&amp;s=36' width='18' height='18' />{$contrib_username}</a></li>";
883
+ }
884
+ }
885
+ ?>
886
+ </ul>
887
+ <?php if ( ! empty( $api->donate_link ) ) { ?>
888
+ <a target="_blank"
889
+ href="<?php echo esc_url( $api->donate_link ); ?>"><?php _e( 'Donate to this plugin &#187;' ); ?></a>
890
  <?php } ?>
891
+ <?php } ?>
892
  </div>
893
  <div id="section-holder" class="wrap">
894
  <?php
913
  $missing_notice = array(
914
  'type' => 'error',
915
  'id' => md5( microtime() ),
916
+ 'message' => __fs( ( $api->is_paid ? 'paid-addon-not-deployed' : 'free-addon-not-deployed' ), $api->slug ),
917
  );
918
  fs_require_template( 'admin-notice.php', $missing_notice );
919
  }
freemius/includes/i18n.php CHANGED
@@ -98,6 +98,7 @@
98
  'verified' => __( 'Verified', 'freemius' ),
99
  'plugin' => __( 'Plugin', 'freemius' ),
100
  'plugins' => __( 'Plugins', 'freemius' ),
 
101
  'path' => _x( 'Path', 'as file/folder path', 'freemius' ),
102
  'title' => __( 'Title', 'freemius' ),
103
  'free-version' => __( 'Free version', 'freemius' ),
@@ -115,9 +116,16 @@
115
  'no-id' => __( 'No ID', 'freemius' ),
116
  'sync-license' => _x( 'Sync License', 'as synchronize license', 'freemius' ),
117
  'sync' => _x( 'Sync', 'as synchronize', 'freemius' ),
 
 
 
 
 
 
118
  'deactivate-license' => __( 'Deactivate License', 'freemius' ),
119
  'activate' => __( 'Activate', 'freemius' ),
120
  'deactivate' => __( 'Deactivate', 'freemius' ),
 
121
  'no-deactivate' => __( 'No - just deactivate', 'freemius' ),
122
  'yes-do-your-thing' => __( 'Yes - do your thing', 'freemius' ),
123
  'active' => _x( 'Active', 'active mode', 'freemius' ),
@@ -127,6 +135,8 @@
127
  'more-information-about-x' => __( 'More information about %s', 'freemius' ),
128
  'localhost' => __( 'Localhost', 'freemius' ),
129
  'activate-x-plan' => _x( 'Activate %s Plan', 'as activate Professional plan', 'freemius' ),
 
 
130
  'what-is-your-x' => __( 'What is your %s?', 'freemius' ),
131
  'activate-this-addon' => __( 'Activate this add-on', 'freemius' ),
132
  'deactivate-license-confirm' => __( 'Deactivating your license will block all premium features, but will enable you to activate the license on another site. Are you sure you want to proceed?', 'freemius' ),
@@ -152,7 +162,9 @@
152
  'reason-broke-my-site' => __( 'The plugin broke my site', 'freemius' ),
153
  'reason-suddenly-stopped-working' => __( 'The plugin suddenly stopped working', 'freemius' ),
154
  'reason-cant-pay-anymore' => __( "I can't pay for it anymore", 'freemius' ),
 
155
  'reason-other' => _x( 'Other', 'the text of the "other" reason for deactivating the plugin that is shown in the modal box.', 'freemius' ),
 
156
  'placeholder-plugin-name' => __( "What's the plugin's name?", 'freemius' ),
157
  'placeholder-comfortable-price' => __( 'What price would you feel comfortable paying?', 'freemius' ),
158
  'reason-couldnt-make-it-work' => __( "I couldn't understand how to make it work", 'freemius' ),
@@ -174,13 +186,17 @@
174
  'connect-message' => __( 'In order to enjoy all our features and functionality, %s needs to connect your user, %s at %s, to %s', 'freemius' ),
175
  'connect-message_on-update' => __( 'Please help us improve %2$s! If you opt-in, some data about your usage of %2$s will be sent to %5$s. If you skip this, that\'s okay! %2$s will still work just fine.', 'freemius' ),
176
  'pending-activation-message' => __( 'You should receive an activation email for %s to your mailbox at %s. Please make sure you click the activation button in that email to complete the install.', 'freemius' ),
 
 
177
  'what-permissions' => __( 'What permissions are being granted?', 'freemius' ),
178
  'permissions-profile' => __( 'Your Profile Overview', 'freemius' ),
179
  'permissions-profile_desc' => __( 'Name and email address', 'freemius' ),
180
  'permissions-site' => __( 'Your Site Overview', 'freemius' ),
181
- 'permissions-site_desc' => __( 'Site address, WordPress version, PHP Version', 'freemius' ),
182
- 'permissions-events' => __( 'Plugin Events', 'freemius' ),
183
  'permissions-events_desc' => __( 'Activation, deactivation and uninstall', 'freemius' ),
 
 
184
  'permissions-newsletter' => __( 'Newsletter', 'freemius' ),
185
  'permissions-newsletter_desc' => __( 'Updates, announcements, marketing, no spam', 'freemius' ),
186
  'privacy-policy' => __( 'Privacy Policy', 'freemius' ),
@@ -188,8 +204,12 @@
188
  'activating' => _x( 'Activating', 'as activating plugin', 'freemius' ),
189
  'sending-email' => _x( 'Sending email', 'as in the process of sending an email', 'freemius' ),
190
  'opt-in-connect' => _x( 'Allow & Continue', 'button label', 'freemius' ),
 
191
  'skip' => _x( 'Skip', 'verb', 'freemius' ),
192
  'resend-activation-email' => __( 'Re-send activation email', 'freemius' ),
 
 
 
193
  #endregion Connect
194
 
195
  #region Screenshots
@@ -218,6 +238,7 @@
218
  'clear-api-cache' => __( 'Clear API Cache', 'freemius' ),
219
  'sync-data-from-server' => __( 'Sync Data From Server', 'freemius' ),
220
  'scheduled-crons' => __( 'Scheduled Crons', 'freemius' ),
 
221
  #endregion Debug
222
 
223
  #region Expressions
@@ -255,6 +276,7 @@
255
  'plan-upgraded-message' => __( 'Your plan was successfully upgraded.', 'freemius' ),
256
  'plan-changed-to-x-message' => __( 'Your plan was successfully changed to %s.', 'freemius' ),
257
  'license-expired-blocking-message' => __( 'Your license has expired. You can still continue using the free plugin forever.', 'freemius' ),
 
258
  'trial-started-message' => __( 'Your trial has been successfully started.', 'freemius' ),
259
  'license-activated-message' => __( 'Your license was successfully activated.', 'freemius' ),
260
  'no-active-license-message' => __( 'It looks like your site currently doesn\'t have an active license.', 'freemius' ),
@@ -273,6 +295,12 @@
273
  'trial-x-promotion-message' => __( 'How do you like %s so far? Test all our %s premium features with a %d-day free trial.', 'freemius' ),
274
  'start-free-trial' => _x( 'Start free trial', 'call to action', 'freemius' ),
275
  'trial-cancel-failure-message' => __( 'Seems like we are having some temporary issue with your trial cancellation. Please try again in few minutes.', 'freemius' ),
 
 
 
 
 
 
276
  'no-commitment-for-x-days' => __( 'No commitment for %s days - cancel anytime!', 'freemius' ),
277
  'license-expired-non-blocking-message' => __( 'Your license has expired. You can still continue using all the %s features, but you\'ll need to renew your license to continue getting updates and support.', 'freemius' ),
278
  'could-not-activate-x' => __( 'Couldn\'t activate %s.', 'freemius' ),
@@ -321,4 +349,17 @@
321
  'addon-no-license-message' => __( '%s is a premium only add-on. You have to purchase a license first before activating the plugin.', 'freemius' ),
322
  'addon-trial-cancelled-message' => __( '%s free trial was successfully cancelled. Since the add-on is premium only it was automatically deactivated. If you like to use it in the future, you\'ll have to purchase a license.', 'freemius' ),
323
  #endregion Add-On Licensing
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  );
98
  'verified' => __( 'Verified', 'freemius' ),
99
  'plugin' => __( 'Plugin', 'freemius' ),
100
  'plugins' => __( 'Plugins', 'freemius' ),
101
+ 'themes' => __( 'Themes', 'freemius' ),
102
  'path' => _x( 'Path', 'as file/folder path', 'freemius' ),
103
  'title' => __( 'Title', 'freemius' ),
104
  'free-version' => __( 'Free version', 'freemius' ),
116
  'no-id' => __( 'No ID', 'freemius' ),
117
  'sync-license' => _x( 'Sync License', 'as synchronize license', 'freemius' ),
118
  'sync' => _x( 'Sync', 'as synchronize', 'freemius' ),
119
+ 'activate-license' => __( 'Activate License', 'freemius' ),
120
+ 'activate-free-version' => __( 'Activate Free Version', 'freemius' ),
121
+ 'activate-license-message' => __( 'Please enter the license key that you received in the email right after the purchase:', 'freemius' ),
122
+ 'activating-license' => __( 'Activating license...', 'freemius' ),
123
+ 'change-license' => __( 'Change License', 'freemius' ),
124
+ 'update-license' => __( 'Update License', 'freemius' ),
125
  'deactivate-license' => __( 'Deactivate License', 'freemius' ),
126
  'activate' => __( 'Activate', 'freemius' ),
127
  'deactivate' => __( 'Deactivate', 'freemius' ),
128
+ 'skip-deactivate' => __( 'Skip & Deactivate', 'freemius' ),
129
  'no-deactivate' => __( 'No - just deactivate', 'freemius' ),
130
  'yes-do-your-thing' => __( 'Yes - do your thing', 'freemius' ),
131
  'active' => _x( 'Active', 'active mode', 'freemius' ),
135
  'more-information-about-x' => __( 'More information about %s', 'freemius' ),
136
  'localhost' => __( 'Localhost', 'freemius' ),
137
  'activate-x-plan' => _x( 'Activate %s Plan', 'as activate Professional plan', 'freemius' ),
138
+ 'x-left' => _x( '%s left', 'as 5 licenses left', 'freemius' ),
139
+ 'last-license' => __( 'Last license', 'freemius' ),
140
  'what-is-your-x' => __( 'What is your %s?', 'freemius' ),
141
  'activate-this-addon' => __( 'Activate this add-on', 'freemius' ),
142
  'deactivate-license-confirm' => __( 'Deactivating your license will block all premium features, but will enable you to activate the license on another site. Are you sure you want to proceed?', 'freemius' ),
162
  'reason-broke-my-site' => __( 'The plugin broke my site', 'freemius' ),
163
  'reason-suddenly-stopped-working' => __( 'The plugin suddenly stopped working', 'freemius' ),
164
  'reason-cant-pay-anymore' => __( "I can't pay for it anymore", 'freemius' ),
165
+ 'reason-temporary-deactivation' => __( "It's a temporary deactivation. I'm just debugging an issue.", 'freemius' ),
166
  'reason-other' => _x( 'Other', 'the text of the "other" reason for deactivating the plugin that is shown in the modal box.', 'freemius' ),
167
+ 'ask-for-reason-message' => __( 'Kindly tell us the reason so we can improve.', 'freemius' ),
168
  'placeholder-plugin-name' => __( "What's the plugin's name?", 'freemius' ),
169
  'placeholder-comfortable-price' => __( 'What price would you feel comfortable paying?', 'freemius' ),
170
  'reason-couldnt-make-it-work' => __( "I couldn't understand how to make it work", 'freemius' ),
186
  'connect-message' => __( 'In order to enjoy all our features and functionality, %s needs to connect your user, %s at %s, to %s', 'freemius' ),
187
  'connect-message_on-update' => __( 'Please help us improve %2$s! If you opt-in, some data about your usage of %2$s will be sent to %5$s. If you skip this, that\'s okay! %2$s will still work just fine.', 'freemius' ),
188
  'pending-activation-message' => __( 'You should receive an activation email for %s to your mailbox at %s. Please make sure you click the activation button in that email to complete the install.', 'freemius' ),
189
+ 'thanks-for-purchasing' => __( 'Thanks for purchasing %s! To get started, please enter your license key:', 'freemius' ),
190
+ 'license-sync-disclaimer' => __( 'The plugin will be periodically sending data to %s to check for plugin updates and verify the validity of your license.', 'freemius' ),
191
  'what-permissions' => __( 'What permissions are being granted?', 'freemius' ),
192
  'permissions-profile' => __( 'Your Profile Overview', 'freemius' ),
193
  'permissions-profile_desc' => __( 'Name and email address', 'freemius' ),
194
  'permissions-site' => __( 'Your Site Overview', 'freemius' ),
195
+ 'permissions-site_desc' => __( 'Site URL, WP version, PHP info, plugins & themes', 'freemius' ),
196
+ 'permissions-events' => __( 'Current Plugin Events', 'freemius' ),
197
  'permissions-events_desc' => __( 'Activation, deactivation and uninstall', 'freemius' ),
198
+ 'permissions-plugins_themes' => __( 'Plugins & Themes', 'freemius' ),
199
+ 'permissions-plugins_themes_desc' => __( 'Titles, versions and state.', 'freemius' ),
200
  'permissions-newsletter' => __( 'Newsletter', 'freemius' ),
201
  'permissions-newsletter_desc' => __( 'Updates, announcements, marketing, no spam', 'freemius' ),
202
  'privacy-policy' => __( 'Privacy Policy', 'freemius' ),
204
  'activating' => _x( 'Activating', 'as activating plugin', 'freemius' ),
205
  'sending-email' => _x( 'Sending email', 'as in the process of sending an email', 'freemius' ),
206
  'opt-in-connect' => _x( 'Allow & Continue', 'button label', 'freemius' ),
207
+ 'agree-activate-license' => _x( 'Agree & Activate License', 'button label', 'freemius' ),
208
  'skip' => _x( 'Skip', 'verb', 'freemius' ),
209
  'resend-activation-email' => __( 'Re-send activation email', 'freemius' ),
210
+ 'license-key' => __( 'License key', 'freemius' ),
211
+ 'have-license-key' => __( 'Have a license key?', 'freemius' ),
212
+ 'dont-have-license-key' => __( 'Don\'t have a license key?', 'freemius' ),
213
  #endregion Connect
214
 
215
  #region Screenshots
238
  'clear-api-cache' => __( 'Clear API Cache', 'freemius' ),
239
  'sync-data-from-server' => __( 'Sync Data From Server', 'freemius' ),
240
  'scheduled-crons' => __( 'Scheduled Crons', 'freemius' ),
241
+ 'plugins-themes-sync' => __( 'Plugins & Themes Sync', 'freemius' ),
242
  #endregion Debug
243
 
244
  #region Expressions
276
  'plan-upgraded-message' => __( 'Your plan was successfully upgraded.', 'freemius' ),
277
  'plan-changed-to-x-message' => __( 'Your plan was successfully changed to %s.', 'freemius' ),
278
  'license-expired-blocking-message' => __( 'Your license has expired. You can still continue using the free plugin forever.', 'freemius' ),
279
+ 'license-cancelled' => __( 'Your license has been cancelled. If you think it\'s a mistake, please contact support.', 'freemius' ),
280
  'trial-started-message' => __( 'Your trial has been successfully started.', 'freemius' ),
281
  'license-activated-message' => __( 'Your license was successfully activated.', 'freemius' ),
282
  'no-active-license-message' => __( 'It looks like your site currently doesn\'t have an active license.', 'freemius' ),
295
  'trial-x-promotion-message' => __( 'How do you like %s so far? Test all our %s premium features with a %d-day free trial.', 'freemius' ),
296
  'start-free-trial' => _x( 'Start free trial', 'call to action', 'freemius' ),
297
  'trial-cancel-failure-message' => __( 'Seems like we are having some temporary issue with your trial cancellation. Please try again in few minutes.', 'freemius' ),
298
+ 'trial-utilized' => __( 'You already utilized a trial before.', 'freemius' ),
299
+ 'in-trial-mode' => __( 'You are already running the plugin in a trial mode.', 'freemius' ),
300
+ 'trial-plan-x-not-exist' => __( 'Plan %s do not exist, therefore, can\'t start a trial.', 'freemius' ),
301
+ 'plan-x-no-trial' => __( 'Plan %s does not support a trial period.', 'freemius' ),
302
+ 'no-trials' => __( 'None of the plugin\'s plans supports a trial period.', 'freemius' ),
303
+ 'unexpected-api-error' => __( 'Unexpected API error. Please contact the plugin\'s author with the following error.', 'freemius' ),
304
  'no-commitment-for-x-days' => __( 'No commitment for %s days - cancel anytime!', 'freemius' ),
305
  'license-expired-non-blocking-message' => __( 'Your license has expired. You can still continue using all the %s features, but you\'ll need to renew your license to continue getting updates and support.', 'freemius' ),
306
  'could-not-activate-x' => __( 'Couldn\'t activate %s.', 'freemius' ),
349
  'addon-no-license-message' => __( '%s is a premium only add-on. You have to purchase a license first before activating the plugin.', 'freemius' ),
350
  'addon-trial-cancelled-message' => __( '%s free trial was successfully cancelled. Since the add-on is premium only it was automatically deactivated. If you like to use it in the future, you\'ll have to purchase a license.', 'freemius' ),
351
  #endregion Add-On Licensing
352
+ #region Billing Cycles
353
+ 'monthly' => _x( 'Monthly', 'as every month', 'freemius' ),
354
+ 'mo' => _x( 'mo', 'as monthly period', 'freemius' ),
355
+ 'annual' => _x( 'Annual', 'as once a year', 'freemius' ),
356
+ 'annually' => _x( 'Annually', 'as once a year', 'freemius' ),
357
+ 'once' => _x( 'Once', 'as once a year', 'freemius' ),
358
+ 'year' => _x( 'year', 'as annual period', 'freemius' ),
359
+ 'lifetime' => __( 'Lifetime', 'freemius' ),
360
+ 'best' => _x( 'Best', 'e.g. the best product', 'freemius' ),
361
+ 'billed-x' => _x( 'Billed %s', 'e.g. billed monthly', 'freemius' ),
362
+ 'save-x' => _x( 'Save %s', 'as a discount of $5 or 10%', 'freemius' ),
363
+ #endregion Billing Cycles
364
+ 'view-details' => __( 'View details', 'freemius' ),
365
  );
freemius/includes/managers/class-fs-admin-menu-manager.php CHANGED
@@ -110,7 +110,7 @@
110
  }
111
 
112
  private function get_bool_option( &$options, $key, $default = false ) {
113
- return isset( $options[ $key ] ) &&is_bool( $options[ $key ] ) ? $options[ $key ] : $default;
114
  }
115
 
116
  #endregion Helpers
@@ -527,6 +527,9 @@
527
  } else {
528
  global $menu;
529
 
 
 
 
530
  // Create new top-level menu action.
531
  $hookname = add_menu_page(
532
  $found_menu['menu'][3],
@@ -537,9 +540,6 @@
537
  $found_menu['menu'][6],
538
  $found_menu['position']
539
  );
540
-
541
- // Remove original CPT menu.
542
- unset( $menu[ $found_menu['position'] ] );
543
  }
544
 
545
  return $hookname;
110
  }
111
 
112
  private function get_bool_option( &$options, $key, $default = false ) {
113
+ return isset( $options[ $key ] ) && is_bool( $options[ $key ] ) ? $options[ $key ] : $default;
114
  }
115
 
116
  #endregion Helpers
527
  } else {
528
  global $menu;
529
 
530
+ // Remove original CPT menu.
531
+ unset( $menu[ $found_menu['position'] ] );
532
+
533
  // Create new top-level menu action.
534
  $hookname = add_menu_page(
535
  $found_menu['menu'][3],
540
  $found_menu['menu'][6],
541
  $found_menu['position']
542
  );
 
 
 
543
  }
544
 
545
  return $hookname;
freemius/includes/managers/class-fs-admin-notice-manager.php CHANGED
@@ -129,6 +129,13 @@
129
  function _admin_notices_hook() {
130
  $notice_type = 'admin_notices';
131
 
 
 
 
 
 
 
 
132
  if ( ! isset( $this->_admin_messages[ $notice_type ] ) || ! is_array( $this->_admin_messages[ $notice_type ] ) ) {
133
  return;
134
  }
@@ -224,7 +231,7 @@
224
  * @author Vova Feldman (@svovaf)
225
  * @since 1.0.7
226
  *
227
- * @param string $ids
228
  */
229
  function remove_sticky( $ids ) {
230
  if ( ! is_array( $ids ) ) {
129
  function _admin_notices_hook() {
130
  $notice_type = 'admin_notices';
131
 
132
+ if ( function_exists( 'current_user_can' ) &&
133
+ ! current_user_can( 'manage_options' )
134
+ ) {
135
+ // Only show messages to admins.
136
+ return;
137
+ }
138
+
139
  if ( ! isset( $this->_admin_messages[ $notice_type ] ) || ! is_array( $this->_admin_messages[ $notice_type ] ) ) {
140
  return;
141
  }
231
  * @author Vova Feldman (@svovaf)
232
  * @since 1.0.7
233
  *
234
+ * @param string|string[] $ids
235
  */
236
  function remove_sticky( $ids ) {
237
  if ( ! is_array( $ids ) ) {
freemius/includes/managers/class-fs-option-manager.php CHANGED
@@ -100,6 +100,11 @@
100
  $option_name = $this->_get_option_manager_name();
101
 
102
  if ( $flush || ! isset( $this->_options ) ) {
 
 
 
 
 
103
  if ( ! WP_FS__DEBUG_SDK ) {
104
  $this->_options = wp_cache_get( $option_name, WP_FS__SLUG );
105
  }
100
  $option_name = $this->_get_option_manager_name();
101
 
102
  if ( $flush || ! isset( $this->_options ) ) {
103
+ if ( isset( $this->_options ) ) {
104
+ // Clear prev options.
105
+ $this->clear();
106
+ }
107
+
108
  if ( ! WP_FS__DEBUG_SDK ) {
109
  $this->_options = wp_cache_get( $option_name, WP_FS__SLUG );
110
  }
freemius/includes/sdk/Freemius.php CHANGED
@@ -328,7 +328,9 @@
328
  $opts[ CURLOPT_RETURNTRANSFER ] = true;
329
  }
330
 
331
- $opts[ CURLOPT_URL ] = Freemius_Api::GetUrl( $pCanonizedPath, $pIsSandbox );
 
 
332
  $opts[ CURLOPT_CUSTOMREQUEST ] = $pMethod;
333
 
334
  $resource = explode( '?', $pCanonizedPath );
@@ -337,7 +339,7 @@
337
  // for 2 seconds if the server does not support this header.
338
  $opts[ CURLOPT_HTTPHEADER ][] = 'Expect:';
339
 
340
- if ( 'https' === substr( strtolower( $pCanonizedPath ), 0, 5 ) ) {
341
  $opts[ CURLOPT_SSL_VERIFYHOST ] = false;
342
  $opts[ CURLOPT_SSL_VERIFYPEER ] = false;
343
  }
328
  $opts[ CURLOPT_RETURNTRANSFER ] = true;
329
  }
330
 
331
+ $request_url = Freemius_Api::GetUrl( $pCanonizedPath, $pIsSandbox );
332
+
333
+ $opts[ CURLOPT_URL ] = $request_url;
334
  $opts[ CURLOPT_CUSTOMREQUEST ] = $pMethod;
335
 
336
  $resource = explode( '?', $pCanonizedPath );
339
  // for 2 seconds if the server does not support this header.
340
  $opts[ CURLOPT_HTTPHEADER ][] = 'Expect:';
341
 
342
+ if ( 'https' === substr( strtolower( $request_url ), 0, 5 ) ) {
343
  $opts[ CURLOPT_SSL_VERIFYHOST ] = false;
344
  $opts[ CURLOPT_SSL_VERIFYPEER ] = false;
345
  }
freemius/includes/sdk/FreemiusBase.php CHANGED
@@ -33,7 +33,7 @@
33
  );
34
 
35
  foreach ( $exceptions as $e ) {
36
- require FS_SDK__EXCEPTIONS_PATH . $e . '.php';
37
  }
38
 
39
  abstract class Freemius_Api_Base {
33
  );
34
 
35
  foreach ( $exceptions as $e ) {
36
+ require_once FS_SDK__EXCEPTIONS_PATH . $e . '.php';
37
  }
38
 
39
  abstract class Freemius_Api_Base {
freemius/start.php CHANGED
@@ -10,7 +10,12 @@
10
  exit;
11
  }
12
 
13
- $this_sdk_version = '1.1.7.5';
 
 
 
 
 
14
 
15
  #region SDK Selection Logic --------------------------------------------------------------------
16
 
@@ -208,6 +213,7 @@
208
  * fs_pending_activation_message_{plugin_slug}
209
  * fs_is_submenu_visible_{plugin_slug}
210
  * fs_plugin_icon_{plugin_slug}
 
211
  *
212
  * --------------------------------------------------------
213
  *
@@ -286,6 +292,7 @@
286
  require_once WP_FS__DIR_INCLUDES . '/class-fs-plugin-updater.php';
287
  require_once WP_FS__DIR_INCLUDES . '/class-fs-security.php';
288
  require_once WP_FS__DIR_INCLUDES . '/class-freemius-abstract.php';
 
289
  require_once WP_FS__DIR_INCLUDES . '/class-freemius.php';
290
 
291
  /**
10
  exit;
11
  }
12
 
13
+ /**
14
+ * Freemius SDK Version.
15
+ *
16
+ * @var string
17
+ */
18
+ $this_sdk_version = '1.1.9';
19
 
20
  #region SDK Selection Logic --------------------------------------------------------------------
21
 
213
  * fs_pending_activation_message_{plugin_slug}
214
  * fs_is_submenu_visible_{plugin_slug}
215
  * fs_plugin_icon_{plugin_slug}
216
+ * fs_show_trial_{plugin_slug}
217
  *
218
  * --------------------------------------------------------
219
  *
292
  require_once WP_FS__DIR_INCLUDES . '/class-fs-plugin-updater.php';
293
  require_once WP_FS__DIR_INCLUDES . '/class-fs-security.php';
294
  require_once WP_FS__DIR_INCLUDES . '/class-freemius-abstract.php';
295
+ require_once WP_FS__DIR_INCLUDES . '/sdk/Exceptions/Exception.php';
296
  require_once WP_FS__DIR_INCLUDES . '/class-freemius.php';
297
 
298
  /**
freemius/templates/account.php CHANGED
@@ -33,586 +33,593 @@
33
  $show_upgrade = ( ! $is_paying && ! $is_paid_trial );
34
  ?>
35
 
36
- <div class="wrap">
37
- <h2 class="nav-tab-wrapper">
38
- <a href="<?php $fs->get_account_url() ?>" class="nav-tab nav-tab-active"><?php _efs( 'account', $slug ) ?></a>
39
- <?php if ( $fs->has_addons() ) : ?>
40
- <a href="<?php echo $fs->_get_admin_page_url( 'addons' ) ?>"
41
- class="nav-tab"><?php _efs( 'add-ons', $slug ) ?></a>
42
- <?php endif ?>
43
- <?php if ( $fs->is_not_paying() && $fs->has_paid_plan() ) : ?>
44
- <a href="<?php echo $fs->get_upgrade_url() ?>" class="nav-tab"><?php _efs( 'upgrade', $slug ) ?></a>
45
- <?php if ( ! $fs->is_trial_utilized() && $fs->has_trial_plan() ) : ?>
46
- <a href="<?php echo $fs->get_trial_url() ?>" class="nav-tab"><?php _efs( 'free-trial', $slug ) ?></a>
47
- <?php endif ?>
48
  <?php endif ?>
49
- </h2>
 
50
 
51
- <div id="poststuff">
52
- <div id="fs_account">
53
- <div class="has-sidebar has-right-sidebar">
54
- <div class="has-sidebar-content">
55
- <div class="postbox">
56
- <h3><?php _efs( 'account-details', $slug ) ?></h3>
57
 
58
- <div class="fs-header-actions">
59
- <ul>
60
- <li>
61
- <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST">
62
- <input type="hidden" name="fs_action" value="delete_account">
63
- <?php wp_nonce_field( 'delete_account' ) ?>
64
- <a href="#" onclick="if (confirm('<?php
65
- if ( $is_active_subscription ) {
66
- echo esc_attr( sprintf( __fs( 'delete-account-x-confirm', $slug ), $plan->title ) );
67
- } else {
68
- _efs( 'delete-account-confirm', $slug );
69
- }
70
- ?>')) this.parentNode.submit(); return false;"><i
71
- class="dashicons dashicons-no"></i> <?php _efs( 'delete-account', $slug ) ?></a>
72
- </form>
73
- </li>
74
- <?php if ( $is_paying ) : ?>
75
- <li>
76
- &nbsp;•&nbsp;
77
- <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST">
78
- <input type="hidden" name="fs_action" value="deactivate_license">
79
- <?php wp_nonce_field( 'deactivate_license' ) ?>
80
- <a href="#"
81
- onclick="if (confirm('<?php _efs( 'deactivate-license-confirm', $slug ) ?>')) this.parentNode.submit(); return false;"><i
82
- class="dashicons dashicons-admin-network"></i> <?php _efs( 'deactivate-license', $slug ) ?>
83
- </a>
84
- </form>
85
- </li>
86
- <?php if ( ! $license->is_lifetime() &&
87
- $is_active_subscription
88
- ) : ?>
89
- <li>
90
- &nbsp;•&nbsp;
91
- <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST">
92
- <input type="hidden" name="fs_action" value="downgrade_account">
93
- <?php wp_nonce_field( 'downgrade_account' ) ?>
94
- <a href="#"
95
- onclick="if (confirm('<?php printf( __fs( 'downgrade-x-confirm', $slug ), $plan->title, human_time_diff( time(), strtotime( $license->expiration ) ) ) ?> <?php if ( ! $license->is_block_features ) {
96
- printf( __fs( 'after-downgrade-non-blocking', $slug ), $plan->title );
97
- } else {
98
- printf( __fs( 'after-downgrade-blocking', $slug ), $plan->title );
99
- }?> <?php _efs( 'proceed-confirmation', $slug ) ?>')) this.parentNode.submit(); return false;"><i
100
- class="dashicons dashicons-download"></i> <?php _efs( 'downgrade', $slug ) ?></a>
101
- </form>
102
- </li>
103
- <?php endif ?>
104
- <li>
105
- &nbsp;•&nbsp;
106
- <a href="<?php echo $fs->get_upgrade_url() ?>"><i
107
- class="dashicons dashicons-grid-view"></i> <?php _efs( 'change-plan', $slug ) ?></a>
108
- </li>
109
- <?php elseif ( $is_paid_trial ) : ?>
110
- <li>
111
- &nbsp;•&nbsp;
112
- <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST">
113
- <input type="hidden" name="fs_action" value="cancel_trial">
114
- <?php wp_nonce_field( 'cancel_trial' ) ?>
115
- <a href="#"
116
- onclick="if (confirm('<?php _efs( 'cancel-trial-confirm' ) ?>')) this.parentNode.submit(); return false;"><i
117
- class="dashicons dashicons-download"></i> <?php _efs( 'cancel-trial', $slug ) ?></a>
118
- </form>
119
- </li>
120
- <?php endif ?>
121
- <li>
122
- &nbsp;•&nbsp;
123
- <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST">
124
- <input type="hidden" name="fs_action" value="<?php echo $slug ?>_sync_license">
125
- <?php wp_nonce_field( $slug . '_sync_license' ) ?>
126
- <a href="#" onclick="this.parentNode.submit(); return false;"><i
127
- class="dashicons dashicons-image-rotate"></i> <?php _efs( 'sync', $slug ) ?></a>
128
- </form>
129
- </li>
130
 
131
- </ul>
132
- </div>
133
- <div class="inside">
134
- <table id="fs_account_details" cellspacing="0" class="fs-key-value-table">
135
- <?php
136
- $profile = array();
137
- $profile[] = array(
138
- 'id' => 'user_name',
139
- 'title' => __fs( 'name', $slug ),
140
- 'value' => $name
141
- );
142
- // if (isset($user->email) && false !== strpos($user->email, '@'))
143
- $profile[] = array(
144
- 'id' => 'email',
145
- 'title' => __fs( 'email', $slug ),
146
- 'value' => $user->email
147
- );
148
- if ( is_numeric( $user->id ) ) {
149
- $profile[] = array(
150
- 'id' => 'user_id',
151
- 'title' => __fs( 'user-id', $slug ),
152
- 'value' => $user->id
153
- );
154
- }
155
 
156
- $profile[] = array(
157
- 'id' => 'site_id',
158
- 'title' => __fs( 'site-id', $slug ),
159
- 'value' => is_string( $site->id ) ?
160
- $site->id :
161
- __fs( 'no-id', $slug )
162
- );
163
 
164
- $profile[] = array(
165
- 'id' => 'site_public_key',
166
- 'title' => __fs( 'public-key', $slug ),
167
- 'value' => $site->public_key
168
- );
169
 
170
- $profile[] = array(
171
- 'id' => 'site_secret_key',
172
- 'title' => __fs( 'secret-key', $slug ),
173
- 'value' => ( ( is_string( $site->secret_key ) ) ?
174
- $site->secret_key :
175
- __fs( 'no-secret', $slug )
176
- )
177
- );
178
 
179
- if ( $fs->has_paid_plan() ) {
180
- if ( $fs->is_trial() ) {
181
- $trial_plan = $fs->get_trial_plan();
182
 
183
- $profile[] = array(
184
- 'id' => 'plan',
185
- 'title' => __fs( 'plan', $slug ),
186
- 'value' => ( is_string( $trial_plan->name ) ?
187
- strtoupper( $trial_plan->title ) :
188
- __fs( 'trial', $slug ) )
189
- );
190
- } else {
191
- $profile[] = array(
192
- 'id' => 'plan',
193
- 'title' => __fs( 'plan', $slug ),
194
- 'value' => is_string( $site->plan->name ) ?
195
- strtoupper( $site->plan->title ) :
196
- strtoupper( __fs( 'free', $slug ) )
197
- );
198
- }
199
- }
200
 
201
- $profile[] = array(
202
- 'id' => 'version',
203
- 'title' => __fs( 'version', $slug ),
204
- 'value' => $fs->get_plugin_version()
205
- );
206
- ?>
207
  <?php $odd = true;
208
- foreach ( $profile as $p ) : ?>
209
  <?php
210
- if ( 'plan' === $p['id'] && ! $fs->has_paid_plan() ) {
211
- // If plugin don't have any paid plans, there's no reason
212
- // to show current plan.
213
- continue;
214
- }
215
- ?>
216
- <tr class="fs-field-<?php echo $p['id'] ?><?php if ( $odd ) : ?> alternate<?php endif ?>">
217
- <td>
218
- <nobr><?php echo $p['title'] ?>:</nobr>
219
- </td>
220
- <td>
221
- <code><?php echo htmlspecialchars( $p['value'] ) ?></code>
222
- <?php if ( 'email' === $p['id'] && ! $user->is_verified() ) : ?>
223
- <label class="fs-tag fs-warn"><?php _efs( 'not-verified', $slug ) ?></label>
224
- <?php endif ?>
225
- <?php if ( 'plan' === $p['id'] ) : ?>
226
- <?php if ( $fs->is_trial() ) : ?>
227
- <label class="fs-tag fs-success"><?php _efs( 'trial', $slug ) ?></label>
228
- <?php endif ?>
229
- <?php if ( is_object( $license ) && ! $license->is_lifetime() ) : ?>
230
- <?php if ( ! $is_active_subscription && ! $license->is_first_payment_pending() ) : ?>
231
- <label
232
- class="fs-tag fs-warn"><?php printf( __fs( 'expires-in', $slug ), human_time_diff( time(), strtotime( $license->expiration ) ) ) ?></label>
233
- <?php elseif ( $is_active_subscription && ! $subscription->is_first_payment_pending() ) : ?>
234
- <label
235
- class="fs-tag fs-success"><?php printf( __fs( 'renews-in', $slug ), human_time_diff( time(), strtotime( $subscription->next_payment ) ) ) ?></label>
236
- <?php endif ?>
237
- <?php elseif ( $fs->is_trial() ) : ?>
238
- <label
239
- class="fs-tag fs-warn"><?php printf( __fs( 'expires-in', $slug ), human_time_diff( time(), strtotime( $site->trial_ends ) ) ) ?></label>
240
- <?php endif ?>
241
- <?php endif ?>
242
- <?php if ( 'version' === $p['id'] && $fs->has_paid_plan() ) : ?>
243
- <?php if ( $fs->is_premium() ) : ?>
244
- <label
245
- class="fs-tag fs-<?php echo $fs->can_use_premium_code() ? 'success' : 'warn' ?>"><?php _efs( 'premium-version' ) ?></label>
246
- <?php elseif ( $fs->can_use_premium_code() ) : ?>
247
- <label class="fs-tag fs-warn"><?php _efs( 'free-version' ) ?></label>
248
- <?php endif ?>
249
  <?php endif ?>
250
- </td>
251
- <td class="fs-right">
252
- <?php if ( 'email' === $p['id'] && ! $user->is_verified() ) : ?>
253
- <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST">
254
- <input type="hidden" name="fs_action" value="verify_email">
255
- <?php wp_nonce_field( 'verify_email' ) ?>
256
- <input type="submit" class="button button-small"
257
- value="<?php _efs( 'verify-email', $slug ) ?>">
258
- </form>
259
  <?php endif ?>
260
- <?php if ( 'plan' === $p['id'] ) : ?>
261
- <div class="button-group">
262
- <?php $license = $fs->is_free_plan() ? $fs->_get_available_premium_license() : false ?>
263
- <?php if ( false !== $license && ( $license->left() > 0 || ( $site->is_localhost() && $license->is_free_localhost ) ) ) : ?>
264
- <?php $premium_plan = $fs->_get_plan_by_id( $license->plan_id ) ?>
265
- <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>"
266
- method="POST">
267
- <input type="hidden" name="fs_action" value="activate_license">
268
- <input type="hidden" name="license_id" value="<?php echo $license->id ?>">
269
- <?php wp_nonce_field( 'activate_license' ) ?>
270
- <input type="submit" class="button button-primary"
271
- value="<?php printf(
272
- __fs( 'activate-x-plan', $slug ),
273
- $premium_plan->title,
274
- ( $site->is_localhost() && $license->is_free_localhost ) ?
275
- '[' . __fs( 'localhost', $slug ) . ']' :
276
- ( 1 < $license->left() ? $license->left() . ' left' : '' )
277
- ) ?> ">
278
- </form>
279
- <?php else : ?>
280
- <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>"
281
- method="POST" class="button-group">
282
- <input type="submit" class="button"
283
- value="<?php _efs( 'sync-license', $slug ) ?>">
284
- <input type="hidden" name="fs_action"
285
- value="<?php echo $slug ?>_sync_license">
286
- <?php wp_nonce_field( $slug . '_sync_license' ) ?>
287
- <a href="<?php echo $fs->get_upgrade_url() ?>"
288
- class="button<?php if ( $show_upgrade ) {
289
- echo ' button-primary';
290
- } ?> button-upgrade"><i
291
- class="dashicons dashicons-cart"></i> <?php ( $show_upgrade ) ?
292
- _efs( 'upgrade', $slug ) :
293
- _efs( 'change-plan', $slug )
294
- ?></a>
295
- </form>
296
- <?php endif ?>
297
- </div>
298
- <?php elseif ( 'version' === $p['id'] ) : ?>
299
- <div class="button-group">
300
- <?php if ( $is_paying || $fs->is_trial() ) : ?>
301
- <?php if ( ! $fs->is_allowed_to_install() ) : ?>
302
- <a target="_blank" class="button button-primary"
303
- href="<?php echo $fs->_get_latest_download_local_url() ?>"><?php echo sprintf( __fs( 'download-x-version', $slug ), $site->plan->title ) . ( is_object( $update ) ? ' [' . $update->version . ']' : '' ) ?></a>
304
- <?php elseif ( is_object( $update ) ) : ?>
305
- <a class="button button-primary"
306
- href="<?php echo wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' . $fs->get_plugin_basename() ), 'upgrade-plugin_' . $fs->get_plugin_basename() ) ?>"><?php echo __fs( 'install-update-now', $slug ) . ' [' . $update->version . ']' ?></a>
307
- <?php endif ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  <?php endif; ?>
309
- </div>
310
- <?php
311
- elseif (/*in_array($p['id'], array('site_secret_key', 'site_id', 'site_public_key')) ||*/
312
- ( is_string( $user->secret_key ) && in_array( $p['id'], array(
313
- 'email',
314
- 'user_name'
315
- ) ) )
316
- ) : ?>
317
- <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST"
318
- onsubmit="var val = prompt('<?php printf( __fs( 'what-is-your-x', $slug ), $p['title'] ) ?>', '<?php echo $p['value'] ?>'); if (null == val || '' === val) return false; jQuery('input[name=fs_<?php echo $p['id'] ?>_<?php echo $slug ?>]').val(val); return true;">
319
- <input type="hidden" name="fs_action" value="update_<?php echo $p['id'] ?>">
320
- <input type="hidden" name="fs_<?php echo $p['id'] ?>_<?php echo $slug ?>"
321
- value="">
322
- <?php wp_nonce_field( 'update_' . $p['id'] ) ?>
323
- <input type="submit" class="button button-small"
324
- value="<?php _ex( 'Edit', 'verb', 'freemius' ) ?>">
325
- </form>
326
- <?php endif ?>
327
- </td>
328
- </tr>
329
- <?php $odd = ! $odd; endforeach ?>
330
- </table>
331
- </div>
332
- </div>
333
- <?php
334
- $account_addons = $fs->get_account_addons();
335
- if ( ! is_array( $account_addons ) ) {
336
- $account_addons = array();
337
- }
 
338
 
339
- $installed_addons = $fs->get_installed_addons();
340
- $installed_addons_ids = array();
341
- foreach ( $installed_addons as $fs_addon ) {
342
- $installed_addons_ids[] = $fs_addon->get_id();
343
- }
344
 
345
- $addons_to_show = array_unique( array_merge( $installed_addons_ids, $account_addons ) );
346
- ?>
347
- <?php if ( 0 < count( $addons_to_show ) ) : ?>
348
- <div class="postbox">
349
- <div class="">
350
- <!-- <div class="inside">-->
351
- <table id="fs_addons" class="widefat">
352
- <thead>
353
- <tr>
354
- <th><h3><?php _efs( 'add-ons', $slug ) ?></h3></th>
355
- <th><?php _efs( 'id', $slug ) ?></th>
356
- <th><?php _efs( 'version', $slug ) ?></th>
357
- <th><?php _efs( 'plan', $slug ) ?></th>
358
- <th><?php _efs( 'license', $slug ) ?></th>
359
- <th></th>
360
- <?php if ( defined( 'WP_FS__DEV_MODE' ) && WP_FS__DEV_MODE ) : ?>
361
- <th></th>
362
- <?php endif ?>
363
- </tr>
364
- </thead>
365
- <tbody>
366
- <?php $odd = true;
367
- foreach ( $addons_to_show as $addon_id ) : ?>
368
  <?php
369
- $addon = $fs->get_addon( $addon_id );
370
- $is_addon_activated = $fs->is_addon_activated( $addon->slug );
371
- $is_addon_connected = $fs->is_addon_connected( $addon->slug );
372
 
373
- $fs_addon = $is_addon_connected ? freemius( $addon->slug ) : false;
374
- if ( is_object( $fs_addon ) ) {
375
- $is_paying = $fs_addon->is_paying();
376
- $user = $fs_addon->get_user();
377
- $site = $fs_addon->get_site();
378
- $license = $fs_addon->_get_license();
379
- $subscription = $fs_addon->_get_subscription();
380
- $plan = $fs_addon->get_plan();
381
- $is_active_subscription = ( is_object( $subscription ) && $subscription->is_active() );
382
- $is_paid_trial = $fs_addon->is_paid_trial();
383
- $show_upgrade = ( ! $is_paying && ! $is_paid_trial && ! $fs_addon->_has_premium_license() );
384
- $is_current_license_expired = is_object( $license ) && $license->is_expired();
385
- }
386
 
387
- // var_dump( $is_paid_trial, $license, $site, $subscription );
388
 
389
- ?>
390
- <tr<?php if ( $odd ) {
391
- echo ' class="alternate"';
392
- } ?>>
393
- <td>
394
- <!-- Title -->
395
- <?php echo $addon->title ?>
396
- </td>
397
- <?php if ( $is_addon_connected ) : ?>
398
  <?php // Add-on Installed ?>
399
  <?php $addon_site = $fs_addon->get_site(); ?>
400
- <td>
401
- <!-- ID -->
402
- <?php echo $addon_site->id ?>
403
- </td>
404
- <td>
405
- <!-- Version -->
406
- <?php echo $fs_addon->get_plugin_version() ?>
407
- </td>
408
- <td>
409
- <!-- Plan Title -->
410
- <?php echo is_string( $addon_site->plan->name ) ? strtoupper( $addon_site->plan->title ) : 'FREE' ?>
411
- </td>
412
- <td>
413
- <!-- Expiration -->
414
- <?php
415
- $tags = array();
416
 
417
- if ( $fs_addon->is_trial() ) {
418
- $tags[] = array( 'label' => __fs( 'trial', $slug ), 'type' => 'success' );
419
 
420
- $tags[] = array(
421
- 'label' => sprintf( __fs( ( $is_paid_trial ? 'renews-in' : 'expires-in' ), $slug ), human_time_diff( time(), strtotime( $site->trial_ends ) ) ),
422
- 'type' => ( $is_paid_trial ? 'success' : 'warn' )
423
- );
424
- } else {
425
- if ( is_object( $license ) ) {
426
- if ( $license->is_cancelled ) {
427
- $tags[] = array(
428
- 'label' => __fs( 'cancelled', $slug ),
429
- 'type' => 'error'
430
- );
431
- } else if ( $license->is_expired() ) {
432
- $tags[] = array(
433
- 'label' => __fs( 'expired', $slug ),
434
- 'type' => 'error'
435
- );
436
- } else if ( $license->is_lifetime() ) {
437
- $tags[] = array(
438
- 'label' => __fs( 'no-expiration', $slug ),
439
- 'type' => 'success'
440
- );
441
- } else if ( ! $is_active_subscription && ! $license->is_first_payment_pending() ) {
442
- $tags[] = array(
443
- 'label' => sprintf( __fs( 'expires-in', $slug ), human_time_diff( time(), strtotime( $license->expiration ) ) ),
444
- 'type' => 'warn'
445
- );
446
- } else if ( $is_active_subscription && ! $subscription->is_first_payment_pending() ) {
447
- $tags[] = array(
448
- 'label' => sprintf( __fs( 'renews-in', $slug ), human_time_diff( time(), strtotime( $subscription->next_payment ) ) ),
449
- 'type' => 'success'
450
- );
451
- }
452
- }
453
- }
454
 
455
- foreach ( $tags as $t ) {
456
- printf( '<label class="fs-tag fs-%s">%s</label>' . "\n", $t['type'], $t['label'] );
457
- }
458
- ?>
459
- </td>
460
- <?php
461
- $buttons = array();
462
- if ( $is_addon_activated ) {
463
- if ( $is_paying ) {
464
- $buttons[] = fs_ui_get_action_button(
465
- $slug,
466
- 'account',
467
- 'deactivate_license',
468
- __fs( 'deactivate-license', $slug ),
469
- array( 'plugin_id' => $addon_id ),
470
- false
471
- );
472
- } else if ( $is_paid_trial ) {
473
- $buttons[] = fs_ui_get_action_button(
474
- $slug,
475
- 'account',
476
- 'cancel_trial',
477
- __fs( 'cancel-trial', $slug ),
478
- array( 'plugin_id' => $addon_id ),
479
- false,
480
- 'dashicons dashicons-download',
481
- __fs( 'cancel-trial-confirm', $slug ),
482
- 'POST'
483
- );
484
- } else {
485
- $premium_license = $fs_addon->_get_available_premium_license();
486
 
487
- if ( is_object( $premium_license ) ) {
488
- $site = $fs_addon->get_site();
489
 
490
- $buttons[] = fs_ui_get_action_button(
491
- $slug,
492
- 'account',
493
- 'activate_license',
494
- sprintf( __fs( 'activate-x-plan', $slug ), $fs_addon->get_plan_title(), ( $site->is_localhost() && $premium_license->is_free_localhost ) ? '[localhost]' : ( 1 < $premium_license->left() ? $premium_license->left() . ' left' : '' ) ),
495
- array(
496
- 'plugin_id' => $addon_id,
497
- 'license_id' => $premium_license->id,
498
- )
499
- );
500
- }
501
- }
502
 
503
- if ( 0 == count( $buttons ) ) {
504
- // Add sync license only if non of the other CTAs are visible.
505
- $buttons[] = fs_ui_get_action_button(
506
- $slug,
507
- 'account',
508
- $slug . '_sync_license',
509
- __fs( 'sync-license', $slug ),
510
- array( 'plugin_id' => $addon_id ),
511
- false
512
- );
513
 
514
- }
515
- } else if ( ! $show_upgrade ) {
516
- if ( $fs->is_addon_installed( $addon->slug ) ) {
517
- $addon_file = $fs->get_addon_basename( $addon->slug );
518
- $buttons[] = sprintf(
519
- '<a class="button button-primary" href="%s" title="%s" class="edit">%s</a>',
520
- wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $addon_file, 'activate-plugin_' . $addon_file ),
521
- esc_attr( __fs( 'activate-this-addon', $slug ) ),
522
- __fs( 'activate', $slug )
523
- );
524
- } else {
525
- if ( $fs->is_allowed_to_install() ) {
526
- $buttons[] = sprintf(
527
- '<a class="button button-primary" href="%s" class="edit">%s</a>',
528
- wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $addon->slug ), 'install-plugin_' . $addon->slug ),
529
- __fs( 'install-now', $slug )
530
- );
531
- } else {
532
- $buttons[] = sprintf(
533
- '<a target="_blank" class="button button-primary" href="%s" class="edit">%s</a>',
534
- $fs->_get_latest_download_local_url( $addon_id ),
535
- __fs( 'download-latest', $slug )
536
- );
537
- }
538
- }
539
- }
540
 
541
- if ( $show_upgrade ) {
542
- $buttons[] = sprintf( '<a href="%s" class="thickbox button button-primary" aria-label="%s" data-title="%s"><i class="dashicons dashicons-cart"></i> %s</a>',
543
- esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
544
- '&TB_iframe=true&width=600&height=550' ) ),
545
- esc_attr( sprintf( __fs( 'more-information-about-x', $slug ), $addon->title ) ),
546
- esc_attr( $addon->title ),
547
- __fs( ( $fs_addon->has_free_plan() ? 'upgrade' : 'purchase' ), $slug )
548
- );
549
- }
550
 
551
- $buttons_count = count( $buttons );
552
- ?>
553
 
554
- <td>
555
- <!-- Actions -->
556
- <?php if ($buttons_count > 1) : ?>
557
- <div class="button-group">
558
- <?php endif ?>
559
- <?php foreach ( $buttons as $button ) : ?>
560
  <?php echo $button ?>
561
  <?php endforeach ?>
562
  <?php if ($buttons_count > 1) : ?>
563
- </div>
564
- <?php endif ?>
565
- </td>
566
- <?php else : ?>
567
  <?php // Add-on NOT Installed or was never connected.
568
- ?>
569
- <td colspan="4">
570
- <!-- Action -->
571
- <?php if ( $fs->is_addon_installed( $addon->slug ) ) : ?>
572
- <?php $addon_file = $fs->get_addon_basename( $addon->slug ) ?>
573
- <a class="button button-primary"
574
- href="<?php echo wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $addon_file, 'activate-plugin_' . $addon_file ) ?>"
575
- title="<?php esc_attr( __fs( 'activate-this-addon', $slug ) ) ?>"
576
- class="edit"><?php _efs( 'activate', $slug ) ?></a>
577
- <?php else : ?>
578
- <?php if ( $fs->is_allowed_to_install() ) : ?>
579
- <a class="button button-primary"
580
- href="<?php echo wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $addon->slug ), 'install-plugin_' . $addon->slug ) ?>"><?php _efs( 'install-now', $slug ) ?></a>
581
- <?php else : ?>
582
- <a target="_blank" class="button button-primary"
583
- href="<?php echo $fs->_get_latest_download_local_url( $addon_id ) ?>"><?php _efs( 'download-latest', $slug ) ?></a>
584
- <?php endif ?>
585
- <?php endif ?>
586
- </td>
587
- <?php endif ?>
588
- <?php if ( defined( 'WP_FS__DEV_MODE' ) && WP_FS__DEV_MODE ) : ?>
589
- <td>
590
- <!-- Optional Delete Action -->
591
- <?php
592
- if ( $is_addon_activated ) {
593
- fs_ui_action_button(
594
- $slug, 'account',
595
- 'delete_account',
596
- __fs( 'delete', $slug ),
597
- array( 'plugin_id' => $addon_id ),
598
- false
599
- );
600
- }
601
- ?>
602
- </td>
603
- <?php endif ?>
604
- </tr>
605
- <?php $odd = ! $odd; endforeach ?>
606
- </tbody>
607
- </table>
608
- </div>
609
- </div>
610
  <?php endif ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
611
 
612
- <?php $fs->do_action( 'after_account_details' ) ?>
613
- </div>
614
- </div>
615
- </div>
616
- </div>
617
- </div>
618
- <?php fs_require_template( 'powered-by.php' ) ?>
33
  $show_upgrade = ( ! $is_paying && ! $is_paid_trial );
34
  ?>
35
 
36
+ <div class="wrap">
37
+ <h2 class="nav-tab-wrapper">
38
+ <a href="<?php $fs->get_account_url() ?>" class="nav-tab nav-tab-active"><?php _efs( 'account', $slug ) ?></a>
39
+ <?php if ( $fs->has_addons() ) : ?>
40
+ <a href="<?php echo $fs->_get_admin_page_url( 'addons' ) ?>"
41
+ class="nav-tab"><?php _efs( 'add-ons', $slug ) ?></a>
42
+ <?php endif ?>
43
+ <?php if ( $fs->is_not_paying() && $fs->has_paid_plan() ) : ?>
44
+ <a href="<?php echo $fs->get_upgrade_url() ?>" class="nav-tab"><?php _efs( 'upgrade', $slug ) ?></a>
45
+ <?php if ( $fs->apply_filters( 'show_trial', true ) && ! $fs->is_trial_utilized() && $fs->has_trial_plan() ) : ?>
46
+ <a href="<?php echo $fs->get_trial_url() ?>" class="nav-tab"><?php _efs( 'free-trial', $slug ) ?></a>
 
47
  <?php endif ?>
48
+ <?php endif ?>
49
+ </h2>
50
 
51
+ <div id="poststuff">
52
+ <div id="fs_account">
53
+ <div class="has-sidebar has-right-sidebar">
54
+ <div class="has-sidebar-content">
55
+ <div class="postbox">
56
+ <h3><?php _efs('account-details', $slug) ?></h3>
57
 
58
+ <div class="fs-header-actions">
59
+ <ul>
60
+ <li>
61
+ <form action="<?php echo $fs->_get_admin_page_url('account') ?>" method="POST">
62
+ <input type="hidden" name="fs_action" value="delete_account">
63
+ <?php wp_nonce_field('delete_account') ?>
64
+ <a href="#" onclick="if (confirm('<?php
65
+ if ($is_active_subscription) {
66
+ echo esc_attr(sprintf(__fs('delete-account-x-confirm', $slug), $plan->title));
67
+ } else {
68
+ _efs('delete-account-confirm', $slug);
69
+ }
70
+ ?>')) this.parentNode.submit(); return false;"><i
71
+ class="dashicons dashicons-no"></i> <?php _efs('delete-account', $slug) ?></a>
72
+ </form>
73
+ </li>
74
+ <?php if ($is_paying) : ?>
75
+ <li>
76
+ &nbsp;•&nbsp;
77
+ <form action="<?php echo $fs->_get_admin_page_url('account') ?>" method="POST">
78
+ <input type="hidden" name="fs_action" value="deactivate_license">
79
+ <?php wp_nonce_field('deactivate_license') ?>
80
+ <a href="#"
81
+ onclick="if (confirm('<?php _efs('deactivate-license-confirm', $slug) ?>')) this.parentNode.submit(); return false;"><i
82
+ class="dashicons dashicons-admin-network"></i> <?php _efs('deactivate-license', $slug) ?>
83
+ </a>
84
+ </form>
85
+ </li>
86
+ <?php if (! $license->is_lifetime() &&
87
+ $is_active_subscription
88
+ ) : ?>
89
+ <li>
90
+ &nbsp;•&nbsp;
91
+ <form action="<?php echo $fs->_get_admin_page_url('account') ?>" method="POST">
92
+ <input type="hidden" name="fs_action" value="downgrade_account">
93
+ <?php wp_nonce_field('downgrade_account') ?>
94
+ <a href="#"
95
+ onclick="if (confirm('<?php printf(__fs('downgrade-x-confirm', $slug), $plan->title, human_time_diff(time(), strtotime($license->expiration))) ?> <?php if (! $license->is_block_features) {
96
+ printf(__fs('after-downgrade-non-blocking', $slug), $plan->title);
97
+ } else {
98
+ printf(__fs('after-downgrade-blocking', $slug), $plan->title);
99
+ }?> <?php _efs('proceed-confirmation', $slug) ?>')) this.parentNode.submit(); return false;"><i
100
+ class="dashicons dashicons-download"></i> <?php _efs('downgrade', $slug) ?></a>
101
+ </form>
102
+ </li>
103
+ <?php endif ?>
104
+ <li>
105
+ &nbsp;•&nbsp;
106
+ <a href="<?php echo $fs->get_upgrade_url() ?>"><i
107
+ class="dashicons dashicons-grid-view"></i> <?php _efs('change-plan', $slug) ?></a>
108
+ </li>
109
+ <?php elseif ($is_paid_trial) : ?>
110
+ <li>
111
+ &nbsp;•&nbsp;
112
+ <form action="<?php echo $fs->_get_admin_page_url('account') ?>" method="POST">
113
+ <input type="hidden" name="fs_action" value="cancel_trial">
114
+ <?php wp_nonce_field('cancel_trial') ?>
115
+ <a href="#"
116
+ onclick="if (confirm('<?php _efs('cancel-trial-confirm') ?>')) this.parentNode.submit(); return false;"><i
117
+ class="dashicons dashicons-download"></i> <?php _efs('cancel-trial', $slug) ?></a>
118
+ </form>
119
+ </li>
120
+ <?php endif ?>
121
+ <li>
122
+ &nbsp;•&nbsp;
123
+ <form action="<?php echo $fs->_get_admin_page_url('account') ?>" method="POST">
124
+ <input type="hidden" name="fs_action" value="<?php echo $slug ?>_sync_license">
125
+ <?php wp_nonce_field($slug . '_sync_license') ?>
126
+ <a href="#" onclick="this.parentNode.submit(); return false;"><i
127
+ class="dashicons dashicons-image-rotate"></i> <?php _efs('sync', $slug) ?></a>
128
+ </form>
129
+ </li>
130
 
131
+ </ul>
132
+ </div>
133
+ <div class="inside">
134
+ <table id="fs_account_details" cellspacing="0" class="fs-key-value-table">
135
+ <?php
136
+ $profile = array();
137
+ $profile[] = array(
138
+ 'id' => 'user_name',
139
+ 'title' => __fs('name', $slug),
140
+ 'value' => $name
141
+ );
142
+ // if (isset($user->email) && false !== strpos($user->email, '@'))
143
+ $profile[] = array(
144
+ 'id' => 'email',
145
+ 'title' => __fs('email', $slug),
146
+ 'value' => $user->email
147
+ );
148
+ if (is_numeric($user->id)) {
149
+ $profile[] = array(
150
+ 'id' => 'user_id',
151
+ 'title' => __fs('user-id', $slug),
152
+ 'value' => $user->id
153
+ );
154
+ }
155
 
156
+ $profile[] = array(
157
+ 'id' => 'site_id',
158
+ 'title' => __fs('site-id', $slug),
159
+ 'value' => is_string($site->id) ?
160
+ $site->id :
161
+ __fs('no-id', $slug)
162
+ );
163
 
164
+ $profile[] = array(
165
+ 'id' => 'site_public_key',
166
+ 'title' => __fs('public-key', $slug),
167
+ 'value' => $site->public_key
168
+ );
169
 
170
+ $profile[] = array(
171
+ 'id' => 'site_secret_key',
172
+ 'title' => __fs('secret-key', $slug),
173
+ 'value' => ((is_string($site->secret_key)) ?
174
+ $site->secret_key :
175
+ __fs('no-secret', $slug)
176
+ )
177
+ );
178
 
179
+ if ($fs->has_paid_plan()) {
180
+ if ($fs->is_trial()) {
181
+ $trial_plan = $fs->get_trial_plan();
182
 
183
+ $profile[] = array(
184
+ 'id' => 'plan',
185
+ 'title' => __fs('plan', $slug),
186
+ 'value' => (is_string($trial_plan->name) ?
187
+ strtoupper($trial_plan->title) :
188
+ __fs('trial', $slug))
189
+ );
190
+ } else {
191
+ $profile[] = array(
192
+ 'id' => 'plan',
193
+ 'title' => __fs('plan', $slug),
194
+ 'value' => is_string($site->plan->name) ?
195
+ strtoupper($site->plan->title) :
196
+ strtoupper(__fs('free', $slug))
197
+ );
198
+ }
199
+ }
200
 
201
+ $profile[] = array(
202
+ 'id' => 'version',
203
+ 'title' => __fs('version', $slug),
204
+ 'value' => $fs->get_plugin_version()
205
+ );
206
+ ?>
207
  <?php $odd = true;
208
+ foreach ($profile as $p) : ?>
209
  <?php
210
+ if ('plan' === $p['id'] && ! $fs->has_paid_plan()) {
211
+ // If plugin don't have any paid plans, there's no reason
212
+ // to show current plan.
213
+ continue;
214
+ }
215
+ ?>
216
+ <tr class="fs-field-<?php echo $p['id'] ?><?php if ($odd) : ?> alternate<?php endif ?>">
217
+ <td>
218
+ <nobr><?php echo $p['title'] ?>:</nobr>
219
+ </td>
220
+ <td>
221
+ <code><?php echo htmlspecialchars($p['value']) ?></code>
222
+ <?php if ('email' === $p['id'] && ! $user->is_verified()) : ?>
223
+ <label class="fs-tag fs-warn"><?php _efs('not-verified', $slug) ?></label>
224
+ <?php endif ?>
225
+ <?php if ('plan' === $p['id']) : ?>
226
+ <?php if ($fs->is_trial()) : ?>
227
+ <label class="fs-tag fs-success"><?php _efs('trial', $slug) ?></label>
228
+ <?php endif ?>
229
+ <?php if (is_object($license) && ! $license->is_lifetime()) : ?>
230
+ <?php if (! $is_active_subscription && ! $license->is_first_payment_pending()) : ?>
231
+ <label
232
+ class="fs-tag fs-warn"><?php printf(__fs('expires-in', $slug), human_time_diff(time(), strtotime($license->expiration))) ?></label>
233
+ <?php elseif ($is_active_subscription && ! $subscription->is_first_payment_pending()) : ?>
234
+ <label
235
+ class="fs-tag fs-success"><?php printf(__fs('renews-in', $slug), human_time_diff(time(), strtotime($subscription->next_payment))) ?></label>
236
+ <?php endif ?>
237
+ <?php elseif ($fs->is_trial()) : ?>
238
+ <label
239
+ class="fs-tag fs-warn"><?php printf(__fs('expires-in', $slug), human_time_diff(time(), strtotime($site->trial_ends))) ?></label>
240
+ <?php endif ?>
 
 
 
 
 
 
 
 
241
  <?php endif ?>
242
+ <?php if ('version' === $p['id'] && $fs->has_paid_plan()) : ?>
243
+ <?php if ($fs->is_premium()) : ?>
244
+ <label
245
+ class="fs-tag fs-<?php echo $fs->can_use_premium_code() ? 'success' : 'warn' ?>"><?php _efs('premium-version') ?></label>
246
+ <?php elseif ($fs->can_use_premium_code()) : ?>
247
+ <label class="fs-tag fs-warn"><?php _efs('free-version') ?></label>
248
+ <?php endif ?>
 
 
249
  <?php endif ?>
250
+ </td>
251
+ <td class="fs-right">
252
+ <?php if ('email' === $p['id'] && ! $user->is_verified()) : ?>
253
+ <form action="<?php echo $fs->_get_admin_page_url('account') ?>" method="POST">
254
+ <input type="hidden" name="fs_action" value="verify_email">
255
+ <?php wp_nonce_field('verify_email') ?>
256
+ <input type="submit" class="button button-small"
257
+ value="<?php _efs('verify-email', $slug) ?>">
258
+ </form>
259
+ <?php endif ?>
260
+ <?php if ('plan' === $p['id']) : ?>
261
+ <div class="button-group">
262
+ <?php $license = $fs->is_free_plan() ? $fs->_get_available_premium_license() : false ?>
263
+ <?php if (false !== $license && ($license->left() > 0 || ($site->is_localhost() && $license->is_free_localhost))) : ?>
264
+ <?php $premium_plan = $fs->_get_plan_by_id($license->plan_id) ?>
265
+ <form action="<?php echo $fs->_get_admin_page_url('account') ?>"
266
+ method="POST">
267
+ <input type="hidden" name="fs_action" value="activate_license">
268
+ <input type="hidden" name="license_id" value="<?php echo $license->id ?>">
269
+ <?php wp_nonce_field('activate_license') ?>
270
+ <input type="submit" class="button button-primary"
271
+ value="<?php printf(
272
+ __fs( 'activate-x-plan', $slug ) . '%s',
273
+ $premium_plan->title,
274
+ ( $site->is_localhost() && $license->is_free_localhost ) ?
275
+ ' [' . __fs( 'localhost', $slug ) . ']' :
276
+ ( $license->is_single_site() ?
277
+ '' :
278
+ ' [' . ( 1 < $license->left() ?
279
+ sprintf( __fs( 'x-left', $slug ), $license->left() ) :
280
+ strtolower( __fs( 'last-license', $slug ) ) ) . ']'
281
+ )
282
+ ) ?> ">
283
+ </form>
284
+ <?php else : ?>
285
+ <form action="<?php echo $fs->_get_admin_page_url('account') ?>"
286
+ method="POST" class="button-group">
287
+ <input type="submit" class="button"
288
+ value="<?php _efs('sync-license', $slug) ?>">
289
+ <input type="hidden" name="fs_action"
290
+ value="<?php echo $slug ?>_sync_license">
291
+ <?php wp_nonce_field($slug . '_sync_license') ?>
292
+ <a href="<?php echo $fs->get_upgrade_url() ?>"
293
+ class="button<?php if ($show_upgrade) {
294
+ echo ' button-primary';
295
+ } ?> button-upgrade"><i
296
+ class="dashicons dashicons-cart"></i> <?php ($show_upgrade) ?
297
+ _efs('upgrade', $slug) :
298
+ _efs('change-plan', $slug)
299
+ ?></a>
300
+ </form>
301
+ <?php endif ?>
302
+ </div>
303
+ <?php elseif ('version' === $p['id']) : ?>
304
+ <div class="button-group">
305
+ <?php if ($is_paying || $fs->is_trial()) : ?>
306
+ <?php if (! $fs->is_allowed_to_install()) : ?>
307
+ <a target="_blank" class="button button-primary"
308
+ href="<?php echo $fs->_get_latest_download_local_url() ?>"><?php echo sprintf(__fs('download-x-version', $slug), $site->plan->title) . (is_object($update) ? ' [' . $update->version . ']' : '') ?></a>
309
+ <?php elseif (is_object($update)) : ?>
310
+ <a class="button button-primary"
311
+ href="<?php echo wp_nonce_url(self_admin_url('update.php?action=upgrade-plugin&plugin=' . $fs->get_plugin_basename()), 'upgrade-plugin_' . $fs->get_plugin_basename()) ?>"><?php echo __fs('install-update-now', $slug) . ' [' . $update->version . ']' ?></a>
312
+ <?php endif ?>
313
  <?php endif; ?>
314
+ </div>
315
+ <?php
316
+ elseif (/*in_array($p['id'], array('site_secret_key', 'site_id', 'site_public_key')) ||*/
317
+ (is_string($user->secret_key) && in_array($p['id'], array(
318
+ 'email',
319
+ 'user_name'
320
+ )))
321
+ ) : ?>
322
+ <form action="<?php echo $fs->_get_admin_page_url('account') ?>" method="POST"
323
+ onsubmit="var val = prompt('<?php printf(__fs('what-is-your-x', $slug), $p['title']) ?>', '<?php echo $p['value'] ?>'); if (null == val || '' === val) return false; jQuery('input[name=fs_<?php echo $p['id'] ?>_<?php echo $slug ?>]').val(val); return true;">
324
+ <input type="hidden" name="fs_action" value="update_<?php echo $p['id'] ?>">
325
+ <input type="hidden" name="fs_<?php echo $p['id'] ?>_<?php echo $slug ?>"
326
+ value="">
327
+ <?php wp_nonce_field('update_' . $p['id']) ?>
328
+ <input type="submit" class="button button-small"
329
+ value="<?php _ex('Edit', 'verb', 'freemius') ?>">
330
+ </form>
331
+ <?php endif ?>
332
+ </td>
333
+ </tr>
334
+ <?php $odd = ! $odd;
335
+ endforeach ?>
336
+ </table>
337
+ </div>
338
+ </div>
339
+ <?php
340
+ $account_addons = $fs->get_account_addons();
341
+ if (! is_array($account_addons)) {
342
+ $account_addons = array();
343
+ }
344
 
345
+ $installed_addons = $fs->get_installed_addons();
346
+ $installed_addons_ids = array();
347
+ foreach ($installed_addons as $fs_addon) {
348
+ $installed_addons_ids[] = $fs_addon->get_id();
349
+ }
350
 
351
+ $addons_to_show = array_unique(array_merge($installed_addons_ids, $account_addons));
352
+ ?>
353
+ <?php if (0 < count($addons_to_show)) : ?>
354
+ <div class="postbox">
355
+ <div class="">
356
+ <!-- <div class="inside">-->
357
+ <table id="fs_addons" class="widefat">
358
+ <thead>
359
+ <tr>
360
+ <th><h3><?php _efs('add-ons', $slug) ?></h3></th>
361
+ <th><?php _efs('id', $slug) ?></th>
362
+ <th><?php _efs('version', $slug) ?></th>
363
+ <th><?php _efs('plan', $slug) ?></th>
364
+ <th><?php _efs('license', $slug) ?></th>
365
+ <th></th>
366
+ <?php if (defined('WP_FS__DEV_MODE') && WP_FS__DEV_MODE) : ?>
367
+ <th></th>
368
+ <?php endif ?>
369
+ </tr>
370
+ </thead>
371
+ <tbody>
372
+ <?php $odd = true;
373
+ foreach ($addons_to_show as $addon_id) : ?>
374
  <?php
375
+ $addon = $fs->get_addon($addon_id);
376
+ $is_addon_activated = $fs->is_addon_activated($addon->slug);
377
+ $is_addon_connected = $fs->is_addon_connected($addon->slug);
378
 
379
+ $fs_addon = $is_addon_connected ? freemius($addon->slug) : false;
380
+ if (is_object($fs_addon)) {
381
+ $is_paying = $fs_addon->is_paying();
382
+ $user = $fs_addon->get_user();
383
+ $site = $fs_addon->get_site();
384
+ $license = $fs_addon->_get_license();
385
+ $subscription = $fs_addon->_get_subscription();
386
+ $plan = $fs_addon->get_plan();
387
+ $is_active_subscription = (is_object($subscription) && $subscription->is_active());
388
+ $is_paid_trial = $fs_addon->is_paid_trial();
389
+ $show_upgrade = (! $is_paying && ! $is_paid_trial && ! $fs_addon->_has_premium_license());
390
+ $is_current_license_expired = is_object($license) && $license->is_expired();
391
+ }
392
 
393
+ // var_dump( $is_paid_trial, $license, $site, $subscription );
394
 
395
+ ?>
396
+ <tr<?php if ($odd) {
397
+ echo ' class="alternate"';
398
+ } ?>>
399
+ <td>
400
+ <!-- Title -->
401
+ <?php echo $addon->title ?>
402
+ </td>
403
+ <?php if ($is_addon_connected) : ?>
404
  <?php // Add-on Installed ?>
405
  <?php $addon_site = $fs_addon->get_site(); ?>
406
+ <td>
407
+ <!-- ID -->
408
+ <?php echo $addon_site->id ?>
409
+ </td>
410
+ <td>
411
+ <!-- Version -->
412
+ <?php echo $fs_addon->get_plugin_version() ?>
413
+ </td>
414
+ <td>
415
+ <!-- Plan Title -->
416
+ <?php echo is_string($addon_site->plan->name) ? strtoupper($addon_site->plan->title) : 'FREE' ?>
417
+ </td>
418
+ <td>
419
+ <!-- Expiration -->
420
+ <?php
421
+ $tags = array();
422
 
423
+ if ($fs_addon->is_trial()) {
424
+ $tags[] = array('label' => __fs('trial', $slug), 'type' => 'success');
425
 
426
+ $tags[] = array(
427
+ 'label' => sprintf(__fs(($is_paid_trial ? 'renews-in' : 'expires-in'), $slug), human_time_diff(time(), strtotime($site->trial_ends))),
428
+ 'type' => ($is_paid_trial ? 'success' : 'warn')
429
+ );
430
+ } else {
431
+ if (is_object($license)) {
432
+ if ($license->is_cancelled) {
433
+ $tags[] = array(
434
+ 'label' => __fs('cancelled', $slug),
435
+ 'type' => 'error'
436
+ );
437
+ } else if ($license->is_expired()) {
438
+ $tags[] = array(
439
+ 'label' => __fs('expired', $slug),
440
+ 'type' => 'error'
441
+ );
442
+ } else if ($license->is_lifetime()) {
443
+ $tags[] = array(
444
+ 'label' => __fs('no-expiration', $slug),
445
+ 'type' => 'success'
446
+ );
447
+ } else if (! $is_active_subscription && ! $license->is_first_payment_pending()) {
448
+ $tags[] = array(
449
+ 'label' => sprintf(__fs('expires-in', $slug), human_time_diff(time(), strtotime($license->expiration))),
450
+ 'type' => 'warn'
451
+ );
452
+ } else if ($is_active_subscription && ! $subscription->is_first_payment_pending()) {
453
+ $tags[] = array(
454
+ 'label' => sprintf(__fs('renews-in', $slug), human_time_diff(time(), strtotime($subscription->next_payment))),
455
+ 'type' => 'success'
456
+ );
457
+ }
458
+ }
459
+ }
460
 
461
+ foreach ($tags as $t) {
462
+ printf('<label class="fs-tag fs-%s">%s</label>' . "\n", $t['type'], $t['label']);
463
+ }
464
+ ?>
465
+ </td>
466
+ <?php
467
+ $buttons = array();
468
+ if ($is_addon_activated) {
469
+ if ($is_paying) {
470
+ $buttons[] = fs_ui_get_action_button(
471
+ $slug,
472
+ 'account',
473
+ 'deactivate_license',
474
+ __fs('deactivate-license', $slug),
475
+ array('plugin_id' => $addon_id),
476
+ false
477
+ );
478
+ } else if ($is_paid_trial) {
479
+ $buttons[] = fs_ui_get_action_button(
480
+ $slug,
481
+ 'account',
482
+ 'cancel_trial',
483
+ __fs('cancel-trial', $slug),
484
+ array('plugin_id' => $addon_id),
485
+ false,
486
+ 'dashicons dashicons-download',
487
+ __fs('cancel-trial-confirm', $slug),
488
+ 'POST'
489
+ );
490
+ } else {
491
+ $premium_license = $fs_addon->_get_available_premium_license();
492
 
493
+ if (is_object($premium_license)) {
494
+ $site = $fs_addon->get_site();
495
 
496
+ $buttons[] = fs_ui_get_action_button(
497
+ $slug,
498
+ 'account',
499
+ 'activate_license',
500
+ sprintf(__fs('activate-x-plan', $slug), $fs_addon->get_plan_title(), ($site->is_localhost() && $premium_license->is_free_localhost) ? '[localhost]' : (1 < $premium_license->left() ? $premium_license->left() . ' left' : '')),
501
+ array(
502
+ 'plugin_id' => $addon_id,
503
+ 'license_id' => $premium_license->id,
504
+ )
505
+ );
506
+ }
507
+ }
508
 
509
+ if (0 == count($buttons)) {
510
+ // Add sync license only if non of the other CTAs are visible.
511
+ $buttons[] = fs_ui_get_action_button(
512
+ $slug,
513
+ 'account',
514
+ $slug . '_sync_license',
515
+ __fs('sync-license', $slug),
516
+ array('plugin_id' => $addon_id),
517
+ false
518
+ );
519
 
520
+ }
521
+ } else if (! $show_upgrade) {
522
+ if ($fs->is_addon_installed($addon->slug)) {
523
+ $addon_file = $fs->get_addon_basename($addon->slug);
524
+ $buttons[] = sprintf(
525
+ '<a class="button button-primary" href="%s" title="%s" class="edit">%s</a>',
526
+ wp_nonce_url('plugins.php?action=activate&amp;plugin=' . $addon_file, 'activate-plugin_' . $addon_file),
527
+ esc_attr(__fs('activate-this-addon', $slug)),
528
+ __fs('activate', $slug)
529
+ );
530
+ } else {
531
+ if ($fs->is_allowed_to_install()) {
532
+ $buttons[] = sprintf(
533
+ '<a class="button button-primary" href="%s" class="edit">%s</a>',
534
+ wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $addon->slug), 'install-plugin_' . $addon->slug),
535
+ __fs('install-now', $slug)
536
+ );
537
+ } else {
538
+ $buttons[] = sprintf(
539
+ '<a target="_blank" class="button button-primary" href="%s" class="edit">%s</a>',
540
+ $fs->_get_latest_download_local_url($addon_id),
541
+ __fs('download-latest', $slug)
542
+ );
543
+ }
544
+ }
545
+ }
546
 
547
+ if ($show_upgrade) {
548
+ $buttons[] = sprintf('<a href="%s" class="thickbox button button-primary" aria-label="%s" data-title="%s"><i class="dashicons dashicons-cart"></i> %s</a>',
549
+ esc_url(network_admin_url('plugin-install.php?tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
550
+ '&TB_iframe=true&width=600&height=550')),
551
+ esc_attr(sprintf(__fs('more-information-about-x', $slug), $addon->title)),
552
+ esc_attr($addon->title),
553
+ __fs(($fs_addon->has_free_plan() ? 'upgrade' : 'purchase'), $slug)
554
+ );
555
+ }
556
 
557
+ $buttons_count = count($buttons);
558
+ ?>
559
 
560
+ <td>
561
+ <!-- Actions -->
562
+ <?php if ($buttons_count > 1) : ?>
563
+ <div class="button-group">
564
+ <?php endif ?>
565
+ <?php foreach ($buttons as $button) : ?>
566
  <?php echo $button ?>
567
  <?php endforeach ?>
568
  <?php if ($buttons_count > 1) : ?>
569
+ </div>
570
+ <?php endif ?>
571
+ </td>
572
+ <?php else : ?>
573
  <?php // Add-on NOT Installed or was never connected.
574
+ ?>
575
+ <td colspan="4">
576
+ <!-- Action -->
577
+ <?php if ($fs->is_addon_installed($addon->slug)) : ?>
578
+ <?php $addon_file = $fs->get_addon_basename($addon->slug) ?>
579
+ <a class="button button-primary"
580
+ href="<?php echo wp_nonce_url('plugins.php?action=activate&amp;plugin=' . $addon_file, 'activate-plugin_' . $addon_file) ?>"
581
+ title="<?php esc_attr(__fs('activate-this-addon', $slug)) ?>"
582
+ class="edit"><?php _efs('activate', $slug) ?></a>
583
+ <?php else : ?>
584
+ <?php if ($fs->is_allowed_to_install()) : ?>
585
+ <a class="button button-primary"
586
+ href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $addon->slug), 'install-plugin_' . $addon->slug) ?>"><?php _efs('install-now', $slug) ?></a>
587
+ <?php else : ?>
588
+ <a target="_blank" class="button button-primary"
589
+ href="<?php echo $fs->_get_latest_download_local_url($addon_id) ?>"><?php _efs('download-latest', $slug) ?></a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
590
  <?php endif ?>
591
+ <?php endif ?>
592
+ </td>
593
+ <?php endif ?>
594
+ <?php if (defined('WP_FS__DEV_MODE') && WP_FS__DEV_MODE) : ?>
595
+ <td>
596
+ <!-- Optional Delete Action -->
597
+ <?php
598
+ if ($is_addon_activated) {
599
+ fs_ui_action_button(
600
+ $slug, 'account',
601
+ 'delete_account',
602
+ __fs('delete', $slug),
603
+ array('plugin_id' => $addon_id),
604
+ false
605
+ );
606
+ }
607
+ ?>
608
+ </td>
609
+ <?php endif ?>
610
+ </tr>
611
+ <?php $odd = ! $odd;
612
+ endforeach ?>
613
+ </tbody>
614
+ </table>
615
+ </div>
616
+ </div>
617
+ <?php endif ?>
618
 
619
+ <?php $fs->do_action('after_account_details') ?>
620
+ </div>
621
+ </div>
622
+ </div>
623
+ </div>
624
+ </div>
625
+ <?php fs_require_template('powered-by.php') ?>
freemius/templates/add-ons.php CHANGED
@@ -24,29 +24,33 @@
24
  * @var FS_Plugin[]
25
  */
26
  $addons = $fs->get_addons();
 
 
27
  ?>
28
  <div id="fs_addons" class="wrap">
29
  <h2><?php printf( __fs( 'add-ons-for-x', $slug ), $fs->get_plugin_name() ) ?></h2>
30
 
31
  <div id="poststuff">
32
- <?php if ( ! is_array( $addons ) || 0 == count( $addons ) ) : ?>
33
  <h3><?php printf(
34
  '%s... %s',
35
  __fs( 'oops', $slug ),
36
  __fs( 'add-ons-missing', $slug )
37
  ) ?></h3>
38
- <?php else : ?>
39
- <ul class="fs-cards-list">
 
40
  <?php foreach ( $addons as $addon ) : ?>
41
  <?php
42
  $open_addon = ( $open_addon || ( $open_addon_slug === $addon->slug ) );
43
 
44
  $price = 0;
 
45
  $plans_result = $fs->get_api_site_or_plugin_scope()->get( "/addons/{$addon->id}/plans.json" );
46
  if ( ! isset( $plans_result->error ) ) {
47
  $plans = $plans_result->plans;
48
  if ( is_array( $plans ) && 0 < count( $plans ) ) {
49
- $plan = $plans[0];
50
  $pricing_result = $fs->get_api_site_or_plugin_scope()->get( "/addons/{$addon->id}/plans/{$plan->id}/pricing.json" );
51
  if ( ! isset( $pricing_result->error ) ) {
52
  // Update plan's pricing.
@@ -70,7 +74,7 @@
70
  }
71
  }
72
  ?>
73
- <li class="fs-card" data-slug="<?php echo $addon->slug ?>">
74
  <?php
75
  echo sprintf( '<a href="%s" class="thickbox fs-overlay" aria-label="%s" data-title="%s"></a>',
76
  esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
@@ -94,23 +98,26 @@
94
  <ul>
95
  <li class="fs-card-banner"
96
  style="background-image: url('<?php echo $addon->info->card_banner_url ?>');"></li>
 
97
  <li class="fs-title"><?php echo $addon->title ?></li>
98
  <li class="fs-offer">
99
  <span
100
- class="fs-price"><?php echo ( 0 == $price ) ? __fs( 'free', $slug ) : '$' . number_format( $price, 2 ) ?></span>
101
  </li>
102
  <li class="fs-description"><?php echo ! empty( $addon->info->short_description ) ? $addon->info->short_description : 'SHORT DESCRIPTION' ?></li>
 
103
  </ul>
104
  </div>
105
  </li>
106
  <?php endforeach ?>
107
- </ul>
108
- <?php endif ?>
109
  </div>
110
  </div>
111
- <?php if ( $open_addon ) : ?>
112
  <script type="text/javascript">
113
  (function ($) {
 
 
114
  var interval = setInterval(function () {
115
  // Open add-on information page.
116
  $('.fs-card[data-slug=<?php echo $open_addon_slug ?>] a').click();
@@ -119,7 +126,19 @@
119
  interval = null;
120
  }
121
  }, 200);
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  })(jQuery);
123
  </script>
124
- <?php endif ?>
125
  <?php fs_require_template( 'powered-by.php' ) ?>
24
  * @var FS_Plugin[]
25
  */
26
  $addons = $fs->get_addons();
27
+
28
+ $has_addons = ( is_array( $addons ) && 0 < count( $addons ) );
29
  ?>
30
  <div id="fs_addons" class="wrap">
31
  <h2><?php printf( __fs( 'add-ons-for-x', $slug ), $fs->get_plugin_name() ) ?></h2>
32
 
33
  <div id="poststuff">
34
+ <?php if ( ! $has_addons ) : ?>
35
  <h3><?php printf(
36
  '%s... %s',
37
  __fs( 'oops', $slug ),
38
  __fs( 'add-ons-missing', $slug )
39
  ) ?></h3>
40
+ <?php endif ?>
41
+ <ul class="fs-cards-list">
42
+ <?php if ( $has_addons ) : ?>
43
  <?php foreach ( $addons as $addon ) : ?>
44
  <?php
45
  $open_addon = ( $open_addon || ( $open_addon_slug === $addon->slug ) );
46
 
47
  $price = 0;
48
+ $plan = null;
49
  $plans_result = $fs->get_api_site_or_plugin_scope()->get( "/addons/{$addon->id}/plans.json" );
50
  if ( ! isset( $plans_result->error ) ) {
51
  $plans = $plans_result->plans;
52
  if ( is_array( $plans ) && 0 < count( $plans ) ) {
53
+ $plan = new FS_Plugin_Plan( $plans[0] );
54
  $pricing_result = $fs->get_api_site_or_plugin_scope()->get( "/addons/{$addon->id}/plans/{$plan->id}/pricing.json" );
55
  if ( ! isset( $pricing_result->error ) ) {
56
  // Update plan's pricing.
74
  }
75
  }
76
  ?>
77
+ <li class="fs-card fs-addon" data-slug="<?php echo $addon->slug ?>">
78
  <?php
79
  echo sprintf( '<a href="%s" class="thickbox fs-overlay" aria-label="%s" data-title="%s"></a>',
80
  esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
98
  <ul>
99
  <li class="fs-card-banner"
100
  style="background-image: url('<?php echo $addon->info->card_banner_url ?>');"></li>
101
+ <!-- <li class="fs-tag"></li>-->
102
  <li class="fs-title"><?php echo $addon->title ?></li>
103
  <li class="fs-offer">
104
  <span
105
+ class="fs-price"><?php echo ( 0 == $price ) ? __fs( 'free', $slug ) : ('$' . number_format( $price, 2 ) . ($plan->has_trial() ? ' - ' . __fs('trial', $slug) : '')) ?></span>
106
  </li>
107
  <li class="fs-description"><?php echo ! empty( $addon->info->short_description ) ? $addon->info->short_description : 'SHORT DESCRIPTION' ?></li>
108
+ <li class="fs-cta"><a class="button"><?php _efs( 'view-details', $slug ) ?></a></li>
109
  </ul>
110
  </div>
111
  </li>
112
  <?php endforeach ?>
113
+ <?php endif ?>
114
+ </ul>
115
  </div>
116
  </div>
 
117
  <script type="text/javascript">
118
  (function ($) {
119
+ <?php if ( $open_addon ) : ?>
120
+
121
  var interval = setInterval(function () {
122
  // Open add-on information page.
123
  $('.fs-card[data-slug=<?php echo $open_addon_slug ?>] a').click();
126
  interval = null;
127
  }
128
  }, 200);
129
+
130
+ <?php else : ?>
131
+
132
+
133
+ $('.fs-card.fs-addon').mouseover(function(){
134
+ $(this).find('.fs-cta .button').addClass('button-primary');
135
+ });
136
+
137
+ $('.fs-card.fs-addon').mouseout(function(){
138
+ $(this).find('.fs-cta .button').removeClass('button-primary');
139
+ });
140
+
141
+ <?php endif ?>
142
  })(jQuery);
143
  </script>
 
144
  <?php fs_require_template( 'powered-by.php' ) ?>
freemius/templates/connect.php CHANGED
@@ -13,6 +13,10 @@
13
  $slug = $VARS['slug'];
14
  $fs = freemius( $slug );
15
  $is_pending_activation = $fs->is_pending_activation();
 
 
 
 
16
 
17
  $fs->_enqueue_connect_essentials();
18
 
@@ -32,11 +36,23 @@
32
  $freemius_site_url = $fs->has_paid_plan() ?
33
  'https://freemius.com/wordpress/' :
34
  // Insights platform information.
35
- 'https://freemius.com/wordpress/insights/';
 
 
 
 
 
 
 
 
 
 
 
36
  ?>
37
- <div id="fs_connect" class="wrap<?php if ( ! $fs->enable_anonymous() || $is_pending_activation ) {
38
- echo ' fs-anonymous-disabled';
39
- } ?>">
 
40
  <div class="fs-visual">
41
  <b class="fs-site-icon"><i class="dashicons dashicons-wordpress"></i></b>
42
  <i class="dashicons dashicons-plus fs-first"></i>
@@ -48,8 +64,15 @@
48
  <img class="fs-connect-logo" width="80" height="80" src="//img.freemius.com/connect-logo.png"/>
49
  </div>
50
  <div class="fs-content">
 
 
 
51
  <p><?php
 
 
52
  if ( $is_pending_activation ) {
 
 
53
  echo $fs->apply_filters( 'pending_activation_message', sprintf(
54
  __fs( 'thanks-x', $slug ) . '<br>' .
55
  __fs( 'pending-activation-message', $slug ),
@@ -57,6 +80,15 @@
57
  '<b>' . $fs->get_plugin_name() . '</b>',
58
  '<b>' . $current_user->user_email . '</b>'
59
  ) );
 
 
 
 
 
 
 
 
 
60
  } else {
61
  $filter = 'connect_message';
62
  $default_optin_message = 'connect-message';
@@ -82,19 +114,26 @@
82
  '<b>' . $fs->get_plugin_name() . '</b>',
83
  '<b>' . $current_user->user_login . '</b>',
84
  '<a href="' . $site_url . '" target="_blank">' . $site_url . '</a>',
85
- '<a href="' . $freemius_site_url . '" target="_blank">freemius.com</a>'
86
  ),
87
  $first_name,
88
  $fs->get_plugin_name(),
89
  $current_user->user_login,
90
  '<a href="' . $site_url . '" target="_blank">' . $site_url . '</a>',
91
- '<a href="' . $freemius_site_url . '" target="_blank">freemius.com</a>'
92
  );
93
  }
94
  ?></p>
 
 
 
 
 
 
 
95
  </div>
96
  <div class="fs-actions">
97
- <?php if ( $fs->enable_anonymous() && ! $is_pending_activation ) : ?>
98
  <a href="<?php echo wp_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $slug . '_skip_activation' ) ), $slug . '_skip_activation' ) ?>"
99
  class="button button-secondary" tabindex="2"><?php _efs( 'skip', $slug ) ?></a>
100
  <?php endif ?>
@@ -105,7 +144,9 @@
105
  <input type="hidden" name="fs_action" value="<?php echo $slug ?>_activate_existing">
106
  <?php wp_nonce_field( 'activate_existing_' . $fs->get_public_key() ) ?>
107
  <button class="button button-primary" tabindex="1"
108
- type="submit"><?php _efs( 'opt-in-connect', $slug ) ?></button>
 
 
109
  </form>
110
  <?php else : ?>
111
  <form method="post" action="<?php echo WP_FS__ADDRESS ?>/action/service/user/install/">
@@ -114,7 +155,9 @@
114
  <input type="hidden" name="<?php echo $name ?>" value="<?php echo esc_attr( $value ) ?>">
115
  <?php endforeach ?>
116
  <button class="button button-primary" tabindex="1"
117
- type="submit"><?php _efs( $is_pending_activation ? 'resend-activation-email' : 'opt-in-connect', $slug ) ?></button>
 
 
118
  </form>
119
  <?php endif ?>
120
  </div><?php
@@ -128,7 +171,7 @@
128
  'priority' => 5,
129
  ),
130
  'site' => array(
131
- 'icon-class' => 'dashicons dashicons-wordpress',
132
  'label' => __fs( 'permissions-site' ),
133
  'desc' => __fs( 'permissions-site_desc' ),
134
  'priority' => 10,
@@ -139,6 +182,12 @@
139
  'desc' => __fs( 'permissions-events_desc' ),
140
  'priority' => 20,
141
  ),
 
 
 
 
 
 
142
  );
143
 
144
  // Add newsletter permissions if enabled.
@@ -159,7 +208,10 @@
159
 
160
  if ( ! empty( $permissions ) ) : ?>
161
  <div class="fs-permissions">
162
- <a class="fs-trigger" href="#"><?php _efs( 'what-permissions', $slug ) ?></a>
 
 
 
163
  <ul><?php
164
  foreach ( $permissions as $id => $permission ) : ?>
165
  <li id="fs-permission-<?php esc_attr_e( $id ); ?>"
@@ -175,26 +227,107 @@
175
  <?php endforeach; ?>
176
  </ul>
177
  </div>
178
- <?php endif; ?>
179
-
 
 
 
 
 
 
 
 
 
 
 
 
180
  <div class="fs-terms">
181
- <a href="https://freemius.com/privacy/" target="_blank"><?php _efs( 'privacy-policy', $slug ) ?></a>
 
182
  &nbsp;&nbsp;-&nbsp;&nbsp;
183
- <a href="https://freemius.com/terms/" target="_blank"><?php _efs( 'tos', $slug ) ?></a>
184
  </div>
185
  </div>
186
  <script type="text/javascript">
187
  (function ($) {
188
- $('.button').on('click', function () {
 
 
 
 
 
 
189
  // Set loading mode.
190
  $(document.body).css({'cursor': 'wait'});
191
  });
192
- $('.button.button-primary').on('click', function () {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  $(this).addClass('fs-loading');
194
  $(this).html('<?php _efs( $is_pending_activation ? 'sending-email' : 'activating' , $slug ) ?>...').css({'cursor': 'wait'});
195
  });
 
196
  $('.fs-permissions .fs-trigger').on('click', function () {
197
  $('.fs-permissions').toggleClass('fs-open');
198
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  })(jQuery);
200
  </script>
13
  $slug = $VARS['slug'];
14
  $fs = freemius( $slug );
15
  $is_pending_activation = $fs->is_pending_activation();
16
+ $is_premium_only = $fs->is_only_premium();
17
+ $has_paid_plans = $fs->has_paid_plan();
18
+ $is_premium_code = $fs->is_premium();
19
+ $is_freemium = $fs->is_freemium();
20
 
21
  $fs->_enqueue_connect_essentials();
22
 
36
  $freemius_site_url = $fs->has_paid_plan() ?
37
  'https://freemius.com/wordpress/' :
38
  // Insights platform information.
39
+ 'https://freemius.com/wordpress/usage-tracking/';
40
+
41
+ $freemius_site_url .= '?' . http_build_query( array(
42
+ 'plugin_id' => $fs->get_id(),
43
+ ) );
44
+
45
+ $freemius_link = '<a href="' . $freemius_site_url . '" target="_blank" tabindex="1">freemius.com</a>';
46
+
47
+ $error = fs_request_get( 'error' );
48
+
49
+ $require_license_key = $is_premium_only ||
50
+ ( $is_freemium && $is_premium_code && fs_request_get_bool( 'require_license', true ) );
51
  ?>
52
+ <div id="fs_connect"
53
+ class="wrap<?php if ( ! $fs->is_enable_anonymous() || $is_pending_activation || $require_license_key ) {
54
+ echo ' fs-anonymous-disabled';
55
+ } ?>">
56
  <div class="fs-visual">
57
  <b class="fs-site-icon"><i class="dashicons dashicons-wordpress"></i></b>
58
  <i class="dashicons dashicons-plus fs-first"></i>
64
  <img class="fs-connect-logo" width="80" height="80" src="//img.freemius.com/connect-logo.png"/>
65
  </div>
66
  <div class="fs-content">
67
+ <?php if ( ! empty( $error ) ) : ?>
68
+ <p class="fs-error"><?php echo $error ?></p>
69
+ <?php endif ?>
70
  <p><?php
71
+ $button_label = 'opt-in-connect';
72
+
73
  if ( $is_pending_activation ) {
74
+ $button_label = 'resend-activation-email';
75
+
76
  echo $fs->apply_filters( 'pending_activation_message', sprintf(
77
  __fs( 'thanks-x', $slug ) . '<br>' .
78
  __fs( 'pending-activation-message', $slug ),
80
  '<b>' . $fs->get_plugin_name() . '</b>',
81
  '<b>' . $current_user->user_email . '</b>'
82
  ) );
83
+ } else if ( $require_license_key ) {
84
+ $button_label = 'agree-activate-license';
85
+
86
+ echo $fs->apply_filters( 'connect-message_on-premium',
87
+ sprintf( __fs( 'hey-x', $slug ), $first_name ) . '<br>' .
88
+ sprintf( __fs( 'thanks-for-purchasing', $slug ), '<b>' . $fs->get_plugin_name() . '</b>' ),
89
+ $first_name,
90
+ $fs->get_plugin_name()
91
+ );
92
  } else {
93
  $filter = 'connect_message';
94
  $default_optin_message = 'connect-message';
114
  '<b>' . $fs->get_plugin_name() . '</b>',
115
  '<b>' . $current_user->user_login . '</b>',
116
  '<a href="' . $site_url . '" target="_blank">' . $site_url . '</a>',
117
+ $freemius_link
118
  ),
119
  $first_name,
120
  $fs->get_plugin_name(),
121
  $current_user->user_login,
122
  '<a href="' . $site_url . '" target="_blank">' . $site_url . '</a>',
123
+ $freemius_link
124
  );
125
  }
126
  ?></p>
127
+ <?php if ( $require_license_key ) : ?>
128
+ <div class="fs-license-key-container">
129
+ <input id="fs_license_key" name="fs_key" type="text" required maxlength="32"
130
+ placeholder="<?php _efs( 'license-key', $slug ) ?>" tabindex="1"/>
131
+ <i class="dashicons dashicons-admin-network"></i>
132
+ </div>
133
+ <?php endif ?>
134
  </div>
135
  <div class="fs-actions">
136
+ <?php if ( $fs->is_enable_anonymous() && ! $is_pending_activation && ! $require_license_key ) : ?>
137
  <a href="<?php echo wp_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $slug . '_skip_activation' ) ), $slug . '_skip_activation' ) ?>"
138
  class="button button-secondary" tabindex="2"><?php _efs( 'skip', $slug ) ?></a>
139
  <?php endif ?>
144
  <input type="hidden" name="fs_action" value="<?php echo $slug ?>_activate_existing">
145
  <?php wp_nonce_field( 'activate_existing_' . $fs->get_public_key() ) ?>
146
  <button class="button button-primary" tabindex="1"
147
+ type="submit"<?php if ( $require_license_key ) {
148
+ echo ' disabled="disabled"';
149
+ } ?>><?php _efs( $button_label, $slug ) ?></button>
150
  </form>
151
  <?php else : ?>
152
  <form method="post" action="<?php echo WP_FS__ADDRESS ?>/action/service/user/install/">
155
  <input type="hidden" name="<?php echo $name ?>" value="<?php echo esc_attr( $value ) ?>">
156
  <?php endforeach ?>
157
  <button class="button button-primary" tabindex="1"
158
+ type="submit"<?php if ( $require_license_key ) {
159
+ echo ' disabled="disabled"';
160
+ } ?>><?php _efs( $button_label, $slug ) ?></button>
161
  </form>
162
  <?php endif ?>
163
  </div><?php
171
  'priority' => 5,
172
  ),
173
  'site' => array(
174
+ 'icon-class' => 'dashicons dashicons-admin-settings',
175
  'label' => __fs( 'permissions-site' ),
176
  'desc' => __fs( 'permissions-site_desc' ),
177
  'priority' => 10,
182
  'desc' => __fs( 'permissions-events_desc' ),
183
  'priority' => 20,
184
  ),
185
+ // 'plugins_themes' => array(
186
+ // 'icon-class' => 'dashicons dashicons-admin-settings',
187
+ // 'label' => __fs( 'permissions-plugins_themes' ),
188
+ // 'desc' => __fs( 'permissions-plugins_themes_desc' ),
189
+ // 'priority' => 30,
190
+ // ),
191
  );
192
 
193
  // Add newsletter permissions if enabled.
208
 
209
  if ( ! empty( $permissions ) ) : ?>
210
  <div class="fs-permissions">
211
+ <?php if ( $require_license_key ) : ?>
212
+ <p class="fs-license-sync-disclaimer"><?php printf( __fs( 'license-sync-disclaimer', $slug ), $freemius_link ) ?></p>
213
+ <?php endif ?>
214
+ <a class="fs-trigger" href="#" tabindex="1"><?php _efs( 'what-permissions', $slug ) ?></a>
215
  <ul><?php
216
  foreach ( $permissions as $id => $permission ) : ?>
217
  <li id="fs-permission-<?php esc_attr_e( $id ); ?>"
227
  <?php endforeach; ?>
228
  </ul>
229
  </div>
230
+ <?php endif ?>
231
+ <?php if ( $is_premium_code && $is_freemium ) : ?>
232
+ <div class="fs-freemium-licensing">
233
+ <p>
234
+ <?php if ( $require_license_key ) : ?>
235
+ <?php _efs( 'dont-have-license-key', $slug ) ?>
236
+ <a data-require-license="false" tabindex="1"><?php _efs( 'activate-free-version', $slug ) ?></a>
237
+ <?php else : ?>
238
+ <?php _efs( 'have-license-key', $slug ) ?>
239
+ <a data-require-license="true" tabindex="1"><?php _efs( 'activate-license', $slug ) ?></a>
240
+ <?php endif ?>
241
+ </p>
242
+ </div>
243
+ <?php endif ?>
244
  <div class="fs-terms">
245
+ <a href="https://freemius.com/privacy/" target="_blank"
246
+ tabindex="1"><?php _efs( 'privacy-policy', $slug ) ?></a>
247
  &nbsp;&nbsp;-&nbsp;&nbsp;
248
+ <a href="https://freemius.com/terms/" target="_blank" tabindex="1"><?php _efs( 'tos', $slug ) ?></a>
249
  </div>
250
  </div>
251
  <script type="text/javascript">
252
  (function ($) {
253
+ var $primaryCta = $('.fs-actions .button.button-primary'),
254
+ $form = $('.fs-actions form'),
255
+ requireLicenseKey = <?php echo $require_license_key ? 'true' : 'false' ?>,
256
+ $licenseSecret,
257
+ $licenseKeyInput = $('#fs_license_key');
258
+
259
+ $('.fs-actions .button').on('click', function () {
260
  // Set loading mode.
261
  $(document.body).css({'cursor': 'wait'});
262
  });
263
+
264
+ $form.on('submit', function () {
265
+ /**
266
+ * @author Vova Feldman (@svovaf)
267
+ * @since 1.1.9
268
+ */
269
+ if (requireLicenseKey) {
270
+ if (null == $licenseSecret) {
271
+ $licenseSecret = $('<input type="hidden" name="license_secret_key" value="" />');
272
+ $form.append($licenseSecret);
273
+ }
274
+
275
+ // Update secret key if premium only plugin.
276
+ $licenseSecret.val($licenseKeyInput.val());
277
+ }
278
+
279
+ return true;
280
+ });
281
+
282
+ $primaryCta.on('click', function () {
283
  $(this).addClass('fs-loading');
284
  $(this).html('<?php _efs( $is_pending_activation ? 'sending-email' : 'activating' , $slug ) ?>...').css({'cursor': 'wait'});
285
  });
286
+
287
  $('.fs-permissions .fs-trigger').on('click', function () {
288
  $('.fs-permissions').toggleClass('fs-open');
289
  });
290
+
291
+ if (requireLicenseKey) {
292
+ /**
293
+ * Submit license key on enter.
294
+ *
295
+ * @author Vova Feldman (@svovaf)
296
+ * @since 1.1.9
297
+ */
298
+ $licenseKeyInput.keypress(function (e) {
299
+ if (e.which == 13) {
300
+ if ('' !== $(this).val()) {
301
+ $primaryCta.click();
302
+ return false;
303
+ }
304
+ }
305
+ });
306
+
307
+ /**
308
+ * Disable activation button when empty license key.
309
+ *
310
+ * @author Vova Feldman (@svovaf)
311
+ * @since 1.1.9
312
+ */
313
+ $licenseKeyInput.on('keyup', function () {
314
+ if ('' === $(this).val()) {
315
+ $primaryCta.attr('disabled', 'disabled');
316
+ } else {
317
+ $primaryCta.prop('disabled', false);
318
+ }
319
+ }).focus();
320
+ }
321
+
322
+ /**
323
+ * Set license mode trigger URL.
324
+ *
325
+ * @author Vova Feldman (@svovaf)
326
+ * @since 1.1.9
327
+ */
328
+ var $connectLicenseModeTrigger = $('#fs_connect .fs-freemium-licensing a');
329
+ if ($connectLicenseModeTrigger.length > 0) {
330
+ $connectLicenseModeTrigger.attr('href', window.location.href + '&require_license=' + $connectLicenseModeTrigger.attr('data-require-license'))
331
+ }
332
  })(jQuery);
333
  </script>
freemius/templates/deactivation-feedback-modal.php CHANGED
@@ -25,177 +25,258 @@
25
  }
26
  ?>
27
  <script type="text/javascript">
28
- (function ($) {
29
- var reasonsHtml = <?php echo json_encode( $reasons_list_items_html ); ?>,
30
- modalHtml =
31
- '<div class="fs-modal<?php echo empty( $confirmation_message ) ? ' no-confirmation-message' : ''; ?>">'
32
- + ' <div class="fs-modal-dialog">'
33
- + ' <div class="fs-modal-body">'
34
- + ' <div class="fs-modal-panel" data-panel-id="confirm"><p><?php echo $confirmation_message; ?></p></div>'
35
- + ' <div class="fs-modal-panel active" data-panel-id="reasons"><h3><strong><?php printf( __fs( 'deactivation-share-reason' , $slug ) ); ?>:</strong></h3><ul id="reasons-list">' + reasonsHtml + '</ul></div>'
36
- + ' </div>'
37
- + ' <div class="fs-modal-footer">'
38
- + ' <a href="#" class="button button-secondary button-deactivate"></a>'
39
- + ' <a href="#" class="button button-primary button-close"><?php printf( __fs( 'deactivation-modal-button-cancel' , $slug ) ); ?></a>'
40
- + ' </div>'
41
- + ' </div>'
42
- + '</div>',
43
- $modal = $(modalHtml),
44
- $deactivateLink = $('#the-list .deactivate > [data-slug=<?php echo $VARS['slug']; ?>].fs-slug').prev();
45
-
46
- $modal.appendTo($('body'));
47
-
48
- registerEventHandlers();
49
-
50
- function registerEventHandlers() {
51
- $deactivateLink.click(function (evt) {
52
- evt.preventDefault();
53
-
54
- showModal();
55
- });
56
-
57
- $modal.on('click', '.button', function (evt) {
58
- evt.preventDefault();
59
-
60
- if ($(this).hasClass('disabled')) {
61
- return;
62
- }
63
 
64
- var _parent = $(this).parents('.fs-modal:first');
65
- var _this = $(this);
66
 
67
- if (_this.hasClass('allow-deactivate')) {
68
- var $radio = $('input[type="radio"]:checked');
 
 
 
 
 
 
 
69
 
70
- if (0 === $radio.length) {
71
- // If no selected reason, just deactivate the plugin.
72
- window.location.href = $deactivateLink.attr('href');
73
- return;
74
- }
75
 
76
- var $selected_reason = $radio.parents('li:first'),
77
- $input = $selected_reason.find('textarea, input[type="text"]');
78
-
79
- $.ajax({
80
- url : ajaxurl,
81
- method : 'POST',
82
- data : {
83
- 'action' : 'submit-uninstall-reason',
84
- 'reason_id' : $radio.val(),
85
- 'reason_info': ( 0 !== $input.length ) ? $input.val().trim() : ''
86
- },
87
- beforeSend: function () {
88
- _parent.find('.button').addClass('disabled');
89
- _parent.find('.button-secondary').text('Processing...');
90
- },
91
- complete : function () {
92
- // Do not show the dialog box, deactivate the plugin.
93
- window.location.href = $deactivateLink.attr('href');
94
- }
95
- });
96
- } else if (_this.hasClass('button-deactivate')) {
97
- // Change the Deactivate button's text and show the reasons panel.
98
- _parent.find('.button-deactivate').addClass('allow-deactivate');
99
-
100
- showPanel('reasons');
101
  }
102
- });
103
 
104
- $modal.on('click', 'input[type="radio"]', function () {
105
- var _parent = $(this).parents('li:first');
 
 
 
 
 
 
 
 
106
 
107
- $modal.find('.reason-input').remove();
108
- $modal.find('.button-deactivate').text('<?php printf( __fs( 'deactivation-modal-button-submit' , $slug ) ); ?>');
109
 
110
- if (_parent.hasClass('has-input')) {
111
- var inputType = _parent.data('input-type'),
112
- inputPlaceholder = _parent.data('input-placeholder'),
113
- reasonInputHtml = '<div class="reason-input">' + ( ( 'textfield' === inputType ) ? '<input type="text" />' : '<textarea rows="5"></textarea>' ) + '</div>';
114
 
115
- _parent.append($(reasonInputHtml));
116
- _parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus();
117
- }
118
- });
119
 
120
- // If the user has clicked outside the window, cancel it.
121
- $modal.on('click', function (evt) {
122
- var $target = $(evt.target);
123
 
124
- // If the user has clicked anywhere in the modal dialog, just return.
125
- if ($target.hasClass('fs-modal-body') || $target.hasClass('fs-modal-footer')) {
 
126
  return;
127
  }
128
 
129
- // If the user has not clicked the close button and the clicked element is inside the modal dialog, just return.
130
- if (!$target.hasClass('button-close') && ( $target.parents('.fs-modal-body').length > 0 || $target.parents('.fs-modal-footer').length > 0 )) {
 
 
 
131
  return;
132
  }
133
 
134
- closeModal();
135
- });
136
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
- function showModal() {
139
- resetModal();
 
140
 
141
- // Display the dialog box.
142
- $modal.addClass('active');
143
 
144
- $('body').addClass('has-fs-modal');
145
- }
 
146
 
147
- function closeModal() {
148
- $modal.removeClass('active');
149
 
150
- $('body').removeClass('has-fs-modal');
151
- }
152
 
153
- function resetModal() {
154
- $modal.find('.button').removeClass('disabled');
155
 
156
- // Uncheck all radio buttons.
157
- $modal.find('input[type="radio"]').prop('checked', false);
158
 
159
- // Remove all input fields ( textfield, textarea ).
160
- $modal.find('.reason-input').remove();
 
 
161
 
162
- var $deactivateButton = $modal.find('.button-deactivate');
 
163
 
164
- /*
165
- * If the modal dialog has no confirmation message, that is, it has only one panel, then ensure
166
- * that clicking the deactivate button will actually deactivate the plugin.
167
- */
168
- if ($modal.hasClass('no-confirmation-message')) {
169
- $deactivateButton.addClass('allow-deactivate');
170
 
171
- showPanel('reasons');
172
- } else {
173
- $deactivateButton.removeClass('allow-deactivate');
174
 
175
- showPanel('confirm');
 
 
176
  }
177
- }
178
 
179
- function showPanel(panelType) {
180
- $modal.find('.fs-modal-panel').removeClass('active ');
181
- $modal.find('[data-panel-id="' + panelType + '"]').addClass('active');
 
182
 
183
- updateButtonLabels();
184
- }
 
185
 
186
- function updateButtonLabels() {
187
- var $deactivateButton = $modal.find('.button-deactivate');
 
 
188
 
189
- // Reset the deactivate button's text.
190
- if ('confirm' === getCurrentPanel()) {
191
- $deactivateButton.text('<?php printf( __fs( 'deactivation-modal-button-confirm' , $slug ) ); ?>');
192
- } else {
193
- $deactivateButton.text('<?php printf( __fs( 'deactivate' , $slug ) ); ?>');
194
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
196
 
197
- function getCurrentPanel() {
198
- return $modal.find('.fs-modal-panel.active').attr('data-panel-id');
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  }
200
- })(jQuery);
 
 
 
 
 
201
  </script>
25
  }
26
  ?>
27
  <script type="text/javascript">
28
+ (function ($) {
29
+ var reasonsHtml = <?php echo json_encode( $reasons_list_items_html ); ?>,
30
+ modalHtml =
31
+ '<div class="fs-modal<?php echo empty( $confirmation_message ) ? ' no-confirmation-message' : ''; ?>">'
32
+ + ' <div class="fs-modal-dialog">'
33
+ + ' <div class="fs-modal-body">'
34
+ + ' <div class="fs-modal-panel" data-panel-id="confirm"><p><?php echo $confirmation_message; ?></p></div>'
35
+ + ' <div class="fs-modal-panel active" data-panel-id="reasons"><h3><strong><?php printf( __fs( 'deactivation-share-reason' , $slug ) ); ?>:</strong></h3><ul id="reasons-list">' + reasonsHtml + '</ul></div>'
36
+ + ' </div>'
37
+ + ' <div class="fs-modal-footer">'
38
+ + ' <a href="#" class="button button-secondary button-deactivate"></a>'
39
+ + ' <a href="#" class="button button-primary button-close"><?php printf( __fs( 'deactivation-modal-button-cancel' , $slug ) ); ?></a>'
40
+ + ' </div>'
41
+ + ' </div>'
42
+ + '</div>',
43
+ $modal = $(modalHtml),
44
+ $deactivateLink = $('#the-list .deactivate > [data-slug=<?php echo $VARS['slug']; ?>].fs-slug').prev(),
45
+ selectedReasonID = false;
46
+
47
+ $modal.appendTo($('body'));
48
+
49
+ registerEventHandlers();
50
+
51
+ function registerEventHandlers() {
52
+ $deactivateLink.click(function (evt) {
53
+ evt.preventDefault();
54
+
55
+ showModal();
56
+ });
57
+
58
+ $modal.on('input propertychange', '.reason-input input', function () {
59
+ if (!isOtherReasonSelected()) {
60
+ return;
61
+ }
 
62
 
63
+ var reason = $(this).val().trim();
 
64
 
65
+ /**
66
+ * If reason is not empty, remove the error-message class of the message container
67
+ * to change the message color back to default.
68
+ */
69
+ if (reason.length > 0) {
70
+ $('.message').removeClass('error-message');
71
+ enableDeactivateButton();
72
+ }
73
+ });
74
 
75
+ $modal.on('blur', '.reason-input input', function () {
76
+ var $userReason = $(this);
 
 
 
77
 
78
+ setTimeout(function () {
79
+ if (!isOtherReasonSelected()) {
80
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
 
82
 
83
+ /**
84
+ * If reason is empty, add the error-message class to the message container
85
+ * to change the message color to red.
86
+ */
87
+ if (0 === $userReason.val().trim().length) {
88
+ $('.message').addClass('error-message');
89
+ disableDeactivateButton();
90
+ }
91
+ }, 150);
92
+ });
93
 
94
+ $modal.on('click', '.button', function (evt) {
95
+ evt.preventDefault();
96
 
97
+ if ($(this).hasClass('disabled')) {
98
+ return;
99
+ }
 
100
 
101
+ var _parent = $(this).parents('.fs-modal:first');
102
+ var _this = $(this);
 
 
103
 
104
+ if (_this.hasClass('allow-deactivate')) {
105
+ var $radio = $('input[type="radio"]:checked');
 
106
 
107
+ if (0 === $radio.length) {
108
+ // If no selected reason, just deactivate the plugin.
109
+ window.location.href = $deactivateLink.attr('href');
110
  return;
111
  }
112
 
113
+ var $selected_reason = $radio.parents('li:first'),
114
+ $input = $selected_reason.find('textarea, input[type="text"]'),
115
+ userReason = ( 0 !== $input.length ) ? $input.val().trim() : '';
116
+
117
+ if (isOtherReasonSelected() && ( '' === userReason )) {
118
  return;
119
  }
120
 
121
+ $.ajax({
122
+ url : ajaxurl,
123
+ method : 'POST',
124
+ data : {
125
+ 'action' : 'submit-uninstall-reason',
126
+ 'reason_id' : $radio.val(),
127
+ 'reason_info': userReason
128
+ },
129
+ beforeSend: function () {
130
+ _parent.find('.button').addClass('disabled');
131
+ _parent.find('.button-secondary').text('Processing...');
132
+ },
133
+ complete : function () {
134
+ // Do not show the dialog box, deactivate the plugin.
135
+ window.location.href = $deactivateLink.attr('href');
136
+ }
137
+ });
138
+ } else if (_this.hasClass('button-deactivate')) {
139
+ // Change the Deactivate button's text and show the reasons panel.
140
+ _parent.find('.button-deactivate').addClass('allow-deactivate');
141
 
142
+ showPanel('reasons');
143
+ }
144
+ });
145
 
146
+ $modal.on('click', 'input[type="radio"]', function () {
147
+ var $selectedReasonOption = $(this);
148
 
149
+ // If the selection has not changed, do not proceed.
150
+ if (selectedReasonID === $selectedReasonOption.val())
151
+ return;
152
 
153
+ selectedReasonID = $selectedReasonOption.val();
 
154
 
155
+ var _parent = $(this).parents('li:first');
 
156
 
157
+ $modal.find('.reason-input').remove();
158
+ $modal.find('.button-deactivate').text('<?php printf( __fs( 'deactivation-modal-button-submit' , $slug ) ); ?>');
159
 
160
+ enableDeactivateButton();
 
161
 
162
+ if (_parent.hasClass('has-input')) {
163
+ var inputType = _parent.data('input-type'),
164
+ inputPlaceholder = _parent.data('input-placeholder'),
165
+ reasonInputHtml = '<div class="reason-input"><span class="message"></span>' + ( ( 'textfield' === inputType ) ? '<input type="text" />' : '<textarea rows="5"></textarea>' ) + '</div>';
166
 
167
+ _parent.append($(reasonInputHtml));
168
+ _parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus();
169
 
170
+ if (isOtherReasonSelected()) {
171
+ showMessage('<?php printf( __fs( 'ask-for-reason-message' , $slug ) ); ?>');
172
+ disableDeactivateButton();
173
+ }
174
+ }
175
+ });
176
 
177
+ // If the user has clicked outside the window, cancel it.
178
+ $modal.on('click', function (evt) {
179
+ var $target = $(evt.target);
180
 
181
+ // If the user has clicked anywhere in the modal dialog, just return.
182
+ if ($target.hasClass('fs-modal-body') || $target.hasClass('fs-modal-footer')) {
183
+ return;
184
  }
 
185
 
186
+ // If the user has not clicked the close button and the clicked element is inside the modal dialog, just return.
187
+ if (!$target.hasClass('button-close') && ( $target.parents('.fs-modal-body').length > 0 || $target.parents('.fs-modal-footer').length > 0 )) {
188
+ return;
189
+ }
190
 
191
+ closeModal();
192
+ });
193
+ }
194
 
195
+ function isOtherReasonSelected() {
196
+ // Get the selected radio input element.
197
+ var $selectedReasonOption = $modal.find('input[type="radio"]:checked'),
198
+ selectedReason = $selectedReasonOption.parent().next().text().trim();
199
 
200
+ return ( 'Other' === selectedReason );
201
+ }
202
+
203
+ function showModal() {
204
+ resetModal();
205
+
206
+ // Display the dialog box.
207
+ $modal.addClass('active');
208
+
209
+ $('body').addClass('has-fs-modal');
210
+ }
211
+
212
+ function closeModal() {
213
+ $modal.removeClass('active');
214
+
215
+ $('body').removeClass('has-fs-modal');
216
+ }
217
+
218
+ function resetModal() {
219
+ selectedReasonID = false;
220
+
221
+ enableDeactivateButton();
222
+
223
+ // Uncheck all radio buttons.
224
+ $modal.find('input[type="radio"]').prop('checked', false);
225
+
226
+ // Remove all input fields ( textfield, textarea ).
227
+ $modal.find('.reason-input').remove();
228
+
229
+ $modal.find('.message').hide();
230
+
231
+ var $deactivateButton = $modal.find('.button-deactivate');
232
+
233
+ /*
234
+ * If the modal dialog has no confirmation message, that is, it has only one panel, then ensure
235
+ * that clicking the deactivate button will actually deactivate the plugin.
236
+ */
237
+ if ($modal.hasClass('no-confirmation-message')) {
238
+ $deactivateButton.addClass('allow-deactivate');
239
+
240
+ showPanel('reasons');
241
+ } else {
242
+ $deactivateButton.removeClass('allow-deactivate');
243
+
244
+ showPanel('confirm');
245
  }
246
+ }
247
+
248
+ function showMessage(message) {
249
+ $modal.find('.message').text(message).show();
250
+ }
251
+
252
+ function enableDeactivateButton() {
253
+ $modal.find('.button-deactivate').removeClass('disabled');
254
+ }
255
+
256
+ function disableDeactivateButton() {
257
+ $modal.find('.button-deactivate').addClass('disabled');
258
+ }
259
 
260
+ function showPanel(panelType) {
261
+ $modal.find('.fs-modal-panel').removeClass('active ');
262
+ $modal.find('[data-panel-id="' + panelType + '"]').addClass('active');
263
+
264
+ updateButtonLabels();
265
+ }
266
+
267
+ function updateButtonLabels() {
268
+ var $deactivateButton = $modal.find('.button-deactivate');
269
+
270
+ // Reset the deactivate button's text.
271
+ if ('confirm' === getCurrentPanel()) {
272
+ $deactivateButton.text('<?php printf( __fs( 'deactivation-modal-button-confirm' , $slug ) ); ?>');
273
+ } else {
274
+ $deactivateButton.text('<?php printf( __fs( 'skip-deactivate' , $slug ) ); ?>');
275
  }
276
+ }
277
+
278
+ function getCurrentPanel() {
279
+ return $modal.find('.fs-modal-panel.active').attr('data-panel-id');
280
+ }
281
+ })(jQuery);
282
  </script>
freemius/templates/plugin-icon.php CHANGED
@@ -34,10 +34,10 @@
34
  }
35
  }
36
 
37
- $icons = glob( fs_normalize_path( $img_dir . '/icon.*' ) );
38
  if ( ! is_array( $icons ) || 0 === count( $icons ) ) {
39
  $icon_found = false;
40
- $local_path = fs_normalize_path( $img_dir . '/icon.png' );
41
  $have_write_permissions = is_writable( fs_normalize_path( $img_dir ) );
42
 
43
  if ( WP_FS__IS_LOCALHOST && $fs->is_org_repo_compliant() && $have_write_permissions ) {
@@ -62,7 +62,7 @@
62
  foreach ( $suffixes as $s ) {
63
  $headers = get_headers( $base_url . $s );
64
  if ( strpos( $headers[0], '200' ) ) {
65
- $local_path = fs_normalize_path( $img_dir . '/icon.' . substr( $s, strpos( $s, '.' ) + 1 ) );
66
  fs_download_image( $base_url . $s, $local_path );
67
  $icon_found = true;
68
  break;
@@ -89,5 +89,5 @@
89
  $relative_url = fs_img_url( substr( $icons[0], strlen( $icon_dir ) ), $icon_dir );
90
  ?>
91
  <div class="fs-plugin-icon">
92
- <img src="<?php echo $relative_url ?>"/>
93
  </div>
34
  }
35
  }
36
 
37
+ $icons = glob( fs_normalize_path( $img_dir . '/' . $slug . '.*' ) );
38
  if ( ! is_array( $icons ) || 0 === count( $icons ) ) {
39
  $icon_found = false;
40
+ $local_path = fs_normalize_path( $img_dir . '/' . $slug . '.png' );
41
  $have_write_permissions = is_writable( fs_normalize_path( $img_dir ) );
42
 
43
  if ( WP_FS__IS_LOCALHOST && $fs->is_org_repo_compliant() && $have_write_permissions ) {
62
  foreach ( $suffixes as $s ) {
63
  $headers = get_headers( $base_url . $s );
64
  if ( strpos( $headers[0], '200' ) ) {
65
+ $local_path = fs_normalize_path( $img_dir . '/' . $slug . '.' . substr( $s, strpos( $s, '.' ) + 1 ) );
66
  fs_download_image( $base_url . $s, $local_path );
67
  $icon_found = true;
68
  break;
89
  $relative_url = fs_img_url( substr( $icons[0], strlen( $icon_dir ) ), $icon_dir );
90
  ?>
91
  <div class="fs-plugin-icon">
92
+ <img src="<?php echo $relative_url ?>" width="80" height="80" />
93
  </div>
index.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Intergeo Maps - Google Maps Plugin
4
  Plugin URI: http://themeisle.com/plugins/intergeo-maps-lite/
5
  Description: A simple, easy and quite powerful Google Map tool to create, manage and embed custom Google Maps into your WordPress posts and pages. The plugin allows you to deeply customize look and feel of a map, add overlays like markers, rectangles, circles, polylines and polygons to your map. It could even be integraded with your Google Adsense account and show ad on your maps.
6
- Version: 1.0.5
7
  Author: Themeisle
8
  Author URI: http://themeisle.com
9
  License: GPL v2.0 or later
@@ -15,7 +15,7 @@ Domain Path: /languages
15
  // <editor-fold defaultstate="collapsed" desc="constants">
16
 
17
  define( 'INTERGEO_PLUGIN_NAME', 'intergeo' ); // don't change it whatever
18
- define( 'INTERGEO_VERSION', '1.0.5' );
19
  define( 'INTERGEO_ABSPATH', dirname( __FILE__ ) );
20
  define( 'INTERGEO_ABSURL', plugins_url( '/', __FILE__ ) );
21
  define( 'INTERGEO_PRO_URL', "http://themeisle.com/plugins/intergeo-maps-pro/" );
@@ -52,6 +52,7 @@ function im_fs() {
52
  'slug' => 'intergeo',
53
  'account' => false,
54
  'support' => false,
 
55
  'parent' => array(
56
  'slug' => 'upload.php',
57
  ),
@@ -251,9 +252,10 @@ function intergeo_map_popup_init() {
251
  }
252
  }
253
 
254
- intergeo_enqueue_google_maps_script( 'adsense,panoramio,weather,drawing' );
 
255
 
256
- wp_enqueue_script( 'intergeo-editor', INTERGEO_ABSURL . 'js/editor.js', array( 'wp-color-picker', 'google-maps-v3', 'jquery' ), INTERGEO_VERSION );
257
  wp_localize_script( 'intergeo-editor', 'intergeo_options', array(
258
  'send_to_editor' => $send_to_editor,
259
  'adsense' => array( 'publisher_id' => get_option( 'intergeo_adsense_publisher_id' ) ),
@@ -389,6 +391,7 @@ function intergeo_filter_overlays_marker( $marker ) {
389
  'icon' => isset( $marker['icon'] ) ? filter_var( $marker['icon'], FILTER_VALIDATE_URL ) : '',
390
  'info' => isset( $marker['info'] ) ? trim( preg_replace( '/\<\/?script.*?\>/is', '', $marker['info'] ) ) : '',
391
  'title' => isset( $marker['title'] ) ? strip_tags( trim( $marker['title'] ) ) : '',
 
392
  );
393
  }
394
 
3
  Plugin Name: Intergeo Maps - Google Maps Plugin
4
  Plugin URI: http://themeisle.com/plugins/intergeo-maps-lite/
5
  Description: A simple, easy and quite powerful Google Map tool to create, manage and embed custom Google Maps into your WordPress posts and pages. The plugin allows you to deeply customize look and feel of a map, add overlays like markers, rectangles, circles, polylines and polygons to your map. It could even be integraded with your Google Adsense account and show ad on your maps.
6
+ Version: 1.0.6
7
  Author: Themeisle
8
  Author URI: http://themeisle.com
9
  License: GPL v2.0 or later
15
  // <editor-fold defaultstate="collapsed" desc="constants">
16
 
17
  define( 'INTERGEO_PLUGIN_NAME', 'intergeo' ); // don't change it whatever
18
+ define( 'INTERGEO_VERSION', '1.0.6' );
19
  define( 'INTERGEO_ABSPATH', dirname( __FILE__ ) );
20
  define( 'INTERGEO_ABSURL', plugins_url( '/', __FILE__ ) );
21
  define( 'INTERGEO_PRO_URL', "http://themeisle.com/plugins/intergeo-maps-pro/" );
52
  'slug' => 'intergeo',
53
  'account' => false,
54
  'support' => false,
55
+ 'contact' => false,
56
  'parent' => array(
57
  'slug' => 'upload.php',
58
  ),
252
  }
253
  }
254
 
255
+ intergeo_enqueue_google_maps_script( 'adsense,panoramio,weather,drawing,places' );
256
+ wp_enqueue_script('jquery-ddslick', INTERGEO_ABSURL . 'js/jquery.ddslick.min.js', array('jquery'));
257
 
258
+ wp_enqueue_script( 'intergeo-editor', INTERGEO_ABSURL . 'js/editor.js', array( 'jquery-ddslick', 'wp-color-picker', 'google-maps-v3' ), INTERGEO_VERSION );
259
  wp_localize_script( 'intergeo-editor', 'intergeo_options', array(
260
  'send_to_editor' => $send_to_editor,
261
  'adsense' => array( 'publisher_id' => get_option( 'intergeo_adsense_publisher_id' ) ),
391
  'icon' => isset( $marker['icon'] ) ? filter_var( $marker['icon'], FILTER_VALIDATE_URL ) : '',
392
  'info' => isset( $marker['info'] ) ? trim( preg_replace( '/\<\/?script.*?\>/is', '', $marker['info'] ) ) : '',
393
  'title' => isset( $marker['title'] ) ? strip_tags( trim( $marker['title'] ) ) : '',
394
+ 'loc' => isset( $marker['loc'] ) ? strip_tags( trim( $marker['loc'] ) ) : '',
395
  );
396
  }
397
 
js/editor.js CHANGED
@@ -126,8 +126,16 @@ if (!window.intergeo.maps) {
126
  })
127
  }
128
  });
 
 
 
 
 
 
129
  a.Marker = a.Overlay.extend({
130
  initialize: function(i, f, g, d) {
 
 
131
  var e = this,
132
  h = new b.InfoWindow();
133
  e.supr(i, f, g, d, "markers");
@@ -141,12 +149,53 @@ if (!window.intergeo.maps) {
141
  }
142
  });
143
  e.html.find(".intergeo_tlbr_actn_edit").click(function() {
 
 
144
  var j = c("#intergeo_marker_ppp");
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  j.find(".intergeo_ppp_frm").attr("data-position", d);
146
  j.find(".intergeo_tlbr_marker_title").val(g.find(".intergeo_tlbr_marker_title").val());
147
- j.find(".intergeo_tlbr_marker_icon").val(g.find(".intergeo_tlbr_marker_icon").val());
148
- j.find(".intergeo_tlbr_marker_info").val(g.find(".intergeo_tlbr_marker_info").val());
149
- j.fadeIn(150)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  });
151
  b.event.addListener(f, "dragend", function(j) {
152
  g.find(".intergeo_tlbr_marker_location").val(j.latLng.toUrlValue())
@@ -168,8 +217,36 @@ if (!window.intergeo.maps) {
168
  e = {},
169
  i = c.trim(g.find(".intergeo_tlbr_marker_title").val()),
170
  f = c.trim(g.find(".intergeo_tlbr_marker_icon").val()),
171
- h = c.trim(g.find(".intergeo_tlbr_marker_info").val()),
172
- j = d.html.find(".intergeo_tlbr_marker_title_td");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  e.title = i;
174
  if (/^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(f)) {
175
  e.icon = f
@@ -179,6 +256,8 @@ if (!window.intergeo.maps) {
179
  d.html.find(".intergeo_tlbr_marker_title").val(i);
180
  d.html.find(".intergeo_tlbr_marker_icon").val(f);
181
  d.html.find(".intergeo_tlbr_marker_info").val(h);
 
 
182
  d.overlay.setOptions(e);
183
  if (i != "") {
184
  j.text(i)
@@ -390,7 +469,7 @@ if (!window.intergeo.maps) {
390
  var f = this;
391
  f.map = new c.Map(document.getElementById(e), g);
392
  f.drawing = new c.drawing.DrawingManager({
393
- drawingControl: false,
394
  map: f.map,
395
  circleOptions: {
396
  editable: true
@@ -1071,12 +1150,6 @@ if (!window.intergeo.maps) {
1071
  status: d(this).is(":checked") ? 1 : 0
1072
  })
1073
  });
1074
- d("#intergeo_tlbr_drawing_tools").change(function() {
1075
- f.drawing.setDrawingMode(null);
1076
- f.drawing.setOptions({
1077
- drawingControl: d(this).is(":checked")
1078
- })
1079
- });
1080
  d(".intergeo_ppp_cls").click(function() {
1081
  d(this).parents(".intergeo_ppp").fadeOut(150);
1082
  return false
@@ -1118,6 +1191,38 @@ if (!window.intergeo.maps) {
1118
  d("#intergeo_tlbr_new_drctn").click(function() {
1119
  f.createDirection();
1120
  return false
1121
- })
1122
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1123
  })(jQuery, google.maps, intergeo.maps);
126
  })
127
  }
128
  });
129
+
130
+ var ig_editMarker = null;
131
+ var ig_latlng = null;
132
+ var ig_mapInstance = null;
133
+ var ig_mapMarkers = [];
134
+
135
  a.Marker = a.Overlay.extend({
136
  initialize: function(i, f, g, d) {
137
+ ig_mapMarkers.push(f);
138
+ ig_mapInstance = i.map;
139
  var e = this,
140
  h = new b.InfoWindow();
141
  e.supr(i, f, g, d, "markers");
149
  }
150
  });
151
  e.html.find(".intergeo_tlbr_actn_edit").click(function() {
152
+ ig_editMarker = f;
153
+ ig_latlng = null;
154
  var j = c("#intergeo_marker_ppp");
155
+ j.find("input[name='intergeo_tlbr_marker_address_hidden']").val(g.find(".intergeo_tlbr_marker_location").val());
156
+
157
+ var autocomplete = new b.places.Autocomplete(j.find(".intergeo_tlbr_marker_address").get(0));
158
+ autocomplete.bindTo('bounds', i.map);
159
+
160
+ autocomplete.addListener('place_changed', function() {
161
+ var place = autocomplete.getPlace();
162
+ if (place.geometry) {
163
+ ig_latlng = place.geometry.location;
164
+ j.find("input[name='intergeo_tlbr_marker_address_hidden']").val(place.geometry.location.toUrlValue());
165
+ }
166
+ });
167
+
168
  j.find(".intergeo_ppp_frm").attr("data-position", d);
169
  j.find(".intergeo_tlbr_marker_title").val(g.find(".intergeo_tlbr_marker_title").val());
170
+
171
+ var igMarkerSet = false;
172
+ var igMarker = g.find(".intergeo_tlbr_marker_icon").val();
173
+ var indx = 0;
174
+ j.find('.intergeo_tlbr_marker_icon').val("");
175
+ j.find('ul.dd-options .dd-option-value').each(function(){
176
+ if(j.find(this).val() == igMarker){
177
+ j.find('#intergeo_tlbr_marker_icon_select').ddslick('select', { index: indx });
178
+ igMarkerSet = true;
179
+ return;
180
+ }
181
+ indx++;
182
+ });
183
+ if(!igMarkerSet && igMarker != ""){
184
+ indx = 0;
185
+ igMarker = "custom";
186
+ j.find('ul.dd-options .dd-option-value').each(function(){
187
+ if(j.find(this).val() == igMarker){
188
+ j.find('#intergeo_tlbr_marker_icon_select').ddslick('select', { index: indx });
189
+ j.find('.intergeo_tlbr_marker_icon').val(g.find(".intergeo_tlbr_marker_icon").val());
190
+ return;
191
+ }
192
+ indx++;
193
+ });
194
+ }
195
+
196
+ j.find(".intergeo_tlbr_marker_address").val(g.find(".intergeo_tlbr_marker_loc").val());
197
+ j.find("iframe").contents().find(".intergeo-marker-editor").html(g.find(".intergeo_tlbr_marker_info").val());
198
+ j.fadeIn(150);
199
  });
200
  b.event.addListener(f, "dragend", function(j) {
201
  g.find(".intergeo_tlbr_marker_location").val(j.latLng.toUrlValue())
217
  e = {},
218
  i = c.trim(g.find(".intergeo_tlbr_marker_title").val()),
219
  f = c.trim(g.find(".intergeo_tlbr_marker_icon").val()),
220
+ h = c.trim(g.find("iframe").contents().find(".intergeo-marker-editor").html()),
221
+ j = d.html.find(".intergeo_tlbr_marker_title_td"),
222
+ loc1 = c.trim(g.find(".intergeo_tlbr_marker_address").val()),
223
+ loc = c.trim(g.find("input[name='intergeo_tlbr_marker_address_hidden']").val());
224
+
225
+ var str = new RegExp("^[0-9\., \-]*$");
226
+ if(str.length > 0 && str.test(loc1)){
227
+ var pos = c.trim(g.find(".intergeo_tlbr_marker_address").val()).split(",");
228
+ ig_latlng = new b.LatLng(c.trim(pos[0]), c.trim(pos[1]));
229
+ loc = ig_latlng.toUrlValue();
230
+ }
231
+
232
+ if(ig_latlng != null) {
233
+ ig_editMarker.setPosition(ig_latlng);
234
+ var bounds = new b.LatLngBounds();
235
+ bounds.extend(ig_latlng);
236
+ for(var x = 0; x < ig_mapMarkers.length; x++) {
237
+ bounds.extend(ig_mapMarkers[x].getPosition());
238
+ }
239
+ ig_mapInstance.fitBounds(bounds);
240
+ if(ig_mapMarkers.length == 1){
241
+ ig_mapInstance.setZoom(ig_mapInstance.getZoom() - 8);
242
+ }
243
+ g.find("#intergeo_map_zoom").val(ig_mapInstance.getZoom())
244
+ }
245
+
246
+ if(f.length == 0){
247
+ f = g.find('#intergeo_tlbr_marker_icon_select').data("ddslick").selectedData.value;
248
+ }
249
+
250
  e.title = i;
251
  if (/^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(f)) {
252
  e.icon = f
256
  d.html.find(".intergeo_tlbr_marker_title").val(i);
257
  d.html.find(".intergeo_tlbr_marker_icon").val(f);
258
  d.html.find(".intergeo_tlbr_marker_info").val(h);
259
+ d.html.find(".intergeo_tlbr_marker_location").val(loc);
260
+ d.html.find(".intergeo_tlbr_marker_loc").val(c.trim(g.find(".intergeo_tlbr_marker_address").val()));
261
  d.overlay.setOptions(e);
262
  if (i != "") {
263
  j.text(i)
469
  var f = this;
470
  f.map = new c.Map(document.getElementById(e), g);
471
  f.drawing = new c.drawing.DrawingManager({
472
+ drawingControl: true,
473
  map: f.map,
474
  circleOptions: {
475
  editable: true
1150
  status: d(this).is(":checked") ? 1 : 0
1151
  })
1152
  });
 
 
 
 
 
 
1153
  d(".intergeo_ppp_cls").click(function() {
1154
  d(this).parents(".intergeo_ppp").fadeOut(150);
1155
  return false
1191
  d("#intergeo_tlbr_new_drctn").click(function() {
1192
  f.createDirection();
1193
  return false
1194
+ });
1195
+
1196
+ d("#intergeo_add_marker_bttn").on("click", function(ee){
1197
+ var marker = new c.Marker({
1198
+ position: f.map.getCenter(),
1199
+ map: f.map,
1200
+ draggable: true
1201
+ });
1202
+ marker.setAnimation(c.Animation.BOUNCE);
1203
+ var e = f.markers.length;
1204
+ var h = d(d("#intergeo_tlbr_marker_tmpl").html().replaceByHash({
1205
+ "%pos%": e,
1206
+ "%num%": e + 1
1207
+ }));
1208
+ var m = new intergeo.maps.Marker(f, marker, h, e);
1209
+ h.find(".intergeo_tlbr_marker_location").val(marker.getPosition().toUrlValue());
1210
+ d("#intergeo_tlbr_markers").append(h);
1211
+ f.markers.push(m);
1212
+ d("table.intergeo_tlbr_cntrl_tbl.intergeo_tlbr_overlay.intergeo_tlbr_marker[data-table-num=" + (e + 1) + "]").find(".intergeo_tlbr_actn_edit").trigger("click");
1213
+ });
1214
+
1215
+ d("#intergeo_tlbr_marker_icon_select").ddslick({
1216
+ width: "100%",
1217
+ background: "#ffffff",
1218
+ onSelected: function(data){
1219
+ if(data.selectedData.value == 'custom'){
1220
+ d('#intergeo_marker_ppp .intergeo_tlbr_marker_icon').val("").show();
1221
+ }else{
1222
+ d('#intergeo_marker_ppp .intergeo_tlbr_marker_icon').val(data.selectedData.value).hide();
1223
+ }
1224
+ }
1225
+ });
1226
+ });
1227
+
1228
  })(jQuery, google.maps, intergeo.maps);
js/jquery.ddslick.min.js ADDED
@@ -0,0 +1 @@
 
1
+ (function (a) { function g(a, b) { var c = a.data("ddslick"); var d = a.find(".dd-selected"), e = d.siblings(".dd-selected-value"), f = a.find(".dd-options"), g = d.siblings(".dd-pointer"), h = a.find(".dd-option").eq(b), k = h.closest("li"), l = c.settings, m = c.settings.data[b]; a.find(".dd-option").removeClass("dd-option-selected"); h.addClass("dd-option-selected"); c.selectedIndex = b; c.selectedItem = k; c.selectedData = m; if (l.showSelectedHTML) { d.html((m.imageSrc ? '<img class="dd-selected-image' + (l.imagePosition == "right" ? " dd-image-right" : "") + '" src="' + m.imageSrc + '" />' : "") + (m.text ? '<label class="dd-selected-text">' + m.text + "</label>" : "") + (m.description ? '<small class="dd-selected-description dd-desc' + (l.truncateDescription ? " dd-selected-description-truncated" : "") + '" >' + m.description + "</small>" : "")) } else d.html(m.text); e.val(m.value); c.original.val(m.value); a.data("ddslick", c); i(a); j(a); if (typeof l.onSelected == "function") { l.onSelected.call(this, c) } } function h(b) { var c = b.find(".dd-select"), d = c.siblings(".dd-options"), e = c.find(".dd-pointer"), f = d.is(":visible"); a(".dd-click-off-close").not(d).slideUp(50); a(".dd-pointer").removeClass("dd-pointer-up"); if (f) { d.slideUp("fast"); e.removeClass("dd-pointer-up") } else { d.slideDown("fast"); e.addClass("dd-pointer-up") } k(b) } function i(a) { a.find(".dd-options").slideUp(50); a.find(".dd-pointer").removeClass("dd-pointer-up").removeClass("dd-pointer-up") } function j(a) { var b = a.find(".dd-select").css("height"); var c = a.find(".dd-selected-description"); var d = a.find(".dd-selected-image"); if (c.length <= 0 && d.length > 0) { a.find(".dd-selected-text").css("lineHeight", b) } } function k(b) { b.find(".dd-option").each(function () { var c = a(this); var d = c.css("height"); var e = c.find(".dd-option-description"); var f = b.find(".dd-option-image"); if (e.length <= 0 && f.length > 0) { c.find(".dd-option-text").css("lineHeight", d) } }) } a.fn.ddslick = function (c) { if (b[c]) { return b[c].apply(this, Array.prototype.slice.call(arguments, 1)) } else if (typeof c === "object" || !c) { return b.init.apply(this, arguments) } else { a.error("Method " + c + " does not exists.") } }; var b = {}, c = { data: [], keepJSONItemsOnTop: false, width: 260, height: null, background: "#eee", selectText: "", defaultSelectedIndex: null, truncateDescription: true, imagePosition: "left", showSelectedHTML: true, clickOffToClose: true, onSelected: function () { } }, d = '<div class="dd-select"><input class="dd-selected-value" type="hidden" /><a class="dd-selected"></a><span class="dd-pointer dd-pointer-down"></span></div>', e = '<ul class="dd-options"></ul>', f = '<style id="css-ddslick" type="text/css">' + ".dd-select{ border-radius:2px; border:solid 1px #ccc; position:relative; cursor:pointer;}" + ".dd-desc { color:#aaa; display:block; overflow: hidden; font-weight:normal; line-height: 1.4em; }" + ".dd-selected{ overflow:hidden; display:block; padding:10px; font-weight:bold;}" + ".dd-pointer{ width:0; height:0; position:absolute; right:10px; top:50%; margin-top:-3px;}" + ".dd-pointer-down{ border:solid 5px transparent; border-top:solid 5px #000; }" + ".dd-pointer-up{border:solid 5px transparent !important; border-bottom:solid 5px #000 !important; margin-top:-8px;}" + ".dd-options{ border:solid 1px #ccc; border-top:none; list-style:none; box-shadow:0px 1px 5px #ddd; display:none; position:absolute; z-index:2000; margin:0; padding:0;background:#fff; overflow:auto;}" + ".dd-option{ padding:10px; display:block; border-bottom:solid 1px #ddd; overflow:hidden; text-decoration:none; color:#333; cursor:pointer;-webkit-transition: all 0.25s ease-in-out; -moz-transition: all 0.25s ease-in-out;-o-transition: all 0.25s ease-in-out;-ms-transition: all 0.25s ease-in-out; }" + ".dd-options > li:last-child > .dd-option{ border-bottom:none;}" + ".dd-option:hover{ background:#f3f3f3; color:#000;}" + ".dd-selected-description-truncated { text-overflow: ellipsis; white-space:nowrap; }" + ".dd-option-selected { background:#f6f6f6; }" + ".dd-option-image, .dd-selected-image { vertical-align:middle; float:left; margin-right:5px; max-width:64px;}" + ".dd-image-right { float:right; margin-right:15px; margin-left:5px;}" + ".dd-container{ position:relative;}? .dd-selected-text { font-weight:bold}?</style>"; if (a("#css-ddslick").length <= 0) { a(f).appendTo("head") } b.init = function (b) { var b = a.extend({}, c, b); return this.each(function () { var c = a(this), f = c.data("ddslick"); if (!f) { var i = [], j = b.data; c.find("option").each(function () { var b = a(this), c = b.data(); i.push({ text: a.trim(b.text()), value: b.val(), selected: b.is(":selected"), description: c.description, imageSrc: c.imagesrc }) }); if (b.keepJSONItemsOnTop) a.merge(b.data, i); else b.data = a.merge(i, b.data); var k = c, l = a('<div id="' + c.attr("id") + '"></div>'); c.replaceWith(l); c = l; c.addClass("dd-container").append(d).append(e); var i = c.find(".dd-select"), m = c.find(".dd-options"); m.css({ width: b.width }); i.css({ width: b.width, background: b.background }); c.css({ width: b.width }); if (b.height != null) m.css({ height: b.height, overflow: "auto" }); a.each(b.data, function (a, c) { if (c.selected) b.defaultSelectedIndex = a; m.append("<li>" + '<a class="dd-option">' + (c.value ? ' <input class="dd-option-value" type="hidden" value="' + c.value + '" />' : "") + (c.imageSrc ? ' <img class="dd-option-image' + (b.imagePosition == "right" ? " dd-image-right" : "") + '" src="' + c.imageSrc + '" />' : "") + (c.text ? ' <label class="dd-option-text">' + c.text + "</label>" : "") + (c.description ? ' <small class="dd-option-description dd-desc">' + c.description + "</small>" : "") + "</a>" + "</li>") }); var n = { settings: b, original: k, selectedIndex: -1, selectedItem: null, selectedData: null }; c.data("ddslick", n); if (b.selectText.length > 0 && b.defaultSelectedIndex == null) { c.find(".dd-selected").html(b.selectText) } else { var o = b.defaultSelectedIndex != null && b.defaultSelectedIndex >= 0 && b.defaultSelectedIndex < b.data.length ? b.defaultSelectedIndex : 0; g(c, o) } c.find(".dd-select").on("click.ddslick", function () { h(c) }); c.find(".dd-option").on("click.ddslick", function () { g(c, a(this).closest("li").index()) }); if (b.clickOffToClose) { m.addClass("dd-click-off-close"); c.on("click.ddslick", function (a) { a.stopPropagation() }); a("body").on("click", function () { a(".dd-click-off-close").slideUp(50).siblings(".dd-select").find(".dd-pointer").removeClass("dd-pointer-up") }) } } }) }; b.select = function (b) { return this.each(function () { if (b.index) g(a(this), b.index) }) }; b.open = function () { return this.each(function () { var b = a(this), c = b.data("ddslick"); if (c) h(b) }) }; b.close = function () { return this.each(function () { var b = a(this), c = b.data("ddslick"); if (c) i(b) }) }; b.destroy = function () { return this.each(function () { var b = a(this), c = b.data("ddslick"); if (c) { var d = c.original; b.removeData("ddslick").unbind(".ddslick").replaceWith(d) } }) } })(jQuery)
readme.txt CHANGED
@@ -140,6 +140,10 @@ function filter_intergeo_map_settings( $options ) {
140
  * Fix issue for non-admins in freemius
141
 
142
 
 
 
 
 
143
  = 1.0.4 =
144
 
145
  * Added uninstall feedback
140
  * Fix issue for non-admins in freemius
141
 
142
 
143
+ = 1.0.6 =
144
+
145
+ * improved the usability of the builder, markers are added now in a more intuitive way.
146
+
147
  = 1.0.4 =
148
 
149
  * Added uninstall feedback
templates/iframe/form.php CHANGED
@@ -6,6 +6,9 @@
6
  <div id="intergeo_tlbr">
7
  <div id="intergeo_tlbr_ttl">Inter<span style="color:#4067dc">g</span><span style="color:#e21b31">e</span><span style="color:#fcaa08">o</span> <?php esc_html_e( 'Maps', INTERGEO_PLUGIN_NAME ) ?></div>
8
  <ul id="intergeo_tlbr_ul">
 
 
 
9
  <li class="intergeo_tlbr_ul_li">
10
  <?php include INTERGEO_ABSPATH . '/templates/iframe/positioning.php' ?>
11
  </li>
@@ -15,9 +18,6 @@
15
  <li class="intergeo_tlbr_ul_li">
16
  <?php include INTERGEO_ABSPATH . '/templates/iframe/styles.php' ?>
17
  </li>
18
- <li class="intergeo_tlbr_ul_li">
19
- <?php include INTERGEO_ABSPATH . '/templates/iframe/overlays.php' ?>
20
- </li>
21
  <li class="intergeo_tlbr_ul_li">
22
  <?php include INTERGEO_ABSPATH . '/templates/iframe/directions.php' ?>
23
  </li>
6
  <div id="intergeo_tlbr">
7
  <div id="intergeo_tlbr_ttl">Inter<span style="color:#4067dc">g</span><span style="color:#e21b31">e</span><span style="color:#fcaa08">o</span> <?php esc_html_e( 'Maps', INTERGEO_PLUGIN_NAME ) ?></div>
8
  <ul id="intergeo_tlbr_ul">
9
+ <li class="intergeo_tlbr_ul_li open">
10
+ <?php include INTERGEO_ABSPATH . '/templates/iframe/overlays.php' ?>
11
+ </li>
12
  <li class="intergeo_tlbr_ul_li">
13
  <?php include INTERGEO_ABSPATH . '/templates/iframe/positioning.php' ?>
14
  </li>
18
  <li class="intergeo_tlbr_ul_li">
19
  <?php include INTERGEO_ABSPATH . '/templates/iframe/styles.php' ?>
20
  </li>
 
 
 
21
  <li class="intergeo_tlbr_ul_li">
22
  <?php include INTERGEO_ABSPATH . '/templates/iframe/directions.php' ?>
23
  </li>
templates/iframe/overlays.php CHANGED
@@ -1,26 +1,8 @@
1
  <h3 class="intergeo_tlbr_ul_li_h3"><?php esc_html_e( 'Overlays', INTERGEO_PLUGIN_NAME ) ?></h3>
2
  <ul class="intergeo_tlbr_ul_li_ul">
3
- <li class="intergeo_tlbr_li_ul_li">
4
- <p class="intergeo_tlbr_grp_dsc">
5
- <?php esc_html_e( 'Drawing tools allows you to add overlays over the map. You can add markers, polylines, polygons, circles and rectangles. To enable drawing tools just put a tick in the checkbox below.', INTERGEO_PLUGIN_NAME ) ?>
6
- </p>
7
- <p class="intergeo_tlbr_grp_dsc">
8
- <?php esc_html_e( 'To delete a marker, just double click on it and an item will be removed.', INTERGEO_PLUGIN_NAME ) ?>
9
- </p>
10
- </li>
11
- <li class="intergeo_tlbr_ul_li_ul_li">
12
- <div class="intergeo_tlbr_cntrl_items" style="display:block">
13
- <div class="intergeo_tlbr_cntrl_item">
14
- <label>
15
- <input type="checkbox" id="intergeo_tlbr_drawing_tools">
16
- <?php esc_html_e( 'Enable drawing tools', INTERGEO_PLUGIN_NAME ) ?>
17
- </label>
18
- </div>
19
- </div>
20
- </li>
21
  <li class="intergeo_tlbr_ul_li_ul_li">
22
  <script id="intergeo_tlbr_marker_tmpl" type="text/html">
23
- <table class="intergeo_tlbr_cntrl_tbl intergeo_tlbr_overlay intergeo_tlbr_marker" border="0" cellspacing="0" cellpadding="0">
24
  <tr>
25
  <td class="intergeo_tlbr_marker_title_td">
26
  #%num% <?php esc_html_e( 'marker', INTERGEO_PLUGIN_NAME ) ?>
@@ -30,6 +12,7 @@
30
  <input type="hidden" class="intergeo_tlbr_marker_title" name="overlays_marker[%pos%][title]">
31
  <input type="hidden" class="intergeo_tlbr_marker_icon" name="overlays_marker[%pos%][icon]">
32
  <input type="hidden" class="intergeo_tlbr_marker_info" name="overlays_marker[%pos%][info]">
 
33
 
34
  <a class="intergeo_tlbr_actn_delete intergeo_tlbr_actn" href="javascript:;" title="<?php esc_attr_e( 'Delete marker', INTERGEO_PLUGIN_NAME ) ?>"></a>
35
  <a class="intergeo_tlbr_actn_edit intergeo_tlbr_actn" href="javascript:;" title="<?php esc_attr_e( 'Edit marker', INTERGEO_PLUGIN_NAME ) ?>"></a>
@@ -39,10 +22,11 @@
39
  </script>
40
 
41
  <span class="intergeo_tlbr_cntrl_ttl"><?php esc_html_e( 'Markers', INTERGEO_PLUGIN_NAME ) ?></span>
42
- <div id="intergeo_tlbr_markers" class="intergeo_tlbr_cntrl_items">
 
43
  <?php if ( !empty( $json['overlays']['marker'] ) ) : ?>
44
  <?php foreach ( $json['overlays']['marker'] as $i => $overlay ) : ?>
45
- <table class="intergeo_tlbr_cntrl_tbl intergeo_tlbr_overlay intergeo_tlbr_marker" border="0" cellspacing="0" cellpadding="0">
46
  <tr>
47
  <td class="intergeo_tlbr_marker_title_td">
48
  <?php if ( empty( $overlay['title'] ) ) : ?>
@@ -56,6 +40,7 @@
56
  <input type="hidden" class="intergeo_tlbr_marker_title" name="overlays_marker[<?php echo $i ?>][title]" value="<?php echo esc_attr( $overlay['title'] ) ?>">
57
  <input type="hidden" class="intergeo_tlbr_marker_icon" name="overlays_marker[<?php echo $i ?>][icon]" value="<?php echo esc_attr( $overlay['icon'] ) ?>">
58
  <input type="hidden" class="intergeo_tlbr_marker_info" name="overlays_marker[<?php echo $i ?>][info]" value="<?php echo esc_attr( $overlay['info'] ) ?>">
 
59
 
60
  <a class="intergeo_tlbr_actn_delete intergeo_tlbr_actn" href="javascript:;" title="<?php esc_attr_e( 'Delete marker', INTERGEO_PLUGIN_NAME ) ?>"></a>
61
  <a class="intergeo_tlbr_actn_edit intergeo_tlbr_actn" href="javascript:;" title="<?php esc_attr_e( 'Edit marker', INTERGEO_PLUGIN_NAME ) ?>"></a>
@@ -65,6 +50,18 @@
65
  <?php endforeach; ?>
66
  <?php endif; ?>
67
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
68
  </li>
69
  <li class="intergeo_tlbr_ul_li_ul_li">
70
  <script id="intergeo_tlbr_polyline_tmpl" type="text/html">
1
  <h3 class="intergeo_tlbr_ul_li_h3"><?php esc_html_e( 'Overlays', INTERGEO_PLUGIN_NAME ) ?></h3>
2
  <ul class="intergeo_tlbr_ul_li_ul">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  <li class="intergeo_tlbr_ul_li_ul_li">
4
  <script id="intergeo_tlbr_marker_tmpl" type="text/html">
5
+ <table class="intergeo_tlbr_cntrl_tbl intergeo_tlbr_overlay intergeo_tlbr_marker" border="0" cellspacing="0" cellpadding="0" data-table-num="%num%">
6
  <tr>
7
  <td class="intergeo_tlbr_marker_title_td">
8
  #%num% <?php esc_html_e( 'marker', INTERGEO_PLUGIN_NAME ) ?>
12
  <input type="hidden" class="intergeo_tlbr_marker_title" name="overlays_marker[%pos%][title]">
13
  <input type="hidden" class="intergeo_tlbr_marker_icon" name="overlays_marker[%pos%][icon]">
14
  <input type="hidden" class="intergeo_tlbr_marker_info" name="overlays_marker[%pos%][info]">
15
+ <input type="hidden" class="intergeo_tlbr_marker_loc" name="overlays_marker[%pos%][loc]">
16
 
17
  <a class="intergeo_tlbr_actn_delete intergeo_tlbr_actn" href="javascript:;" title="<?php esc_attr_e( 'Delete marker', INTERGEO_PLUGIN_NAME ) ?>"></a>
18
  <a class="intergeo_tlbr_actn_edit intergeo_tlbr_actn" href="javascript:;" title="<?php esc_attr_e( 'Edit marker', INTERGEO_PLUGIN_NAME ) ?>"></a>
22
  </script>
23
 
24
  <span class="intergeo_tlbr_cntrl_ttl"><?php esc_html_e( 'Markers', INTERGEO_PLUGIN_NAME ) ?></span>
25
+ <div class="intergeo_tlbr_cntrl_items" style="display:block">
26
+ <div id="intergeo_tlbr_markers">
27
  <?php if ( !empty( $json['overlays']['marker'] ) ) : ?>
28
  <?php foreach ( $json['overlays']['marker'] as $i => $overlay ) : ?>
29
+ <table class="intergeo_tlbr_cntrl_tbl intergeo_tlbr_overlay intergeo_tlbr_marker" border="0" cellspacing="0" cellpadding="0" data-table-num="<?php echo $i + 1;?>">
30
  <tr>
31
  <td class="intergeo_tlbr_marker_title_td">
32
  <?php if ( empty( $overlay['title'] ) ) : ?>
40
  <input type="hidden" class="intergeo_tlbr_marker_title" name="overlays_marker[<?php echo $i ?>][title]" value="<?php echo esc_attr( $overlay['title'] ) ?>">
41
  <input type="hidden" class="intergeo_tlbr_marker_icon" name="overlays_marker[<?php echo $i ?>][icon]" value="<?php echo esc_attr( $overlay['icon'] ) ?>">
42
  <input type="hidden" class="intergeo_tlbr_marker_info" name="overlays_marker[<?php echo $i ?>][info]" value="<?php echo esc_attr( $overlay['info'] ) ?>">
43
+ <input type="hidden" class="intergeo_tlbr_marker_loc" name="overlays_marker[<?php echo $i ?>][loc]" value="<?php echo esc_attr( isset($overlay['loc']) ? $overlay['loc'] : '' ) ?>">
44
 
45
  <a class="intergeo_tlbr_actn_delete intergeo_tlbr_actn" href="javascript:;" title="<?php esc_attr_e( 'Delete marker', INTERGEO_PLUGIN_NAME ) ?>"></a>
46
  <a class="intergeo_tlbr_actn_edit intergeo_tlbr_actn" href="javascript:;" title="<?php esc_attr_e( 'Edit marker', INTERGEO_PLUGIN_NAME ) ?>"></a>
50
  <?php endforeach; ?>
51
  <?php endif; ?>
52
  </div>
53
+
54
+
55
+ <table class="intergeo_tlbr_cntrl_tbl intergeo_tlbr_marker_add" border="0" cellspacing="0" cellpadding="0">
56
+ <tr>
57
+ <td class="intergeo_tlbr_marker_title_td_add">
58
+ <input type="button" id="intergeo_add_marker_bttn" class="button button-secondary button-small" value="<?php esc_html_e('Add Marker', INTERGEO_PLUGIN_NAME);?>">
59
+ </td>
60
+ </tr>
61
+ </table>
62
+
63
+ </div>
64
+
65
  </li>
66
  <li class="intergeo_tlbr_ul_li_ul_li">
67
  <script id="intergeo_tlbr_polyline_tmpl" type="text/html">
templates/iframe/popups.php CHANGED
@@ -35,18 +35,30 @@
35
  <tr>
36
  <td>
37
  <input type="text"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  class="intergeo_tlbr_marker_icon intergeo_tlbr_cntrl_txt"
39
  placeholder="<?php esc_attr_e( 'Enter icon URL', INTERGEO_PLUGIN_NAME ) ?>"
40
- title="<?php esc_attr_e( 'Enter icon URL', INTERGEO_PLUGIN_NAME ) ?>">
 
 
41
  </td>
42
  </tr>
43
  <tr>
44
  <td>
45
- <textarea cols="20" rows="5"
46
- class="intergeo_tlbr_marker_info intergeo_tlbr_cntrl_txt"
47
- title="<?php esc_attr_e( 'Enter html for info window', INTERGEO_PLUGIN_NAME ) ?>"
48
- placeholder="<?php esc_attr_e( 'Enter html for info window', INTERGEO_PLUGIN_NAME ) ?>"
49
- ></textarea>
50
  </td>
51
  </tr>
52
  <tr>
35
  <tr>
36
  <td>
37
  <input type="text"
38
+ class="intergeo_tlbr_marker_address intergeo_tlbr_cntrl_txt"
39
+ placeholder="<?php esc_attr_e( 'Enter address or lat, long', INTERGEO_PLUGIN_NAME ) ?>"
40
+ title="<?php esc_attr_e( 'Enter address or lat, long', INTERGEO_PLUGIN_NAME ) ?>">
41
+ <input type="hidden" name="intergeo_tlbr_marker_address_hidden" value="">
42
+ </td>
43
+ </tr>
44
+ <tr>
45
+ <td>
46
+ <select name="intergeo_tlbr_marker_icon_select" id="intergeo_tlbr_marker_icon_select" class="intergeo_tlbr_marker_icon_select intergeo_tlbr_cntrl_txt">
47
+ <option value="http://maps.google.com/mapfiles/ms/icons/red-dot.png" data-imagesrc="http://maps.google.com/mapfiles/ms/icons/red-dot.png"><?php _e("Default", INTERGEO_PLUGIN_NAME);?></option>
48
+ <option value="http://maps.google.com/mapfiles/ms/icons/blue-dot.png" data-imagesrc="http://maps.google.com/mapfiles/ms/icons/blue-dot.png"><?php _e("Blue", INTERGEO_PLUGIN_NAME);?></option>
49
+ <option value="custom"><?php _e("Custom", INTERGEO_PLUGIN_NAME);?></option>
50
+ </select>
51
+ <input type="text" style="display: none"
52
  class="intergeo_tlbr_marker_icon intergeo_tlbr_cntrl_txt"
53
  placeholder="<?php esc_attr_e( 'Enter icon URL', INTERGEO_PLUGIN_NAME ) ?>"
54
+ title="<?php esc_attr_e( 'Enter icon URL', INTERGEO_PLUGIN_NAME ) ?>"
55
+ value="http://maps.google.com/mapfiles/ms/icons/red-dot.png"
56
+ >
57
  </td>
58
  </tr>
59
  <tr>
60
  <td>
61
+ <?php wp_editor("", "intergeo-marker-editor", array("media_buttons" => false, "textarea_rows" => 5, "teeny"=> true, "editor_class" => "intergeo_tlbr_marker_info intergeo_tlbr_cntrl_txt"));?>
 
 
 
 
62
  </td>
63
  </tr>
64
  <tr>