Version Description
- Fix : Album 404 issues when used on homepage
- Fix : Dimension attributes missing for upscaling small images
- Fix : Issue when galleries cannot be added to an album
- Fix : Lightbox caption mismatch
- New : Setting for legacy thumb cropping in Simple Portfolio gallery
- Update : FooGallery client side 1.0.26
Download this release
Release Info
Developer | bradvin |
Plugin | FooGallery – Image Gallery WordPress Plugin |
Version | 1.4.30 |
Comparing to | |
See all releases |
Code changes from version 1.4.29 to 1.4.30
- README.txt +9 -0
- extensions/albums/js/admin-foogallery-album.js +1 -0
- extensions/albums/public/class-rewrite-rules.php +31 -1
- extensions/default-templates/justified/class-justified-gallery-template.php +2 -1
- extensions/default-templates/shared/css/foogallery.css +2 -0
- extensions/default-templates/shared/css/foogallery.min.css +1 -1
- extensions/default-templates/shared/js/foogallery.js +169 -118
- extensions/default-templates/shared/js/foogallery.min.js +3 -2
- extensions/default-templates/simple-portfolio/class-simple-portfolio-gallery-template.php +18 -3
- foogallery.php +2 -2
- freemius/.codeclimate.yml +19 -19
- freemius/.github/ISSUE_TEMPLATE.md +29 -29
- freemius/.travis.yml +11 -11
- freemius/assets/css/admin/account.css +1 -1
- freemius/assets/css/admin/affiliation.css +1 -1
- freemius/assets/css/admin/connect.css +1 -1
- freemius/assets/css/admin/dialog-boxes.css +2 -2
- freemius/assets/css/admin/index.php +2 -2
- freemius/assets/css/index.php +2 -2
- freemius/assets/img/index.php +2 -2
- freemius/assets/js/index.php +2 -2
- freemius/assets/scss/_colors.scss +65 -65
- freemius/assets/scss/admin/_license-activation.scss +6 -6
- freemius/assets/scss/admin/_modal-common.scss +185 -185
- freemius/assets/scss/admin/account.scss +255 -255
- freemius/assets/scss/admin/dialog-boxes.scss +6 -6
- freemius/assets/scss/admin/index.php +2 -2
- freemius/assets/scss/index.php +2 -2
- freemius/gulpfile.js +166 -166
- freemius/includes/class-fs-logger.php +687 -687
- freemius/includes/customizer/class-fs-customizer-support-section.php +101 -101
- freemius/includes/customizer/class-fs-customizer-upsell-control.php +156 -156
- freemius/includes/customizer/index.php +2 -2
- freemius/includes/debug/class-fs-debug-bar-panel.php +64 -64
- freemius/includes/debug/debug-bar-start.php +51 -51
- freemius/includes/entities/class-fs-plugin-license.php +224 -224
- freemius/includes/entities/class-fs-plugin-tag.php +23 -23
- freemius/includes/entities/class-fs-plugin.php +116 -116
- freemius/includes/entities/class-fs-site.php +147 -147
- freemius/includes/l10n.php +48 -48
- freemius/includes/managers/class-fs-admin-menu-manager.php +849 -849
- freemius/includes/managers/class-fs-cache-manager.php +280 -280
- freemius/includes/managers/class-fs-key-value-storage.php +327 -327
- freemius/includes/managers/class-fs-option-manager.php +352 -352
- freemius/includes/managers/class-fs-plugin-manager.php +219 -219
- freemius/includes/supplements/fs-essential-functions-1.1.7.1.php +47 -47
- freemius/package.json +27 -27
- freemius/require.php +44 -44
- freemius/templates/account/billing.php +430 -430
- freemius/templates/account/payments.php +58 -58
- freemius/templates/add-ons.php +192 -192
- freemius/templates/admin-notice.php +48 -48
- freemius/templates/all-admin-notice.php +38 -38
- freemius/templates/checkout-legacy.php +242 -242
- freemius/templates/debug/api-calls.php +154 -154
- freemius/templates/debug/logger.php +65 -65
- freemius/templates/forms/deactivation/contact.php +23 -23
- freemius/templates/forms/deactivation/form.php +409 -409
- freemius/templates/forms/deactivation/retry-skip.php +23 -23
- freemius/templates/forms/optout.php +267 -267
- freemius/templates/forms/resend-key.php +247 -247
- freemius/templates/forms/trial-start.php +181 -181
- freemius/templates/js/style-premium-theme.php +44 -44
- freemius/templates/plugin-icon.php +129 -129
- freemius/templates/plugin-info/description.php +77 -77
- freemius/templates/plugin-info/features.php +113 -113
- freemius/templates/plugin-info/screenshots.php +34 -34
- freemius/templates/secure-https-header.php +38 -38
- includes/admin/class-settings.php +8 -0
- includes/class-thumbnail-dimensions.php +54 -3
- includes/class-thumbnails.php +21 -4
- includes/functions.php +8 -2
- js/foogallery.admin.min.js +1 -1
README.txt
CHANGED
@@ -150,6 +150,15 @@ Update now to get all the latest features, bug fixes and improvements!
|
|
150 |
|
151 |
== Changelog ==
|
152 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
= 1.4.29 =
|
154 |
|
155 |
* New : Added an album setting to set the gallery title size (h2,h3,h4,h5,h6)
|
150 |
|
151 |
== Changelog ==
|
152 |
|
153 |
+
= 1.4.30 =
|
154 |
+
|
155 |
+
* Fix : Album 404 issues when used on homepage
|
156 |
+
* Fix : Dimension attributes missing for upscaling small images
|
157 |
+
* Fix : Issue when galleries cannot be added to an album
|
158 |
+
* Fix : Lightbox caption mismatch
|
159 |
+
* New : Setting for legacy thumb cropping in Simple Portfolio gallery
|
160 |
+
* Update : FooGallery client side 1.0.26
|
161 |
+
|
162 |
= 1.4.29 =
|
163 |
|
164 |
* New : Added an album setting to set the gallery title size (h2,h3,h4,h5,h6)
|
extensions/albums/js/admin-foogallery-album.js
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
FOOGALLERYALBUM.bindElements = function() {
|
4 |
$('.foogallery-album-gallery-list')
|
5 |
.on('click', '.foogallery-gallery-select', function(e) {
|
|
|
6 |
$(this).toggleClass('selected');
|
7 |
FOOGALLERYALBUM.changeSelection();
|
8 |
})
|
3 |
FOOGALLERYALBUM.bindElements = function() {
|
4 |
$('.foogallery-album-gallery-list')
|
5 |
.on('click', '.foogallery-gallery-select', function(e) {
|
6 |
+
e.stopPropagation();
|
7 |
$(this).toggleClass('selected');
|
8 |
FOOGALLERYALBUM.changeSelection();
|
9 |
})
|
extensions/albums/public/class-rewrite-rules.php
CHANGED
@@ -8,10 +8,40 @@ if (!class_exists('FooGallery_Album_Rewrite_Rules')) {
|
|
8 |
|
9 |
function __construct() {
|
10 |
add_action( 'init', array( $this, 'add_gallery_endpoint' ) );
|
|
|
|
|
11 |
}
|
12 |
|
13 |
function add_gallery_endpoint() {
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
}
|
17 |
}
|
8 |
|
9 |
function __construct() {
|
10 |
add_action( 'init', array( $this, 'add_gallery_endpoint' ) );
|
11 |
+
add_filter( 'redirect_canonical', array( $this, 'disable_canonical_redirect_for_front_page' ), 10, 2 );
|
12 |
+
add_action( 'update_option_page_on_front', array( $this, 'flush_rules' ) );
|
13 |
}
|
14 |
|
15 |
function add_gallery_endpoint() {
|
16 |
+
$gallery_slug = foogallery_album_gallery_url_slug();
|
17 |
+
|
18 |
+
// Ensures the $query_vars['item'] is available
|
19 |
+
add_rewrite_tag( "%{$gallery_slug}%", '([^&]+)' );
|
20 |
+
|
21 |
+
// Requires flushing endpoints whenever the front page is switched to a different page
|
22 |
+
$page_on_front = get_option( 'page_on_front' );
|
23 |
+
|
24 |
+
// Match the front page and pass item value as a query var.
|
25 |
+
add_rewrite_rule( "^{$gallery_slug}/([^/]*)/?", 'index.php?page_id='.$page_on_front.'&'.$gallery_slug.'=$matches[1]', 'top' );
|
26 |
+
// Match non-front page pages.
|
27 |
+
add_rewrite_rule( "^(.*)/{$gallery_slug}/([^/]*)/?", 'index.php?pagename=$matches[1]&static=true&'.$gallery_slug.'=$matches[2]', 'top' );
|
28 |
}
|
29 |
+
|
30 |
+
// http://wordpress.stackexchange.com/a/220484/52463
|
31 |
+
// In order to keep WordPress from forcing a redirect to the canonical
|
32 |
+
// home page, the redirect needs to be disabled.
|
33 |
+
function disable_canonical_redirect_for_front_page( $redirect_url, $requested_url ) {
|
34 |
+
if ( is_page() && $front_page = get_option( 'page_on_front' ) ) {
|
35 |
+
if ( is_page( $front_page ) ) {
|
36 |
+
$redirect_url = false;
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
return $redirect_url;
|
41 |
+
}
|
42 |
+
|
43 |
+
function flush_rules() {
|
44 |
+
flush_rewrite_rules();
|
45 |
+
}
|
46 |
}
|
47 |
}
|
extensions/default-templates/justified/class-justified-gallery-template.php
CHANGED
@@ -262,7 +262,8 @@ if ( !class_exists( 'FooGallery_Justified_Gallery_Template' ) ) {
|
|
262 |
$height = foogallery_gallery_template_setting( 'thumb_height', '250' );
|
263 |
$args = array(
|
264 |
'height' => $height,
|
265 |
-
'link' => foogallery_gallery_template_setting( 'thumbnail_link', 'image' )
|
|
|
266 |
);
|
267 |
|
268 |
return $args;
|
262 |
$height = foogallery_gallery_template_setting( 'thumb_height', '250' );
|
263 |
$args = array(
|
264 |
'height' => $height,
|
265 |
+
'link' => foogallery_gallery_template_setting( 'thumbnail_link', 'image' ),
|
266 |
+
'crop' => false
|
267 |
);
|
268 |
|
269 |
return $args;
|
extensions/default-templates/shared/css/foogallery.css
CHANGED
@@ -1748,6 +1748,8 @@ only screen and (min-resolution: 2.25dppx) {
|
|
1748 |
width: 100%;
|
1749 |
height: auto;
|
1750 |
min-height: 100%;
|
|
|
|
|
1751 |
}
|
1752 |
/* Base Styles */
|
1753 |
.fg-simple_portfolio {
|
1748 |
width: 100%;
|
1749 |
height: auto;
|
1750 |
min-height: 100%;
|
1751 |
+
top: 50%;
|
1752 |
+
transform: translateY(-50%);
|
1753 |
}
|
1754 |
/* Base Styles */
|
1755 |
.fg-simple_portfolio {
|
extensions/default-templates/shared/css/foogallery.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.foogallery,.foogallery *{box-sizing:border-box}.foogallery{display:block;z-index:1;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;position:relative;line-height:0;font-size:0;width:100%;max-width:100%}.foogallery .fg-item{display:inline-block;position:relative;background-color:transparent;z-index:2;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.foogallery .fg-item-inner{display:block;position:relative;visibility:hidden;overflow:hidden;opacity:0;z-index:3;margin:0;border:solid 0 transparent}.foogallery .fg-item.fg-error,.foogallery .fg-item.fg-loading{background:no-repeat center}.foogallery .fg-item.fg-error{background-image:url(../img/image.png)}@media only screen and (-o-min-device-pixel-ratio:5/4),only screen and (-webkit-min-device-pixel-ratio:1.25),only screen and (min-device-pixel-ratio:1.25),only screen and (min-resolution:1.25dppx){.foogallery .fg-item.fg-error{background-image:url(../img/image@2x.png)}}@media only screen and (-o-min-device-pixel-ratio:9/4),only screen and (-webkit-min-device-pixel-ratio:2.25),only screen and (min-device-pixel-ratio:2.25),only screen and (min-resolution:2.25dppx){.foogallery .fg-item.fg-error{background-image:url(../img/image@3x.png)}}.foogallery .fg-item.fg-loaded{z-index:4}.foogallery .fg-loaded .fg-item-inner{visibility:visible;opacity:1;z-index:5}.foogallery .fg-error .fg-item-inner{pointer-events:none;cursor:default}.foogallery .fg-thumb{display:block;position:relative;border:none;outline:0;text-decoration:none;z-index:4}.foogallery .fg-image{display:block;position:relative;border:none;outline:0;text-decoration:none;z-index:5;max-width:none;height:auto;margin:0}.foogallery .fg-loaded .fg-thumb{z-index:6}.foogallery .fg-loaded .fg-image{z-index:7}.foogallery.fg-light .fg-item-inner{background-color:#fff;color:#333;border-color:#fff}.foogallery.fg-dark .fg-item-inner{background-color:#333;color:#fff;border-color:#333}.foogallery.fg-light .fg-item.fg-error,.foogallery.fg-light .fg-item.fg-idle,.foogallery.fg-light .fg-item.fg-loading{background-color:#eee;box-shadow:inset 0 0 0 1px #ddd}.foogallery.fg-dark .fg-item.fg-error,.foogallery.fg-dark .fg-item.fg-idle,.foogallery.fg-dark .fg-item.fg-loading{background-color:#444;box-shadow:inset 0 0 0 1px #333}.foogallery.fg-border-thin .fg-item-inner{border-width:4px}.foogallery.fg-border-medium .fg-item-inner{border-width:10px}.foogallery.fg-border-thick .fg-item-inner{border-width:16px}.foogallery.fg-light.fg-shadow-outline .fg-item-inner{box-shadow:0 0 0 1px #ddd}.foogallery.fg-dark.fg-shadow-outline .fg-item-inner{box-shadow:0 0 0 1px #222}.foogallery.fg-dark.fg-shadow-small .fg-item-inner,.foogallery.fg-light.fg-shadow-small .fg-item-inner{box-shadow:0 1px 4px 0 rgba(0,0,0,.5)}.foogallery.fg-dark.fg-shadow-medium .fg-item-inner,.foogallery.fg-light.fg-shadow-medium .fg-item-inner{box-shadow:0 1px 10px 0 rgba(0,0,0,.5)}.foogallery.fg-dark.fg-shadow-large .fg-item-inner,.foogallery.fg-light.fg-shadow-large .fg-item-inner{box-shadow:0 1px 16px 0 rgba(0,0,0,.5)}.foogallery.fg-shadow-inset-large .fg-thumb:after,.foogallery.fg-shadow-inset-medium .fg-thumb:after,.foogallery.fg-shadow-inset-small .fg-thumb:after{display:block;content:"";position:absolute;top:0;left:0;right:0;bottom:0;z-index:7}.foogallery.fg-dark.fg-shadow-inset-small .fg-thumb:after,.foogallery.fg-light.fg-shadow-inset-small .fg-thumb:after{box-shadow:inset 0 1px 4px 0 rgba(0,0,0,.3)}.foogallery.fg-dark.fg-shadow-inset-medium .fg-thumb:after,.foogallery.fg-light.fg-shadow-inset-medium .fg-thumb:after{box-shadow:inset 0 1px 10px 0 rgba(0,0,0,.3)}.foogallery.fg-dark.fg-shadow-inset-large .fg-thumb:after,.foogallery.fg-light.fg-shadow-inset-large .fg-thumb:after{box-shadow:inset 0 1px 16px 0 rgba(0,0,0,.3)}.foogallery.fg-round-full.fg-shadow-inset-large .fg-thumb:after,.foogallery.fg-round-full.fg-shadow-inset-medium .fg-thumb:after,.foogallery.fg-round-full.fg-shadow-inset-small .fg-thumb:after{border-radius:50%}.foogallery.fg-round-small .fg-item,.foogallery.fg-round-small .fg-item-inner{border-radius:5px}.foogallery.fg-round-medium .fg-item,.foogallery.fg-round-medium .fg-item-inner{border-radius:10px}.foogallery.fg-round-large .fg-item,.foogallery.fg-round-large .fg-item-inner{border-radius:15px}.foogallery.fg-round-full .fg-item,.foogallery.fg-round-full .fg-item-inner{border-radius:50%}.foogallery .fg-loader{position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);width:1em;height:1em;font-size:5px;visibility:hidden;opacity:0}.foogallery .fg-loading .fg-loader{visibility:visible;opacity:1}.fg-loading-default .fg-loader{border-radius:50%;text-indent:-9999em;-webkit-animation:loading-default 1.1s infinite ease;animation:loading-default 1.1s infinite ease}@-webkit-keyframes loading-default{0%,100%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,1),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.5),-1.8em -1.8em 0 0 rgba(130,130,130,.7)}12.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.7),1.8em -1.8em 0 0 rgba(130,130,130,1),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.5)}25%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.5),1.8em -1.8em 0 0 rgba(130,130,130,.7),2.5em 0 0 0 rgba(130,130,130,1),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}37.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.5),2.5em 0 0 0 rgba(130,130,130,.7),1.75em 1.75em 0 0 rgba(130,130,130,1),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}50%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.5),1.75em 1.75em 0 0 rgba(130,130,130,.7),0 2.5em 0 0 rgba(130,130,130,1),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}62.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.5),0 2.5em 0 0 rgba(130,130,130,.7),-1.8em 1.8em 0 0 rgba(130,130,130,1),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}75%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.5),-1.8em 1.8em 0 0 rgba(130,130,130,.7),-2.6em 0 0 0 rgba(130,130,130,1),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}87.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.5),-2.6em 0 0 0 rgba(130,130,130,.7),-1.8em -1.8em 0 0 rgba(130,130,130,1)}}@keyframes loading-default{0%,100%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,1),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.5),-1.8em -1.8em 0 0 rgba(130,130,130,.7)}12.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.7),1.8em -1.8em 0 0 rgba(130,130,130,1),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.5)}25%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.5),1.8em -1.8em 0 0 rgba(130,130,130,.7),2.5em 0 0 0 rgba(130,130,130,1),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}37.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.5),2.5em 0 0 0 rgba(130,130,130,.7),1.75em 1.75em 0 0 rgba(130,130,130,1),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}50%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.5),1.75em 1.75em 0 0 rgba(130,130,130,.7),0 2.5em 0 0 rgba(130,130,130,1),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}62.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.5),0 2.5em 0 0 rgba(130,130,130,.7),-1.8em 1.8em 0 0 rgba(130,130,130,1),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}75%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.5),-1.8em 1.8em 0 0 rgba(130,130,130,.7),-2.6em 0 0 0 rgba(130,130,130,1),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}87.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.5),-2.6em 0 0 0 rgba(130,130,130,.7),-1.8em -1.8em 0 0 rgba(130,130,130,1)}}.fg-loading-bars .fg-loader,.fg-loading-bars .fg-loader:after,.fg-loading-bars .fg-loader:before{background:rgba(130,130,130,1);-webkit-animation:loading-bars 1s infinite ease-in-out;animation:loading-bars 1s infinite ease-in-out;width:1em;height:4em}.fg-loading-bars .fg-loader{color:rgba(130,130,130,1);text-indent:-9999em;font-size:4px;-webkit-animation-delay:-.16s;animation-delay:-.16s}.fg-loading-bars .fg-loader:after,.fg-loading-bars .fg-loader:before{position:absolute;top:0;content:''}.fg-loading-bars .fg-loader:before{left:-1.5em;-webkit-animation-delay:-.32s;animation-delay:-.32s}.fg-loading-bars .fg-loader:after{left:1.5em}@-webkit-keyframes loading-bars{0%,100%,80%{box-shadow:0 0;height:4em}40%{box-shadow:0 -2em;height:5em}}@keyframes loading-bars{0%,100%,80%{box-shadow:0 0;height:4em}40%{box-shadow:0 -2em;height:5em}}.fg-loading-trail .fg-loader{color:#828282;font-size:20px;text-indent:-9999em;overflow:hidden;border-radius:50%;-webkit-animation:loading-trail-1 1.7s infinite ease,loading-trail-2 1.7s infinite ease;animation:loading-trail-1 1.7s infinite ease,loading-trail-2 1.7s infinite ease}@-webkit-keyframes loading-trail-1{0%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}5%,95%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}10%,59%{box-shadow:0 -.83em 0 -.4em,-.087em -.825em 0 -.42em,-.173em -.812em 0 -.44em,-.256em -.789em 0 -.46em,-.297em -.775em 0 -.477em}20%{box-shadow:0 -.83em 0 -.4em,-.338em -.758em 0 -.42em,-.555em -.617em 0 -.44em,-.671em -.488em 0 -.46em,-.749em -.34em 0 -.477em}38%{box-shadow:0 -.83em 0 -.4em,-.377em -.74em 0 -.42em,-.645em -.522em 0 -.44em,-.775em -.297em 0 -.46em,-.82em -.09em 0 -.477em}100%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}}@keyframes loading-trail-1{0%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}5%,95%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}10%,59%{box-shadow:0 -.83em 0 -.4em,-.087em -.825em 0 -.42em,-.173em -.812em 0 -.44em,-.256em -.789em 0 -.46em,-.297em -.775em 0 -.477em}20%{box-shadow:0 -.83em 0 -.4em,-.338em -.758em 0 -.42em,-.555em -.617em 0 -.44em,-.671em -.488em 0 -.46em,-.749em -.34em 0 -.477em}38%{box-shadow:0 -.83em 0 -.4em,-.377em -.74em 0 -.42em,-.645em -.522em 0 -.44em,-.775em -.297em 0 -.46em,-.82em -.09em 0 -.477em}100%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}}@-webkit-keyframes loading-trail-2{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}@keyframes loading-trail-2{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}.fg-loading-pulse .fg-loader,.fg-loading-pulse .fg-loader:after,.fg-loading-pulse .fg-loader:before{border-radius:50%;width:2.5em;height:2.5em;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation:loading-pulse 1.8s infinite ease-in-out;animation:loading-pulse 1.8s infinite ease-in-out}.fg-loading-pulse .fg-loader{color:#828282;font-size:4px;text-indent:-9999em;transform:translateX(-50%) translateY(-150%);-webkit-animation-delay:-.16s;animation-delay:-.16s}.fg-loading-pulse .fg-loader:after,.fg-loading-pulse .fg-loader:before{content:'';position:absolute;top:0}.fg-loading-pulse .fg-loader:before{left:-3.5em;-webkit-animation-delay:-.32s;animation-delay:-.32s}.fg-loading-pulse .fg-loader:after{left:3.5em}@-webkit-keyframes loading-pulse{0%,100%,80%{box-shadow:0 2.5em 0 -1.3em}40%{box-shadow:0 2.5em 0 0}}@keyframes loading-pulse{0%,100%,80%{box-shadow:0 2.5em 0 -1.3em}40%{box-shadow:0 2.5em 0 0}}.fg-loading-dots .fg-loader{color:#828282;font-size:5px;border-radius:50%;text-indent:-9999em;-webkit-animation:loading-dots 1.3s infinite linear;animation:loading-dots 1.3s infinite linear}@-webkit-keyframes loading-dots{0%,100%{box-shadow:0 -3em 0 .2em,2em -2em 0 0,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 0}12.5%{box-shadow:0 -3em 0 0,2em -2em 0 .2em,3em 0 0 0,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}25%{box-shadow:0 -3em 0 -.5em,2em -2em 0 0,3em 0 0 .2em,2em 2em 0 0,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}37.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 0,2em 2em 0 .2em,0 3em 0 0,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}50%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 0,0 3em 0 .2em,-2em 2em 0 0,-3em 0 0 -1em,-2em -2em 0 -1em}62.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 0,-2em 2em 0 .2em,-3em 0 0 0,-2em -2em 0 -1em}75%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 .2em,-2em -2em 0 0}87.5%{box-shadow:0 -3em 0 0,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 0,-2em -2em 0 .2em}}@keyframes loading-dots{0%,100%{box-shadow:0 -3em 0 .2em,2em -2em 0 0,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 0}12.5%{box-shadow:0 -3em 0 0,2em -2em 0 .2em,3em 0 0 0,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}25%{box-shadow:0 -3em 0 -.5em,2em -2em 0 0,3em 0 0 .2em,2em 2em 0 0,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}37.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 0,2em 2em 0 .2em,0 3em 0 0,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}50%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 0,0 3em 0 .2em,-2em 2em 0 0,-3em 0 0 -1em,-2em -2em 0 -1em}62.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 0,-2em 2em 0 .2em,-3em 0 0 0,-2em -2em 0 -1em}75%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 .2em,-2em -2em 0 0}87.5%{box-shadow:0 -3em 0 0,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 0,-2em -2em 0 .2em}}.fg-loading-partial .fg-loader,.fg-loading-partial .fg-loader:after{border-radius:50%;width:10em;height:10em}.fg-loading-partial .fg-loader{font-size:4px;text-indent:-9999em;border-top:1.1em solid rgba(130,130,130,.2);border-right:1.1em solid rgba(130,130,130,.2);border-bottom:1.1em solid rgba(130,130,130,.2);border-left:1.1em solid #828282;-webkit-animation:loading-partial 1.1s infinite linear;animation:loading-partial 1.1s infinite linear}@-webkit-keyframes loading-partial{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}@keyframes loading-partial{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}.foogallery.fg-loaded-drop .fg-item,.foogallery.fg-loaded-fade-in .fg-item,.foogallery.fg-loaded-flip .fg-item,.foogallery.fg-loaded-fly .fg-item,.foogallery.fg-loaded-scale-up .fg-item,.foogallery.fg-loaded-slide-down .fg-item,.foogallery.fg-loaded-slide-left .fg-item,.foogallery.fg-loaded-slide-right .fg-item,.foogallery.fg-loaded-slide-up .fg-item,.foogallery.fg-loaded-swing-down .fg-item{transition-timing-function:ease;transition-duration:650ms;transition-property:background-color,transform}.foogallery.fg-loaded-drop .fg-item-inner,.foogallery.fg-loaded-fade-in .fg-item-inner,.foogallery.fg-loaded-flip .fg-item-inner,.foogallery.fg-loaded-fly .fg-item-inner,.foogallery.fg-loaded-scale-up .fg-item-inner,.foogallery.fg-loaded-slide-down .fg-item-inner,.foogallery.fg-loaded-slide-left .fg-item-inner,.foogallery.fg-loaded-slide-right .fg-item-inner,.foogallery.fg-loaded-slide-up .fg-item-inner,.foogallery.fg-loaded-swing-down .fg-item-inner{transition-timing-function:ease;transition-duration:650ms}.foogallery.fg-loaded-drop .fg-item.fg-loaded,.foogallery.fg-loaded-flip .fg-item.fg-loaded,.foogallery.fg-loaded-fly .fg-item.fg-loaded,.foogallery.fg-loaded-swing-down .fg-item.fg-loaded{perspective:1300px}.foogallery.fg-loaded-fade-in .fg-item-inner{transition-property:visibility,opacity}.foogallery .fg-caption{visibility:hidden;opacity:0;background-color:rgba(0,0,0,.6);color:#fff;position:absolute;z-index:8;width:100%;max-height:100%;overflow:hidden;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:13px;font-weight:400;line-height:1.3;border:none;text-align:center;cursor:pointer}.foogallery .fg-caption a{text-decoration:none;color:#fff;border-bottom:1px solid #fff}.foogallery .fg-caption a:hover{border-bottom:none}.foogallery .fg-caption-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:16px;font-weight:400;padding:5px}.foogallery .fg-caption-desc{padding:5px}.foogallery .fg-caption-title+.fg-caption-desc{padding-top:0}.foogallery.fg-caption-always .fg-caption .fg-caption-inner:before{display:none}.foogallery.fg-caption-always .fg-item.fg-loaded .fg-caption{left:0;bottom:0;transition-timing-function:ease;transition-duration:.3s;transition-property:visibility,opacity;visibility:visible;opacity:1;text-align:left}.foogallery.fg-caption-hover .fg-caption .fg-caption-inner{width:100%;max-height:100%;position:absolute;top:50%;left:0;transform:translateY(-50%)}.foogallery.fg-caption-hover .fg-item.fg-loaded .fg-thumb:before{display:none}.foogallery.fg-hover-circle-plus .fg-thumb:before,.foogallery.fg-hover-external .fg-thumb:before,.foogallery.fg-hover-eye .fg-thumb:before,.foogallery.fg-hover-plus .fg-thumb:before,.foogallery.fg-hover-tint .fg-thumb:before,.foogallery.fg-hover-zoom .fg-thumb:before,.foogallery.fg-hover-zoom2 .fg-thumb:before,.foogallery.fg-hover-zoom3 .fg-thumb:before{content:"";display:block;position:absolute;visibility:hidden;opacity:0;top:0;bottom:0;left:0;right:0;z-index:8;background:rgba(0,0,0,.5) no-repeat center center;background-size:32px 32px}.foogallery.fg-hover-circle-plus .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-circle-plus .fg-thumb:focus:before,.foogallery.fg-hover-external .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-external .fg-thumb:focus:before,.foogallery.fg-hover-eye .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-eye .fg-thumb:focus:before,.foogallery.fg-hover-plus .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-plus .fg-thumb:focus:before,.foogallery.fg-hover-tint .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-tint .fg-thumb:focus:before,.foogallery.fg-hover-zoom .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-zoom .fg-thumb:focus:before,.foogallery.fg-hover-zoom2 .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-zoom2 .fg-thumb:focus:before,.foogallery.fg-hover-zoom3 .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-zoom3 .fg-thumb:focus:before{visibility:visible;opacity:1}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-tint .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-caption-inner:before{content:"";display:inline-block;position:relative;width:32px;height:32px;margin:10px 0 5px 0;background:transparent no-repeat center center;background-size:32px 32px;vertical-align:middle}.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-thumb:before{background-image:url(../img/zoom.png)}.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-thumb:before{background-image:url(../img/zoom2.png)}.foogallery.fg-hover-zoom3 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-thumb:before{background-image:url(../img/zoom3.png)}.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-thumb:before{background-image:url(../img/plus.png)}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-circle-plus .fg-thumb:before{background-image:url(../img/circle-plus.png)}.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-thumb:before{background-image:url(../img/eye.png)}.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-external .fg-thumb:before{background-image:url(../img/external.png)}@media only screen and (-o-min-device-pixel-ratio:5/4),only screen and (-webkit-min-device-pixel-ratio:1.25),only screen and (min-device-pixel-ratio:1.25),only screen and (min-resolution:1.25dppx){.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-thumb:before{background-image:url(../img/zoom@2x.png)}.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-thumb:before{background-image:url(../img/zoom2@2x.png)}.foogallery.fg-hover-zoom3 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-thumb:before{background-image:url(../img/zoom3@2x.png)}.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-thumb:before{background-image:url(../img/plus@2x.png)}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-circle-plus .fg-thumb:before{background-image:url(../img/circle-plus@2x.png)}.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-thumb:before{background-image:url(../img/eye@2x.png)}.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-external .fg-thumb:before{background-image:url(../img/external@2x.png)}}@media only screen and (-o-min-device-pixel-ratio:9/4),only screen and (-webkit-min-device-pixel-ratio:2.25),only screen and (min-device-pixel-ratio:2.25),only screen and (min-resolution:2.25dppx){.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-thumb:before{background-image:url(../img/zoom@3x.png)}.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-thumb:before{background-image:url(../img/zoom2@3x.png)}.foogallery.fg-hover-zoom3 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-thumb:before{background-image:url(../img/zoom3@3x.png)}.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-thumb:before{background-image:url(../img/plus@3x.png)}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-circle-plus .fg-thumb:before{background-image:url(../img/circle-plus@3x.png)}.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-thumb:before{background-image:url(../img/eye@3x.png)}.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-external .fg-thumb:before{background-image:url(../img/external@3x.png)}}.foogallery.fg-caption-hover.fg-hover-colorize .fg-caption,.foogallery.fg-caption-hover.fg-hover-fade .fg-caption,.foogallery.fg-caption-hover.fg-hover-grayscale .fg-caption,.foogallery.fg-caption-hover.fg-hover-instant .fg-caption,.foogallery.fg-caption-hover.fg-hover-push .fg-caption,.foogallery.fg-caption-hover.fg-hover-scale .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-down .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-left .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-right .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-up .fg-caption,.foogallery.fg-hover-colorize .fg-image,.foogallery.fg-hover-colorize .fg-thumb:before,.foogallery.fg-hover-fade .fg-thumb:before,.foogallery.fg-hover-grayscale .fg-image,.foogallery.fg-hover-grayscale .fg-thumb:before,.foogallery.fg-hover-instant .fg-thumb:before,.foogallery.fg-hover-push .fg-thumb,.foogallery.fg-hover-scale .fg-item,.foogallery.fg-hover-scale .fg-thumb:before,.foogallery.fg-hover-slide-down .fg-thumb:before,.foogallery.fg-hover-slide-left .fg-thumb:before,.foogallery.fg-hover-slide-right .fg-thumb:before,.foogallery.fg-hover-slide-up .fg-thumb:before{transition-timing-function:ease;transition-duration:.3s}.foogallery.fg-hover-colorize .fg-image{filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'saturate\' values=\'0\'/></filter></svg>#grayscale");filter:gray;-webkit-filter:grayscale(100%);-webkit-transition-property:-webkit-filter;transition-property:filter}.foogallery.fg-hover-colorize .fg-item-inner:hover .fg-image{-webkit-filter:none;filter:none}.foogallery.fg-caption-hover.fg-hover-colorize .fg-caption,.foogallery.fg-hover-colorize .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity}.foogallery.fg-caption-hover.fg-hover-colorize .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-colorize .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-fade .fg-loaded .fg-caption,.foogallery.fg-hover-fade .fg-loaded .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity}.foogallery.fg-caption-hover.fg-hover-fade .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-fade .fg-loaded .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-hover-grayscale .fg-image{-webkit-filter:none;filter:none;-webkit-transition-property:-webkit-filter;transition-property:filter}.foogallery.fg-hover-grayscale .fg-item-inner:hover .fg-image{-webkit-filter:grayscale(1);-webkit-filter:grayscale(100%);filter:grayscale(100%);filter:gray;opacity:1}.foogallery.fg-caption-hover.fg-hover-grayscale .fg-caption,.foogallery.fg-hover-grayscale .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity}.foogallery.fg-caption-hover.fg-hover-grayscale .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-grayscale .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-instant .fg-loaded .fg-caption,.foogallery.fg-hover-instant .fg-loaded .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:none}.foogallery.fg-caption-hover.fg-hover-instant .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-instant .fg-loaded .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-caption,.foogallery.fg-hover-push .fg-loaded .fg-thumb:before{display:block;left:0;top:0;bottom:0;transform:translateX(100%);visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-caption,.foogallery.fg-hover-push .fg-loaded .fg-thumb{transition-property:transform}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-item-inner:hover .fg-caption{transform:translateY(0)}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-item-inner:hover .fg-thumb,.foogallery.fg-hover-push .fg-loaded .fg-item-inner:hover .fg-thumb{transform:translateX(-100%)}.foogallery.fg-hover-scale .fg-item{transition-property:transform;z-index:4}.foogallery.fg-hover-scale .fg-item:hover{transform:scale(1.048);z-index:10}.foogallery.fg-caption-hover.fg-hover-scale .fg-caption,.foogallery.fg-hover-scale .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity}.foogallery.fg-caption-hover.fg-hover-scale .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-scale .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-caption,.foogallery.fg-hover-slide-down .fg-loaded .fg-thumb:before,.foogallery.fg-hover-slide-left .fg-loaded .fg-thumb:before,.foogallery.fg-hover-slide-right .fg-loaded .fg-thumb:before,.foogallery.fg-hover-slide-up .fg-loaded .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:transform;visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-slide-down .fg-loaded .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-slide-left .fg-loaded .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-slide-right .fg-loaded .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-slide-up .fg-loaded .fg-item-inner:hover .fg-thumb:before{transform:translateY(0) translateX(0)}.foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-caption,.foogallery.fg-hover-slide-up .fg-loaded .fg-thumb:before{transform:translateY(100%)}.foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-caption,.foogallery.fg-hover-slide-down .fg-loaded .fg-thumb:before{transform:translateY(-100%)}.foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-caption,.foogallery.fg-hover-slide-left .fg-loaded .fg-thumb:before{transform:translateX(100%)}.foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-caption,.foogallery.fg-hover-slide-right .fg-loaded .fg-thumb:before{transform:translateX(-100%)}.fg-paging-container,.fg-paging-container *,.fg-paging-container :after,.fg-paging-container :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fg-paging-container{display:block;padding:15px;text-align:center;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fg-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.fg-paging-container .fg-dot-item,.fg-paging-container .fg-dots{display:inline-block;margin:0;padding:0;outline:0;list-style:none}.fg-paging-container .fg-dot-item .fg-dot-link{display:inline-block;margin:3px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;user-select:none;background-image:none;text-decoration:none;border:1px solid transparent;position:relative;border-radius:50%;padding:0;font-size:0;outline:0;color:transparent;box-shadow:none}.fg-paging-container .fg-dot-item .fg-dot-link:before{content:"";background-color:transparent;border:1px solid transparent;display:block;border-radius:50%;width:9px;height:9px;padding:0;margin:2px}.fg-paging-container .fg-dot-item .fg-dot-link:active,.fg-paging-container .fg-dot-item .fg-dot-link:focus,.fg-paging-container .fg-dot-item .fg-dot-link:hover{text-decoration:none;box-shadow:none;outline:0}.fg-paging-container .fg-dot-item.fg-disabled .fg-dot-link,.fg-paging-container .fg-dot-item.fg-selected .fg-dot-link{cursor:not-allowed;pointer-events:none}.fg-paging-container .fg-dot-item.fg-disabled .fg-dot-link{cursor:not-allowed;pointer-events:none;outline:0}.fg-paging-container.fg-light .fg-dot-item .fg-dot-link,.fg-paging-container.fg-light .fg-dot-item .fg-dot-link:before{transition-timing-function:ease-out;transition-duration:.3s;transition-property:color,border-color,background-color}.fg-paging-container.fg-light .fg-dot-item .fg-dot-link{background-color:#eee;border-color:#9e9e9e}.fg-paging-container.fg-light .fg-dot-item.fg-selected .fg-dot-link{border-color:#8a8a8a}.fg-paging-container.fg-light .fg-dot-item .fg-dot-link:focus:before,.fg-paging-container.fg-light .fg-dot-item .fg-dot-link:hover:before,.fg-paging-container.fg-light .fg-dot-item.fg-selected .fg-dot-link:before{background-color:#666;border-color:#8a8a8a}.fg-paging-container.fg-light .fg-dot-item.fg-disabled .fg-dot-link,.fg-paging-container.fg-light .fg-dot-item.fg-disabled .fg-dot-link:focus,.fg-paging-container.fg-light .fg-dot-item.fg-disabled .fg-dot-link:hover{background-color:#eee;border-color:#9e9e9e;opacity:.5}.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link,.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link:before{transition-timing-function:ease-out;transition-duration:.3s;transition-property:color,border-color,background-color}.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link{background-color:#666;border-color:#333}.fg-paging-container.fg-dark .fg-dot-item.fg-selected .fg-dot-link{border-color:#444}.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link:focus:before,.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link:hover:before,.fg-paging-container.fg-dark .fg-dot-item.fg-selected .fg-dot-link:before{background-color:#333;border-color:#444}.fg-paging-container.fg-dark .fg-dot-item.fg-disabled .fg-dot-link,.fg-paging-container.fg-dark .fg-dot-item.fg-disabled .fg-dot-link:focus,.fg-paging-container.fg-dark .fg-dot-item.fg-disabled .fg-dot-link:hover{background-color:#666;border-color:#333;opacity:.5}.fg-default:after{content:'';display:block;clear:both}.fg-default .fg-item,.fg-default .fg-item-inner,.fg-default .fg-thumb{display:inline-block;vertical-align:top;max-width:100%}.fg-default .fg-image{border-radius:0;display:block;max-width:100%;height:auto;margin:0;padding:0}.fg-default .fg-image{vertical-align:top}.fg-default.fg-left{text-align:left}.fg-default.fg-center{text-align:center}.fg-default.fg-right{text-align:right}.fg-default.fg-gutter-5{padding-left:5px;margin-bottom:-5px}.fg-default.fg-gutter-5 .fg-item{margin-right:5px;margin-bottom:5px}.fg-default.fg-gutter-10{padding-left:10px;margin-bottom:-10px}.fg-default.fg-gutter-10 .fg-item{margin-right:10px;margin-bottom:10px}.fg-default.fg-gutter-15{padding-left:15px;margin-bottom:-15px}.fg-default.fg-gutter-15 .fg-item{margin-right:15px;margin-bottom:15px}.fg-default.fg-gutter-20{padding-left:20px;margin-bottom:-20px}.fg-default.fg-gutter-20 .fg-item{margin-right:20px;margin-bottom:20px}.fg-default.fg-gutter-25{padding-left:25px;margin-bottom:-25px}.fg-default.fg-gutter-25 .fg-item{margin-right:25px;margin-bottom:25px}.fg-masonry *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.foogallery.fg-masonry.fg-center{margin:0 auto}.fg-masonry .fg-thumb{display:block}.fg-masonry.fg-masonry-fixed .fg-thumb{display:inline-block}.fg-masonry.fg-masonry-fixed .fg-image{max-width:100%}.fg-masonry .fg-column-width{display:inline-block;visibility:hidden;height:0;border:solid 0 transparent}.fg-masonry.fg-masonry-2col .fg-image,.fg-masonry.fg-masonry-3col .fg-image,.fg-masonry.fg-masonry-4col .fg-image,.fg-masonry.fg-masonry-5col .fg-image{width:100%;height:auto;max-width:100%}.fg-masonry .fg-item{line-height:0;font-size:0}.fg-masonry.fg-masonry-2col .fg-item{margin-bottom:1%;width:49%}.fg-masonry.fg-masonry-2col .fg-column-width{width:49%}.fg-masonry.fg-masonry-2col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-item{margin-bottom:0;width:50%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-column-width{width:50%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-item{margin-bottom:3%;width:47%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-column-width{width:47%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-gutter-width{width:3%}.fg-masonry.fg-masonry-3col .fg-item{margin-bottom:1%;width:32%}.fg-masonry.fg-masonry-3col .fg-column-width{width:32%}.fg-masonry.fg-masonry-3col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-item{margin-bottom:0;width:33%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-column-width{width:33%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-item{margin-bottom:3%;width:30%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-column-width{width:30%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-gutter-width{width:3%}.fg-masonry.fg-masonry-4col .fg-item{margin-bottom:1%;width:24%}.fg-masonry.fg-masonry-4col .fg-column-width{width:24%}.fg-masonry.fg-masonry-4col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item{margin-bottom:0;width:25%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width{width:25%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item{margin-bottom:3%;width:22%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width{width:22%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width{width:3%}.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:19%}.fg-masonry.fg-masonry-5col .fg-column-width{width:19%}.fg-masonry.fg-masonry-5col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:20%}.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:20%}.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:17%}.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:17%}.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:3%}@media screen and (max-width:720px){.fg-masonry.fg-masonry-4col .fg-item,.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:32%}.fg-masonry.fg-masonry-4col .fg-column-width,.fg-masonry.fg-masonry-5col .fg-column-width{width:32%}.fg-masonry.fg-masonry-4col .fg-gutter-width,.fg-masonry.fg-masonry-5col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:33%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:33%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:30%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:30%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:3%}}@media screen and (max-width:480px){.fg-masonry.fg-masonry-3col .fg-item,.fg-masonry.fg-masonry-4col .fg-item,.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:49%}.fg-masonry.fg-masonry-3col .fg-column-width,.fg-masonry.fg-masonry-4col .fg-column-width,.fg-masonry.fg-masonry-5col .fg-column-width{width:49%}.fg-masonry.fg-masonry-3col .fg-gutter-width,.fg-masonry.fg-masonry-4col .fg-gutter-width,.fg-masonry.fg-masonry-5col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:50%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:50%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:47%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:47%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:3%}}@media screen and (max-width:320px){.fg-masonry.fg-masonry-2col .fg-item,.fg-masonry.fg-masonry-3col .fg-item,.fg-masonry.fg-masonry-4col .fg-item,.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:100%}.fg-masonry.fg-masonry-2col .fg-column-width,.fg-masonry.fg-masonry-3col .fg-column-width,.fg-masonry.fg-masonry-4col .fg-column-width,.fg-masonry.fg-masonry-5col .fg-column-width{width:100%}.fg-masonry.fg-masonry-2col .fg-gutter-width,.fg-masonry.fg-masonry-3col .fg-gutter-width,.fg-masonry.fg-masonry-4col .fg-gutter-width,.fg-masonry.fg-masonry-5col .fg-gutter-width{width:0}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:0}}.foogallery.fg-border-thin .fg-column-width{border-width:5px}.foogallery.fg-border-medium .fg-column-width{border-width:10px}.foogallery.fg-border-thick .fg-column-width{border-width:15px}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption{visibility:visible;opacity:1;font-size:13px;position:relative;display:block;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;text-transform:none;transform:none;transition:none;background-color:transparent;border-style:solid;border-color:transparent}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner:hover .fg-caption{transform:none;transition:none}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption-inner{display:block;position:relative;max-height:none;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;border:none;transform:none;transition:none}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption-inner:before{display:none}.foogallery.fg-masonry.fg-captions-bottom.fg-caption-hover .fg-item-inner .fg-thumb:before{display:block}.foogallery.fg-masonry.fg-captions-bottom.fg-caption-always .fg-item-inner:hover .fg-caption{visibility:visible;opacity:1}.fg-masonry.fg-captions-bottom .fg-caption-desc,.fg-masonry.fg-captions-bottom .fg-caption-title{text-align:left}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption,.fg-masonry.fg-captions-bottom.fg-light .fg-caption{color:#828282}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption a,.fg-masonry.fg-captions-bottom.fg-light .fg-caption a{color:#828282;border-bottom:1px solid #828282}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption a:hover,.fg-masonry.fg-captions-bottom.fg-light .fg-caption a:hover{border-bottom:none}.fg-masonry.fg-captions-bottom.fg-light .fg-caption-title,.fg-masonry.fg-captions-bottom.fg-light .fg-caption-title a{color:#222}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption-title,.fg-masonry.fg-captions-bottom.fg-dark .fg-caption-title a{color:#fff}.fg-masonry.fg-captions-bottom.fg-light .fg-caption-title a{border-bottom:1px solid #222}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption-title a{border-bottom:1px solid #fff}.fg-masonry.fg-captions-bottom .fg-caption{border-width:10px}.fg-masonry.fg-captions-bottom .fg-caption-title+.fg-caption-desc{margin-top:5px}.fg-masonry.fg-captions-bottom.fg-border-thin .fg-caption{border-width:10px 5px 5px 5px}.fg-masonry.fg-captions-bottom.fg-border-medium .fg-caption{border-width:10px 0 0 0}.fg-masonry.fg-captions-bottom.fg-border-thick .fg-caption{border-width:15px 0 0 0}.fg-masonry.fg-captions-bottom.fg-border-thick .fg-caption-title+.fg-caption-desc{margin-top:10px}.fg-justified{box-sizing:border-box;position:relative}.foogallery.fg-justified .fg-image,.foogallery.fg-justified .fg-item,.foogallery.fg-justified .fg-item-inner,.foogallery.fg-justified .fg-thumb{box-sizing:border-box;display:block;margin:0;padding:0}.fg-justified .fg-item{visibility:visible;position:absolute}.fg-justified .fg-item-inner{position:relative;width:100%;height:100%}.fg-justified .fg-thumb{position:relative;overflow:hidden}.fg-justified .fg-image{z-index:1}.fg-justified .fg-item.fg-positioned .fg-thumb{width:100%;height:100%}.fg-justified .fg-item.fg-positioned .fg-image{width:100%;height:auto;min-height:100%}.fg-simple_portfolio{box-sizing:border-box;position:relative;font-size:16px;margin:0 auto;padding:0;width:100%}.fg-simple_portfolio .fg-item{position:absolute;display:inline-block;margin:0;padding:0;outline:0}.fg-simple_portfolio .fg-image,.fg-simple_portfolio .fg-item-inner,.fg-simple_portfolio .fg-thumb{display:block;margin:0;padding:0;outline:0}.fg-simple_portfolio .fg-item-inner{position:relative;width:100%;height:100%}.fg-simple_portfolio .fg-thumb{box-sizing:border-box;display:block;margin:0;padding:0;border:none;outline:0;position:relative;overflow:hidden}.fg-simple_portfolio .fg-item.fg-positioned .fg-image{width:100%;height:auto}.fg-simple_portfolio .fg-image{z-index:1}.foogallery.fg-simple_portfolio .fg-item-inner .fg-caption{visibility:visible;opacity:1;font-size:13px;position:relative;display:block;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;text-transform:none;transform:none;transition:none;background-color:transparent;border-style:solid;border-color:transparent}.foogallery.fg-simple_portfolio .fg-item-inner:hover .fg-caption{transform:none;transition:none}.foogallery.fg-simple_portfolio .fg-item-inner .fg-caption-inner{display:block;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;border:none;transform:none;transition:none}.foogallery.fg-simple_portfolio .fg-item-inner .fg-caption-inner:before{display:none}.foogallery.fg-simple_portfolio.fg-caption-hover .fg-item-inner .fg-thumb:before{display:block}.foogallery.fg-simple_portfolio.fg-caption-always .fg-item-inner:hover .fg-caption{visibility:visible;opacity:1}.fg-simple_portfolio .fg-caption-title{text-align:left}.fg-simple_portfolio .fg-caption-desc{text-align:left}.fg-simple_portfolio.fg-dark .fg-caption,.fg-simple_portfolio.fg-light .fg-caption{color:#828282}.fg-simple_portfolio.fg-dark .fg-caption a,.fg-simple_portfolio.fg-light .fg-caption a{color:#828282;border-bottom:1px solid #828282}.fg-simple_portfolio.fg-dark .fg-caption a:hover,.fg-simple_portfolio.fg-light .fg-caption a:hover{border-bottom:none}.fg-simple_portfolio.fg-light .fg-caption-title,.fg-simple_portfolio.fg-light .fg-caption-title a{color:#222}.fg-simple_portfolio.fg-dark .fg-caption-title,.fg-simple_portfolio.fg-dark .fg-caption-title a{color:#fff}.fg-simple_portfolio.fg-light .fg-caption-title a{border-bottom:1px solid #222}.fg-simple_portfolio.fg-dark .fg-caption-title a{border-bottom:1px solid #fff}.fg-simple_portfolio.fg-captions-top .fg-item.fg-positioned .fg-thumb{position:absolute;bottom:0;left:0}.fg-simple_portfolio .fg-caption{border-width:0}.fg-simple_portfolio .fg-caption-title+.fg-caption-desc{margin-top:5px}.fg-simple_portfolio.fg-border-thin .fg-caption{border-width:10px 5px 5px 5px}.fg-simple_portfolio.fg-captions-top.fg-border-thin .fg-caption{border-width:5px 5px 10px 5px}.fg-simple_portfolio.fg-border-medium .fg-caption{border-width:10px 0 0 0}.fg-simple_portfolio.fg-captions-top.fg-border-medium .fg-caption{border-width:0 0 10px 0}.fg-simple_portfolio.fg-border-thick .fg-caption{border-width:15px 0 0 0}.fg-simple_portfolio.fg-captions-top.fg-border-thick .fg-caption{border-width:0 0 15px 0}.fg-simple_portfolio.fg-border-thick .fg-caption-title+.fg-caption-desc{margin-top:10px}.foogallery.fg-preset.fg-polaroid .fg-item{-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transition:-webkit-transform .35s,background-color .65s;transition:transform .35s,background-color .65s}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(2n+1){-webkit-transform:rotate(3deg);transform:rotate(3deg)}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(2n){-webkit-transform:rotate(-3deg);transform:rotate(-3deg)}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(3n){-webkit-transform:rotate(1deg);transform:rotate(1deg)}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(5n){-webkit-transform:rotate(-2deg);transform:rotate(-2deg)}.foogallery.fg-preset.fg-polaroid .fg-item:hover{-webkit-transform:rotate(0);transform:rotate(0)}.foogallery.fg-preset.fg-polaroid .fg-caption{position:relative;width:auto;font-family:"Segoe Print Regular",-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}.foogallery.fg-preset.fg-polaroid .fg-caption-inner,.foogallery.fg-preset.fg-polaroid .fg-caption-title{position:relative;width:auto}.foogallery.fg-preset.fg-polaroid .fg-caption-title{text-align:center}.foogallery.fg-preset.fg-polaroid .fg-caption-desc{display:none}.foogallery.fg-light.fg-preset.fg-polaroid .fg-caption-title,.foogallery.fg-preset.fg-polaroid .fg-caption-title{color:#333}.foogallery.fg-dark.fg-preset.fg-polaroid .fg-caption-title{color:#fff}.foogallery.fg-preset.fg-polaroid .fg-caption{border-style:solid;border-color:transparent;border-width:10px}.foogallery.fg-preset.fg-polaroid .fg-caption-title+.fg-caption-desc{margin-top:5px}.foogallery.fg-preset.fg-polaroid.fg-border-thin .fg-caption{border-width:10px 5px 5px 5px}.foogallery.fg-preset.fg-polaroid.fg-captions-top.fg-border-thin .fg-caption{border-width:5px 5px 10px 5px}.foogallery.fg-preset.fg-polaroid.fg-border-medium .fg-caption{border-width:10px 0 0 0}.foogallery.fg-preset.fg-polaroid.fg-captions-top.fg-border-medium .fg-caption{border-width:0 0 10px 0}.foogallery.fg-preset.fg-polaroid.fg-border-thick .fg-caption{border-width:15px 0 0 0}.foogallery.fg-preset.fg-polaroid.fg-captions-top.fg-border-thick .fg-caption{border-width:0 0 15px 0}.foogallery.fg-preset.fg-polaroid.fg-border-thick .fg-caption-title+.fg-caption-desc{margin-top:10px}.fg-image-viewer{display:block;font-family:'Open Sans','Helvetica Neue',Arial,sans-serif}.fg-image-viewer.fg-left{text-align:left}.fg-image-viewer.fg-center{text-align:center}.fg-image-viewer.fg-right{text-align:right}.fiv-inner{position:relative;display:inline-block;max-width:100%;overflow:hidden;z-index:6}.fiv-inner .fiv-inner-container{position:relative;overflow:hidden;max-width:100%;border-style:solid;border-width:0;border-bottom-width:4px;z-index:5}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb,.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb:active,.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb:hover,.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb:visited{position:relative;display:block;border:none;outline:0;text-decoration:none;box-shadow:none;max-width:100%}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item{position:relative;visibility:visible;opacity:1;border:none;outline:0;text-decoration:none;box-shadow:none;max-width:100%}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb img{display:block;max-width:100%;height:auto;border:none;outline:0;text-decoration:none}.fg-image-viewer .fiv-inner .fiv-ctrls{display:block;text-align:center;font-size:14px;border-style:solid;line-height:34px}.fg-image-viewer .fiv-inner .fiv-ctrls:after{content:'';display:block;clear:both}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-count{display:inline-block;font-weight:400;margin:0}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:none;min-width:80px;position:relative;overflow:hidden;transition:background-color .3s}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:before,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:before{display:block;position:absolute;font-size:24px;line-height:30px;top:0;left:0;width:100%;transform:translateY(0);transition:transform .3s}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:hover:before,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:hover:before{transform:translateY(-100%)}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next span,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev span{display:block;width:100%;transform:translateY(100%);transition:transform .3s}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:hover span,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:hover span{transform:translateY(0)}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev{float:left}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:before{content:'\2190'}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next{float:right}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:before{content:'\2192'}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-count span{margin:0 4px}/*!* Theme - Default (Light) *!*//*!* Theme - Dark *!*/.foogallery.fg-image-viewer.fg-caption-always .fg-item-inner .fg-caption{padding:0;border:none;background:#000;background:-moz-linear-gradient(left,rgba(0,0,0,.8) 0,rgba(0,0,0,.8) 60%,rgba(0,0,0,0) 100%);background:-webkit-linear-gradient(left,rgba(0,0,0,.8) 0,rgba(0,0,0,.8) 60%,rgba(0,0,0,0) 100%);background:linear-gradient(to right,rgba(0,0,0,.8) 0,rgba(0,0,0,.8) 60%,rgba(0,0,0,0) 100%)}.foogallery.fg-image-viewer.fg-caption-always .fg-caption-title{padding:10px 10px 10px 10px}.foogallery.fg-image-viewer.fg-caption-always .fg-caption-desc{padding:10px 10px 10px 10px}.foogallery.fg-image-viewer.fg-caption-always .fg-caption-title+.fg-caption-desc{padding:0 10px 10px 10px}.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-count,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-next,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-prev,.fg-image-viewer.fg-light .fiv-inner .fiv-inner-container{background-color:#fff;color:#333;border-color:#fff}.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-next:hover,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-prev:hover{background-color:#f2f2f2}.fg-image-viewer.fg-light .fiv-next,.fg-image-viewer.fg-light .fiv-prev{box-shadow:inset 0 0 0 1px #ddd}.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-count,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-next,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-prev,.fg-image-viewer.fg-dark .fiv-inner .fiv-inner-container{background-color:#333;color:#fff;border-color:#333}.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-next:hover,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-prev:hover{background-color:#444}.fg-image-viewer.fg-dark .fiv-next,.fg-image-viewer.fg-dark .fiv-prev{box-shadow:inset 0 0 0 1px #222}.foogallery.fg-image-viewer.fg-border-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin .fg-item-inner{border-width:0}.foogallery.fg-image-viewer .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thin .fiv-inner-container{border-width:4px}.foogallery.fg-image-viewer.fg-border-medium .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-medium .fiv-inner-container{border-width:10px}.foogallery.fg-image-viewer.fg-border-thick .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thick .fiv-inner-container{border-width:16px}.foogallery.fg-image-viewer .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-medium .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thick .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thin .fiv-ctrls{border-top-width:1px}.foogallery.fg-image-viewer.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-round-small .fiv-inner{border-radius:5px}.foogallery.fg-image-viewer.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-round-small .fg-item-inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.foogallery.fg-image-viewer.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-round-small .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fiv-prev,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fiv-prev,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-round-medium .fiv-inner{border-radius:10px}.foogallery.fg-image-viewer.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-round-medium .fg-item-inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.foogallery.fg-image-viewer.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-round-medium .fiv-prev{border-radius:5px}.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fiv-prev{border-radius:5px}.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fiv-prev,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-round-large .fiv-inner{border-radius:15px}.foogallery.fg-image-viewer.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-round-large .fg-item-inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.foogallery.fg-image-viewer.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-round-large .fiv-prev{border-radius:11px}.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fiv-prev{border-radius:11px}.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fiv-prev{border-radius:5px}.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-round-full .fiv-inner,.foogallery.fg-image-viewer.fg-round-full .fiv-next,.foogallery.fg-image-viewer.fg-round-full .fiv-prev{border-radius:50%}.foogallery.fg-image-viewer.fg-dark.fg-shadow-large .fg-item-inner,.foogallery.fg-image-viewer.fg-dark.fg-shadow-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-dark.fg-shadow-outline .fg-item-inner,.foogallery.fg-image-viewer.fg-dark.fg-shadow-small .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-large .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-outline .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-small .fg-item-inner{box-shadow:none}.foogallery.fg-image-viewer.fg-light.fg-shadow-outline .fiv-inner{box-shadow:0 0 0 1px #ddd}.foogallery.fg-image-viewer.fg-dark.fg-shadow-outline .fiv-inner{box-shadow:0 0 0 1px #222}.foogallery.fg-image-viewer.fg-dark.fg-shadow-small .fiv-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-small .fiv-inner{box-shadow:0 1px 4px 0 rgba(0,0,0,.5)}.foogallery.fg-image-viewer.fg-dark.fg-shadow-medium .fiv-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-medium .fiv-inner{box-shadow:0 1px 10px 0 rgba(0,0,0,.5)}.foogallery.fg-image-viewer.fg-dark.fg-shadow-large .fiv-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-large .fiv-inner{box-shadow:0 1px 16px 0 rgba(0,0,0,.5)}.foogallery.fg-thumbnail,.foogallery.fg-thumbnail.fg-center{text-align:center}.foogallery.fg-thumbnail.fg-left{text-align:left}.foogallery.fg-thumbnail.fg-right{text-align:right}.foogallery.fg-thumbnail.fg-float-left{float:left;width:auto}.foogallery.fg-thumbnail.fg-float-right{float:right;width:auto}.foogallery.fg-thumbnail .fg-item{display:inline-block;vertical-align:top;max-width:100%}.foogallery.fg-thumbnail .fg-image{max-width:100%}.foogallery.fg-thumbnail .fg-st-hidden{display:none}
|
1 |
+
.foogallery,.foogallery *{box-sizing:border-box}.foogallery{display:block;z-index:1;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;position:relative;line-height:0;font-size:0;width:100%;max-width:100%}.foogallery .fg-item{display:inline-block;position:relative;background-color:transparent;z-index:2;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.foogallery .fg-item-inner{display:block;position:relative;visibility:hidden;overflow:hidden;opacity:0;z-index:3;margin:0;border:solid 0 transparent}.foogallery .fg-item.fg-error,.foogallery .fg-item.fg-loading{background:no-repeat center}.foogallery .fg-item.fg-error{background-image:url(../img/image.png)}@media only screen and (-o-min-device-pixel-ratio:5/4),only screen and (-webkit-min-device-pixel-ratio:1.25),only screen and (min-device-pixel-ratio:1.25),only screen and (min-resolution:1.25dppx){.foogallery .fg-item.fg-error{background-image:url(../img/image@2x.png)}}@media only screen and (-o-min-device-pixel-ratio:9/4),only screen and (-webkit-min-device-pixel-ratio:2.25),only screen and (min-device-pixel-ratio:2.25),only screen and (min-resolution:2.25dppx){.foogallery .fg-item.fg-error{background-image:url(../img/image@3x.png)}}.foogallery .fg-item.fg-loaded{z-index:4}.foogallery .fg-loaded .fg-item-inner{visibility:visible;opacity:1;z-index:5}.foogallery .fg-error .fg-item-inner{pointer-events:none;cursor:default}.foogallery .fg-thumb{display:block;position:relative;border:none;outline:0;text-decoration:none;z-index:4}.foogallery .fg-image{display:block;position:relative;border:none;outline:0;text-decoration:none;z-index:5;max-width:none;height:auto;margin:0}.foogallery .fg-loaded .fg-thumb{z-index:6}.foogallery .fg-loaded .fg-image{z-index:7}.foogallery.fg-light .fg-item-inner{background-color:#fff;color:#333;border-color:#fff}.foogallery.fg-dark .fg-item-inner{background-color:#333;color:#fff;border-color:#333}.foogallery.fg-light .fg-item.fg-error,.foogallery.fg-light .fg-item.fg-idle,.foogallery.fg-light .fg-item.fg-loading{background-color:#eee;box-shadow:inset 0 0 0 1px #ddd}.foogallery.fg-dark .fg-item.fg-error,.foogallery.fg-dark .fg-item.fg-idle,.foogallery.fg-dark .fg-item.fg-loading{background-color:#444;box-shadow:inset 0 0 0 1px #333}.foogallery.fg-border-thin .fg-item-inner{border-width:4px}.foogallery.fg-border-medium .fg-item-inner{border-width:10px}.foogallery.fg-border-thick .fg-item-inner{border-width:16px}.foogallery.fg-light.fg-shadow-outline .fg-item-inner{box-shadow:0 0 0 1px #ddd}.foogallery.fg-dark.fg-shadow-outline .fg-item-inner{box-shadow:0 0 0 1px #222}.foogallery.fg-dark.fg-shadow-small .fg-item-inner,.foogallery.fg-light.fg-shadow-small .fg-item-inner{box-shadow:0 1px 4px 0 rgba(0,0,0,.5)}.foogallery.fg-dark.fg-shadow-medium .fg-item-inner,.foogallery.fg-light.fg-shadow-medium .fg-item-inner{box-shadow:0 1px 10px 0 rgba(0,0,0,.5)}.foogallery.fg-dark.fg-shadow-large .fg-item-inner,.foogallery.fg-light.fg-shadow-large .fg-item-inner{box-shadow:0 1px 16px 0 rgba(0,0,0,.5)}.foogallery.fg-shadow-inset-large .fg-thumb:after,.foogallery.fg-shadow-inset-medium .fg-thumb:after,.foogallery.fg-shadow-inset-small .fg-thumb:after{display:block;content:"";position:absolute;top:0;left:0;right:0;bottom:0;z-index:7}.foogallery.fg-dark.fg-shadow-inset-small .fg-thumb:after,.foogallery.fg-light.fg-shadow-inset-small .fg-thumb:after{box-shadow:inset 0 1px 4px 0 rgba(0,0,0,.3)}.foogallery.fg-dark.fg-shadow-inset-medium .fg-thumb:after,.foogallery.fg-light.fg-shadow-inset-medium .fg-thumb:after{box-shadow:inset 0 1px 10px 0 rgba(0,0,0,.3)}.foogallery.fg-dark.fg-shadow-inset-large .fg-thumb:after,.foogallery.fg-light.fg-shadow-inset-large .fg-thumb:after{box-shadow:inset 0 1px 16px 0 rgba(0,0,0,.3)}.foogallery.fg-round-full.fg-shadow-inset-large .fg-thumb:after,.foogallery.fg-round-full.fg-shadow-inset-medium .fg-thumb:after,.foogallery.fg-round-full.fg-shadow-inset-small .fg-thumb:after{border-radius:50%}.foogallery.fg-round-small .fg-item,.foogallery.fg-round-small .fg-item-inner{border-radius:5px}.foogallery.fg-round-medium .fg-item,.foogallery.fg-round-medium .fg-item-inner{border-radius:10px}.foogallery.fg-round-large .fg-item,.foogallery.fg-round-large .fg-item-inner{border-radius:15px}.foogallery.fg-round-full .fg-item,.foogallery.fg-round-full .fg-item-inner{border-radius:50%}.foogallery .fg-loader{position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);width:1em;height:1em;font-size:5px;visibility:hidden;opacity:0}.foogallery .fg-loading .fg-loader{visibility:visible;opacity:1}.fg-loading-default .fg-loader{border-radius:50%;text-indent:-9999em;-webkit-animation:loading-default 1.1s infinite ease;animation:loading-default 1.1s infinite ease}@-webkit-keyframes loading-default{0%,100%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,1),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.5),-1.8em -1.8em 0 0 rgba(130,130,130,.7)}12.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.7),1.8em -1.8em 0 0 rgba(130,130,130,1),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.5)}25%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.5),1.8em -1.8em 0 0 rgba(130,130,130,.7),2.5em 0 0 0 rgba(130,130,130,1),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}37.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.5),2.5em 0 0 0 rgba(130,130,130,.7),1.75em 1.75em 0 0 rgba(130,130,130,1),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}50%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.5),1.75em 1.75em 0 0 rgba(130,130,130,.7),0 2.5em 0 0 rgba(130,130,130,1),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}62.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.5),0 2.5em 0 0 rgba(130,130,130,.7),-1.8em 1.8em 0 0 rgba(130,130,130,1),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}75%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.5),-1.8em 1.8em 0 0 rgba(130,130,130,.7),-2.6em 0 0 0 rgba(130,130,130,1),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}87.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.5),-2.6em 0 0 0 rgba(130,130,130,.7),-1.8em -1.8em 0 0 rgba(130,130,130,1)}}@keyframes loading-default{0%,100%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,1),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.5),-1.8em -1.8em 0 0 rgba(130,130,130,.7)}12.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.7),1.8em -1.8em 0 0 rgba(130,130,130,1),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.5)}25%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.5),1.8em -1.8em 0 0 rgba(130,130,130,.7),2.5em 0 0 0 rgba(130,130,130,1),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}37.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.5),2.5em 0 0 0 rgba(130,130,130,.7),1.75em 1.75em 0 0 rgba(130,130,130,1),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}50%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.5),1.75em 1.75em 0 0 rgba(130,130,130,.7),0 2.5em 0 0 rgba(130,130,130,1),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}62.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.5),0 2.5em 0 0 rgba(130,130,130,.7),-1.8em 1.8em 0 0 rgba(130,130,130,1),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}75%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.5),-1.8em 1.8em 0 0 rgba(130,130,130,.7),-2.6em 0 0 0 rgba(130,130,130,1),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}87.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.5),-2.6em 0 0 0 rgba(130,130,130,.7),-1.8em -1.8em 0 0 rgba(130,130,130,1)}}.fg-loading-bars .fg-loader,.fg-loading-bars .fg-loader:after,.fg-loading-bars .fg-loader:before{background:rgba(130,130,130,1);-webkit-animation:loading-bars 1s infinite ease-in-out;animation:loading-bars 1s infinite ease-in-out;width:1em;height:4em}.fg-loading-bars .fg-loader{color:rgba(130,130,130,1);text-indent:-9999em;font-size:4px;-webkit-animation-delay:-.16s;animation-delay:-.16s}.fg-loading-bars .fg-loader:after,.fg-loading-bars .fg-loader:before{position:absolute;top:0;content:''}.fg-loading-bars .fg-loader:before{left:-1.5em;-webkit-animation-delay:-.32s;animation-delay:-.32s}.fg-loading-bars .fg-loader:after{left:1.5em}@-webkit-keyframes loading-bars{0%,100%,80%{box-shadow:0 0;height:4em}40%{box-shadow:0 -2em;height:5em}}@keyframes loading-bars{0%,100%,80%{box-shadow:0 0;height:4em}40%{box-shadow:0 -2em;height:5em}}.fg-loading-trail .fg-loader{color:#828282;font-size:20px;text-indent:-9999em;overflow:hidden;border-radius:50%;-webkit-animation:loading-trail-1 1.7s infinite ease,loading-trail-2 1.7s infinite ease;animation:loading-trail-1 1.7s infinite ease,loading-trail-2 1.7s infinite ease}@-webkit-keyframes loading-trail-1{0%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}5%,95%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}10%,59%{box-shadow:0 -.83em 0 -.4em,-.087em -.825em 0 -.42em,-.173em -.812em 0 -.44em,-.256em -.789em 0 -.46em,-.297em -.775em 0 -.477em}20%{box-shadow:0 -.83em 0 -.4em,-.338em -.758em 0 -.42em,-.555em -.617em 0 -.44em,-.671em -.488em 0 -.46em,-.749em -.34em 0 -.477em}38%{box-shadow:0 -.83em 0 -.4em,-.377em -.74em 0 -.42em,-.645em -.522em 0 -.44em,-.775em -.297em 0 -.46em,-.82em -.09em 0 -.477em}100%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}}@keyframes loading-trail-1{0%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}5%,95%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}10%,59%{box-shadow:0 -.83em 0 -.4em,-.087em -.825em 0 -.42em,-.173em -.812em 0 -.44em,-.256em -.789em 0 -.46em,-.297em -.775em 0 -.477em}20%{box-shadow:0 -.83em 0 -.4em,-.338em -.758em 0 -.42em,-.555em -.617em 0 -.44em,-.671em -.488em 0 -.46em,-.749em -.34em 0 -.477em}38%{box-shadow:0 -.83em 0 -.4em,-.377em -.74em 0 -.42em,-.645em -.522em 0 -.44em,-.775em -.297em 0 -.46em,-.82em -.09em 0 -.477em}100%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}}@-webkit-keyframes loading-trail-2{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}@keyframes loading-trail-2{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}.fg-loading-pulse .fg-loader,.fg-loading-pulse .fg-loader:after,.fg-loading-pulse .fg-loader:before{border-radius:50%;width:2.5em;height:2.5em;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation:loading-pulse 1.8s infinite ease-in-out;animation:loading-pulse 1.8s infinite ease-in-out}.fg-loading-pulse .fg-loader{color:#828282;font-size:4px;text-indent:-9999em;transform:translateX(-50%) translateY(-150%);-webkit-animation-delay:-.16s;animation-delay:-.16s}.fg-loading-pulse .fg-loader:after,.fg-loading-pulse .fg-loader:before{content:'';position:absolute;top:0}.fg-loading-pulse .fg-loader:before{left:-3.5em;-webkit-animation-delay:-.32s;animation-delay:-.32s}.fg-loading-pulse .fg-loader:after{left:3.5em}@-webkit-keyframes loading-pulse{0%,100%,80%{box-shadow:0 2.5em 0 -1.3em}40%{box-shadow:0 2.5em 0 0}}@keyframes loading-pulse{0%,100%,80%{box-shadow:0 2.5em 0 -1.3em}40%{box-shadow:0 2.5em 0 0}}.fg-loading-dots .fg-loader{color:#828282;font-size:5px;border-radius:50%;text-indent:-9999em;-webkit-animation:loading-dots 1.3s infinite linear;animation:loading-dots 1.3s infinite linear}@-webkit-keyframes loading-dots{0%,100%{box-shadow:0 -3em 0 .2em,2em -2em 0 0,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 0}12.5%{box-shadow:0 -3em 0 0,2em -2em 0 .2em,3em 0 0 0,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}25%{box-shadow:0 -3em 0 -.5em,2em -2em 0 0,3em 0 0 .2em,2em 2em 0 0,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}37.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 0,2em 2em 0 .2em,0 3em 0 0,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}50%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 0,0 3em 0 .2em,-2em 2em 0 0,-3em 0 0 -1em,-2em -2em 0 -1em}62.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 0,-2em 2em 0 .2em,-3em 0 0 0,-2em -2em 0 -1em}75%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 .2em,-2em -2em 0 0}87.5%{box-shadow:0 -3em 0 0,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 0,-2em -2em 0 .2em}}@keyframes loading-dots{0%,100%{box-shadow:0 -3em 0 .2em,2em -2em 0 0,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 0}12.5%{box-shadow:0 -3em 0 0,2em -2em 0 .2em,3em 0 0 0,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}25%{box-shadow:0 -3em 0 -.5em,2em -2em 0 0,3em 0 0 .2em,2em 2em 0 0,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}37.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 0,2em 2em 0 .2em,0 3em 0 0,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}50%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 0,0 3em 0 .2em,-2em 2em 0 0,-3em 0 0 -1em,-2em -2em 0 -1em}62.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 0,-2em 2em 0 .2em,-3em 0 0 0,-2em -2em 0 -1em}75%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 .2em,-2em -2em 0 0}87.5%{box-shadow:0 -3em 0 0,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 0,-2em -2em 0 .2em}}.fg-loading-partial .fg-loader,.fg-loading-partial .fg-loader:after{border-radius:50%;width:10em;height:10em}.fg-loading-partial .fg-loader{font-size:4px;text-indent:-9999em;border-top:1.1em solid rgba(130,130,130,.2);border-right:1.1em solid rgba(130,130,130,.2);border-bottom:1.1em solid rgba(130,130,130,.2);border-left:1.1em solid #828282;-webkit-animation:loading-partial 1.1s infinite linear;animation:loading-partial 1.1s infinite linear}@-webkit-keyframes loading-partial{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}@keyframes loading-partial{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}.foogallery.fg-loaded-drop .fg-item,.foogallery.fg-loaded-fade-in .fg-item,.foogallery.fg-loaded-flip .fg-item,.foogallery.fg-loaded-fly .fg-item,.foogallery.fg-loaded-scale-up .fg-item,.foogallery.fg-loaded-slide-down .fg-item,.foogallery.fg-loaded-slide-left .fg-item,.foogallery.fg-loaded-slide-right .fg-item,.foogallery.fg-loaded-slide-up .fg-item,.foogallery.fg-loaded-swing-down .fg-item{transition-timing-function:ease;transition-duration:650ms;transition-property:background-color,transform}.foogallery.fg-loaded-drop .fg-item-inner,.foogallery.fg-loaded-fade-in .fg-item-inner,.foogallery.fg-loaded-flip .fg-item-inner,.foogallery.fg-loaded-fly .fg-item-inner,.foogallery.fg-loaded-scale-up .fg-item-inner,.foogallery.fg-loaded-slide-down .fg-item-inner,.foogallery.fg-loaded-slide-left .fg-item-inner,.foogallery.fg-loaded-slide-right .fg-item-inner,.foogallery.fg-loaded-slide-up .fg-item-inner,.foogallery.fg-loaded-swing-down .fg-item-inner{transition-timing-function:ease;transition-duration:650ms}.foogallery.fg-loaded-drop .fg-item.fg-loaded,.foogallery.fg-loaded-flip .fg-item.fg-loaded,.foogallery.fg-loaded-fly .fg-item.fg-loaded,.foogallery.fg-loaded-swing-down .fg-item.fg-loaded{perspective:1300px}.foogallery.fg-loaded-fade-in .fg-item-inner{transition-property:visibility,opacity}.foogallery .fg-caption{visibility:hidden;opacity:0;background-color:rgba(0,0,0,.6);color:#fff;position:absolute;z-index:8;width:100%;max-height:100%;overflow:hidden;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:13px;font-weight:400;line-height:1.3;border:none;text-align:center;cursor:pointer}.foogallery .fg-caption a{text-decoration:none;color:#fff;border-bottom:1px solid #fff}.foogallery .fg-caption a:hover{border-bottom:none}.foogallery .fg-caption-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:16px;font-weight:400;padding:5px}.foogallery .fg-caption-desc{padding:5px}.foogallery .fg-caption-title+.fg-caption-desc{padding-top:0}.foogallery.fg-caption-always .fg-caption .fg-caption-inner:before{display:none}.foogallery.fg-caption-always .fg-item.fg-loaded .fg-caption{left:0;bottom:0;transition-timing-function:ease;transition-duration:.3s;transition-property:visibility,opacity;visibility:visible;opacity:1;text-align:left}.foogallery.fg-caption-hover .fg-caption .fg-caption-inner{width:100%;max-height:100%;position:absolute;top:50%;left:0;transform:translateY(-50%)}.foogallery.fg-caption-hover .fg-item.fg-loaded .fg-thumb:before{display:none}.foogallery.fg-hover-circle-plus .fg-thumb:before,.foogallery.fg-hover-external .fg-thumb:before,.foogallery.fg-hover-eye .fg-thumb:before,.foogallery.fg-hover-plus .fg-thumb:before,.foogallery.fg-hover-tint .fg-thumb:before,.foogallery.fg-hover-zoom .fg-thumb:before,.foogallery.fg-hover-zoom2 .fg-thumb:before,.foogallery.fg-hover-zoom3 .fg-thumb:before{content:"";display:block;position:absolute;visibility:hidden;opacity:0;top:0;bottom:0;left:0;right:0;z-index:8;background:rgba(0,0,0,.5) no-repeat center center;background-size:32px 32px}.foogallery.fg-hover-circle-plus .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-circle-plus .fg-thumb:focus:before,.foogallery.fg-hover-external .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-external .fg-thumb:focus:before,.foogallery.fg-hover-eye .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-eye .fg-thumb:focus:before,.foogallery.fg-hover-plus .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-plus .fg-thumb:focus:before,.foogallery.fg-hover-tint .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-tint .fg-thumb:focus:before,.foogallery.fg-hover-zoom .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-zoom .fg-thumb:focus:before,.foogallery.fg-hover-zoom2 .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-zoom2 .fg-thumb:focus:before,.foogallery.fg-hover-zoom3 .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-zoom3 .fg-thumb:focus:before{visibility:visible;opacity:1}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-tint .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-caption-inner:before{content:"";display:inline-block;position:relative;width:32px;height:32px;margin:10px 0 5px 0;background:transparent no-repeat center center;background-size:32px 32px;vertical-align:middle}.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-thumb:before{background-image:url(../img/zoom.png)}.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-thumb:before{background-image:url(../img/zoom2.png)}.foogallery.fg-hover-zoom3 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-thumb:before{background-image:url(../img/zoom3.png)}.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-thumb:before{background-image:url(../img/plus.png)}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-circle-plus .fg-thumb:before{background-image:url(../img/circle-plus.png)}.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-thumb:before{background-image:url(../img/eye.png)}.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-external .fg-thumb:before{background-image:url(../img/external.png)}@media only screen and (-o-min-device-pixel-ratio:5/4),only screen and (-webkit-min-device-pixel-ratio:1.25),only screen and (min-device-pixel-ratio:1.25),only screen and (min-resolution:1.25dppx){.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-thumb:before{background-image:url(../img/zoom@2x.png)}.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-thumb:before{background-image:url(../img/zoom2@2x.png)}.foogallery.fg-hover-zoom3 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-thumb:before{background-image:url(../img/zoom3@2x.png)}.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-thumb:before{background-image:url(../img/plus@2x.png)}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-circle-plus .fg-thumb:before{background-image:url(../img/circle-plus@2x.png)}.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-thumb:before{background-image:url(../img/eye@2x.png)}.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-external .fg-thumb:before{background-image:url(../img/external@2x.png)}}@media only screen and (-o-min-device-pixel-ratio:9/4),only screen and (-webkit-min-device-pixel-ratio:2.25),only screen and (min-device-pixel-ratio:2.25),only screen and (min-resolution:2.25dppx){.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-thumb:before{background-image:url(../img/zoom@3x.png)}.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-thumb:before{background-image:url(../img/zoom2@3x.png)}.foogallery.fg-hover-zoom3 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-thumb:before{background-image:url(../img/zoom3@3x.png)}.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-thumb:before{background-image:url(../img/plus@3x.png)}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-circle-plus .fg-thumb:before{background-image:url(../img/circle-plus@3x.png)}.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-thumb:before{background-image:url(../img/eye@3x.png)}.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-external .fg-thumb:before{background-image:url(../img/external@3x.png)}}.foogallery.fg-caption-hover.fg-hover-colorize .fg-caption,.foogallery.fg-caption-hover.fg-hover-fade .fg-caption,.foogallery.fg-caption-hover.fg-hover-grayscale .fg-caption,.foogallery.fg-caption-hover.fg-hover-instant .fg-caption,.foogallery.fg-caption-hover.fg-hover-push .fg-caption,.foogallery.fg-caption-hover.fg-hover-scale .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-down .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-left .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-right .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-up .fg-caption,.foogallery.fg-hover-colorize .fg-image,.foogallery.fg-hover-colorize .fg-thumb:before,.foogallery.fg-hover-fade .fg-thumb:before,.foogallery.fg-hover-grayscale .fg-image,.foogallery.fg-hover-grayscale .fg-thumb:before,.foogallery.fg-hover-instant .fg-thumb:before,.foogallery.fg-hover-push .fg-thumb,.foogallery.fg-hover-scale .fg-item,.foogallery.fg-hover-scale .fg-thumb:before,.foogallery.fg-hover-slide-down .fg-thumb:before,.foogallery.fg-hover-slide-left .fg-thumb:before,.foogallery.fg-hover-slide-right .fg-thumb:before,.foogallery.fg-hover-slide-up .fg-thumb:before{transition-timing-function:ease;transition-duration:.3s}.foogallery.fg-hover-colorize .fg-image{filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'saturate\' values=\'0\'/></filter></svg>#grayscale");filter:gray;-webkit-filter:grayscale(100%);-webkit-transition-property:-webkit-filter;transition-property:filter}.foogallery.fg-hover-colorize .fg-item-inner:hover .fg-image{-webkit-filter:none;filter:none}.foogallery.fg-caption-hover.fg-hover-colorize .fg-caption,.foogallery.fg-hover-colorize .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity}.foogallery.fg-caption-hover.fg-hover-colorize .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-colorize .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-fade .fg-loaded .fg-caption,.foogallery.fg-hover-fade .fg-loaded .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity}.foogallery.fg-caption-hover.fg-hover-fade .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-fade .fg-loaded .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-hover-grayscale .fg-image{-webkit-filter:none;filter:none;-webkit-transition-property:-webkit-filter;transition-property:filter}.foogallery.fg-hover-grayscale .fg-item-inner:hover .fg-image{-webkit-filter:grayscale(1);-webkit-filter:grayscale(100%);filter:grayscale(100%);filter:gray;opacity:1}.foogallery.fg-caption-hover.fg-hover-grayscale .fg-caption,.foogallery.fg-hover-grayscale .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity}.foogallery.fg-caption-hover.fg-hover-grayscale .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-grayscale .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-instant .fg-loaded .fg-caption,.foogallery.fg-hover-instant .fg-loaded .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:none}.foogallery.fg-caption-hover.fg-hover-instant .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-instant .fg-loaded .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-caption,.foogallery.fg-hover-push .fg-loaded .fg-thumb:before{display:block;left:0;top:0;bottom:0;transform:translateX(100%);visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-caption,.foogallery.fg-hover-push .fg-loaded .fg-thumb{transition-property:transform}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-item-inner:hover .fg-caption{transform:translateY(0)}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-item-inner:hover .fg-thumb,.foogallery.fg-hover-push .fg-loaded .fg-item-inner:hover .fg-thumb{transform:translateX(-100%)}.foogallery.fg-hover-scale .fg-item{transition-property:transform;z-index:4}.foogallery.fg-hover-scale .fg-item:hover{transform:scale(1.048);z-index:10}.foogallery.fg-caption-hover.fg-hover-scale .fg-caption,.foogallery.fg-hover-scale .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity}.foogallery.fg-caption-hover.fg-hover-scale .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-scale .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-caption,.foogallery.fg-hover-slide-down .fg-loaded .fg-thumb:before,.foogallery.fg-hover-slide-left .fg-loaded .fg-thumb:before,.foogallery.fg-hover-slide-right .fg-loaded .fg-thumb:before,.foogallery.fg-hover-slide-up .fg-loaded .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:transform;visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-slide-down .fg-loaded .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-slide-left .fg-loaded .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-slide-right .fg-loaded .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-slide-up .fg-loaded .fg-item-inner:hover .fg-thumb:before{transform:translateY(0) translateX(0)}.foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-caption,.foogallery.fg-hover-slide-up .fg-loaded .fg-thumb:before{transform:translateY(100%)}.foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-caption,.foogallery.fg-hover-slide-down .fg-loaded .fg-thumb:before{transform:translateY(-100%)}.foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-caption,.foogallery.fg-hover-slide-left .fg-loaded .fg-thumb:before{transform:translateX(100%)}.foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-caption,.foogallery.fg-hover-slide-right .fg-loaded .fg-thumb:before{transform:translateX(-100%)}.fg-paging-container,.fg-paging-container *,.fg-paging-container :after,.fg-paging-container :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fg-paging-container{display:block;padding:15px;text-align:center;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fg-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.fg-paging-container .fg-dot-item,.fg-paging-container .fg-dots{display:inline-block;margin:0;padding:0;outline:0;list-style:none}.fg-paging-container .fg-dot-item .fg-dot-link{display:inline-block;margin:3px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;user-select:none;background-image:none;text-decoration:none;border:1px solid transparent;position:relative;border-radius:50%;padding:0;font-size:0;outline:0;color:transparent;box-shadow:none}.fg-paging-container .fg-dot-item .fg-dot-link:before{content:"";background-color:transparent;border:1px solid transparent;display:block;border-radius:50%;width:9px;height:9px;padding:0;margin:2px}.fg-paging-container .fg-dot-item .fg-dot-link:active,.fg-paging-container .fg-dot-item .fg-dot-link:focus,.fg-paging-container .fg-dot-item .fg-dot-link:hover{text-decoration:none;box-shadow:none;outline:0}.fg-paging-container .fg-dot-item.fg-disabled .fg-dot-link,.fg-paging-container .fg-dot-item.fg-selected .fg-dot-link{cursor:not-allowed;pointer-events:none}.fg-paging-container .fg-dot-item.fg-disabled .fg-dot-link{cursor:not-allowed;pointer-events:none;outline:0}.fg-paging-container.fg-light .fg-dot-item .fg-dot-link,.fg-paging-container.fg-light .fg-dot-item .fg-dot-link:before{transition-timing-function:ease-out;transition-duration:.3s;transition-property:color,border-color,background-color}.fg-paging-container.fg-light .fg-dot-item .fg-dot-link{background-color:#eee;border-color:#9e9e9e}.fg-paging-container.fg-light .fg-dot-item.fg-selected .fg-dot-link{border-color:#8a8a8a}.fg-paging-container.fg-light .fg-dot-item .fg-dot-link:focus:before,.fg-paging-container.fg-light .fg-dot-item .fg-dot-link:hover:before,.fg-paging-container.fg-light .fg-dot-item.fg-selected .fg-dot-link:before{background-color:#666;border-color:#8a8a8a}.fg-paging-container.fg-light .fg-dot-item.fg-disabled .fg-dot-link,.fg-paging-container.fg-light .fg-dot-item.fg-disabled .fg-dot-link:focus,.fg-paging-container.fg-light .fg-dot-item.fg-disabled .fg-dot-link:hover{background-color:#eee;border-color:#9e9e9e;opacity:.5}.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link,.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link:before{transition-timing-function:ease-out;transition-duration:.3s;transition-property:color,border-color,background-color}.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link{background-color:#666;border-color:#333}.fg-paging-container.fg-dark .fg-dot-item.fg-selected .fg-dot-link{border-color:#444}.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link:focus:before,.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link:hover:before,.fg-paging-container.fg-dark .fg-dot-item.fg-selected .fg-dot-link:before{background-color:#333;border-color:#444}.fg-paging-container.fg-dark .fg-dot-item.fg-disabled .fg-dot-link,.fg-paging-container.fg-dark .fg-dot-item.fg-disabled .fg-dot-link:focus,.fg-paging-container.fg-dark .fg-dot-item.fg-disabled .fg-dot-link:hover{background-color:#666;border-color:#333;opacity:.5}.fg-default:after{content:'';display:block;clear:both}.fg-default .fg-item,.fg-default .fg-item-inner,.fg-default .fg-thumb{display:inline-block;vertical-align:top;max-width:100%}.fg-default .fg-image{border-radius:0;display:block;max-width:100%;height:auto;margin:0;padding:0}.fg-default .fg-image{vertical-align:top}.fg-default.fg-left{text-align:left}.fg-default.fg-center{text-align:center}.fg-default.fg-right{text-align:right}.fg-default.fg-gutter-5{padding-left:5px;margin-bottom:-5px}.fg-default.fg-gutter-5 .fg-item{margin-right:5px;margin-bottom:5px}.fg-default.fg-gutter-10{padding-left:10px;margin-bottom:-10px}.fg-default.fg-gutter-10 .fg-item{margin-right:10px;margin-bottom:10px}.fg-default.fg-gutter-15{padding-left:15px;margin-bottom:-15px}.fg-default.fg-gutter-15 .fg-item{margin-right:15px;margin-bottom:15px}.fg-default.fg-gutter-20{padding-left:20px;margin-bottom:-20px}.fg-default.fg-gutter-20 .fg-item{margin-right:20px;margin-bottom:20px}.fg-default.fg-gutter-25{padding-left:25px;margin-bottom:-25px}.fg-default.fg-gutter-25 .fg-item{margin-right:25px;margin-bottom:25px}.fg-masonry *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.foogallery.fg-masonry.fg-center{margin:0 auto}.fg-masonry .fg-thumb{display:block}.fg-masonry.fg-masonry-fixed .fg-thumb{display:inline-block}.fg-masonry.fg-masonry-fixed .fg-image{max-width:100%}.fg-masonry .fg-column-width{display:inline-block;visibility:hidden;height:0;border:solid 0 transparent}.fg-masonry.fg-masonry-2col .fg-image,.fg-masonry.fg-masonry-3col .fg-image,.fg-masonry.fg-masonry-4col .fg-image,.fg-masonry.fg-masonry-5col .fg-image{width:100%;height:auto;max-width:100%}.fg-masonry .fg-item{line-height:0;font-size:0}.fg-masonry.fg-masonry-2col .fg-item{margin-bottom:1%;width:49%}.fg-masonry.fg-masonry-2col .fg-column-width{width:49%}.fg-masonry.fg-masonry-2col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-item{margin-bottom:0;width:50%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-column-width{width:50%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-item{margin-bottom:3%;width:47%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-column-width{width:47%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-gutter-width{width:3%}.fg-masonry.fg-masonry-3col .fg-item{margin-bottom:1%;width:32%}.fg-masonry.fg-masonry-3col .fg-column-width{width:32%}.fg-masonry.fg-masonry-3col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-item{margin-bottom:0;width:33%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-column-width{width:33%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-item{margin-bottom:3%;width:30%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-column-width{width:30%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-gutter-width{width:3%}.fg-masonry.fg-masonry-4col .fg-item{margin-bottom:1%;width:24%}.fg-masonry.fg-masonry-4col .fg-column-width{width:24%}.fg-masonry.fg-masonry-4col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item{margin-bottom:0;width:25%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width{width:25%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item{margin-bottom:3%;width:22%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width{width:22%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width{width:3%}.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:19%}.fg-masonry.fg-masonry-5col .fg-column-width{width:19%}.fg-masonry.fg-masonry-5col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:20%}.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:20%}.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:17%}.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:17%}.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:3%}@media screen and (max-width:720px){.fg-masonry.fg-masonry-4col .fg-item,.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:32%}.fg-masonry.fg-masonry-4col .fg-column-width,.fg-masonry.fg-masonry-5col .fg-column-width{width:32%}.fg-masonry.fg-masonry-4col .fg-gutter-width,.fg-masonry.fg-masonry-5col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:33%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:33%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:30%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:30%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:3%}}@media screen and (max-width:480px){.fg-masonry.fg-masonry-3col .fg-item,.fg-masonry.fg-masonry-4col .fg-item,.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:49%}.fg-masonry.fg-masonry-3col .fg-column-width,.fg-masonry.fg-masonry-4col .fg-column-width,.fg-masonry.fg-masonry-5col .fg-column-width{width:49%}.fg-masonry.fg-masonry-3col .fg-gutter-width,.fg-masonry.fg-masonry-4col .fg-gutter-width,.fg-masonry.fg-masonry-5col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:50%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:50%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:47%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:47%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:3%}}@media screen and (max-width:320px){.fg-masonry.fg-masonry-2col .fg-item,.fg-masonry.fg-masonry-3col .fg-item,.fg-masonry.fg-masonry-4col .fg-item,.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:100%}.fg-masonry.fg-masonry-2col .fg-column-width,.fg-masonry.fg-masonry-3col .fg-column-width,.fg-masonry.fg-masonry-4col .fg-column-width,.fg-masonry.fg-masonry-5col .fg-column-width{width:100%}.fg-masonry.fg-masonry-2col .fg-gutter-width,.fg-masonry.fg-masonry-3col .fg-gutter-width,.fg-masonry.fg-masonry-4col .fg-gutter-width,.fg-masonry.fg-masonry-5col .fg-gutter-width{width:0}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:0}}.foogallery.fg-border-thin .fg-column-width{border-width:5px}.foogallery.fg-border-medium .fg-column-width{border-width:10px}.foogallery.fg-border-thick .fg-column-width{border-width:15px}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption{visibility:visible;opacity:1;font-size:13px;position:relative;display:block;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;text-transform:none;transform:none;transition:none;background-color:transparent;border-style:solid;border-color:transparent}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner:hover .fg-caption{transform:none;transition:none}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption-inner{display:block;position:relative;max-height:none;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;border:none;transform:none;transition:none}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption-inner:before{display:none}.foogallery.fg-masonry.fg-captions-bottom.fg-caption-hover .fg-item-inner .fg-thumb:before{display:block}.foogallery.fg-masonry.fg-captions-bottom.fg-caption-always .fg-item-inner:hover .fg-caption{visibility:visible;opacity:1}.fg-masonry.fg-captions-bottom .fg-caption-desc,.fg-masonry.fg-captions-bottom .fg-caption-title{text-align:left}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption,.fg-masonry.fg-captions-bottom.fg-light .fg-caption{color:#828282}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption a,.fg-masonry.fg-captions-bottom.fg-light .fg-caption a{color:#828282;border-bottom:1px solid #828282}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption a:hover,.fg-masonry.fg-captions-bottom.fg-light .fg-caption a:hover{border-bottom:none}.fg-masonry.fg-captions-bottom.fg-light .fg-caption-title,.fg-masonry.fg-captions-bottom.fg-light .fg-caption-title a{color:#222}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption-title,.fg-masonry.fg-captions-bottom.fg-dark .fg-caption-title a{color:#fff}.fg-masonry.fg-captions-bottom.fg-light .fg-caption-title a{border-bottom:1px solid #222}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption-title a{border-bottom:1px solid #fff}.fg-masonry.fg-captions-bottom .fg-caption{border-width:10px}.fg-masonry.fg-captions-bottom .fg-caption-title+.fg-caption-desc{margin-top:5px}.fg-masonry.fg-captions-bottom.fg-border-thin .fg-caption{border-width:10px 5px 5px 5px}.fg-masonry.fg-captions-bottom.fg-border-medium .fg-caption{border-width:10px 0 0 0}.fg-masonry.fg-captions-bottom.fg-border-thick .fg-caption{border-width:15px 0 0 0}.fg-masonry.fg-captions-bottom.fg-border-thick .fg-caption-title+.fg-caption-desc{margin-top:10px}.fg-justified{box-sizing:border-box;position:relative}.foogallery.fg-justified .fg-image,.foogallery.fg-justified .fg-item,.foogallery.fg-justified .fg-item-inner,.foogallery.fg-justified .fg-thumb{box-sizing:border-box;display:block;margin:0;padding:0}.fg-justified .fg-item{visibility:visible;position:absolute}.fg-justified .fg-item-inner{position:relative;width:100%;height:100%}.fg-justified .fg-thumb{position:relative;overflow:hidden}.fg-justified .fg-image{z-index:1}.fg-justified .fg-item.fg-positioned .fg-thumb{width:100%;height:100%}.fg-justified .fg-item.fg-positioned .fg-image{width:100%;height:auto;min-height:100%;top:50%;transform:translateY(-50%)}.fg-simple_portfolio{box-sizing:border-box;position:relative;font-size:16px;margin:0 auto;padding:0;width:100%}.fg-simple_portfolio .fg-item{position:absolute;display:inline-block;margin:0;padding:0;outline:0}.fg-simple_portfolio .fg-image,.fg-simple_portfolio .fg-item-inner,.fg-simple_portfolio .fg-thumb{display:block;margin:0;padding:0;outline:0}.fg-simple_portfolio .fg-item-inner{position:relative;width:100%;height:100%}.fg-simple_portfolio .fg-thumb{box-sizing:border-box;display:block;margin:0;padding:0;border:none;outline:0;position:relative;overflow:hidden}.fg-simple_portfolio .fg-item.fg-positioned .fg-image{width:100%;height:auto}.fg-simple_portfolio .fg-image{z-index:1}.foogallery.fg-simple_portfolio .fg-item-inner .fg-caption{visibility:visible;opacity:1;font-size:13px;position:relative;display:block;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;text-transform:none;transform:none;transition:none;background-color:transparent;border-style:solid;border-color:transparent}.foogallery.fg-simple_portfolio .fg-item-inner:hover .fg-caption{transform:none;transition:none}.foogallery.fg-simple_portfolio .fg-item-inner .fg-caption-inner{display:block;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;border:none;transform:none;transition:none}.foogallery.fg-simple_portfolio .fg-item-inner .fg-caption-inner:before{display:none}.foogallery.fg-simple_portfolio.fg-caption-hover .fg-item-inner .fg-thumb:before{display:block}.foogallery.fg-simple_portfolio.fg-caption-always .fg-item-inner:hover .fg-caption{visibility:visible;opacity:1}.fg-simple_portfolio .fg-caption-title{text-align:left}.fg-simple_portfolio .fg-caption-desc{text-align:left}.fg-simple_portfolio.fg-dark .fg-caption,.fg-simple_portfolio.fg-light .fg-caption{color:#828282}.fg-simple_portfolio.fg-dark .fg-caption a,.fg-simple_portfolio.fg-light .fg-caption a{color:#828282;border-bottom:1px solid #828282}.fg-simple_portfolio.fg-dark .fg-caption a:hover,.fg-simple_portfolio.fg-light .fg-caption a:hover{border-bottom:none}.fg-simple_portfolio.fg-light .fg-caption-title,.fg-simple_portfolio.fg-light .fg-caption-title a{color:#222}.fg-simple_portfolio.fg-dark .fg-caption-title,.fg-simple_portfolio.fg-dark .fg-caption-title a{color:#fff}.fg-simple_portfolio.fg-light .fg-caption-title a{border-bottom:1px solid #222}.fg-simple_portfolio.fg-dark .fg-caption-title a{border-bottom:1px solid #fff}.fg-simple_portfolio.fg-captions-top .fg-item.fg-positioned .fg-thumb{position:absolute;bottom:0;left:0}.fg-simple_portfolio .fg-caption{border-width:0}.fg-simple_portfolio .fg-caption-title+.fg-caption-desc{margin-top:5px}.fg-simple_portfolio.fg-border-thin .fg-caption{border-width:10px 5px 5px 5px}.fg-simple_portfolio.fg-captions-top.fg-border-thin .fg-caption{border-width:5px 5px 10px 5px}.fg-simple_portfolio.fg-border-medium .fg-caption{border-width:10px 0 0 0}.fg-simple_portfolio.fg-captions-top.fg-border-medium .fg-caption{border-width:0 0 10px 0}.fg-simple_portfolio.fg-border-thick .fg-caption{border-width:15px 0 0 0}.fg-simple_portfolio.fg-captions-top.fg-border-thick .fg-caption{border-width:0 0 15px 0}.fg-simple_portfolio.fg-border-thick .fg-caption-title+.fg-caption-desc{margin-top:10px}.foogallery.fg-preset.fg-polaroid .fg-item{-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transition:-webkit-transform .35s,background-color .65s;transition:transform .35s,background-color .65s}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(2n+1){-webkit-transform:rotate(3deg);transform:rotate(3deg)}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(2n){-webkit-transform:rotate(-3deg);transform:rotate(-3deg)}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(3n){-webkit-transform:rotate(1deg);transform:rotate(1deg)}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(5n){-webkit-transform:rotate(-2deg);transform:rotate(-2deg)}.foogallery.fg-preset.fg-polaroid .fg-item:hover{-webkit-transform:rotate(0);transform:rotate(0)}.foogallery.fg-preset.fg-polaroid .fg-caption{position:relative;width:auto;font-family:"Segoe Print Regular",-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}.foogallery.fg-preset.fg-polaroid .fg-caption-inner,.foogallery.fg-preset.fg-polaroid .fg-caption-title{position:relative;width:auto}.foogallery.fg-preset.fg-polaroid .fg-caption-title{text-align:center}.foogallery.fg-preset.fg-polaroid .fg-caption-desc{display:none}.foogallery.fg-light.fg-preset.fg-polaroid .fg-caption-title,.foogallery.fg-preset.fg-polaroid .fg-caption-title{color:#333}.foogallery.fg-dark.fg-preset.fg-polaroid .fg-caption-title{color:#fff}.foogallery.fg-preset.fg-polaroid .fg-caption{border-style:solid;border-color:transparent;border-width:10px}.foogallery.fg-preset.fg-polaroid .fg-caption-title+.fg-caption-desc{margin-top:5px}.foogallery.fg-preset.fg-polaroid.fg-border-thin .fg-caption{border-width:10px 5px 5px 5px}.foogallery.fg-preset.fg-polaroid.fg-captions-top.fg-border-thin .fg-caption{border-width:5px 5px 10px 5px}.foogallery.fg-preset.fg-polaroid.fg-border-medium .fg-caption{border-width:10px 0 0 0}.foogallery.fg-preset.fg-polaroid.fg-captions-top.fg-border-medium .fg-caption{border-width:0 0 10px 0}.foogallery.fg-preset.fg-polaroid.fg-border-thick .fg-caption{border-width:15px 0 0 0}.foogallery.fg-preset.fg-polaroid.fg-captions-top.fg-border-thick .fg-caption{border-width:0 0 15px 0}.foogallery.fg-preset.fg-polaroid.fg-border-thick .fg-caption-title+.fg-caption-desc{margin-top:10px}.fg-image-viewer{display:block;font-family:'Open Sans','Helvetica Neue',Arial,sans-serif}.fg-image-viewer.fg-left{text-align:left}.fg-image-viewer.fg-center{text-align:center}.fg-image-viewer.fg-right{text-align:right}.fiv-inner{position:relative;display:inline-block;max-width:100%;overflow:hidden;z-index:6}.fiv-inner .fiv-inner-container{position:relative;overflow:hidden;max-width:100%;border-style:solid;border-width:0;border-bottom-width:4px;z-index:5}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb,.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb:active,.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb:hover,.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb:visited{position:relative;display:block;border:none;outline:0;text-decoration:none;box-shadow:none;max-width:100%}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item{position:relative;visibility:visible;opacity:1;border:none;outline:0;text-decoration:none;box-shadow:none;max-width:100%}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb img{display:block;max-width:100%;height:auto;border:none;outline:0;text-decoration:none}.fg-image-viewer .fiv-inner .fiv-ctrls{display:block;text-align:center;font-size:14px;border-style:solid;line-height:34px}.fg-image-viewer .fiv-inner .fiv-ctrls:after{content:'';display:block;clear:both}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-count{display:inline-block;font-weight:400;margin:0}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:none;min-width:80px;position:relative;overflow:hidden;transition:background-color .3s}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:before,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:before{display:block;position:absolute;font-size:24px;line-height:30px;top:0;left:0;width:100%;transform:translateY(0);transition:transform .3s}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:hover:before,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:hover:before{transform:translateY(-100%)}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next span,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev span{display:block;width:100%;transform:translateY(100%);transition:transform .3s}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:hover span,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:hover span{transform:translateY(0)}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev{float:left}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:before{content:'\2190'}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next{float:right}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:before{content:'\2192'}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-count span{margin:0 4px}/*!* Theme - Default (Light) *!*//*!* Theme - Dark *!*/.foogallery.fg-image-viewer.fg-caption-always .fg-item-inner .fg-caption{padding:0;border:none;background:#000;background:-moz-linear-gradient(left,rgba(0,0,0,.8) 0,rgba(0,0,0,.8) 60%,rgba(0,0,0,0) 100%);background:-webkit-linear-gradient(left,rgba(0,0,0,.8) 0,rgba(0,0,0,.8) 60%,rgba(0,0,0,0) 100%);background:linear-gradient(to right,rgba(0,0,0,.8) 0,rgba(0,0,0,.8) 60%,rgba(0,0,0,0) 100%)}.foogallery.fg-image-viewer.fg-caption-always .fg-caption-title{padding:10px 10px 10px 10px}.foogallery.fg-image-viewer.fg-caption-always .fg-caption-desc{padding:10px 10px 10px 10px}.foogallery.fg-image-viewer.fg-caption-always .fg-caption-title+.fg-caption-desc{padding:0 10px 10px 10px}.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-count,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-next,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-prev,.fg-image-viewer.fg-light .fiv-inner .fiv-inner-container{background-color:#fff;color:#333;border-color:#fff}.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-next:hover,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-prev:hover{background-color:#f2f2f2}.fg-image-viewer.fg-light .fiv-next,.fg-image-viewer.fg-light .fiv-prev{box-shadow:inset 0 0 0 1px #ddd}.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-count,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-next,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-prev,.fg-image-viewer.fg-dark .fiv-inner .fiv-inner-container{background-color:#333;color:#fff;border-color:#333}.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-next:hover,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-prev:hover{background-color:#444}.fg-image-viewer.fg-dark .fiv-next,.fg-image-viewer.fg-dark .fiv-prev{box-shadow:inset 0 0 0 1px #222}.foogallery.fg-image-viewer.fg-border-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin .fg-item-inner{border-width:0}.foogallery.fg-image-viewer .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thin .fiv-inner-container{border-width:4px}.foogallery.fg-image-viewer.fg-border-medium .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-medium .fiv-inner-container{border-width:10px}.foogallery.fg-image-viewer.fg-border-thick .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thick .fiv-inner-container{border-width:16px}.foogallery.fg-image-viewer .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-medium .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thick .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thin .fiv-ctrls{border-top-width:1px}.foogallery.fg-image-viewer.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-round-small .fiv-inner{border-radius:5px}.foogallery.fg-image-viewer.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-round-small .fg-item-inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.foogallery.fg-image-viewer.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-round-small .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fiv-prev,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fiv-prev,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-round-medium .fiv-inner{border-radius:10px}.foogallery.fg-image-viewer.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-round-medium .fg-item-inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.foogallery.fg-image-viewer.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-round-medium .fiv-prev{border-radius:5px}.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fiv-prev{border-radius:5px}.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fiv-prev,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-round-large .fiv-inner{border-radius:15px}.foogallery.fg-image-viewer.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-round-large .fg-item-inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.foogallery.fg-image-viewer.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-round-large .fiv-prev{border-radius:11px}.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fiv-prev{border-radius:11px}.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fiv-prev{border-radius:5px}.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-round-full .fiv-inner,.foogallery.fg-image-viewer.fg-round-full .fiv-next,.foogallery.fg-image-viewer.fg-round-full .fiv-prev{border-radius:50%}.foogallery.fg-image-viewer.fg-dark.fg-shadow-large .fg-item-inner,.foogallery.fg-image-viewer.fg-dark.fg-shadow-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-dark.fg-shadow-outline .fg-item-inner,.foogallery.fg-image-viewer.fg-dark.fg-shadow-small .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-large .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-outline .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-small .fg-item-inner{box-shadow:none}.foogallery.fg-image-viewer.fg-light.fg-shadow-outline .fiv-inner{box-shadow:0 0 0 1px #ddd}.foogallery.fg-image-viewer.fg-dark.fg-shadow-outline .fiv-inner{box-shadow:0 0 0 1px #222}.foogallery.fg-image-viewer.fg-dark.fg-shadow-small .fiv-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-small .fiv-inner{box-shadow:0 1px 4px 0 rgba(0,0,0,.5)}.foogallery.fg-image-viewer.fg-dark.fg-shadow-medium .fiv-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-medium .fiv-inner{box-shadow:0 1px 10px 0 rgba(0,0,0,.5)}.foogallery.fg-image-viewer.fg-dark.fg-shadow-large .fiv-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-large .fiv-inner{box-shadow:0 1px 16px 0 rgba(0,0,0,.5)}.foogallery.fg-thumbnail,.foogallery.fg-thumbnail.fg-center{text-align:center}.foogallery.fg-thumbnail.fg-left{text-align:left}.foogallery.fg-thumbnail.fg-right{text-align:right}.foogallery.fg-thumbnail.fg-float-left{float:left;width:auto}.foogallery.fg-thumbnail.fg-float-right{float:right;width:auto}.foogallery.fg-thumbnail .fg-item{display:inline-block;vertical-align:top;max-width:100%}.foogallery.fg-thumbnail .fg-image{max-width:100%}.foogallery.fg-thumbnail .fg-st-hidden{display:none}
|
extensions/default-templates/shared/js/foogallery.js
CHANGED
@@ -6963,6 +6963,8 @@
|
|
6963 |
this.$el = $(element);
|
6964 |
this.options = $.extend(true, {}, _.Justified.defaults, options);
|
6965 |
this._items = [];
|
|
|
|
|
6966 |
},
|
6967 |
init: function(){
|
6968 |
var self = this;
|
@@ -6974,11 +6976,22 @@
|
|
6974 |
}
|
6975 |
}
|
6976 |
$(window).on("resize.justified", {self: self}, self.onWindowResize);
|
|
|
|
|
|
|
6977 |
},
|
6978 |
destroy: function(){
|
|
|
6979 |
$(window).off("resize.justified");
|
6980 |
this.$el.removeAttr("style");
|
6981 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6982 |
parse: function(){
|
6983 |
var self = this, visible = self.$el.is(':visible'),
|
6984 |
$test = $('<div/>', {'class': self.$el.attr('class')}).css({
|
@@ -6989,7 +7002,7 @@
|
|
6989 |
maxWidth: self.getContainerWidth()
|
6990 |
}).appendTo('body');
|
6991 |
self._items = self.$el.find(self.options.itemSelector).removeAttr("style").removeClass("fg-positioned").map(function(i, el){
|
6992 |
-
var $item = $(el), width = 0, height = 0
|
6993 |
if (!visible){
|
6994 |
var $clone = $item.clone();
|
6995 |
$clone.appendTo($test);
|
@@ -6999,12 +7012,11 @@
|
|
6999 |
width = $item.outerWidth();
|
7000 |
height = $item.outerHeight();
|
7001 |
}
|
7002 |
-
ratio = self.options.rowHeight / height;
|
7003 |
|
7004 |
return {
|
7005 |
index: i,
|
7006 |
-
width: width
|
7007 |
-
height:
|
7008 |
top: 0,
|
7009 |
left: 0,
|
7010 |
$item: $item
|
@@ -7013,9 +7025,16 @@
|
|
7013 |
$test.remove();
|
7014 |
return self._items;
|
7015 |
},
|
7016 |
-
|
7017 |
-
|
7018 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7019 |
},
|
7020 |
getContainerWidth: function(){
|
7021 |
var self = this, visible = self.$el.is(':visible');
|
@@ -7033,23 +7052,21 @@
|
|
7033 |
}
|
7034 |
|
7035 |
var self = this,
|
7036 |
-
|
7037 |
-
|
7038 |
-
|
7039 |
-
|
7040 |
-
|
7041 |
-
|
7042 |
-
if (
|
7043 |
-
|
7044 |
-
|
7045 |
-
offsetTop = self.justify(row, containerWidth, offsetTop);
|
7046 |
-
}
|
7047 |
self.render(row);
|
7048 |
-
}
|
7049 |
-
self.$el.height(
|
7050 |
// if our layout caused the container width to get smaller
|
7051 |
// i.e. makes a scrollbar appear then layout again to account for it
|
7052 |
-
if (autoCorrect && self.getContainerWidth() <
|
7053 |
self.layout(false, false);
|
7054 |
}
|
7055 |
},
|
@@ -7070,69 +7087,107 @@
|
|
7070 |
}
|
7071 |
}
|
7072 |
},
|
7073 |
-
|
7074 |
-
var self = this;
|
7075 |
-
switch(self.options.lastRow){
|
7076 |
-
case "hide":
|
7077 |
-
row.visible = false;
|
7078 |
-
break;
|
7079 |
-
case "justify":
|
7080 |
-
offsetTop = self.justify(row, containerWidth, offsetTop);
|
7081 |
-
break;
|
7082 |
-
case "nojustify":
|
7083 |
-
if (row.width / containerWidth > self.options.justifyThreshold){
|
7084 |
-
offsetTop = self.justify(row, containerWidth, offsetTop);
|
7085 |
-
} else {
|
7086 |
-
offsetTop = self.position(row, containerWidth, offsetTop, "left");
|
7087 |
-
}
|
7088 |
-
break;
|
7089 |
-
case "right":
|
7090 |
-
case "center":
|
7091 |
-
case "left":
|
7092 |
-
offsetTop = self.position(row, containerWidth, offsetTop, self.options.lastRow);
|
7093 |
-
break;
|
7094 |
-
default:
|
7095 |
-
offsetTop = self.position(row, containerWidth, offsetTop, "left");
|
7096 |
-
break;
|
7097 |
-
}
|
7098 |
-
return offsetTop;
|
7099 |
-
},
|
7100 |
-
justify: function(row, containerWidth, offsetTop){
|
7101 |
var self = this,
|
7102 |
-
left = 0,
|
7103 |
margins = self.options.margins * (row.items.length - 1),
|
7104 |
-
|
7105 |
|
7106 |
-
|
7107 |
-
row.
|
7108 |
-
row.
|
7109 |
-
row.
|
7110 |
|
7111 |
-
|
7112 |
-
|
7113 |
-
|
7114 |
-
|
7115 |
-
|
7116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7117 |
item.left = left;
|
|
|
|
|
|
|
|
|
|
|
|
|
7118 |
left += item.width;
|
7119 |
}
|
7120 |
-
|
|
|
7121 |
},
|
7122 |
-
position: function(row,
|
7123 |
-
var self = this,
|
7124 |
-
|
7125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7126 |
for (var i = 0, l = row.items.length, item; i < l; i++){
|
|
|
7127 |
item = row.items[i];
|
7128 |
-
item.
|
7129 |
-
|
7130 |
-
|
7131 |
-
|
7132 |
-
|
7133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7134 |
}
|
7135 |
-
return offsetTop + row.height;
|
7136 |
},
|
7137 |
items: function(){
|
7138 |
return $.map(this._items, function(item){
|
@@ -7146,57 +7201,52 @@
|
|
7146 |
};
|
7147 |
});
|
7148 |
},
|
7149 |
-
rows: function(
|
7150 |
var self = this,
|
7151 |
items = self.items(),
|
7152 |
rows = [],
|
7153 |
-
|
7154 |
-
index = -1, offsetTop = 0;
|
7155 |
|
7156 |
-
|
7157 |
-
index += 1;
|
7158 |
-
if (index > 0) offsetTop += self.options.margins;
|
7159 |
var row = {
|
7160 |
-
index: index,
|
7161 |
visible: true,
|
7162 |
-
top: offsetTop,
|
7163 |
width: 0,
|
7164 |
height: self.options.rowHeight,
|
|
|
|
|
7165 |
items: []
|
7166 |
-
}
|
|
|
|
|
|
|
|
|
7167 |
|
7168 |
-
|
7169 |
-
|
7170 |
-
|
7171 |
-
|
7172 |
-
|
7173 |
-
|
7174 |
-
|
7175 |
-
|
7176 |
-
item.width = self.round(item.width * ratio);
|
7177 |
-
item.height = self.round(item.height * ratio);
|
7178 |
-
row.height = item.height;
|
7179 |
-
}
|
7180 |
-
item.top = row.top;
|
7181 |
-
if (i > 0) left += self.options.margins;
|
7182 |
-
item.left = left;
|
7183 |
-
left += item.width;
|
7184 |
-
row.width = tmp;
|
7185 |
-
row.items.push(item);
|
7186 |
-
remove.push(i);
|
7187 |
}
|
7188 |
-
|
7189 |
-
if (
|
7190 |
-
|
7191 |
-
|
7192 |
-
|
7193 |
-
|
7194 |
-
|
7195 |
-
items.splice(remove[j], 1);
|
7196 |
}
|
7197 |
-
|
7198 |
-
|
|
|
|
|
|
|
7199 |
}
|
|
|
|
|
7200 |
return rows;
|
7201 |
},
|
7202 |
onWindowResize: function(e){
|
@@ -7210,7 +7260,8 @@
|
|
7210 |
maxRowHeight: "200%",
|
7211 |
margins: 0,
|
7212 |
lastRow: "center",
|
7213 |
-
justifyThreshold: 0.5
|
|
|
7214 |
};
|
7215 |
|
7216 |
})(
|
@@ -7241,13 +7292,13 @@
|
|
7241 |
self.justified.layout( true );
|
7242 |
},
|
7243 |
onParsedItems: function(event, self, items){
|
7244 |
-
self.justified.layout( true );
|
7245 |
},
|
7246 |
onAppendedItems: function(event, self, items){
|
7247 |
-
self.justified.layout( true );
|
7248 |
},
|
7249 |
onDetachedItems: function(event, self, items){
|
7250 |
-
self.justified.layout( true );
|
7251 |
}
|
7252 |
});
|
7253 |
|
@@ -7496,13 +7547,13 @@
|
|
7496 |
self.portfolio.layout( true );
|
7497 |
},
|
7498 |
onParsedItems: function(event, self, items){
|
7499 |
-
self.portfolio.layout( true );
|
7500 |
},
|
7501 |
onAppendedItems: function(event, self, items){
|
7502 |
-
self.portfolio.layout( true );
|
7503 |
},
|
7504 |
onDetachedItems: function(event, self, items){
|
7505 |
-
self.portfolio.layout( true );
|
7506 |
}
|
7507 |
});
|
7508 |
|
6963 |
this.$el = $(element);
|
6964 |
this.options = $.extend(true, {}, _.Justified.defaults, options);
|
6965 |
this._items = [];
|
6966 |
+
this._lastRefresh = 0;
|
6967 |
+
this._refresh = null;
|
6968 |
},
|
6969 |
init: function(){
|
6970 |
var self = this;
|
6976 |
}
|
6977 |
}
|
6978 |
$(window).on("resize.justified", {self: self}, self.onWindowResize);
|
6979 |
+
this._refresh = setInterval(function(){
|
6980 |
+
self.refresh();
|
6981 |
+
}, self.options.refreshInterval);
|
6982 |
},
|
6983 |
destroy: function(){
|
6984 |
+
if (this._refresh) clearInterval(this._refresh);
|
6985 |
$(window).off("resize.justified");
|
6986 |
this.$el.removeAttr("style");
|
6987 |
},
|
6988 |
+
refresh: function(){
|
6989 |
+
var maxWidth = this.getContainerWidth();
|
6990 |
+
if (maxWidth != this._lastRefresh){
|
6991 |
+
this.layout();
|
6992 |
+
this._lastRefresh = maxWidth;
|
6993 |
+
}
|
6994 |
+
},
|
6995 |
parse: function(){
|
6996 |
var self = this, visible = self.$el.is(':visible'),
|
6997 |
$test = $('<div/>', {'class': self.$el.attr('class')}).css({
|
7002 |
maxWidth: self.getContainerWidth()
|
7003 |
}).appendTo('body');
|
7004 |
self._items = self.$el.find(self.options.itemSelector).removeAttr("style").removeClass("fg-positioned").map(function(i, el){
|
7005 |
+
var $item = $(el), width = 0, height = 0;
|
7006 |
if (!visible){
|
7007 |
var $clone = $item.clone();
|
7008 |
$clone.appendTo($test);
|
7012 |
width = $item.outerWidth();
|
7013 |
height = $item.outerHeight();
|
7014 |
}
|
|
|
7015 |
|
7016 |
return {
|
7017 |
index: i,
|
7018 |
+
width: width,
|
7019 |
+
height: height,
|
7020 |
top: 0,
|
7021 |
left: 0,
|
7022 |
$item: $item
|
7025 |
$test.remove();
|
7026 |
return self._items;
|
7027 |
},
|
7028 |
+
getMaxRowHeight: function() {
|
7029 |
+
var self = this;
|
7030 |
+
if (_is.string(self.options.maxRowHeight)){
|
7031 |
+
if (self.options.maxRowHeight.indexOf('%')){
|
7032 |
+
self.options.maxRowHeight = self.options.rowHeight * (parseInt(self.options.maxRowHeight) / 100);
|
7033 |
+
} else {
|
7034 |
+
self.options.maxRowHeight = parseInt(self.options.maxRowHeight);
|
7035 |
+
}
|
7036 |
+
}
|
7037 |
+
return _is.number(self.options.maxRowHeight) ? self.options.maxRowHeight : self.options.rowHeight;
|
7038 |
},
|
7039 |
getContainerWidth: function(){
|
7040 |
var self = this, visible = self.$el.is(':visible');
|
7052 |
}
|
7053 |
|
7054 |
var self = this,
|
7055 |
+
height = 0,
|
7056 |
+
maxWidth = self.getContainerWidth(),
|
7057 |
+
maxHeight = self.getMaxRowHeight(),
|
7058 |
+
rows = self.rows(maxWidth, maxHeight);
|
7059 |
+
|
7060 |
+
$.each(rows, function(ri, row){
|
7061 |
+
if (!row.visible) return;
|
7062 |
+
if (ri > 0) height += self.options.margins;
|
7063 |
+
height += row.height;
|
|
|
|
|
7064 |
self.render(row);
|
7065 |
+
});
|
7066 |
+
self.$el.height(height);
|
7067 |
// if our layout caused the container width to get smaller
|
7068 |
// i.e. makes a scrollbar appear then layout again to account for it
|
7069 |
+
if (autoCorrect && self.getContainerWidth() < maxWidth){
|
7070 |
self.layout(false, false);
|
7071 |
}
|
7072 |
},
|
7087 |
}
|
7088 |
}
|
7089 |
},
|
7090 |
+
justify: function(row, top, maxWidth, maxHeight){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7091 |
var self = this,
|
|
|
7092 |
margins = self.options.margins * (row.items.length - 1),
|
7093 |
+
max = maxWidth - margins;
|
7094 |
|
7095 |
+
var w_ratio = max / row.width;
|
7096 |
+
row.width = row.width * w_ratio;
|
7097 |
+
row.height = row.height * w_ratio;
|
7098 |
+
row.top = top;
|
7099 |
|
7100 |
+
if (row.height > maxHeight){
|
7101 |
+
row.height = maxHeight;
|
7102 |
+
}
|
7103 |
+
|
7104 |
+
row.left = 0;
|
7105 |
+
if (row.width < max){
|
7106 |
+
// here I'm not sure if I should center, left or right align a row that cannot be displayed at 100% width
|
7107 |
+
row.left = (max - row.width) / 2;
|
7108 |
+
}
|
7109 |
+
row.width += margins;
|
7110 |
+
|
7111 |
+
var left = row.left;
|
7112 |
+
for (var i = 0, l = row.items.length, item; i < l; i++){
|
7113 |
+
if (i > 0) left += self.options.margins;
|
7114 |
+
item = row.items[i];
|
7115 |
item.left = left;
|
7116 |
+
item.top = top;
|
7117 |
+
item.width = item.width * w_ratio;
|
7118 |
+
item.height = item.height * w_ratio;
|
7119 |
+
if (item.height > maxHeight){
|
7120 |
+
item.height = maxHeight;
|
7121 |
+
}
|
7122 |
left += item.width;
|
7123 |
}
|
7124 |
+
|
7125 |
+
return row.height;
|
7126 |
},
|
7127 |
+
position: function(row, top, maxWidth, align){
|
7128 |
+
var self = this,
|
7129 |
+
margins = self.options.margins * (row.items.length - 1),
|
7130 |
+
max = maxWidth - margins;
|
7131 |
+
|
7132 |
+
row.top = top;
|
7133 |
+
row.left = 0;
|
7134 |
+
if (row.width < max){
|
7135 |
+
switch (align){
|
7136 |
+
case "center":
|
7137 |
+
row.left = (max - row.width) / 2;
|
7138 |
+
break;
|
7139 |
+
case "right":
|
7140 |
+
row.left = max - row.width;
|
7141 |
+
break;
|
7142 |
+
}
|
7143 |
+
}
|
7144 |
+
row.width += margins;
|
7145 |
+
|
7146 |
+
var left = row.left;
|
7147 |
for (var i = 0, l = row.items.length, item; i < l; i++){
|
7148 |
+
if (i > 0) left += self.options.margins;
|
7149 |
item = row.items[i];
|
7150 |
+
item.left = left;
|
7151 |
+
item.top = top;
|
7152 |
+
left += item.width;
|
7153 |
+
}
|
7154 |
+
|
7155 |
+
return row.height;
|
7156 |
+
},
|
7157 |
+
lastRow: function(row, top, maxWidth, maxHeight){
|
7158 |
+
var self = this,
|
7159 |
+
margins = self.options.margins * (row.items.length - 1),
|
7160 |
+
max = maxWidth - margins,
|
7161 |
+
threshold = row.width / max > self.options.justifyThreshold;
|
7162 |
+
|
7163 |
+
switch (self.options.lastRow){
|
7164 |
+
case "hide":
|
7165 |
+
if (threshold){
|
7166 |
+
self.justify(row, top, maxWidth, maxHeight);
|
7167 |
+
} else {
|
7168 |
+
row.visible = false;
|
7169 |
+
}
|
7170 |
+
break;
|
7171 |
+
case "justify":
|
7172 |
+
self.justify(row, top, maxWidth, maxHeight);
|
7173 |
+
break;
|
7174 |
+
case "nojustify":
|
7175 |
+
if (threshold){
|
7176 |
+
self.justify(row, top, maxWidth, maxHeight);
|
7177 |
+
} else {
|
7178 |
+
self.position(row, top, maxWidth, "left");
|
7179 |
+
}
|
7180 |
+
break;
|
7181 |
+
case "left":
|
7182 |
+
case "center":
|
7183 |
+
case "right":
|
7184 |
+
if (threshold){
|
7185 |
+
self.justify(row, top, maxWidth, maxHeight);
|
7186 |
+
} else {
|
7187 |
+
self.position(row, top, maxWidth, self.options.lastRow);
|
7188 |
+
}
|
7189 |
+
break;
|
7190 |
}
|
|
|
7191 |
},
|
7192 |
items: function(){
|
7193 |
return $.map(this._items, function(item){
|
7201 |
};
|
7202 |
});
|
7203 |
},
|
7204 |
+
rows: function(maxWidth, maxHeight){
|
7205 |
var self = this,
|
7206 |
items = self.items(),
|
7207 |
rows = [],
|
7208 |
+
index = -1;
|
|
|
7209 |
|
7210 |
+
function create(){
|
|
|
|
|
7211 |
var row = {
|
7212 |
+
index: ++index,
|
7213 |
visible: true,
|
|
|
7214 |
width: 0,
|
7215 |
height: self.options.rowHeight,
|
7216 |
+
top: 0,
|
7217 |
+
left: 0,
|
7218 |
items: []
|
7219 |
+
};
|
7220 |
+
// push the row into the result collection now
|
7221 |
+
rows.push(row);
|
7222 |
+
return row;
|
7223 |
+
}
|
7224 |
|
7225 |
+
var row = create(), top = 0, tmp = 0;
|
7226 |
+
for (var i = 0, il = items.length, item; i < il; i++){
|
7227 |
+
item = items[i];
|
7228 |
+
// first make all the items match the row height
|
7229 |
+
if (item.height != self.options.rowHeight){
|
7230 |
+
var ratio = self.options.rowHeight / item.height;
|
7231 |
+
item.height = item.height * ratio;
|
7232 |
+
item.width = item.width * ratio;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7233 |
}
|
7234 |
+
|
7235 |
+
if (tmp + item.width > maxWidth && i > 0){
|
7236 |
+
// adding this item to the row would exceed the max width
|
7237 |
+
if (rows.length > 1) top += self.options.margins;
|
7238 |
+
top += self.justify(row, top, maxWidth, maxHeight); // first justify the current row
|
7239 |
+
row = create(); // then make the new one
|
7240 |
+
tmp = 0;
|
|
|
7241 |
}
|
7242 |
+
|
7243 |
+
if (row.items.length > 0) tmp += self.options.margins;
|
7244 |
+
tmp += item.width;
|
7245 |
+
row.width += item.width;
|
7246 |
+
row.items.push(item);
|
7247 |
}
|
7248 |
+
if (rows.length > 1) top += self.options.margins;
|
7249 |
+
self.lastRow(row, top, maxWidth, maxHeight);
|
7250 |
return rows;
|
7251 |
},
|
7252 |
onWindowResize: function(e){
|
7260 |
maxRowHeight: "200%",
|
7261 |
margins: 0,
|
7262 |
lastRow: "center",
|
7263 |
+
justifyThreshold: 0.5,
|
7264 |
+
refreshInterval: 250
|
7265 |
};
|
7266 |
|
7267 |
})(
|
7292 |
self.justified.layout( true );
|
7293 |
},
|
7294 |
onParsedItems: function(event, self, items){
|
7295 |
+
if (self.initialized) self.justified.layout( true );
|
7296 |
},
|
7297 |
onAppendedItems: function(event, self, items){
|
7298 |
+
if (self.initialized) self.justified.layout( true );
|
7299 |
},
|
7300 |
onDetachedItems: function(event, self, items){
|
7301 |
+
if (self.initialized) self.justified.layout( true );
|
7302 |
}
|
7303 |
});
|
7304 |
|
7547 |
self.portfolio.layout( true );
|
7548 |
},
|
7549 |
onParsedItems: function(event, self, items){
|
7550 |
+
if (self.initialized) self.portfolio.layout( true );
|
7551 |
},
|
7552 |
onAppendedItems: function(event, self, items){
|
7553 |
+
if (self.initialized) self.portfolio.layout( true );
|
7554 |
},
|
7555 |
onDetachedItems: function(event, self, items){
|
7556 |
+
if (self.initialized) self.portfolio.layout( true );
|
7557 |
}
|
7558 |
});
|
7559 |
|
extensions/default-templates/shared/js/foogallery.min.js
CHANGED
@@ -1,10 +1,11 @@
|
|
1 |
/*
|
2 |
* FooGallery - The Most Intuitive and Extensible Gallery Creation and Management Tool Ever Created for WordPress
|
3 |
-
* @version 1.0.
|
4 |
* @link
|
5 |
* @copyright Steven Usher & Brad Vincent 2015
|
6 |
* @license Released under the GPLv3 license.
|
7 |
*/
|
8 |
|
9 |
!function(a,b){b.$=a}(jQuery,window.FooGallery=window.FooGallery||{}),function(a){if(!a)return void console.warn("jQuery must be included in the page prior to the FooGallery.utils library.");var b={$:a,version:"0.0.8"};b.versionCompare=function(a,b){function c(a){for(var b=a.split("."),c=0,d=b.length;c<d;c++)b[c]=parseInt(b[c]),isNaN(b[c])&&(b[c]=0);return b}if(!/[\d.]/.test(a)||!/[\d.]/.test(b))return NaN;for(var d=c(a),e=c(b);d.length<e.length;)d.push(0);for(;e.length<d.length;)e.push(0);for(var f=0;f<d.length;++f){if(e.length==f)return 1;if(d[f]!=e[f])return d[f]>e[f]?1:-1}return d.length!=e.length?-1:0},!function(){try{return!!window.FooGallery.utils}catch(a){return!1}}()?window.FooGallery.utils=b:b.versionCompare(b.version,window.FooGallery.utils.version)>0?(console.warn("An older version of FooGallery.utils ("+window.FooGallery.utils.version+") already exists in the page, version "+b.version+" will override it."),window.FooGallery.utils=b):console.warn("A newer version of FooGallery.utils ("+window.FooGallery.utils.version+") already exists in the page, version "+b.version+" will not register itself.")}(jQuery),function(a,b){"0.0.8"===b.version&&(b.is={},b.is.array=function(a){return"[object Array]"===Object.prototype.toString.call(a)},b.is.boolean=function(a){return"[object Boolean]"===Object.prototype.toString.call(a)},b.is.element=function(a){return"object"==typeof HTMLElement?a instanceof HTMLElement:!!a&&"object"==typeof a&&null!==a&&1===a.nodeType&&"string"==typeof a.nodeName},b.is.empty=function(a){if(b.is.undef(a)||null===a)return!0;if(b.is.number(a)&&0==a)return!0;if(b.is.boolean(a)&&!1===a)return!0;if(b.is.string(a)&&0===a.length)return!0;if(b.is.array(a)&&0===a.length)return!0;if(b.is.jq(a)&&0===a.length)return!0;if(b.is.hash(a)){for(var c in a)if(a.hasOwnProperty(c))return!1;return!0}return!1},b.is.error=function(a){return"[object Error]"===Object.prototype.toString.call(a)},b.is.fn=function(a){return a===window.alert||"[object Function]"===Object.prototype.toString.call(a)},b.is.hash=function(a){return b.is.object(a)&&a.constructor===Object&&!a.nodeType&&!a.setInterval},b.is.jq=function(c){return!b.is.undef(a)&&c instanceof a},b.is.number=function(a){return"[object Number]"===Object.prototype.toString.call(a)&&!isNaN(a)},b.is.object=function(a){return"[object Object]"===Object.prototype.toString.call(a)&&!b.is.undef(a)&&null!==a},b.is.promise=function(a){return b.is.object(a)&&b.is.fn(a.then)&&b.is.fn(a.promise)},b.is.size=function(a){return!!(b.is.string(a)&&!b.is.empty(a)||b.is.number(a))&&/^(auto|none|(?:[\d\.]*)+?(?:%|px|mm|q|cm|in|pt|pc|em|ex|ch|rem|vh|vw|vmin|vmax)?)$/.test(a)},b.is.string=function(a){return"[object String]"===Object.prototype.toString.call(a)},b.is.undef=function(a){return void 0===a})}(FooGallery.utils.$,FooGallery.utils),function(a,b,c){if("0.0.8"===b.version){b.fn={};var d=Function.prototype.toString;b.fn.CONTAINS_SUPER=/xyz/.test(d.call(function(){xyz}))?/\b_super\b/:/.*/,b.fn.addOrOverride=function(a,e,f){if(c.object(a)&&c.string(e)&&!c.empty(e)&&c.fn(f)){var g=a[e],h=c.fn(g)&&b.fn.CONTAINS_SUPER.test(d.call(f));a[e]=h?function(a,b){return function(){var c=this._super;this._super=a;var d=b.apply(this,arguments);return this._super=c,d}}(g,f):f}},b.fn.apply=function(a,b){function d(){return a.apply(this,b)}return b=c.array(b)?b:[],d.prototype=a.prototype,new d},b.fn.arg2arr=function(a){return Array.prototype.slice.call(a)},b.fn.check=function(d,e,f,g){function h(a){return function(){return a.apply(d,arguments)}}return f=c.fn(f)?f:a.noop,d=c.object(d)?d:window,e=c.string(e)?b.fn.fetch(e,g):e,h(c.fn(e)?e:f)},b.fn.fetch=function(b,d){return!c.string(b)||c.empty(b)?null:(d=c.object(d)?d:window,a.each(b.split("."),function(a,b){if(!d[b])return!1;d=d[b]}),c.fn(d)?d:null)},b.fn.enqueue=function(d,e,f,g){function h(a,b){try{return n.push(a),b.apply(a,i)}catch(a){return j.reject(a,n),j}}var i=b.fn.arg2arr(arguments),j=a.Deferred(),k=a.Deferred(),l=k.promise(),m=[],n=[],o=!0;return d=i.shift(),e=i.shift(),a.each(d,function(a,d){c.fn(d[e])&&(l=l.then(function(){if(!o){var a=b.fn.arg2arr(arguments);m.push(a)}return o=!1,h(d,d[e])}))}),l.then(function(){if(!o){var a=b.fn.arg2arr(arguments);m.push(a)}o=!1,j.resolve(m)}),l.fail(function(){var a=b.fn.arg2arr(arguments);a.push(n),j.reject.apply(j,a)}),k.resolve(),j.promise()},b.fn.when=function(b){if(!c.array(b)||c.empty(b))return a.when();for(var d=a.Deferred(),e=[],f=b.length,g=0;g<b.length;g++)b[g].then(function(a){e.push(a)}).always(function(){--f||d.resolve(e)});return d.promise()},b.fn.rejectWith=function(c,d){var e=a.Deferred(),f=b.fn.arg2arr(arguments);return e.reject.apply(e,f).promise()},b.fn.resolveWith=function(c,d){var e=a.Deferred(),f=b.fn.arg2arr(arguments);return e.resolve.apply(e,f).promise()},b.fn.resolved=a.Deferred().resolve().promise(),b.fn.rejected=a.Deferred().reject().promise()}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b){if("0.0.8"===a.version){a.url={};var c=document.createElement("a");a.url.parts=function(a){return c.href=a,{hash:c.hash,host:c.host,hostname:c.hostname,href:c.href,origin:c.origin,pathname:c.pathname,port:c.port,protocol:c.protocol,search:c.search}},a.url.full=function(a){return!b.string(a)||b.empty(a)?null:(c.href=a,c.href)},a.url.param=function(a,c,d){if(!b.string(a)||!b.string(c)||b.empty(c))return a;var e,f,g,h;return b.undef(d)?(e=new RegExp("[?|&]"+c+"=([^&;]+?)(&|#|;|$)"),f=e.exec(a)||[,""],g=f[1].replace(/\+/g,"%20"),b.string(g)&&!b.empty(g)?decodeURIComponent(g):null):(""===d||null===d?(e=new RegExp("^([^#]*?)(([^#]*)&)?"+c+"(=[^&#]*)?(&|#|$)"),g=a.replace(e,"$1$3$5").replace(/^([^#]*)((\?)&|\?(#|$))/,"$1$3$4")):(e=new RegExp("([?&])"+c+"[^&]*"),h=c+"="+encodeURIComponent(d),(g=a.replace(e,"$1"+h))!==a||e.test(g)||(g+=(-1!==g.indexOf("?")?"&":"?")+h)),g)}}}(FooGallery.utils,FooGallery.utils.is),function(a,b,c){"0.0.8"===a.version&&(a.str={},a.str.camel=function(a){return b.empty(a)?a:a.toUpperCase()===a?a.toLowerCase():a.replace(/^([A-Z])|[-\s_]+(\w)/g,function(a,c,d){return b.string(d)?d.toUpperCase():c.toLowerCase()})},a.str.contains=function(a,c,d){return!(!b.string(a)||b.empty(a)||!b.string(c)||b.empty(c))&&(c.length<=a.length&&-1!==(d?a.toUpperCase().indexOf(c.toUpperCase()):a.indexOf(c)))},a.str.containsWord=function(a,c,d){if(!b.string(a)||b.empty(a)||!b.string(c)||b.empty(c)||a.length<c.length)return!1;for(var e=a.split(/\W/),f=0,g=e.length;f<g;f++)if(d?e[f].toUpperCase()==c.toUpperCase():e[f]==c)return!0;return!1},a.str.endsWith=function(a,c){return!b.string(a)||b.empty(a)||!b.string(c)||b.empty(c)?a==c:a.slice(a.length-c.length)==c},a.str.escapeRegExp=function(a){return b.empty(a)?a:a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},a.str.fnv1a=function(a){if(!b.string(a)||b.empty(a))return null;var c,d,e=2166136261;for(c=0,d=a.length;c<d;c++)e^=a.charCodeAt(c),e+=(e<<1)+(e<<4)+(e<<7)+(e<<8)+(e<<24);return e>>>0},a.str.from=function(c,d){return!b.string(c)||b.empty(c)||!b.string(d)||b.empty(d)?null:a.str.contains(c,d)?c.substring(c.indexOf(d)+d.length):null},a.str.join=function(d,e,f){if(!b.string(d)||!b.string(e))return null;var g=c.arg2arr(arguments);d=g.shift();var h,i,j=g.shift();for(h=0,i=g.length;h<i;h++)e=g[h],b.empty(e)||(a.str.endsWith(j,d)&&(j=j.slice(0,j.length-d.length)),a.str.startsWith(e,d)&&(e=e.slice(d.length)),j+=d+e);return j},a.str.startsWith=function(a,c){return!b.empty(a)&&!b.empty(c)&&a.slice(0,c.length)==c},a.str.until=function(c,d){return b.empty(c)||b.empty(d)?c:a.str.contains(c,d)?c.substring(0,c.indexOf(d)):c},a.str.format=function(a,d,e){var f=c.arg2arr(arguments);if(a=f.shift(),b.empty(a)||b.empty(f))return a;1===f.length&&(b.array(f[0])||b.object(f[0]))&&(f=f[0]);for(var g in f)a=a.replace(new RegExp("\\{"+g+"\\}","gi"),f[g]);return a})}(FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c,d,e){if("0.0.8"===b.version){b.obj={};var f=function(){};b.obj.create=function(a){if(!c.object(a))throw TypeError("Argument must be an object");f.prototype=a;var b=new f;return f.prototype=null,b},b.obj.extend=function(e,f,g){e=c.object(e)?e:{};var h=d.arg2arr(arguments);return h.shift(),a.each(h,function(a,c){b.obj.merge(e,c)}),e},b.obj.merge=function(a,d){a=c.hash(a)?a:{},d=c.hash(d)?d:{};for(var e in d)d.hasOwnProperty(e)&&(c.hash(d[e])?(a[e]=c.hash(a[e])?a[e]:{},b.obj.merge(a[e],d[e])):c.array(d[e])?a[e]=d[e].slice():a[e]=d[e]);return a},b.obj.mergeValid=function(d,e,f,g){if(!c.hash(f)||!c.hash(e))return d;e=c.hash(e)?e:{},g=c.hash(g)?g:{};var h,i,j;for(h in e)e.hasOwnProperty(h)&&c.fn(e[h])&&(i=c.array(g[h])?g[h]:c.string(g[h])?[g[h]]:[h],a.each(i,function(a,g){if(j=b.obj.prop(f,g),!c.undef(j))return e[h](j)?(b.obj.prop(d,h,j),!1):void 0}));return d},b.obj.prop=function(b,d,f){if(c.object(b)&&!c.empty(d)){var g,h;if(c.undef(f))return e.contains(d,".")?(g=d.split("."),h=g.length-1,a.each(g,function(a,d){if(a===h)f=b[d];else{if(!c.hash(b[d]))return!1;b=b[d]}})):c.undef(b[d])||(f=b[d]),f;e.contains(d,".")?(g=d.split("."),h=g.length-1,a.each(g,function(a,d){a===h?b[d]=f:b=c.hash(b[d])?b[d]:b[d]={}})):c.undef(b[d])||(b[d]=f)}}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.str),function(a,b,c){if("0.0.8"===b.version){b.ready=function(a){function c(){try{a.call(window,b.$)}catch(a){console.error(a)}}(Function("/*@cc_on return true@*/")()?"complete"===document.readyState:"loading"!==document.readyState)?c():document.addEventListener("DOMContentLoaded",c,!1)};var d=0;b.uniqueId=function(a,b){var e=a.attr("id");return c.empty(e)&&(b=c.string(b)&&!c.empty(b)?b:"uid-",e=b+ ++d,a.attr("id",e).data("__uniqueId__",!0)),e},b.removeUniqueId=function(a){a.data("__uniqueId__")&&a.removeAttr("id").removeData("__uniqueId__")}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c){if("0.0.8"===b.version){b.transition={};var d=document.createElement("div");b.transition.supported=function(a){var b=a.style;return c.string(b.transition)||c.string(b.WebkitTransition)||c.string(b.MozTransition)||c.string(b.msTransition)||c.string(b.OTransition)}(d),b.transition.end=function(a){var b=a.style;return c.string(b.transition)?"transitionend":c.string(b.WebkitTransition)?"webkitTransitionEnd":c.string(b.MozTransition)?"transitionend":c.string(b.msTransition)?"msTransitionEnd":c.string(b.OTransition)?"oTransitionEnd":null}(d),b.transition.duration=function(a,b){if(b=c.number(b)?b:0,!c.jq(a))return b;var d=a.css("transition-duration");if(/^([\d\.]*)+?(ms|s)$/i.test(d)){var e=d.match(/^([\d\.]*)+?(ms|s)$/i),f=parseFloat(e[1]);return"s"===e[2].toLowerCase()&&(f*=1e3),f}return b},b.transition.start=function(d,e,f,g){var h=a.Deferred();if(d=d.first(),b.transition.supported){var i=d.data("transition_safety");c.hash(i)&&c.number(i.timer)&&(clearTimeout(i.timer),d.removeData("transition_safety").off(b.transition.end+".utils"),i.deferred.reject()),g=c.number(g)?g:b.transition.duration(d)+50,i={deferred:h,timer:setTimeout(function(){d.removeData("transition_safety").off(b.transition.end+".utils"),h.resolve()},g)},d.data("transition_safety",i),d.on(b.transition.end+".utils",function(a){d.is(a.target)&&(clearTimeout(i.timer),d.removeData("transition_safety").off(b.transition.end+".utils"),h.resolve())})}return setTimeout(function(){c.fn(e)?e.apply(d.get(0),[d]):d.toggleClass(e,f),b.transition.supported||h.resolve()},20),h.promise()}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d,e){"0.0.8"===b.version&&(b.Class=function(){},b.Class.extend=function(a){function f(){if(!c.fn(this.construct))throw new SyntaxError('FooGallery.utils.Class objects must be constructed with the "new" keyword.');this.construct.apply(this,arguments)}a=c.hash(a)?a:{};var g=d.create(this.prototype);for(var h in a)a.hasOwnProperty(h)&&e.addOrOverride(g,h,a[h]);return g.construct=c.fn(g.construct)?g.construct:function(){},f.prototype=g,f.prototype.constructor=c.fn(g.__ctor__)?g.__ctor__:f,f.extend=b.Class.extend,f.override=b.Class.override,f},b.Class.override=function(a,b){e.addOrOverride(this.prototype,a,b)})}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.obj,FooGallery.utils.fn),function(a,b,c){if("0.0.8"===b.version){b.Bounds=b.Class.extend({construct:function(){var a=this;a.top=0,a.right=0,a.bottom=0,a.left=0,a.width=0,a.height=0},inflate:function(a){var b=this;return c.number(a)&&(b.top-=a,b.right+=a,b.bottom+=a,b.left-=a,b.width+=2*a,b.height+=2*a),b},intersects:function(a){var b=this;return b.left<=a.right&&a.left<=b.right&&b.top<=a.bottom&&a.top<=b.bottom}});var d;b.getViewportBounds=function(c){d||(d=a(window));var e=new b.Bounds;return e.top=d.scrollTop(),e.left=d.scrollLeft(),e.width=d.width(),e.height=d.height(),e.right=e.left+e.width,e.bottom=e.top+e.height,e.inflate(c),e},b.getElementBounds=function(d){c.jq(d)||(d=a(d));var e=new b.Bounds;if(0!==d.length){var f=d.offset();e.top=f.top,e.left=f.left,e.width=d.width(),e.height=d.height()}return e.right=e.left+e.width,e.bottom=e.top+e.height,e}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){"0.0.8"===b.version&&(b.Factory=b.Class.extend({construct:function(){this.registered={}},contains:function(a){return!c.undef(this.registered[a])},load:function(b,e,f){var g,h,i=this,j=d.arg2arr(arguments),k=[],l=[];b=j.shift()||{};for(g in i.registered)if(i.registered.hasOwnProperty(g)){var m=i.registered[g];b.hasOwnProperty(g)&&(h=b[g],c.string(h)&&(h=d.fetch(b[g])),c.fn(h)&&(m={name:g,klass:h,priority:i.registered[g].priority})),k.push(m)}for(g in b)b.hasOwnProperty(g)&&!i.registered.hasOwnProperty(g)&&(h=b[g],c.string(h)&&(h=d.fetch(b[g])),c.fn(h)&&k.push({name:g,klass:h,priority:0}));return k.sort(function(a,b){return b.priority-a.priority}),a.each(k,function(a,b){c.fn(b.klass)&&l.push(d.apply(b.klass,j))}),l},make:function(a,b,e){var f,g=this,h=d.arg2arr(arguments);return a=h.shift(),f=g.registered[a],c.hash(f)&&c.fn(f.klass)?d.apply(f.klass,h):null},names:function(b){b=!!c.boolean(b)&&b;var d,e=[];if(b){var f=[];for(d in this.registered)this.registered.hasOwnProperty(d)&&f.push(this.registered[d]);f.sort(function(a,b){return b.priority-a.priority}),a.each(f,function(a,b){e.push(b.name)})}else for(d in this.registered)this.registered.hasOwnProperty(d)&&e.push(d);return e},register:function(a,b,d){if(!c.string(a)||c.empty(a)||!c.fn(b))return!1;d=c.number(d)?d:0;var e=this.registered[a];return this.registered[a]={name:a,klass:b,priority:c.undef(e)?d:e.priority},!0}}))}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c){if("0.0.8"===a.version){var d=!1;try{d=!!window.localStorage}catch(a){d=!1}a.Debugger=a.Class.extend({construct:function(a){this.key=a,this.enabled=!!d&&!!localStorage.getItem(this.key)},enable:function(){d&&(this.enabled=!0,localStorage.setItem(this.key,this.enabled))},disable:function(){d&&(this.enabled=!1,localStorage.removeItem(this.key))},log:function(a,c){this.enabled&&console.log.apply(console,b.arg2arr(arguments))},logf:function(a,d,e){if(this.enabled){var f=b.arg2arr(arguments);a=f.shift(),d=f.shift(),f.unshift(c.format(a,d)),this.log.apply(this,f)}}})}}(FooGallery.utils,FooGallery.utils.fn,FooGallery.utils.str),function(a,b,c){"0.0.8"===b.version&&(b.Throttle=b.Class.extend({construct:function(a){this.id=null,this.active=!1,this.idle=c.number(a)?a:0},limit:function(a){if(c.fn(a)){this.clear();var b=this;this.active=!0,this.id=setTimeout(function(){b.active=!1,b.id=null,a()},this.idle)}},clear:function(){c.number(this.id)&&(clearTimeout(this.id),this.active=!1,this.id=null)}}))}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d,e){b.debug=new c.Debugger("__FooGallery__"),c.selectify=function(b){if(d.empty(b))return null;if(d.hash(b)){var e,f={};for(var g in b)b.hasOwnProperty(g)&&(e=c.selectify(b[g]))&&(f[g]=e);return f}return d.string(b)||d.array(b)?(d.string(b)&&(b=[b]),a.map(b,function(a){return d.string(a)?"."+a.split(/\s/g).join("."):null}).join(",")):null},b.emptyImage="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",b.dataTemplate="__FooGallery__",b.dataItem="__FooGalleryItem__",b.init=function(a,c){return b.template.make(a,c).initialize()},b.initAll=function(c){return e.when(a(".foogallery").map(function(a,d){return b.init(c,d)}).get())},b.parseSrc=function(b,c,e,f,g,h){if(!d.string(b))return null;if(!d.string(f))return b;var i=a.map(f.replace(/(\s[\d.]+[whx]),/g,"$1 @,@ ").split(" @,@ "),function(a){return{url:/^\s*(\S*)/.exec(a)[1],w:parseFloat((/\S\s+(\d+)w/.exec(a)||[0,1/0])[1]),h:parseFloat((/\S\s+(\d+)h/.exec(a)||[0,1/0])[1]),x:parseFloat((/\S\s+([\d.]+)x/.exec(a)||[0,1])[1])}});if(!i.length)return b;i.unshift({url:b,w:i[0].w!==1/0&&i[0].h===1/0?c:1/0,h:i[0].h!==1/0&&i[0].w===1/0?e:1/0,x:1});var j,k=window.devicePixelRatio||1,l={w:g*k,h:h*k,x:k};for(j in l)l.hasOwnProperty(j)&&(i=a.grep(i,function(a,b){return function(c){return c[a]>=l[a]||c[a]===b}}(j,Math.max.apply(null,a.map(i,function(a){return a[j]})))));for(j in l)l.hasOwnProperty(j)&&(i=a.grep(i,function(a,b){return function(c){return c[a]===b}}(j,Math.min.apply(null,a.map(i,function(a){return a[j]})))));return i[0].url},a.fn.foogallery=function(c,e){return this.each(function(f,g){if(d.string(c)){var h=a.data(g,b.dataTemplate);if(h instanceof b.Template)switch(c){case"layout":return void h.layout();case"destroy":return void h.destroy()}}else b.template.make(c,g).initialize().then(function(a){d.fn(e)&&e(a)})})}}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c,d,e,f){b.TemplateFactory=c.Factory.extend({construct:function(){this.registered={}},register:function(a,b,c,e,f,g){var h=this,i=h._super(a,b,g);if(i){var j=h.registered;j[a].opt=d.hash(c)?c:{},j[a].cls=d.hash(e)?e:{},j[a].il8n=d.hash(f)?f:{}}return i},make:function(b,c){c=d.jq(c)?c:a(c),b=f.extend({},b,c.data("foogallery"));var e=this,g=e.type(b,c);return e.contains(g)?(b=e.options(g,b),e._super(g,b,c)):null},type:function(b,e){e=d.jq(e)?e:a(e);var f=this,g=d.hash(b)&&d.hash(b)&&d.string(b.type)&&f.contains(b.type)?b.type:"core";if("core"===g&&e.length>0)for(var h=f.registered,i=f.names(!0),j=0,k=i.length;j<k;j++)if(h.hasOwnProperty(i[j])){var l=i[j],m=h[l].cls;if(d.string(m.container)){var n=c.selectify(m.container);if(e.is(n)){g=i[j];break}}}return g},configure:function(a,b,c,d){var e=this;if(e.contains(a)){var g=e.registered;f.extend(g[a].opt,b),f.extend(g[a].cls,c),f.extend(g[a].il8n,d)}},options:function(a,c){c=f.extend({type:a},c);var e=this,g=e.registered,h=g.core.opt,i=g.core.cls,j=g.core.il8n;return d.hash(c.cls)||(c.cls={}),d.hash(c.il8n)||(c.il8n={}),d.undef(b.filtering)||(c=b.filtering.merge(c)),d.undef(b.paging)||(c=b.paging.merge(c)),"core"!==a&&e.contains(a)?(c=f.extend({},h,g[a].opt,c),c.cls=f.extend({},i,g[a].cls,c.cls),c.il8n=f.extend({},j,g[a].il8n,c.il8n)):(c=f.extend({},h,c),c.cls=f.extend({},i,c.cls),c.il8n=f.extend({},j,c.il8n)),c}}),b.template=new b.TemplateFactory}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d,e){a.PagingFactory=b.Factory.extend({construct:function(){this.registered={}},register:function(a,b,d,e,f,g,h){var i=this,j=i._super(a,b,h);if(j){var k=i.registered;k[a].ctrl=c.fn(d)?d:null,k[a].opt=c.hash(e)?e:{},k[a].cls=c.hash(f)?f:{},k[a].il8n=c.hash(g)?g:{}}return j},type:function(a){var b,d=this;return c.hash(a)&&c.hash(b=a.paging)&&c.string(b.type)&&d.contains(b.type)?b.type:null},merge:function(a){a=e.extend({},a);var b=this,d=b.type(a),f=b.registered,g=f.default.opt,h=f.default.cls,i=f.default.il8n,j=c.hash(a.paging)?a.paging:{},k=c.hash(a.cls)&&c.hash(a.cls.paging)?e.extend({},a.cls.paging):{},l=c.hash(a.il8n)&&c.hash(a.il8n.paging)?e.extend({},a.il8n.paging):{};return c.hash(a.cls)||(a.cls={}),c.hash(a.il8n)||(a.il8n={}),"default"!==d&&b.contains(d)?(a.paging=e.extend({},g,f[d].opt,j,{type:d}),a.cls=e.extend(a.cls,{paging:h},{paging:f[d].cls},{paging:k}),a.il8n=e.extend(a.il8n,{paging:i},{paging:f[d].il8n},{paging:l})):(a.paging=e.extend({},g,j,{type:d}),a.cls=e.extend(a.cls,{paging:h},{paging:k}),a.il8n=e.extend(a.il8n,{paging:i},{paging:l})),a},configure:function(a,b,c,d){var f=this;if(f.contains(a)){var g=f.registered;e.extend(g[a].opt,b),e.extend(g[a].cls,c),e.extend(g[a].il8n,d)}},hasCtrl:function(a){var b=this,d=b.registered[a];return c.hash(d)&&c.fn(d.ctrl)},makeCtrl:function(a,b,d,e){var f=this,g=f.registered[a];return c.hash(g)&&c.fn(g.ctrl)?new g.ctrl(b,d,e):null}}),a.paging=new a.PagingFactory}(FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d,e,f){var g=0;b.Template=c.Class.extend({construct:function(e,f){var h=this;h.namespace=".foogallery-"+ ++g,h.$el=d.jq(f)?f:a(f),h.opt=e,h.template=e.template,h.id=h.$el.prop("id")||e.id,h.cls=e.cls,h.il8n=e.il8n,h.sel=c.selectify(h.cls),h.items=b.components.make("items",h),h.pages=d.undef(b.paging)?null:b.paging.make(e.paging.type,h),h.filter=d.undef(b.filtering)?null:b.filtering.make(e.filtering.type,h),h.state=b.components.make("state",h),h._initialize=null,h.initializing=!1,h.initialized=!1,h.destroying=!1,h.destroyed=!1,h._undo={classes:"",style:"",create:!1,children:!1}},initialize:function(f){var g=this;return d.promise(g._initialize)?g._initialize:(f=d.jq(f)?f:a(f),g._initialize=a.Deferred(function(h){if(g.initializing=!0,0===f.length&&0===g.$el.parent().length)return void h.reject("A parent element is required.");0===g.$el.length&&(g.$el=g.create(),g._undo.create=!0),f.length>0&&g.$el.appendTo(f);var i,j=a.Deferred(),k=j.promise();g.$el.length>0&&(i=g.$el.data(b.dataTemplate))instanceof b.Template?k=k.then(function(){return i.destroy().then(function(){g.$el.data(b.dataTemplate,g)})}):g.$el.data(b.dataTemplate,g),k.then(function(){if(g.destroying)return e.rejectWith("destroy in progress");d.empty(g.opt.on)||g.$el.on(g.opt.on),g._undo.classes=g.$el.attr("class"),g._undo.style=g.$el.attr("style"),g.$el.is(g.sel.container)||g.$el.addClass(g.cls.container);var a=c.selectify(g.opt.classes);return null==a||g.$el.is(a)||g.$el.addClass(g.opt.classes),0==g.$el.children().length&&(g.$el.append(g.createChildren()),g._undo.children=!0),g.raise("pre-init").isDefaultPrevented()?e.rejectWith("pre-init default prevented"):void 0}).then(function(){return g.destroying?e.rejectWith("destroy in progress"):g.opt.delay<=0?e.resolved:a.Deferred(function(a){g._delay=setTimeout(function(){g._delay=null,a.resolve()},g.opt.delay)}).promise()}).then(function(){return g.destroying?e.rejectWith("destroy in progress"):g.raise("init").isDefaultPrevented()?e.rejectWith("init default prevented"):g.items.fetch()}).then(function(){if(g.destroying)return e.rejectWith("destroy in progress");if(g.raise("post-init").isDefaultPrevented())return e.rejectWith("post-init default prevented");var b=g.state.parse();g.state.set(d.empty(b)?g.state.initial():b),a(window).on("scroll"+g.namespace,{self:g},g.throttle(g.onWindowScroll,g.opt.throttle)).on("popstate"+g.namespace,{self:g},g.onWindowPopState)}).then(function(){return g.destroying?e.rejectWith("destroy in progress"):(g.raise("first-load"),g.loadAvailable())}).then(function(){if(g.destroying)return e.rejectWith("destroy in progress");g.initializing=!1,g.initialized=!0,g._check(200),g._check(500),g._check(1e3),g._check(2e3),g._check(5e3),g.raise("ready"),h.resolve(g)}).fail(function(a){h.reject(a)}),j.resolve()}).promise().fail(function(a){console.log("initialize failed",g,a),g.destroy()}))},create:function(){var b=this;return a("<div/>",{id:b.id,class:b.cls.container}).addClass(b.opt.classes)},createChildren:function(){return a()},destroy:function(){var b=this;return b.destroyed?e.resolved:(b.destroying=!0,a.Deferred(function(a){b.initializing&&d.promise(b._initialize)?b._initialize.always(function(){b.destroying=!1,b._destroy(),a.resolve()}):(b.destroying=!1,b._destroy(),a.resolve())}).promise())},_destroy:function(){var c=this;c.destroyed||(c.raise("destroy"),a(window).off(c.namespace),c.state.destroy(),c.filter&&c.filter.destroy(),c.pages&&c.pages.destroy(),c.items.destroy(),d.empty(c.opt.on)||c.$el.off(c.opt.on),c.raise("destroyed"),c.$el.removeData(b.dataTemplate),d.empty(c._undo.classes)?c.$el.removeAttr("class"):c.$el.attr("class",c._undo.classes),d.empty(c._undo.style)?c.$el.removeAttr("style"):c.$el.attr("style",c._undo.style),c._undo.children&&c.$el.empty(),c._undo.create&&c.$el.remove(),c.$el=c.state=c.items=c.pages=null,c.destroyed=!0,c.initializing=!1,c.initialized=!1)},getAvailable:function(){return this.pages?this.pages.available():this.items.available()},loadAvailable:function(){return this.items.load(this.getAvailable())},_check:function(a){a=d.number(a)?a:0;var b=this;setTimeout(function(){!b.initialized||b.destroying&&b.destroyed||b.loadAvailable()},a)},raise:function(c,e){if(!d.string(c)||d.empty(c))return null;e=d.array(e)?e:[];var g=this,h=c.split(".")[0],i=f.camel("on-"+h),j=a.Event(h+".foogallery");return e.unshift(g),g.$el.trigger(j,e),b.debug.logf("{id}|{name}:",{id:g.id,name:h},e),d.fn(g[i])&&(e.unshift(j),g[i].apply(g.$el.get(0),e)),j},layout:function(){var a=this;null!==a._initialize&&a.raise("layout")},throttle:function(a,b){var c=Date.now();return function(){if(c+b-Date.now()<0){var d=e.arg2arr(arguments);a.apply(this,d),c=Date.now()}}},onWindowPopState:function(a){var b=a.data.self,c=a.originalEvent.state;d.empty(c)||c.id!==b.id||(b.state.set(c),b.loadAvailable())},onWindowScroll:function(a){a.data.self.loadAvailable()}}),b.template.register("core",b.Template,{id:null,type:"core",classes:"",on:{},lazy:!0,viewport:200,items:[],delay:100,throttle:50,timeout:6e4,srcset:"data-srcset",src:"data-src",template:{}},{container:"foogallery"},{},-100)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.str),function(a,b){a.Component=b.Class.extend({construct:function(a){this.tmpl=a},destroy:function(){this.tmpl=null}}),a.components=new b.Factory}(FooGallery,FooGallery.utils),function(a,b,c,d){b.State=b.Component.extend({construct:function(a){var b=this;b._super(a),b.apiEnabled=!!window.history&&!!history.replaceState,b.opt=b.tmpl.opt.state,b.enabled=b.opt.enabled,b.pushOrReplace=b.isPushOrReplace(b.opt.pushOrReplace)?b.opt.pushOrReplace:"replace";var c=d.escapeRegExp(b.tmpl.id),e=d.escapeRegExp(b.opt.values),f=d.escapeRegExp(b.opt.pair);b.regex={exists:new RegExp("^#"+c+"\\"+e+".+?"),values:new RegExp("(\\w+)"+f+"([^"+e+"]+)","g")}},destroy:function(){var a=this;a.clear(),a.opt=a.regex={},a._super()},isPushOrReplace:function(b){return-1!==a.inArray(b,["push","replace"])},exists:function(){return this.regex.exists.test(location.hash)&&this.regex.values.test(location.hash)},parse:function(){var b=this,d={};if(b.exists())if(b.enabled){d.id=b.tmpl.id;var e=location.hash.match(b.regex.values);a.each(e,function(e,f){var g=f.split(b.opt.pair);2===g.length&&(d[g[0]]=-1===g[1].indexOf(b.opt.array)?decodeURIComponent(g[1]):a.map(g[1].split(b.opt.array),function(a){return decodeURIComponent(a)}),c.string(d[g[0]])&&!isNaN(d[g[0]])&&(d[g[0]]=parseInt(d[g[0]])))})}else b.apiEnabled?history.replaceState(null,"",location.pathname+location.search):location.hash="#";return d},hashify:function(b){var d=this;if(c.hash(b)){var e=[];return a.each(b,function(b,f){c.empty(f)||"id"===b||(f=c.array(f)?a.map(f,function(a){return encodeURIComponent(a)}).join("+"):encodeURIComponent(f),e.push(b+d.opt.pair+f))}),e.length>0&&e.unshift("#"+d.tmpl.id),e.join(d.opt.values)}return""},replace:function(a){var b=this;if(b.enabled&&b.apiEnabled){a.id=b.tmpl.id;var d=b.hashify(a),e=c.empty(d);history.replaceState(e?null:a,"",e?location.pathname+location.search:d)}},push:function(a){var b=this;if(b.enabled&&b.apiEnabled){a.id=b.tmpl.id;var d=b.hashify(a),e=c.empty(d);history.pushState(e?null:a,"",e?location.pathname+location.search:d)}},update:function(a,b){var c=this;c.enabled&&c.apiEnabled&&(b=c.isPushOrReplace(b)?b:c.pushOrReplace,c[b](a))},clear:function(){this.exists()&&this.replace({})},initial:function(){var a=this,b=a.tmpl,d={};return b.filter&&!c.empty(b.filter.current)&&(d.f=b.filter.current),b.pages&&b.pages.current>1&&(d.p=b.pages.current),d},get:function(a){var d=this,e=d.tmpl,f={};return a instanceof b.Item&&(f.i=a.id),e.filter&&!c.empty(e.filter.current)&&(f.f=e.filter.current),e.pages&&e.pages.isValid(e.pages.current)&&(f.p=e.pages.current),f},set:function(a){var b=this,d=b.tmpl;if(c.hash(a)){d.items.reset();var e=d.items.get(a.i);if(d.filter){d.filter.rebuild();var f=c.empty(a.f)?[]:a.f;d.filter.set(f,!1)}if(d.pages){d.pages.rebuild();var g=d.pages.number(a.p);e&&!d.pages.contains(g,e)&&(g=d.pages.find(e),g=0!==g?g:1),d.pages.set(g,!c.empty(a),!1),e&&d.pages.contains(g,e)&&e.scrollTo()}else d.items.detach(d.items.all()),d.items.create(d.items.available(),!0),e&&e.scrollTo();c.empty(a.i)||(a.i=null,b.replace(a))}}}),b.template.configure("core",{state:{enabled:!1,pushOrReplace:"replace",values:"/",pair:":",array:"+"}}),b.components.register("state",b.State)}(FooGallery.$,FooGallery,FooGallery.utils.is,FooGallery.utils.str),function(a,b,c,d,e,f){b.Item=b.Component.extend({construct:function(a,b){var c=this;c._super(a),c.cls=a.cls.item,c.il8n=a.il8n.item,c.sel=a.sel.item,c.opt=f.extend({},a.opt.item,b),c.isAttached=!1,c.isCreated=!1,c.isLoading=!1,c.isLoaded=!1,c.isError=!1,c.isParsed=!1,c.$el=null,c.$inner=null,c.$anchor=null,c.$image=null,c.$caption=null,c.type=c.opt.type,c.id=c.opt.id,c.href=c.opt.href,c.src=c.opt.src,c.srcset=c.opt.srcset,c.width=c.opt.width,c.height=c.opt.height,c.title=c.opt.title,c.alt=c.opt.alt,c.caption=d.empty(c.opt.caption)?c.title:c.opt.caption,c.description=d.empty(c.opt.description)?c.alt:c.opt.description,c.attr=c.opt.attr,c.tags=c.opt.tags,c.maxWidth=c.opt.maxWidth,c.maxCaptionLength=c.opt.maxCaptionLength,c.maxDescriptionLength=c.opt.maxDescriptionLength,c.showCaptionTitle=c.opt.showCaptionTitle,c.showCaptionDescription=c.opt.showCaptionDescription,c._thumbUrl=null,c._placeholder=null,c._load=null,c._undo={classes:"",style:"",loader:!1,placeholder:!1}},destroy:function(){var a=this;return a.tmpl.raise("destroy-item").isDefaultPrevented()||(a.doDestroyItem(),a._super()),null===a.tmpl},doDestroyItem:function(){var a=this;a.isParsed?(a.append(),d.empty(a._undo.classes)?a.$el.removeAttr("class"):a.$el.attr("class",a._undo.classes),d.empty(a._undo.style)?a.$el.removeAttr("style"):a.$el.attr("style",a._undo.style),a._undo.loader&&a.$el.find(a.sel.loader).remove(),a._undo.placeholder&&a.$image.prop("src")==a._placeholder&&a.$image.removeAttr("src")):a.isCreated&&(a.detach(),a.$el.remove())},parse:function(b){var c=this,d=a(b);return!c.tmpl.raise("parse-item",[c,d]).isDefaultPrevented()&&(c.isCreated=d.is(c.sel.elem))&&(c.isParsed=c.doParseItem(d),c.fix()),c.isParsed&&c.tmpl.raise("parsed-item",[c]),c.isParsed},doParseItem:function(c){var e=this,f=e.tmpl.opt,g=e.cls,h=e.sel;return e._undo.classes=c.attr("class")||"",e._undo.style=c.attr("style")||"",e.$el=c.data(b.dataItem,e),e.$inner=e.$el.find(h.inner),e.$anchor=e.$el.find(h.anchor).on("click.foogallery",{self:e},e.onAnchorClick),e.$image=e.$anchor.find(h.image),e.$caption=e.$el.find(h.caption.elem).on("click.foogallery",{self:e},e.onCaptionClick),e.isAttached=e.$el.parent().length>0,e.isLoading=e.$el.is(h.loading),e.isLoaded=e.$el.is(h.loaded),e.isError=e.$el.is(h.error),e.id=e.$anchor.data("id")||e.id,e.tags=e.$anchor.data("tags")||e.tags,e.href=e.$anchor.attr("href")||e.href,e.src=e.$image.attr(f.src)||e.src,e.srcset=e.$image.attr(f.srcset)||e.srcset,e.width=parseInt(e.$image.attr("width"))||e.width,e.height=parseInt(e.$image.attr("height"))||e.height,e.title=e.$image.attr("title")||e.title,e.alt=e.$image.attr("alt")||e.alt,e.caption=e.$anchor.data("title")||e.$anchor.data("captionTitle")||e.caption||e.title,e.description=e.$anchor.data("description")||e.$anchor.data("captionDesc")||e.description||e.alt,d.empty(e.caption)&&(e.caption=a.trim(e.$caption.find(h.caption.title).html())),
|
10 |
-
d.empty(e.description)&&(e.description=a.trim(e.$caption.find(h.caption.description).html())),d.number(e.maxCaptionLength)&&e.maxCaptionLength>0&&!d.empty(e.caption)&&d.string(e.caption)&&e.caption.length>e.maxCaptionLength&&e.$caption.find(h.caption.title).html(e.caption.substr(0,e.maxCaptionLength)+"…"),d.number(e.maxDescriptionLength)&&e.maxDescriptionLength>0&&!d.empty(e.description)&&d.string(e.description)&&e.description.length>e.maxDescriptionLength&&e.$caption.find(h.caption.description).html(e.description.substr(0,e.maxDescriptionLength)+"…"),0===e.$el.find(h.loader).length&&(e.$el.append(a("<div/>",{class:g.loader})),e._undo.loader=!0),d.empty(e.$image.prop("src"))&&(e._placeholder=e.tmpl.items.placeholder(e.width,e.height),e.$image.prop("src",e._placeholder),e._undo.placeholder=!0),!e.isCreated||!e.isAttached||e.isLoading||e.isLoaded||e.isError||e.$el.addClass(g.idle),!0},create:function(){var a=this;if(!a.isCreated&&d.string(a.href)&&d.string(a.src)&&d.number(a.width)&&d.number(a.height)){a.tmpl.raise("create-item",[a]).isDefaultPrevented()||(a.isCreated=a.doCreateItem()),a.isCreated&&a.tmpl.raise("created-item",[a])}return a.isCreated},doCreateItem:function(){var c=this,e=c.tmpl.opt,f=c.cls,g=c.attr;g.elem.class=f.elem+" "+f.idle,g.inner.class=f.inner,g.anchor.class=f.anchor,g.anchor.href=c.href,g.anchor["data-id"]=c.id,g.anchor["data-title"]=c.caption,g.anchor["data-description"]=c.description,d.empty(c.tags)||(g.anchor["data-tags"]=JSON.stringify(c.tags)),g.image.class=f.image,g.image.src=c.tmpl.items.placeholder(c.width,c.height),g.image[e.src]=c.src,g.image[e.srcset]=c.srcset,g.image.width=c.width,g.image.height=c.height,g.image.title=c.title,g.image.alt=c.alt,c.$el=a("<div/>").attr(g.elem).data(b.dataItem,c),c.$inner=a("<figure/>").attr(g.inner).appendTo(c.$el),c.$anchor=a("<a/>").attr(g.anchor).appendTo(c.$inner).on("click.foogallery",{self:c},c.onAnchorClick),c.$image=a("<img/>").attr(g.image).appendTo(c.$anchor),f=c.cls.caption,g=c.attr.caption,g.elem.class=f.elem,c.$caption=a("<figcaption/>").attr(g.elem).on("click.foogallery",{self:c},c.onCaptionClick);var h=!d.empty(c.caption),i=!d.empty(c.description);if(h||i){g.inner.class=f.inner,g.title.class=f.title,g.description.class=f.description;var j=a("<div/>").attr(g.inner).appendTo(c.$caption);if(h){var k;k=d.number(c.maxCaptionLength)&&c.maxCaptionLength>0&&d.string(c.caption)&&c.caption.length>c.maxCaptionLength?a("<div/>").attr(g.title).html(c.caption.substr(0,c.maxCaptionLength)+"…"):a("<div/>").attr(g.title).html(c.caption),j.append(k)}if(i){var l;l=d.number(c.maxDescriptionLength)&&c.maxDescriptionLength>0&&d.string(c.description)&&c.description.length>c.maxDescriptionLength?a("<div/>").attr(g.description).html(c.description.substr(0,c.maxDescriptionLength)+"…"):a("<div/>").attr(g.description).html(c.description),j.append(l)}}return c.$caption.appendTo(c.$inner),0===c.$el.find(c.sel.loader).length&&c.$el.append(a("<div/>",{class:c.cls.loader})),!0},append:function(){var a=this;if(a.isCreated&&!a.isAttached){a.tmpl.raise("append-item",[a]).isDefaultPrevented()||(a.tmpl.$el.append(a.$el),a.fix(),a.isAttached=!0),a.isAttached&&a.tmpl.raise("appended-item",[a])}return a.isAttached},detach:function(){var a=this;if(a.isCreated&&a.isAttached){a.tmpl.raise("detach-item",[a]).isDefaultPrevented()||(a.$el.detach(),a.unfix(),a.isAttached=!1),a.isAttached||a.tmpl.raise("detached-item",[a])}return!a.isAttached},load:function(){var b=this;if(d.promise(b._load))return b._load;if(!b.isCreated||!b.isAttached)return e.rejectWith("not created or attached");if(b.tmpl.raise("load-item",[b]).isDefaultPrevented())return e.rejectWith("default prevented");var c=b.cls,f=b.$image.get(0),g=f.src;return b.isLoading=!0,b.$el.removeClass(c.idle).removeClass(c.loaded).removeClass(c.error).addClass(c.loading),b._load=a.Deferred(function(a){d.undef(window.InstallTrigger)||(f.src=""),f.onload=function(){f.onload=f.onerror=null,b.isLoading=!1,b.isLoaded=!0,b.$el.removeClass(c.loading).addClass(c.loaded),b.unfix(),b.tmpl.raise("loaded-item",[b]),a.resolve(b)},f.onerror=function(){f.onload=f.onerror=null,b.isLoading=!1,b.isError=!0,b.$el.removeClass(c.loading).addClass(c.error),d.string(g)&&b.$image.prop("src",g),b.tmpl.raise("error-item",[b]),a.reject(b)},f.src=b.getThumbUrl()}).promise()},fix:function(){var a=this;if(!a.tmpl.raise("fix-item",[a]).isDefaultPrevented()&&a.isCreated&&!a.isLoading&&!a.isLoaded&&!a.isError){var b=a.width,c=a.height;if(!isNaN(b)&&!isNaN(c)){var e=d.fn(a.maxWidth)?a.maxWidth(a):a.$image.width();e<=0&&(e=b);var f=e/b,g=c*f;a.$image.css({width:e,height:g})}}return a},unfix:function(){var a=this;return!a.tmpl.raise("unfix-item",[a]).isDefaultPrevented()&&a.isCreated&&a.$image.css({width:"",height:""}),a},getThumbUrl:function(a){a=!!d.boolean(a)&&a;var c=this;return!a&&d.string(c._thumbUrl)?c._thumbUrl:c._thumbUrl=b.parseSrc(c.src,c.width,c.height,c.srcset,c.$anchor.innerWidth(),c.$anchor.innerHeight())},scrollTo:function(a){var b=this;if(b.isAttached){var d=b.bounds(),e=c.getViewportBounds();switch(a){case"top":d.left+=d.width/2-e.width/2,d.top-=e.height/5;break;default:d.left+=d.width/2-e.width/2,d.top+=d.height/2-e.height/2}window.scrollTo(d.left,d.top)}return b},bounds:function(){return this.isAttached?c.getElementBounds(this.$el):null},intersects:function(a){return!!this.isAttached&&this.bounds().intersects(a)},onAnchorClick:function(a){var b=a.data.self,c=b.tmpl.state.get(b);b.tmpl.state.update(c)},onCaptionClick:function(b){var c=b.data.self;a(b.target).is(c.sel.caption.all)&&c.$anchor.length>0&&c.$anchor.get(0).click()}}),b.template.configure("core",{item:{type:"item",id:"",href:"",src:"",srcset:"",width:0,height:0,title:"",alt:"",caption:"",description:"",tags:[],maxWidth:null,maxCaptionLength:0,maxDescriptionLength:0,showCaptionTitle:!0,showCaptionDescription:!0,attr:{elem:{},inner:{},anchor:{},image:{},caption:{elem:{},inner:{},title:{},description:{}}}}},{item:{elem:"fg-item",inner:"fg-item-inner",anchor:"fg-thumb",image:"fg-image",loader:"fg-loader",idle:"fg-idle",loading:"fg-loading",loaded:"fg-loaded",error:"fg-error",caption:{elem:"fg-caption",inner:"fg-caption-inner",title:"fg-caption-title",description:"fg-caption-desc"}}},{item:{}}),b.components.register("item",b.Item)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d,e,f){b.Items=b.Component.extend({construct:function(a){var b=this;b._super(a),b.idMap={},b._fetched=null,b._arr=[],b._available=[],b._canvas=document.createElement("canvas");var d=b.tmpl.cls.item.caption;b.tmpl.sel.item.caption.all=c.selectify([d.elem,d.inner,d.title,d.description])},destroy:function(){var b=this,c=b.all(),d=[];c.length>0&&(b.tmpl.raise("destroy-items",[c]),d=a.map(c,function(a){return a.destroy()?a:null}),d.length>0&&b.tmpl.raise("destroyed-items",[d])),b.idMap={},b._canvas=b._fetched=null,b._arr=[],b._available=[],b._super()},fetch:function(b){var c=this;if(!b&&d.promise(c._fetched))return c._fetched;var e=c.tmpl,f=e.sel,g=e.opt.items,h=a.Deferred(),i=c.make(e.$el.find(f.item.elem));return d.empty(g)?(i.push.apply(i,c.make(window[e.id+"-items"])),h.resolve(i)):d.array(g)?(i.push.apply(i,c.make(g)),h.resolve(i)):d.string(g)?a.get(g).then(function(a){i.push.apply(i,c.make(a)),h.resolve(i)},function(a,b,c){console.log("FooGallery: GET items error.",g,a,b,c),h.resolve(i)}):h.resolve(i),h.then(function(a){c.setAll(a)}),c._fetched=h.promise()},all:function(){return this._arr.slice()},count:function(a){return a?this.all().length:this.available().length},available:function(){return this._available.slice()},get:function(a){return!d.empty(a)&&this.idMap[a]?this.idMap[a]:null},setAll:function(a){this._arr=d.array(a)?a:[],this.idMap=this.createIdMap(a),this._available=this.all()},setAvailable:function(a){this._available=d.array(a)?a:[]},reset:function(){this.setAvailable(this.all())},placeholder:function(a,c){return this._canvas&&this._canvas.toDataURL&&d.number(a)&&d.number(c)?(this._canvas.width=a,this._canvas.height=c,this._canvas.toDataURL()):b.emptyImage},loadable:function(b){var e,f=this,g=f.tmpl.opt;return g.lazy&&(e=c.getViewportBounds(g.viewport)),d.array(b)?a.map(b,function(a){return a.isCreated&&a.isAttached&&!a.isLoading&&!a.isLoaded&&!a.isError&&(!g.lazy||g.lazy&&a.intersects(e))?a:null}):[]},creatable:function(c){return d.array(c)?a.map(c,function(a){return a instanceof b.Item&&!a.isCreated?a:null}):[]},appendable:function(c){return d.array(c)?a.map(c,function(a){return a instanceof b.Item&&a.isCreated&&!a.isAttached?a:null}):[]},detachable:function(c){return d.array(c)?a.map(c,function(a){return a instanceof b.Item&&a.isCreated&&a.isAttached?a:null}):[]},jquerify:function(b){return a(a.map(b,function(a){return a.$el.get()}))},make:function(c){var e=this,g=[];if(d.jq(c)||d.array(c)){var h=[],i=a.makeArray(c);if(0===i.length)return g;e.tmpl.raise("make-items",[i]).isDefaultPrevented()||(g=a.map(i,function(a){var c=e.type(a),g=f.extend(d.hash(a)?a:{},{type:c}),i=b.components.make(c,e.tmpl,g);return d.element(a)?i.parse(a)?(h.push(i),i):null:i})),g.length>0&&e.tmpl.raise("made-items",[g]),h.length>0&&e.tmpl.raise("parsed-items",[h])}return g},type:function(c){var e;return d.hash(c)?e=c.type:d.element(c)&&(e=a(c).find(this.tmpl.sel.item.anchor).data("type")),d.string(e)&&b.components.contains(e)?e:"item"},create:function(b,c){var e=this,f=[],g=e.creatable(b);if(g.length>0){e.tmpl.raise("create-items",[g]).isDefaultPrevented()||(f=a.map(g,function(a){return a.create()?a:null})),f.length>0&&e.tmpl.raise("created-items",[f])}return d.boolean(c)&&c?e.append(b):f},append:function(b){var c=this,d=[],e=c.appendable(b);if(e.length>0){c.tmpl.raise("append-items",[e]).isDefaultPrevented()||(d=a.map(e,function(a){return a.append()?a:null})),d.length>0&&c.tmpl.raise("appended-items",[d])}return d},detach:function(b){var c=this,d=[],e=c.detachable(b);if(e.length>0){c.tmpl.raise("detach-items",[e]).isDefaultPrevented()||(d=a.map(e,function(a){return a.detach()?a:null})),d.length>0&&c.tmpl.raise("detached-items",[d])}return d},load:function(b){var c=this;if(b=c.loadable(b),b.length>0){if(!c.tmpl.raise("load-items",[b]).isDefaultPrevented()){var d=a.map(b,function(a){return a.load()});return e.when(d).done(function(a){c.tmpl.raise("loaded-items",[a])})}}return e.resolveWith([])},createIdMap:function(b){var c={};return a.each(b,function(a,b){d.empty(b.id)&&(b.id=""+(a+1)),c[b.id]=b}),c}}),b.components.register("items",b.Items)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d){b.Paging=b.Component.extend({construct:function(a){var b=this;b._super(a),b.opt=b.tmpl.opt.paging,b.cls=b.tmpl.cls.paging,b.il8n=b.tmpl.il8n.paging,b.sel=b.tmpl.sel.paging,b.pushOrReplace=b.opt.pushOrReplace,b.type=b.opt.type,b.theme=b.opt.theme,b.size=b.opt.size,b.position=b.opt.position,b.scrollToTop=b.opt.scrollToTop,b.current=0,b.total=0,b.ctrls=[],b._arr=[]},destroy:function(){var b=this;b._arr.splice(0,b._arr.length),a.each(b.ctrls.splice(0,b.ctrls.length),function(a,b){b.destroy()}),b._super()},build:function(){var a=this,c=a.tmpl.items.available();a.total=a.size>0&&c.length>0?Math.ceil(c.length/a.size):1;for(var d=0;d<a.total;d++)a._arr.push(c.splice(0,a.size));if(a.total>1&&b.paging.hasCtrl(a.type)){var e,f,g=a.position;"both"!==g&&"top"!==g||(e=b.paging.makeCtrl(a.type,a.tmpl,a,"top"),e.create()&&(e.append(),a.ctrls.push(e))),"both"!==g&&"bottom"!==g||(f=b.paging.makeCtrl(a.type,a.tmpl,a,"bottom"),f.create()&&(f.append(),a.ctrls.push(f)))}},rebuild:function(){var b=this;b.current=0,b.total=0,b._arr.splice(0,b._arr.length),a.each(b.ctrls.splice(0,b.ctrls.length),function(a,b){b.destroy()}),b.build()},all:function(){return this._arr.slice()},available:function(){return this.get(this.current)},controls:function(b){var c=this;c.isValid(b)&&a.each(c.ctrls,function(a,c){c.update(b)})},isValid:function(a){return d.number(a)&&a>0&&a<=this.total},number:function(a){return this.isValid(a)?a:0===this.current?1:this.current},create:function(a,b){var c=this;a=c.number(a);var d=a-1;c.tmpl.items.detach(c.tmpl.items.all()),c.tmpl.items.create(c._arr[d],!0),c.current=a},get:function(a){var b=this;return b.isValid(a)?(a=b.number(a),b._arr[a-1]):[]},set:function(a,b,c,e){var f=this;if(f.isValid(a)){var g,h=f.number(a);if(h!==f.current){var i=f.current,j=function(){if(c=!d.boolean(c)||c,e=!!d.boolean(e)&&e,c&&1===f.current&&!f.tmpl.state.exists()&&(g=f.tmpl.state.get(),f.tmpl.state.update(g,f.pushOrReplace)),f.controls(a),f.create(h,e),c&&(g=f.tmpl.state.get(),f.tmpl.state.update(g,f.pushOrReplace)),f.scrollToTop&&d.boolean(b)&&b){var j=f.get(f.current);j.length>0&&j[0].scrollTo("top")}f.tmpl.raise("after-page-change",[f.current,i,e])};return!f.tmpl.raise("before-page-change",[f.current,h,j,e]).isDefaultPrevented()&&(j(),!0)}}return!1},find:function(b){for(var c=this,d=0,e=c._arr.length;d<e;d++)if(-1!==a.inArray(b,c._arr[d]))return d+1;return 0},contains:function(b,c){var d=this.get(b);return-1!==a.inArray(c,d)},first:function(){this.goto(1)},last:function(){this.goto(this._arr.length)},prev:function(){this.goto(this.current-1)},next:function(){this.goto(this.current+1)},goto:function(a){var b=this;b.set(a,!0)&&b.tmpl.loadAvailable()}}),b.PagingControl=b.Component.extend({construct:function(a,b,c){var d=this;d._super(a),d.pages=b,d.position=c,d.$container=null},create:function(){var b=this;return b.$container=a("<nav/>",{class:b.pages.cls.container}).addClass(b.pages.theme),!0},destroy:function(){var a=this;a.$container.remove(),a.$container=null},append:function(){var a=this;"top"===a.position?a.$container.insertBefore(a.tmpl.$el):a.$container.insertAfter(a.tmpl.$el)},update:function(a){}}),b.paging.register("default",b.Paging,null,{type:"none",theme:"fg-light",size:30,pushOrReplace:"push",position:"none",scrollToTop:!0},{container:"fg-paging-container"},null,-100)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){b.Dots=b.Paging.extend({}),b.DotsControl=b.PagingControl.extend({construct:function(b,c,d){this._super(b,c,d),this.$container=a(),this.$list=a(),this.$items=a()},create:function(){for(var b,c=this,d=c.pages.cls,e=c.pages.il8n,f=[],g=a("<ul/>",{class:d.list}),h=0,i=c.pages.total;h<i;h++)f.push(b=c.createItem(h+1,e.page)),g.append(b);return c.$list=g,c.$container=a("<nav/>",{class:d.container}).addClass(c.pages.theme).append(g),c.$items=a(a.map(f,function(a){return a.get()})),!0},append:function(){var a=this;"top"===a.position?a.$container.insertBefore(a.tmpl.$el):a.$container.insertAfter(a.tmpl.$el)},destroy:function(){var b=this,c=b.pages.sel;b.$list.find(c.link).off("click.foogallery",b.onLinkClick),b.$container.remove(),b.$container=a(),b.$list=a(),b.$items=a()},update:function(a){this.setSelected(a-1)},setSelected:function(b){var c=this,e=c.pages.cls,f=c.pages.il8n,g=c.pages.sel;c.$items.filter(g.selected).removeClass(e.selected).each(function(b,c){var e=a(c),f=e.data("label"),h=e.find(g.reader);d.string(f)&&0!==h.length&&h.html(f)}),c.$items.eq(b).addClass(e.selected).each(function(b,c){var e=a(c),h=e.find(g.reader),i=h.html();d.string(i)&&0!==h.length&&(e.data("label",i),h.html(f.current))})},createItem:function(b,c,e,f,g){e=d.string(e)?e:b,c=d.string(c)?c:"";var h=this,i=h.pages.opt,j=h.pages.cls,k=a("<a/>",{class:j.link,href:"#page-"+b}).html(e).on("click.foogallery",{self:h,page:b},h.onLinkClick);d.empty(c)||k.attr("title",c.replace(/\{PAGE}/g,b).replace(/\{LIMIT}/g,i.limit+"")),g=d.string(g)?g:c,d.empty(g)||k.prepend(a("<span/>",{class:j.reader,text:g.replace(/\{PAGE}/g,"").replace(/\{LIMIT}/g,i.limit+"")}));var l=a("<li/>",{class:j.item}).append(k);return f=d.string(f)?f:"",d.empty(f)||l.addClass(f),l},onLinkClick:function(b){b.preventDefault();var c=b.data.self,d=b.data.page,e=c.pages.sel;a(this).closest(e.item).is(e.disabled)||(c.pages.set(d,!0),c.tmpl.loadAvailable())}}),b.paging.register("dots",b.Dots,b.DotsControl,{type:"dots",position:"both",pushOrReplace:"push"},{list:"fg-dots",item:"fg-dot-item",link:"fg-dot-link",disabled:"fg-disabled",selected:"fg-selected",visible:"fg-visible",reader:"fg-sr-only"},{current:"Current page",page:"Page {PAGE}"})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c){b.DefaultTemplate=b.Template.extend({}),b.template.register("default",b.DefaultTemplate,null,{container:"foogallery fg-default"})}(FooGallery.$,FooGallery,FooGallery.utils),function(a,b,c,d){b.MasonryTemplate=b.Template.extend({construct:function(a,b){this._super(a,b),this.masonry=null,this.style=null,this.$columnWidth=null},getStylesheet:function(){var a=this;return null===a.style&&(a.style=document.createElement("style"),a.style.appendChild(document.createTextNode("")),document.head.appendChild(a.style)),a.style.sheet},onPreInit:function(b,c){var e=c.sel,f=c.cls;f.layouts=a.map(f.layout,function(a){return a}).join(" ");for(var g=a.map(f.layout,function(a,b){return{key:b,value:a}}),h=0,i=g.length;h<i;h++)if(c.$el.hasClass(g[h].value)){c.template.layout=g[h].key;break}d.string(f.layout[c.template.layout])||(c.template.layout="col4");var j,k,l="fixed"===c.template.layout;if(c.template.isFitWidth=l,c.template.percentPosition=!l,c.template.transitionDuration=0,c.template.itemSelector=e.item.elem,c.$el.removeClass(f.layouts).addClass(f.layout[c.template.layout]),l||(0===c.$el.find(e.gutterWidth).length&&c.$el.prepend(a("<div/>").addClass(f.gutterWidth)),c.template.gutter=e.gutterWidth),0===c.$el.find(e.columnWidth).length&&c.$el.prepend(a("<div/>").addClass(f.columnWidth)),l&&d.number(c.template.columnWidth)){var m=c.$el.find(e.columnWidth).width(c.template.columnWidth);j=c.getStylesheet(),k="#"+c.id+e.container+" "+e.item.elem+" { width: "+m.outerWidth()+"px; }",j.insertRule(k,0)}c.template.columnWidth=e.columnWidth,l&&d.number(c.template.gutter)&&(j=c.getStylesheet(),k="#"+c.id+e.container+" "+e.item.elem+" { margin-bottom: "+c.template.gutter+"px; }",j.insertRule(k,0)),c.masonry=new Masonry(c.$el.get(0),c.template)},onPostInit:function(a,b){b.masonry.layout()},onFirstLoad:function(a,b){b.masonry.layout()},onReady:function(a,b){b.masonry.layout()},onDestroy:function(a,b){b.$el.find(b.sel.columnWidth).remove(),b.$el.find(b.sel.gutterWidth).remove(),b.style&&b.style.parentNode&&b.style.parentNode.removeChild(b.style)},onDestroyed:function(a,b){b.masonry instanceof Masonry&&b.masonry.destroy()},onLayout:function(a,b){b.masonry.layout()},onParsedItems:function(a,b,c){b.masonry.layout()},onAppendedItems:function(a,b,c){c=b.items.jquerify(c),c=b.masonry.addItems(c),b.masonry.layoutItems(c,!0)},onDetachItem:function(a,b,c){a.isDefaultPrevented()||(a.preventDefault(),b.masonry.remove(c.$el),c.isAttached=!1,c.unfix())},onDetachedItems:function(a,b,c){b.masonry.layout()},onLoadedItems:function(a,b,c){b.masonry.layout()}}),b.template.register("masonry",b.MasonryTemplate,{template:{initLayout:!1,isInitLayout:!1,layout:"col4"}},{container:"foogallery fg-masonry",columnWidth:"fg-column-width",gutterWidth:"fg-gutter-width",layout:{fixed:"fg-masonry-fixed",col2:"fg-masonry-2col",col3:"fg-masonry-3col",col4:"fg-masonry-4col",col5:"fg-masonry-5col"}})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){b.Justified=c.Class.extend({construct:function(c,d){this.$el=a(c),this.options=a.extend(!0,{},b.Justified.defaults,d),this._items=[]},init:function(){var b=this;d.string(b.options.maxRowHeight)&&(b.options.maxRowHeight.indexOf("%")?b.options.maxRowHeight=b.options.rowHeight*(parseInt(b.options.maxRowHeight)/100):b.options.maxRowHeight=parseInt(b.options.maxRowHeight)),a(window).on("resize.justified",{self:b},b.onWindowResize)},destroy:function(){a(window).off("resize.justified"),this.$el.removeAttr("style")},parse:function(){var b=this,c=b.$el.is(":visible"),d=a("<div/>",{class:b.$el.attr("class")}).css({position:"absolute",top:0,left:-9999,visibility:"hidden",maxWidth:b.getContainerWidth()}).appendTo("body");return b._items=b.$el.find(b.options.itemSelector).removeAttr("style").removeClass("fg-positioned").map(function(e,f){var g,h=a(f),i=0,j=0;if(c)i=h.outerWidth(),j=h.outerHeight();else{var k=h.clone();k.appendTo(d),i=k.outerWidth(),j=k.outerHeight()}return g=b.options.rowHeight/j,{index:e,width:i*g,height:b.options.rowHeight,top:0,left:0,$item:h}}).get(),d.remove(),b._items},round:function(a){return Math.round(a)},getContainerWidth:function(){var a=this;return a.$el.is(":visible")?a.$el.width():a.$el.parents(":visible:first").innerWidth()},layout:function(a,b){a=!!d.boolean(a)&&a,b=!d.boolean(b)||b,(a||0===this._items.length)&&this.parse();for(var c,e=this,f=e.getContainerWidth(),g=e.rows(f),h=0,i=0,j=g.length;i<j;i++)c=g[i],h=i===j-1?e.lastRow(c,f,h):e.justify(c,f,h),e.render(c);e.$el.height(h),b&&e.getContainerWidth()<f&&e.layout(!1,!1)},render:function(a){for(var b,c=0,d=a.items.length;c<d;c++)b=a.items[c],a.visible?b.$item.css({width:b.width,height:b.height,top:b.top,left:b.left,display:"",maxHeight:this.options.maxRowHeight>0?this.options.maxRowHeight:""}).addClass("fg-positioned"):b.$item.css("display","none")},lastRow:function(a,b,c){var d=this;switch(d.options.lastRow){case"hide":a.visible=!1;break;case"justify":c=d.justify(a,b,c);break;case"nojustify":c=a.width/b>d.options.justifyThreshold?d.justify(a,b,c):d.position(a,b,c,"left");break;case"right":case"center":case"left":c=d.position(a,b,c,d.options.lastRow);break;default:c=d.position(a,b,c,"left")}return c},justify:function(a,b,c){var d=this,e=0,f=d.options.margins*(a.items.length-1),g=(b-f)/a.width;a.index>0&&(c+=d.options.margins),a.top=c,a.width=d.round(a.width*g),a.height=d.round(a.height*g);for(var h,i=0,j=a.items.length;i<j;i++)h=a.items[i],h.width=d.round(h.width*g),h.height=d.round(h.height*g),h.top=c,i>0&&(e+=d.options.margins),h.left=e,e+=h.width;return c+(a.height>d.options.maxRowHeight?d.options.maxRowHeight:a.height)},position:function(a,b,c,d){var e=this,f=a.items[a.items.length-1],g=b-(f.left+f.width);a.index>0&&(c+=e.options.margins),a.top=c;for(var h,i=0,j=a.items.length;i<j;i++)h=a.items[i],h.top=c,"center"===d?h.left+=g/2:"right"===d&&(h.left+=g);return c+a.height},items:function(){return a.map(this._items,function(a){return{index:a.index,width:a.width,height:a.height,$item:a.$item,top:a.top,left:a.left}})},rows:function(a){for(var b=this,c=b.items(),d=[],e=c.length>0,f=-1,g=0;e;){f+=1,f>0&&(g+=b.options.margins);for(var h,i,j,k={index:f,visible:!0,top:g,width:0,height:b.options.rowHeight,items:[]},l=[],m=0,n=0,o=c.length;n<o&&(i=c[n],!((h=k.width+i.width)>a&&n>0));n++)h>a&&0==n&&(h=a,j=a/i.width,i.width=b.round(i.width*j),i.height=b.round(i.height*j),k.height=i.height),i.top=k.top,n>0&&(m+=b.options.margins),i.left=m,m+=i.width,k.width=h,k.items.push(i),l.push(n);if(0===l.length){e=!1;break}l.sort(function(a,b){return b-a});for(var p=0,q=l.length;p<q;p++)c.splice(l[p],1);d.push(k),e=c.length>0}return d},onWindowResize:function(a){a.data.self.layout()}}),b.Justified.defaults={itemSelector:".fg-item",rowHeight:150,maxRowHeight:"200%",margins:0,lastRow:"center",justifyThreshold:.5}}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c){b.JustifiedTemplate=b.Template.extend({onPreInit:function(a,c){c.justified=new b.Justified(c.$el.get(0),c.template)},onInit:function(a,b){b.justified.init()},onFirstLoad:function(a,b){b.justified.layout(!0)},onReady:function(a,b){b.justified.layout(!0)},onDestroy:function(a,b){b.justified.destroy()},onLayout:function(a,b){b.justified.layout(!0)},onParsedItems:function(a,b,c){b.justified.layout(!0)},onAppendedItems:function(a,b,c){b.justified.layout(!0)},onDetachedItems:function(a,b,c){b.justified.layout(!0)}}),b.template.register("justified",b.JustifiedTemplate,null,{container:"foogallery fg-justified"})}(FooGallery.$,FooGallery,FooGallery.utils),function(a,b,c,d){b.Portfolio=c.Class.extend({construct:function(c,d){this.$el=a(c),this.options=a.extend(!0,{},b.Portfolio.defaults,d),this._items=[]},init:function(){var b=this;a(window).on("resize.portfolio",{self:b},b.onWindowResize)},destroy:function(){a(window).off("resize.portfolio"),this.$el.removeAttr("style")},parse:function(){var b=this,c=b.$el.is(":visible"),d=a("<div/>",{class:b.$el.attr("class")}).css({position:"absolute",top:0,left:-9999,visibility:"hidden",maxWidth:b.getContainerWidth()}).appendTo("body");return b._items=b.$el.find(".fg-item").removeAttr("style").removeClass("fg-positioned").map(function(b,e){var f=a(e),g=f.find(".fg-thumb"),h=f.find(".fg-image"),i=0,j=0;if(f.find(".fg-caption").css("max-width",parseFloat(h.attr("width"))),h.css({width:h.attr("width"),height:h.attr("height")}),c)i=f.outerWidth(),j=f.outerHeight();else{var k=f.clone();k.appendTo(d),i=k.outerWidth(),j=k.outerHeight()}return h.css({width:"",height:""}),{index:b,width:i,height:j,top:0,left:0,$item:f,$thumb:g}}).get(),d.remove(),b._items},round:function(a){return Math.round(2*a)/2},getContainerWidth:function(){var a=this;return a.$el.is(":visible")?a.$el.width():a.$el.parents(":visible:first").innerWidth()},layout:function(a,b){a=!!d.boolean(a)&&a,b=!d.boolean(b)||b,(a||0===this._items.length)&&this.parse();for(var c,e=this,f=e.getContainerWidth(),g=e.rows(f),h=0,i=0,j=g.length;i<j;i++)c=g[i],h=e.position(c,f,h,e.options.align),e.render(c);e.$el.height(h),b&&e.getContainerWidth()<f&&e.layout(!1,!1)},render:function(a){for(var b,c=0,d=a.items.length;c<d;c++)b=a.items[c],a.visible?b.$item.css({width:b.width,height:a.height,top:b.top,left:b.left,display:""}).addClass("fg-positioned"):b.$item.css("display","none")},position:function(a,b,c,d){var e=this,f=a.items[a.items.length-1],g=b-(f.left+f.width);a.index>0&&(c+=e.options.gutter),a.top=c;for(var h,i=0,j=a.items.length;i<j;i++)h=a.items[i],h.top=c,"center"===d?h.left+=g/2:"right"===d&&(h.left+=g);return c+a.height},items:function(){return a.map(this._items,function(a){return{index:a.index,width:a.width,height:a.height,$item:a.$item,$thumb:a.$thumb,top:a.top,left:a.left}})},rows:function(a){for(var b=this,c=b.items(),d=[],e=c.length>0,f=-1,g=0;e;){f+=1,f>0&&(g+=b.options.gutter);for(var h,i,j,k={index:f,visible:!0,top:g,width:0,height:0,items:[]},l=[],m=0,n=0,o=c.length;n<o&&(i=c[n],!((h=k.width+i.width)>a&&n>0));n++)h>a&&0==n&&(h=a,j=a/i.width,i.width=b.round(i.width*j),i.height=b.round(i.height*j),k.height=i.height),i.top=k.top,n>0&&(m+=b.options.gutter),n!==o-1&&(h+=b.options.gutter),i.left=m,m+=i.width,i.height>k.height&&(k.height=i.height),k.width=h,k.items.push(i),l.push(n);if(0===l.length){e=!1;break}l.sort(function(a,b){return b-a});for(var p=0,q=l.length;p<q;p++)c.splice(l[p],1);d.push(k),e=c.length>0}return d},onWindowResize:function(a){a.data.self.layout()}}),b.Portfolio.defaults={gutter:40,align:"center"}}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c){b.PortfolioTemplate=b.Template.extend({construct:function(a,b){this._super(a,b),this.portfolio=null},onPreInit:function(a,c){c.portfolio=new b.Portfolio(c.$el.get(0),c.template)},onInit:function(a,b){b.portfolio.init()},onFirstLoad:function(a,b){b.portfolio.layout(!0)},onReady:function(a,b){b.portfolio.layout(!0)},onDestroy:function(a,b){b.portfolio.destroy()},onLayout:function(a,b){b.portfolio.layout(!0)},onParsedItems:function(a,b,c){b.portfolio.layout(!0)},onAppendedItems:function(a,b,c){b.portfolio.layout(!0)},onDetachedItems:function(a,b,c){b.portfolio.layout(!0)}}),b.template.register("simple_portfolio",b.PortfolioTemplate,{gutter:40},{container:"foogallery fg-simple_portfolio"})}(FooGallery.$,FooGallery,FooGallery.utils),function(a,b,c,d){b.ImageViewerTemplate=b.Template.extend({construct:function(b,c){this._super(d.extend({},b,{paging:{pushOrReplace:"replace",theme:"fg-light",type:"default",size:1,position:"none",scrollToTop:!1}}),c),this.$inner=a(),this.$current=a(),this.$total=a(),this.$prev=a(),this.$next=a()},createChildren:function(){var b=this;return a("<div/>",{class:b.cls.inner}).append(a("<div/>",{class:b.cls.innerContainer}),a("<div/>",{class:b.cls.controls}).append(a("<div/>",{class:b.cls.prev}).append(a("<span/>",{text:b.il8n.prev})),a("<label/>",{class:b.cls.count,text:b.il8n.count}).prepend(a("<span/>",{class:b.cls.countCurrent,text:"0"})).append(a("<span/>",{class:b.cls.countTotal,text:"0"})),a("<div/>",{class:b.cls.next}).append(a("<span/>",{text:b.il8n.next}))))},onPreInit:function(a,b){b.$inner=b.$el.find(b.sel.innerContainer),b.$current=b.$el.find(b.sel.countCurrent),b.$total=b.$el.find(b.sel.countTotal),b.$prev=b.$el.find(b.sel.prev),b.$next=b.$el.find(b.sel.next)},onInit:function(a,b){b.template.attachFooBox&&b.$el.on("foobox.previous",{self:b},b.onFooBoxPrev).on("foobox.next",{self:b},b.onFooBoxNext),b.$prev.on("click",{self:b},b.onPrevClick),b.$next.on("click",{self:b},b.onNextClick)},onFirstLoad:function(a,b){b.update()},onDestroy:function(a,b){b.template.attachFooBox&&b.$el.off({"foobox.previous":b.onFooBoxPrev,"foobox.next":b.onFooBoxNext}),b.$prev.off("click",b.onPrevClick),b.$next.off("click",b.onNextClick)},onAppendItem:function(a,b,c){a.preventDefault(),b.$inner.append(c.$el),c.fix(),c.isAttached=!0},onAfterPageChange:function(a,b,c,d,e){e||b.update()},onAfterFilterChange:function(a,b){b.update()},update:function(){this.pages&&(this.$current.text(this.pages.current),this.$total.text(this.pages.total))},prev:function(){this.pages&&(this.template.loop&&1===this.pages.current?this.pages.last():this.pages.prev(),this.update())},next:function(){this.pages&&(this.template.loop&&this.pages.current===this.pages.total?this.pages.first():this.pages.next(),this.update())},onFooBoxPrev:function(a){a.data.self.prev()},onFooBoxNext:function(a){a.data.self.next()},onPrevClick:function(a){a.preventDefault(),a.stopPropagation(),a.data.self.prev()},onNextClick:function(a){a.preventDefault(),a.stopPropagation(),a.data.self.next()}}),b.template.register("image-viewer",b.ImageViewerTemplate,{template:{attachFooBox:!1,loop:!1}},{container:"foogallery fg-image-viewer",inner:"fiv-inner",innerContainer:"fiv-inner-container",controls:"fiv-ctrls",prev:"fiv-prev",next:"fiv-next",count:"fiv-count",countCurrent:"fiv-count-current",countTotal:"fiv-count-total"},{prev:"Prev",next:"Next",count:"of"})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.obj),function(a,b,c){b.ThumbnailTemplate=b.Template.extend({construct:function(b,d){this._super(c.extend({},b,{filtering:{type:"none"},paging:{type:"none"}}),d),this.$hidden=a()},createChildren:function(){var b=this;return b.$hidden=a("<div/>",{class:b.cls.hidden})},onPreInit:function(a,b){b.$hidden=b.$el.find(b.sel.hidden)},onPostInit:function(b,c){for(var d,e=c.items.all().slice(1),f=0,g=e.length;f<g;f++)d=e[f],c.$hidden.append(a("<a/>",{href:d.href,rel:"lightbox["+c.id+"]"}).attr(d.attr.anchor));c.items.setAll(c.items.all().slice(0,1))}}),b.template.register("thumbnail",b.ThumbnailTemplate,null,{container:"foogallery fg-thumbnail",hidden:"fg-st-hidden"})}(FooGallery.$,FooGallery,FooGallery.utils.obj),function(a,b,c,d){b.triggerPostLoad=function(b,c,d,e,f){("first-load"===b.type||c.initialized&&("after-page-change"===b.type&&!f||"after-filter-change"===b.type))&&a("body").trigger("post-load")},b.autoDefaults={on:{"first-load.foogallery after-page-change.foogallery after-filter-change.foogallery":b.triggerPostLoad}},b.auto=function(a){b.autoDefaults=d.merge(b.autoDefaults,a)},a(function(){a('[id^="foogallery-gallery-"]:not(.fg-ready)').foogallery(b.autoDefaults)}),c.ready(function(){a('[id^="foogallery-gallery-"].fg-ready').foogallery(b.autoDefaults)})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.obj);
|
|
1 |
/*
|
2 |
* FooGallery - The Most Intuitive and Extensible Gallery Creation and Management Tool Ever Created for WordPress
|
3 |
+
* @version 1.0.26
|
4 |
* @link
|
5 |
* @copyright Steven Usher & Brad Vincent 2015
|
6 |
* @license Released under the GPLv3 license.
|
7 |
*/
|
8 |
|
9 |
!function(a,b){b.$=a}(jQuery,window.FooGallery=window.FooGallery||{}),function(a){if(!a)return void console.warn("jQuery must be included in the page prior to the FooGallery.utils library.");var b={$:a,version:"0.0.8"};b.versionCompare=function(a,b){function c(a){for(var b=a.split("."),c=0,d=b.length;c<d;c++)b[c]=parseInt(b[c]),isNaN(b[c])&&(b[c]=0);return b}if(!/[\d.]/.test(a)||!/[\d.]/.test(b))return NaN;for(var d=c(a),e=c(b);d.length<e.length;)d.push(0);for(;e.length<d.length;)e.push(0);for(var f=0;f<d.length;++f){if(e.length==f)return 1;if(d[f]!=e[f])return d[f]>e[f]?1:-1}return d.length!=e.length?-1:0},!function(){try{return!!window.FooGallery.utils}catch(a){return!1}}()?window.FooGallery.utils=b:b.versionCompare(b.version,window.FooGallery.utils.version)>0?(console.warn("An older version of FooGallery.utils ("+window.FooGallery.utils.version+") already exists in the page, version "+b.version+" will override it."),window.FooGallery.utils=b):console.warn("A newer version of FooGallery.utils ("+window.FooGallery.utils.version+") already exists in the page, version "+b.version+" will not register itself.")}(jQuery),function(a,b){"0.0.8"===b.version&&(b.is={},b.is.array=function(a){return"[object Array]"===Object.prototype.toString.call(a)},b.is.boolean=function(a){return"[object Boolean]"===Object.prototype.toString.call(a)},b.is.element=function(a){return"object"==typeof HTMLElement?a instanceof HTMLElement:!!a&&"object"==typeof a&&null!==a&&1===a.nodeType&&"string"==typeof a.nodeName},b.is.empty=function(a){if(b.is.undef(a)||null===a)return!0;if(b.is.number(a)&&0==a)return!0;if(b.is.boolean(a)&&!1===a)return!0;if(b.is.string(a)&&0===a.length)return!0;if(b.is.array(a)&&0===a.length)return!0;if(b.is.jq(a)&&0===a.length)return!0;if(b.is.hash(a)){for(var c in a)if(a.hasOwnProperty(c))return!1;return!0}return!1},b.is.error=function(a){return"[object Error]"===Object.prototype.toString.call(a)},b.is.fn=function(a){return a===window.alert||"[object Function]"===Object.prototype.toString.call(a)},b.is.hash=function(a){return b.is.object(a)&&a.constructor===Object&&!a.nodeType&&!a.setInterval},b.is.jq=function(c){return!b.is.undef(a)&&c instanceof a},b.is.number=function(a){return"[object Number]"===Object.prototype.toString.call(a)&&!isNaN(a)},b.is.object=function(a){return"[object Object]"===Object.prototype.toString.call(a)&&!b.is.undef(a)&&null!==a},b.is.promise=function(a){return b.is.object(a)&&b.is.fn(a.then)&&b.is.fn(a.promise)},b.is.size=function(a){return!!(b.is.string(a)&&!b.is.empty(a)||b.is.number(a))&&/^(auto|none|(?:[\d\.]*)+?(?:%|px|mm|q|cm|in|pt|pc|em|ex|ch|rem|vh|vw|vmin|vmax)?)$/.test(a)},b.is.string=function(a){return"[object String]"===Object.prototype.toString.call(a)},b.is.undef=function(a){return void 0===a})}(FooGallery.utils.$,FooGallery.utils),function(a,b,c){if("0.0.8"===b.version){b.fn={};var d=Function.prototype.toString;b.fn.CONTAINS_SUPER=/xyz/.test(d.call(function(){xyz}))?/\b_super\b/:/.*/,b.fn.addOrOverride=function(a,e,f){if(c.object(a)&&c.string(e)&&!c.empty(e)&&c.fn(f)){var g=a[e],h=c.fn(g)&&b.fn.CONTAINS_SUPER.test(d.call(f));a[e]=h?function(a,b){return function(){var c=this._super;this._super=a;var d=b.apply(this,arguments);return this._super=c,d}}(g,f):f}},b.fn.apply=function(a,b){function d(){return a.apply(this,b)}return b=c.array(b)?b:[],d.prototype=a.prototype,new d},b.fn.arg2arr=function(a){return Array.prototype.slice.call(a)},b.fn.check=function(d,e,f,g){function h(a){return function(){return a.apply(d,arguments)}}return f=c.fn(f)?f:a.noop,d=c.object(d)?d:window,e=c.string(e)?b.fn.fetch(e,g):e,h(c.fn(e)?e:f)},b.fn.fetch=function(b,d){return!c.string(b)||c.empty(b)?null:(d=c.object(d)?d:window,a.each(b.split("."),function(a,b){if(!d[b])return!1;d=d[b]}),c.fn(d)?d:null)},b.fn.enqueue=function(d,e,f,g){function h(a,b){try{return n.push(a),b.apply(a,i)}catch(a){return j.reject(a,n),j}}var i=b.fn.arg2arr(arguments),j=a.Deferred(),k=a.Deferred(),l=k.promise(),m=[],n=[],o=!0;return d=i.shift(),e=i.shift(),a.each(d,function(a,d){c.fn(d[e])&&(l=l.then(function(){if(!o){var a=b.fn.arg2arr(arguments);m.push(a)}return o=!1,h(d,d[e])}))}),l.then(function(){if(!o){var a=b.fn.arg2arr(arguments);m.push(a)}o=!1,j.resolve(m)}),l.fail(function(){var a=b.fn.arg2arr(arguments);a.push(n),j.reject.apply(j,a)}),k.resolve(),j.promise()},b.fn.when=function(b){if(!c.array(b)||c.empty(b))return a.when();for(var d=a.Deferred(),e=[],f=b.length,g=0;g<b.length;g++)b[g].then(function(a){e.push(a)}).always(function(){--f||d.resolve(e)});return d.promise()},b.fn.rejectWith=function(c,d){var e=a.Deferred(),f=b.fn.arg2arr(arguments);return e.reject.apply(e,f).promise()},b.fn.resolveWith=function(c,d){var e=a.Deferred(),f=b.fn.arg2arr(arguments);return e.resolve.apply(e,f).promise()},b.fn.resolved=a.Deferred().resolve().promise(),b.fn.rejected=a.Deferred().reject().promise()}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b){if("0.0.8"===a.version){a.url={};var c=document.createElement("a");a.url.parts=function(a){return c.href=a,{hash:c.hash,host:c.host,hostname:c.hostname,href:c.href,origin:c.origin,pathname:c.pathname,port:c.port,protocol:c.protocol,search:c.search}},a.url.full=function(a){return!b.string(a)||b.empty(a)?null:(c.href=a,c.href)},a.url.param=function(a,c,d){if(!b.string(a)||!b.string(c)||b.empty(c))return a;var e,f,g,h;return b.undef(d)?(e=new RegExp("[?|&]"+c+"=([^&;]+?)(&|#|;|$)"),f=e.exec(a)||[,""],g=f[1].replace(/\+/g,"%20"),b.string(g)&&!b.empty(g)?decodeURIComponent(g):null):(""===d||null===d?(e=new RegExp("^([^#]*?)(([^#]*)&)?"+c+"(=[^&#]*)?(&|#|$)"),g=a.replace(e,"$1$3$5").replace(/^([^#]*)((\?)&|\?(#|$))/,"$1$3$4")):(e=new RegExp("([?&])"+c+"[^&]*"),h=c+"="+encodeURIComponent(d),(g=a.replace(e,"$1"+h))!==a||e.test(g)||(g+=(-1!==g.indexOf("?")?"&":"?")+h)),g)}}}(FooGallery.utils,FooGallery.utils.is),function(a,b,c){"0.0.8"===a.version&&(a.str={},a.str.camel=function(a){return b.empty(a)?a:a.toUpperCase()===a?a.toLowerCase():a.replace(/^([A-Z])|[-\s_]+(\w)/g,function(a,c,d){return b.string(d)?d.toUpperCase():c.toLowerCase()})},a.str.contains=function(a,c,d){return!(!b.string(a)||b.empty(a)||!b.string(c)||b.empty(c))&&(c.length<=a.length&&-1!==(d?a.toUpperCase().indexOf(c.toUpperCase()):a.indexOf(c)))},a.str.containsWord=function(a,c,d){if(!b.string(a)||b.empty(a)||!b.string(c)||b.empty(c)||a.length<c.length)return!1;for(var e=a.split(/\W/),f=0,g=e.length;f<g;f++)if(d?e[f].toUpperCase()==c.toUpperCase():e[f]==c)return!0;return!1},a.str.endsWith=function(a,c){return!b.string(a)||b.empty(a)||!b.string(c)||b.empty(c)?a==c:a.slice(a.length-c.length)==c},a.str.escapeRegExp=function(a){return b.empty(a)?a:a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},a.str.fnv1a=function(a){if(!b.string(a)||b.empty(a))return null;var c,d,e=2166136261;for(c=0,d=a.length;c<d;c++)e^=a.charCodeAt(c),e+=(e<<1)+(e<<4)+(e<<7)+(e<<8)+(e<<24);return e>>>0},a.str.from=function(c,d){return!b.string(c)||b.empty(c)||!b.string(d)||b.empty(d)?null:a.str.contains(c,d)?c.substring(c.indexOf(d)+d.length):null},a.str.join=function(d,e,f){if(!b.string(d)||!b.string(e))return null;var g=c.arg2arr(arguments);d=g.shift();var h,i,j=g.shift();for(h=0,i=g.length;h<i;h++)e=g[h],b.empty(e)||(a.str.endsWith(j,d)&&(j=j.slice(0,j.length-d.length)),a.str.startsWith(e,d)&&(e=e.slice(d.length)),j+=d+e);return j},a.str.startsWith=function(a,c){return!b.empty(a)&&!b.empty(c)&&a.slice(0,c.length)==c},a.str.until=function(c,d){return b.empty(c)||b.empty(d)?c:a.str.contains(c,d)?c.substring(0,c.indexOf(d)):c},a.str.format=function(a,d,e){var f=c.arg2arr(arguments);if(a=f.shift(),b.empty(a)||b.empty(f))return a;1===f.length&&(b.array(f[0])||b.object(f[0]))&&(f=f[0]);for(var g in f)a=a.replace(new RegExp("\\{"+g+"\\}","gi"),f[g]);return a})}(FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c,d,e){if("0.0.8"===b.version){b.obj={};var f=function(){};b.obj.create=function(a){if(!c.object(a))throw TypeError("Argument must be an object");f.prototype=a;var b=new f;return f.prototype=null,b},b.obj.extend=function(e,f,g){e=c.object(e)?e:{};var h=d.arg2arr(arguments);return h.shift(),a.each(h,function(a,c){b.obj.merge(e,c)}),e},b.obj.merge=function(a,d){a=c.hash(a)?a:{},d=c.hash(d)?d:{};for(var e in d)d.hasOwnProperty(e)&&(c.hash(d[e])?(a[e]=c.hash(a[e])?a[e]:{},b.obj.merge(a[e],d[e])):c.array(d[e])?a[e]=d[e].slice():a[e]=d[e]);return a},b.obj.mergeValid=function(d,e,f,g){if(!c.hash(f)||!c.hash(e))return d;e=c.hash(e)?e:{},g=c.hash(g)?g:{};var h,i,j;for(h in e)e.hasOwnProperty(h)&&c.fn(e[h])&&(i=c.array(g[h])?g[h]:c.string(g[h])?[g[h]]:[h],a.each(i,function(a,g){if(j=b.obj.prop(f,g),!c.undef(j))return e[h](j)?(b.obj.prop(d,h,j),!1):void 0}));return d},b.obj.prop=function(b,d,f){if(c.object(b)&&!c.empty(d)){var g,h;if(c.undef(f))return e.contains(d,".")?(g=d.split("."),h=g.length-1,a.each(g,function(a,d){if(a===h)f=b[d];else{if(!c.hash(b[d]))return!1;b=b[d]}})):c.undef(b[d])||(f=b[d]),f;e.contains(d,".")?(g=d.split("."),h=g.length-1,a.each(g,function(a,d){a===h?b[d]=f:b=c.hash(b[d])?b[d]:b[d]={}})):c.undef(b[d])||(b[d]=f)}}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.str),function(a,b,c){if("0.0.8"===b.version){b.ready=function(a){function c(){try{a.call(window,b.$)}catch(a){console.error(a)}}(Function("/*@cc_on return true@*/")()?"complete"===document.readyState:"loading"!==document.readyState)?c():document.addEventListener("DOMContentLoaded",c,!1)};var d=0;b.uniqueId=function(a,b){var e=a.attr("id");return c.empty(e)&&(b=c.string(b)&&!c.empty(b)?b:"uid-",e=b+ ++d,a.attr("id",e).data("__uniqueId__",!0)),e},b.removeUniqueId=function(a){a.data("__uniqueId__")&&a.removeAttr("id").removeData("__uniqueId__")}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c){if("0.0.8"===b.version){b.transition={};var d=document.createElement("div");b.transition.supported=function(a){var b=a.style;return c.string(b.transition)||c.string(b.WebkitTransition)||c.string(b.MozTransition)||c.string(b.msTransition)||c.string(b.OTransition)}(d),b.transition.end=function(a){var b=a.style;return c.string(b.transition)?"transitionend":c.string(b.WebkitTransition)?"webkitTransitionEnd":c.string(b.MozTransition)?"transitionend":c.string(b.msTransition)?"msTransitionEnd":c.string(b.OTransition)?"oTransitionEnd":null}(d),b.transition.duration=function(a,b){if(b=c.number(b)?b:0,!c.jq(a))return b;var d=a.css("transition-duration");if(/^([\d\.]*)+?(ms|s)$/i.test(d)){var e=d.match(/^([\d\.]*)+?(ms|s)$/i),f=parseFloat(e[1]);return"s"===e[2].toLowerCase()&&(f*=1e3),f}return b},b.transition.start=function(d,e,f,g){var h=a.Deferred();if(d=d.first(),b.transition.supported){var i=d.data("transition_safety");c.hash(i)&&c.number(i.timer)&&(clearTimeout(i.timer),d.removeData("transition_safety").off(b.transition.end+".utils"),i.deferred.reject()),g=c.number(g)?g:b.transition.duration(d)+50,i={deferred:h,timer:setTimeout(function(){d.removeData("transition_safety").off(b.transition.end+".utils"),h.resolve()},g)},d.data("transition_safety",i),d.on(b.transition.end+".utils",function(a){d.is(a.target)&&(clearTimeout(i.timer),d.removeData("transition_safety").off(b.transition.end+".utils"),h.resolve())})}return setTimeout(function(){c.fn(e)?e.apply(d.get(0),[d]):d.toggleClass(e,f),b.transition.supported||h.resolve()},20),h.promise()}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d,e){"0.0.8"===b.version&&(b.Class=function(){},b.Class.extend=function(a){function f(){if(!c.fn(this.construct))throw new SyntaxError('FooGallery.utils.Class objects must be constructed with the "new" keyword.');this.construct.apply(this,arguments)}a=c.hash(a)?a:{};var g=d.create(this.prototype);for(var h in a)a.hasOwnProperty(h)&&e.addOrOverride(g,h,a[h]);return g.construct=c.fn(g.construct)?g.construct:function(){},f.prototype=g,f.prototype.constructor=c.fn(g.__ctor__)?g.__ctor__:f,f.extend=b.Class.extend,f.override=b.Class.override,f},b.Class.override=function(a,b){e.addOrOverride(this.prototype,a,b)})}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.obj,FooGallery.utils.fn),function(a,b,c){if("0.0.8"===b.version){b.Bounds=b.Class.extend({construct:function(){var a=this;a.top=0,a.right=0,a.bottom=0,a.left=0,a.width=0,a.height=0},inflate:function(a){var b=this;return c.number(a)&&(b.top-=a,b.right+=a,b.bottom+=a,b.left-=a,b.width+=2*a,b.height+=2*a),b},intersects:function(a){var b=this;return b.left<=a.right&&a.left<=b.right&&b.top<=a.bottom&&a.top<=b.bottom}});var d;b.getViewportBounds=function(c){d||(d=a(window));var e=new b.Bounds;return e.top=d.scrollTop(),e.left=d.scrollLeft(),e.width=d.width(),e.height=d.height(),e.right=e.left+e.width,e.bottom=e.top+e.height,e.inflate(c),e},b.getElementBounds=function(d){c.jq(d)||(d=a(d));var e=new b.Bounds;if(0!==d.length){var f=d.offset();e.top=f.top,e.left=f.left,e.width=d.width(),e.height=d.height()}return e.right=e.left+e.width,e.bottom=e.top+e.height,e}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){"0.0.8"===b.version&&(b.Factory=b.Class.extend({construct:function(){this.registered={}},contains:function(a){return!c.undef(this.registered[a])},load:function(b,e,f){var g,h,i=this,j=d.arg2arr(arguments),k=[],l=[];b=j.shift()||{};for(g in i.registered)if(i.registered.hasOwnProperty(g)){var m=i.registered[g];b.hasOwnProperty(g)&&(h=b[g],c.string(h)&&(h=d.fetch(b[g])),c.fn(h)&&(m={name:g,klass:h,priority:i.registered[g].priority})),k.push(m)}for(g in b)b.hasOwnProperty(g)&&!i.registered.hasOwnProperty(g)&&(h=b[g],c.string(h)&&(h=d.fetch(b[g])),c.fn(h)&&k.push({name:g,klass:h,priority:0}));return k.sort(function(a,b){return b.priority-a.priority}),a.each(k,function(a,b){c.fn(b.klass)&&l.push(d.apply(b.klass,j))}),l},make:function(a,b,e){var f,g=this,h=d.arg2arr(arguments);return a=h.shift(),f=g.registered[a],c.hash(f)&&c.fn(f.klass)?d.apply(f.klass,h):null},names:function(b){b=!!c.boolean(b)&&b;var d,e=[];if(b){var f=[];for(d in this.registered)this.registered.hasOwnProperty(d)&&f.push(this.registered[d]);f.sort(function(a,b){return b.priority-a.priority}),a.each(f,function(a,b){e.push(b.name)})}else for(d in this.registered)this.registered.hasOwnProperty(d)&&e.push(d);return e},register:function(a,b,d){if(!c.string(a)||c.empty(a)||!c.fn(b))return!1;d=c.number(d)?d:0;var e=this.registered[a];return this.registered[a]={name:a,klass:b,priority:c.undef(e)?d:e.priority},!0}}))}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c){if("0.0.8"===a.version){var d=!1;try{d=!!window.localStorage}catch(a){d=!1}a.Debugger=a.Class.extend({construct:function(a){this.key=a,this.enabled=!!d&&!!localStorage.getItem(this.key)},enable:function(){d&&(this.enabled=!0,localStorage.setItem(this.key,this.enabled))},disable:function(){d&&(this.enabled=!1,localStorage.removeItem(this.key))},log:function(a,c){this.enabled&&console.log.apply(console,b.arg2arr(arguments))},logf:function(a,d,e){if(this.enabled){var f=b.arg2arr(arguments);a=f.shift(),d=f.shift(),f.unshift(c.format(a,d)),this.log.apply(this,f)}}})}}(FooGallery.utils,FooGallery.utils.fn,FooGallery.utils.str),function(a,b,c){"0.0.8"===b.version&&(b.Throttle=b.Class.extend({construct:function(a){this.id=null,this.active=!1,this.idle=c.number(a)?a:0},limit:function(a){if(c.fn(a)){this.clear();var b=this;this.active=!0,this.id=setTimeout(function(){b.active=!1,b.id=null,a()},this.idle)}},clear:function(){c.number(this.id)&&(clearTimeout(this.id),this.active=!1,this.id=null)}}))}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d,e){b.debug=new c.Debugger("__FooGallery__"),c.selectify=function(b){if(d.empty(b))return null;if(d.hash(b)){var e,f={};for(var g in b)b.hasOwnProperty(g)&&(e=c.selectify(b[g]))&&(f[g]=e);return f}return d.string(b)||d.array(b)?(d.string(b)&&(b=[b]),a.map(b,function(a){return d.string(a)?"."+a.split(/\s/g).join("."):null}).join(",")):null},b.emptyImage="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",b.dataTemplate="__FooGallery__",b.dataItem="__FooGalleryItem__",b.init=function(a,c){return b.template.make(a,c).initialize()},b.initAll=function(c){return e.when(a(".foogallery").map(function(a,d){return b.init(c,d)}).get())},b.parseSrc=function(b,c,e,f,g,h){if(!d.string(b))return null;if(!d.string(f))return b;var i=a.map(f.replace(/(\s[\d.]+[whx]),/g,"$1 @,@ ").split(" @,@ "),function(a){return{url:/^\s*(\S*)/.exec(a)[1],w:parseFloat((/\S\s+(\d+)w/.exec(a)||[0,1/0])[1]),h:parseFloat((/\S\s+(\d+)h/.exec(a)||[0,1/0])[1]),x:parseFloat((/\S\s+([\d.]+)x/.exec(a)||[0,1])[1])}});if(!i.length)return b;i.unshift({url:b,w:i[0].w!==1/0&&i[0].h===1/0?c:1/0,h:i[0].h!==1/0&&i[0].w===1/0?e:1/0,x:1});var j,k=window.devicePixelRatio||1,l={w:g*k,h:h*k,x:k};for(j in l)l.hasOwnProperty(j)&&(i=a.grep(i,function(a,b){return function(c){return c[a]>=l[a]||c[a]===b}}(j,Math.max.apply(null,a.map(i,function(a){return a[j]})))));for(j in l)l.hasOwnProperty(j)&&(i=a.grep(i,function(a,b){return function(c){return c[a]===b}}(j,Math.min.apply(null,a.map(i,function(a){return a[j]})))));return i[0].url},a.fn.foogallery=function(c,e){return this.each(function(f,g){if(d.string(c)){var h=a.data(g,b.dataTemplate);if(h instanceof b.Template)switch(c){case"layout":return void h.layout();case"destroy":return void h.destroy()}}else b.template.make(c,g).initialize().then(function(a){d.fn(e)&&e(a)})})}}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c,d,e,f){b.TemplateFactory=c.Factory.extend({construct:function(){this.registered={}},register:function(a,b,c,e,f,g){var h=this,i=h._super(a,b,g);if(i){var j=h.registered;j[a].opt=d.hash(c)?c:{},j[a].cls=d.hash(e)?e:{},j[a].il8n=d.hash(f)?f:{}}return i},make:function(b,c){c=d.jq(c)?c:a(c),b=f.extend({},b,c.data("foogallery"));var e=this,g=e.type(b,c);return e.contains(g)?(b=e.options(g,b),e._super(g,b,c)):null},type:function(b,e){e=d.jq(e)?e:a(e);var f=this,g=d.hash(b)&&d.hash(b)&&d.string(b.type)&&f.contains(b.type)?b.type:"core";if("core"===g&&e.length>0)for(var h=f.registered,i=f.names(!0),j=0,k=i.length;j<k;j++)if(h.hasOwnProperty(i[j])){var l=i[j],m=h[l].cls;if(d.string(m.container)){var n=c.selectify(m.container);if(e.is(n)){g=i[j];break}}}return g},configure:function(a,b,c,d){var e=this;if(e.contains(a)){var g=e.registered;f.extend(g[a].opt,b),f.extend(g[a].cls,c),f.extend(g[a].il8n,d)}},options:function(a,c){c=f.extend({type:a},c);var e=this,g=e.registered,h=g.core.opt,i=g.core.cls,j=g.core.il8n;return d.hash(c.cls)||(c.cls={}),d.hash(c.il8n)||(c.il8n={}),d.undef(b.filtering)||(c=b.filtering.merge(c)),d.undef(b.paging)||(c=b.paging.merge(c)),"core"!==a&&e.contains(a)?(c=f.extend({},h,g[a].opt,c),c.cls=f.extend({},i,g[a].cls,c.cls),c.il8n=f.extend({},j,g[a].il8n,c.il8n)):(c=f.extend({},h,c),c.cls=f.extend({},i,c.cls),c.il8n=f.extend({},j,c.il8n)),c}}),b.template=new b.TemplateFactory}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d,e){a.PagingFactory=b.Factory.extend({construct:function(){this.registered={}},register:function(a,b,d,e,f,g,h){var i=this,j=i._super(a,b,h);if(j){var k=i.registered;k[a].ctrl=c.fn(d)?d:null,k[a].opt=c.hash(e)?e:{},k[a].cls=c.hash(f)?f:{},k[a].il8n=c.hash(g)?g:{}}return j},type:function(a){var b,d=this;return c.hash(a)&&c.hash(b=a.paging)&&c.string(b.type)&&d.contains(b.type)?b.type:null},merge:function(a){a=e.extend({},a);var b=this,d=b.type(a),f=b.registered,g=f.default.opt,h=f.default.cls,i=f.default.il8n,j=c.hash(a.paging)?a.paging:{},k=c.hash(a.cls)&&c.hash(a.cls.paging)?e.extend({},a.cls.paging):{},l=c.hash(a.il8n)&&c.hash(a.il8n.paging)?e.extend({},a.il8n.paging):{};return c.hash(a.cls)||(a.cls={}),c.hash(a.il8n)||(a.il8n={}),"default"!==d&&b.contains(d)?(a.paging=e.extend({},g,f[d].opt,j,{type:d}),a.cls=e.extend(a.cls,{paging:h},{paging:f[d].cls},{paging:k}),a.il8n=e.extend(a.il8n,{paging:i},{paging:f[d].il8n},{paging:l})):(a.paging=e.extend({},g,j,{type:d}),a.cls=e.extend(a.cls,{paging:h},{paging:k}),a.il8n=e.extend(a.il8n,{paging:i},{paging:l})),a},configure:function(a,b,c,d){var f=this;if(f.contains(a)){var g=f.registered;e.extend(g[a].opt,b),e.extend(g[a].cls,c),e.extend(g[a].il8n,d)}},hasCtrl:function(a){var b=this,d=b.registered[a];return c.hash(d)&&c.fn(d.ctrl)},makeCtrl:function(a,b,d,e){var f=this,g=f.registered[a];return c.hash(g)&&c.fn(g.ctrl)?new g.ctrl(b,d,e):null}}),a.paging=new a.PagingFactory}(FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d,e,f){var g=0;b.Template=c.Class.extend({construct:function(e,f){var h=this;h.namespace=".foogallery-"+ ++g,h.$el=d.jq(f)?f:a(f),h.opt=e,h.template=e.template,h.id=h.$el.prop("id")||e.id,h.cls=e.cls,h.il8n=e.il8n,h.sel=c.selectify(h.cls),h.items=b.components.make("items",h),h.pages=d.undef(b.paging)?null:b.paging.make(e.paging.type,h),h.filter=d.undef(b.filtering)?null:b.filtering.make(e.filtering.type,h),h.state=b.components.make("state",h),h._initialize=null,h.initializing=!1,h.initialized=!1,h.destroying=!1,h.destroyed=!1,h._undo={classes:"",style:"",create:!1,children:!1}},initialize:function(f){var g=this;return d.promise(g._initialize)?g._initialize:(f=d.jq(f)?f:a(f),g._initialize=a.Deferred(function(h){if(g.initializing=!0,0===f.length&&0===g.$el.parent().length)return void h.reject("A parent element is required.");0===g.$el.length&&(g.$el=g.create(),g._undo.create=!0),f.length>0&&g.$el.appendTo(f);var i,j=a.Deferred(),k=j.promise();g.$el.length>0&&(i=g.$el.data(b.dataTemplate))instanceof b.Template?k=k.then(function(){return i.destroy().then(function(){g.$el.data(b.dataTemplate,g)})}):g.$el.data(b.dataTemplate,g),k.then(function(){if(g.destroying)return e.rejectWith("destroy in progress");d.empty(g.opt.on)||g.$el.on(g.opt.on),g._undo.classes=g.$el.attr("class"),g._undo.style=g.$el.attr("style"),g.$el.is(g.sel.container)||g.$el.addClass(g.cls.container);var a=c.selectify(g.opt.classes);return null==a||g.$el.is(a)||g.$el.addClass(g.opt.classes),0==g.$el.children().length&&(g.$el.append(g.createChildren()),g._undo.children=!0),g.raise("pre-init").isDefaultPrevented()?e.rejectWith("pre-init default prevented"):void 0}).then(function(){return g.destroying?e.rejectWith("destroy in progress"):g.opt.delay<=0?e.resolved:a.Deferred(function(a){g._delay=setTimeout(function(){g._delay=null,a.resolve()},g.opt.delay)}).promise()}).then(function(){return g.destroying?e.rejectWith("destroy in progress"):g.raise("init").isDefaultPrevented()?e.rejectWith("init default prevented"):g.items.fetch()}).then(function(){if(g.destroying)return e.rejectWith("destroy in progress");if(g.raise("post-init").isDefaultPrevented())return e.rejectWith("post-init default prevented");var b=g.state.parse();g.state.set(d.empty(b)?g.state.initial():b),a(window).on("scroll"+g.namespace,{self:g},g.throttle(g.onWindowScroll,g.opt.throttle)).on("popstate"+g.namespace,{self:g},g.onWindowPopState)}).then(function(){return g.destroying?e.rejectWith("destroy in progress"):(g.raise("first-load"),g.loadAvailable())}).then(function(){if(g.destroying)return e.rejectWith("destroy in progress");g.initializing=!1,g.initialized=!0,g._check(200),g._check(500),g._check(1e3),g._check(2e3),g._check(5e3),g.raise("ready"),h.resolve(g)}).fail(function(a){h.reject(a)}),j.resolve()}).promise().fail(function(a){console.log("initialize failed",g,a),g.destroy()}))},create:function(){var b=this;return a("<div/>",{id:b.id,class:b.cls.container}).addClass(b.opt.classes)},createChildren:function(){return a()},destroy:function(){var b=this;return b.destroyed?e.resolved:(b.destroying=!0,a.Deferred(function(a){b.initializing&&d.promise(b._initialize)?b._initialize.always(function(){b.destroying=!1,b._destroy(),a.resolve()}):(b.destroying=!1,b._destroy(),a.resolve())}).promise())},_destroy:function(){var c=this;c.destroyed||(c.raise("destroy"),a(window).off(c.namespace),c.state.destroy(),c.filter&&c.filter.destroy(),c.pages&&c.pages.destroy(),c.items.destroy(),d.empty(c.opt.on)||c.$el.off(c.opt.on),c.raise("destroyed"),c.$el.removeData(b.dataTemplate),d.empty(c._undo.classes)?c.$el.removeAttr("class"):c.$el.attr("class",c._undo.classes),d.empty(c._undo.style)?c.$el.removeAttr("style"):c.$el.attr("style",c._undo.style),c._undo.children&&c.$el.empty(),c._undo.create&&c.$el.remove(),c.$el=c.state=c.items=c.pages=null,c.destroyed=!0,c.initializing=!1,c.initialized=!1)},getAvailable:function(){return this.pages?this.pages.available():this.items.available()},loadAvailable:function(){return this.items.load(this.getAvailable())},_check:function(a){a=d.number(a)?a:0;var b=this;setTimeout(function(){!b.initialized||b.destroying&&b.destroyed||b.loadAvailable()},a)},raise:function(c,e){if(!d.string(c)||d.empty(c))return null;e=d.array(e)?e:[];var g=this,h=c.split(".")[0],i=f.camel("on-"+h),j=a.Event(h+".foogallery");return e.unshift(g),g.$el.trigger(j,e),b.debug.logf("{id}|{name}:",{id:g.id,name:h},e),d.fn(g[i])&&(e.unshift(j),g[i].apply(g.$el.get(0),e)),j},layout:function(){var a=this;null!==a._initialize&&a.raise("layout")},throttle:function(a,b){var c=Date.now();return function(){if(c+b-Date.now()<0){var d=e.arg2arr(arguments);a.apply(this,d),c=Date.now()}}},onWindowPopState:function(a){var b=a.data.self,c=a.originalEvent.state;d.empty(c)||c.id!==b.id||(b.state.set(c),b.loadAvailable())},onWindowScroll:function(a){a.data.self.loadAvailable()}}),b.template.register("core",b.Template,{id:null,type:"core",classes:"",on:{},lazy:!0,viewport:200,items:[],delay:100,throttle:50,timeout:6e4,srcset:"data-srcset",src:"data-src",template:{}},{container:"foogallery"},{},-100)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.str),function(a,b){a.Component=b.Class.extend({construct:function(a){this.tmpl=a},destroy:function(){this.tmpl=null}}),a.components=new b.Factory}(FooGallery,FooGallery.utils),function(a,b,c,d){b.State=b.Component.extend({construct:function(a){var b=this;b._super(a),b.apiEnabled=!!window.history&&!!history.replaceState,b.opt=b.tmpl.opt.state,b.enabled=b.opt.enabled,b.pushOrReplace=b.isPushOrReplace(b.opt.pushOrReplace)?b.opt.pushOrReplace:"replace";var c=d.escapeRegExp(b.tmpl.id),e=d.escapeRegExp(b.opt.values),f=d.escapeRegExp(b.opt.pair);b.regex={exists:new RegExp("^#"+c+"\\"+e+".+?"),values:new RegExp("(\\w+)"+f+"([^"+e+"]+)","g")}},destroy:function(){var a=this;a.clear(),a.opt=a.regex={},a._super()},isPushOrReplace:function(b){return-1!==a.inArray(b,["push","replace"])},exists:function(){return this.regex.exists.test(location.hash)&&this.regex.values.test(location.hash)},parse:function(){var b=this,d={};if(b.exists())if(b.enabled){d.id=b.tmpl.id;var e=location.hash.match(b.regex.values);a.each(e,function(e,f){var g=f.split(b.opt.pair);2===g.length&&(d[g[0]]=-1===g[1].indexOf(b.opt.array)?decodeURIComponent(g[1]):a.map(g[1].split(b.opt.array),function(a){return decodeURIComponent(a)}),c.string(d[g[0]])&&!isNaN(d[g[0]])&&(d[g[0]]=parseInt(d[g[0]])))})}else b.apiEnabled?history.replaceState(null,"",location.pathname+location.search):location.hash="#";return d},hashify:function(b){var d=this;if(c.hash(b)){var e=[];return a.each(b,function(b,f){c.empty(f)||"id"===b||(f=c.array(f)?a.map(f,function(a){return encodeURIComponent(a)}).join("+"):encodeURIComponent(f),e.push(b+d.opt.pair+f))}),e.length>0&&e.unshift("#"+d.tmpl.id),e.join(d.opt.values)}return""},replace:function(a){var b=this;if(b.enabled&&b.apiEnabled){a.id=b.tmpl.id;var d=b.hashify(a),e=c.empty(d);history.replaceState(e?null:a,"",e?location.pathname+location.search:d)}},push:function(a){var b=this;if(b.enabled&&b.apiEnabled){a.id=b.tmpl.id;var d=b.hashify(a),e=c.empty(d);history.pushState(e?null:a,"",e?location.pathname+location.search:d)}},update:function(a,b){var c=this;c.enabled&&c.apiEnabled&&(b=c.isPushOrReplace(b)?b:c.pushOrReplace,c[b](a))},clear:function(){this.exists()&&this.replace({})},initial:function(){var a=this,b=a.tmpl,d={};return b.filter&&!c.empty(b.filter.current)&&(d.f=b.filter.current),b.pages&&b.pages.current>1&&(d.p=b.pages.current),d},get:function(a){var d=this,e=d.tmpl,f={};return a instanceof b.Item&&(f.i=a.id),e.filter&&!c.empty(e.filter.current)&&(f.f=e.filter.current),e.pages&&e.pages.isValid(e.pages.current)&&(f.p=e.pages.current),f},set:function(a){var b=this,d=b.tmpl;if(c.hash(a)){d.items.reset();var e=d.items.get(a.i);if(d.filter){d.filter.rebuild();var f=c.empty(a.f)?[]:a.f;d.filter.set(f,!1)}if(d.pages){d.pages.rebuild();var g=d.pages.number(a.p);e&&!d.pages.contains(g,e)&&(g=d.pages.find(e),g=0!==g?g:1),d.pages.set(g,!c.empty(a),!1),e&&d.pages.contains(g,e)&&e.scrollTo()}else d.items.detach(d.items.all()),d.items.create(d.items.available(),!0),e&&e.scrollTo();c.empty(a.i)||(a.i=null,b.replace(a))}}}),b.template.configure("core",{state:{enabled:!1,pushOrReplace:"replace",values:"/",pair:":",array:"+"}}),b.components.register("state",b.State)}(FooGallery.$,FooGallery,FooGallery.utils.is,FooGallery.utils.str),function(a,b,c,d,e,f){b.Item=b.Component.extend({construct:function(a,b){var c=this;c._super(a),c.cls=a.cls.item,c.il8n=a.il8n.item,c.sel=a.sel.item,c.opt=f.extend({},a.opt.item,b),c.isAttached=!1,c.isCreated=!1,c.isLoading=!1,c.isLoaded=!1,c.isError=!1,c.isParsed=!1,c.$el=null,c.$inner=null,c.$anchor=null,c.$image=null,c.$caption=null,c.type=c.opt.type,c.id=c.opt.id,c.href=c.opt.href,c.src=c.opt.src,c.srcset=c.opt.srcset,c.width=c.opt.width,c.height=c.opt.height,c.title=c.opt.title,c.alt=c.opt.alt,c.caption=d.empty(c.opt.caption)?c.title:c.opt.caption,c.description=d.empty(c.opt.description)?c.alt:c.opt.description,c.attr=c.opt.attr,c.tags=c.opt.tags,c.maxWidth=c.opt.maxWidth,c.maxCaptionLength=c.opt.maxCaptionLength,c.maxDescriptionLength=c.opt.maxDescriptionLength,c.showCaptionTitle=c.opt.showCaptionTitle,c.showCaptionDescription=c.opt.showCaptionDescription,c._thumbUrl=null,c._placeholder=null,c._load=null,c._undo={classes:"",style:"",loader:!1,placeholder:!1}},destroy:function(){var a=this;return a.tmpl.raise("destroy-item").isDefaultPrevented()||(a.doDestroyItem(),a._super()),null===a.tmpl},doDestroyItem:function(){var a=this;a.isParsed?(a.append(),d.empty(a._undo.classes)?a.$el.removeAttr("class"):a.$el.attr("class",a._undo.classes),d.empty(a._undo.style)?a.$el.removeAttr("style"):a.$el.attr("style",a._undo.style),a._undo.loader&&a.$el.find(a.sel.loader).remove(),a._undo.placeholder&&a.$image.prop("src")==a._placeholder&&a.$image.removeAttr("src")):a.isCreated&&(a.detach(),a.$el.remove())},parse:function(b){var c=this,d=a(b);return!c.tmpl.raise("parse-item",[c,d]).isDefaultPrevented()&&(c.isCreated=d.is(c.sel.elem))&&(c.isParsed=c.doParseItem(d),c.fix()),c.isParsed&&c.tmpl.raise("parsed-item",[c]),c.isParsed},doParseItem:function(c){var e=this,f=e.tmpl.opt,g=e.cls,h=e.sel;return e._undo.classes=c.attr("class")||"",e._undo.style=c.attr("style")||"",e.$el=c.data(b.dataItem,e),e.$inner=e.$el.find(h.inner),e.$anchor=e.$el.find(h.anchor).on("click.foogallery",{self:e},e.onAnchorClick),e.$image=e.$anchor.find(h.image),e.$caption=e.$el.find(h.caption.elem).on("click.foogallery",{self:e},e.onCaptionClick),e.isAttached=e.$el.parent().length>0,e.isLoading=e.$el.is(h.loading),e.isLoaded=e.$el.is(h.loaded),e.isError=e.$el.is(h.error),e.id=e.$anchor.data("id")||e.id,e.tags=e.$anchor.data("tags")||e.tags,e.href=e.$anchor.attr("href")||e.href,e.src=e.$image.attr(f.src)||e.src,e.srcset=e.$image.attr(f.srcset)||e.srcset,e.width=parseInt(e.$image.attr("width"))||e.width,e.height=parseInt(e.$image.attr("height"))||e.height,e.title=e.$image.attr("title")||e.title,e.alt=e.$image.attr("alt")||e.alt,e.caption=e.$anchor.data("title")||e.$anchor.data("captionTitle")||e.caption||e.title,e.description=e.$anchor.data("description")||e.$anchor.data("captionDesc")||e.description||e.alt,d.empty(e.caption)&&(e.caption=a.trim(e.$caption.find(h.caption.title).html())),
|
10 |
+
d.empty(e.description)&&(e.description=a.trim(e.$caption.find(h.caption.description).html())),d.number(e.maxCaptionLength)&&e.maxCaptionLength>0&&!d.empty(e.caption)&&d.string(e.caption)&&e.caption.length>e.maxCaptionLength&&e.$caption.find(h.caption.title).html(e.caption.substr(0,e.maxCaptionLength)+"…"),d.number(e.maxDescriptionLength)&&e.maxDescriptionLength>0&&!d.empty(e.description)&&d.string(e.description)&&e.description.length>e.maxDescriptionLength&&e.$caption.find(h.caption.description).html(e.description.substr(0,e.maxDescriptionLength)+"…"),0===e.$el.find(h.loader).length&&(e.$el.append(a("<div/>",{class:g.loader})),e._undo.loader=!0),d.empty(e.$image.prop("src"))&&(e._placeholder=e.tmpl.items.placeholder(e.width,e.height),e.$image.prop("src",e._placeholder),e._undo.placeholder=!0),!e.isCreated||!e.isAttached||e.isLoading||e.isLoaded||e.isError||e.$el.addClass(g.idle),!0},create:function(){var a=this;if(!a.isCreated&&d.string(a.href)&&d.string(a.src)&&d.number(a.width)&&d.number(a.height)){a.tmpl.raise("create-item",[a]).isDefaultPrevented()||(a.isCreated=a.doCreateItem()),a.isCreated&&a.tmpl.raise("created-item",[a])}return a.isCreated},doCreateItem:function(){var c=this,e=c.tmpl.opt,f=c.cls,g=c.attr;g.elem.class=f.elem+" "+f.idle,g.inner.class=f.inner,g.anchor.class=f.anchor,g.anchor.href=c.href,g.anchor["data-id"]=c.id,g.anchor["data-title"]=c.caption,g.anchor["data-description"]=c.description,d.empty(c.tags)||(g.anchor["data-tags"]=JSON.stringify(c.tags)),g.image.class=f.image,g.image.src=c.tmpl.items.placeholder(c.width,c.height),g.image[e.src]=c.src,g.image[e.srcset]=c.srcset,g.image.width=c.width,g.image.height=c.height,g.image.title=c.title,g.image.alt=c.alt,c.$el=a("<div/>").attr(g.elem).data(b.dataItem,c),c.$inner=a("<figure/>").attr(g.inner).appendTo(c.$el),c.$anchor=a("<a/>").attr(g.anchor).appendTo(c.$inner).on("click.foogallery",{self:c},c.onAnchorClick),c.$image=a("<img/>").attr(g.image).appendTo(c.$anchor),f=c.cls.caption,g=c.attr.caption,g.elem.class=f.elem,c.$caption=a("<figcaption/>").attr(g.elem).on("click.foogallery",{self:c},c.onCaptionClick);var h=!d.empty(c.caption),i=!d.empty(c.description);if(h||i){g.inner.class=f.inner,g.title.class=f.title,g.description.class=f.description;var j=a("<div/>").attr(g.inner).appendTo(c.$caption);if(h){var k;k=d.number(c.maxCaptionLength)&&c.maxCaptionLength>0&&d.string(c.caption)&&c.caption.length>c.maxCaptionLength?a("<div/>").attr(g.title).html(c.caption.substr(0,c.maxCaptionLength)+"…"):a("<div/>").attr(g.title).html(c.caption),j.append(k)}if(i){var l;l=d.number(c.maxDescriptionLength)&&c.maxDescriptionLength>0&&d.string(c.description)&&c.description.length>c.maxDescriptionLength?a("<div/>").attr(g.description).html(c.description.substr(0,c.maxDescriptionLength)+"…"):a("<div/>").attr(g.description).html(c.description),j.append(l)}}return c.$caption.appendTo(c.$inner),0===c.$el.find(c.sel.loader).length&&c.$el.append(a("<div/>",{class:c.cls.loader})),!0},append:function(){var a=this;if(a.isCreated&&!a.isAttached){a.tmpl.raise("append-item",[a]).isDefaultPrevented()||(a.tmpl.$el.append(a.$el),a.fix(),a.isAttached=!0),a.isAttached&&a.tmpl.raise("appended-item",[a])}return a.isAttached},detach:function(){var a=this;if(a.isCreated&&a.isAttached){a.tmpl.raise("detach-item",[a]).isDefaultPrevented()||(a.$el.detach(),a.unfix(),a.isAttached=!1),a.isAttached||a.tmpl.raise("detached-item",[a])}return!a.isAttached},load:function(){var b=this;if(d.promise(b._load))return b._load;if(!b.isCreated||!b.isAttached)return e.rejectWith("not created or attached");if(b.tmpl.raise("load-item",[b]).isDefaultPrevented())return e.rejectWith("default prevented");var c=b.cls,f=b.$image.get(0),g=f.src;return b.isLoading=!0,b.$el.removeClass(c.idle).removeClass(c.loaded).removeClass(c.error).addClass(c.loading),b._load=a.Deferred(function(a){d.undef(window.InstallTrigger)||(f.src=""),f.onload=function(){f.onload=f.onerror=null,b.isLoading=!1,b.isLoaded=!0,b.$el.removeClass(c.loading).addClass(c.loaded),b.unfix(),b.tmpl.raise("loaded-item",[b]),a.resolve(b)},f.onerror=function(){f.onload=f.onerror=null,b.isLoading=!1,b.isError=!0,b.$el.removeClass(c.loading).addClass(c.error),d.string(g)&&b.$image.prop("src",g),b.tmpl.raise("error-item",[b]),a.reject(b)},f.src=b.getThumbUrl()}).promise()},fix:function(){var a=this;if(!a.tmpl.raise("fix-item",[a]).isDefaultPrevented()&&a.isCreated&&!a.isLoading&&!a.isLoaded&&!a.isError){var b=a.width,c=a.height;if(!isNaN(b)&&!isNaN(c)){var e=d.fn(a.maxWidth)?a.maxWidth(a):a.$image.width();e<=0&&(e=b);var f=e/b,g=c*f;a.$image.css({width:e,height:g})}}return a},unfix:function(){var a=this;return!a.tmpl.raise("unfix-item",[a]).isDefaultPrevented()&&a.isCreated&&a.$image.css({width:"",height:""}),a},getThumbUrl:function(a){a=!!d.boolean(a)&&a;var c=this;return!a&&d.string(c._thumbUrl)?c._thumbUrl:c._thumbUrl=b.parseSrc(c.src,c.width,c.height,c.srcset,c.$anchor.innerWidth(),c.$anchor.innerHeight())},scrollTo:function(a){var b=this;if(b.isAttached){var d=b.bounds(),e=c.getViewportBounds();switch(a){case"top":d.left+=d.width/2-e.width/2,d.top-=e.height/5;break;default:d.left+=d.width/2-e.width/2,d.top+=d.height/2-e.height/2}window.scrollTo(d.left,d.top)}return b},bounds:function(){return this.isAttached?c.getElementBounds(this.$el):null},intersects:function(a){return!!this.isAttached&&this.bounds().intersects(a)},onAnchorClick:function(a){var b=a.data.self,c=b.tmpl.state.get(b);b.tmpl.state.update(c)},onCaptionClick:function(b){var c=b.data.self;a(b.target).is(c.sel.caption.all)&&c.$anchor.length>0&&c.$anchor.get(0).click()}}),b.template.configure("core",{item:{type:"item",id:"",href:"",src:"",srcset:"",width:0,height:0,title:"",alt:"",caption:"",description:"",tags:[],maxWidth:null,maxCaptionLength:0,maxDescriptionLength:0,showCaptionTitle:!0,showCaptionDescription:!0,attr:{elem:{},inner:{},anchor:{},image:{},caption:{elem:{},inner:{},title:{},description:{}}}}},{item:{elem:"fg-item",inner:"fg-item-inner",anchor:"fg-thumb",image:"fg-image",loader:"fg-loader",idle:"fg-idle",loading:"fg-loading",loaded:"fg-loaded",error:"fg-error",caption:{elem:"fg-caption",inner:"fg-caption-inner",title:"fg-caption-title",description:"fg-caption-desc"}}},{item:{}}),b.components.register("item",b.Item)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d,e,f){b.Items=b.Component.extend({construct:function(a){var b=this;b._super(a),b.idMap={},b._fetched=null,b._arr=[],b._available=[],b._canvas=document.createElement("canvas");var d=b.tmpl.cls.item.caption;b.tmpl.sel.item.caption.all=c.selectify([d.elem,d.inner,d.title,d.description])},destroy:function(){var b=this,c=b.all(),d=[];c.length>0&&(b.tmpl.raise("destroy-items",[c]),d=a.map(c,function(a){return a.destroy()?a:null}),d.length>0&&b.tmpl.raise("destroyed-items",[d])),b.idMap={},b._canvas=b._fetched=null,b._arr=[],b._available=[],b._super()},fetch:function(b){var c=this;if(!b&&d.promise(c._fetched))return c._fetched;var e=c.tmpl,f=e.sel,g=e.opt.items,h=a.Deferred(),i=c.make(e.$el.find(f.item.elem));return d.empty(g)?(i.push.apply(i,c.make(window[e.id+"-items"])),h.resolve(i)):d.array(g)?(i.push.apply(i,c.make(g)),h.resolve(i)):d.string(g)?a.get(g).then(function(a){i.push.apply(i,c.make(a)),h.resolve(i)},function(a,b,c){console.log("FooGallery: GET items error.",g,a,b,c),h.resolve(i)}):h.resolve(i),h.then(function(a){c.setAll(a)}),c._fetched=h.promise()},all:function(){return this._arr.slice()},count:function(a){return a?this.all().length:this.available().length},available:function(){return this._available.slice()},get:function(a){return!d.empty(a)&&this.idMap[a]?this.idMap[a]:null},setAll:function(a){this._arr=d.array(a)?a:[],this.idMap=this.createIdMap(a),this._available=this.all()},setAvailable:function(a){this._available=d.array(a)?a:[]},reset:function(){this.setAvailable(this.all())},placeholder:function(a,c){return this._canvas&&this._canvas.toDataURL&&d.number(a)&&d.number(c)?(this._canvas.width=a,this._canvas.height=c,this._canvas.toDataURL()):b.emptyImage},loadable:function(b){var e,f=this,g=f.tmpl.opt;return g.lazy&&(e=c.getViewportBounds(g.viewport)),d.array(b)?a.map(b,function(a){return a.isCreated&&a.isAttached&&!a.isLoading&&!a.isLoaded&&!a.isError&&(!g.lazy||g.lazy&&a.intersects(e))?a:null}):[]},creatable:function(c){return d.array(c)?a.map(c,function(a){return a instanceof b.Item&&!a.isCreated?a:null}):[]},appendable:function(c){return d.array(c)?a.map(c,function(a){return a instanceof b.Item&&a.isCreated&&!a.isAttached?a:null}):[]},detachable:function(c){return d.array(c)?a.map(c,function(a){return a instanceof b.Item&&a.isCreated&&a.isAttached?a:null}):[]},jquerify:function(b){return a(a.map(b,function(a){return a.$el.get()}))},make:function(c){var e=this,g=[];if(d.jq(c)||d.array(c)){var h=[],i=a.makeArray(c);if(0===i.length)return g;e.tmpl.raise("make-items",[i]).isDefaultPrevented()||(g=a.map(i,function(a){var c=e.type(a),g=f.extend(d.hash(a)?a:{},{type:c}),i=b.components.make(c,e.tmpl,g);return d.element(a)?i.parse(a)?(h.push(i),i):null:i})),g.length>0&&e.tmpl.raise("made-items",[g]),h.length>0&&e.tmpl.raise("parsed-items",[h])}return g},type:function(c){var e;return d.hash(c)?e=c.type:d.element(c)&&(e=a(c).find(this.tmpl.sel.item.anchor).data("type")),d.string(e)&&b.components.contains(e)?e:"item"},create:function(b,c){var e=this,f=[],g=e.creatable(b);if(g.length>0){e.tmpl.raise("create-items",[g]).isDefaultPrevented()||(f=a.map(g,function(a){return a.create()?a:null})),f.length>0&&e.tmpl.raise("created-items",[f])}return d.boolean(c)&&c?e.append(b):f},append:function(b){var c=this,d=[],e=c.appendable(b);if(e.length>0){c.tmpl.raise("append-items",[e]).isDefaultPrevented()||(d=a.map(e,function(a){return a.append()?a:null})),d.length>0&&c.tmpl.raise("appended-items",[d])}return d},detach:function(b){var c=this,d=[],e=c.detachable(b);if(e.length>0){c.tmpl.raise("detach-items",[e]).isDefaultPrevented()||(d=a.map(e,function(a){return a.detach()?a:null})),d.length>0&&c.tmpl.raise("detached-items",[d])}return d},load:function(b){var c=this;if(b=c.loadable(b),b.length>0){if(!c.tmpl.raise("load-items",[b]).isDefaultPrevented()){var d=a.map(b,function(a){return a.load()});return e.when(d).done(function(a){c.tmpl.raise("loaded-items",[a])})}}return e.resolveWith([])},createIdMap:function(b){var c={};return a.each(b,function(a,b){d.empty(b.id)&&(b.id=""+(a+1)),c[b.id]=b}),c}}),b.components.register("items",b.Items)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d){b.Paging=b.Component.extend({construct:function(a){var b=this;b._super(a),b.opt=b.tmpl.opt.paging,b.cls=b.tmpl.cls.paging,b.il8n=b.tmpl.il8n.paging,b.sel=b.tmpl.sel.paging,b.pushOrReplace=b.opt.pushOrReplace,b.type=b.opt.type,b.theme=b.opt.theme,b.size=b.opt.size,b.position=b.opt.position,b.scrollToTop=b.opt.scrollToTop,b.current=0,b.total=0,b.ctrls=[],b._arr=[]},destroy:function(){var b=this;b._arr.splice(0,b._arr.length),a.each(b.ctrls.splice(0,b.ctrls.length),function(a,b){b.destroy()}),b._super()},build:function(){var a=this,c=a.tmpl.items.available();a.total=a.size>0&&c.length>0?Math.ceil(c.length/a.size):1;for(var d=0;d<a.total;d++)a._arr.push(c.splice(0,a.size));if(a.total>1&&b.paging.hasCtrl(a.type)){var e,f,g=a.position;"both"!==g&&"top"!==g||(e=b.paging.makeCtrl(a.type,a.tmpl,a,"top"),e.create()&&(e.append(),a.ctrls.push(e))),"both"!==g&&"bottom"!==g||(f=b.paging.makeCtrl(a.type,a.tmpl,a,"bottom"),f.create()&&(f.append(),a.ctrls.push(f)))}},rebuild:function(){var b=this;b.current=0,b.total=0,b._arr.splice(0,b._arr.length),a.each(b.ctrls.splice(0,b.ctrls.length),function(a,b){b.destroy()}),b.build()},all:function(){return this._arr.slice()},available:function(){return this.get(this.current)},controls:function(b){var c=this;c.isValid(b)&&a.each(c.ctrls,function(a,c){c.update(b)})},isValid:function(a){return d.number(a)&&a>0&&a<=this.total},number:function(a){return this.isValid(a)?a:0===this.current?1:this.current},create:function(a,b){var c=this;a=c.number(a);var d=a-1;c.tmpl.items.detach(c.tmpl.items.all()),c.tmpl.items.create(c._arr[d],!0),c.current=a},get:function(a){var b=this;return b.isValid(a)?(a=b.number(a),b._arr[a-1]):[]},set:function(a,b,c,e){var f=this;if(f.isValid(a)){var g,h=f.number(a);if(h!==f.current){var i=f.current,j=function(){if(c=!d.boolean(c)||c,e=!!d.boolean(e)&&e,c&&1===f.current&&!f.tmpl.state.exists()&&(g=f.tmpl.state.get(),f.tmpl.state.update(g,f.pushOrReplace)),f.controls(a),f.create(h,e),c&&(g=f.tmpl.state.get(),f.tmpl.state.update(g,f.pushOrReplace)),f.scrollToTop&&d.boolean(b)&&b){var j=f.get(f.current);j.length>0&&j[0].scrollTo("top")}f.tmpl.raise("after-page-change",[f.current,i,e])};return!f.tmpl.raise("before-page-change",[f.current,h,j,e]).isDefaultPrevented()&&(j(),!0)}}return!1},find:function(b){for(var c=this,d=0,e=c._arr.length;d<e;d++)if(-1!==a.inArray(b,c._arr[d]))return d+1;return 0},contains:function(b,c){var d=this.get(b);return-1!==a.inArray(c,d)},first:function(){this.goto(1)},last:function(){this.goto(this._arr.length)},prev:function(){this.goto(this.current-1)},next:function(){this.goto(this.current+1)},goto:function(a){var b=this;b.set(a,!0)&&b.tmpl.loadAvailable()}}),b.PagingControl=b.Component.extend({construct:function(a,b,c){var d=this;d._super(a),d.pages=b,d.position=c,d.$container=null},create:function(){var b=this;return b.$container=a("<nav/>",{class:b.pages.cls.container}).addClass(b.pages.theme),!0},destroy:function(){var a=this;a.$container.remove(),a.$container=null},append:function(){var a=this;"top"===a.position?a.$container.insertBefore(a.tmpl.$el):a.$container.insertAfter(a.tmpl.$el)},update:function(a){}}),b.paging.register("default",b.Paging,null,{type:"none",theme:"fg-light",size:30,pushOrReplace:"push",position:"none",scrollToTop:!0},{container:"fg-paging-container"},null,-100)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){b.Dots=b.Paging.extend({}),b.DotsControl=b.PagingControl.extend({construct:function(b,c,d){this._super(b,c,d),this.$container=a(),this.$list=a(),this.$items=a()},create:function(){for(var b,c=this,d=c.pages.cls,e=c.pages.il8n,f=[],g=a("<ul/>",{class:d.list}),h=0,i=c.pages.total;h<i;h++)f.push(b=c.createItem(h+1,e.page)),g.append(b);return c.$list=g,c.$container=a("<nav/>",{class:d.container}).addClass(c.pages.theme).append(g),c.$items=a(a.map(f,function(a){return a.get()})),!0},append:function(){var a=this;"top"===a.position?a.$container.insertBefore(a.tmpl.$el):a.$container.insertAfter(a.tmpl.$el)},destroy:function(){var b=this,c=b.pages.sel;b.$list.find(c.link).off("click.foogallery",b.onLinkClick),b.$container.remove(),b.$container=a(),b.$list=a(),b.$items=a()},update:function(a){this.setSelected(a-1)},setSelected:function(b){var c=this,e=c.pages.cls,f=c.pages.il8n,g=c.pages.sel;c.$items.filter(g.selected).removeClass(e.selected).each(function(b,c){var e=a(c),f=e.data("label"),h=e.find(g.reader);d.string(f)&&0!==h.length&&h.html(f)}),c.$items.eq(b).addClass(e.selected).each(function(b,c){var e=a(c),h=e.find(g.reader),i=h.html();d.string(i)&&0!==h.length&&(e.data("label",i),h.html(f.current))})},createItem:function(b,c,e,f,g){e=d.string(e)?e:b,c=d.string(c)?c:"";var h=this,i=h.pages.opt,j=h.pages.cls,k=a("<a/>",{class:j.link,href:"#page-"+b}).html(e).on("click.foogallery",{self:h,page:b},h.onLinkClick);d.empty(c)||k.attr("title",c.replace(/\{PAGE}/g,b).replace(/\{LIMIT}/g,i.limit+"")),g=d.string(g)?g:c,d.empty(g)||k.prepend(a("<span/>",{class:j.reader,text:g.replace(/\{PAGE}/g,"").replace(/\{LIMIT}/g,i.limit+"")}));var l=a("<li/>",{class:j.item}).append(k);return f=d.string(f)?f:"",d.empty(f)||l.addClass(f),l},onLinkClick:function(b){b.preventDefault();var c=b.data.self,d=b.data.page,e=c.pages.sel;a(this).closest(e.item).is(e.disabled)||(c.pages.set(d,!0),c.tmpl.loadAvailable())}}),b.paging.register("dots",b.Dots,b.DotsControl,{type:"dots",position:"both",pushOrReplace:"push"},{list:"fg-dots",item:"fg-dot-item",link:"fg-dot-link",disabled:"fg-disabled",selected:"fg-selected",visible:"fg-visible",reader:"fg-sr-only"},{current:"Current page",page:"Page {PAGE}"})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c){b.DefaultTemplate=b.Template.extend({}),b.template.register("default",b.DefaultTemplate,null,{container:"foogallery fg-default"})}(FooGallery.$,FooGallery,FooGallery.utils),function(a,b,c,d){b.MasonryTemplate=b.Template.extend({construct:function(a,b){this._super(a,b),this.masonry=null,this.style=null,this.$columnWidth=null},getStylesheet:function(){var a=this;return null===a.style&&(a.style=document.createElement("style"),a.style.appendChild(document.createTextNode("")),document.head.appendChild(a.style)),a.style.sheet},onPreInit:function(b,c){var e=c.sel,f=c.cls;f.layouts=a.map(f.layout,function(a){return a}).join(" ");for(var g=a.map(f.layout,function(a,b){return{key:b,value:a}}),h=0,i=g.length;h<i;h++)if(c.$el.hasClass(g[h].value)){c.template.layout=g[h].key;break}d.string(f.layout[c.template.layout])||(c.template.layout="col4");var j,k,l="fixed"===c.template.layout;if(c.template.isFitWidth=l,c.template.percentPosition=!l,c.template.transitionDuration=0,c.template.itemSelector=e.item.elem,c.$el.removeClass(f.layouts).addClass(f.layout[c.template.layout]),l||(0===c.$el.find(e.gutterWidth).length&&c.$el.prepend(a("<div/>").addClass(f.gutterWidth)),c.template.gutter=e.gutterWidth),0===c.$el.find(e.columnWidth).length&&c.$el.prepend(a("<div/>").addClass(f.columnWidth)),l&&d.number(c.template.columnWidth)){var m=c.$el.find(e.columnWidth).width(c.template.columnWidth);j=c.getStylesheet(),k="#"+c.id+e.container+" "+e.item.elem+" { width: "+m.outerWidth()+"px; }",j.insertRule(k,0)}c.template.columnWidth=e.columnWidth,l&&d.number(c.template.gutter)&&(j=c.getStylesheet(),k="#"+c.id+e.container+" "+e.item.elem+" { margin-bottom: "+c.template.gutter+"px; }",j.insertRule(k,0)),c.masonry=new Masonry(c.$el.get(0),c.template)},onPostInit:function(a,b){b.masonry.layout()},onFirstLoad:function(a,b){b.masonry.layout()},onReady:function(a,b){b.masonry.layout()},onDestroy:function(a,b){b.$el.find(b.sel.columnWidth).remove(),b.$el.find(b.sel.gutterWidth).remove(),b.style&&b.style.parentNode&&b.style.parentNode.removeChild(b.style)},onDestroyed:function(a,b){b.masonry instanceof Masonry&&b.masonry.destroy()},onLayout:function(a,b){b.masonry.layout()},onParsedItems:function(a,b,c){b.masonry.layout()},onAppendedItems:function(a,b,c){c=b.items.jquerify(c),c=b.masonry.addItems(c),b.masonry.layoutItems(c,!0)},onDetachItem:function(a,b,c){a.isDefaultPrevented()||(a.preventDefault(),b.masonry.remove(c.$el),c.isAttached=!1,c.unfix())},onDetachedItems:function(a,b,c){b.masonry.layout()},onLoadedItems:function(a,b,c){b.masonry.layout()}}),b.template.register("masonry",b.MasonryTemplate,{template:{initLayout:!1,isInitLayout:!1,layout:"col4"}},{container:"foogallery fg-masonry",columnWidth:"fg-column-width",gutterWidth:"fg-gutter-width",layout:{fixed:"fg-masonry-fixed",col2:"fg-masonry-2col",col3:"fg-masonry-3col",col4:"fg-masonry-4col",col5:"fg-masonry-5col"}})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){b.Justified=c.Class.extend({construct:function(c,d){this.$el=a(c),this.options=a.extend(!0,{},b.Justified.defaults,d),this._items=[],this._lastRefresh=0,this._refresh=null},init:function(){var b=this;d.string(b.options.maxRowHeight)&&(b.options.maxRowHeight.indexOf("%")?b.options.maxRowHeight=b.options.rowHeight*(parseInt(b.options.maxRowHeight)/100):b.options.maxRowHeight=parseInt(b.options.maxRowHeight)),a(window).on("resize.justified",{self:b},b.onWindowResize),this._refresh=setInterval(function(){b.refresh()},b.options.refreshInterval)},destroy:function(){this._refresh&&clearInterval(this._refresh),a(window).off("resize.justified"),this.$el.removeAttr("style")},refresh:function(){var a=this.getContainerWidth();a!=this._lastRefresh&&(this.layout(),this._lastRefresh=a)},parse:function(){var b=this,c=b.$el.is(":visible"),d=a("<div/>",{class:b.$el.attr("class")}).css({position:"absolute",top:0,left:-9999,visibility:"hidden",maxWidth:b.getContainerWidth()}).appendTo("body");return b._items=b.$el.find(b.options.itemSelector).removeAttr("style").removeClass("fg-positioned").map(function(b,e){var f=a(e),g=0,h=0;if(c)g=f.outerWidth(),h=f.outerHeight();else{var i=f.clone();i.appendTo(d),g=i.outerWidth(),h=i.outerHeight()}return{index:b,width:g,height:h,top:0,left:0,$item:f}}).get(),d.remove(),b._items},getMaxRowHeight:function(){var a=this;return d.string(a.options.maxRowHeight)&&(a.options.maxRowHeight.indexOf("%")?a.options.maxRowHeight=a.options.rowHeight*(parseInt(a.options.maxRowHeight)/100):a.options.maxRowHeight=parseInt(a.options.maxRowHeight)),d.number(a.options.maxRowHeight)?a.options.maxRowHeight:a.options.rowHeight},getContainerWidth:function(){var a=this;return a.$el.is(":visible")?a.$el.width():a.$el.parents(":visible:first").innerWidth()},layout:function(b,c){b=!!d.boolean(b)&&b,c=!d.boolean(c)||c,(b||0===this._items.length)&&this.parse();var e=this,f=0,g=e.getContainerWidth(),h=e.getMaxRowHeight(),i=e.rows(g,h);a.each(i,function(a,b){b.visible&&(a>0&&(f+=e.options.margins),f+=b.height,e.render(b))}),e.$el.height(f),c&&e.getContainerWidth()<g&&e.layout(!1,!1)},render:function(a){for(var b,c=0,d=a.items.length;c<d;c++)b=a.items[c],a.visible?b.$item.css({width:b.width,height:b.height,top:b.top,left:b.left,display:"",maxHeight:this.options.maxRowHeight>0?this.options.maxRowHeight:""}).addClass("fg-positioned"):b.$item.css("display","none")},justify:function(a,b,c,d){var e=this,f=e.options.margins*(a.items.length-1),g=c-f,h=g/a.width;a.width=a.width*h,a.height=a.height*h,a.top=b,a.height>d&&(a.height=d),a.left=0,a.width<g&&(a.left=(g-a.width)/2),a.width+=f;for(var i,j=a.left,k=0,l=a.items.length;k<l;k++)k>0&&(j+=e.options.margins),i=a.items[k],i.left=j,i.top=b,i.width=i.width*h,i.height=i.height*h,i.height>d&&(i.height=d),j+=i.width;return a.height},position:function(a,b,c,d){var e=this,f=e.options.margins*(a.items.length-1),g=c-f;if(a.top=b,a.left=0,a.width<g)switch(d){case"center":a.left=(g-a.width)/2;break;case"right":a.left=g-a.width}a.width+=f;for(var h,i=a.left,j=0,k=a.items.length;j<k;j++)j>0&&(i+=e.options.margins),h=a.items[j],h.left=i,h.top=b,i+=h.width;return a.height},lastRow:function(a,b,c,d){var e=this,f=e.options.margins*(a.items.length-1),g=c-f,h=a.width/g>e.options.justifyThreshold;switch(e.options.lastRow){case"hide":h?e.justify(a,b,c,d):a.visible=!1;break;case"justify":e.justify(a,b,c,d);break;case"nojustify":h?e.justify(a,b,c,d):e.position(a,b,c,"left");break;case"left":case"center":case"right":h?e.justify(a,b,c,d):e.position(a,b,c,e.options.lastRow)}},items:function(){return a.map(this._items,function(a){return{index:a.index,width:a.width,height:a.height,$item:a.$item,top:a.top,left:a.left}})},rows:function(a,b){function c(){var a={index:++h,visible:!0,width:0,height:e.options.rowHeight,top:0,left:0,items:[]};return g.push(a),a}for(var d,e=this,f=e.items(),g=[],h=-1,i=c(),j=0,k=0,l=0,m=f.length;l<m;l++){if(d=f[l],d.height!=e.options.rowHeight){var n=e.options.rowHeight/d.height;d.height=d.height*n,d.width=d.width*n}k+d.width>a&&l>0&&(g.length>1&&(j+=e.options.margins),j+=e.justify(i,j,a,b),i=c(),k=0),i.items.length>0&&(k+=e.options.margins),k+=d.width,i.width+=d.width,i.items.push(d)}return g.length>1&&(j+=e.options.margins),e.lastRow(i,j,a,b),g},onWindowResize:function(a){a.data.self.layout()}}),b.Justified.defaults={itemSelector:".fg-item",rowHeight:150,maxRowHeight:"200%",margins:0,lastRow:"center",justifyThreshold:.5,refreshInterval:250}}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c){b.JustifiedTemplate=b.Template.extend({onPreInit:function(a,c){c.justified=new b.Justified(c.$el.get(0),c.template)},onInit:function(a,b){b.justified.init()},onFirstLoad:function(a,b){b.justified.layout(!0)},onReady:function(a,b){b.justified.layout(!0)},onDestroy:function(a,b){b.justified.destroy()},onLayout:function(a,b){b.justified.layout(!0)},onParsedItems:function(a,b,c){b.initialized&&b.justified.layout(!0)},onAppendedItems:function(a,b,c){b.initialized&&b.justified.layout(!0)},onDetachedItems:function(a,b,c){b.initialized&&b.justified.layout(!0)}}),b.template.register("justified",b.JustifiedTemplate,null,{container:"foogallery fg-justified"})}(FooGallery.$,FooGallery,FooGallery.utils),function(a,b,c,d){b.Portfolio=c.Class.extend({construct:function(c,d){this.$el=a(c),this.options=a.extend(!0,{},b.Portfolio.defaults,d),this._items=[]},init:function(){var b=this;a(window).on("resize.portfolio",{self:b},b.onWindowResize)},destroy:function(){a(window).off("resize.portfolio"),this.$el.removeAttr("style")},parse:function(){var b=this,c=b.$el.is(":visible"),d=a("<div/>",{class:b.$el.attr("class")}).css({position:"absolute",top:0,left:-9999,visibility:"hidden",maxWidth:b.getContainerWidth()}).appendTo("body");return b._items=b.$el.find(".fg-item").removeAttr("style").removeClass("fg-positioned").map(function(b,e){var f=a(e),g=f.find(".fg-thumb"),h=f.find(".fg-image"),i=0,j=0;if(f.find(".fg-caption").css("max-width",parseFloat(h.attr("width"))),h.css({width:h.attr("width"),height:h.attr("height")}),c)i=f.outerWidth(),j=f.outerHeight();else{var k=f.clone();k.appendTo(d),i=k.outerWidth(),j=k.outerHeight()}return h.css({width:"",height:""}),{index:b,width:i,height:j,top:0,left:0,$item:f,$thumb:g}}).get(),d.remove(),b._items},round:function(a){return Math.round(2*a)/2},getContainerWidth:function(){var a=this;return a.$el.is(":visible")?a.$el.width():a.$el.parents(":visible:first").innerWidth()},layout:function(a,b){a=!!d.boolean(a)&&a,b=!d.boolean(b)||b,(a||0===this._items.length)&&this.parse();for(var c,e=this,f=e.getContainerWidth(),g=e.rows(f),h=0,i=0,j=g.length;i<j;i++)c=g[i],h=e.position(c,f,h,e.options.align),e.render(c);e.$el.height(h),b&&e.getContainerWidth()<f&&e.layout(!1,!1)},render:function(a){for(var b,c=0,d=a.items.length;c<d;c++)b=a.items[c],a.visible?b.$item.css({width:b.width,height:a.height,top:b.top,left:b.left,display:""}).addClass("fg-positioned"):b.$item.css("display","none")},position:function(a,b,c,d){var e=this,f=a.items[a.items.length-1],g=b-(f.left+f.width);a.index>0&&(c+=e.options.gutter),a.top=c;for(var h,i=0,j=a.items.length;i<j;i++)h=a.items[i],h.top=c,"center"===d?h.left+=g/2:"right"===d&&(h.left+=g);return c+a.height},items:function(){return a.map(this._items,function(a){return{index:a.index,width:a.width,height:a.height,$item:a.$item,$thumb:a.$thumb,top:a.top,left:a.left}})},rows:function(a){for(var b=this,c=b.items(),d=[],e=c.length>0,f=-1,g=0;e;){f+=1,f>0&&(g+=b.options.gutter);for(var h,i,j,k={index:f,visible:!0,top:g,width:0,height:0,items:[]},l=[],m=0,n=0,o=c.length;n<o&&(i=c[n],!((h=k.width+i.width)>a&&n>0));n++)h>a&&0==n&&(h=a,j=a/i.width,i.width=b.round(i.width*j),i.height=b.round(i.height*j),k.height=i.height),i.top=k.top,n>0&&(m+=b.options.gutter),n!==o-1&&(h+=b.options.gutter),i.left=m,m+=i.width,i.height>k.height&&(k.height=i.height),k.width=h,k.items.push(i),l.push(n);if(0===l.length){e=!1;break}l.sort(function(a,b){return b-a});for(var p=0,q=l.length;p<q;p++)c.splice(l[p],1);d.push(k),e=c.length>0}return d},onWindowResize:function(a){a.data.self.layout()}}),b.Portfolio.defaults={gutter:40,align:"center"}}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c){b.PortfolioTemplate=b.Template.extend({construct:function(a,b){this._super(a,b),this.portfolio=null},onPreInit:function(a,c){c.portfolio=new b.Portfolio(c.$el.get(0),c.template)},onInit:function(a,b){b.portfolio.init()},onFirstLoad:function(a,b){b.portfolio.layout(!0)},onReady:function(a,b){b.portfolio.layout(!0)},onDestroy:function(a,b){b.portfolio.destroy()},onLayout:function(a,b){b.portfolio.layout(!0)},onParsedItems:function(a,b,c){b.initialized&&b.portfolio.layout(!0)},onAppendedItems:function(a,b,c){b.initialized&&b.portfolio.layout(!0)},onDetachedItems:function(a,b,c){b.initialized&&b.portfolio.layout(!0)}}),b.template.register("simple_portfolio",b.PortfolioTemplate,{gutter:40},{container:"foogallery fg-simple_portfolio"})}(FooGallery.$,FooGallery,FooGallery.utils),function(a,b,c,d){b.ImageViewerTemplate=b.Template.extend({construct:function(b,c){this._super(d.extend({},b,{paging:{pushOrReplace:"replace",theme:"fg-light",type:"default",size:1,position:"none",scrollToTop:!1}}),c),this.$inner=a(),this.$current=a(),this.$total=a(),this.$prev=a(),this.$next=a()},createChildren:function(){var b=this;return a("<div/>",{class:b.cls.inner}).append(a("<div/>",{class:b.cls.innerContainer}),a("<div/>",{class:b.cls.controls}).append(a("<div/>",{class:b.cls.prev}).append(a("<span/>",{text:b.il8n.prev})),a("<label/>",{class:b.cls.count,text:b.il8n.count}).prepend(a("<span/>",{class:b.cls.countCurrent,text:"0"})).append(a("<span/>",{class:b.cls.countTotal,text:"0"})),a("<div/>",{class:b.cls.next}).append(a("<span/>",{text:b.il8n.next}))))},onPreInit:function(a,b){b.$inner=b.$el.find(b.sel.innerContainer),b.$current=b.$el.find(b.sel.countCurrent),b.$total=b.$el.find(b.sel.countTotal),b.$prev=b.$el.find(b.sel.prev),b.$next=b.$el.find(b.sel.next)},onInit:function(a,b){b.template.attachFooBox&&b.$el.on("foobox.previous",{self:b},b.onFooBoxPrev).on("foobox.next",{self:b},b.onFooBoxNext),b.$prev.on("click",{self:b},b.onPrevClick),b.$next.on("click",{self:b},b.onNextClick)},onFirstLoad:function(a,b){b.update()},onDestroy:function(a,b){b.template.attachFooBox&&b.$el.off({"foobox.previous":b.onFooBoxPrev,"foobox.next":b.onFooBoxNext}),b.$prev.off("click",b.onPrevClick),b.$next.off("click",b.onNextClick)},onAppendItem:function(a,b,c){a.preventDefault(),b.$inner.append(c.$el),c.fix(),c.isAttached=!0},onAfterPageChange:function(a,b,c,d,e){e||b.update()},onAfterFilterChange:function(a,b){b.update()},update:function(){this.pages&&(this.$current.text(this.pages.current),this.$total.text(this.pages.total))},prev:function(){this.pages&&(this.template.loop&&1===this.pages.current?this.pages.last():this.pages.prev(),this.update())},next:function(){this.pages&&(this.template.loop&&this.pages.current===this.pages.total?this.pages.first():this.pages.next(),this.update())},onFooBoxPrev:function(a){a.data.self.prev()},onFooBoxNext:function(a){a.data.self.next()},onPrevClick:function(a){a.preventDefault(),a.stopPropagation(),a.data.self.prev()},onNextClick:function(a){a.preventDefault(),a.stopPropagation(),a.data.self.next()}}),b.template.register("image-viewer",b.ImageViewerTemplate,{template:{attachFooBox:!1,loop:!1}},{container:"foogallery fg-image-viewer",inner:"fiv-inner",innerContainer:"fiv-inner-container",controls:"fiv-ctrls",prev:"fiv-prev",next:"fiv-next",count:"fiv-count",countCurrent:"fiv-count-current",countTotal:"fiv-count-total"},{prev:"Prev",next:"Next",count:"of"})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.obj),function(a,b,c){b.ThumbnailTemplate=b.Template.extend({construct:function(b,d){this._super(c.extend({},b,{filtering:{type:"none"},paging:{type:"none"}}),d),this.$hidden=a()},createChildren:function(){var b=this;return b.$hidden=a("<div/>",{class:b.cls.hidden})},onPreInit:function(a,b){b.$hidden=b.$el.find(b.sel.hidden)},onPostInit:function(b,c){for(var d,e=c.items.all().slice(1),f=0,g=e.length;f<g;f++)d=e[f],c.$hidden.append(a("<a/>",{href:d.href,rel:"lightbox["+c.id+"]"}).attr(d.attr.anchor));c.items.setAll(c.items.all().slice(0,1))}}),b.template.register("thumbnail",b.ThumbnailTemplate,null,{container:"foogallery fg-thumbnail",hidden:"fg-st-hidden"})}(FooGallery.$,FooGallery,FooGallery.utils.obj),function(a,b,c,d){b.triggerPostLoad=function(b,c,d,e,f){("first-load"===b.type||c.initialized&&("after-page-change"===b.type&&!f||"after-filter-change"===b.type))&&a("body").trigger("post-load")},b.autoDefaults={on:{
|
11 |
+
"first-load.foogallery after-page-change.foogallery after-filter-change.foogallery":b.triggerPostLoad}},b.auto=function(a){b.autoDefaults=d.merge(b.autoDefaults,a)},a(function(){a('[id^="foogallery-gallery-"]:not(.fg-ready)').foogallery(b.autoDefaults)}),c.ready(function(){a('[id^="foogallery-gallery-"].fg-ready').foogallery(b.autoDefaults)})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.obj);
|
extensions/default-templates/simple-portfolio/class-simple-portfolio-gallery-template.php
CHANGED
@@ -264,11 +264,17 @@ if ( !class_exists( 'FooGallery_Simple_Portfolio_Gallery_Template' ) ) {
|
|
264 |
*/
|
265 |
function build_thumbnail_dimensions_from_arguments( $dimensions, $arguments ) {
|
266 |
if ( array_key_exists( 'thumbnail_dimensions', $arguments) ) {
|
267 |
-
|
268 |
'height' => intval($arguments['thumbnail_dimensions']['height']),
|
269 |
'width' => intval($arguments['thumbnail_dimensions']['width']),
|
270 |
'crop' => '1'
|
271 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
}
|
273 |
return null;
|
274 |
}
|
@@ -284,9 +290,15 @@ if ( !class_exists( 'FooGallery_Simple_Portfolio_Gallery_Template' ) ) {
|
|
284 |
function get_thumbnail_dimensions( $dimensions, $foogallery ) {
|
285 |
$dimensions = $foogallery->get_meta( 'simple_portfolio_thumbnail_dimensions', array(
|
286 |
'width' => 250,
|
287 |
-
'height' => 200
|
|
|
288 |
) );
|
289 |
-
|
|
|
|
|
|
|
|
|
|
|
290 |
return $dimensions;
|
291 |
}
|
292 |
|
@@ -299,6 +311,9 @@ if ( !class_exists( 'FooGallery_Simple_Portfolio_Gallery_Template' ) ) {
|
|
299 |
function build_gallery_template_arguments( $args ) {
|
300 |
$args = foogallery_gallery_template_setting( 'thumbnail_dimensions', array() );
|
301 |
$args['crop'] = '1'; //we now force thumbs to be cropped
|
|
|
|
|
|
|
302 |
$args['link'] = foogallery_gallery_template_setting( 'thumbnail_link', 'image' );
|
303 |
$args['image_attributes'] = array(
|
304 |
'class' => 'bf-img',
|
264 |
*/
|
265 |
function build_thumbnail_dimensions_from_arguments( $dimensions, $arguments ) {
|
266 |
if ( array_key_exists( 'thumbnail_dimensions', $arguments) ) {
|
267 |
+
$dimensions = array(
|
268 |
'height' => intval($arguments['thumbnail_dimensions']['height']),
|
269 |
'width' => intval($arguments['thumbnail_dimensions']['width']),
|
270 |
'crop' => '1'
|
271 |
);
|
272 |
+
|
273 |
+
if ( 'on' === foogallery_get_setting('enable_legacy_thumb_cropping') ) {
|
274 |
+
$dimensions['crop'] = '0';
|
275 |
+
}
|
276 |
+
|
277 |
+
return $dimensions;
|
278 |
}
|
279 |
return null;
|
280 |
}
|
290 |
function get_thumbnail_dimensions( $dimensions, $foogallery ) {
|
291 |
$dimensions = $foogallery->get_meta( 'simple_portfolio_thumbnail_dimensions', array(
|
292 |
'width' => 250,
|
293 |
+
'height' => 200,
|
294 |
+
'crop' => true
|
295 |
) );
|
296 |
+
|
297 |
+
if ( 'on' === foogallery_get_setting('enable_legacy_thumb_cropping') ) {
|
298 |
+
$dimensions['crop'] = false;
|
299 |
+
} else {
|
300 |
+
$dimensions['crop'] = true;
|
301 |
+
}
|
302 |
return $dimensions;
|
303 |
}
|
304 |
|
311 |
function build_gallery_template_arguments( $args ) {
|
312 |
$args = foogallery_gallery_template_setting( 'thumbnail_dimensions', array() );
|
313 |
$args['crop'] = '1'; //we now force thumbs to be cropped
|
314 |
+
if ( 'on' === foogallery_get_setting('enable_legacy_thumb_cropping') ) {
|
315 |
+
$args['crop'] = '0';
|
316 |
+
}
|
317 |
$args['link'] = foogallery_gallery_template_setting( 'thumbnail_link', 'image' );
|
318 |
$args['image_attributes'] = array(
|
319 |
'class' => 'bf-img',
|
foogallery.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
/*
|
4 |
Plugin Name: FooGallery
|
5 |
Description: FooGallery is the most intuitive and extensible gallery management tool ever created for WordPress
|
6 |
-
Version: 1.4.
|
7 |
Author: FooPlugins
|
8 |
Plugin URI: https://foo.gallery
|
9 |
Author URI: http://fooplugins.com
|
@@ -23,7 +23,7 @@ if ( !class_exists( 'FooGallery_Plugin' ) ) {
|
|
23 |
define( 'FOOGALLERY_PATH', plugin_dir_path( __FILE__ ) );
|
24 |
define( 'FOOGALLERY_URL', plugin_dir_url( __FILE__ ) );
|
25 |
define( 'FOOGALLERY_FILE', __FILE__ );
|
26 |
-
define( 'FOOGALLERY_VERSION', '1.4.
|
27 |
define( 'FOOGALLERY_SETTINGS_VERSION', '2' );
|
28 |
require_once FOOGALLERY_PATH . 'includes/constants.php';
|
29 |
// Create a helper function for easy SDK access.
|
3 |
/*
|
4 |
Plugin Name: FooGallery
|
5 |
Description: FooGallery is the most intuitive and extensible gallery management tool ever created for WordPress
|
6 |
+
Version: 1.4.30
|
7 |
Author: FooPlugins
|
8 |
Plugin URI: https://foo.gallery
|
9 |
Author URI: http://fooplugins.com
|
23 |
define( 'FOOGALLERY_PATH', plugin_dir_path( __FILE__ ) );
|
24 |
define( 'FOOGALLERY_URL', plugin_dir_url( __FILE__ ) );
|
25 |
define( 'FOOGALLERY_FILE', __FILE__ );
|
26 |
+
define( 'FOOGALLERY_VERSION', '1.4.30' );
|
27 |
define( 'FOOGALLERY_SETTINGS_VERSION', '2' );
|
28 |
require_once FOOGALLERY_PATH . 'includes/constants.php';
|
29 |
// Create a helper function for easy SDK access.
|
freemius/.codeclimate.yml
CHANGED
@@ -1,19 +1,19 @@
|
|
1 |
-
engines:
|
2 |
-
phpcodesniffer:
|
3 |
-
enabled: true
|
4 |
-
config:
|
5 |
-
standard: "WordPress"
|
6 |
-
checks:
|
7 |
-
Squiz Commenting InlineComment InvalidEndChar:
|
8 |
-
enabled: false
|
9 |
-
Squiz Commenting InlineComment SpacingBefore:
|
10 |
-
enabled: false
|
11 |
-
Squiz Commenting InlineComment WrongStyle:
|
12 |
-
enabled: false
|
13 |
-
Generic Commenting DocComment MissingShort:
|
14 |
-
enabled: false
|
15 |
-
Generic WhiteSpace ScopeIndent IncorrectExact:
|
16 |
-
enabled: false
|
17 |
-
ratings:
|
18 |
-
paths:
|
19 |
-
- "**.php"
|
1 |
+
engines:
|
2 |
+
phpcodesniffer:
|
3 |
+
enabled: true
|
4 |
+
config:
|
5 |
+
standard: "WordPress"
|
6 |
+
checks:
|
7 |
+
Squiz Commenting InlineComment InvalidEndChar:
|
8 |
+
enabled: false
|
9 |
+
Squiz Commenting InlineComment SpacingBefore:
|
10 |
+
enabled: false
|
11 |
+
Squiz Commenting InlineComment WrongStyle:
|
12 |
+
enabled: false
|
13 |
+
Generic Commenting DocComment MissingShort:
|
14 |
+
enabled: false
|
15 |
+
Generic WhiteSpace ScopeIndent IncorrectExact:
|
16 |
+
enabled: false
|
17 |
+
ratings:
|
18 |
+
paths:
|
19 |
+
- "**.php"
|
freemius/.github/ISSUE_TEMPLATE.md
CHANGED
@@ -1,29 +1,29 @@
|
|
1 |
-
**Actual Behavior**:
|
2 |
-
- `What is the issue? (*)`
|
3 |
-
- `What is the expected behavior?`
|
4 |
-
|
5 |
-
**Versions**: (*)
|
6 |
-
- `Freemius SDK Version:`
|
7 |
-
- `WordPress Version:`
|
8 |
-
- `PHP Version:`
|
9 |
-
|
10 |
-
**Plugin / Theme**: (*)
|
11 |
-
- `Name:`
|
12 |
-
- `Slug:`
|
13 |
-
- `Freemius ID:`
|
14 |
-
|
15 |
-
**Additional Information**:
|
16 |
-
- `Browser Type: (*)`
|
17 |
-
- `Browser Version: (*)`
|
18 |
-
- `OS: (*)`
|
19 |
-
- `Stack Traces:`
|
20 |
-
|
21 |
-
----
|
22 |
-
**Note:** `(*)` indicates required information. Without this information, your issue may be auto-closed.
|
23 |
-
|
24 |
-
> You can find your Freemius SDK version at `/freemius/start.php`
|
25 |
-
|
26 |
-
> You can find your Freemius product ID in the Freemius dashboard: `SETTINGS -> INTEGRATION`.
|
27 |
-
|
28 |
-
> Do not modify the titles or questions. Simply add your responses to the ends of the questions.
|
29 |
-
Add more lines if needed.
|
1 |
+
**Actual Behavior**:
|
2 |
+
- `What is the issue? (*)`
|
3 |
+
- `What is the expected behavior?`
|
4 |
+
|
5 |
+
**Versions**: (*)
|
6 |
+
- `Freemius SDK Version:`
|
7 |
+
- `WordPress Version:`
|
8 |
+
- `PHP Version:`
|
9 |
+
|
10 |
+
**Plugin / Theme**: (*)
|
11 |
+
- `Name:`
|
12 |
+
- `Slug:`
|
13 |
+
- `Freemius ID:`
|
14 |
+
|
15 |
+
**Additional Information**:
|
16 |
+
- `Browser Type: (*)`
|
17 |
+
- `Browser Version: (*)`
|
18 |
+
- `OS: (*)`
|
19 |
+
- `Stack Traces:`
|
20 |
+
|
21 |
+
----
|
22 |
+
**Note:** `(*)` indicates required information. Without this information, your issue may be auto-closed.
|
23 |
+
|
24 |
+
> You can find your Freemius SDK version at `/freemius/start.php`
|
25 |
+
|
26 |
+
> You can find your Freemius product ID in the Freemius dashboard: `SETTINGS -> INTEGRATION`.
|
27 |
+
|
28 |
+
> Do not modify the titles or questions. Simply add your responses to the ends of the questions.
|
29 |
+
Add more lines if needed.
|
freemius/.travis.yml
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
-
sudo: false
|
2 |
-
|
3 |
-
language: php
|
4 |
-
|
5 |
-
php:
|
6 |
-
- 5.3
|
7 |
-
- 5.4
|
8 |
-
- 5.5
|
9 |
-
- 5.6
|
10 |
-
- 7.0
|
11 |
-
- hhvm
|
1 |
+
sudo: false
|
2 |
+
|
3 |
+
language: php
|
4 |
+
|
5 |
+
php:
|
6 |
+
- 5.3
|
7 |
+
- 5.4
|
8 |
+
- 5.5
|
9 |
+
- 5.6
|
10 |
+
- 7.0
|
11 |
+
- hhvm
|
freemius/assets/css/admin/account.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
#fs_account .postbox,#fs_account .widefat{max-width:700px}#fs_account h3{font-size:1.3em;padding:12px 15px;margin:0 0 12px 0;line-height:1.4;border-bottom:1px solid #F1F1F1}#fs_account h3 .dashicons{width:26px;height:26px;font-size:1.3em}#fs_account i.dashicons{font-size:1.2em;height:1.2em;width:1.2em}#fs_account .button i.dashicons{vertical-align:middle}#fs_account .fs-header-actions{position:absolute;top:17px;right:15px;font-size:0.9em}#fs_account .fs-header-actions ul{margin:0}#fs_account .fs-header-actions li{float:left}#fs_account .fs-header-actions li form{display:inline-block}#fs_account .fs-header-actions li a{text-decoration:none}#fs_account_details .button-group{float:right}.rtl #fs_account .fs-header-actions{left:15px;right:auto}.fs-key-value-table{width:100%}.fs-key-value-table form{display:inline-block}.fs-key-value-table tr td:first-child{text-align:right}.fs-key-value-table tr td:first-child nobr{font-weight:bold}.fs-key-value-table tr td:first-child form{display:block}.fs-key-value-table tr td.fs-right{text-align:right}.fs-key-value-table tr.fs-odd{background:#ebebeb}.fs-key-value-table td,.fs-key-value-table th{padding:10px}.fs-key-value-table code{line-height:28px}.fs-key-value-table var,.fs-key-value-table code,.fs-key-value-table input[type="text"]{color:#0073AA;font-size:16px;background:none}.fs-key-value-table input[type="text"]{width:100%;font-weight:bold}label.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error{background:#dc3232}#fs_addons h3{border:none;margin-bottom:0;padding:4px 5px}#fs_addons td{vertical-align:middle}#fs_addons thead{white-space:nowrap}#fs_addons td:first-child,#fs_addons th:first-child{text-align:left;font-weight:bold}#fs_addons td:last-child,#fs_addons th:last-child{text-align:right}#fs_addons th{font-weight:bold}#fs_billing_address{width:100%}#fs_billing_address tr td{width:50%;padding:5px}#fs_billing_address tr:first-of-type td{padding-top:0}#fs_billing_address span{font-weight:bold}#fs_billing_address input,#fs_billing_address select{display:block;width:100%;margin-top:5px}#fs_billing_address input::-moz-placeholder,#fs_billing_address select::-moz-placeholder{color:transparent;opacity:1}#fs_billing_address input:-ms-input-placeholder,#fs_billing_address select:-ms-input-placeholder{color:transparent}#fs_billing_address input::-webkit-input-placeholder,#fs_billing_address select::-webkit-input-placeholder{color:transparent}#fs_billing_address input.fs-read-mode,#fs_billing_address select.fs-read-mode{border-color:transparent;color:#777;border-bottom:1px dashed #ccc;padding-left:0;background:none}#fs_billing_address.fs-read-mode td span{display:none}#fs_billing_address.fs-read-mode input,#fs_billing_address.fs-read-mode select{border-color:transparent;color:#777;border-bottom:1px dashed #ccc;padding-left:0;background:none}#fs_billing_address.fs-read-mode input::-moz-placeholder,#fs_billing_address.fs-read-mode select::-moz-placeholder{color:#ccc;opacity:1}#fs_billing_address.fs-read-mode input:-ms-input-placeholder,#fs_billing_address.fs-read-mode select:-ms-input-placeholder{color:#ccc}#fs_billing_address.fs-read-mode input::-webkit-input-placeholder,#fs_billing_address.fs-read-mode select::-webkit-input-placeholder{color:#ccc}#fs_billing_address button{display:block;width:100%}
|
1 |
+
#fs_account .postbox,#fs_account .widefat{max-width:700px}#fs_account h3{font-size:1.3em;padding:12px 15px;margin:0 0 12px 0;line-height:1.4;border-bottom:1px solid #F1F1F1}#fs_account h3 .dashicons{width:26px;height:26px;font-size:1.3em}#fs_account i.dashicons{font-size:1.2em;height:1.2em;width:1.2em}#fs_account .button i.dashicons{vertical-align:middle}#fs_account .fs-header-actions{position:absolute;top:17px;right:15px;font-size:0.9em}#fs_account .fs-header-actions ul{margin:0}#fs_account .fs-header-actions li{float:left}#fs_account .fs-header-actions li form{display:inline-block}#fs_account .fs-header-actions li a{text-decoration:none}#fs_account_details .button-group{float:right}.rtl #fs_account .fs-header-actions{left:15px;right:auto}.fs-key-value-table{width:100%}.fs-key-value-table form{display:inline-block}.fs-key-value-table tr td:first-child{text-align:right}.fs-key-value-table tr td:first-child nobr{font-weight:bold}.fs-key-value-table tr td:first-child form{display:block}.fs-key-value-table tr td.fs-right{text-align:right}.fs-key-value-table tr.fs-odd{background:#ebebeb}.fs-key-value-table td,.fs-key-value-table th{padding:10px}.fs-key-value-table code{line-height:28px}.fs-key-value-table var,.fs-key-value-table code,.fs-key-value-table input[type="text"]{color:#0073AA;font-size:16px;background:none}.fs-key-value-table input[type="text"]{width:100%;font-weight:bold}label.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error{background:#dc3232}#fs_addons h3{border:none;margin-bottom:0;padding:4px 5px}#fs_addons td{vertical-align:middle}#fs_addons thead{white-space:nowrap}#fs_addons td:first-child,#fs_addons th:first-child{text-align:left;font-weight:bold}#fs_addons td:last-child,#fs_addons th:last-child{text-align:right}#fs_addons th{font-weight:bold}#fs_billing_address{width:100%}#fs_billing_address tr td{width:50%;padding:5px}#fs_billing_address tr:first-of-type td{padding-top:0}#fs_billing_address span{font-weight:bold}#fs_billing_address input,#fs_billing_address select{display:block;width:100%;margin-top:5px}#fs_billing_address input::-moz-placeholder,#fs_billing_address select::-moz-placeholder{color:transparent;opacity:1}#fs_billing_address input:-ms-input-placeholder,#fs_billing_address select:-ms-input-placeholder{color:transparent}#fs_billing_address input::-webkit-input-placeholder,#fs_billing_address select::-webkit-input-placeholder{color:transparent}#fs_billing_address input.fs-read-mode,#fs_billing_address select.fs-read-mode{border-color:transparent;color:#777;border-bottom:1px dashed #ccc;padding-left:0;background:none}#fs_billing_address.fs-read-mode td span{display:none}#fs_billing_address.fs-read-mode input,#fs_billing_address.fs-read-mode select{border-color:transparent;color:#777;border-bottom:1px dashed #ccc;padding-left:0;background:none}#fs_billing_address.fs-read-mode input::-moz-placeholder,#fs_billing_address.fs-read-mode select::-moz-placeholder{color:#ccc;opacity:1}#fs_billing_address.fs-read-mode input:-ms-input-placeholder,#fs_billing_address.fs-read-mode select:-ms-input-placeholder{color:#ccc}#fs_billing_address.fs-read-mode input::-webkit-input-placeholder,#fs_billing_address.fs-read-mode select::-webkit-input-placeholder{color:#ccc}#fs_billing_address button{display:block;width:100%}
|
freemius/assets/css/admin/affiliation.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
@charset "UTF-8";#fs_affiliation_content_wrapper #messages{margin-top:25px}#fs_affiliation_content_wrapper h3{font-size:24px;padding:0;margin-left:0}#fs_affiliation_content_wrapper ul li{box-sizing:border-box;list-style-type:none}#fs_affiliation_content_wrapper ul li:before{content:'✓';margin-right:10px;font-weight:bold}#fs_affiliation_content_wrapper p:not(.description),#fs_affiliation_content_wrapper li,#fs_affiliation_content_wrapper label{font-size:16px !important;line-height:26px !important}#fs_affiliation_content_wrapper .button{margin-top:20px;margin-bottom:7px;line-height:35px;height:40px;font-size:16px}#fs_affiliation_content_wrapper .button#cancel_button{margin-right:5px}#fs_affiliation_content_wrapper form .input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form .input-container .input-label{font-weight:bold;display:block;width:100%}#fs_affiliation_content_wrapper form .input-container.input-container-text label,#fs_affiliation_content_wrapper form .input-container.input-container-text input,#fs_affiliation_content_wrapper form .input-container.input-container-text textarea{display:block}#fs_affiliation_content_wrapper form .input-container #add_domain,#fs_affiliation_content_wrapper form .input-container .remove-domain{text-decoration:none;display:inline-block;margin-top:3px}#fs_affiliation_content_wrapper form .input-container #add_domain:focus,#fs_affiliation_content_wrapper form .input-container .remove-domain:focus{box-shadow:none}#fs_affiliation_content_wrapper form .input-container #add_domain.disabled,#fs_affiliation_content_wrapper form .input-container .remove-domain.disabled{color:#aaa;cursor:default}#fs_affiliation_content_wrapper form #extra_domains_container .description{margin-top:0;position:relative;top:-4px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain{display:inline-block;margin-right:5px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain:last-of-type{margin-bottom:0}
|
1 |
+
@charset "UTF-8";#fs_affiliation_content_wrapper #messages{margin-top:25px}#fs_affiliation_content_wrapper h3{font-size:24px;padding:0;margin-left:0}#fs_affiliation_content_wrapper ul li{box-sizing:border-box;list-style-type:none}#fs_affiliation_content_wrapper ul li:before{content:'✓';margin-right:10px;font-weight:bold}#fs_affiliation_content_wrapper p:not(.description),#fs_affiliation_content_wrapper li,#fs_affiliation_content_wrapper label{font-size:16px !important;line-height:26px !important}#fs_affiliation_content_wrapper .button{margin-top:20px;margin-bottom:7px;line-height:35px;height:40px;font-size:16px}#fs_affiliation_content_wrapper .button#cancel_button{margin-right:5px}#fs_affiliation_content_wrapper form .input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form .input-container .input-label{font-weight:bold;display:block;width:100%}#fs_affiliation_content_wrapper form .input-container.input-container-text label,#fs_affiliation_content_wrapper form .input-container.input-container-text input,#fs_affiliation_content_wrapper form .input-container.input-container-text textarea{display:block}#fs_affiliation_content_wrapper form .input-container #add_domain,#fs_affiliation_content_wrapper form .input-container .remove-domain{text-decoration:none;display:inline-block;margin-top:3px}#fs_affiliation_content_wrapper form .input-container #add_domain:focus,#fs_affiliation_content_wrapper form .input-container .remove-domain:focus{box-shadow:none}#fs_affiliation_content_wrapper form .input-container #add_domain.disabled,#fs_affiliation_content_wrapper form .input-container .remove-domain.disabled{color:#aaa;cursor:default}#fs_affiliation_content_wrapper form #extra_domains_container .description{margin-top:0;position:relative;top:-4px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain{display:inline-block;margin-right:5px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain:last-of-type{margin-bottom:0}
|
freemius/assets/css/admin/connect.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
#fs_connect{width:480px;-moz-box-shadow:0px 1px 2px rgba(0,0,0,0.3);-webkit-box-shadow:0px 1px 2px rgba(0,0,0,0.3);box-shadow:0px 1px 2px rgba(0,0,0,0.3);margin:20px 0}@media screen and (max-width: 479px){#fs_connect{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none;width:auto;margin:0 0 0 -10px}}#fs_connect .fs-content{background:#fff;padding:15px 20px}#fs_connect .fs-content .fs-error{background:snow;color:#d3135a;border:1px solid #d3135a;-moz-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);text-align:center;padding:5px;margin-bottom:10px}#fs_connect .fs-content p{margin:0;padding:0;font-size:1.2em}#fs_connect .fs-license-key-container{position:relative;width:280px;margin:10px auto 0 auto}#fs_connect .fs-license-key-container input{width:100%}#fs_connect .fs-license-key-container .dashicons{position:absolute;top:5px;right:5px}#fs_connect .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}#fs_theme_connect_wrapper{position:fixed;top:0;height:100%;width:100%;z-index:99990;background:rgba(0,0,0,0.75);text-align:center;overflow-y:auto}#fs_theme_connect_wrapper:before{content:"";display:inline-block;vertical-align:middle;height:100%}#fs_theme_connect_wrapper>button.close{color:white;cursor:pointer;height:40px;width:40px;position:absolute;right:0;border:0;background-color:transparent;top:32px}#fs_theme_connect_wrapper #fs_connect{top:0;text-align:left;display:inline-block;vertical-align:middle;margin-top:52px;margin-bottom:20px}#fs_theme_connect_wrapper #fs_connect .fs-terms{background:rgba(140,140,140,0.64)}#fs_theme_connect_wrapper #fs_connect .fs-terms,#fs_theme_connect_wrapper #fs_connect .fs-terms a{color:#c5c5c5}.wp-pointer-content #fs_connect{margin:0;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.fs-opt-in-pointer .wp-pointer-content{padding:0}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow{border-bottom-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#fafafa}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow{border-top-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow-inner{border-top-color:#fafafa}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow{border-right-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow-inner{border-right-color:#fafafa}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow{border-left-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow-inner{border-left-color:#fafafa}
|
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}#fs_theme_connect_wrapper{position:fixed;top:0;height:100%;width:100%;z-index:99990;background:rgba(0,0,0,0.75);text-align:center;overflow-y:auto}#fs_theme_connect_wrapper:before{content:"";display:inline-block;vertical-align:middle;height:100%}#fs_theme_connect_wrapper>button.close{color:white;cursor:pointer;height:40px;width:40px;position:absolute;right:0;border:0;background-color:transparent;top:32px}#fs_theme_connect_wrapper #fs_connect{top:0;text-align:left;display:inline-block;vertical-align:middle;margin-top:52px;margin-bottom:20px}#fs_theme_connect_wrapper #fs_connect .fs-terms{background:rgba(140,140,140,0.64)}#fs_theme_connect_wrapper #fs_connect .fs-terms,#fs_theme_connect_wrapper #fs_connect .fs-terms a{color:#c5c5c5}.wp-pointer-content #fs_connect{margin:0;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.fs-opt-in-pointer .wp-pointer-content{padding:0}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow{border-bottom-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#fafafa}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow{border-top-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow-inner{border-top-color:#fafafa}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow{border-right-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow-inner{border-right-color:#fafafa}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow{border-left-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow-inner{border-left-color:#fafafa}
|
freemius/assets/css/admin/dialog-boxes.css
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
.fs-modal{position:fixed;overflow:auto;height:100%;width:100%;top:0;z-index:100000;display:none;background:rgba(0,0,0,0.6)}.fs-modal .fs-modal-dialog{background:transparent;position:absolute;left:50%;margin-left:-298px;padding-bottom:30px;top:-100%;z-index:100001;width:596px}@media (max-width: 650px){.fs-modal .fs-modal-dialog{margin-left:-50%;box-sizing:border-box;padding-left:10px;padding-right:10px;width:100%}.fs-modal .fs-modal-dialog .fs-modal-panel>h3>strong{font-size:1.3em}}.fs-modal.active{display:block}.fs-modal.active:before{display:block}.fs-modal.active .fs-modal-dialog{top:10%}.fs-modal.fs-success .fs-modal-header{border-bottom-color:#46b450}.fs-modal.fs-success .fs-modal-body{background-color:#f7fff7}.fs-modal.fs-warn .fs-modal-header{border-bottom-color:#ffb900}.fs-modal.fs-warn .fs-modal-body{background-color:#fff8e5}.fs-modal.fs-error .fs-modal-header{border-bottom-color:#dc3232}.fs-modal.fs-error .fs-modal-body{background-color:#ffeaea}.fs-modal .fs-modal-body,.fs-modal .fs-modal-footer{border:0;background:#fefefe;padding:20px}.fs-modal .fs-modal-header{border-bottom:#eeeeee solid 1px;background:#fbfbfb;padding:15px 20px;position:relative;margin-bottom:-10px}.fs-modal .fs-modal-header h4{margin:0;padding:0;text-transform:uppercase;font-size:1.2em;font-weight:bold;color:#cacaca;text-shadow:1px 1px 1px #fff;letter-spacing:0.6px;-webkit-font-smoothing:antialiased}.fs-modal .fs-modal-header .fs-close{position:absolute;right:10px;top:12px;cursor:pointer;color:#bbb;-moz-border-radius:20px;-webkit-border-radius:20px;border-radius:20px;padding:3px;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;-ms-transition:all 0.2s ease-in-out;-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.fs-modal .fs-modal-header .fs-close:hover{color:#fff;background:#aaa}.fs-modal .fs-modal-body{border-bottom:0}.fs-modal .fs-modal-body p{font-size:14px}.fs-modal .fs-modal-body h2{font-size:20px;line-height:1.5em}.fs-modal .fs-modal-body>div{margin-top:10px}.fs-modal .fs-modal-body>div h2{font-weight:bold;font-size:20px;margin-top:0}.fs-modal .fs-modal-footer{border-top:#eeeeee solid 1px;text-align:right}.fs-modal .fs-modal-footer>.button{margin:0 7px}.fs-modal .fs-modal-footer>.button:first-child{margin:0}.fs-modal .fs-modal-panel>.notice.inline{margin:0;display:none}.fs-modal .fs-modal-panel:not(.active){display:none}.rtl .fs-modal .fs-modal-header .fs-close{right:auto;left:20px}body.has-fs-modal{overflow:hidden}.fs-modal.fs-modal-deactivation-feedback .reason-input,.fs-modal.fs-modal-deactivation-feedback .internal-message{margin:3px 0 3px 22px}.fs-modal.fs-modal-deactivation-feedback .reason-input input,.fs-modal.fs-modal-deactivation-feedback .reason-input textarea,.fs-modal.fs-modal-deactivation-feedback .internal-message input,.fs-modal.fs-modal-deactivation-feedback .internal-message textarea{width:100%}.fs-modal.fs-modal-deactivation-feedback li.reason.has-internal-message .internal-message{border:1px solid #ccc;padding:7px;display:none}@media (max-width: 650px){.fs-modal.fs-modal-deactivation-feedback li.reason li.reason{margin-bottom:10px}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason .reason-input,.fs-modal.fs-modal-deactivation-feedback li.reason li.reason .internal-message{margin-left:29px}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason label{display:table}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason label>span{display:table-cell;font-size:1.3em}}.fs-modal.fs-modal-deactivation-feedback .anonymous-feedback-label{float:left}.fs-modal.fs-modal-deactivation-feedback .fs-modal-panel{margin-top:0 !important}.fs-modal.fs-modal-deactivation-feedback .fs-modal-panel h3{margin-top:0;line-height:1.5em}#the-list .deactivate>.fs-slug{display:none}.fs-modal.fs-modal-license-activation .fs-modal-body input.license_key{width:100%}.fs-modal.fs-modal-license-key-resend .email-address-container{overflow:hidden;padding-right:2px}.fs-modal.fs-modal-license-key-resend.fs-freemium input.email-address{width:300px}.fs-modal.fs-modal-license-key-resend.fs-freemium label{display:block;margin-bottom:10px}.fs-modal.fs-modal-license-key-resend.fs-premium input.email-address{width:100%}.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{float:right;margin-left:7px}@media (max-width: 650px){.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{margin-top:2px}}
|
2 |
-
.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .input-container>.email-address-container{padding-left:2px;padding-right:0}.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .button-container{float:left;margin-right:7px;margin-left:0}a.show-license-resend-modal{margin-top:4px;display:inline-block}.fs-ajax-loader{position:relative;width:170px;height:20px;margin:auto}.fs-ajax-loader .fs-ajax-loader-bar{position:absolute;top:0;background-color:#0074a3;width:20px;height:20px;-webkit-animation-name:bounce_ajaxLoader;-moz-animation-name:bounce_ajaxLoader;-ms-animation-name:bounce_ajaxLoader;-o-animation-name:bounce_ajaxLoader;animation-name:bounce_ajaxLoader;-webkit-animation-duration:1.5s;-moz-animation-duration:1.5s;-ms-animation-duration:1.5s;-o-animation-duration:1.5s;animation-duration:1.5s;animation-iteration-count:infinite;-o-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;-webkit-animation-iteration-count:infinite;-moz-animation-iteration-count:infinite;-webkit-animation-direction:normal;-moz-animation-direction:normal;-ms-animation-direction:normal;-o-animation-direction:normal;animation-direction:normal;-moz-transform:0.3;-o-transform:0.3;-ms-transform:0.3;-webkit-transform:0.3;transform:0.3}.fs-ajax-loader .fs-ajax-loader-bar-1{left:0px;animation-delay:0.6s;-o-animation-delay:0.6s;-ms-animation-delay:0.6s;-webkit-animation-delay:0.6s;-moz-animation-delay:0.6s}.fs-ajax-loader .fs-ajax-loader-bar-2{left:19px;animation-delay:0.75s;-o-animation-delay:0.75s;-ms-animation-delay:0.75s;-webkit-animation-delay:0.75s;-moz-animation-delay:0.75s}.fs-ajax-loader .fs-ajax-loader-bar-3{left:38px;animation-delay:0.9s;-o-animation-delay:0.9s;-ms-animation-delay:0.9s;-webkit-animation-delay:0.9s;-moz-animation-delay:0.9s}.fs-ajax-loader .fs-ajax-loader-bar-4{left:57px;animation-delay:1.05s;-o-animation-delay:1.05s;-ms-animation-delay:1.05s;-webkit-animation-delay:1.05s;-moz-animation-delay:1.05s}.fs-ajax-loader .fs-ajax-loader-bar-5{left:76px;animation-delay:1.2s;-o-animation-delay:1.2s;-ms-animation-delay:1.2s;-webkit-animation-delay:1.2s;-moz-animation-delay:1.2s}.fs-ajax-loader .fs-ajax-loader-bar-6{left:95px;animation-delay:1.35s;-o-animation-delay:1.35s;-ms-animation-delay:1.35s;-webkit-animation-delay:1.35s;-moz-animation-delay:1.35s}.fs-ajax-loader .fs-ajax-loader-bar-7{left:114px;animation-delay:1.5s;-o-animation-delay:1.5s;-ms-animation-delay:1.5s;-webkit-animation-delay:1.5s;-moz-animation-delay:1.5s}.fs-ajax-loader .fs-ajax-loader-bar-8{left:133px;animation-delay:1.65s;-o-animation-delay:1.65s;-ms-animation-delay:1.65s;-webkit-animation-delay:1.65s;-moz-animation-delay:1.65s}@-moz-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-ms-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-o-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-webkit-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}.fs-modal-auto-install #request-filesystem-credentials-form h2,.fs-modal-auto-install #request-filesystem-credentials-form .request-filesystem-credentials-action-buttons{display:none}.fs-modal-auto-install #request-filesystem-credentials-form input[type=password],.fs-modal-auto-install #request-filesystem-credentials-form input[type=email],.fs-modal-auto-install #request-filesystem-credentials-form input[type=text]{-webkit-appearance:none;padding:10px 10px 5px 10px;width:300px;max-width:100%}.fs-modal-auto-install #request-filesystem-credentials-form>div,.fs-modal-auto-install #request-filesystem-credentials-form label,.fs-modal-auto-install #request-filesystem-credentials-form fieldset{width:300px;max-width:100%;margin:0 auto;display:block}
|
1 |
+
.fs-modal{position:fixed;overflow:auto;height:100%;width:100%;top:0;z-index:100000;display:none;background:rgba(0,0,0,0.6)}.fs-modal .fs-modal-dialog{background:transparent;position:absolute;left:50%;margin-left:-298px;padding-bottom:30px;top:-100%;z-index:100001;width:596px}@media (max-width: 650px){.fs-modal .fs-modal-dialog{margin-left:-50%;box-sizing:border-box;padding-left:10px;padding-right:10px;width:100%}.fs-modal .fs-modal-dialog .fs-modal-panel>h3>strong{font-size:1.3em}}.fs-modal.active{display:block}.fs-modal.active:before{display:block}.fs-modal.active .fs-modal-dialog{top:10%}.fs-modal.fs-success .fs-modal-header{border-bottom-color:#46b450}.fs-modal.fs-success .fs-modal-body{background-color:#f7fff7}.fs-modal.fs-warn .fs-modal-header{border-bottom-color:#ffb900}.fs-modal.fs-warn .fs-modal-body{background-color:#fff8e5}.fs-modal.fs-error .fs-modal-header{border-bottom-color:#dc3232}.fs-modal.fs-error .fs-modal-body{background-color:#ffeaea}.fs-modal .fs-modal-body,.fs-modal .fs-modal-footer{border:0;background:#fefefe;padding:20px}.fs-modal .fs-modal-header{border-bottom:#eeeeee solid 1px;background:#fbfbfb;padding:15px 20px;position:relative;margin-bottom:-10px}.fs-modal .fs-modal-header h4{margin:0;padding:0;text-transform:uppercase;font-size:1.2em;font-weight:bold;color:#cacaca;text-shadow:1px 1px 1px #fff;letter-spacing:0.6px;-webkit-font-smoothing:antialiased}.fs-modal .fs-modal-header .fs-close{position:absolute;right:10px;top:12px;cursor:pointer;color:#bbb;-moz-border-radius:20px;-webkit-border-radius:20px;border-radius:20px;padding:3px;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;-ms-transition:all 0.2s ease-in-out;-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.fs-modal .fs-modal-header .fs-close:hover{color:#fff;background:#aaa}.fs-modal .fs-modal-body{border-bottom:0}.fs-modal .fs-modal-body p{font-size:14px}.fs-modal .fs-modal-body h2{font-size:20px;line-height:1.5em}.fs-modal .fs-modal-body>div{margin-top:10px}.fs-modal .fs-modal-body>div h2{font-weight:bold;font-size:20px;margin-top:0}.fs-modal .fs-modal-footer{border-top:#eeeeee solid 1px;text-align:right}.fs-modal .fs-modal-footer>.button{margin:0 7px}.fs-modal .fs-modal-footer>.button:first-child{margin:0}.fs-modal .fs-modal-panel>.notice.inline{margin:0;display:none}.fs-modal .fs-modal-panel:not(.active){display:none}.rtl .fs-modal .fs-modal-header .fs-close{right:auto;left:20px}body.has-fs-modal{overflow:hidden}.fs-modal.fs-modal-deactivation-feedback .reason-input,.fs-modal.fs-modal-deactivation-feedback .internal-message{margin:3px 0 3px 22px}.fs-modal.fs-modal-deactivation-feedback .reason-input input,.fs-modal.fs-modal-deactivation-feedback .reason-input textarea,.fs-modal.fs-modal-deactivation-feedback .internal-message input,.fs-modal.fs-modal-deactivation-feedback .internal-message textarea{width:100%}.fs-modal.fs-modal-deactivation-feedback li.reason.has-internal-message .internal-message{border:1px solid #ccc;padding:7px;display:none}@media (max-width: 650px){.fs-modal.fs-modal-deactivation-feedback li.reason li.reason{margin-bottom:10px}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason .reason-input,.fs-modal.fs-modal-deactivation-feedback li.reason li.reason .internal-message{margin-left:29px}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason label{display:table}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason label>span{display:table-cell;font-size:1.3em}}.fs-modal.fs-modal-deactivation-feedback .anonymous-feedback-label{float:left}.fs-modal.fs-modal-deactivation-feedback .fs-modal-panel{margin-top:0 !important}.fs-modal.fs-modal-deactivation-feedback .fs-modal-panel h3{margin-top:0;line-height:1.5em}#the-list .deactivate>.fs-slug{display:none}.fs-modal.fs-modal-license-activation .fs-modal-body input.license_key{width:100%}.fs-modal.fs-modal-license-key-resend .email-address-container{overflow:hidden;padding-right:2px}.fs-modal.fs-modal-license-key-resend.fs-freemium input.email-address{width:300px}.fs-modal.fs-modal-license-key-resend.fs-freemium label{display:block;margin-bottom:10px}.fs-modal.fs-modal-license-key-resend.fs-premium input.email-address{width:100%}.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{float:right;margin-left:7px}@media (max-width: 650px){.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{margin-top:2px}}
|
2 |
+
.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .input-container>.email-address-container{padding-left:2px;padding-right:0}.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .button-container{float:left;margin-right:7px;margin-left:0}a.show-license-resend-modal{margin-top:4px;display:inline-block}.fs-ajax-loader{position:relative;width:170px;height:20px;margin:auto}.fs-ajax-loader .fs-ajax-loader-bar{position:absolute;top:0;background-color:#0074a3;width:20px;height:20px;-webkit-animation-name:bounce_ajaxLoader;-moz-animation-name:bounce_ajaxLoader;-ms-animation-name:bounce_ajaxLoader;-o-animation-name:bounce_ajaxLoader;animation-name:bounce_ajaxLoader;-webkit-animation-duration:1.5s;-moz-animation-duration:1.5s;-ms-animation-duration:1.5s;-o-animation-duration:1.5s;animation-duration:1.5s;animation-iteration-count:infinite;-o-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;-webkit-animation-iteration-count:infinite;-moz-animation-iteration-count:infinite;-webkit-animation-direction:normal;-moz-animation-direction:normal;-ms-animation-direction:normal;-o-animation-direction:normal;animation-direction:normal;-moz-transform:0.3;-o-transform:0.3;-ms-transform:0.3;-webkit-transform:0.3;transform:0.3}.fs-ajax-loader .fs-ajax-loader-bar-1{left:0px;animation-delay:0.6s;-o-animation-delay:0.6s;-ms-animation-delay:0.6s;-webkit-animation-delay:0.6s;-moz-animation-delay:0.6s}.fs-ajax-loader .fs-ajax-loader-bar-2{left:19px;animation-delay:0.75s;-o-animation-delay:0.75s;-ms-animation-delay:0.75s;-webkit-animation-delay:0.75s;-moz-animation-delay:0.75s}.fs-ajax-loader .fs-ajax-loader-bar-3{left:38px;animation-delay:0.9s;-o-animation-delay:0.9s;-ms-animation-delay:0.9s;-webkit-animation-delay:0.9s;-moz-animation-delay:0.9s}.fs-ajax-loader .fs-ajax-loader-bar-4{left:57px;animation-delay:1.05s;-o-animation-delay:1.05s;-ms-animation-delay:1.05s;-webkit-animation-delay:1.05s;-moz-animation-delay:1.05s}.fs-ajax-loader .fs-ajax-loader-bar-5{left:76px;animation-delay:1.2s;-o-animation-delay:1.2s;-ms-animation-delay:1.2s;-webkit-animation-delay:1.2s;-moz-animation-delay:1.2s}.fs-ajax-loader .fs-ajax-loader-bar-6{left:95px;animation-delay:1.35s;-o-animation-delay:1.35s;-ms-animation-delay:1.35s;-webkit-animation-delay:1.35s;-moz-animation-delay:1.35s}.fs-ajax-loader .fs-ajax-loader-bar-7{left:114px;animation-delay:1.5s;-o-animation-delay:1.5s;-ms-animation-delay:1.5s;-webkit-animation-delay:1.5s;-moz-animation-delay:1.5s}.fs-ajax-loader .fs-ajax-loader-bar-8{left:133px;animation-delay:1.65s;-o-animation-delay:1.65s;-ms-animation-delay:1.65s;-webkit-animation-delay:1.65s;-moz-animation-delay:1.65s}@-moz-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-ms-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-o-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-webkit-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}.fs-modal-auto-install #request-filesystem-credentials-form h2,.fs-modal-auto-install #request-filesystem-credentials-form .request-filesystem-credentials-action-buttons{display:none}.fs-modal-auto-install #request-filesystem-credentials-form input[type=password],.fs-modal-auto-install #request-filesystem-credentials-form input[type=email],.fs-modal-auto-install #request-filesystem-credentials-form input[type=text]{-webkit-appearance:none;padding:10px 10px 5px 10px;width:300px;max-width:100%}.fs-modal-auto-install #request-filesystem-credentials-form>div,.fs-modal-auto-install #request-filesystem-credentials-form label,.fs-modal-auto-install #request-filesystem-credentials-form fieldset{width:300px;max-width:100%;margin:0 auto;display:block}
|
freemius/assets/css/admin/index.php
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<?php
|
2 |
-
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
freemius/assets/css/index.php
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<?php
|
2 |
-
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
freemius/assets/img/index.php
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<?php
|
2 |
-
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
freemius/assets/js/index.php
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<?php
|
2 |
-
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
freemius/assets/scss/_colors.scss
CHANGED
@@ -1,65 +1,65 @@
|
|
1 |
-
$menu-hover-color: #333;
|
2 |
-
$darkest-color: #000;
|
3 |
-
$fms-live-color: #71ae00;
|
4 |
-
$fms-test-color: #f7941d;
|
5 |
-
$fms-link-color: #29abe1;
|
6 |
-
$fms-link-hover-color: darken(#29abe1, 10%);
|
7 |
-
$body-bkg: #111;
|
8 |
-
$special-color: #d3135a;
|
9 |
-
$body-color: #f1f1f1;
|
10 |
-
$fms-white: #f1f1f1;
|
11 |
-
$container-bkg: #222;
|
12 |
-
$container-bkg-odd: #262626;
|
13 |
-
$container-border-color: #333;
|
14 |
-
$table-head-bkg: #333;
|
15 |
-
$table-head-color: #999;
|
16 |
-
$info-color: #999;
|
17 |
-
$error-color: #ff0000;
|
18 |
-
|
19 |
-
$fs-logo-blue-color: #29abe1;
|
20 |
-
$fs-logo-green-color: #71ae00;
|
21 |
-
$fs-logo-magenta-color: #d3135a;
|
22 |
-
|
23 |
-
// WordPress colors.
|
24 |
-
$page-header-bkg: #333;
|
25 |
-
$page-header-color: $fms-white;
|
26 |
-
$text-dark-color: #333;
|
27 |
-
$text-light-color: #666;
|
28 |
-
$text-lightest-color: #999;
|
29 |
-
|
30 |
-
// Notices.
|
31 |
-
$wp-notice-success-color: #f7fff7;
|
32 |
-
$wp-notice-success-dark-color: #46b450;
|
33 |
-
$wp-notice-error-color: #ffeaea;
|
34 |
-
$wp-notice-error-dark-color: #dc3232;
|
35 |
-
$wp-notice-warn-color: #fff8e5;
|
36 |
-
$wp-notice-warn-dark-color: #ffb900;
|
37 |
-
$fs-notice-promotion-border-color: #00a0d2;
|
38 |
-
$fs-notice-promotion-bkg: #f2fcff;
|
39 |
-
|
40 |
-
// WP Buttons.
|
41 |
-
$button-primary-bkg: #6bc406;
|
42 |
-
$button-primary-color: $fms-white;
|
43 |
-
$button-secondary-bkg: #333;
|
44 |
-
$button-secondary-color: $fms-white;
|
45 |
-
$featured-color: #6bc406;
|
46 |
-
$wp-selected-color: #0074a3;
|
47 |
-
|
48 |
-
$wordpress_color: #01749A;
|
49 |
-
$blogger_color: #ff8100;
|
50 |
-
$wix_color: #fac102;
|
51 |
-
$shopify_color: #80d100;
|
52 |
-
$addthis_color: #fe6d4e;
|
53 |
-
$tumblr_color: #34506b;
|
54 |
-
$zepo_color: #00baf2;
|
55 |
-
$jquery_color: #000919;
|
56 |
-
$javascript_color: #00baf2;
|
57 |
-
$squarespace_color: #000;
|
58 |
-
|
59 |
-
$blog_color: #ff6600;
|
60 |
-
$facebook_color: #3b5998;
|
61 |
-
$twitter_color: #4099ff;
|
62 |
-
$linkedin_color: #4875b4;
|
63 |
-
$youtube_color: #ff3333;
|
64 |
-
$gplus_color: #c63d2d;
|
65 |
-
|
1 |
+
$menu-hover-color: #333;
|
2 |
+
$darkest-color: #000;
|
3 |
+
$fms-live-color: #71ae00;
|
4 |
+
$fms-test-color: #f7941d;
|
5 |
+
$fms-link-color: #29abe1;
|
6 |
+
$fms-link-hover-color: darken(#29abe1, 10%);
|
7 |
+
$body-bkg: #111;
|
8 |
+
$special-color: #d3135a;
|
9 |
+
$body-color: #f1f1f1;
|
10 |
+
$fms-white: #f1f1f1;
|
11 |
+
$container-bkg: #222;
|
12 |
+
$container-bkg-odd: #262626;
|
13 |
+
$container-border-color: #333;
|
14 |
+
$table-head-bkg: #333;
|
15 |
+
$table-head-color: #999;
|
16 |
+
$info-color: #999;
|
17 |
+
$error-color: #ff0000;
|
18 |
+
|
19 |
+
$fs-logo-blue-color: #29abe1;
|
20 |
+
$fs-logo-green-color: #71ae00;
|
21 |
+
$fs-logo-magenta-color: #d3135a;
|
22 |
+
|
23 |
+
// WordPress colors.
|
24 |
+
$page-header-bkg: #333;
|
25 |
+
$page-header-color: $fms-white;
|
26 |
+
$text-dark-color: #333;
|
27 |
+
$text-light-color: #666;
|
28 |
+
$text-lightest-color: #999;
|
29 |
+
|
30 |
+
// Notices.
|
31 |
+
$wp-notice-success-color: #f7fff7;
|
32 |
+
$wp-notice-success-dark-color: #46b450;
|
33 |
+
$wp-notice-error-color: #ffeaea;
|
34 |
+
$wp-notice-error-dark-color: #dc3232;
|
35 |
+
$wp-notice-warn-color: #fff8e5;
|
36 |
+
$wp-notice-warn-dark-color: #ffb900;
|
37 |
+
$fs-notice-promotion-border-color: #00a0d2;
|
38 |
+
$fs-notice-promotion-bkg: #f2fcff;
|
39 |
+
|
40 |
+
// WP Buttons.
|
41 |
+
$button-primary-bkg: #6bc406;
|
42 |
+
$button-primary-color: $fms-white;
|
43 |
+
$button-secondary-bkg: #333;
|
44 |
+
$button-secondary-color: $fms-white;
|
45 |
+
$featured-color: #6bc406;
|
46 |
+
$wp-selected-color: #0074a3;
|
47 |
+
|
48 |
+
$wordpress_color: #01749A;
|
49 |
+
$blogger_color: #ff8100;
|
50 |
+
$wix_color: #fac102;
|
51 |
+
$shopify_color: #80d100;
|
52 |
+
$addthis_color: #fe6d4e;
|
53 |
+
$tumblr_color: #34506b;
|
54 |
+
$zepo_color: #00baf2;
|
55 |
+
$jquery_color: #000919;
|
56 |
+
$javascript_color: #00baf2;
|
57 |
+
$squarespace_color: #000;
|
58 |
+
|
59 |
+
$blog_color: #ff6600;
|
60 |
+
$facebook_color: #3b5998;
|
61 |
+
$twitter_color: #4099ff;
|
62 |
+
$linkedin_color: #4875b4;
|
63 |
+
$youtube_color: #ff3333;
|
64 |
+
$gplus_color: #c63d2d;
|
65 |
+
|
freemius/assets/scss/admin/_license-activation.scss
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
-
.fs-modal.fs-modal-license-activation {
|
2 |
-
.fs-modal-body {
|
3 |
-
input.license_key {
|
4 |
-
width: 100%;
|
5 |
-
}
|
6 |
-
}
|
7 |
}
|
1 |
+
.fs-modal.fs-modal-license-activation {
|
2 |
+
.fs-modal-body {
|
3 |
+
input.license_key {
|
4 |
+
width: 100%;
|
5 |
+
}
|
6 |
+
}
|
7 |
}
|
freemius/assets/scss/admin/_modal-common.scss
CHANGED
@@ -1,186 +1,186 @@
|
|
1 |
-
@import "../colors";
|
2 |
-
@import "../mixins";
|
3 |
-
|
4 |
-
.fs-modal {
|
5 |
-
position: fixed;
|
6 |
-
overflow: auto;
|
7 |
-
height: 100%;
|
8 |
-
width: 100%;
|
9 |
-
top: 0;
|
10 |
-
z-index: 100000;
|
11 |
-
display: none;
|
12 |
-
background: rgba(0, 0, 0, 0.6);
|
13 |
-
|
14 |
-
.fs-modal-dialog {
|
15 |
-
background: transparent;
|
16 |
-
position: absolute;
|
17 |
-
left: 50%;
|
18 |
-
margin-left: -298px;
|
19 |
-
padding-bottom: 30px;
|
20 |
-
top: -100%;
|
21 |
-
z-index: 100001;
|
22 |
-
width: 596px;
|
23 |
-
|
24 |
-
@media (max-width: 650px) {
|
25 |
-
margin-left: -50%;
|
26 |
-
box-sizing: border-box;
|
27 |
-
padding-left: 10px;
|
28 |
-
padding-right: 10px;
|
29 |
-
width: 100%;
|
30 |
-
|
31 |
-
.fs-modal-panel > h3 > strong {
|
32 |
-
font-size: 1.3em;
|
33 |
-
}
|
34 |
-
}
|
35 |
-
}
|
36 |
-
|
37 |
-
&.active {
|
38 |
-
display: block;
|
39 |
-
|
40 |
-
&:before {
|
41 |
-
display: block;
|
42 |
-
}
|
43 |
-
|
44 |
-
.fs-modal-dialog {
|
45 |
-
top: 10%;
|
46 |
-
}
|
47 |
-
}
|
48 |
-
|
49 |
-
&.fs-success {
|
50 |
-
.fs-modal-header {
|
51 |
-
border-bottom-color: $wp-notice-success-dark-color;
|
52 |
-
}
|
53 |
-
|
54 |
-
.fs-modal-body {
|
55 |
-
background-color: $wp-notice-success-color;
|
56 |
-
}
|
57 |
-
}
|
58 |
-
|
59 |
-
&.fs-warn {
|
60 |
-
.fs-modal-header {
|
61 |
-
border-bottom-color: $wp-notice-warn-dark-color;
|
62 |
-
}
|
63 |
-
|
64 |
-
.fs-modal-body {
|
65 |
-
background-color: $wp-notice-warn-color;
|
66 |
-
}
|
67 |
-
}
|
68 |
-
|
69 |
-
&.fs-error {
|
70 |
-
.fs-modal-header {
|
71 |
-
border-bottom-color: $wp-notice-error-dark-color;
|
72 |
-
}
|
73 |
-
|
74 |
-
.fs-modal-body {
|
75 |
-
background-color: $wp-notice-error-color;
|
76 |
-
}
|
77 |
-
}
|
78 |
-
|
79 |
-
|
80 |
-
.fs-modal-body,
|
81 |
-
.fs-modal-footer {
|
82 |
-
border: 0;
|
83 |
-
background: #fefefe;
|
84 |
-
padding: 20px;
|
85 |
-
}
|
86 |
-
|
87 |
-
.fs-modal-header {
|
88 |
-
border-bottom: #eeeeee solid 1px;
|
89 |
-
background: #fbfbfb;
|
90 |
-
padding: 15px 20px;
|
91 |
-
position: relative;
|
92 |
-
margin-bottom: -10px;
|
93 |
-
// z-index: 2;
|
94 |
-
|
95 |
-
h4 {
|
96 |
-
margin: 0;
|
97 |
-
padding: 0;
|
98 |
-
text-transform: uppercase;
|
99 |
-
font-size: 1.2em;
|
100 |
-
font-weight: bold;
|
101 |
-
color: #cacaca;
|
102 |
-
text-shadow: 1px 1px 1px #fff;
|
103 |
-
letter-spacing: 0.6px;
|
104 |
-
-webkit-font-smoothing: antialiased;
|
105 |
-
}
|
106 |
-
|
107 |
-
.fs-close {
|
108 |
-
position: absolute;
|
109 |
-
right: 10px;
|
110 |
-
top: 12px;
|
111 |
-
cursor: pointer;
|
112 |
-
color: #bbb;
|
113 |
-
@include border-radius(20px);
|
114 |
-
padding: 3px;
|
115 |
-
@include transition(all 0.2s ease-in-out);
|
116 |
-
|
117 |
-
&:hover {
|
118 |
-
color: #fff;
|
119 |
-
background: #aaa;
|
120 |
-
}
|
121 |
-
}
|
122 |
-
}
|
123 |
-
|
124 |
-
.fs-modal-body {
|
125 |
-
border-bottom: 0;
|
126 |
-
|
127 |
-
p {
|
128 |
-
font-size: 14px;
|
129 |
-
}
|
130 |
-
|
131 |
-
h2 {
|
132 |
-
font-size: 20px;
|
133 |
-
line-height: 1.5em;
|
134 |
-
}
|
135 |
-
|
136 |
-
> div {
|
137 |
-
margin-top: 10px;
|
138 |
-
|
139 |
-
h2 {
|
140 |
-
font-weight: bold;
|
141 |
-
font-size: 20px;
|
142 |
-
margin-top: 0;
|
143 |
-
}
|
144 |
-
}
|
145 |
-
}
|
146 |
-
|
147 |
-
.fs-modal-footer {
|
148 |
-
border-top: #eeeeee solid 1px;
|
149 |
-
text-align: right;
|
150 |
-
|
151 |
-
> .button {
|
152 |
-
margin: 0 7px;
|
153 |
-
|
154 |
-
&:first-child {
|
155 |
-
margin: 0;
|
156 |
-
}
|
157 |
-
}
|
158 |
-
}
|
159 |
-
|
160 |
-
.fs-modal-panel {
|
161 |
-
> .notice.inline {
|
162 |
-
margin: 0;
|
163 |
-
display: none;
|
164 |
-
}
|
165 |
-
|
166 |
-
&:not(.active) {
|
167 |
-
display: none;
|
168 |
-
}
|
169 |
-
}
|
170 |
-
}
|
171 |
-
|
172 |
-
.rtl
|
173 |
-
{
|
174 |
-
.fs-modal {
|
175 |
-
.fs-modal-header {
|
176 |
-
.fs-close {
|
177 |
-
right: auto;
|
178 |
-
left: 20px;
|
179 |
-
}
|
180 |
-
}
|
181 |
-
}
|
182 |
-
}
|
183 |
-
|
184 |
-
body.has-fs-modal {
|
185 |
-
overflow: hidden;
|
186 |
}
|
1 |
+
@import "../colors";
|
2 |
+
@import "../mixins";
|
3 |
+
|
4 |
+
.fs-modal {
|
5 |
+
position: fixed;
|
6 |
+
overflow: auto;
|
7 |
+
height: 100%;
|
8 |
+
width: 100%;
|
9 |
+
top: 0;
|
10 |
+
z-index: 100000;
|
11 |
+
display: none;
|
12 |
+
background: rgba(0, 0, 0, 0.6);
|
13 |
+
|
14 |
+
.fs-modal-dialog {
|
15 |
+
background: transparent;
|
16 |
+
position: absolute;
|
17 |
+
left: 50%;
|
18 |
+
margin-left: -298px;
|
19 |
+
padding-bottom: 30px;
|
20 |
+
top: -100%;
|
21 |
+
z-index: 100001;
|
22 |
+
width: 596px;
|
23 |
+
|
24 |
+
@media (max-width: 650px) {
|
25 |
+
margin-left: -50%;
|
26 |
+
box-sizing: border-box;
|
27 |
+
padding-left: 10px;
|
28 |
+
padding-right: 10px;
|
29 |
+
width: 100%;
|
30 |
+
|
31 |
+
.fs-modal-panel > h3 > strong {
|
32 |
+
font-size: 1.3em;
|
33 |
+
}
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
&.active {
|
38 |
+
display: block;
|
39 |
+
|
40 |
+
&:before {
|
41 |
+
display: block;
|
42 |
+
}
|
43 |
+
|
44 |
+
.fs-modal-dialog {
|
45 |
+
top: 10%;
|
46 |
+
}
|
47 |
+
}
|
48 |
+
|
49 |
+
&.fs-success {
|
50 |
+
.fs-modal-header {
|
51 |
+
border-bottom-color: $wp-notice-success-dark-color;
|
52 |
+
}
|
53 |
+
|
54 |
+
.fs-modal-body {
|
55 |
+
background-color: $wp-notice-success-color;
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
&.fs-warn {
|
60 |
+
.fs-modal-header {
|
61 |
+
border-bottom-color: $wp-notice-warn-dark-color;
|
62 |
+
}
|
63 |
+
|
64 |
+
.fs-modal-body {
|
65 |
+
background-color: $wp-notice-warn-color;
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
&.fs-error {
|
70 |
+
.fs-modal-header {
|
71 |
+
border-bottom-color: $wp-notice-error-dark-color;
|
72 |
+
}
|
73 |
+
|
74 |
+
.fs-modal-body {
|
75 |
+
background-color: $wp-notice-error-color;
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
.fs-modal-body,
|
81 |
+
.fs-modal-footer {
|
82 |
+
border: 0;
|
83 |
+
background: #fefefe;
|
84 |
+
padding: 20px;
|
85 |
+
}
|
86 |
+
|
87 |
+
.fs-modal-header {
|
88 |
+
border-bottom: #eeeeee solid 1px;
|
89 |
+
background: #fbfbfb;
|
90 |
+
padding: 15px 20px;
|
91 |
+
position: relative;
|
92 |
+
margin-bottom: -10px;
|
93 |
+
// z-index: 2;
|
94 |
+
|
95 |
+
h4 {
|
96 |
+
margin: 0;
|
97 |
+
padding: 0;
|
98 |
+
text-transform: uppercase;
|
99 |
+
font-size: 1.2em;
|
100 |
+
font-weight: bold;
|
101 |
+
color: #cacaca;
|
102 |
+
text-shadow: 1px 1px 1px #fff;
|
103 |
+
letter-spacing: 0.6px;
|
104 |
+
-webkit-font-smoothing: antialiased;
|
105 |
+
}
|
106 |
+
|
107 |
+
.fs-close {
|
108 |
+
position: absolute;
|
109 |
+
right: 10px;
|
110 |
+
top: 12px;
|
111 |
+
cursor: pointer;
|
112 |
+
color: #bbb;
|
113 |
+
@include border-radius(20px);
|
114 |
+
padding: 3px;
|
115 |
+
@include transition(all 0.2s ease-in-out);
|
116 |
+
|
117 |
+
&:hover {
|
118 |
+
color: #fff;
|
119 |
+
background: #aaa;
|
120 |
+
}
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
.fs-modal-body {
|
125 |
+
border-bottom: 0;
|
126 |
+
|
127 |
+
p {
|
128 |
+
font-size: 14px;
|
129 |
+
}
|
130 |
+
|
131 |
+
h2 {
|
132 |
+
font-size: 20px;
|
133 |
+
line-height: 1.5em;
|
134 |
+
}
|
135 |
+
|
136 |
+
> div {
|
137 |
+
margin-top: 10px;
|
138 |
+
|
139 |
+
h2 {
|
140 |
+
font-weight: bold;
|
141 |
+
font-size: 20px;
|
142 |
+
margin-top: 0;
|
143 |
+
}
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
.fs-modal-footer {
|
148 |
+
border-top: #eeeeee solid 1px;
|
149 |
+
text-align: right;
|
150 |
+
|
151 |
+
> .button {
|
152 |
+
margin: 0 7px;
|
153 |
+
|
154 |
+
&:first-child {
|
155 |
+
margin: 0;
|
156 |
+
}
|
157 |
+
}
|
158 |
+
}
|
159 |
+
|
160 |
+
.fs-modal-panel {
|
161 |
+
> .notice.inline {
|
162 |
+
margin: 0;
|
163 |
+
display: none;
|
164 |
+
}
|
165 |
+
|
166 |
+
&:not(.active) {
|
167 |
+
display: none;
|
168 |
+
}
|
169 |
+
}
|
170 |
+
}
|
171 |
+
|
172 |
+
.rtl
|
173 |
+
{
|
174 |
+
.fs-modal {
|
175 |
+
.fs-modal-header {
|
176 |
+
.fs-close {
|
177 |
+
right: auto;
|
178 |
+
left: 20px;
|
179 |
+
}
|
180 |
+
}
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
body.has-fs-modal {
|
185 |
+
overflow: hidden;
|
186 |
}
|
freemius/assets/scss/admin/account.scss
CHANGED
@@ -1,256 +1,256 @@
|
|
1 |
-
@import "../start";
|
2 |
-
|
3 |
-
#fs_account
|
4 |
-
{
|
5 |
-
.postbox,
|
6 |
-
.widefat
|
7 |
-
{
|
8 |
-
max-width: 700px;
|
9 |
-
}
|
10 |
-
|
11 |
-
h3
|
12 |
-
{
|
13 |
-
font-size: 1.3em;
|
14 |
-
padding: 12px 15px;
|
15 |
-
margin: 0 0 12px 0;
|
16 |
-
line-height: 1.4;
|
17 |
-
border-bottom: 1px solid #F1F1F1;
|
18 |
-
|
19 |
-
.dashicons {
|
20 |
-
width: 26px;
|
21 |
-
height: 26px;
|
22 |
-
font-size: 1.3em;
|
23 |
-
}
|
24 |
-
}
|
25 |
-
|
26 |
-
i.dashicons
|
27 |
-
{
|
28 |
-
font-size: 1.2em;
|
29 |
-
height: 1.2em;
|
30 |
-
width: 1.2em;
|
31 |
-
}
|
32 |
-
|
33 |
-
.button
|
34 |
-
{
|
35 |
-
i.dashicons
|
36 |
-
{
|
37 |
-
vertical-align: middle;
|
38 |
-
}
|
39 |
-
}
|
40 |
-
|
41 |
-
.fs-header-actions
|
42 |
-
{
|
43 |
-
position: absolute;
|
44 |
-
top: 17px;
|
45 |
-
right: 15px;
|
46 |
-
font-size: 0.9em;
|
47 |
-
|
48 |
-
ul
|
49 |
-
{
|
50 |
-
margin: 0;
|
51 |
-
}
|
52 |
-
|
53 |
-
li
|
54 |
-
{
|
55 |
-
form
|
56 |
-
{
|
57 |
-
display: inline-block;
|
58 |
-
}
|
59 |
-
|
60 |
-
float: left;
|
61 |
-
a
|
62 |
-
{
|
63 |
-
text-decoration: none;
|
64 |
-
}
|
65 |
-
}
|
66 |
-
}
|
67 |
-
}
|
68 |
-
|
69 |
-
#fs_account_details .button-group {
|
70 |
-
float: right;
|
71 |
-
}
|
72 |
-
|
73 |
-
.rtl #fs_account .fs-header-actions
|
74 |
-
{
|
75 |
-
left: 15px;
|
76 |
-
right: auto;
|
77 |
-
}
|
78 |
-
|
79 |
-
.fs-key-value-table
|
80 |
-
{
|
81 |
-
width: 100%;
|
82 |
-
|
83 |
-
form
|
84 |
-
{
|
85 |
-
display: inline-block;
|
86 |
-
}
|
87 |
-
|
88 |
-
tr
|
89 |
-
{
|
90 |
-
td:first-child
|
91 |
-
{
|
92 |
-
nobr
|
93 |
-
{
|
94 |
-
font-weight: bold;
|
95 |
-
}
|
96 |
-
|
97 |
-
text-align: right;
|
98 |
-
|
99 |
-
form
|
100 |
-
{
|
101 |
-
display: block;
|
102 |
-
}
|
103 |
-
}
|
104 |
-
|
105 |
-
td.fs-right
|
106 |
-
{
|
107 |
-
text-align: right;
|
108 |
-
}
|
109 |
-
|
110 |
-
&.fs-odd
|
111 |
-
{
|
112 |
-
background: #ebebeb;
|
113 |
-
}
|
114 |
-
}
|
115 |
-
|
116 |
-
td, th
|
117 |
-
{
|
118 |
-
padding: 10px;
|
119 |
-
}
|
120 |
-
|
121 |
-
code {
|
122 |
-
line-height: 28px;
|
123 |
-
}
|
124 |
-
|
125 |
-
var, code, input[type="text"]
|
126 |
-
{
|
127 |
-
color: #0073AA;
|
128 |
-
font-size: 16px;
|
129 |
-
background: none;
|
130 |
-
}
|
131 |
-
|
132 |
-
input[type="text"] {
|
133 |
-
width: 100%;
|
134 |
-
font-weight: bold;
|
135 |
-
}
|
136 |
-
}
|
137 |
-
|
138 |
-
label.fs-tag
|
139 |
-
{
|
140 |
-
background: #ffba00;
|
141 |
-
color: #fff;
|
142 |
-
display: inline-block;
|
143 |
-
border-radius: 3px;
|
144 |
-
padding: 5px;
|
145 |
-
font-size: 11px;
|
146 |
-
line-height: 11px;
|
147 |
-
vertical-align: baseline;
|
148 |
-
|
149 |
-
&.fs-warn
|
150 |
-
{
|
151 |
-
background: #ffba00;
|
152 |
-
}
|
153 |
-
&.fs-success
|
154 |
-
{
|
155 |
-
background: #46b450;
|
156 |
-
}
|
157 |
-
&.fs-error
|
158 |
-
{
|
159 |
-
background: #dc3232;
|
160 |
-
}
|
161 |
-
}
|
162 |
-
|
163 |
-
#fs_addons
|
164 |
-
{
|
165 |
-
h3
|
166 |
-
{
|
167 |
-
border: none;
|
168 |
-
margin-bottom: 0;
|
169 |
-
padding: 4px 5px;
|
170 |
-
}
|
171 |
-
|
172 |
-
td
|
173 |
-
{
|
174 |
-
vertical-align: middle;
|
175 |
-
}
|
176 |
-
|
177 |
-
thead {
|
178 |
-
white-space: nowrap;
|
179 |
-
}
|
180 |
-
|
181 |
-
td:first-child,
|
182 |
-
th:first-child
|
183 |
-
{
|
184 |
-
text-align: left;
|
185 |
-
font-weight: bold;
|
186 |
-
}
|
187 |
-
td:last-child,
|
188 |
-
th:last-child
|
189 |
-
{
|
190 |
-
text-align: right;
|
191 |
-
}
|
192 |
-
th
|
193 |
-
{
|
194 |
-
font-weight: bold;
|
195 |
-
}
|
196 |
-
}
|
197 |
-
|
198 |
-
#fs_billing_address {
|
199 |
-
width: 100%;
|
200 |
-
|
201 |
-
tr {
|
202 |
-
td {
|
203 |
-
width: 50%;
|
204 |
-
padding: 5px;
|
205 |
-
}
|
206 |
-
|
207 |
-
&:first-of-type {
|
208 |
-
td {
|
209 |
-
padding-top: 0;
|
210 |
-
}
|
211 |
-
}
|
212 |
-
}
|
213 |
-
|
214 |
-
@mixin read-mode {
|
215 |
-
border-color: transparent;
|
216 |
-
color: #777;
|
217 |
-
border-bottom: 1px dashed #ccc;
|
218 |
-
padding-left: 0;
|
219 |
-
background: none;
|
220 |
-
}
|
221 |
-
|
222 |
-
span {
|
223 |
-
font-weight: bold;
|
224 |
-
}
|
225 |
-
|
226 |
-
input, select {
|
227 |
-
@include placeholder(transparent);
|
228 |
-
|
229 |
-
display: block;
|
230 |
-
width: 100%;
|
231 |
-
margin-top: 5px;
|
232 |
-
|
233 |
-
&.fs-read-mode {
|
234 |
-
@include read-mode();
|
235 |
-
}
|
236 |
-
}
|
237 |
-
|
238 |
-
|
239 |
-
&.fs-read-mode {
|
240 |
-
td span {
|
241 |
-
display: none;
|
242 |
-
}
|
243 |
-
|
244 |
-
input, select
|
245 |
-
{
|
246 |
-
@include read-mode();
|
247 |
-
@include placeholder(#ccc);
|
248 |
-
}
|
249 |
-
}
|
250 |
-
|
251 |
-
|
252 |
-
button {
|
253 |
-
display: block;
|
254 |
-
width: 100%;
|
255 |
-
}
|
256 |
}
|
1 |
+
@import "../start";
|
2 |
+
|
3 |
+
#fs_account
|
4 |
+
{
|
5 |
+
.postbox,
|
6 |
+
.widefat
|
7 |
+
{
|
8 |
+
max-width: 700px;
|
9 |
+
}
|
10 |
+
|
11 |
+
h3
|
12 |
+
{
|
13 |
+
font-size: 1.3em;
|
14 |
+
padding: 12px 15px;
|
15 |
+
margin: 0 0 12px 0;
|
16 |
+
line-height: 1.4;
|
17 |
+
border-bottom: 1px solid #F1F1F1;
|
18 |
+
|
19 |
+
.dashicons {
|
20 |
+
width: 26px;
|
21 |
+
height: 26px;
|
22 |
+
font-size: 1.3em;
|
23 |
+
}
|
24 |
+
}
|
25 |
+
|
26 |
+
i.dashicons
|
27 |
+
{
|
28 |
+
font-size: 1.2em;
|
29 |
+
height: 1.2em;
|
30 |
+
width: 1.2em;
|
31 |
+
}
|
32 |
+
|
33 |
+
.button
|
34 |
+
{
|
35 |
+
i.dashicons
|
36 |
+
{
|
37 |
+
vertical-align: middle;
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
.fs-header-actions
|
42 |
+
{
|
43 |
+
position: absolute;
|
44 |
+
top: 17px;
|
45 |
+
right: 15px;
|
46 |
+
font-size: 0.9em;
|
47 |
+
|
48 |
+
ul
|
49 |
+
{
|
50 |
+
margin: 0;
|
51 |
+
}
|
52 |
+
|
53 |
+
li
|
54 |
+
{
|
55 |
+
form
|
56 |
+
{
|
57 |
+
display: inline-block;
|
58 |
+
}
|
59 |
+
|
60 |
+
float: left;
|
61 |
+
a
|
62 |
+
{
|
63 |
+
text-decoration: none;
|
64 |
+
}
|
65 |
+
}
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
#fs_account_details .button-group {
|
70 |
+
float: right;
|
71 |
+
}
|
72 |
+
|
73 |
+
.rtl #fs_account .fs-header-actions
|
74 |
+
{
|
75 |
+
left: 15px;
|
76 |
+
right: auto;
|
77 |
+
}
|
78 |
+
|
79 |
+
.fs-key-value-table
|
80 |
+
{
|
81 |
+
width: 100%;
|
82 |
+
|
83 |
+
form
|
84 |
+
{
|
85 |
+
display: inline-block;
|
86 |
+
}
|
87 |
+
|
88 |
+
tr
|
89 |
+
{
|
90 |
+
td:first-child
|
91 |
+
{
|
92 |
+
nobr
|
93 |
+
{
|
94 |
+
font-weight: bold;
|
95 |
+
}
|
96 |
+
|
97 |
+
text-align: right;
|
98 |
+
|
99 |
+
form
|
100 |
+
{
|
101 |
+
display: block;
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
+
td.fs-right
|
106 |
+
{
|
107 |
+
text-align: right;
|
108 |
+
}
|
109 |
+
|
110 |
+
&.fs-odd
|
111 |
+
{
|
112 |
+
background: #ebebeb;
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
td, th
|
117 |
+
{
|
118 |
+
padding: 10px;
|
119 |
+
}
|
120 |
+
|
121 |
+
code {
|
122 |
+
line-height: 28px;
|
123 |
+
}
|
124 |
+
|
125 |
+
var, code, input[type="text"]
|
126 |
+
{
|
127 |
+
color: #0073AA;
|
128 |
+
font-size: 16px;
|
129 |
+
background: none;
|
130 |
+
}
|
131 |
+
|
132 |
+
input[type="text"] {
|
133 |
+
width: 100%;
|
134 |
+
font-weight: bold;
|
135 |
+
}
|
136 |
+
}
|
137 |
+
|
138 |
+
label.fs-tag
|
139 |
+
{
|
140 |
+
background: #ffba00;
|
141 |
+
color: #fff;
|
142 |
+
display: inline-block;
|
143 |
+
border-radius: 3px;
|
144 |
+
padding: 5px;
|
145 |
+
font-size: 11px;
|
146 |
+
line-height: 11px;
|
147 |
+
vertical-align: baseline;
|
148 |
+
|
149 |
+
&.fs-warn
|
150 |
+
{
|
151 |
+
background: #ffba00;
|
152 |
+
}
|
153 |
+
&.fs-success
|
154 |
+
{
|
155 |
+
background: #46b450;
|
156 |
+
}
|
157 |
+
&.fs-error
|
158 |
+
{
|
159 |
+
background: #dc3232;
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
#fs_addons
|
164 |
+
{
|
165 |
+
h3
|
166 |
+
{
|
167 |
+
border: none;
|
168 |
+
margin-bottom: 0;
|
169 |
+
padding: 4px 5px;
|
170 |
+
}
|
171 |
+
|
172 |
+
td
|
173 |
+
{
|
174 |
+
vertical-align: middle;
|
175 |
+
}
|
176 |
+
|
177 |
+
thead {
|
178 |
+
white-space: nowrap;
|
179 |
+
}
|
180 |
+
|
181 |
+
td:first-child,
|
182 |
+
th:first-child
|
183 |
+
{
|
184 |
+
text-align: left;
|
185 |
+
font-weight: bold;
|
186 |
+
}
|
187 |
+
td:last-child,
|
188 |
+
th:last-child
|
189 |
+
{
|
190 |
+
text-align: right;
|
191 |
+
}
|
192 |
+
th
|
193 |
+
{
|
194 |
+
font-weight: bold;
|
195 |
+
}
|
196 |
+
}
|
197 |
+
|
198 |
+
#fs_billing_address {
|
199 |
+
width: 100%;
|
200 |
+
|
201 |
+
tr {
|
202 |
+
td {
|
203 |
+
width: 50%;
|
204 |
+
padding: 5px;
|
205 |
+
}
|
206 |
+
|
207 |
+
&:first-of-type {
|
208 |
+
td {
|
209 |
+
padding-top: 0;
|
210 |
+
}
|
211 |
+
}
|
212 |
+
}
|
213 |
+
|
214 |
+
@mixin read-mode {
|
215 |
+
border-color: transparent;
|
216 |
+
color: #777;
|
217 |
+
border-bottom: 1px dashed #ccc;
|
218 |
+
padding-left: 0;
|
219 |
+
background: none;
|
220 |
+
}
|
221 |
+
|
222 |
+
span {
|
223 |
+
font-weight: bold;
|
224 |
+
}
|
225 |
+
|
226 |
+
input, select {
|
227 |
+
@include placeholder(transparent);
|
228 |
+
|
229 |
+
display: block;
|
230 |
+
width: 100%;
|
231 |
+
margin-top: 5px;
|
232 |
+
|
233 |
+
&.fs-read-mode {
|
234 |
+
@include read-mode();
|
235 |
+
}
|
236 |
+
}
|
237 |
+
|
238 |
+
|
239 |
+
&.fs-read-mode {
|
240 |
+
td span {
|
241 |
+
display: none;
|
242 |
+
}
|
243 |
+
|
244 |
+
input, select
|
245 |
+
{
|
246 |
+
@include read-mode();
|
247 |
+
@include placeholder(#ccc);
|
248 |
+
}
|
249 |
+
}
|
250 |
+
|
251 |
+
|
252 |
+
button {
|
253 |
+
display: block;
|
254 |
+
width: 100%;
|
255 |
+
}
|
256 |
}
|
freemius/assets/scss/admin/dialog-boxes.scss
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
-
@import "../start";
|
2 |
-
@import "modal-common";
|
3 |
-
@import "deactivation-feedback";
|
4 |
-
@import "license-activation";
|
5 |
-
@import "license-key-resend";
|
6 |
-
@import "ajax-loader";
|
7 |
@import "auto-install";
|
1 |
+
@import "../start";
|
2 |
+
@import "modal-common";
|
3 |
+
@import "deactivation-feedback";
|
4 |
+
@import "license-activation";
|
5 |
+
@import "license-key-resend";
|
6 |
+
@import "ajax-loader";
|
7 |
@import "auto-install";
|
freemius/assets/scss/admin/index.php
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<?php
|
2 |
-
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
freemius/assets/scss/index.php
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<?php
|
2 |
-
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
freemius/gulpfile.js
CHANGED
@@ -1,167 +1,167 @@
|
|
1 |
-
var gulp = require('gulp');
|
2 |
-
var path = require('path');
|
3 |
-
var filesystem = require('fs');
|
4 |
-
var wpPot = require('gulp-wp-pot');
|
5 |
-
var gettext = require('gulp-gettext');
|
6 |
-
var sort = require('gulp-sort');
|
7 |
-
var pofill = require('gulp-pofill');
|
8 |
-
var rename = require('gulp-rename');
|
9 |
-
var clean = require('gulp-clean');
|
10 |
-
|
11 |
-
var languagesFolder = './languages/';
|
12 |
-
|
13 |
-
var options = require('./transifex-config.json');
|
14 |
-
|
15 |
-
function getFolders(dir) {
|
16 |
-
return filesystem.readdirSync(dir)
|
17 |
-
.filter(function (file) {
|
18 |
-
return filesystem.statSync(path.join(dir, file)).isDirectory();
|
19 |
-
});
|
20 |
-
}
|
21 |
-
|
22 |
-
var transifex = require('gulp-transifex').createClient(options);
|
23 |
-
|
24 |
-
// Create POT out of i18n.php.
|
25 |
-
gulp.task('prepare-source', function () {
|
26 |
-
gulp.src('**/*.php')
|
27 |
-
.pipe(sort())
|
28 |
-
.pipe(wpPot({
|
29 |
-
destFile : 'freemius.pot',
|
30 |
-
package : 'freemius',
|
31 |
-
bugReport : 'https://github.com/Freemius/wordpress-sdk/issues',
|
32 |
-
lastTranslator : 'Vova Feldman <vova@freemius.com>',
|
33 |
-
team : 'Freemius Team <admin@freemius.com>',
|
34 |
-
/*gettextMethods: {
|
35 |
-
instances: ['this', '_fs'],
|
36 |
-
methods: [
|
37 |
-
'get_text_inline'
|
38 |
-
]
|
39 |
-
},*/
|
40 |
-
gettextFunctions: [
|
41 |
-
{name: 'get_text_inline'},
|
42 |
-
|
43 |
-
{name: 'fs_text_inline'},
|
44 |
-
{name: 'fs_echo_inline'},
|
45 |
-
{name: 'fs_esc_js_inline'},
|
46 |
-
{name: 'fs_esc_attr_inline'},
|
47 |
-
{name: 'fs_esc_attr_echo_inline'},
|
48 |
-
{name: 'fs_esc_html_inline'},
|
49 |
-
{name: 'fs_esc_html_echo_inline'},
|
50 |
-
|
51 |
-
{name: 'get_text_x_inline', context: 2},
|
52 |
-
{name: 'fs_text_x_inline', context: 2},
|
53 |
-
{name: 'fs_echo_x_inline', context: 2},
|
54 |
-
{name: 'fs_esc_attr_x_inline', context: 2},
|
55 |
-
{name: 'fs_esc_js_x_inline', context: 2},
|
56 |
-
{name: 'fs_esc_js_echo_x_inline', context: 2},
|
57 |
-
{name: 'fs_esc_html_x_inline', context: 2},
|
58 |
-
{name: 'fs_esc_html_echo_x_inline', context: 2}
|
59 |
-
/*,
|
60 |
-
|
61 |
-
|
62 |
-
{name: '_fs_text'},
|
63 |
-
{name: '_fs_x', context: 2},
|
64 |
-
{name: '_fs_echo'},
|
65 |
-
{name: '_fs_esc_attr'},
|
66 |
-
{name: '_fs_esc_attr_echo'},
|
67 |
-
{name: '_fs_esc_html'},
|
68 |
-
{name: '_fs_esc_html_echo'},
|
69 |
-
{name: '_fs_ex', context: 2},
|
70 |
-
{name: '_fs_esc_attr_x', context: 2},
|
71 |
-
{name: '_fs_esc_html_x', context: 2},
|
72 |
-
|
73 |
-
{name: '_fs_n', plural: 2},
|
74 |
-
{name: '_fs_n_noop', plural: 2},
|
75 |
-
{name: '_fs_nx', plural: 2, context: 4},
|
76 |
-
{name: '_fs_nx_noop', plural: 2, context: 3}*/
|
77 |
-
]
|
78 |
-
}))
|
79 |
-
.pipe(gulp.dest(languagesFolder + 'freemius.pot'));
|
80 |
-
|
81 |
-
// Create English PO out of the POT.
|
82 |
-
return gulp.src(languagesFolder + 'freemius.pot')
|
83 |
-
.pipe(pofill({
|
84 |
-
items: function (item) {
|
85 |
-
// If msgstr is empty, use identity translation
|
86 |
-
if (!item.msgstr.length) {
|
87 |
-
item.msgstr = [''];
|
88 |
-
}
|
89 |
-
if (!item.msgstr[0]) {
|
90 |
-
item.msgstr[0] = item.msgid;
|
91 |
-
}
|
92 |
-
return item;
|
93 |
-
}
|
94 |
-
}))
|
95 |
-
.pipe(rename('freemius-en.po'))
|
96 |
-
.pipe(gulp.dest(languagesFolder));
|
97 |
-
});
|
98 |
-
|
99 |
-
// Push updated po resource to transifex.
|
100 |
-
gulp.task('update-transifex', ['prepare-source'], function () {
|
101 |
-
return gulp.src(languagesFolder + 'freemius-en.po')
|
102 |
-
.pipe(transifex.pushResource());
|
103 |
-
});
|
104 |
-
|
105 |
-
// Download latest *.po translations.
|
106 |
-
gulp.task('download-translations', ['update-transifex'], function () {
|
107 |
-
return gulp.src(languagesFolder + 'freemius-en.po')
|
108 |
-
.pipe(transifex.pullResource());
|
109 |
-
});
|
110 |
-
|
111 |
-
// Move translations to languages root.
|
112 |
-
gulp.task('prepare-translations', ['download-translations'], function () {
|
113 |
-
var folders = getFolders(languagesFolder);
|
114 |
-
|
115 |
-
return folders.map(function (folder) {
|
116 |
-
return gulp.src(path.join(languagesFolder, folder, 'freemius-en.po'))
|
117 |
-
.pipe(rename('freemius-' + folder + '.po'))
|
118 |
-
.pipe(gulp.dest(languagesFolder));
|
119 |
-
});
|
120 |
-
});
|
121 |
-
|
122 |
-
// Feel up empty translations with English.
|
123 |
-
gulp.task('translations-feelup', ['prepare-translations'], function () {
|
124 |
-
return gulp.src(languagesFolder + '*.po')
|
125 |
-
.pipe(pofill({
|
126 |
-
items: function (item) {
|
127 |
-
// If msgstr is empty, use identity translation
|
128 |
-
if (0 == item.msgstr.length) {
|
129 |
-
item.msgstr = [''];
|
130 |
-
}
|
131 |
-
if (0 == item.msgstr[0].length) {
|
132 |
-
// item.msgid[0] = item.msgid;
|
133 |
-
item.msgstr[0] = item.msgid;
|
134 |
-
}
|
135 |
-
return item;
|
136 |
-
}
|
137 |
-
}))
|
138 |
-
.pipe(gulp.dest(languagesFolder));
|
139 |
-
});
|
140 |
-
|
141 |
-
// Cleanup temporary translation folders.
|
142 |
-
gulp.task('cleanup', ['prepare-translations'], function () {
|
143 |
-
var folders = getFolders(languagesFolder);
|
144 |
-
|
145 |
-
return folders.map(function (folder) {
|
146 |
-
return gulp.src(path.join(languagesFolder, folder), {read: false})
|
147 |
-
.pipe(clean());
|
148 |
-
});
|
149 |
-
});
|
150 |
-
|
151 |
-
// Compile *.po to *.mo binaries for usage.
|
152 |
-
gulp.task('compile-translations', ['translations-feelup'], function () {
|
153 |
-
// Compile POs to MOs.
|
154 |
-
return gulp.src(languagesFolder + '*.po')
|
155 |
-
.pipe(gettext())
|
156 |
-
.pipe(gulp.dest(languagesFolder))
|
157 |
-
});
|
158 |
-
|
159 |
-
gulp.task('default', [], function () {
|
160 |
-
gulp.run('prepare-source');
|
161 |
-
gulp.run('update-transifex');
|
162 |
-
gulp.run('download-translations');
|
163 |
-
gulp.run('prepare-translations');
|
164 |
-
gulp.run('translations-feelup');
|
165 |
-
gulp.run('cleanup');
|
166 |
-
gulp.run('compile-translations');
|
167 |
});
|
1 |
+
var gulp = require('gulp');
|
2 |
+
var path = require('path');
|
3 |
+
var filesystem = require('fs');
|
4 |
+
var wpPot = require('gulp-wp-pot');
|
5 |
+
var gettext = require('gulp-gettext');
|
6 |
+
var sort = require('gulp-sort');
|
7 |
+
var pofill = require('gulp-pofill');
|
8 |
+
var rename = require('gulp-rename');
|
9 |
+
var clean = require('gulp-clean');
|
10 |
+
|
11 |
+
var languagesFolder = './languages/';
|
12 |
+
|
13 |
+
var options = require('./transifex-config.json');
|
14 |
+
|
15 |
+
function getFolders(dir) {
|
16 |
+
return filesystem.readdirSync(dir)
|
17 |
+
.filter(function (file) {
|
18 |
+
return filesystem.statSync(path.join(dir, file)).isDirectory();
|
19 |
+
});
|
20 |
+
}
|
21 |
+
|
22 |
+
var transifex = require('gulp-transifex').createClient(options);
|
23 |
+
|
24 |
+
// Create POT out of i18n.php.
|
25 |
+
gulp.task('prepare-source', function () {
|
26 |
+
gulp.src('**/*.php')
|
27 |
+
.pipe(sort())
|
28 |
+
.pipe(wpPot({
|
29 |
+
destFile : 'freemius.pot',
|
30 |
+
package : 'freemius',
|
31 |
+
bugReport : 'https://github.com/Freemius/wordpress-sdk/issues',
|
32 |
+
lastTranslator : 'Vova Feldman <vova@freemius.com>',
|
33 |
+
team : 'Freemius Team <admin@freemius.com>',
|
34 |
+
/*gettextMethods: {
|
35 |
+
instances: ['this', '_fs'],
|
36 |
+
methods: [
|
37 |
+
'get_text_inline'
|
38 |
+
]
|
39 |
+
},*/
|
40 |
+
gettextFunctions: [
|
41 |
+
{name: 'get_text_inline'},
|
42 |
+
|
43 |
+
{name: 'fs_text_inline'},
|
44 |
+
{name: 'fs_echo_inline'},
|
45 |
+
{name: 'fs_esc_js_inline'},
|
46 |
+
{name: 'fs_esc_attr_inline'},
|
47 |
+
{name: 'fs_esc_attr_echo_inline'},
|
48 |
+
{name: 'fs_esc_html_inline'},
|
49 |
+
{name: 'fs_esc_html_echo_inline'},
|
50 |
+
|
51 |
+
{name: 'get_text_x_inline', context: 2},
|
52 |
+
{name: 'fs_text_x_inline', context: 2},
|
53 |
+
{name: 'fs_echo_x_inline', context: 2},
|
54 |
+
{name: 'fs_esc_attr_x_inline', context: 2},
|
55 |
+
{name: 'fs_esc_js_x_inline', context: 2},
|
56 |
+
{name: 'fs_esc_js_echo_x_inline', context: 2},
|
57 |
+
{name: 'fs_esc_html_x_inline', context: 2},
|
58 |
+
{name: 'fs_esc_html_echo_x_inline', context: 2}
|
59 |
+
/*,
|
60 |
+
|
61 |
+
|
62 |
+
{name: '_fs_text'},
|
63 |
+
{name: '_fs_x', context: 2},
|
64 |
+
{name: '_fs_echo'},
|
65 |
+
{name: '_fs_esc_attr'},
|
66 |
+
{name: '_fs_esc_attr_echo'},
|
67 |
+
{name: '_fs_esc_html'},
|
68 |
+
{name: '_fs_esc_html_echo'},
|
69 |
+
{name: '_fs_ex', context: 2},
|
70 |
+
{name: '_fs_esc_attr_x', context: 2},
|
71 |
+
{name: '_fs_esc_html_x', context: 2},
|
72 |
+
|
73 |
+
{name: '_fs_n', plural: 2},
|
74 |
+
{name: '_fs_n_noop', plural: 2},
|
75 |
+
{name: '_fs_nx', plural: 2, context: 4},
|
76 |
+
{name: '_fs_nx_noop', plural: 2, context: 3}*/
|
77 |
+
]
|
78 |
+
}))
|
79 |
+
.pipe(gulp.dest(languagesFolder + 'freemius.pot'));
|
80 |
+
|
81 |
+
// Create English PO out of the POT.
|
82 |
+
return gulp.src(languagesFolder + 'freemius.pot')
|
83 |
+
.pipe(pofill({
|
84 |
+
items: function (item) {
|
85 |
+
// If msgstr is empty, use identity translation
|
86 |
+
if (!item.msgstr.length) {
|
87 |
+
item.msgstr = [''];
|
88 |
+
}
|
89 |
+
if (!item.msgstr[0]) {
|
90 |
+
item.msgstr[0] = item.msgid;
|
91 |
+
}
|
92 |
+
return item;
|
93 |
+
}
|
94 |
+
}))
|
95 |
+
.pipe(rename('freemius-en.po'))
|
96 |
+
.pipe(gulp.dest(languagesFolder));
|
97 |
+
});
|
98 |
+
|
99 |
+
// Push updated po resource to transifex.
|
100 |
+
gulp.task('update-transifex', ['prepare-source'], function () {
|
101 |
+
return gulp.src(languagesFolder + 'freemius-en.po')
|
102 |
+
.pipe(transifex.pushResource());
|
103 |
+
});
|
104 |
+
|
105 |
+
// Download latest *.po translations.
|
106 |
+
gulp.task('download-translations', ['update-transifex'], function () {
|
107 |
+
return gulp.src(languagesFolder + 'freemius-en.po')
|
108 |
+
.pipe(transifex.pullResource());
|
109 |
+
});
|
110 |
+
|
111 |
+
// Move translations to languages root.
|
112 |
+
gulp.task('prepare-translations', ['download-translations'], function () {
|
113 |
+
var folders = getFolders(languagesFolder);
|
114 |
+
|
115 |
+
return folders.map(function (folder) {
|
116 |
+
return gulp.src(path.join(languagesFolder, folder, 'freemius-en.po'))
|
117 |
+
.pipe(rename('freemius-' + folder + '.po'))
|
118 |
+
.pipe(gulp.dest(languagesFolder));
|
119 |
+
});
|
120 |
+
});
|
121 |
+
|
122 |
+
// Feel up empty translations with English.
|
123 |
+
gulp.task('translations-feelup', ['prepare-translations'], function () {
|
124 |
+
return gulp.src(languagesFolder + '*.po')
|
125 |
+
.pipe(pofill({
|
126 |
+
items: function (item) {
|
127 |
+
// If msgstr is empty, use identity translation
|
128 |
+
if (0 == item.msgstr.length) {
|
129 |
+
item.msgstr = [''];
|
130 |
+
}
|
131 |
+
if (0 == item.msgstr[0].length) {
|
132 |
+
// item.msgid[0] = item.msgid;
|
133 |
+
item.msgstr[0] = item.msgid;
|
134 |
+
}
|
135 |
+
return item;
|
136 |
+
}
|
137 |
+
}))
|
138 |
+
.pipe(gulp.dest(languagesFolder));
|
139 |
+
});
|
140 |
+
|
141 |
+
// Cleanup temporary translation folders.
|
142 |
+
gulp.task('cleanup', ['prepare-translations'], function () {
|
143 |
+
var folders = getFolders(languagesFolder);
|
144 |
+
|
145 |
+
return folders.map(function (folder) {
|
146 |
+
return gulp.src(path.join(languagesFolder, folder), {read: false})
|
147 |
+
.pipe(clean());
|
148 |
+
});
|
149 |
+
});
|
150 |
+
|
151 |
+
// Compile *.po to *.mo binaries for usage.
|
152 |
+
gulp.task('compile-translations', ['translations-feelup'], function () {
|
153 |
+
// Compile POs to MOs.
|
154 |
+
return gulp.src(languagesFolder + '*.po')
|
155 |
+
.pipe(gettext())
|
156 |
+
.pipe(gulp.dest(languagesFolder))
|
157 |
+
});
|
158 |
+
|
159 |
+
gulp.task('default', [], function () {
|
160 |
+
gulp.run('prepare-source');
|
161 |
+
gulp.run('update-transifex');
|
162 |
+
gulp.run('download-translations');
|
163 |
+
gulp.run('prepare-translations');
|
164 |
+
gulp.run('translations-feelup');
|
165 |
+
gulp.run('cleanup');
|
166 |
+
gulp.run('compile-translations');
|
167 |
});
|
freemius/includes/class-fs-logger.php
CHANGED
@@ -1,688 +1,688 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
class FS_Logger {
|
14 |
-
private $_id;
|
15 |
-
private $_on = false;
|
16 |
-
private $_echo = false;
|
17 |
-
private $_file_start = 0;
|
18 |
-
/**
|
19 |
-
* @var int PHP Process ID.
|
20 |
-
*/
|
21 |
-
private static $_processID;
|
22 |
-
/**
|
23 |
-
* @var string PHP Script user name.
|
24 |
-
*/
|
25 |
-
private static $_ownerName;
|
26 |
-
/**
|
27 |
-
* @var bool Is storage logging turned on.
|
28 |
-
*/
|
29 |
-
private static $_isStorageLoggingOn;
|
30 |
-
/**
|
31 |
-
* @var int ABSPATH length.
|
32 |
-
*/
|
33 |
-
private static $_abspathLength;
|
34 |
-
|
35 |
-
private static $LOGGERS = array();
|
36 |
-
private static $LOG = array();
|
37 |
-
private static $CNT = 0;
|
38 |
-
private static $_HOOKED_FOOTER = false;
|
39 |
-
|
40 |
-
private function __construct( $id, $on = false, $echo = false ) {
|
41 |
-
$this->_id = $id;
|
42 |
-
|
43 |
-
$bt = debug_backtrace();
|
44 |
-
$caller = $bt[2];
|
45 |
-
|
46 |
-
if ( false !== strpos( $caller['file'], 'plugins' ) ) {
|
47 |
-
$this->_file_start = strpos( $caller['file'], 'plugins' ) + strlen( 'plugins/' );
|
48 |
-
} else {
|
49 |
-
$this->_file_start = strpos( $caller['file'], 'themes' ) + strlen( 'themes/' );
|
50 |
-
}
|
51 |
-
|
52 |
-
if ( $on ) {
|
53 |
-
$this->on();
|
54 |
-
}
|
55 |
-
if ( $echo ) {
|
56 |
-
$this->echo_on();
|
57 |
-
}
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* @param string $id
|
62 |
-
* @param bool $on
|
63 |
-
* @param bool $echo
|
64 |
-
*
|
65 |
-
* @return FS_Logger
|
66 |
-
*/
|
67 |
-
public static function get_logger( $id, $on = false, $echo = false ) {
|
68 |
-
$id = strtolower( $id );
|
69 |
-
|
70 |
-
if ( ! isset( self::$_processID ) ) {
|
71 |
-
self::init();
|
72 |
-
}
|
73 |
-
|
74 |
-
if ( ! isset( self::$LOGGERS[ $id ] ) ) {
|
75 |
-
self::$LOGGERS[ $id ] = new FS_Logger( $id, $on, $echo );
|
76 |
-
}
|
77 |
-
|
78 |
-
return self::$LOGGERS[ $id ];
|
79 |
-
}
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Initialize logging global info.
|
83 |
-
*
|
84 |
-
* @author Vova Feldman (@svovaf)
|
85 |
-
* @since 1.2.1.6
|
86 |
-
*/
|
87 |
-
private static function init() {
|
88 |
-
self::$_ownerName = function_exists( 'get_current_user' ) ?
|
89 |
-
get_current_user() :
|
90 |
-
'unknown';
|
91 |
-
self::$_isStorageLoggingOn = ( 1 == get_option( 'fs_storage_logger', 0 ) );
|
92 |
-
self::$_abspathLength = strlen( ABSPATH );
|
93 |
-
self::$_processID = mt_rand( 0, 32000 );
|
94 |
-
|
95 |
-
// Process ID may be `false` on errors.
|
96 |
-
if ( ! is_numeric( self::$_processID ) ) {
|
97 |
-
self::$_processID = 0;
|
98 |
-
}
|
99 |
-
}
|
100 |
-
|
101 |
-
private static function hook_footer() {
|
102 |
-
if ( self::$_HOOKED_FOOTER ) {
|
103 |
-
return;
|
104 |
-
}
|
105 |
-
|
106 |
-
if ( is_admin() ) {
|
107 |
-
add_action( 'admin_footer', 'FS_Logger::dump', 100 );
|
108 |
-
} else {
|
109 |
-
add_action( 'wp_footer', 'FS_Logger::dump', 100 );
|
110 |
-
}
|
111 |
-
}
|
112 |
-
|
113 |
-
function is_on() {
|
114 |
-
return $this->_on;
|
115 |
-
}
|
116 |
-
|
117 |
-
function on() {
|
118 |
-
$this->_on = true;
|
119 |
-
|
120 |
-
if ( ! function_exists( 'dbDelta' ) ) {
|
121 |
-
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
122 |
-
}
|
123 |
-
|
124 |
-
self::hook_footer();
|
125 |
-
}
|
126 |
-
|
127 |
-
function echo_on() {
|
128 |
-
$this->on();
|
129 |
-
|
130 |
-
$this->_echo = true;
|
131 |
-
}
|
132 |
-
|
133 |
-
function is_echo_on() {
|
134 |
-
return $this->_echo;
|
135 |
-
}
|
136 |
-
|
137 |
-
function get_id() {
|
138 |
-
return $this->_id;
|
139 |
-
}
|
140 |
-
|
141 |
-
function get_file() {
|
142 |
-
return $this->_file_start;
|
143 |
-
}
|
144 |
-
|
145 |
-
private function _log( &$message, $type = 'log', $wrapper ) {
|
146 |
-
if ( ! $this->is_on() ) {
|
147 |
-
return;
|
148 |
-
}
|
149 |
-
|
150 |
-
$bt = debug_backtrace();
|
151 |
-
$depth = $wrapper ? 3 : 2;
|
152 |
-
while ( $depth < count( $bt ) - 1 && 'eval' === $bt[ $depth ]['function'] ) {
|
153 |
-
$depth ++;
|
154 |
-
}
|
155 |
-
|
156 |
-
$caller = $bt[ $depth ];
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Retrieve the correct call file & line number from backtrace
|
160 |
-
* when logging from a wrapper method.
|
161 |
-
*
|
162 |
-
* @author Vova Feldman
|
163 |
-
* @since 1.2.1.6
|
164 |
-
*/
|
165 |
-
if ( empty( $caller['line'] ) ) {
|
166 |
-
$depth --;
|
167 |
-
|
168 |
-
while ( $depth >= 0 ) {
|
169 |
-
if ( ! empty( $bt[ $depth ]['line'] ) ) {
|
170 |
-
$caller['line'] = $bt[ $depth ]['line'];
|
171 |
-
$caller['file'] = $bt[ $depth ]['file'];
|
172 |
-
break;
|
173 |
-
}
|
174 |
-
}
|
175 |
-
}
|
176 |
-
|
177 |
-
$log = array_merge( $caller, array(
|
178 |
-
'cnt' => self::$CNT ++,
|
179 |
-
'logger' => $this,
|
180 |
-
'timestamp' => microtime( true ),
|
181 |
-
'log_type' => $type,
|
182 |
-
'msg' => $message,
|
183 |
-
) );
|
184 |
-
|
185 |
-
if ( self::$_isStorageLoggingOn ) {
|
186 |
-
$this->db_log( $type, $message, self::$CNT, $caller );
|
187 |
-
}
|
188 |
-
|
189 |
-
self::$LOG[] = $log;
|
190 |
-
|
191 |
-
if ( $this->is_echo_on() && ! Freemius::is_ajax() ) {
|
192 |
-
echo self::format_html( $log ) . "\n";
|
193 |
-
}
|
194 |
-
}
|
195 |
-
|
196 |
-
function log( $message, $wrapper = false ) {
|
197 |
-
$this->_log( $message, 'log', $wrapper );
|
198 |
-
}
|
199 |
-
|
200 |
-
function info( $message, $wrapper = false ) {
|
201 |
-
$this->_log( $message, 'info', $wrapper );
|
202 |
-
}
|
203 |
-
|
204 |
-
function warn( $message, $wrapper = false ) {
|
205 |
-
$this->_log( $message, 'warn', $wrapper );
|
206 |
-
}
|
207 |
-
|
208 |
-
function error( $message, $wrapper = false ) {
|
209 |
-
$this->_log( $message, 'error', $wrapper );
|
210 |
-
}
|
211 |
-
|
212 |
-
/**
|
213 |
-
* Log API error.
|
214 |
-
*
|
215 |
-
* @author Vova Feldman (@svovaf)
|
216 |
-
* @since 1.2.1.5
|
217 |
-
*
|
218 |
-
* @param mixed $api_result
|
219 |
-
* @param bool $wrapper
|
220 |
-
*/
|
221 |
-
function api_error( $api_result, $wrapper = false ) {
|
222 |
-
$message = '';
|
223 |
-
if ( is_object( $api_result ) && isset( $api_result->error ) ) {
|
224 |
-
$message = $api_result->error->message;
|
225 |
-
} else if ( is_object( $api_result ) ) {
|
226 |
-
$message = var_export( $api_result, true );
|
227 |
-
} else if ( is_string( $api_result ) ) {
|
228 |
-
$message = $api_result;
|
229 |
-
} else if ( empty( $api_result ) ) {
|
230 |
-
$message = 'Empty API result.';
|
231 |
-
}
|
232 |
-
|
233 |
-
$message = 'API Error: ' . $message;
|
234 |
-
|
235 |
-
$this->_log( $message, 'error', $wrapper );
|
236 |
-
}
|
237 |
-
|
238 |
-
function entrance( $message = '', $wrapper = false ) {
|
239 |
-
$msg = 'Entrance' . ( empty( $message ) ? '' : ' > ' ) . $message;
|
240 |
-
|
241 |
-
$this->_log( $msg, 'log', $wrapper );
|
242 |
-
}
|
243 |
-
|
244 |
-
function departure( $message = '', $wrapper = false ) {
|
245 |
-
$msg = 'Departure' . ( empty( $message ) ? '' : ' > ' ) . $message;
|
246 |
-
|
247 |
-
$this->_log( $msg, 'log', $wrapper );
|
248 |
-
}
|
249 |
-
|
250 |
-
#--------------------------------------------------------------------------------
|
251 |
-
#region Log Formatting
|
252 |
-
#--------------------------------------------------------------------------------
|
253 |
-
|
254 |
-
private static function format( $log, $show_type = true ) {
|
255 |
-
return '[' . str_pad( $log['cnt'], strlen( self::$CNT ), '0', STR_PAD_LEFT ) . '] [' . $log['logger']->_id . '] ' . ( $show_type ? '[' . $log['log_type'] . ']' : '' ) . ( ! empty( $log['class'] ) ? $log['class'] . $log['type'] : '' ) . $log['function'] . ' >> ' . $log['msg'] . ( isset( $log['file'] ) ? ' (' . substr( $log['file'], $log['logger']->_file_start ) . ' ' . $log['line'] . ') ' : '' ) . ' [' . $log['timestamp'] . ']';
|
256 |
-
}
|
257 |
-
|
258 |
-
private static function format_html( $log ) {
|
259 |
-
return '<div style="font-size: 13px; font-family: monospace; color: #7da767; padding: 8px 3px; background: #000; border-bottom: 1px solid #555;">[' . $log['cnt'] . '] [' . $log['logger']->_id . '] [' . $log['log_type'] . '] <b><code style="color: #c4b1e0;">' . ( ! empty( $log['class'] ) ? $log['class'] . $log['type'] : '' ) . $log['function'] . '</code> >> <b style="color: #f59330;">' . esc_html( $log['msg'] ) . '</b></b>' . ( isset( $log['file'] ) ? ' (' . substr( $log['file'], $log['logger']->_file_start ) . ' ' . $log['line'] . ')' : '' ) . ' [' . $log['timestamp'] . ']</div>';
|
260 |
-
}
|
261 |
-
|
262 |
-
#endregion
|
263 |
-
|
264 |
-
static function dump() {
|
265 |
-
?>
|
266 |
-
<!-- BEGIN: Freemius PHP Console Log -->
|
267 |
-
<script type="text/javascript">
|
268 |
-
<?php
|
269 |
-
foreach ( self::$LOG as $log ) {
|
270 |
-
echo 'console.' . $log['log_type'] . '(' . json_encode( self::format( $log, false ) ) . ')' . "\n";
|
271 |
-
}
|
272 |
-
?>
|
273 |
-
</script>
|
274 |
-
<!-- END: Freemius PHP Console Log -->
|
275 |
-
<?php
|
276 |
-
}
|
277 |
-
|
278 |
-
static function get_log() {
|
279 |
-
return self::$LOG;
|
280 |
-
}
|
281 |
-
|
282 |
-
#--------------------------------------------------------------------------------
|
283 |
-
#region Database Logging
|
284 |
-
#--------------------------------------------------------------------------------
|
285 |
-
|
286 |
-
/**
|
287 |
-
* @author Vova Feldman (@svovaf)
|
288 |
-
* @since 1.2.1.6
|
289 |
-
*
|
290 |
-
* @return bool
|
291 |
-
*/
|
292 |
-
public static function is_storage_logging_on() {
|
293 |
-
if ( ! isset( self::$_isStorageLoggingOn ) ) {
|
294 |
-
self::$_isStorageLoggingOn = ( 1 == get_option( 'fs_storage_logger', 0 ) );
|
295 |
-
}
|
296 |
-
|
297 |
-
return self::$_isStorageLoggingOn;
|
298 |
-
}
|
299 |
-
|
300 |
-
/**
|
301 |
-
* Turns on/off database persistent debugging to capture
|
302 |
-
* multi-session logs to debug complex flows like
|
303 |
-
* plugin auto-deactivate on premium version activation.
|
304 |
-
*
|
305 |
-
* @todo Check if Theme Check has issues with DB tables for themes.
|
306 |
-
*
|
307 |
-
* @author Vova Feldman (@svovaf)
|
308 |
-
* @since 1.2.1.6
|
309 |
-
*
|
310 |
-
* @param bool $is_on
|
311 |
-
*
|
312 |
-
* @return bool
|
313 |
-
*/
|
314 |
-
public static function _set_storage_logging( $is_on = true ) {
|
315 |
-
global $wpdb;
|
316 |
-
|
317 |
-
$table = "{$wpdb->prefix}fs_logger";
|
318 |
-
|
319 |
-
if ( $is_on ) {
|
320 |
-
/**
|
321 |
-
* Create logging table.
|
322 |
-
*
|
323 |
-
* NOTE:
|
324 |
-
* dbDelta must use KEY and not INDEX for indexes.
|
325 |
-
*
|
326 |
-
* @link https://core.trac.wordpress.org/ticket/2695
|
327 |
-
*/
|
328 |
-
$result = $wpdb->query( "CREATE TABLE {$table} (
|
329 |
-
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
330 |
-
`process_id` INT UNSIGNED NOT NULL,
|
331 |
-
`user_name` VARCHAR(64) NOT NULL,
|
332 |
-
`logger` VARCHAR(128) NOT NULL,
|
333 |
-
`log_order` INT UNSIGNED NOT NULL,
|
334 |
-
`type` ENUM('log','info','warn','error') NOT NULL DEFAULT 'log',
|
335 |
-
`message` TEXT NOT NULL,
|
336 |
-
`file` VARCHAR(256) NOT NULL,
|
337 |
-
`line` INT UNSIGNED NOT NULL,
|
338 |
-
`function` VARCHAR(256) NOT NULL,
|
339 |
-
`request_type` ENUM('call','ajax','cron') NOT NULL DEFAULT 'call',
|
340 |
-
`request_url` VARCHAR(1024) NOT NULL,
|
341 |
-
`created` DECIMAL(16, 6) NOT NULL,
|
342 |
-
PRIMARY KEY (`id`),
|
343 |
-
KEY `process_id` (`process_id` ASC),
|
344 |
-
KEY `process_logger` (`process_id` ASC, `logger` ASC),
|
345 |
-
KEY `function` (`function` ASC),
|
346 |
-
KEY `type` (`type` ASC))" );
|
347 |
-
} else {
|
348 |
-
/**
|
349 |
-
* Drop logging table.
|
350 |
-
*/
|
351 |
-
$result = $wpdb->query( "DROP TABLE IF EXISTS $table;" );
|
352 |
-
}
|
353 |
-
|
354 |
-
if ( false !== $result ) {
|
355 |
-
update_option( 'fs_storage_logger', ( $is_on ? 1 : 0 ) );
|
356 |
-
}
|
357 |
-
|
358 |
-
return ( false !== $result );
|
359 |
-
}
|
360 |
-
|
361 |
-
/**
|
362 |
-
* @author Vova Feldman (@svovaf)
|
363 |
-
* @since 1.2.1.6
|
364 |
-
*
|
365 |
-
* @param string $type
|
366 |
-
* @param string $message
|
367 |
-
* @param int $log_order
|
368 |
-
* @param array $caller
|
369 |
-
*
|
370 |
-
* @return false|int
|
371 |
-
*/
|
372 |
-
private function db_log(
|
373 |
-
&$type,
|
374 |
-
&$message,
|
375 |
-
&$log_order,
|
376 |
-
&$caller
|
377 |
-
) {
|
378 |
-
global $wpdb;
|
379 |
-
|
380 |
-
$request_type = 'call';
|
381 |
-
if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
|
382 |
-
$request_type = 'cron';
|
383 |
-
} else if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
384 |
-
$request_type = 'ajax';
|
385 |
-
}
|
386 |
-
|
387 |
-
$request_url = WP_FS__IS_HTTP_REQUEST ?
|
388 |
-
$_SERVER['REQUEST_URI'] :
|
389 |
-
'';
|
390 |
-
|
391 |
-
return $wpdb->insert(
|
392 |
-
"{$wpdb->prefix}fs_logger",
|
393 |
-
array(
|
394 |
-
'process_id' => self::$_processID,
|
395 |
-
'user_name' => self::$_ownerName,
|
396 |
-
'logger' => $this->_id,
|
397 |
-
'log_order' => $log_order,
|
398 |
-
'type' => $type,
|
399 |
-
'request_type' => $request_type,
|
400 |
-
'request_url' => $request_url,
|
401 |
-
'message' => $message,
|
402 |
-
'file' => isset( $caller['file'] ) ?
|
403 |
-
substr( $caller['file'], self::$_abspathLength ) :
|
404 |
-
'',
|
405 |
-
'line' => $caller['line'],
|
406 |
-
'function' => ( ! empty( $caller['class'] ) ? $caller['class'] . $caller['type'] : '' ) . $caller['function'],
|
407 |
-
'created' => microtime( true ),
|
408 |
-
)
|
409 |
-
);
|
410 |
-
}
|
411 |
-
|
412 |
-
/**
|
413 |
-
* Persistent DB logger columns.
|
414 |
-
*
|
415 |
-
* @var array
|
416 |
-
*/
|
417 |
-
private static $_log_columns = array(
|
418 |
-
'id',
|
419 |
-
'process_id',
|
420 |
-
'user_name',
|
421 |
-
'logger',
|
422 |
-
'log_order',
|
423 |
-
'type',
|
424 |
-
'message',
|
425 |
-
'file',
|
426 |
-
'line',
|
427 |
-
'function',
|
428 |
-
'request_type',
|
429 |
-
'request_url',
|
430 |
-
'created',
|
431 |
-
);
|
432 |
-
|
433 |
-
/**
|
434 |
-
* Create DB logs query.
|
435 |
-
*
|
436 |
-
* @author Vova Feldman (@svovaf)
|
437 |
-
* @since 1.2.1.6
|
438 |
-
*
|
439 |
-
* @param bool $filters
|
440 |
-
* @param int $limit
|
441 |
-
* @param int $offset
|
442 |
-
* @param bool $order
|
443 |
-
* @param bool $escape_eol
|
444 |
-
*
|
445 |
-
* @return string
|
446 |
-
*/
|
447 |
-
private static function build_db_logs_query(
|
448 |
-
$filters = false,
|
449 |
-
$limit = 200,
|
450 |
-
$offset = 0,
|
451 |
-
$order = false,
|
452 |
-
$escape_eol = false
|
453 |
-
) {
|
454 |
-
global $wpdb;
|
455 |
-
|
456 |
-
$select = '*';
|
457 |
-
|
458 |
-
if ( $escape_eol ) {
|
459 |
-
$select = '';
|
460 |
-
for ( $i = 0, $len = count( self::$_log_columns ); $i < $len; $i ++ ) {
|
461 |
-
if ( $i > 0 ) {
|
462 |
-
$select .= ', ';
|
463 |
-
}
|
464 |
-
|
465 |
-
if ( 'message' !== self::$_log_columns[ $i ] ) {
|
466 |
-
$select .= self::$_log_columns[ $i ];
|
467 |
-
} else {
|
468 |
-
$select .= 'REPLACE(message , \'\n\', \' \') AS message';
|
469 |
-
}
|
470 |
-
}
|
471 |
-
}
|
472 |
-
|
473 |
-
$query = "SELECT {$select} FROM {$wpdb->prefix}fs_logger";
|
474 |
-
if ( is_array( $filters ) ) {
|
475 |
-
$criteria = array();
|
476 |
-
|
477 |
-
if ( ! empty( $filters['type'] ) && 'all' !== $filters['type'] ) {
|
478 |
-
$filters['type'] = strtolower( $filters['type'] );
|
479 |
-
|
480 |
-
switch ( $filters['type'] ) {
|
481 |
-
case 'warn_error':
|
482 |
-
$criteria[] = array( 'col' => 'type', 'val' => array( 'warn', 'error' ) );
|
483 |
-
break;
|
484 |
-
case 'error':
|
485 |
-
case 'warn':
|
486 |
-
$criteria[] = array( 'col' => 'type', 'val' => $filters['type'] );
|
487 |
-
break;
|
488 |
-
case 'info':
|
489 |
-
default:
|
490 |
-
$criteria[] = array( 'col' => 'type', 'val' => array( 'info', 'log' ) );
|
491 |
-
break;
|
492 |
-
}
|
493 |
-
}
|
494 |
-
|
495 |
-
if ( ! empty( $filters['request_type'] ) ) {
|
496 |
-
$filters['request_type'] = strtolower( $filters['request_type'] );
|
497 |
-
|
498 |
-
if ( in_array( $filters['request_type'], array( 'call', 'ajax', 'cron' ) ) ) {
|
499 |
-
$criteria[] = array( 'col' => 'request_type', 'val' => $filters['request_type'] );
|
500 |
-
}
|
501 |
-
}
|
502 |
-
|
503 |
-
if ( ! empty( $filters['file'] ) ) {
|
504 |
-
$criteria[] = array(
|
505 |
-
'col' => 'file',
|
506 |
-
'op' => 'LIKE',
|
507 |
-
'val' => '%' . esc_sql( $filters['file'] ),
|
508 |
-
);
|
509 |
-
}
|
510 |
-
|
511 |
-
if ( ! empty( $filters['function'] ) ) {
|
512 |
-
$criteria[] = array(
|
513 |
-
'col' => 'function',
|
514 |
-
'op' => 'LIKE',
|
515 |
-
'val' => '%' . esc_sql( $filters['function'] ),
|
516 |
-
);
|
517 |
-
}
|
518 |
-
|
519 |
-
if ( ! empty( $filters['process_id'] ) && is_numeric( $filters['process_id'] ) ) {
|
520 |
-
$criteria[] = array( 'col' => 'process_id', 'val' => $filters['process_id'] );
|
521 |
-
}
|
522 |
-
|
523 |
-
if ( ! empty( $filters['logger'] ) ) {
|
524 |
-
$criteria[] = array(
|
525 |
-
'col' => 'logger',
|
526 |
-
'op' => 'LIKE',
|
527 |
-
'val' => '%' . esc_sql( $filters['logger'] ) . '%',
|
528 |
-
);
|
529 |
-
}
|
530 |
-
|
531 |
-
if ( ! empty( $filters['message'] ) ) {
|
532 |
-
$criteria[] = array(
|
533 |
-
'col' => 'message',
|
534 |
-
'op' => 'LIKE',
|
535 |
-
'val' => '%' . esc_sql( $filters['message'] ) . '%',
|
536 |
-
);
|
537 |
-
}
|
538 |
-
|
539 |
-
if ( 0 < count( $criteria ) ) {
|
540 |
-
$query .= "\nWHERE\n";
|
541 |
-
|
542 |
-
$first = true;
|
543 |
-
foreach ( $criteria as $c ) {
|
544 |
-
if ( ! $first ) {
|
545 |
-
$query .= "AND\n";
|
546 |
-
}
|
547 |
-
|
548 |
-
if ( is_array( $c['val'] ) ) {
|
549 |
-
$operator = 'IN';
|
550 |
-
|
551 |
-
for ( $i = 0, $len = count( $c['val'] ); $i < $len; $i ++ ) {
|
552 |
-
$c['val'][ $i ] = "'" . esc_sql( $c['val'][ $i ] ) . "'";
|
553 |
-
}
|
554 |
-
|
555 |
-
$val = '(' . implode( ',', $c['val'] ) . ')';
|
556 |
-
} else {
|
557 |
-
$operator = ! empty( $c['op'] ) ? $c['op'] : '=';
|
558 |
-
$val = "'" . esc_sql( $c['val'] ) . "'";
|
559 |
-
}
|
560 |
-
|
561 |
-
$query .= "`{$c['col']}` {$operator} {$val}\n";
|
562 |
-
|
563 |
-
$first = false;
|
564 |
-
}
|
565 |
-
}
|
566 |
-
}
|
567 |
-
|
568 |
-
if ( ! is_array( $order ) ) {
|
569 |
-
$order = array(
|
570 |
-
'col' => 'id',
|
571 |
-
'order' => 'desc'
|
572 |
-
);
|
573 |
-
}
|
574 |
-
|
575 |
-
$query .= " ORDER BY {$order['col']} {$order['order']} LIMIT {$offset},{$limit}";
|
576 |
-
|
577 |
-
return $query;
|
578 |
-
}
|
579 |
-
|
580 |
-
/**
|
581 |
-
* Load logs from DB.
|
582 |
-
*
|
583 |
-
* @author Vova Feldman (@svovaf)
|
584 |
-
* @since 1.2.1.6
|
585 |
-
*
|
586 |
-
* @param bool $filters
|
587 |
-
* @param int $limit
|
588 |
-
* @param int $offset
|
589 |
-
* @param bool $order
|
590 |
-
*
|
591 |
-
* @return object[]|null
|
592 |
-
*/
|
593 |
-
public static function load_db_logs(
|
594 |
-
$filters = false,
|
595 |
-
$limit = 200,
|
596 |
-
$offset = 0,
|
597 |
-
$order = false
|
598 |
-
) {
|
599 |
-
global $wpdb;
|
600 |
-
|
601 |
-
$query = self::build_db_logs_query(
|
602 |
-
$filters,
|
603 |
-
$limit,
|
604 |
-
$offset,
|
605 |
-
$order
|
606 |
-
);
|
607 |
-
|
608 |
-
return $wpdb->get_results( $query );
|
609 |
-
}
|
610 |
-
|
611 |
-
/**
|
612 |
-
* Load logs from DB.
|
613 |
-
*
|
614 |
-
* @author Vova Feldman (@svovaf)
|
615 |
-
* @since 1.2.1.6
|
616 |
-
*
|
617 |
-
* @param bool $filters
|
618 |
-
* @param string $filename
|
619 |
-
* @param int $limit
|
620 |
-
* @param int $offset
|
621 |
-
* @param bool $order
|
622 |
-
*
|
623 |
-
* @return false|string File download URL or false on failure.
|
624 |
-
*/
|
625 |
-
public static function download_db_logs(
|
626 |
-
$filters = false,
|
627 |
-
$filename = '',
|
628 |
-
$limit = 10000,
|
629 |
-
$offset = 0,
|
630 |
-
$order = false
|
631 |
-
) {
|
632 |
-
global $wpdb;
|
633 |
-
|
634 |
-
$query = self::build_db_logs_query(
|
635 |
-
$filters,
|
636 |
-
$limit,
|
637 |
-
$offset,
|
638 |
-
$order,
|
639 |
-
true
|
640 |
-
);
|
641 |
-
|
642 |
-
$upload_dir = wp_upload_dir();
|
643 |
-
if ( empty( $filename ) ) {
|
644 |
-
$filename = 'fs-logs-' . date( 'Y-m-d_H-i-s', WP_FS__SCRIPT_START_TIME ) . '.csv';
|
645 |
-
}
|
646 |
-
$filepath = rtrim( $upload_dir['path'], '/' ) . "/{$filename}";
|
647 |
-
|
648 |
-
$query .= " INTO OUTFILE '{$filepath}' FIELDS TERMINATED BY '\t' ESCAPED BY '\\\\' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\\n'";
|
649 |
-
|
650 |
-
$columns = '';
|
651 |
-
for ( $i = 0, $len = count( self::$_log_columns ); $i < $len; $i ++ ) {
|
652 |
-
if ( $i > 0 ) {
|
653 |
-
$columns .= ', ';
|
654 |
-
}
|
655 |
-
|
656 |
-
$columns .= "'" . self::$_log_columns[ $i ] . "'";
|
657 |
-
}
|
658 |
-
|
659 |
-
$query = "SELECT {$columns} UNION ALL " . $query;
|
660 |
-
|
661 |
-
$result = $wpdb->query( $query );
|
662 |
-
|
663 |
-
if ( false === $result ) {
|
664 |
-
return false;
|
665 |
-
}
|
666 |
-
|
667 |
-
return rtrim( $upload_dir['url'], '/' ) . '/' . $filename;
|
668 |
-
}
|
669 |
-
|
670 |
-
/**
|
671 |
-
* @author Vova Feldman (@svovaf)
|
672 |
-
* @since 1.2.1.6
|
673 |
-
*
|
674 |
-
* @param string $filename
|
675 |
-
*
|
676 |
-
* @return string
|
677 |
-
*/
|
678 |
-
public static function get_logs_download_url( $filename = '' ) {
|
679 |
-
$upload_dir = wp_upload_dir();
|
680 |
-
if ( empty( $filename ) ) {
|
681 |
-
$filename = 'fs-logs-' . date( 'Y-m-d_H-i-s', WP_FS__SCRIPT_START_TIME ) . '.csv';
|
682 |
-
}
|
683 |
-
|
684 |
-
return rtrim( $upload_dir['url'], '/' ) . $filename;
|
685 |
-
}
|
686 |
-
|
687 |
-
#endregion
|
688 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
class FS_Logger {
|
14 |
+
private $_id;
|
15 |
+
private $_on = false;
|
16 |
+
private $_echo = false;
|
17 |
+
private $_file_start = 0;
|
18 |
+
/**
|
19 |
+
* @var int PHP Process ID.
|
20 |
+
*/
|
21 |
+
private static $_processID;
|
22 |
+
/**
|
23 |
+
* @var string PHP Script user name.
|
24 |
+
*/
|
25 |
+
private static $_ownerName;
|
26 |
+
/**
|
27 |
+
* @var bool Is storage logging turned on.
|
28 |
+
*/
|
29 |
+
private static $_isStorageLoggingOn;
|
30 |
+
/**
|
31 |
+
* @var int ABSPATH length.
|
32 |
+
*/
|
33 |
+
private static $_abspathLength;
|
34 |
+
|
35 |
+
private static $LOGGERS = array();
|
36 |
+
private static $LOG = array();
|
37 |
+
private static $CNT = 0;
|
38 |
+
private static $_HOOKED_FOOTER = false;
|
39 |
+
|
40 |
+
private function __construct( $id, $on = false, $echo = false ) {
|
41 |
+
$this->_id = $id;
|
42 |
+
|
43 |
+
$bt = debug_backtrace();
|
44 |
+
$caller = $bt[2];
|
45 |
+
|
46 |
+
if ( false !== strpos( $caller['file'], 'plugins' ) ) {
|
47 |
+
$this->_file_start = strpos( $caller['file'], 'plugins' ) + strlen( 'plugins/' );
|
48 |
+
} else {
|
49 |
+
$this->_file_start = strpos( $caller['file'], 'themes' ) + strlen( 'themes/' );
|
50 |
+
}
|
51 |
+
|
52 |
+
if ( $on ) {
|
53 |
+
$this->on();
|
54 |
+
}
|
55 |
+
if ( $echo ) {
|
56 |
+
$this->echo_on();
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @param string $id
|
62 |
+
* @param bool $on
|
63 |
+
* @param bool $echo
|
64 |
+
*
|
65 |
+
* @return FS_Logger
|
66 |
+
*/
|
67 |
+
public static function get_logger( $id, $on = false, $echo = false ) {
|
68 |
+
$id = strtolower( $id );
|
69 |
+
|
70 |
+
if ( ! isset( self::$_processID ) ) {
|
71 |
+
self::init();
|
72 |
+
}
|
73 |
+
|
74 |
+
if ( ! isset( self::$LOGGERS[ $id ] ) ) {
|
75 |
+
self::$LOGGERS[ $id ] = new FS_Logger( $id, $on, $echo );
|
76 |
+
}
|
77 |
+
|
78 |
+
return self::$LOGGERS[ $id ];
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Initialize logging global info.
|
83 |
+
*
|
84 |
+
* @author Vova Feldman (@svovaf)
|
85 |
+
* @since 1.2.1.6
|
86 |
+
*/
|
87 |
+
private static function init() {
|
88 |
+
self::$_ownerName = function_exists( 'get_current_user' ) ?
|
89 |
+
get_current_user() :
|
90 |
+
'unknown';
|
91 |
+
self::$_isStorageLoggingOn = ( 1 == get_option( 'fs_storage_logger', 0 ) );
|
92 |
+
self::$_abspathLength = strlen( ABSPATH );
|
93 |
+
self::$_processID = mt_rand( 0, 32000 );
|
94 |
+
|
95 |
+
// Process ID may be `false` on errors.
|
96 |
+
if ( ! is_numeric( self::$_processID ) ) {
|
97 |
+
self::$_processID = 0;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
private static function hook_footer() {
|
102 |
+
if ( self::$_HOOKED_FOOTER ) {
|
103 |
+
return;
|
104 |
+
}
|
105 |
+
|
106 |
+
if ( is_admin() ) {
|
107 |
+
add_action( 'admin_footer', 'FS_Logger::dump', 100 );
|
108 |
+
} else {
|
109 |
+
add_action( 'wp_footer', 'FS_Logger::dump', 100 );
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
function is_on() {
|
114 |
+
return $this->_on;
|
115 |
+
}
|
116 |
+
|
117 |
+
function on() {
|
118 |
+
$this->_on = true;
|
119 |
+
|
120 |
+
if ( ! function_exists( 'dbDelta' ) ) {
|
121 |
+
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
122 |
+
}
|
123 |
+
|
124 |
+
self::hook_footer();
|
125 |
+
}
|
126 |
+
|
127 |
+
function echo_on() {
|
128 |
+
$this->on();
|
129 |
+
|
130 |
+
$this->_echo = true;
|
131 |
+
}
|
132 |
+
|
133 |
+
function is_echo_on() {
|
134 |
+
return $this->_echo;
|
135 |
+
}
|
136 |
+
|
137 |
+
function get_id() {
|
138 |
+
return $this->_id;
|
139 |
+
}
|
140 |
+
|
141 |
+
function get_file() {
|
142 |
+
return $this->_file_start;
|
143 |
+
}
|
144 |
+
|
145 |
+
private function _log( &$message, $type = 'log', $wrapper ) {
|
146 |
+
if ( ! $this->is_on() ) {
|
147 |
+
return;
|
148 |
+
}
|
149 |
+
|
150 |
+
$bt = debug_backtrace();
|
151 |
+
$depth = $wrapper ? 3 : 2;
|
152 |
+
while ( $depth < count( $bt ) - 1 && 'eval' === $bt[ $depth ]['function'] ) {
|
153 |
+
$depth ++;
|
154 |
+
}
|
155 |
+
|
156 |
+
$caller = $bt[ $depth ];
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Retrieve the correct call file & line number from backtrace
|
160 |
+
* when logging from a wrapper method.
|
161 |
+
*
|
162 |
+
* @author Vova Feldman
|
163 |
+
* @since 1.2.1.6
|
164 |
+
*/
|
165 |
+
if ( empty( $caller['line'] ) ) {
|
166 |
+
$depth --;
|
167 |
+
|
168 |
+
while ( $depth >= 0 ) {
|
169 |
+
if ( ! empty( $bt[ $depth ]['line'] ) ) {
|
170 |
+
$caller['line'] = $bt[ $depth ]['line'];
|
171 |
+
$caller['file'] = $bt[ $depth ]['file'];
|
172 |
+
break;
|
173 |
+
}
|
174 |
+
}
|
175 |
+
}
|
176 |
+
|
177 |
+
$log = array_merge( $caller, array(
|
178 |
+
'cnt' => self::$CNT ++,
|
179 |
+
'logger' => $this,
|
180 |
+
'timestamp' => microtime( true ),
|
181 |
+
'log_type' => $type,
|
182 |
+
'msg' => $message,
|
183 |
+
) );
|
184 |
+
|
185 |
+
if ( self::$_isStorageLoggingOn ) {
|
186 |
+
$this->db_log( $type, $message, self::$CNT, $caller );
|
187 |
+
}
|
188 |
+
|
189 |
+
self::$LOG[] = $log;
|
190 |
+
|
191 |
+
if ( $this->is_echo_on() && ! Freemius::is_ajax() ) {
|
192 |
+
echo self::format_html( $log ) . "\n";
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
function log( $message, $wrapper = false ) {
|
197 |
+
$this->_log( $message, 'log', $wrapper );
|
198 |
+
}
|
199 |
+
|
200 |
+
function info( $message, $wrapper = false ) {
|
201 |
+
$this->_log( $message, 'info', $wrapper );
|
202 |
+
}
|
203 |
+
|
204 |
+
function warn( $message, $wrapper = false ) {
|
205 |
+
$this->_log( $message, 'warn', $wrapper );
|
206 |
+
}
|
207 |
+
|
208 |
+
function error( $message, $wrapper = false ) {
|
209 |
+
$this->_log( $message, 'error', $wrapper );
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Log API error.
|
214 |
+
*
|
215 |
+
* @author Vova Feldman (@svovaf)
|
216 |
+
* @since 1.2.1.5
|
217 |
+
*
|
218 |
+
* @param mixed $api_result
|
219 |
+
* @param bool $wrapper
|
220 |
+
*/
|
221 |
+
function api_error( $api_result, $wrapper = false ) {
|
222 |
+
$message = '';
|
223 |
+
if ( is_object( $api_result ) && isset( $api_result->error ) ) {
|
224 |
+
$message = $api_result->error->message;
|
225 |
+
} else if ( is_object( $api_result ) ) {
|
226 |
+
$message = var_export( $api_result, true );
|
227 |
+
} else if ( is_string( $api_result ) ) {
|
228 |
+
$message = $api_result;
|
229 |
+
} else if ( empty( $api_result ) ) {
|
230 |
+
$message = 'Empty API result.';
|
231 |
+
}
|
232 |
+
|
233 |
+
$message = 'API Error: ' . $message;
|
234 |
+
|
235 |
+
$this->_log( $message, 'error', $wrapper );
|
236 |
+
}
|
237 |
+
|
238 |
+
function entrance( $message = '', $wrapper = false ) {
|
239 |
+
$msg = 'Entrance' . ( empty( $message ) ? '' : ' > ' ) . $message;
|
240 |
+
|
241 |
+
$this->_log( $msg, 'log', $wrapper );
|
242 |
+
}
|
243 |
+
|
244 |
+
function departure( $message = '', $wrapper = false ) {
|
245 |
+
$msg = 'Departure' . ( empty( $message ) ? '' : ' > ' ) . $message;
|
246 |
+
|
247 |
+
$this->_log( $msg, 'log', $wrapper );
|
248 |
+
}
|
249 |
+
|
250 |
+
#--------------------------------------------------------------------------------
|
251 |
+
#region Log Formatting
|
252 |
+
#--------------------------------------------------------------------------------
|
253 |
+
|
254 |
+
private static function format( $log, $show_type = true ) {
|
255 |
+
return '[' . str_pad( $log['cnt'], strlen( self::$CNT ), '0', STR_PAD_LEFT ) . '] [' . $log['logger']->_id . '] ' . ( $show_type ? '[' . $log['log_type'] . ']' : '' ) . ( ! empty( $log['class'] ) ? $log['class'] . $log['type'] : '' ) . $log['function'] . ' >> ' . $log['msg'] . ( isset( $log['file'] ) ? ' (' . substr( $log['file'], $log['logger']->_file_start ) . ' ' . $log['line'] . ') ' : '' ) . ' [' . $log['timestamp'] . ']';
|
256 |
+
}
|
257 |
+
|
258 |
+
private static function format_html( $log ) {
|
259 |
+
return '<div style="font-size: 13px; font-family: monospace; color: #7da767; padding: 8px 3px; background: #000; border-bottom: 1px solid #555;">[' . $log['cnt'] . '] [' . $log['logger']->_id . '] [' . $log['log_type'] . '] <b><code style="color: #c4b1e0;">' . ( ! empty( $log['class'] ) ? $log['class'] . $log['type'] : '' ) . $log['function'] . '</code> >> <b style="color: #f59330;">' . esc_html( $log['msg'] ) . '</b></b>' . ( isset( $log['file'] ) ? ' (' . substr( $log['file'], $log['logger']->_file_start ) . ' ' . $log['line'] . ')' : '' ) . ' [' . $log['timestamp'] . ']</div>';
|
260 |
+
}
|
261 |
+
|
262 |
+
#endregion
|
263 |
+
|
264 |
+
static function dump() {
|
265 |
+
?>
|
266 |
+
<!-- BEGIN: Freemius PHP Console Log -->
|
267 |
+
<script type="text/javascript">
|
268 |
+
<?php
|
269 |
+
foreach ( self::$LOG as $log ) {
|
270 |
+
echo 'console.' . $log['log_type'] . '(' . json_encode( self::format( $log, false ) ) . ')' . "\n";
|
271 |
+
}
|
272 |
+
?>
|
273 |
+
</script>
|
274 |
+
<!-- END: Freemius PHP Console Log -->
|
275 |
+
<?php
|
276 |
+
}
|
277 |
+
|
278 |
+
static function get_log() {
|
279 |
+
return self::$LOG;
|
280 |
+
}
|
281 |
+
|
282 |
+
#--------------------------------------------------------------------------------
|
283 |
+
#region Database Logging
|
284 |
+
#--------------------------------------------------------------------------------
|
285 |
+
|
286 |
+
/**
|
287 |
+
* @author Vova Feldman (@svovaf)
|
288 |
+
* @since 1.2.1.6
|
289 |
+
*
|
290 |
+
* @return bool
|
291 |
+
*/
|
292 |
+
public static function is_storage_logging_on() {
|
293 |
+
if ( ! isset( self::$_isStorageLoggingOn ) ) {
|
294 |
+
self::$_isStorageLoggingOn = ( 1 == get_option( 'fs_storage_logger', 0 ) );
|
295 |
+
}
|
296 |
+
|
297 |
+
return self::$_isStorageLoggingOn;
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Turns on/off database persistent debugging to capture
|
302 |
+
* multi-session logs to debug complex flows like
|
303 |
+
* plugin auto-deactivate on premium version activation.
|
304 |
+
*
|
305 |
+
* @todo Check if Theme Check has issues with DB tables for themes.
|
306 |
+
*
|
307 |
+
* @author Vova Feldman (@svovaf)
|
308 |
+
* @since 1.2.1.6
|
309 |
+
*
|
310 |
+
* @param bool $is_on
|
311 |
+
*
|
312 |
+
* @return bool
|
313 |
+
*/
|
314 |
+
public static function _set_storage_logging( $is_on = true ) {
|
315 |
+
global $wpdb;
|
316 |
+
|
317 |
+
$table = "{$wpdb->prefix}fs_logger";
|
318 |
+
|
319 |
+
if ( $is_on ) {
|
320 |
+
/**
|
321 |
+
* Create logging table.
|
322 |
+
*
|
323 |
+
* NOTE:
|
324 |
+
* dbDelta must use KEY and not INDEX for indexes.
|
325 |
+
*
|
326 |
+
* @link https://core.trac.wordpress.org/ticket/2695
|
327 |
+
*/
|
328 |
+
$result = $wpdb->query( "CREATE TABLE {$table} (
|
329 |
+
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
330 |
+
`process_id` INT UNSIGNED NOT NULL,
|
331 |
+
`user_name` VARCHAR(64) NOT NULL,
|
332 |
+
`logger` VARCHAR(128) NOT NULL,
|
333 |
+
`log_order` INT UNSIGNED NOT NULL,
|
334 |
+
`type` ENUM('log','info','warn','error') NOT NULL DEFAULT 'log',
|
335 |
+
`message` TEXT NOT NULL,
|
336 |
+
`file` VARCHAR(256) NOT NULL,
|
337 |
+
`line` INT UNSIGNED NOT NULL,
|
338 |
+
`function` VARCHAR(256) NOT NULL,
|
339 |
+
`request_type` ENUM('call','ajax','cron') NOT NULL DEFAULT 'call',
|
340 |
+
`request_url` VARCHAR(1024) NOT NULL,
|
341 |
+
`created` DECIMAL(16, 6) NOT NULL,
|
342 |
+
PRIMARY KEY (`id`),
|
343 |
+
KEY `process_id` (`process_id` ASC),
|
344 |
+
KEY `process_logger` (`process_id` ASC, `logger` ASC),
|
345 |
+
KEY `function` (`function` ASC),
|
346 |
+
KEY `type` (`type` ASC))" );
|
347 |
+
} else {
|
348 |
+
/**
|
349 |
+
* Drop logging table.
|
350 |
+
*/
|
351 |
+
$result = $wpdb->query( "DROP TABLE IF EXISTS $table;" );
|
352 |
+
}
|
353 |
+
|
354 |
+
if ( false !== $result ) {
|
355 |
+
update_option( 'fs_storage_logger', ( $is_on ? 1 : 0 ) );
|
356 |
+
}
|
357 |
+
|
358 |
+
return ( false !== $result );
|
359 |
+
}
|
360 |
+
|
361 |
+
/**
|
362 |
+
* @author Vova Feldman (@svovaf)
|
363 |
+
* @since 1.2.1.6
|
364 |
+
*
|
365 |
+
* @param string $type
|
366 |
+
* @param string $message
|
367 |
+
* @param int $log_order
|
368 |
+
* @param array $caller
|
369 |
+
*
|
370 |
+
* @return false|int
|
371 |
+
*/
|
372 |
+
private function db_log(
|
373 |
+
&$type,
|
374 |
+
&$message,
|
375 |
+
&$log_order,
|
376 |
+
&$caller
|
377 |
+
) {
|
378 |
+
global $wpdb;
|
379 |
+
|
380 |
+
$request_type = 'call';
|
381 |
+
if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
|
382 |
+
$request_type = 'cron';
|
383 |
+
} else if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
384 |
+
$request_type = 'ajax';
|
385 |
+
}
|
386 |
+
|
387 |
+
$request_url = WP_FS__IS_HTTP_REQUEST ?
|
388 |
+
$_SERVER['REQUEST_URI'] :
|
389 |
+
'';
|
390 |
+
|
391 |
+
return $wpdb->insert(
|
392 |
+
"{$wpdb->prefix}fs_logger",
|
393 |
+
array(
|
394 |
+
'process_id' => self::$_processID,
|
395 |
+
'user_name' => self::$_ownerName,
|
396 |
+
'logger' => $this->_id,
|
397 |
+
'log_order' => $log_order,
|
398 |
+
'type' => $type,
|
399 |
+
'request_type' => $request_type,
|
400 |
+
'request_url' => $request_url,
|
401 |
+
'message' => $message,
|
402 |
+
'file' => isset( $caller['file'] ) ?
|
403 |
+
substr( $caller['file'], self::$_abspathLength ) :
|
404 |
+
'',
|
405 |
+
'line' => $caller['line'],
|
406 |
+
'function' => ( ! empty( $caller['class'] ) ? $caller['class'] . $caller['type'] : '' ) . $caller['function'],
|
407 |
+
'created' => microtime( true ),
|
408 |
+
)
|
409 |
+
);
|
410 |
+
}
|
411 |
+
|
412 |
+
/**
|
413 |
+
* Persistent DB logger columns.
|
414 |
+
*
|
415 |
+
* @var array
|
416 |
+
*/
|
417 |
+
private static $_log_columns = array(
|
418 |
+
'id',
|
419 |
+
'process_id',
|
420 |
+
'user_name',
|
421 |
+
'logger',
|
422 |
+
'log_order',
|
423 |
+
'type',
|
424 |
+
'message',
|
425 |
+
'file',
|
426 |
+
'line',
|
427 |
+
'function',
|
428 |
+
'request_type',
|
429 |
+
'request_url',
|
430 |
+
'created',
|
431 |
+
);
|
432 |
+
|
433 |
+
/**
|
434 |
+
* Create DB logs query.
|
435 |
+
*
|
436 |
+
* @author Vova Feldman (@svovaf)
|
437 |
+
* @since 1.2.1.6
|
438 |
+
*
|
439 |
+
* @param bool $filters
|
440 |
+
* @param int $limit
|
441 |
+
* @param int $offset
|
442 |
+
* @param bool $order
|
443 |
+
* @param bool $escape_eol
|
444 |
+
*
|
445 |
+
* @return string
|
446 |
+
*/
|
447 |
+
private static function build_db_logs_query(
|
448 |
+
$filters = false,
|
449 |
+
$limit = 200,
|
450 |
+
$offset = 0,
|
451 |
+
$order = false,
|
452 |
+
$escape_eol = false
|
453 |
+
) {
|
454 |
+
global $wpdb;
|
455 |
+
|
456 |
+
$select = '*';
|
457 |
+
|
458 |
+
if ( $escape_eol ) {
|
459 |
+
$select = '';
|
460 |
+
for ( $i = 0, $len = count( self::$_log_columns ); $i < $len; $i ++ ) {
|
461 |
+
if ( $i > 0 ) {
|
462 |
+
$select .= ', ';
|
463 |
+
}
|
464 |
+
|
465 |
+
if ( 'message' !== self::$_log_columns[ $i ] ) {
|
466 |
+
$select .= self::$_log_columns[ $i ];
|
467 |
+
} else {
|
468 |
+
$select .= 'REPLACE(message , \'\n\', \' \') AS message';
|
469 |
+
}
|
470 |
+
}
|
471 |
+
}
|
472 |
+
|
473 |
+
$query = "SELECT {$select} FROM {$wpdb->prefix}fs_logger";
|
474 |
+
if ( is_array( $filters ) ) {
|
475 |
+
$criteria = array();
|
476 |
+
|
477 |
+
if ( ! empty( $filters['type'] ) && 'all' !== $filters['type'] ) {
|
478 |
+
$filters['type'] = strtolower( $filters['type'] );
|
479 |
+
|
480 |
+
switch ( $filters['type'] ) {
|
481 |
+
case 'warn_error':
|
482 |
+
$criteria[] = array( 'col' => 'type', 'val' => array( 'warn', 'error' ) );
|
483 |
+
break;
|
484 |
+
case 'error':
|
485 |
+
case 'warn':
|
486 |
+
$criteria[] = array( 'col' => 'type', 'val' => $filters['type'] );
|
487 |
+
break;
|
488 |
+
case 'info':
|
489 |
+
default:
|
490 |
+
$criteria[] = array( 'col' => 'type', 'val' => array( 'info', 'log' ) );
|
491 |
+
break;
|
492 |
+
}
|
493 |
+
}
|
494 |
+
|
495 |
+
if ( ! empty( $filters['request_type'] ) ) {
|
496 |
+
$filters['request_type'] = strtolower( $filters['request_type'] );
|
497 |
+
|
498 |
+
if ( in_array( $filters['request_type'], array( 'call', 'ajax', 'cron' ) ) ) {
|
499 |
+
$criteria[] = array( 'col' => 'request_type', 'val' => $filters['request_type'] );
|
500 |
+
}
|
501 |
+
}
|
502 |
+
|
503 |
+
if ( ! empty( $filters['file'] ) ) {
|
504 |
+
$criteria[] = array(
|
505 |
+
'col' => 'file',
|
506 |
+
'op' => 'LIKE',
|
507 |
+
'val' => '%' . esc_sql( $filters['file'] ),
|
508 |
+
);
|
509 |
+
}
|
510 |
+
|
511 |
+
if ( ! empty( $filters['function'] ) ) {
|
512 |
+
$criteria[] = array(
|
513 |
+
'col' => 'function',
|
514 |
+
'op' => 'LIKE',
|
515 |
+
'val' => '%' . esc_sql( $filters['function'] ),
|
516 |
+
);
|
517 |
+
}
|
518 |
+
|
519 |
+
if ( ! empty( $filters['process_id'] ) && is_numeric( $filters['process_id'] ) ) {
|
520 |
+
$criteria[] = array( 'col' => 'process_id', 'val' => $filters['process_id'] );
|
521 |
+
}
|
522 |
+
|
523 |
+
if ( ! empty( $filters['logger'] ) ) {
|
524 |
+
$criteria[] = array(
|
525 |
+
'col' => 'logger',
|
526 |
+
'op' => 'LIKE',
|
527 |
+
'val' => '%' . esc_sql( $filters['logger'] ) . '%',
|
528 |
+
);
|
529 |
+
}
|
530 |
+
|
531 |
+
if ( ! empty( $filters['message'] ) ) {
|
532 |
+
$criteria[] = array(
|
533 |
+
'col' => 'message',
|
534 |
+
'op' => 'LIKE',
|
535 |
+
'val' => '%' . esc_sql( $filters['message'] ) . '%',
|
536 |
+
);
|
537 |
+
}
|
538 |
+
|
539 |
+
if ( 0 < count( $criteria ) ) {
|
540 |
+
$query .= "\nWHERE\n";
|
541 |
+
|
542 |
+
$first = true;
|
543 |
+
foreach ( $criteria as $c ) {
|
544 |
+
if ( ! $first ) {
|
545 |
+
$query .= "AND\n";
|
546 |
+
}
|
547 |
+
|
548 |
+
if ( is_array( $c['val'] ) ) {
|
549 |
+
$operator = 'IN';
|
550 |
+
|
551 |
+
for ( $i = 0, $len = count( $c['val'] ); $i < $len; $i ++ ) {
|
552 |
+
$c['val'][ $i ] = "'" . esc_sql( $c['val'][ $i ] ) . "'";
|
553 |
+
}
|
554 |
+
|
555 |
+
$val = '(' . implode( ',', $c['val'] ) . ')';
|
556 |
+
} else {
|
557 |
+
$operator = ! empty( $c['op'] ) ? $c['op'] : '=';
|
558 |
+
$val = "'" . esc_sql( $c['val'] ) . "'";
|
559 |
+
}
|
560 |
+
|
561 |
+
$query .= "`{$c['col']}` {$operator} {$val}\n";
|
562 |
+
|
563 |
+
$first = false;
|
564 |
+
}
|
565 |
+
}
|
566 |
+
}
|
567 |
+
|
568 |
+
if ( ! is_array( $order ) ) {
|
569 |
+
$order = array(
|
570 |
+
'col' => 'id',
|
571 |
+
'order' => 'desc'
|
572 |
+
);
|
573 |
+
}
|
574 |
+
|
575 |
+
$query .= " ORDER BY {$order['col']} {$order['order']} LIMIT {$offset},{$limit}";
|
576 |
+
|
577 |
+
return $query;
|
578 |
+
}
|
579 |
+
|
580 |
+
/**
|
581 |
+
* Load logs from DB.
|
582 |
+
*
|
583 |
+
* @author Vova Feldman (@svovaf)
|
584 |
+
* @since 1.2.1.6
|
585 |
+
*
|
586 |
+
* @param bool $filters
|
587 |
+
* @param int $limit
|
588 |
+
* @param int $offset
|
589 |
+
* @param bool $order
|
590 |
+
*
|
591 |
+
* @return object[]|null
|
592 |
+
*/
|
593 |
+
public static function load_db_logs(
|
594 |
+
$filters = false,
|
595 |
+
$limit = 200,
|
596 |
+
$offset = 0,
|
597 |
+
$order = false
|
598 |
+
) {
|
599 |
+
global $wpdb;
|
600 |
+
|
601 |
+
$query = self::build_db_logs_query(
|
602 |
+
$filters,
|
603 |
+
$limit,
|
604 |
+
$offset,
|
605 |
+
$order
|
606 |
+
);
|
607 |
+
|
608 |
+
return $wpdb->get_results( $query );
|
609 |
+
}
|
610 |
+
|
611 |
+
/**
|
612 |
+
* Load logs from DB.
|
613 |
+
*
|
614 |
+
* @author Vova Feldman (@svovaf)
|
615 |
+
* @since 1.2.1.6
|
616 |
+
*
|
617 |
+
* @param bool $filters
|
618 |
+
* @param string $filename
|
619 |
+
* @param int $limit
|
620 |
+
* @param int $offset
|
621 |
+
* @param bool $order
|
622 |
+
*
|
623 |
+
* @return false|string File download URL or false on failure.
|
624 |
+
*/
|
625 |
+
public static function download_db_logs(
|
626 |
+
$filters = false,
|
627 |
+
$filename = '',
|
628 |
+
$limit = 10000,
|
629 |
+
$offset = 0,
|
630 |
+
$order = false
|
631 |
+
) {
|
632 |
+
global $wpdb;
|
633 |
+
|
634 |
+
$query = self::build_db_logs_query(
|
635 |
+
$filters,
|
636 |
+
$limit,
|
637 |
+
$offset,
|
638 |
+
$order,
|
639 |
+
true
|
640 |
+
);
|
641 |
+
|
642 |
+
$upload_dir = wp_upload_dir();
|
643 |
+
if ( empty( $filename ) ) {
|
644 |
+
$filename = 'fs-logs-' . date( 'Y-m-d_H-i-s', WP_FS__SCRIPT_START_TIME ) . '.csv';
|
645 |
+
}
|
646 |
+
$filepath = rtrim( $upload_dir['path'], '/' ) . "/{$filename}";
|
647 |
+
|
648 |
+
$query .= " INTO OUTFILE '{$filepath}' FIELDS TERMINATED BY '\t' ESCAPED BY '\\\\' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\\n'";
|
649 |
+
|
650 |
+
$columns = '';
|
651 |
+
for ( $i = 0, $len = count( self::$_log_columns ); $i < $len; $i ++ ) {
|
652 |
+
if ( $i > 0 ) {
|
653 |
+
$columns .= ', ';
|
654 |
+
}
|
655 |
+
|
656 |
+
$columns .= "'" . self::$_log_columns[ $i ] . "'";
|
657 |
+
}
|
658 |
+
|
659 |
+
$query = "SELECT {$columns} UNION ALL " . $query;
|
660 |
+
|
661 |
+
$result = $wpdb->query( $query );
|
662 |
+
|
663 |
+
if ( false === $result ) {
|
664 |
+
return false;
|
665 |
+
}
|
666 |
+
|
667 |
+
return rtrim( $upload_dir['url'], '/' ) . '/' . $filename;
|
668 |
+
}
|
669 |
+
|
670 |
+
/**
|
671 |
+
* @author Vova Feldman (@svovaf)
|
672 |
+
* @since 1.2.1.6
|
673 |
+
*
|
674 |
+
* @param string $filename
|
675 |
+
*
|
676 |
+
* @return string
|
677 |
+
*/
|
678 |
+
public static function get_logs_download_url( $filename = '' ) {
|
679 |
+
$upload_dir = wp_upload_dir();
|
680 |
+
if ( empty( $filename ) ) {
|
681 |
+
$filename = 'fs-logs-' . date( 'Y-m-d_H-i-s', WP_FS__SCRIPT_START_TIME ) . '.csv';
|
682 |
+
}
|
683 |
+
|
684 |
+
return rtrim( $upload_dir['url'], '/' ) . $filename;
|
685 |
+
}
|
686 |
+
|
687 |
+
#endregion
|
688 |
}
|
freemius/includes/customizer/class-fs-customizer-support-section.php
CHANGED
@@ -1,102 +1,102 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.2.2.7
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Class Zerif_Customizer_Theme_Info_Main
|
15 |
-
*
|
16 |
-
* @since 1.0.0
|
17 |
-
* @access public
|
18 |
-
*/
|
19 |
-
class FS_Customizer_Support_Section extends WP_Customize_Section {
|
20 |
-
|
21 |
-
function __construct( $manager, $id, $args = array() ) {
|
22 |
-
$manager->register_section_type( 'FS_Customizer_Support_Section' );
|
23 |
-
|
24 |
-
parent::__construct( $manager, $id, $args );
|
25 |
-
}
|
26 |
-
|
27 |
-
/**
|
28 |
-
* The type of customize section being rendered.
|
29 |
-
*
|
30 |
-
* @since 1.0.0
|
31 |
-
* @access public
|
32 |
-
* @var string
|
33 |
-
*/
|
34 |
-
public $type = 'freemius-support-section';
|
35 |
-
|
36 |
-
/**
|
37 |
-
* @var Freemius
|
38 |
-
*/
|
39 |
-
public $fs = null;
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Add custom parameters to pass to the JS via JSON.
|
43 |
-
*
|
44 |
-
* @since 1.0.0
|
45 |
-
*/
|
46 |
-
public function json() {
|
47 |
-
$json = parent::json();
|
48 |
-
|
49 |
-
$is_contact_visible = $this->fs->is_page_visible( 'contact' );
|
50 |
-
$is_support_visible = $this->fs->is_page_visible( 'support' );
|
51 |
-
|
52 |
-
$json['theme_title'] = $this->fs->get_plugin_name();
|
53 |
-
|
54 |
-
if ( $is_contact_visible && $is_support_visible ) {
|
55 |
-
$json['theme_title'] .= ' ' . $this->fs->get_text_inline( 'Support', 'support' );
|
56 |
-
}
|
57 |
-
|
58 |
-
if ( $is_contact_visible ) {
|
59 |
-
$json['contact'] = array(
|
60 |
-
'label' => $this->fs->get_text_inline( 'Contact Us', 'contact-us' ),
|
61 |
-
'url' => $this->fs->contact_url(),
|
62 |
-
);
|
63 |
-
}
|
64 |
-
|
65 |
-
if ( $is_support_visible ) {
|
66 |
-
$json['support'] = array(
|
67 |
-
'label' => $this->fs->get_text_inline( 'Support Forum', 'support-forum' ),
|
68 |
-
'url' => $this->fs->get_support_forum_url()
|
69 |
-
);
|
70 |
-
}
|
71 |
-
|
72 |
-
return $json;
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* Outputs the Underscore.js template.
|
77 |
-
*
|
78 |
-
* @since 1.0.0
|
79 |
-
*/
|
80 |
-
protected function render_template() {
|
81 |
-
?>
|
82 |
-
<li id="fs_customizer_support"
|
83 |
-
class="accordion-section control-section control-section-{{ data.type }} cannot-expand">
|
84 |
-
<h3 class="accordion-section-title">
|
85 |
-
<span>{{ data.theme_title }}</span>
|
86 |
-
<# if ( data.contact && data.support ) { #>
|
87 |
-
<div class="button-group">
|
88 |
-
<# } #>
|
89 |
-
<# if ( data.contact ) { #>
|
90 |
-
<a class="button" href="{{ data.contact.url }}" target="_blank">{{ data.contact.label }} </a>
|
91 |
-
<# } #>
|
92 |
-
<# if ( data.support ) { #>
|
93 |
-
<a class="button" href="{{ data.support.url }}" target="_blank">{{ data.support.label }} </a>
|
94 |
-
<# } #>
|
95 |
-
<# if ( data.contact && data.support ) { #>
|
96 |
-
</div>
|
97 |
-
<# } #>
|
98 |
-
</h3>
|
99 |
-
</li>
|
100 |
-
<?php
|
101 |
-
}
|
102 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.2.2.7
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class Zerif_Customizer_Theme_Info_Main
|
15 |
+
*
|
16 |
+
* @since 1.0.0
|
17 |
+
* @access public
|
18 |
+
*/
|
19 |
+
class FS_Customizer_Support_Section extends WP_Customize_Section {
|
20 |
+
|
21 |
+
function __construct( $manager, $id, $args = array() ) {
|
22 |
+
$manager->register_section_type( 'FS_Customizer_Support_Section' );
|
23 |
+
|
24 |
+
parent::__construct( $manager, $id, $args );
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* The type of customize section being rendered.
|
29 |
+
*
|
30 |
+
* @since 1.0.0
|
31 |
+
* @access public
|
32 |
+
* @var string
|
33 |
+
*/
|
34 |
+
public $type = 'freemius-support-section';
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var Freemius
|
38 |
+
*/
|
39 |
+
public $fs = null;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Add custom parameters to pass to the JS via JSON.
|
43 |
+
*
|
44 |
+
* @since 1.0.0
|
45 |
+
*/
|
46 |
+
public function json() {
|
47 |
+
$json = parent::json();
|
48 |
+
|
49 |
+
$is_contact_visible = $this->fs->is_page_visible( 'contact' );
|
50 |
+
$is_support_visible = $this->fs->is_page_visible( 'support' );
|
51 |
+
|
52 |
+
$json['theme_title'] = $this->fs->get_plugin_name();
|
53 |
+
|
54 |
+
if ( $is_contact_visible && $is_support_visible ) {
|
55 |
+
$json['theme_title'] .= ' ' . $this->fs->get_text_inline( 'Support', 'support' );
|
56 |
+
}
|
57 |
+
|
58 |
+
if ( $is_contact_visible ) {
|
59 |
+
$json['contact'] = array(
|
60 |
+
'label' => $this->fs->get_text_inline( 'Contact Us', 'contact-us' ),
|
61 |
+
'url' => $this->fs->contact_url(),
|
62 |
+
);
|
63 |
+
}
|
64 |
+
|
65 |
+
if ( $is_support_visible ) {
|
66 |
+
$json['support'] = array(
|
67 |
+
'label' => $this->fs->get_text_inline( 'Support Forum', 'support-forum' ),
|
68 |
+
'url' => $this->fs->get_support_forum_url()
|
69 |
+
);
|
70 |
+
}
|
71 |
+
|
72 |
+
return $json;
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Outputs the Underscore.js template.
|
77 |
+
*
|
78 |
+
* @since 1.0.0
|
79 |
+
*/
|
80 |
+
protected function render_template() {
|
81 |
+
?>
|
82 |
+
<li id="fs_customizer_support"
|
83 |
+
class="accordion-section control-section control-section-{{ data.type }} cannot-expand">
|
84 |
+
<h3 class="accordion-section-title">
|
85 |
+
<span>{{ data.theme_title }}</span>
|
86 |
+
<# if ( data.contact && data.support ) { #>
|
87 |
+
<div class="button-group">
|
88 |
+
<# } #>
|
89 |
+
<# if ( data.contact ) { #>
|
90 |
+
<a class="button" href="{{ data.contact.url }}" target="_blank">{{ data.contact.label }} </a>
|
91 |
+
<# } #>
|
92 |
+
<# if ( data.support ) { #>
|
93 |
+
<a class="button" href="{{ data.support.url }}" target="_blank">{{ data.support.label }} </a>
|
94 |
+
<# } #>
|
95 |
+
<# if ( data.contact && data.support ) { #>
|
96 |
+
</div>
|
97 |
+
<# } #>
|
98 |
+
</h3>
|
99 |
+
</li>
|
100 |
+
<?php
|
101 |
+
}
|
102 |
}
|
freemius/includes/customizer/class-fs-customizer-upsell-control.php
CHANGED
@@ -1,157 +1,157 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.2.2.7
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Class FS_Customizer_Upsell_Control
|
15 |
-
*/
|
16 |
-
class FS_Customizer_Upsell_Control extends WP_Customize_Control {
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Control type
|
20 |
-
*
|
21 |
-
* @var string control type
|
22 |
-
*/
|
23 |
-
public $type = 'freemius-upsell-control';
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @var Freemius
|
27 |
-
*/
|
28 |
-
public $fs = null;
|
29 |
-
|
30 |
-
/**
|
31 |
-
* @param WP_Customize_Manager $manager the customize manager class.
|
32 |
-
* @param string $id id.
|
33 |
-
* @param array $args customizer manager parameters.
|
34 |
-
*/
|
35 |
-
public function __construct( WP_Customize_Manager $manager, $id, array $args ) {
|
36 |
-
$manager->register_control_type( 'FS_Customizer_Upsell_Control' );
|
37 |
-
|
38 |
-
parent::__construct( $manager, $id, $args );
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Enqueue resources for the control.
|
43 |
-
*/
|
44 |
-
public function enqueue() {
|
45 |
-
fs_enqueue_local_style( 'fs_customizer', 'customizer.css' );
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Json conversion
|
50 |
-
*/
|
51 |
-
public function to_json() {
|
52 |
-
$pricing_cta = esc_html( $this->fs->get_pricing_cta_label() ) . ' ' . ( is_rtl() ? '←' : '➤' );
|
53 |
-
|
54 |
-
parent::to_json();
|
55 |
-
|
56 |
-
$this->json['button_text'] = $pricing_cta;
|
57 |
-
$this->json['button_url'] = $this->fs->is_in_trial_promotion() ?
|
58 |
-
$this->fs->get_trial_url() :
|
59 |
-
$this->fs->get_upgrade_url();
|
60 |
-
|
61 |
-
// Load features.
|
62 |
-
$pricing = $this->fs->get_api_plugin_scope()->get( 'pricing.json' );
|
63 |
-
|
64 |
-
if ( $this->fs->is_api_result_object( $pricing, 'plans' ) ) {
|
65 |
-
// Add support features.
|
66 |
-
if ( is_array( $pricing->plans ) && 0 < count( $pricing->plans ) ) {
|
67 |
-
$support_features = array(
|
68 |
-
'kb' => 'Help Center',
|
69 |
-
'forum' => 'Support Forum',
|
70 |
-
'email' => 'Priority Email Support',
|
71 |
-
'phone' => 'Phone Support',
|
72 |
-
'skype' => 'Skype Support',
|
73 |
-
'is_success_manager' => 'Personal Success Manager',
|
74 |
-
);
|
75 |
-
|
76 |
-
for ( $i = 0, $len = count( $pricing->plans ); $i < $len; $i ++ ) {
|
77 |
-
if ( 'free' == $pricing->plans[$i]->name ) {
|
78 |
-
continue;
|
79 |
-
}
|
80 |
-
|
81 |
-
if ( ! isset( $pricing->plans[ $i ]->features ) ||
|
82 |
-
! is_array( $pricing->plans[ $i ]->features ) ) {
|
83 |
-
$pricing->plans[$i]->features = array();
|
84 |
-
}
|
85 |
-
|
86 |
-
foreach ( $support_features as $key => $label ) {
|
87 |
-
$key = ( 'is_success_manager' !== $key ) ?
|
88 |
-
"support_{$key}" :
|
89 |
-
$key;
|
90 |
-
|
91 |
-
if ( ! empty( $pricing->plans[ $i ]->{$key} ) ) {
|
92 |
-
|
93 |
-
$support_feature = new stdClass();
|
94 |
-
$support_feature->title = $label;
|
95 |
-
|
96 |
-
$pricing->plans[ $i ]->features[] = $support_feature;
|
97 |
-
}
|
98 |
-
}
|
99 |
-
}
|
100 |
-
}
|
101 |
-
}
|
102 |
-
|
103 |
-
$this->json['plans'] = $pricing->plans;
|
104 |
-
|
105 |
-
$this->json['strings'] = array(
|
106 |
-
'plan' => $this->fs->get_text_x_inline( 'Plan', 'as product pricing plan', 'plan' ),
|
107 |
-
);
|
108 |
-
}
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Control content
|
112 |
-
*/
|
113 |
-
public function content_template() {
|
114 |
-
?>
|
115 |
-
<div id="fs_customizer_upsell">
|
116 |
-
<# if ( data.plans ) { #>
|
117 |
-
<ul class="fs-customizer-plans">
|
118 |
-
<# for (i in data.plans) { #>
|
119 |
-
<# if ( 'free' != data.plans[i].name && (null != data.plans[i].features && 0 < data.plans[i].features.length) ) { #>
|
120 |
-
<li class="fs-customizer-plan">
|
121 |
-
<div class="fs-accordion-section-open">
|
122 |
-
<h2 class="fs-accordion-section-title menu-item">
|
123 |
-
<span>{{ data.plans[i].title }}</span>
|
124 |
-
<button type="button" class="button-link item-edit" aria-expanded="true">
|
125 |
-
<span class="screen-reader-text">Toggle section: {{ data.plans[i].title }} {{ data.strings.plan }}</span>
|
126 |
-
<span class="toggle-indicator" aria-hidden="true"></span>
|
127 |
-
</button>
|
128 |
-
</h2>
|
129 |
-
<div class="fs-accordion-section-content">
|
130 |
-
<# if ( data.plans[i].description ) { #>
|
131 |
-
<h3>{{ data.plans[i].description }}</h3>
|
132 |
-
<# } #>
|
133 |
-
<# if ( data.plans[i].features ) { #>
|
134 |
-
<ul>
|
135 |
-
<# for ( j in data.plans[i].features ) { #>
|
136 |
-
<li><div class="fs-feature">
|
137 |
-
<span class="dashicons dashicons-yes"></span><span><# if ( data.plans[i].features[j].value ) { #>{{ data.plans[i].features[j].value }} <# } #>{{ data.plans[i].features[j].title }}</span>
|
138 |
-
<# if ( data.plans[i].features[j].description ) { #>
|
139 |
-
<span class="dashicons dashicons-editor-help"><span class="fs-feature-desc">{{ data.plans[i].features[j].description }}</span></span>
|
140 |
-
<# } #>
|
141 |
-
</div></li>
|
142 |
-
<# } #>
|
143 |
-
</ul>
|
144 |
-
<# } #>
|
145 |
-
<# if ( 'free' != data.plans[i].name ) { #>
|
146 |
-
<a href="{{ data.button_url }}" class="button button-primary" target="_blank">{{{ data.button_text }}}</a>
|
147 |
-
<# } #>
|
148 |
-
</div>
|
149 |
-
</div>
|
150 |
-
</li>
|
151 |
-
<# } #>
|
152 |
-
<# } #>
|
153 |
-
</ul>
|
154 |
-
<# } #>
|
155 |
-
</div>
|
156 |
-
<?php }
|
157 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.2.2.7
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class FS_Customizer_Upsell_Control
|
15 |
+
*/
|
16 |
+
class FS_Customizer_Upsell_Control extends WP_Customize_Control {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Control type
|
20 |
+
*
|
21 |
+
* @var string control type
|
22 |
+
*/
|
23 |
+
public $type = 'freemius-upsell-control';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var Freemius
|
27 |
+
*/
|
28 |
+
public $fs = null;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @param WP_Customize_Manager $manager the customize manager class.
|
32 |
+
* @param string $id id.
|
33 |
+
* @param array $args customizer manager parameters.
|
34 |
+
*/
|
35 |
+
public function __construct( WP_Customize_Manager $manager, $id, array $args ) {
|
36 |
+
$manager->register_control_type( 'FS_Customizer_Upsell_Control' );
|
37 |
+
|
38 |
+
parent::__construct( $manager, $id, $args );
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Enqueue resources for the control.
|
43 |
+
*/
|
44 |
+
public function enqueue() {
|
45 |
+
fs_enqueue_local_style( 'fs_customizer', 'customizer.css' );
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Json conversion
|
50 |
+
*/
|
51 |
+
public function to_json() {
|
52 |
+
$pricing_cta = esc_html( $this->fs->get_pricing_cta_label() ) . ' ' . ( is_rtl() ? '←' : '➤' );
|
53 |
+
|
54 |
+
parent::to_json();
|
55 |
+
|
56 |
+
$this->json['button_text'] = $pricing_cta;
|
57 |
+
$this->json['button_url'] = $this->fs->is_in_trial_promotion() ?
|
58 |
+
$this->fs->get_trial_url() :
|
59 |
+
$this->fs->get_upgrade_url();
|
60 |
+
|
61 |
+
// Load features.
|
62 |
+
$pricing = $this->fs->get_api_plugin_scope()->get( 'pricing.json' );
|
63 |
+
|
64 |
+
if ( $this->fs->is_api_result_object( $pricing, 'plans' ) ) {
|
65 |
+
// Add support features.
|
66 |
+
if ( is_array( $pricing->plans ) && 0 < count( $pricing->plans ) ) {
|
67 |
+
$support_features = array(
|
68 |
+
'kb' => 'Help Center',
|
69 |
+
'forum' => 'Support Forum',
|
70 |
+
'email' => 'Priority Email Support',
|
71 |
+
'phone' => 'Phone Support',
|
72 |
+
'skype' => 'Skype Support',
|
73 |
+
'is_success_manager' => 'Personal Success Manager',
|
74 |
+
);
|
75 |
+
|
76 |
+
for ( $i = 0, $len = count( $pricing->plans ); $i < $len; $i ++ ) {
|
77 |
+
if ( 'free' == $pricing->plans[$i]->name ) {
|
78 |
+
continue;
|
79 |
+
}
|
80 |
+
|
81 |
+
if ( ! isset( $pricing->plans[ $i ]->features ) ||
|
82 |
+
! is_array( $pricing->plans[ $i ]->features ) ) {
|
83 |
+
$pricing->plans[$i]->features = array();
|
84 |
+
}
|
85 |
+
|
86 |
+
foreach ( $support_features as $key => $label ) {
|
87 |
+
$key = ( 'is_success_manager' !== $key ) ?
|
88 |
+
"support_{$key}" :
|
89 |
+
$key;
|
90 |
+
|
91 |
+
if ( ! empty( $pricing->plans[ $i ]->{$key} ) ) {
|
92 |
+
|
93 |
+
$support_feature = new stdClass();
|
94 |
+
$support_feature->title = $label;
|
95 |
+
|
96 |
+
$pricing->plans[ $i ]->features[] = $support_feature;
|
97 |
+
}
|
98 |
+
}
|
99 |
+
}
|
100 |
+
}
|
101 |
+
}
|
102 |
+
|
103 |
+
$this->json['plans'] = $pricing->plans;
|
104 |
+
|
105 |
+
$this->json['strings'] = array(
|
106 |
+
'plan' => $this->fs->get_text_x_inline( 'Plan', 'as product pricing plan', 'plan' ),
|
107 |
+
);
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Control content
|
112 |
+
*/
|
113 |
+
public function content_template() {
|
114 |
+
?>
|
115 |
+
<div id="fs_customizer_upsell">
|
116 |
+
<# if ( data.plans ) { #>
|
117 |
+
<ul class="fs-customizer-plans">
|
118 |
+
<# for (i in data.plans) { #>
|
119 |
+
<# if ( 'free' != data.plans[i].name && (null != data.plans[i].features && 0 < data.plans[i].features.length) ) { #>
|
120 |
+
<li class="fs-customizer-plan">
|
121 |
+
<div class="fs-accordion-section-open">
|
122 |
+
<h2 class="fs-accordion-section-title menu-item">
|
123 |
+
<span>{{ data.plans[i].title }}</span>
|
124 |
+
<button type="button" class="button-link item-edit" aria-expanded="true">
|
125 |
+
<span class="screen-reader-text">Toggle section: {{ data.plans[i].title }} {{ data.strings.plan }}</span>
|
126 |
+
<span class="toggle-indicator" aria-hidden="true"></span>
|
127 |
+
</button>
|
128 |
+
</h2>
|
129 |
+
<div class="fs-accordion-section-content">
|
130 |
+
<# if ( data.plans[i].description ) { #>
|
131 |
+
<h3>{{ data.plans[i].description }}</h3>
|
132 |
+
<# } #>
|
133 |
+
<# if ( data.plans[i].features ) { #>
|
134 |
+
<ul>
|
135 |
+
<# for ( j in data.plans[i].features ) { #>
|
136 |
+
<li><div class="fs-feature">
|
137 |
+
<span class="dashicons dashicons-yes"></span><span><# if ( data.plans[i].features[j].value ) { #>{{ data.plans[i].features[j].value }} <# } #>{{ data.plans[i].features[j].title }}</span>
|
138 |
+
<# if ( data.plans[i].features[j].description ) { #>
|
139 |
+
<span class="dashicons dashicons-editor-help"><span class="fs-feature-desc">{{ data.plans[i].features[j].description }}</span></span>
|
140 |
+
<# } #>
|
141 |
+
</div></li>
|
142 |
+
<# } #>
|
143 |
+
</ul>
|
144 |
+
<# } #>
|
145 |
+
<# if ( 'free' != data.plans[i].name ) { #>
|
146 |
+
<a href="{{ data.button_url }}" class="button button-primary" target="_blank">{{{ data.button_text }}}</a>
|
147 |
+
<# } #>
|
148 |
+
</div>
|
149 |
+
</div>
|
150 |
+
</li>
|
151 |
+
<# } #>
|
152 |
+
<# } #>
|
153 |
+
</ul>
|
154 |
+
<# } #>
|
155 |
+
</div>
|
156 |
+
<?php }
|
157 |
}
|
freemius/includes/customizer/index.php
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<?php
|
2 |
-
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
3 |
// Hide file structure from users on unprotected servers.
|
freemius/includes/debug/class-fs-debug-bar-panel.php
CHANGED
@@ -1,64 +1,64 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.1.7.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Extends Debug Bar plugin by adding a panel to show all Freemius API requests.
|
15 |
-
*
|
16 |
-
* @author Vova Feldman (@svovaf)
|
17 |
-
* @since 1.1.7.3
|
18 |
-
*
|
19 |
-
* Class Freemius_Debug_Bar_Panel
|
20 |
-
*/
|
21 |
-
class Freemius_Debug_Bar_Panel extends Debug_Bar_Panel {
|
22 |
-
function init() {
|
23 |
-
$this->title( 'Freemius' );
|
24 |
-
}
|
25 |
-
|
26 |
-
static function requests_count() {
|
27 |
-
if ( class_exists( 'Freemius_Api_WordPress' ) ) {
|
28 |
-
$logger = Freemius_Api_WordPress::GetLogger();
|
29 |
-
} else {
|
30 |
-
$logger = array();
|
31 |
-
}
|
32 |
-
|
33 |
-
return number_format( count( $logger ) );
|
34 |
-
}
|
35 |
-
|
36 |
-
static function total_time() {
|
37 |
-
if ( class_exists( 'Freemius_Api_WordPress' ) ) {
|
38 |
-
$logger = Freemius_Api_WordPress::GetLogger();
|
39 |
-
} else {
|
40 |
-
$logger = array();
|
41 |
-
}
|
42 |
-
|
43 |
-
$total_time = .0;
|
44 |
-
foreach ( $logger as $l ) {
|
45 |
-
$total_time += $l['total'];
|
46 |
-
}
|
47 |
-
|
48 |
-
return number_format( 100 * $total_time, 2 ) . ' ' . fs_text_x_inline( 'ms', 'milliseconds' );
|
49 |
-
}
|
50 |
-
|
51 |
-
function render() {
|
52 |
-
?>
|
53 |
-
<div id='debug-bar-php'>
|
54 |
-
<?php fs_require_template( '/debug/api-calls.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
|
63 |
-
}
|
64 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.1.7.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Extends Debug Bar plugin by adding a panel to show all Freemius API requests.
|
15 |
+
*
|
16 |
+
* @author Vova Feldman (@svovaf)
|
17 |
+
* @since 1.1.7.3
|
18 |
+
*
|
19 |
+
* Class Freemius_Debug_Bar_Panel
|
20 |
+
*/
|
21 |
+
class Freemius_Debug_Bar_Panel extends Debug_Bar_Panel {
|
22 |
+
function init() {
|
23 |
+
$this->title( 'Freemius' );
|
24 |
+
}
|
25 |
+
|
26 |
+
static function requests_count() {
|
27 |
+
if ( class_exists( 'Freemius_Api_WordPress' ) ) {
|
28 |
+
$logger = Freemius_Api_WordPress::GetLogger();
|
29 |
+
} else {
|
30 |
+
$logger = array();
|
31 |
+
}
|
32 |
+
|
33 |
+
return number_format( count( $logger ) );
|
34 |
+
}
|
35 |
+
|
36 |
+
static function total_time() {
|
37 |
+
if ( class_exists( 'Freemius_Api_WordPress' ) ) {
|
38 |
+
$logger = Freemius_Api_WordPress::GetLogger();
|
39 |
+
} else {
|
40 |
+
$logger = array();
|
41 |
+
}
|
42 |
+
|
43 |
+
$total_time = .0;
|
44 |
+
foreach ( $logger as $l ) {
|
45 |
+
$total_time += $l['total'];
|
46 |
+
}
|
47 |
+
|
48 |
+
return number_format( 100 * $total_time, 2 ) . ' ' . fs_text_x_inline( 'ms', 'milliseconds' );
|
49 |
+
}
|
50 |
+
|
51 |
+
function render() {
|
52 |
+
?>
|
53 |
+
<div id='debug-bar-php'>
|
54 |
+
<?php fs_require_template( '/debug/api-calls.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
|
63 |
+
}
|
64 |
+
}
|
freemius/includes/debug/debug-bar-start.php
CHANGED
@@ -1,52 +1,52 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.1.7.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
if ( ! WP_FS__DEBUG_SDK ) {
|
14 |
-
return;
|
15 |
-
}
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Initialize Freemius custom debug panels.
|
19 |
-
*
|
20 |
-
* @param array $panels Debug bar panels objects
|
21 |
-
*
|
22 |
-
* @return array Debug bar panels with your custom panels
|
23 |
-
*/
|
24 |
-
function fs_custom_panels_init( $panels ) {
|
25 |
-
if ( class_exists( 'Debug_Bar_Panel' ) ) {
|
26 |
-
if ( FS_API__LOGGER_ON ) {
|
27 |
-
require_once dirname( __FILE__ ) . '/class-fs-debug-bar-panel.php';
|
28 |
-
$panels[] = new Freemius_Debug_Bar_Panel();
|
29 |
-
}
|
30 |
-
}
|
31 |
-
|
32 |
-
return $panels;
|
33 |
-
}
|
34 |
-
|
35 |
-
function fs_custom_status_init( $statuses ) {
|
36 |
-
if ( class_exists( 'Debug_Bar_Panel' ) ) {
|
37 |
-
if ( FS_API__LOGGER_ON ) {
|
38 |
-
require_once dirname( __FILE__ ) . '/class-fs-debug-bar-panel.php';
|
39 |
-
$statuses[] = array(
|
40 |
-
'fs_api_requests',
|
41 |
-
fs_text_inline( 'Freemius API' ),
|
42 |
-
Freemius_Debug_Bar_Panel::requests_count() . ' ' . fs_text_inline( 'Requests' ) .
|
43 |
-
' (' . Freemius_Debug_Bar_Panel::total_time() . ')'
|
44 |
-
);
|
45 |
-
}
|
46 |
-
}
|
47 |
-
|
48 |
-
return $statuses;
|
49 |
-
}
|
50 |
-
|
51 |
-
add_filter( 'debug_bar_panels', 'fs_custom_panels_init' );
|
52 |
add_filter( 'debug_bar_statuses', 'fs_custom_status_init' );
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.1.7.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
if ( ! WP_FS__DEBUG_SDK ) {
|
14 |
+
return;
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Initialize Freemius custom debug panels.
|
19 |
+
*
|
20 |
+
* @param array $panels Debug bar panels objects
|
21 |
+
*
|
22 |
+
* @return array Debug bar panels with your custom panels
|
23 |
+
*/
|
24 |
+
function fs_custom_panels_init( $panels ) {
|
25 |
+
if ( class_exists( 'Debug_Bar_Panel' ) ) {
|
26 |
+
if ( FS_API__LOGGER_ON ) {
|
27 |
+
require_once dirname( __FILE__ ) . '/class-fs-debug-bar-panel.php';
|
28 |
+
$panels[] = new Freemius_Debug_Bar_Panel();
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
return $panels;
|
33 |
+
}
|
34 |
+
|
35 |
+
function fs_custom_status_init( $statuses ) {
|
36 |
+
if ( class_exists( 'Debug_Bar_Panel' ) ) {
|
37 |
+
if ( FS_API__LOGGER_ON ) {
|
38 |
+
require_once dirname( __FILE__ ) . '/class-fs-debug-bar-panel.php';
|
39 |
+
$statuses[] = array(
|
40 |
+
'fs_api_requests',
|
41 |
+
fs_text_inline( 'Freemius API' ),
|
42 |
+
Freemius_Debug_Bar_Panel::requests_count() . ' ' . fs_text_inline( 'Requests' ) .
|
43 |
+
' (' . Freemius_Debug_Bar_Panel::total_time() . ')'
|
44 |
+
);
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
return $statuses;
|
49 |
+
}
|
50 |
+
|
51 |
+
add_filter( 'debug_bar_panels', 'fs_custom_panels_init' );
|
52 |
add_filter( 'debug_bar_statuses', 'fs_custom_status_init' );
|
freemius/includes/entities/class-fs-plugin-license.php
CHANGED
@@ -1,224 +1,224 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.5
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Class FS_Plugin_License
|
15 |
-
*/
|
16 |
-
class FS_Plugin_License extends FS_Entity {
|
17 |
-
|
18 |
-
#region Properties
|
19 |
-
|
20 |
-
/**
|
21 |
-
* @var number
|
22 |
-
*/
|
23 |
-
public $plugin_id;
|
24 |
-
/**
|
25 |
-
* @var number
|
26 |
-
*/
|
27 |
-
public $user_id;
|
28 |
-
/**
|
29 |
-
* @var number
|
30 |
-
*/
|
31 |
-
public $plan_id;
|
32 |
-
/**
|
33 |
-
* @var number
|
34 |
-
*/
|
35 |
-
public $pricing_id;
|
36 |
-
/**
|
37 |
-
* @var int|null
|
38 |
-
*/
|
39 |
-
public $quota;
|
40 |
-
/**
|
41 |
-
* @var int
|
42 |
-
*/
|
43 |
-
public $activated;
|
44 |
-
/**
|
45 |
-
* @var int
|
46 |
-
*/
|
47 |
-
public $activated_local;
|
48 |
-
/**
|
49 |
-
* @var string
|
50 |
-
*/
|
51 |
-
public $expiration;
|
52 |
-
/**
|
53 |
-
* @var string
|
54 |
-
*/
|
55 |
-
public $secret_key;
|
56 |
-
/**
|
57 |
-
* @var bool $is_free_localhost Defaults to true. If true, allow unlimited localhost installs with the same
|
58 |
-
* license.
|
59 |
-
*/
|
60 |
-
public $is_free_localhost;
|
61 |
-
/**
|
62 |
-
* @var bool $is_block_features Defaults to true. If false, don't block features after license expiry - only
|
63 |
-
* block updates and support.
|
64 |
-
*/
|
65 |
-
public $is_block_features;
|
66 |
-
/**
|
67 |
-
* @var bool
|
68 |
-
*/
|
69 |
-
public $is_cancelled;
|
70 |
-
|
71 |
-
#endregion Properties
|
72 |
-
|
73 |
-
/**
|
74 |
-
* @param stdClass|bool $license
|
75 |
-
*/
|
76 |
-
function __construct( $license = false ) {
|
77 |
-
parent::__construct( $license );
|
78 |
-
}
|
79 |
-
|
80 |
-
/**
|
81 |
-
* Get entity type.
|
82 |
-
*
|
83 |
-
* @return string
|
84 |
-
*/
|
85 |
-
static function get_type() {
|
86 |
-
return 'license';
|
87 |
-
}
|
88 |
-
|
89 |
-
/**
|
90 |
-
* Check how many site activations left.
|
91 |
-
*
|
92 |
-
* @author Vova Feldman (@svovaf)
|
93 |
-
* @since 1.0.5
|
94 |
-
*
|
95 |
-
* @return int
|
96 |
-
*/
|
97 |
-
function left() {
|
98 |
-
if ( ! $this->is_active() || $this->is_expired() ) {
|
99 |
-
return 0;
|
100 |
-
}
|
101 |
-
|
102 |
-
if ( $this->is_unlimited() ) {
|
103 |
-
return 999;
|
104 |
-
}
|
105 |
-
|
106 |
-
return ( $this->quota - $this->activated - ( $this->is_free_localhost ? 0 : $this->activated_local ) );
|
107 |
-
}
|
108 |
-
|
109 |
-
/**
|
110 |
-
* Check if single site license.
|
111 |
-
*
|
112 |
-
* @author Vova Feldman (@svovaf)
|
113 |
-
* @since 1.1.8.1
|
114 |
-
*
|
115 |
-
* @return bool
|
116 |
-
*/
|
117 |
-
function is_single_site() {
|
118 |
-
return ( is_numeric( $this->quota ) && 1 == $this->quota );
|
119 |
-
}
|
120 |
-
|
121 |
-
/**
|
122 |
-
* @author Vova Feldman (@svovaf)
|
123 |
-
* @since 1.0.5
|
124 |
-
*
|
125 |
-
* @return bool
|
126 |
-
*/
|
127 |
-
function is_expired() {
|
128 |
-
return ! $this->is_lifetime() && ( strtotime( $this->expiration ) < WP_FS__SCRIPT_START_TIME );
|
129 |
-
}
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Check if license is not expired.
|
133 |
-
*
|
134 |
-
* @author Vova Feldman (@svovaf)
|
135 |
-
* @since 1.2.1
|
136 |
-
*
|
137 |
-
* @return bool
|
138 |
-
*/
|
139 |
-
function is_valid() {
|
140 |
-
return ! $this->is_expired();
|
141 |
-
}
|
142 |
-
|
143 |
-
/**
|
144 |
-
* @author Vova Feldman (@svovaf)
|
145 |
-
* @since 1.0.6
|
146 |
-
*
|
147 |
-
* @return bool
|
148 |
-
*/
|
149 |
-
function is_lifetime() {
|
150 |
-
return is_null( $this->expiration );
|
151 |
-
}
|
152 |
-
|
153 |
-
/**
|
154 |
-
* @author Vova Feldman (@svovaf)
|
155 |
-
* @since 1.2.0
|
156 |
-
*
|
157 |
-
* @return bool
|
158 |
-
*/
|
159 |
-
function is_unlimited() {
|
160 |
-
return is_null( $this->quota );
|
161 |
-
}
|
162 |
-
|
163 |
-
/**
|
164 |
-
* Check if license is fully utilized.
|
165 |
-
*
|
166 |
-
* @author Vova Feldman (@svovaf)
|
167 |
-
* @since 1.0.6
|
168 |
-
*
|
169 |
-
* @param bool $is_localhost
|
170 |
-
*
|
171 |
-
* @return bool
|
172 |
-
*/
|
173 |
-
function is_utilized( $is_localhost = null ) {
|
174 |
-
if ( is_null( $is_localhost ) ) {
|
175 |
-
$is_localhost = WP_FS__IS_LOCALHOST_FOR_SERVER;
|
176 |
-
}
|
177 |
-
|
178 |
-
if ( $this->is_unlimited() ) {
|
179 |
-
return false;
|
180 |
-
}
|
181 |
-
|
182 |
-
return ! ( $this->is_free_localhost && $is_localhost ) &&
|
183 |
-
( $this->quota <= $this->activated + ( $this->is_free_localhost ? 0 : $this->activated_local ) );
|
184 |
-
}
|
185 |
-
|
186 |
-
/**
|
187 |
-
* @author Vova Feldman (@svovaf)
|
188 |
-
* @since 1.2.1
|
189 |
-
*
|
190 |
-
* @return bool
|
191 |
-
*/
|
192 |
-
function is_active() {
|
193 |
-
return ( ! $this->is_cancelled );
|
194 |
-
}
|
195 |
-
|
196 |
-
/**
|
197 |
-
* Check if license's plan features are enabled.
|
198 |
-
*
|
199 |
-
* - Either if plan not expired
|
200 |
-
* - If expired, based on the configuration to block features or not.
|
201 |
-
*
|
202 |
-
* @author Vova Feldman (@svovaf)
|
203 |
-
* @since 1.0.6
|
204 |
-
*
|
205 |
-
* @return bool
|
206 |
-
*/
|
207 |
-
function is_features_enabled() {
|
208 |
-
return $this->is_active() && ( ! $this->is_block_features || ! $this->is_expired() );
|
209 |
-
}
|
210 |
-
|
211 |
-
/**
|
212 |
-
* Subscription considered to be new without any payments
|
213 |
-
* if the license expires in less than 24 hours
|
214 |
-
* from the license creation.
|
215 |
-
*
|
216 |
-
* @author Vova Feldman (@svovaf)
|
217 |
-
* @since 1.0.9
|
218 |
-
*
|
219 |
-
* @return bool
|
220 |
-
*/
|
221 |
-
function is_first_payment_pending() {
|
222 |
-
return ( WP_FS__TIME_24_HOURS_IN_SEC >= strtotime( $this->expiration ) - strtotime( $this->created ) );
|
223 |
-
}
|
224 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.5
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class FS_Plugin_License
|
15 |
+
*/
|
16 |
+
class FS_Plugin_License extends FS_Entity {
|
17 |
+
|
18 |
+
#region Properties
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var number
|
22 |
+
*/
|
23 |
+
public $plugin_id;
|
24 |
+
/**
|
25 |
+
* @var number
|
26 |
+
*/
|
27 |
+
public $user_id;
|
28 |
+
/**
|
29 |
+
* @var number
|
30 |
+
*/
|
31 |
+
public $plan_id;
|
32 |
+
/**
|
33 |
+
* @var number
|
34 |
+
*/
|
35 |
+
public $pricing_id;
|
36 |
+
/**
|
37 |
+
* @var int|null
|
38 |
+
*/
|
39 |
+
public $quota;
|
40 |
+
/**
|
41 |
+
* @var int
|
42 |
+
*/
|
43 |
+
public $activated;
|
44 |
+
/**
|
45 |
+
* @var int
|
46 |
+
*/
|
47 |
+
public $activated_local;
|
48 |
+
/**
|
49 |
+
* @var string
|
50 |
+
*/
|
51 |
+
public $expiration;
|
52 |
+
/**
|
53 |
+
* @var string
|
54 |
+
*/
|
55 |
+
public $secret_key;
|
56 |
+
/**
|
57 |
+
* @var bool $is_free_localhost Defaults to true. If true, allow unlimited localhost installs with the same
|
58 |
+
* license.
|
59 |
+
*/
|
60 |
+
public $is_free_localhost;
|
61 |
+
/**
|
62 |
+
* @var bool $is_block_features Defaults to true. If false, don't block features after license expiry - only
|
63 |
+
* block updates and support.
|
64 |
+
*/
|
65 |
+
public $is_block_features;
|
66 |
+
/**
|
67 |
+
* @var bool
|
68 |
+
*/
|
69 |
+
public $is_cancelled;
|
70 |
+
|
71 |
+
#endregion Properties
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @param stdClass|bool $license
|
75 |
+
*/
|
76 |
+
function __construct( $license = false ) {
|
77 |
+
parent::__construct( $license );
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Get entity type.
|
82 |
+
*
|
83 |
+
* @return string
|
84 |
+
*/
|
85 |
+
static function get_type() {
|
86 |
+
return 'license';
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Check how many site activations left.
|
91 |
+
*
|
92 |
+
* @author Vova Feldman (@svovaf)
|
93 |
+
* @since 1.0.5
|
94 |
+
*
|
95 |
+
* @return int
|
96 |
+
*/
|
97 |
+
function left() {
|
98 |
+
if ( ! $this->is_active() || $this->is_expired() ) {
|
99 |
+
return 0;
|
100 |
+
}
|
101 |
+
|
102 |
+
if ( $this->is_unlimited() ) {
|
103 |
+
return 999;
|
104 |
+
}
|
105 |
+
|
106 |
+
return ( $this->quota - $this->activated - ( $this->is_free_localhost ? 0 : $this->activated_local ) );
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Check if single site license.
|
111 |
+
*
|
112 |
+
* @author Vova Feldman (@svovaf)
|
113 |
+
* @since 1.1.8.1
|
114 |
+
*
|
115 |
+
* @return bool
|
116 |
+
*/
|
117 |
+
function is_single_site() {
|
118 |
+
return ( is_numeric( $this->quota ) && 1 == $this->quota );
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* @author Vova Feldman (@svovaf)
|
123 |
+
* @since 1.0.5
|
124 |
+
*
|
125 |
+
* @return bool
|
126 |
+
*/
|
127 |
+
function is_expired() {
|
128 |
+
return ! $this->is_lifetime() && ( strtotime( $this->expiration ) < WP_FS__SCRIPT_START_TIME );
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Check if license is not expired.
|
133 |
+
*
|
134 |
+
* @author Vova Feldman (@svovaf)
|
135 |
+
* @since 1.2.1
|
136 |
+
*
|
137 |
+
* @return bool
|
138 |
+
*/
|
139 |
+
function is_valid() {
|
140 |
+
return ! $this->is_expired();
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* @author Vova Feldman (@svovaf)
|
145 |
+
* @since 1.0.6
|
146 |
+
*
|
147 |
+
* @return bool
|
148 |
+
*/
|
149 |
+
function is_lifetime() {
|
150 |
+
return is_null( $this->expiration );
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* @author Vova Feldman (@svovaf)
|
155 |
+
* @since 1.2.0
|
156 |
+
*
|
157 |
+
* @return bool
|
158 |
+
*/
|
159 |
+
function is_unlimited() {
|
160 |
+
return is_null( $this->quota );
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Check if license is fully utilized.
|
165 |
+
*
|
166 |
+
* @author Vova Feldman (@svovaf)
|
167 |
+
* @since 1.0.6
|
168 |
+
*
|
169 |
+
* @param bool $is_localhost
|
170 |
+
*
|
171 |
+
* @return bool
|
172 |
+
*/
|
173 |
+
function is_utilized( $is_localhost = null ) {
|
174 |
+
if ( is_null( $is_localhost ) ) {
|
175 |
+
$is_localhost = WP_FS__IS_LOCALHOST_FOR_SERVER;
|
176 |
+
}
|
177 |
+
|
178 |
+
if ( $this->is_unlimited() ) {
|
179 |
+
return false;
|
180 |
+
}
|
181 |
+
|
182 |
+
return ! ( $this->is_free_localhost && $is_localhost ) &&
|
183 |
+
( $this->quota <= $this->activated + ( $this->is_free_localhost ? 0 : $this->activated_local ) );
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* @author Vova Feldman (@svovaf)
|
188 |
+
* @since 1.2.1
|
189 |
+
*
|
190 |
+
* @return bool
|
191 |
+
*/
|
192 |
+
function is_active() {
|
193 |
+
return ( ! $this->is_cancelled );
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Check if license's plan features are enabled.
|
198 |
+
*
|
199 |
+
* - Either if plan not expired
|
200 |
+
* - If expired, based on the configuration to block features or not.
|
201 |
+
*
|
202 |
+
* @author Vova Feldman (@svovaf)
|
203 |
+
* @since 1.0.6
|
204 |
+
*
|
205 |
+
* @return bool
|
206 |
+
*/
|
207 |
+
function is_features_enabled() {
|
208 |
+
return $this->is_active() && ( ! $this->is_block_features || ! $this->is_expired() );
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Subscription considered to be new without any payments
|
213 |
+
* if the license expires in less than 24 hours
|
214 |
+
* from the license creation.
|
215 |
+
*
|
216 |
+
* @author Vova Feldman (@svovaf)
|
217 |
+
* @since 1.0.9
|
218 |
+
*
|
219 |
+
* @return bool
|
220 |
+
*/
|
221 |
+
function is_first_payment_pending() {
|
222 |
+
return ( WP_FS__TIME_24_HOURS_IN_SEC >= strtotime( $this->expiration ) - strtotime( $this->created ) );
|
223 |
+
}
|
224 |
+
}
|
freemius/includes/entities/class-fs-plugin-tag.php
CHANGED
@@ -1,24 +1,24 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.4
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
class FS_Plugin_Tag extends FS_Entity {
|
14 |
-
public $version;
|
15 |
-
public $url;
|
16 |
-
|
17 |
-
function __construct( $tag = false ) {
|
18 |
-
parent::__construct( $tag );
|
19 |
-
}
|
20 |
-
|
21 |
-
static function get_type() {
|
22 |
-
return 'tag';
|
23 |
-
}
|
24 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.4
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
class FS_Plugin_Tag extends FS_Entity {
|
14 |
+
public $version;
|
15 |
+
public $url;
|
16 |
+
|
17 |
+
function __construct( $tag = false ) {
|
18 |
+
parent::__construct( $tag );
|
19 |
+
}
|
20 |
+
|
21 |
+
static function get_type() {
|
22 |
+
return 'tag';
|
23 |
+
}
|
24 |
}
|
freemius/includes/entities/class-fs-plugin.php
CHANGED
@@ -1,117 +1,117 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
class FS_Plugin extends FS_Scope_Entity {
|
14 |
-
/**
|
15 |
-
* @since 1.0.6
|
16 |
-
* @var null|number
|
17 |
-
*/
|
18 |
-
public $parent_plugin_id;
|
19 |
-
/**
|
20 |
-
* @var string
|
21 |
-
*/
|
22 |
-
public $title;
|
23 |
-
/**
|
24 |
-
* @var string
|
25 |
-
*/
|
26 |
-
public $slug;
|
27 |
-
/**
|
28 |
-
* @since 1.2.2
|
29 |
-
*
|
30 |
-
* @var string 'plugin' or 'theme'
|
31 |
-
*/
|
32 |
-
public $type;
|
33 |
-
|
34 |
-
#region Install Specific Properties
|
35 |
-
|
36 |
-
/**
|
37 |
-
* @var string
|
38 |
-
*/
|
39 |
-
public $file;
|
40 |
-
/**
|
41 |
-
* @var string
|
42 |
-
*/
|
43 |
-
public $version;
|
44 |
-
/**
|
45 |
-
* @var bool
|
46 |
-
*/
|
47 |
-
public $auto_update;
|
48 |
-
/**
|
49 |
-
* @var FS_Plugin_Info
|
50 |
-
*/
|
51 |
-
public $info;
|
52 |
-
/**
|
53 |
-
* @since 1.0.9
|
54 |
-
*
|
55 |
-
* @var bool
|
56 |
-
*/
|
57 |
-
public $is_premium;
|
58 |
-
/**
|
59 |
-
* @since 1.0.9
|
60 |
-
*
|
61 |
-
* @var bool
|
62 |
-
*/
|
63 |
-
public $is_live;
|
64 |
-
/**
|
65 |
-
* @author Leo Fajardo (@leorw)
|
66 |
-
*
|
67 |
-
* @since 1.2.3
|
68 |
-
*
|
69 |
-
* @var string|false false if the module doesn't have an affiliate program or one of the following:
|
70 |
-
* 'selected', 'customers', or 'all'.
|
71 |
-
*/
|
72 |
-
public $affiliate_moderation;
|
73 |
-
|
74 |
-
const AFFILIATE_MODERATION_CUSTOMERS = 'customers';
|
75 |
-
|
76 |
-
#endregion Install Specific Properties
|
77 |
-
|
78 |
-
/**
|
79 |
-
* @param stdClass|bool $plugin
|
80 |
-
*/
|
81 |
-
function __construct( $plugin = false ) {
|
82 |
-
parent::__construct( $plugin );
|
83 |
-
|
84 |
-
$this->is_premium = false;
|
85 |
-
$this->is_live = true;
|
86 |
-
|
87 |
-
if ( isset( $plugin->info ) && is_object( $plugin->info ) ) {
|
88 |
-
$this->info = new FS_Plugin_Info( $plugin->info );
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
/**
|
93 |
-
* Check if plugin is an add-on (has parent).
|
94 |
-
*
|
95 |
-
* @author Vova Feldman (@svovaf)
|
96 |
-
* @since 1.0.6
|
97 |
-
*
|
98 |
-
* @return bool
|
99 |
-
*/
|
100 |
-
function is_addon() {
|
101 |
-
return isset( $this->parent_plugin_id ) && is_numeric( $this->parent_plugin_id );
|
102 |
-
}
|
103 |
-
|
104 |
-
/**
|
105 |
-
* @author Leo Fajardo (@leorw)
|
106 |
-
* @since 1.2.3
|
107 |
-
*
|
108 |
-
* @return bool
|
109 |
-
*/
|
110 |
-
function has_affiliate_program() {
|
111 |
-
return ( ! empty( $this->affiliate_moderation ) );
|
112 |
-
}
|
113 |
-
|
114 |
-
static function get_type() {
|
115 |
-
return 'plugin';
|
116 |
-
}
|
117 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
class FS_Plugin extends FS_Scope_Entity {
|
14 |
+
/**
|
15 |
+
* @since 1.0.6
|
16 |
+
* @var null|number
|
17 |
+
*/
|
18 |
+
public $parent_plugin_id;
|
19 |
+
/**
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
public $title;
|
23 |
+
/**
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
public $slug;
|
27 |
+
/**
|
28 |
+
* @since 1.2.2
|
29 |
+
*
|
30 |
+
* @var string 'plugin' or 'theme'
|
31 |
+
*/
|
32 |
+
public $type;
|
33 |
+
|
34 |
+
#region Install Specific Properties
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var string
|
38 |
+
*/
|
39 |
+
public $file;
|
40 |
+
/**
|
41 |
+
* @var string
|
42 |
+
*/
|
43 |
+
public $version;
|
44 |
+
/**
|
45 |
+
* @var bool
|
46 |
+
*/
|
47 |
+
public $auto_update;
|
48 |
+
/**
|
49 |
+
* @var FS_Plugin_Info
|
50 |
+
*/
|
51 |
+
public $info;
|
52 |
+
/**
|
53 |
+
* @since 1.0.9
|
54 |
+
*
|
55 |
+
* @var bool
|
56 |
+
*/
|
57 |
+
public $is_premium;
|
58 |
+
/**
|
59 |
+
* @since 1.0.9
|
60 |
+
*
|
61 |
+
* @var bool
|
62 |
+
*/
|
63 |
+
public $is_live;
|
64 |
+
/**
|
65 |
+
* @author Leo Fajardo (@leorw)
|
66 |
+
*
|
67 |
+
* @since 1.2.3
|
68 |
+
*
|
69 |
+
* @var string|false false if the module doesn't have an affiliate program or one of the following:
|
70 |
+
* 'selected', 'customers', or 'all'.
|
71 |
+
*/
|
72 |
+
public $affiliate_moderation;
|
73 |
+
|
74 |
+
const AFFILIATE_MODERATION_CUSTOMERS = 'customers';
|
75 |
+
|
76 |
+
#endregion Install Specific Properties
|
77 |
+
|
78 |
+
/**
|
79 |
+
* @param stdClass|bool $plugin
|
80 |
+
*/
|
81 |
+
function __construct( $plugin = false ) {
|
82 |
+
parent::__construct( $plugin );
|
83 |
+
|
84 |
+
$this->is_premium = false;
|
85 |
+
$this->is_live = true;
|
86 |
+
|
87 |
+
if ( isset( $plugin->info ) && is_object( $plugin->info ) ) {
|
88 |
+
$this->info = new FS_Plugin_Info( $plugin->info );
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Check if plugin is an add-on (has parent).
|
94 |
+
*
|
95 |
+
* @author Vova Feldman (@svovaf)
|
96 |
+
* @since 1.0.6
|
97 |
+
*
|
98 |
+
* @return bool
|
99 |
+
*/
|
100 |
+
function is_addon() {
|
101 |
+
return isset( $this->parent_plugin_id ) && is_numeric( $this->parent_plugin_id );
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* @author Leo Fajardo (@leorw)
|
106 |
+
* @since 1.2.3
|
107 |
+
*
|
108 |
+
* @return bool
|
109 |
+
*/
|
110 |
+
function has_affiliate_program() {
|
111 |
+
return ( ! empty( $this->affiliate_moderation ) );
|
112 |
+
}
|
113 |
+
|
114 |
+
static function get_type() {
|
115 |
+
return 'plugin';
|
116 |
+
}
|
117 |
}
|
freemius/includes/entities/class-fs-site.php
CHANGED
@@ -1,148 +1,148 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
class FS_Site extends FS_Scope_Entity {
|
14 |
-
/**
|
15 |
-
* @var string
|
16 |
-
*/
|
17 |
-
public $slug;
|
18 |
-
/**
|
19 |
-
* @var number
|
20 |
-
*/
|
21 |
-
public $site_id;
|
22 |
-
/**
|
23 |
-
* @var number
|
24 |
-
*/
|
25 |
-
public $plugin_id;
|
26 |
-
/**
|
27 |
-
* @var number
|
28 |
-
*/
|
29 |
-
public $user_id;
|
30 |
-
/**
|
31 |
-
* @var string
|
32 |
-
*/
|
33 |
-
public $title;
|
34 |
-
/**
|
35 |
-
* @var string
|
36 |
-
*/
|
37 |
-
public $url;
|
38 |
-
/**
|
39 |
-
* @var string
|
40 |
-
*/
|
41 |
-
public $version;
|
42 |
-
/**
|
43 |
-
* @var string E.g. en-GB
|
44 |
-
*/
|
45 |
-
public $language;
|
46 |
-
/**
|
47 |
-
* @var string E.g. UTF-8
|
48 |
-
*/
|
49 |
-
public $charset;
|
50 |
-
/**
|
51 |
-
* @var string Platform version (e.g WordPress version).
|
52 |
-
*/
|
53 |
-
public $platform_version;
|
54 |
-
/**
|
55 |
-
* Freemius SDK version
|
56 |
-
*
|
57 |
-
* @author Leo Fajardo (@leorw)
|
58 |
-
* @since 1.2.2
|
59 |
-
*
|
60 |
-
* @var string SDK version (e.g.: 1.2.2)
|
61 |
-
*/
|
62 |
-
public $sdk_version;
|
63 |
-
/**
|
64 |
-
* @var string Programming language version (e.g PHP version).
|
65 |
-
*/
|
66 |
-
public $programming_language_version;
|
67 |
-
/**
|
68 |
-
* @var FS_Plugin_Plan $plan
|
69 |
-
*/
|
70 |
-
public $plan;
|
71 |
-
/**
|
72 |
-
* @var number|null
|
73 |
-
*/
|
74 |
-
public $license_id;
|
75 |
-
/**
|
76 |
-
* @var number|null
|
77 |
-
*/
|
78 |
-
public $trial_plan_id;
|
79 |
-
/**
|
80 |
-
* @var string|null
|
81 |
-
*/
|
82 |
-
public $trial_ends;
|
83 |
-
/**
|
84 |
-
* @since 1.0.9
|
85 |
-
*
|
86 |
-
* @var bool
|
87 |
-
*/
|
88 |
-
public $is_premium = false;
|
89 |
-
/**
|
90 |
-
* @author Leo Fajardo (@leorw)
|
91 |
-
*
|
92 |
-
* @since 1.2.1.5
|
93 |
-
*
|
94 |
-
* @var bool
|
95 |
-
*/
|
96 |
-
public $is_disconnected = false;
|
97 |
-
|
98 |
-
/**
|
99 |
-
* @param stdClass|bool $site
|
100 |
-
*/
|
101 |
-
function __construct( $site = false ) {
|
102 |
-
$this->plan = new FS_Plugin_Plan();
|
103 |
-
|
104 |
-
parent::__construct( $site );
|
105 |
-
|
106 |
-
if ( is_object( $site ) ) {
|
107 |
-
$this->plan->id = $site->plan_id;
|
108 |
-
}
|
109 |
-
|
110 |
-
if ( ! is_bool( $this->is_disconnected ) ) {
|
111 |
-
$this->is_disconnected = false;
|
112 |
-
}
|
113 |
-
}
|
114 |
-
|
115 |
-
static function get_type() {
|
116 |
-
return 'install';
|
117 |
-
}
|
118 |
-
|
119 |
-
function is_localhost() {
|
120 |
-
// The server has no way to verify if localhost unless localhost appears in domain.
|
121 |
-
return WP_FS__IS_LOCALHOST_FOR_SERVER;
|
122 |
-
// return (substr($_SERVER['REMOTE_ADDR'], 0, 4) == '127.' || $_SERVER['REMOTE_ADDR'] == '::1');
|
123 |
-
}
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Check if site in trial.
|
127 |
-
*
|
128 |
-
* @author Vova Feldman (@svovaf)
|
129 |
-
* @since 1.0.9
|
130 |
-
*
|
131 |
-
* @return bool
|
132 |
-
*/
|
133 |
-
function is_trial() {
|
134 |
-
return is_numeric( $this->trial_plan_id ) && ( strtotime( $this->trial_ends ) > WP_FS__SCRIPT_START_TIME );
|
135 |
-
}
|
136 |
-
|
137 |
-
/**
|
138 |
-
* Check if user already utilized the trial with the current install.
|
139 |
-
*
|
140 |
-
* @author Vova Feldman (@svovaf)
|
141 |
-
* @since 1.0.9
|
142 |
-
*
|
143 |
-
* @return bool
|
144 |
-
*/
|
145 |
-
function is_trial_utilized() {
|
146 |
-
return is_numeric( $this->trial_plan_id );
|
147 |
-
}
|
148 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
class FS_Site extends FS_Scope_Entity {
|
14 |
+
/**
|
15 |
+
* @var string
|
16 |
+
*/
|
17 |
+
public $slug;
|
18 |
+
/**
|
19 |
+
* @var number
|
20 |
+
*/
|
21 |
+
public $site_id;
|
22 |
+
/**
|
23 |
+
* @var number
|
24 |
+
*/
|
25 |
+
public $plugin_id;
|
26 |
+
/**
|
27 |
+
* @var number
|
28 |
+
*/
|
29 |
+
public $user_id;
|
30 |
+
/**
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
public $title;
|
34 |
+
/**
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
public $url;
|
38 |
+
/**
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
public $version;
|
42 |
+
/**
|
43 |
+
* @var string E.g. en-GB
|
44 |
+
*/
|
45 |
+
public $language;
|
46 |
+
/**
|
47 |
+
* @var string E.g. UTF-8
|
48 |
+
*/
|
49 |
+
public $charset;
|
50 |
+
/**
|
51 |
+
* @var string Platform version (e.g WordPress version).
|
52 |
+
*/
|
53 |
+
public $platform_version;
|
54 |
+
/**
|
55 |
+
* Freemius SDK version
|
56 |
+
*
|
57 |
+
* @author Leo Fajardo (@leorw)
|
58 |
+
* @since 1.2.2
|
59 |
+
*
|
60 |
+
* @var string SDK version (e.g.: 1.2.2)
|
61 |
+
*/
|
62 |
+
public $sdk_version;
|
63 |
+
/**
|
64 |
+
* @var string Programming language version (e.g PHP version).
|
65 |
+
*/
|
66 |
+
public $programming_language_version;
|
67 |
+
/**
|
68 |
+
* @var FS_Plugin_Plan $plan
|
69 |
+
*/
|
70 |
+
public $plan;
|
71 |
+
/**
|
72 |
+
* @var number|null
|
73 |
+
*/
|
74 |
+
public $license_id;
|
75 |
+
/**
|
76 |
+
* @var number|null
|
77 |
+
*/
|
78 |
+
public $trial_plan_id;
|
79 |
+
/**
|
80 |
+
* @var string|null
|
81 |
+
*/
|
82 |
+
public $trial_ends;
|
83 |
+
/**
|
84 |
+
* @since 1.0.9
|
85 |
+
*
|
86 |
+
* @var bool
|
87 |
+
*/
|
88 |
+
public $is_premium = false;
|
89 |
+
/**
|
90 |
+
* @author Leo Fajardo (@leorw)
|
91 |
+
*
|
92 |
+
* @since 1.2.1.5
|
93 |
+
*
|
94 |
+
* @var bool
|
95 |
+
*/
|
96 |
+
public $is_disconnected = false;
|
97 |
+
|
98 |
+
/**
|
99 |
+
* @param stdClass|bool $site
|
100 |
+
*/
|
101 |
+
function __construct( $site = false ) {
|
102 |
+
$this->plan = new FS_Plugin_Plan();
|
103 |
+
|
104 |
+
parent::__construct( $site );
|
105 |
+
|
106 |
+
if ( is_object( $site ) ) {
|
107 |
+
$this->plan->id = $site->plan_id;
|
108 |
+
}
|
109 |
+
|
110 |
+
if ( ! is_bool( $this->is_disconnected ) ) {
|
111 |
+
$this->is_disconnected = false;
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
static function get_type() {
|
116 |
+
return 'install';
|
117 |
+
}
|
118 |
+
|
119 |
+
function is_localhost() {
|
120 |
+
// The server has no way to verify if localhost unless localhost appears in domain.
|
121 |
+
return WP_FS__IS_LOCALHOST_FOR_SERVER;
|
122 |
+
// return (substr($_SERVER['REMOTE_ADDR'], 0, 4) == '127.' || $_SERVER['REMOTE_ADDR'] == '::1');
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Check if site in trial.
|
127 |
+
*
|
128 |
+
* @author Vova Feldman (@svovaf)
|
129 |
+
* @since 1.0.9
|
130 |
+
*
|
131 |
+
* @return bool
|
132 |
+
*/
|
133 |
+
function is_trial() {
|
134 |
+
return is_numeric( $this->trial_plan_id ) && ( strtotime( $this->trial_ends ) > WP_FS__SCRIPT_START_TIME );
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Check if user already utilized the trial with the current install.
|
139 |
+
*
|
140 |
+
* @author Vova Feldman (@svovaf)
|
141 |
+
* @since 1.0.9
|
142 |
+
*
|
143 |
+
* @return bool
|
144 |
+
*/
|
145 |
+
function is_trial_utilized() {
|
146 |
+
return is_numeric( $this->trial_plan_id );
|
147 |
+
}
|
148 |
}
|
freemius/includes/l10n.php
CHANGED
@@ -1,48 +1,48 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.2.1.6
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Retrieve the translation of $text.
|
15 |
-
*
|
16 |
-
* @since 1.2.1.6
|
17 |
-
*
|
18 |
-
* @param string $text
|
19 |
-
*
|
20 |
-
* @return string
|
21 |
-
*/
|
22 |
-
function _fs_text( $text ) {
|
23 |
-
// Avoid misleading Theme Check warning.
|
24 |
-
$fn = 'translate';
|
25 |
-
return $fn( $text, 'freemius' );
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Retrieve translated string with gettext context.
|
30 |
-
*
|
31 |
-
* Quite a few times, there will be collisions with similar translatable text
|
32 |
-
* found in more than two places, but with different translated context.
|
33 |
-
*
|
34 |
-
* By including the context in the pot file, translators can translate the two
|
35 |
-
* strings differently.
|
36 |
-
*
|
37 |
-
* @since 1.2.1.6
|
38 |
-
*
|
39 |
-
* @param string $text
|
40 |
-
* @param string $context
|
41 |
-
*
|
42 |
-
* @return string
|
43 |
-
*/
|
44 |
-
function _fs_x( $text, $context ) {
|
45 |
-
// Avoid misleading Theme Check warning.
|
46 |
-
$fn = 'translate_with_gettext_context';
|
47 |
-
return $fn( $text, $context, 'freemius' );
|
48 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.2.1.6
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Retrieve the translation of $text.
|
15 |
+
*
|
16 |
+
* @since 1.2.1.6
|
17 |
+
*
|
18 |
+
* @param string $text
|
19 |
+
*
|
20 |
+
* @return string
|
21 |
+
*/
|
22 |
+
function _fs_text( $text ) {
|
23 |
+
// Avoid misleading Theme Check warning.
|
24 |
+
$fn = 'translate';
|
25 |
+
return $fn( $text, 'freemius' );
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Retrieve translated string with gettext context.
|
30 |
+
*
|
31 |
+
* Quite a few times, there will be collisions with similar translatable text
|
32 |
+
* found in more than two places, but with different translated context.
|
33 |
+
*
|
34 |
+
* By including the context in the pot file, translators can translate the two
|
35 |
+
* strings differently.
|
36 |
+
*
|
37 |
+
* @since 1.2.1.6
|
38 |
+
*
|
39 |
+
* @param string $text
|
40 |
+
* @param string $context
|
41 |
+
*
|
42 |
+
* @return string
|
43 |
+
*/
|
44 |
+
function _fs_x( $text, $context ) {
|
45 |
+
// Avoid misleading Theme Check warning.
|
46 |
+
$fn = 'translate_with_gettext_context';
|
47 |
+
return $fn( $text, $context, 'freemius' );
|
48 |
+
}
|
freemius/includes/managers/class-fs-admin-menu-manager.php
CHANGED
@@ -1,850 +1,850 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.1.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
class FS_Admin_Menu_Manager {
|
14 |
-
|
15 |
-
#region Properties
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @since 1.2.2
|
19 |
-
*
|
20 |
-
* @var string
|
21 |
-
*/
|
22 |
-
protected $_module_unique_affix;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @since 1.2.2
|
26 |
-
*
|
27 |
-
* @var number
|
28 |
-
*/
|
29 |
-
protected $_module_id;
|
30 |
-
|
31 |
-
/**
|
32 |
-
* @since 1.2.2
|
33 |
-
*
|
34 |
-
* @var string
|
35 |
-
*/
|
36 |
-
protected $_module_type;
|
37 |
-
|
38 |
-
/**
|
39 |
-
* @since 1.0.6
|
40 |
-
*
|
41 |
-
* @var string
|
42 |
-
*/
|
43 |
-
private $_menu_slug;
|
44 |
-
/**
|
45 |
-
* @since 1.1.3
|
46 |
-
*
|
47 |
-
* @var string
|
48 |
-
*/
|
49 |
-
private $_parent_slug;
|
50 |
-
/**
|
51 |
-
* @since 1.1.3
|
52 |
-
*
|
53 |
-
* @var string
|
54 |
-
*/
|
55 |
-
private $_parent_type;
|
56 |
-
/**
|
57 |
-
* @since 1.1.3
|
58 |
-
*
|
59 |
-
* @var string
|
60 |
-
*/
|
61 |
-
private $_type;
|
62 |
-
/**
|
63 |
-
* @since 1.1.3
|
64 |
-
*
|
65 |
-
* @var bool
|
66 |
-
*/
|
67 |
-
private $_is_top_level;
|
68 |
-
/**
|
69 |
-
* @since 1.1.3
|
70 |
-
*
|
71 |
-
* @var bool
|
72 |
-
*/
|
73 |
-
private $_is_override_exact;
|
74 |
-
/**
|
75 |
-
* @since 1.1.3
|
76 |
-
*
|
77 |
-
* @var array<string,bool>
|
78 |
-
*/
|
79 |
-
private $_default_submenu_items;
|
80 |
-
/**
|
81 |
-
* @since 1.1.3
|
82 |
-
*
|
83 |
-
* @var string
|
84 |
-
*/
|
85 |
-
private $_first_time_path;
|
86 |
-
/**
|
87 |
-
* @since 1.2.2
|
88 |
-
*
|
89 |
-
* @var bool
|
90 |
-
*/
|
91 |
-
private $_menu_exists;
|
92 |
-
|
93 |
-
#endregion Properties
|
94 |
-
|
95 |
-
/**
|
96 |
-
* @var FS_Logger
|
97 |
-
*/
|
98 |
-
protected $_logger;
|
99 |
-
|
100 |
-
#region Singleton
|
101 |
-
|
102 |
-
/**
|
103 |
-
* @var FS_Admin_Menu_Manager[]
|
104 |
-
*/
|
105 |
-
private static $_instances = array();
|
106 |
-
|
107 |
-
/**
|
108 |
-
* @param number $module_id
|
109 |
-
* @param string $module_type
|
110 |
-
* @param string $module_unique_affix
|
111 |
-
*
|
112 |
-
* @return FS_Admin_Menu_Manager
|
113 |
-
*/
|
114 |
-
static function instance( $module_id, $module_type, $module_unique_affix ) {
|
115 |
-
$key = 'm_' . $module_id;
|
116 |
-
|
117 |
-
if ( ! isset( self::$_instances[ $key ] ) ) {
|
118 |
-
self::$_instances[ $key ] = new FS_Admin_Menu_Manager( $module_id, $module_type, $module_unique_affix );
|
119 |
-
}
|
120 |
-
|
121 |
-
return self::$_instances[ $key ];
|
122 |
-
}
|
123 |
-
|
124 |
-
protected function __construct( $module_id, $module_type, $module_unique_affix ) {
|
125 |
-
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $module_id . '_admin_menu', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
126 |
-
|
127 |
-
$this->_module_id = $module_id;
|
128 |
-
$this->_module_type = $module_type;
|
129 |
-
$this->_module_unique_affix = $module_unique_affix;
|
130 |
-
}
|
131 |
-
|
132 |
-
#endregion Singleton
|
133 |
-
|
134 |
-
#region Helpers
|
135 |
-
|
136 |
-
private function get_option( &$options, $key, $default = false ) {
|
137 |
-
return ! empty( $options[ $key ] ) ? $options[ $key ] : $default;
|
138 |
-
}
|
139 |
-
|
140 |
-
private function get_bool_option( &$options, $key, $default = false ) {
|
141 |
-
return isset( $options[ $key ] ) && is_bool( $options[ $key ] ) ? $options[ $key ] : $default;
|
142 |
-
}
|
143 |
-
|
144 |
-
#endregion Helpers
|
145 |
-
|
146 |
-
/**
|
147 |
-
* @param array $menu
|
148 |
-
* @param bool $is_addon
|
149 |
-
*/
|
150 |
-
function init( $menu, $is_addon = false ) {
|
151 |
-
$this->_menu_exists = ( isset( $menu['slug'] ) && ! empty( $menu['slug'] ) );
|
152 |
-
|
153 |
-
$this->_menu_slug = ( $this->_menu_exists ? $menu['slug'] : $this->_module_unique_affix );
|
154 |
-
|
155 |
-
$this->_default_submenu_items = array();
|
156 |
-
// @deprecated
|
157 |
-
$this->_type = 'page';
|
158 |
-
$this->_is_top_level = true;
|
159 |
-
$this->_is_override_exact = false;
|
160 |
-
$this->_parent_slug = false;
|
161 |
-
// @deprecated
|
162 |
-
$this->_parent_type = 'page';
|
163 |
-
|
164 |
-
if ( ! $is_addon && isset( $menu ) ) {
|
165 |
-
$this->_default_submenu_items = array(
|
166 |
-
'contact' => $this->get_bool_option( $menu, 'contact', true ),
|
167 |
-
'support' => $this->get_bool_option( $menu, 'support', true ),
|
168 |
-
'affiliation' => $this->get_bool_option( $menu, 'affiliation', true ),
|
169 |
-
'account' => $this->get_bool_option( $menu, 'account', true ),
|
170 |
-
'pricing' => $this->get_bool_option( $menu, 'pricing', true ),
|
171 |
-
'addons' => $this->get_bool_option( $menu, 'addons', true ),
|
172 |
-
);
|
173 |
-
|
174 |
-
// @deprecated
|
175 |
-
$this->_type = $this->get_option( $menu, 'type', 'page' );
|
176 |
-
$this->_is_override_exact = $this->get_bool_option( $menu, 'override_exact' );
|
177 |
-
|
178 |
-
if ( isset( $menu['parent'] ) ) {
|
179 |
-
$this->_parent_slug = $this->get_option( $menu['parent'], 'slug' );
|
180 |
-
// @deprecated
|
181 |
-
$this->_parent_type = $this->get_option( $menu['parent'], 'type', 'page' );
|
182 |
-
|
183 |
-
// If parent's slug is different, then it's NOT a top level menu item.
|
184 |
-
$this->_is_top_level = ( $this->_parent_slug === $this->_menu_slug );
|
185 |
-
} else {
|
186 |
-
/**
|
187 |
-
* If no parent then top level if:
|
188 |
-
* - Has custom admin menu ('page')
|
189 |
-
* - CPT menu type ('cpt')
|
190 |
-
*/
|
191 |
-
// $this->_is_top_level = in_array( $this->_type, array(
|
192 |
-
// 'cpt',
|
193 |
-
// 'page'
|
194 |
-
// ) );
|
195 |
-
}
|
196 |
-
|
197 |
-
$this->_first_time_path = $this->get_option( $menu, 'first-path', false );
|
198 |
-
if ( ! empty( $this->_first_time_path ) && is_string( $this->_first_time_path ) ) {
|
199 |
-
$this->_first_time_path = admin_url( $this->_first_time_path, 'admin' );
|
200 |
-
}
|
201 |
-
}
|
202 |
-
}
|
203 |
-
|
204 |
-
/**
|
205 |
-
* Check if top level menu.
|
206 |
-
*
|
207 |
-
* @author Vova Feldman (@svovaf)
|
208 |
-
* @since 1.1.3
|
209 |
-
*
|
210 |
-
* @return bool False if submenu item.
|
211 |
-
*/
|
212 |
-
function is_top_level() {
|
213 |
-
return $this->_is_top_level;
|
214 |
-
}
|
215 |
-
|
216 |
-
/**
|
217 |
-
* Check if the page should be override on exact URL match.
|
218 |
-
*
|
219 |
-
* @author Vova Feldman (@svovaf)
|
220 |
-
* @since 1.1.3
|
221 |
-
*
|
222 |
-
* @return bool False if submenu item.
|
223 |
-
*/
|
224 |
-
function is_override_exact() {
|
225 |
-
return $this->_is_override_exact;
|
226 |
-
}
|
227 |
-
|
228 |
-
|
229 |
-
/**
|
230 |
-
* Get the path of the page the user should be forwarded to after first activation.
|
231 |
-
*
|
232 |
-
* @author Vova Feldman (@svovaf)
|
233 |
-
* @since 1.1.3
|
234 |
-
*
|
235 |
-
* @return string
|
236 |
-
*/
|
237 |
-
function get_first_time_path() {
|
238 |
-
return $this->_first_time_path;
|
239 |
-
}
|
240 |
-
|
241 |
-
/**
|
242 |
-
* Check if plugin's menu item is part of a custom top level menu.
|
243 |
-
*
|
244 |
-
* @author Vova Feldman (@svovaf)
|
245 |
-
* @since 1.1.3
|
246 |
-
*
|
247 |
-
* @return bool
|
248 |
-
*/
|
249 |
-
function has_custom_parent() {
|
250 |
-
return ! $this->_is_top_level && is_string( $this->_parent_slug );
|
251 |
-
}
|
252 |
-
|
253 |
-
/**
|
254 |
-
* @author Leo Fajardo (@leorw)
|
255 |
-
* @since 1.2.2
|
256 |
-
*
|
257 |
-
* @return bool
|
258 |
-
*/
|
259 |
-
function has_menu() {
|
260 |
-
return $this->_menu_exists;
|
261 |
-
}
|
262 |
-
|
263 |
-
/**
|
264 |
-
* @author Vova Feldman (@svovaf)
|
265 |
-
* @since 1.1.3
|
266 |
-
*
|
267 |
-
* @param string $id
|
268 |
-
* @param bool $default
|
269 |
-
* @param bool $ignore_menu_existence Since 1.2.2.7 If true, check if the submenu item visible even if there's no parent menu.
|
270 |
-
*
|
271 |
-
* @return bool
|
272 |
-
*/
|
273 |
-
function is_submenu_item_visible( $id, $default = true, $ignore_menu_existence = false ) {
|
274 |
-
if ( ! $ignore_menu_existence && ! $this->has_menu() ) {
|
275 |
-
return false;
|
276 |
-
}
|
277 |
-
|
278 |
-
return fs_apply_filter(
|
279 |
-
$this->_module_unique_affix,
|
280 |
-
'is_submenu_visible',
|
281 |
-
$this->get_bool_option( $this->_default_submenu_items, $id, $default ),
|
282 |
-
$id
|
283 |
-
);
|
284 |
-
}
|
285 |
-
|
286 |
-
/**
|
287 |
-
* Calculates admin settings menu slug.
|
288 |
-
* If plugin's menu slug is a file (e.g. CPT), uses plugin's slug as the menu slug.
|
289 |
-
*
|
290 |
-
* @author Vova Feldman (@svovaf)
|
291 |
-
* @since 1.1.3
|
292 |
-
*
|
293 |
-
* @param string $page
|
294 |
-
*
|
295 |
-
* @return string
|
296 |
-
*/
|
297 |
-
function get_slug( $page = '' ) {
|
298 |
-
return ( ( false === strpos( $this->_menu_slug, '.php?' ) ) ?
|
299 |
-
$this->_menu_slug :
|
300 |
-
$this->_module_unique_affix ) . ( empty( $page ) ? '' : ( '-' . $page ) );
|
301 |
-
}
|
302 |
-
|
303 |
-
/**
|
304 |
-
* @author Vova Feldman (@svovaf)
|
305 |
-
* @since 1.1.3
|
306 |
-
*
|
307 |
-
* @return string
|
308 |
-
*/
|
309 |
-
function get_parent_slug() {
|
310 |
-
return $this->_parent_slug;
|
311 |
-
}
|
312 |
-
|
313 |
-
/**
|
314 |
-
* @author Vova Feldman (@svovaf)
|
315 |
-
* @since 1.1.3
|
316 |
-
*
|
317 |
-
* @return string
|
318 |
-
*/
|
319 |
-
function get_type() {
|
320 |
-
return $this->_type;
|
321 |
-
}
|
322 |
-
|
323 |
-
/**
|
324 |
-
* @author Vova Feldman (@svovaf)
|
325 |
-
* @since 1.1.3
|
326 |
-
*
|
327 |
-
* @return bool
|
328 |
-
*/
|
329 |
-
function is_cpt() {
|
330 |
-
return ( 0 === strpos( $this->_menu_slug, 'edit.php?post_type=' ) ||
|
331 |
-
// Back compatibility.
|
332 |
-
'cpt' === $this->_type
|
333 |
-
);
|
334 |
-
}
|
335 |
-
|
336 |
-
/**
|
337 |
-
* @author Vova Feldman (@svovaf)
|
338 |
-
* @since 1.1.3
|
339 |
-
*
|
340 |
-
* @return string
|
341 |
-
*/
|
342 |
-
function get_parent_type() {
|
343 |
-
return $this->_parent_type;
|
344 |
-
}
|
345 |
-
|
346 |
-
/**
|
347 |
-
* @author Vova Feldman (@svovaf)
|
348 |
-
* @since 1.1.3
|
349 |
-
*
|
350 |
-
* @return string
|
351 |
-
*/
|
352 |
-
function get_raw_slug() {
|
353 |
-
return $this->_menu_slug;
|
354 |
-
}
|
355 |
-
|
356 |
-
/**
|
357 |
-
* Get plugin's original menu slug.
|
358 |
-
*
|
359 |
-
* @author Vova Feldman (@svovaf)
|
360 |
-
* @since 1.1.3
|
361 |
-
*
|
362 |
-
* @return string
|
363 |
-
*/
|
364 |
-
function get_original_menu_slug() {
|
365 |
-
if ( 'cpt' === $this->_type ) {
|
366 |
-
return add_query_arg( array(
|
367 |
-
'post_type' => $this->_menu_slug
|
368 |
-
), 'edit.php' );
|
369 |
-
}
|
370 |
-
|
371 |
-
if ( false === strpos( $this->_menu_slug, '.php?' ) ) {
|
372 |
-
return $this->_menu_slug;
|
373 |
-
} else {
|
374 |
-
return $this->_module_unique_affix;
|
375 |
-
}
|
376 |
-
}
|
377 |
-
|
378 |
-
/**
|
379 |
-
* @author Vova Feldman (@svovaf)
|
380 |
-
* @since 1.1.3
|
381 |
-
*
|
382 |
-
* @return string
|
383 |
-
*/
|
384 |
-
function get_top_level_menu_slug() {
|
385 |
-
return $this->has_custom_parent() ?
|
386 |
-
$this->get_parent_slug() :
|
387 |
-
$this->get_raw_slug();
|
388 |
-
}
|
389 |
-
|
390 |
-
/**
|
391 |
-
* Is user on plugin's admin activation page.
|
392 |
-
*
|
393 |
-
* @author Vova Feldman (@svovaf)
|
394 |
-
* @since 1.0.8
|
395 |
-
*
|
396 |
-
* @return bool
|
397 |
-
*/
|
398 |
-
function is_main_settings_page() {
|
399 |
-
if ( $this->_menu_exists &&
|
400 |
-
( fs_is_plugin_page( $this->_menu_slug ) || fs_is_plugin_page( $this->_module_unique_affix ) )
|
401 |
-
) {
|
402 |
-
/**
|
403 |
-
* Module has a settings menu and the context page is the main settings page, so assume it's in
|
404 |
-
* activation (doesn't really check if already opted-in/skipped or not).
|
405 |
-
*
|
406 |
-
* @since 1.2.2
|
407 |
-
*/
|
408 |
-
return true;
|
409 |
-
}
|
410 |
-
|
411 |
-
global $pagenow;
|
412 |
-
if ( ( WP_FS__MODULE_TYPE_THEME === $this->_module_type ) && Freemius::is_themes_page() ) {
|
413 |
-
/**
|
414 |
-
* In activation only when show_optin query string param is given.
|
415 |
-
*
|
416 |
-
* @since 1.2.2
|
417 |
-
*/
|
418 |
-
return fs_request_get_bool( $this->_module_unique_affix . '_show_optin' );
|
419 |
-
}
|
420 |
-
|
421 |
-
return false;
|
422 |
-
}
|
423 |
-
|
424 |
-
#region Submenu Override
|
425 |
-
|
426 |
-
/**
|
427 |
-
* Override submenu's action.
|
428 |
-
*
|
429 |
-
* @author Vova Feldman (@svovaf)
|
430 |
-
* @since 1.1.0
|
431 |
-
*
|
432 |
-
* @param string $parent_slug
|
433 |
-
* @param string $menu_slug
|
434 |
-
* @param callable $function
|
435 |
-
*
|
436 |
-
* @return false|string If submenu exist, will return the hook name.
|
437 |
-
*/
|
438 |
-
function override_submenu_action( $parent_slug, $menu_slug, $function ) {
|
439 |
-
global $submenu;
|
440 |
-
|
441 |
-
$menu_slug = plugin_basename( $menu_slug );
|
442 |
-
$parent_slug = plugin_basename( $parent_slug );
|
443 |
-
|
444 |
-
if ( ! isset( $submenu[ $parent_slug ] ) ) {
|
445 |
-
// Parent menu not exist.
|
446 |
-
return false;
|
447 |
-
}
|
448 |
-
|
449 |
-
$found_submenu_item = false;
|
450 |
-
foreach ( $submenu[ $parent_slug ] as $submenu_item ) {
|
451 |
-
if ( $menu_slug === $submenu_item[2] ) {
|
452 |
-
$found_submenu_item = $submenu_item;
|
453 |
-
break;
|
454 |
-
}
|
455 |
-
}
|
456 |
-
|
457 |
-
if ( false === $found_submenu_item ) {
|
458 |
-
// Submenu item not found.
|
459 |
-
return false;
|
460 |
-
}
|
461 |
-
|
462 |
-
// Remove current function.
|
463 |
-
$hookname = get_plugin_page_hookname( $menu_slug, $parent_slug );
|
464 |
-
remove_all_actions( $hookname );
|
465 |
-
|
466 |
-
// Attach new action.
|
467 |
-
add_action( $hookname, $function );
|
468 |
-
|
469 |
-
return $hookname;
|
470 |
-
}
|
471 |
-
|
472 |
-
#endregion Submenu Override
|
473 |
-
|
474 |
-
#region Top level menu Override
|
475 |
-
|
476 |
-
/**
|
477 |
-
* Find plugin's admin dashboard main menu item.
|
478 |
-
*
|
479 |
-
* @author Vova Feldman (@svovaf)
|
480 |
-
* @since 1.0.2
|
481 |
-
*
|
482 |
-
* @return string[]|false
|
483 |
-
*/
|
484 |
-
private function find_top_level_menu() {
|
485 |
-
global $menu;
|
486 |
-
|
487 |
-
$position = - 1;
|
488 |
-
$found_menu = false;
|
489 |
-
|
490 |
-
$menu_slug = $this->get_raw_slug();
|
491 |
-
|
492 |
-
$hook_name = get_plugin_page_hookname( $menu_slug, '' );
|
493 |
-
foreach ( $menu as $pos => $m ) {
|
494 |
-
if ( $menu_slug === $m[2] ) {
|
495 |
-
$position = $pos;
|
496 |
-
$found_menu = $m;
|
497 |
-
break;
|
498 |
-
}
|
499 |
-
}
|
500 |
-
|
501 |
-
if ( false === $found_menu ) {
|
502 |
-
return false;
|
503 |
-
}
|
504 |
-
|
505 |
-
return array(
|
506 |
-
'menu' => $found_menu,
|
507 |
-
'position' => $position,
|
508 |
-
'hook_name' => $hook_name
|
509 |
-
);
|
510 |
-
}
|
511 |
-
|
512 |
-
/**
|
513 |
-
* Find plugin's admin dashboard main submenu item.
|
514 |
-
*
|
515 |
-
* @author Vova Feldman (@svovaf)
|
516 |
-
* @since 1.2.1.6
|
517 |
-
*
|
518 |
-
* @return array|false
|
519 |
-
*/
|
520 |
-
private function find_main_submenu() {
|
521 |
-
global $submenu;
|
522 |
-
|
523 |
-
$top_level_menu_slug = $this->get_top_level_menu_slug();
|
524 |
-
|
525 |
-
if ( ! isset( $submenu[ $top_level_menu_slug ] ) ) {
|
526 |
-
return false;
|
527 |
-
}
|
528 |
-
|
529 |
-
$submenu_slug = $this->get_raw_slug();
|
530 |
-
|
531 |
-
$position = - 1;
|
532 |
-
$found_submenu = false;
|
533 |
-
|
534 |
-
$hook_name = get_plugin_page_hookname( $submenu_slug, '' );
|
535 |
-
|
536 |
-
foreach ( $submenu[ $top_level_menu_slug ] as $pos => $sub ) {
|
537 |
-
if ( $submenu_slug === $sub[2] ) {
|
538 |
-
$position = $pos;
|
539 |
-
$found_submenu = $sub;
|
540 |
-
}
|
541 |
-
}
|
542 |
-
|
543 |
-
if ( false === $found_submenu ) {
|
544 |
-
return false;
|
545 |
-
}
|
546 |
-
|
547 |
-
return array(
|
548 |
-
'menu' => $found_submenu,
|
549 |
-
'parent_slug' => $top_level_menu_slug,
|
550 |
-
'position' => $position,
|
551 |
-
'hook_name' => $hook_name
|
552 |
-
);
|
553 |
-
}
|
554 |
-
|
555 |
-
/**
|
556 |
-
* Remove all sub-menu items.
|
557 |
-
*
|
558 |
-
* @author Vova Feldman (@svovaf)
|
559 |
-
* @since 1.0.7
|
560 |
-
*
|
561 |
-
* @return bool If submenu with plugin's menu slug was found.
|
562 |
-
*/
|
563 |
-
private function remove_all_submenu_items() {
|
564 |
-
global $submenu;
|
565 |
-
|
566 |
-
$menu_slug = $this->get_raw_slug();
|
567 |
-
|
568 |
-
if ( ! isset( $submenu[ $menu_slug ] ) ) {
|
569 |
-
return false;
|
570 |
-
}
|
571 |
-
|
572 |
-
/**
|
573 |
-
* This method is NOT executed for WordPress.org themes.
|
574 |
-
* Since we maintain only one version of the SDK we added this small
|
575 |
-
* hack to avoid the error from Theme Check since it's a false-positive.
|
576 |
-
*
|
577 |
-
* @author Vova Feldman (@svovaf)
|
578 |
-
* @since 1.2.2.7
|
579 |
-
*/
|
580 |
-
$submenu_ref = &$submenu;
|
581 |
-
$submenu_ref[ $menu_slug ] = array();
|
582 |
-
|
583 |
-
return true;
|
584 |
-
}
|
585 |
-
|
586 |
-
/**
|
587 |
-
*
|
588 |
-
* @author Vova Feldman (@svovaf)
|
589 |
-
* @since 1.0.9
|
590 |
-
*
|
591 |
-
* @return false|array[string]mixed
|
592 |
-
*/
|
593 |
-
function remove_menu_item() {
|
594 |
-
$this->_logger->entrance();
|
595 |
-
|
596 |
-
// Find main menu item.
|
597 |
-
$menu = $this->find_top_level_menu();
|
598 |
-
|
599 |
-
if ( false === $menu ) {
|
600 |
-
return false;
|
601 |
-
}
|
602 |
-
|
603 |
-
// Remove it with its actions.
|
604 |
-
remove_all_actions( $menu['hook_name'] );
|
605 |
-
|
606 |
-
// Remove all submenu items.
|
607 |
-
$this->remove_all_submenu_items();
|
608 |
-
|
609 |
-
return $menu;
|
610 |
-
}
|
611 |
-
|
612 |
-
/**
|
613 |
-
* Get module's main admin setting page URL.
|
614 |
-
*
|
615 |
-
* @todo This method was only tested for wp.org compliant themes with a submenu item. Need to test for plugins with top level, submenu, and CPT top level, menu items.
|
616 |
-
*
|
617 |
-
* @author Vova Feldman (@svovaf)
|
618 |
-
* @since 1.2.2.7
|
619 |
-
*
|
620 |
-
* @return string
|
621 |
-
*/
|
622 |
-
function main_menu_url() {
|
623 |
-
$this->_logger->entrance();
|
624 |
-
|
625 |
-
if ( $this->_is_top_level ) {
|
626 |
-
$menu = $this->find_top_level_menu();
|
627 |
-
} else {
|
628 |
-
$menu = $this->find_main_submenu();
|
629 |
-
}
|
630 |
-
|
631 |
-
$parent_slug = isset( $menu['parent_slug'] ) ?
|
632 |
-
$menu['parent_slug'] :
|
633 |
-
'admin.php';
|
634 |
-
|
635 |
-
return admin_url( $parent_slug . '?page=' . $menu['menu'][2] );
|
636 |
-
}
|
637 |
-
|
638 |
-
/**
|
639 |
-
* @author Vova Feldman (@svovaf)
|
640 |
-
* @since 1.1.4
|
641 |
-
*
|
642 |
-
* @param callable $function
|
643 |
-
*
|
644 |
-
* @return false|array[string]mixed
|
645 |
-
*/
|
646 |
-
function override_menu_item( $function ) {
|
647 |
-
$found_menu = $this->remove_menu_item();
|
648 |
-
|
649 |
-
if ( false === $found_menu ) {
|
650 |
-
return false;
|
651 |
-
}
|
652 |
-
|
653 |
-
if ( ! $this->is_top_level() || ! $this->is_cpt() ) {
|
654 |
-
$menu_slug = plugin_basename( $this->get_slug() );
|
655 |
-
|
656 |
-
$hookname = get_plugin_page_hookname( $menu_slug, '' );
|
657 |
-
|
658 |
-
// Override menu action.
|
659 |
-
add_action( $hookname, $function );
|
660 |
-
} else {
|
661 |
-
global $menu;
|
662 |
-
|
663 |
-
// Remove original CPT menu.
|
664 |
-
unset( $menu[ $found_menu['position'] ] );
|
665 |
-
|
666 |
-
// Create new top-level menu action.
|
667 |
-
$hookname = self::add_page(
|
668 |
-
$found_menu['menu'][3],
|
669 |
-
$found_menu['menu'][0],
|
670 |
-
'manage_options',
|
671 |
-
$this->get_slug(),
|
672 |
-
$function,
|
673 |
-
$found_menu['menu'][6],
|
674 |
-
$found_menu['position']
|
675 |
-
);
|
676 |
-
}
|
677 |
-
|
678 |
-
return $hookname;
|
679 |
-
}
|
680 |
-
|
681 |
-
/**
|
682 |
-
* Adds a counter to the module's top level menu item.
|
683 |
-
*
|
684 |
-
* @author Vova Feldman (@svovaf)
|
685 |
-
* @since 1.2.1.5
|
686 |
-
*
|
687 |
-
* @param int $counter
|
688 |
-
* @param string $class
|
689 |
-
*/
|
690 |
-
function add_counter_to_menu_item( $counter = 1, $class = '' ) {
|
691 |
-
global $menu, $submenu;
|
692 |
-
|
693 |
-
$mask = '%s <span class="update-plugins %s count-%3$s" aria-hidden="true"><span>%3$s<span class="screen-reader-text">%3$s notifications</span></span></span>';
|
694 |
-
|
695 |
-
/**
|
696 |
-
* This method is NOT executed for WordPress.org themes.
|
697 |
-
* Since we maintain only one version of the SDK we added this small
|
698 |
-
* hack to avoid the error from Theme Check since it's a false-positive.
|
699 |
-
*
|
700 |
-
* @author Vova Feldman (@svovaf)
|
701 |
-
* @since 1.2.2.7
|
702 |
-
*/
|
703 |
-
$menu_ref = &$menu;
|
704 |
-
$submenu_ref = &$submenu;
|
705 |
-
|
706 |
-
if ( $this->_is_top_level ) {
|
707 |
-
// Find main menu item.
|
708 |
-
$found_menu = $this->find_top_level_menu();
|
709 |
-
|
710 |
-
if ( false !== $found_menu ) {
|
711 |
-
// Override menu label.
|
712 |
-
$menu_ref[ $found_menu['position'] ][0] = sprintf(
|
713 |
-
$mask,
|
714 |
-
$found_menu['menu'][0],
|
715 |
-
$class,
|
716 |
-
$counter
|
717 |
-
);
|
718 |
-
}
|
719 |
-
} else {
|
720 |
-
$found_submenu = $this->find_main_submenu();
|
721 |
-
|
722 |
-
if ( false !== $found_submenu ) {
|
723 |
-
// Override menu label.
|
724 |
-
$submenu_ref[ $found_submenu['parent_slug'] ][ $found_submenu['position'] ][0] = sprintf(
|
725 |
-
$mask,
|
726 |
-
$found_submenu['menu'][0],
|
727 |
-
$class,
|
728 |
-
$counter
|
729 |
-
);
|
730 |
-
}
|
731 |
-
}
|
732 |
-
}
|
733 |
-
|
734 |
-
#endregion Top level menu Override
|
735 |
-
|
736 |
-
/**
|
737 |
-
* Add a top-level menu page.
|
738 |
-
*
|
739 |
-
* Note for WordPress.org Theme/Plugin reviewer:
|
740 |
-
*
|
741 |
-
* This is a replication of `add_menu_page()` to avoid Theme Check warning.
|
742 |
-
*
|
743 |
-
* Why?
|
744 |
-
* ====
|
745 |
-
* Freemius is an SDK for plugin and theme developers. Since the core
|
746 |
-
* of the SDK is relevant both for plugins and themes, for obvious reasons,
|
747 |
-
* we only develop and maintain one code base.
|
748 |
-
*
|
749 |
-
* This method will not run for wp.org themes (only plugins) since theme
|
750 |
-
* admin settings/options are now only allowed in the customizer.
|
751 |
-
*
|
752 |
-
* If you have any questions or need clarifications, please don't hesitate
|
753 |
-
* pinging me on slack, my username is @svovaf.
|
754 |
-
*
|
755 |
-
* @author Vova Feldman (@svovaf)
|
756 |
-
* @since 1.2.2
|
757 |
-
*
|
758 |
-
* @param string $page_title The text to be displayed in the title tags of the page when the menu is
|
759 |
-
* selected.
|
760 |
-
* @param string $menu_title The text to be used for the menu.
|
761 |
-
* @param string $capability The capability required for this menu to be displayed to the user.
|
762 |
-
* @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu).
|
763 |
-
* @param callable|string $function The function to be called to output the content for this page.
|
764 |
-
* @param string $icon_url The URL to the icon to be used for this menu.
|
765 |
-
* * Pass a base64-encoded SVG using a data URI, which will be colored to
|
766 |
-
* match the color scheme. This should begin with
|
767 |
-
* 'data:image/svg+xml;base64,'.
|
768 |
-
* * Pass the name of a Dashicons helper class to use a font icon,
|
769 |
-
* e.g. 'dashicons-chart-pie'.
|
770 |
-
* * Pass 'none' to leave div.wp-menu-image empty so an icon can be added
|
771 |
-
* via CSS.
|
772 |
-
* @param int $position The position in the menu order this one should appear.
|
773 |
-
*
|
774 |
-
* @return string The resulting page's hook_suffix.
|
775 |
-
*/
|
776 |
-
static function add_page(
|
777 |
-
$page_title,
|
778 |
-
$menu_title,
|
779 |
-
$capability,
|
780 |
-
$menu_slug,
|
781 |
-
$function = '',
|
782 |
-
$icon_url = '',
|
783 |
-
$position = null
|
784 |
-
) {
|
785 |
-
$fn = 'add_menu' . '_page';
|
786 |
-
|
787 |
-
return $fn(
|
788 |
-
$page_title,
|
789 |
-
$menu_title,
|
790 |
-
$capability,
|
791 |
-
$menu_slug,
|
792 |
-
$function,
|
793 |
-
$icon_url,
|
794 |
-
$position
|
795 |
-
);
|
796 |
-
}
|
797 |
-
|
798 |
-
/**
|
799 |
-
* Add a submenu page.
|
800 |
-
*
|
801 |
-
* Note for WordPress.org Theme/Plugin reviewer:
|
802 |
-
*
|
803 |
-
* This is a replication of `add_submenu_page()` to avoid Theme Check warning.
|
804 |
-
*
|
805 |
-
* Why?
|
806 |
-
* ====
|
807 |
-
* Freemius is an SDK for plugin and theme developers. Since the core
|
808 |
-
* of the SDK is relevant both for plugins and themes, for obvious reasons,
|
809 |
-
* we only develop and maintain one code base.
|
810 |
-
*
|
811 |
-
* This method will not run for wp.org themes (only plugins) since theme
|
812 |
-
* admin settings/options are now only allowed in the customizer.
|
813 |
-
*
|
814 |
-
* If you have any questions or need clarifications, please don't hesitate
|
815 |
-
* pinging me on slack, my username is @svovaf.
|
816 |
-
*
|
817 |
-
* @author Vova Feldman (@svovaf)
|
818 |
-
* @since 1.2.2
|
819 |
-
*
|
820 |
-
* @param string $parent_slug The slug name for the parent menu (or the file name of a standard
|
821 |
-
* WordPress admin page).
|
822 |
-
* @param string $page_title The text to be displayed in the title tags of the page when the menu is
|
823 |
-
* selected.
|
824 |
-
* @param string $menu_title The text to be used for the menu.
|
825 |
-
* @param string $capability The capability required for this menu to be displayed to the user.
|
826 |
-
* @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu).
|
827 |
-
* @param callable|string $function The function to be called to output the content for this page.
|
828 |
-
*
|
829 |
-
* @return false|string The resulting page's hook_suffix, or false if the user does not have the capability
|
830 |
-
* required.
|
831 |
-
*/
|
832 |
-
static function add_subpage(
|
833 |
-
$parent_slug,
|
834 |
-
$page_title,
|
835 |
-
$menu_title,
|
836 |
-
$capability,
|
837 |
-
$menu_slug,
|
838 |
-
$function = ''
|
839 |
-
) {
|
840 |
-
$fn = 'add_submenu' . '_page';
|
841 |
-
|
842 |
-
return $fn( $parent_slug,
|
843 |
-
$page_title,
|
844 |
-
$menu_title,
|
845 |
-
$capability,
|
846 |
-
$menu_slug,
|
847 |
-
$function
|
848 |
-
);
|
849 |
-
}
|
850 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.1.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
class FS_Admin_Menu_Manager {
|
14 |
+
|
15 |
+
#region Properties
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @since 1.2.2
|
19 |
+
*
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
protected $_module_unique_affix;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @since 1.2.2
|
26 |
+
*
|
27 |
+
* @var number
|
28 |
+
*/
|
29 |
+
protected $_module_id;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @since 1.2.2
|
33 |
+
*
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
protected $_module_type;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @since 1.0.6
|
40 |
+
*
|
41 |
+
* @var string
|
42 |
+
*/
|
43 |
+
private $_menu_slug;
|
44 |
+
/**
|
45 |
+
* @since 1.1.3
|
46 |
+
*
|
47 |
+
* @var string
|
48 |
+
*/
|
49 |
+
private $_parent_slug;
|
50 |
+
/**
|
51 |
+
* @since 1.1.3
|
52 |
+
*
|
53 |
+
* @var string
|
54 |
+
*/
|
55 |
+
private $_parent_type;
|
56 |
+
/**
|
57 |
+
* @since 1.1.3
|
58 |
+
*
|
59 |
+
* @var string
|
60 |
+
*/
|
61 |
+
private $_type;
|
62 |
+
/**
|
63 |
+
* @since 1.1.3
|
64 |
+
*
|
65 |
+
* @var bool
|
66 |
+
*/
|
67 |
+
private $_is_top_level;
|
68 |
+
/**
|
69 |
+
* @since 1.1.3
|
70 |
+
*
|
71 |
+
* @var bool
|
72 |
+
*/
|
73 |
+
private $_is_override_exact;
|
74 |
+
/**
|
75 |
+
* @since 1.1.3
|
76 |
+
*
|
77 |
+
* @var array<string,bool>
|
78 |
+
*/
|
79 |
+
private $_default_submenu_items;
|
80 |
+
/**
|
81 |
+
* @since 1.1.3
|
82 |
+
*
|
83 |
+
* @var string
|
84 |
+
*/
|
85 |
+
private $_first_time_path;
|
86 |
+
/**
|
87 |
+
* @since 1.2.2
|
88 |
+
*
|
89 |
+
* @var bool
|
90 |
+
*/
|
91 |
+
private $_menu_exists;
|
92 |
+
|
93 |
+
#endregion Properties
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @var FS_Logger
|
97 |
+
*/
|
98 |
+
protected $_logger;
|
99 |
+
|
100 |
+
#region Singleton
|
101 |
+
|
102 |
+
/**
|
103 |
+
* @var FS_Admin_Menu_Manager[]
|
104 |
+
*/
|
105 |
+
private static $_instances = array();
|
106 |
+
|
107 |
+
/**
|
108 |
+
* @param number $module_id
|
109 |
+
* @param string $module_type
|
110 |
+
* @param string $module_unique_affix
|
111 |
+
*
|
112 |
+
* @return FS_Admin_Menu_Manager
|
113 |
+
*/
|
114 |
+
static function instance( $module_id, $module_type, $module_unique_affix ) {
|
115 |
+
$key = 'm_' . $module_id;
|
116 |
+
|
117 |
+
if ( ! isset( self::$_instances[ $key ] ) ) {
|
118 |
+
self::$_instances[ $key ] = new FS_Admin_Menu_Manager( $module_id, $module_type, $module_unique_affix );
|
119 |
+
}
|
120 |
+
|
121 |
+
return self::$_instances[ $key ];
|
122 |
+
}
|
123 |
+
|
124 |
+
protected function __construct( $module_id, $module_type, $module_unique_affix ) {
|
125 |
+
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $module_id . '_admin_menu', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
126 |
+
|
127 |
+
$this->_module_id = $module_id;
|
128 |
+
$this->_module_type = $module_type;
|
129 |
+
$this->_module_unique_affix = $module_unique_affix;
|
130 |
+
}
|
131 |
+
|
132 |
+
#endregion Singleton
|
133 |
+
|
134 |
+
#region Helpers
|
135 |
+
|
136 |
+
private function get_option( &$options, $key, $default = false ) {
|
137 |
+
return ! empty( $options[ $key ] ) ? $options[ $key ] : $default;
|
138 |
+
}
|
139 |
+
|
140 |
+
private function get_bool_option( &$options, $key, $default = false ) {
|
141 |
+
return isset( $options[ $key ] ) && is_bool( $options[ $key ] ) ? $options[ $key ] : $default;
|
142 |
+
}
|
143 |
+
|
144 |
+
#endregion Helpers
|
145 |
+
|
146 |
+
/**
|
147 |
+
* @param array $menu
|
148 |
+
* @param bool $is_addon
|
149 |
+
*/
|
150 |
+
function init( $menu, $is_addon = false ) {
|
151 |
+
$this->_menu_exists = ( isset( $menu['slug'] ) && ! empty( $menu['slug'] ) );
|
152 |
+
|
153 |
+
$this->_menu_slug = ( $this->_menu_exists ? $menu['slug'] : $this->_module_unique_affix );
|
154 |
+
|
155 |
+
$this->_default_submenu_items = array();
|
156 |
+
// @deprecated
|
157 |
+
$this->_type = 'page';
|
158 |
+
$this->_is_top_level = true;
|
159 |
+
$this->_is_override_exact = false;
|
160 |
+
$this->_parent_slug = false;
|
161 |
+
// @deprecated
|
162 |
+
$this->_parent_type = 'page';
|
163 |
+
|
164 |
+
if ( ! $is_addon && isset( $menu ) ) {
|
165 |
+
$this->_default_submenu_items = array(
|
166 |
+
'contact' => $this->get_bool_option( $menu, 'contact', true ),
|
167 |
+
'support' => $this->get_bool_option( $menu, 'support', true ),
|
168 |
+
'affiliation' => $this->get_bool_option( $menu, 'affiliation', true ),
|
169 |
+
'account' => $this->get_bool_option( $menu, 'account', true ),
|
170 |
+
'pricing' => $this->get_bool_option( $menu, 'pricing', true ),
|
171 |
+
'addons' => $this->get_bool_option( $menu, 'addons', true ),
|
172 |
+
);
|
173 |
+
|
174 |
+
// @deprecated
|
175 |
+
$this->_type = $this->get_option( $menu, 'type', 'page' );
|
176 |
+
$this->_is_override_exact = $this->get_bool_option( $menu, 'override_exact' );
|
177 |
+
|
178 |
+
if ( isset( $menu['parent'] ) ) {
|
179 |
+
$this->_parent_slug = $this->get_option( $menu['parent'], 'slug' );
|
180 |
+
// @deprecated
|
181 |
+
$this->_parent_type = $this->get_option( $menu['parent'], 'type', 'page' );
|
182 |
+
|
183 |
+
// If parent's slug is different, then it's NOT a top level menu item.
|
184 |
+
$this->_is_top_level = ( $this->_parent_slug === $this->_menu_slug );
|
185 |
+
} else {
|
186 |
+
/**
|
187 |
+
* If no parent then top level if:
|
188 |
+
* - Has custom admin menu ('page')
|
189 |
+
* - CPT menu type ('cpt')
|
190 |
+
*/
|
191 |
+
// $this->_is_top_level = in_array( $this->_type, array(
|
192 |
+
// 'cpt',
|
193 |
+
// 'page'
|
194 |
+
// ) );
|
195 |
+
}
|
196 |
+
|
197 |
+
$this->_first_time_path = $this->get_option( $menu, 'first-path', false );
|
198 |
+
if ( ! empty( $this->_first_time_path ) && is_string( $this->_first_time_path ) ) {
|
199 |
+
$this->_first_time_path = admin_url( $this->_first_time_path, 'admin' );
|
200 |
+
}
|
201 |
+
}
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Check if top level menu.
|
206 |
+
*
|
207 |
+
* @author Vova Feldman (@svovaf)
|
208 |
+
* @since 1.1.3
|
209 |
+
*
|
210 |
+
* @return bool False if submenu item.
|
211 |
+
*/
|
212 |
+
function is_top_level() {
|
213 |
+
return $this->_is_top_level;
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Check if the page should be override on exact URL match.
|
218 |
+
*
|
219 |
+
* @author Vova Feldman (@svovaf)
|
220 |
+
* @since 1.1.3
|
221 |
+
*
|
222 |
+
* @return bool False if submenu item.
|
223 |
+
*/
|
224 |
+
function is_override_exact() {
|
225 |
+
return $this->_is_override_exact;
|
226 |
+
}
|
227 |
+
|
228 |
+
|
229 |
+
/**
|
230 |
+
* Get the path of the page the user should be forwarded to after first activation.
|
231 |
+
*
|
232 |
+
* @author Vova Feldman (@svovaf)
|
233 |
+
* @since 1.1.3
|
234 |
+
*
|
235 |
+
* @return string
|
236 |
+
*/
|
237 |
+
function get_first_time_path() {
|
238 |
+
return $this->_first_time_path;
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Check if plugin's menu item is part of a custom top level menu.
|
243 |
+
*
|
244 |
+
* @author Vova Feldman (@svovaf)
|
245 |
+
* @since 1.1.3
|
246 |
+
*
|
247 |
+
* @return bool
|
248 |
+
*/
|
249 |
+
function has_custom_parent() {
|
250 |
+
return ! $this->_is_top_level && is_string( $this->_parent_slug );
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* @author Leo Fajardo (@leorw)
|
255 |
+
* @since 1.2.2
|
256 |
+
*
|
257 |
+
* @return bool
|
258 |
+
*/
|
259 |
+
function has_menu() {
|
260 |
+
return $this->_menu_exists;
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* @author Vova Feldman (@svovaf)
|
265 |
+
* @since 1.1.3
|
266 |
+
*
|
267 |
+
* @param string $id
|
268 |
+
* @param bool $default
|
269 |
+
* @param bool $ignore_menu_existence Since 1.2.2.7 If true, check if the submenu item visible even if there's no parent menu.
|
270 |
+
*
|
271 |
+
* @return bool
|
272 |
+
*/
|
273 |
+
function is_submenu_item_visible( $id, $default = true, $ignore_menu_existence = false ) {
|
274 |
+
if ( ! $ignore_menu_existence && ! $this->has_menu() ) {
|
275 |
+
return false;
|
276 |
+
}
|
277 |
+
|
278 |
+
return fs_apply_filter(
|
279 |
+
$this->_module_unique_affix,
|
280 |
+
'is_submenu_visible',
|
281 |
+
$this->get_bool_option( $this->_default_submenu_items, $id, $default ),
|
282 |
+
$id
|
283 |
+
);
|
284 |
+
}
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Calculates admin settings menu slug.
|
288 |
+
* If plugin's menu slug is a file (e.g. CPT), uses plugin's slug as the menu slug.
|
289 |
+
*
|
290 |
+
* @author Vova Feldman (@svovaf)
|
291 |
+
* @since 1.1.3
|
292 |
+
*
|
293 |
+
* @param string $page
|
294 |
+
*
|
295 |
+
* @return string
|
296 |
+
*/
|
297 |
+
function get_slug( $page = '' ) {
|
298 |
+
return ( ( false === strpos( $this->_menu_slug, '.php?' ) ) ?
|
299 |
+
$this->_menu_slug :
|
300 |
+
$this->_module_unique_affix ) . ( empty( $page ) ? '' : ( '-' . $page ) );
|
301 |
+
}
|
302 |
+
|
303 |
+
/**
|
304 |
+
* @author Vova Feldman (@svovaf)
|
305 |
+
* @since 1.1.3
|
306 |
+
*
|
307 |
+
* @return string
|
308 |
+
*/
|
309 |
+
function get_parent_slug() {
|
310 |
+
return $this->_parent_slug;
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* @author Vova Feldman (@svovaf)
|
315 |
+
* @since 1.1.3
|
316 |
+
*
|
317 |
+
* @return string
|
318 |
+
*/
|
319 |
+
function get_type() {
|
320 |
+
return $this->_type;
|
321 |
+
}
|
322 |
+
|
323 |
+
/**
|
324 |
+
* @author Vova Feldman (@svovaf)
|
325 |
+
* @since 1.1.3
|
326 |
+
*
|
327 |
+
* @return bool
|
328 |
+
*/
|
329 |
+
function is_cpt() {
|
330 |
+
return ( 0 === strpos( $this->_menu_slug, 'edit.php?post_type=' ) ||
|
331 |
+
// Back compatibility.
|
332 |
+
'cpt' === $this->_type
|
333 |
+
);
|
334 |
+
}
|
335 |
+
|
336 |
+
/**
|
337 |
+
* @author Vova Feldman (@svovaf)
|
338 |
+
* @since 1.1.3
|
339 |
+
*
|
340 |
+
* @return string
|
341 |
+
*/
|
342 |
+
function get_parent_type() {
|
343 |
+
return $this->_parent_type;
|
344 |
+
}
|
345 |
+
|
346 |
+
/**
|
347 |
+
* @author Vova Feldman (@svovaf)
|
348 |
+
* @since 1.1.3
|
349 |
+
*
|
350 |
+
* @return string
|
351 |
+
*/
|
352 |
+
function get_raw_slug() {
|
353 |
+
return $this->_menu_slug;
|
354 |
+
}
|
355 |
+
|
356 |
+
/**
|
357 |
+
* Get plugin's original menu slug.
|
358 |
+
*
|
359 |
+
* @author Vova Feldman (@svovaf)
|
360 |
+
* @since 1.1.3
|
361 |
+
*
|
362 |
+
* @return string
|
363 |
+
*/
|
364 |
+
function get_original_menu_slug() {
|
365 |
+
if ( 'cpt' === $this->_type ) {
|
366 |
+
return add_query_arg( array(
|
367 |
+
'post_type' => $this->_menu_slug
|
368 |
+
), 'edit.php' );
|
369 |
+
}
|
370 |
+
|
371 |
+
if ( false === strpos( $this->_menu_slug, '.php?' ) ) {
|
372 |
+
return $this->_menu_slug;
|
373 |
+
} else {
|
374 |
+
return $this->_module_unique_affix;
|
375 |
+
}
|
376 |
+
}
|
377 |
+
|
378 |
+
/**
|
379 |
+
* @author Vova Feldman (@svovaf)
|
380 |
+
* @since 1.1.3
|
381 |
+
*
|
382 |
+
* @return string
|
383 |
+
*/
|
384 |
+
function get_top_level_menu_slug() {
|
385 |
+
return $this->has_custom_parent() ?
|
386 |
+
$this->get_parent_slug() :
|
387 |
+
$this->get_raw_slug();
|
388 |
+
}
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Is user on plugin's admin activation page.
|
392 |
+
*
|
393 |
+
* @author Vova Feldman (@svovaf)
|
394 |
+
* @since 1.0.8
|
395 |
+
*
|
396 |
+
* @return bool
|
397 |
+
*/
|
398 |
+
function is_main_settings_page() {
|
399 |
+
if ( $this->_menu_exists &&
|
400 |
+
( fs_is_plugin_page( $this->_menu_slug ) || fs_is_plugin_page( $this->_module_unique_affix ) )
|
401 |
+
) {
|
402 |
+
/**
|
403 |
+
* Module has a settings menu and the context page is the main settings page, so assume it's in
|
404 |
+
* activation (doesn't really check if already opted-in/skipped or not).
|
405 |
+
*
|
406 |
+
* @since 1.2.2
|
407 |
+
*/
|
408 |
+
return true;
|
409 |
+
}
|
410 |
+
|
411 |
+
global $pagenow;
|
412 |
+
if ( ( WP_FS__MODULE_TYPE_THEME === $this->_module_type ) && Freemius::is_themes_page() ) {
|
413 |
+
/**
|
414 |
+
* In activation only when show_optin query string param is given.
|
415 |
+
*
|
416 |
+
* @since 1.2.2
|
417 |
+
*/
|
418 |
+
return fs_request_get_bool( $this->_module_unique_affix . '_show_optin' );
|
419 |
+
}
|
420 |
+
|
421 |
+
return false;
|
422 |
+
}
|
423 |
+
|
424 |
+
#region Submenu Override
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Override submenu's action.
|
428 |
+
*
|
429 |
+
* @author Vova Feldman (@svovaf)
|
430 |
+
* @since 1.1.0
|
431 |
+
*
|
432 |
+
* @param string $parent_slug
|
433 |
+
* @param string $menu_slug
|
434 |
+
* @param callable $function
|
435 |
+
*
|
436 |
+
* @return false|string If submenu exist, will return the hook name.
|
437 |
+
*/
|
438 |
+
function override_submenu_action( $parent_slug, $menu_slug, $function ) {
|
439 |
+
global $submenu;
|
440 |
+
|
441 |
+
$menu_slug = plugin_basename( $menu_slug );
|
442 |
+
$parent_slug = plugin_basename( $parent_slug );
|
443 |
+
|
444 |
+
if ( ! isset( $submenu[ $parent_slug ] ) ) {
|
445 |
+
// Parent menu not exist.
|
446 |
+
return false;
|
447 |
+
}
|
448 |
+
|
449 |
+
$found_submenu_item = false;
|
450 |
+
foreach ( $submenu[ $parent_slug ] as $submenu_item ) {
|
451 |
+
if ( $menu_slug === $submenu_item[2] ) {
|
452 |
+
$found_submenu_item = $submenu_item;
|
453 |
+
break;
|
454 |
+
}
|
455 |
+
}
|
456 |
+
|
457 |
+
if ( false === $found_submenu_item ) {
|
458 |
+
// Submenu item not found.
|
459 |
+
return false;
|
460 |
+
}
|
461 |
+
|
462 |
+
// Remove current function.
|
463 |
+
$hookname = get_plugin_page_hookname( $menu_slug, $parent_slug );
|
464 |
+
remove_all_actions( $hookname );
|
465 |
+
|
466 |
+
// Attach new action.
|
467 |
+
add_action( $hookname, $function );
|
468 |
+
|
469 |
+
return $hookname;
|
470 |
+
}
|
471 |
+
|
472 |
+
#endregion Submenu Override
|
473 |
+
|
474 |
+
#region Top level menu Override
|
475 |
+
|
476 |
+
/**
|
477 |
+
* Find plugin's admin dashboard main menu item.
|
478 |
+
*
|
479 |
+
* @author Vova Feldman (@svovaf)
|
480 |
+
* @since 1.0.2
|
481 |
+
*
|
482 |
+
* @return string[]|false
|
483 |
+
*/
|
484 |
+
private function find_top_level_menu() {
|
485 |
+
global $menu;
|
486 |
+
|
487 |
+
$position = - 1;
|
488 |
+
$found_menu = false;
|
489 |
+
|
490 |
+
$menu_slug = $this->get_raw_slug();
|
491 |
+
|
492 |
+
$hook_name = get_plugin_page_hookname( $menu_slug, '' );
|
493 |
+
foreach ( $menu as $pos => $m ) {
|
494 |
+
if ( $menu_slug === $m[2] ) {
|
495 |
+
$position = $pos;
|
496 |
+
$found_menu = $m;
|
497 |
+
break;
|
498 |
+
}
|
499 |
+
}
|
500 |
+
|
501 |
+
if ( false === $found_menu ) {
|
502 |
+
return false;
|
503 |
+
}
|
504 |
+
|
505 |
+
return array(
|
506 |
+
'menu' => $found_menu,
|
507 |
+
'position' => $position,
|
508 |
+
'hook_name' => $hook_name
|
509 |
+
);
|
510 |
+
}
|
511 |
+
|
512 |
+
/**
|
513 |
+
* Find plugin's admin dashboard main submenu item.
|
514 |
+
*
|
515 |
+
* @author Vova Feldman (@svovaf)
|
516 |
+
* @since 1.2.1.6
|
517 |
+
*
|
518 |
+
* @return array|false
|
519 |
+
*/
|
520 |
+
private function find_main_submenu() {
|
521 |
+
global $submenu;
|
522 |
+
|
523 |
+
$top_level_menu_slug = $this->get_top_level_menu_slug();
|
524 |
+
|
525 |
+
if ( ! isset( $submenu[ $top_level_menu_slug ] ) ) {
|
526 |
+
return false;
|
527 |
+
}
|
528 |
+
|
529 |
+
$submenu_slug = $this->get_raw_slug();
|
530 |
+
|
531 |
+
$position = - 1;
|
532 |
+
$found_submenu = false;
|
533 |
+
|
534 |
+
$hook_name = get_plugin_page_hookname( $submenu_slug, '' );
|
535 |
+
|
536 |
+
foreach ( $submenu[ $top_level_menu_slug ] as $pos => $sub ) {
|
537 |
+
if ( $submenu_slug === $sub[2] ) {
|
538 |
+
$position = $pos;
|
539 |
+
$found_submenu = $sub;
|
540 |
+
}
|
541 |
+
}
|
542 |
+
|
543 |
+
if ( false === $found_submenu ) {
|
544 |
+
return false;
|
545 |
+
}
|
546 |
+
|
547 |
+
return array(
|
548 |
+
'menu' => $found_submenu,
|
549 |
+
'parent_slug' => $top_level_menu_slug,
|
550 |
+
'position' => $position,
|
551 |
+
'hook_name' => $hook_name
|
552 |
+
);
|
553 |
+
}
|
554 |
+
|
555 |
+
/**
|
556 |
+
* Remove all sub-menu items.
|
557 |
+
*
|
558 |
+
* @author Vova Feldman (@svovaf)
|
559 |
+
* @since 1.0.7
|
560 |
+
*
|
561 |
+
* @return bool If submenu with plugin's menu slug was found.
|
562 |
+
*/
|
563 |
+
private function remove_all_submenu_items() {
|
564 |
+
global $submenu;
|
565 |
+
|
566 |
+
$menu_slug = $this->get_raw_slug();
|
567 |
+
|
568 |
+
if ( ! isset( $submenu[ $menu_slug ] ) ) {
|
569 |
+
return false;
|
570 |
+
}
|
571 |
+
|
572 |
+
/**
|
573 |
+
* This method is NOT executed for WordPress.org themes.
|
574 |
+
* Since we maintain only one version of the SDK we added this small
|
575 |
+
* hack to avoid the error from Theme Check since it's a false-positive.
|
576 |
+
*
|
577 |
+
* @author Vova Feldman (@svovaf)
|
578 |
+
* @since 1.2.2.7
|
579 |
+
*/
|
580 |
+
$submenu_ref = &$submenu;
|
581 |
+
$submenu_ref[ $menu_slug ] = array();
|
582 |
+
|
583 |
+
return true;
|
584 |
+
}
|
585 |
+
|
586 |
+
/**
|
587 |
+
*
|
588 |
+
* @author Vova Feldman (@svovaf)
|
589 |
+
* @since 1.0.9
|
590 |
+
*
|
591 |
+
* @return false|array[string]mixed
|
592 |
+
*/
|
593 |
+
function remove_menu_item() {
|
594 |
+
$this->_logger->entrance();
|
595 |
+
|
596 |
+
// Find main menu item.
|
597 |
+
$menu = $this->find_top_level_menu();
|
598 |
+
|
599 |
+
if ( false === $menu ) {
|
600 |
+
return false;
|
601 |
+
}
|
602 |
+
|
603 |
+
// Remove it with its actions.
|
604 |
+
remove_all_actions( $menu['hook_name'] );
|
605 |
+
|
606 |
+
// Remove all submenu items.
|
607 |
+
$this->remove_all_submenu_items();
|
608 |
+
|
609 |
+
return $menu;
|
610 |
+
}
|
611 |
+
|
612 |
+
/**
|
613 |
+
* Get module's main admin setting page URL.
|
614 |
+
*
|
615 |
+
* @todo This method was only tested for wp.org compliant themes with a submenu item. Need to test for plugins with top level, submenu, and CPT top level, menu items.
|
616 |
+
*
|
617 |
+
* @author Vova Feldman (@svovaf)
|
618 |
+
* @since 1.2.2.7
|
619 |
+
*
|
620 |
+
* @return string
|
621 |
+
*/
|
622 |
+
function main_menu_url() {
|
623 |
+
$this->_logger->entrance();
|
624 |
+
|
625 |
+
if ( $this->_is_top_level ) {
|
626 |
+
$menu = $this->find_top_level_menu();
|
627 |
+
} else {
|
628 |
+
$menu = $this->find_main_submenu();
|
629 |
+
}
|
630 |
+
|
631 |
+
$parent_slug = isset( $menu['parent_slug'] ) ?
|
632 |
+
$menu['parent_slug'] :
|
633 |
+
'admin.php';
|
634 |
+
|
635 |
+
return admin_url( $parent_slug . '?page=' . $menu['menu'][2] );
|
636 |
+
}
|
637 |
+
|
638 |
+
/**
|
639 |
+
* @author Vova Feldman (@svovaf)
|
640 |
+
* @since 1.1.4
|
641 |
+
*
|
642 |
+
* @param callable $function
|
643 |
+
*
|
644 |
+
* @return false|array[string]mixed
|
645 |
+
*/
|
646 |
+
function override_menu_item( $function ) {
|
647 |
+
$found_menu = $this->remove_menu_item();
|
648 |
+
|
649 |
+
if ( false === $found_menu ) {
|
650 |
+
return false;
|
651 |
+
}
|
652 |
+
|
653 |
+
if ( ! $this->is_top_level() || ! $this->is_cpt() ) {
|
654 |
+
$menu_slug = plugin_basename( $this->get_slug() );
|
655 |
+
|
656 |
+
$hookname = get_plugin_page_hookname( $menu_slug, '' );
|
657 |
+
|
658 |
+
// Override menu action.
|
659 |
+
add_action( $hookname, $function );
|
660 |
+
} else {
|
661 |
+
global $menu;
|
662 |
+
|
663 |
+
// Remove original CPT menu.
|
664 |
+
unset( $menu[ $found_menu['position'] ] );
|
665 |
+
|
666 |
+
// Create new top-level menu action.
|
667 |
+
$hookname = self::add_page(
|
668 |
+
$found_menu['menu'][3],
|
669 |
+
$found_menu['menu'][0],
|
670 |
+
'manage_options',
|
671 |
+
$this->get_slug(),
|
672 |
+
$function,
|
673 |
+
$found_menu['menu'][6],
|
674 |
+
$found_menu['position']
|
675 |
+
);
|
676 |
+
}
|
677 |
+
|
678 |
+
return $hookname;
|
679 |
+
}
|
680 |
+
|
681 |
+
/**
|
682 |
+
* Adds a counter to the module's top level menu item.
|
683 |
+
*
|
684 |
+
* @author Vova Feldman (@svovaf)
|
685 |
+
* @since 1.2.1.5
|
686 |
+
*
|
687 |
+
* @param int $counter
|
688 |
+
* @param string $class
|
689 |
+
*/
|
690 |
+
function add_counter_to_menu_item( $counter = 1, $class = '' ) {
|
691 |
+
global $menu, $submenu;
|
692 |
+
|
693 |
+
$mask = '%s <span class="update-plugins %s count-%3$s" aria-hidden="true"><span>%3$s<span class="screen-reader-text">%3$s notifications</span></span></span>';
|
694 |
+
|
695 |
+
/**
|
696 |
+
* This method is NOT executed for WordPress.org themes.
|
697 |
+
* Since we maintain only one version of the SDK we added this small
|
698 |
+
* hack to avoid the error from Theme Check since it's a false-positive.
|
699 |
+
*
|
700 |
+
* @author Vova Feldman (@svovaf)
|
701 |
+
* @since 1.2.2.7
|
702 |
+
*/
|
703 |
+
$menu_ref = &$menu;
|
704 |
+
$submenu_ref = &$submenu;
|
705 |
+
|
706 |
+
if ( $this->_is_top_level ) {
|
707 |
+
// Find main menu item.
|
708 |
+
$found_menu = $this->find_top_level_menu();
|
709 |
+
|
710 |
+
if ( false !== $found_menu ) {
|
711 |
+
// Override menu label.
|
712 |
+
$menu_ref[ $found_menu['position'] ][0] = sprintf(
|
713 |
+
$mask,
|
714 |
+
$found_menu['menu'][0],
|
715 |
+
$class,
|
716 |
+
$counter
|
717 |
+
);
|
718 |
+
}
|
719 |
+
} else {
|
720 |
+
$found_submenu = $this->find_main_submenu();
|
721 |
+
|
722 |
+
if ( false !== $found_submenu ) {
|
723 |
+
// Override menu label.
|
724 |
+
$submenu_ref[ $found_submenu['parent_slug'] ][ $found_submenu['position'] ][0] = sprintf(
|
725 |
+
$mask,
|
726 |
+
$found_submenu['menu'][0],
|
727 |
+
$class,
|
728 |
+
$counter
|
729 |
+
);
|
730 |
+
}
|
731 |
+
}
|
732 |
+
}
|
733 |
+
|
734 |
+
#endregion Top level menu Override
|
735 |
+
|
736 |
+
/**
|
737 |
+
* Add a top-level menu page.
|
738 |
+
*
|
739 |
+
* Note for WordPress.org Theme/Plugin reviewer:
|
740 |
+
*
|
741 |
+
* This is a replication of `add_menu_page()` to avoid Theme Check warning.
|
742 |
+
*
|
743 |
+
* Why?
|
744 |
+
* ====
|
745 |
+
* Freemius is an SDK for plugin and theme developers. Since the core
|
746 |
+
* of the SDK is relevant both for plugins and themes, for obvious reasons,
|
747 |
+
* we only develop and maintain one code base.
|
748 |
+
*
|
749 |
+
* This method will not run for wp.org themes (only plugins) since theme
|
750 |
+
* admin settings/options are now only allowed in the customizer.
|
751 |
+
*
|
752 |
+
* If you have any questions or need clarifications, please don't hesitate
|
753 |
+
* pinging me on slack, my username is @svovaf.
|
754 |
+
*
|
755 |
+
* @author Vova Feldman (@svovaf)
|
756 |
+
* @since 1.2.2
|
757 |
+
*
|
758 |
+
* @param string $page_title The text to be displayed in the title tags of the page when the menu is
|
759 |
+
* selected.
|
760 |
+
* @param string $menu_title The text to be used for the menu.
|
761 |
+
* @param string $capability The capability required for this menu to be displayed to the user.
|
762 |
+
* @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu).
|
763 |
+
* @param callable|string $function The function to be called to output the content for this page.
|
764 |
+
* @param string $icon_url The URL to the icon to be used for this menu.
|
765 |
+
* * Pass a base64-encoded SVG using a data URI, which will be colored to
|
766 |
+
* match the color scheme. This should begin with
|
767 |
+
* 'data:image/svg+xml;base64,'.
|
768 |
+
* * Pass the name of a Dashicons helper class to use a font icon,
|
769 |
+
* e.g. 'dashicons-chart-pie'.
|
770 |
+
* * Pass 'none' to leave div.wp-menu-image empty so an icon can be added
|
771 |
+
* via CSS.
|
772 |
+
* @param int $position The position in the menu order this one should appear.
|
773 |
+
*
|
774 |
+
* @return string The resulting page's hook_suffix.
|
775 |
+
*/
|
776 |
+
static function add_page(
|
777 |
+
$page_title,
|
778 |
+
$menu_title,
|
779 |
+
$capability,
|
780 |
+
$menu_slug,
|
781 |
+
$function = '',
|
782 |
+
$icon_url = '',
|
783 |
+
$position = null
|
784 |
+
) {
|
785 |
+
$fn = 'add_menu' . '_page';
|
786 |
+
|
787 |
+
return $fn(
|
788 |
+
$page_title,
|
789 |
+
$menu_title,
|
790 |
+
$capability,
|
791 |
+
$menu_slug,
|
792 |
+
$function,
|
793 |
+
$icon_url,
|
794 |
+
$position
|
795 |
+
);
|
796 |
+
}
|
797 |
+
|
798 |
+
/**
|
799 |
+
* Add a submenu page.
|
800 |
+
*
|
801 |
+
* Note for WordPress.org Theme/Plugin reviewer:
|
802 |
+
*
|
803 |
+
* This is a replication of `add_submenu_page()` to avoid Theme Check warning.
|
804 |
+
*
|
805 |
+
* Why?
|
806 |
+
* ====
|
807 |
+
* Freemius is an SDK for plugin and theme developers. Since the core
|
808 |
+
* of the SDK is relevant both for plugins and themes, for obvious reasons,
|
809 |
+
* we only develop and maintain one code base.
|
810 |
+
*
|
811 |
+
* This method will not run for wp.org themes (only plugins) since theme
|
812 |
+
* admin settings/options are now only allowed in the customizer.
|
813 |
+
*
|
814 |
+
* If you have any questions or need clarifications, please don't hesitate
|
815 |
+
* pinging me on slack, my username is @svovaf.
|
816 |
+
*
|
817 |
+
* @author Vova Feldman (@svovaf)
|
818 |
+
* @since 1.2.2
|
819 |
+
*
|
820 |
+
* @param string $parent_slug The slug name for the parent menu (or the file name of a standard
|
821 |
+
* WordPress admin page).
|
822 |
+
* @param string $page_title The text to be displayed in the title tags of the page when the menu is
|
823 |
+
* selected.
|
824 |
+
* @param string $menu_title The text to be used for the menu.
|
825 |
+
* @param string $capability The capability required for this menu to be displayed to the user.
|
826 |
+
* @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu).
|
827 |
+
* @param callable|string $function The function to be called to output the content for this page.
|
828 |
+
*
|
829 |
+
* @return false|string The resulting page's hook_suffix, or false if the user does not have the capability
|
830 |
+
* required.
|
831 |
+
*/
|
832 |
+
static function add_subpage(
|
833 |
+
$parent_slug,
|
834 |
+
$page_title,
|
835 |
+
$menu_title,
|
836 |
+
$capability,
|
837 |
+
$menu_slug,
|
838 |
+
$function = ''
|
839 |
+
) {
|
840 |
+
$fn = 'add_submenu' . '_page';
|
841 |
+
|
842 |
+
return $fn( $parent_slug,
|
843 |
+
$page_title,
|
844 |
+
$menu_title,
|
845 |
+
$capability,
|
846 |
+
$menu_slug,
|
847 |
+
$function
|
848 |
+
);
|
849 |
+
}
|
850 |
}
|
freemius/includes/managers/class-fs-cache-manager.php
CHANGED
@@ -1,281 +1,281 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.1.6
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
class FS_Cache_Manager {
|
14 |
-
/**
|
15 |
-
* @var FS_Option_Manager
|
16 |
-
*/
|
17 |
-
private $_options;
|
18 |
-
/**
|
19 |
-
* @var FS_Logger
|
20 |
-
*/
|
21 |
-
private $_logger;
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @var FS_Cache_Manager[]
|
25 |
-
*/
|
26 |
-
private static $_MANAGERS = array();
|
27 |
-
|
28 |
-
/**
|
29 |
-
* @author Vova Feldman (@svovaf)
|
30 |
-
* @since 1.1.3
|
31 |
-
*
|
32 |
-
* @param string $id
|
33 |
-
*/
|
34 |
-
private function __construct( $id ) {
|
35 |
-
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_cach_mngr_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
36 |
-
|
37 |
-
$this->_logger->entrance();
|
38 |
-
$this->_logger->log( 'id = ' . $id );
|
39 |
-
|
40 |
-
$this->_options = FS_Option_Manager::get_manager( $id, true );
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* @author Vova Feldman (@svovaf)
|
45 |
-
* @since 1.1.6
|
46 |
-
*
|
47 |
-
* @param $id
|
48 |
-
*
|
49 |
-
* @return FS_Cache_Manager
|
50 |
-
*/
|
51 |
-
static function get_manager( $id ) {
|
52 |
-
$id = strtolower( $id );
|
53 |
-
|
54 |
-
if ( ! isset( self::$_MANAGERS[ $id ] ) ) {
|
55 |
-
self::$_MANAGERS[ $id ] = new FS_Cache_Manager( $id );
|
56 |
-
}
|
57 |
-
|
58 |
-
return self::$_MANAGERS[ $id ];
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* @author Vova Feldman (@svovaf)
|
63 |
-
* @since 1.1.6
|
64 |
-
*
|
65 |
-
* @return bool
|
66 |
-
*/
|
67 |
-
function is_empty() {
|
68 |
-
$this->_logger->entrance();
|
69 |
-
|
70 |
-
return $this->_options->is_empty();
|
71 |
-
}
|
72 |
-
|
73 |
-
/**
|
74 |
-
* @author Vova Feldman (@svovaf)
|
75 |
-
* @since 1.1.6
|
76 |
-
*/
|
77 |
-
function clear() {
|
78 |
-
$this->_logger->entrance();
|
79 |
-
|
80 |
-
$this->_options->clear( true );
|
81 |
-
}
|
82 |
-
|
83 |
-
/**
|
84 |
-
* Delete cache manager from DB.
|
85 |
-
*
|
86 |
-
* @author Vova Feldman (@svovaf)
|
87 |
-
* @since 1.0.9
|
88 |
-
*/
|
89 |
-
function delete() {
|
90 |
-
$this->_options->delete();
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* Check if there's a cached item.
|
95 |
-
*
|
96 |
-
* @author Vova Feldman (@svovaf)
|
97 |
-
* @since 1.1.6
|
98 |
-
*
|
99 |
-
* @param string $key
|
100 |
-
*
|
101 |
-
* @return bool
|
102 |
-
*/
|
103 |
-
function has( $key ) {
|
104 |
-
$cache_entry = $this->_options->get_option( $key, false );
|
105 |
-
|
106 |
-
return ( is_object( $cache_entry ) &&
|
107 |
-
isset( $cache_entry->timestamp ) &&
|
108 |
-
is_numeric( $cache_entry->timestamp )
|
109 |
-
);
|
110 |
-
}
|
111 |
-
|
112 |
-
/**
|
113 |
-
* Check if there's a valid cached item.
|
114 |
-
*
|
115 |
-
* @author Vova Feldman (@svovaf)
|
116 |
-
* @since 1.1.6
|
117 |
-
*
|
118 |
-
* @param string $key
|
119 |
-
* @param null|int $expiration Since 1.2.2.7
|
120 |
-
*
|
121 |
-
* @return bool
|
122 |
-
*/
|
123 |
-
function has_valid( $key, $expiration = null ) {
|
124 |
-
$cache_entry = $this->_options->get_option( $key, false );
|
125 |
-
|
126 |
-
$is_valid = ( is_object( $cache_entry ) &&
|
127 |
-
isset( $cache_entry->timestamp ) &&
|
128 |
-
is_numeric( $cache_entry->timestamp ) &&
|
129 |
-
$cache_entry->timestamp > WP_FS__SCRIPT_START_TIME
|
130 |
-
);
|
131 |
-
|
132 |
-
if ( $is_valid &&
|
133 |
-
is_numeric( $expiration ) &&
|
134 |
-
isset( $cache_entry->created ) &&
|
135 |
-
is_numeric( $cache_entry->created ) &&
|
136 |
-
$cache_entry->created + $expiration < WP_FS__SCRIPT_START_TIME
|
137 |
-
) {
|
138 |
-
/**
|
139 |
-
* Even if the cache is still valid, since we are checking for validity
|
140 |
-
* with an explicit expiration period, if the period has past, return
|
141 |
-
* `false` as if the cache is invalid.
|
142 |
-
*
|
143 |
-
* @since 1.2.2.7
|
144 |
-
*/
|
145 |
-
$is_valid = false;
|
146 |
-
}
|
147 |
-
|
148 |
-
return $is_valid;
|
149 |
-
}
|
150 |
-
|
151 |
-
/**
|
152 |
-
* @author Vova Feldman (@svovaf)
|
153 |
-
* @since 1.1.6
|
154 |
-
*
|
155 |
-
* @param string $key
|
156 |
-
* @param mixed $default
|
157 |
-
*
|
158 |
-
* @return mixed
|
159 |
-
*/
|
160 |
-
function get( $key, $default = null ) {
|
161 |
-
$this->_logger->entrance( 'key = ' . $key );
|
162 |
-
|
163 |
-
$cache_entry = $this->_options->get_option( $key, false );
|
164 |
-
|
165 |
-
if ( is_object( $cache_entry ) &&
|
166 |
-
isset( $cache_entry->timestamp ) &&
|
167 |
-
is_numeric( $cache_entry->timestamp )
|
168 |
-
) {
|
169 |
-
return $cache_entry->result;
|
170 |
-
}
|
171 |
-
|
172 |
-
return is_object($default) ? clone $default : $default;
|
173 |
-
}
|
174 |
-
|
175 |
-
/**
|
176 |
-
* @author Vova Feldman (@svovaf)
|
177 |
-
* @since 1.1.6
|
178 |
-
*
|
179 |
-
* @param string $key
|
180 |
-
* @param mixed $default
|
181 |
-
*
|
182 |
-
* @return mixed
|
183 |
-
*/
|
184 |
-
function get_valid( $key, $default = null ) {
|
185 |
-
$this->_logger->entrance( 'key = ' . $key );
|
186 |
-
|
187 |
-
$cache_entry = $this->_options->get_option( $key, false );
|
188 |
-
|
189 |
-
if ( is_object( $cache_entry ) &&
|
190 |
-
isset( $cache_entry->timestamp ) &&
|
191 |
-
is_numeric( $cache_entry->timestamp ) &&
|
192 |
-
$cache_entry->timestamp > WP_FS__SCRIPT_START_TIME
|
193 |
-
) {
|
194 |
-
return $cache_entry->result;
|
195 |
-
}
|
196 |
-
|
197 |
-
return is_object($default) ? clone $default : $default;
|
198 |
-
}
|
199 |
-
|
200 |
-
/**
|
201 |
-
* @author Vova Feldman (@svovaf)
|
202 |
-
* @since 1.1.6
|
203 |
-
*
|
204 |
-
* @param string $key
|
205 |
-
* @param mixed $value
|
206 |
-
* @param int $expiration
|
207 |
-
*/
|
208 |
-
function set( $key, $value, $expiration = WP_FS__TIME_24_HOURS_IN_SEC ) {
|
209 |
-
$this->_logger->entrance( 'key = ' . $key );
|
210 |
-
|
211 |
-
$cache_entry = new stdClass();
|
212 |
-
|
213 |
-
$cache_entry->result = $value;
|
214 |
-
$cache_entry->created = WP_FS__SCRIPT_START_TIME;
|
215 |
-
$cache_entry->timestamp = WP_FS__SCRIPT_START_TIME + $expiration;
|
216 |
-
$this->_options->set_option( $key, $cache_entry, true );
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* Get cached record expiration, or false if not cached or expired.
|
221 |
-
*
|
222 |
-
* @author Vova Feldman (@svovaf)
|
223 |
-
* @since 1.1.7.3
|
224 |
-
*
|
225 |
-
* @param string $key
|
226 |
-
*
|
227 |
-
* @return bool|int
|
228 |
-
*/
|
229 |
-
function get_record_expiration( $key ) {
|
230 |
-
$this->_logger->entrance( 'key = ' . $key );
|
231 |
-
|
232 |
-
$cache_entry = $this->_options->get_option( $key, false );
|
233 |
-
|
234 |
-
if ( is_object( $cache_entry ) &&
|
235 |
-
isset( $cache_entry->timestamp ) &&
|
236 |
-
is_numeric( $cache_entry->timestamp ) &&
|
237 |
-
$cache_entry->timestamp > WP_FS__SCRIPT_START_TIME
|
238 |
-
) {
|
239 |
-
return $cache_entry->timestamp;
|
240 |
-
}
|
241 |
-
|
242 |
-
return false;
|
243 |
-
}
|
244 |
-
|
245 |
-
/**
|
246 |
-
* Purge cached item.
|
247 |
-
*
|
248 |
-
* @author Vova Feldman (@svovaf)
|
249 |
-
* @since 1.1.6
|
250 |
-
*
|
251 |
-
* @param string $key
|
252 |
-
*/
|
253 |
-
function purge( $key ) {
|
254 |
-
$this->_logger->entrance( 'key = ' . $key );
|
255 |
-
|
256 |
-
$this->_options->unset_option( $key, true );
|
257 |
-
}
|
258 |
-
|
259 |
-
/**
|
260 |
-
* Set cached item as expired.
|
261 |
-
*
|
262 |
-
* @author Vova Feldman (@svovaf)
|
263 |
-
* @since 1.2.2.7
|
264 |
-
*
|
265 |
-
* @param string $key
|
266 |
-
*/
|
267 |
-
function expire( $key ) {
|
268 |
-
$this->_logger->entrance( 'key = ' . $key );
|
269 |
-
|
270 |
-
$cache_entry = $this->_options->get_option( $key, false );
|
271 |
-
|
272 |
-
if ( is_object( $cache_entry ) &&
|
273 |
-
isset( $cache_entry->timestamp ) &&
|
274 |
-
is_numeric( $cache_entry->timestamp ))
|
275 |
-
{
|
276 |
-
// Set to expired.
|
277 |
-
$cache_entry->timestamp = WP_FS__SCRIPT_START_TIME;
|
278 |
-
$this->_options->set_option( $key, $cache_entry, true );
|
279 |
-
}
|
280 |
-
}
|
281 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.1.6
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
class FS_Cache_Manager {
|
14 |
+
/**
|
15 |
+
* @var FS_Option_Manager
|
16 |
+
*/
|
17 |
+
private $_options;
|
18 |
+
/**
|
19 |
+
* @var FS_Logger
|
20 |
+
*/
|
21 |
+
private $_logger;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @var FS_Cache_Manager[]
|
25 |
+
*/
|
26 |
+
private static $_MANAGERS = array();
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @author Vova Feldman (@svovaf)
|
30 |
+
* @since 1.1.3
|
31 |
+
*
|
32 |
+
* @param string $id
|
33 |
+
*/
|
34 |
+
private function __construct( $id ) {
|
35 |
+
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_cach_mngr_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
36 |
+
|
37 |
+
$this->_logger->entrance();
|
38 |
+
$this->_logger->log( 'id = ' . $id );
|
39 |
+
|
40 |
+
$this->_options = FS_Option_Manager::get_manager( $id, true );
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @author Vova Feldman (@svovaf)
|
45 |
+
* @since 1.1.6
|
46 |
+
*
|
47 |
+
* @param $id
|
48 |
+
*
|
49 |
+
* @return FS_Cache_Manager
|
50 |
+
*/
|
51 |
+
static function get_manager( $id ) {
|
52 |
+
$id = strtolower( $id );
|
53 |
+
|
54 |
+
if ( ! isset( self::$_MANAGERS[ $id ] ) ) {
|
55 |
+
self::$_MANAGERS[ $id ] = new FS_Cache_Manager( $id );
|
56 |
+
}
|
57 |
+
|
58 |
+
return self::$_MANAGERS[ $id ];
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @author Vova Feldman (@svovaf)
|
63 |
+
* @since 1.1.6
|
64 |
+
*
|
65 |
+
* @return bool
|
66 |
+
*/
|
67 |
+
function is_empty() {
|
68 |
+
$this->_logger->entrance();
|
69 |
+
|
70 |
+
return $this->_options->is_empty();
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @author Vova Feldman (@svovaf)
|
75 |
+
* @since 1.1.6
|
76 |
+
*/
|
77 |
+
function clear() {
|
78 |
+
$this->_logger->entrance();
|
79 |
+
|
80 |
+
$this->_options->clear( true );
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Delete cache manager from DB.
|
85 |
+
*
|
86 |
+
* @author Vova Feldman (@svovaf)
|
87 |
+
* @since 1.0.9
|
88 |
+
*/
|
89 |
+
function delete() {
|
90 |
+
$this->_options->delete();
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Check if there's a cached item.
|
95 |
+
*
|
96 |
+
* @author Vova Feldman (@svovaf)
|
97 |
+
* @since 1.1.6
|
98 |
+
*
|
99 |
+
* @param string $key
|
100 |
+
*
|
101 |
+
* @return bool
|
102 |
+
*/
|
103 |
+
function has( $key ) {
|
104 |
+
$cache_entry = $this->_options->get_option( $key, false );
|
105 |
+
|
106 |
+
return ( is_object( $cache_entry ) &&
|
107 |
+
isset( $cache_entry->timestamp ) &&
|
108 |
+
is_numeric( $cache_entry->timestamp )
|
109 |
+
);
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Check if there's a valid cached item.
|
114 |
+
*
|
115 |
+
* @author Vova Feldman (@svovaf)
|
116 |
+
* @since 1.1.6
|
117 |
+
*
|
118 |
+
* @param string $key
|
119 |
+
* @param null|int $expiration Since 1.2.2.7
|
120 |
+
*
|
121 |
+
* @return bool
|
122 |
+
*/
|
123 |
+
function has_valid( $key, $expiration = null ) {
|
124 |
+
$cache_entry = $this->_options->get_option( $key, false );
|
125 |
+
|
126 |
+
$is_valid = ( is_object( $cache_entry ) &&
|
127 |
+
isset( $cache_entry->timestamp ) &&
|
128 |
+
is_numeric( $cache_entry->timestamp ) &&
|
129 |
+
$cache_entry->timestamp > WP_FS__SCRIPT_START_TIME
|
130 |
+
);
|
131 |
+
|
132 |
+
if ( $is_valid &&
|
133 |
+
is_numeric( $expiration ) &&
|
134 |
+
isset( $cache_entry->created ) &&
|
135 |
+
is_numeric( $cache_entry->created ) &&
|
136 |
+
$cache_entry->created + $expiration < WP_FS__SCRIPT_START_TIME
|
137 |
+
) {
|
138 |
+
/**
|
139 |
+
* Even if the cache is still valid, since we are checking for validity
|
140 |
+
* with an explicit expiration period, if the period has past, return
|
141 |
+
* `false` as if the cache is invalid.
|
142 |
+
*
|
143 |
+
* @since 1.2.2.7
|
144 |
+
*/
|
145 |
+
$is_valid = false;
|
146 |
+
}
|
147 |
+
|
148 |
+
return $is_valid;
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* @author Vova Feldman (@svovaf)
|
153 |
+
* @since 1.1.6
|
154 |
+
*
|
155 |
+
* @param string $key
|
156 |
+
* @param mixed $default
|
157 |
+
*
|
158 |
+
* @return mixed
|
159 |
+
*/
|
160 |
+
function get( $key, $default = null ) {
|
161 |
+
$this->_logger->entrance( 'key = ' . $key );
|
162 |
+
|
163 |
+
$cache_entry = $this->_options->get_option( $key, false );
|
164 |
+
|
165 |
+
if ( is_object( $cache_entry ) &&
|
166 |
+
isset( $cache_entry->timestamp ) &&
|
167 |
+
is_numeric( $cache_entry->timestamp )
|
168 |
+
) {
|
169 |
+
return $cache_entry->result;
|
170 |
+
}
|
171 |
+
|
172 |
+
return is_object($default) ? clone $default : $default;
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* @author Vova Feldman (@svovaf)
|
177 |
+
* @since 1.1.6
|
178 |
+
*
|
179 |
+
* @param string $key
|
180 |
+
* @param mixed $default
|
181 |
+
*
|
182 |
+
* @return mixed
|
183 |
+
*/
|
184 |
+
function get_valid( $key, $default = null ) {
|
185 |
+
$this->_logger->entrance( 'key = ' . $key );
|
186 |
+
|
187 |
+
$cache_entry = $this->_options->get_option( $key, false );
|
188 |
+
|
189 |
+
if ( is_object( $cache_entry ) &&
|
190 |
+
isset( $cache_entry->timestamp ) &&
|
191 |
+
is_numeric( $cache_entry->timestamp ) &&
|
192 |
+
$cache_entry->timestamp > WP_FS__SCRIPT_START_TIME
|
193 |
+
) {
|
194 |
+
return $cache_entry->result;
|
195 |
+
}
|
196 |
+
|
197 |
+
return is_object($default) ? clone $default : $default;
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* @author Vova Feldman (@svovaf)
|
202 |
+
* @since 1.1.6
|
203 |
+
*
|
204 |
+
* @param string $key
|
205 |
+
* @param mixed $value
|
206 |
+
* @param int $expiration
|
207 |
+
*/
|
208 |
+
function set( $key, $value, $expiration = WP_FS__TIME_24_HOURS_IN_SEC ) {
|
209 |
+
$this->_logger->entrance( 'key = ' . $key );
|
210 |
+
|
211 |
+
$cache_entry = new stdClass();
|
212 |
+
|
213 |
+
$cache_entry->result = $value;
|
214 |
+
$cache_entry->created = WP_FS__SCRIPT_START_TIME;
|
215 |
+
$cache_entry->timestamp = WP_FS__SCRIPT_START_TIME + $expiration;
|
216 |
+
$this->_options->set_option( $key, $cache_entry, true );
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Get cached record expiration, or false if not cached or expired.
|
221 |
+
*
|
222 |
+
* @author Vova Feldman (@svovaf)
|
223 |
+
* @since 1.1.7.3
|
224 |
+
*
|
225 |
+
* @param string $key
|
226 |
+
*
|
227 |
+
* @return bool|int
|
228 |
+
*/
|
229 |
+
function get_record_expiration( $key ) {
|
230 |
+
$this->_logger->entrance( 'key = ' . $key );
|
231 |
+
|
232 |
+
$cache_entry = $this->_options->get_option( $key, false );
|
233 |
+
|
234 |
+
if ( is_object( $cache_entry ) &&
|
235 |
+
isset( $cache_entry->timestamp ) &&
|
236 |
+
is_numeric( $cache_entry->timestamp ) &&
|
237 |
+
$cache_entry->timestamp > WP_FS__SCRIPT_START_TIME
|
238 |
+
) {
|
239 |
+
return $cache_entry->timestamp;
|
240 |
+
}
|
241 |
+
|
242 |
+
return false;
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Purge cached item.
|
247 |
+
*
|
248 |
+
* @author Vova Feldman (@svovaf)
|
249 |
+
* @since 1.1.6
|
250 |
+
*
|
251 |
+
* @param string $key
|
252 |
+
*/
|
253 |
+
function purge( $key ) {
|
254 |
+
$this->_logger->entrance( 'key = ' . $key );
|
255 |
+
|
256 |
+
$this->_options->unset_option( $key, true );
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Set cached item as expired.
|
261 |
+
*
|
262 |
+
* @author Vova Feldman (@svovaf)
|
263 |
+
* @since 1.2.2.7
|
264 |
+
*
|
265 |
+
* @param string $key
|
266 |
+
*/
|
267 |
+
function expire( $key ) {
|
268 |
+
$this->_logger->entrance( 'key = ' . $key );
|
269 |
+
|
270 |
+
$cache_entry = $this->_options->get_option( $key, false );
|
271 |
+
|
272 |
+
if ( is_object( $cache_entry ) &&
|
273 |
+
isset( $cache_entry->timestamp ) &&
|
274 |
+
is_numeric( $cache_entry->timestamp ))
|
275 |
+
{
|
276 |
+
// Set to expired.
|
277 |
+
$cache_entry->timestamp = WP_FS__SCRIPT_START_TIME;
|
278 |
+
$this->_options->set_option( $key, $cache_entry, true );
|
279 |
+
}
|
280 |
+
}
|
281 |
}
|
freemius/includes/managers/class-fs-key-value-storage.php
CHANGED
@@ -1,328 +1,328 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.7
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Class FS_Key_Value_Storage
|
15 |
-
*
|
16 |
-
* @property int $install_timestamp
|
17 |
-
* @property int $activation_timestamp
|
18 |
-
* @property int $sync_timestamp
|
19 |
-
* @property object $sync_cron
|
20 |
-
* @property int $install_sync_timestamp
|
21 |
-
* @property array $connectivity_test
|
22 |
-
* @property array $is_on
|
23 |
-
* @property object $trial_plan
|
24 |
-
* @property bool $has_trial_plan
|
25 |
-
* @property bool $trial_promotion_shown
|
26 |
-
* @property string $sdk_version
|
27 |
-
* @property string $sdk_last_version
|
28 |
-
* @property bool $sdk_upgrade_mode
|
29 |
-
* @property bool $sdk_downgrade_mode
|
30 |
-
* @property bool $plugin_upgrade_mode
|
31 |
-
* @property bool $plugin_downgrade_mode
|
32 |
-
* @property string $plugin_version
|
33 |
-
* @property string $plugin_last_version
|
34 |
-
* @property bool $is_plugin_new_install
|
35 |
-
* @property bool $was_plugin_loaded
|
36 |
-
* @property object $plugin_main_file
|
37 |
-
* @property bool $prev_is_premium
|
38 |
-
* @property array $is_anonymous
|
39 |
-
* @property bool $is_pending_activation
|
40 |
-
* @property bool $sticky_optin_added
|
41 |
-
* @property object $uninstall_reason
|
42 |
-
* @property object $subscription
|
43 |
-
*/
|
44 |
-
class FS_Key_Value_Storage implements ArrayAccess, Iterator, Countable {
|
45 |
-
/**
|
46 |
-
* @var string
|
47 |
-
*/
|
48 |
-
protected $_id;
|
49 |
-
/**
|
50 |
-
* @since 1.2.2
|
51 |
-
*
|
52 |
-
* @var string
|
53 |
-
*/
|
54 |
-
protected $_secondary_id;
|
55 |
-
/**
|
56 |
-
* @var array
|
57 |
-
*/
|
58 |
-
protected $_data;
|
59 |
-
|
60 |
-
/**
|
61 |
-
* @var FS_Plugin_Manager[]
|
62 |
-
*/
|
63 |
-
private static $_instances = array();
|
64 |
-
/**
|
65 |
-
* @var FS_Logger
|
66 |
-
*/
|
67 |
-
protected $_logger;
|
68 |
-
|
69 |
-
/**
|
70 |
-
* @param string $id
|
71 |
-
* @param string $secondary_id
|
72 |
-
*
|
73 |
-
* @return FS_Key_Value_Storage
|
74 |
-
*/
|
75 |
-
static function instance( $id, $secondary_id ) {
|
76 |
-
$key = $id . ':' . $secondary_id;
|
77 |
-
if ( ! isset( self::$_instances[ $key ] ) ) {
|
78 |
-
self::$_instances[ $key ] = new FS_Key_Value_Storage( $id, $secondary_id );
|
79 |
-
}
|
80 |
-
|
81 |
-
return self::$_instances[ $key ];
|
82 |
-
}
|
83 |
-
|
84 |
-
protected function __construct( $id, $secondary_id ) {
|
85 |
-
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $secondary_id . '_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
86 |
-
|
87 |
-
$this->_secondary_id = $secondary_id;
|
88 |
-
$this->_id = $id;
|
89 |
-
$this->load();
|
90 |
-
}
|
91 |
-
|
92 |
-
protected function get_option_manager() {
|
93 |
-
return FS_Option_Manager::get_manager( WP_FS__ACCOUNTS_OPTION_NAME, true );
|
94 |
-
}
|
95 |
-
|
96 |
-
protected function get_all_data() {
|
97 |
-
return $this->get_option_manager()->get_option( $this->_id, array() );
|
98 |
-
}
|
99 |
-
|
100 |
-
/**
|
101 |
-
* Load plugin data from local DB.
|
102 |
-
*
|
103 |
-
* @author Vova Feldman (@svovaf)
|
104 |
-
* @since 1.0.7
|
105 |
-
*/
|
106 |
-
function load() {
|
107 |
-
$all_plugins_data = $this->get_all_data();
|
108 |
-
$this->_data = isset( $all_plugins_data[ $this->_secondary_id ] ) ?
|
109 |
-
$all_plugins_data[ $this->_secondary_id ] :
|
110 |
-
array();
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* @author Vova Feldman (@svovaf)
|
115 |
-
* @since 1.0.7
|
116 |
-
*
|
117 |
-
* @param string $key
|
118 |
-
* @param mixed $value
|
119 |
-
* @param bool $flush
|
120 |
-
*/
|
121 |
-
function store( $key, $value, $flush = true ) {
|
122 |
-
if ( $this->_logger->is_on() ) {
|
123 |
-
$this->_logger->entrance( $key . ' = ' . var_export( $value, true ) );
|
124 |
-
}
|
125 |
-
|
126 |
-
if ( array_key_exists( $key, $this->_data ) && $value === $this->_data[ $key ] ) {
|
127 |
-
// No need to store data if the value wasn't changed.
|
128 |
-
return;
|
129 |
-
}
|
130 |
-
|
131 |
-
$all_data = $this->get_all_data();
|
132 |
-
|
133 |
-
$this->_data[ $key ] = $value;
|
134 |
-
|
135 |
-
$all_data[ $this->_secondary_id ] = $this->_data;
|
136 |
-
|
137 |
-
$options_manager = $this->get_option_manager();
|
138 |
-
$options_manager->set_option( $this->_id, $all_data, $flush );
|
139 |
-
}
|
140 |
-
|
141 |
-
/**
|
142 |
-
* @author Vova Feldman (@svovaf)
|
143 |
-
* @since 1.0.7
|
144 |
-
*
|
145 |
-
* @param bool $store
|
146 |
-
* @param string[] $exceptions Set of keys to keep and not clear.
|
147 |
-
*/
|
148 |
-
function clear_all( $store = true, $exceptions = array() ) {
|
149 |
-
$new_data = array();
|
150 |
-
foreach ( $exceptions as $key ) {
|
151 |
-
if ( isset( $this->_data[ $key ] ) ) {
|
152 |
-
$new_data[ $key ] = $this->_data[ $key ];
|
153 |
-
}
|
154 |
-
}
|
155 |
-
|
156 |
-
$this->_data = $new_data;
|
157 |
-
|
158 |
-
if ( $store ) {
|
159 |
-
$all_data = $this->get_all_data();
|
160 |
-
$all_data[ $this->_secondary_id ] = $this->_data;
|
161 |
-
$options_manager = $this->get_option_manager();
|
162 |
-
$options_manager->set_option( $this->_id, $all_data, true );
|
163 |
-
}
|
164 |
-
}
|
165 |
-
|
166 |
-
/**
|
167 |
-
* Delete key-value storage.
|
168 |
-
*
|
169 |
-
* @author Vova Feldman (@svovaf)
|
170 |
-
* @since 1.0.9
|
171 |
-
*/
|
172 |
-
function delete() {
|
173 |
-
$this->_data = array();
|
174 |
-
|
175 |
-
$all_data = $this->get_all_data();
|
176 |
-
unset( $all_data[ $this->_secondary_id ] );
|
177 |
-
$options_manager = $this->get_option_manager();
|
178 |
-
$options_manager->set_option( $this->_id, $all_data, true );
|
179 |
-
}
|
180 |
-
|
181 |
-
/**
|
182 |
-
* @author Vova Feldman (@svovaf)
|
183 |
-
* @since 1.0.7
|
184 |
-
*
|
185 |
-
* @param string $key
|
186 |
-
* @param bool $store
|
187 |
-
*/
|
188 |
-
function remove( $key, $store = true ) {
|
189 |
-
if ( ! array_key_exists( $key, $this->_data ) ) {
|
190 |
-
return;
|
191 |
-
}
|
192 |
-
|
193 |
-
unset( $this->_data[ $key ] );
|
194 |
-
|
195 |
-
if ( $store ) {
|
196 |
-
$all_data = $this->get_all_data();
|
197 |
-
$all_data[ $this->_secondary_id ] = $this->_data;
|
198 |
-
$options_manager = $this->get_option_manager();
|
199 |
-
$options_manager->set_option( $this->_id, $all_data, true );
|
200 |
-
}
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* @author Vova Feldman (@svovaf)
|
205 |
-
* @since 1.0.7
|
206 |
-
*
|
207 |
-
* @param string $key
|
208 |
-
* @param mixed $default
|
209 |
-
*
|
210 |
-
* @return bool|\FS_Plugin
|
211 |
-
*/
|
212 |
-
function get( $key, $default = false ) {
|
213 |
-
return array_key_exists( $key, $this->_data ) ?
|
214 |
-
$this->_data[ $key ] :
|
215 |
-
$default;
|
216 |
-
}
|
217 |
-
|
218 |
-
|
219 |
-
/* ArrayAccess + Magic Access (better for refactoring)
|
220 |
-
-----------------------------------------------------------------------------------*/
|
221 |
-
function __set( $k, $v ) {
|
222 |
-
$this->store( $k, $v );
|
223 |
-
}
|
224 |
-
|
225 |
-
function __isset( $k ) {
|
226 |
-
return array_key_exists( $k, $this->_data );
|
227 |
-
}
|
228 |
-
|
229 |
-
function __unset( $k ) {
|
230 |
-
$this->remove( $k );
|
231 |
-
}
|
232 |
-
|
233 |
-
function __get( $k ) {
|
234 |
-
return $this->get( $k, null );
|
235 |
-
}
|
236 |
-
|
237 |
-
function offsetSet( $k, $v ) {
|
238 |
-
if ( is_null( $k ) ) {
|
239 |
-
throw new Exception( 'Can\'t append value to request params.' );
|
240 |
-
} else {
|
241 |
-
$this->{$k} = $v;
|
242 |
-
}
|
243 |
-
}
|
244 |
-
|
245 |
-
function offsetExists( $k ) {
|
246 |
-
return array_key_exists( $k, $this->_data );
|
247 |
-
}
|
248 |
-
|
249 |
-
function offsetUnset( $k ) {
|
250 |
-
unset( $this->$k );
|
251 |
-
}
|
252 |
-
|
253 |
-
function offsetGet( $k ) {
|
254 |
-
return $this->get( $k, null );
|
255 |
-
}
|
256 |
-
|
257 |
-
/**
|
258 |
-
* (PHP 5 >= 5.0.0)<br/>
|
259 |
-
* Return the current element
|
260 |
-
*
|
261 |
-
* @link http://php.net/manual/en/iterator.current.php
|
262 |
-
* @return mixed Can return any type.
|
263 |
-
*/
|
264 |
-
public function current() {
|
265 |
-
return current( $this->_data );
|
266 |
-
}
|
267 |
-
|
268 |
-
/**
|
269 |
-
* (PHP 5 >= 5.0.0)<br/>
|
270 |
-
* Move forward to next element
|
271 |
-
*
|
272 |
-
* @link http://php.net/manual/en/iterator.next.php
|
273 |
-
* @return void Any returned value is ignored.
|
274 |
-
*/
|
275 |
-
public function next() {
|
276 |
-
next( $this->_data );
|
277 |
-
}
|
278 |
-
|
279 |
-
/**
|
280 |
-
* (PHP 5 >= 5.0.0)<br/>
|
281 |
-
* Return the key of the current element
|
282 |
-
*
|
283 |
-
* @link http://php.net/manual/en/iterator.key.php
|
284 |
-
* @return mixed scalar on success, or null on failure.
|
285 |
-
*/
|
286 |
-
public function key() {
|
287 |
-
return key( $this->_data );
|
288 |
-
}
|
289 |
-
|
290 |
-
/**
|
291 |
-
* (PHP 5 >= 5.0.0)<br/>
|
292 |
-
* Checks if current position is valid
|
293 |
-
*
|
294 |
-
* @link http://php.net/manual/en/iterator.valid.php
|
295 |
-
* @return boolean The return value will be casted to boolean and then evaluated.
|
296 |
-
* Returns true on success or false on failure.
|
297 |
-
*/
|
298 |
-
public function valid() {
|
299 |
-
$key = key( $this->_data );
|
300 |
-
|
301 |
-
return ( $key !== null && $key !== false );
|
302 |
-
}
|
303 |
-
|
304 |
-
/**
|
305 |
-
* (PHP 5 >= 5.0.0)<br/>
|
306 |
-
* Rewind the Iterator to the first element
|
307 |
-
*
|
308 |
-
* @link http://php.net/manual/en/iterator.rewind.php
|
309 |
-
* @return void Any returned value is ignored.
|
310 |
-
*/
|
311 |
-
public function rewind() {
|
312 |
-
reset( $this->_data );
|
313 |
-
}
|
314 |
-
|
315 |
-
/**
|
316 |
-
* (PHP 5 >= 5.1.0)<br/>
|
317 |
-
* Count elements of an object
|
318 |
-
*
|
319 |
-
* @link http://php.net/manual/en/countable.count.php
|
320 |
-
* @return int The custom count as an integer.
|
321 |
-
* </p>
|
322 |
-
* <p>
|
323 |
-
* The return value is cast to an integer.
|
324 |
-
*/
|
325 |
-
public function count() {
|
326 |
-
return count( $this->_data );
|
327 |
-
}
|
328 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.7
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class FS_Key_Value_Storage
|
15 |
+
*
|
16 |
+
* @property int $install_timestamp
|
17 |
+
* @property int $activation_timestamp
|
18 |
+
* @property int $sync_timestamp
|
19 |
+
* @property object $sync_cron
|
20 |
+
* @property int $install_sync_timestamp
|
21 |
+
* @property array $connectivity_test
|
22 |
+
* @property array $is_on
|
23 |
+
* @property object $trial_plan
|
24 |
+
* @property bool $has_trial_plan
|
25 |
+
* @property bool $trial_promotion_shown
|
26 |
+
* @property string $sdk_version
|
27 |
+
* @property string $sdk_last_version
|
28 |
+
* @property bool $sdk_upgrade_mode
|
29 |
+
* @property bool $sdk_downgrade_mode
|
30 |
+
* @property bool $plugin_upgrade_mode
|
31 |
+
* @property bool $plugin_downgrade_mode
|
32 |
+
* @property string $plugin_version
|
33 |
+
* @property string $plugin_last_version
|
34 |
+
* @property bool $is_plugin_new_install
|
35 |
+
* @property bool $was_plugin_loaded
|
36 |
+
* @property object $plugin_main_file
|
37 |
+
* @property bool $prev_is_premium
|
38 |
+
* @property array $is_anonymous
|
39 |
+
* @property bool $is_pending_activation
|
40 |
+
* @property bool $sticky_optin_added
|
41 |
+
* @property object $uninstall_reason
|
42 |
+
* @property object $subscription
|
43 |
+
*/
|
44 |
+
class FS_Key_Value_Storage implements ArrayAccess, Iterator, Countable {
|
45 |
+
/**
|
46 |
+
* @var string
|
47 |
+
*/
|
48 |
+
protected $_id;
|
49 |
+
/**
|
50 |
+
* @since 1.2.2
|
51 |
+
*
|
52 |
+
* @var string
|
53 |
+
*/
|
54 |
+
protected $_secondary_id;
|
55 |
+
/**
|
56 |
+
* @var array
|
57 |
+
*/
|
58 |
+
protected $_data;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @var FS_Plugin_Manager[]
|
62 |
+
*/
|
63 |
+
private static $_instances = array();
|
64 |
+
/**
|
65 |
+
* @var FS_Logger
|
66 |
+
*/
|
67 |
+
protected $_logger;
|
68 |
+
|
69 |
+
/**
|
70 |
+
* @param string $id
|
71 |
+
* @param string $secondary_id
|
72 |
+
*
|
73 |
+
* @return FS_Key_Value_Storage
|
74 |
+
*/
|
75 |
+
static function instance( $id, $secondary_id ) {
|
76 |
+
$key = $id . ':' . $secondary_id;
|
77 |
+
if ( ! isset( self::$_instances[ $key ] ) ) {
|
78 |
+
self::$_instances[ $key ] = new FS_Key_Value_Storage( $id, $secondary_id );
|
79 |
+
}
|
80 |
+
|
81 |
+
return self::$_instances[ $key ];
|
82 |
+
}
|
83 |
+
|
84 |
+
protected function __construct( $id, $secondary_id ) {
|
85 |
+
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $secondary_id . '_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
86 |
+
|
87 |
+
$this->_secondary_id = $secondary_id;
|
88 |
+
$this->_id = $id;
|
89 |
+
$this->load();
|
90 |
+
}
|
91 |
+
|
92 |
+
protected function get_option_manager() {
|
93 |
+
return FS_Option_Manager::get_manager( WP_FS__ACCOUNTS_OPTION_NAME, true );
|
94 |
+
}
|
95 |
+
|
96 |
+
protected function get_all_data() {
|
97 |
+
return $this->get_option_manager()->get_option( $this->_id, array() );
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Load plugin data from local DB.
|
102 |
+
*
|
103 |
+
* @author Vova Feldman (@svovaf)
|
104 |
+
* @since 1.0.7
|
105 |
+
*/
|
106 |
+
function load() {
|
107 |
+
$all_plugins_data = $this->get_all_data();
|
108 |
+
$this->_data = isset( $all_plugins_data[ $this->_secondary_id ] ) ?
|
109 |
+
$all_plugins_data[ $this->_secondary_id ] :
|
110 |
+
array();
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* @author Vova Feldman (@svovaf)
|
115 |
+
* @since 1.0.7
|
116 |
+
*
|
117 |
+
* @param string $key
|
118 |
+
* @param mixed $value
|
119 |
+
* @param bool $flush
|
120 |
+
*/
|
121 |
+
function store( $key, $value, $flush = true ) {
|
122 |
+
if ( $this->_logger->is_on() ) {
|
123 |
+
$this->_logger->entrance( $key . ' = ' . var_export( $value, true ) );
|
124 |
+
}
|
125 |
+
|
126 |
+
if ( array_key_exists( $key, $this->_data ) && $value === $this->_data[ $key ] ) {
|
127 |
+
// No need to store data if the value wasn't changed.
|
128 |
+
return;
|
129 |
+
}
|
130 |
+
|
131 |
+
$all_data = $this->get_all_data();
|
132 |
+
|
133 |
+
$this->_data[ $key ] = $value;
|
134 |
+
|
135 |
+
$all_data[ $this->_secondary_id ] = $this->_data;
|
136 |
+
|
137 |
+
$options_manager = $this->get_option_manager();
|
138 |
+
$options_manager->set_option( $this->_id, $all_data, $flush );
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* @author Vova Feldman (@svovaf)
|
143 |
+
* @since 1.0.7
|
144 |
+
*
|
145 |
+
* @param bool $store
|
146 |
+
* @param string[] $exceptions Set of keys to keep and not clear.
|
147 |
+
*/
|
148 |
+
function clear_all( $store = true, $exceptions = array() ) {
|
149 |
+
$new_data = array();
|
150 |
+
foreach ( $exceptions as $key ) {
|
151 |
+
if ( isset( $this->_data[ $key ] ) ) {
|
152 |
+
$new_data[ $key ] = $this->_data[ $key ];
|
153 |
+
}
|
154 |
+
}
|
155 |
+
|
156 |
+
$this->_data = $new_data;
|
157 |
+
|
158 |
+
if ( $store ) {
|
159 |
+
$all_data = $this->get_all_data();
|
160 |
+
$all_data[ $this->_secondary_id ] = $this->_data;
|
161 |
+
$options_manager = $this->get_option_manager();
|
162 |
+
$options_manager->set_option( $this->_id, $all_data, true );
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Delete key-value storage.
|
168 |
+
*
|
169 |
+
* @author Vova Feldman (@svovaf)
|
170 |
+
* @since 1.0.9
|
171 |
+
*/
|
172 |
+
function delete() {
|
173 |
+
$this->_data = array();
|
174 |
+
|
175 |
+
$all_data = $this->get_all_data();
|
176 |
+
unset( $all_data[ $this->_secondary_id ] );
|
177 |
+
$options_manager = $this->get_option_manager();
|
178 |
+
$options_manager->set_option( $this->_id, $all_data, true );
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* @author Vova Feldman (@svovaf)
|
183 |
+
* @since 1.0.7
|
184 |
+
*
|
185 |
+
* @param string $key
|
186 |
+
* @param bool $store
|
187 |
+
*/
|
188 |
+
function remove( $key, $store = true ) {
|
189 |
+
if ( ! array_key_exists( $key, $this->_data ) ) {
|
190 |
+
return;
|
191 |
+
}
|
192 |
+
|
193 |
+
unset( $this->_data[ $key ] );
|
194 |
+
|
195 |
+
if ( $store ) {
|
196 |
+
$all_data = $this->get_all_data();
|
197 |
+
$all_data[ $this->_secondary_id ] = $this->_data;
|
198 |
+
$options_manager = $this->get_option_manager();
|
199 |
+
$options_manager->set_option( $this->_id, $all_data, true );
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* @author Vova Feldman (@svovaf)
|
205 |
+
* @since 1.0.7
|
206 |
+
*
|
207 |
+
* @param string $key
|
208 |
+
* @param mixed $default
|
209 |
+
*
|
210 |
+
* @return bool|\FS_Plugin
|
211 |
+
*/
|
212 |
+
function get( $key, $default = false ) {
|
213 |
+
return array_key_exists( $key, $this->_data ) ?
|
214 |
+
$this->_data[ $key ] :
|
215 |
+
$default;
|
216 |
+
}
|
217 |
+
|
218 |
+
|
219 |
+
/* ArrayAccess + Magic Access (better for refactoring)
|
220 |
+
-----------------------------------------------------------------------------------*/
|
221 |
+
function __set( $k, $v ) {
|
222 |
+
$this->store( $k, $v );
|
223 |
+
}
|
224 |
+
|
225 |
+
function __isset( $k ) {
|
226 |
+
return array_key_exists( $k, $this->_data );
|
227 |
+
}
|
228 |
+
|
229 |
+
function __unset( $k ) {
|
230 |
+
$this->remove( $k );
|
231 |
+
}
|
232 |
+
|
233 |
+
function __get( $k ) {
|
234 |
+
return $this->get( $k, null );
|
235 |
+
}
|
236 |
+
|
237 |
+
function offsetSet( $k, $v ) {
|
238 |
+
if ( is_null( $k ) ) {
|
239 |
+
throw new Exception( 'Can\'t append value to request params.' );
|
240 |
+
} else {
|
241 |
+
$this->{$k} = $v;
|
242 |
+
}
|
243 |
+
}
|
244 |
+
|
245 |
+
function offsetExists( $k ) {
|
246 |
+
return array_key_exists( $k, $this->_data );
|
247 |
+
}
|
248 |
+
|
249 |
+
function offsetUnset( $k ) {
|
250 |
+
unset( $this->$k );
|
251 |
+
}
|
252 |
+
|
253 |
+
function offsetGet( $k ) {
|
254 |
+
return $this->get( $k, null );
|
255 |
+
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* (PHP 5 >= 5.0.0)<br/>
|
259 |
+
* Return the current element
|
260 |
+
*
|
261 |
+
* @link http://php.net/manual/en/iterator.current.php
|
262 |
+
* @return mixed Can return any type.
|
263 |
+
*/
|
264 |
+
public function current() {
|
265 |
+
return current( $this->_data );
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* (PHP 5 >= 5.0.0)<br/>
|
270 |
+
* Move forward to next element
|
271 |
+
*
|
272 |
+
* @link http://php.net/manual/en/iterator.next.php
|
273 |
+
* @return void Any returned value is ignored.
|
274 |
+
*/
|
275 |
+
public function next() {
|
276 |
+
next( $this->_data );
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* (PHP 5 >= 5.0.0)<br/>
|
281 |
+
* Return the key of the current element
|
282 |
+
*
|
283 |
+
* @link http://php.net/manual/en/iterator.key.php
|
284 |
+
* @return mixed scalar on success, or null on failure.
|
285 |
+
*/
|
286 |
+
public function key() {
|
287 |
+
return key( $this->_data );
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* (PHP 5 >= 5.0.0)<br/>
|
292 |
+
* Checks if current position is valid
|
293 |
+
*
|
294 |
+
* @link http://php.net/manual/en/iterator.valid.php
|
295 |
+
* @return boolean The return value will be casted to boolean and then evaluated.
|
296 |
+
* Returns true on success or false on failure.
|
297 |
+
*/
|
298 |
+
public function valid() {
|
299 |
+
$key = key( $this->_data );
|
300 |
+
|
301 |
+
return ( $key !== null && $key !== false );
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* (PHP 5 >= 5.0.0)<br/>
|
306 |
+
* Rewind the Iterator to the first element
|
307 |
+
*
|
308 |
+
* @link http://php.net/manual/en/iterator.rewind.php
|
309 |
+
* @return void Any returned value is ignored.
|
310 |
+
*/
|
311 |
+
public function rewind() {
|
312 |
+
reset( $this->_data );
|
313 |
+
}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* (PHP 5 >= 5.1.0)<br/>
|
317 |
+
* Count elements of an object
|
318 |
+
*
|
319 |
+
* @link http://php.net/manual/en/countable.count.php
|
320 |
+
* @return int The custom count as an integer.
|
321 |
+
* </p>
|
322 |
+
* <p>
|
323 |
+
* The return value is cast to an integer.
|
324 |
+
*/
|
325 |
+
public function count() {
|
326 |
+
return count( $this->_data );
|
327 |
+
}
|
328 |
}
|
freemius/includes/managers/class-fs-option-manager.php
CHANGED
@@ -1,353 +1,353 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* 3-layer lazy options manager.
|
15 |
-
* layer 3: Memory
|
16 |
-
* layer 2: Cache (if there's any caching plugin and if WP_FS__DEBUG_SDK is FALSE)
|
17 |
-
* layer 1: Database (options table). All options stored as one option record in the DB to reduce number of DB
|
18 |
-
* queries.
|
19 |
-
*
|
20 |
-
* If load() is not explicitly called, starts as empty manager. Same thing about saving the data - you have to
|
21 |
-
* explicitly call store().
|
22 |
-
*
|
23 |
-
* Class Freemius_Option_Manager
|
24 |
-
*/
|
25 |
-
class FS_Option_Manager {
|
26 |
-
/**
|
27 |
-
* @var string
|
28 |
-
*/
|
29 |
-
private $_id;
|
30 |
-
/**
|
31 |
-
* @var array
|
32 |
-
*/
|
33 |
-
private $_options;
|
34 |
-
/**
|
35 |
-
* @var FS_Logger
|
36 |
-
*/
|
37 |
-
private $_logger;
|
38 |
-
|
39 |
-
/**
|
40 |
-
* @var FS_Option_Manager[]
|
41 |
-
*/
|
42 |
-
private static $_MANAGERS = array();
|
43 |
-
|
44 |
-
/**
|
45 |
-
* @author Vova Feldman (@svovaf)
|
46 |
-
* @since 1.0.3
|
47 |
-
*
|
48 |
-
* @param string $id
|
49 |
-
* @param bool $load
|
50 |
-
*/
|
51 |
-
private function __construct( $id, $load = false ) {
|
52 |
-
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_opt_mngr_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
53 |
-
|
54 |
-
$this->_logger->entrance();
|
55 |
-
$this->_logger->log( 'id = ' . $id );
|
56 |
-
|
57 |
-
$this->_id = $id;
|
58 |
-
|
59 |
-
if ( $load ) {
|
60 |
-
$this->load();
|
61 |
-
}
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* @author Vova Feldman (@svovaf)
|
66 |
-
* @since 1.0.3
|
67 |
-
*
|
68 |
-
* @param $id
|
69 |
-
* @param $load
|
70 |
-
*
|
71 |
-
* @return FS_Option_Manager
|
72 |
-
*/
|
73 |
-
static function get_manager( $id, $load = false ) {
|
74 |
-
$id = strtolower( $id );
|
75 |
-
|
76 |
-
if ( ! isset( self::$_MANAGERS[ $id ] ) ) {
|
77 |
-
self::$_MANAGERS[ $id ] = new FS_Option_Manager( $id, $load );
|
78 |
-
} // If load required but not yet loaded, load.
|
79 |
-
else if ( $load && ! self::$_MANAGERS[ $id ]->is_loaded() ) {
|
80 |
-
self::$_MANAGERS[ $id ]->load();
|
81 |
-
}
|
82 |
-
|
83 |
-
return self::$_MANAGERS[ $id ];
|
84 |
-
}
|
85 |
-
|
86 |
-
private function _get_option_manager_name() {
|
87 |
-
// return WP_FS__SLUG . '_' . $this->_id;
|
88 |
-
return $this->_id;
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* @author Vova Feldman (@svovaf)
|
93 |
-
* @since 1.0.3
|
94 |
-
*
|
95 |
-
* @param bool $flush
|
96 |
-
*/
|
97 |
-
function load( $flush = false ) {
|
98 |
-
$this->_logger->entrance();
|
99 |
-
|
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 |
-
}
|
111 |
-
|
112 |
-
// $this->_logger->info('wp_cache_get = ' . var_export($this->_options, true));
|
113 |
-
|
114 |
-
// if ( is_array( $this->_options ) ) {
|
115 |
-
// $this->clear();
|
116 |
-
// }
|
117 |
-
|
118 |
-
$cached = true;
|
119 |
-
|
120 |
-
if ( empty( $this->_options ) ) {
|
121 |
-
$this->_options = get_option( $option_name );
|
122 |
-
|
123 |
-
if ( is_string( $this->_options ) ) {
|
124 |
-
$this->_options = json_decode( $this->_options );
|
125 |
-
}
|
126 |
-
|
127 |
-
// $this->_logger->info('get_option = ' . var_export($this->_options, true));
|
128 |
-
|
129 |
-
if ( false === $this->_options ) {
|
130 |
-
$this->clear();
|
131 |
-
}
|
132 |
-
|
133 |
-
$cached = false;
|
134 |
-
}
|
135 |
-
|
136 |
-
if ( ! WP_FS__DEBUG_SDK && ! $cached ) // Set non encoded cache.
|
137 |
-
{
|
138 |
-
wp_cache_set( $option_name, $this->_options, WP_FS__SLUG );
|
139 |
-
}
|
140 |
-
}
|
141 |
-
}
|
142 |
-
|
143 |
-
/**
|
144 |
-
* @author Vova Feldman (@svovaf)
|
145 |
-
* @since 1.0.3
|
146 |
-
*
|
147 |
-
* @return bool
|
148 |
-
*/
|
149 |
-
function is_loaded() {
|
150 |
-
return isset( $this->_options );
|
151 |
-
}
|
152 |
-
|
153 |
-
/**
|
154 |
-
* @author Vova Feldman (@svovaf)
|
155 |
-
* @since 1.0.3
|
156 |
-
*
|
157 |
-
* @return bool
|
158 |
-
*/
|
159 |
-
function is_empty() {
|
160 |
-
return ( $this->is_loaded() && false === $this->_options );
|
161 |
-
}
|
162 |
-
|
163 |
-
/**
|
164 |
-
* @author Vova Feldman (@svovaf)
|
165 |
-
* @since 1.0.6
|
166 |
-
*
|
167 |
-
* @param bool $flush
|
168 |
-
*/
|
169 |
-
function clear( $flush = false ) {
|
170 |
-
$this->_logger->entrance();
|
171 |
-
|
172 |
-
$this->_options = array();
|
173 |
-
|
174 |
-
if ( $flush ) {
|
175 |
-
$this->store();
|
176 |
-
}
|
177 |
-
}
|
178 |
-
|
179 |
-
/**
|
180 |
-
* Delete options manager from DB.
|
181 |
-
*
|
182 |
-
* @author Vova Feldman (@svovaf)
|
183 |
-
* @since 1.0.9
|
184 |
-
*/
|
185 |
-
function delete() {
|
186 |
-
delete_option( $this->_get_option_manager_name() );
|
187 |
-
}
|
188 |
-
|
189 |
-
/**
|
190 |
-
* @author Vova Feldman (@svovaf)
|
191 |
-
* @since 1.0.6
|
192 |
-
*
|
193 |
-
* @param string $option
|
194 |
-
*
|
195 |
-
* @return bool
|
196 |
-
*/
|
197 |
-
function has_option( $option ) {
|
198 |
-
return array_key_exists( $option, $this->_options );
|
199 |
-
}
|
200 |
-
|
201 |
-
/**
|
202 |
-
* @author Vova Feldman (@svovaf)
|
203 |
-
* @since 1.0.3
|
204 |
-
*
|
205 |
-
* @param string $option
|
206 |
-
* @param mixed $default
|
207 |
-
*
|
208 |
-
* @return mixed
|
209 |
-
*/
|
210 |
-
function get_option( $option, $default = null ) {
|
211 |
-
$this->_logger->entrance( 'option = ' . $option );
|
212 |
-
|
213 |
-
if ( is_array( $this->_options ) ) {
|
214 |
-
$value = isset( $this->_options[ $option ] ) ?
|
215 |
-
$this->_options[ $option ] :
|
216 |
-
$default;
|
217 |
-
} else if ( is_object( $this->_options ) ) {
|
218 |
-
$value = isset( $this->_options->{$option} ) ?
|
219 |
-
$this->_options->{$option} :
|
220 |
-
$default;
|
221 |
-
} else {
|
222 |
-
$value = $default;
|
223 |
-
}
|
224 |
-
|
225 |
-
/**
|
226 |
-
* If it's an object, return a clone of the object, otherwise,
|
227 |
-
* external changes of the object will actually change the value
|
228 |
-
* of the object in the options manager which may lead to an unexpected
|
229 |
-
* behaviour and data integrity when a store() call is triggered.
|
230 |
-
*
|
231 |
-
* Example:
|
232 |
-
* $object1 = $options->get_option( 'object1' );
|
233 |
-
* $object1->x = 123;
|
234 |
-
*
|
235 |
-
* $object2 = $options->get_option( 'object2' );
|
236 |
-
* $object2->y = 'dummy';
|
237 |
-
*
|
238 |
-
* $options->set_option( 'object2', $object2, true );
|
239 |
-
*
|
240 |
-
* If we don't return a clone of option 'object1', setting 'object2'
|
241 |
-
* will also store the updated value of 'object1' which is quite not
|
242 |
-
* an expected behaviour.
|
243 |
-
*
|
244 |
-
* @author Vova Feldman
|
245 |
-
*/
|
246 |
-
return is_object($value) ? clone $value : $value;
|
247 |
-
}
|
248 |
-
|
249 |
-
/**
|
250 |
-
* @author Vova Feldman (@svovaf)
|
251 |
-
* @since 1.0.3
|
252 |
-
*
|
253 |
-
* @param string $option
|
254 |
-
* @param mixed $value
|
255 |
-
* @param bool $flush
|
256 |
-
*/
|
257 |
-
function set_option( $option, $value, $flush = false ) {
|
258 |
-
$this->_logger->entrance( 'option = ' . $option );
|
259 |
-
|
260 |
-
if ( ! $this->is_loaded() ) {
|
261 |
-
$this->clear();
|
262 |
-
}
|
263 |
-
|
264 |
-
/**
|
265 |
-
* If it's an object, store a clone of the object, otherwise,
|
266 |
-
* external changes of the object will actually change the value
|
267 |
-
* of the object in the options manager which may lead to an unexpected
|
268 |
-
* behaviour and data integrity when a store() call is triggered.
|
269 |
-
*
|
270 |
-
* Example:
|
271 |
-
* $object1 = new stdClass();
|
272 |
-
* $object1->x = 123;
|
273 |
-
*
|
274 |
-
* $options->set_option( 'object1', $object1 );
|
275 |
-
*
|
276 |
-
* $object1->x = 456;
|
277 |
-
*
|
278 |
-
* $options->set_option( 'object2', $object2, true );
|
279 |
-
*
|
280 |
-
* If we don't set the option as a clone of option 'object1', setting 'object2'
|
281 |
-
* will also store the updated value of 'object1' ($object1->x = 456 instead of
|
282 |
-
* $object1->x = 123) which is quite not an expected behaviour.
|
283 |
-
*
|
284 |
-
* @author Vova Feldman
|
285 |
-
*/
|
286 |
-
$copy = is_object($value) ? clone $value : $value;
|
287 |
-
|
288 |
-
if ( is_array( $this->_options ) ) {
|
289 |
-
$this->_options[ $option ] = $copy;
|
290 |
-
} else if ( is_object( $this->_options ) ) {
|
291 |
-
$this->_options->{$option} = $copy;
|
292 |
-
}
|
293 |
-
|
294 |
-
if ( $flush ) {
|
295 |
-
$this->store();
|
296 |
-
}
|
297 |
-
}
|
298 |
-
|
299 |
-
/**
|
300 |
-
* Unset option.
|
301 |
-
*
|
302 |
-
* @author Vova Feldman (@svovaf)
|
303 |
-
* @since 1.0.3
|
304 |
-
*
|
305 |
-
* @param string $option
|
306 |
-
* @param bool $flush
|
307 |
-
*/
|
308 |
-
function unset_option( $option, $flush = false ) {
|
309 |
-
$this->_logger->entrance( 'option = ' . $option );
|
310 |
-
|
311 |
-
if ( is_array( $this->_options ) ) {
|
312 |
-
if ( ! isset( $this->_options[ $option ] ) ) {
|
313 |
-
return;
|
314 |
-
}
|
315 |
-
|
316 |
-
unset( $this->_options[ $option ] );
|
317 |
-
|
318 |
-
} else if ( is_object( $this->_options ) ) {
|
319 |
-
if ( ! isset( $this->_options->{$option} ) ) {
|
320 |
-
return;
|
321 |
-
}
|
322 |
-
|
323 |
-
unset( $this->_options->{$option} );
|
324 |
-
}
|
325 |
-
|
326 |
-
if ( $flush ) {
|
327 |
-
$this->store();
|
328 |
-
}
|
329 |
-
}
|
330 |
-
|
331 |
-
/**
|
332 |
-
* Dump options to database.
|
333 |
-
*
|
334 |
-
* @author Vova Feldman (@svovaf)
|
335 |
-
* @since 1.0.3
|
336 |
-
*/
|
337 |
-
function store() {
|
338 |
-
$this->_logger->entrance();
|
339 |
-
|
340 |
-
$option_name = $this->_get_option_manager_name();
|
341 |
-
|
342 |
-
if ( $this->_logger->is_on() ) {
|
343 |
-
$this->_logger->info( $option_name . ' = ' . var_export( $this->_options, true ) );
|
344 |
-
}
|
345 |
-
|
346 |
-
// Update DB.
|
347 |
-
update_option( $option_name, $this->_options );
|
348 |
-
|
349 |
-
if ( ! WP_FS__DEBUG_SDK ) {
|
350 |
-
wp_cache_set( $option_name, $this->_options, WP_FS__SLUG );
|
351 |
-
}
|
352 |
-
}
|
353 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* 3-layer lazy options manager.
|
15 |
+
* layer 3: Memory
|
16 |
+
* layer 2: Cache (if there's any caching plugin and if WP_FS__DEBUG_SDK is FALSE)
|
17 |
+
* layer 1: Database (options table). All options stored as one option record in the DB to reduce number of DB
|
18 |
+
* queries.
|
19 |
+
*
|
20 |
+
* If load() is not explicitly called, starts as empty manager. Same thing about saving the data - you have to
|
21 |
+
* explicitly call store().
|
22 |
+
*
|
23 |
+
* Class Freemius_Option_Manager
|
24 |
+
*/
|
25 |
+
class FS_Option_Manager {
|
26 |
+
/**
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
private $_id;
|
30 |
+
/**
|
31 |
+
* @var array
|
32 |
+
*/
|
33 |
+
private $_options;
|
34 |
+
/**
|
35 |
+
* @var FS_Logger
|
36 |
+
*/
|
37 |
+
private $_logger;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @var FS_Option_Manager[]
|
41 |
+
*/
|
42 |
+
private static $_MANAGERS = array();
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @author Vova Feldman (@svovaf)
|
46 |
+
* @since 1.0.3
|
47 |
+
*
|
48 |
+
* @param string $id
|
49 |
+
* @param bool $load
|
50 |
+
*/
|
51 |
+
private function __construct( $id, $load = false ) {
|
52 |
+
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_opt_mngr_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
53 |
+
|
54 |
+
$this->_logger->entrance();
|
55 |
+
$this->_logger->log( 'id = ' . $id );
|
56 |
+
|
57 |
+
$this->_id = $id;
|
58 |
+
|
59 |
+
if ( $load ) {
|
60 |
+
$this->load();
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* @author Vova Feldman (@svovaf)
|
66 |
+
* @since 1.0.3
|
67 |
+
*
|
68 |
+
* @param $id
|
69 |
+
* @param $load
|
70 |
+
*
|
71 |
+
* @return FS_Option_Manager
|
72 |
+
*/
|
73 |
+
static function get_manager( $id, $load = false ) {
|
74 |
+
$id = strtolower( $id );
|
75 |
+
|
76 |
+
if ( ! isset( self::$_MANAGERS[ $id ] ) ) {
|
77 |
+
self::$_MANAGERS[ $id ] = new FS_Option_Manager( $id, $load );
|
78 |
+
} // If load required but not yet loaded, load.
|
79 |
+
else if ( $load && ! self::$_MANAGERS[ $id ]->is_loaded() ) {
|
80 |
+
self::$_MANAGERS[ $id ]->load();
|
81 |
+
}
|
82 |
+
|
83 |
+
return self::$_MANAGERS[ $id ];
|
84 |
+
}
|
85 |
+
|
86 |
+
private function _get_option_manager_name() {
|
87 |
+
// return WP_FS__SLUG . '_' . $this->_id;
|
88 |
+
return $this->_id;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @author Vova Feldman (@svovaf)
|
93 |
+
* @since 1.0.3
|
94 |
+
*
|
95 |
+
* @param bool $flush
|
96 |
+
*/
|
97 |
+
function load( $flush = false ) {
|
98 |
+
$this->_logger->entrance();
|
99 |
+
|
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 |
+
}
|
111 |
+
|
112 |
+
// $this->_logger->info('wp_cache_get = ' . var_export($this->_options, true));
|
113 |
+
|
114 |
+
// if ( is_array( $this->_options ) ) {
|
115 |
+
// $this->clear();
|
116 |
+
// }
|
117 |
+
|
118 |
+
$cached = true;
|
119 |
+
|
120 |
+
if ( empty( $this->_options ) ) {
|
121 |
+
$this->_options = get_option( $option_name );
|
122 |
+
|
123 |
+
if ( is_string( $this->_options ) ) {
|
124 |
+
$this->_options = json_decode( $this->_options );
|
125 |
+
}
|
126 |
+
|
127 |
+
// $this->_logger->info('get_option = ' . var_export($this->_options, true));
|
128 |
+
|
129 |
+
if ( false === $this->_options ) {
|
130 |
+
$this->clear();
|
131 |
+
}
|
132 |
+
|
133 |
+
$cached = false;
|
134 |
+
}
|
135 |
+
|
136 |
+
if ( ! WP_FS__DEBUG_SDK && ! $cached ) // Set non encoded cache.
|
137 |
+
{
|
138 |
+
wp_cache_set( $option_name, $this->_options, WP_FS__SLUG );
|
139 |
+
}
|
140 |
+
}
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* @author Vova Feldman (@svovaf)
|
145 |
+
* @since 1.0.3
|
146 |
+
*
|
147 |
+
* @return bool
|
148 |
+
*/
|
149 |
+
function is_loaded() {
|
150 |
+
return isset( $this->_options );
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* @author Vova Feldman (@svovaf)
|
155 |
+
* @since 1.0.3
|
156 |
+
*
|
157 |
+
* @return bool
|
158 |
+
*/
|
159 |
+
function is_empty() {
|
160 |
+
return ( $this->is_loaded() && false === $this->_options );
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* @author Vova Feldman (@svovaf)
|
165 |
+
* @since 1.0.6
|
166 |
+
*
|
167 |
+
* @param bool $flush
|
168 |
+
*/
|
169 |
+
function clear( $flush = false ) {
|
170 |
+
$this->_logger->entrance();
|
171 |
+
|
172 |
+
$this->_options = array();
|
173 |
+
|
174 |
+
if ( $flush ) {
|
175 |
+
$this->store();
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Delete options manager from DB.
|
181 |
+
*
|
182 |
+
* @author Vova Feldman (@svovaf)
|
183 |
+
* @since 1.0.9
|
184 |
+
*/
|
185 |
+
function delete() {
|
186 |
+
delete_option( $this->_get_option_manager_name() );
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* @author Vova Feldman (@svovaf)
|
191 |
+
* @since 1.0.6
|
192 |
+
*
|
193 |
+
* @param string $option
|
194 |
+
*
|
195 |
+
* @return bool
|
196 |
+
*/
|
197 |
+
function has_option( $option ) {
|
198 |
+
return array_key_exists( $option, $this->_options );
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* @author Vova Feldman (@svovaf)
|
203 |
+
* @since 1.0.3
|
204 |
+
*
|
205 |
+
* @param string $option
|
206 |
+
* @param mixed $default
|
207 |
+
*
|
208 |
+
* @return mixed
|
209 |
+
*/
|
210 |
+
function get_option( $option, $default = null ) {
|
211 |
+
$this->_logger->entrance( 'option = ' . $option );
|
212 |
+
|
213 |
+
if ( is_array( $this->_options ) ) {
|
214 |
+
$value = isset( $this->_options[ $option ] ) ?
|
215 |
+
$this->_options[ $option ] :
|
216 |
+
$default;
|
217 |
+
} else if ( is_object( $this->_options ) ) {
|
218 |
+
$value = isset( $this->_options->{$option} ) ?
|
219 |
+
$this->_options->{$option} :
|
220 |
+
$default;
|
221 |
+
} else {
|
222 |
+
$value = $default;
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* If it's an object, return a clone of the object, otherwise,
|
227 |
+
* external changes of the object will actually change the value
|
228 |
+
* of the object in the options manager which may lead to an unexpected
|
229 |
+
* behaviour and data integrity when a store() call is triggered.
|
230 |
+
*
|
231 |
+
* Example:
|
232 |
+
* $object1 = $options->get_option( 'object1' );
|
233 |
+
* $object1->x = 123;
|
234 |
+
*
|
235 |
+
* $object2 = $options->get_option( 'object2' );
|
236 |
+
* $object2->y = 'dummy';
|
237 |
+
*
|
238 |
+
* $options->set_option( 'object2', $object2, true );
|
239 |
+
*
|
240 |
+
* If we don't return a clone of option 'object1', setting 'object2'
|
241 |
+
* will also store the updated value of 'object1' which is quite not
|
242 |
+
* an expected behaviour.
|
243 |
+
*
|
244 |
+
* @author Vova Feldman
|
245 |
+
*/
|
246 |
+
return is_object($value) ? clone $value : $value;
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* @author Vova Feldman (@svovaf)
|
251 |
+
* @since 1.0.3
|
252 |
+
*
|
253 |
+
* @param string $option
|
254 |
+
* @param mixed $value
|
255 |
+
* @param bool $flush
|
256 |
+
*/
|
257 |
+
function set_option( $option, $value, $flush = false ) {
|
258 |
+
$this->_logger->entrance( 'option = ' . $option );
|
259 |
+
|
260 |
+
if ( ! $this->is_loaded() ) {
|
261 |
+
$this->clear();
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* If it's an object, store a clone of the object, otherwise,
|
266 |
+
* external changes of the object will actually change the value
|
267 |
+
* of the object in the options manager which may lead to an unexpected
|
268 |
+
* behaviour and data integrity when a store() call is triggered.
|
269 |
+
*
|
270 |
+
* Example:
|
271 |
+
* $object1 = new stdClass();
|
272 |
+
* $object1->x = 123;
|
273 |
+
*
|
274 |
+
* $options->set_option( 'object1', $object1 );
|
275 |
+
*
|
276 |
+
* $object1->x = 456;
|
277 |
+
*
|
278 |
+
* $options->set_option( 'object2', $object2, true );
|
279 |
+
*
|
280 |
+
* If we don't set the option as a clone of option 'object1', setting 'object2'
|
281 |
+
* will also store the updated value of 'object1' ($object1->x = 456 instead of
|
282 |
+
* $object1->x = 123) which is quite not an expected behaviour.
|
283 |
+
*
|
284 |
+
* @author Vova Feldman
|
285 |
+
*/
|
286 |
+
$copy = is_object($value) ? clone $value : $value;
|
287 |
+
|
288 |
+
if ( is_array( $this->_options ) ) {
|
289 |
+
$this->_options[ $option ] = $copy;
|
290 |
+
} else if ( is_object( $this->_options ) ) {
|
291 |
+
$this->_options->{$option} = $copy;
|
292 |
+
}
|
293 |
+
|
294 |
+
if ( $flush ) {
|
295 |
+
$this->store();
|
296 |
+
}
|
297 |
+
}
|
298 |
+
|
299 |
+
/**
|
300 |
+
* Unset option.
|
301 |
+
*
|
302 |
+
* @author Vova Feldman (@svovaf)
|
303 |
+
* @since 1.0.3
|
304 |
+
*
|
305 |
+
* @param string $option
|
306 |
+
* @param bool $flush
|
307 |
+
*/
|
308 |
+
function unset_option( $option, $flush = false ) {
|
309 |
+
$this->_logger->entrance( 'option = ' . $option );
|
310 |
+
|
311 |
+
if ( is_array( $this->_options ) ) {
|
312 |
+
if ( ! isset( $this->_options[ $option ] ) ) {
|
313 |
+
return;
|
314 |
+
}
|
315 |
+
|
316 |
+
unset( $this->_options[ $option ] );
|
317 |
+
|
318 |
+
} else if ( is_object( $this->_options ) ) {
|
319 |
+
if ( ! isset( $this->_options->{$option} ) ) {
|
320 |
+
return;
|
321 |
+
}
|
322 |
+
|
323 |
+
unset( $this->_options->{$option} );
|
324 |
+
}
|
325 |
+
|
326 |
+
if ( $flush ) {
|
327 |
+
$this->store();
|
328 |
+
}
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Dump options to database.
|
333 |
+
*
|
334 |
+
* @author Vova Feldman (@svovaf)
|
335 |
+
* @since 1.0.3
|
336 |
+
*/
|
337 |
+
function store() {
|
338 |
+
$this->_logger->entrance();
|
339 |
+
|
340 |
+
$option_name = $this->_get_option_manager_name();
|
341 |
+
|
342 |
+
if ( $this->_logger->is_on() ) {
|
343 |
+
$this->_logger->info( $option_name . ' = ' . var_export( $this->_options, true ) );
|
344 |
+
}
|
345 |
+
|
346 |
+
// Update DB.
|
347 |
+
update_option( $option_name, $this->_options );
|
348 |
+
|
349 |
+
if ( ! WP_FS__DEBUG_SDK ) {
|
350 |
+
wp_cache_set( $option_name, $this->_options, WP_FS__SLUG );
|
351 |
+
}
|
352 |
+
}
|
353 |
}
|
freemius/includes/managers/class-fs-plugin-manager.php
CHANGED
@@ -1,220 +1,220 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.6
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
class FS_Plugin_Manager {
|
14 |
-
/**
|
15 |
-
* @since 1.2.2
|
16 |
-
*
|
17 |
-
* @var string|number
|
18 |
-
*/
|
19 |
-
protected $_module_id;
|
20 |
-
/**
|
21 |
-
* @since 1.2.2
|
22 |
-
*
|
23 |
-
* @var FS_Plugin
|
24 |
-
*/
|
25 |
-
protected $_module;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* @var FS_Plugin_Manager[]
|
29 |
-
*/
|
30 |
-
private static $_instances = array();
|
31 |
-
/**
|
32 |
-
* @var FS_Logger
|
33 |
-
*/
|
34 |
-
protected $_logger;
|
35 |
-
|
36 |
-
/**
|
37 |
-
* Option names
|
38 |
-
*
|
39 |
-
* @author Leo Fajardo (@leorw)
|
40 |
-
* @since 1.2.2
|
41 |
-
*/
|
42 |
-
const OPTION_NAME_PLUGINS = 'plugins';
|
43 |
-
const OPTION_NAME_THEMES = 'themes';
|
44 |
-
|
45 |
-
/**
|
46 |
-
* @param string|number $module_id
|
47 |
-
*
|
48 |
-
* @return FS_Plugin_Manager
|
49 |
-
*/
|
50 |
-
static function instance( $module_id ) {
|
51 |
-
$key = 'm_' . $module_id;
|
52 |
-
|
53 |
-
if ( ! isset( self::$_instances[ $key ] ) ) {
|
54 |
-
self::$_instances[ $key ] = new FS_Plugin_Manager( $module_id );
|
55 |
-
}
|
56 |
-
|
57 |
-
return self::$_instances[ $key ];
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* @param string|number $module_id
|
62 |
-
*/
|
63 |
-
protected function __construct( $module_id ) {
|
64 |
-
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $module_id . '_' . 'plugins', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
65 |
-
$this->_module_id = $module_id;
|
66 |
-
|
67 |
-
$this->load();
|
68 |
-
}
|
69 |
-
|
70 |
-
protected function get_option_manager() {
|
71 |
-
return FS_Option_Manager::get_manager( WP_FS__ACCOUNTS_OPTION_NAME, true );
|
72 |
-
}
|
73 |
-
|
74 |
-
/**
|
75 |
-
* @author Leo Fajardo (@leorw)
|
76 |
-
* @since 1.2.2
|
77 |
-
*
|
78 |
-
* @param string|false $module_type "plugin", "theme", or "false" for all modules.
|
79 |
-
*
|
80 |
-
* @return array
|
81 |
-
*/
|
82 |
-
protected function get_all_modules( $module_type = false ) {
|
83 |
-
$option_manager = $this->get_option_manager();
|
84 |
-
|
85 |
-
if ( false !== $module_type ) {
|
86 |
-
return $option_manager->get_option( $module_type . 's', array() );
|
87 |
-
}
|
88 |
-
|
89 |
-
return array(
|
90 |
-
self::OPTION_NAME_PLUGINS => $option_manager->get_option( self::OPTION_NAME_PLUGINS, array() ),
|
91 |
-
self::OPTION_NAME_THEMES => $option_manager->get_option( self::OPTION_NAME_THEMES, array() ),
|
92 |
-
);
|
93 |
-
}
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Load plugin data from local DB.
|
97 |
-
*
|
98 |
-
* @author Vova Feldman (@svovaf)
|
99 |
-
* @since 1.0.6
|
100 |
-
*/
|
101 |
-
function load() {
|
102 |
-
$all_modules = $this->get_all_modules();
|
103 |
-
|
104 |
-
if ( ! is_numeric( $this->_module_id ) ) {
|
105 |
-
unset( $all_modules[ self::OPTION_NAME_THEMES ] );
|
106 |
-
}
|
107 |
-
|
108 |
-
foreach ( $all_modules as $modules ) {
|
109 |
-
/**
|
110 |
-
* @since 1.2.2
|
111 |
-
*
|
112 |
-
* @var $modules FS_Plugin[]
|
113 |
-
*/
|
114 |
-
foreach ( $modules as $module ) {
|
115 |
-
$found_module = false;
|
116 |
-
|
117 |
-
/**
|
118 |
-
* If module ID is not numeric, it must be a plugin's slug.
|
119 |
-
*
|
120 |
-
* @author Leo Fajardo (@leorw)
|
121 |
-
* @since 1.2.2
|
122 |
-
*/
|
123 |
-
if ( ! is_numeric( $this->_module_id ) ) {
|
124 |
-
if ( $this->_module_id === $module->slug ) {
|
125 |
-
$this->_module_id = $module->id;
|
126 |
-
$found_module = true;
|
127 |
-
}
|
128 |
-
} else if ( $this->_module_id == $module->id ) {
|
129 |
-
$found_module = true;
|
130 |
-
}
|
131 |
-
|
132 |
-
if ( $found_module ) {
|
133 |
-
$this->_module = $module;
|
134 |
-
break;
|
135 |
-
}
|
136 |
-
}
|
137 |
-
}
|
138 |
-
}
|
139 |
-
|
140 |
-
/**
|
141 |
-
* Store plugin on local DB.
|
142 |
-
*
|
143 |
-
* @author Vova Feldman (@svovaf)
|
144 |
-
* @since 1.0.6
|
145 |
-
*
|
146 |
-
* @param bool|FS_Plugin $module
|
147 |
-
* @param bool $flush
|
148 |
-
*
|
149 |
-
* @return bool|\FS_Plugin
|
150 |
-
*/
|
151 |
-
function store( $module = false, $flush = true ) {
|
152 |
-
if ( false !== $module ) {
|
153 |
-
$this->_module = $module;
|
154 |
-
}
|
155 |
-
|
156 |
-
$all_modules = $this->get_all_modules( $this->_module->type );
|
157 |
-
$all_modules[ $this->_module->slug ] = $this->_module;
|
158 |
-
|
159 |
-
$options_manager = $this->get_option_manager();
|
160 |
-
$options_manager->set_option( $this->_module->type . 's', $all_modules, $flush );
|
161 |
-
|
162 |
-
return $this->_module;
|
163 |
-
}
|
164 |
-
|
165 |
-
/**
|
166 |
-
* Update local plugin data if different.
|
167 |
-
*
|
168 |
-
* @author Vova Feldman (@svovaf)
|
169 |
-
* @since 1.0.6
|
170 |
-
*
|
171 |
-
* @param \FS_Plugin $plugin
|
172 |
-
* @param bool $store
|
173 |
-
*
|
174 |
-
* @return bool True if plugin was updated.
|
175 |
-
*/
|
176 |
-
function update( FS_Plugin $plugin, $store = true ) {
|
177 |
-
if ( ! ($this->_module instanceof FS_Plugin ) ||
|
178 |
-
$this->_module->slug != $plugin->slug ||
|
179 |
-
$this->_module->public_key != $plugin->public_key ||
|
180 |
-
$this->_module->secret_key != $plugin->secret_key ||
|
181 |
-
$this->_module->parent_plugin_id != $plugin->parent_plugin_id ||
|
182 |
-
$this->_module->title != $plugin->title
|
183 |
-
) {
|
184 |
-
$this->store( $plugin, $store );
|
185 |
-
|
186 |
-
return true;
|
187 |
-
}
|
188 |
-
|
189 |
-
return false;
|
190 |
-
}
|
191 |
-
|
192 |
-
/**
|
193 |
-
* @author Vova Feldman (@svovaf)
|
194 |
-
* @since 1.0.6
|
195 |
-
*
|
196 |
-
* @param FS_Plugin $plugin
|
197 |
-
* @param bool $store
|
198 |
-
*/
|
199 |
-
function set( FS_Plugin $plugin, $store = false ) {
|
200 |
-
$this->_module = $plugin;
|
201 |
-
|
202 |
-
if ( $store ) {
|
203 |
-
$this->store();
|
204 |
-
}
|
205 |
-
}
|
206 |
-
|
207 |
-
/**
|
208 |
-
* @author Vova Feldman (@svovaf)
|
209 |
-
* @since 1.0.6
|
210 |
-
*
|
211 |
-
* @return bool|\FS_Plugin
|
212 |
-
*/
|
213 |
-
function get() {
|
214 |
-
return isset( $this->_module ) ?
|
215 |
-
$this->_module :
|
216 |
-
false;
|
217 |
-
}
|
218 |
-
|
219 |
-
|
220 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.6
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
class FS_Plugin_Manager {
|
14 |
+
/**
|
15 |
+
* @since 1.2.2
|
16 |
+
*
|
17 |
+
* @var string|number
|
18 |
+
*/
|
19 |
+
protected $_module_id;
|
20 |
+
/**
|
21 |
+
* @since 1.2.2
|
22 |
+
*
|
23 |
+
* @var FS_Plugin
|
24 |
+
*/
|
25 |
+
protected $_module;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var FS_Plugin_Manager[]
|
29 |
+
*/
|
30 |
+
private static $_instances = array();
|
31 |
+
/**
|
32 |
+
* @var FS_Logger
|
33 |
+
*/
|
34 |
+
protected $_logger;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Option names
|
38 |
+
*
|
39 |
+
* @author Leo Fajardo (@leorw)
|
40 |
+
* @since 1.2.2
|
41 |
+
*/
|
42 |
+
const OPTION_NAME_PLUGINS = 'plugins';
|
43 |
+
const OPTION_NAME_THEMES = 'themes';
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @param string|number $module_id
|
47 |
+
*
|
48 |
+
* @return FS_Plugin_Manager
|
49 |
+
*/
|
50 |
+
static function instance( $module_id ) {
|
51 |
+
$key = 'm_' . $module_id;
|
52 |
+
|
53 |
+
if ( ! isset( self::$_instances[ $key ] ) ) {
|
54 |
+
self::$_instances[ $key ] = new FS_Plugin_Manager( $module_id );
|
55 |
+
}
|
56 |
+
|
57 |
+
return self::$_instances[ $key ];
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @param string|number $module_id
|
62 |
+
*/
|
63 |
+
protected function __construct( $module_id ) {
|
64 |
+
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $module_id . '_' . 'plugins', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
|
65 |
+
$this->_module_id = $module_id;
|
66 |
+
|
67 |
+
$this->load();
|
68 |
+
}
|
69 |
+
|
70 |
+
protected function get_option_manager() {
|
71 |
+
return FS_Option_Manager::get_manager( WP_FS__ACCOUNTS_OPTION_NAME, true );
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @author Leo Fajardo (@leorw)
|
76 |
+
* @since 1.2.2
|
77 |
+
*
|
78 |
+
* @param string|false $module_type "plugin", "theme", or "false" for all modules.
|
79 |
+
*
|
80 |
+
* @return array
|
81 |
+
*/
|
82 |
+
protected function get_all_modules( $module_type = false ) {
|
83 |
+
$option_manager = $this->get_option_manager();
|
84 |
+
|
85 |
+
if ( false !== $module_type ) {
|
86 |
+
return $option_manager->get_option( $module_type . 's', array() );
|
87 |
+
}
|
88 |
+
|
89 |
+
return array(
|
90 |
+
self::OPTION_NAME_PLUGINS => $option_manager->get_option( self::OPTION_NAME_PLUGINS, array() ),
|
91 |
+
self::OPTION_NAME_THEMES => $option_manager->get_option( self::OPTION_NAME_THEMES, array() ),
|
92 |
+
);
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Load plugin data from local DB.
|
97 |
+
*
|
98 |
+
* @author Vova Feldman (@svovaf)
|
99 |
+
* @since 1.0.6
|
100 |
+
*/
|
101 |
+
function load() {
|
102 |
+
$all_modules = $this->get_all_modules();
|
103 |
+
|
104 |
+
if ( ! is_numeric( $this->_module_id ) ) {
|
105 |
+
unset( $all_modules[ self::OPTION_NAME_THEMES ] );
|
106 |
+
}
|
107 |
+
|
108 |
+
foreach ( $all_modules as $modules ) {
|
109 |
+
/**
|
110 |
+
* @since 1.2.2
|
111 |
+
*
|
112 |
+
* @var $modules FS_Plugin[]
|
113 |
+
*/
|
114 |
+
foreach ( $modules as $module ) {
|
115 |
+
$found_module = false;
|
116 |
+
|
117 |
+
/**
|
118 |
+
* If module ID is not numeric, it must be a plugin's slug.
|
119 |
+
*
|
120 |
+
* @author Leo Fajardo (@leorw)
|
121 |
+
* @since 1.2.2
|
122 |
+
*/
|
123 |
+
if ( ! is_numeric( $this->_module_id ) ) {
|
124 |
+
if ( $this->_module_id === $module->slug ) {
|
125 |
+
$this->_module_id = $module->id;
|
126 |
+
$found_module = true;
|
127 |
+
}
|
128 |
+
} else if ( $this->_module_id == $module->id ) {
|
129 |
+
$found_module = true;
|
130 |
+
}
|
131 |
+
|
132 |
+
if ( $found_module ) {
|
133 |
+
$this->_module = $module;
|
134 |
+
break;
|
135 |
+
}
|
136 |
+
}
|
137 |
+
}
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Store plugin on local DB.
|
142 |
+
*
|
143 |
+
* @author Vova Feldman (@svovaf)
|
144 |
+
* @since 1.0.6
|
145 |
+
*
|
146 |
+
* @param bool|FS_Plugin $module
|
147 |
+
* @param bool $flush
|
148 |
+
*
|
149 |
+
* @return bool|\FS_Plugin
|
150 |
+
*/
|
151 |
+
function store( $module = false, $flush = true ) {
|
152 |
+
if ( false !== $module ) {
|
153 |
+
$this->_module = $module;
|
154 |
+
}
|
155 |
+
|
156 |
+
$all_modules = $this->get_all_modules( $this->_module->type );
|
157 |
+
$all_modules[ $this->_module->slug ] = $this->_module;
|
158 |
+
|
159 |
+
$options_manager = $this->get_option_manager();
|
160 |
+
$options_manager->set_option( $this->_module->type . 's', $all_modules, $flush );
|
161 |
+
|
162 |
+
return $this->_module;
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Update local plugin data if different.
|
167 |
+
*
|
168 |
+
* @author Vova Feldman (@svovaf)
|
169 |
+
* @since 1.0.6
|
170 |
+
*
|
171 |
+
* @param \FS_Plugin $plugin
|
172 |
+
* @param bool $store
|
173 |
+
*
|
174 |
+
* @return bool True if plugin was updated.
|
175 |
+
*/
|
176 |
+
function update( FS_Plugin $plugin, $store = true ) {
|
177 |
+
if ( ! ($this->_module instanceof FS_Plugin ) ||
|
178 |
+
$this->_module->slug != $plugin->slug ||
|
179 |
+
$this->_module->public_key != $plugin->public_key ||
|
180 |
+
$this->_module->secret_key != $plugin->secret_key ||
|
181 |
+
$this->_module->parent_plugin_id != $plugin->parent_plugin_id ||
|
182 |
+
$this->_module->title != $plugin->title
|
183 |
+
) {
|
184 |
+
$this->store( $plugin, $store );
|
185 |
+
|
186 |
+
return true;
|
187 |
+
}
|
188 |
+
|
189 |
+
return false;
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* @author Vova Feldman (@svovaf)
|
194 |
+
* @since 1.0.6
|
195 |
+
*
|
196 |
+
* @param FS_Plugin $plugin
|
197 |
+
* @param bool $store
|
198 |
+
*/
|
199 |
+
function set( FS_Plugin $plugin, $store = false ) {
|
200 |
+
$this->_module = $plugin;
|
201 |
+
|
202 |
+
if ( $store ) {
|
203 |
+
$this->store();
|
204 |
+
}
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
* @author Vova Feldman (@svovaf)
|
209 |
+
* @since 1.0.6
|
210 |
+
*
|
211 |
+
* @return bool|\FS_Plugin
|
212 |
+
*/
|
213 |
+
function get() {
|
214 |
+
return isset( $this->_module ) ?
|
215 |
+
$this->_module :
|
216 |
+
false;
|
217 |
+
}
|
218 |
+
|
219 |
+
|
220 |
}
|
freemius/includes/supplements/fs-essential-functions-1.1.7.1.php
CHANGED
@@ -1,47 +1,47 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.1.7
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Find the plugin main file path based on any give file inside the plugin's folder.
|
15 |
-
*
|
16 |
-
* @author Vova Feldman (@svovaf)
|
17 |
-
* @since 1.1.7.1
|
18 |
-
*
|
19 |
-
* @param string $file Absolute path to a file inside a plugin's folder.
|
20 |
-
*
|
21 |
-
* @return string
|
22 |
-
*/
|
23 |
-
function fs_find_direct_caller_plugin_file( $file ) {
|
24 |
-
/**
|
25 |
-
* All the code below will be executed once on activation.
|
26 |
-
* If the user changes the main plugin's file name, the file_exists()
|
27 |
-
* will catch it.
|
28 |
-
*/
|
29 |
-
if ( ! function_exists( 'get_plugins' ) ) {
|
30 |
-
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
31 |
-
}
|
32 |
-
|
33 |
-
$all_plugins = get_plugins();
|
34 |
-
|
35 |
-
$file_real_path = fs_normalize_path( realpath( $file ) );
|
36 |
-
|
37 |
-
// Get active plugin's main files real full names (might be symlinks).
|
38 |
-
foreach ( $all_plugins as $relative_path => &$data ) {
|
39 |
-
if ( 0 === strpos( $file_real_path, fs_normalize_path( dirname( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) ) ) ) ) {
|
40 |
-
if ( '.' !== dirname( trailingslashit( $relative_path ) ) ) {
|
41 |
-
return $relative_path;
|
42 |
-
}
|
43 |
-
}
|
44 |
-
}
|
45 |
-
|
46 |
-
return null;
|
47 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.1.7
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Find the plugin main file path based on any give file inside the plugin's folder.
|
15 |
+
*
|
16 |
+
* @author Vova Feldman (@svovaf)
|
17 |
+
* @since 1.1.7.1
|
18 |
+
*
|
19 |
+
* @param string $file Absolute path to a file inside a plugin's folder.
|
20 |
+
*
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
function fs_find_direct_caller_plugin_file( $file ) {
|
24 |
+
/**
|
25 |
+
* All the code below will be executed once on activation.
|
26 |
+
* If the user changes the main plugin's file name, the file_exists()
|
27 |
+
* will catch it.
|
28 |
+
*/
|
29 |
+
if ( ! function_exists( 'get_plugins' ) ) {
|
30 |
+
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
31 |
+
}
|
32 |
+
|
33 |
+
$all_plugins = get_plugins();
|
34 |
+
|
35 |
+
$file_real_path = fs_normalize_path( realpath( $file ) );
|
36 |
+
|
37 |
+
// Get active plugin's main files real full names (might be symlinks).
|
38 |
+
foreach ( $all_plugins as $relative_path => &$data ) {
|
39 |
+
if ( 0 === strpos( $file_real_path, fs_normalize_path( dirname( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) ) ) ) ) {
|
40 |
+
if ( '.' !== dirname( trailingslashit( $relative_path ) ) ) {
|
41 |
+
return $relative_path;
|
42 |
+
}
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
return null;
|
47 |
+
}
|
freemius/package.json
CHANGED
@@ -1,27 +1,27 @@
|
|
1 |
-
{
|
2 |
-
"name": "freemius-wordpress-sdk",
|
3 |
-
"description": "Monetization, analytics, and marketing automation platform for plugin & theme developers.",
|
4 |
-
"author": "Freemius, Inc.",
|
5 |
-
"license": "GPL-3.0",
|
6 |
-
"homepage": "https://freemius.com",
|
7 |
-
"version": "1.2.3",
|
8 |
-
"main": "gulpfile.js",
|
9 |
-
"dependencies": {},
|
10 |
-
"scripts": {
|
11 |
-
"test": "echo \"Error: no test specified\" && exit 1",
|
12 |
-
"prune": "rimraf .codeclimate.yml .git .github .gitignore .travis.yml gulpfile.js composer.json"
|
13 |
-
},
|
14 |
-
"repository": "Freemius/wordpress-sdk.git",
|
15 |
-
"devDependencies": {
|
16 |
-
"gulp": "^3.9.1",
|
17 |
-
"gulp-clean": "^0.3.2",
|
18 |
-
"gulp-fs": "0.0.2",
|
19 |
-
"gulp-gettext": "^0.3.0",
|
20 |
-
"gulp-path": "^3.0.3",
|
21 |
-
"gulp-pofill": "^1.0.0",
|
22 |
-
"gulp-rename": "^1.2.2",
|
23 |
-
"gulp-sort": "^2.0.0",
|
24 |
-
"gulp-transifex": "^0.1.17",
|
25 |
-
"gulp-wp-pot": "^1.3.5"
|
26 |
-
}
|
27 |
-
}
|
1 |
+
{
|
2 |
+
"name": "freemius-wordpress-sdk",
|
3 |
+
"description": "Monetization, analytics, and marketing automation platform for plugin & theme developers.",
|
4 |
+
"author": "Freemius, Inc.",
|
5 |
+
"license": "GPL-3.0",
|
6 |
+
"homepage": "https://freemius.com",
|
7 |
+
"version": "1.2.3",
|
8 |
+
"main": "gulpfile.js",
|
9 |
+
"dependencies": {},
|
10 |
+
"scripts": {
|
11 |
+
"test": "echo \"Error: no test specified\" && exit 1",
|
12 |
+
"prune": "rimraf .codeclimate.yml .git .github .gitignore .travis.yml gulpfile.js composer.json"
|
13 |
+
},
|
14 |
+
"repository": "Freemius/wordpress-sdk.git",
|
15 |
+
"devDependencies": {
|
16 |
+
"gulp": "^3.9.1",
|
17 |
+
"gulp-clean": "^0.3.2",
|
18 |
+
"gulp-fs": "0.0.2",
|
19 |
+
"gulp-gettext": "^0.3.0",
|
20 |
+
"gulp-path": "^3.0.3",
|
21 |
+
"gulp-pofill": "^1.0.0",
|
22 |
+
"gulp-rename": "^1.2.2",
|
23 |
+
"gulp-sort": "^2.0.0",
|
24 |
+
"gulp-transifex": "^0.1.17",
|
25 |
+
"gulp-wp-pot": "^1.3.5"
|
26 |
+
}
|
27 |
+
}
|
freemius/require.php
CHANGED
@@ -1,45 +1,45 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2016, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.1.9
|
7 |
-
*/
|
8 |
-
|
9 |
-
// Configuration should be loaded first.
|
10 |
-
require_once dirname( __FILE__ ) . '/config.php';
|
11 |
-
require_once WP_FS__DIR_INCLUDES . '/fs-core-functions.php';
|
12 |
-
|
13 |
-
// Logger must be loaded before any other.
|
14 |
-
require_once WP_FS__DIR_INCLUDES . '/class-fs-logger.php';
|
15 |
-
require_once WP_FS__DIR_INCLUDES . '/debug/debug-bar-start.php';
|
16 |
-
|
17 |
-
// require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-abstract-manager.php';
|
18 |
-
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-option-manager.php';
|
19 |
-
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-cache-manager.php';
|
20 |
-
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-admin-notice-manager.php';
|
21 |
-
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-admin-menu-manager.php';
|
22 |
-
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-key-value-storage.php';
|
23 |
-
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-license-manager.php';
|
24 |
-
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-plan-manager.php';
|
25 |
-
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-plugin-manager.php';
|
26 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-entity.php';
|
27 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-scope-entity.php';
|
28 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-user.php';
|
29 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-site.php';
|
30 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-plugin.php';
|
31 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-affiliate.php';
|
32 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-affiliate-terms.php';
|
33 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-plugin-info.php';
|
34 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-plugin-tag.php';
|
35 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-plugin-plan.php';
|
36 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-pricing.php';
|
37 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-payment.php';
|
38 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-plugin-license.php';
|
39 |
-
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-subscription.php';
|
40 |
-
require_once WP_FS__DIR_INCLUDES . '/class-fs-api.php';
|
41 |
-
require_once WP_FS__DIR_INCLUDES . '/class-fs-plugin-updater.php';
|
42 |
-
require_once WP_FS__DIR_INCLUDES . '/class-fs-security.php';
|
43 |
-
require_once WP_FS__DIR_INCLUDES . '/class-freemius-abstract.php';
|
44 |
-
require_once WP_FS__DIR_INCLUDES . '/sdk/Exceptions/Exception.php';
|
45 |
require_once WP_FS__DIR_INCLUDES . '/class-freemius.php';
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2016, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.1.9
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Configuration should be loaded first.
|
10 |
+
require_once dirname( __FILE__ ) . '/config.php';
|
11 |
+
require_once WP_FS__DIR_INCLUDES . '/fs-core-functions.php';
|
12 |
+
|
13 |
+
// Logger must be loaded before any other.
|
14 |
+
require_once WP_FS__DIR_INCLUDES . '/class-fs-logger.php';
|
15 |
+
require_once WP_FS__DIR_INCLUDES . '/debug/debug-bar-start.php';
|
16 |
+
|
17 |
+
// require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-abstract-manager.php';
|
18 |
+
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-option-manager.php';
|
19 |
+
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-cache-manager.php';
|
20 |
+
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-admin-notice-manager.php';
|
21 |
+
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-admin-menu-manager.php';
|
22 |
+
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-key-value-storage.php';
|
23 |
+
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-license-manager.php';
|
24 |
+
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-plan-manager.php';
|
25 |
+
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-plugin-manager.php';
|
26 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-entity.php';
|
27 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-scope-entity.php';
|
28 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-user.php';
|
29 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-site.php';
|
30 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-plugin.php';
|
31 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-affiliate.php';
|
32 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-affiliate-terms.php';
|
33 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-plugin-info.php';
|
34 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-plugin-tag.php';
|
35 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-plugin-plan.php';
|
36 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-pricing.php';
|
37 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-payment.php';
|
38 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-plugin-license.php';
|
39 |
+
require_once WP_FS__DIR_INCLUDES . '/entities/class-fs-subscription.php';
|
40 |
+
require_once WP_FS__DIR_INCLUDES . '/class-fs-api.php';
|
41 |
+
require_once WP_FS__DIR_INCLUDES . '/class-fs-plugin-updater.php';
|
42 |
+
require_once WP_FS__DIR_INCLUDES . '/class-fs-security.php';
|
43 |
+
require_once WP_FS__DIR_INCLUDES . '/class-freemius-abstract.php';
|
44 |
+
require_once WP_FS__DIR_INCLUDES . '/sdk/Exceptions/Exception.php';
|
45 |
require_once WP_FS__DIR_INCLUDES . '/class-freemius.php';
|
freemius/templates/account/billing.php
CHANGED
@@ -1,431 +1,431 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2016, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.2.0
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array $VARS
|
15 |
-
* @var Freemius $fs
|
16 |
-
*/
|
17 |
-
$fs = freemius( $VARS['id'] );
|
18 |
-
|
19 |
-
$slug = $fs->get_slug();
|
20 |
-
|
21 |
-
$payments = $fs->_fetch_payments();
|
22 |
-
|
23 |
-
$show_billing = ( is_array( $payments ) && 0 < count( $payments ) );
|
24 |
-
|
25 |
-
if ( $show_billing ) :
|
26 |
-
|
27 |
-
$edit_text = fs_text_x_inline( 'Edit', 'verb', 'edit', $slug );
|
28 |
-
$update_text = fs_text_x_inline( 'Update', 'verb', 'update', $slug );
|
29 |
-
|
30 |
-
$billing = $fs->_fetch_billing();
|
31 |
-
$has_billing = ( $billing instanceof FS_Billing );
|
32 |
-
if ( ! $has_billing ) {
|
33 |
-
$billing = new FS_Billing();
|
34 |
-
}
|
35 |
-
?>
|
36 |
-
<!-- Billing -->
|
37 |
-
<div class="postbox">
|
38 |
-
<div id="fs_billing">
|
39 |
-
<h3><span class="dashicons dashicons-portfolio"></span> <?php fs_esc_html_echo_inline( 'Billing', 'billing', $slug ) ?></h3>
|
40 |
-
<table id="fs_billing_address"<?php if ( $has_billing ) {
|
41 |
-
echo ' class="fs-read-mode"';
|
42 |
-
} ?>>
|
43 |
-
<tr>
|
44 |
-
<td><label><span><?php fs_esc_html_echo_inline( 'Business name', 'business-name', $slug ) ?>:</span> <input id="business_name" value="<?php echo $billing->business_name ?>" placeholder="<?php fs_esc_attr_echo_inline( 'Business name', 'business-name', $slug ) ?>"></label></td>
|
45 |
-
<td><label><span><?php fs_esc_html_echo_inline( 'Tax / VAT ID', 'tax-vat-id', $slug ) ?>:</span> <input id="tax_id" value="<?php echo $billing->tax_id ?>" placeholder="<?php fs_esc_attr_echo_inline( 'Tax / VAT ID', 'tax-vat-id', $slug ) ?>"></label></td>
|
46 |
-
</tr>
|
47 |
-
<tr>
|
48 |
-
<td><label><span><?php printf( fs_esc_html_inline( 'Address Line %d', 'address-line-n', $slug ), 1 ) ?>:</span> <input id="address_street" value="<?php echo $billing->address_street ?>" placeholder="<?php printf( fs_esc_attr_inline( 'Address Line %d', 'address-line-n', $slug ), 1 ) ?>"></label></td>
|
49 |
-
<td><label><span><?php printf( fs_esc_html_inline( 'Address Line %d', 'address-line-n', $slug ), 2 ) ?>:</span> <input id="address_apt" value="<?php echo $billing->address_apt ?>" placeholder="<?php printf( fs_esc_attr_inline( 'Address Line %d', 'address-line-n', $slug ), 2 ) ?>"></label></td>
|
50 |
-
</tr>
|
51 |
-
<tr>
|
52 |
-
<td><label><span><?php fs_esc_html_echo_inline( 'City', 'city', $slug ) ?> / <?php fs_esc_html_echo_inline( 'Town', 'town', $slug ) ?>:</span> <input id="address_city" value="<?php echo $billing->address_city ?>" placeholder="<?php fs_esc_attr_echo_inline( 'City', 'city', $slug ) ?> / <?php fs_esc_attr_echo_inline( 'Town', 'town', $slug ) ?>"></label></td>
|
53 |
-
<td><label><span><?php fs_esc_html_echo_inline( 'ZIP / Postal Code', 'zip-postal-code', $slug ) ?>:</span> <input id="address_zip" value="<?php echo $billing->address_zip ?>" placeholder="<?php fs_esc_attr_echo_inline( 'ZIP / Postal Code', 'zip-postal-code', $slug ) ?>"></label></td>
|
54 |
-
</tr>
|
55 |
-
<tr>
|
56 |
-
<?php $countries = array(
|
57 |
-
'AF' => 'Afghanistan',
|
58 |
-
'AX' => 'Aland Islands',
|
59 |
-
'AL' => 'Albania',
|
60 |
-
'DZ' => 'Algeria',
|
61 |
-
'AS' => 'American Samoa',
|
62 |
-
'AD' => 'Andorra',
|
63 |
-
'AO' => 'Angola',
|
64 |
-
'AI' => 'Anguilla',
|
65 |
-
'AQ' => 'Antarctica',
|
66 |
-
'AG' => 'Antigua and Barbuda',
|
67 |
-
'AR' => 'Argentina',
|
68 |
-
'AM' => 'Armenia',
|
69 |
-
'AW' => 'Aruba',
|
70 |
-
'AU' => 'Australia',
|
71 |
-
'AT' => 'Austria',
|
72 |
-
'AZ' => 'Azerbaijan',
|
73 |
-
'BS' => 'Bahamas',
|
74 |
-
'BH' => 'Bahrain',
|
75 |
-
'BD' => 'Bangladesh',
|
76 |
-
'BB' => 'Barbados',
|
77 |
-
'BY' => 'Belarus',
|
78 |
-
'BE' => 'Belgium',
|
79 |
-
'BZ' => 'Belize',
|
80 |
-
'BJ' => 'Benin',
|
81 |
-
'BM' => 'Bermuda',
|
82 |
-
'BT' => 'Bhutan',
|
83 |
-
'BO' => 'Bolivia',
|
84 |
-
'BQ' => 'Bonaire, Saint Eustatius and Saba',
|
85 |
-
'BA' => 'Bosnia and Herzegovina',
|
86 |
-
'BW' => 'Botswana',
|
87 |
-
'BV' => 'Bouvet Island',
|
88 |
-
'BR' => 'Brazil',
|
89 |
-
'IO' => 'British Indian Ocean Territory',
|
90 |
-
'VG' => 'British Virgin Islands',
|
91 |
-
'BN' => 'Brunei',
|
92 |
-
'BG' => 'Bulgaria',
|
93 |
-
'BF' => 'Burkina Faso',
|
94 |
-
'BI' => 'Burundi',
|
95 |
-
'KH' => 'Cambodia',
|
96 |
-
'CM' => 'Cameroon',
|
97 |
-
'CA' => 'Canada',
|
98 |
-
'CV' => 'Cape Verde',
|
99 |
-
'KY' => 'Cayman Islands',
|
100 |
-
'CF' => 'Central African Republic',
|
101 |
-
'TD' => 'Chad',
|
102 |
-
'CL' => 'Chile',
|
103 |
-
'CN' => 'China',
|
104 |
-
'CX' => 'Christmas Island',
|
105 |
-
'CC' => 'Cocos Islands',
|
106 |
-
'CO' => 'Colombia',
|
107 |
-
'KM' => 'Comoros',
|
108 |
-
'CK' => 'Cook Islands',
|
109 |
-
'CR' => 'Costa Rica',
|
110 |
-
'HR' => 'Croatia',
|
111 |
-
'CU' => 'Cuba',
|
112 |
-
'CW' => 'Curacao',
|
113 |
-
'CY' => 'Cyprus',
|
114 |
-
'CZ' => 'Czech Republic',
|
115 |
-
'CD' => 'Democratic Republic of the Congo',
|
116 |
-
'DK' => 'Denmark',
|
117 |
-
'DJ' => 'Djibouti',
|
118 |
-
'DM' => 'Dominica',
|
119 |
-
'DO' => 'Dominican Republic',
|
120 |
-
'TL' => 'East Timor',
|
121 |
-
'EC' => 'Ecuador',
|
122 |
-
'EG' => 'Egypt',
|
123 |
-
'SV' => 'El Salvador',
|
124 |
-
'GQ' => 'Equatorial Guinea',
|
125 |
-
'ER' => 'Eritrea',
|
126 |
-
'EE' => 'Estonia',
|
127 |
-
'ET' => 'Ethiopia',
|
128 |
-
'FK' => 'Falkland Islands',
|
129 |
-
'FO' => 'Faroe Islands',
|
130 |
-
'FJ' => 'Fiji',
|
131 |
-
'FI' => 'Finland',
|
132 |
-
'FR' => 'France',
|
133 |
-
'GF' => 'French Guiana',
|
134 |
-
'PF' => 'French Polynesia',
|
135 |
-
'TF' => 'French Southern Territories',
|
136 |
-
'GA' => 'Gabon',
|
137 |
-
'GM' => 'Gambia',
|
138 |
-
'GE' => 'Georgia',
|
139 |
-
'DE' => 'Germany',
|
140 |
-
'GH' => 'Ghana',
|
141 |
-
'GI' => 'Gibraltar',
|
142 |
-
'GR' => 'Greece',
|
143 |
-
'GL' => 'Greenland',
|
144 |
-
'GD' => 'Grenada',
|
145 |
-
'GP' => 'Guadeloupe',
|
146 |
-
'GU' => 'Guam',
|
147 |
-
'GT' => 'Guatemala',
|
148 |
-
'GG' => 'Guernsey',
|
149 |
-
'GN' => 'Guinea',
|
150 |
-
'GW' => 'Guinea-Bissau',
|
151 |
-
'GY' => 'Guyana',
|
152 |
-
'HT' => 'Haiti',
|
153 |
-
'HM' => 'Heard Island and McDonald Islands',
|
154 |
-
'HN' => 'Honduras',
|
155 |
-
'HK' => 'Hong Kong',
|
156 |
-
'HU' => 'Hungary',
|
157 |
-
'IS' => 'Iceland',
|
158 |
-
'IN' => 'India',
|
159 |
-
'ID' => 'Indonesia',
|
160 |
-
'IR' => 'Iran',
|
161 |
-
'IQ' => 'Iraq',
|
162 |
-
'IE' => 'Ireland',
|
163 |
-
'IM' => 'Isle of Man',
|
164 |
-
'IL' => 'Israel',
|
165 |
-
'IT' => 'Italy',
|
166 |
-
'CI' => 'Ivory Coast',
|
167 |
-
'JM' => 'Jamaica',
|
168 |
-
'JP' => 'Japan',
|
169 |
-
'JE' => 'Jersey',
|
170 |
-
'JO' => 'Jordan',
|
171 |
-
'KZ' => 'Kazakhstan',
|
172 |
-
'KE' => 'Kenya',
|
173 |
-
'KI' => 'Kiribati',
|
174 |
-
'XK' => 'Kosovo',
|
175 |
-
'KW' => 'Kuwait',
|
176 |
-
'KG' => 'Kyrgyzstan',
|
177 |
-
'LA' => 'Laos',
|
178 |
-
'LV' => 'Latvia',
|
179 |
-
'LB' => 'Lebanon',
|
180 |
-
'LS' => 'Lesotho',
|
181 |
-
'LR' => 'Liberia',
|
182 |
-
'LY' => 'Libya',
|
183 |
-
'LI' => 'Liechtenstein',
|
184 |
-
'LT' => 'Lithuania',
|
185 |
-
'LU' => 'Luxembourg',
|
186 |
-
'MO' => 'Macao',
|
187 |
-
'MK' => 'Macedonia',
|
188 |
-
'MG' => 'Madagascar',
|
189 |
-
'MW' => 'Malawi',
|
190 |
-
'MY' => 'Malaysia',
|
191 |
-
'MV' => 'Maldives',
|
192 |
-
'ML' => 'Mali',
|
193 |
-
'MT' => 'Malta',
|
194 |
-
'MH' => 'Marshall Islands',
|
195 |
-
'MQ' => 'Martinique',
|
196 |
-
'MR' => 'Mauritania',
|
197 |
-
'MU' => 'Mauritius',
|
198 |
-
'YT' => 'Mayotte',
|
199 |
-
'MX' => 'Mexico',
|
200 |
-
'FM' => 'Micronesia',
|
201 |
-
'MD' => 'Moldova',
|
202 |
-
'MC' => 'Monaco',
|
203 |
-
'MN' => 'Mongolia',
|
204 |
-
'ME' => 'Montenegro',
|
205 |
-
'MS' => 'Montserrat',
|
206 |
-
'MA' => 'Morocco',
|
207 |
-
'MZ' => 'Mozambique',
|
208 |
-
'MM' => 'Myanmar',
|
209 |
-
'NA' => 'Namibia',
|
210 |
-
'NR' => 'Nauru',
|
211 |
-
'NP' => 'Nepal',
|
212 |
-
'NL' => 'Netherlands',
|
213 |
-
'NC' => 'New Caledonia',
|
214 |
-
'NZ' => 'New Zealand',
|
215 |
-
'NI' => 'Nicaragua',
|
216 |
-
'NE' => 'Niger',
|
217 |
-
'NG' => 'Nigeria',
|
218 |
-
'NU' => 'Niue',
|
219 |
-
'NF' => 'Norfolk Island',
|
220 |
-
'KP' => 'North Korea',
|
221 |
-
'MP' => 'Northern Mariana Islands',
|
222 |
-
'NO' => 'Norway',
|
223 |
-
'OM' => 'Oman',
|
224 |
-
'PK' => 'Pakistan',
|
225 |
-
'PW' => 'Palau',
|
226 |
-
'PS' => 'Palestinian Territory',
|
227 |
-
'PA' => 'Panama',
|
228 |
-
'PG' => 'Papua New Guinea',
|
229 |
-
'PY' => 'Paraguay',
|
230 |
-
'PE' => 'Peru',
|
231 |
-
'PH' => 'Philippines',
|
232 |
-
'PN' => 'Pitcairn',
|
233 |
-
'PL' => 'Poland',
|
234 |
-
'PT' => 'Portugal',
|
235 |
-
'PR' => 'Puerto Rico',
|
236 |
-
'QA' => 'Qatar',
|
237 |
-
'CG' => 'Republic of the Congo',
|
238 |
-
'RE' => 'Reunion',
|
239 |
-
'RO' => 'Romania',
|
240 |
-
'RU' => 'Russia',
|
241 |
-
'RW' => 'Rwanda',
|
242 |
-
'BL' => 'Saint Barthelemy',
|
243 |
-
'SH' => 'Saint Helena',
|
244 |
-
'KN' => 'Saint Kitts and Nevis',
|
245 |
-
'LC' => 'Saint Lucia',
|
246 |
-
'MF' => 'Saint Martin',
|
247 |
-
'PM' => 'Saint Pierre and Miquelon',
|
248 |
-
'VC' => 'Saint Vincent and the Grenadines',
|
249 |
-
'WS' => 'Samoa',
|
250 |
-
'SM' => 'San Marino',
|
251 |
-
'ST' => 'Sao Tome and Principe',
|
252 |
-
'SA' => 'Saudi Arabia',
|
253 |
-
'SN' => 'Senegal',
|
254 |
-
'RS' => 'Serbia',
|
255 |
-
'SC' => 'Seychelles',
|
256 |
-
'SL' => 'Sierra Leone',
|
257 |
-
'SG' => 'Singapore',
|
258 |
-
'SX' => 'Sint Maarten',
|
259 |
-
'SK' => 'Slovakia',
|
260 |
-
'SI' => 'Slovenia',
|
261 |
-
'SB' => 'Solomon Islands',
|
262 |
-
'SO' => 'Somalia',
|
263 |
-
'ZA' => 'South Africa',
|
264 |
-
'GS' => 'South Georgia and the South Sandwich Islands',
|
265 |
-
'KR' => 'South Korea',
|
266 |
-
'SS' => 'South Sudan',
|
267 |
-
'ES' => 'Spain',
|
268 |
-
'LK' => 'Sri Lanka',
|
269 |
-
'SD' => 'Sudan',
|
270 |
-
'SR' => 'Suriname',
|
271 |
-
'SJ' => 'Svalbard and Jan Mayen',
|
272 |
-
'SZ' => 'Swaziland',
|
273 |
-
'SE' => 'Sweden',
|
274 |
-
'CH' => 'Switzerland',
|
275 |
-
'SY' => 'Syria',
|
276 |
-
'TW' => 'Taiwan',
|
277 |
-
'TJ' => 'Tajikistan',
|
278 |
-
'TZ' => 'Tanzania',
|
279 |
-
'TH' => 'Thailand',
|
280 |
-
'TG' => 'Togo',
|
281 |
-
'TK' => 'Tokelau',
|
282 |
-
'TO' => 'Tonga',
|
283 |
-
'TT' => 'Trinidad and Tobago',
|
284 |
-
'TN' => 'Tunisia',
|
285 |
-
'TR' => 'Turkey',
|
286 |
-
'TM' => 'Turkmenistan',
|
287 |
-
'TC' => 'Turks and Caicos Islands',
|
288 |
-
'TV' => 'Tuvalu',
|
289 |
-
'VI' => 'U.S. Virgin Islands',
|
290 |
-
'UG' => 'Uganda',
|
291 |
-
'UA' => 'Ukraine',
|
292 |
-
'AE' => 'United Arab Emirates',
|
293 |
-
'GB' => 'United Kingdom',
|
294 |
-
'US' => 'United States',
|
295 |
-
'UM' => 'United States Minor Outlying Islands',
|
296 |
-
'UY' => 'Uruguay',
|
297 |
-
'UZ' => 'Uzbekistan',
|
298 |
-
'VU' => 'Vanuatu',
|
299 |
-
'VA' => 'Vatican',
|
300 |
-
'VE' => 'Venezuela',
|
301 |
-
'VN' => 'Vietnam',
|
302 |
-
'WF' => 'Wallis and Futuna',
|
303 |
-
'EH' => 'Western Sahara',
|
304 |
-
'YE' => 'Yemen',
|
305 |
-
'ZM' => 'Zambia',
|
306 |
-
'ZW' => 'Zimbabwe',
|
307 |
-
) ?>
|
308 |
-
<td><label><span><?php fs_esc_html_echo_inline( 'Country', 'country', $slug ) ?>:</span> <select id="address_country_code">
|
309 |
-
<?php if ( empty( $billing->address_country_code ) ) : ?>
|
310 |
-
<option value="" selected><?php fs_esc_html_echo_inline( 'Select Country', 'select-country', $slug ) ?></option>
|
311 |
-
<?php endif ?>
|
312 |
-
<?php foreach ( $countries as $code => $country ) : ?>
|
313 |
-
<option
|
314 |
-
value="<?php echo $code ?>" <?php selected( $billing->address_country_code, $code ) ?>><?php echo $country ?></option>
|
315 |
-
<?php endforeach ?>
|
316 |
-
</select></label></td>
|
317 |
-
<td><label><span><?php fs_esc_html_echo_inline( 'State', 'state', $slug ) ?> / <?php fs_esc_html_echo_inline( 'Province', 'province', $slug ) ?>:</span>
|
318 |
-
<input id="address_state" value="<?php echo $billing->address_state ?>" placeholder="<?php fs_esc_html_echo_inline( 'State', 'state', $slug ) ?> / <?php fs_esc_html_echo_inline( 'Province', 'province', $slug ) ?>"></label></td>
|
319 |
-
</tr>
|
320 |
-
<tr>
|
321 |
-
<td colspan="2">
|
322 |
-
<button
|
323 |
-
class="button"><?php echo esc_html( $has_billing ?
|
324 |
-
$edit_text :
|
325 |
-
$update_text
|
326 |
-
) ?></button>
|
327 |
-
</td>
|
328 |
-
</tr>
|
329 |
-
</table>
|
330 |
-
</div>
|
331 |
-
</div>
|
332 |
-
<!--/ Billing -->
|
333 |
-
<script type="text/javascript">
|
334 |
-
(function($){
|
335 |
-
var $billingAddress = $('#fs_billing_address'),
|
336 |
-
$billingInputs = $billingAddress.find('input, select');
|
337 |
-
|
338 |
-
var setPrevValues = function () {
|
339 |
-
$billingInputs.each(function () {
|
340 |
-
$(this).attr('data-val', $(this).val());
|
341 |
-
});
|
342 |
-
};
|
343 |
-
|
344 |
-
setPrevValues();
|
345 |
-
|
346 |
-
var hasBillingChanged = function () {
|
347 |
-
for (var i = 0, len = $billingInputs.length; i < len; i++){
|
348 |
-
var $this = $($billingInputs[i]);
|
349 |
-
if ($this.attr('data-val') !== $this.val()) {
|
350 |
-
return true;
|
351 |
-
}
|
352 |
-
}
|
353 |
-
|
354 |
-
return false;
|
355 |
-
};
|
356 |
-
|
357 |
-
var isEditAllFieldsMode = false;
|
358 |
-
|
359 |
-
$billingAddress.find('.button').click(function(){
|
360 |
-
$billingAddress.toggleClass('fs-read-mode');
|
361 |
-
|
362 |
-
var isEditMode = !$billingAddress.hasClass('fs-read-mode');
|
363 |
-
|
364 |
-
$(this)
|
365 |
-
.html(isEditMode ? '<?php echo esc_js( $update_text ) ?>' : '<?php echo esc_js( $edit_text ) ?>')
|
366 |
-
.toggleClass('button-primary');
|
367 |
-
|
368 |
-
if (isEditMode) {
|
369 |
-
$('#business_name').focus().select();
|
370 |
-
isEditAllFieldsMode = true;
|
371 |
-
} else {
|
372 |
-
isEditAllFieldsMode = false;
|
373 |
-
|
374 |
-
if (!hasBillingChanged())
|
375 |
-
return;
|
376 |
-
|
377 |
-
var billing = {};
|
378 |
-
|
379 |
-
$billingInputs.each(function(){
|
380 |
-
if ($(this).attr('data-val') !== $(this).val()) {
|
381 |
-
billing[$(this).attr('id')] = $(this).val();
|
382 |
-
}
|
383 |
-
});
|
384 |
-
|
385 |
-
$.ajax({
|
386 |
-
url : ajaxurl,
|
387 |
-
method : 'POST',
|
388 |
-
data : {
|
389 |
-
action : '<?php echo $fs->get_ajax_action( 'update_billing' ) ?>',
|
390 |
-
security : '<?php echo $fs->get_ajax_security( 'update_billing' ) ?>',
|
391 |
-
module_id: '<?php echo $fs->get_id() ?>',
|
392 |
-
billing : billing
|
393 |
-
},
|
394 |
-
success: function (resultObj) {
|
395 |
-
if (resultObj.success) {
|
396 |
-
setPrevValues();
|
397 |
-
} else {
|
398 |
-
alert(resultObj.error);
|
399 |
-
}
|
400 |
-
}
|
401 |
-
});
|
402 |
-
}
|
403 |
-
});
|
404 |
-
|
405 |
-
$billingInputs
|
406 |
-
// Get into edit mode upon selection.
|
407 |
-
.focus(function () {
|
408 |
-
var isEditMode = !$billingAddress.hasClass('fs-read-mode');
|
409 |
-
|
410 |
-
if (isEditMode) {
|
411 |
-
return;
|
412 |
-
}
|
413 |
-
|
414 |
-
$billingAddress.toggleClass('fs-read-mode');
|
415 |
-
$billingAddress.find('.button')
|
416 |
-
.html('<?php echo esc_js( $update_text ) ?>')
|
417 |
-
.toggleClass('button-primary');
|
418 |
-
})
|
419 |
-
// If blured after editing only one field without changes, exit edit mode.
|
420 |
-
.blur(function () {
|
421 |
-
if (!isEditAllFieldsMode && !hasBillingChanged()) {
|
422 |
-
$billingAddress.toggleClass('fs-read-mode');
|
423 |
-
$billingAddress.find('.button')
|
424 |
-
.html('<?php echo esc_js( $edit_text ) ?>')
|
425 |
-
.toggleClass('button-primary');
|
426 |
-
}
|
427 |
-
});
|
428 |
-
})(jQuery);
|
429 |
-
</script>
|
430 |
-
<?php
|
431 |
endif;
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2016, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.2.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
* @var Freemius $fs
|
16 |
+
*/
|
17 |
+
$fs = freemius( $VARS['id'] );
|
18 |
+
|
19 |
+
$slug = $fs->get_slug();
|
20 |
+
|
21 |
+
$payments = $fs->_fetch_payments();
|
22 |
+
|
23 |
+
$show_billing = ( is_array( $payments ) && 0 < count( $payments ) );
|
24 |
+
|
25 |
+
if ( $show_billing ) :
|
26 |
+
|
27 |
+
$edit_text = fs_text_x_inline( 'Edit', 'verb', 'edit', $slug );
|
28 |
+
$update_text = fs_text_x_inline( 'Update', 'verb', 'update', $slug );
|
29 |
+
|
30 |
+
$billing = $fs->_fetch_billing();
|
31 |
+
$has_billing = ( $billing instanceof FS_Billing );
|
32 |
+
if ( ! $has_billing ) {
|
33 |
+
$billing = new FS_Billing();
|
34 |
+
}
|
35 |
+
?>
|
36 |
+
<!-- Billing -->
|
37 |
+
<div class="postbox">
|
38 |
+
<div id="fs_billing">
|
39 |
+
<h3><span class="dashicons dashicons-portfolio"></span> <?php fs_esc_html_echo_inline( 'Billing', 'billing', $slug ) ?></h3>
|
40 |
+
<table id="fs_billing_address"<?php if ( $has_billing ) {
|
41 |
+
echo ' class="fs-read-mode"';
|
42 |
+
} ?>>
|
43 |
+
<tr>
|
44 |
+
<td><label><span><?php fs_esc_html_echo_inline( 'Business name', 'business-name', $slug ) ?>:</span> <input id="business_name" value="<?php echo $billing->business_name ?>" placeholder="<?php fs_esc_attr_echo_inline( 'Business name', 'business-name', $slug ) ?>"></label></td>
|
45 |
+
<td><label><span><?php fs_esc_html_echo_inline( 'Tax / VAT ID', 'tax-vat-id', $slug ) ?>:</span> <input id="tax_id" value="<?php echo $billing->tax_id ?>" placeholder="<?php fs_esc_attr_echo_inline( 'Tax / VAT ID', 'tax-vat-id', $slug ) ?>"></label></td>
|
46 |
+
</tr>
|
47 |
+
<tr>
|
48 |
+
<td><label><span><?php printf( fs_esc_html_inline( 'Address Line %d', 'address-line-n', $slug ), 1 ) ?>:</span> <input id="address_street" value="<?php echo $billing->address_street ?>" placeholder="<?php printf( fs_esc_attr_inline( 'Address Line %d', 'address-line-n', $slug ), 1 ) ?>"></label></td>
|
49 |
+
<td><label><span><?php printf( fs_esc_html_inline( 'Address Line %d', 'address-line-n', $slug ), 2 ) ?>:</span> <input id="address_apt" value="<?php echo $billing->address_apt ?>" placeholder="<?php printf( fs_esc_attr_inline( 'Address Line %d', 'address-line-n', $slug ), 2 ) ?>"></label></td>
|
50 |
+
</tr>
|
51 |
+
<tr>
|
52 |
+
<td><label><span><?php fs_esc_html_echo_inline( 'City', 'city', $slug ) ?> / <?php fs_esc_html_echo_inline( 'Town', 'town', $slug ) ?>:</span> <input id="address_city" value="<?php echo $billing->address_city ?>" placeholder="<?php fs_esc_attr_echo_inline( 'City', 'city', $slug ) ?> / <?php fs_esc_attr_echo_inline( 'Town', 'town', $slug ) ?>"></label></td>
|
53 |
+
<td><label><span><?php fs_esc_html_echo_inline( 'ZIP / Postal Code', 'zip-postal-code', $slug ) ?>:</span> <input id="address_zip" value="<?php echo $billing->address_zip ?>" placeholder="<?php fs_esc_attr_echo_inline( 'ZIP / Postal Code', 'zip-postal-code', $slug ) ?>"></label></td>
|
54 |
+
</tr>
|
55 |
+
<tr>
|
56 |
+
<?php $countries = array(
|
57 |
+
'AF' => 'Afghanistan',
|
58 |
+
'AX' => 'Aland Islands',
|
59 |
+
'AL' => 'Albania',
|
60 |
+
'DZ' => 'Algeria',
|
61 |
+
'AS' => 'American Samoa',
|
62 |
+
'AD' => 'Andorra',
|
63 |
+
'AO' => 'Angola',
|
64 |
+
'AI' => 'Anguilla',
|
65 |
+
'AQ' => 'Antarctica',
|
66 |
+
'AG' => 'Antigua and Barbuda',
|
67 |
+
'AR' => 'Argentina',
|
68 |
+
'AM' => 'Armenia',
|
69 |
+
'AW' => 'Aruba',
|
70 |
+
'AU' => 'Australia',
|
71 |
+
'AT' => 'Austria',
|
72 |
+
'AZ' => 'Azerbaijan',
|
73 |
+
'BS' => 'Bahamas',
|
74 |
+
'BH' => 'Bahrain',
|
75 |
+
'BD' => 'Bangladesh',
|
76 |
+
'BB' => 'Barbados',
|
77 |
+
'BY' => 'Belarus',
|
78 |
+
'BE' => 'Belgium',
|
79 |
+
'BZ' => 'Belize',
|
80 |
+
'BJ' => 'Benin',
|
81 |
+
'BM' => 'Bermuda',
|
82 |
+
'BT' => 'Bhutan',
|
83 |
+
'BO' => 'Bolivia',
|
84 |
+
'BQ' => 'Bonaire, Saint Eustatius and Saba',
|
85 |
+
'BA' => 'Bosnia and Herzegovina',
|
86 |
+
'BW' => 'Botswana',
|
87 |
+
'BV' => 'Bouvet Island',
|
88 |
+
'BR' => 'Brazil',
|
89 |
+
'IO' => 'British Indian Ocean Territory',
|
90 |
+
'VG' => 'British Virgin Islands',
|
91 |
+
'BN' => 'Brunei',
|
92 |
+
'BG' => 'Bulgaria',
|
93 |
+
'BF' => 'Burkina Faso',
|
94 |
+
'BI' => 'Burundi',
|
95 |
+
'KH' => 'Cambodia',
|
96 |
+
'CM' => 'Cameroon',
|
97 |
+
'CA' => 'Canada',
|
98 |
+
'CV' => 'Cape Verde',
|
99 |
+
'KY' => 'Cayman Islands',
|
100 |
+
'CF' => 'Central African Republic',
|
101 |
+
'TD' => 'Chad',
|
102 |
+
'CL' => 'Chile',
|
103 |
+
'CN' => 'China',
|
104 |
+
'CX' => 'Christmas Island',
|
105 |
+
'CC' => 'Cocos Islands',
|
106 |
+
'CO' => 'Colombia',
|
107 |
+
'KM' => 'Comoros',
|
108 |
+
'CK' => 'Cook Islands',
|
109 |
+
'CR' => 'Costa Rica',
|
110 |
+
'HR' => 'Croatia',
|
111 |
+
'CU' => 'Cuba',
|
112 |
+
'CW' => 'Curacao',
|
113 |
+
'CY' => 'Cyprus',
|
114 |
+
'CZ' => 'Czech Republic',
|
115 |
+
'CD' => 'Democratic Republic of the Congo',
|
116 |
+
'DK' => 'Denmark',
|
117 |
+
'DJ' => 'Djibouti',
|
118 |
+
'DM' => 'Dominica',
|
119 |
+
'DO' => 'Dominican Republic',
|
120 |
+
'TL' => 'East Timor',
|
121 |
+
'EC' => 'Ecuador',
|
122 |
+
'EG' => 'Egypt',
|
123 |
+
'SV' => 'El Salvador',
|
124 |
+
'GQ' => 'Equatorial Guinea',
|
125 |
+
'ER' => 'Eritrea',
|
126 |
+
'EE' => 'Estonia',
|
127 |
+
'ET' => 'Ethiopia',
|
128 |
+
'FK' => 'Falkland Islands',
|
129 |
+
'FO' => 'Faroe Islands',
|
130 |
+
'FJ' => 'Fiji',
|
131 |
+
'FI' => 'Finland',
|
132 |
+
'FR' => 'France',
|
133 |
+
'GF' => 'French Guiana',
|
134 |
+
'PF' => 'French Polynesia',
|
135 |
+
'TF' => 'French Southern Territories',
|
136 |
+
'GA' => 'Gabon',
|
137 |
+
'GM' => 'Gambia',
|
138 |
+
'GE' => 'Georgia',
|
139 |
+
'DE' => 'Germany',
|
140 |
+
'GH' => 'Ghana',
|
141 |
+
'GI' => 'Gibraltar',
|
142 |
+
'GR' => 'Greece',
|
143 |
+
'GL' => 'Greenland',
|
144 |
+
'GD' => 'Grenada',
|
145 |
+
'GP' => 'Guadeloupe',
|
146 |
+
'GU' => 'Guam',
|
147 |
+
'GT' => 'Guatemala',
|
148 |
+
'GG' => 'Guernsey',
|
149 |
+
'GN' => 'Guinea',
|
150 |
+
'GW' => 'Guinea-Bissau',
|
151 |
+
'GY' => 'Guyana',
|
152 |
+
'HT' => 'Haiti',
|
153 |
+
'HM' => 'Heard Island and McDonald Islands',
|
154 |
+
'HN' => 'Honduras',
|
155 |
+
'HK' => 'Hong Kong',
|
156 |
+
'HU' => 'Hungary',
|
157 |
+
'IS' => 'Iceland',
|
158 |
+
'IN' => 'India',
|
159 |
+
'ID' => 'Indonesia',
|
160 |
+
'IR' => 'Iran',
|
161 |
+
'IQ' => 'Iraq',
|
162 |
+
'IE' => 'Ireland',
|
163 |
+
'IM' => 'Isle of Man',
|
164 |
+
'IL' => 'Israel',
|
165 |
+
'IT' => 'Italy',
|
166 |
+
'CI' => 'Ivory Coast',
|
167 |
+
'JM' => 'Jamaica',
|
168 |
+
'JP' => 'Japan',
|
169 |
+
'JE' => 'Jersey',
|
170 |
+
'JO' => 'Jordan',
|
171 |
+
'KZ' => 'Kazakhstan',
|
172 |
+
'KE' => 'Kenya',
|
173 |
+
'KI' => 'Kiribati',
|
174 |
+
'XK' => 'Kosovo',
|
175 |
+
'KW' => 'Kuwait',
|
176 |
+
'KG' => 'Kyrgyzstan',
|
177 |
+
'LA' => 'Laos',
|
178 |
+
'LV' => 'Latvia',
|
179 |
+
'LB' => 'Lebanon',
|
180 |
+
'LS' => 'Lesotho',
|
181 |
+
'LR' => 'Liberia',
|
182 |
+
'LY' => 'Libya',
|
183 |
+
'LI' => 'Liechtenstein',
|
184 |
+
'LT' => 'Lithuania',
|
185 |
+
'LU' => 'Luxembourg',
|
186 |
+
'MO' => 'Macao',
|
187 |
+
'MK' => 'Macedonia',
|
188 |
+
'MG' => 'Madagascar',
|
189 |
+
'MW' => 'Malawi',
|
190 |
+
'MY' => 'Malaysia',
|
191 |
+
'MV' => 'Maldives',
|
192 |
+
'ML' => 'Mali',
|
193 |
+
'MT' => 'Malta',
|
194 |
+
'MH' => 'Marshall Islands',
|
195 |
+
'MQ' => 'Martinique',
|
196 |
+
'MR' => 'Mauritania',
|
197 |
+
'MU' => 'Mauritius',
|
198 |
+
'YT' => 'Mayotte',
|
199 |
+
'MX' => 'Mexico',
|
200 |
+
'FM' => 'Micronesia',
|
201 |
+
'MD' => 'Moldova',
|
202 |
+
'MC' => 'Monaco',
|
203 |
+
'MN' => 'Mongolia',
|
204 |
+
'ME' => 'Montenegro',
|
205 |
+
'MS' => 'Montserrat',
|
206 |
+
'MA' => 'Morocco',
|
207 |
+
'MZ' => 'Mozambique',
|
208 |
+
'MM' => 'Myanmar',
|
209 |
+
'NA' => 'Namibia',
|
210 |
+
'NR' => 'Nauru',
|
211 |
+
'NP' => 'Nepal',
|
212 |
+
'NL' => 'Netherlands',
|
213 |
+
'NC' => 'New Caledonia',
|
214 |
+
'NZ' => 'New Zealand',
|
215 |
+
'NI' => 'Nicaragua',
|
216 |
+
'NE' => 'Niger',
|
217 |
+
'NG' => 'Nigeria',
|
218 |
+
'NU' => 'Niue',
|
219 |
+
'NF' => 'Norfolk Island',
|
220 |
+
'KP' => 'North Korea',
|
221 |
+
'MP' => 'Northern Mariana Islands',
|
222 |
+
'NO' => 'Norway',
|
223 |
+
'OM' => 'Oman',
|
224 |
+
'PK' => 'Pakistan',
|
225 |
+
'PW' => 'Palau',
|
226 |
+
'PS' => 'Palestinian Territory',
|
227 |
+
'PA' => 'Panama',
|
228 |
+
'PG' => 'Papua New Guinea',
|
229 |
+
'PY' => 'Paraguay',
|
230 |
+
'PE' => 'Peru',
|
231 |
+
'PH' => 'Philippines',
|
232 |
+
'PN' => 'Pitcairn',
|
233 |
+
'PL' => 'Poland',
|
234 |
+
'PT' => 'Portugal',
|
235 |
+
'PR' => 'Puerto Rico',
|
236 |
+
'QA' => 'Qatar',
|
237 |
+
'CG' => 'Republic of the Congo',
|
238 |
+
'RE' => 'Reunion',
|
239 |
+
'RO' => 'Romania',
|
240 |
+
'RU' => 'Russia',
|
241 |
+
'RW' => 'Rwanda',
|
242 |
+
'BL' => 'Saint Barthelemy',
|
243 |
+
'SH' => 'Saint Helena',
|
244 |
+
'KN' => 'Saint Kitts and Nevis',
|
245 |
+
'LC' => 'Saint Lucia',
|
246 |
+
'MF' => 'Saint Martin',
|
247 |
+
'PM' => 'Saint Pierre and Miquelon',
|
248 |
+
'VC' => 'Saint Vincent and the Grenadines',
|
249 |
+
'WS' => 'Samoa',
|
250 |
+
'SM' => 'San Marino',
|
251 |
+
'ST' => 'Sao Tome and Principe',
|
252 |
+
'SA' => 'Saudi Arabia',
|
253 |
+
'SN' => 'Senegal',
|
254 |
+
'RS' => 'Serbia',
|
255 |
+
'SC' => 'Seychelles',
|
256 |
+
'SL' => 'Sierra Leone',
|
257 |
+
'SG' => 'Singapore',
|
258 |
+
'SX' => 'Sint Maarten',
|
259 |
+
'SK' => 'Slovakia',
|
260 |
+
'SI' => 'Slovenia',
|
261 |
+
'SB' => 'Solomon Islands',
|
262 |
+
'SO' => 'Somalia',
|
263 |
+
'ZA' => 'South Africa',
|
264 |
+
'GS' => 'South Georgia and the South Sandwich Islands',
|
265 |
+
'KR' => 'South Korea',
|
266 |
+
'SS' => 'South Sudan',
|
267 |
+
'ES' => 'Spain',
|
268 |
+
'LK' => 'Sri Lanka',
|
269 |
+
'SD' => 'Sudan',
|
270 |
+
'SR' => 'Suriname',
|
271 |
+
'SJ' => 'Svalbard and Jan Mayen',
|
272 |
+
'SZ' => 'Swaziland',
|
273 |
+
'SE' => 'Sweden',
|
274 |
+
'CH' => 'Switzerland',
|
275 |
+
'SY' => 'Syria',
|
276 |
+
'TW' => 'Taiwan',
|
277 |
+
'TJ' => 'Tajikistan',
|
278 |
+
'TZ' => 'Tanzania',
|
279 |
+
'TH' => 'Thailand',
|
280 |
+
'TG' => 'Togo',
|
281 |
+
'TK' => 'Tokelau',
|
282 |
+
'TO' => 'Tonga',
|
283 |
+
'TT' => 'Trinidad and Tobago',
|
284 |
+
'TN' => 'Tunisia',
|
285 |
+
'TR' => 'Turkey',
|
286 |
+
'TM' => 'Turkmenistan',
|
287 |
+
'TC' => 'Turks and Caicos Islands',
|
288 |
+
'TV' => 'Tuvalu',
|
289 |
+
'VI' => 'U.S. Virgin Islands',
|
290 |
+
'UG' => 'Uganda',
|
291 |
+
'UA' => 'Ukraine',
|
292 |
+
'AE' => 'United Arab Emirates',
|
293 |
+
'GB' => 'United Kingdom',
|
294 |
+
'US' => 'United States',
|
295 |
+
'UM' => 'United States Minor Outlying Islands',
|
296 |
+
'UY' => 'Uruguay',
|
297 |
+
'UZ' => 'Uzbekistan',
|
298 |
+
'VU' => 'Vanuatu',
|
299 |
+
'VA' => 'Vatican',
|
300 |
+
'VE' => 'Venezuela',
|
301 |
+
'VN' => 'Vietnam',
|
302 |
+
'WF' => 'Wallis and Futuna',
|
303 |
+
'EH' => 'Western Sahara',
|
304 |
+
'YE' => 'Yemen',
|
305 |
+
'ZM' => 'Zambia',
|
306 |
+
'ZW' => 'Zimbabwe',
|
307 |
+
) ?>
|
308 |
+
<td><label><span><?php fs_esc_html_echo_inline( 'Country', 'country', $slug ) ?>:</span> <select id="address_country_code">
|
309 |
+
<?php if ( empty( $billing->address_country_code ) ) : ?>
|
310 |
+
<option value="" selected><?php fs_esc_html_echo_inline( 'Select Country', 'select-country', $slug ) ?></option>
|
311 |
+
<?php endif ?>
|
312 |
+
<?php foreach ( $countries as $code => $country ) : ?>
|
313 |
+
<option
|
314 |
+
value="<?php echo $code ?>" <?php selected( $billing->address_country_code, $code ) ?>><?php echo $country ?></option>
|
315 |
+
<?php endforeach ?>
|
316 |
+
</select></label></td>
|
317 |
+
<td><label><span><?php fs_esc_html_echo_inline( 'State', 'state', $slug ) ?> / <?php fs_esc_html_echo_inline( 'Province', 'province', $slug ) ?>:</span>
|
318 |
+
<input id="address_state" value="<?php echo $billing->address_state ?>" placeholder="<?php fs_esc_html_echo_inline( 'State', 'state', $slug ) ?> / <?php fs_esc_html_echo_inline( 'Province', 'province', $slug ) ?>"></label></td>
|
319 |
+
</tr>
|
320 |
+
<tr>
|
321 |
+
<td colspan="2">
|
322 |
+
<button
|
323 |
+
class="button"><?php echo esc_html( $has_billing ?
|
324 |
+
$edit_text :
|
325 |
+
$update_text
|
326 |
+
) ?></button>
|
327 |
+
</td>
|
328 |
+
</tr>
|
329 |
+
</table>
|
330 |
+
</div>
|
331 |
+
</div>
|
332 |
+
<!--/ Billing -->
|
333 |
+
<script type="text/javascript">
|
334 |
+
(function($){
|
335 |
+
var $billingAddress = $('#fs_billing_address'),
|
336 |
+
$billingInputs = $billingAddress.find('input, select');
|
337 |
+
|
338 |
+
var setPrevValues = function () {
|
339 |
+
$billingInputs.each(function () {
|
340 |
+
$(this).attr('data-val', $(this).val());
|
341 |
+
});
|
342 |
+
};
|
343 |
+
|
344 |
+
setPrevValues();
|
345 |
+
|
346 |
+
var hasBillingChanged = function () {
|
347 |
+
for (var i = 0, len = $billingInputs.length; i < len; i++){
|
348 |
+
var $this = $($billingInputs[i]);
|
349 |
+
if ($this.attr('data-val') !== $this.val()) {
|
350 |
+
return true;
|
351 |
+
}
|
352 |
+
}
|
353 |
+
|
354 |
+
return false;
|
355 |
+
};
|
356 |
+
|
357 |
+
var isEditAllFieldsMode = false;
|
358 |
+
|
359 |
+
$billingAddress.find('.button').click(function(){
|
360 |
+
$billingAddress.toggleClass('fs-read-mode');
|
361 |
+
|
362 |
+
var isEditMode = !$billingAddress.hasClass('fs-read-mode');
|
363 |
+
|
364 |
+
$(this)
|
365 |
+
.html(isEditMode ? '<?php echo esc_js( $update_text ) ?>' : '<?php echo esc_js( $edit_text ) ?>')
|
366 |
+
.toggleClass('button-primary');
|
367 |
+
|
368 |
+
if (isEditMode) {
|
369 |
+
$('#business_name').focus().select();
|
370 |
+
isEditAllFieldsMode = true;
|
371 |
+
} else {
|
372 |
+
isEditAllFieldsMode = false;
|
373 |
+
|
374 |
+
if (!hasBillingChanged())
|
375 |
+
return;
|
376 |
+
|
377 |
+
var billing = {};
|
378 |
+
|
379 |
+
$billingInputs.each(function(){
|
380 |
+
if ($(this).attr('data-val') !== $(this).val()) {
|
381 |
+
billing[$(this).attr('id')] = $(this).val();
|
382 |
+
}
|
383 |
+
});
|
384 |
+
|
385 |
+
$.ajax({
|
386 |
+
url : ajaxurl,
|
387 |
+
method : 'POST',
|
388 |
+
data : {
|
389 |
+
action : '<?php echo $fs->get_ajax_action( 'update_billing' ) ?>',
|
390 |
+
security : '<?php echo $fs->get_ajax_security( 'update_billing' ) ?>',
|
391 |
+
module_id: '<?php echo $fs->get_id() ?>',
|
392 |
+
billing : billing
|
393 |
+
},
|
394 |
+
success: function (resultObj) {
|
395 |
+
if (resultObj.success) {
|
396 |
+
setPrevValues();
|
397 |
+
} else {
|
398 |
+
alert(resultObj.error);
|
399 |
+
}
|
400 |
+
}
|
401 |
+
});
|
402 |
+
}
|
403 |
+
});
|
404 |
+
|
405 |
+
$billingInputs
|
406 |
+
// Get into edit mode upon selection.
|
407 |
+
.focus(function () {
|
408 |
+
var isEditMode = !$billingAddress.hasClass('fs-read-mode');
|
409 |
+
|
410 |
+
if (isEditMode) {
|
411 |
+
return;
|
412 |
+
}
|
413 |
+
|
414 |
+
$billingAddress.toggleClass('fs-read-mode');
|
415 |
+
$billingAddress.find('.button')
|
416 |
+
.html('<?php echo esc_js( $update_text ) ?>')
|
417 |
+
.toggleClass('button-primary');
|
418 |
+
})
|
419 |
+
// If blured after editing only one field without changes, exit edit mode.
|
420 |
+
.blur(function () {
|
421 |
+
if (!isEditAllFieldsMode && !hasBillingChanged()) {
|
422 |
+
$billingAddress.toggleClass('fs-read-mode');
|
423 |
+
$billingAddress.find('.button')
|
424 |
+
.html('<?php echo esc_js( $edit_text ) ?>')
|
425 |
+
.toggleClass('button-primary');
|
426 |
+
}
|
427 |
+
});
|
428 |
+
})(jQuery);
|
429 |
+
</script>
|
430 |
+
<?php
|
431 |
endif;
|
freemius/templates/account/payments.php
CHANGED
@@ -1,59 +1,59 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2016, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.2.0
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array $VARS
|
15 |
-
* @var Freemius $fs
|
16 |
-
*/
|
17 |
-
$fs = freemius( $VARS['id'] );
|
18 |
-
|
19 |
-
$slug = $fs->get_slug();
|
20 |
-
|
21 |
-
$payments = $fs->_fetch_payments();
|
22 |
-
|
23 |
-
$show_payments = ( is_array( $payments ) && 0 < count( $payments ) );
|
24 |
-
|
25 |
-
if ( $show_payments ) :
|
26 |
-
?>
|
27 |
-
<div class="postbox">
|
28 |
-
<div id="fs_payments">
|
29 |
-
<h3><span class="dashicons dashicons-paperclip"></span> <?php fs_esc_html_echo_inline( 'Payments', 'payments', $slug ) ?></h3>
|
30 |
-
|
31 |
-
<div class="inside">
|
32 |
-
<table class="widefat">
|
33 |
-
<thead>
|
34 |
-
<tr>
|
35 |
-
<th><?php fs_esc_html_echo_inline( 'ID', 'id', $slug ) ?></th>
|
36 |
-
<th><?php fs_esc_html_echo_inline( 'Date', 'date', $slug ) ?></th>
|
37 |
-
<th><?php fs_esc_html_echo_inline( 'Amount', 'amount', $slug ) ?></th>
|
38 |
-
<th><?php fs_esc_html_echo_inline( 'Invoice', 'invoice', $slug ) ?></th>
|
39 |
-
</tr>
|
40 |
-
</thead>
|
41 |
-
<tbody>
|
42 |
-
<?php $odd = true ?>
|
43 |
-
<?php foreach ( $payments as $payment ) : ?>
|
44 |
-
<tr<?php echo $odd ? ' class="alternate"' : '' ?>>
|
45 |
-
<td><?php echo $payment->id ?></td>
|
46 |
-
<td><?php echo date( 'M j, Y', strtotime( $payment->created ) ) ?></td>
|
47 |
-
<td>$<?php echo $payment->gross ?></td>
|
48 |
-
<td><a href="<?php echo $fs->_get_invoice_api_url( $payment->id ) ?>"
|
49 |
-
class="button button-small"
|
50 |
-
target="_blank"><?php fs_esc_html_echo_inline( 'Invoice', 'invoice', $slug ) ?></a></td>
|
51 |
-
</tr>
|
52 |
-
<?php $odd = ! $odd; endforeach ?>
|
53 |
-
</tbody>
|
54 |
-
</table>
|
55 |
-
</div>
|
56 |
-
</div>
|
57 |
-
</div>
|
58 |
-
<?php
|
59 |
endif;
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2016, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.2.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
* @var Freemius $fs
|
16 |
+
*/
|
17 |
+
$fs = freemius( $VARS['id'] );
|
18 |
+
|
19 |
+
$slug = $fs->get_slug();
|
20 |
+
|
21 |
+
$payments = $fs->_fetch_payments();
|
22 |
+
|
23 |
+
$show_payments = ( is_array( $payments ) && 0 < count( $payments ) );
|
24 |
+
|
25 |
+
if ( $show_payments ) :
|
26 |
+
?>
|
27 |
+
<div class="postbox">
|
28 |
+
<div id="fs_payments">
|
29 |
+
<h3><span class="dashicons dashicons-paperclip"></span> <?php fs_esc_html_echo_inline( 'Payments', 'payments', $slug ) ?></h3>
|
30 |
+
|
31 |
+
<div class="inside">
|
32 |
+
<table class="widefat">
|
33 |
+
<thead>
|
34 |
+
<tr>
|
35 |
+
<th><?php fs_esc_html_echo_inline( 'ID', 'id', $slug ) ?></th>
|
36 |
+
<th><?php fs_esc_html_echo_inline( 'Date', 'date', $slug ) ?></th>
|
37 |
+
<th><?php fs_esc_html_echo_inline( 'Amount', 'amount', $slug ) ?></th>
|
38 |
+
<th><?php fs_esc_html_echo_inline( 'Invoice', 'invoice', $slug ) ?></th>
|
39 |
+
</tr>
|
40 |
+
</thead>
|
41 |
+
<tbody>
|
42 |
+
<?php $odd = true ?>
|
43 |
+
<?php foreach ( $payments as $payment ) : ?>
|
44 |
+
<tr<?php echo $odd ? ' class="alternate"' : '' ?>>
|
45 |
+
<td><?php echo $payment->id ?></td>
|
46 |
+
<td><?php echo date( 'M j, Y', strtotime( $payment->created ) ) ?></td>
|
47 |
+
<td>$<?php echo $payment->gross ?></td>
|
48 |
+
<td><a href="<?php echo $fs->_get_invoice_api_url( $payment->id ) ?>"
|
49 |
+
class="button button-small"
|
50 |
+
target="_blank"><?php fs_esc_html_echo_inline( 'Invoice', 'invoice', $slug ) ?></a></td>
|
51 |
+
</tr>
|
52 |
+
<?php $odd = ! $odd; endforeach ?>
|
53 |
+
</tbody>
|
54 |
+
</table>
|
55 |
+
</div>
|
56 |
+
</div>
|
57 |
+
</div>
|
58 |
+
<?php
|
59 |
endif;
|
freemius/templates/add-ons.php
CHANGED
@@ -1,193 +1,193 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array $VARS
|
15 |
-
* @var Freemius
|
16 |
-
*/
|
17 |
-
$fs = freemius( $VARS['id'] );
|
18 |
-
|
19 |
-
$slug = $fs->get_slug();
|
20 |
-
|
21 |
-
$open_addon_slug = fs_request_get( 'slug' );
|
22 |
-
|
23 |
-
$open_addon = false;
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @var FS_Plugin[]
|
27 |
-
*/
|
28 |
-
$addons = $fs->get_addons();
|
29 |
-
|
30 |
-
$has_addons = ( is_array( $addons ) && 0 < count( $addons ) );
|
31 |
-
|
32 |
-
$has_tabs = $fs->_add_tabs_before_content();
|
33 |
-
?>
|
34 |
-
<div id="fs_addons" class="wrap fs-section">
|
35 |
-
<?php if ( ! $has_tabs ) : ?>
|
36 |
-
<h2><?php echo esc_html( sprintf( fs_text_inline( 'Add Ons for %s', 'add-ons-for-x', $slug ), $fs->get_plugin_name() ) ) ?></h2>
|
37 |
-
<?php endif ?>
|
38 |
-
|
39 |
-
<div id="poststuff">
|
40 |
-
<?php if ( ! $has_addons ) : ?>
|
41 |
-
<h3><?php echo esc_html( sprintf(
|
42 |
-
'%s... %s',
|
43 |
-
fs_text_x_inline( 'Oops', 'exclamation', 'oops', $slug ),
|
44 |
-
fs_text_inline( 'We could\'nt load the add-ons list. It\'s probably an issue on our side, please try to come back in few minutes.', 'add-ons-missing', $slug )
|
45 |
-
) ) ?></h3>
|
46 |
-
<?php endif ?>
|
47 |
-
<ul class="fs-cards-list">
|
48 |
-
<?php if ( $has_addons ) : ?>
|
49 |
-
<?php foreach ( $addons as $addon ) : ?>
|
50 |
-
<?php
|
51 |
-
$open_addon = ( $open_addon || ( $open_addon_slug === $addon->slug ) );
|
52 |
-
|
53 |
-
$price = 0;
|
54 |
-
$has_trial = false;
|
55 |
-
$has_free_plan = false;
|
56 |
-
$has_paid_plan = false;
|
57 |
-
|
58 |
-
$result = $fs->get_api_plugin_scope()->get( "/addons/{$addon->id}/pricing.json?type=visible" );
|
59 |
-
if ( ! isset( $result->error ) ) {
|
60 |
-
$plans = $result->plans;
|
61 |
-
|
62 |
-
if ( is_array( $plans ) && 0 < count( $plans ) ) {
|
63 |
-
foreach ( $plans as $plan ) {
|
64 |
-
if ( ! isset( $plan->pricing ) ||
|
65 |
-
! is_array( $plan->pricing ) ||
|
66 |
-
0 == count( $plan->pricing )
|
67 |
-
) {
|
68 |
-
// No pricing means a free plan.
|
69 |
-
$has_free_plan = true;
|
70 |
-
continue;
|
71 |
-
}
|
72 |
-
|
73 |
-
|
74 |
-
$has_paid_plan = true;
|
75 |
-
$has_trial = $has_trial || ( is_numeric( $plan->trial_period ) && ( $plan->trial_period > 0 ) );
|
76 |
-
|
77 |
-
$min_price = 999999;
|
78 |
-
foreach ( $plan->pricing as $pricing ) {
|
79 |
-
if ( ! is_null( $pricing->annual_price ) && $pricing->annual_price > 0 ) {
|
80 |
-
$min_price = min( $min_price, $pricing->annual_price );
|
81 |
-
} else if ( ! is_null( $pricing->monthly_price ) && $pricing->monthly_price > 0 ) {
|
82 |
-
$min_price = min( $min_price, 12 * $pricing->monthly_price );
|
83 |
-
}
|
84 |
-
}
|
85 |
-
|
86 |
-
if ( $min_price < 999999 ) {
|
87 |
-
$price = $min_price;
|
88 |
-
}
|
89 |
-
|
90 |
-
}
|
91 |
-
}
|
92 |
-
}
|
93 |
-
?>
|
94 |
-
<li class="fs-card fs-addon" data-slug="<?php echo $addon->slug ?>">
|
95 |
-
<?php
|
96 |
-
echo sprintf( '<a href="%s" class="thickbox fs-overlay" aria-label="%s" data-title="%s"></a>',
|
97 |
-
esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
|
98 |
-
'&TB_iframe=true&width=600&height=550' ) ),
|
99 |
-
esc_attr( sprintf( fs_text_inline( 'More information about %s', 'more-information-about-x', $slug ), $addon->title ) ),
|
100 |
-
esc_attr( $addon->title )
|
101 |
-
);
|
102 |
-
?>
|
103 |
-
<?php
|
104 |
-
if ( is_null( $addon->info ) ) {
|
105 |
-
$addon->info = new stdClass();
|
106 |
-
}
|
107 |
-
if ( ! isset( $addon->info->card_banner_url ) ) {
|
108 |
-
$addon->info->card_banner_url = '//dashboard.freemius.com/assets/img/marketing/blueprint-300x100.jpg';
|
109 |
-
}
|
110 |
-
if ( ! isset( $addon->info->short_description ) ) {
|
111 |
-
$addon->info->short_description = 'What\'s the one thing your add-on does really, really well?';
|
112 |
-
}
|
113 |
-
?>
|
114 |
-
<div class="fs-inner">
|
115 |
-
<ul>
|
116 |
-
<li class="fs-card-banner"
|
117 |
-
style="background-image: url('<?php echo $addon->info->card_banner_url ?>');"></li>
|
118 |
-
<!-- <li class="fs-tag"></li> -->
|
119 |
-
<li class="fs-title"><?php echo $addon->title ?></li>
|
120 |
-
<li class="fs-offer">
|
121 |
-
<span
|
122 |
-
class="fs-price"><?php
|
123 |
-
$descriptors = array();
|
124 |
-
|
125 |
-
if ($has_free_plan)
|
126 |
-
$descriptors[] = fs_text_inline( 'Free', 'free', $slug );
|
127 |
-
if ($has_paid_plan && $price > 0)
|
128 |
-
$descriptors[] = '$' . number_format( $price, 2 );
|
129 |
-
if ($has_trial)
|
130 |
-
$descriptors[] = fs_text_x_inline( 'Trial', 'trial period', 'trial', $slug );
|
131 |
-
|
132 |
-
echo implode(' - ', $descriptors) ?></span>
|
133 |
-
</li>
|
134 |
-
<li class="fs-description"><?php echo ! empty( $addon->info->short_description ) ? $addon->info->short_description : 'SHORT DESCRIPTION' ?></li>
|
135 |
-
<li class="fs-cta"><a class="button"><?php fs_esc_html_echo_inline( 'View details', 'view-details', $slug ) ?></a></li>
|
136 |
-
</ul>
|
137 |
-
</div>
|
138 |
-
</li>
|
139 |
-
<?php endforeach ?>
|
140 |
-
<?php endif ?>
|
141 |
-
</ul>
|
142 |
-
</div>
|
143 |
-
</div>
|
144 |
-
<script type="text/javascript">
|
145 |
-
(function ($) {
|
146 |
-
<?php if ( $open_addon ) : ?>
|
147 |
-
|
148 |
-
var interval = setInterval(function () {
|
149 |
-
// Open add-on information page.
|
150 |
-
<?php
|
151 |
-
/**
|
152 |
-
* @author Vova Feldman
|
153 |
-
*
|
154 |
-
* This code does NOT expose an XSS vulnerability because:
|
155 |
-
* 1. This page only renders for admins, so if an attacker manage to get
|
156 |
-
* admin access, they can do more harm.
|
157 |
-
* 2. This code won't be rendered unless $open_addon_slug matches any of
|
158 |
-
* the plugin's add-ons slugs.
|
159 |
-
*/
|
160 |
-
?>
|
161 |
-
$('.fs-card[data-slug=<?php echo $open_addon_slug ?>] a').click();
|
162 |
-
if ($('#TB_iframeContent').length > 0) {
|
163 |
-
clearInterval(interval);
|
164 |
-
interval = null;
|
165 |
-
}
|
166 |
-
}, 200);
|
167 |
-
|
168 |
-
<?php else : ?>
|
169 |
-
|
170 |
-
|
171 |
-
$('.fs-card.fs-addon')
|
172 |
-
.mouseover(function () {
|
173 |
-
$(this).find('.fs-cta .button').addClass('button-primary');
|
174 |
-
}).mouseout(function () {
|
175 |
-
$(this).find('.fs-cta .button').removeClass('button-primary');
|
176 |
-
});
|
177 |
-
|
178 |
-
<?php endif ?>
|
179 |
-
})(jQuery);
|
180 |
-
</script>
|
181 |
-
<?php
|
182 |
-
if ( $has_tabs ) {
|
183 |
-
$fs->_add_tabs_after_content();
|
184 |
-
}
|
185 |
-
|
186 |
-
$params = array(
|
187 |
-
'page' => 'addons',
|
188 |
-
'module_id' => $fs->get_id(),
|
189 |
-
'module_type' => $fs->get_module_type(),
|
190 |
-
'module_slug' => $slug,
|
191 |
-
'module_version' => $fs->get_plugin_version(),
|
192 |
-
);
|
193 |
fs_require_template( 'powered-by.php', $params );
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
* @var Freemius
|
16 |
+
*/
|
17 |
+
$fs = freemius( $VARS['id'] );
|
18 |
+
|
19 |
+
$slug = $fs->get_slug();
|
20 |
+
|
21 |
+
$open_addon_slug = fs_request_get( 'slug' );
|
22 |
+
|
23 |
+
$open_addon = false;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var FS_Plugin[]
|
27 |
+
*/
|
28 |
+
$addons = $fs->get_addons();
|
29 |
+
|
30 |
+
$has_addons = ( is_array( $addons ) && 0 < count( $addons ) );
|
31 |
+
|
32 |
+
$has_tabs = $fs->_add_tabs_before_content();
|
33 |
+
?>
|
34 |
+
<div id="fs_addons" class="wrap fs-section">
|
35 |
+
<?php if ( ! $has_tabs ) : ?>
|
36 |
+
<h2><?php echo esc_html( sprintf( fs_text_inline( 'Add Ons for %s', 'add-ons-for-x', $slug ), $fs->get_plugin_name() ) ) ?></h2>
|
37 |
+
<?php endif ?>
|
38 |
+
|
39 |
+
<div id="poststuff">
|
40 |
+
<?php if ( ! $has_addons ) : ?>
|
41 |
+
<h3><?php echo esc_html( sprintf(
|
42 |
+
'%s... %s',
|
43 |
+
fs_text_x_inline( 'Oops', 'exclamation', 'oops', $slug ),
|
44 |
+
fs_text_inline( 'We could\'nt load the add-ons list. It\'s probably an issue on our side, please try to come back in few minutes.', 'add-ons-missing', $slug )
|
45 |
+
) ) ?></h3>
|
46 |
+
<?php endif ?>
|
47 |
+
<ul class="fs-cards-list">
|
48 |
+
<?php if ( $has_addons ) : ?>
|
49 |
+
<?php foreach ( $addons as $addon ) : ?>
|
50 |
+
<?php
|
51 |
+
$open_addon = ( $open_addon || ( $open_addon_slug === $addon->slug ) );
|
52 |
+
|
53 |
+
$price = 0;
|
54 |
+
$has_trial = false;
|
55 |
+
$has_free_plan = false;
|
56 |
+
$has_paid_plan = false;
|
57 |
+
|
58 |
+
$result = $fs->get_api_plugin_scope()->get( "/addons/{$addon->id}/pricing.json?type=visible" );
|
59 |
+
if ( ! isset( $result->error ) ) {
|
60 |
+
$plans = $result->plans;
|
61 |
+
|
62 |
+
if ( is_array( $plans ) && 0 < count( $plans ) ) {
|
63 |
+
foreach ( $plans as $plan ) {
|
64 |
+
if ( ! isset( $plan->pricing ) ||
|
65 |
+
! is_array( $plan->pricing ) ||
|
66 |
+
0 == count( $plan->pricing )
|
67 |
+
) {
|
68 |
+
// No pricing means a free plan.
|
69 |
+
$has_free_plan = true;
|
70 |
+
continue;
|
71 |
+
}
|
72 |
+
|
73 |
+
|
74 |
+
$has_paid_plan = true;
|
75 |
+
$has_trial = $has_trial || ( is_numeric( $plan->trial_period ) && ( $plan->trial_period > 0 ) );
|
76 |
+
|
77 |
+
$min_price = 999999;
|
78 |
+
foreach ( $plan->pricing as $pricing ) {
|
79 |
+
if ( ! is_null( $pricing->annual_price ) && $pricing->annual_price > 0 ) {
|
80 |
+
$min_price = min( $min_price, $pricing->annual_price );
|
81 |
+
} else if ( ! is_null( $pricing->monthly_price ) && $pricing->monthly_price > 0 ) {
|
82 |
+
$min_price = min( $min_price, 12 * $pricing->monthly_price );
|
83 |
+
}
|
84 |
+
}
|
85 |
+
|
86 |
+
if ( $min_price < 999999 ) {
|
87 |
+
$price = $min_price;
|
88 |
+
}
|
89 |
+
|
90 |
+
}
|
91 |
+
}
|
92 |
+
}
|
93 |
+
?>
|
94 |
+
<li class="fs-card fs-addon" data-slug="<?php echo $addon->slug ?>">
|
95 |
+
<?php
|
96 |
+
echo sprintf( '<a href="%s" class="thickbox fs-overlay" aria-label="%s" data-title="%s"></a>',
|
97 |
+
esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
|
98 |
+
'&TB_iframe=true&width=600&height=550' ) ),
|
99 |
+
esc_attr( sprintf( fs_text_inline( 'More information about %s', 'more-information-about-x', $slug ), $addon->title ) ),
|
100 |
+
esc_attr( $addon->title )
|
101 |
+
);
|
102 |
+
?>
|
103 |
+
<?php
|
104 |
+
if ( is_null( $addon->info ) ) {
|
105 |
+
$addon->info = new stdClass();
|
106 |
+
}
|
107 |
+
if ( ! isset( $addon->info->card_banner_url ) ) {
|
108 |
+
$addon->info->card_banner_url = '//dashboard.freemius.com/assets/img/marketing/blueprint-300x100.jpg';
|
109 |
+
}
|
110 |
+
if ( ! isset( $addon->info->short_description ) ) {
|
111 |
+
$addon->info->short_description = 'What\'s the one thing your add-on does really, really well?';
|
112 |
+
}
|
113 |
+
?>
|
114 |
+
<div class="fs-inner">
|
115 |
+
<ul>
|
116 |
+
<li class="fs-card-banner"
|
117 |
+
style="background-image: url('<?php echo $addon->info->card_banner_url ?>');"></li>
|
118 |
+
<!-- <li class="fs-tag"></li> -->
|
119 |
+
<li class="fs-title"><?php echo $addon->title ?></li>
|
120 |
+
<li class="fs-offer">
|
121 |
+
<span
|
122 |
+
class="fs-price"><?php
|
123 |
+
$descriptors = array();
|
124 |
+
|
125 |
+
if ($has_free_plan)
|
126 |
+
$descriptors[] = fs_text_inline( 'Free', 'free', $slug );
|
127 |
+
if ($has_paid_plan && $price > 0)
|
128 |
+
$descriptors[] = '$' . number_format( $price, 2 );
|
129 |
+
if ($has_trial)
|
130 |
+
$descriptors[] = fs_text_x_inline( 'Trial', 'trial period', 'trial', $slug );
|
131 |
+
|
132 |
+
echo implode(' - ', $descriptors) ?></span>
|
133 |
+
</li>
|
134 |
+
<li class="fs-description"><?php echo ! empty( $addon->info->short_description ) ? $addon->info->short_description : 'SHORT DESCRIPTION' ?></li>
|
135 |
+
<li class="fs-cta"><a class="button"><?php fs_esc_html_echo_inline( 'View details', 'view-details', $slug ) ?></a></li>
|
136 |
+
</ul>
|
137 |
+
</div>
|
138 |
+
</li>
|
139 |
+
<?php endforeach ?>
|
140 |
+
<?php endif ?>
|
141 |
+
</ul>
|
142 |
+
</div>
|
143 |
+
</div>
|
144 |
+
<script type="text/javascript">
|
145 |
+
(function ($) {
|
146 |
+
<?php if ( $open_addon ) : ?>
|
147 |
+
|
148 |
+
var interval = setInterval(function () {
|
149 |
+
// Open add-on information page.
|
150 |
+
<?php
|
151 |
+
/**
|
152 |
+
* @author Vova Feldman
|
153 |
+
*
|
154 |
+
* This code does NOT expose an XSS vulnerability because:
|
155 |
+
* 1. This page only renders for admins, so if an attacker manage to get
|
156 |
+
* admin access, they can do more harm.
|
157 |
+
* 2. This code won't be rendered unless $open_addon_slug matches any of
|
158 |
+
* the plugin's add-ons slugs.
|
159 |
+
*/
|
160 |
+
?>
|
161 |
+
$('.fs-card[data-slug=<?php echo $open_addon_slug ?>] a').click();
|
162 |
+
if ($('#TB_iframeContent').length > 0) {
|
163 |
+
clearInterval(interval);
|
164 |
+
interval = null;
|
165 |
+
}
|
166 |
+
}, 200);
|
167 |
+
|
168 |
+
<?php else : ?>
|
169 |
+
|
170 |
+
|
171 |
+
$('.fs-card.fs-addon')
|
172 |
+
.mouseover(function () {
|
173 |
+
$(this).find('.fs-cta .button').addClass('button-primary');
|
174 |
+
}).mouseout(function () {
|
175 |
+
$(this).find('.fs-cta .button').removeClass('button-primary');
|
176 |
+
});
|
177 |
+
|
178 |
+
<?php endif ?>
|
179 |
+
})(jQuery);
|
180 |
+
</script>
|
181 |
+
<?php
|
182 |
+
if ( $has_tabs ) {
|
183 |
+
$fs->_add_tabs_after_content();
|
184 |
+
}
|
185 |
+
|
186 |
+
$params = array(
|
187 |
+
'page' => 'addons',
|
188 |
+
'module_id' => $fs->get_id(),
|
189 |
+
'module_type' => $fs->get_module_type(),
|
190 |
+
'module_slug' => $slug,
|
191 |
+
'module_version' => $fs->get_plugin_version(),
|
192 |
+
);
|
193 |
fs_require_template( 'powered-by.php', $params );
|
freemius/templates/admin-notice.php
CHANGED
@@ -1,48 +1,48 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
$dismiss_text = fs_text_x_inline( 'Dismiss', 'as close a window', 'dismiss' );
|
14 |
-
?>
|
15 |
-
<div<?php if ( ! empty( $VARS['id'] ) ) : ?> data-id="<?php echo $VARS['id'] ?>"<?php endif ?><?php if ( ! empty( $VARS['manager_id'] ) ) : ?> data-manager-id="<?php echo $VARS['manager_id'] ?>"<?php endif ?>
|
16 |
-
class="<?php
|
17 |
-
switch ( $VARS['type'] ) {
|
18 |
-
case 'error':
|
19 |
-
echo 'error form-invalid';
|
20 |
-
break;
|
21 |
-
case 'promotion':
|
22 |
-
echo 'updated promotion';
|
23 |
-
break;
|
24 |
-
case 'update':
|
25 |
-
// echo 'update-nag update';
|
26 |
-
// break;
|
27 |
-
case 'success':
|
28 |
-
default:
|
29 |
-
echo 'updated success';
|
30 |
-
break;
|
31 |
-
}
|
32 |
-
?> fs-notice<?php if ( ! empty( $VARS['sticky'] ) ) {
|
33 |
-
echo ' fs-sticky';
|
34 |
-
} ?><?php if ( ! empty( $VARS['plugin'] ) ) {
|
35 |
-
echo ' fs-has-title';
|
36 |
-
} ?>"><?php if ( ! empty( $VARS['plugin'] ) ) : ?>
|
37 |
-
<label class="fs-plugin-title"><?php echo $VARS['plugin'] ?></label>
|
38 |
-
<?php endif ?>
|
39 |
-
<?php if ( ! empty( $VARS['sticky'] ) ) : ?>
|
40 |
-
<div class="fs-close"><i class="dashicons dashicons-no"
|
41 |
-
title="<?php echo esc_attr( $dismiss_text ) ?>"></i> <span><?php echo esc_html( $dismiss_text ) ?></span>
|
42 |
-
</div>
|
43 |
-
<?php endif ?>
|
44 |
-
<div class="fs-notice-body">
|
45 |
-
<?php if ( ! empty( $VARS['title'] ) ) : ?><b><?php echo $VARS['title'] ?></b> <?php endif ?>
|
46 |
-
<?php echo $VARS['message'] ?>
|
47 |
-
</div>
|
48 |
-
</div>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
$dismiss_text = fs_text_x_inline( 'Dismiss', 'as close a window', 'dismiss' );
|
14 |
+
?>
|
15 |
+
<div<?php if ( ! empty( $VARS['id'] ) ) : ?> data-id="<?php echo $VARS['id'] ?>"<?php endif ?><?php if ( ! empty( $VARS['manager_id'] ) ) : ?> data-manager-id="<?php echo $VARS['manager_id'] ?>"<?php endif ?>
|
16 |
+
class="<?php
|
17 |
+
switch ( $VARS['type'] ) {
|
18 |
+
case 'error':
|
19 |
+
echo 'error form-invalid';
|
20 |
+
break;
|
21 |
+
case 'promotion':
|
22 |
+
echo 'updated promotion';
|
23 |
+
break;
|
24 |
+
case 'update':
|
25 |
+
// echo 'update-nag update';
|
26 |
+
// break;
|
27 |
+
case 'success':
|
28 |
+
default:
|
29 |
+
echo 'updated success';
|
30 |
+
break;
|
31 |
+
}
|
32 |
+
?> fs-notice<?php if ( ! empty( $VARS['sticky'] ) ) {
|
33 |
+
echo ' fs-sticky';
|
34 |
+
} ?><?php if ( ! empty( $VARS['plugin'] ) ) {
|
35 |
+
echo ' fs-has-title';
|
36 |
+
} ?>"><?php if ( ! empty( $VARS['plugin'] ) ) : ?>
|
37 |
+
<label class="fs-plugin-title"><?php echo $VARS['plugin'] ?></label>
|
38 |
+
<?php endif ?>
|
39 |
+
<?php if ( ! empty( $VARS['sticky'] ) ) : ?>
|
40 |
+
<div class="fs-close"><i class="dashicons dashicons-no"
|
41 |
+
title="<?php echo esc_attr( $dismiss_text ) ?>"></i> <span><?php echo esc_html( $dismiss_text ) ?></span>
|
42 |
+
</div>
|
43 |
+
<?php endif ?>
|
44 |
+
<div class="fs-notice-body">
|
45 |
+
<?php if ( ! empty( $VARS['title'] ) ) : ?><b><?php echo $VARS['title'] ?></b> <?php endif ?>
|
46 |
+
<?php echo $VARS['message'] ?>
|
47 |
+
</div>
|
48 |
+
</div>
|
freemius/templates/all-admin-notice.php
CHANGED
@@ -1,39 +1,39 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array $VARS
|
15 |
-
*/
|
16 |
-
?>
|
17 |
-
<div class="<?php
|
18 |
-
switch ($VARS['type']) {
|
19 |
-
case 'error':
|
20 |
-
echo 'error form-invalid';
|
21 |
-
break;
|
22 |
-
case 'update-nag':
|
23 |
-
echo 'update-nag ';
|
24 |
-
break;
|
25 |
-
case 'update':
|
26 |
-
case 'success':
|
27 |
-
default:
|
28 |
-
echo 'updated success';
|
29 |
-
break;
|
30 |
-
}
|
31 |
-
?> fs-notice">
|
32 |
-
<?php if ('update-nag' !== $VARS['type']) : ?><p><?php endif ?>
|
33 |
-
<?php if (!empty($VARS['title'])) : ?>
|
34 |
-
<b><?php echo $VARS['title'] ?></b>
|
35 |
-
<?php endif ?>
|
36 |
-
<?php echo $VARS['message'] ?>
|
37 |
-
<?php if ('update-nag' !== $VARS['type']) : ?></p><?php endif ?>
|
38 |
-
<?php if ($VARS['sticky']) : ?><i class="dashicons dashicons-no"></i><?php endif ?>
|
39 |
</div>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
*/
|
16 |
+
?>
|
17 |
+
<div class="<?php
|
18 |
+
switch ($VARS['type']) {
|
19 |
+
case 'error':
|
20 |
+
echo 'error form-invalid';
|
21 |
+
break;
|
22 |
+
case 'update-nag':
|
23 |
+
echo 'update-nag ';
|
24 |
+
break;
|
25 |
+
case 'update':
|
26 |
+
case 'success':
|
27 |
+
default:
|
28 |
+
echo 'updated success';
|
29 |
+
break;
|
30 |
+
}
|
31 |
+
?> fs-notice">
|
32 |
+
<?php if ('update-nag' !== $VARS['type']) : ?><p><?php endif ?>
|
33 |
+
<?php if (!empty($VARS['title'])) : ?>
|
34 |
+
<b><?php echo $VARS['title'] ?></b>
|
35 |
+
<?php endif ?>
|
36 |
+
<?php echo $VARS['message'] ?>
|
37 |
+
<?php if ('update-nag' !== $VARS['type']) : ?></p><?php endif ?>
|
38 |
+
<?php if ($VARS['sticky']) : ?><i class="dashicons dashicons-no"></i><?php endif ?>
|
39 |
</div>
|
freemius/templates/checkout-legacy.php
CHANGED
@@ -1,242 +1,242 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
wp_enqueue_script( 'jquery' );
|
14 |
-
wp_enqueue_script( 'json2' );
|
15 |
-
fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
|
16 |
-
fs_enqueue_local_script( 'fs-postmessage', 'postmessage.js' );
|
17 |
-
fs_enqueue_local_style( 'fs_common', '/admin/common.css' );
|
18 |
-
|
19 |
-
/**
|
20 |
-
* @var array $VARS
|
21 |
-
*/
|
22 |
-
$slug = $VARS['slug'];
|
23 |
-
$fs = freemius( $slug );
|
24 |
-
|
25 |
-
$timestamp = time();
|
26 |
-
|
27 |
-
$context_params = array(
|
28 |
-
'plugin_id' => $fs->get_id(),
|
29 |
-
'plugin_public_key' => $fs->get_public_key(),
|
30 |
-
'plugin_version' => $fs->get_plugin_version(),
|
31 |
-
);
|
32 |
-
|
33 |
-
// Get site context secure params.
|
34 |
-
if ( $fs->is_registered() ) {
|
35 |
-
$site = $fs->get_site();
|
36 |
-
$plugin_id = fs_request_get( 'plugin_id', $fs->get_id() );
|
37 |
-
|
38 |
-
if ( $plugin_id != $fs->get_id() ) {
|
39 |
-
if ( $fs->is_addon_activated( $plugin_id ) ) {
|
40 |
-
$fs_addon = Freemius::get_instance_by_id( $plugin_id );
|
41 |
-
$site = $fs_addon->get_site();
|
42 |
-
}
|
43 |
-
}
|
44 |
-
|
45 |
-
$context_params = array_merge( $context_params, FS_Security::instance()->get_context_params(
|
46 |
-
$site,
|
47 |
-
$timestamp,
|
48 |
-
'checkout'
|
49 |
-
) );
|
50 |
-
} else {
|
51 |
-
$current_user = Freemius::_get_current_wp_user();
|
52 |
-
|
53 |
-
// Add site and user info to the request, this information
|
54 |
-
// is NOT being stored unless the user complete the purchase
|
55 |
-
// and agrees to the TOS.
|
56 |
-
$context_params = array_merge( $context_params, array(
|
57 |
-
'user_firstname' => $current_user->user_firstname,
|
58 |
-
'user_lastname' => $current_user->user_lastname,
|
59 |
-
'user_email' => $current_user->user_email,
|
60 |
-
'home_url' => home_url(),
|
61 |
-
) );
|
62 |
-
|
63 |
-
$fs_user = Freemius::_get_user_by_email( $current_user->user_email );
|
64 |
-
|
65 |
-
if ( is_object( $fs_user ) ) {
|
66 |
-
$context_params = array_merge( $context_params, FS_Security::instance()->get_context_params(
|
67 |
-
$fs_user,
|
68 |
-
$timestamp,
|
69 |
-
'checkout'
|
70 |
-
) );
|
71 |
-
}
|
72 |
-
}
|
73 |
-
|
74 |
-
if ( $fs->is_payments_sandbox() ) {
|
75 |
-
// Append plugin secure token for sandbox mode authentication.
|
76 |
-
$context_params['sandbox'] = FS_Security::instance()->get_secure_token(
|
77 |
-
$fs->get_plugin(),
|
78 |
-
$timestamp,
|
79 |
-
'checkout'
|
80 |
-
);
|
81 |
-
|
82 |
-
/**
|
83 |
-
* @since 1.1.7.3 Add security timestamp for sandbox even for anonymous user.
|
84 |
-
*/
|
85 |
-
if ( empty( $context_params['s_ctx_ts'] ) ) {
|
86 |
-
$context_params['s_ctx_ts'] = $timestamp;
|
87 |
-
}
|
88 |
-
}
|
89 |
-
|
90 |
-
$return_url = $fs->_get_sync_license_url( isset( $_GET['plugin_id'] ) ? $_GET['plugin_id'] : $fs->get_id() );
|
91 |
-
|
92 |
-
$query_params = array_merge( $context_params, $_GET, array(
|
93 |
-
// Current plugin version.
|
94 |
-
'plugin_version' => $fs->get_plugin_version(),
|
95 |
-
'sdk_version' => WP_FS__SDK_VERSION,
|
96 |
-
'return_url' => $return_url,
|
97 |
-
// Admin CSS URL for style/design competability.
|
98 |
-
// 'wp_admin_css' => get_bloginfo('wpurl') . "/wp-admin/load-styles.php?c=1&load=buttons,wp-admin,dashicons",
|
99 |
-
) );
|
100 |
-
?>
|
101 |
-
<div id="fs_checkout" class="wrap" style="margin: 0 0 -65px -20px;">
|
102 |
-
<div id="iframe"></div>
|
103 |
-
<script type="text/javascript">
|
104 |
-
// http://stackoverflow.com/questions/4583703/jquery-post-request-not-ajax
|
105 |
-
jQuery(function ($) {
|
106 |
-
$.extend({
|
107 |
-
form: function (url, data, method) {
|
108 |
-
if (method == null) method = 'POST';
|
109 |
-
if (data == null) data = {};
|
110 |
-
|
111 |
-
var form = $('<form>').attr({
|
112 |
-
method: method,
|
113 |
-
action: url
|
114 |
-
}).css({
|
115 |
-
display: 'none'
|
116 |
-
});
|
117 |
-
|
118 |
-
var addData = function (name, data) {
|
119 |
-
if ($.isArray(data)) {
|
120 |
-
for (var i = 0; i < data.length; i++) {
|
121 |
-
var value = data[i];
|
122 |
-
addData(name + '[]', value);
|
123 |
-
}
|
124 |
-
} else if (typeof data === 'object') {
|
125 |
-
for (var key in data) {
|
126 |
-
if (data.hasOwnProperty(key)) {
|
127 |
-
addData(name + '[' + key + ']', data[key]);
|
128 |
-
}
|
129 |
-
}
|
130 |
-
} else if (data != null) {
|
131 |
-
form.append($('<input>').attr({
|
132 |
-
type : 'hidden',
|
133 |
-
name : String(name),
|
134 |
-
value: String(data)
|
135 |
-
}));
|
136 |
-
}
|
137 |
-
};
|
138 |
-
|
139 |
-
for (var key in data) {
|
140 |
-
if (data.hasOwnProperty(key)) {
|
141 |
-
addData(key, data[key]);
|
142 |
-
}
|
143 |
-
}
|
144 |
-
|
145 |
-
return form.appendTo('body');
|
146 |
-
}
|
147 |
-
});
|
148 |
-
});
|
149 |
-
|
150 |
-
(function ($) {
|
151 |
-
$(function () {
|
152 |
-
|
153 |
-
var
|
154 |
-
// Keep track of the iframe height.
|
155 |
-
iframe_height = 800,
|
156 |
-
base_url = '<?php echo WP_FS__ADDRESS ?>',
|
157 |
-
// Pass the parent page URL into the Iframe in a meaningful way (this URL could be
|
158 |
-
// passed via query string or hard coded into the child page, it depends on your needs).
|
159 |
-
src = base_url + '/checkout/?<?php echo ( isset( $_REQUEST['XDEBUG_SESSION'] ) ? 'XDEBUG_SESSION=' . $_REQUEST['XDEBUG_SESSION'] . '&' : '' ) . http_build_query( $query_params ) ?>#' + encodeURIComponent(document.location.href),
|
160 |
-
|
161 |
-
// Append the Iframe into the DOM.
|
162 |
-
iframe = $('<iframe " src="' + src + '" width="100%" height="' + iframe_height + 'px" scrolling="no" frameborder="0" style="background: transparent;"><\/iframe>')
|
163 |
-
.appendTo('#iframe');
|
164 |
-
|
165 |
-
FS.PostMessage.init(base_url, [iframe[0]]);
|
166 |
-
FS.PostMessage.receiveOnce('height', function (data) {
|
167 |
-
var h = data.height;
|
168 |
-
if (!isNaN(h) && h > 0 && h != iframe_height) {
|
169 |
-
iframe_height = h;
|
170 |
-
iframe.height(iframe_height + 'px');
|
171 |
-
|
172 |
-
FS.PostMessage.postScroll(iframe[0]);
|
173 |
-
}
|
174 |
-
});
|
175 |
-
|
176 |
-
FS.PostMessage.receiveOnce('install', function (data) {
|
177 |
-
// Post data to activation URL.
|
178 |
-
$.form('<?php echo fs_nonce_url( $fs->_get_admin_page_url( 'account', array(
|
179 |
-
'fs_action' => $slug . '_activate_new',
|
180 |
-
'plugin_id' => isset( $_GET['plugin_id'] ) ? $_GET['plugin_id'] : $fs->get_id()
|
181 |
-
) ), $slug . '_activate_new' ) ?>', {
|
182 |
-
user_id : data.user.id,
|
183 |
-
user_secret_key : data.user.secret_key,
|
184 |
-
user_public_key : data.user.public_key,
|
185 |
-
install_id : data.install.id,
|
186 |
-
install_secret_key: data.install.secret_key,
|
187 |
-
install_public_key: data.install.public_key
|
188 |
-
}).submit();
|
189 |
-
});
|
190 |
-
|
191 |
-
FS.PostMessage.receiveOnce('pending_activation', function (data) {
|
192 |
-
$.form('<?php echo fs_nonce_url( $fs->_get_admin_page_url( 'account', array(
|
193 |
-
'fs_action' => $slug . '_activate_new',
|
194 |
-
'plugin_id' => fs_request_get( 'plugin_id', $fs->get_id() ),
|
195 |
-
'pending_activation' => true,
|
196 |
-
) ), $slug . '_activate_new' ) ?>', {
|
197 |
-
user_email: data.user_email
|
198 |
-
}).submit();
|
199 |
-
});
|
200 |
-
|
201 |
-
FS.PostMessage.receiveOnce('get_context', function () {
|
202 |
-
console.debug('receiveOnce', 'get_context');
|
203 |
-
|
204 |
-
// If the user didn't connect his account with Freemius,
|
205 |
-
// once he accepts the Terms of Service and Privacy Policy,
|
206 |
-
// and then click the purchase button, the context information
|
207 |
-
// of the user will be shared with Freemius in order to complete the
|
208 |
-
// purchase workflow and activate the license for the right user.
|
209 |
-
<?php $install_data = array_merge( $fs->get_opt_in_params(),
|
210 |
-
array(
|
211 |
-
'activation_url' => fs_nonce_url( $fs->_get_admin_page_url( '',
|
212 |
-
array(
|
213 |
-
'fs_action' => $slug . '_activate_new',
|
214 |
-
'plugin_id' => fs_request_get( 'plugin_id', $fs->get_id() ),
|
215 |
-
|
216 |
-
) ),
|
217 |
-
$slug . '_activate_new' )
|
218 |
-
) ) ?>
|
219 |
-
FS.PostMessage.post('context', <?php echo json_encode( $install_data ) ?>, iframe[0]);
|
220 |
-
});
|
221 |
-
|
222 |
-
FS.PostMessage.receiveOnce('get_dimensions', function (data) {
|
223 |
-
console.debug('receiveOnce', 'get_dimensions');
|
224 |
-
|
225 |
-
FS.PostMessage.post('dimensions', {
|
226 |
-
height : $(document.body).height(),
|
227 |
-
scrollTop: $(document).scrollTop()
|
228 |
-
}, iframe[0]);
|
229 |
-
});
|
230 |
-
});
|
231 |
-
})(jQuery);
|
232 |
-
</script>
|
233 |
-
</div>
|
234 |
-
<?php
|
235 |
-
$params = array(
|
236 |
-
'page' => 'checkout',
|
237 |
-
'module_id' => $fs->get_id(),
|
238 |
-
'module_slug' => $slug,
|
239 |
-
'module_version' => $fs->get_plugin_version(),
|
240 |
-
);
|
241 |
-
fs_require_template( 'powered-by.php', $params );
|
242 |
-
?>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
wp_enqueue_script( 'jquery' );
|
14 |
+
wp_enqueue_script( 'json2' );
|
15 |
+
fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
|
16 |
+
fs_enqueue_local_script( 'fs-postmessage', 'postmessage.js' );
|
17 |
+
fs_enqueue_local_style( 'fs_common', '/admin/common.css' );
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var array $VARS
|
21 |
+
*/
|
22 |
+
$slug = $VARS['slug'];
|
23 |
+
$fs = freemius( $slug );
|
24 |
+
|
25 |
+
$timestamp = time();
|
26 |
+
|
27 |
+
$context_params = array(
|
28 |
+
'plugin_id' => $fs->get_id(),
|
29 |
+
'plugin_public_key' => $fs->get_public_key(),
|
30 |
+
'plugin_version' => $fs->get_plugin_version(),
|
31 |
+
);
|
32 |
+
|
33 |
+
// Get site context secure params.
|
34 |
+
if ( $fs->is_registered() ) {
|
35 |
+
$site = $fs->get_site();
|
36 |
+
$plugin_id = fs_request_get( 'plugin_id', $fs->get_id() );
|
37 |
+
|
38 |
+
if ( $plugin_id != $fs->get_id() ) {
|
39 |
+
if ( $fs->is_addon_activated( $plugin_id ) ) {
|
40 |
+
$fs_addon = Freemius::get_instance_by_id( $plugin_id );
|
41 |
+
$site = $fs_addon->get_site();
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
$context_params = array_merge( $context_params, FS_Security::instance()->get_context_params(
|
46 |
+
$site,
|
47 |
+
$timestamp,
|
48 |
+
'checkout'
|
49 |
+
) );
|
50 |
+
} else {
|
51 |
+
$current_user = Freemius::_get_current_wp_user();
|
52 |
+
|
53 |
+
// Add site and user info to the request, this information
|
54 |
+
// is NOT being stored unless the user complete the purchase
|
55 |
+
// and agrees to the TOS.
|
56 |
+
$context_params = array_merge( $context_params, array(
|
57 |
+
'user_firstname' => $current_user->user_firstname,
|
58 |
+
'user_lastname' => $current_user->user_lastname,
|
59 |
+
'user_email' => $current_user->user_email,
|
60 |
+
'home_url' => home_url(),
|
61 |
+
) );
|
62 |
+
|
63 |
+
$fs_user = Freemius::_get_user_by_email( $current_user->user_email );
|
64 |
+
|
65 |
+
if ( is_object( $fs_user ) ) {
|
66 |
+
$context_params = array_merge( $context_params, FS_Security::instance()->get_context_params(
|
67 |
+
$fs_user,
|
68 |
+
$timestamp,
|
69 |
+
'checkout'
|
70 |
+
) );
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
if ( $fs->is_payments_sandbox() ) {
|
75 |
+
// Append plugin secure token for sandbox mode authentication.
|
76 |
+
$context_params['sandbox'] = FS_Security::instance()->get_secure_token(
|
77 |
+
$fs->get_plugin(),
|
78 |
+
$timestamp,
|
79 |
+
'checkout'
|
80 |
+
);
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @since 1.1.7.3 Add security timestamp for sandbox even for anonymous user.
|
84 |
+
*/
|
85 |
+
if ( empty( $context_params['s_ctx_ts'] ) ) {
|
86 |
+
$context_params['s_ctx_ts'] = $timestamp;
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
$return_url = $fs->_get_sync_license_url( isset( $_GET['plugin_id'] ) ? $_GET['plugin_id'] : $fs->get_id() );
|
91 |
+
|
92 |
+
$query_params = array_merge( $context_params, $_GET, array(
|
93 |
+
// Current plugin version.
|
94 |
+
'plugin_version' => $fs->get_plugin_version(),
|
95 |
+
'sdk_version' => WP_FS__SDK_VERSION,
|
96 |
+
'return_url' => $return_url,
|
97 |
+
// Admin CSS URL for style/design competability.
|
98 |
+
// 'wp_admin_css' => get_bloginfo('wpurl') . "/wp-admin/load-styles.php?c=1&load=buttons,wp-admin,dashicons",
|
99 |
+
) );
|
100 |
+
?>
|
101 |
+
<div id="fs_checkout" class="wrap" style="margin: 0 0 -65px -20px;">
|
102 |
+
<div id="iframe"></div>
|
103 |
+
<script type="text/javascript">
|
104 |
+
// http://stackoverflow.com/questions/4583703/jquery-post-request-not-ajax
|
105 |
+
jQuery(function ($) {
|
106 |
+
$.extend({
|
107 |
+
form: function (url, data, method) {
|
108 |
+
if (method == null) method = 'POST';
|
109 |
+
if (data == null) data = {};
|
110 |
+
|
111 |
+
var form = $('<form>').attr({
|
112 |
+
method: method,
|
113 |
+
action: url
|
114 |
+
}).css({
|
115 |
+
display: 'none'
|
116 |
+
});
|
117 |
+
|
118 |
+
var addData = function (name, data) {
|
119 |
+
if ($.isArray(data)) {
|
120 |
+
for (var i = 0; i < data.length; i++) {
|
121 |
+
var value = data[i];
|
122 |
+
addData(name + '[]', value);
|
123 |
+
}
|
124 |
+
} else if (typeof data === 'object') {
|
125 |
+
for (var key in data) {
|
126 |
+
if (data.hasOwnProperty(key)) {
|
127 |
+
addData(name + '[' + key + ']', data[key]);
|
128 |
+
}
|
129 |
+
}
|
130 |
+
} else if (data != null) {
|
131 |
+
form.append($('<input>').attr({
|
132 |
+
type : 'hidden',
|
133 |
+
name : String(name),
|
134 |
+
value: String(data)
|
135 |
+
}));
|
136 |
+
}
|
137 |
+
};
|
138 |
+
|
139 |
+
for (var key in data) {
|
140 |
+
if (data.hasOwnProperty(key)) {
|
141 |
+
addData(key, data[key]);
|
142 |
+
}
|
143 |
+
}
|
144 |
+
|
145 |
+
return form.appendTo('body');
|
146 |
+
}
|
147 |
+
});
|
148 |
+
});
|
149 |
+
|
150 |
+
(function ($) {
|
151 |
+
$(function () {
|
152 |
+
|
153 |
+
var
|
154 |
+
// Keep track of the iframe height.
|
155 |
+
iframe_height = 800,
|
156 |
+
base_url = '<?php echo WP_FS__ADDRESS ?>',
|
157 |
+
// Pass the parent page URL into the Iframe in a meaningful way (this URL could be
|
158 |
+
// passed via query string or hard coded into the child page, it depends on your needs).
|
159 |
+
src = base_url + '/checkout/?<?php echo ( isset( $_REQUEST['XDEBUG_SESSION'] ) ? 'XDEBUG_SESSION=' . $_REQUEST['XDEBUG_SESSION'] . '&' : '' ) . http_build_query( $query_params ) ?>#' + encodeURIComponent(document.location.href),
|
160 |
+
|
161 |
+
// Append the Iframe into the DOM.
|
162 |
+
iframe = $('<iframe " src="' + src + '" width="100%" height="' + iframe_height + 'px" scrolling="no" frameborder="0" style="background: transparent;"><\/iframe>')
|
163 |
+
.appendTo('#iframe');
|
164 |
+
|
165 |
+
FS.PostMessage.init(base_url, [iframe[0]]);
|
166 |
+
FS.PostMessage.receiveOnce('height', function (data) {
|
167 |
+
var h = data.height;
|
168 |
+
if (!isNaN(h) && h > 0 && h != iframe_height) {
|
169 |
+
iframe_height = h;
|
170 |
+
iframe.height(iframe_height + 'px');
|
171 |
+
|
172 |
+
FS.PostMessage.postScroll(iframe[0]);
|
173 |
+
}
|
174 |
+
});
|
175 |
+
|
176 |
+
FS.PostMessage.receiveOnce('install', function (data) {
|
177 |
+
// Post data to activation URL.
|
178 |
+
$.form('<?php echo fs_nonce_url( $fs->_get_admin_page_url( 'account', array(
|
179 |
+
'fs_action' => $slug . '_activate_new',
|
180 |
+
'plugin_id' => isset( $_GET['plugin_id'] ) ? $_GET['plugin_id'] : $fs->get_id()
|
181 |
+
) ), $slug . '_activate_new' ) ?>', {
|
182 |
+
user_id : data.user.id,
|
183 |
+
user_secret_key : data.user.secret_key,
|
184 |
+
user_public_key : data.user.public_key,
|
185 |
+
install_id : data.install.id,
|
186 |
+
install_secret_key: data.install.secret_key,
|
187 |
+
install_public_key: data.install.public_key
|
188 |
+
}).submit();
|
189 |
+
});
|
190 |
+
|
191 |
+
FS.PostMessage.receiveOnce('pending_activation', function (data) {
|
192 |
+
$.form('<?php echo fs_nonce_url( $fs->_get_admin_page_url( 'account', array(
|
193 |
+
'fs_action' => $slug . '_activate_new',
|
194 |
+
'plugin_id' => fs_request_get( 'plugin_id', $fs->get_id() ),
|
195 |
+
'pending_activation' => true,
|
196 |
+
) ), $slug . '_activate_new' ) ?>', {
|
197 |
+
user_email: data.user_email
|
198 |
+
}).submit();
|
199 |
+
});
|
200 |
+
|
201 |
+
FS.PostMessage.receiveOnce('get_context', function () {
|
202 |
+
console.debug('receiveOnce', 'get_context');
|
203 |
+
|
204 |
+
// If the user didn't connect his account with Freemius,
|
205 |
+
// once he accepts the Terms of Service and Privacy Policy,
|
206 |
+
// and then click the purchase button, the context information
|
207 |
+
// of the user will be shared with Freemius in order to complete the
|
208 |
+
// purchase workflow and activate the license for the right user.
|
209 |
+
<?php $install_data = array_merge( $fs->get_opt_in_params(),
|
210 |
+
array(
|
211 |
+
'activation_url' => fs_nonce_url( $fs->_get_admin_page_url( '',
|
212 |
+
array(
|
213 |
+
'fs_action' => $slug . '_activate_new',
|
214 |
+
'plugin_id' => fs_request_get( 'plugin_id', $fs->get_id() ),
|
215 |
+
|
216 |
+
) ),
|
217 |
+
$slug . '_activate_new' )
|
218 |
+
) ) ?>
|
219 |
+
FS.PostMessage.post('context', <?php echo json_encode( $install_data ) ?>, iframe[0]);
|
220 |
+
});
|
221 |
+
|
222 |
+
FS.PostMessage.receiveOnce('get_dimensions', function (data) {
|
223 |
+
console.debug('receiveOnce', 'get_dimensions');
|
224 |
+
|
225 |
+
FS.PostMessage.post('dimensions', {
|
226 |
+
height : $(document.body).height(),
|
227 |
+
scrollTop: $(document).scrollTop()
|
228 |
+
}, iframe[0]);
|
229 |
+
});
|
230 |
+
});
|
231 |
+
})(jQuery);
|
232 |
+
</script>
|
233 |
+
</div>
|
234 |
+
<?php
|
235 |
+
$params = array(
|
236 |
+
'page' => 'checkout',
|
237 |
+
'module_id' => $fs->get_id(),
|
238 |
+
'module_slug' => $slug,
|
239 |
+
'module_version' => $fs->get_plugin_version(),
|
240 |
+
);
|
241 |
+
fs_require_template( 'powered-by.php', $params );
|
242 |
+
?>
|
freemius/templates/debug/api-calls.php
CHANGED
@@ -1,155 +1,155 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.1.7.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
if ( class_exists( 'Freemius_Api_WordPress' ) ) {
|
14 |
-
$logger = Freemius_Api_WordPress::GetLogger();
|
15 |
-
} else {
|
16 |
-
$logger = array();
|
17 |
-
}
|
18 |
-
|
19 |
-
$counters = array(
|
20 |
-
'GET' => 0,
|
21 |
-
'POST' => 0,
|
22 |
-
'PUT' => 0,
|
23 |
-
'DELETE' => 0
|
24 |
-
);
|
25 |
-
|
26 |
-
$show_body = false;
|
27 |
-
foreach ( $logger as $log ) {
|
28 |
-
$counters[ $log['method'] ] ++;
|
29 |
-
|
30 |
-
if ( ! is_null( $log['body'] ) ) {
|
31 |
-
$show_body = true;
|
32 |
-
}
|
33 |
-
}
|
34 |
-
|
35 |
-
$pretty_print = $show_body && defined( 'JSON_PRETTY_PRINT' ) && version_compare( phpversion(), '5.3', '>=' );
|
36 |
-
|
37 |
-
/**
|
38 |
-
* This template is used for debugging, therefore, when possible
|
39 |
-
* we'd like to prettify the output of a JSON encoded variable.
|
40 |
-
* This will only be executed when $pretty_print is `true`, and
|
41 |
-
* the var is `true` only for PHP 5.3 and higher. Due to the
|
42 |
-
* limitations of the current Theme Check, it throws an error
|
43 |
-
* that using the "options" parameter (the 2nd param) is not
|
44 |
-
* supported in PHP 5.2 and lower. Thus, we added this alias
|
45 |
-
* variable to work around that false-positive.
|
46 |
-
*
|
47 |
-
* @author Vova Feldman (@svovaf)
|
48 |
-
* @since 1.2.2.7
|
49 |
-
*/
|
50 |
-
$encode = 'json_encode';
|
51 |
-
|
52 |
-
$root_path_len = strlen( ABSPATH );
|
53 |
-
|
54 |
-
$ms_text = fs_text_x_inline( 'ms', 'milliseconds' );
|
55 |
-
?>
|
56 |
-
<h1><?php fs_echo_inline( 'API' ) ?></h1>
|
57 |
-
|
58 |
-
<h2><span>Total Time:</span><?php echo Freemius_Debug_Bar_Panel::total_time() ?></h2>
|
59 |
-
|
60 |
-
<h2><span>Total Requests:</span><?php echo Freemius_Debug_Bar_Panel::requests_count() ?></h2>
|
61 |
-
<?php foreach ( $counters as $method => $count ) : ?>
|
62 |
-
<h2><span><?php echo $method ?>:</span><?php echo number_format( $count ) ?></h2>
|
63 |
-
<?php endforeach ?>
|
64 |
-
<table class="widefat">
|
65 |
-
<thead>
|
66 |
-
<tr>
|
67 |
-
<th>#</th>
|
68 |
-
<th><?php fs_esc_html_echo_inline( 'Method' ) ?></th>
|
69 |
-
<th><?php fs_esc_html_echo_inline( 'Code' ) ?></th>
|
70 |
-
<th><?php fs_esc_html_echo_inline( 'Length' ) ?></th>
|
71 |
-
<th><?php fs_esc_html_echo_x_inline( 'Path', 'as file/folder path' ) ?></th>
|
72 |
-
<?php if ( $show_body ) : ?>
|
73 |
-
<th><?php fs_esc_html_echo_inline( 'Body' ) ?></th>
|
74 |
-
<?php endif ?>
|
75 |
-
<th><?php fs_esc_html_echo_inline( 'Result' ) ?></th>
|
76 |
-
<th><?php fs_esc_html_echo_inline( 'Start' ) ?></th>
|
77 |
-
<th><?php fs_esc_html_echo_inline( 'End' ) ?></th>
|
78 |
-
</tr>
|
79 |
-
</thead>
|
80 |
-
<tbody>
|
81 |
-
<?php foreach ( $logger as $log ) : ?>
|
82 |
-
<tr>
|
83 |
-
<td><?php echo $log['id'] ?>.</td>
|
84 |
-
<td><?php echo $log['method'] ?></td>
|
85 |
-
<td><?php echo $log['code'] ?></td>
|
86 |
-
<td><?php echo number_format( 100 * $log['total'], 2 ) . ' ' . $ms_text ?></td>
|
87 |
-
<td>
|
88 |
-
<?php
|
89 |
-
printf( '<a href="#" onclick="jQuery(this).parent().find(\'table\').toggle(); return false;">%s</a>',
|
90 |
-
$log['path']
|
91 |
-
);
|
92 |
-
?>
|
93 |
-
<table class="widefat" style="display: none">
|
94 |
-
<tbody>
|
95 |
-
<?php for ( $i = 0, $bt = $log['backtrace'], $len = count( $bt ); $i < $len; $i ++ ) : ?>
|
96 |
-
<tr>
|
97 |
-
<td><?php echo( $len - $i ) ?></td>
|
98 |
-
<td><?php if ( isset( $bt[ $i ]['function'] ) ) {
|
99 |
-
echo ( isset( $bt[ $i ]['class'] ) ? $bt[ $i ]['class'] . $bt[ $i ]['type'] : '' ) . $bt[ $i ]['function'];
|
100 |
-
} ?></td>
|
101 |
-
<td><?php if ( isset( $bt[ $i ]['file'] ) ) {
|
102 |
-
echo substr( $bt[ $i ]['file'], $root_path_len ) . ':' . $bt[ $i ]['line'];
|
103 |
-
} ?></td>
|
104 |
-
</tr>
|
105 |
-
<?php endfor ?>
|
106 |
-
</tbody>
|
107 |
-
</table>
|
108 |
-
</td>
|
109 |
-
<?php if ( $show_body ) : ?>
|
110 |
-
<td>
|
111 |
-
<?php if ( 'GET' !== $log['method'] ) : ?>
|
112 |
-
<?php
|
113 |
-
$body = $log['body'];
|
114 |
-
printf(
|
115 |
-
'<a href="#" onclick="jQuery(this).parent().find(\'pre\').toggle(); return false;">%s</a>',
|
116 |
-
substr( $body, 0, 32 ) . ( 32 < strlen( $body ) ? '...' : '' )
|
117 |
-
);
|
118 |
-
if ( $pretty_print ) {
|
119 |
-
$body = $encode( json_decode( $log['body'] ), JSON_PRETTY_PRINT );
|
120 |
-
}
|
121 |
-
?>
|
122 |
-
<pre style="display: none"><code><?php echo esc_html( $body ) ?></code></pre>
|
123 |
-
<?php endif ?>
|
124 |
-
</td>
|
125 |
-
<?php endif ?>
|
126 |
-
<td>
|
127 |
-
<?php
|
128 |
-
$result = $log['result'];
|
129 |
-
|
130 |
-
$is_not_empty_result = ( is_string( $result ) && ! empty( $result ) );
|
131 |
-
|
132 |
-
if ( $is_not_empty_result ) {
|
133 |
-
printf(
|
134 |
-
'<a href="#" onclick="jQuery(this).parent().find(\'pre\').toggle(); return false;">%s</a>',
|
135 |
-
substr( $result, 0, 32 ) . ( 32 < strlen( $result ) ? '...' : '' )
|
136 |
-
);
|
137 |
-
}
|
138 |
-
|
139 |
-
if ( $is_not_empty_result && $pretty_print ) {
|
140 |
-
$decoded = json_decode( $result );
|
141 |
-
if ( ! is_null( $decoded ) ) {
|
142 |
-
$result = $encode( $decoded, JSON_PRETTY_PRINT );
|
143 |
-
}
|
144 |
-
} else {
|
145 |
-
$result = is_string( $result ) ? $result : json_encode( $result );
|
146 |
-
}
|
147 |
-
?>
|
148 |
-
<pre<?php if ( $is_not_empty_result ) : ?> style="display: none"<?php endif ?>><code><?php echo esc_html( $result ) ?></code></pre>
|
149 |
-
</td>
|
150 |
-
<td><?php echo number_format( 100 * ( $log['start'] - WP_FS__SCRIPT_START_TIME ), 2 ) . ' ' . $ms_text ?></td>
|
151 |
-
<td><?php echo number_format( 100 * ( $log['end'] - WP_FS__SCRIPT_START_TIME ), 2 ) . ' ' . $ms_text ?></td>
|
152 |
-
</tr>
|
153 |
-
<?php endforeach ?>
|
154 |
-
</tbody>
|
155 |
</table>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.1.7.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
if ( class_exists( 'Freemius_Api_WordPress' ) ) {
|
14 |
+
$logger = Freemius_Api_WordPress::GetLogger();
|
15 |
+
} else {
|
16 |
+
$logger = array();
|
17 |
+
}
|
18 |
+
|
19 |
+
$counters = array(
|
20 |
+
'GET' => 0,
|
21 |
+
'POST' => 0,
|
22 |
+
'PUT' => 0,
|
23 |
+
'DELETE' => 0
|
24 |
+
);
|
25 |
+
|
26 |
+
$show_body = false;
|
27 |
+
foreach ( $logger as $log ) {
|
28 |
+
$counters[ $log['method'] ] ++;
|
29 |
+
|
30 |
+
if ( ! is_null( $log['body'] ) ) {
|
31 |
+
$show_body = true;
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
$pretty_print = $show_body && defined( 'JSON_PRETTY_PRINT' ) && version_compare( phpversion(), '5.3', '>=' );
|
36 |
+
|
37 |
+
/**
|
38 |
+
* This template is used for debugging, therefore, when possible
|
39 |
+
* we'd like to prettify the output of a JSON encoded variable.
|
40 |
+
* This will only be executed when $pretty_print is `true`, and
|
41 |
+
* the var is `true` only for PHP 5.3 and higher. Due to the
|
42 |
+
* limitations of the current Theme Check, it throws an error
|
43 |
+
* that using the "options" parameter (the 2nd param) is not
|
44 |
+
* supported in PHP 5.2 and lower. Thus, we added this alias
|
45 |
+
* variable to work around that false-positive.
|
46 |
+
*
|
47 |
+
* @author Vova Feldman (@svovaf)
|
48 |
+
* @since 1.2.2.7
|
49 |
+
*/
|
50 |
+
$encode = 'json_encode';
|
51 |
+
|
52 |
+
$root_path_len = strlen( ABSPATH );
|
53 |
+
|
54 |
+
$ms_text = fs_text_x_inline( 'ms', 'milliseconds' );
|
55 |
+
?>
|
56 |
+
<h1><?php fs_echo_inline( 'API' ) ?></h1>
|
57 |
+
|
58 |
+
<h2><span>Total Time:</span><?php echo Freemius_Debug_Bar_Panel::total_time() ?></h2>
|
59 |
+
|
60 |
+
<h2><span>Total Requests:</span><?php echo Freemius_Debug_Bar_Panel::requests_count() ?></h2>
|
61 |
+
<?php foreach ( $counters as $method => $count ) : ?>
|
62 |
+
<h2><span><?php echo $method ?>:</span><?php echo number_format( $count ) ?></h2>
|
63 |
+
<?php endforeach ?>
|
64 |
+
<table class="widefat">
|
65 |
+
<thead>
|
66 |
+
<tr>
|
67 |
+
<th>#</th>
|
68 |
+
<th><?php fs_esc_html_echo_inline( 'Method' ) ?></th>
|
69 |
+
<th><?php fs_esc_html_echo_inline( 'Code' ) ?></th>
|
70 |
+
<th><?php fs_esc_html_echo_inline( 'Length' ) ?></th>
|
71 |
+
<th><?php fs_esc_html_echo_x_inline( 'Path', 'as file/folder path' ) ?></th>
|
72 |
+
<?php if ( $show_body ) : ?>
|
73 |
+
<th><?php fs_esc_html_echo_inline( 'Body' ) ?></th>
|
74 |
+
<?php endif ?>
|
75 |
+
<th><?php fs_esc_html_echo_inline( 'Result' ) ?></th>
|
76 |
+
<th><?php fs_esc_html_echo_inline( 'Start' ) ?></th>
|
77 |
+
<th><?php fs_esc_html_echo_inline( 'End' ) ?></th>
|
78 |
+
</tr>
|
79 |
+
</thead>
|
80 |
+
<tbody>
|
81 |
+
<?php foreach ( $logger as $log ) : ?>
|
82 |
+
<tr>
|
83 |
+
<td><?php echo $log['id'] ?>.</td>
|
84 |
+
<td><?php echo $log['method'] ?></td>
|
85 |
+
<td><?php echo $log['code'] ?></td>
|
86 |
+
<td><?php echo number_format( 100 * $log['total'], 2 ) . ' ' . $ms_text ?></td>
|
87 |
+
<td>
|
88 |
+
<?php
|
89 |
+
printf( '<a href="#" onclick="jQuery(this).parent().find(\'table\').toggle(); return false;">%s</a>',
|
90 |
+
$log['path']
|
91 |
+
);
|
92 |
+
?>
|
93 |
+
<table class="widefat" style="display: none">
|
94 |
+
<tbody>
|
95 |
+
<?php for ( $i = 0, $bt = $log['backtrace'], $len = count( $bt ); $i < $len; $i ++ ) : ?>
|
96 |
+
<tr>
|
97 |
+
<td><?php echo( $len - $i ) ?></td>
|
98 |
+
<td><?php if ( isset( $bt[ $i ]['function'] ) ) {
|
99 |
+
echo ( isset( $bt[ $i ]['class'] ) ? $bt[ $i ]['class'] . $bt[ $i ]['type'] : '' ) . $bt[ $i ]['function'];
|
100 |
+
} ?></td>
|
101 |
+
<td><?php if ( isset( $bt[ $i ]['file'] ) ) {
|
102 |
+
echo substr( $bt[ $i ]['file'], $root_path_len ) . ':' . $bt[ $i ]['line'];
|
103 |
+
} ?></td>
|
104 |
+
</tr>
|
105 |
+
<?php endfor ?>
|
106 |
+
</tbody>
|
107 |
+
</table>
|
108 |
+
</td>
|
109 |
+
<?php if ( $show_body ) : ?>
|
110 |
+
<td>
|
111 |
+
<?php if ( 'GET' !== $log['method'] ) : ?>
|
112 |
+
<?php
|
113 |
+
$body = $log['body'];
|
114 |
+
printf(
|
115 |
+
'<a href="#" onclick="jQuery(this).parent().find(\'pre\').toggle(); return false;">%s</a>',
|
116 |
+
substr( $body, 0, 32 ) . ( 32 < strlen( $body ) ? '...' : '' )
|
117 |
+
);
|
118 |
+
if ( $pretty_print ) {
|
119 |
+
$body = $encode( json_decode( $log['body'] ), JSON_PRETTY_PRINT );
|
120 |
+
}
|
121 |
+
?>
|
122 |
+
<pre style="display: none"><code><?php echo esc_html( $body ) ?></code></pre>
|
123 |
+
<?php endif ?>
|
124 |
+
</td>
|
125 |
+
<?php endif ?>
|
126 |
+
<td>
|
127 |
+
<?php
|
128 |
+
$result = $log['result'];
|
129 |
+
|
130 |
+
$is_not_empty_result = ( is_string( $result ) && ! empty( $result ) );
|
131 |
+
|
132 |
+
if ( $is_not_empty_result ) {
|
133 |
+
printf(
|
134 |
+
'<a href="#" onclick="jQuery(this).parent().find(\'pre\').toggle(); return false;">%s</a>',
|
135 |
+
substr( $result, 0, 32 ) . ( 32 < strlen( $result ) ? '...' : '' )
|
136 |
+
);
|
137 |
+
}
|
138 |
+
|
139 |
+
if ( $is_not_empty_result && $pretty_print ) {
|
140 |
+
$decoded = json_decode( $result );
|
141 |
+
if ( ! is_null( $decoded ) ) {
|
142 |
+
$result = $encode( $decoded, JSON_PRETTY_PRINT );
|
143 |
+
}
|
144 |
+
} else {
|
145 |
+
$result = is_string( $result ) ? $result : json_encode( $result );
|
146 |
+
}
|
147 |
+
?>
|
148 |
+
<pre<?php if ( $is_not_empty_result ) : ?> style="display: none"<?php endif ?>><code><?php echo esc_html( $result ) ?></code></pre>
|
149 |
+
</td>
|
150 |
+
<td><?php echo number_format( 100 * ( $log['start'] - WP_FS__SCRIPT_START_TIME ), 2 ) . ' ' . $ms_text ?></td>
|
151 |
+
<td><?php echo number_format( 100 * ( $log['end'] - WP_FS__SCRIPT_START_TIME ), 2 ) . ' ' . $ms_text ?></td>
|
152 |
+
</tr>
|
153 |
+
<?php endforeach ?>
|
154 |
+
</tbody>
|
155 |
</table>
|
freemius/templates/debug/logger.php
CHANGED
@@ -1,66 +1,66 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.1.7.3
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
$log_book = FS_Logger::get_log();
|
14 |
-
?>
|
15 |
-
<h1><?php fs_echo_inline( 'Log' ) ?></h1>
|
16 |
-
|
17 |
-
<table class="widefat" style="font-size: 11px;">
|
18 |
-
<thead>
|
19 |
-
<tr>
|
20 |
-
<th>#</th>
|
21 |
-
<th><?php fs_esc_html_echo_inline( 'ID', 'id' ) ?></th>
|
22 |
-
<th><?php fs_esc_html_echo_inline( 'Type' ) ?></th>
|
23 |
-
<th><?php fs_esc_html_echo_inline( 'Function' ) ?></th>
|
24 |
-
<th><?php fs_esc_html_echo_inline( 'Message' ) ?></th>
|
25 |
-
<th><?php fs_esc_html_echo_inline( 'File' ) ?></th>
|
26 |
-
<th><?php fs_esc_html_echo_inline( 'Timestamp' ) ?></th>
|
27 |
-
</tr>
|
28 |
-
</thead>
|
29 |
-
<tbody>
|
30 |
-
|
31 |
-
<?php $i = 0;
|
32 |
-
foreach ( $log_book as $log ) : ?>
|
33 |
-
<?php
|
34 |
-
/**
|
35 |
-
* @var FS_Logger $logger
|
36 |
-
*/
|
37 |
-
$logger = $log['logger'];
|
38 |
-
?>
|
39 |
-
<tr<?php if ( $i % 2 ) {
|
40 |
-
echo ' class="alternate"';
|
41 |
-
} ?>>
|
42 |
-
<td><?php echo $log['cnt'] ?>.</td>
|
43 |
-
<td><?php echo $logger->get_id() ?></td>
|
44 |
-
<td><?php echo $log['log_type'] ?></td>
|
45 |
-
<td><b><code style="color: blue;"><?php echo ( ! empty( $log['class'] ) ? $log['class'] . $log['type'] : '' ) . $log['function'] ?></code></b></td>
|
46 |
-
<td>
|
47 |
-
<?php
|
48 |
-
printf(
|
49 |
-
'<a href="#" style="color: darkorange !important;" onclick="jQuery(this).parent().find(\'div\').toggle(); return false;"><nobr>%s</nobr></a>',
|
50 |
-
esc_html( substr( $log['msg'], 0, 32 ) ) . ( 32 < strlen( $log['msg'] ) ? '...' : '' )
|
51 |
-
);
|
52 |
-
?>
|
53 |
-
<div style="display: none;">
|
54 |
-
<b style="color: darkorange;"><?php echo esc_html( $log['msg'] ) ?></b>
|
55 |
-
</div>
|
56 |
-
</td>
|
57 |
-
<td><?php
|
58 |
-
if ( isset( $log['file'] ) ) {
|
59 |
-
echo substr( $log['file'], $logger->get_file() ) . ':' . $log['line'];
|
60 |
-
}
|
61 |
-
?></td>
|
62 |
-
<td><?php echo number_format( 100 * ( $log['timestamp'] - WP_FS__SCRIPT_START_TIME ), 2 ) . ' ' . fs_text_x_inline( 'ms', 'milliseconds' ) ?></td>
|
63 |
-
</tr>
|
64 |
-
<?php $i ++; endforeach ?>
|
65 |
-
</tbody>
|
66 |
</table>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.1.7.3
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
$log_book = FS_Logger::get_log();
|
14 |
+
?>
|
15 |
+
<h1><?php fs_echo_inline( 'Log' ) ?></h1>
|
16 |
+
|
17 |
+
<table class="widefat" style="font-size: 11px;">
|
18 |
+
<thead>
|
19 |
+
<tr>
|
20 |
+
<th>#</th>
|
21 |
+
<th><?php fs_esc_html_echo_inline( 'ID', 'id' ) ?></th>
|
22 |
+
<th><?php fs_esc_html_echo_inline( 'Type' ) ?></th>
|
23 |
+
<th><?php fs_esc_html_echo_inline( 'Function' ) ?></th>
|
24 |
+
<th><?php fs_esc_html_echo_inline( 'Message' ) ?></th>
|
25 |
+
<th><?php fs_esc_html_echo_inline( 'File' ) ?></th>
|
26 |
+
<th><?php fs_esc_html_echo_inline( 'Timestamp' ) ?></th>
|
27 |
+
</tr>
|
28 |
+
</thead>
|
29 |
+
<tbody>
|
30 |
+
|
31 |
+
<?php $i = 0;
|
32 |
+
foreach ( $log_book as $log ) : ?>
|
33 |
+
<?php
|
34 |
+
/**
|
35 |
+
* @var FS_Logger $logger
|
36 |
+
*/
|
37 |
+
$logger = $log['logger'];
|
38 |
+
?>
|
39 |
+
<tr<?php if ( $i % 2 ) {
|
40 |
+
echo ' class="alternate"';
|
41 |
+
} ?>>
|
42 |
+
<td><?php echo $log['cnt'] ?>.</td>
|
43 |
+
<td><?php echo $logger->get_id() ?></td>
|
44 |
+
<td><?php echo $log['log_type'] ?></td>
|
45 |
+
<td><b><code style="color: blue;"><?php echo ( ! empty( $log['class'] ) ? $log['class'] . $log['type'] : '' ) . $log['function'] ?></code></b></td>
|
46 |
+
<td>
|
47 |
+
<?php
|
48 |
+
printf(
|
49 |
+
'<a href="#" style="color: darkorange !important;" onclick="jQuery(this).parent().find(\'div\').toggle(); return false;"><nobr>%s</nobr></a>',
|
50 |
+
esc_html( substr( $log['msg'], 0, 32 ) ) . ( 32 < strlen( $log['msg'] ) ? '...' : '' )
|
51 |
+
);
|
52 |
+
?>
|
53 |
+
<div style="display: none;">
|
54 |
+
<b style="color: darkorange;"><?php echo esc_html( $log['msg'] ) ?></b>
|
55 |
+
</div>
|
56 |
+
</td>
|
57 |
+
<td><?php
|
58 |
+
if ( isset( $log['file'] ) ) {
|
59 |
+
echo substr( $log['file'], $logger->get_file() ) . ':' . $log['line'];
|
60 |
+
}
|
61 |
+
?></td>
|
62 |
+
<td><?php echo number_format( 100 * ( $log['timestamp'] - WP_FS__SCRIPT_START_TIME ), 2 ) . ' ' . fs_text_x_inline( 'ms', 'milliseconds' ) ?></td>
|
63 |
+
</tr>
|
64 |
+
<?php $i ++; endforeach ?>
|
65 |
+
</tbody>
|
66 |
</table>
|
freemius/templates/forms/deactivation/contact.php
CHANGED
@@ -1,23 +1,23 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.2.0
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array $VARS
|
15 |
-
*/
|
16 |
-
$fs = freemius( $VARS['id'] );
|
17 |
-
$slug = $fs->get_slug();
|
18 |
-
|
19 |
-
echo fs_text_inline( 'Sorry for the inconvenience and we are here to help if you give us a chance.', 'contact-support-before-deactivation', $slug )
|
20 |
-
. sprintf(" <a href='%s' class='button button-small button-primary'>%s</a>",
|
21 |
-
$fs->contact_url( 'technical_support' ),
|
22 |
-
fs_text_inline( 'Contact Support', 'contact-support', $slug )
|
23 |
-
);
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.2.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
*/
|
16 |
+
$fs = freemius( $VARS['id'] );
|
17 |
+
$slug = $fs->get_slug();
|
18 |
+
|
19 |
+
echo fs_text_inline( 'Sorry for the inconvenience and we are here to help if you give us a chance.', 'contact-support-before-deactivation', $slug )
|
20 |
+
. sprintf(" <a href='%s' class='button button-small button-primary'>%s</a>",
|
21 |
+
$fs->contact_url( 'technical_support' ),
|
22 |
+
fs_text_inline( 'Contact Support', 'contact-support', $slug )
|
23 |
+
);
|
freemius/templates/forms/deactivation/form.php
CHANGED
@@ -1,409 +1,409 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.1.2
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
$fs = freemius( $VARS['id'] );
|
14 |
-
$slug = $fs->get_slug();
|
15 |
-
|
16 |
-
$confirmation_message = $fs->apply_filters( 'uninstall_confirmation_message', '' );
|
17 |
-
|
18 |
-
$reasons = $VARS['reasons'];
|
19 |
-
|
20 |
-
$reasons_list_items_html = '';
|
21 |
-
|
22 |
-
foreach ( $reasons as $reason ) {
|
23 |
-
$list_item_classes = 'reason' . ( ! empty( $reason['input_type'] ) ? ' has-input' : '' );
|
24 |
-
|
25 |
-
if ( isset( $reason['internal_message'] ) && ! empty( $reason['internal_message'] ) ) {
|
26 |
-
$list_item_classes .= ' has-internal-message';
|
27 |
-
$reason_internal_message = $reason['internal_message'];
|
28 |
-
} else {
|
29 |
-
$reason_internal_message = '';
|
30 |
-
}
|
31 |
-
|
32 |
-
$reason_input_type = ( ! empty( $reason['input_type'] ) ? $reason['input_type'] : '' );
|
33 |
-
$reason_input_placeholder = ( ! empty( $reason['input_placeholder'] ) ? $reason['input_placeholder'] : '' );
|
34 |
-
|
35 |
-
$reason_list_item_html = <<< HTML
|
36 |
-
<li class="{$list_item_classes}"
|
37 |
-
data-input-type="{$reason_input_type}"
|
38 |
-
data-input-placeholder="{$reason_input_placeholder}">
|
39 |
-
<label>
|
40 |
-
<span>
|
41 |
-
<input type="radio" name="selected-reason" value="{$reason['id']}"/>
|
42 |
-
</span>
|
43 |
-
<span>{$reason['text']}</span>
|
44 |
-
</label>
|
45 |
-
<div class="internal-message">{$reason_internal_message}</div>
|
46 |
-
</li>
|
47 |
-
HTML;
|
48 |
-
|
49 |
-
$reasons_list_items_html .= $reason_list_item_html;
|
50 |
-
}
|
51 |
-
|
52 |
-
$is_anonymous = ( ! $fs->is_registered() );
|
53 |
-
if ( $is_anonymous ) {
|
54 |
-
$anonymous_feedback_checkbox_html = sprintf(
|
55 |
-
'<label class="anonymous-feedback-label"><input type="checkbox" class="anonymous-feedback-checkbox"> %s</label>',
|
56 |
-
fs_esc_html_inline( 'Anonymous feedback', 'anonymous-feedback', $slug )
|
57 |
-
);
|
58 |
-
} else {
|
59 |
-
$anonymous_feedback_checkbox_html = '';
|
60 |
-
}
|
61 |
-
|
62 |
-
// Aliases.
|
63 |
-
$deactivate_text = fs_text_inline( 'Deactivate', 'deactivate', $slug );
|
64 |
-
$theme_text = fs_text_inline( 'Theme', 'theme', $slug );
|
65 |
-
$activate_x_text = fs_text_inline( 'Activate %s', 'activate-x', $slug );
|
66 |
-
|
67 |
-
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
68 |
-
?>
|
69 |
-
<script type="text/javascript">
|
70 |
-
(function ($) {
|
71 |
-
var reasonsHtml = <?php echo json_encode( $reasons_list_items_html ); ?>,
|
72 |
-
modalHtml =
|
73 |
-
'<div class="fs-modal fs-modal-deactivation-feedback<?php echo empty( $confirmation_message ) ? ' no-confirmation-message' : ''; ?>">'
|
74 |
-
+ ' <div class="fs-modal-dialog">'
|
75 |
-
+ ' <div class="fs-modal-header">'
|
76 |
-
+ ' <h4><?php fs_esc_attr_echo_inline( 'Quick feedback', 'quick-feedback' , $slug ) ?></h4>'
|
77 |
-
+ ' </div>'
|
78 |
-
+ ' <div class="fs-modal-body">'
|
79 |
-
+ ' <div class="fs-modal-panel" data-panel-id="confirm"><p><?php echo $confirmation_message; ?></p></div>'
|
80 |
-
+ ' <div class="fs-modal-panel active" data-panel-id="reasons"><h3><strong><?php echo esc_js( sprintf( fs_text_inline( 'If you have a moment, please let us know why you are %s', 'deactivation-share-reason' , $slug ), ( $fs->is_plugin() ? fs_text_inline( 'deactivating', 'deactivating', $slug ) : fs_text_inline( 'switching', 'switching', $slug ) ) ) ) ?>:</strong></h3><ul id="reasons-list">' + reasonsHtml + '</ul></div>'
|
81 |
-
+ ' </div>'
|
82 |
-
+ ' <div class="fs-modal-footer">'
|
83 |
-
+ ' <?php echo $anonymous_feedback_checkbox_html ?>'
|
84 |
-
+ ' <a href="#" class="button button-secondary button-deactivate"></a>'
|
85 |
-
+ ' <a href="#" class="button button-primary button-close"><?php fs_esc_js_echo_inline( 'Cancel', 'cancel' , $slug ) ?></a>'
|
86 |
-
+ ' </div>'
|
87 |
-
+ ' </div>'
|
88 |
-
+ '</div>',
|
89 |
-
$modal = $(modalHtml),
|
90 |
-
$deactivateLink = $('#the-list .deactivate > [data-module-id=<?php echo $fs->get_id() ?>].fs-module-id').prev(),
|
91 |
-
selectedReasonID = false,
|
92 |
-
redirectLink = '',
|
93 |
-
$anonymousFeedback = $modal.find( '.anonymous-feedback-label' ),
|
94 |
-
isAnonymous = <?php echo ( $is_anonymous ? 'true' : 'false' ); ?>,
|
95 |
-
otherReasonID = <?php echo Freemius::REASON_OTHER; ?>,
|
96 |
-
dontShareDataReasonID = <?php echo Freemius::REASON_DONT_LIKE_TO_SHARE_MY_INFORMATION; ?>;
|
97 |
-
|
98 |
-
$modal.appendTo($('body'));
|
99 |
-
|
100 |
-
registerEventHandlers();
|
101 |
-
|
102 |
-
function registerEventHandlers() {
|
103 |
-
<?php
|
104 |
-
if ( $fs->is_plugin() ) { ?>
|
105 |
-
$deactivateLink.click(function (evt) {
|
106 |
-
evt.preventDefault();
|
107 |
-
|
108 |
-
redirectLink = $(this).attr('href');
|
109 |
-
|
110 |
-
showModal();
|
111 |
-
});
|
112 |
-
<?php
|
113 |
-
/**
|
114 |
-
* For "theme" module type, the modal is shown when the current user clicks on
|
115 |
-
* the "Activate" button of any other theme. The "Activate" button is actually
|
116 |
-
* a link to the "Themes" page (/wp-admin/themes.php) containing query params
|
117 |
-
* that tell WordPress to deactivate the current theme and activate a different theme.
|
118 |
-
*
|
119 |
-
* @author Leo Fajardo (@leorw)
|
120 |
-
* @since 1.2.2
|
121 |
-
*
|
122 |
-
* @since 1.2.2.7 Don't trigger the deactivation feedback form if activating the premium version of the theme.
|
123 |
-
*/
|
124 |
-
} else { ?>
|
125 |
-
$('body').on('click', '.theme-browser .theme:not([data-slug=<?php echo $slug ?>-premium]) .theme-actions .button.activate', function (evt) {
|
126 |
-
evt.preventDefault();
|
127 |
-
|
128 |
-
redirectLink = $(this).attr('href');
|
129 |
-
|
130 |
-
showModal();
|
131 |
-
});
|
132 |
-
<?php
|
133 |
-
} ?>
|
134 |
-
|
135 |
-
$modal.on('input propertychange', '.reason-input input', function () {
|
136 |
-
if (!isOtherReasonSelected()) {
|
137 |
-
return;
|
138 |
-
}
|
139 |
-
|
140 |
-
var reason = $(this).val().trim();
|
141 |
-
|
142 |
-
/**
|
143 |
-
* If reason is not empty, remove the error-message class of the message container
|
144 |
-
* to change the message color back to default.
|
145 |
-
*/
|
146 |
-
if (reason.length > 0) {
|
147 |
-
$('.message').removeClass('error-message');
|
148 |
-
enableDeactivateButton();
|
149 |
-
}
|
150 |
-
});
|
151 |
-
|
152 |
-
$modal.on('blur', '.reason-input input', function () {
|
153 |
-
var $userReason = $(this);
|
154 |
-
|
155 |
-
setTimeout(function () {
|
156 |
-
if (!isOtherReasonSelected()) {
|
157 |
-
return;
|
158 |
-
}
|
159 |
-
|
160 |
-
/**
|
161 |
-
* If reason is empty, add the error-message class to the message container
|
162 |
-
* to change the message color to red.
|
163 |
-
*/
|
164 |
-
if (0 === $userReason.val().trim().length) {
|
165 |
-
$('.message').addClass('error-message');
|
166 |
-
disableDeactivateButton();
|
167 |
-
}
|
168 |
-
}, 150);
|
169 |
-
});
|
170 |
-
|
171 |
-
$modal.on('click', '.fs-modal-footer .button', function (evt) {
|
172 |
-
evt.preventDefault();
|
173 |
-
|
174 |
-
if ($(this).hasClass('disabled')) {
|
175 |
-
return;
|
176 |
-
}
|
177 |
-
|
178 |
-
var _parent = $(this).parents('.fs-modal:first');
|
179 |
-
var _this = $(this);
|
180 |
-
|
181 |
-
if (_this.hasClass('allow-deactivate')) {
|
182 |
-
var $radio = $('input[type="radio"]:checked');
|
183 |
-
|
184 |
-
if (0 === $radio.length) {
|
185 |
-
// If no selected reason, just deactivate the plugin.
|
186 |
-
window.location.href = redirectLink;
|
187 |
-
return;
|
188 |
-
}
|
189 |
-
|
190 |
-
var $selected_reason = $radio.parents('li:first'),
|
191 |
-
$input = $selected_reason.find('textarea, input[type="text"]'),
|
192 |
-
userReason = ( 0 !== $input.length ) ? $input.val().trim() : '';
|
193 |
-
|
194 |
-
if (isOtherReasonSelected() && ( '' === userReason )) {
|
195 |
-
return;
|
196 |
-
}
|
197 |
-
|
198 |
-
$.ajax({
|
199 |
-
url : ajaxurl,
|
200 |
-
method : 'POST',
|
201 |
-
data : {
|
202 |
-
action : '<?php echo $fs->get_ajax_action( 'submit_uninstall_reason' ) ?>',
|
203 |
-
security : '<?php echo $fs->get_ajax_security( 'submit_uninstall_reason' ) ?>',
|
204 |
-
module_id : '<?php echo $fs->get_id() ?>',
|
205 |
-
reason_id : $radio.val(),
|
206 |
-
reason_info : userReason,
|
207 |
-
is_anonymous: isAnonymousFeedback()
|
208 |
-
},
|
209 |
-
beforeSend: function () {
|
210 |
-
_parent.find('.fs-modal-footer .button').addClass('disabled');
|
211 |
-
_parent.find('.fs-modal-footer .button-secondary').text('Processing...');
|
212 |
-
},
|
213 |
-
complete : function () {
|
214 |
-
// Do not show the dialog box, deactivate the plugin.
|
215 |
-
window.location.href = redirectLink;
|
216 |
-
}
|
217 |
-
});
|
218 |
-
} else if (_this.hasClass('button-deactivate')) {
|
219 |
-
// Change the Deactivate button's text and show the reasons panel.
|
220 |
-
_parent.find('.button-deactivate').addClass('allow-deactivate');
|
221 |
-
|
222 |
-
showPanel('reasons');
|
223 |
-
}
|
224 |
-
});
|
225 |
-
|
226 |
-
$modal.on('click', 'input[type="radio"]', function () {
|
227 |
-
var $selectedReasonOption = $(this);
|
228 |
-
|
229 |
-
// If the selection has not changed, do not proceed.
|
230 |
-
if (selectedReasonID === $selectedReasonOption.val())
|
231 |
-
return;
|
232 |
-
|
233 |
-
selectedReasonID = $selectedReasonOption.val();
|
234 |
-
|
235 |
-
if ( isAnonymous ) {
|
236 |
-
if ( isReasonSelected( dontShareDataReasonID ) ) {
|
237 |
-
$anonymousFeedback.hide();
|
238 |
-
} else {
|
239 |
-
$anonymousFeedback.show();
|
240 |
-
}
|
241 |
-
}
|
242 |
-
|
243 |
-
var _parent = $(this).parents('li:first');
|
244 |
-
|
245 |
-
$modal.find('.reason-input').remove();
|
246 |
-
$modal.find( '.internal-message' ).hide();
|
247 |
-
$modal.find('.button-deactivate').html('<?php echo esc_js( sprintf(
|
248 |
-
fs_text_inline( 'Submit & %s', 'deactivation-modal-button-submit' , $slug ),
|
249 |
-
$fs->is_plugin() ?
|
250 |
-
$deactivate_text :
|
251 |
-
sprintf( $activate_x_text, $theme_text )
|
252 |
-
) ) ?>');
|
253 |
-
|
254 |
-
enableDeactivateButton();
|
255 |
-
|
256 |
-
if ( _parent.hasClass( 'has-internal-message' ) ) {
|
257 |
-
_parent.find( '.internal-message' ).show();
|
258 |
-
}
|
259 |
-
|
260 |
-
if (_parent.hasClass('has-input')) {
|
261 |
-
var inputType = _parent.data('input-type'),
|
262 |
-
inputPlaceholder = _parent.data('input-placeholder'),
|
263 |
-
reasonInputHtml = '<div class="reason-input"><span class="message"></span>' + ( ( 'textfield' === inputType ) ? '<input type="text" />' : '<textarea rows="5"></textarea>' ) + '</div>';
|
264 |
-
|
265 |
-
_parent.append($(reasonInputHtml));
|
266 |
-
_parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus();
|
267 |
-
|
268 |
-
if (isOtherReasonSelected()) {
|
269 |
-
showMessage('<?php echo esc_js( fs_text_inline( 'Kindly tell us the reason so we can improve.', 'ask-for-reason-message' , $slug ) ); ?>');
|
270 |
-
disableDeactivateButton();
|
271 |
-
}
|
272 |
-
}
|
273 |
-
});
|
274 |
-
|
275 |
-
// If the user has clicked outside the window, cancel it.
|
276 |
-
$modal.on('click', function (evt) {
|
277 |
-
var $target = $(evt.target);
|
278 |
-
|
279 |
-
// If the user has clicked anywhere in the modal dialog, just return.
|
280 |
-
if ($target.hasClass('fs-modal-body') || $target.hasClass('fs-modal-footer')) {
|
281 |
-
return;
|
282 |
-
}
|
283 |
-
|
284 |
-
// If the user has not clicked the close button and the clicked element is inside the modal dialog, just return.
|
285 |
-
if (!$target.hasClass('button-close') && ( $target.parents('.fs-modal-body').length > 0 || $target.parents('.fs-modal-footer').length > 0 )) {
|
286 |
-
return;
|
287 |
-
}
|
288 |
-
|
289 |
-
closeModal();
|
290 |
-
return false;
|
291 |
-
});
|
292 |
-
}
|
293 |
-
|
294 |
-
function isAnonymousFeedback() {
|
295 |
-
if ( ! isAnonymous ) {
|
296 |
-
return false;
|
297 |
-
}
|
298 |
-
|
299 |
-
return ( isReasonSelected( dontShareDataReasonID ) || $anonymousFeedback.find( 'input' ).prop( 'checked' ) );
|
300 |
-
}
|
301 |
-
|
302 |
-
function isReasonSelected( reasonID ) {
|
303 |
-
// Get the selected radio input element.
|
304 |
-
var $selectedReasonOption = $modal.find('input[type="radio"]:checked');
|
305 |
-
|
306 |
-
return ( reasonID == $selectedReasonOption.val() );
|
307 |
-
}
|
308 |
-
|
309 |
-
function isOtherReasonSelected() {
|
310 |
-
return isReasonSelected( otherReasonID );
|
311 |
-
}
|
312 |
-
|
313 |
-
function showModal() {
|
314 |
-
resetModal();
|
315 |
-
|
316 |
-
// Display the dialog box.
|
317 |
-
$modal.addClass('active');
|
318 |
-
|
319 |
-
$('body').addClass('has-fs-modal');
|
320 |
-
}
|
321 |
-
|
322 |
-
function closeModal() {
|
323 |
-
$modal.removeClass('active');
|
324 |
-
|
325 |
-
$('body').removeClass('has-fs-modal');
|
326 |
-
}
|
327 |
-
|
328 |
-
function resetModal() {
|
329 |
-
selectedReasonID = false;
|
330 |
-
|
331 |
-
enableDeactivateButton();
|
332 |
-
|
333 |
-
// Uncheck all radio buttons.
|
334 |
-
$modal.find('input[type="radio"]').prop('checked', false);
|
335 |
-
|
336 |
-
// Remove all input fields ( textfield, textarea ).
|
337 |
-
$modal.find('.reason-input').remove();
|
338 |
-
|
339 |
-
$modal.find('.message').hide();
|
340 |
-
|
341 |
-
if ( isAnonymous ) {
|
342 |
-
$anonymousFeedback.find( 'input' ).prop( 'checked', false );
|
343 |
-
|
344 |
-
// Hide, since by default there is no selected reason.
|
345 |
-
$anonymousFeedback.hide();
|
346 |
-
}
|
347 |
-
|
348 |
-
var $deactivateButton = $modal.find('.button-deactivate');
|
349 |
-
|
350 |
-
/*
|
351 |
-
* If the modal dialog has no confirmation message, that is, it has only one panel, then ensure
|
352 |
-
* that clicking the deactivate button will actually deactivate the plugin.
|
353 |
-
*/
|
354 |
-
if ($modal.hasClass('no-confirmation-message')) {
|
355 |
-
$deactivateButton.addClass('allow-deactivate');
|
356 |
-
|
357 |
-
showPanel('reasons');
|
358 |
-
} else {
|
359 |
-
$deactivateButton.removeClass('allow-deactivate');
|
360 |
-
|
361 |
-
showPanel('confirm');
|
362 |
-
}
|
363 |
-
}
|
364 |
-
|
365 |
-
function showMessage(message) {
|
366 |
-
$modal.find('.message').text(message).show();
|
367 |
-
}
|
368 |
-
|
369 |
-
function enableDeactivateButton() {
|
370 |
-
$modal.find('.button-deactivate').removeClass('disabled');
|
371 |
-
}
|
372 |
-
|
373 |
-
function disableDeactivateButton() {
|
374 |
-
$modal.find('.button-deactivate').addClass('disabled');
|
375 |
-
}
|
376 |
-
|
377 |
-
function showPanel(panelType) {
|
378 |
-
$modal.find('.fs-modal-panel').removeClass('active ');
|
379 |
-
$modal.find('[data-panel-id="' + panelType + '"]').addClass('active');
|
380 |
-
|
381 |
-
updateButtonLabels();
|
382 |
-
}
|
383 |
-
|
384 |
-
function updateButtonLabels() {
|
385 |
-
var $deactivateButton = $modal.find('.button-deactivate');
|
386 |
-
|
387 |
-
// Reset the deactivate button's text.
|
388 |
-
if ('confirm' === getCurrentPanel()) {
|
389 |
-
$deactivateButton.text('<?php echo esc_js( sprintf(
|
390 |
-
fs_text_inline( 'Yes - %s', 'deactivation-modal-button-confirm' , $slug ),
|
391 |
-
$fs->is_plugin() ?
|
392 |
-
$deactivate_text :
|
393 |
-
sprintf( $activate_x_text, $theme_text )
|
394 |
-
) ) ?>');
|
395 |
-
} else {
|
396 |
-
$deactivateButton.html('<?php echo esc_js( sprintf(
|
397 |
-
fs_text_inline('Skip & %s', 'skip-and-x', $slug ),
|
398 |
-
$fs->is_plugin() ?
|
399 |
-
$deactivate_text :
|
400 |
-
sprintf( $activate_x_text, $theme_text )
|
401 |
-
) ) ?>');
|
402 |
-
}
|
403 |
-
}
|
404 |
-
|
405 |
-
function getCurrentPanel() {
|
406 |
-
return $modal.find('.fs-modal-panel.active').attr('data-panel-id');
|
407 |
-
}
|
408 |
-
})(jQuery);
|
409 |
-
</script>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.1.2
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
$fs = freemius( $VARS['id'] );
|
14 |
+
$slug = $fs->get_slug();
|
15 |
+
|
16 |
+
$confirmation_message = $fs->apply_filters( 'uninstall_confirmation_message', '' );
|
17 |
+
|
18 |
+
$reasons = $VARS['reasons'];
|
19 |
+
|
20 |
+
$reasons_list_items_html = '';
|
21 |
+
|
22 |
+
foreach ( $reasons as $reason ) {
|
23 |
+
$list_item_classes = 'reason' . ( ! empty( $reason['input_type'] ) ? ' has-input' : '' );
|
24 |
+
|
25 |
+
if ( isset( $reason['internal_message'] ) && ! empty( $reason['internal_message'] ) ) {
|
26 |
+
$list_item_classes .= ' has-internal-message';
|
27 |
+
$reason_internal_message = $reason['internal_message'];
|
28 |
+
} else {
|
29 |
+
$reason_internal_message = '';
|
30 |
+
}
|
31 |
+
|
32 |
+
$reason_input_type = ( ! empty( $reason['input_type'] ) ? $reason['input_type'] : '' );
|
33 |
+
$reason_input_placeholder = ( ! empty( $reason['input_placeholder'] ) ? $reason['input_placeholder'] : '' );
|
34 |
+
|
35 |
+
$reason_list_item_html = <<< HTML
|
36 |
+
<li class="{$list_item_classes}"
|
37 |
+
data-input-type="{$reason_input_type}"
|
38 |
+
data-input-placeholder="{$reason_input_placeholder}">
|
39 |
+
<label>
|
40 |
+
<span>
|
41 |
+
<input type="radio" name="selected-reason" value="{$reason['id']}"/>
|
42 |
+
</span>
|
43 |
+
<span>{$reason['text']}</span>
|
44 |
+
</label>
|
45 |
+
<div class="internal-message">{$reason_internal_message}</div>
|
46 |
+
</li>
|
47 |
+
HTML;
|
48 |
+
|
49 |
+
$reasons_list_items_html .= $reason_list_item_html;
|
50 |
+
}
|
51 |
+
|
52 |
+
$is_anonymous = ( ! $fs->is_registered() );
|
53 |
+
if ( $is_anonymous ) {
|
54 |
+
$anonymous_feedback_checkbox_html = sprintf(
|
55 |
+
'<label class="anonymous-feedback-label"><input type="checkbox" class="anonymous-feedback-checkbox"> %s</label>',
|
56 |
+
fs_esc_html_inline( 'Anonymous feedback', 'anonymous-feedback', $slug )
|
57 |
+
);
|
58 |
+
} else {
|
59 |
+
$anonymous_feedback_checkbox_html = '';
|
60 |
+
}
|
61 |
+
|
62 |
+
// Aliases.
|
63 |
+
$deactivate_text = fs_text_inline( 'Deactivate', 'deactivate', $slug );
|
64 |
+
$theme_text = fs_text_inline( 'Theme', 'theme', $slug );
|
65 |
+
$activate_x_text = fs_text_inline( 'Activate %s', 'activate-x', $slug );
|
66 |
+
|
67 |
+
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
68 |
+
?>
|
69 |
+
<script type="text/javascript">
|
70 |
+
(function ($) {
|
71 |
+
var reasonsHtml = <?php echo json_encode( $reasons_list_items_html ); ?>,
|
72 |
+
modalHtml =
|
73 |
+
'<div class="fs-modal fs-modal-deactivation-feedback<?php echo empty( $confirmation_message ) ? ' no-confirmation-message' : ''; ?>">'
|
74 |
+
+ ' <div class="fs-modal-dialog">'
|
75 |
+
+ ' <div class="fs-modal-header">'
|
76 |
+
+ ' <h4><?php fs_esc_attr_echo_inline( 'Quick feedback', 'quick-feedback' , $slug ) ?></h4>'
|
77 |
+
+ ' </div>'
|
78 |
+
+ ' <div class="fs-modal-body">'
|
79 |
+
+ ' <div class="fs-modal-panel" data-panel-id="confirm"><p><?php echo $confirmation_message; ?></p></div>'
|
80 |
+
+ ' <div class="fs-modal-panel active" data-panel-id="reasons"><h3><strong><?php echo esc_js( sprintf( fs_text_inline( 'If you have a moment, please let us know why you are %s', 'deactivation-share-reason' , $slug ), ( $fs->is_plugin() ? fs_text_inline( 'deactivating', 'deactivating', $slug ) : fs_text_inline( 'switching', 'switching', $slug ) ) ) ) ?>:</strong></h3><ul id="reasons-list">' + reasonsHtml + '</ul></div>'
|
81 |
+
+ ' </div>'
|
82 |
+
+ ' <div class="fs-modal-footer">'
|
83 |
+
+ ' <?php echo $anonymous_feedback_checkbox_html ?>'
|
84 |
+
+ ' <a href="#" class="button button-secondary button-deactivate"></a>'
|
85 |
+
+ ' <a href="#" class="button button-primary button-close"><?php fs_esc_js_echo_inline( 'Cancel', 'cancel' , $slug ) ?></a>'
|
86 |
+
+ ' </div>'
|
87 |
+
+ ' </div>'
|
88 |
+
+ '</div>',
|
89 |
+
$modal = $(modalHtml),
|
90 |
+
$deactivateLink = $('#the-list .deactivate > [data-module-id=<?php echo $fs->get_id() ?>].fs-module-id').prev(),
|
91 |
+
selectedReasonID = false,
|
92 |
+
redirectLink = '',
|
93 |
+
$anonymousFeedback = $modal.find( '.anonymous-feedback-label' ),
|
94 |
+
isAnonymous = <?php echo ( $is_anonymous ? 'true' : 'false' ); ?>,
|
95 |
+
otherReasonID = <?php echo Freemius::REASON_OTHER; ?>,
|
96 |
+
dontShareDataReasonID = <?php echo Freemius::REASON_DONT_LIKE_TO_SHARE_MY_INFORMATION; ?>;
|
97 |
+
|
98 |
+
$modal.appendTo($('body'));
|
99 |
+
|
100 |
+
registerEventHandlers();
|
101 |
+
|
102 |
+
function registerEventHandlers() {
|
103 |
+
<?php
|
104 |
+
if ( $fs->is_plugin() ) { ?>
|
105 |
+
$deactivateLink.click(function (evt) {
|
106 |
+
evt.preventDefault();
|
107 |
+
|
108 |
+
redirectLink = $(this).attr('href');
|
109 |
+
|
110 |
+
showModal();
|
111 |
+
});
|
112 |
+
<?php
|
113 |
+
/**
|
114 |
+
* For "theme" module type, the modal is shown when the current user clicks on
|
115 |
+
* the "Activate" button of any other theme. The "Activate" button is actually
|
116 |
+
* a link to the "Themes" page (/wp-admin/themes.php) containing query params
|
117 |
+
* that tell WordPress to deactivate the current theme and activate a different theme.
|
118 |
+
*
|
119 |
+
* @author Leo Fajardo (@leorw)
|
120 |
+
* @since 1.2.2
|
121 |
+
*
|
122 |
+
* @since 1.2.2.7 Don't trigger the deactivation feedback form if activating the premium version of the theme.
|
123 |
+
*/
|
124 |
+
} else { ?>
|
125 |
+
$('body').on('click', '.theme-browser .theme:not([data-slug=<?php echo $slug ?>-premium]) .theme-actions .button.activate', function (evt) {
|
126 |
+
evt.preventDefault();
|
127 |
+
|
128 |
+
redirectLink = $(this).attr('href');
|
129 |
+
|
130 |
+
showModal();
|
131 |
+
});
|
132 |
+
<?php
|
133 |
+
} ?>
|
134 |
+
|
135 |
+
$modal.on('input propertychange', '.reason-input input', function () {
|
136 |
+
if (!isOtherReasonSelected()) {
|
137 |
+
return;
|
138 |
+
}
|
139 |
+
|
140 |
+
var reason = $(this).val().trim();
|
141 |
+
|
142 |
+
/**
|
143 |
+
* If reason is not empty, remove the error-message class of the message container
|
144 |
+
* to change the message color back to default.
|
145 |
+
*/
|
146 |
+
if (reason.length > 0) {
|
147 |
+
$('.message').removeClass('error-message');
|
148 |
+
enableDeactivateButton();
|
149 |
+
}
|
150 |
+
});
|
151 |
+
|
152 |
+
$modal.on('blur', '.reason-input input', function () {
|
153 |
+
var $userReason = $(this);
|
154 |
+
|
155 |
+
setTimeout(function () {
|
156 |
+
if (!isOtherReasonSelected()) {
|
157 |
+
return;
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* If reason is empty, add the error-message class to the message container
|
162 |
+
* to change the message color to red.
|
163 |
+
*/
|
164 |
+
if (0 === $userReason.val().trim().length) {
|
165 |
+
$('.message').addClass('error-message');
|
166 |
+
disableDeactivateButton();
|
167 |
+
}
|
168 |
+
}, 150);
|
169 |
+
});
|
170 |
+
|
171 |
+
$modal.on('click', '.fs-modal-footer .button', function (evt) {
|
172 |
+
evt.preventDefault();
|
173 |
+
|
174 |
+
if ($(this).hasClass('disabled')) {
|
175 |
+
return;
|
176 |
+
}
|
177 |
+
|
178 |
+
var _parent = $(this).parents('.fs-modal:first');
|
179 |
+
var _this = $(this);
|
180 |
+
|
181 |
+
if (_this.hasClass('allow-deactivate')) {
|
182 |
+
var $radio = $('input[type="radio"]:checked');
|
183 |
+
|
184 |
+
if (0 === $radio.length) {
|
185 |
+
// If no selected reason, just deactivate the plugin.
|
186 |
+
window.location.href = redirectLink;
|
187 |
+
return;
|
188 |
+
}
|
189 |
+
|
190 |
+
var $selected_reason = $radio.parents('li:first'),
|
191 |
+
$input = $selected_reason.find('textarea, input[type="text"]'),
|
192 |
+
userReason = ( 0 !== $input.length ) ? $input.val().trim() : '';
|
193 |
+
|
194 |
+
if (isOtherReasonSelected() && ( '' === userReason )) {
|
195 |
+
return;
|
196 |
+
}
|
197 |
+
|
198 |
+
$.ajax({
|
199 |
+
url : ajaxurl,
|
200 |
+
method : 'POST',
|
201 |
+
data : {
|
202 |
+
action : '<?php echo $fs->get_ajax_action( 'submit_uninstall_reason' ) ?>',
|
203 |
+
security : '<?php echo $fs->get_ajax_security( 'submit_uninstall_reason' ) ?>',
|
204 |
+
module_id : '<?php echo $fs->get_id() ?>',
|
205 |
+
reason_id : $radio.val(),
|
206 |
+
reason_info : userReason,
|
207 |
+
is_anonymous: isAnonymousFeedback()
|
208 |
+
},
|
209 |
+
beforeSend: function () {
|
210 |
+
_parent.find('.fs-modal-footer .button').addClass('disabled');
|
211 |
+
_parent.find('.fs-modal-footer .button-secondary').text('Processing...');
|
212 |
+
},
|
213 |
+
complete : function () {
|
214 |
+
// Do not show the dialog box, deactivate the plugin.
|
215 |
+
window.location.href = redirectLink;
|
216 |
+
}
|
217 |
+
});
|
218 |
+
} else if (_this.hasClass('button-deactivate')) {
|
219 |
+
// Change the Deactivate button's text and show the reasons panel.
|
220 |
+
_parent.find('.button-deactivate').addClass('allow-deactivate');
|
221 |
+
|
222 |
+
showPanel('reasons');
|
223 |
+
}
|
224 |
+
});
|
225 |
+
|
226 |
+
$modal.on('click', 'input[type="radio"]', function () {
|
227 |
+
var $selectedReasonOption = $(this);
|
228 |
+
|
229 |
+
// If the selection has not changed, do not proceed.
|
230 |
+
if (selectedReasonID === $selectedReasonOption.val())
|
231 |
+
return;
|
232 |
+
|
233 |
+
selectedReasonID = $selectedReasonOption.val();
|
234 |
+
|
235 |
+
if ( isAnonymous ) {
|
236 |
+
if ( isReasonSelected( dontShareDataReasonID ) ) {
|
237 |
+
$anonymousFeedback.hide();
|
238 |
+
} else {
|
239 |
+
$anonymousFeedback.show();
|
240 |
+
}
|
241 |
+
}
|
242 |
+
|
243 |
+
var _parent = $(this).parents('li:first');
|
244 |
+
|
245 |
+
$modal.find('.reason-input').remove();
|
246 |
+
$modal.find( '.internal-message' ).hide();
|
247 |
+
$modal.find('.button-deactivate').html('<?php echo esc_js( sprintf(
|
248 |
+
fs_text_inline( 'Submit & %s', 'deactivation-modal-button-submit' , $slug ),
|
249 |
+
$fs->is_plugin() ?
|
250 |
+
$deactivate_text :
|
251 |
+
sprintf( $activate_x_text, $theme_text )
|
252 |
+
) ) ?>');
|
253 |
+
|
254 |
+
enableDeactivateButton();
|
255 |
+
|
256 |
+
if ( _parent.hasClass( 'has-internal-message' ) ) {
|
257 |
+
_parent.find( '.internal-message' ).show();
|
258 |
+
}
|
259 |
+
|
260 |
+
if (_parent.hasClass('has-input')) {
|
261 |
+
var inputType = _parent.data('input-type'),
|
262 |
+
inputPlaceholder = _parent.data('input-placeholder'),
|
263 |
+
reasonInputHtml = '<div class="reason-input"><span class="message"></span>' + ( ( 'textfield' === inputType ) ? '<input type="text" />' : '<textarea rows="5"></textarea>' ) + '</div>';
|
264 |
+
|
265 |
+
_parent.append($(reasonInputHtml));
|
266 |
+
_parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus();
|
267 |
+
|
268 |
+
if (isOtherReasonSelected()) {
|
269 |
+
showMessage('<?php echo esc_js( fs_text_inline( 'Kindly tell us the reason so we can improve.', 'ask-for-reason-message' , $slug ) ); ?>');
|
270 |
+
disableDeactivateButton();
|
271 |
+
}
|
272 |
+
}
|
273 |
+
});
|
274 |
+
|
275 |
+
// If the user has clicked outside the window, cancel it.
|
276 |
+
$modal.on('click', function (evt) {
|
277 |
+
var $target = $(evt.target);
|
278 |
+
|
279 |
+
// If the user has clicked anywhere in the modal dialog, just return.
|
280 |
+
if ($target.hasClass('fs-modal-body') || $target.hasClass('fs-modal-footer')) {
|
281 |
+
return;
|
282 |
+
}
|
283 |
+
|
284 |
+
// If the user has not clicked the close button and the clicked element is inside the modal dialog, just return.
|
285 |
+
if (!$target.hasClass('button-close') && ( $target.parents('.fs-modal-body').length > 0 || $target.parents('.fs-modal-footer').length > 0 )) {
|
286 |
+
return;
|
287 |
+
}
|
288 |
+
|
289 |
+
closeModal();
|
290 |
+
return false;
|
291 |
+
});
|
292 |
+
}
|
293 |
+
|
294 |
+
function isAnonymousFeedback() {
|
295 |
+
if ( ! isAnonymous ) {
|
296 |
+
return false;
|
297 |
+
}
|
298 |
+
|
299 |
+
return ( isReasonSelected( dontShareDataReasonID ) || $anonymousFeedback.find( 'input' ).prop( 'checked' ) );
|
300 |
+
}
|
301 |
+
|
302 |
+
function isReasonSelected( reasonID ) {
|
303 |
+
// Get the selected radio input element.
|
304 |
+
var $selectedReasonOption = $modal.find('input[type="radio"]:checked');
|
305 |
+
|
306 |
+
return ( reasonID == $selectedReasonOption.val() );
|
307 |
+
}
|
308 |
+
|
309 |
+
function isOtherReasonSelected() {
|
310 |
+
return isReasonSelected( otherReasonID );
|
311 |
+
}
|
312 |
+
|
313 |
+
function showModal() {
|
314 |
+
resetModal();
|
315 |
+
|
316 |
+
// Display the dialog box.
|
317 |
+
$modal.addClass('active');
|
318 |
+
|
319 |
+
$('body').addClass('has-fs-modal');
|
320 |
+
}
|
321 |
+
|
322 |
+
function closeModal() {
|
323 |
+
$modal.removeClass('active');
|
324 |
+
|
325 |
+
$('body').removeClass('has-fs-modal');
|
326 |
+
}
|
327 |
+
|
328 |
+
function resetModal() {
|
329 |
+
selectedReasonID = false;
|
330 |
+
|
331 |
+
enableDeactivateButton();
|
332 |
+
|
333 |
+
// Uncheck all radio buttons.
|
334 |
+
$modal.find('input[type="radio"]').prop('checked', false);
|
335 |
+
|
336 |
+
// Remove all input fields ( textfield, textarea ).
|
337 |
+
$modal.find('.reason-input').remove();
|
338 |
+
|
339 |
+
$modal.find('.message').hide();
|
340 |
+
|
341 |
+
if ( isAnonymous ) {
|
342 |
+
$anonymousFeedback.find( 'input' ).prop( 'checked', false );
|
343 |
+
|
344 |
+
// Hide, since by default there is no selected reason.
|
345 |
+
$anonymousFeedback.hide();
|
346 |
+
}
|
347 |
+
|
348 |
+
var $deactivateButton = $modal.find('.button-deactivate');
|
349 |
+
|
350 |
+
/*
|
351 |
+
* If the modal dialog has no confirmation message, that is, it has only one panel, then ensure
|
352 |
+
* that clicking the deactivate button will actually deactivate the plugin.
|
353 |
+
*/
|
354 |
+
if ($modal.hasClass('no-confirmation-message')) {
|
355 |
+
$deactivateButton.addClass('allow-deactivate');
|
356 |
+
|
357 |
+
showPanel('reasons');
|
358 |
+
} else {
|
359 |
+
$deactivateButton.removeClass('allow-deactivate');
|
360 |
+
|
361 |
+
showPanel('confirm');
|
362 |
+
}
|
363 |
+
}
|
364 |
+
|
365 |
+
function showMessage(message) {
|
366 |
+
$modal.find('.message').text(message).show();
|
367 |
+
}
|
368 |
+
|
369 |
+
function enableDeactivateButton() {
|
370 |
+
$modal.find('.button-deactivate').removeClass('disabled');
|
371 |
+
}
|
372 |
+
|
373 |
+
function disableDeactivateButton() {
|
374 |
+
$modal.find('.button-deactivate').addClass('disabled');
|
375 |
+
}
|
376 |
+
|
377 |
+
function showPanel(panelType) {
|
378 |
+
$modal.find('.fs-modal-panel').removeClass('active ');
|
379 |
+
$modal.find('[data-panel-id="' + panelType + '"]').addClass('active');
|
380 |
+
|
381 |
+
updateButtonLabels();
|
382 |
+
}
|
383 |
+
|
384 |
+
function updateButtonLabels() {
|
385 |
+
var $deactivateButton = $modal.find('.button-deactivate');
|
386 |
+
|
387 |
+
// Reset the deactivate button's text.
|
388 |
+
if ('confirm' === getCurrentPanel()) {
|
389 |
+
$deactivateButton.text('<?php echo esc_js( sprintf(
|
390 |
+
fs_text_inline( 'Yes - %s', 'deactivation-modal-button-confirm' , $slug ),
|
391 |
+
$fs->is_plugin() ?
|
392 |
+
$deactivate_text :
|
393 |
+
sprintf( $activate_x_text, $theme_text )
|
394 |
+
) ) ?>');
|
395 |
+
} else {
|
396 |
+
$deactivateButton.html('<?php echo esc_js( sprintf(
|
397 |
+
fs_text_inline('Skip & %s', 'skip-and-x', $slug ),
|
398 |
+
$fs->is_plugin() ?
|
399 |
+
$deactivate_text :
|
400 |
+
sprintf( $activate_x_text, $theme_text )
|
401 |
+
) ) ?>');
|
402 |
+
}
|
403 |
+
}
|
404 |
+
|
405 |
+
function getCurrentPanel() {
|
406 |
+
return $modal.find('.fs-modal-panel.active').attr('data-panel-id');
|
407 |
+
}
|
408 |
+
})(jQuery);
|
409 |
+
</script>
|
freemius/templates/forms/deactivation/retry-skip.php
CHANGED
@@ -1,24 +1,24 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.2.0
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array $VARS
|
15 |
-
*/
|
16 |
-
$fs = freemius( $VARS['id'] );
|
17 |
-
$slug = $fs->get_slug();
|
18 |
-
|
19 |
-
$skip_url = fs_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $fs->get_unique_affix() . '_skip_activation' ) ), $fs->get_unique_affix() . '_skip_activation' );
|
20 |
-
$skip_text = strtolower( fs_text_x_inline( 'Skip', 'verb', 'skip', $slug ) );
|
21 |
-
$use_plugin_anonymously_text = fs_text_inline( 'Click here to use the plugin anonymously', 'click-here-to-use-plugin-anonymously', $slug );
|
22 |
-
|
23 |
-
echo sprintf( fs_text_inline( "You might have missed it, but you don't have to share any data and can just %s the opt-in.", 'dont-have-to-share-any-data', $slug ), "<a href='{$skip_url}'>{$skip_text}</a>" )
|
24 |
. " <a href='{$skip_url}' class='button button-small button-secondary'>{$use_plugin_anonymously_text}</a>";
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.2.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
*/
|
16 |
+
$fs = freemius( $VARS['id'] );
|
17 |
+
$slug = $fs->get_slug();
|
18 |
+
|
19 |
+
$skip_url = fs_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $fs->get_unique_affix() . '_skip_activation' ) ), $fs->get_unique_affix() . '_skip_activation' );
|
20 |
+
$skip_text = strtolower( fs_text_x_inline( 'Skip', 'verb', 'skip', $slug ) );
|
21 |
+
$use_plugin_anonymously_text = fs_text_inline( 'Click here to use the plugin anonymously', 'click-here-to-use-plugin-anonymously', $slug );
|
22 |
+
|
23 |
+
echo sprintf( fs_text_inline( "You might have missed it, but you don't have to share any data and can just %s the opt-in.", 'dont-have-to-share-any-data', $slug ), "<a href='{$skip_url}'>{$skip_text}</a>" )
|
24 |
. " <a href='{$skip_url}' class='button button-small button-secondary'>{$use_plugin_anonymously_text}</a>";
|
freemius/templates/forms/optout.php
CHANGED
@@ -1,267 +1,267 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.2.1.5
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array $VARS
|
15 |
-
* @var Freemius $fs
|
16 |
-
*/
|
17 |
-
$fs = freemius( $VARS['id'] );
|
18 |
-
$slug = $fs->get_slug();
|
19 |
-
|
20 |
-
$action = $fs->is_tracking_allowed() ?
|
21 |
-
'stop_tracking' :
|
22 |
-
'allow_tracking';
|
23 |
-
|
24 |
-
$reconnect_url = $fs->get_activation_url( array(
|
25 |
-
'nonce' => wp_create_nonce( $fs->get_unique_affix() . '_reconnect' ),
|
26 |
-
'fs_action' => ( $fs->get_unique_affix() . '_reconnect' ),
|
27 |
-
) );
|
28 |
-
|
29 |
-
$plugin_title = "<strong>{$fs->get_plugin()->title}</strong>";
|
30 |
-
$opt_out_text = fs_text_x_inline( 'Opt Out', 'verb', 'opt-out', $slug );
|
31 |
-
$opt_in_text = fs_text_x_inline( 'Opt In', 'verb', 'opt-in', $slug );
|
32 |
-
$opt_out_message_appreciation = sprintf( fs_text_inline( 'We appreciate your help in making the %s better by letting us track some usage data.', 'opt-out-message-appreciation', $slug ), $fs->get_module_type() );
|
33 |
-
$opt_out_message_usage_tracking = sprintf( fs_text_inline( "Usage tracking is done in the name of making %s better. Making a better user experience, prioritizing new features, and more good things. We'd really appreciate if you'll reconsider letting us continue with the tracking.", 'opt-out-message-usage-tracking', $slug ), $plugin_title );
|
34 |
-
$opt_out_message_clicking_opt_out = sprintf(
|
35 |
-
fs_text_inline( 'By clicking "Opt Out", we will no longer be sending any data from %s to %s.', 'opt-out-message-clicking-opt-out', $slug ),
|
36 |
-
$plugin_title,
|
37 |
-
sprintf(
|
38 |
-
'<a href="%s" target="_blank">%s</a>',
|
39 |
-
'https://freemius.com',
|
40 |
-
'freemius.com'
|
41 |
-
)
|
42 |
-
);
|
43 |
-
|
44 |
-
$admin_notice_params = array(
|
45 |
-
'id' => '',
|
46 |
-
'slug' => $fs->get_id(),
|
47 |
-
'type' => 'success',
|
48 |
-
'sticky' => false,
|
49 |
-
'plugin' => $fs->get_plugin()->title,
|
50 |
-
'message' => $opt_out_message_appreciation
|
51 |
-
);
|
52 |
-
|
53 |
-
$admin_notice_html = fs_get_template( 'admin-notice.php', $admin_notice_params );
|
54 |
-
|
55 |
-
$modal_content_html = <<< HTML
|
56 |
-
<h2>{$opt_out_message_appreciation}</h2>
|
57 |
-
<div class="notice notice-error inline opt-out-error-message"><p></p></div>
|
58 |
-
<p>{$opt_out_message_usage_tracking}</p>
|
59 |
-
<p>{$opt_out_message_clicking_opt_out}</p>
|
60 |
-
HTML;
|
61 |
-
|
62 |
-
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
63 |
-
fs_enqueue_local_style( 'fs_common', '/admin/common.css' );
|
64 |
-
?>
|
65 |
-
<script type="text/javascript">
|
66 |
-
(function( $ ) {
|
67 |
-
$( document ).ready(function() {
|
68 |
-
var modalContentHtml = <?php echo json_encode( $modal_content_html ) ?>,
|
69 |
-
modalHtml =
|
70 |
-
'<div class="fs-modal fs-modal-opt-out">'
|
71 |
-
+ ' <div class="fs-modal-dialog">'
|
72 |
-
+ ' <div class="fs-modal-header">'
|
73 |
-
+ ' <h4><?php echo esc_js( $opt_out_text ) ?></h4>'
|
74 |
-
+ ' </div>'
|
75 |
-
+ ' <div class="fs-modal-body">'
|
76 |
-
+ ' <div class="fs-modal-panel active">' + modalContentHtml + '</div>'
|
77 |
-
+ ' </div>'
|
78 |
-
+ ' <div class="fs-modal-footer">'
|
79 |
-
+ ' <button class="button button-secondary button-opt-out" tabindex="1"><?php echo esc_js( $opt_out_text ) ?></button>'
|
80 |
-
+ ' <button class="button button-primary button-close" tabindex="2"><?php fs_esc_js_echo_inline( 'On second thought - I want to continue helping', 'opt-out-cancel', $slug ) ?></button>'
|
81 |
-
+ ' </div>'
|
82 |
-
+ ' </div>'
|
83 |
-
+ '</div>',
|
84 |
-
$modal = $( modalHtml ),
|
85 |
-
$adminNotice = $( <?php echo json_encode( $admin_notice_html ) ?> ),
|
86 |
-
action = '<?php echo $action ?>',
|
87 |
-
$actionLink = $( 'span.opt-in-or-opt-out.<?php echo $slug ?> a' ),
|
88 |
-
$optOutButton = $modal.find( '.button-opt-out' ),
|
89 |
-
$optOutErrorMessage = $modal.find( '.opt-out-error-message' ),
|
90 |
-
moduleID = '<?php echo $fs->get_id() ?>';
|
91 |
-
|
92 |
-
$actionLink.attr( 'data-action', action );
|
93 |
-
$modal.appendTo( $( 'body' ) );
|
94 |
-
|
95 |
-
function registerActionLinkClick() {
|
96 |
-
$actionLink.click(function( evt ) {
|
97 |
-
evt.preventDefault();
|
98 |
-
|
99 |
-
if ( 'stop_tracking' == $actionLink.attr( 'data-action' ) ) {
|
100 |
-
showModal();
|
101 |
-
} else {
|
102 |
-
optIn();
|
103 |
-
}
|
104 |
-
|
105 |
-
return false;
|
106 |
-
});
|
107 |
-
}
|
108 |
-
|
109 |
-
function registerEventHandlers() {
|
110 |
-
registerActionLinkClick();
|
111 |
-
|
112 |
-
$modal.on( 'click', '.button-opt-out', function( evt ) {
|
113 |
-
evt.preventDefault();
|
114 |
-
|
115 |
-
if ( $( this ).hasClass( 'disabled' ) ) {
|
116 |
-
return;
|
117 |
-
}
|
118 |
-
|
119 |
-
disableOptOutButton();
|
120 |
-
optOut();
|
121 |
-
});
|
122 |
-
|
123 |
-
// If the user has clicked outside the window, close the modal.
|
124 |
-
$modal.on( 'click', '.fs-close, .button-close', function() {
|
125 |
-
closeModal();
|
126 |
-
return false;
|
127 |
-
});
|
128 |
-
}
|
129 |
-
|
130 |
-
registerEventHandlers();
|
131 |
-
|
132 |
-
function showModal() {
|
133 |
-
resetModal();
|
134 |
-
|
135 |
-
// Display the dialog box.
|
136 |
-
$modal.addClass( 'active' );
|
137 |
-
$( 'body' ).addClass( 'has-fs-modal' );
|
138 |
-
}
|
139 |
-
|
140 |
-
function closeModal() {
|
141 |
-
$modal.removeClass( 'active' );
|
142 |
-
$( 'body' ).removeClass( 'has-fs-modal' );
|
143 |
-
}
|
144 |
-
|
145 |
-
function resetOptOutButton() {
|
146 |
-
enableOptOutButton();
|
147 |
-
$optOutButton.text( <?php echo json_encode( $opt_out_text ) ?> );
|
148 |
-
}
|
149 |
-
|
150 |
-
function resetModal() {
|
151 |
-
hideError();
|
152 |
-
resetOptOutButton();
|
153 |
-
}
|
154 |
-
|
155 |
-
function optIn() {
|
156 |
-
sendRequest();
|
157 |
-
}
|
158 |
-
|
159 |
-
function optOut() {
|
160 |
-
sendRequest();
|
161 |
-
}
|
162 |
-
|
163 |
-
function sendRequest() {
|
164 |
-
$.ajax({
|
165 |
-
url: ajaxurl,
|
166 |
-
method: 'POST',
|
167 |
-
data: {
|
168 |
-
action : ( 'stop_tracking' == action ?
|
169 |
-
'<?php echo $fs->get_ajax_action( 'stop_tracking' ) ?>' :
|
170 |
-
'<?php echo $fs->get_ajax_action( 'allow_tracking' ) ?>'
|
171 |
-
),
|
172 |
-
security : ( 'stop_tracking' == action ?
|
173 |
-
'<?php echo $fs->get_ajax_security( 'stop_tracking' ) ?>' :
|
174 |
-
'<?php echo $fs->get_ajax_security( 'allow_tracking' ) ?>'
|
175 |
-
),
|
176 |
-
module_id: moduleID
|
177 |
-
},
|
178 |
-
beforeSend: function() {
|
179 |
-
if ( 'opt-in' == action ) {
|
180 |
-
$actionLink.text( '<?php fs_esc_js_echo_inline( 'Opting in', 'opting-in', $slug ) ?>...' );
|
181 |
-
} else {
|
182 |
-
$optOutButton.text( '<?php fs_esc_js_echo_inline( 'Opting out', 'opting-out', $slug ) ?>...' );
|
183 |
-
}
|
184 |
-
},
|
185 |
-
success: function( resultObj ) {
|
186 |
-
if ( resultObj.success ) {
|
187 |
-
if ( 'allow_tracking' == action ) {
|
188 |
-
action = 'stop_tracking';
|
189 |
-
$actionLink.text( '<?php echo esc_js( $opt_out_text ) ?>' );
|
190 |
-
showOptInAppreciationMessageAndScrollToTop();
|
191 |
-
} else {
|
192 |
-
action = 'allow_tracking';
|
193 |
-
$actionLink.text( '<?php echo esc_js( $opt_in_text ) ?>' );
|
194 |
-
closeModal();
|
195 |
-
|
196 |
-
if ( $adminNotice.length > 0 ) {
|
197 |
-
$adminNotice.remove();
|
198 |
-
}
|
199 |
-
}
|
200 |
-
|
201 |
-
$actionLink.attr( 'data-action', action );
|
202 |
-
} else {
|
203 |
-
showError( resultObj.error );
|
204 |
-
resetOptOutButton();
|
205 |
-
}
|
206 |
-
}
|
207 |
-
});
|
208 |
-
}
|
209 |
-
|
210 |
-
function enableOptOutButton() {
|
211 |
-
$optOutButton.removeClass( 'disabled' );
|
212 |
-
}
|
213 |
-
|
214 |
-
function disableOptOutButton() {
|
215 |
-
$optOutButton.addClass( 'disabled' );
|
216 |
-
}
|
217 |
-
|
218 |
-
function hideError() {
|
219 |
-
$optOutErrorMessage.hide();
|
220 |
-
}
|
221 |
-
|
222 |
-
function showOptInAppreciationMessageAndScrollToTop() {
|
223 |
-
$adminNotice.insertAfter( $( '#wpbody-content' ).find( ' > .wrap > h1' ) );
|
224 |
-
window.scrollTo(0, 0);
|
225 |
-
}
|
226 |
-
|
227 |
-
function showError( msg ) {
|
228 |
-
$optOutErrorMessage.find( ' > p' ).html( msg );
|
229 |
-
$optOutErrorMessage.show();
|
230 |
-
}
|
231 |
-
|
232 |
-
<?php if ( $fs->is_theme() ) : ?>
|
233 |
-
/**
|
234 |
-
* Add opt-in/out button to the active theme's buttons collection
|
235 |
-
* in the theme's extended details overlay.
|
236 |
-
*
|
237 |
-
* @author Vova Feldman (@svovaf)
|
238 |
-
* @since 1.2.2.7
|
239 |
-
*/
|
240 |
-
$('.theme-overlay').contentChange(function () {
|
241 |
-
if (!$(this).find('.theme-overlay').hasClass('active')) {
|
242 |
-
// Add opt-in/out button only to the currently active theme.
|
243 |
-
return;
|
244 |
-
}
|
245 |
-
|
246 |
-
if ($('#fs_theme_opt_in_out').length > 0){
|
247 |
-
// Button already there.
|
248 |
-
return;
|
249 |
-
}
|
250 |
-
|
251 |
-
var label = (('stop_tracking' == action) ?
|
252 |
-
'<?php echo esc_js( $opt_out_text ) ?>' :
|
253 |
-
'<?php echo esc_js( $opt_in_text ) ?>'),
|
254 |
-
href = (('stop_tracking' != action) ?
|
255 |
-
'<?php echo esc_js( $reconnect_url ) ?>' :
|
256 |
-
'');
|
257 |
-
|
258 |
-
$actionLink = $('<a id="fs_theme_opt_in_out" href="' + encodeURI(href) + '" class="button" data-action="' + action + '">' + label + '</a>');
|
259 |
-
|
260 |
-
$('.theme-wrap .theme-actions .active-theme').append($actionLink);
|
261 |
-
|
262 |
-
registerActionLinkClick();
|
263 |
-
});
|
264 |
-
<?php endif ?>
|
265 |
-
});
|
266 |
-
})( jQuery );
|
267 |
-
</script>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.2.1.5
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
* @var Freemius $fs
|
16 |
+
*/
|
17 |
+
$fs = freemius( $VARS['id'] );
|
18 |
+
$slug = $fs->get_slug();
|
19 |
+
|
20 |
+
$action = $fs->is_tracking_allowed() ?
|
21 |
+
'stop_tracking' :
|
22 |
+
'allow_tracking';
|
23 |
+
|
24 |
+
$reconnect_url = $fs->get_activation_url( array(
|
25 |
+
'nonce' => wp_create_nonce( $fs->get_unique_affix() . '_reconnect' ),
|
26 |
+
'fs_action' => ( $fs->get_unique_affix() . '_reconnect' ),
|
27 |
+
) );
|
28 |
+
|
29 |
+
$plugin_title = "<strong>{$fs->get_plugin()->title}</strong>";
|
30 |
+
$opt_out_text = fs_text_x_inline( 'Opt Out', 'verb', 'opt-out', $slug );
|
31 |
+
$opt_in_text = fs_text_x_inline( 'Opt In', 'verb', 'opt-in', $slug );
|
32 |
+
$opt_out_message_appreciation = sprintf( fs_text_inline( 'We appreciate your help in making the %s better by letting us track some usage data.', 'opt-out-message-appreciation', $slug ), $fs->get_module_type() );
|
33 |
+
$opt_out_message_usage_tracking = sprintf( fs_text_inline( "Usage tracking is done in the name of making %s better. Making a better user experience, prioritizing new features, and more good things. We'd really appreciate if you'll reconsider letting us continue with the tracking.", 'opt-out-message-usage-tracking', $slug ), $plugin_title );
|
34 |
+
$opt_out_message_clicking_opt_out = sprintf(
|
35 |
+
fs_text_inline( 'By clicking "Opt Out", we will no longer be sending any data from %s to %s.', 'opt-out-message-clicking-opt-out', $slug ),
|
36 |
+
$plugin_title,
|
37 |
+
sprintf(
|
38 |
+
'<a href="%s" target="_blank">%s</a>',
|
39 |
+
'https://freemius.com',
|
40 |
+
'freemius.com'
|
41 |
+
)
|
42 |
+
);
|
43 |
+
|
44 |
+
$admin_notice_params = array(
|
45 |
+
'id' => '',
|
46 |
+
'slug' => $fs->get_id(),
|
47 |
+
'type' => 'success',
|
48 |
+
'sticky' => false,
|
49 |
+
'plugin' => $fs->get_plugin()->title,
|
50 |
+
'message' => $opt_out_message_appreciation
|
51 |
+
);
|
52 |
+
|
53 |
+
$admin_notice_html = fs_get_template( 'admin-notice.php', $admin_notice_params );
|
54 |
+
|
55 |
+
$modal_content_html = <<< HTML
|
56 |
+
<h2>{$opt_out_message_appreciation}</h2>
|
57 |
+
<div class="notice notice-error inline opt-out-error-message"><p></p></div>
|
58 |
+
<p>{$opt_out_message_usage_tracking}</p>
|
59 |
+
<p>{$opt_out_message_clicking_opt_out}</p>
|
60 |
+
HTML;
|
61 |
+
|
62 |
+
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
63 |
+
fs_enqueue_local_style( 'fs_common', '/admin/common.css' );
|
64 |
+
?>
|
65 |
+
<script type="text/javascript">
|
66 |
+
(function( $ ) {
|
67 |
+
$( document ).ready(function() {
|
68 |
+
var modalContentHtml = <?php echo json_encode( $modal_content_html ) ?>,
|
69 |
+
modalHtml =
|
70 |
+
'<div class="fs-modal fs-modal-opt-out">'
|
71 |
+
+ ' <div class="fs-modal-dialog">'
|
72 |
+
+ ' <div class="fs-modal-header">'
|
73 |
+
+ ' <h4><?php echo esc_js( $opt_out_text ) ?></h4>'
|
74 |
+
+ ' </div>'
|
75 |
+
+ ' <div class="fs-modal-body">'
|
76 |
+
+ ' <div class="fs-modal-panel active">' + modalContentHtml + '</div>'
|
77 |
+
+ ' </div>'
|
78 |
+
+ ' <div class="fs-modal-footer">'
|
79 |
+
+ ' <button class="button button-secondary button-opt-out" tabindex="1"><?php echo esc_js( $opt_out_text ) ?></button>'
|
80 |
+
+ ' <button class="button button-primary button-close" tabindex="2"><?php fs_esc_js_echo_inline( 'On second thought - I want to continue helping', 'opt-out-cancel', $slug ) ?></button>'
|
81 |
+
+ ' </div>'
|
82 |
+
+ ' </div>'
|
83 |
+
+ '</div>',
|
84 |
+
$modal = $( modalHtml ),
|
85 |
+
$adminNotice = $( <?php echo json_encode( $admin_notice_html ) ?> ),
|
86 |
+
action = '<?php echo $action ?>',
|
87 |
+
$actionLink = $( 'span.opt-in-or-opt-out.<?php echo $slug ?> a' ),
|
88 |
+
$optOutButton = $modal.find( '.button-opt-out' ),
|
89 |
+
$optOutErrorMessage = $modal.find( '.opt-out-error-message' ),
|
90 |
+
moduleID = '<?php echo $fs->get_id() ?>';
|
91 |
+
|
92 |
+
$actionLink.attr( 'data-action', action );
|
93 |
+
$modal.appendTo( $( 'body' ) );
|
94 |
+
|
95 |
+
function registerActionLinkClick() {
|
96 |
+
$actionLink.click(function( evt ) {
|
97 |
+
evt.preventDefault();
|
98 |
+
|
99 |
+
if ( 'stop_tracking' == $actionLink.attr( 'data-action' ) ) {
|
100 |
+
showModal();
|
101 |
+
} else {
|
102 |
+
optIn();
|
103 |
+
}
|
104 |
+
|
105 |
+
return false;
|
106 |
+
});
|
107 |
+
}
|
108 |
+
|
109 |
+
function registerEventHandlers() {
|
110 |
+
registerActionLinkClick();
|
111 |
+
|
112 |
+
$modal.on( 'click', '.button-opt-out', function( evt ) {
|
113 |
+
evt.preventDefault();
|
114 |
+
|
115 |
+
if ( $( this ).hasClass( 'disabled' ) ) {
|
116 |
+
return;
|
117 |
+
}
|
118 |
+
|
119 |
+
disableOptOutButton();
|
120 |
+
optOut();
|
121 |
+
});
|
122 |
+
|
123 |
+
// If the user has clicked outside the window, close the modal.
|
124 |
+
$modal.on( 'click', '.fs-close, .button-close', function() {
|
125 |
+
closeModal();
|
126 |
+
return false;
|
127 |
+
});
|
128 |
+
}
|
129 |
+
|
130 |
+
registerEventHandlers();
|
131 |
+
|
132 |
+
function showModal() {
|
133 |
+
resetModal();
|
134 |
+
|
135 |
+
// Display the dialog box.
|
136 |
+
$modal.addClass( 'active' );
|
137 |
+
$( 'body' ).addClass( 'has-fs-modal' );
|
138 |
+
}
|
139 |
+
|
140 |
+
function closeModal() {
|
141 |
+
$modal.removeClass( 'active' );
|
142 |
+
$( 'body' ).removeClass( 'has-fs-modal' );
|
143 |
+
}
|
144 |
+
|
145 |
+
function resetOptOutButton() {
|
146 |
+
enableOptOutButton();
|
147 |
+
$optOutButton.text( <?php echo json_encode( $opt_out_text ) ?> );
|
148 |
+
}
|
149 |
+
|
150 |
+
function resetModal() {
|
151 |
+
hideError();
|
152 |
+
resetOptOutButton();
|
153 |
+
}
|
154 |
+
|
155 |
+
function optIn() {
|
156 |
+
sendRequest();
|
157 |
+
}
|
158 |
+
|
159 |
+
function optOut() {
|
160 |
+
sendRequest();
|
161 |
+
}
|
162 |
+
|
163 |
+
function sendRequest() {
|
164 |
+
$.ajax({
|
165 |
+
url: ajaxurl,
|
166 |
+
method: 'POST',
|
167 |
+
data: {
|
168 |
+
action : ( 'stop_tracking' == action ?
|
169 |
+
'<?php echo $fs->get_ajax_action( 'stop_tracking' ) ?>' :
|
170 |
+
'<?php echo $fs->get_ajax_action( 'allow_tracking' ) ?>'
|
171 |
+
),
|
172 |
+
security : ( 'stop_tracking' == action ?
|
173 |
+
'<?php echo $fs->get_ajax_security( 'stop_tracking' ) ?>' :
|
174 |
+
'<?php echo $fs->get_ajax_security( 'allow_tracking' ) ?>'
|
175 |
+
),
|
176 |
+
module_id: moduleID
|
177 |
+
},
|
178 |
+
beforeSend: function() {
|
179 |
+
if ( 'opt-in' == action ) {
|
180 |
+
$actionLink.text( '<?php fs_esc_js_echo_inline( 'Opting in', 'opting-in', $slug ) ?>...' );
|
181 |
+
} else {
|
182 |
+
$optOutButton.text( '<?php fs_esc_js_echo_inline( 'Opting out', 'opting-out', $slug ) ?>...' );
|
183 |
+
}
|
184 |
+
},
|
185 |
+
success: function( resultObj ) {
|
186 |
+
if ( resultObj.success ) {
|
187 |
+
if ( 'allow_tracking' == action ) {
|
188 |
+
action = 'stop_tracking';
|
189 |
+
$actionLink.text( '<?php echo esc_js( $opt_out_text ) ?>' );
|
190 |
+
showOptInAppreciationMessageAndScrollToTop();
|
191 |
+
} else {
|
192 |
+
action = 'allow_tracking';
|
193 |
+
$actionLink.text( '<?php echo esc_js( $opt_in_text ) ?>' );
|
194 |
+
closeModal();
|
195 |
+
|
196 |
+
if ( $adminNotice.length > 0 ) {
|
197 |
+
$adminNotice.remove();
|
198 |
+
}
|
199 |
+
}
|
200 |
+
|
201 |
+
$actionLink.attr( 'data-action', action );
|
202 |
+
} else {
|
203 |
+
showError( resultObj.error );
|
204 |
+
resetOptOutButton();
|
205 |
+
}
|
206 |
+
}
|
207 |
+
});
|
208 |
+
}
|
209 |
+
|
210 |
+
function enableOptOutButton() {
|
211 |
+
$optOutButton.removeClass( 'disabled' );
|
212 |
+
}
|
213 |
+
|
214 |
+
function disableOptOutButton() {
|
215 |
+
$optOutButton.addClass( 'disabled' );
|
216 |
+
}
|
217 |
+
|
218 |
+
function hideError() {
|
219 |
+
$optOutErrorMessage.hide();
|
220 |
+
}
|
221 |
+
|
222 |
+
function showOptInAppreciationMessageAndScrollToTop() {
|
223 |
+
$adminNotice.insertAfter( $( '#wpbody-content' ).find( ' > .wrap > h1' ) );
|
224 |
+
window.scrollTo(0, 0);
|
225 |
+
}
|
226 |
+
|
227 |
+
function showError( msg ) {
|
228 |
+
$optOutErrorMessage.find( ' > p' ).html( msg );
|
229 |
+
$optOutErrorMessage.show();
|
230 |
+
}
|
231 |
+
|
232 |
+
<?php if ( $fs->is_theme() ) : ?>
|
233 |
+
/**
|
234 |
+
* Add opt-in/out button to the active theme's buttons collection
|
235 |
+
* in the theme's extended details overlay.
|
236 |
+
*
|
237 |
+
* @author Vova Feldman (@svovaf)
|
238 |
+
* @since 1.2.2.7
|
239 |
+
*/
|
240 |
+
$('.theme-overlay').contentChange(function () {
|
241 |
+
if (!$(this).find('.theme-overlay').hasClass('active')) {
|
242 |
+
// Add opt-in/out button only to the currently active theme.
|
243 |
+
return;
|
244 |
+
}
|
245 |
+
|
246 |
+
if ($('#fs_theme_opt_in_out').length > 0){
|
247 |
+
// Button already there.
|
248 |
+
return;
|
249 |
+
}
|
250 |
+
|
251 |
+
var label = (('stop_tracking' == action) ?
|
252 |
+
'<?php echo esc_js( $opt_out_text ) ?>' :
|
253 |
+
'<?php echo esc_js( $opt_in_text ) ?>'),
|
254 |
+
href = (('stop_tracking' != action) ?
|
255 |
+
'<?php echo esc_js( $reconnect_url ) ?>' :
|
256 |
+
'');
|
257 |
+
|
258 |
+
$actionLink = $('<a id="fs_theme_opt_in_out" href="' + encodeURI(href) + '" class="button" data-action="' + action + '">' + label + '</a>');
|
259 |
+
|
260 |
+
$('.theme-wrap .theme-actions .active-theme').append($actionLink);
|
261 |
+
|
262 |
+
registerActionLinkClick();
|
263 |
+
});
|
264 |
+
<?php endif ?>
|
265 |
+
});
|
266 |
+
})( jQuery );
|
267 |
+
</script>
|
freemius/templates/forms/resend-key.php
CHANGED
@@ -1,247 +1,247 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.2.0
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array $VARS
|
15 |
-
* @var Freemius $fs
|
16 |
-
*/
|
17 |
-
$fs = freemius( $VARS['id'] );
|
18 |
-
|
19 |
-
$slug = $fs->get_slug();
|
20 |
-
|
21 |
-
$send_button_text = fs_text_inline( 'Send License Key', 'send-license-key', $slug );
|
22 |
-
$cancel_button_text = fs_text_inline( 'Cancel', 'cancel', $slug );
|
23 |
-
$email_address_placeholder = fs_esc_attr_inline( 'Email address', 'email-address', $slug );
|
24 |
-
$other_text = fs_text_inline( 'Other', 'other', $slug );
|
25 |
-
|
26 |
-
$is_freemium = $fs->is_freemium();
|
27 |
-
|
28 |
-
$send_button_text_html = esc_html($send_button_text);
|
29 |
-
|
30 |
-
$button_html = <<< HTML
|
31 |
-
<div class="button-container">
|
32 |
-
<a href="#" class="button button-primary button-send-license-key" tabindex="2">{$send_button_text_html}</a>
|
33 |
-
</div>
|
34 |
-
HTML;
|
35 |
-
|
36 |
-
if ( $is_freemium ) {
|
37 |
-
$current_user = Freemius::_get_current_wp_user();
|
38 |
-
$email = $current_user->user_email;
|
39 |
-
$esc_email = esc_attr( $email );
|
40 |
-
$form_html = <<< HTML
|
41 |
-
<div class="email-address-container">
|
42 |
-
<label><input name="email-address" type="radio" checked="checked" tabindex="1" value="{$esc_email}"> {$email}</label>
|
43 |
-
<label><input name="email-address" type="radio" tabindex="1" value="other">{$other_text}: <input class="email-address" type="text" placeholder="{$email_address_placeholder}"></label>
|
44 |
-
</div>
|
45 |
-
{$button_html}
|
46 |
-
HTML;
|
47 |
-
} else {
|
48 |
-
$email = '';
|
49 |
-
$form_html = <<< HTML
|
50 |
-
{$button_html}
|
51 |
-
<div class="email-address-container">
|
52 |
-
<input class="email-address" type="text" placeholder="{$email_address_placeholder}" tabindex="1">
|
53 |
-
</div>
|
54 |
-
HTML;
|
55 |
-
}
|
56 |
-
|
57 |
-
$message_above_input_field = fs_esc_html_inline( "Enter the email address you've used for the upgrade below and we will resend you the license key.", 'ask-for-upgrade-email-address', $slug );
|
58 |
-
$modal_content_html = <<< HTML
|
59 |
-
<div class="notice notice-error inline license-resend-message"><p></p></div>
|
60 |
-
<p>{$message_above_input_field}</p>
|
61 |
-
<div class="input-container">
|
62 |
-
{$form_html}
|
63 |
-
</div>
|
64 |
-
HTML;
|
65 |
-
|
66 |
-
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
67 |
-
?>
|
68 |
-
<script type="text/javascript">
|
69 |
-
(function ($) {
|
70 |
-
$(document).ready(function () {
|
71 |
-
var contentHtml = <?php echo json_encode( $modal_content_html ); ?>,
|
72 |
-
modalHtml =
|
73 |
-
'<div class="fs-modal fs-modal-license-key-resend <?php echo $is_freemium ? 'fs-freemium' : 'fs-premium' ?>">'
|
74 |
-
+ ' <div class="fs-modal-dialog">'
|
75 |
-
+ ' <div class="fs-modal-header">'
|
76 |
-
+ ' <h4><?php echo esc_js( $send_button_text ) ?></h4>'
|
77 |
-
+ ' <a href="#!" class="fs-close" tabindex="3" title="Close"><i class="dashicons dashicons-no" title="<?php echo esc_js( fs_text_x_inline( 'Dismiss', 'as close a window', 'dismiss', $slug ) ) ?>"></i></a>'
|
78 |
-
+ ' </div>'
|
79 |
-
+ ' <div class="fs-modal-body">'
|
80 |
-
+ ' <div class="fs-modal-panel active">' + contentHtml + '</div>'
|
81 |
-
+ ' </div>'
|
82 |
-
+ ' </div>'
|
83 |
-
+ '</div>',
|
84 |
-
$modal = $(modalHtml),
|
85 |
-
$sendButton = $modal.find('.button-send-license-key'),
|
86 |
-
$emailInput = $modal.find('input.email-address'),
|
87 |
-
$feedbackMessage = $modal.find('.license-resend-message'),
|
88 |
-
isFreemium = <?php echo json_encode( $is_freemium ) ?>,
|
89 |
-
userEmail = <?php echo json_encode( $email ) ?>,
|
90 |
-
moduleID = '<?php echo $fs->get_id() ?>',
|
91 |
-
isChild = false;
|
92 |
-
|
93 |
-
|
94 |
-
$modal.appendTo($('body'));
|
95 |
-
|
96 |
-
function registerEventHandlers() {
|
97 |
-
$('a.show-license-resend-modal-<?php echo $fs->get_unique_affix() ?>').click(function (evt) {
|
98 |
-
evt.preventDefault();
|
99 |
-
|
100 |
-
showModal();
|
101 |
-
});
|
102 |
-
|
103 |
-
if (isFreemium) {
|
104 |
-
$modal.on('change', 'input[type=radio][name=email-address]', function () {
|
105 |
-
updateButtonState();
|
106 |
-
});
|
107 |
-
|
108 |
-
$modal.on('focus', 'input.email-address', function () {
|
109 |
-
// Check custom email radio button on email input focus.
|
110 |
-
$($modal.find('input[type=radio]')[1]).prop('checked', true);
|
111 |
-
|
112 |
-
updateButtonState();
|
113 |
-
});
|
114 |
-
}
|
115 |
-
|
116 |
-
$modal.on('input propertychange', 'input.email-address', function () {
|
117 |
-
updateButtonState();
|
118 |
-
});
|
119 |
-
|
120 |
-
$modal.on('blur', 'input.email-address', function () {
|
121 |
-
updateButtonState();
|
122 |
-
});
|
123 |
-
|
124 |
-
$modal.on('click', '.fs-close', function (){
|
125 |
-
closeModal();
|
126 |
-
return false;
|
127 |
-
});
|
128 |
-
|
129 |
-
$modal.on('click', '.button', function (evt) {
|
130 |
-
evt.preventDefault();
|
131 |
-
|
132 |
-
if ($(this).hasClass('disabled')) {
|
133 |
-
return;
|
134 |
-
}
|
135 |
-
|
136 |
-
var email = getEmail();
|
137 |
-
|
138 |
-
disableButton();
|
139 |
-
|
140 |
-
if (!(-1 < email.indexOf('@'))) {
|
141 |
-
return;
|
142 |
-
}
|
143 |
-
|
144 |
-
$.ajax({
|
145 |
-
url : ajaxurl,
|
146 |
-
method : 'POST',
|
147 |
-
data : {
|
148 |
-
action : '<?php echo $fs->get_ajax_action( 'resend_license_key' ) ?>',
|
149 |
-
security : '<?php echo $fs->get_ajax_security( 'resend_license_key' ) ?>',
|
150 |
-
module_id : moduleID,
|
151 |
-
email : email
|
152 |
-
},
|
153 |
-
beforeSend: function () {
|
154 |
-
$sendButton.text('<?php fs_esc_js_echo_inline( 'Sending license key', 'sending-license-key', $slug ) ?>...');
|
155 |
-
},
|
156 |
-
success : function (result) {
|
157 |
-
var resultObj = $.parseJSON(result);
|
158 |
-
if (resultObj.success) {
|
159 |
-
closeModal();
|
160 |
-
} else {
|
161 |
-
showError(resultObj.error);
|
162 |
-
resetButton();
|
163 |
-
}
|
164 |
-
}
|
165 |
-
});
|
166 |
-
});
|
167 |
-
}
|
168 |
-
|
169 |
-
registerEventHandlers();
|
170 |
-
|
171 |
-
resetButton();
|
172 |
-
|
173 |
-
function showModal() {
|
174 |
-
resetModal();
|
175 |
-
|
176 |
-
// Display the dialog box.
|
177 |
-
$modal.addClass('active');
|
178 |
-
|
179 |
-
if (!isFreemium)
|
180 |
-
$emailInput.focus();
|
181 |
-
|
182 |
-
var $body = $('body');
|
183 |
-
|
184 |
-
isChild = $body.hasClass('has-fs-modal');
|
185 |
-
if (isChild) {
|
186 |
-
return;
|
187 |
-
}
|
188 |
-
|
189 |
-
$body.addClass('has-fs-modal');
|
190 |
-
}
|
191 |
-
|
192 |
-
function closeModal() {
|
193 |
-
$modal.removeClass('active');
|
194 |
-
|
195 |
-
// If child modal, do not remove the "has-fs-modal" class of the <body> element to keep its scrollbars hidden.
|
196 |
-
if (isChild) {
|
197 |
-
return;
|
198 |
-
}
|
199 |
-
|
200 |
-
$('body').removeClass('has-fs-modal');
|
201 |
-
}
|
202 |
-
|
203 |
-
function resetButton() {
|
204 |
-
updateButtonState();
|
205 |
-
$sendButton.text(<?php echo json_encode($send_button_text) ?>);
|
206 |
-
}
|
207 |
-
|
208 |
-
function resetModal() {
|
209 |
-
hideError();
|
210 |
-
resetButton();
|
211 |
-
$emailInput.val('');
|
212 |
-
}
|
213 |
-
|
214 |
-
function getEmail() {
|
215 |
-
var email = $emailInput.val().trim();
|
216 |
-
|
217 |
-
if (isFreemium) {
|
218 |
-
if ('other' != $modal.find('input[type=radio][name=email-address]:checked').val()) {
|
219 |
-
email = userEmail;
|
220 |
-
}
|
221 |
-
}
|
222 |
-
|
223 |
-
return email;
|
224 |
-
}
|
225 |
-
|
226 |
-
function updateButtonState() {
|
227 |
-
/**
|
228 |
-
* If email address is not empty, enable the send license key button.
|
229 |
-
*/
|
230 |
-
$sendButton.toggleClass('disabled', !( -1 < getEmail().indexOf('@') ));
|
231 |
-
}
|
232 |
-
|
233 |
-
function disableButton() {
|
234 |
-
$sendButton.addClass('disabled');
|
235 |
-
}
|
236 |
-
|
237 |
-
function hideError() {
|
238 |
-
$feedbackMessage.hide();
|
239 |
-
}
|
240 |
-
|
241 |
-
function showError(msg) {
|
242 |
-
$feedbackMessage.find(' > p').html(msg);
|
243 |
-
$feedbackMessage.show();
|
244 |
-
}
|
245 |
-
});
|
246 |
-
})(jQuery);
|
247 |
-
</script>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.2.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
* @var Freemius $fs
|
16 |
+
*/
|
17 |
+
$fs = freemius( $VARS['id'] );
|
18 |
+
|
19 |
+
$slug = $fs->get_slug();
|
20 |
+
|
21 |
+
$send_button_text = fs_text_inline( 'Send License Key', 'send-license-key', $slug );
|
22 |
+
$cancel_button_text = fs_text_inline( 'Cancel', 'cancel', $slug );
|
23 |
+
$email_address_placeholder = fs_esc_attr_inline( 'Email address', 'email-address', $slug );
|
24 |
+
$other_text = fs_text_inline( 'Other', 'other', $slug );
|
25 |
+
|
26 |
+
$is_freemium = $fs->is_freemium();
|
27 |
+
|
28 |
+
$send_button_text_html = esc_html($send_button_text);
|
29 |
+
|
30 |
+
$button_html = <<< HTML
|
31 |
+
<div class="button-container">
|
32 |
+
<a href="#" class="button button-primary button-send-license-key" tabindex="2">{$send_button_text_html}</a>
|
33 |
+
</div>
|
34 |
+
HTML;
|
35 |
+
|
36 |
+
if ( $is_freemium ) {
|
37 |
+
$current_user = Freemius::_get_current_wp_user();
|
38 |
+
$email = $current_user->user_email;
|
39 |
+
$esc_email = esc_attr( $email );
|
40 |
+
$form_html = <<< HTML
|
41 |
+
<div class="email-address-container">
|
42 |
+
<label><input name="email-address" type="radio" checked="checked" tabindex="1" value="{$esc_email}"> {$email}</label>
|
43 |
+
<label><input name="email-address" type="radio" tabindex="1" value="other">{$other_text}: <input class="email-address" type="text" placeholder="{$email_address_placeholder}"></label>
|
44 |
+
</div>
|
45 |
+
{$button_html}
|
46 |
+
HTML;
|
47 |
+
} else {
|
48 |
+
$email = '';
|
49 |
+
$form_html = <<< HTML
|
50 |
+
{$button_html}
|
51 |
+
<div class="email-address-container">
|
52 |
+
<input class="email-address" type="text" placeholder="{$email_address_placeholder}" tabindex="1">
|
53 |
+
</div>
|
54 |
+
HTML;
|
55 |
+
}
|
56 |
+
|
57 |
+
$message_above_input_field = fs_esc_html_inline( "Enter the email address you've used for the upgrade below and we will resend you the license key.", 'ask-for-upgrade-email-address', $slug );
|
58 |
+
$modal_content_html = <<< HTML
|
59 |
+
<div class="notice notice-error inline license-resend-message"><p></p></div>
|
60 |
+
<p>{$message_above_input_field}</p>
|
61 |
+
<div class="input-container">
|
62 |
+
{$form_html}
|
63 |
+
</div>
|
64 |
+
HTML;
|
65 |
+
|
66 |
+
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
67 |
+
?>
|
68 |
+
<script type="text/javascript">
|
69 |
+
(function ($) {
|
70 |
+
$(document).ready(function () {
|
71 |
+
var contentHtml = <?php echo json_encode( $modal_content_html ); ?>,
|
72 |
+
modalHtml =
|
73 |
+
'<div class="fs-modal fs-modal-license-key-resend <?php echo $is_freemium ? 'fs-freemium' : 'fs-premium' ?>">'
|
74 |
+
+ ' <div class="fs-modal-dialog">'
|
75 |
+
+ ' <div class="fs-modal-header">'
|
76 |
+
+ ' <h4><?php echo esc_js( $send_button_text ) ?></h4>'
|
77 |
+
+ ' <a href="#!" class="fs-close" tabindex="3" title="Close"><i class="dashicons dashicons-no" title="<?php echo esc_js( fs_text_x_inline( 'Dismiss', 'as close a window', 'dismiss', $slug ) ) ?>"></i></a>'
|
78 |
+
+ ' </div>'
|
79 |
+
+ ' <div class="fs-modal-body">'
|
80 |
+
+ ' <div class="fs-modal-panel active">' + contentHtml + '</div>'
|
81 |
+
+ ' </div>'
|
82 |
+
+ ' </div>'
|
83 |
+
+ '</div>',
|
84 |
+
$modal = $(modalHtml),
|
85 |
+
$sendButton = $modal.find('.button-send-license-key'),
|
86 |
+
$emailInput = $modal.find('input.email-address'),
|
87 |
+
$feedbackMessage = $modal.find('.license-resend-message'),
|
88 |
+
isFreemium = <?php echo json_encode( $is_freemium ) ?>,
|
89 |
+
userEmail = <?php echo json_encode( $email ) ?>,
|
90 |
+
moduleID = '<?php echo $fs->get_id() ?>',
|
91 |
+
isChild = false;
|
92 |
+
|
93 |
+
|
94 |
+
$modal.appendTo($('body'));
|
95 |
+
|
96 |
+
function registerEventHandlers() {
|
97 |
+
$('a.show-license-resend-modal-<?php echo $fs->get_unique_affix() ?>').click(function (evt) {
|
98 |
+
evt.preventDefault();
|
99 |
+
|
100 |
+
showModal();
|
101 |
+
});
|
102 |
+
|
103 |
+
if (isFreemium) {
|
104 |
+
$modal.on('change', 'input[type=radio][name=email-address]', function () {
|
105 |
+
updateButtonState();
|
106 |
+
});
|
107 |
+
|
108 |
+
$modal.on('focus', 'input.email-address', function () {
|
109 |
+
// Check custom email radio button on email input focus.
|
110 |
+
$($modal.find('input[type=radio]')[1]).prop('checked', true);
|
111 |
+
|
112 |
+
updateButtonState();
|
113 |
+
});
|
114 |
+
}
|
115 |
+
|
116 |
+
$modal.on('input propertychange', 'input.email-address', function () {
|
117 |
+
updateButtonState();
|
118 |
+
});
|
119 |
+
|
120 |
+
$modal.on('blur', 'input.email-address', function () {
|
121 |
+
updateButtonState();
|
122 |
+
});
|
123 |
+
|
124 |
+
$modal.on('click', '.fs-close', function (){
|
125 |
+
closeModal();
|
126 |
+
return false;
|
127 |
+
});
|
128 |
+
|
129 |
+
$modal.on('click', '.button', function (evt) {
|
130 |
+
evt.preventDefault();
|
131 |
+
|
132 |
+
if ($(this).hasClass('disabled')) {
|
133 |
+
return;
|
134 |
+
}
|
135 |
+
|
136 |
+
var email = getEmail();
|
137 |
+
|
138 |
+
disableButton();
|
139 |
+
|
140 |
+
if (!(-1 < email.indexOf('@'))) {
|
141 |
+
return;
|
142 |
+
}
|
143 |
+
|
144 |
+
$.ajax({
|
145 |
+
url : ajaxurl,
|
146 |
+
method : 'POST',
|
147 |
+
data : {
|
148 |
+
action : '<?php echo $fs->get_ajax_action( 'resend_license_key' ) ?>',
|
149 |
+
security : '<?php echo $fs->get_ajax_security( 'resend_license_key' ) ?>',
|
150 |
+
module_id : moduleID,
|
151 |
+
email : email
|
152 |
+
},
|
153 |
+
beforeSend: function () {
|
154 |
+
$sendButton.text('<?php fs_esc_js_echo_inline( 'Sending license key', 'sending-license-key', $slug ) ?>...');
|
155 |
+
},
|
156 |
+
success : function (result) {
|
157 |
+
var resultObj = $.parseJSON(result);
|
158 |
+
if (resultObj.success) {
|
159 |
+
closeModal();
|
160 |
+
} else {
|
161 |
+
showError(resultObj.error);
|
162 |
+
resetButton();
|
163 |
+
}
|
164 |
+
}
|
165 |
+
});
|
166 |
+
});
|
167 |
+
}
|
168 |
+
|
169 |
+
registerEventHandlers();
|
170 |
+
|
171 |
+
resetButton();
|
172 |
+
|
173 |
+
function showModal() {
|
174 |
+
resetModal();
|
175 |
+
|
176 |
+
// Display the dialog box.
|
177 |
+
$modal.addClass('active');
|
178 |
+
|
179 |
+
if (!isFreemium)
|
180 |
+
$emailInput.focus();
|
181 |
+
|
182 |
+
var $body = $('body');
|
183 |
+
|
184 |
+
isChild = $body.hasClass('has-fs-modal');
|
185 |
+
if (isChild) {
|
186 |
+
return;
|
187 |
+
}
|
188 |
+
|
189 |
+
$body.addClass('has-fs-modal');
|
190 |
+
}
|
191 |
+
|
192 |
+
function closeModal() {
|
193 |
+
$modal.removeClass('active');
|
194 |
+
|
195 |
+
// If child modal, do not remove the "has-fs-modal" class of the <body> element to keep its scrollbars hidden.
|
196 |
+
if (isChild) {
|
197 |
+
return;
|
198 |
+
}
|
199 |
+
|
200 |
+
$('body').removeClass('has-fs-modal');
|
201 |
+
}
|
202 |
+
|
203 |
+
function resetButton() {
|
204 |
+
updateButtonState();
|
205 |
+
$sendButton.text(<?php echo json_encode($send_button_text) ?>);
|
206 |
+
}
|
207 |
+
|
208 |
+
function resetModal() {
|
209 |
+
hideError();
|
210 |
+
resetButton();
|
211 |
+
$emailInput.val('');
|
212 |
+
}
|
213 |
+
|
214 |
+
function getEmail() {
|
215 |
+
var email = $emailInput.val().trim();
|
216 |
+
|
217 |
+
if (isFreemium) {
|
218 |
+
if ('other' != $modal.find('input[type=radio][name=email-address]:checked').val()) {
|
219 |
+
email = userEmail;
|
220 |
+
}
|
221 |
+
}
|
222 |
+
|
223 |
+
return email;
|
224 |
+
}
|
225 |
+
|
226 |
+
function updateButtonState() {
|
227 |
+
/**
|
228 |
+
* If email address is not empty, enable the send license key button.
|
229 |
+
*/
|
230 |
+
$sendButton.toggleClass('disabled', !( -1 < getEmail().indexOf('@') ));
|
231 |
+
}
|
232 |
+
|
233 |
+
function disableButton() {
|
234 |
+
$sendButton.addClass('disabled');
|
235 |
+
}
|
236 |
+
|
237 |
+
function hideError() {
|
238 |
+
$feedbackMessage.hide();
|
239 |
+
}
|
240 |
+
|
241 |
+
function showError(msg) {
|
242 |
+
$feedbackMessage.find(' > p').html(msg);
|
243 |
+
$feedbackMessage.show();
|
244 |
+
}
|
245 |
+
});
|
246 |
+
})(jQuery);
|
247 |
+
</script>
|
freemius/templates/forms/trial-start.php
CHANGED
@@ -1,181 +1,181 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.2.0
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array $VARS
|
15 |
-
* @var Freemius $fs
|
16 |
-
*/
|
17 |
-
$fs = freemius( $VARS['id'] );
|
18 |
-
$slug = $fs->get_slug();
|
19 |
-
|
20 |
-
$message_header = sprintf(
|
21 |
-
/* translators: %1$s: Number of trial days; %2$s: Plan name; */
|
22 |
-
fs_text_inline( 'You are 1-click away from starting your %1$s-day free trial of the %2$s plan.', 'start-trial-prompt-header', $slug ),
|
23 |
-
'<span class="var-trial_period"></span>',
|
24 |
-
'<span class="var-plan_title"></span>'
|
25 |
-
);
|
26 |
-
$message_content = sprintf(
|
27 |
-
/* translators: %s: Link to freemius.com */
|
28 |
-
fs_text_inline( 'For compliance with the WordPress.org guidelines, before we start the trial we ask that you opt in with your user and non-sensitive site information, allowing the %s to periodically send data to %s to check for version updates and to validate your trial.', 'start-trial-prompt-message', $slug ),
|
29 |
-
$fs->get_module_type(),
|
30 |
-
sprintf(
|
31 |
-
'<a href="%s" target="_blank">%s</a>',
|
32 |
-
'https://freemius.com',
|
33 |
-
'freemius.com'
|
34 |
-
)
|
35 |
-
);
|
36 |
-
|
37 |
-
$modal_content_html = <<< HTML
|
38 |
-
<div class="notice notice-error inline"><p></p></div>
|
39 |
-
<h3>{$message_header}</h3>
|
40 |
-
<p>{$message_content}</p>
|
41 |
-
HTML;
|
42 |
-
|
43 |
-
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
44 |
-
?>
|
45 |
-
<script type="text/javascript">
|
46 |
-
(function ($) {
|
47 |
-
$(document).ready(function () {
|
48 |
-
var modalContentHtml = <?php echo json_encode( $modal_content_html ); ?>,
|
49 |
-
modalHtml =
|
50 |
-
'<div class="fs-modal fs-modal-license-key-resend">'
|
51 |
-
+ ' <div class="fs-modal-dialog">'
|
52 |
-
+ ' <div class="fs-modal-header">'
|
53 |
-
+ ' <h4><?php echo esc_js( fs_text_x_inline( 'Start free trial', 'call to action', 'start-free-trial', $slug ) ) ?></h4>'
|
54 |
-
+ ' </div>'
|
55 |
-
+ ' <div class="fs-modal-body">' + modalContentHtml + '</div>'
|
56 |
-
+ ' <div class="fs-modal-footer">'
|
57 |
-
+ ' <button class="button button-secondary button-close">' + <?php fs_json_encode_echo_inline( 'Cancel', 'cancel', $slug ) ?> +'</button>'
|
58 |
-
+ ' <button class="button button-primary button-connect">' + <?php fs_json_encode_echo_inline( 'Approve & Start Trial', 'approve-start-trial', $slug ) ?> +'</button>'
|
59 |
-
+ ' </div>'
|
60 |
-
+ ' </div>'
|
61 |
-
+ '</div>',
|
62 |
-
$modal = $( modalHtml ),
|
63 |
-
trialData;
|
64 |
-
|
65 |
-
$modal.appendTo($('body'));
|
66 |
-
|
67 |
-
var $errorNotice = $modal.find('.notice-error');
|
68 |
-
|
69 |
-
registerEventHandlers();
|
70 |
-
|
71 |
-
function registerEventHandlers() {
|
72 |
-
$modal.on('click', '.button-close', function () {
|
73 |
-
closeModal();
|
74 |
-
return false;
|
75 |
-
});
|
76 |
-
|
77 |
-
$modal.on('click', '.button-connect', function (evt) {
|
78 |
-
evt.preventDefault();
|
79 |
-
|
80 |
-
var $button = $(this);
|
81 |
-
|
82 |
-
$.ajax({
|
83 |
-
url : ajaxurl,
|
84 |
-
method : 'POST',
|
85 |
-
data : {
|
86 |
-
action : '<?php echo $fs->get_ajax_action( 'start_trial' ) ?>',
|
87 |
-
security : '<?php echo $fs->get_ajax_security( 'start_trial' ) ?>',
|
88 |
-
module_id: '<?php echo $fs->get_id() ?>',
|
89 |
-
trial : trialData
|
90 |
-
},
|
91 |
-
beforeSend: function () {
|
92 |
-
// Disable all buttons during trial activation.
|
93 |
-
$modal.find('.button').prop('disabled', true);
|
94 |
-
|
95 |
-
$button.text(<?php fs_json_encode_echo_inline( 'Starting trial', 'starting-trial', $slug ) ?> + '...');
|
96 |
-
|
97 |
-
setLoadingMode();
|
98 |
-
},
|
99 |
-
success : function (resultObj) {
|
100 |
-
if (resultObj.success) {
|
101 |
-
$button.text(<?php fs_json_encode_echo_inline( 'Please wait', 'please-wait', $slug ) ?> + '...');
|
102 |
-
|
103 |
-
// Redirect to the "Account" page and sync the license.
|
104 |
-
window.location.href = resultObj.data.next_page;
|
105 |
-
} else {
|
106 |
-
$button.text(<?php fs_json_encode_echo( 'approve-start-trial', $slug ) ?>);
|
107 |
-
|
108 |
-
resetLoadingMode();
|
109 |
-
showError(resultObj.error);
|
110 |
-
}
|
111 |
-
}
|
112 |
-
});
|
113 |
-
});
|
114 |
-
}
|
115 |
-
|
116 |
-
window.openTrialConfirmationModal = function showModal(data) {
|
117 |
-
resetModal();
|
118 |
-
|
119 |
-
// Display the dialog box.
|
120 |
-
$modal.addClass('active');
|
121 |
-
|
122 |
-
trialData = data;
|
123 |
-
|
124 |
-
var $modalBody = $modal.find('.fs-modal-body'),
|
125 |
-
$var;
|
126 |
-
|
127 |
-
for (var key in data) {
|
128 |
-
if (data.hasOwnProperty(key)) {
|
129 |
-
$var = $modalBody.find('.var-' + key);
|
130 |
-
|
131 |
-
if ($var.length > 0)
|
132 |
-
$var.html(data[key]);
|
133 |
-
}
|
134 |
-
}
|
135 |
-
|
136 |
-
$('body').addClass('has-fs-modal');
|
137 |
-
};
|
138 |
-
|
139 |
-
function closeModal() {
|
140 |
-
$modal.removeClass('active');
|
141 |
-
|
142 |
-
$('body').removeClass('has-fs-modal');
|
143 |
-
}
|
144 |
-
|
145 |
-
function resetModal() {
|
146 |
-
hideError();
|
147 |
-
}
|
148 |
-
|
149 |
-
function hideError() {
|
150 |
-
$errorNotice.hide();
|
151 |
-
}
|
152 |
-
|
153 |
-
function setLoadingMode() {
|
154 |
-
$modal.find('.button')
|
155 |
-
// Re-enable all buttons.
|
156 |
-
.prop('disabled', trialData)
|
157 |
-
// Stop loading cursor.
|
158 |
-
.css({'cursor': 'wait'});
|
159 |
-
|
160 |
-
// Stop loading cursor.
|
161 |
-
$(document.body).css({'cursor': 'wait'});
|
162 |
-
}
|
163 |
-
|
164 |
-
function resetLoadingMode() {
|
165 |
-
$modal.find('.button')
|
166 |
-
// Re-enable all buttons.
|
167 |
-
.prop('disabled', false)
|
168 |
-
// Stop loading cursor.
|
169 |
-
.css({'cursor': 'initial'});
|
170 |
-
|
171 |
-
// Stop loading cursor.
|
172 |
-
$(document.body).css({'cursor': 'initial'});
|
173 |
-
}
|
174 |
-
|
175 |
-
function showError(msg) {
|
176 |
-
$errorNotice.find(' > p').html(msg);
|
177 |
-
$errorNotice.show();
|
178 |
-
}
|
179 |
-
});
|
180 |
-
})(jQuery);
|
181 |
-
</script>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.2.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
* @var Freemius $fs
|
16 |
+
*/
|
17 |
+
$fs = freemius( $VARS['id'] );
|
18 |
+
$slug = $fs->get_slug();
|
19 |
+
|
20 |
+
$message_header = sprintf(
|
21 |
+
/* translators: %1$s: Number of trial days; %2$s: Plan name; */
|
22 |
+
fs_text_inline( 'You are 1-click away from starting your %1$s-day free trial of the %2$s plan.', 'start-trial-prompt-header', $slug ),
|
23 |
+
'<span class="var-trial_period"></span>',
|
24 |
+
'<span class="var-plan_title"></span>'
|
25 |
+
);
|
26 |
+
$message_content = sprintf(
|
27 |
+
/* translators: %s: Link to freemius.com */
|
28 |
+
fs_text_inline( 'For compliance with the WordPress.org guidelines, before we start the trial we ask that you opt in with your user and non-sensitive site information, allowing the %s to periodically send data to %s to check for version updates and to validate your trial.', 'start-trial-prompt-message', $slug ),
|
29 |
+
$fs->get_module_type(),
|
30 |
+
sprintf(
|
31 |
+
'<a href="%s" target="_blank">%s</a>',
|
32 |
+
'https://freemius.com',
|
33 |
+
'freemius.com'
|
34 |
+
)
|
35 |
+
);
|
36 |
+
|
37 |
+
$modal_content_html = <<< HTML
|
38 |
+
<div class="notice notice-error inline"><p></p></div>
|
39 |
+
<h3>{$message_header}</h3>
|
40 |
+
<p>{$message_content}</p>
|
41 |
+
HTML;
|
42 |
+
|
43 |
+
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
|
44 |
+
?>
|
45 |
+
<script type="text/javascript">
|
46 |
+
(function ($) {
|
47 |
+
$(document).ready(function () {
|
48 |
+
var modalContentHtml = <?php echo json_encode( $modal_content_html ); ?>,
|
49 |
+
modalHtml =
|
50 |
+
'<div class="fs-modal fs-modal-license-key-resend">'
|
51 |
+
+ ' <div class="fs-modal-dialog">'
|
52 |
+
+ ' <div class="fs-modal-header">'
|
53 |
+
+ ' <h4><?php echo esc_js( fs_text_x_inline( 'Start free trial', 'call to action', 'start-free-trial', $slug ) ) ?></h4>'
|
54 |
+
+ ' </div>'
|
55 |
+
+ ' <div class="fs-modal-body">' + modalContentHtml + '</div>'
|
56 |
+
+ ' <div class="fs-modal-footer">'
|
57 |
+
+ ' <button class="button button-secondary button-close">' + <?php fs_json_encode_echo_inline( 'Cancel', 'cancel', $slug ) ?> +'</button>'
|
58 |
+
+ ' <button class="button button-primary button-connect">' + <?php fs_json_encode_echo_inline( 'Approve & Start Trial', 'approve-start-trial', $slug ) ?> +'</button>'
|
59 |
+
+ ' </div>'
|
60 |
+
+ ' </div>'
|
61 |
+
+ '</div>',
|
62 |
+
$modal = $( modalHtml ),
|
63 |
+
trialData;
|
64 |
+
|
65 |
+
$modal.appendTo($('body'));
|
66 |
+
|
67 |
+
var $errorNotice = $modal.find('.notice-error');
|
68 |
+
|
69 |
+
registerEventHandlers();
|
70 |
+
|
71 |
+
function registerEventHandlers() {
|
72 |
+
$modal.on('click', '.button-close', function () {
|
73 |
+
closeModal();
|
74 |
+
return false;
|
75 |
+
});
|
76 |
+
|
77 |
+
$modal.on('click', '.button-connect', function (evt) {
|
78 |
+
evt.preventDefault();
|
79 |
+
|
80 |
+
var $button = $(this);
|
81 |
+
|
82 |
+
$.ajax({
|
83 |
+
url : ajaxurl,
|
84 |
+
method : 'POST',
|
85 |
+
data : {
|
86 |
+
action : '<?php echo $fs->get_ajax_action( 'start_trial' ) ?>',
|
87 |
+
security : '<?php echo $fs->get_ajax_security( 'start_trial' ) ?>',
|
88 |
+
module_id: '<?php echo $fs->get_id() ?>',
|
89 |
+
trial : trialData
|
90 |
+
},
|
91 |
+
beforeSend: function () {
|
92 |
+
// Disable all buttons during trial activation.
|
93 |
+
$modal.find('.button').prop('disabled', true);
|
94 |
+
|
95 |
+
$button.text(<?php fs_json_encode_echo_inline( 'Starting trial', 'starting-trial', $slug ) ?> + '...');
|
96 |
+
|
97 |
+
setLoadingMode();
|
98 |
+
},
|
99 |
+
success : function (resultObj) {
|
100 |
+
if (resultObj.success) {
|
101 |
+
$button.text(<?php fs_json_encode_echo_inline( 'Please wait', 'please-wait', $slug ) ?> + '...');
|
102 |
+
|
103 |
+
// Redirect to the "Account" page and sync the license.
|
104 |
+
window.location.href = resultObj.data.next_page;
|
105 |
+
} else {
|
106 |
+
$button.text(<?php fs_json_encode_echo( 'approve-start-trial', $slug ) ?>);
|
107 |
+
|
108 |
+
resetLoadingMode();
|
109 |
+
showError(resultObj.error);
|
110 |
+
}
|
111 |
+
}
|
112 |
+
});
|
113 |
+
});
|
114 |
+
}
|
115 |
+
|
116 |
+
window.openTrialConfirmationModal = function showModal(data) {
|
117 |
+
resetModal();
|
118 |
+
|
119 |
+
// Display the dialog box.
|
120 |
+
$modal.addClass('active');
|
121 |
+
|
122 |
+
trialData = data;
|
123 |
+
|
124 |
+
var $modalBody = $modal.find('.fs-modal-body'),
|
125 |
+
$var;
|
126 |
+
|
127 |
+
for (var key in data) {
|
128 |
+
if (data.hasOwnProperty(key)) {
|
129 |
+
$var = $modalBody.find('.var-' + key);
|
130 |
+
|
131 |
+
if ($var.length > 0)
|
132 |
+
$var.html(data[key]);
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
$('body').addClass('has-fs-modal');
|
137 |
+
};
|
138 |
+
|
139 |
+
function closeModal() {
|
140 |
+
$modal.removeClass('active');
|
141 |
+
|
142 |
+
$('body').removeClass('has-fs-modal');
|
143 |
+
}
|
144 |
+
|
145 |
+
function resetModal() {
|
146 |
+
hideError();
|
147 |
+
}
|
148 |
+
|
149 |
+
function hideError() {
|
150 |
+
$errorNotice.hide();
|
151 |
+
}
|
152 |
+
|
153 |
+
function setLoadingMode() {
|
154 |
+
$modal.find('.button')
|
155 |
+
// Re-enable all buttons.
|
156 |
+
.prop('disabled', trialData)
|
157 |
+
// Stop loading cursor.
|
158 |
+
.css({'cursor': 'wait'});
|
159 |
+
|
160 |
+
// Stop loading cursor.
|
161 |
+
$(document.body).css({'cursor': 'wait'});
|
162 |
+
}
|
163 |
+
|
164 |
+
function resetLoadingMode() {
|
165 |
+
$modal.find('.button')
|
166 |
+
// Re-enable all buttons.
|
167 |
+
.prop('disabled', false)
|
168 |
+
// Stop loading cursor.
|
169 |
+
.css({'cursor': 'initial'});
|
170 |
+
|
171 |
+
// Stop loading cursor.
|
172 |
+
$(document.body).css({'cursor': 'initial'});
|
173 |
+
}
|
174 |
+
|
175 |
+
function showError(msg) {
|
176 |
+
$errorNotice.find(' > p').html(msg);
|
177 |
+
$errorNotice.show();
|
178 |
+
}
|
179 |
+
});
|
180 |
+
})(jQuery);
|
181 |
+
</script>
|
freemius/templates/js/style-premium-theme.php
CHANGED
@@ -1,45 +1,45 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.2.2.7
|
7 |
-
*
|
8 |
-
*/
|
9 |
-
|
10 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
11 |
-
exit;
|
12 |
-
}
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @var array $VARS
|
16 |
-
* @var Freemius $fs
|
17 |
-
*/
|
18 |
-
$fs = freemius( $VARS['id'] );
|
19 |
-
|
20 |
-
$slug = $fs->get_slug();
|
21 |
-
|
22 |
-
?>
|
23 |
-
<script type="text/javascript">
|
24 |
-
(function ($) {
|
25 |
-
// Select the premium theme version.
|
26 |
-
var $theme = $('#<?php echo $slug ?>-premium-name').parents('.theme'),
|
27 |
-
addPremiumMetadata = function (firstCall) {
|
28 |
-
if (!firstCall) {
|
29 |
-
// Seems like the original theme element is removed from the DOM,
|
30 |
-
// so we need to reselect the updated one.
|
31 |
-
$theme = $('#<?php echo $slug ?>-premium-name').parents('.theme');
|
32 |
-
}
|
33 |
-
|
34 |
-
if (0 === $theme.find('.fs-premium-theme-badge').length) {
|
35 |
-
$theme.addClass('fs-premium');
|
36 |
-
|
37 |
-
$theme.append('<span class="fs-premium-theme-badge">' + <?php echo json_encode( $fs->get_text_inline( 'Premium', 'premium' ) ) ?> +'</span>');
|
38 |
-
}
|
39 |
-
};
|
40 |
-
|
41 |
-
addPremiumMetadata(true);
|
42 |
-
|
43 |
-
$theme.contentChange(addPremiumMetadata);
|
44 |
-
})(jQuery);
|
45 |
</script>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.2.2.7
|
7 |
+
*
|
8 |
+
*/
|
9 |
+
|
10 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
11 |
+
exit;
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @var array $VARS
|
16 |
+
* @var Freemius $fs
|
17 |
+
*/
|
18 |
+
$fs = freemius( $VARS['id'] );
|
19 |
+
|
20 |
+
$slug = $fs->get_slug();
|
21 |
+
|
22 |
+
?>
|
23 |
+
<script type="text/javascript">
|
24 |
+
(function ($) {
|
25 |
+
// Select the premium theme version.
|
26 |
+
var $theme = $('#<?php echo $slug ?>-premium-name').parents('.theme'),
|
27 |
+
addPremiumMetadata = function (firstCall) {
|
28 |
+
if (!firstCall) {
|
29 |
+
// Seems like the original theme element is removed from the DOM,
|
30 |
+
// so we need to reselect the updated one.
|
31 |
+
$theme = $('#<?php echo $slug ?>-premium-name').parents('.theme');
|
32 |
+
}
|
33 |
+
|
34 |
+
if (0 === $theme.find('.fs-premium-theme-badge').length) {
|
35 |
+
$theme.addClass('fs-premium');
|
36 |
+
|
37 |
+
$theme.append('<span class="fs-premium-theme-badge">' + <?php echo json_encode( $fs->get_text_inline( 'Premium', 'premium' ) ) ?> +'</span>');
|
38 |
+
}
|
39 |
+
};
|
40 |
+
|
41 |
+
addPremiumMetadata(true);
|
42 |
+
|
43 |
+
$theme.contentChange(addPremiumMetadata);
|
44 |
+
})(jQuery);
|
45 |
</script>
|
freemius/templates/plugin-icon.php
CHANGED
@@ -1,130 +1,130 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.1.4
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
$fs = freemius( $VARS['id'] );
|
14 |
-
$slug = $fs->get_slug();
|
15 |
-
|
16 |
-
/**
|
17 |
-
* @since 1.1.7.5
|
18 |
-
*/
|
19 |
-
$local_path = $fs->apply_filters( 'plugin_icon', false );
|
20 |
-
|
21 |
-
if ( is_string( $local_path ) ) {
|
22 |
-
$icons = array( $local_path );
|
23 |
-
} else {
|
24 |
-
global $fs_active_plugins;
|
25 |
-
|
26 |
-
$img_dir = WP_FS__DIR_IMG;
|
27 |
-
|
28 |
-
if ( 1 < count( $fs_active_plugins->plugins ) ) {
|
29 |
-
$plugin_or_theme_img_dir = ( $fs->is_plugin() ? WP_PLUGIN_DIR : get_theme_root() );
|
30 |
-
|
31 |
-
foreach ( $fs_active_plugins->plugins as $sdk_path => &$data ) {
|
32 |
-
if ( $data->plugin_path == $fs->get_plugin_basename() ) {
|
33 |
-
$img_dir = $plugin_or_theme_img_dir
|
34 |
-
. '/'
|
35 |
-
. str_replace( '../themes/', '', $sdk_path )
|
36 |
-
. '/assets/img';
|
37 |
-
|
38 |
-
break;
|
39 |
-
}
|
40 |
-
}
|
41 |
-
}
|
42 |
-
|
43 |
-
if ( $fs->is_theme() ) {
|
44 |
-
$icons = array(
|
45 |
-
fs_normalize_path( $img_dir . '/theme-icon.png' )
|
46 |
-
);
|
47 |
-
} else {
|
48 |
-
$icons = glob( fs_normalize_path( $img_dir . '/' . $slug . '.*' ) );
|
49 |
-
if ( ! is_array( $icons ) || 0 === count( $icons ) ) {
|
50 |
-
$icon_found = false;
|
51 |
-
$local_path = fs_normalize_path( $img_dir . '/' . $slug . '.png' );
|
52 |
-
|
53 |
-
$have_write_permissions = ( 'direct' === get_filesystem_method( array(), fs_normalize_path( $img_dir ) ) );
|
54 |
-
|
55 |
-
if ( WP_FS__IS_LOCALHOST && $fs->is_org_repo_compliant() && $have_write_permissions ) {
|
56 |
-
/**
|
57 |
-
* IMPORTANT: THIS CODE WILL NEVER RUN AFTER THE PLUGIN IS IN THE REPO.
|
58 |
-
*
|
59 |
-
* This code will only be executed once during the testing
|
60 |
-
* of the plugin in a local environment. The plugin icon file WILL
|
61 |
-
* already exist in the assets folder when the plugin is deployed to
|
62 |
-
* the repository.
|
63 |
-
*/
|
64 |
-
if ( ! function_exists( 'plugins_api' ) ) {
|
65 |
-
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
|
66 |
-
}
|
67 |
-
|
68 |
-
$plugin_information = plugins_api( 'plugin_information', array(
|
69 |
-
'slug' => $slug,
|
70 |
-
'fields' => array(
|
71 |
-
'sections' => false,
|
72 |
-
'tags' => false,
|
73 |
-
'icons' => true
|
74 |
-
)
|
75 |
-
) );
|
76 |
-
|
77 |
-
if (
|
78 |
-
! is_wp_error( $plugin_information )
|
79 |
-
&& isset( $plugin_information->icons )
|
80 |
-
&& ! empty( $plugin_information->icons )
|
81 |
-
) {
|
82 |
-
/**
|
83 |
-
* Get the smallest icon.
|
84 |
-
*
|
85 |
-
* @author Leo Fajardo (@leorw)
|
86 |
-
* @since 1.2.2
|
87 |
-
*/
|
88 |
-
$icon = end( $plugin_information->icons );
|
89 |
-
|
90 |
-
if ( 0 !== strpos( $icon, 'http' ) ) {
|
91 |
-
$icon = 'http:' . $icon;
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* Get a clean file extension, e.g.: "jpg" and not "jpg?rev=1305765".
|
96 |
-
*
|
97 |
-
* @author Leo Fajardo (@leorw)
|
98 |
-
* @since 1.2.2
|
99 |
-
*/
|
100 |
-
$ext = pathinfo( strtok( $icon, '?' ), PATHINFO_EXTENSION );
|
101 |
-
|
102 |
-
$local_path = fs_normalize_path( $img_dir . '/' . $slug . '.' . $ext );
|
103 |
-
|
104 |
-
// Try to download the icon.
|
105 |
-
$icon_found = fs_download_image( $icon, $local_path );
|
106 |
-
}
|
107 |
-
}
|
108 |
-
|
109 |
-
if ( ! $icon_found ) {
|
110 |
-
// No icons found, fallback to default icon.
|
111 |
-
if ( $have_write_permissions ) {
|
112 |
-
// If have write permissions, copy default icon.
|
113 |
-
copy( fs_normalize_path( $img_dir . '/plugin-icon.png' ), $local_path );
|
114 |
-
} else {
|
115 |
-
// If doesn't have write permissions, use default icon path.
|
116 |
-
$local_path = fs_normalize_path( $img_dir . '/plugin-icon.png' );
|
117 |
-
}
|
118 |
-
}
|
119 |
-
|
120 |
-
$icons = array( $local_path );
|
121 |
-
}
|
122 |
-
}
|
123 |
-
}
|
124 |
-
|
125 |
-
$icon_dir = dirname( $icons[0] );
|
126 |
-
$relative_url = fs_img_url( substr( $icons[0], strlen( $icon_dir ) ), $icon_dir );
|
127 |
-
?>
|
128 |
-
<div class="fs-plugin-icon">
|
129 |
-
<img src="<?php echo $relative_url ?>" width="80" height="80"/>
|
130 |
</div>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.1.4
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
$fs = freemius( $VARS['id'] );
|
14 |
+
$slug = $fs->get_slug();
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @since 1.1.7.5
|
18 |
+
*/
|
19 |
+
$local_path = $fs->apply_filters( 'plugin_icon', false );
|
20 |
+
|
21 |
+
if ( is_string( $local_path ) ) {
|
22 |
+
$icons = array( $local_path );
|
23 |
+
} else {
|
24 |
+
global $fs_active_plugins;
|
25 |
+
|
26 |
+
$img_dir = WP_FS__DIR_IMG;
|
27 |
+
|
28 |
+
if ( 1 < count( $fs_active_plugins->plugins ) ) {
|
29 |
+
$plugin_or_theme_img_dir = ( $fs->is_plugin() ? WP_PLUGIN_DIR : get_theme_root() );
|
30 |
+
|
31 |
+
foreach ( $fs_active_plugins->plugins as $sdk_path => &$data ) {
|
32 |
+
if ( $data->plugin_path == $fs->get_plugin_basename() ) {
|
33 |
+
$img_dir = $plugin_or_theme_img_dir
|
34 |
+
. '/'
|
35 |
+
. str_replace( '../themes/', '', $sdk_path )
|
36 |
+
. '/assets/img';
|
37 |
+
|
38 |
+
break;
|
39 |
+
}
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
if ( $fs->is_theme() ) {
|
44 |
+
$icons = array(
|
45 |
+
fs_normalize_path( $img_dir . '/theme-icon.png' )
|
46 |
+
);
|
47 |
+
} else {
|
48 |
+
$icons = glob( fs_normalize_path( $img_dir . '/' . $slug . '.*' ) );
|
49 |
+
if ( ! is_array( $icons ) || 0 === count( $icons ) ) {
|
50 |
+
$icon_found = false;
|
51 |
+
$local_path = fs_normalize_path( $img_dir . '/' . $slug . '.png' );
|
52 |
+
|
53 |
+
$have_write_permissions = ( 'direct' === get_filesystem_method( array(), fs_normalize_path( $img_dir ) ) );
|
54 |
+
|
55 |
+
if ( WP_FS__IS_LOCALHOST && $fs->is_org_repo_compliant() && $have_write_permissions ) {
|
56 |
+
/**
|
57 |
+
* IMPORTANT: THIS CODE WILL NEVER RUN AFTER THE PLUGIN IS IN THE REPO.
|
58 |
+
*
|
59 |
+
* This code will only be executed once during the testing
|
60 |
+
* of the plugin in a local environment. The plugin icon file WILL
|
61 |
+
* already exist in the assets folder when the plugin is deployed to
|
62 |
+
* the repository.
|
63 |
+
*/
|
64 |
+
if ( ! function_exists( 'plugins_api' ) ) {
|
65 |
+
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
|
66 |
+
}
|
67 |
+
|
68 |
+
$plugin_information = plugins_api( 'plugin_information', array(
|
69 |
+
'slug' => $slug,
|
70 |
+
'fields' => array(
|
71 |
+
'sections' => false,
|
72 |
+
'tags' => false,
|
73 |
+
'icons' => true
|
74 |
+
)
|
75 |
+
) );
|
76 |
+
|
77 |
+
if (
|
78 |
+
! is_wp_error( $plugin_information )
|
79 |
+
&& isset( $plugin_information->icons )
|
80 |
+
&& ! empty( $plugin_information->icons )
|
81 |
+
) {
|
82 |
+
/**
|
83 |
+
* Get the smallest icon.
|
84 |
+
*
|
85 |
+
* @author Leo Fajardo (@leorw)
|
86 |
+
* @since 1.2.2
|
87 |
+
*/
|
88 |
+
$icon = end( $plugin_information->icons );
|
89 |
+
|
90 |
+
if ( 0 !== strpos( $icon, 'http' ) ) {
|
91 |
+
$icon = 'http:' . $icon;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Get a clean file extension, e.g.: "jpg" and not "jpg?rev=1305765".
|
96 |
+
*
|
97 |
+
* @author Leo Fajardo (@leorw)
|
98 |
+
* @since 1.2.2
|
99 |
+
*/
|
100 |
+
$ext = pathinfo( strtok( $icon, '?' ), PATHINFO_EXTENSION );
|
101 |
+
|
102 |
+
$local_path = fs_normalize_path( $img_dir . '/' . $slug . '.' . $ext );
|
103 |
+
|
104 |
+
// Try to download the icon.
|
105 |
+
$icon_found = fs_download_image( $icon, $local_path );
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
if ( ! $icon_found ) {
|
110 |
+
// No icons found, fallback to default icon.
|
111 |
+
if ( $have_write_permissions ) {
|
112 |
+
// If have write permissions, copy default icon.
|
113 |
+
copy( fs_normalize_path( $img_dir . '/plugin-icon.png' ), $local_path );
|
114 |
+
} else {
|
115 |
+
// If doesn't have write permissions, use default icon path.
|
116 |
+
$local_path = fs_normalize_path( $img_dir . '/plugin-icon.png' );
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
$icons = array( $local_path );
|
121 |
+
}
|
122 |
+
}
|
123 |
+
}
|
124 |
+
|
125 |
+
$icon_dir = dirname( $icons[0] );
|
126 |
+
$relative_url = fs_img_url( substr( $icons[0], strlen( $icon_dir ) ), $icon_dir );
|
127 |
+
?>
|
128 |
+
<div class="fs-plugin-icon">
|
129 |
+
<img src="<?php echo $relative_url ?>" width="80" height="80"/>
|
130 |
</div>
|
freemius/templates/plugin-info/description.php
CHANGED
@@ -1,78 +1,78 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.6
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array $VARS
|
15 |
-
*
|
16 |
-
* @var FS_Plugin $plugin
|
17 |
-
*/
|
18 |
-
$plugin = $VARS['plugin'];
|
19 |
-
|
20 |
-
if ( ! empty( $plugin->info->selling_point_0 ) ||
|
21 |
-
! empty( $plugin->info->selling_point_1 ) ||
|
22 |
-
! empty( $plugin->info->selling_point_2 )
|
23 |
-
) : ?>
|
24 |
-
<div class="fs-selling-points">
|
25 |
-
<ul>
|
26 |
-
<?php for ( $i = 0; $i < 3; $i ++ ) : ?>
|
27 |
-
<?php if ( ! empty( $plugin->info->{'selling_point_' . $i} ) ) : ?>
|
28 |
-
<li><i class="dashicons dashicons-yes"></i>
|
29 |
-
|
30 |
-
<h3><?php echo esc_html( $plugin->info->{'selling_point_' . $i} ) ?></h3></li>
|
31 |
-
<?php endif ?>
|
32 |
-
<?php endfor ?>
|
33 |
-
</ul>
|
34 |
-
</div>
|
35 |
-
<?php endif ?>
|
36 |
-
<div>
|
37 |
-
<?php
|
38 |
-
echo wp_kses( $plugin->info->description, array(
|
39 |
-
'a' => array( 'href' => array(), 'title' => array(), 'target' => array() ),
|
40 |
-
'b' => array(),
|
41 |
-
'i' => array(),
|
42 |
-
'p' => array(),
|
43 |
-
'blockquote' => array(),
|
44 |
-
'h2' => array(),
|
45 |
-
'h3' => array(),
|
46 |
-
'ul' => array(),
|
47 |
-
'ol' => array(),
|
48 |
-
'li' => array()
|
49 |
-
) );
|
50 |
-
?>
|
51 |
-
</div>
|
52 |
-
<?php if ( ! empty( $plugin->info->screenshots ) ) : ?>
|
53 |
-
<?php $screenshots = $plugin->info->screenshots ?>
|
54 |
-
<div class="fs-screenshots clearfix">
|
55 |
-
<h2><?php fs_esc_html_echo_inline( 'Screenshots', 'screenshots', $plugin->slug ) ?></h2>
|
56 |
-
<ul>
|
57 |
-
<?php $i = 0;
|
58 |
-
foreach ( $screenshots as $s => $url ) : ?>
|
59 |
-
<?php
|
60 |
-
// Relative URLs are replaced with WordPress.org base URL
|
61 |
-
// therefore we need to set absolute URLs.
|
62 |
-
$url = 'http' . ( WP_FS__IS_HTTPS ? 's' : '' ) . ':' . $url;
|
63 |
-
?>
|
64 |
-
<li class="<?php echo ( 0 === $i % 2 ) ? 'odd' : 'even' ?>">
|
65 |
-
<style>
|
66 |
-
#section-description .fs-screenshots <?php echo ".fs-screenshot-{$i}" ?>
|
67 |
-
{
|
68 |
-
background-image: url('<?php echo $url ?>');
|
69 |
-
}
|
70 |
-
</style>
|
71 |
-
<a href="<?php echo $url ?>"
|
72 |
-
title="<?php echo esc_attr( sprintf( fs_text_inline( 'Click to view full-size screenshot %d', 'view-full-size-x', $plugin->slug ), $i ) ) ?>"
|
73 |
-
class="fs-screenshot-<?php echo $i ?>"></a>
|
74 |
-
</li>
|
75 |
-
<?php $i ++; endforeach ?>
|
76 |
-
</ul>
|
77 |
-
</div>
|
78 |
<?php endif ?>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.6
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
*
|
16 |
+
* @var FS_Plugin $plugin
|
17 |
+
*/
|
18 |
+
$plugin = $VARS['plugin'];
|
19 |
+
|
20 |
+
if ( ! empty( $plugin->info->selling_point_0 ) ||
|
21 |
+
! empty( $plugin->info->selling_point_1 ) ||
|
22 |
+
! empty( $plugin->info->selling_point_2 )
|
23 |
+
) : ?>
|
24 |
+
<div class="fs-selling-points">
|
25 |
+
<ul>
|
26 |
+
<?php for ( $i = 0; $i < 3; $i ++ ) : ?>
|
27 |
+
<?php if ( ! empty( $plugin->info->{'selling_point_' . $i} ) ) : ?>
|
28 |
+
<li><i class="dashicons dashicons-yes"></i>
|
29 |
+
|
30 |
+
<h3><?php echo esc_html( $plugin->info->{'selling_point_' . $i} ) ?></h3></li>
|
31 |
+
<?php endif ?>
|
32 |
+
<?php endfor ?>
|
33 |
+
</ul>
|
34 |
+
</div>
|
35 |
+
<?php endif ?>
|
36 |
+
<div>
|
37 |
+
<?php
|
38 |
+
echo wp_kses( $plugin->info->description, array(
|
39 |
+
'a' => array( 'href' => array(), 'title' => array(), 'target' => array() ),
|
40 |
+
'b' => array(),
|
41 |
+
'i' => array(),
|
42 |
+
'p' => array(),
|
43 |
+
'blockquote' => array(),
|
44 |
+
'h2' => array(),
|
45 |
+
'h3' => array(),
|
46 |
+
'ul' => array(),
|
47 |
+
'ol' => array(),
|
48 |
+
'li' => array()
|
49 |
+
) );
|
50 |
+
?>
|
51 |
+
</div>
|
52 |
+
<?php if ( ! empty( $plugin->info->screenshots ) ) : ?>
|
53 |
+
<?php $screenshots = $plugin->info->screenshots ?>
|
54 |
+
<div class="fs-screenshots clearfix">
|
55 |
+
<h2><?php fs_esc_html_echo_inline( 'Screenshots', 'screenshots', $plugin->slug ) ?></h2>
|
56 |
+
<ul>
|
57 |
+
<?php $i = 0;
|
58 |
+
foreach ( $screenshots as $s => $url ) : ?>
|
59 |
+
<?php
|
60 |
+
// Relative URLs are replaced with WordPress.org base URL
|
61 |
+
// therefore we need to set absolute URLs.
|
62 |
+
$url = 'http' . ( WP_FS__IS_HTTPS ? 's' : '' ) . ':' . $url;
|
63 |
+
?>
|
64 |
+
<li class="<?php echo ( 0 === $i % 2 ) ? 'odd' : 'even' ?>">
|
65 |
+
<style>
|
66 |
+
#section-description .fs-screenshots <?php echo ".fs-screenshot-{$i}" ?>
|
67 |
+
{
|
68 |
+
background-image: url('<?php echo $url ?>');
|
69 |
+
}
|
70 |
+
</style>
|
71 |
+
<a href="<?php echo $url ?>"
|
72 |
+
title="<?php echo esc_attr( sprintf( fs_text_inline( 'Click to view full-size screenshot %d', 'view-full-size-x', $plugin->slug ), $i ) ) ?>"
|
73 |
+
class="fs-screenshot-<?php echo $i ?>"></a>
|
74 |
+
</li>
|
75 |
+
<?php $i ++; endforeach ?>
|
76 |
+
</ul>
|
77 |
+
</div>
|
78 |
<?php endif ?>
|
freemius/templates/plugin-info/features.php
CHANGED
@@ -1,114 +1,114 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.6
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array $VARS
|
15 |
-
*
|
16 |
-
* @var FS_Plugin $plugin
|
17 |
-
*/
|
18 |
-
$plugin = $VARS['plugin'];
|
19 |
-
|
20 |
-
$plans = $VARS['plans'];
|
21 |
-
|
22 |
-
$features_plan_map = array();
|
23 |
-
foreach ( $plans as $plan ) {
|
24 |
-
if (!empty($plan->features) && is_array($plan->features)) {
|
25 |
-
foreach ( $plan->features as $feature ) {
|
26 |
-
if ( ! isset( $features_plan_map[ $feature->id ] ) ) {
|
27 |
-
$features_plan_map[ $feature->id ] = array( 'feature' => $feature, 'plans' => array() );
|
28 |
-
}
|
29 |
-
|
30 |
-
$features_plan_map[ $feature->id ]['plans'][ $plan->id ] = $feature;
|
31 |
-
}
|
32 |
-
}
|
33 |
-
|
34 |
-
// Add support as a feature.
|
35 |
-
if ( ! empty( $plan->support_email ) ||
|
36 |
-
! empty( $plan->support_skype ) ||
|
37 |
-
! empty( $plan->support_phone ) ||
|
38 |
-
true === $plan->is_success_manager
|
39 |
-
) {
|
40 |
-
if ( ! isset( $features_plan_map['support'] ) ) {
|
41 |
-
$support_feature = new stdClass();
|
42 |
-
$support_feature->id = 'support';
|
43 |
-
$support_feature->title = fs_text_inline( 'Support', $plugin->slug );
|
44 |
-
$features_plan_map[ $support_feature->id ] = array( 'feature' => $support_feature, 'plans' => array() );
|
45 |
-
} else {
|
46 |
-
$support_feature = $features_plan_map['support'];
|
47 |
-
}
|
48 |
-
|
49 |
-
$features_plan_map[ $support_feature->id ]['plans'][ $plan->id ] = $support_feature;
|
50 |
-
}
|
51 |
-
}
|
52 |
-
|
53 |
-
// Add updates as a feature for all plans.
|
54 |
-
$updates_feature = new stdClass();
|
55 |
-
$updates_feature->id = 'updates';
|
56 |
-
$updates_feature->title = fs_text_inline( 'Unlimited Updates', 'unlimited-updates', $plugin->slug );
|
57 |
-
$features_plan_map[ $updates_feature->id ] = array( 'feature' => $updates_feature, 'plans' => array() );
|
58 |
-
foreach ( $plans as $plan ) {
|
59 |
-
$features_plan_map[ $updates_feature->id ]['plans'][ $plan->id ] = $updates_feature;
|
60 |
-
}
|
61 |
-
?>
|
62 |
-
<div class="fs-features">
|
63 |
-
<table>
|
64 |
-
<thead>
|
65 |
-
<tr>
|
66 |
-
<th></th>
|
67 |
-
<?php foreach ( $plans as $plan ) : ?>
|
68 |
-
<th>
|
69 |
-
<?php echo $plan->title ?>
|
70 |
-
<span class="fs-price"><?php
|
71 |
-
if ( empty( $plan->pricing ) ) {
|
72 |
-
fs_esc_html_echo_inline( 'Free', 'free', $plugin->slug );
|
73 |
-
} else {
|
74 |
-
foreach ( $plan->pricing as $pricing ) {
|
75 |
-
/**
|
76 |
-
* @var FS_Pricing $pricing
|
77 |
-
*/
|
78 |
-
if ( 1 == $pricing->licenses ) {
|
79 |
-
if ( $pricing->has_annual() ) {
|
80 |
-
echo "\${$pricing->annual_price} / " . fs_esc_html_x_inline( 'year', 'as annual period', 'year', $plugin->slug );
|
81 |
-
} else if ( $pricing->has_monthly() ) {
|
82 |
-
echo "\${$pricing->monthly_price} / " . fs_esc_html_x_inline( 'mo', 'as monthly period', 'mo', $plugin->slug );
|
83 |
-
} else {
|
84 |
-
echo "\${$pricing->lifetime_price}";
|
85 |
-
}
|
86 |
-
}
|
87 |
-
}
|
88 |
-
}
|
89 |
-
?></span>
|
90 |
-
</th>
|
91 |
-
<?php endforeach ?>
|
92 |
-
</tr>
|
93 |
-
</thead>
|
94 |
-
<tbody>
|
95 |
-
<?php $odd = true;
|
96 |
-
foreach ( $features_plan_map as $feature_id => $data ) : ?>
|
97 |
-
<tr class="fs-<?php echo $odd ? 'odd' : 'even' ?>">
|
98 |
-
<td><?php echo esc_html( ucfirst( $data['feature']->title ) ) ?></td>
|
99 |
-
<?php foreach ( $plans as $plan ) : ?>
|
100 |
-
<td>
|
101 |
-
<?php if ( isset( $data['plans'][ $plan->id ] ) ) : ?>
|
102 |
-
<?php if ( ! empty( $data['plans'][ $plan->id ]->value ) ) : ?>
|
103 |
-
<b><?php echo esc_html( $data['plans'][ $plan->id ]->value ) ?></b>
|
104 |
-
<?php else : ?>
|
105 |
-
<i class="dashicons dashicons-yes"></i>
|
106 |
-
<?php endif ?>
|
107 |
-
<?php endif ?>
|
108 |
-
</td>
|
109 |
-
<?php endforeach ?>
|
110 |
-
</tr>
|
111 |
-
<?php $odd = ! $odd; endforeach ?>
|
112 |
-
</tbody>
|
113 |
-
</table>
|
114 |
</div>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.6
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
*
|
16 |
+
* @var FS_Plugin $plugin
|
17 |
+
*/
|
18 |
+
$plugin = $VARS['plugin'];
|
19 |
+
|
20 |
+
$plans = $VARS['plans'];
|
21 |
+
|
22 |
+
$features_plan_map = array();
|
23 |
+
foreach ( $plans as $plan ) {
|
24 |
+
if (!empty($plan->features) && is_array($plan->features)) {
|
25 |
+
foreach ( $plan->features as $feature ) {
|
26 |
+
if ( ! isset( $features_plan_map[ $feature->id ] ) ) {
|
27 |
+
$features_plan_map[ $feature->id ] = array( 'feature' => $feature, 'plans' => array() );
|
28 |
+
}
|
29 |
+
|
30 |
+
$features_plan_map[ $feature->id ]['plans'][ $plan->id ] = $feature;
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
// Add support as a feature.
|
35 |
+
if ( ! empty( $plan->support_email ) ||
|
36 |
+
! empty( $plan->support_skype ) ||
|
37 |
+
! empty( $plan->support_phone ) ||
|
38 |
+
true === $plan->is_success_manager
|
39 |
+
) {
|
40 |
+
if ( ! isset( $features_plan_map['support'] ) ) {
|
41 |
+
$support_feature = new stdClass();
|
42 |
+
$support_feature->id = 'support';
|
43 |
+
$support_feature->title = fs_text_inline( 'Support', $plugin->slug );
|
44 |
+
$features_plan_map[ $support_feature->id ] = array( 'feature' => $support_feature, 'plans' => array() );
|
45 |
+
} else {
|
46 |
+
$support_feature = $features_plan_map['support'];
|
47 |
+
}
|
48 |
+
|
49 |
+
$features_plan_map[ $support_feature->id ]['plans'][ $plan->id ] = $support_feature;
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
// Add updates as a feature for all plans.
|
54 |
+
$updates_feature = new stdClass();
|
55 |
+
$updates_feature->id = 'updates';
|
56 |
+
$updates_feature->title = fs_text_inline( 'Unlimited Updates', 'unlimited-updates', $plugin->slug );
|
57 |
+
$features_plan_map[ $updates_feature->id ] = array( 'feature' => $updates_feature, 'plans' => array() );
|
58 |
+
foreach ( $plans as $plan ) {
|
59 |
+
$features_plan_map[ $updates_feature->id ]['plans'][ $plan->id ] = $updates_feature;
|
60 |
+
}
|
61 |
+
?>
|
62 |
+
<div class="fs-features">
|
63 |
+
<table>
|
64 |
+
<thead>
|
65 |
+
<tr>
|
66 |
+
<th></th>
|
67 |
+
<?php foreach ( $plans as $plan ) : ?>
|
68 |
+
<th>
|
69 |
+
<?php echo $plan->title ?>
|
70 |
+
<span class="fs-price"><?php
|
71 |
+
if ( empty( $plan->pricing ) ) {
|
72 |
+
fs_esc_html_echo_inline( 'Free', 'free', $plugin->slug );
|
73 |
+
} else {
|
74 |
+
foreach ( $plan->pricing as $pricing ) {
|
75 |
+
/**
|
76 |
+
* @var FS_Pricing $pricing
|
77 |
+
*/
|
78 |
+
if ( 1 == $pricing->licenses ) {
|
79 |
+
if ( $pricing->has_annual() ) {
|
80 |
+
echo "\${$pricing->annual_price} / " . fs_esc_html_x_inline( 'year', 'as annual period', 'year', $plugin->slug );
|
81 |
+
} else if ( $pricing->has_monthly() ) {
|
82 |
+
echo "\${$pricing->monthly_price} / " . fs_esc_html_x_inline( 'mo', 'as monthly period', 'mo', $plugin->slug );
|
83 |
+
} else {
|
84 |
+
echo "\${$pricing->lifetime_price}";
|
85 |
+
}
|
86 |
+
}
|
87 |
+
}
|
88 |
+
}
|
89 |
+
?></span>
|
90 |
+
</th>
|
91 |
+
<?php endforeach ?>
|
92 |
+
</tr>
|
93 |
+
</thead>
|
94 |
+
<tbody>
|
95 |
+
<?php $odd = true;
|
96 |
+
foreach ( $features_plan_map as $feature_id => $data ) : ?>
|
97 |
+
<tr class="fs-<?php echo $odd ? 'odd' : 'even' ?>">
|
98 |
+
<td><?php echo esc_html( ucfirst( $data['feature']->title ) ) ?></td>
|
99 |
+
<?php foreach ( $plans as $plan ) : ?>
|
100 |
+
<td>
|
101 |
+
<?php if ( isset( $data['plans'][ $plan->id ] ) ) : ?>
|
102 |
+
<?php if ( ! empty( $data['plans'][ $plan->id ]->value ) ) : ?>
|
103 |
+
<b><?php echo esc_html( $data['plans'][ $plan->id ]->value ) ?></b>
|
104 |
+
<?php else : ?>
|
105 |
+
<i class="dashicons dashicons-yes"></i>
|
106 |
+
<?php endif ?>
|
107 |
+
<?php endif ?>
|
108 |
+
</td>
|
109 |
+
<?php endforeach ?>
|
110 |
+
</tr>
|
111 |
+
<?php $odd = ! $odd; endforeach ?>
|
112 |
+
</tbody>
|
113 |
+
</table>
|
114 |
</div>
|
freemius/templates/plugin-info/screenshots.php
CHANGED
@@ -1,34 +1,34 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.0.6
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array $VARS
|
15 |
-
*
|
16 |
-
* @var FS_Plugin $plugin
|
17 |
-
*/
|
18 |
-
$plugin = $VARS['plugin'];
|
19 |
-
|
20 |
-
$screenshots = $VARS['screenshots'];
|
21 |
-
?>
|
22 |
-
<ol>
|
23 |
-
<?php $i = 0;
|
24 |
-
foreach ( $screenshots as $s => $url ) : ?>
|
25 |
-
<?php
|
26 |
-
// Relative URLs are replaced with WordPress.org base URL
|
27 |
-
// therefore we need to set absolute URLs.
|
28 |
-
$url = 'http' . ( WP_FS__IS_HTTPS ? 's' : '' ) . ':' . $url;
|
29 |
-
?>
|
30 |
-
<li>
|
31 |
-
<a href="<?php echo $url ?>" title="<?php echo esc_attr( sprintf( fs_text_inline( 'Click to view full-size screenshot %d', 'view-full-size-x', $plugin->slug ), $i ) ) ?>"><img src="<?php echo $url ?>"></a>
|
32 |
-
</li>
|
33 |
-
<?php $i ++; endforeach ?>
|
34 |
-
</ol>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.0.6
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array $VARS
|
15 |
+
*
|
16 |
+
* @var FS_Plugin $plugin
|
17 |
+
*/
|
18 |
+
$plugin = $VARS['plugin'];
|
19 |
+
|
20 |
+
$screenshots = $VARS['screenshots'];
|
21 |
+
?>
|
22 |
+
<ol>
|
23 |
+
<?php $i = 0;
|
24 |
+
foreach ( $screenshots as $s => $url ) : ?>
|
25 |
+
<?php
|
26 |
+
// Relative URLs are replaced with WordPress.org base URL
|
27 |
+
// therefore we need to set absolute URLs.
|
28 |
+
$url = 'http' . ( WP_FS__IS_HTTPS ? 's' : '' ) . ':' . $url;
|
29 |
+
?>
|
30 |
+
<li>
|
31 |
+
<a href="<?php echo $url ?>" title="<?php echo esc_attr( sprintf( fs_text_inline( 'Click to view full-size screenshot %d', 'view-full-size-x', $plugin->slug ), $i ) ) ?>"><img src="<?php echo $url ?>"></a>
|
32 |
+
</li>
|
33 |
+
<?php $i ++; endforeach ?>
|
34 |
+
</ol>
|
freemius/templates/secure-https-header.php
CHANGED
@@ -1,39 +1,39 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Freemius
|
4 |
-
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
-
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
-
* @since 1.2.1.8
|
7 |
-
*
|
8 |
-
* @var array $VARS
|
9 |
-
*/
|
10 |
-
|
11 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
-
exit;
|
13 |
-
}
|
14 |
-
?>
|
15 |
-
<div class="fs-secure-notice">
|
16 |
-
<i class="dashicons dashicons-lock"></i>
|
17 |
-
<span><?php
|
18 |
-
if ( ! empty( $VARS['message'] ) ) {
|
19 |
-
echo esc_html( $VARS['message'] );
|
20 |
-
} else {
|
21 |
-
/**
|
22 |
-
* @var Freemius $fs
|
23 |
-
*/
|
24 |
-
$fs = freemius( $VARS['id'] );
|
25 |
-
|
26 |
-
echo esc_html( sprintf(
|
27 |
-
/* translators: %s: Page name */
|
28 |
-
$fs->get_text_inline( 'Secure HTTPS %s page, running from an external domain', 'secure-x-page-header' ),
|
29 |
-
$VARS['page']
|
30 |
-
) ) .
|
31 |
-
' - ' .
|
32 |
-
sprintf(
|
33 |
-
'<a class="fs-security-proof" href="%s" target="_blank">%s</a>',
|
34 |
-
'https://www.mcafeesecure.com/verify?host=' . WP_FS__ROOT_DOMAIN_PRODUCTION,
|
35 |
-
'Freemius Inc. [US]'
|
36 |
-
);
|
37 |
-
}
|
38 |
-
?></span>
|
39 |
</div>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Freemius
|
4 |
+
* @copyright Copyright (c) 2015, Freemius, Inc.
|
5 |
+
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
|
6 |
+
* @since 1.2.1.8
|
7 |
+
*
|
8 |
+
* @var array $VARS
|
9 |
+
*/
|
10 |
+
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
?>
|
15 |
+
<div class="fs-secure-notice">
|
16 |
+
<i class="dashicons dashicons-lock"></i>
|
17 |
+
<span><?php
|
18 |
+
if ( ! empty( $VARS['message'] ) ) {
|
19 |
+
echo esc_html( $VARS['message'] );
|
20 |
+
} else {
|
21 |
+
/**
|
22 |
+
* @var Freemius $fs
|
23 |
+
*/
|
24 |
+
$fs = freemius( $VARS['id'] );
|
25 |
+
|
26 |
+
echo esc_html( sprintf(
|
27 |
+
/* translators: %s: Page name */
|
28 |
+
$fs->get_text_inline( 'Secure HTTPS %s page, running from an external domain', 'secure-x-page-header' ),
|
29 |
+
$VARS['page']
|
30 |
+
) ) .
|
31 |
+
' - ' .
|
32 |
+
sprintf(
|
33 |
+
'<a class="fs-security-proof" href="%s" target="_blank">%s</a>',
|
34 |
+
'https://www.mcafeesecure.com/verify?host=' . WP_FS__ROOT_DOMAIN_PRODUCTION,
|
35 |
+
'Freemius Inc. [US]'
|
36 |
+
);
|
37 |
+
}
|
38 |
+
?></span>
|
39 |
</div>
|
includes/admin/class-settings.php
CHANGED
@@ -281,6 +281,14 @@ if ( ! class_exists( 'FooGallery_Admin_Settings' ) ) {
|
|
281 |
'tab' => 'advanced'
|
282 |
);
|
283 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
$settings[] = array(
|
285 |
'id' => 'enable_debugging',
|
286 |
'title' => __( 'Enable Debugging', 'foogallery' ),
|
281 |
'tab' => 'advanced'
|
282 |
);
|
283 |
|
284 |
+
$settings[] = array(
|
285 |
+
'id' => 'enable_legacy_thumb_cropping',
|
286 |
+
'title' => __( 'Enable Legacy Thumb Cropping', 'foogallery' ),
|
287 |
+
'desc' => __( 'For when you want to enable legacy cropping options in certain gallery templates. This is not recommended.', 'foogallery' ),
|
288 |
+
'type' => 'checkbox',
|
289 |
+
'tab' => 'advanced'
|
290 |
+
);
|
291 |
+
|
292 |
$settings[] = array(
|
293 |
'id' => 'enable_debugging',
|
294 |
'title' => __( 'Enable Debugging', 'foogallery' ),
|
includes/class-thumbnail-dimensions.php
CHANGED
@@ -91,9 +91,21 @@ if ( ! class_exists( 'FooGallery_Thumbnail_Dimensions' ) ) {
|
|
91 |
$calculated_thumb_width = $thumb_width;
|
92 |
$calculated_thumb_height = $thumb_height;
|
93 |
} else {
|
94 |
-
$size_array = image_resize_dimensions($attachment->width, $attachment->height, $thumb_width, $thumb_height, $thumb_crop);
|
95 |
-
|
96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
}
|
98 |
|
99 |
$attachment->has_thumbnail_dimensions = true;
|
@@ -105,6 +117,45 @@ if ( ! class_exists( 'FooGallery_Thumbnail_Dimensions' ) ) {
|
|
105 |
}
|
106 |
}
|
107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
/**
|
109 |
* Include the thumb dimension html attributes in the rendered HTML
|
110 |
*
|
91 |
$calculated_thumb_width = $thumb_width;
|
92 |
$calculated_thumb_height = $thumb_height;
|
93 |
} else {
|
94 |
+
$size_array = image_resize_dimensions( $attachment->width, $attachment->height, $thumb_width, $thumb_height, $thumb_crop );
|
95 |
+
if ( false !== $size_array ) {
|
96 |
+
$calculated_thumb_width = $size_array[4];
|
97 |
+
$calculated_thumb_height = $size_array[5];
|
98 |
+
} else {
|
99 |
+
$size_array = $this->calculate_dimensions( $attachment->width, $attachment->height, $thumb_width, $thumb_height );
|
100 |
+
if ( false !== $size_array ) {
|
101 |
+
$calculated_thumb_width = $size_array[0];
|
102 |
+
$calculated_thumb_height = $size_array[1];
|
103 |
+
} else {
|
104 |
+
//fallback for when we cannot calculate dimensions. Use the originals
|
105 |
+
$calculated_thumb_width = $attachment->width;
|
106 |
+
$calculated_thumb_height = $attachment->height;
|
107 |
+
}
|
108 |
+
}
|
109 |
}
|
110 |
|
111 |
$attachment->has_thumbnail_dimensions = true;
|
117 |
}
|
118 |
}
|
119 |
|
120 |
+
/**
|
121 |
+
* Returns a resized width and height value given the original dimensions and then either the new width or height value, one can be 0.
|
122 |
+
*
|
123 |
+
* @param {int} $orig_width - The original width of the image.
|
124 |
+
* @param {int} $orig_height - The original height of the image.
|
125 |
+
* @param {int} $new_width - The new width for the image or 0 to calculate it from the supplied new height and original dimensions.
|
126 |
+
* @param {int} $new_height - The new height for the image or 0 to calculate it from the supplied new width and original dimensions.
|
127 |
+
*
|
128 |
+
* @return array|false - Returns an array with the width value at index 0 and the height value at index 1.
|
129 |
+
* Returns false if the original dimensions are invalid or if both the new width and height are invalid.
|
130 |
+
*
|
131 |
+
* @example
|
132 |
+
*
|
133 |
+
* $size_1 = calculate_dimensions(800, 600, 0, 300); // => [400, 300]
|
134 |
+
*
|
135 |
+
* $size_2 = calculate_dimensions(800, 600, 400, 0); // => [400, 300]
|
136 |
+
*/
|
137 |
+
function calculate_dimensions($orig_width, $orig_height, $new_width, $new_height){
|
138 |
+
// if we have an invalid original size provided exit early and return false
|
139 |
+
if (!is_numeric($orig_width) || $orig_width === 0 || !is_numeric($orig_height) || $orig_height === 0){
|
140 |
+
return false;
|
141 |
+
}
|
142 |
+
$needs_width = !is_numeric($new_width) || $new_width === 0;
|
143 |
+
$needs_height = !is_numeric($new_height) || $new_height === 0;
|
144 |
+
// if we have an invalid new size provided i.e. both new values are not numbers or both are 0 then exit early and return false
|
145 |
+
if ($needs_width && $needs_height){
|
146 |
+
return false;
|
147 |
+
}
|
148 |
+
// otherwise get the ratio of the original so we can calculate any missing new values
|
149 |
+
$ratio = $orig_width / $orig_height;
|
150 |
+
if ($needs_width){
|
151 |
+
$new_width = $new_height * $ratio;
|
152 |
+
}
|
153 |
+
if ($needs_height){
|
154 |
+
$new_height = $new_width / $ratio;
|
155 |
+
}
|
156 |
+
return array($new_width, $new_height);
|
157 |
+
}
|
158 |
+
|
159 |
/**
|
160 |
* Include the thumb dimension html attributes in the rendered HTML
|
161 |
*
|
includes/class-thumbnails.php
CHANGED
@@ -109,14 +109,31 @@ if ( !class_exists( 'FooGallery_Thumbnails' ) ) {
|
|
109 |
unset( $args['height'] );
|
110 |
}
|
111 |
|
112 |
-
//
|
113 |
-
|
114 |
-
|
115 |
-
|
|
|
|
|
|
|
116 |
|
117 |
return $foogallery_last_generated_thumb_url;
|
118 |
}
|
119 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
function run_thumbnail_generation_tests() {
|
121 |
$test_image_url = foogallery_test_thumb_url();
|
122 |
|
109 |
unset( $args['height'] );
|
110 |
}
|
111 |
|
112 |
+
//do some checks to see if the image is smaller
|
113 |
+
if ( $this->should_resize( $thumbnail_object, $args ) ) {
|
114 |
+
//save the generated thumb url to a global so that we can use it later if needed
|
115 |
+
$foogallery_last_generated_thumb_url = wpthumb( $original_image_src, $args );
|
116 |
+
} else {
|
117 |
+
$foogallery_last_generated_thumb_url = $original_image_src;
|
118 |
+
}
|
119 |
|
120 |
return $foogallery_last_generated_thumb_url;
|
121 |
}
|
122 |
|
123 |
+
function should_resize($thumbnail_object, $args) {
|
124 |
+
$original_width = $thumbnail_object->width;
|
125 |
+
$original_height = $thumbnail_object->height;
|
126 |
+
$new_width = isset( $args['width'] ) ? $args['width'] : 0;
|
127 |
+
$new_height = isset( $args['height'] ) ? $args['height'] : 0;
|
128 |
+
|
129 |
+
if ( $new_width > 0 && $new_height > 0 ) {
|
130 |
+
return $original_width > $new_width || $original_height > $new_height;
|
131 |
+
} else if ( $new_width > 0 ) {
|
132 |
+
return $original_width > $new_width;
|
133 |
+
}
|
134 |
+
return $original_height > $new_height;
|
135 |
+
}
|
136 |
+
|
137 |
function run_thumbnail_generation_tests() {
|
138 |
$test_image_url = foogallery_test_thumb_url();
|
139 |
|
includes/functions.php
CHANGED
@@ -629,7 +629,10 @@ function foogallery_caption_title_source() {
|
|
629 |
*/
|
630 |
function foogallery_get_caption_title_for_attachment($attachment_post, $source = false) {
|
631 |
if ( false === $source ) {
|
632 |
-
$source =
|
|
|
|
|
|
|
633 |
}
|
634 |
|
635 |
switch ( $source ) {
|
@@ -674,7 +677,10 @@ function foogallery_caption_desc_source() {
|
|
674 |
*/
|
675 |
function foogallery_get_caption_desc_for_attachment($attachment_post, $source = false) {
|
676 |
if ( false === $source ) {
|
677 |
-
$source =
|
|
|
|
|
|
|
678 |
}
|
679 |
|
680 |
switch ( $source ) {
|
629 |
*/
|
630 |
function foogallery_get_caption_title_for_attachment($attachment_post, $source = false) {
|
631 |
if ( false === $source ) {
|
632 |
+
$source = foogallery_gallery_template_setting( 'caption_title_source', false );
|
633 |
+
if ( false === $source || "none" === $source ) {
|
634 |
+
$source = foogallery_caption_title_source();
|
635 |
+
}
|
636 |
}
|
637 |
|
638 |
switch ( $source ) {
|
677 |
*/
|
678 |
function foogallery_get_caption_desc_for_attachment($attachment_post, $source = false) {
|
679 |
if ( false === $source ) {
|
680 |
+
$source = foogallery_gallery_template_setting( 'caption_desc_source', false );
|
681 |
+
if ( false === $source || "none" === $source ) {
|
682 |
+
$source = foogallery_caption_desc_source();
|
683 |
+
}
|
684 |
}
|
685 |
|
686 |
switch ( $source ) {
|
js/foogallery.admin.min.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
/*
|
2 |
* FooGallery - The Most Intuitive and Extensible Gallery Creation and Management Tool Ever Created for WordPress
|
3 |
-
* @version 1.0.
|
4 |
* @link
|
5 |
* @copyright Steven Usher & Brad Vincent 2015
|
6 |
* @license Released under the GPLv3 license.
|
1 |
/*
|
2 |
* FooGallery - The Most Intuitive and Extensible Gallery Creation and Management Tool Ever Created for WordPress
|
3 |
+
* @version 1.0.26
|
4 |
* @link
|
5 |
* @copyright Steven Usher & Brad Vincent 2015
|
6 |
* @license Released under the GPLv3 license.
|