diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..0498657 --- /dev/null +++ b/.babelrc @@ -0,0 +1,8 @@ +{ + "presets": [ + "@wordpress/default" + ], + "plugins": [ + "@babel/proposal-class-properties", + ] +} \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..8955d81 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,19 @@ +{ + "parser": "babel-eslint", + "extends": [ + "eslint:recommended", + "wordpress" + ], + "plugins": [], + "env": { + "jest": true, + "node": true, + "amd": true, + "es6": true + }, + "parserOptions": { + "ecmaFeatures": { + "jsx": true + } + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2e840e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,74 @@ +# Packages # +############ +*.7z +*.dmg +*.gz +*.bz2 +*.iso +*.jar +*.rar +*.tar +*.tgz +*.map + +# Logs and databases # +###################### +*.log +*.sql + +# OS generated files # +###################### +**.DS_Store* +ehthumbs.db +Icon? +Thumbs.db +._* + +# Vim generated files # +###################### +*.un~ + +# SASS # +########## +**/.sass-cache +**/.sass-cache/* +**/.map + +# Composer # +########## +vendors/composer/ +!assets/js/vendor/ +wpcs/ +composer.lock + +# Bower # +########## +assets/bower_components/* + +# Codekit # +########## +/codekit-config.json +*.codekit +**.codekit-cache/* + +# NPM # +########## +node_modules + +# Compiled Files and Build Dirs # +########## +/README.html +/assets/ +/build/ + +# PhpStrom Project Files # +.idea/ +library/vendors/composer +assets/img/.DS_Store +assets/sass/HTML +assets/sass/Rails +HTML +Rails + +# WordPress SVN Repo +wordpress-svn/ diff --git a/README.md b/README.md index 6834033..fcfd367 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# StylePress for Elementor +# StylePress StylePress is a WordPress plugin that lets you design your entire website quickly and easily. Facebook: https://www.facebook.com/groups/325046057898459/ -Slack: https://dtbaker.net/blog/wordpress/2017/03/elementor-developers-slack-group/ +Slack: https://stylepress.org/blog/wordpress/2017/03/elementor-developers-slack-group/ -WordPress: https://wordpress.org/plugins/full-site-builder-for-elementor/ \ No newline at end of file +WordPress: https://wordpress.org/plugins/stylepress/ \ No newline at end of file diff --git a/admin/_header.php b/admin/_header.php deleted file mode 100644 index 6c12ba9..0000000 --- a/admin/_header.php +++ /dev/null @@ -1,24 +0,0 @@ -
- -
- StylePress by dtbaker - v - - -

- StylePress is BETA - there are bugs!
- Report issues and feedback on github -
- -
- Import - Create New Style -
- -
\ No newline at end of file diff --git a/admin/_help_text.php b/admin/_help_text.php deleted file mode 100644 index 9f75066..0000000 --- a/admin/_help_text.php +++ /dev/null @@ -1,66 +0,0 @@ - -

Getting Started

-
    -
  1. Create your "Site Style" in Elementor from the Styles page. -
  2. -
  3. Choose which Outer Styles to apply to your site using the options below. The Outer Style is the - header/sidebar/footer that wraps around your page content. -
  4. -
  5. Choose which Inner Styles to apply to your site components. The Inner Styles are dynamic layouts that replace - the default the_content() output. -
  6. -
  7. When editing individual pages you can apply a different style to the default, look in the page metabox area. -
  8. -
  9. Disable Theme CSS if the page layout looks funky (recommended).
  10. -
  11. View more help and videos at https://stylepress.org/help/
  12. -
-add_help_tab( array( - 'id' => 'stylepress-help', - 'title' => __( 'Getting Started', 'stylepress' ), - 'content' => $help_customize, -) ); - - -ob_start(); -?> -

Recommended Plugins:

-

It is recommended to install these plugins to get best results:

-
    -
  1. Elementor Pro
  2. -
  3. Max Mega Menu
  4. -
  5. Easy Google Fonts
  6. -
-add_help_tab( array( - 'id' => 'stylepress-help-recommended', - 'title' => __( 'Recommended Plugins', 'stylepress' ), - 'content' => $help_customize, -) ); - - -get_current_screen()->set_help_sidebar( - '

' . __( 'For more information:', 'stylepress' ) . '

' . - '

' . __( 'Read More on stylepress.org', 'stylepress' ) . '

' -); diff --git a/admin/settings-page.php b/admin/settings-page.php deleted file mode 100644 index d67d252..0000000 --- a/admin/settings-page.php +++ /dev/null @@ -1,165 +0,0 @@ -has_permission() ) { - die ( 'No permissions' ); -} - - -add_thickbox(); - -$styles = DtbakerElementorManager::get_instance()->get_all_page_styles(); -$components = DtbakerElementorManager::get_instance()->get_all_page_components(); -$settings = DtbakerElementorManager::get_instance()->get_settings(); -$page_types = DtbakerElementorManager::get_instance()->get_possible_page_types(); - -?> - -
- - - - - -

Settings updated.

- -
- - - -

Style Imported! Your new - style has been imported. Please assign it to your site below (hint: Start with "Global" and test from there). -

- -
- - -
- - - - -

- Configure Website Styles - Choose which styles to apply on various parts of your website. See the help menu above for more details. - -

- - -
-
-
- - - - - - - - - - - - - $post_type_title ) { - ?> - - - - - - - - -
Page TypeOuter Style - (Header/Footer) - Inner Style - (Page + CPT Layouts) - Remove Theme CSS?
- - - - - - > -
- -

- -

-
- -
-
-

Need help? - -
- The "Outer" style is generally the same on every page of the site.
- It contains your logo, header, footer and sidebars.
- The "Inner" style is can be different for posts, pages and CPT's.
- It contains a page title area and other dynamic fields. -
-

-

 

-
- -
-
-
-
-
- - -
- - -
diff --git a/admin/styles-page.php b/admin/styles-page.php deleted file mode 100644 index ad1b2c3..0000000 --- a/admin/styles-page.php +++ /dev/null @@ -1,204 +0,0 @@ -has_permission() ) { - - die ( 'No permissions' ); -} - - -add_thickbox(); - -$settings = DtbakerElementorManager::get_instance()->get_settings(); -$page_types = DtbakerElementorManager::get_instance()->get_possible_page_types(); -$designs = DtbakerElementorManager::get_instance()->get_all_page_styles(); -$downloadable = DtbakerElementorManager::get_instance()->get_downloadable_styles(); -?> - -
- - -
- -
- -

- - Your Styles - These are your website styles. A style can be applied to your website from the Settings - page. - -

- -
- -

None yet! Create your own or install from the list below.

-

 

- $design ) : - $post = get_post( $design_id ); - if ( $post->post_parent ) { - continue; - } - ?> -
- - - - - - - - - - - 'dtbaker_style', - 'post_parent' => $design_id, - 'post_status' => 'any', - 'posts_per_page' => - 1, - 'ignore_sticky_posts' => 1, - ); - $posts_array = get_posts( $args ); - - foreach ( $page_types as $post_type => $post_type_title ) { - if ( $settings && ! empty( $settings['defaults'][ $post_type ] ) && (int) $settings['defaults'][ $post_type ] === (int) $design_id ) { - $used[ $post_type ] = $post_type_title; - } - // check if any of the child posts are used in this particular post type. - foreach ( $posts_array as $post_array ) { - if ( $settings && ! empty( $settings['defaults'][ $post_type ] ) && (int) $settings['defaults'][ $post_type ] === (int) $post_array->ID ) { - $used[ $post_type ] = $post_type_title; - } - } - // todo: query what custom pages have a different style overview - } - - ?> - - -

- -
- - - -
- -
- -
-
- - -
-

- Available Styles - These site styles can be installed and then edited with Elementor. -

- -
- $design ) : - - $type = ! empty( $design['cost'] ) ? 'paid' : 'free'; - $has_purchased = false; - if ( 'paid' === $type && ! empty( $design['pay_nonce'] ) ) { - $has_purchased = true; - } else { - - } - ?> -
- - - -
- -
- -

- v -

- -
- - - - - - -
-
- - - -
-
-
- -
- - -
- - div { - display: table; - table-layout: fixed; -} -.dtbaker-elementor-instructions > div > div { - display: table-cell; - width: 25%; -} -.dtbaker-elementor-instructions > div > div h3 { - color: #000; - font-size: 16px; - font-weight: 400; - margin: 0 0 .2em; - padding: 0; -} -.dtbaker-elementor-instructions tr.highlightstyle { - background: rgba(61, 153, 212, 0.5) !important; -} -.dtbaker-elementor-instructions:after { - clear: both; - display: table; - content: ''; -} -.wp-admin.post-type-dtbaker_style #elementor-switch-mode, -.wp-admin.post-type-dtbaker_style #elementor-editor { - display: none; -} -.wp-admin.post-type-dtbaker_style #titlediv { - margin-bottom: 20px; -} -.wp-admin.post-type-dtbaker_style #edit-slug-box { - display: none; -} -.wp-admin.post-type-dtbaker_style #dtbaker-return-to-style { - padding: 0 0 20px; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox > h3 { - background: #f5f5f5; - padding: 15px 20px; - position: relative; - margin: 0 0 30px; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox > h3:before { - position: absolute; - left: 0; - content: ''; - display: block; - top: 0; - bottom: 0; - width: 4px; - background: #e6e6e6; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox > h3 span { - font-weight: bold; - display: block; - padding: 0 0 5px; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox > h3 small { - font-weight: normal; - display: block; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox > h3 a { - float: right; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox .inner-wrap { - margin: 0 0 40px; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox .inner-wrap > ul { - display: block; - padding: 0; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox .inner-wrap > ul > li { - display: inline-block; - padding: 5px; - margin: 0 1% 3% 0; - width: 23%; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox .inner-wrap > ul > li:nth-child(4n+4) { - margin-right: 0; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox .inner-wrap > ul > li:nth-child(4n+5) { - clear: left; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox .inner-wrap > ul > li .design-name { - text-align: center; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox .inner-wrap > ul > li .theme-actions { - position: relative; - display: block; - text-align: center; -} -.wp-admin.post-type-dtbaker_style .stylepress-metabox .advanced-settings { - width: 70%; - min-height: 150px; -} -.stylepress-header { - background: #FFF; - padding: 15px 20px; - position: relative; - margin: 0 0 30px; -} -.stylepress-header:before { - position: absolute; - left: 0; - content: ''; - display: block; - top: 0; - bottom: 0; - width: 4px; - background: #e6e6e6; -} -.stylepress-header span { - font-weight: bold; - display: block; - padding: 0 0 5px; -} -.stylepress-header small { - font-weight: normal; - display: block; -} -.stylepress-header .buttons { - font-weight: normal; - float: right; -} -.stylepress-header { - background: #FFF; - padding: 15px 20px; - position: relative; - margin: 0 0 30px; -} -.stylepress-header:before { - position: absolute; - left: 0; - content: ''; - display: block; - top: 0; - bottom: 0; - width: 4px; - background: #e6e6e6; -} -.stylepress-header span { - font-weight: bold; - display: block; - padding: 0 0 5px; -} -.stylepress-header small { - font-weight: normal; - display: block; -} -.stylepress-header .buttons { - font-weight: normal; - float: right; -} -.stylepress-header { - background: #FFF; - padding: 15px 20px; - position: relative; - margin: 0 0 30px; -} -.stylepress-header:before { - position: absolute; - left: 0; - content: ''; - display: block; - top: 0; - bottom: 0; - width: 4px; - background: #e6e6e6; -} -.stylepress-header span { - font-weight: bold; - display: block; - padding: 0 0 5px; -} -.stylepress-header small { - font-weight: normal; - display: block; -} -.stylepress-header .buttons { - font-weight: normal; - float: right; -} -.wp-admin.post-type-dtbaker_style.post-new-php #elementor-editor { - display: none !important; -} -.sub2-dtbaker-stylepress a { - color: #8bcc3c; -} -#stylepress-header { - margin: 40px 0 40px; - background: #FFF; - padding: 20px; - border-radius: 10px; -} -#stylepress-header .stylepress-logo img { - width: 334px; - height: 75px; -} -#stylepress-header .icons { - float: right; - text-align: right; - padding: 5px 4px 20px; -} -#stylepress-header .icons a { - text-decoration: none; - color: #545c63; -} -#stylepress-header .icons a:after { - content: '|'; - color: #545c63; - padding: 0 4px 0 7px; -} -#stylepress-header .icons a:last-child:after { - display: none; -} -#stylepress-header .buttons { - float: right; - clear: right; - text-align: right; -} -@-webkit-keyframes sk-scaleout { - 0% { - -webkit-transform: scale(0); - } - 100% { - -webkit-transform: scale(1); - opacity: 0; - } -} -@keyframes sk-scaleout { - 0% { - -webkit-transform: scale(0); - transform: scale(0); - } - 100% { - -webkit-transform: scale(1); - transform: scale(1); - opacity: 0; - } -} -.stylepress-payment-popup { - position: relative; -} -.stylepress-payment-popup.processing .loadingbar { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: -3px; - z-index: 9999999; - background: rgba(255, 255, 255, 0.72); -} -.stylepress-payment-popup.processing .loadingbar:before { - top: 34%; - left: 41%; - z-index: 5; - content: ''; - position: absolute; - width: 80px; - height: 80px; - background-color: #55b2d8; - border-radius: 100%; - -webkit-animation: sk-scaleout 1s infinite ease-in-out; - animation: sk-scaleout 1s infinite ease-in-out; -} -.stylepress-payment-popup label { - display: block; - margin-bottom: 8px; - font-weight: 500; - font-size: 14px; -} -.stylepress-payment-popup .form-row { - margin-bottom: 16px; -} -.stylepress-payment-popup .text-field, -.stylepress-payment-popup .StripeElement { - background-color: white; - padding: 8px 12px; - border-radius: 4px; - border: 1px solid rgba(226, 196, 196, 0.88); - box-shadow: 0 1px 3px 0 #e6ebf1; - -webkit-transition: box-shadow 150ms ease; - transition: box-shadow 150ms ease; -} -.stylepress-payment-popup .form-row > .text-field { - padding: 12px 12px; -} -.stylepress-payment-popup .slider-range { - width: 100%; -} -.stylepress-payment-popup .stripe-card-element:before { - content: 'Loading...'; -} -.stylepress-payment-popup .stripe-card-element.StripeElement:before { - display: none; -} -.stylepress-payment-popup .StripeElement--focus { - box-shadow: 0 1px 3px 0 #cfd7df; -} -.stylepress-payment-popup .StripeElement--invalid { - border-color: #fa755a; -} -.stylepress-payment-popup .StripeElement--webkit-autofill { - background-color: #fefde5 !important; -} -.stylepress-payment-popup .slider { - width: 100%; - height: 0.7rem; - border: 1px solid rgba(226, 196, 196, 0.88); - position: relative; -} -.stylepress-payment-popup .slider.one-way .handle.handle-left { - visibility: hidden; -} -.stylepress-payment-popup .slider .slider-circle { - width: 10px; - height: 10px; - border-radius: 50%; - background-color: #0a84c1; - position: relative; - display: inline-block; - margin-top: 10px; - pointer-events: none; - -webkit-user-select: none; -} -.stylepress-payment-popup .slider .handle { - width: 30px; - height: 30px; - border-radius: 50%; - position: absolute; - top: -10px; - border: 1px solid rgba(226, 196, 196, 0.88); - background-color: #fff; - text-align: center; - cursor: pointer; - z-index: 1; - -webkit-tap-highlight-color: transparent; -} -.stylepress-payment-popup .slider .handle.ontop { - z-index: 2; -} -.stylepress-payment-popup .slider .handle:active { - border-color: #0a84c1; - box-shadow: 0 0 0.5rem #0a84c1; -} -.stylepress-payment-popup .slider .handle-left { - left: 0; -} -.stylepress-payment-popup .slider .handle-right { - right: 0; -} -.stylepress-payment-popup .slider .slider-fill { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - background: #0a84c1; - pointer-events: none; - -webkit-user-select: none; -} -.stylepress-payment-popup .slider .slider-transition { - -webkit-transition: all 0.5s ease; - transition: all 0.5s ease; -} -.style-list { - margin-bottom: 30px; -} diff --git a/assets/css/admin.less b/assets/css/admin.less deleted file mode 100644 index b000fbb..0000000 --- a/assets/css/admin.less +++ /dev/null @@ -1,493 +0,0 @@ -.dtbaker-elementor-browser { - margin-top: 40px; - .design { - float: left; - margin: 0 4% 4% 0; - width: 21.6%; - &:nth-child(4n+4) { - margin-right: 0; - } - &:nth-child(4n+5) { - clear: left; - } - } - .stylebox { - cursor: pointer; - position: relative; - border: 1px solid #ddd; - -webkit-box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.1); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - .thumb { - display: block; - overflow: hidden; - position: relative; - -webkit-backface-visibility: hidden; - -webkit-transition: opacity 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out; - img { - max-width: 100%; - height: auto; - } - } - .theme-usage { - padding: 6px 0 6px 12px; - font-size: 12px; - background-color: #fafafa; - text-overflow: ellipsis; - min-height: 18px; - &.style-description { - height: auto; - } - a { - text-decoration: none; - color: #444; - } - } - h3.design-name { - font-size: 15px; - font-weight: 600; - height: 18px; - margin: 0; - padding: 15px; - -webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1); - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - background-color: #fafafa; - color: #23282d; - small { - font-weight: normal; - font-size: 12px; - color: #CCC; - } - a { - color: #23282d; - text-decoration: none; - } - } - .theme-actions { - position: absolute; - bottom: 0; - right: 0; - height: 38px; - padding: 9px 10px 0 10px; - background: rgba(244, 244, 244, 0.7); - border-left: 1px solid rgba(0, 0, 0, 0.05); - } - &.add-new { - a { - text-decoration: none; - display: block; - position: relative; - z-index: 1; - } - } - } -} - -.dtbaker-elementor-instructions { - margin: 40px 0 0; - > div { - display: table; - table-layout: fixed; - > div { - display: table-cell; - width: 25%; - h3 { - color: #000; - font-size: 16px; - font-weight: 400; - margin: 0 0 .2em; - padding: 0; - } - } - } - tr.highlightstyle { - background: rgba(61, 153, 212, 0.5) !important; - } - &:after { - clear: both; - display: table; - content: ''; - } -} - -.wp-admin.post-type-dtbaker_style { - #elementor-switch-mode, - #elementor-editor { - display: none; - } - #titlediv { - margin-bottom: 20px; - } - #edit-slug-box { - display: none; - } - #dtbaker-return-to-style { - padding: 0 0 20px; - } - .stylepress-metabox { - > h3 { - background: #f5f5f5; - padding: 15px 20px; - position: relative; - margin: 0 0 30px; - &:before { - position: absolute; - left: 0; - content: ''; - display: block; - top: 0; - bottom: 0; - width: 4px; - background: #e6e6e6 - } - span { - font-weight: bold; - display: block; - padding: 0 0 5px; - } - small { - font-weight: normal; - display: block; - } - a { - float: right; - } - } - .inner-wrap { - margin: 0 0 40px; - > ul { - display: block; - padding: 0; - > li { - display: inline-block; - padding: 5px; - margin: 0 1% 3% 0; - width: 23%; - &:nth-child(4n+4) { - margin-right: 0; - } - &:nth-child(4n+5) { - clear: left; - } - .design-name { - text-align: center; - } - .theme-actions { - position: relative; - display: block; - text-align: center; - } - } - } - } - .advanced-settings { - width: 70%; - min-height: 150px; - } - } -} - -.stylepress-header { - background: #FFF; - padding: 15px 20px; - position: relative; - margin: 0 0 30px; - &:before { - position: absolute; - left: 0; - content: ''; - display: block; - top: 0; - bottom: 0; - width: 4px; - background: #e6e6e6 - } - span { - font-weight: bold; - display: block; - padding: 0 0 5px; - } - small { - font-weight: normal; - display: block; - } - .buttons { - font-weight: normal; - float: right; - } -} - -.stylepress-header { - background: #FFF; - padding: 15px 20px; - position: relative; - margin: 0 0 30px; - &:before { - position: absolute; - left: 0; - content: ''; - display: block; - top: 0; - bottom: 0; - width: 4px; - background: #e6e6e6 - } - span { - font-weight: bold; - display: block; - padding: 0 0 5px; - } - small { - font-weight: normal; - display: block; - } - .buttons { - font-weight: normal; - float: right; - } -} - -.stylepress-header { - background: #FFF; - padding: 15px 20px; - position: relative; - margin: 0 0 30px; - &:before { - position: absolute; - left: 0; - content: ''; - display: block; - top: 0; - bottom: 0; - width: 4px; - background: #e6e6e6 - } - span { - font-weight: bold; - display: block; - padding: 0 0 5px; - } - small { - font-weight: normal; - display: block; - } - .buttons { - font-weight: normal; - float: right; - } -} - -.wp-admin.post-type-dtbaker_style.post-new-php { - #elementor-editor { - display: none !important; - } -} - -.sub2-dtbaker-stylepress a { - color: #8bcc3c; -} - -#stylepress-header { - margin: 40px 0 40px; - background: #FFF; - padding: 20px; - border-radius: 10px; - .stylepress-logo { - img { - width: 334px; - height: 75px; - } - } - .icons { - float: right; - text-align: right; - padding: 5px 4px 20px; - a { - text-decoration: none; - color: #545c63; - &:after { - content: '|'; - color: #545c63; - padding: 0 4px 0 7px; - } - &:last-child:after { - display: none; - } - } - } - .buttons { - float: right; - clear: right; - text-align: right - } -} - -@-webkit-keyframes sk-scaleout { - 0% { - -webkit-transform: scale(0) - } - 100% { - -webkit-transform: scale(1.0); - opacity: 0; - } -} - -@keyframes sk-scaleout { - 0% { - -webkit-transform: scale(0); - transform: scale(0); - } - 100% { - -webkit-transform: scale(1.0); - transform: scale(1.0); - opacity: 0; - } -} - -.stylepress-payment-popup { - position: relative; - &.processing { - - .loadingbar { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: -3px; - z-index: 9999999; - background: rgba(255, 255, 255, 0.72); - &:before { - top: 34%; - left: 41%; - z-index: 5; - content: ''; - position: absolute; - width: 80px; - height: 80px; - background-color: #55b2d8; - border-radius: 100%; - -webkit-animation: sk-scaleout 1.0s infinite ease-in-out; - animation: sk-scaleout 1.0s infinite ease-in-out; - } - } - } - - label { - display: block; - margin-bottom: 8px; - font-weight: 500; - font-size: 14px; - } - .form-row { - margin-bottom: 16px; - } - .text-field, - .StripeElement { - background-color: white; - padding: 8px 12px; - border-radius: 4px; - border: 1px solid rgba(226, 196, 196, 0.88); - box-shadow: 0 1px 3px 0 #e6ebf1; - -webkit-transition: box-shadow 150ms ease; - transition: box-shadow 150ms ease; - } - .form-row > .text-field { - padding: 12px 12px; - } - .slider-range { - width: 100%; - } - - .stripe-card-element { - &:before { - content: 'Loading...'; - } - &.StripeElement:before { - display: none; - } - } - - .StripeElement--focus { - box-shadow: 0 1px 3px 0 #cfd7df; - } - - .StripeElement--invalid { - border-color: #fa755a; - } - - .StripeElement--webkit-autofill { - background-color: #fefde5 !important; - } - - .slider { - width: 100%; - height: 0.7rem; - border: 1px solid rgba(226, 196, 196, 0.88); - position: relative; - } - .slider.one-way .handle.handle-left { - visibility: hidden; - } - .slider .slider-circle { - width: 10px; - height: 10px; - border-radius: 50%; - background-color: #0a84c1; - position: relative; - display: inline-block; - margin-top: 10px; - pointer-events: none; - -webkit-user-select: none; - } - .slider .handle { - width: 30px; - height: 30px; - border-radius: 50%; - position: absolute; - top: -10px; - border: 1px solid rgba(226, 196, 196, 0.88); - background-color: #fff; - text-align: center; - cursor: pointer; - z-index: 1; - -webkit-tap-highlight-color: transparent; - } - .slider .handle.ontop { - z-index: 2; - } - .slider .handle:active { - border-color: #0a84c1; - box-shadow: 0 0 0.5rem #0a84c1; - } - .slider .handle-left { - left: 0; - } - .slider .handle-right { - right: 0; - } - .slider .slider-fill { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - background: #0a84c1; - pointer-events: none; - -webkit-user-select: none; - } - .slider .slider-transition { - -webkit-transition: all 0.5s ease; - transition: all 0.5s ease; - } - -} - -.style-list { - margin-bottom: 30px; -} \ No newline at end of file diff --git a/assets/css/editor-in.css b/assets/css/editor-in.css deleted file mode 100644 index f0a503f..0000000 --- a/assets/css/editor-in.css +++ /dev/null @@ -1,18 +0,0 @@ -.elementor-editor-active.dtbaker-elementor-template-component .elementor-edit-mode:before { - content: 'Design Your Inner Style Below'; - position: absolute; - display: block; - left: 50%; - padding: 18px; - margin-left: -265px; - font-size: 25px; -} -.elementor-editor-active.dtbaker-elementor-template-component .elementor-inner { - margin-top: 0 !important; - padding: 120px 50px; - background: #f5f5f5; -} -.elementor-editor-active.dtbaker-elementor-template-component .elementor-inner > .elementor-section-wrap { - background: #FFF; - padding: 50px 0; -} diff --git a/assets/css/editor-in.less b/assets/css/editor-in.less deleted file mode 100644 index 9ab8185..0000000 --- a/assets/css/editor-in.less +++ /dev/null @@ -1,28 +0,0 @@ -.elementor-editor-active.dtbaker-elementor-template-component { - .elementor-edit-mode { - &:before { - content: 'Design Your Inner Style Below'; - position: absolute; - display: block; - left: 50%; - padding: 18px; - margin-left: -265px; - font-size: 25px; - } - } - .elementor-inner { - margin-top: 0 !important; - padding: 120px 50px; - background: #f5f5f5; - > .elementor-section-wrap { - background: #FFF; - padding: 50px 0; - > section { - - } - .elementor-editor-column-settings-list { - - } - } - } -} \ No newline at end of file diff --git a/assets/css/editor.css b/assets/css/editor.css deleted file mode 100644 index 15541bb..0000000 --- a/assets/css/editor.css +++ /dev/null @@ -1,44 +0,0 @@ -.dtbaker-elementor-page-style-item { - text-align: center; - padding: 30px; -} -.elementor-control-stylepress-modal { - position: absolute; - top: 0; - right: 37px; - padding: 0; - height: 100%; - width: 40px; - border: none; - border-left: 1px solid #CCC; - background: none; - cursor: pointer; - font-size: 10px; - border-radius: 0 3px 3px 0; -} -.elementor-control-stylepress-modal span { - opacity: .5; -} -.elementor-panel .elementor-control-type-url .elementor-control-url-target { - border-left: 1px solid #CCC; -} -.elementor-control-stylepress-modal-title { - padding-top: 4px; -} -.dtbaker-stylepress-elementor-widget { - background: url(../img/widget-logo.png) no-repeat center; - background-size: contain; - padding: 26px; - font-size: 20px; - line-height: 46px; -} -.dtbaker-elementor-page-style-item { - text-align: center; - padding: 30px; -} -#elementor-controls div[class*="elementor-control-section_stylepress_"] .elementor-panel-heading { - background: #b1defb; -} -.stylepress-elementor-description p { - padding: 7px 0; -} diff --git a/assets/css/editor.less b/assets/css/editor.less deleted file mode 100644 index eaba5ac..0000000 --- a/assets/css/editor.less +++ /dev/null @@ -1,56 +0,0 @@ -.dtbaker-elementor-page-style-item { - text-align: center; - padding: 30px; -} - -.elementor-control-stylepress-modal { - position: absolute; - top: 0; - right: 37px; - padding: 0; - height: 100%; - width: 40px; - border: none; - border-left: 1px solid #CCC; - background: none; - cursor: pointer; - font-size: 10px; - border-radius: 0 3px 3px 0; - span { - opacity: .5; - } -} - -.elementor-panel .elementor-control-type-url .elementor-control-url-target { - border-left: 1px solid #CCC; -} - -.elementor-control-stylepress-modal-title { - padding-top: 4px; -} - -.dtbaker-stylepress-elementor-widget { - background: url(../img/widget-logo.png) no-repeat center; - background-size: contain; - padding: 26px; - font-size: 20px; - line-height: 46px; -} - -.dtbaker-elementor-page-style-item { - text-align: center; - padding: 30px; -} - -#elementor-controls [class*="elementor-control-stylepress"] { - -} - -#elementor-controls div[class*="elementor-control-section_stylepress_"] .elementor-panel-heading { - background: #b1defb; - -} - -.stylepress-elementor-description p { - padding: 7px 0; -} \ No newline at end of file diff --git a/assets/css/frontend-css-editor.css b/assets/css/frontend-css-editor.css deleted file mode 100644 index 6831b7f..0000000 --- a/assets/css/frontend-css-editor.css +++ /dev/null @@ -1,66 +0,0 @@ -@media screen and (min-width: 782px) { - #stylepress_csser { - direction: ltr; - color: #ccc; - font-size: 13px; - font-weight: 400; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; - line-height: 32px; - height: 32px; - position: fixed; - top: 32px; - left: 0; - width: 100%; - min-width: 600px; - z-index: 99991; - background: #363b40; - } - #stylepress_csser .stylepress-css-info, - #stylepress_csser .stylepress-css-box { - display: none; - } - #stylepress_csser .stylepress-css-buttons { - position: absolute; - bottom: 0; - right: 0; - z-index: 300; - } - #stylepress_csser .stylepress-css-buttons a { - display: inline-block; - padding: 5px; - background: #23282d; - color: #FFF; - border-radius: 6px; - margin: 5px; - font-size: 11px; - line-height: 13px; - } - #stylepress_csser .stylepress-css-buttons a:hover { - background: #3c434a; - } - #stylepress_csser .stylepress-css-buttons a.stylepress-csser-save { - displaY: none; - } - html.stylepress-csser { - margin-top: 342px !important; - } - html.stylepress-csser #stylepress_csser { - height: 310px; - padding: 0; - } - html.stylepress-csser #stylepress_csser .stylepress-css-info, - html.stylepress-csser #stylepress_csser .stylepress-css-box { - display: block; - } - html.stylepress-csser #stylepress_csser .stylepress-css-buttons .stylepress-csser-save { - display: inline-block; - } - html.stylepress-csser #stylepress_csser .stylepress-css-box { - height: 270px; - } -} -@media screen and (max-width: 782px) { - html #stylepress_csser { - display: none; - } -} diff --git a/assets/css/frontend-css-editor.less b/assets/css/frontend-css-editor.less deleted file mode 100644 index 7e8b492..0000000 --- a/assets/css/frontend-css-editor.less +++ /dev/null @@ -1,68 +0,0 @@ -@media screen and (min-width: 782px) { - #stylepress_csser { - direction: ltr; - color: #ccc; - font-size: 13px; - font-weight: 400; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; - line-height: 32px; - height: 32px; - position: fixed; - top: 32px; - left: 0; - width: 100%; - min-width: 600px; - z-index: 99991; - background: #363b40; - .stylepress-css-info, - .stylepress-css-box { - display: none; - } - .stylepress-css-buttons { - position: absolute; - bottom: 0; - right: 0; - z-index: 300; - a { - display: inline-block; - padding: 5px; - background: #23282d; - color: #FFF; - border-radius: 6px; - margin: 5px; - font-size: 11px; - line-height: 13px; - &:hover { - background: #3c434a; - } - } - a.stylepress-csser-save { - displaY: none; - } - } - } - - html.stylepress-csser { - margin-top: 32px + 310px !important; - #stylepress_csser { - height: 310px; - padding: 0; - .stylepress-css-info, - .stylepress-css-box { - display: block; - } - .stylepress-css-buttons .stylepress-csser-save { - display: inline-block; - } - .stylepress-css-box { - height: 270px; - } - } - } -} - -@media screen and (max-width: 782px) { - html #stylepress_csser { - display: none; - } -} \ No newline at end of file diff --git a/assets/css/frontend.css b/assets/css/frontend.css deleted file mode 100644 index 3b71adf..0000000 --- a/assets/css/frontend.css +++ /dev/null @@ -1,67 +0,0 @@ -.inner-page-content-area { - text-align: center; - padding: 80px 20px; - color: #000; - background: #FFF; - background: -webkit-repeating-linear-gradient(45deg, #efefef, #efefef 10px, #FFFFFF 10px, #FFFFFF 20px); - background: repeating-linear-gradient(45deg, #efefef, #efefef 10px, #FFFFFF 10px, #FFFFFF 20px); -} -#site-offcanvas-wrap > .elementor > .elementor-inner > .elementor-section-wrap section.elementor-section { - position: relative; -} -#site-offcanvas-wrap > .elementor > .elementor-inner > .elementor-section-wrap section.elementor-section:nth-child(1) { - z-index: 7; -} -#site-offcanvas-wrap > .elementor > .elementor-inner > .elementor-section-wrap section.elementor-section:nth-child(2) { - z-index: 6; -} -#site-offcanvas-wrap > .elementor > .elementor-inner > .elementor-section-wrap section.elementor-section:nth-child(3) { - z-index: 5; -} -#site-offcanvas-wrap > .elementor > .elementor-inner > .elementor-section-wrap section.elementor-section:nth-child(4) { - z-index: 4; -} -#site-offcanvas-wrap > .elementor > .elementor-inner > .elementor-section-wrap section.elementor-section:nth-child(5) { - z-index: 3; -} -#site-offcanvas-wrap > .elementor > .elementor-inner > .elementor-section-wrap section.elementor-section:nth-child(6) { - z-index: 2; -} -body.dtbaker-elementor-template.elementor-editor-active #site-offcanvas-wrap > .elementor > .elementor-inner > .elementor-section-wrap section.elementor-section { - z-index: 1 !important; -} -.stylepress-debug { - background: #fff; - border-left: 4px solid #fff; - -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); - margin: 10px 15px; - padding: 5px 12px; - position: relative; - font-size: 13px; - border-left-color: #46b450; - color: #444; -} -.stylepress-debug span { - color: #CCC; -} -/** -StylePress Custom Addons: - */ -.elementor-widget-icon-list[data-element_type="icon-list.stylepress-icons-inline"] ul.elementor-icon-list-items { - display: flex; -} -.elementor-widget-icon-list[data-element_type="icon-list.stylepress-icons-inline"] ul.elementor-icon-list-items > li.elementor-icon-list-item { - padding: 6px 10px; -} -.elementor-widget-icon-list[data-element_type="icon-list.stylepress-icons-inline"] ul.elementor-icon-list-items > li.elementor-icon-list-item:after { - border-top: 0 !important; - border-right-style: solid; - border-right-width: 1px; - border-right-color: #ddd; - left: auto; - bottom: auto; - right: 0; - height: 58%; - width: auto; -} diff --git a/assets/css/frontend.less b/assets/css/frontend.less deleted file mode 100644 index 9c99899..0000000 --- a/assets/css/frontend.less +++ /dev/null @@ -1,91 +0,0 @@ - -.inner-page-content-area { - text-align: center; - padding: 80px 20px; - color: #000; - background: #FFF; - background: -webkit-repeating-linear-gradient(45deg, #efefef, #efefef 10px, #FFFFFF 10px, #FFFFFF 20px); - background: repeating-linear-gradient(45deg, #efefef, #efefef 10px, #FFFFFF 10px, #FFFFFF 20px); -} - -#site-offcanvas-wrap > .elementor > .elementor-inner > .elementor-section-wrap { - section.elementor-section { - // fix for menu drop down - position: relative; - &:nth-child(1) { - z-index: 7; - } - &:nth-child(2) { - z-index: 6; - } - &:nth-child(3) { - z-index: 5; - } - &:nth-child(4) { - z-index: 4; - } - &:nth-child(5) { - z-index: 3; - } - &:nth-child(6) { - z-index: 2; - } - } -} - -body.dtbaker-elementor-template.elementor-editor-active #site-offcanvas-wrap > .elementor > .elementor-inner > .elementor-section-wrap { - section.elementor-section { - z-index: 1 !important; - } -} - -.stylepress-debug { - background: #fff; - border-left: 4px solid #fff; - -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); - margin: 10px 15px; - padding: 5px 12px; - position: relative; - font-size: 13px; - border-left-color: #46b450; - color: #444; - span { - color: #CCC; - } -} - -/** -StylePress Custom Addons: - */ -.elementor-widget-icon-list[data-element_type="icon-list.stylepress-icons-inline"] { - ul.elementor-icon-list-items { - display: flex; - //justify-content: center; - > li.elementor-icon-list-item { - padding: 6px 10px; - &:after { - border-top: 0 !important; - border-right-style: solid; - border-right-width: 1px; - border-right-color: #ddd; - left: auto; - bottom: auto; - right: 0; - height: 58%; - width: auto; - } - } - } - - &.elementor-align-left { - ul.elementor-icon-list-items { - //justify-content: flex-start; - } - } - &.elementor-align-right { - ul.elementor-icon-list-items { - //justify-content: flex-end; - } - } -} diff --git a/assets/css/theme-overwrites.css b/assets/css/theme-overwrites.css deleted file mode 100644 index cb04c15..0000000 --- a/assets/css/theme-overwrites.css +++ /dev/null @@ -1,1806 +0,0 @@ -/* =Reset --------------------------------------------------------------- */ -html, -body, -div, -span, -applet, -object, -iframe, -h1, -h2, -h3, -h4, -h5, -h6, -p, -blockquote, -pre, -a, -abbr, -acronym, -address, -big, -cite, -code, -del, -dfn, -em, -font, -ins, -kbd, -q, -s, -samp, -small, -strike, -strong, -sub, -sup, -tt, -var, -dl, -dt, -dd, -ol, -ul, -li, -fieldset, -form, -label, -legend, -table, -caption, -tbody, -tfoot, -thead, -tr, -th, -td { - border: 0; - margin: 0; - outline: 0; - padding: 0; -} -html { - font-family: sans-serif; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} -article, -aside, -details, -figcaption, -figure, -footer, -header, -main, -nav, -section { - display: block; -} -audio, -canvas, -progress, -video { - display: inline-block; - vertical-align: baseline; -} -audio:not([controls]) { - display: none; - height: 0; -} -[hidden], -template { - display: none; -} -ol, -ul { - list-style: none; -} -table { - /* tables still need 'cellspacing="0"' in the markup */ - border-collapse: separate; - border-spacing: 0; -} -caption, -th, -td { - font-weight: normal; - text-align: left; - padding: 5px; -} -blockquote:before, -blockquote:after, -q:before, -q:after { - content: ""; -} -blockquote, -q { - quotes: "" ""; -} -a { - background-color: transparent; -} -a:active, -a:hover { - outline: 0; -} -a img { - border: 0; -} -/* =Global ------------------------------------------------ */ -body, -button, -input, -select, -textarea { - font-family: sans-serif; - font-size: 16px; - font-size: 1.6rem; - line-height: 1.5; - -webkit-transition: all 0.1s ease-in-out; - -moz-transition: all 0.1s ease-in-out; - -o-transition: all 0.1s ease-in-out; - transition: all 0.1s ease-in-out; -} -hr { - background-color: #ccc; - border: 0; - height: 1px; - margin-bottom: 40px; - margin-top: 40px; -} -/* Text elements */ -p { - margin-bottom: 1.5em; -} -ul, -ol { - margin: 0 0 1.5em 3em; -} -ul { - list-style: disc; -} -ol { - list-style: decimal; -} -li > ul, -li > ol { - margin-bottom: 0; - margin-left: 1.5em; -} -dt { - font-weight: bold; -} -dd { - margin: 0 1.5em 1.5em; -} -b, -strong { - font-weight: bold; -} -dfn, -cite, -em, -i { - font-style: italic; -} -blockquote { - margin: 0 1.5em 1.5em; -} -address { - margin: 0 0 1.5em; -} -pre { - background: #eee; - font-family: "Courier 10 Pitch", Courier, monospace; - font-size: 15px; - font-size: 1.5rem; - line-height: 1.6; - margin-bottom: 1.6em; - padding: 1.6em; - overflow: auto; - max-width: 100%; -} -code, -kbd, -tt, -var { - font: 15px Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; -} -abbr, -acronym { - border-bottom: 1px dotted #666; - cursor: help; -} -mark, -ins { - text-decoration: none; -} -sup, -sub { - font-size: 75%; - height: 0; - line-height: 0; - position: relative; - vertical-align: baseline; -} -sup { - bottom: 1ex; -} -sub { - top: .5ex; -} -small { - font-size: 75%; -} -big { - font-size: 125%; -} -figure { - margin: 0; -} -table { - margin: 0 0 1.5em; - width: 100%; -} -th { - font-weight: bold; -} -img { - height: auto; - /* Make sure images are scaled correctly. */ - max-width: 100%; - /* Adhere to container width. */ -} -button, -input, -select, -textarea { - font-size: 100%; - /* Corrects font size not being inherited in all browsers */ - margin: 0; - /* Addresses margins set differently in IE6/7, F3/4, S5, Chrome */ - vertical-align: baseline; - /* Improves appearance and consistency in all browsers */ - *vertical-align: middle; - /* Improves appearance and consistency in all browsers */ -} -button, -input { - line-height: normal; - /* Addresses FF3/4 setting line-height using !important in the UA stylesheet */ -} -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - border: 0; - background: #666; - cursor: pointer; - /* Improves usability and consistency of cursor style between image-type 'input' and others */ - -webkit-appearance: button; - /* Corrects inability to style clickable 'input' types in iOS */ - padding: 10px 20px; - color: #FFF; -} -button:hover, -html input[type="button"]:hover, -input[type="reset"]:hover, -input[type="submit"]:hover { - background: #606060; -} -button:focus, -html input[type="button"]:focus, -input[type="reset"]:focus, -input[type="submit"]:focus, -button:active, -html input[type="button"]:active, -input[type="reset"]:active, -input[type="submit"]:active { - background: #606060; -} -.button { - padding: 10px 20px; - display: inline-block; - *display: inline; -} -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; - /* Addresses box sizing set to content-box in IE8/9 */ - padding: 0; - /* Addresses excess padding in IE8/9 */ -} -input[type="search"] { - -webkit-appearance: textfield; - /* Addresses appearance set to searchfield in S5, Chrome */ - -webkit-box-sizing: content-box; - /* Addresses box sizing set to border-box in S5, Chrome (include -moz to future-proof) */ - -moz-box-sizing: content-box; - box-sizing: content-box; -} -input[type="search"]::-webkit-search-decoration { - /* Corrects inner padding displayed oddly in S5, Chrome on OSX */ - -webkit-appearance: none; -} -button::-moz-focus-inner, -input::-moz-focus-inner { - /* Corrects inner padding and border displayed oddly in FF3/4 www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/ */ - border: 0; - padding: 0; -} -input[type="text"], -input[type="email"], -input[type="url"], -input[type="password"], -input[type="search"], -input[type="tel"], -textarea { - background: #FAFAFA; - color: #666; - border: 1px solid #ccc; - border-radius: 0px; - padding: 10px 15px; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - max-width: 100%; -} -input[type="text"]:focus, -input[type="email"]:focus, -input[type="url"]:focus, -input[type="password"]:focus, -input[type="tel"]:focus, -input[type="search"]:focus, -textarea:focus { - color: #111; - background: #FFF; -} -textarea { - overflow: auto; - /* Removes default vertical scrollbar in IE6/7/8/9 */ - vertical-align: top; - /* Improves readability and alignment in all browsers */ - width: 100%; -} -input[type="file"] { - max-width: 100%; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -/* Alignment */ -.alignleft { - display: inline; - float: left; - margin-right: 1.5em; -} -.alignright { - display: inline; - float: right; - margin-left: 1.5em; -} -.aligncenter { - clear: both; - display: block; - margin: 0 auto; -} -.size-auto, -.size-full, -.size-large, -.size-medium, -.size-thumbnail { - max-width: 100%; - height: auto; -} -/* Text meant only for screen readers */ -.screen-reader-text { - clip: rect(1px, 1px, 1px, 1px); - position: absolute !important; -} -.screen-reader-text:hover, -.screen-reader-text:active, -.screen-reader-text:focus { - background-color: #f1f1f1; - border-radius: 3px; - box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6); - clip: auto !important; - color: #21759b; - display: block; - font-size: 14px; - font-weight: bold; - height: auto; - left: 5px; - line-height: normal; - padding: 15px 23px 14px; - text-decoration: none; - top: 5px; - width: auto; - z-index: 100000; - /* Above WP toolbar */ -} -/* Clearing */ -.clear:before, -.clear:after, -[class*="content"]:before, -[class*="content"]:after, -[class*="site"]:before, -[class*="site"]:after { - content: ''; - display: table; -} -.clear:after, -[class*="content"]:after, -[class*="site"]:after { - clear: both; -} -/* =Menu ------------------------------------------------ */ -.main-navigation { - z-index: 100; -} -.main-navigation { - padding: 0; -} -.main-navigation ul li a { - display: block; -} -.menu-toggle { - margin: 0; - padding: 0; -} -.menu-toggle:before { - content: "\f0c9"; - font-family: FontAwesome; - line-height: 1em; - speak: none; -} -.toggled .menu-toggle:before { - content: "\f00d"; - speak: none; -} -.menu-toggle .mobile-menu { - margin-left: 10px; -} -.menu-toggle .mobile-menu:empty { - display: none; -} -.main-navigation .main-nav ul ul li a { - line-height: normal; - padding: 10px 20px; -} -.main-navigation { - clear: both; - display: block; -} -.inside-navigation { - position: relative; -} -.main-navigation ul, -.menu-toggle li.search-item { - list-style: none; - margin: 0; - padding-left: 0; -} -.search-item .screen-reader-text { - top: 0; - right: 0; - left: auto; -} -.main-navigation li { - float: left; - position: relative; -} -.main-navigation a { - display: block; - text-decoration: none; -} -.main-navigation ul ul { - box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1); - display: none; - float: left; - position: absolute; - left: 0; - z-index: 99999; - width: 200px; - text-align: left; - top: auto; -} -.main-navigation ul ul ul { - left: 100%; - top: 0; -} -.main-navigation ul ul a { - display: block; -} -.main-navigation ul ul li { - width: 100%; -} -.main-navigation ul li:hover > ul, -.main-navigation ul li.sfHover > ul, -.secondary-navigation ul li:hover > ul, -.secondary-navigation ul li.sfHover > ul { - display: block; -} -.dropdown-click .main-navigation ul li:hover > ul, -.dropdown-click .main-navigation ul li.sfHover > ul, -.dropdown-click .secondary-navigation ul li:hover > ul, -.dropdown-click .secondary-navigation ul li.sfHover > ul { - display: none; -} -.dropdown-click .main-navigation ul.toggled-on, -.dropdown-click .main-navigation ul li:hover > ul.toggled-on, -.dropdown-click .main-navigation ul li.sfHover > ul.toggled-on, -.dropdown-click .secondary-navigation ul.toggled-on, -.dropdown-click .secondary-navigation ul li:hover > ul.toggled-on, -.dropdown-click .secondary-navigation ul li.sfHover > ul.toggled-on { - display: block; -} -.dropdown-click nav ul ul ul { - background-color: transparent; -} -.nav-float-right .inside-header .main-navigation { - float: right; - clear: right; -} -.nav-float-left .inside-header .main-navigation { - float: left; - clear: left; -} -.nav-float-left .inside-header .site-branding, -.nav-float-left .inside-header .site-logo { - float: right; - clear: right; -} -.nav-float-left .inside-header:after { - clear: both; - content: ''; - display: table; -} -.nav-float-right .inside-header .site-branding { - display: inline-block; -} -.site-header { - position: relative; -} -.header-aligned-left .site-header { - text-align: left; -} -.header-aligned-center .site-header { - text-align: center; -} -.header-aligned-right .site-header { - text-align: right; -} -.site-header .header-image { - vertical-align: middle; -} -.main-navigation .main-nav ul ul li a, -.nav-float-right .main-navigation .main-nav ul ul li a { - line-height: normal; -} -.nav-float-right .main-navigation ul ul ul { - top: 0; -} -.main-navigation li.search-item { - float: right; - z-index: 21; -} -.rtl .main-navigation li.search-item, -.rtl.nav-aligned-right.nav-below-header .main-navigation .menu > li.search-item { - float: left; -} -.nav-aligned-center .main-navigation li.search-item.current-menu-item { - position: absolute; - right: 0; -} -.rtl.nav-aligned-center .main-navigation li.search-item.current-menu-item { - position: absolute; - left: 0; -} -.main-navigation li.search-item i { - transform: rotate(90deg); -} -.navigation-search { - position: absolute; - right: 0; - display: none; - z-index: 20; - width: 100%; - top: 0; -} -.gen-sidebar-nav .navigation-search { - top: auto; - bottom: 0; -} -.navigation-search input { - border: 0; - vertical-align: bottom; - line-height: 0; - opacity: 0.9; - width: 100%; - z-index: 20; - border-radius: 0; - -webkit-appearance: none; -} -.navigation-search input::-ms-clear { - display: none; - width: 0; - height: 0; -} -.navigation-search input::-ms-reveal { - display: none; - width: 0; - height: 0; -} -.navigation-search input::-webkit-search-decoration, -.navigation-search input::-webkit-search-cancel-button, -.navigation-search input::-webkit-search-results-button, -.navigation-search input::-webkit-search-results-decoration { - display: none; -} -.nav-left-sidebar .main-navigation li.search-item, -.nav-right-sidebar .main-navigation li.search-item { - width: auto; - display: inline-block; -} -.nav-left-sidebar .main-navigation li.search-item.current-menu-item, -.nav-right-sidebar .main-navigation li.search-item.current-menu-item { - float: right; -} -.navigation-search input:focus { - outline: 0; -} -.nav-aligned-right.nav-below-header .main-navigation .menu > li, -.nav-aligned-right.nav-above-header .main-navigation .menu > li, -.nav-aligned-center.nav-below-header .main-navigation .menu > li, -.nav-aligned-center.nav-above-header .main-navigation .menu > li { - float: none; - display: inline-block; - *display: inline; - *zoom: 1; -} -.nav-aligned-right .main-navigation ul, -.nav-aligned-center .main-navigation ul { - letter-spacing: -0.31em; - font-size: 1em; -} -.nav-aligned-right .main-navigation ul li, -.nav-aligned-center .main-navigation ul li { - letter-spacing: normal; -} -.nav-aligned-left.nav-below-header .main-navigation, -.nav-aligned-left.nav-above-header .main-navigation { - text-align: left; -} -.nav-aligned-center.nav-below-header .main-navigation, -.nav-aligned-center.nav-above-header .main-navigation { - text-align: center; -} -.nav-aligned-right.nav-below-header .main-navigation, -.nav-aligned-right.nav-above-header .main-navigation { - text-align: right; -} -.main-navigation ul li .dropdown-toggle, -.secondary-navigation ul li .dropdown-toggle { - display: none; -} -.menu-item-has-children .dropdown-menu-toggle { - display: inline-block; - height: 100%; - clear: both; - padding-left: 10px; -} -nav ul ul .menu-item-has-children .dropdown-menu-toggle { - float: right; -} -nav:not(.toggled):not(.slideout-navigation) ul ul .menu-item-has-children .dropdown-menu-toggle { - padding-right: 15px; -} -.sidebar .menu-item-has-children .dropdown-menu-toggle { - float: right; -} -.dropdown-menu-toggle:before { - content: "\f107"; - font-family: FontAwesome; - line-height: 1em; - speak: none; -} -.dropdown-click .menu-item-has-children.sfHover > a .dropdown-menu-toggle:before { - content: "\f106"; -} -.dropdown-hover .sub-menu .dropdown-menu-toggle:before, -.dropdown-hover .children .dropdown-menu-toggle:before { - content: "\f105"; -} -.dropdown-hover.both-right .inside-left-sidebar .dropdown-menu-toggle:before, -.dropdown-hover .inside-right-sidebar .dropdown-menu-toggle:before { - content: "\f104"; -} -.dropdown-hover.both-left .inside-right-sidebar .dropdown-menu-toggle:before, -.dropdown-hover .inside-left-sidebar .dropdown-menu-toggle:before { - content: "\f105"; -} -.dropdown-click .main-navigation ul ul ul, -.dropdown-click .secondary-navigation ul ul ul { - left: 0; - top: auto; - position: relative; -} -.dropdown-click.both-right .widget-area .secondary-navigation ul ul, -.dropdown-click.right-sidebar .widget-area .secondary-navigation ul ul, -.dropdown-click.both-sidebars .widget-area .inside-right-sidebar .secondary-navigation ul ul { - right: 0; -} -.dropdown-click .widget-area .main-navigation ul ul, -.dropdown-click .widget-area .secondary-navigation ul ul { - left: 0; - right: 0; - top: auto; - position: relative; - float: none; - width: 100%; -} -.main-navigation .main-nav ul li.menu-item-has-children > a, -.secondary-navigation .main-nav ul li.menu-item-has-children > a { - padding-right: 0; - position: relative; -} -.widget-area .main-navigation li, -.widget-area .secondary-navigation li { - float: none; - display: block; - width: 100%; - padding: 0; - margin: 0; -} -.widget-area .main-navigation ul ul, -.widget-area .secondary-navigation ul ul { - top: 0; - left: 100%; - width: 220px; -} -.dropdown-hover.both-right .widget-area .main-navigation ul ul, -.dropdown-hover.right-sidebar .widget-area .main-navigation ul ul, -.dropdown-hover.both-sidebars .widget-area .inside-right-sidebar .main-navigation ul ul { - right: 100%; - left: auto; -} -.slideout-navigation .dropdown-menu-toggle:before { - content: "\f107" !important; -} -.slideout-navigation .sfHover > a .dropdown-menu-toggle:before { - content: "\f106" !important; -} -/* =Content ------------------------------------------------ */ -.post { - margin: 0 0 2em; -} -.posted-on .updated { - display: none; -} -.byline { - display: inline; -} -.single .byline, -.group-blog .byline { - display: inline; -} -.page-content, -.entry-content, -.entry-summary { - margin: 2em 0 0; -} -.page-links { - clear: both; - margin: 0 0 1.5em; -} -.blog .format-status .entry-title, -.archive .format-status .entry-title, -.blog .format-aside .entry-header, -.archive .format-aside .entry-header, -.blog .format-status .entry-header, -.archive .format-status .entry-header, -.blog .format-status .entry-meta, -.archive .format-status .entry-meta { - display: none; -} -.blog .format-aside .entry-content, -.archive .format-aside .entry-content, -.blog .format-status .entry-content, -.archive .format-status .entry-content { - margin-top: 0; -} -.blog .format-status .entry-content p:last-child, -.archive .format-status .entry-content p:last-child { - margin-bottom: 0; -} -/* =Media ------------------------------------------------ */ -.page-content img.wp-smiley, -.entry-content img.wp-smiley, -.comment-content img.wp-smiley { - border: none; - margin-bottom: 0; - margin-top: 0; - padding: 0; -} -.wp-caption { - margin-bottom: 1.5em; - max-width: 100%; - position: relative; -} -.wp-caption img[class*="wp-image-"] { - display: block; - margin: 0 auto 0; - max-width: 100%; -} -.wp-caption .wp-caption-text { - font-size: 75%; - padding-top: 5px; - opacity: 0.8; -} -.wp-caption img { - position: relative; - vertical-align: bottom; -} -/*-------------------------------------------------------------- -## Galleries ---------------------------------------------------------------*/ -.gallery { - margin-bottom: 1.5em; -} -.gallery-item { - display: inline-block; - text-align: center; - vertical-align: top; - width: 100%; -} -.gallery-columns-2 .gallery-item { - max-width: 50%; -} -.gallery-columns-3 .gallery-item { - max-width: 33.33%; -} -.gallery-columns-4 .gallery-item { - max-width: 25%; -} -.gallery-columns-5 .gallery-item { - max-width: 20%; -} -.gallery-columns-6 .gallery-item { - max-width: 16.66%; -} -.gallery-columns-7 .gallery-item { - max-width: 14.28%; -} -.gallery-columns-8 .gallery-item { - max-width: 12.5%; -} -.gallery-columns-9 .gallery-item { - max-width: 11.11%; -} -.gallery-caption { - display: block; -} -/* Make sure embeds and iframes fit their containers */ -embed, -iframe, -object { - max-width: 100%; -} -/* =Navigation ------------------------------------------------ */ -.site-main [class*="navigation"] { - margin: 0 0 2em; - overflow: hidden; -} -/* =Comments ------------------------------------------------ */ -.comment-content a { - word-wrap: break-word; -} -.comment, -.comment-list { - list-style-type: none; - padding: 0; - margin: 0; -} -.comment-author-info { - display: inline-block; - *display: inline; - *zoom: 1; - vertical-align: middle; -} -.comment-meta .avatar { - float: left; - margin-right: 10px; - -moz-border-radius: 50%; - -webkit-border-radius: 50%; - border-radius: 50%; -} -.comment-author cite { - font-style: normal; - font-weight: bold; -} -.entry-meta.comment-metadata { - margin-top: 0; -} -.comment-content { - margin-top: 1.5em; -} -.comment-respond { - margin-top: 1.5em; -} -.comment-form > .form-submit { - margin-bottom: 0; -} -.comment-form input, -.comment-form-comment { - margin-bottom: 10px; -} -.comment-form #author, -.comment-form #email, -.comment-form #url { - display: block; -} -.comment-metadata .edit-link:before { - display: none; -} -.comment-body { - padding: 30px 0; -} -.comment-content { - padding: 30px; - border: 1px solid rgba(0, 0, 0, 0.05); -} -.depth-1.parent > .children { - border-bottom: 1px solid rgba(0, 0, 0, 0.05); -} -.comment .children { - padding-left: 30px; - margin-top: -30px; - border-left: 1px solid rgba(0, 0, 0, 0.05); -} -.pingback .comment-body, -.trackback .comment-body { - border-bottom: 1px solid rgba(0, 0, 0, 0.05); -} -.pingback .edit-link { - font-size: 13px; -} -.comment-content p:last-child { - margin-bottom: 0; -} -.comment-list > .comment:first-child { - padding-top: 0; - margin-top: 0; - border-top: 0; -} -ol.comment-list { - margin-bottom: 1.5em; -} -/* =Widgets ------------------------------------------------ */ -.widget { - margin: 0 0 30px; -} -/* Make sure select elements fit in widgets */ -.widget select { - max-width: 100%; -} -/* Search widget */ -.widget_search .search-submit { - display: none; -} -/* Categories widget */ -.widget_categories .children { - margin-left: 1.5em; - padding-top: 5px; -} -.widget_categories .children li:last-child { - padding-bottom: 0; -} -/* =Infinite Scroll ------------------------------------------------ */ -/* Globally hidden elements when Infinite Scroll is supported and in use. */ -.infinite-scroll .paging-navigation, -.infinite-scroll.neverending .site-footer { - /* Theme Footer (when set to scrolling) */ - display: none; -} -/* When Infinite Scroll has reached its end we need to re-display elements that were hidden (via .neverending) before */ -.infinity-end.neverending .site-footer { - display: block; -} -/* =Start custom CSS ------------------------------------------------ */ -body { - font-size: 15px; -} -a { - -webkit-transition: all 0.1s ease-in-out; - -moz-transition: all 0.1s ease-in-out; - -o-transition: all 0.1s ease-in-out; - transition: all 0.1s ease-in-out; -} -a, -a:visited, -a:hover, -a:focus { - text-decoration: none; -} -.main-title { - word-wrap: break-word; -} -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: inherit; - font-size: 100%; - font-style: inherit; - font-weight: inherit; -} -pre { - background: rgba(0, 0, 0, 0.05); - font-family: inherit; - font-size: inherit; - line-height: normal; - margin-bottom: 1.5em; - padding: 20px; - overflow: auto; - max-width: 100%; -} -blockquote { - border-left: 5px solid rgba(0, 0, 0, 0.05); - padding: 20px; - font-size: 1.2em; - font-style: italic; - margin: 0 0 1.5em; - position: relative; -} -blockquote p:last-child { - margin: 0; -} -table, -th, -td { - border: 1px solid rgba(0, 0, 0, 0.1); -} -table { - border-collapse: separate; - border-spacing: 0; - border-width: 1px 0 0 1px; - margin: 0 0 1.5em; - width: 100%; -} -th, -td { - padding: 8px; -} -th { - border-width: 0 1px 1px 0; -} -td { - border-width: 0 1px 1px 0; -} -hr { - background-color: rgba(0, 0, 0, 0.1); - border: 0; - height: 1px; - margin-bottom: 40px; - margin-top: 40px; -} -fieldset { - padding: 0; - border: 0; - min-width: inherit; -} -fieldset legend { - padding: 0; - margin-bottom: 1.5em; -} -.site-main .gallery { - margin-bottom: 1.5em; -} -.gallery-item img { - vertical-align: bottom; -} -.gallery-icon { - padding: 5px; -} -.separate-containers .inside-article, -.separate-containers .widget, -.separate-containers .comments-area, -.separate-containers .page-header, -.separate-containers .paging-navigation { - padding: 40px; -} -.one-container .comments-area { - margin-top: 1.5em; -} -h1 { - font-size: 35px; - margin-bottom: 20px; - line-height: 1.2em; -} -h2 { - font-size: 25px; - margin-bottom: 20px; - line-height: 1.2em; -} -h3 { - font-size: 20px; - margin-bottom: 20px; - line-height: 1.2em; -} -h4, -h5, -h6 { - margin-bottom: 20px; -} -/* Full width inner elements */ -.inside-navigation:not(.grid-container):after, -.inside-navigation:not(.grid-container):before, -.inside-header:not(.grid-container):after, -.inside-header:not(.grid-container):before, -.inside-footer-widgets:not(.grid-container):after, -.inside-footer-widgets:not(.grid-container):before { - content: "."; - display: block; - overflow: hidden; - visibility: hidden; - font-size: 0; - line-height: 0; - width: 0; - height: 0; - clear: both; -} -/* Layout spacing */ -.one-container.both-left .inside-left-sidebar { - margin-right: 15px; -} -.one-container.both-left .inside-right-sidebar { - margin-left: 15px; -} -.one-container.both-right .inside-left-sidebar { - margin-right: 15px; -} -.one-container.both-right .inside-right-sidebar { - margin-left: 15px; -} -.site-content { - word-wrap: break-word; -} -.separate-containers .site-main > *:last-child, -.one-container .site-main > *:last-child { - margin-bottom: 0; -} -.one-container .site-main { - margin-top: 0; - margin-bottom: 0; -} -.one-container .site-main { - margin-top: 0; - margin-left: 0; - margin-right: 0; -} -.one-container .inside-right-sidebar, -.one-container .inside-left-sidebar { - margin-top: 0; -} -.one-container .inside-article { - padding: 0 0 30px 0; -} -.one-container.page .inside-article { - padding-bottom: 0; -} -.page-content > *:last-child, -.entry-content > *:last-child, -.entry-summary > *:last-child { - margin-bottom: 0; -} -/* Widget styling */ -.sidebar .widget *:last-child, -.footer-widgets .widget *:last-child { - margin-bottom: 0; -} -.widget { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; -} -.widget-title { - margin-bottom: 30px; - font-size: 20px; - line-height: 1.5; -} -.widget ul, -.widget ol { - margin: 0; -} -.widget ul li { - list-style-type: none; - position: relative; - padding-bottom: 5px; -} -.widget ul li ul li:before { - opacity: .7; -} -.widget .search-field { - width: 100%; -} -.widget:last-child, -.separate-containers .widget:last-child { - margin-bottom: 0; -} -.widget_nav_menu ul ul, -.widget_pages ul ul { - margin-left: 1em; - margin-top: 5px; -} -.widget ul li.menu-item-has-children, -.widget ul li.menu-item-has-children, -.widget ul li.page_item_has_children, -.widget ul li.page_item_has_children { - padding-bottom: 0; -} -.header-widget .widget-title { - margin-bottom: 15px; -} -#wp-calendar { - table-layout: fixed; - font-size: 80%; -} -#wp-calendar #prev, -#wp-calendar #prev + .pad { - border-right: 0; -} -.sidebar .grid-container { - max-width: 100%; - width: 100%; -} -.footer-widgets { - padding: 40px 0; -} -.inside-footer-widgets .inner-padding { - padding: 0 40px; -} -.site-info { - text-align: center; -} -/* Footer bar */ -.footer-bar-active .footer-bar .widget { - padding: 0; -} -.footer-bar .widget_nav_menu > div > ul { - display: inline-block; - vertical-align: top; -} -/* Footer bar aligned right */ -.footer-bar-align-right .copyright-bar { - float: left; -} -.footer-bar-align-right .footer-bar { - float: right; - text-align: right; -} -/* Footer bar aligned left */ -.footer-bar-align-left .copyright-bar { - float: right; - text-align: right; -} -.footer-bar-align-left .footer-bar { - float: left; -} -/* Footer bar aligned center */ -.footer-bar-align-center .copyright-bar { - float: none; - text-align: center; -} -.footer-bar-align-center .footer-bar { - float: none; - text-align: center; - margin-bottom: 10px; -} -/* Footer bar menu */ -.footer-bar .widget_nav_menu li { - margin: 0 10px; - float: left; - padding: 0; -} -.footer-bar .widget_nav_menu li:first-child { - margin-left: 0; -} -.footer-bar .widget_nav_menu li:last-child { - margin-right: 0; -} -.footer-bar .widget_nav_menu li ul { - display: none; -} -/* Posts */ -.entry-title { - margin-bottom: 0; -} -.entry-header { - word-wrap: break-word; -} -.page-header { - margin-bottom: 30px; -} -.page-header h1 { - font-size: 25px; -} -.page-header .avatar { - float: left; - margin-right: 1.5em; -} -.page-header .author-info { - overflow: hidden; -} -.page-header > *:last-child { - margin-bottom: 0; -} -.entry-meta { - font-size: 85%; - margin-top: .5em; - line-height: 1.5; -} -footer.entry-meta { - margin-top: 2em; -} -footer.entry-meta .author:before, -footer.entry-meta .posted-on:before, -.cat-links:before, -.tags-links:before, -.comments-link:before, -.nav-previous .prev:before, -.nav-next .next:before { - font-family: FontAwesome; - font-weight: normal; - font-style: normal; - display: inline-block; - text-decoration: inherit; - position: relative; - margin-right: 0.6em; - width: 13px; - text-align: center; - speak: none; -} -footer.entry-meta .author:before { - content: "\f007"; -} -footer.entry-meta .posted-on:before { - content: "\f073"; -} -.cat-links:before { - content: "\f07b"; -} -.tags-links:before { - content: "\f02c"; -} -.comments-link:before { - content: "\f086"; -} -.nav-previous .prev:before { - content: "\f104"; -} -.nav-next .next:before { - content: "\f105"; -} -.cat-links, -.tags-links, -.comments-link, -footer.entry-meta .posted-on, -footer.entry-meta .byline { - display: block; -} -.taxonomy-description p:last-child { - margin-bottom: 0; -} -.paging-navigation:before, -.paging-navigation:after { - content: "."; - display: block; - overflow: hidden; - visibility: hidden; - font-size: 0; - line-height: 0; - width: 0; - height: 0; -} -.paging-navigation:after { - clear: both; -} -.paging-navigation .nav-previous, -.paging-navigation .nav-next { - display: none; -} -.comment-respond { - margin-top: 0; -} -.read-more-container { - margin-bottom: 0; -} -.site-main .post-navigation { - margin-bottom: 0; -} -/* Site header */ -.main-title { - margin: 0; - font-size: 50px; - line-height: 1.2em; -} -.site-logo { - display: inline-block; - *display: inline; - *zoom: 1; - max-width: 100%; -} -.site-description { - margin: 0; - line-height: 1.5; -} -.header-widget { - float: right; - overflow: hidden; - max-width: 50%; -} -.header-widget .widget { - padding: 0 0 20px; - margin-bottom: 0; -} -.header-widget .widget:last-child { - padding-bottom: 0; -} -.nav-float-right .header-widget .widget { - padding: 0 0 10px; -} -.nav-float-right .header-widget .widget:last-child { - padding-bottom: 0; -} -.nav-float-right .header-widget { - position: relative; - top: -10px; -} -.post-image { - margin: 2em 0 0; -} -/* Page Header Add-on */ -.page-header-image, -.page-header-image-single { - line-height: 0; - /* no more weird spacing */ -} -.separate-containers .page-header-image, -.separate-containers .page-header-content { - margin-top: 30px; -} -.inside-page-header { - padding: 40px; -} -.separate-containers .page-header-image-single, -.separate-containers .page-header-content-single { - margin-top: 30px; -} -.separate-containers .inside-article .page-header-image-single, -.separate-containers .inside-article .page-header-content-single, -.one-container .inside-article .page-header-image-single, -.one-container .inside-article .page-header-content-single, -.separate-containers .inside-article .page-header-image, -.separate-containers .inside-article .page-header-content, -.one-container .inside-article .page-header-image, -.one-container .inside-article .page-header-content { - margin-bottom: 2em; - margin-top: 0; -} -.inside-article .page-header-image-single.page-header-below-title { - margin-top: 2em; -} -/* Full width template */ -.full-width-content .container.grid-container { - max-width: 100%; -} -.full-width-content.no-sidebar.separate-containers .site-main { - margin: 0; -} -.full-width-content.separate-containers .inside-article, -.full-width-content.one-container .site-content { - padding: 0; -} -/* WooCommerce */ -.woocommerce .page-header-image-single { - display: none; -} -.woocommerce .entry-content, -.woocommerce .product .entry-summary { - margin-top: 0; -} -.related.products { - clear: both; -} -.checkout-subscribe-prompt.clear { - visibility: visible; - height: initial; - width: initial; -} -/* bbPress */ -#bbpress-forums ul.bbp-lead-topic, -#bbpress-forums ul.bbp-topics, -#bbpress-forums ul.bbp-forums, -#bbpress-forums ul.bbp-replies, -#bbpress-forums ul.bbp-search-results, -#bbpress-forums, -div.bbp-breadcrumb, -div.bbp-topic-tags { - font-size: inherit; -} -.single-forum #subscription-toggle { - display: block; - margin: 1em 0; - clear: left; -} -#bbpress-forums .bbp-search-form { - margin-bottom: 10px; -} -.bbp-login-form fieldset { - border: 0; - padding: 0; -} -/* BuddyPress */ -#buddypress form#whats-new-form #whats-new-options[style] { - min-height: 6rem; - overflow: visible; -} -/* SiteOrigin Page Builder */ -.so-panel.widget { - padding: 0; -} -/* Beaver Builder */ -.fl-builder.no-sidebar .container.grid-container { - max-width: 100%; -} -.fl-builder.one-container.no-sidebar .site-content { - padding: 0; -} -/* MailChimp CSS */ -#mc_embed_signup .clear { - display: block; - height: auto; - visibility: visible; - width: auto; -} -/* Bootstrap fix */ -.container.grid-container { - width: auto; -} -/* Menu class for items to float right */ -.sf-menu > li.menu-item-float-right { - float: right !important; -} -/* Back to top icon */ -.stylepress-back-to-top, -.stylepress-back-to-top:visited { - font-size: 20px; - background: rgba(0, 0, 0, 0.4); - color: #FFF; - border-radius: 3px; - position: fixed; - bottom: 30px; - right: 30px; - line-height: 40px; - width: 40px; - text-align: center; - z-index: 10; -} -.stylepress-back-to-top:hover, -.stylepress-back-to-top:focus { - background: rgba(0, 0, 0, 0.6); - color: #FFF; -} -.stylepress-back-to-top .screen-reader-text { - left: 0; -} -/* Mobile menu */ -.menu-toggle, -.mobile-bar-items { - display: none; - cursor: pointer; -} -/* - * Backwards compatibility until Slideout is updated - * GP Premium 1.2.93 - */ -.slideout-navigation .menu-item-has-children .dropdown-menu-toggle { - float: right; -} -body { - background-color: #FFF; - color: #3a3a3a; -} -a, -a:visited { - color: #1e73be; - text-decoration: none; -} -a:hover, -a:focus, -a:active { - color: #000000; - text-decoration: none; -} -body .grid-container { - max-width: 1100px; -} -.site-header { - background-color: #ffffff; - color: #3a3a3a; -} -.site-header a, -.site-header a:visited { - color: #3a3a3a; -} -.main-title a, -.main-title a:hover, -.main-title a:visited { - color: #222222; -} -.site-description { - color: #999999; -} -.main-navigation, -.main-navigation ul ul { - background-color: rgba(239, 239, 239, 0.44); -} -.main-navigation .main-nav ul li a, -.menu-toggle { - color: #000; -} -.main-navigation .main-nav ul li > a:hover, -.main-navigation .main-nav ul li > a:focus, -.main-navigation .main-nav ul li.sfHover > a { - color: #000; - background-color: #eaeaea; -} -button.menu-toggle:hover, -button.menu-toggle:focus, -.main-navigation .mobile-bar-items a, -.main-navigation .mobile-bar-items a:hover, -.main-navigation .mobile-bar-items a:focus { - color: #ffffff; -} -.main-navigation .main-nav ul li[class*="current-menu-"] > a { - color: #000; - background-color: #eaeaea; -} -.main-navigation .main-nav ul li[class*="current-menu-"] > a:hover, -.main-navigation .main-nav ul li[class*="current-menu-"].sfHover > a { - color: #000; - background-color: #eaeaea; -} -.main-navigation ul ul { - background-color: #eaeaea; -} -.main-navigation .main-nav ul ul li a { - color: #ffffff; -} -.main-navigation .main-nav ul ul li > a:hover, -.main-navigation .main-nav ul ul li > a:focus, -.main-navigation .main-nav ul ul li.sfHover > a { - color: #000; - background-color: #eaeaea; -} -.main-navigation .main-nav ul ul li[class*="current-menu-"] > a { - color: #000; - background-color: #eaeaea; -} -.main-navigation .main-nav ul ul li[class*="current-menu-"] > a:hover, -.main-navigation .main-nav ul ul li[class*="current-menu-"].sfHover > a { - color: #000; - background-color: #eaeaea; -} -.separate-containers .inside-article, -.separate-containers .comments-area, -.separate-containers .page-header, -.one-container .container, -.separate-containers .paging-navigation, -.inside-page-header { - background-color: rgba(239, 239, 239, 0.44); -} -.entry-meta { - color: #888888; -} -.entry-meta a, -.entry-meta a:visited { - color: #666666; -} -.entry-meta a:hover { - color: #1e73be; -} -.sidebar .widget { - background-color: rgba(239, 239, 239, 0.44); -} -.sidebar .widget .widget-title { - color: #000000; -} -.footer-widgets { - background-color: #ffffff; -} -.footer-widgets .widget-title { - color: #000000; -} -.site-info { - color: #000; - background-color: rgba(239, 239, 239, 0.44); -} -.site-info a, -.site-info a:visited { - color: #ffffff; -} -.site-info a:hover { - color: #606060; -} -.footer-bar .widget_nav_menu .current-menu-item a { - color: #606060; -} -input[type="text"], -input[type="email"], -input[type="url"], -input[type="password"], -input[type="search"], -textarea { - color: #666666; - background-color: #fafafa; - border-color: #cccccc; -} -input[type="text"]:focus, -input[type="email"]:focus, -input[type="url"]:focus, -input[type="password"]:focus, -input[type="search"]:focus, -textarea:focus { - color: #666666; - background-color: #ffffff; - border-color: #bfbfbf; -} -button, -html input[type="button"], -input[type="reset"], -input[type="submit"], -.button, -.button:visited { - color: #ffffff; - background-color: #666666; -} -button:hover, -html input[type="button"]:hover, -input[type="reset"]:hover, -input[type="submit"]:hover, -.button:hover, -button:focus, -html input[type="button"]:focus, -input[type="reset"]:focus, -input[type="submit"]:focus, -.button:focus { - color: #666666; - background-color: #eaeaea; -} -.main-navigation ul ul { - top: auto; -} -@media (max-width: 768px) { - .separate-containers .inside-article, - .separate-containers .comments-area, - .separate-containers .page-header, - .separate-containers .paging-navigation, - .one-container .site-content { - padding: 30px; - } -} diff --git a/assets/css/theme-overwrites.less b/assets/css/theme-overwrites.less deleted file mode 100644 index f8001fa..0000000 --- a/assets/css/theme-overwrites.less +++ /dev/null @@ -1,2036 +0,0 @@ -/* =Reset --------------------------------------------------------------- */ - -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, font, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td { - border: 0; - margin: 0; - outline: 0; - padding: 0; -} - -html { - font-family: sans-serif; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} - -article, -aside, -details, -figcaption, -figure, -footer, -header, -main, -nav, -section { - display: block; -} - -audio, -canvas, -progress, -video { - display: inline-block; - vertical-align: baseline; -} - -audio:not([controls]) { - display: none; - height: 0; -} - -[hidden], -template { - display: none; -} - -ol, ul { - list-style: none; -} - -table { /* tables still need 'cellspacing="0"' in the markup */ - border-collapse: separate; - border-spacing: 0; -} - -caption, th, td { - font-weight: normal; - text-align: left; - padding: 5px; -} - -blockquote:before, blockquote:after, -q:before, q:after { - content: ""; -} - -blockquote, q { - quotes: "" ""; -} - -a { - background-color: transparent; -} - -a:active, -a:hover { - outline: 0; -} - -a img { - border: 0; -} - -/* =Global ------------------------------------------------ */ - -body, -button, -input, -select, -textarea { - font-family: sans-serif; - font-size: 16px; - font-size: 1.6rem; - line-height: 1.5; - -webkit-transition: all 0.1s ease-in-out; - -moz-transition: all 0.1s ease-in-out; - -o-transition: all 0.1s ease-in-out; - transition: all 0.1s ease-in-out; -} - -hr { - background-color: #ccc; - border: 0; - height: 1px; - margin-bottom: 40px; - margin-top: 40px; -} - -/* Text elements */ -p { - margin-bottom: 1.5em; -} - -ul, ol { - margin: 0 0 1.5em 3em; -} - -ul { - list-style: disc; -} - -ol { - list-style: decimal; -} - -li > ul, -li > ol { - margin-bottom: 0; - margin-left: 1.5em; -} - -dt { - font-weight: bold; -} - -dd { - margin: 0 1.5em 1.5em; -} - -b, strong { - font-weight: bold; -} - -dfn, cite, em, i { - font-style: italic; -} - -blockquote { - margin: 0 1.5em 1.5em; -} - -address { - margin: 0 0 1.5em; -} - -pre { - background: #eee; - font-family: "Courier 10 Pitch", Courier, monospace; - font-size: 15px; - font-size: 1.5rem; - line-height: 1.6; - margin-bottom: 1.6em; - padding: 1.6em; - overflow: auto; - max-width: 100%; -} - -code, kbd, tt, var { - font: 15px Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; -} - -abbr, acronym { - border-bottom: 1px dotted #666; - cursor: help; -} - -mark, ins { - text-decoration: none; -} - -sup, -sub { - font-size: 75%; - height: 0; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - bottom: 1ex; -} - -sub { - top: .5ex; -} - -small { - font-size: 75%; -} - -big { - font-size: 125%; -} - -figure { - margin: 0; -} - -table { - margin: 0 0 1.5em; - width: 100%; -} - -th { - font-weight: bold; -} - -img { - height: auto; /* Make sure images are scaled correctly. */ - max-width: 100%; /* Adhere to container width. */ -} - -button, -input, -select, -textarea { - font-size: 100%; /* Corrects font size not being inherited in all browsers */ - margin: 0; /* Addresses margins set differently in IE6/7, F3/4, S5, Chrome */ - vertical-align: baseline; /* Improves appearance and consistency in all browsers */ - *vertical-align: middle; /* Improves appearance and consistency in all browsers */ -} - -button, -input { - line-height: normal; /* Addresses FF3/4 setting line-height using !important in the UA stylesheet */ -} - -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - border: 0; - background: #666; - cursor: pointer; /* Improves usability and consistency of cursor style between image-type 'input' and others */ - -webkit-appearance: button; /* Corrects inability to style clickable 'input' types in iOS */ - padding: 10px 20px; - color: #FFF; -} - -button:hover, -html input[type="button"]:hover, -input[type="reset"]:hover, -input[type="submit"]:hover { - background: #606060; -} - -button:focus, -html input[type="button"]:focus, -input[type="reset"]:focus, -input[type="submit"]:focus, -button:active, -html input[type="button"]:active, -input[type="reset"]:active, -input[type="submit"]:active { - background: #606060; -} - -.button { - padding: 10px 20px; - display: inline-block; - *display: inline; -} - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; /* Addresses box sizing set to content-box in IE8/9 */ - padding: 0; /* Addresses excess padding in IE8/9 */ -} - -input[type="search"] { - -webkit-appearance: textfield; /* Addresses appearance set to searchfield in S5, Chrome */ - -webkit-box-sizing: content-box; /* Addresses box sizing set to border-box in S5, Chrome (include -moz to future-proof) */ - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -input[type="search"]::-webkit-search-decoration { /* Corrects inner padding displayed oddly in S5, Chrome on OSX */ - -webkit-appearance: none; -} - -button::-moz-focus-inner, -input::-moz-focus-inner { /* Corrects inner padding and border displayed oddly in FF3/4 www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/ */ - border: 0; - padding: 0; -} - -input[type="text"], -input[type="email"], -input[type="url"], -input[type="password"], -input[type="search"], -input[type="tel"], -textarea { - background: #FAFAFA; - color: #666; - border: 1px solid #ccc; - border-radius: 0px; - padding: 10px 15px; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - max-width: 100%; -} - -input[type="text"]:focus, -input[type="email"]:focus, -input[type="url"]:focus, -input[type="password"]:focus, -input[type="tel"]:focus, -input[type="search"]:focus, -textarea:focus { - color: #111; - background: #FFF; -} - -textarea { - overflow: auto; /* Removes default vertical scrollbar in IE6/7/8/9 */ - vertical-align: top; /* Improves readability and alignment in all browsers */ - width: 100%; -} - -input[type="file"] { - max-width: 100%; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} - -/* Alignment */ -.alignleft { - display: inline; - float: left; - margin-right: 1.5em; -} - -.alignright { - display: inline; - float: right; - margin-left: 1.5em; -} - -.aligncenter { - clear: both; - display: block; - margin: 0 auto; -} - -.size-auto, -.size-full, -.size-large, -.size-medium, -.size-thumbnail { - max-width: 100%; - height: auto; -} - -/* Text meant only for screen readers */ -.screen-reader-text { - clip: rect(1px, 1px, 1px, 1px); - position: absolute !important; -} - -.screen-reader-text:hover, -.screen-reader-text:active, -.screen-reader-text:focus { - background-color: #f1f1f1; - border-radius: 3px; - box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6); - clip: auto !important; - color: #21759b; - display: block; - font-size: 14px; - font-weight: bold; - height: auto; - left: 5px; - line-height: normal; - padding: 15px 23px 14px; - text-decoration: none; - top: 5px; - width: auto; - z-index: 100000; /* Above WP toolbar */ -} - -/* Clearing */ -.clear:before, -.clear:after, -[class*="content"]:before, -[class*="content"]:after, -[class*="site"]:before, -[class*="site"]:after { - content: ''; - display: table; -} - -.clear:after, -[class*="content"]:after, -[class*="site"]:after { - clear: both; -} - -/* =Menu ------------------------------------------------ */ - -.main-navigation { - z-index: 100; -} - -.main-navigation { - padding: 0; -} - -.main-navigation ul li a { - display: block; -} - -.menu-toggle { - margin: 0; - padding: 0; -} - -.menu-toggle:before { - content: "\f0c9"; - font-family: FontAwesome; - line-height: 1em; - speak: none; -} - -.toggled .menu-toggle:before { - content: "\f00d"; - speak: none; -} - -.menu-toggle .mobile-menu { - margin-left: 10px; -} - -.menu-toggle .mobile-menu:empty { - display: none; -} - -.main-navigation .main-nav ul ul li a { - line-height: normal; - padding: 10px 20px; -} - -.main-navigation { - clear: both; - display: block; -} - -.inside-navigation { - position: relative; -} - -.main-navigation ul, -.menu-toggle li.search-item { - list-style: none; - margin: 0; - padding-left: 0; -} - -.search-item .screen-reader-text { - top: 0; - right: 0; - left: auto; -} - -.main-navigation li { - float: left; - position: relative; -} - -.main-navigation a { - display: block; - text-decoration: none; -} - -.main-navigation ul ul { - box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1); - display: none; - float: left; - position: absolute; - left: 0; - z-index: 99999; - width: 200px; - text-align: left; - top: auto; -} - -.main-navigation ul ul ul { - left: 100%; - top: 0; -} - -.main-navigation ul ul a { - display: block; -} - -.main-navigation ul ul li { - width: 100%; -} - -.main-navigation ul li:hover > ul, -.main-navigation ul li.sfHover > ul, -.secondary-navigation ul li:hover > ul, -.secondary-navigation ul li.sfHover > ul { - display: block; -} - -.dropdown-click .main-navigation ul li:hover > ul, -.dropdown-click .main-navigation ul li.sfHover > ul, -.dropdown-click .secondary-navigation ul li:hover > ul, -.dropdown-click .secondary-navigation ul li.sfHover > ul { - display: none; -} - -.dropdown-click .main-navigation ul.toggled-on, -.dropdown-click .main-navigation ul li:hover > ul.toggled-on, -.dropdown-click .main-navigation ul li.sfHover > ul.toggled-on, -.dropdown-click .secondary-navigation ul.toggled-on, -.dropdown-click .secondary-navigation ul li:hover > ul.toggled-on, -.dropdown-click .secondary-navigation ul li.sfHover > ul.toggled-on { - display: block; -} - -.dropdown-click nav ul ul ul { - background-color: transparent; -} - -.nav-float-right .inside-header .main-navigation { - float: right; - clear: right; -} - -.nav-float-left .inside-header .main-navigation { - float: left; - clear: left; -} - -.nav-float-left .inside-header .site-branding, -.nav-float-left .inside-header .site-logo { - float: right; - clear: right; -} - -.nav-float-left .inside-header:after { - clear: both; - content: ''; - display: table; -} - -.nav-float-right .inside-header .site-branding { - display: inline-block; -} - -.site-header { - position: relative; -} - -.header-aligned-left .site-header { - text-align: left; -} - -.header-aligned-center .site-header { - text-align: center; -} - -.header-aligned-right .site-header { - text-align: right; -} - -.site-header .header-image { - vertical-align: middle; -} - -.main-navigation .main-nav ul ul li a, -.nav-float-right .main-navigation .main-nav ul ul li a { - line-height: normal; -} - -.nav-float-right .main-navigation ul ul ul { - top: 0 -} - -.main-navigation li.search-item { - float: right; - z-index: 21; -} - -.rtl .main-navigation li.search-item, -.rtl.nav-aligned-right.nav-below-header .main-navigation .menu > li.search-item { - float: left; -} - -.nav-aligned-center .main-navigation li.search-item.current-menu-item { - position: absolute; - right: 0; -} - -.rtl.nav-aligned-center .main-navigation li.search-item.current-menu-item { - position: absolute; - left: 0; -} - -.main-navigation li.search-item i { - transform: rotate(90deg); -} - -.navigation-search { - position: absolute; - right: 0; - display: none; - z-index: 20; - width: 100%; - top: 0; -} - -.gen-sidebar-nav .navigation-search { - top: auto; - bottom: 0; -} - -.navigation-search input { - border: 0; - vertical-align: bottom; - line-height: 0; - opacity: 0.9; - width: 100%; - z-index: 20; - border-radius: 0; - -webkit-appearance: none; -} - -.navigation-search input::-ms-clear { - display: none; - width: 0; - height: 0; -} - -.navigation-search input::-ms-reveal { - display: none; - width: 0; - height: 0; -} - -.navigation-search input::-webkit-search-decoration, -.navigation-search input::-webkit-search-cancel-button, -.navigation-search input::-webkit-search-results-button, -.navigation-search input::-webkit-search-results-decoration { - display: none; -} - -.nav-left-sidebar .main-navigation li.search-item, -.nav-right-sidebar .main-navigation li.search-item { - width: auto; - display: inline-block; -} - -.nav-left-sidebar .main-navigation li.search-item.current-menu-item, -.nav-right-sidebar .main-navigation li.search-item.current-menu-item { - float: right; -} - -.navigation-search input:focus { - outline: 0; -} - -.nav-aligned-right.nav-below-header .main-navigation .menu > li, -.nav-aligned-right.nav-above-header .main-navigation .menu > li, -.nav-aligned-center.nav-below-header .main-navigation .menu > li, -.nav-aligned-center.nav-above-header .main-navigation .menu > li { - float: none; - display: inline-block; - *display: inline; - *zoom: 1; -} - -.nav-aligned-right .main-navigation ul, -.nav-aligned-center .main-navigation ul { - letter-spacing: -0.31em; - font-size: 1em; -} - -.nav-aligned-right .main-navigation ul li, -.nav-aligned-center .main-navigation ul li { - letter-spacing: normal; -} - -.nav-aligned-left.nav-below-header .main-navigation, -.nav-aligned-left.nav-above-header .main-navigation { - text-align: left; -} - -.nav-aligned-center.nav-below-header .main-navigation, -.nav-aligned-center.nav-above-header .main-navigation { - text-align: center; -} - -.nav-aligned-right.nav-below-header .main-navigation, -.nav-aligned-right.nav-above-header .main-navigation { - text-align: right; -} - -.main-navigation ul li .dropdown-toggle, -.secondary-navigation ul li .dropdown-toggle { - display: none; -} - -.menu-item-has-children .dropdown-menu-toggle { - display: inline-block; - height: 100%; - clear: both; - padding-left: 10px; -} - -nav ul ul .menu-item-has-children .dropdown-menu-toggle { - float: right; -} - -nav:not(.toggled):not(.slideout-navigation) ul ul .menu-item-has-children .dropdown-menu-toggle { - padding-right: 15px; -} - -.sidebar .menu-item-has-children .dropdown-menu-toggle { - float: right; -} - -.dropdown-menu-toggle:before { - content: "\f107"; - font-family: FontAwesome; - line-height: 1em; - speak: none; -} - -.dropdown-click .menu-item-has-children.sfHover > a .dropdown-menu-toggle:before { - content: "\f106"; -} - -.dropdown-hover .sub-menu .dropdown-menu-toggle:before, -.dropdown-hover .children .dropdown-menu-toggle:before { - content: "\f105"; -} - -.dropdown-hover.both-right .inside-left-sidebar .dropdown-menu-toggle:before, -.dropdown-hover .inside-right-sidebar .dropdown-menu-toggle:before { - content: "\f104"; -} - -.dropdown-hover.both-left .inside-right-sidebar .dropdown-menu-toggle:before, -.dropdown-hover .inside-left-sidebar .dropdown-menu-toggle:before { - content: "\f105"; -} - -.dropdown-click .main-navigation ul ul ul, -.dropdown-click .secondary-navigation ul ul ul { - left: 0; - top: auto; - position: relative; -} - -.dropdown-click.both-right .widget-area .secondary-navigation ul ul, -.dropdown-click.right-sidebar .widget-area .secondary-navigation ul ul, -.dropdown-click.both-sidebars .widget-area .inside-right-sidebar .secondary-navigation ul ul { - right: 0; -} - -.dropdown-click .widget-area .main-navigation ul ul, -.dropdown-click .widget-area .secondary-navigation ul ul { - left: 0; - right: 0; - top: auto; - position: relative; - float: none; - width: 100%; -} - -.main-navigation .main-nav ul li.menu-item-has-children > a, -.secondary-navigation .main-nav ul li.menu-item-has-children > a { - padding-right: 0; - position: relative; -} - -.widget-area .main-navigation li, -.widget-area .secondary-navigation li { - float: none; - display: block; - width: 100%; - padding: 0; - margin: 0; -} - -.widget-area .main-navigation ul ul, -.widget-area .secondary-navigation ul ul { - top: 0; - left: 100%; - width: 220px; -} - -.dropdown-hover.both-right .widget-area .main-navigation ul ul, -.dropdown-hover.right-sidebar .widget-area .main-navigation ul ul, -.dropdown-hover.both-sidebars .widget-area .inside-right-sidebar .main-navigation ul ul { - right: 100%; - left: auto; -} - -.slideout-navigation .dropdown-menu-toggle:before { - content: "\f107" !important; -} - -.slideout-navigation .sfHover > a .dropdown-menu-toggle:before { - content: "\f106" !important; -} - -/* =Content ------------------------------------------------ */ - -.sticky { -} - -.post { - margin: 0 0 2em; -} - -.posted-on .updated { - display: none; -} - -.byline { - display: inline; -} - -.single .byline, -.group-blog .byline { - display: inline; -} - -.page-content, -.entry-content, -.entry-summary { - margin: 2em 0 0; -} - -.page-links { - clear: both; - margin: 0 0 1.5em; -} - -.blog .format-status .entry-title, -.archive .format-status .entry-title, -.blog .format-aside .entry-header, -.archive .format-aside .entry-header, -.blog .format-status .entry-header, -.archive .format-status .entry-header, -.blog .format-status .entry-meta, -.archive .format-status .entry-meta { - display: none; -} - -.blog .format-aside .entry-content, -.archive .format-aside .entry-content, -.blog .format-status .entry-content, -.archive .format-status .entry-content { - margin-top: 0; -} - -.blog .format-status .entry-content p:last-child, -.archive .format-status .entry-content p:last-child { - margin-bottom: 0; -} - -/* =Media ------------------------------------------------ */ - -.page-content img.wp-smiley, -.entry-content img.wp-smiley, -.comment-content img.wp-smiley { - border: none; - margin-bottom: 0; - margin-top: 0; - padding: 0; -} - -.wp-caption { - margin-bottom: 1.5em; - max-width: 100%; - position: relative; -} - -.wp-caption img[class*="wp-image-"] { - display: block; - margin: 0 auto 0; - max-width: 100%; -} - -.wp-caption .wp-caption-text { - font-size: 75%; - padding-top: 5px; - opacity: 0.8; -} - -.wp-caption img { - position: relative; - vertical-align: bottom; -} - -/*-------------------------------------------------------------- -## Galleries ---------------------------------------------------------------*/ -.gallery { - margin-bottom: 1.5em; -} - -.gallery-item { - display: inline-block; - text-align: center; - vertical-align: top; - width: 100%; -} - -.gallery-columns-2 .gallery-item { - max-width: 50%; -} - -.gallery-columns-3 .gallery-item { - max-width: 33.33%; -} - -.gallery-columns-4 .gallery-item { - max-width: 25%; -} - -.gallery-columns-5 .gallery-item { - max-width: 20%; -} - -.gallery-columns-6 .gallery-item { - max-width: 16.66%; -} - -.gallery-columns-7 .gallery-item { - max-width: 14.28%; -} - -.gallery-columns-8 .gallery-item { - max-width: 12.5%; -} - -.gallery-columns-9 .gallery-item { - max-width: 11.11%; -} - -.gallery-caption { - display: block; -} - -/* Make sure embeds and iframes fit their containers */ -embed, -iframe, -object { - max-width: 100%; -} - -/* =Navigation ------------------------------------------------ */ - -.site-main [class*="navigation"] { - margin: 0 0 2em; - overflow: hidden; -} - -/* =Comments ------------------------------------------------ */ - -.comment-content a { - word-wrap: break-word; -} - -.bypostauthor { -} - -.comment, -.comment-list { - list-style-type: none; - padding: 0; - margin: 0; -} - -.comment-author-info { - display: inline-block; - *display: inline; - *zoom: 1; - vertical-align: middle; -} - -.comment-meta .avatar { - float: left; - margin-right: 10px; - -moz-border-radius: 50%; - -webkit-border-radius: 50%; - border-radius: 50%; -} - -.comment-author cite { - font-style: normal; - font-weight: bold; -} - -.entry-meta.comment-metadata { - margin-top: 0; -} - -.comment-content { - margin-top: 1.5em; -} - -.comment-respond { - margin-top: 1.5em; -} - -.comment-form > .form-submit { - margin-bottom: 0; -} - -.comment-form input, -.comment-form-comment { - margin-bottom: 10px; -} - -.comment-form #author, -.comment-form #email, -.comment-form #url { - display: block; -} - -.comment-metadata .edit-link:before { - display: none; -} - -.comment-body { - padding: 30px 0; -} - -.comment-content { - padding: 30px; - border: 1px solid rgba(0, 0, 0, 0.05); -} - -.depth-1.parent > .children { - border-bottom: 1px solid rgba(0, 0, 0, 0.05); -} - -.comment .children { - padding-left: 30px; - margin-top: -30px; - border-left: 1px solid rgba(0, 0, 0, 0.05); -} - -.pingback .comment-body, -.trackback .comment-body { - border-bottom: 1px solid rgba(0, 0, 0, 0.05); -} - -.pingback .edit-link { - font-size: 13px; -} - -.comment-content p:last-child { - margin-bottom: 0; -} - -.comment-list > .comment:first-child { - padding-top: 0; - margin-top: 0; - border-top: 0; -} - -ol.comment-list { - margin-bottom: 1.5em; -} - -/* =Widgets ------------------------------------------------ */ - -.widget { - margin: 0 0 30px; -} - -/* Make sure select elements fit in widgets */ -.widget select { - max-width: 100%; -} - -/* Search widget */ -.widget_search .search-submit { - display: none; -} - -/* Categories widget */ -.widget_categories .children { - margin-left: 1.5em; - padding-top: 5px; -} - -.widget_categories .children li:last-child { - padding-bottom: 0; -} - -/* =Infinite Scroll ------------------------------------------------ */ - -/* Globally hidden elements when Infinite Scroll is supported and in use. */ -.infinite-scroll .paging-navigation, /* Older / Newer Posts Navigation (always hidden) */ -.infinite-scroll.neverending .site-footer { /* Theme Footer (when set to scrolling) */ - display: none; -} - -/* When Infinite Scroll has reached its end we need to re-display elements that were hidden (via .neverending) before */ -.infinity-end.neverending .site-footer { - display: block; -} - -/* =Start custom CSS ------------------------------------------------ */ - -body { - font-size: 15px; -} - -a { - -webkit-transition: all 0.1s ease-in-out; - -moz-transition: all 0.1s ease-in-out; - -o-transition: all 0.1s ease-in-out; - transition: all 0.1s ease-in-out; -} - -a, a:visited, a:hover, a:focus { - text-decoration: none; -} - -.main-title { - word-wrap: break-word; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: inherit; - font-size: 100%; - font-style: inherit; - font-weight: inherit; -} - -pre { - background: rgba(0, 0, 0, 0.05); - font-family: inherit; - font-size: inherit; - line-height: normal; - margin-bottom: 1.5em; - padding: 20px; - overflow: auto; - max-width: 100%; -} - -blockquote { - border-left: 5px solid rgba(0, 0, 0, 0.05); - padding: 20px; - font-size: 1.2em; - font-style: italic; - margin: 0 0 1.5em; - position: relative; -} - -blockquote p:last-child { - margin: 0; -} - -table, th, td { - border: 1px solid rgba(0, 0, 0, 0.1); -} - -table { - border-collapse: separate; - border-spacing: 0; - border-width: 1px 0 0 1px; - margin: 0 0 1.5em; - width: 100%; -} - -th, -td { - padding: 8px; -} - -th { - border-width: 0 1px 1px 0; -} - -td { - border-width: 0 1px 1px 0; -} - -hr { - background-color: rgba(0, 0, 0, 0.1); - border: 0; - height: 1px; - margin-bottom: 40px; - margin-top: 40px; -} - -fieldset { - padding: 0; - border: 0; - min-width: inherit; -} - -fieldset legend { - padding: 0; - margin-bottom: 1.5em; -} - -.site-main .gallery { - margin-bottom: 1.5em; -} - -.gallery-item img { - vertical-align: bottom; -} - -.gallery-icon { - padding: 5px; -} - -.separate-containers .inside-article, -.separate-containers .widget, -.separate-containers .comments-area, -.separate-containers .page-header, -.separate-containers .paging-navigation { - padding: 40px; -} - -.one-container .comments-area { - margin-top: 1.5em; -} - -h1 { - font-size: 35px; - margin-bottom: 20px; - line-height: 1.2em; -} - -h2 { - font-size: 25px; - margin-bottom: 20px; - line-height: 1.2em; -} - -h3 { - font-size: 20px; - margin-bottom: 20px; - line-height: 1.2em; -} - -h4, h5, h6 { - margin-bottom: 20px; -} - -/* Full width inner elements */ -.inside-navigation:not(.grid-container):after, -.inside-navigation:not(.grid-container):before, -.inside-header:not(.grid-container):after, -.inside-header:not(.grid-container):before, -.inside-footer-widgets:not(.grid-container):after, -.inside-footer-widgets:not(.grid-container):before { - content: "."; - display: block; - overflow: hidden; - visibility: hidden; - font-size: 0; - line-height: 0; - width: 0; - height: 0; - clear: both; -} - -/* Layout spacing */ -.one-container.both-left .inside-left-sidebar { - margin-right: 15px; -} - -.one-container.both-left .inside-right-sidebar { - margin-left: 15px; -} - -.one-container.both-right .inside-left-sidebar { - margin-right: 15px; -} - -.one-container.both-right .inside-right-sidebar { - margin-left: 15px; -} - -.site-content { - word-wrap: break-word; -} - -.separate-containers .site-main > *:last-child, -.one-container .site-main > *:last-child { - margin-bottom: 0; -} - -.one-container .site-main { - margin-top: 0; - margin-bottom: 0; -} - -.one-container .site-main { - margin-top: 0; - margin-left: 0; - margin-right: 0; -} - -.one-container .inside-right-sidebar, -.one-container .inside-left-sidebar { - margin-top: 0; -} - -.one-container .inside-article { - padding: 0 0 30px 0; -} - -.one-container.page .inside-article { - padding-bottom: 0; -} - -.page-content > *:last-child, -.entry-content > *:last-child, -.entry-summary > *:last-child { - margin-bottom: 0; -} - -/* Widget styling */ -.sidebar .widget *:last-child, -.footer-widgets .widget *:last-child { - margin-bottom: 0; -} - -.widget { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; -} - -.widget-title { - margin-bottom: 30px; - font-size: 20px; - line-height: 1.5; -} - -.widget ul, -.widget ol { - margin: 0; -} - -.widget ul li { - list-style-type: none; - position: relative; - padding-bottom: 5px; -} - -.widget ul li ul li:before { - opacity: .7; -} - -.widget .search-field { - width: 100%; -} - -.widget:last-child, -.separate-containers .widget:last-child { - margin-bottom: 0; -} - -.widget_nav_menu ul ul, -.widget_pages ul ul { - margin-left: 1em; - margin-top: 5px; -} - -.widget ul li.menu-item-has-children, -.widget ul li.menu-item-has-children, -.widget ul li.page_item_has_children, -.widget ul li.page_item_has_children { - padding-bottom: 0; -} - -.header-widget .widget-title { - margin-bottom: 15px; -} - -#wp-calendar { - table-layout: fixed; - font-size: 80%; -} - -#wp-calendar #prev, -#wp-calendar #prev + .pad { - border-right: 0; -} - -.sidebar .grid-container { - max-width: 100%; - width: 100%; -} - -.footer-widgets { - padding: 40px 0; -} - -.inside-footer-widgets .inner-padding { - padding: 0 40px; -} - -.site-info { - text-align: center; -} - -/* Footer bar */ -.footer-bar-active .footer-bar .widget { - padding: 0; -} - -.footer-bar .widget_nav_menu > div > ul { - display: inline-block; - vertical-align: top; -} - -/* Footer bar aligned right */ -.footer-bar-align-right .copyright-bar { - float: left; -} - -.footer-bar-align-right .footer-bar { - float: right; - text-align: right; -} - -/* Footer bar aligned left */ -.footer-bar-align-left .copyright-bar { - float: right; - text-align: right; -} - -.footer-bar-align-left .footer-bar { - float: left; -} - -/* Footer bar aligned center */ -.footer-bar-align-center .copyright-bar { - float: none; - text-align: center; -} - -.footer-bar-align-center .footer-bar { - float: none; - text-align: center; - margin-bottom: 10px; -} - -/* Footer bar menu */ -.footer-bar .widget_nav_menu li { - margin: 0 10px; - float: left; - padding: 0; -} - -.footer-bar .widget_nav_menu li:first-child { - margin-left: 0; -} - -.footer-bar .widget_nav_menu li:last-child { - margin-right: 0; -} - -.footer-bar .widget_nav_menu li ul { - display: none; -} - -/* Posts */ -.entry-title { - margin-bottom: 0; -} - -.entry-header { - word-wrap: break-word; -} - -.page-header { - margin-bottom: 30px; -} - -.page-header h1 { - font-size: 25px; -} - -.page-header .avatar { - float: left; - margin-right: 1.5em; -} - -.page-header .author-info { - overflow: hidden; -} - -.page-header > *:last-child { - margin-bottom: 0; -} - -.entry-meta { - font-size: 85%; - margin-top: .5em; - line-height: 1.5; -} - -footer.entry-meta { - margin-top: 2em; -} - -footer.entry-meta .author:before, -footer.entry-meta .posted-on:before, -.cat-links:before, -.tags-links:before, -.comments-link:before, -.nav-previous .prev:before, -.nav-next .next:before { - font-family: FontAwesome; - font-weight: normal; - font-style: normal; - display: inline-block; - text-decoration: inherit; - position: relative; - margin-right: 0.6em; - width: 13px; - text-align: center; - speak: none; -} - -footer.entry-meta .author:before { - content: "\f007"; -} - -footer.entry-meta .posted-on:before { - content: "\f073"; -} - -.cat-links:before { - content: "\f07b"; -} - -.tags-links:before { - content: "\f02c"; -} - -.comments-link:before { - content: "\f086"; -} - -.nav-previous .prev:before { - content: "\f104"; -} - -.nav-next .next:before { - content: "\f105"; -} - -.cat-links, -.tags-links, -.comments-link, -footer.entry-meta .posted-on, -footer.entry-meta .byline { - display: block; -} - -.taxonomy-description p:last-child { - margin-bottom: 0; -} - -.paging-navigation:before, -.paging-navigation:after { - content: "."; - display: block; - overflow: hidden; - visibility: hidden; - font-size: 0; - line-height: 0; - width: 0; - height: 0; -} - -.paging-navigation:after { - clear: both; -} - -.paging-navigation .nav-previous, -.paging-navigation .nav-next { - display: none; -} - -.comment-respond { - margin-top: 0; -} - -.read-more-container { - margin-bottom: 0; -} - -.site-main .post-navigation { - margin-bottom: 0; -} - -/* Site header */ - -.main-title { - margin: 0; - font-size: 50px; - line-height: 1.2em; -} - -.site-logo { - display: inline-block; - *display: inline; - *zoom: 1; - max-width: 100%; -} - -.site-description { - margin: 0; - line-height: 1.5; -} - -.header-widget { - float: right; - overflow: hidden; - max-width: 50%; -} - -.header-widget .widget { - padding: 0 0 20px; - margin-bottom: 0; -} - -.header-widget .widget:last-child { - padding-bottom: 0; -} - -.nav-float-right .header-widget .widget { - padding: 0 0 10px; -} - -.nav-float-right .header-widget .widget:last-child { - padding-bottom: 0; -} - -.nav-float-right .header-widget { - position: relative; - top: -10px; -} - -.post-image { - margin: 2em 0 0; -} - -/* Page Header Add-on */ -.page-header-image, -.page-header-image-single { - line-height: 0; /* no more weird spacing */ -} - -.separate-containers .page-header-image, -.separate-containers .page-header-content { - margin-top: 30px; -} - -.inside-page-header { - padding: 40px; -} - -.separate-containers .page-header-image-single, -.separate-containers .page-header-content-single { - margin-top: 30px; -} - -.separate-containers .inside-article .page-header-image-single, -.separate-containers .inside-article .page-header-content-single, -.one-container .inside-article .page-header-image-single, -.one-container .inside-article .page-header-content-single, -.separate-containers .inside-article .page-header-image, -.separate-containers .inside-article .page-header-content, -.one-container .inside-article .page-header-image, -.one-container .inside-article .page-header-content { - margin-bottom: 2em; - margin-top: 0; -} - -.inside-article .page-header-image-single.page-header-below-title { - margin-top: 2em; -} - -/* Full width template */ -.full-width-content .container.grid-container { - max-width: 100%; -} - -.full-width-content.no-sidebar.separate-containers .site-main { - margin: 0; -} - -.full-width-content.separate-containers .inside-article, -.full-width-content.one-container .site-content { - padding: 0; -} - -/* WooCommerce */ -.woocommerce .page-header-image-single { - display: none; -} - -.woocommerce .entry-content, -.woocommerce .product .entry-summary { - margin-top: 0; -} - -.related.products { - clear: both; -} - -.checkout-subscribe-prompt.clear { - visibility: visible; - height: initial; - width: initial; -} - -/* bbPress */ -#bbpress-forums ul.bbp-lead-topic, -#bbpress-forums ul.bbp-topics, -#bbpress-forums ul.bbp-forums, -#bbpress-forums ul.bbp-replies, -#bbpress-forums ul.bbp-search-results, -#bbpress-forums, -div.bbp-breadcrumb, -div.bbp-topic-tags { - font-size: inherit; -} - -.single-forum #subscription-toggle { - display: block; - margin: 1em 0; - clear: left; -} - -#bbpress-forums .bbp-search-form { - margin-bottom: 10px; -} - -.bbp-login-form fieldset { - border: 0; - padding: 0; -} - -/* BuddyPress */ -#buddypress form#whats-new-form #whats-new-options[style] { - min-height: 6rem; - overflow: visible; -} - -/* SiteOrigin Page Builder */ -.so-panel.widget { - padding: 0; -} - -/* Beaver Builder */ -.fl-builder.no-sidebar .container.grid-container { - max-width: 100%; -} - -.fl-builder.one-container.no-sidebar .site-content { - padding: 0; -} - -/* MailChimp CSS */ -#mc_embed_signup .clear { - display: block; - height: auto; - visibility: visible; - width: auto; -} - -/* Bootstrap fix */ -.container.grid-container { - width: auto; -} - -/* Menu class for items to float right */ -.sf-menu > li.menu-item-float-right { - float: right !important; -} - -/* Back to top icon */ -.stylepress-back-to-top, -.stylepress-back-to-top:visited { - font-size: 20px; - background: rgba(0, 0, 0, 0.4); - color: #FFF; - border-radius: 3px; - position: fixed; - bottom: 30px; - right: 30px; - line-height: 40px; - width: 40px; - text-align: center; - z-index: 10; -} - -.stylepress-back-to-top:hover, -.stylepress-back-to-top:focus { - background: rgba(0, 0, 0, 0.6); - color: #FFF; -} - -.stylepress-back-to-top .screen-reader-text { - left: 0; -} - -/* Mobile menu */ -.menu-toggle, -.mobile-bar-items { - display: none; - cursor: pointer; -} - -/* - * Backwards compatibility until Slideout is updated - * GP Premium 1.2.93 - */ -.slideout-navigation .menu-item-has-children .dropdown-menu-toggle { - float: right; -} - -body { - background-color: #FFF; - color: #3a3a3a; -} - -a, a:visited { - color: #1e73be; - text-decoration: none; -} - -a:hover, a:focus, a:active { - color: #000000; - text-decoration: none; -} - -body .grid-container { - max-width: 1100px; -} - -.site-header { - background-color: #ffffff; - color: #3a3a3a; -} - -.site-header a, .site-header a:visited { - color: #3a3a3a; -} - -.main-title a, .main-title a:hover, .main-title a:visited { - color: #222222; -} - -.site-description { - color: #999999; -} - -.main-navigation, .main-navigation ul ul { - background-color: rgba(239, 239, 239, 0.44); -} - -.main-navigation .main-nav ul li a, .menu-toggle { - color: #000; -} - -.main-navigation .main-nav ul li > a:hover, .main-navigation .main-nav ul li > a:focus, .main-navigation .main-nav ul li.sfHover > a { - color: #000; - background-color: #eaeaea; -} - -button.menu-toggle:hover, button.menu-toggle:focus, .main-navigation .mobile-bar-items a, .main-navigation .mobile-bar-items a:hover, .main-navigation .mobile-bar-items a:focus { - color: #ffffff; -} - -.main-navigation .main-nav ul li[class*="current-menu-"] > a { - color: #000; - background-color: #eaeaea; -} - -.main-navigation .main-nav ul li[class*="current-menu-"] > a:hover, .main-navigation .main-nav ul li[class*="current-menu-"].sfHover > a { - color: #000; - background-color: #eaeaea; -} - -.main-navigation ul ul { - background-color: #eaeaea; -} - -.main-navigation .main-nav ul ul li a { - color: #ffffff; -} - -.main-navigation .main-nav ul ul li > a:hover, .main-navigation .main-nav ul ul li > a:focus, .main-navigation .main-nav ul ul li.sfHover > a { - color: #000; - background-color: #eaeaea; -} - -.main-navigation .main-nav ul ul li[class*="current-menu-"] > a { - color: #000; - background-color: #eaeaea; -} - -.main-navigation .main-nav ul ul li[class*="current-menu-"] > a:hover, .main-navigation .main-nav ul ul li[class*="current-menu-"].sfHover > a { - color: #000; - background-color: #eaeaea; -} - -.separate-containers .inside-article, .separate-containers .comments-area, .separate-containers .page-header, .one-container .container, .separate-containers .paging-navigation, .inside-page-header { - background-color: rgba(239, 239, 239, 0.44); -} - -.entry-meta { - color: #888888; -} - -.entry-meta a, .entry-meta a:visited { - color: #666666; -} - -.entry-meta a:hover { - color: #1e73be; -} - -.sidebar .widget { - background-color: rgba(239, 239, 239, 0.44); -} - -.sidebar .widget .widget-title { - color: #000000; -} - -.footer-widgets { - background-color: #ffffff; -} - -.footer-widgets .widget-title { - color: #000000; -} - -.site-info { - color: #000; - background-color: rgba(239, 239, 239, 0.44); -} - -.site-info a, .site-info a:visited { - color: #ffffff; -} - -.site-info a:hover { - color: #606060; -} - -.footer-bar .widget_nav_menu .current-menu-item a { - color: #606060; -} - -input[type="text"], input[type="email"], input[type="url"], input[type="password"], input[type="search"], textarea { - color: #666666; - background-color: #fafafa; - border-color: #cccccc; -} - -input[type="text"]:focus, input[type="email"]:focus, input[type="url"]:focus, input[type="password"]:focus, input[type="search"]:focus, textarea:focus { - color: #666666; - background-color: #ffffff; - border-color: #bfbfbf; -} - -button, html input[type="button"], input[type="reset"], input[type="submit"], .button, .button:visited { - color: #ffffff; - background-color: #666666; -} - -button:hover, html input[type="button"]:hover, input[type="reset"]:hover, input[type="submit"]:hover, .button:hover, button:focus, html input[type="button"]:focus, input[type="reset"]:focus, input[type="submit"]:focus, .button:focus { - color: #666666; - background-color: #eaeaea; -} - -.main-navigation ul ul { - top: auto; -} - -@media (max-width: 768px) { - .separate-containers .inside-article, .separate-containers .comments-area, .separate-containers .page-header, .separate-containers .paging-navigation, .one-container .site-content { - padding: 30px; - } -} \ No newline at end of file diff --git a/assets/icons/font-awesome/css/font-awesome.css b/assets/icons/font-awesome/css/font-awesome.css deleted file mode 100644 index 04cc256..0000000 --- a/assets/icons/font-awesome/css/font-awesome.css +++ /dev/null @@ -1,3049 +0,0 @@ -/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */ -/* FONT PATH - * -------------------------- */ -@font-face { - font-family: 'FontAwesome'; - src: url('../fonts/fontawesome-webfont.eot?v=4.7.0'); - src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); - font-weight: normal; - font-style: normal; -} - -.fa { - display: inline-block; - font: normal normal normal 14px/1 FontAwesome; - font-size: inherit; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -/* makes the font 33% larger relative to the icon container */ -.fa-lg { - font-size: 1.33333333em; - line-height: 0.75em; - vertical-align: -15%; -} - -.fa-2x { - font-size: 2em; -} - -.fa-3x { - font-size: 3em; -} - -.fa-4x { - font-size: 4em; -} - -.fa-5x { - font-size: 5em; -} - -.fa-fw { - width: 1.28571429em; - text-align: center; -} - -.fa-ul { - padding-left: 0; - margin-left: 2.14285714em; - list-style-type: none; -} - -.fa-ul > li { - position: relative; -} - -.fa-li { - position: absolute; - left: -2.14285714em; - width: 2.14285714em; - top: 0.14285714em; - text-align: center; -} - -.fa-li.fa-lg { - left: -1.85714286em; -} - -.fa-border { - padding: .2em .25em .15em; - border: solid 0.08em #eeeeee; - border-radius: .1em; -} - -.fa-pull-left { - float: left; -} - -.fa-pull-right { - float: right; -} - -.fa.fa-pull-left { - margin-right: .3em; -} - -.fa.fa-pull-right { - margin-left: .3em; -} - -/* Deprecated as of 4.4.0 */ -.pull-right { - float: right; -} - -.pull-left { - float: left; -} - -.fa.pull-left { - margin-right: .3em; -} - -.fa.pull-right { - margin-left: .3em; -} - -.fa-spin { - -webkit-animation: fa-spin 2s infinite linear; - animation: fa-spin 2s infinite linear; -} - -.fa-pulse { - -webkit-animation: fa-spin 1s infinite steps(8); - animation: fa-spin 1s infinite steps(8); -} - -@-webkit-keyframes fa-spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} - -@keyframes fa-spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} - -.fa-rotate-90 { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; - -webkit-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); -} - -.fa-rotate-180 { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; - -webkit-transform: rotate(180deg); - -ms-transform: rotate(180deg); - transform: rotate(180deg); -} - -.fa-rotate-270 { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; - -webkit-transform: rotate(270deg); - -ms-transform: rotate(270deg); - transform: rotate(270deg); -} - -.fa-flip-horizontal { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; - -webkit-transform: scale(-1, 1); - -ms-transform: scale(-1, 1); - transform: scale(-1, 1); -} - -.fa-flip-vertical { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; - -webkit-transform: scale(1, -1); - -ms-transform: scale(1, -1); - transform: scale(1, -1); -} - -:root .fa-rotate-90, -:root .fa-rotate-180, -:root .fa-rotate-270, -:root .fa-flip-horizontal, -:root .fa-flip-vertical { - filter: none; -} - -.fa-stack { - position: relative; - display: inline-block; - width: 2em; - height: 2em; - line-height: 2em; - vertical-align: middle; -} - -.fa-stack-1x, -.fa-stack-2x { - position: absolute; - left: 0; - width: 100%; - text-align: center; -} - -.fa-stack-1x { - line-height: inherit; -} - -.fa-stack-2x { - font-size: 2em; -} - -.fa-inverse { - color: #ffffff; -} - -/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen - readers do not read off random characters that represent icons */ -.fa-glass:before { - content: "\f000"; -} - -.fa-music:before { - content: "\f001"; -} - -.fa-search:before { - content: "\f002"; -} - -.fa-envelope-o:before { - content: "\f003"; -} - -.fa-heart:before { - content: "\f004"; -} - -.fa-star:before { - content: "\f005"; -} - -.fa-star-o:before { - content: "\f006"; -} - -.fa-user:before { - content: "\f007"; -} - -.fa-film:before { - content: "\f008"; -} - -.fa-th-large:before { - content: "\f009"; -} - -.fa-th:before { - content: "\f00a"; -} - -.fa-th-list:before { - content: "\f00b"; -} - -.fa-check:before { - content: "\f00c"; -} - -.fa-remove:before, -.fa-close:before, -.fa-times:before { - content: "\f00d"; -} - -.fa-search-plus:before { - content: "\f00e"; -} - -.fa-search-minus:before { - content: "\f010"; -} - -.fa-power-off:before { - content: "\f011"; -} - -.fa-signal:before { - content: "\f012"; -} - -.fa-gear:before, -.fa-cog:before { - content: "\f013"; -} - -.fa-trash-o:before { - content: "\f014"; -} - -.fa-home:before { - content: "\f015"; -} - -.fa-file-o:before { - content: "\f016"; -} - -.fa-clock-o:before { - content: "\f017"; -} - -.fa-road:before { - content: "\f018"; -} - -.fa-download:before { - content: "\f019"; -} - -.fa-arrow-circle-o-down:before { - content: "\f01a"; -} - -.fa-arrow-circle-o-up:before { - content: "\f01b"; -} - -.fa-inbox:before { - content: "\f01c"; -} - -.fa-play-circle-o:before { - content: "\f01d"; -} - -.fa-rotate-right:before, -.fa-repeat:before { - content: "\f01e"; -} - -.fa-refresh:before { - content: "\f021"; -} - -.fa-list-alt:before { - content: "\f022"; -} - -.fa-lock:before { - content: "\f023"; -} - -.fa-flag:before { - content: "\f024"; -} - -.fa-headphones:before { - content: "\f025"; -} - -.fa-volume-off:before { - content: "\f026"; -} - -.fa-volume-down:before { - content: "\f027"; -} - -.fa-volume-up:before { - content: "\f028"; -} - -.fa-qrcode:before { - content: "\f029"; -} - -.fa-barcode:before { - content: "\f02a"; -} - -.fa-tag:before { - content: "\f02b"; -} - -.fa-tags:before { - content: "\f02c"; -} - -.fa-book:before { - content: "\f02d"; -} - -.fa-bookmark:before { - content: "\f02e"; -} - -.fa-print:before { - content: "\f02f"; -} - -.fa-camera:before { - content: "\f030"; -} - -.fa-font:before { - content: "\f031"; -} - -.fa-bold:before { - content: "\f032"; -} - -.fa-italic:before { - content: "\f033"; -} - -.fa-text-height:before { - content: "\f034"; -} - -.fa-text-width:before { - content: "\f035"; -} - -.fa-align-left:before { - content: "\f036"; -} - -.fa-align-center:before { - content: "\f037"; -} - -.fa-align-right:before { - content: "\f038"; -} - -.fa-align-justify:before { - content: "\f039"; -} - -.fa-list:before { - content: "\f03a"; -} - -.fa-dedent:before, -.fa-outdent:before { - content: "\f03b"; -} - -.fa-indent:before { - content: "\f03c"; -} - -.fa-video-camera:before { - content: "\f03d"; -} - -.fa-photo:before, -.fa-image:before, -.fa-picture-o:before { - content: "\f03e"; -} - -.fa-pencil:before { - content: "\f040"; -} - -.fa-map-marker:before { - content: "\f041"; -} - -.fa-adjust:before { - content: "\f042"; -} - -.fa-tint:before { - content: "\f043"; -} - -.fa-edit:before, -.fa-pencil-square-o:before { - content: "\f044"; -} - -.fa-share-square-o:before { - content: "\f045"; -} - -.fa-check-square-o:before { - content: "\f046"; -} - -.fa-arrows:before { - content: "\f047"; -} - -.fa-step-backward:before { - content: "\f048"; -} - -.fa-fast-backward:before { - content: "\f049"; -} - -.fa-backward:before { - content: "\f04a"; -} - -.fa-play:before { - content: "\f04b"; -} - -.fa-pause:before { - content: "\f04c"; -} - -.fa-stop:before { - content: "\f04d"; -} - -.fa-forward:before { - content: "\f04e"; -} - -.fa-fast-forward:before { - content: "\f050"; -} - -.fa-step-forward:before { - content: "\f051"; -} - -.fa-eject:before { - content: "\f052"; -} - -.fa-chevron-left:before { - content: "\f053"; -} - -.fa-chevron-right:before { - content: "\f054"; -} - -.fa-plus-circle:before { - content: "\f055"; -} - -.fa-minus-circle:before { - content: "\f056"; -} - -.fa-times-circle:before { - content: "\f057"; -} - -.fa-check-circle:before { - content: "\f058"; -} - -.fa-question-circle:before { - content: "\f059"; -} - -.fa-info-circle:before { - content: "\f05a"; -} - -.fa-crosshairs:before { - content: "\f05b"; -} - -.fa-times-circle-o:before { - content: "\f05c"; -} - -.fa-check-circle-o:before { - content: "\f05d"; -} - -.fa-ban:before { - content: "\f05e"; -} - -.fa-arrow-left:before { - content: "\f060"; -} - -.fa-arrow-right:before { - content: "\f061"; -} - -.fa-arrow-up:before { - content: "\f062"; -} - -.fa-arrow-down:before { - content: "\f063"; -} - -.fa-mail-forward:before, -.fa-share:before { - content: "\f064"; -} - -.fa-expand:before { - content: "\f065"; -} - -.fa-compress:before { - content: "\f066"; -} - -.fa-plus:before { - content: "\f067"; -} - -.fa-minus:before { - content: "\f068"; -} - -.fa-asterisk:before { - content: "\f069"; -} - -.fa-exclamation-circle:before { - content: "\f06a"; -} - -.fa-gift:before { - content: "\f06b"; -} - -.fa-leaf:before { - content: "\f06c"; -} - -.fa-fire:before { - content: "\f06d"; -} - -.fa-eye:before { - content: "\f06e"; -} - -.fa-eye-slash:before { - content: "\f070"; -} - -.fa-warning:before, -.fa-exclamation-triangle:before { - content: "\f071"; -} - -.fa-plane:before { - content: "\f072"; -} - -.fa-calendar:before { - content: "\f073"; -} - -.fa-random:before { - content: "\f074"; -} - -.fa-comment:before { - content: "\f075"; -} - -.fa-magnet:before { - content: "\f076"; -} - -.fa-chevron-up:before { - content: "\f077"; -} - -.fa-chevron-down:before { - content: "\f078"; -} - -.fa-retweet:before { - content: "\f079"; -} - -.fa-shopping-cart:before { - content: "\f07a"; -} - -.fa-folder:before { - content: "\f07b"; -} - -.fa-folder-open:before { - content: "\f07c"; -} - -.fa-arrows-v:before { - content: "\f07d"; -} - -.fa-arrows-h:before { - content: "\f07e"; -} - -.fa-bar-chart-o:before, -.fa-bar-chart:before { - content: "\f080"; -} - -.fa-twitter-square:before { - content: "\f081"; -} - -.fa-facebook-square:before { - content: "\f082"; -} - -.fa-camera-retro:before { - content: "\f083"; -} - -.fa-key:before { - content: "\f084"; -} - -.fa-gears:before, -.fa-cogs:before { - content: "\f085"; -} - -.fa-comments:before { - content: "\f086"; -} - -.fa-thumbs-o-up:before { - content: "\f087"; -} - -.fa-thumbs-o-down:before { - content: "\f088"; -} - -.fa-star-half:before { - content: "\f089"; -} - -.fa-heart-o:before { - content: "\f08a"; -} - -.fa-sign-out:before { - content: "\f08b"; -} - -.fa-linkedin-square:before { - content: "\f08c"; -} - -.fa-thumb-tack:before { - content: "\f08d"; -} - -.fa-external-link:before { - content: "\f08e"; -} - -.fa-sign-in:before { - content: "\f090"; -} - -.fa-trophy:before { - content: "\f091"; -} - -.fa-github-square:before { - content: "\f092"; -} - -.fa-upload:before { - content: "\f093"; -} - -.fa-lemon-o:before { - content: "\f094"; -} - -.fa-phone:before { - content: "\f095"; -} - -.fa-square-o:before { - content: "\f096"; -} - -.fa-bookmark-o:before { - content: "\f097"; -} - -.fa-phone-square:before { - content: "\f098"; -} - -.fa-twitter:before { - content: "\f099"; -} - -.fa-facebook-f:before, -.fa-facebook:before { - content: "\f09a"; -} - -.fa-github:before { - content: "\f09b"; -} - -.fa-unlock:before { - content: "\f09c"; -} - -.fa-credit-card:before { - content: "\f09d"; -} - -.fa-feed:before, -.fa-rss:before { - content: "\f09e"; -} - -.fa-hdd-o:before { - content: "\f0a0"; -} - -.fa-bullhorn:before { - content: "\f0a1"; -} - -.fa-bell:before { - content: "\f0f3"; -} - -.fa-certificate:before { - content: "\f0a3"; -} - -.fa-hand-o-right:before { - content: "\f0a4"; -} - -.fa-hand-o-left:before { - content: "\f0a5"; -} - -.fa-hand-o-up:before { - content: "\f0a6"; -} - -.fa-hand-o-down:before { - content: "\f0a7"; -} - -.fa-arrow-circle-left:before { - content: "\f0a8"; -} - -.fa-arrow-circle-right:before { - content: "\f0a9"; -} - -.fa-arrow-circle-up:before { - content: "\f0aa"; -} - -.fa-arrow-circle-down:before { - content: "\f0ab"; -} - -.fa-globe:before { - content: "\f0ac"; -} - -.fa-wrench:before { - content: "\f0ad"; -} - -.fa-tasks:before { - content: "\f0ae"; -} - -.fa-filter:before { - content: "\f0b0"; -} - -.fa-briefcase:before { - content: "\f0b1"; -} - -.fa-arrows-alt:before { - content: "\f0b2"; -} - -.fa-group:before, -.fa-users:before { - content: "\f0c0"; -} - -.fa-chain:before, -.fa-link:before { - content: "\f0c1"; -} - -.fa-cloud:before { - content: "\f0c2"; -} - -.fa-flask:before { - content: "\f0c3"; -} - -.fa-cut:before, -.fa-scissors:before { - content: "\f0c4"; -} - -.fa-copy:before, -.fa-files-o:before { - content: "\f0c5"; -} - -.fa-paperclip:before { - content: "\f0c6"; -} - -.fa-save:before, -.fa-floppy-o:before { - content: "\f0c7"; -} - -.fa-square:before { - content: "\f0c8"; -} - -.fa-navicon:before, -.fa-reorder:before, -.fa-bars:before { - content: "\f0c9"; -} - -.fa-list-ul:before { - content: "\f0ca"; -} - -.fa-list-ol:before { - content: "\f0cb"; -} - -.fa-strikethrough:before { - content: "\f0cc"; -} - -.fa-underline:before { - content: "\f0cd"; -} - -.fa-table:before { - content: "\f0ce"; -} - -.fa-magic:before { - content: "\f0d0"; -} - -.fa-truck:before { - content: "\f0d1"; -} - -.fa-pinterest:before { - content: "\f0d2"; -} - -.fa-pinterest-square:before { - content: "\f0d3"; -} - -.fa-google-plus-square:before { - content: "\f0d4"; -} - -.fa-google-plus:before { - content: "\f0d5"; -} - -.fa-money:before { - content: "\f0d6"; -} - -.fa-caret-down:before { - content: "\f0d7"; -} - -.fa-caret-up:before { - content: "\f0d8"; -} - -.fa-caret-left:before { - content: "\f0d9"; -} - -.fa-caret-right:before { - content: "\f0da"; -} - -.fa-columns:before { - content: "\f0db"; -} - -.fa-unsorted:before, -.fa-sort:before { - content: "\f0dc"; -} - -.fa-sort-down:before, -.fa-sort-desc:before { - content: "\f0dd"; -} - -.fa-sort-up:before, -.fa-sort-asc:before { - content: "\f0de"; -} - -.fa-envelope:before { - content: "\f0e0"; -} - -.fa-linkedin:before { - content: "\f0e1"; -} - -.fa-rotate-left:before, -.fa-undo:before { - content: "\f0e2"; -} - -.fa-legal:before, -.fa-gavel:before { - content: "\f0e3"; -} - -.fa-dashboard:before, -.fa-tachometer:before { - content: "\f0e4"; -} - -.fa-comment-o:before { - content: "\f0e5"; -} - -.fa-comments-o:before { - content: "\f0e6"; -} - -.fa-flash:before, -.fa-bolt:before { - content: "\f0e7"; -} - -.fa-sitemap:before { - content: "\f0e8"; -} - -.fa-umbrella:before { - content: "\f0e9"; -} - -.fa-paste:before, -.fa-clipboard:before { - content: "\f0ea"; -} - -.fa-lightbulb-o:before { - content: "\f0eb"; -} - -.fa-exchange:before { - content: "\f0ec"; -} - -.fa-cloud-download:before { - content: "\f0ed"; -} - -.fa-cloud-upload:before { - content: "\f0ee"; -} - -.fa-user-md:before { - content: "\f0f0"; -} - -.fa-stethoscope:before { - content: "\f0f1"; -} - -.fa-suitcase:before { - content: "\f0f2"; -} - -.fa-bell-o:before { - content: "\f0a2"; -} - -.fa-coffee:before { - content: "\f0f4"; -} - -.fa-cutlery:before { - content: "\f0f5"; -} - -.fa-file-text-o:before { - content: "\f0f6"; -} - -.fa-building-o:before { - content: "\f0f7"; -} - -.fa-hospital-o:before { - content: "\f0f8"; -} - -.fa-ambulance:before { - content: "\f0f9"; -} - -.fa-medkit:before { - content: "\f0fa"; -} - -.fa-fighter-jet:before { - content: "\f0fb"; -} - -.fa-beer:before { - content: "\f0fc"; -} - -.fa-h-square:before { - content: "\f0fd"; -} - -.fa-plus-square:before { - content: "\f0fe"; -} - -.fa-angle-double-left:before { - content: "\f100"; -} - -.fa-angle-double-right:before { - content: "\f101"; -} - -.fa-angle-double-up:before { - content: "\f102"; -} - -.fa-angle-double-down:before { - content: "\f103"; -} - -.fa-angle-left:before { - content: "\f104"; -} - -.fa-angle-right:before { - content: "\f105"; -} - -.fa-angle-up:before { - content: "\f106"; -} - -.fa-angle-down:before { - content: "\f107"; -} - -.fa-desktop:before { - content: "\f108"; -} - -.fa-laptop:before { - content: "\f109"; -} - -.fa-tablet:before { - content: "\f10a"; -} - -.fa-mobile-phone:before, -.fa-mobile:before { - content: "\f10b"; -} - -.fa-circle-o:before { - content: "\f10c"; -} - -.fa-quote-left:before { - content: "\f10d"; -} - -.fa-quote-right:before { - content: "\f10e"; -} - -.fa-spinner:before { - content: "\f110"; -} - -.fa-circle:before { - content: "\f111"; -} - -.fa-mail-reply:before, -.fa-reply:before { - content: "\f112"; -} - -.fa-github-alt:before { - content: "\f113"; -} - -.fa-folder-o:before { - content: "\f114"; -} - -.fa-folder-open-o:before { - content: "\f115"; -} - -.fa-smile-o:before { - content: "\f118"; -} - -.fa-frown-o:before { - content: "\f119"; -} - -.fa-meh-o:before { - content: "\f11a"; -} - -.fa-gamepad:before { - content: "\f11b"; -} - -.fa-keyboard-o:before { - content: "\f11c"; -} - -.fa-flag-o:before { - content: "\f11d"; -} - -.fa-flag-checkered:before { - content: "\f11e"; -} - -.fa-terminal:before { - content: "\f120"; -} - -.fa-code:before { - content: "\f121"; -} - -.fa-mail-reply-all:before, -.fa-reply-all:before { - content: "\f122"; -} - -.fa-star-half-empty:before, -.fa-star-half-full:before, -.fa-star-half-o:before { - content: "\f123"; -} - -.fa-location-arrow:before { - content: "\f124"; -} - -.fa-crop:before { - content: "\f125"; -} - -.fa-code-fork:before { - content: "\f126"; -} - -.fa-unlink:before, -.fa-chain-broken:before { - content: "\f127"; -} - -.fa-question:before { - content: "\f128"; -} - -.fa-info:before { - content: "\f129"; -} - -.fa-exclamation:before { - content: "\f12a"; -} - -.fa-superscript:before { - content: "\f12b"; -} - -.fa-subscript:before { - content: "\f12c"; -} - -.fa-eraser:before { - content: "\f12d"; -} - -.fa-puzzle-piece:before { - content: "\f12e"; -} - -.fa-microphone:before { - content: "\f130"; -} - -.fa-microphone-slash:before { - content: "\f131"; -} - -.fa-shield:before { - content: "\f132"; -} - -.fa-calendar-o:before { - content: "\f133"; -} - -.fa-fire-extinguisher:before { - content: "\f134"; -} - -.fa-rocket:before { - content: "\f135"; -} - -.fa-maxcdn:before { - content: "\f136"; -} - -.fa-chevron-circle-left:before { - content: "\f137"; -} - -.fa-chevron-circle-right:before { - content: "\f138"; -} - -.fa-chevron-circle-up:before { - content: "\f139"; -} - -.fa-chevron-circle-down:before { - content: "\f13a"; -} - -.fa-html5:before { - content: "\f13b"; -} - -.fa-css3:before { - content: "\f13c"; -} - -.fa-anchor:before { - content: "\f13d"; -} - -.fa-unlock-alt:before { - content: "\f13e"; -} - -.fa-bullseye:before { - content: "\f140"; -} - -.fa-ellipsis-h:before { - content: "\f141"; -} - -.fa-ellipsis-v:before { - content: "\f142"; -} - -.fa-rss-square:before { - content: "\f143"; -} - -.fa-play-circle:before { - content: "\f144"; -} - -.fa-ticket:before { - content: "\f145"; -} - -.fa-minus-square:before { - content: "\f146"; -} - -.fa-minus-square-o:before { - content: "\f147"; -} - -.fa-level-up:before { - content: "\f148"; -} - -.fa-level-down:before { - content: "\f149"; -} - -.fa-check-square:before { - content: "\f14a"; -} - -.fa-pencil-square:before { - content: "\f14b"; -} - -.fa-external-link-square:before { - content: "\f14c"; -} - -.fa-share-square:before { - content: "\f14d"; -} - -.fa-compass:before { - content: "\f14e"; -} - -.fa-toggle-down:before, -.fa-caret-square-o-down:before { - content: "\f150"; -} - -.fa-toggle-up:before, -.fa-caret-square-o-up:before { - content: "\f151"; -} - -.fa-toggle-right:before, -.fa-caret-square-o-right:before { - content: "\f152"; -} - -.fa-euro:before, -.fa-eur:before { - content: "\f153"; -} - -.fa-gbp:before { - content: "\f154"; -} - -.fa-dollar:before, -.fa-usd:before { - content: "\f155"; -} - -.fa-rupee:before, -.fa-inr:before { - content: "\f156"; -} - -.fa-cny:before, -.fa-rmb:before, -.fa-yen:before, -.fa-jpy:before { - content: "\f157"; -} - -.fa-ruble:before, -.fa-rouble:before, -.fa-rub:before { - content: "\f158"; -} - -.fa-won:before, -.fa-krw:before { - content: "\f159"; -} - -.fa-bitcoin:before, -.fa-btc:before { - content: "\f15a"; -} - -.fa-file:before { - content: "\f15b"; -} - -.fa-file-text:before { - content: "\f15c"; -} - -.fa-sort-alpha-asc:before { - content: "\f15d"; -} - -.fa-sort-alpha-desc:before { - content: "\f15e"; -} - -.fa-sort-amount-asc:before { - content: "\f160"; -} - -.fa-sort-amount-desc:before { - content: "\f161"; -} - -.fa-sort-numeric-asc:before { - content: "\f162"; -} - -.fa-sort-numeric-desc:before { - content: "\f163"; -} - -.fa-thumbs-up:before { - content: "\f164"; -} - -.fa-thumbs-down:before { - content: "\f165"; -} - -.fa-youtube-square:before { - content: "\f166"; -} - -.fa-youtube:before { - content: "\f167"; -} - -.fa-xing:before { - content: "\f168"; -} - -.fa-xing-square:before { - content: "\f169"; -} - -.fa-youtube-play:before { - content: "\f16a"; -} - -.fa-dropbox:before { - content: "\f16b"; -} - -.fa-stack-overflow:before { - content: "\f16c"; -} - -.fa-instagram:before { - content: "\f16d"; -} - -.fa-flickr:before { - content: "\f16e"; -} - -.fa-adn:before { - content: "\f170"; -} - -.fa-bitbucket:before { - content: "\f171"; -} - -.fa-bitbucket-square:before { - content: "\f172"; -} - -.fa-tumblr:before { - content: "\f173"; -} - -.fa-tumblr-square:before { - content: "\f174"; -} - -.fa-long-arrow-down:before { - content: "\f175"; -} - -.fa-long-arrow-up:before { - content: "\f176"; -} - -.fa-long-arrow-left:before { - content: "\f177"; -} - -.fa-long-arrow-right:before { - content: "\f178"; -} - -.fa-apple:before { - content: "\f179"; -} - -.fa-windows:before { - content: "\f17a"; -} - -.fa-android:before { - content: "\f17b"; -} - -.fa-linux:before { - content: "\f17c"; -} - -.fa-dribbble:before { - content: "\f17d"; -} - -.fa-skype:before { - content: "\f17e"; -} - -.fa-foursquare:before { - content: "\f180"; -} - -.fa-trello:before { - content: "\f181"; -} - -.fa-female:before { - content: "\f182"; -} - -.fa-male:before { - content: "\f183"; -} - -.fa-gittip:before, -.fa-gratipay:before { - content: "\f184"; -} - -.fa-sun-o:before { - content: "\f185"; -} - -.fa-moon-o:before { - content: "\f186"; -} - -.fa-archive:before { - content: "\f187"; -} - -.fa-bug:before { - content: "\f188"; -} - -.fa-vk:before { - content: "\f189"; -} - -.fa-weibo:before { - content: "\f18a"; -} - -.fa-renren:before { - content: "\f18b"; -} - -.fa-pagelines:before { - content: "\f18c"; -} - -.fa-stack-exchange:before { - content: "\f18d"; -} - -.fa-arrow-circle-o-right:before { - content: "\f18e"; -} - -.fa-arrow-circle-o-left:before { - content: "\f190"; -} - -.fa-toggle-left:before, -.fa-caret-square-o-left:before { - content: "\f191"; -} - -.fa-dot-circle-o:before { - content: "\f192"; -} - -.fa-wheelchair:before { - content: "\f193"; -} - -.fa-vimeo-square:before { - content: "\f194"; -} - -.fa-turkish-lira:before, -.fa-try:before { - content: "\f195"; -} - -.fa-plus-square-o:before { - content: "\f196"; -} - -.fa-space-shuttle:before { - content: "\f197"; -} - -.fa-slack:before { - content: "\f198"; -} - -.fa-envelope-square:before { - content: "\f199"; -} - -.fa-wordpress:before { - content: "\f19a"; -} - -.fa-openid:before { - content: "\f19b"; -} - -.fa-institution:before, -.fa-bank:before, -.fa-university:before { - content: "\f19c"; -} - -.fa-mortar-board:before, -.fa-graduation-cap:before { - content: "\f19d"; -} - -.fa-yahoo:before { - content: "\f19e"; -} - -.fa-google:before { - content: "\f1a0"; -} - -.fa-reddit:before { - content: "\f1a1"; -} - -.fa-reddit-square:before { - content: "\f1a2"; -} - -.fa-stumbleupon-circle:before { - content: "\f1a3"; -} - -.fa-stumbleupon:before { - content: "\f1a4"; -} - -.fa-delicious:before { - content: "\f1a5"; -} - -.fa-digg:before { - content: "\f1a6"; -} - -.fa-pied-piper-pp:before { - content: "\f1a7"; -} - -.fa-pied-piper-alt:before { - content: "\f1a8"; -} - -.fa-drupal:before { - content: "\f1a9"; -} - -.fa-joomla:before { - content: "\f1aa"; -} - -.fa-language:before { - content: "\f1ab"; -} - -.fa-fax:before { - content: "\f1ac"; -} - -.fa-building:before { - content: "\f1ad"; -} - -.fa-child:before { - content: "\f1ae"; -} - -.fa-paw:before { - content: "\f1b0"; -} - -.fa-spoon:before { - content: "\f1b1"; -} - -.fa-cube:before { - content: "\f1b2"; -} - -.fa-cubes:before { - content: "\f1b3"; -} - -.fa-behance:before { - content: "\f1b4"; -} - -.fa-behance-square:before { - content: "\f1b5"; -} - -.fa-steam:before { - content: "\f1b6"; -} - -.fa-steam-square:before { - content: "\f1b7"; -} - -.fa-recycle:before { - content: "\f1b8"; -} - -.fa-automobile:before, -.fa-car:before { - content: "\f1b9"; -} - -.fa-cab:before, -.fa-taxi:before { - content: "\f1ba"; -} - -.fa-tree:before { - content: "\f1bb"; -} - -.fa-spotify:before { - content: "\f1bc"; -} - -.fa-deviantart:before { - content: "\f1bd"; -} - -.fa-soundcloud:before { - content: "\f1be"; -} - -.fa-database:before { - content: "\f1c0"; -} - -.fa-file-pdf-o:before { - content: "\f1c1"; -} - -.fa-file-word-o:before { - content: "\f1c2"; -} - -.fa-file-excel-o:before { - content: "\f1c3"; -} - -.fa-file-powerpoint-o:before { - content: "\f1c4"; -} - -.fa-file-photo-o:before, -.fa-file-picture-o:before, -.fa-file-image-o:before { - content: "\f1c5"; -} - -.fa-file-zip-o:before, -.fa-file-archive-o:before { - content: "\f1c6"; -} - -.fa-file-sound-o:before, -.fa-file-audio-o:before { - content: "\f1c7"; -} - -.fa-file-movie-o:before, -.fa-file-video-o:before { - content: "\f1c8"; -} - -.fa-file-code-o:before { - content: "\f1c9"; -} - -.fa-vine:before { - content: "\f1ca"; -} - -.fa-codepen:before { - content: "\f1cb"; -} - -.fa-jsfiddle:before { - content: "\f1cc"; -} - -.fa-life-bouy:before, -.fa-life-buoy:before, -.fa-life-saver:before, -.fa-support:before, -.fa-life-ring:before { - content: "\f1cd"; -} - -.fa-circle-o-notch:before { - content: "\f1ce"; -} - -.fa-ra:before, -.fa-resistance:before, -.fa-rebel:before { - content: "\f1d0"; -} - -.fa-ge:before, -.fa-empire:before { - content: "\f1d1"; -} - -.fa-git-square:before { - content: "\f1d2"; -} - -.fa-git:before { - content: "\f1d3"; -} - -.fa-y-combinator-square:before, -.fa-yc-square:before, -.fa-hacker-news:before { - content: "\f1d4"; -} - -.fa-tencent-weibo:before { - content: "\f1d5"; -} - -.fa-qq:before { - content: "\f1d6"; -} - -.fa-wechat:before, -.fa-weixin:before { - content: "\f1d7"; -} - -.fa-send:before, -.fa-paper-plane:before { - content: "\f1d8"; -} - -.fa-send-o:before, -.fa-paper-plane-o:before { - content: "\f1d9"; -} - -.fa-history:before { - content: "\f1da"; -} - -.fa-circle-thin:before { - content: "\f1db"; -} - -.fa-header:before { - content: "\f1dc"; -} - -.fa-paragraph:before { - content: "\f1dd"; -} - -.fa-sliders:before { - content: "\f1de"; -} - -.fa-share-alt:before { - content: "\f1e0"; -} - -.fa-share-alt-square:before { - content: "\f1e1"; -} - -.fa-bomb:before { - content: "\f1e2"; -} - -.fa-soccer-ball-o:before, -.fa-futbol-o:before { - content: "\f1e3"; -} - -.fa-tty:before { - content: "\f1e4"; -} - -.fa-binoculars:before { - content: "\f1e5"; -} - -.fa-plug:before { - content: "\f1e6"; -} - -.fa-slideshare:before { - content: "\f1e7"; -} - -.fa-twitch:before { - content: "\f1e8"; -} - -.fa-yelp:before { - content: "\f1e9"; -} - -.fa-newspaper-o:before { - content: "\f1ea"; -} - -.fa-wifi:before { - content: "\f1eb"; -} - -.fa-calculator:before { - content: "\f1ec"; -} - -.fa-paypal:before { - content: "\f1ed"; -} - -.fa-google-wallet:before { - content: "\f1ee"; -} - -.fa-cc-visa:before { - content: "\f1f0"; -} - -.fa-cc-mastercard:before { - content: "\f1f1"; -} - -.fa-cc-discover:before { - content: "\f1f2"; -} - -.fa-cc-amex:before { - content: "\f1f3"; -} - -.fa-cc-paypal:before { - content: "\f1f4"; -} - -.fa-cc-stripe:before { - content: "\f1f5"; -} - -.fa-bell-slash:before { - content: "\f1f6"; -} - -.fa-bell-slash-o:before { - content: "\f1f7"; -} - -.fa-trash:before { - content: "\f1f8"; -} - -.fa-copyright:before { - content: "\f1f9"; -} - -.fa-at:before { - content: "\f1fa"; -} - -.fa-eyedropper:before { - content: "\f1fb"; -} - -.fa-paint-brush:before { - content: "\f1fc"; -} - -.fa-birthday-cake:before { - content: "\f1fd"; -} - -.fa-area-chart:before { - content: "\f1fe"; -} - -.fa-pie-chart:before { - content: "\f200"; -} - -.fa-line-chart:before { - content: "\f201"; -} - -.fa-lastfm:before { - content: "\f202"; -} - -.fa-lastfm-square:before { - content: "\f203"; -} - -.fa-toggle-off:before { - content: "\f204"; -} - -.fa-toggle-on:before { - content: "\f205"; -} - -.fa-bicycle:before { - content: "\f206"; -} - -.fa-bus:before { - content: "\f207"; -} - -.fa-ioxhost:before { - content: "\f208"; -} - -.fa-angellist:before { - content: "\f209"; -} - -.fa-cc:before { - content: "\f20a"; -} - -.fa-shekel:before, -.fa-sheqel:before, -.fa-ils:before { - content: "\f20b"; -} - -.fa-meanpath:before { - content: "\f20c"; -} - -.fa-buysellads:before { - content: "\f20d"; -} - -.fa-connectdevelop:before { - content: "\f20e"; -} - -.fa-dashcube:before { - content: "\f210"; -} - -.fa-forumbee:before { - content: "\f211"; -} - -.fa-leanpub:before { - content: "\f212"; -} - -.fa-sellsy:before { - content: "\f213"; -} - -.fa-shirtsinbulk:before { - content: "\f214"; -} - -.fa-simplybuilt:before { - content: "\f215"; -} - -.fa-skyatlas:before { - content: "\f216"; -} - -.fa-cart-plus:before { - content: "\f217"; -} - -.fa-cart-arrow-down:before { - content: "\f218"; -} - -.fa-diamond:before { - content: "\f219"; -} - -.fa-ship:before { - content: "\f21a"; -} - -.fa-user-secret:before { - content: "\f21b"; -} - -.fa-motorcycle:before { - content: "\f21c"; -} - -.fa-street-view:before { - content: "\f21d"; -} - -.fa-heartbeat:before { - content: "\f21e"; -} - -.fa-venus:before { - content: "\f221"; -} - -.fa-mars:before { - content: "\f222"; -} - -.fa-mercury:before { - content: "\f223"; -} - -.fa-intersex:before, -.fa-transgender:before { - content: "\f224"; -} - -.fa-transgender-alt:before { - content: "\f225"; -} - -.fa-venus-double:before { - content: "\f226"; -} - -.fa-mars-double:before { - content: "\f227"; -} - -.fa-venus-mars:before { - content: "\f228"; -} - -.fa-mars-stroke:before { - content: "\f229"; -} - -.fa-mars-stroke-v:before { - content: "\f22a"; -} - -.fa-mars-stroke-h:before { - content: "\f22b"; -} - -.fa-neuter:before { - content: "\f22c"; -} - -.fa-genderless:before { - content: "\f22d"; -} - -.fa-facebook-official:before { - content: "\f230"; -} - -.fa-pinterest-p:before { - content: "\f231"; -} - -.fa-whatsapp:before { - content: "\f232"; -} - -.fa-server:before { - content: "\f233"; -} - -.fa-user-plus:before { - content: "\f234"; -} - -.fa-user-times:before { - content: "\f235"; -} - -.fa-hotel:before, -.fa-bed:before { - content: "\f236"; -} - -.fa-viacoin:before { - content: "\f237"; -} - -.fa-train:before { - content: "\f238"; -} - -.fa-subway:before { - content: "\f239"; -} - -.fa-medium:before { - content: "\f23a"; -} - -.fa-yc:before, -.fa-y-combinator:before { - content: "\f23b"; -} - -.fa-optin-monster:before { - content: "\f23c"; -} - -.fa-opencart:before { - content: "\f23d"; -} - -.fa-expeditedssl:before { - content: "\f23e"; -} - -.fa-battery-4:before, -.fa-battery:before, -.fa-battery-full:before { - content: "\f240"; -} - -.fa-battery-3:before, -.fa-battery-three-quarters:before { - content: "\f241"; -} - -.fa-battery-2:before, -.fa-battery-half:before { - content: "\f242"; -} - -.fa-battery-1:before, -.fa-battery-quarter:before { - content: "\f243"; -} - -.fa-battery-0:before, -.fa-battery-empty:before { - content: "\f244"; -} - -.fa-mouse-pointer:before { - content: "\f245"; -} - -.fa-i-cursor:before { - content: "\f246"; -} - -.fa-object-group:before { - content: "\f247"; -} - -.fa-object-ungroup:before { - content: "\f248"; -} - -.fa-sticky-note:before { - content: "\f249"; -} - -.fa-sticky-note-o:before { - content: "\f24a"; -} - -.fa-cc-jcb:before { - content: "\f24b"; -} - -.fa-cc-diners-club:before { - content: "\f24c"; -} - -.fa-clone:before { - content: "\f24d"; -} - -.fa-balance-scale:before { - content: "\f24e"; -} - -.fa-hourglass-o:before { - content: "\f250"; -} - -.fa-hourglass-1:before, -.fa-hourglass-start:before { - content: "\f251"; -} - -.fa-hourglass-2:before, -.fa-hourglass-half:before { - content: "\f252"; -} - -.fa-hourglass-3:before, -.fa-hourglass-end:before { - content: "\f253"; -} - -.fa-hourglass:before { - content: "\f254"; -} - -.fa-hand-grab-o:before, -.fa-hand-rock-o:before { - content: "\f255"; -} - -.fa-hand-stop-o:before, -.fa-hand-paper-o:before { - content: "\f256"; -} - -.fa-hand-scissors-o:before { - content: "\f257"; -} - -.fa-hand-lizard-o:before { - content: "\f258"; -} - -.fa-hand-spock-o:before { - content: "\f259"; -} - -.fa-hand-pointer-o:before { - content: "\f25a"; -} - -.fa-hand-peace-o:before { - content: "\f25b"; -} - -.fa-trademark:before { - content: "\f25c"; -} - -.fa-registered:before { - content: "\f25d"; -} - -.fa-creative-commons:before { - content: "\f25e"; -} - -.fa-gg:before { - content: "\f260"; -} - -.fa-gg-circle:before { - content: "\f261"; -} - -.fa-tripadvisor:before { - content: "\f262"; -} - -.fa-odnoklassniki:before { - content: "\f263"; -} - -.fa-odnoklassniki-square:before { - content: "\f264"; -} - -.fa-get-pocket:before { - content: "\f265"; -} - -.fa-wikipedia-w:before { - content: "\f266"; -} - -.fa-safari:before { - content: "\f267"; -} - -.fa-chrome:before { - content: "\f268"; -} - -.fa-firefox:before { - content: "\f269"; -} - -.fa-opera:before { - content: "\f26a"; -} - -.fa-internet-explorer:before { - content: "\f26b"; -} - -.fa-tv:before, -.fa-television:before { - content: "\f26c"; -} - -.fa-contao:before { - content: "\f26d"; -} - -.fa-500px:before { - content: "\f26e"; -} - -.fa-amazon:before { - content: "\f270"; -} - -.fa-calendar-plus-o:before { - content: "\f271"; -} - -.fa-calendar-minus-o:before { - content: "\f272"; -} - -.fa-calendar-times-o:before { - content: "\f273"; -} - -.fa-calendar-check-o:before { - content: "\f274"; -} - -.fa-industry:before { - content: "\f275"; -} - -.fa-map-pin:before { - content: "\f276"; -} - -.fa-map-signs:before { - content: "\f277"; -} - -.fa-map-o:before { - content: "\f278"; -} - -.fa-map:before { - content: "\f279"; -} - -.fa-commenting:before { - content: "\f27a"; -} - -.fa-commenting-o:before { - content: "\f27b"; -} - -.fa-houzz:before { - content: "\f27c"; -} - -.fa-vimeo:before { - content: "\f27d"; -} - -.fa-black-tie:before { - content: "\f27e"; -} - -.fa-fonticons:before { - content: "\f280"; -} - -.fa-reddit-alien:before { - content: "\f281"; -} - -.fa-edge:before { - content: "\f282"; -} - -.fa-credit-card-alt:before { - content: "\f283"; -} - -.fa-codiepie:before { - content: "\f284"; -} - -.fa-modx:before { - content: "\f285"; -} - -.fa-fort-awesome:before { - content: "\f286"; -} - -.fa-usb:before { - content: "\f287"; -} - -.fa-product-hunt:before { - content: "\f288"; -} - -.fa-mixcloud:before { - content: "\f289"; -} - -.fa-scribd:before { - content: "\f28a"; -} - -.fa-pause-circle:before { - content: "\f28b"; -} - -.fa-pause-circle-o:before { - content: "\f28c"; -} - -.fa-stop-circle:before { - content: "\f28d"; -} - -.fa-stop-circle-o:before { - content: "\f28e"; -} - -.fa-shopping-bag:before { - content: "\f290"; -} - -.fa-shopping-basket:before { - content: "\f291"; -} - -.fa-hashtag:before { - content: "\f292"; -} - -.fa-bluetooth:before { - content: "\f293"; -} - -.fa-bluetooth-b:before { - content: "\f294"; -} - -.fa-percent:before { - content: "\f295"; -} - -.fa-gitlab:before { - content: "\f296"; -} - -.fa-wpbeginner:before { - content: "\f297"; -} - -.fa-wpforms:before { - content: "\f298"; -} - -.fa-envira:before { - content: "\f299"; -} - -.fa-universal-access:before { - content: "\f29a"; -} - -.fa-wheelchair-alt:before { - content: "\f29b"; -} - -.fa-question-circle-o:before { - content: "\f29c"; -} - -.fa-blind:before { - content: "\f29d"; -} - -.fa-audio-description:before { - content: "\f29e"; -} - -.fa-volume-control-phone:before { - content: "\f2a0"; -} - -.fa-braille:before { - content: "\f2a1"; -} - -.fa-assistive-listening-systems:before { - content: "\f2a2"; -} - -.fa-asl-interpreting:before, -.fa-american-sign-language-interpreting:before { - content: "\f2a3"; -} - -.fa-deafness:before, -.fa-hard-of-hearing:before, -.fa-deaf:before { - content: "\f2a4"; -} - -.fa-glide:before { - content: "\f2a5"; -} - -.fa-glide-g:before { - content: "\f2a6"; -} - -.fa-signing:before, -.fa-sign-language:before { - content: "\f2a7"; -} - -.fa-low-vision:before { - content: "\f2a8"; -} - -.fa-viadeo:before { - content: "\f2a9"; -} - -.fa-viadeo-square:before { - content: "\f2aa"; -} - -.fa-snapchat:before { - content: "\f2ab"; -} - -.fa-snapchat-ghost:before { - content: "\f2ac"; -} - -.fa-snapchat-square:before { - content: "\f2ad"; -} - -.fa-pied-piper:before { - content: "\f2ae"; -} - -.fa-first-order:before { - content: "\f2b0"; -} - -.fa-yoast:before { - content: "\f2b1"; -} - -.fa-themeisle:before { - content: "\f2b2"; -} - -.fa-google-plus-circle:before, -.fa-google-plus-official:before { - content: "\f2b3"; -} - -.fa-fa:before, -.fa-font-awesome:before { - content: "\f2b4"; -} - -.fa-handshake-o:before { - content: "\f2b5"; -} - -.fa-envelope-open:before { - content: "\f2b6"; -} - -.fa-envelope-open-o:before { - content: "\f2b7"; -} - -.fa-linode:before { - content: "\f2b8"; -} - -.fa-address-book:before { - content: "\f2b9"; -} - -.fa-address-book-o:before { - content: "\f2ba"; -} - -.fa-vcard:before, -.fa-address-card:before { - content: "\f2bb"; -} - -.fa-vcard-o:before, -.fa-address-card-o:before { - content: "\f2bc"; -} - -.fa-user-circle:before { - content: "\f2bd"; -} - -.fa-user-circle-o:before { - content: "\f2be"; -} - -.fa-user-o:before { - content: "\f2c0"; -} - -.fa-id-badge:before { - content: "\f2c1"; -} - -.fa-drivers-license:before, -.fa-id-card:before { - content: "\f2c2"; -} - -.fa-drivers-license-o:before, -.fa-id-card-o:before { - content: "\f2c3"; -} - -.fa-quora:before { - content: "\f2c4"; -} - -.fa-free-code-camp:before { - content: "\f2c5"; -} - -.fa-telegram:before { - content: "\f2c6"; -} - -.fa-thermometer-4:before, -.fa-thermometer:before, -.fa-thermometer-full:before { - content: "\f2c7"; -} - -.fa-thermometer-3:before, -.fa-thermometer-three-quarters:before { - content: "\f2c8"; -} - -.fa-thermometer-2:before, -.fa-thermometer-half:before { - content: "\f2c9"; -} - -.fa-thermometer-1:before, -.fa-thermometer-quarter:before { - content: "\f2ca"; -} - -.fa-thermometer-0:before, -.fa-thermometer-empty:before { - content: "\f2cb"; -} - -.fa-shower:before { - content: "\f2cc"; -} - -.fa-bathtub:before, -.fa-s15:before, -.fa-bath:before { - content: "\f2cd"; -} - -.fa-podcast:before { - content: "\f2ce"; -} - -.fa-window-maximize:before { - content: "\f2d0"; -} - -.fa-window-minimize:before { - content: "\f2d1"; -} - -.fa-window-restore:before { - content: "\f2d2"; -} - -.fa-times-rectangle:before, -.fa-window-close:before { - content: "\f2d3"; -} - -.fa-times-rectangle-o:before, -.fa-window-close-o:before { - content: "\f2d4"; -} - -.fa-bandcamp:before { - content: "\f2d5"; -} - -.fa-grav:before { - content: "\f2d6"; -} - -.fa-etsy:before { - content: "\f2d7"; -} - -.fa-imdb:before { - content: "\f2d8"; -} - -.fa-ravelry:before { - content: "\f2d9"; -} - -.fa-eercast:before { - content: "\f2da"; -} - -.fa-microchip:before { - content: "\f2db"; -} - -.fa-snowflake-o:before { - content: "\f2dc"; -} - -.fa-superpowers:before { - content: "\f2dd"; -} - -.fa-wpexplorer:before { - content: "\f2de"; -} - -.fa-meetup:before { - content: "\f2e0"; -} - -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; -} - -.sr-only-focusable:active, -.sr-only-focusable:focus { - position: static; - width: auto; - height: auto; - margin: 0; - overflow: visible; - clip: auto; -} diff --git a/assets/icons/font-awesome/css/font-awesome.min.css b/assets/icons/font-awesome/css/font-awesome.min.css deleted file mode 100644 index 540440c..0000000 --- a/assets/icons/font-awesome/css/font-awesome.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/assets/icons/font-awesome/fonts/FontAwesome.otf b/assets/icons/font-awesome/fonts/FontAwesome.otf deleted file mode 100644 index 401ec0f..0000000 Binary files a/assets/icons/font-awesome/fonts/FontAwesome.otf and /dev/null differ diff --git a/assets/icons/font-awesome/fonts/fontawesome-webfont.eot b/assets/icons/font-awesome/fonts/fontawesome-webfont.eot deleted file mode 100644 index e9f60ca..0000000 Binary files a/assets/icons/font-awesome/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/assets/icons/font-awesome/fonts/fontawesome-webfont.svg b/assets/icons/font-awesome/fonts/fontawesome-webfont.svg deleted file mode 100644 index 76f1bae..0000000 --- a/assets/icons/font-awesome/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,2672 +0,0 @@ - - - - - Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 - By ,,, - Copyright Dave Gandy 2016. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/icons/font-awesome/fonts/fontawesome-webfont.ttf b/assets/icons/font-awesome/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 35acda2..0000000 Binary files a/assets/icons/font-awesome/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/assets/icons/font-awesome/fonts/fontawesome-webfont.woff b/assets/icons/font-awesome/fonts/fontawesome-webfont.woff deleted file mode 100644 index 400014a..0000000 Binary files a/assets/icons/font-awesome/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/assets/icons/font-awesome/fonts/fontawesome-webfont.woff2 b/assets/icons/font-awesome/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 4d13fc6..0000000 Binary files a/assets/icons/font-awesome/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/assets/js/editor-in.js b/assets/js/editor-in.js deleted file mode 100644 index 87bff02..0000000 --- a/assets/js/editor-in.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Frontend Elementor Tweaks - * - * @package dtbaker-elementor - */ - -(function ($) { - - window.parent.elementor.on('elementor:init', function () { - console.log('loaded'); - }); - -})(jQuery); diff --git a/assets/js/editor.js b/assets/js/editor.js deleted file mode 100644 index aa96093..0000000 --- a/assets/js/editor.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Frontend Elementor Tweaks - * - * @package dtbaker-elementor - */ - -(function ($) { - - $(window).on('elementor:init', function () { - - /*elementor.hooks.addFilter( 'panel/elements/regionViews', function( regionViews ) { - - var regions = elementor.getRegions(); - - regionViews.dtbakerpage = { - region: regionViews.global.region, - view: Marionette.ItemView.extend({ - template: '#tmpl-elementor-panel-dtbakerpage', - - id: 'elementor-panel-dtbakerpage', - - initialize: function () { - setTimeout(function () { - elementor.getPanelView().getCurrentPageView().search.reset(); - }, 100); - }, - - onDestroy: function () { - elementor.getPanelView().getCurrentPageView().showView('search'); - } - } - ) - }; - - return regionViews; - } ); - - - var $templatewrap = $( '#tmpl-elementor-panel-elements' ); - var $template = $( '
' + $templatewrap.html() + '
' ); - $template.find( '.elementor-panel-navigation' ).append( '
Style
' ); - $templatewrap.html( $template.html() ); - elementor.on( 'elementor:init', function(){ - var $tabs = $( '#elementor-panel-elements-navigation' ); - } );*/ - - - //elementor.config.pro_library_url = 'https://elementor.com/pro/?ref=1164&campaign=prolib'; - console.log && console.log('Welcome to StylePress'); - }); - - $('body').on('change', 'select[data-setting="dynamic_field_value"]', function () { - $('#dtbaker-dynamic-code').text($(this).val() ? '{{' + $(this).val() + '}}' : ''); - }); - - var $templatewrap = $('#tmpl-elementor-panel-categories'); - if ($templatewrap.length) { - var $template = $('
' + $templatewrap.html() + '
'); - $template.find('a[href^="https://go.elementor.com"]').each(function () { - //$(this).attr('href', 'https://elementor.com/pro/?ref=1164&campaign=jslink'); - }); - $templatewrap.html($template.html()); - } - - var $templatewrap = $('#tmpl-elementor-panel-global'); - if ($templatewrap.length) { - var $template = $('
' + $templatewrap.html() + '
'); - $template.find('a[href^="https://go.elementor.com"]').each(function () { - //$(this).attr('href', 'https://elementor.com/pro/?ref=1164&campaign=jslinkglobal'); - }); - $templatewrap.html($template.html()); - } - - -})(jQuery); diff --git a/assets/js/frontend-css-editor.js b/assets/js/frontend-css-editor.js deleted file mode 100644 index f0a7df0..0000000 --- a/assets/js/frontend-css-editor.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Frontend CSS Editor - * - * @package dtbaker-elementor - */ - - -(function ($) { - - function async(u, c) { - var d = document, t = 'script', - o = d.createElement(t), - s = d.getElementsByTagName(t)[0]; - o.src = '//' + u; - if (c) { - o.addEventListener('load', function (e) { - c(null, e); - }, false); - } - s.parentNode.insertBefore(o, s); - } - - var css_editor_active = false; - - var $editor_holder, $showhide, $savebutton, ace_editor; - - function save_css() { - - } - - function ace_loaded_show_editor() { - - if (!$editor_holder) { - $editor_holder = $('
'); - $showhide = $('Show/Hide'); - $showhide.click(function (e) { - e.preventDefault(); - toggle_css_editor(); - return false; - }); - $savebutton = $('Save CSS'); - $savebutton.click(function (e) { - e.preventDefault(); - save_css(); - return false; - }); - $editor_holder.append('
'); - var $buttons = $('
'); - $buttons.append($showhide); - $buttons.append($savebutton); - $editor_holder.append($buttons); - $editor_holder.append('
/* loading */
'); - $('#wpadminbar').after($editor_holder); - } - - $('html').addClass('stylepress-csser'); - - - if (!ace_editor) { - // load in the css content from ajax, then init the editor - $.post(stylepress_css.ajaxurl, { - nonce: stylepress_css.nonce, - action: 'stylepress_get_css', - style_id: stylepress_css.style_id, - post_id: stylepress_css.post_id - }, function (response) { - if (response && response.success && response.data) { - $('#stylepress_css').text(response.data.css); - ace_editor = ace.edit("stylepress_css"); - ace_editor.setTheme("ace/theme/monokai"); - ace_editor.getSession().setMode("ace/mode/css"); - ace_editor.getSession().on('change', function (e) { - // e.type, etc - }); - } else { - $('#stylepress_css').text('Failed to load css'); - } - }); - } - css_editor_active = true; - - } - - - function toggle_css_editor() { - - if (!css_editor_active) { - // show it - if (typeof ace !== 'undefined') { - ace_loaded_show_editor(); - } else { - async('cdn.jsdelivr.net/ace/1.2.6/noconflict/ace.js', function () { - ace_loaded_show_editor(); - }); - } - } else { - // hide it - $('html').removeClass('stylepress-csser'); - css_editor_active = false; - } - } - - - $('body').on('click', '#wp-admin-bar-stylepress_navc a', function (e) { - e.preventDefault(); - toggle_css_editor(); - return false; - }); - -})(jQuery); diff --git a/assets/js/frontend.js b/assets/js/frontend.js deleted file mode 100644 index 0d56c71..0000000 --- a/assets/js/frontend.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Frontend Elementor Tweaks - * - * @package dtbaker-elementor - */ - - -(function ($) { - -})(jQuery); diff --git a/assets/js/omni-slider.js b/assets/js/omni-slider.js deleted file mode 100644 index d357903..0000000 --- a/assets/js/omni-slider.js +++ /dev/null @@ -1,564 +0,0 @@ -;(function () { - 'use strict'; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - - /* Constructor function - * elementContainer - this acts as a wrapper for the slider, all of the sliders DOM elements will be transcluded inside the provided - * options - contains the options for the slider - */ - - var Slider = function () { - function Slider() { - var elementContainer = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; - - _classCallCheck(this, Slider); - - // Validation of element, the only required argument - if (!elementContainer || elementContainer.nodeName !== 'DIV' && elementContainer.tagName !== 'DIV') return; - - // Contains the options for this slider - this.options = { - isOneWay: null, - isDate: null, - overlap: null, - callbackFunction: null, - min: null, - max: null, - start: null, - end: null - }; - - // Custom Logic for 1 way - var oneWay = false; - if (options.isOneWay) { - options.isOneWay = false; - options.overlap = true; - if (options.start && !options.end) { - options.end = options.start; - } - options.start = null; - oneWay = true; - } - - // Handles this.options creation and options initialization - this.init(options); - - // Contain pub/sub listeners - this.topics = { - start: [], - moving: [], - stop: [] - }; - - // Contains the DOM elements for the slider - this.UI = { - slider: null, - handleLeft: null, - handleRight: null, - fill: null - }; - - // Slider element - var sliderElem = document.createElement('div'); - if (oneWay) { - sliderElem.className = 'slider one-way'; - } else { - sliderElem.className = 'slider'; - } - this.UI.slider = sliderElem; - - // Left handle - var handleLeft = document.createElement('div'); - handleLeft.className = 'handle handle-left'; - var circleLeft = document.createElement('div'); - circleLeft.className = 'slider-circle'; - handleLeft.appendChild(circleLeft); - this.UI.handleLeft = handleLeft; - this.UI.slider.appendChild(this.UI.handleLeft); - - // Right handle - var handleRight = document.createElement('div'); - handleRight.className = 'handle handle-right'; - var circleRight = document.createElement('div'); - circleRight.className = 'slider-circle'; - handleRight.appendChild(circleRight); - this.UI.handleRight = handleRight; - this.UI.slider.appendChild(this.UI.handleRight); - - // Fill element - var fill = document.createElement('div'); - fill.className = 'slider-fill'; - this.UI.fill = fill; - this.UI.slider.appendChild(this.UI.fill); - - elementContainer.appendChild(this.UI.slider); - - // Move handles to have it's center as the end pointer point - this.UI.handleLeft.style.marginLeft = '-' + handleLeft.offsetWidth / 2 + 'px'; - this.UI.handleRight.style.marginRight = '-' + handleRight.offsetWidth / 2 + 'px'; - - // Push elements to starting positions - var data = { - left: this.options.start, - right: this.options.end - }; - this.move.bind(this)(data, true); - - // Bind events to start listening - this.startingHandler = this.starting.bind(this); - this.UI.handleLeft.onmousedown = this.startingHandler; - this.UI.handleLeft.ontouchstart = this.startingHandler; - this.UI.handleRight.onmousedown = this.startingHandler; - this.UI.handleRight.ontouchstart = this.startingHandler; - } - - /* Default config - * isOneWay (Boolean denotes if slider only has one handle) - * isDate (Boolean denotes if returning a moment wrapped value) - * overlap (Boolean denotes if handles will overlap or just sit next to each other) - * min and max (isDate ? typeof String [yyyy-mm-ddThh:mm] : typeof Number) - bounds - * start and end (isDate ? typeof String [yyyy-mm-ddThh:mm] : typeof Number) - starting position - */ - - - _createClass(Slider, [{ - key: 'extend', - - - /* Helper method (replace with shared function from library) */ - value: function extend() { - var defaults = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; - - var extended = {}; - var prop = void 0; - - for (prop in defaults) { - if (Object.prototype.hasOwnProperty.call(defaults, prop)) { - extended[prop] = defaults[prop]; - } - } - - for (prop in options) { - if (Object.prototype.hasOwnProperty.call(options, prop)) { - extended[prop] = options[prop]; - } - } - - return extended; - } - - // Initialize options and browser sniffing - - }, { - key: 'init', - value: function init() { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - - // Extend default options - if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') { - this.options = this.extend(this.defaultOptions, options); - } else { - this.options = this.defaultOptions; - } - - // Default start/end - this.options.start = this.options.start || this.options.min; - this.options.end = this.options.end || this.options.max; - - // Handle currency vs date type sanitization - if (this.options.isDate) { - this.options.max = new Date(this.options.max).valueOf(); - this.options.min = new Date(this.options.min).valueOf(); - - // Check if max and min are proper - if (this.options.max < this.options.min) { - this.options.min = this.options.max; - } - - // Check if start and end are within bounds - if (typeof this.options.start !== 'undefined' && typeof this.options.end !== 'undefined' && this.options.start <= this.options.end && new Date(this.options.start).valueOf() >= this.options.min && new Date(this.options.end).valueOf() <= this.options.max) { - this.options.start = new Date(this.options.start).valueOf(); - this.options.end = new Date(this.options.end).valueOf(); - } else { - this.options.start = new Date(this.options.min).valueOf(); - this.options.end = new Date(this.options.max).valueOf(); - } - } else { - this.options.max = parseFloat(this.options.max); - this.options.min = parseFloat(this.options.min); - - // Check if max and min are proper - if (this.options.max < this.options.min) { - this.options.min = this.options.max; - } - - // Check if start and end are within bounds - if (typeof this.options.start !== 'undefined' && typeof this.options.end !== 'undefined' && this.options.start <= this.options.end && this.options.start >= this.options.min && this.options.end <= this.options.max) { - this.options.start = parseFloat(this.options.start); - this.options.end = parseFloat(this.options.end); - } else { - this.options.start = this.options.min; - this.options.end = this.options.max; - } - } - } - - /* Provide information about the slider value - * Returns an Object with property left and right denoting left and right values */ - - }, { - key: 'getInfo', - value: function getInfo() { - var info = {}; - var total = this.options.max - this.options.min; - var left = this.UI.fill.style.left ? parseFloat(this.UI.fill.style.left.replace('%', '')) : 0; - var right = this.UI.fill.style.right ? parseFloat(this.UI.fill.style.right.replace('%', '')) : 0; - - if (this.options.isDate) { - info = { - left: new Date(this.options.min + left / 100 * total), - right: new Date(this.options.max - right / 100 * total) - }; - } else { - info = { - left: this.options.min + left / 100 * total, - right: this.options.max - right / 100 * total - }; - } - - if (typeof this.options.callbackFunction === 'function') { - info.left = this._applyCallback_(info.left, this.options.callbackFunction); - info.right = this._applyCallback_(info.right, this.options.callbackFunction); - } - - return info; - } - - /* - * Apply call back using data provided - **/ - - }, { - key: '_applyCallback_', - value: function _applyCallback_() { - var data = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0]; - var callback = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; - - try { - if (!callback) return null; - - return callback.call(undefined, data); - } catch (error) { - - throw error; - } - } - - /* When handle is pressed - * Attach all the necessary event handlers */ - - }, { - key: 'starting', - value: function starting() { - var event = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0]; - - if (!event) return; - - // Exit if disabled - if (this.isDisabled) return; - - var x = 0; - var y = 0; - - // Initialize drag object - this.dragObj = {}; - - // Get handle element node not the child nodes - // If this is a child of the parent try to find the handle element - this.dragObj.elNode = event.target; - - while (!this.dragObj.elNode.classList.contains('handle')) { - this.dragObj.elNode = this.dragObj.elNode.parentNode; - } - - // Direction where the slider control is going - this.dragObj.dir = this.dragObj.elNode.classList.contains('handle-left') ? 'left' : 'right'; - - // Get cursor position wrt the page - // If touch screen (event.touches) and if IE11 (pageXOffset) - x = (typeof event.clientX !== 'undefined' ? event.clientX : event.touches[0].pageX) + (window.scrollX || window.pageXOffset); - y = (typeof event.clientY !== 'undefined' ? event.clientY : event.touches[0].pageY) + (window.scrollY || window.pageYOffset); - - // Save starting positions of cursor and element - this.dragObj.cursorStartX = x; - this.dragObj.cursorStartY = y; - this.dragObj.elStartLeft = parseFloat(this.dragObj.elNode.style.left); - this.dragObj.elStartRight = parseFloat(this.dragObj.elNode.style.right); - if (isNaN(this.dragObj.elStartLeft)) this.dragObj.elStartLeft = 0; - if (isNaN(this.dragObj.elStartRight)) this.dragObj.elStartRight = 0; - - // Update element's positioning for z-index - // The element last moved will have a higher positioning - this.UI.handleLeft.classList.remove('ontop'); - this.UI.handleRight.classList.remove('ontop'); - this.dragObj.elNode.classList.add('ontop'); - - // Capture mousemove and mouseup events on the page - this.movingHandler = this.moving.bind(this); - this.stopHandler = this.stop.bind(this); - document.addEventListener('mousemove', this.movingHandler, true); - document.addEventListener('mouseup', this.stopHandler, true); - document.addEventListener('touchmove', this.movingHandler, true); - document.addEventListener('touchend', this.stopHandler, true); - - // Stop default events - this.stopDefault.bind(this)(event); - this.UI.fill.classList.remove('slider-transition'); - this.UI.handleLeft.classList.remove('slider-transition'); - this.UI.handleRight.classList.remove('slider-transition'); - - // Pub/sub lifecycle - start - this.publish('start', this.getInfo()); - } - - /* When handle is being moved */ - - }, { - key: 'moving', - value: function moving(event) { - // Get cursor position with respect to the page - var x = (typeof event.clientX !== 'undefined' ? event.clientX : event.touches[0].pageX) + (window.scrollX || window.pageXOffset); - - // Move drag element by the same amount the cursor has moved - var sliderWidth = this.UI.slider.offsetWidth; - var calculatedVal = 0; - if (this.dragObj.dir === 'left') { - calculatedVal = this.dragObj.elStartLeft + (x - this.dragObj.cursorStartX) / sliderWidth * 100; - } else if (this.dragObj.dir === 'right') { - calculatedVal = this.dragObj.elStartRight + (this.dragObj.cursorStartX - x) / sliderWidth * 100; - } - - // Keep handles within range - if (calculatedVal < 0) { - calculatedVal = 0; - } else if (calculatedVal > 100) { - calculatedVal = 100; - } - - // Sanitize to work for both directions - // Since we are adding to left and right there should not be a negative number - calculatedVal = Math.abs(calculatedVal); - - // Take into account the handle when calculating space left - var handleOffset = 0; - if (!this.options.overlap) { - handleOffset = this.UI.handleRight.offsetWidth / this.UI.slider.offsetWidth * 100; - } - - // Add movement based on handle direction - var remaining = 0; - if (this.dragObj.dir === 'left') { - remaining = 100 - handleOffset - this.UI.fill.style.right.replace('%', ''); - if (remaining <= calculatedVal) { - calculatedVal = remaining; - } - - this.dragObj.elNode.style.left = calculatedVal + '%'; - this.UI.fill.style.left = calculatedVal + '%'; - } else { - remaining = 100 - handleOffset - this.UI.fill.style.left.replace('%', ''); - if (remaining <= calculatedVal) { - calculatedVal = remaining; - } - - this.dragObj.elNode.style.right = calculatedVal + '%'; - this.UI.fill.style.right = calculatedVal + '%'; - } - - // Stop default events - this.stopDefault.bind(this)(event); - - // Pub/sub lifecycle - moving - this.publish('moving', this.getInfo()); - } - - /* When handle is blured - do clean up */ - - }, { - key: 'stop', - value: function stop(event) { - // Stop capturing mousemove and mouseup events - document.removeEventListener('mousemove', this.movingHandler, true); - document.removeEventListener('mouseup', this.stopHandler, true); - document.removeEventListener('touchmove', this.movingHandler, true); - document.removeEventListener('touchend', this.stopHandler, true); - - // Stop default events - this.stopDefault.bind(this)(event); - - // Pub/sub lifecycle - stop - this.publish('stop', this.getInfo()); - } - - /* Push elements to position based on data */ - - }, { - key: 'move', - value: function move(data, preventPublish) { - var importedData = data; - - // Transition effects (cleaned up at Slider.prototype.starting); - this.UI.fill.classList.add('slider-transition'); - this.UI.handleLeft.classList.add('slider-transition'); - this.UI.handleRight.classList.add('slider-transition'); - - var total = this.options.max - this.options.min; - - if ((typeof importedData === 'undefined' ? 'undefined' : _typeof(importedData)) === 'object') { - if (importedData.left) { - if (importedData.left < this.options.min) importedData.left = this.options.min; - if (importedData.left > this.options.max) importedData.left = this.options.max; - - var posLeft = (importedData.left - this.options.min) / total * 100; - this.UI.handleLeft.style.left = posLeft + '%'; - this.UI.fill.style.left = posLeft + '%'; - } - - if (importedData.right) { - if (importedData.right < this.options.min) importedData.right = this.options.min; - if (importedData.right > this.options.max) importedData.right = this.options.max; - - var posRight = (this.options.max - importedData.right) / total * 100; - this.UI.handleRight.style.right = posRight + '%'; - this.UI.fill.style.right = posRight + '%'; - } - - // If overlap is not enabled then check if the starting positions are overlapping - reset to full - if (!this.options.overlap && this.UI.handleLeft.offsetLeft + this.UI.handleLeft.offsetWidth > this.UI.handleRight.offsetLeft - 1) { - this.UI.fill.style.left = '0%'; - this.UI.fill.style.right = '0%'; - this.UI.handleLeft.style.left = '0%'; - this.UI.handleRight.style.right = '0%'; - } - } else if (!isNaN(importedData)) { - if (importedData < this.options.min) importedData = this.options.min; - if (importedData > this.options.max) importedData = this.options.max; - - var pos = (importedData - this.options.min) / total * 100; - this.UI.handleLeft.style.left = pos + '%'; - this.UI.fill.style.left = '0%'; - this.UI.fill.style.right = 100 - pos + '%'; - } - - // Pub/sub lifecycle - moving - if (!preventPublish) { - this.publish('moving', this.getInfo()); - } - } - - /* Utility function to stop default events */ - - }, { - key: 'stopDefault', - value: function stopDefault() { - var event = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0]; - - if (!event) return; - - event.preventDefault(); - } - - /* Accessor for disable property */ - - }, { - key: 'disable', - value: function disable(boolean) { - this.isDisabled = boolean; - if (this.isDisabled) { - this.UI.slider.classList.add('slider-disabled'); - } else { - this.UI.slider.classList.remove('slider-disabled'); - } - } - - /* Subscribe hook - * Topic - keyword (start, moving, end) - * Listener - function that will be called when topic is fired with argument of getInfo() data - */ - - }, { - key: 'subscribe', - value: function subscribe() { - var topic = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0]; - var listener = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; - - - if (!topic || !listener) return {}; - - // Check validity of topic and listener - if (!this.topics.hasOwnProperty.call(this.topics, topic) || typeof topic !== 'string' || typeof listener !== 'function') return {}; - - // Add the listener to queue - // Retrieve the index for deletion - var index = this.topics[topic].push(listener) - 1; - - // Return instance of the subscription for deletion - return { - remove: function () { - delete this.topics[topic][index]; - }.bind(this) - }; - } - - /* Publish hook - * Topic - keyword (start, moving, end) - * Data - getInfo() result to pass into the listener - */ - - }, { - key: 'publish', - value: function publish() { - var topic = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0]; - var data = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; - - - if (!topic || !data) return; - - // Check validity of topic - if (!this.topics.hasOwnProperty.call(this.topics, topic) || typeof topic !== 'string') return; - - // Cycle through events in the queue and fire them with the slider data - this.topics[topic].forEach(function (event) { - event(data); - }); - } - }, { - key: 'defaultOptions', - get: function get() { - return { - isOneWay: false, - isDate: false, - overlap: false, - callbackFunction: null, - min: 0, - max: 100 - }; - } - }]); - - return Slider; - }(); - - if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { - module.exports = Slider; - } else { - window.Slider = Slider; - } -}()); diff --git a/assets/js/payment.js b/assets/js/payment.js deleted file mode 100644 index bf36957..0000000 --- a/assets/js/payment.js +++ /dev/null @@ -1,208 +0,0 @@ -/** - * Payment pay - * - * @package dtbaker-elementor - */ - - -(function ($) { - - var stripe_pub_key = 'pk_live_sHzlXhBGv3ySRTVbsCGkxcgd'; - var loading_stripe = false; - var stripe_load_done = false; - var purchasing_style = {}; - var $dialog = false; - var stripe = false, card = false; - - function bind_stripe_elements() { - - stripe = Stripe(stripe_pub_key); - var elements = stripe.elements(); - - var style = { - base: { - color: '#32325d', - lineHeight: '24px', - fontFamily: 'Helvetica Neue', - fontSmoothing: 'antialiased', - fontSize: '16px', - '::placeholder': { - color: '#aab7c4' - } - }, - invalid: { - color: '#fa755a', - iconColor: '#fa755a' - } - }; - - - card = elements.create('card', {style: style}); - card.mount('.stripe-card-element'); - - // Handle real-time validation errors from the card Element. - card.addEventListener('change', function (event) { - const displayError = document.getElementById('card-errors'); - if (event.error) { - displayError.textContent = event.error.message; - } else { - displayError.textContent = ''; - } - }); - - } - - function stylepress_stripe_has_loaded() { - - loading_stripe = false; - stripe_load_done = true; - - bind_stripe_elements(); - - - } - - function open_popup() { - if ($('#stylepress-payment-pop').length) { - $('#stylepress-payment-pop').remove(); - } - $dialog = $('
'); - $dialog.html($('#tmpl-stylepress-payment-popup').html()); - - $dialog.dialog({ - title: 'Purchase', - dialogClass: 'wp-dialog', - autoOpen: true, - draggable: true, - width: 'auto', - modal: true, - resizable: false, - closeOnEscape: true, - position: { - my: "center", - at: "center", - of: window - }, - open: function () { - // close dialog by clicking the overlay behind it - $dialog.find('.ui-widget-overlay').bind('click', function () { - $dialog.dialog('close'); - }); - var slider4 = new Slider(document.getElementById('stylepress-card-amount'), { - isOneWay: true, - start: parseInt(purchasing_style.stylecost), - min: 1, - max: 40 - }); - slider4.subscribe('moving', function (data) { - document.getElementById('stylepress-amount-update').innerHTML = '$' + Math.round(data.right); - $('.stylepress-card-amount-value').val(Math.round(data.right)); - }); - document.getElementById('stylepress-amount-update').innerHTML = '$' + Math.round(slider4.getInfo().right); - $('.stylepress-card-amount-value').val(parseInt(purchasing_style.stylecost)); - - var $btn = $dialog.find('.stylepress-final-purchase-button'); - $btn.text('Purchase & Install Style: ' + purchasing_style.stylename); - $btn.click(function () { - $dialog.find('.stylepress-payment-popup').addClass('processing'); - stripe.createToken(card).then(function (result) { - if (!result) { - $dialog.find('.stylepress-payment-popup').removeClass('processing'); - alert('Failed to process stripe'); - } else if (result.error) { - // Inform the user if there was an error - $dialog.find('.stylepress-payment-popup').removeClass('processing'); - var errorElement = document.getElementById('card-errors'); - errorElement.textContent = result.error.message; - } else { - // Send the token to our stylepress server for processing. - var postdata = stylepress_payment || {}; - postdata.token = result.token.id; - postdata.purchase = purchasing_style.styleslug; - postdata.name = $dialog.find('input[name="name"]').val(); - postdata.email = $dialog.find('input[name="email"]').val(); - postdata.amount = $dialog.find('input[name="amount"]').val(); - $.ajax({ - type: 'POST', - url: 'https://styleserver.stylepress.org/wp-admin/admin-ajax.php?action=stylepress_payment', - crossDomain: true, - data: postdata, - dataType: 'json', - success: function (responseData, textStatus, jqXHR) { - if (responseData && responseData.success && responseData.data) { - // success! redirect to install page. - - // post our purchase token to the local wp install, we send this along with install requests to verify payment. - $.post(ajaxurl, { - 'action': 'stylepress_purchase_complete', - 'payment': stylepress_payment, - 'server': responseData.data - }, function (response) { - - if (!response.success) { - alert("failed to record local payment. Please contact dtbaker."); - } - - window.location.href = purchasing_style.redirect; - - }, 'json').fail(function () { - alert("Error saving local payment. Contact dtbaker."); - }); - - } else { - $dialog.find('.stylepress-payment-popup').removeClass('processing'); - alert('Payment failed. ' + (typeof responseData.message != 'undefined' ? responseData.message : '')); - } - }, - error: function (responseData, textStatus, errorThrown) { - $dialog.find('.stylepress-payment-popup').removeClass('processing'); - alert('Payment processing failed.'); - } - }); - } - }); - }); - - - }, - create: function () { - // style fix for WordPress admin - $dialog.find('.ui-dialog-titlebar-close').addClass('ui-button'); - } - }); - } - - function stylepress_load_stripe() { - if (loading_stripe) { - return; - } - if (stripe_load_done) { - stylepress_stripe_has_loaded(); - } - loading_stripe = true; - var script = document.createElement('script'); - script.type = 'text/javascript'; - script.src = 'https://js.stripe.com/v3/'; - document.head.appendChild(script); - script.onload = stylepress_stripe_has_loaded; - } - - $(function () { - $('.button-stylepress-pay').click(function (e) { - e.preventDefault(); - - $(this).addClass('paying'); - - purchasing_style = $(this).data(); - purchasing_style.redirect = $(this).attr('href'); - - open_popup(); - - stylepress_load_stripe(); - - return false; - }); - }); - -})(jQuery); - diff --git a/components/backend/ui.php b/components/backend/ui.php new file mode 100644 index 0000000..9bc1c9b --- /dev/null +++ b/components/backend/ui.php @@ -0,0 +1,130 @@ +add_top_level_menu(); + + if($top_level_slug) { + \StylePress\Layout\Layout::get_instance()->add_submenu($top_level_slug); + \StylePress\Styles\Styles::get_instance()->add_submenu($top_level_slug); + } + } + + /** + * Adds a meta box to every post type. + * + * @since 2.0.0 + */ + public function meta_box_add() { + if(\StylePress\Core\Permissions::get_instance()->can_edit_post_meta_boxes()) { + $post_types = get_post_types(); + foreach ( $post_types as $post_type ) { + if ( ! in_array( $post_type, array( Cpt::CPT, 'elementor_library' ), true ) ) { + add_meta_box( + 'stylepress_style_metabox', + __( 'StylePress', 'stylepress' ), + array( $this, 'meta_box_display' ), + $post_type, + 'side', + 'high' + ); + } + } + } + } + + /** + * This renders our metabox on most page/post types. + * + * @param \WP_Post $post Current post object. + * + * @since 2.0.0 + * + */ + public function meta_box_display( $post ) { + if(\StylePress\Core\Permissions::get_instance()->can_edit_post_meta_boxes($post)) { + $default_styles = Data::get_instance()->get_default_styles(); + $page_styles = Data::get_instance()->get_page_styles( $post->ID ); + $page_status = Data::get_instance()->is_stylpress_enabled( $post ); + $categories = Data::get_instance()->get_categories(); + $page_type = Render::get_instance()->get_current_page_type(); + + include_once __DIR__ . '/views/post-meta-box.php'; + } + } + + /** + * Saves our metabox details, which is the style for a particular page. + * + * @param int $post_id The post we're current saving. + * + * @since 2.0.0 + * + */ + public function meta_box_save( $post_id ) { + // Check if our nonce is set. + if ( ! isset( $_POST['stylepress_style_nonce'] ) ) { // WPCS: input var okay. + return; + } + + // Verify that the nonce is valid. + if ( ! wp_verify_nonce( $_POST['stylepress_style_nonce'], 'stylepress_style_nonce' ) ) { // WPCS: sanitization ok. input var okay. + return; + } + + // If this is an autosave, our form has not been submitted, so we don't want to do anything. + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { + return; + } + + if ( isset( $_POST['stylepress_style'] ) && is_array( $_POST['stylepress_style'] ) ) { // WPCS: sanitization ok. input var okay. + $custom_post_styles = []; + $categories = Data::get_instance()->get_categories(); + $default_styles = Data::get_instance()->get_default_styles(); + + foreach ( $categories as $category ) { + if ( $category['global_selector'] && !empty($_POST['stylepress_style'][$category['slug']])) { + $custom_post_styles[$category['slug']] = $_POST['stylepress_style'][$category['slug']]; + } + } + update_post_meta( $post_id, 'stylepress_style', $custom_post_styles ); // WPCS: sanitization ok. input var okay. + } + } +} diff --git a/components/backend/views/post-meta-box.php b/components/backend/views/post-meta-box.php new file mode 100644 index 0000000..f0afcd0 --- /dev/null +++ b/components/backend/views/post-meta-box.php @@ -0,0 +1,78 @@ + + + +

+ + +

+ + + +

+ and the second %s is a closing link . + printf( esc_html__( 'Choose the styles for this "%s" below.', 'stylepress' ), $page_type ); ?> +

+ get_all_styles( $category['slug'], true ); + if ( $designs ) { + ?> +

+ +

+ + editor->is_edit_mode() ) { + $post = get_post(); + if ( $post->post_type === Cpt::CPT ) { + $post_categories = get_the_terms( $post->ID, STYLEPRESS_SLUG . '-cat' ); + $categories = \StylePress\Styles\Data::get_instance()->get_categories(); + foreach ( $categories as $category ) { + foreach ( $post_categories as $post_category ) { + if ( $post_category->slug === $category['slug'] && ! empty( $category['inner'] ) ) { + $is_inner_content_page = true; + } + } + } + } + } + + return $is_inner_content_page; + } + + + public function has_permission( $post = false ) { + return current_user_can( 'edit_posts' ); + //current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) + } + + + + public function get_active_style_id() { + return get_theme_mod( 'stylepress_active_style_id' ); + } + + public function set_active_style_id( $style_id ) { + set_theme_mod( 'stylepress_active_style_id', $style_id ); + } + + public function get_active_style_data() { + $active_style_id = $this->get_active_style_id(); + if($active_style_id) { + return $this->get_style_data( $active_style_id ); + } + } + + /** + * When a remote style is imported it comes with a bunch of data we use for TGM and other things. + * This is stored in the stylepress_data post meta object. + * + * @param $style_id + * + * @return mixed + */ + public function get_style_data( $style_id ) { + return get_post_meta($style_id, 'stylepress_data', true); + } + + + public function stylepress_export() { + + if ( ! isset( $_GET['stylepress_export_data'] ) || empty( $_GET['post_id'] ) ) { // WPCS: input var okay. + return; + } + + // Verify that the nonce is valid. + if ( ! wp_verify_nonce( $_GET['stylepress_export_data'], 'stylepress_export_data' ) ) { // WPCS: sanitization ok. input var okay. + return; + } + + $post_id = (int) $_GET['post_id']; + + if ( ! $this->has_permission( $post_id ) ) { + return; + } + + require_once STYLEPRESS_PATH . 'inc/class.import-export.php'; + $import_export = StylepressImportExport::get_instance(); + $data = $import_export->export_data( $post_id ); + + echo '
';
+		print_r( $data );
+		echo '
'; + exit; + + wp_send_json( $data ); + + exit; + } + + public function stylepress_clone() { + + if ( ! isset( $_GET['stylepress_clone'] ) || empty( $_GET['post_id'] ) ) { // WPCS: input var okay. + return; + } + + // Verify that the nonce is valid. + if ( ! wp_verify_nonce( $_GET['stylepress_clone'], 'stylepress_clone' ) ) { // WPCS: sanitization ok. input var okay. + return; + } + + $post_id = (int) $_GET['post_id']; + + $post = get_post( $post_id ); + + /* + * if post data exists, create the post duplicate + */ + if ( $post && Styles::CPT === $post->post_type ) { + + if ( ! $post->post_parent ) { + $post->post_parent = $post_id; // we're cloaning the parent one, put it underneath itself. + } + $args = array( + 'comment_status' => $post->comment_status, + 'ping_status' => $post->ping_status, + 'post_author' => $post->post_author, + 'post_content' => $post->post_content, + 'post_excerpt' => $post->post_excerpt, + 'post_name' => $post->post_name, + 'post_parent' => $post->post_parent, + 'post_password' => $post->post_password, + 'post_status' => $post->post_status, + 'post_title' => '(clone) ' . $post->post_title, + 'post_type' => $post->post_type, + 'to_ping' => $post->to_ping, + 'menu_order' => $post->menu_order + ); + + /* + * insert the post by wp_insert_post() function + */ + $new_post_id = wp_insert_post( $args ); + + if ( $new_post_id ) { + global $wpdb; + /* + * duplicate all post meta just in two SQL queries + */ + $post_meta_infos = $wpdb->get_results( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id" ); + if ( count( $post_meta_infos ) != 0 ) { + $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) "; + $sql_query_sel = array(); + foreach ( $post_meta_infos as $meta_info ) { + $meta_key = $meta_info->meta_key; + $meta_value = esc_sql( $meta_info->meta_value ); + $sql_query_sel[] = "SELECT $new_post_id, '$meta_key', '$meta_value'"; + } + + $sql_query .= implode( " UNION ALL ", $sql_query_sel ); + $wpdb->query( $sql_query ); + } + + wp_safe_redirect( get_edit_post_link( $new_post_id, 'edit' ) ); + exit; + + } + + + } + + return false; + + } + + + +} + diff --git a/components/core/settings.php b/components/core/settings.php new file mode 100644 index 0000000..d9129e4 --- /dev/null +++ b/components/core/settings.php @@ -0,0 +1,82 @@ +get(); + $settings[ $key ] = $value; + update_option( self::OPTION_KEY, $settings ); + } + + /** + * Returns a list of all our configuraable page types. + * + * @since 2.0.0 + * + */ + public function get_all_page_types() { + $defaults = array( + '_global' => 'Global Default', + 'front_page' => 'Front/Home Page', + 'page' => 'Single Page', + 'post' => 'Single Blog Post', + 'category' => 'Category', + 'search' => 'Search Results', + '404' => '404 Page', + 'archive' => 'Archive Pages', + 'tag' => 'Tag Pages', + 'attachment' => 'Image Attachment', + ); + + if ( function_exists( 'WC' ) ) { + // add our own woocommerce entries. + $defaults['products'] = 'WooCommerce Shop'; + $defaults['product'] = 'WooCommerce Product'; + $defaults['product_category'] = 'WooCommerce Category'; + } + + $post_types = get_post_types( array( 'public' => true ) ); + foreach ( $post_types as $post_type ) { + if ( ! in_array( $post_type, array( \StylePress\Styles\Cpt::CPT, 'elementor_library', 'attachment' ), true ) ) { + if ( ! isset( $defaults[ $post_type ] ) ) { + $data = get_post_type_object( $post_type ); + $defaults[ $post_type ] = $data->labels->singular_name; + } + } + } + + return apply_filters( 'stylepress_page_types', $defaults ); + } + +} + diff --git a/components/data/envato-setup-export.php b/components/data/envato-setup-export.php new file mode 100644 index 0000000..b879679 --- /dev/null +++ b/components/data/envato-setup-export.php @@ -0,0 +1,249 @@ + '' ) ); +$taxonomies = get_taxonomies(); +foreach ( $post_types_to_export as $post_type ) { + if ( in_array( $post_type, array( 'revision', 'event', 'event-recurring' ) ) ) { + continue; + } // post types to ignore. + $args = array( 'post_type' => $post_type, 'posts_per_page' => - 1 ); + $args['post_status'] = array( 'publish', 'private', 'inherit' ); + $post_datas = get_posts( $args ); + if ( ! isset( $default_content[ $post_type ] ) ) { + $default_content[ $post_type ] = array(); + } + $object = get_post_type_object( $post_type ); + if ( $object && ! empty( $object->labels->singular_name ) ) { + $type_title = $object->labels->name; + } else { + $type_title = ucwords( $post_type ) . 's'; + } + + foreach ( $post_datas as $post_data ) { + $meta = get_post_meta( $post_data->ID, '', true ); + if ( $post_data->ID == 65 ) { + // print_r($meta); exit; + } + foreach ( $meta as $meta_key => $meta_val ) { + if ( + // which keys to nuke all the time + in_array( $meta_key, array( '_location_id' ) ) + || + ( + // which keys we want to keep all the time, using strpos: + strpos( $meta_key, 'elementor' ) === false && + strpos( $meta_key, 'dtbaker' ) === false && + strpos( $meta_key, 'vc_' ) === false && + strpos( $meta_key, 'wpb_' ) === false && + strpos( $meta_key, 'dtbwp_' ) === false && + strpos( $meta_key, '_slider' ) === false && + // which post types we keep all meta values for: + ! in_array( $post_type, array( + 'nav_menu_item', + 'location', + 'event', + 'product', + 'wpcf7_contact_form', + ) ) && + // other meta keys we always want to keep: + ! in_array( $meta_key, array( + 'dtbwp_post_title_details', + 'dtbwp_page_style', + 'sliderlink', + 'slidercolor', + '_wp_attached_file', + '_thumbnail_id', + ) ) + ) + ) { + unset( $meta[ $meta_key ] ); + } else { + $meta[ $meta_key ] = maybe_unserialize( get_post_meta( $post_data->ID, $meta_key, true ) ); + } + } + // copy stock images into the images/stock/ folder for theme import. + if ( $post_type === 'attachment' ) { + $file = get_attached_file( $post_data->ID ); + if ( is_file( $file ) ) { + if ( filesize( $file ) > 1500000 ) { + $image = wp_get_image_editor( $file ); + if ( ! is_wp_error( $image ) ) { + list( $width, $height, $type, $attr ) = getimagesize( $file ); + $image->resize( min( $width, 1200 ), null, false ); + $image->save( $file ); + } + } + $post_data->guid = wp_get_attachment_url( $post_data->ID ); + if ( is_dir( $export_images_path ) ) { + copy( $file, trailingslashit( $export_images_path ) . basename( $file ) ); + } + } + // fix for incorrect GUID when renaming files with the rename plugin, causes import to bust. + + } + $terms = array(); + foreach ( $taxonomies as $taxonomy ) { + $terms[ $taxonomy ] = wp_get_post_terms( $post_data->ID, $taxonomy, array( 'fields' => 'all' ) ); + if ( $terms[ $taxonomy ] ) { + foreach ( $terms[ $taxonomy ] as $tax_id => $tax ) { + if ( ! empty( $tax->term_id ) ) { + $terms[ $taxonomy ][ $tax_id ]->meta = get_term_meta( $tax->term_id ); + if ( ! empty( $terms[ $taxonomy ][ $tax_id ]->meta ) ) { + foreach ( $terms[ $taxonomy ][ $tax_id ]->meta as $key => $val ) { + if ( is_array( $val ) && count( $val ) == 1 && isset( $val[0] ) ) { + $terms[ $taxonomy ][ $tax_id ]->meta[ $key ] = $val[0]; + } + } + } + } + } + } + } + $default_content[ $post_type ][] = array( + 'type_title' => $type_title, + 'post_id' => $post_data->ID, + 'post_title' => $post_data->post_title, + 'post_status' => $post_data->post_status, + 'post_name' => $post_data->post_name, + 'post_content' => $post_data->post_content, + 'post_excerpt' => $post_data->post_excerpt, + 'post_parent' => $post_data->post_parent, + 'menu_order' => $post_data->menu_order, + 'post_date' => $post_data->post_date, + 'post_date_gmt' => $post_data->post_date_gmt, + 'guid' => $post_data->guid, + 'post_mime_type' => $post_data->post_mime_type, + 'meta' => $meta, + 'terms' => $terms, + // 'other' => $post_data, + ); + } +} +// put certain content at very end. +$nav = isset( $default_content['nav_menu_item'] ) ? $default_content['nav_menu_item'] : array(); +if ( $nav ) { + unset( $default_content['nav_menu_item'] ); + $default_content['nav_menu_item'] = $nav; +} +// print_r($default_content); +// exit; +// find the ID of our menu names so we can import them into default menu locations and also the widget positions below. +$menus = get_terms( 'nav_menu' ); +$menu_ids = array(); +foreach ( $menus as $menu ) { + if ( $menu->name == 'Main Menu' ) { + $menu_ids['primary'] = $menu->term_id; + } else if ( $menu->name == 'Quick Links' ) { + $menu_ids['footer_quick'] = $menu->term_id; + } +} +// used for me to export my widget settings. +$widget_positions = get_option( 'sidebars_widgets' ); +$widget_options = array(); +$my_options = array(); +foreach ( $widget_positions as $sidebar_name => $widgets ) { + if ( is_array( $widgets ) ) { + foreach ( $widgets as $widget_name ) { + $widget_name_strip = preg_replace( '#-\d+$#', '', $widget_name ); + $widget_options[ $widget_name_strip ] = get_option( 'widget_' . $widget_name_strip ); + } + } +} +// choose which custom options to load into defaults +$all_options = wp_load_alloptions(); +//print_r($all_options);exit; +foreach ( $all_options as $name => $value ) { + if ( stristr( $name, 'elementor' ) ) { + $my_options[ $name ] = maybe_unserialize( $value ); + } + if ( stristr( $name, '_widget_area_manager' ) ) { + $my_options[ $name ] = $value; + } + if ( stristr( $name, 'wam_' ) ) { + $my_options[ $name ] = $value; + } + //if ( stristr( $name, 'dbem_' ) !== false ) { $my_options[ $name ] = $value; } + // if ( stristr( $name, 'woo' ) !== false ) { $my_options[ $name ] = $value; } + if ( stristr( $name, 'dtbaker_featured_images' ) !== false ) { + $my_options[ $name ] = $value; + } + if ( 'theme_mods_theme-textdomain-here' === $name ) { + $my_options[ $name ] = maybe_unserialize( $value ); + $my_options[ $name . '-child' ] = maybe_unserialize( $value ); + unset( $my_options[ $name ]['nav_menu_locations'] ); + } +} +$my_options['dbem_credits'] = 0; +$my_options['woocommerce_cart_redirect_after_add'] = 'yes'; +$my_options['woocommerce_enable_ajax_add_to_cart'] = 'no'; +//$my_options['travel_settings'] = array( 'api_key' => 'AIzaSyBsnYWO4SSibatp0SjsU9D2aZ6urI-_cJ8' ); +//$my_options['tt-font-google-api-key'] = 'AIzaSyBsnYWO4SSibatp0SjsU9D2aZ6urI-_cJ8'; +$my_options = $this->filter_options( $my_options ); + +if ( is_dir( $export_content_path ) ) { + + // which style are we writing to? + $stylefolder = basename( get_theme_mod( 'dtbwp_site_style', $this->get_default_theme_style() ) ); + if ( $stylefolder ) { + $export_content_path = trailingslashit( $export_content_path ) . $stylefolder; + if ( ! is_dir( $export_content_path ) ) { + wp_mkdir_p( $export_content_path ); // if directory didn't exist, let's create it + } + } + file_put_contents( trailingslashit( $export_content_path ) . 'default.json', json_encode( $default_content ) ); + file_put_contents( trailingslashit( $export_content_path ) . 'widget_positions.json', json_encode( $widget_positions ) ); + file_put_contents( trailingslashit( $export_content_path ) . 'widget_options.json', json_encode( $widget_options ) ); + file_put_contents( trailingslashit( $export_content_path ) . 'menu.json', json_encode( $menu_ids ) ); + file_put_contents( trailingslashit( $export_content_path ) . 'options.json', json_encode( $my_options ) ); +} + +?> +

:

+

+
+ +

+

+ +
+ +

+get_current_site_style() ); + $export_path = trailingslashit( WP_CONTENT_DIR ) . 'stylepress-export/' . basename( $stylefolder ); + $export_images_path = trailingslashit( $export_path ) . 'images'; + $export_content_path = trailingslashit( $export_path ) . 'content'; + $return['current_style'] = $stylefolder; + $return['export_path'] = $export_path; + $return['export_images_path'] = $export_images_path; + $return['export_content_path'] = $export_content_path; + + // if directory didn't exist, let's create it + if ( ! is_dir( $export_content_path ) ) { + wp_mkdir_p( $export_content_path ); + } + if ( ! is_dir( $export_images_path ) ) { + wp_mkdir_p( $export_images_path ); + } + + $default_content = array(); + $post_types_to_export = array( 'attachment', 'wpcf7_contact_form', 'post', 'page' ); + foreach ( get_post_types() as $post_type ) { + if ( ! in_array( $post_type, $post_types_to_export ) ) { // which post types to ignore. + $post_types_to_export[] = $post_type; + } + } + $categories = get_categories( array( 'type' => '' ) ); + $taxonomies = get_taxonomies(); + foreach ( $post_types_to_export as $post_type ) { + if ( in_array( $post_type, array( 'revision', 'event', 'event-recurring' ) ) ) { + continue; + } // post types to ignore. + $args = array( 'post_type' => $post_type, 'posts_per_page' => - 1 ); + $args['post_status'] = array( 'publish', 'private', 'inherit' ); + $post_datas = get_posts( $args ); + if ( ! isset( $default_content[ $post_type ] ) ) { + $default_content[ $post_type ] = array(); + } + $object = get_post_type_object( $post_type ); + if ( $object && ! empty( $object->labels->singular_name ) ) { + $type_title = $object->labels->name; + } else { + $type_title = ucwords( $post_type ) . 's'; + } + + foreach ( $post_datas as $post_data ) { + $meta = get_post_meta( $post_data->ID, '', true ); + if ( $post_data->ID == 65 ) { + // print_r($meta); exit; + } + foreach ( $meta as $meta_key => $meta_val ) { + if ( + // which keys to nuke all the time + in_array( $meta_key, array( '_location_id' ) ) + || + ( + // which keys we want to keep all the time, using strpos: + strpos( $meta_key, 'elementor' ) === false && + strpos( $meta_key, 'dtbaker' ) === false && + strpos( $meta_key, 'stylepress_' ) === false && + strpos( $meta_key, '_slider' ) === false && + // which post types we keep all meta values for: + ! in_array( $post_type, array( + 'nav_menu_item', + 'location', + 'event', + 'product', + 'wpcf7_contact_form', + ) ) && + // other meta keys we always want to keep: + ! in_array( $meta_key, array( + 'stylepress_post_title_details', + 'stylepress_page_style', + 'sliderlink', + 'slidercolor', + '_wp_attached_file', + '_thumbnail_id', + ) ) + ) + ) { + unset( $meta[ $meta_key ] ); + } else { + $meta[ $meta_key ] = maybe_unserialize( get_post_meta( $post_data->ID, $meta_key, true ) ); + } + } + // copy stock images into the images/stock/ folder for theme import. + if ( $post_type === 'attachment' ) { + $file = get_attached_file( $post_data->ID ); + if ( is_file( $file ) ) { + if ( filesize( $file ) > 1500000 ) { + $image = wp_get_image_editor( $file ); + if ( ! is_wp_error( $image ) ) { + list( $width, $height, $type, $attr ) = getimagesize( $file ); + $image->resize( min( $width, 1200 ), null, false ); + $image->save( $file ); + } + } + $post_data->guid = wp_get_attachment_url( $post_data->ID ); + if ( is_dir( $export_images_path ) ) { + copy( $file, trailingslashit( $export_images_path ) . basename( $file ) ); + } + } + // fix for incorrect GUID when renaming files with the rename plugin, causes import to bust. + + } + $terms = array(); + foreach ( $taxonomies as $taxonomy ) { + $terms[ $taxonomy ] = wp_get_post_terms( $post_data->ID, $taxonomy, array( 'fields' => 'all' ) ); + if ( $terms[ $taxonomy ] ) { + foreach ( $terms[ $taxonomy ] as $tax_id => $tax ) { + if ( ! empty( $tax->term_id ) ) { + $terms[ $taxonomy ][ $tax_id ]->meta = get_term_meta( $tax->term_id ); + if ( ! empty( $terms[ $taxonomy ][ $tax_id ]->meta ) ) { + foreach ( $terms[ $taxonomy ][ $tax_id ]->meta as $key => $val ) { + if ( is_array( $val ) && count( $val ) == 1 && isset( $val[0] ) ) { + $terms[ $taxonomy ][ $tax_id ]->meta[ $key ] = $val[0]; + } + } + } + } + } + } + } + $default_content[ $post_type ][] = array( + 'type_title' => $type_title, + 'post_id' => $post_data->ID, + 'post_title' => $post_data->post_title, + 'post_status' => $post_data->post_status, + 'post_name' => $post_data->post_name, + 'post_content' => $post_data->post_content, + 'post_excerpt' => $post_data->post_excerpt, + 'post_parent' => $post_data->post_parent, + 'menu_order' => $post_data->menu_order, + 'post_date' => $post_data->post_date, + 'post_date_gmt' => $post_data->post_date_gmt, + 'guid' => $post_data->guid, + 'post_mime_type' => $post_data->post_mime_type, + 'meta' => $meta, + 'terms' => $terms, + // 'other' => $post_data, + ); + } + } + // put certain content at very end. + $nav = isset( $default_content['nav_menu_item'] ) ? $default_content['nav_menu_item'] : array(); + if ( $nav ) { + unset( $default_content['nav_menu_item'] ); + $default_content['nav_menu_item'] = $nav; + } + // print_r($default_content); + // exit; + // find the ID of our menu names so we can import them into default menu locations and also the widget positions below. + $menus = get_terms( 'nav_menu' ); + $menu_ids = array(); + foreach ( $menus as $menu ) { + if ( $menu->name == 'Main Menu' ) { + $menu_ids['primary'] = $menu->term_id; + } else if ( $menu->name == 'Quick Links' ) { + $menu_ids['footer_quick'] = $menu->term_id; + } + } + + // choose which custom options to load into defaults + $all_options = wp_load_alloptions(); + //print_r($all_options);exit; + foreach ( $all_options as $name => $value ) { + if ( stristr( $name, 'user_roles' ) ) { + continue; + } + if ( stristr( $name, 'stylepress' ) ) { + $my_options[ $name ] = maybe_unserialize( $value ); + } + if ( stristr( $name, 'elementor' ) ) { + $my_options[ $name ] = maybe_unserialize( $value ); + } + if ( stristr( $name, '_widget_area_manager' ) ) { + $my_options[ $name ] = $value; + } + if ( stristr( $name, 'wam_' ) ) { + $my_options[ $name ] = $value; + } + //if ( stristr( $name, 'dbem_' ) !== false ) { $my_options[ $name ] = $value; } + // if ( stristr( $name, 'woo' ) !== false ) { $my_options[ $name ] = $value; } + if ( stristr( $name, 'stylepress_featured_images' ) !== false ) { + $my_options[ $name ] = $value; + } + if ( 'theme_mods_stylepress' === $name ) { + $my_options[ $name ] = maybe_unserialize( $value ); + $my_options[ $name . '-child' ] = maybe_unserialize( $value ); + unset( $my_options[ $name ]['nav_menu_locations'] ); + } + } + // $my_options['dbem_credits'] = 0; + // $my_options['woocommerce_cart_redirect_after_add'] = 'yes'; + // $my_options['woocommerce_enable_ajax_add_to_cart'] = 'no'; + //$my_options['travel_settings'] = array( 'api_key' => 'AIzaSyBsnYWO4SSibatp0SjsU9D2aZ6urI-_cJ8' ); + //$my_options['tt-font-google-api-key'] = 'AIzaSyBsnYWO4SSibatp0SjsU9D2aZ6urI-_cJ8'; + + if ( is_dir( $export_content_path ) ) { + + file_put_contents( trailingslashit( $export_content_path ) . 'default.json', json_encode( $default_content ) ); + file_put_contents( trailingslashit( $export_content_path ) . 'menu.json', json_encode( $menu_ids ) ); + file_put_contents( trailingslashit( $export_content_path ) . 'options.json', json_encode( $my_options ) ); + } + + return $return; + } + + public function export_page_callback() { + + $export_result = $this->do_the_export(); + $this->content = $this->render_template( 'admin/export.php', [ + 'export_result' => $export_result, + ] ); + $this->header = $this->render_template( 'admin/header.php' ); + echo $this->render_template( 'wrapper.php' ); + } + + +} + diff --git a/inc/class.import-export.php b/components/data/import.php similarity index 95% rename from inc/class.import-export.php rename to components/data/import.php index 11244cc..01d4de6 100644 --- a/inc/class.import-export.php +++ b/components/data/import.php @@ -1,44 +1,21 @@ array(), ); - // Export code copied from dtbaker's theme setup wizard shindig. - if ( $post_data && $post_data->post_type == 'dtbaker_style' && ! $post_data->post_parent ) { + // Export code copied from stylepress's theme setup wizard shindig. + if ( $post_data && $post_data->post_type == 'stylepress_style' && ! $post_data->post_parent ) { // cool, we have out post parent ready to export. - $post_type = 'dtbaker_style'; + $post_type = 'stylepress_style'; $media_to_export = array(); // export child style data. $args = array( @@ -89,7 +66,7 @@ public function export_data( $post_id ) { // which keys we want to keep all the time, using strpos: strpos( $meta_key, 'elementor' ) === false && strpos( $meta_key, 'stylepress' ) === false && - strpos( $meta_key, 'dtbaker' ) === false && + strpos( $meta_key, 'stylepress' ) === false && // other meta keys we always want to keep: ! in_array( $meta_key, array( '_wp_attached_file', @@ -163,7 +140,7 @@ public function export_data( $post_id ) { // which keys we want to keep all the time, using strpos: strpos( $meta_key, 'elementor' ) === false && strpos( $meta_key, 'stylepress' ) === false && - strpos( $meta_key, 'dtbaker' ) === false && + strpos( $meta_key, 'stylepress' ) === false && // other meta keys we always want to keep: ! in_array( $meta_key, array( '_wp_attached_file', @@ -458,8 +435,8 @@ private function _process_post_data( $post_type, $post_data, $delayed = 0, $debu // we have to fix up all the visual composer inserted image ids $replace_post_id_keys = array( 'parallax_image', - 'dtbwp_row_image_top', - 'dtbwp_row_image_bottom', + 'stylepress_row_image_top', + 'stylepress_row_image_bottom', 'image', 'item', // vc grid 'post_id', @@ -698,7 +675,7 @@ private function _elementor_id_import( &$item, $key ) { $item = $new_meta_val; } } - if ( $key == 'url' && ! empty( $item ) && ( strstr( $item, 'ocalhost' ) || strstr( $item, 'dev.dtbaker' ) ) ) { + if ( $key == 'url' && ! empty( $item ) && ( strstr( $item, 'ocalhost' ) || strstr( $item, 'dev.stylepress' ) ) ) { // check if this has been imported before $new_meta_val = $this->_imported_post_id( $item ); if ( $new_meta_val ) { diff --git a/components/elementor/integration.php b/components/elementor/integration.php new file mode 100644 index 0000000..4038637 --- /dev/null +++ b/components/elementor/integration.php @@ -0,0 +1,143 @@ +db->is_built_with_elementor( $post_id ); + } + + public static function edit_url_for_design( $design_id ){ + return \Elementor\Plugin::$instance->documents->get( $design_id )->get_edit_url(); + } + + public static function is_in_edit_mode(){ + return self::is_elementor_active() && (\Elementor\Plugin::$instance->editor->is_edit_mode() || \Elementor\Plugin::$instance->preview->is_preview_mode()); + } + + public function dont_allow_new( $types ) { + unset( $types['stylepress'] ); + + return $types; + } + + public function include_our_styles_in_elementor_popup( $option_value ) { + require_once __DIR__ . '/source-stylepress.php'; + \Elementor\Plugin::$instance->templates_manager->register_source( '\Elementor\TemplateLibrary\Source_StylePress' ); + + require_once __DIR__ . '/stylepress-document.php'; + \Elementor\Plugin::$instance->documents + ->register_document_type( 'stylepress', \Elementor\Modules\Library\Documents\Stylepress_Document::get_class_full_name() ); + } + + /** + * Runs once elementor has completed loading. + * This method loads our custom Elementor classes and injects them into the elementor widget_manager + * so our widgets appear in the Elementor ui. + * + * @since 2.0.0 + */ + public function elementor_init_complete() { + + if ( defined( 'ELEMENTOR_PATH' ) && class_exists( '\Elementor\Widget_Base' ) ) { + if ( class_exists( '\Elementor\Plugin' ) ) { + if ( is_callable( '\Elementor\Plugin', 'instance' ) ) { + $elementor = \Elementor\Plugin::instance(); + + // We have to enqueue styles on all pages, even non elementor pages, so global styles work. + // reference: wp-content/plugins/elementor/includes/frontend.php:209 + add_action( 'wp_enqueue_scripts', [ $elementor->frontend, 'enqueue_styles' ] ); + + if ( $elementor && isset( $elementor->elements_manager ) ) { + if ( method_exists( $elementor->elements_manager, 'add_category' ) ) { + $elementor->elements_manager->add_category( + 'stylepress', + [ + 'title' => 'StylePress', + 'icon' => 'eicon-font' + ] + ); + } + } + } + } + } + } + + + public function load_extensions() { + + if ( defined( 'ELEMENTOR_PATH' ) && class_exists( 'Elementor\Widget_Base' ) ) { + if ( class_exists( '\Elementor\Plugin' ) ) { + + if ( is_callable( '\Elementor\Plugin', 'instance' ) ) { + $elementor = \Elementor\Plugin::instance(); + if ( isset( $elementor->widgets_manager ) ) { + if ( method_exists( $elementor->widgets_manager, 'register_widget_type' ) ) { + + //require_once STYLEPRESS_PATH . 'extensions/woocommerce/woocommerce.php'; + do_action( 'stylepress_init_extensions' ); + } + } + } + } + } + + } + + /** + * Adds our new widgets to the Elementor widget area. + * + * @since 2.0.0 + */ + public function elementor_add_new_widgets() { + if ( defined( 'ELEMENTOR_PATH' ) && class_exists( 'Elementor\Widget_Base' ) ) { + if ( class_exists( '\Elementor\Plugin' ) ) { + + if ( is_callable( '\Elementor\Plugin', 'instance' ) ) { + $elementor = \Elementor\Plugin::instance(); + if ( isset( $elementor->widgets_manager ) ) { + if ( method_exists( $elementor->widgets_manager, 'register_widget_type' ) ) { + + require_once STYLEPRESS_PATH . 'extensions/inner-content/inner-content.php'; + do_action( 'stylepress_init_widgets' ); + + } + } + } + } + } + } + +} diff --git a/components/elementor/source-stylepress.php b/components/elementor/source-stylepress.php new file mode 100644 index 0000000..5946335 --- /dev/null +++ b/components/elementor/source-stylepress.php @@ -0,0 +1,720 @@ +get_all_styles( 'demo_content' ) as $post_id => $post_title ) { + $templates[] = $this->get_item( $post_id ); + } + + return $templates; + } + + public function save_item( $template_data ) { + return true; + } + + public function update_item( $new_data ) { + return true; + } + + /** + * Get local template. + * + * Retrieve a single local template saved by the user on his site. + * + * @param int $template_id The template ID. + * + * @return array Local template. + * @since 1.0.0 + * @access public + * + */ + public function get_item( $template_id ) { + $post = get_post( $template_id ); + $parent_style = get_post( $post->post_parent ); + + $user = get_user_by( 'id', $post->post_author ); + + $page = SettingsManager::get_settings_managers( 'page' )->get_model( $template_id ); + + $page_settings = $page->get_data( 'settings' ); + + $date = strtotime( $post->post_date ); + + $type = self::get_template_type( $post->ID ); + + $data = [ + 'template_id' => $post->ID, + 'source' => 'local', //$this->get_id(), + 'type' => $type, + 'title' => $parent_style->post_title .' » ' . $post->post_title, + 'thumbnail' => get_the_post_thumbnail_url( $post ), + 'date' => $date, + 'human_date' => date_i18n( get_option( 'date_format' ), $date ), + 'author' => $user->display_name, + 'hasPageSettings' => ! empty( $page_settings ), + 'tags' => [], + 'export_link' => $this->get_export_link( $template_id ), + 'url' => get_permalink( $post->ID ), + ]; + + /** + * Get template library template. + * + * Filters the template data when retrieving a single template from the + * template library. + * + * @param array $data Template data. + * + * @since 1.0.0 + * + */ + $data = apply_filters( 'elementor/template-library/get_template', $data ); + + return $data; + } + + /** + * Get template data. + * + * Retrieve the data of a single local template saved by the user on his site. + * + * @param array $args Custom template arguments. + * + * @return array Local template data. + * @since 1.5.0 + * @access public + * + */ + public function get_data( array $args ) { + $db = Plugin::$instance->db; + + $template_id = $args['template_id']; + + // TODO: Validate the data (in JS too!). + if ( ! empty( $args['display'] ) ) { + $content = $db->get_builder( $template_id ); + } else { + $document = Plugin::$instance->documents->get( $template_id ); + $content = $document ? $document->get_elements_data() : []; + } + + if ( ! empty( $content ) ) { + $content = $this->replace_elements_ids( $content ); + } + + $data = [ + 'content' => $content, + ]; + + if ( ! empty( $args['with_page_settings'] ) ) { + $page = SettingsManager::get_settings_managers( 'page' )->get_model( $args['template_id'] ); + + $data['page_settings'] = $page->get_data( 'settings' ); + } + + return $data; + } + + /** + * Delete local template. + * + * Delete template from the database. + * + * @param int $template_id The template ID. + * + * @return \WP_Post|\WP_Error|false|null Post data on success, false or null + * or 'WP_Error' on failure. + * @since 1.0.0 + * @access public + * + */ + public function delete_template( $template_id ) { + if ( ! current_user_can( $this->post_type_object->cap->delete_post, $template_id ) ) { + return new \WP_Error( 'template_error', __( 'Access denied.', 'elementor' ) ); + } + + return wp_delete_post( $template_id, true ); + } + + /** + * Export local template. + * + * Export template to a file. + * + * @param int $template_id The template ID. + * + * @return \WP_Error WordPress error if template export failed. + * @since 1.0.0 + * @access public + * + */ + public function export_template( $template_id ) { + wp_die( 'Sorry not implemented' ); + } + + + /** + * Block template frontend + * + * Don't display the single view of the template library post type in the + * frontend, for users that don't have the proper permissions. + * + * Fired by `template_redirect` action. + * + * @since 1.0.0 + * @access public + */ + public function block_template_frontend() { + if ( is_singular( self::CPT ) && ! current_user_can( Editor::EDITING_CAPABILITY ) ) { + wp_safe_redirect( site_url(), 301 ); + die; + } + } + + /** + * Is template library supports export. + * + * whether the template library supports export. + * + * Template saved by the user locally on his site, support export by default + * but this can be changed using a filter. + * + * @param int $template_id The template ID. + * + * @return bool Whether the template library supports export. + * @since 1.0.0 + * @access public + * + */ + public function is_template_supports_export( $template_id ) { + $export_support = true; + + /** + * Is template library supports export. + * + * Filters whether the template library supports export. + * + * @param bool $export_support Whether the template library supports export. + * Default is true. + * @param int $template_id Post ID. + * + * @since 1.0.0 + * + */ + $export_support = apply_filters( 'elementor/template_library/is_template_supports_export', $export_support, $template_id ); + + return $export_support; + } + + + /** + * Get template export link. + * + * Retrieve the link used to export a single template based on the template + * ID. + * + * @param int $template_id The template ID. + * + * @return string Template export URL. + * @since 2.0.0 + * @access private + * + */ + private function get_export_link( $template_id ) { + // TODO: BC since 2.3.0 - Use `$ajax->create_nonce()` + /** @var \Elementor\Core\Common\Modules\Ajax\Module $ajax */ + // $ajax = Plugin::$instance->common->get_component( 'ajax' ); + + return add_query_arg( + [ + 'action' => 'elementor_library_direct_actions', + 'library_action' => 'export_template', + 'source' => $this->get_id(), + '_nonce' => wp_create_nonce( 'elementor_ajax' ), + 'template_id' => $template_id, + ], + admin_url( 'admin-ajax.php' ) + ); + } + + /** + * On template save. + * + * Run this method when template is being saved. + * + * Fired by `save_post` action. + * + * @param int $post_id Post ID. + * @param \WP_Post $post The current post object. + * + * @since 1.0.1 + * @access public + * + */ + public function on_save_post( $post_id, \WP_Post $post ) { + if ( self::CPT !== $post->post_type ) { + return; + } + + if ( self::get_template_type( $post_id ) === 'stylepress' ) { // It's already with a type + return; + } + + // Don't save type on import, the importer will do it. + if ( did_action( 'import_start' ) ) { + return; + } + + $this->save_item_type( $post_id, 'stylepress' ); + } + + /** + * Save item type. + * + * When saving/updating templates, this method is used to update the post + * meta data and the taxonomy. + * + * @param int $post_id Post ID. + * @param string $type Item type. + * + * @since 1.0.1 + * @access private + * + */ + private function save_item_type( $post_id, $type ) { + update_post_meta( $post_id, Document::TYPE_META_KEY, $type ); + wp_cache_flush(); + } + + + /** + * Maybe render blank state. + * + * When the template library has no saved templates, display a blank admin page offering + * to create the very first template. + * + * Fired by `manage_posts_extra_tablenav` action. + * + * @param string $which The location of the extra table nav markup: 'top' or 'bottom'. + * + * @since 2.0.0 + * @access public + * + */ + public function maybe_render_blank_state( $which ) { + global $post_type; + + if ( self::CPT !== $post_type || 'bottom' !== $which ) { + return; + } + + global $wp_list_table; + + $total_items = $wp_list_table->get_pagination_arg( 'total_items' ); + + if ( ! empty( $total_items ) || ! empty( $_REQUEST['s'] ) ) { + return; + } + + $inline_style = '#posts-filter .wp-list-table, #posts-filter .tablenav.top, .tablenav.bottom .actions, .wrap .subsubsub { display:none;}'; + + $current_type = get_query_var( 'elementor_library_type' ); + + $document_types = Plugin::instance()->documents->get_document_types(); + + if ( empty( $document_types[ $current_type ] ) ) { + return; + } + + // TODO: Better way to exclude widget type. + if ( 'widget' === $current_type ) { + return; + } + + if ( empty( $current_type ) ) { + $counts = (array) wp_count_posts( self::CPT ); + unset( $counts['auto-draft'] ); + $count = array_sum( $counts ); + + if ( 0 < $count ) { + return; + } + + $current_type = 'template'; + + $inline_style .= '#elementor-template-library-tabs-wrapper {display: none;}'; + } + + $current_type_label = $this->get_template_label_by_type( $current_type ); + ?> + +
+
+ +

+ +

+ + + +
+
+ documents->get_document_types(); + + if ( isset( $document_types[ $template_type ] ) ) { + $template_label = call_user_func( [ $document_types[ $template_type ], 'get_title' ] ); + } else { + $template_label = ucwords( str_replace( [ '_', '-' ], ' ', $template_type ) ); + } + + /** + * Template label by template type. + * + * Filters the template label by template type in the template library . + * + * @param string $template_label Template label. + * @param string $template_type Template type. + * + * @since 2.0.0 + * + */ + $template_label = apply_filters( 'elementor/template-library/get_template_label_by_type', $template_label, $template_type ); + + return $template_label; + } + + /** + * Filter template types in admin query. + * + * Update the template types in the main admin query. + * + * Fired by `parse_query` action. + * + * @param \WP_Query $query The `WP_Query` instance. + * + * @since 2.4.0 + * @access public + * + */ + public function admin_query_filter_types( \WP_Query $query ) { + if ( empty( $query->query_vars['elementor_library_type'] ) || $query->query_vars['elementor_library_type'] !== 'stylepress' ) { + return; + } + + $query->query_vars['post_type'] = \StylePress\Styles::CPT; + $query->query_vars['meta_key'] = ''; + $query->query_vars['meta_value'] = ''; + + } + + /** + * Add template library actions. + * + * Register filters and actions for the template library. + * + * @since 2.0.0 + * @access private + */ + private function add_actions() { + if ( is_admin() ) { + add_action( 'save_post', [ $this, 'on_save_post' ], 3, 2 ); + + add_action( 'parse_query', [ $this, 'admin_query_filter_types' ] ); + + // Template type column. + add_action( 'manage_' . self::CPT . '_posts_columns', [ $this, 'admin_columns_headers' ] ); + add_action( 'manage_' . self::CPT . '_posts_custom_column', [ $this, 'admin_columns_content' ], 10, 2 ); + + if ( $this->is_current_screen() ) { + add_filter( 'the_title', [ $this, 'add_stylepress_parent_suffix' ], 11, 2 ); + add_action( 'manage_elementor_library_posts_columns', [ $this, 'admin_columns_headers' ] ); + add_action( 'manage_elementor_library_posts_custom_column', [ $this, 'admin_columns_content' ], 10, 2 ); + } + + // Show blank state. + add_action( 'manage_posts_extra_tablenav', [ $this, 'maybe_render_blank_state' ] ); + } + + add_action( 'template_redirect', [ $this, 'block_template_frontend' ] ); + } + + public function add_stylepress_parent_suffix($title, $post_id){ + $post = get_post($post_id); + $parent = get_post($post->post_parent); + if($parent ){ + return $parent->post_title .' » ' . $title; + } + return $title; + } + + /** + * @since 2.0.6 + * @access public + */ + public function admin_columns_content( $column_name, $post_id ) { + if ( 'elementor_library_type' === $column_name ) { + /** @var Document $document */ + $document = Plugin::$instance->documents->get( $post_id ); + + if ( $document && $document instanceof Library_Document ) { + $document->print_admin_column_type(); + } + } + if ( 'stylepress_type' === $column_name ) { + $stylepress_type = get_the_terms( $post_id, STYLEPRESS_SLUG . '-cat' ); + if ( $stylepress_type ) { + if ( $stylepress_type[0]->slug === 'styles' ) { + echo 'Main Style'; + } else { + $categories = \StylePress\Styles::get_instance()->get_categories(); + $found_match = false; + foreach ( $categories as $category ) { + if ( $category['slug'] === $stylepress_type[0]->slug ) { + echo esc_html( $category['title'] ); + $found_match = true; + break; + } + } + if ( ! $found_match ) { + echo 'Unknown'; + } + } + } + } + } + + /** + * @since 2.0.6 + * @access public + */ + public function admin_columns_headers( $posts_columns ) { + // Replace original column that bind to the taxonomy - with another column. + unset( $posts_columns['taxonomy-elementor_library_type'] ); + + $offset = 2; + + $posts_columns = array_slice( $posts_columns, 0, $offset, true ) + [ + 'stylepress_type' => __( 'StylePress Category', 'elementor' ), + 'elementor_library_type' => __( 'Elementor Type', 'elementor' ), + ] + array_slice( $posts_columns, $offset, null, true ); + + return $posts_columns; + } + + private function is_current_screen() { + return isset( $_GET['elementor_library_type'] ) && $_GET['elementor_library_type'] === 'stylepress'; + } + + /** + * Template library local source constructor. + * + * Initializing the template library local source base by registering custom + * template data and running custom actions. + * + * @since 1.0.0 + * @access public + */ + public function __construct() { + parent::__construct(); + + $this->add_actions(); + } +} diff --git a/components/elementor/stylepress-document.php b/components/elementor/stylepress-document.php new file mode 100644 index 0000000..e0468bc --- /dev/null +++ b/components/elementor/stylepress-document.php @@ -0,0 +1,58 @@ +populate_globals(); + + if ( ! empty( $GLOBALS['stylepress_render']['template'] ) ) { + return $GLOBALS['stylepress_render']['template']; + } + + Debug::get_instance()->debug_message( 'Sorry no styles found for this page type' ); + + return $template_include; + } + + + /** + * Works out the type of page we're currently quer\ying. + * Copied from my Widget Area Manager plugin + * + * @return string + * @since 2.0.0 + * + */ + public function get_current_page_type() { + global $wp_query; + // print_r($wp_query->query_vars); + if ( is_search() ) { + return 'search'; + } else if ( is_404() ) { + return '404'; + } else if ( function_exists( 'is_product' ) && is_product() ) { + return 'product'; + } else if ( function_exists( 'is_product_category' ) && is_product_category() ) { + return 'product_category'; + } else if ( is_category() ) { + return 'category'; + } else if ( isset( $wp_query->query_vars ) && ! empty( $wp_query->query_vars['post_type'] ) && ! is_array( $wp_query->query_vars['post_type'] ) ) { + // Elementor sets an array as post_type since the introduction of landing pages. + $post_type = $wp_query->query_vars['post_type']; + + return $post_type . ( is_singular() ? '' : 's' ); + } else if ( ! empty( $wp_query->query_vars['taxonomy'] ) ) { + $current_page_id = $wp_query->query_vars['taxonomy']; + $value = get_query_var( $wp_query->query_vars['taxonomy'] ); + if ( $value ) { + $current_page_id .= '_' . $value; + } + + return $current_page_id; + } else if ( isset( $wp_query->is_posts_page ) && $wp_query->is_posts_page ) { + return 'archive'; + } else if ( is_archive() ) { + return 'archive'; + } else if ( is_home() || is_front_page() ) { + return 'front_page'; + } else if ( is_attachment() ) { + return 'attachment'; + } else if ( is_page() ) { + return 'page'; + } else if ( is_single() ) { + return 'post'; + } + + // todo - look for custom taxonomys + return 'post'; + } + + + public function populate_globals() { + if ( isset( $GLOBALS['stylepress_render'] ) ) { + return; + } + global $post; + $GLOBALS['stylepress_render'] = []; + + // TODO: remove integration with Elementor here + if ( $post && ! empty( $post->ID ) && 'elementor_library' === $post->post_type ) { + $page_templates_module = \Elementor\Plugin::$instance->modules_manager->get_modules( 'page-templates' ); + $path = $page_templates_module->get_template_path( 'elementor_canvas' ); + if ( is_file( $path ) ) { + $GLOBALS['stylepress_render']['template'] = $path; + } + } else if ( $post && ! empty( $post->ID ) && Cpt::CPT === $post->post_type ) { + // User is editing one of our stylepress templates, use a special template so we can show some stuff + // Really only useful in Elementor or when previewing the template on the frontend. + $GLOBALS['stylepress_render']['template'] = __DIR__ . '/views/editor.php'; + } + + $default_styles = Data::get_instance()->get_default_styles(); + $page_type = $this->get_current_page_type(); + $these_styles = isset( $default_styles[ $page_type ] ) ? $default_styles[ $page_type ] : false; + + $queried_object = get_queried_object(); + if ( $these_styles ) { + // If stylepress has been disabled for this particular post then we just use the normal template include. + // Not sure how to do this for category pages. We'll have to add a taxonomy settings area to each tax. + // It can be disabled because a custom template is chosen, or via the disabled flag in advanced layouts. + if ( ! empty( $these_styles['_disabled'] ) ) { + Debug::get_instance()->debug_message( 'Skipping stylepress because post type is flagged as disabled in layout settings.' ); + $GLOBALS['stylepress_render']['template'] = false; + } else if ( $queried_object && $queried_object instanceof \WP_Post && $queried_object->ID ) { + $enabled = Data::get_instance()->is_stylpress_enabled( $post ); + if ( ! $enabled['enabled'] ) { + Debug::get_instance()->debug_message( 'Skipping stylepress template because ' . $enabled['reason'] ); + $GLOBALS['stylepress_render']['template'] = false; + } + // todo: confirm our queried object isn't the first blog post in a list of things view.. that would mess it up. + // We're doing a single object post, should be easy. + $page_styles = Data::get_instance()->get_page_styles( $queried_object->ID ); + if ( $page_styles ) { + foreach ( $page_styles as $category_slug => $chosen_style_id ) { + if ( $chosen_style_id != 0 ) { + $these_styles[ $category_slug ] = $chosen_style_id; + } + } + } + } + } + if ( ! isset( $GLOBALS['stylepress_render']['template'] ) ) { + $GLOBALS['stylepress_render']['template'] = __DIR__ . '/views/render.php'; + } + $GLOBALS['stylepress_render']['queried_object'] = $queried_object; + $GLOBALS['stylepress_render']['page_type'] = $page_type; + $GLOBALS['stylepress_render']['styles'] = $these_styles; + } + + + /** + * Register some frontend css files + * + * @since 2.0.0 + */ + public function frontend_css() { + wp_enqueue_style( 'stylepress-css', STYLEPRESS_URI . 'build/assets/frontend.css', false, STYLEPRESS_VERSION ); + + wp_register_script( 'stylepress-js', STYLEPRESS_URI . 'build/assets/frontend.js', false, STYLEPRESS_VERSION, true ); + wp_localize_script( 'stylepress-js', 'stylepress_frontend', array( + 'ajaxurl' => admin_url( 'admin-ajax.php' ), + 'public_nonce' => wp_create_nonce( 'stylepress-public-nonce' ), + ) + ); + wp_enqueue_script( 'stylepress-js' ); + + if ( \StylePress\Elementor\Integration::is_in_edit_mode() ) { + // This loads extra scripts into the editor iframe only in edit mode. Used for the styling of the helper text at the top of the edit iframe. + wp_enqueue_style( 'stylepress-editor-in', STYLEPRESS_URI . 'build/assets/frontend-edit.css', false, STYLEPRESS_VERSION ); + wp_enqueue_script( 'stylepress-editor-in', STYLEPRESS_URI . 'build/assets/frontend-edit.js', false, STYLEPRESS_VERSION, true ); + } + } + + public function render_content( $post_id ) { + if ( post_password_required( $post_id ) ) { + return; + } + + // TODO: remove reliance on Elementor like this + if ( \StylePress\Elementor\Integration::is_post_built_with_elementor( $post_id ) ) { + $with_css = false; + echo \Elementor\Plugin::$instance->frontend->get_builder_content( $post_id, $with_css ); + } else { + echo apply_filters( 'the_content', get_the_content( null, null, $post_id ) ); + } + } +} + diff --git a/components/frontend/views/editor.php b/components/frontend/views/editor.php new file mode 100644 index 0000000..3e4a676 --- /dev/null +++ b/components/frontend/views/editor.php @@ -0,0 +1,105 @@ +get_categories(); +$post = get_post(); +$is_inner_template = false; +$current_page_category = false; +$post_categories = get_the_terms( $post->ID, STYLEPRESS_SLUG . '-cat' ); + +if($post_categories) { + foreach ( $categories as $category ) { + foreach ( $post_categories as $post_category ) { + if ( $post_category->slug === $category['slug'] ) { + $current_page_category = $category; + if ( ! empty( $category['inner'] ) ) { + $is_inner_template = true; + } + } + } + } +} + +?> + class="no-js"> + + + + + ID, '_elementor_template_type', true ); +// if ( $elementor_template_type === 'kit' ) { +// add_action( 'pre_option_elementor_active_kit', function ( $kit_id ) use ( $post ) { +// if ( $post && $post->ID ) { +// $kit_id = $post->ID; +// } +// +// return $kit_id; +// } ); +// } else { +// // we're editing another type of non kit page +// add_action( 'pre_option_elementor_active_kit', function ( $kit_id ) use ( $current_page_category ) { +// $default_styles = Styles::get_instance()->get_default_styles(); +// if ( $default_styles && ! empty( $default_styles['_global'] ) && ! empty( $default_styles['_global']['theme_styles'] ) ) { +// $kit_id = $default_styles['_global']['theme_styles']; +// } +// +// return $kit_id; +// } ); +// } + wp_head(); ?> + +> + + + +
+ +
+

Style: post_parent ) { + $parent = get_post( $post->post_parent ); + echo esc_html( $parent->post_title ) . ' > '; + } + echo esc_html( $post->post_title ); ?>

+ +
+ Important: Please add at least one Inner Content widget to the page. +
+ +
+
+ + + + + diff --git a/components/frontend/views/render.php b/components/frontend/views/render.php new file mode 100644 index 0000000..b6ce5af --- /dev/null +++ b/components/frontend/views/render.php @@ -0,0 +1,110 @@ +get_categories(); + +$elementor_kit_template = false; + +?> + +> + + + + + 0 ) { +// $elementor_kit_template = get_post( $GLOBALS['stylepress_render']['styles'][ $category['slug'] ] ); +// // We override the Elementor default active kit here based on the current page selection: +// add_action( 'pre_option_elementor_active_kit', function ( $kit_id ) use ( $elementor_kit_template ) { +// if ( $elementor_kit_template && $elementor_kit_template->ID ) { +// $elementor_template_type = get_post_meta( $elementor_kit_template->ID, '_elementor_template_type', true ); +// if ( $elementor_template_type === 'kit' ) { +// $kit_id = $elementor_kit_template->ID; +// } +// } +// +// return $kit_id; +// } ); +// } +// } +// } +// } +// } + wp_head(); + ?> + +> +debug_message( 'Using Elementor Kit: ' . esc_html( $elementor_kit_template->post_title ) . ' (#' . $elementor_kit_template->ID . ')' ); +//} +Debug::get_instance()->debug_message( 'Page Type Detected as: ' . $GLOBALS['stylepress_render']['page_type'] ); +Debug::get_instance()->debug_message( 'Queried object detected as: ' . ( $GLOBALS['stylepress_render']['queried_object'] && isset( $GLOBALS['stylepress_render']['queried_object']->ID ) ? $GLOBALS['stylepress_render']['queried_object']->ID : 'Unknown' ) ); + +do_action( 'stylepress/before-render' ); +if ( ! empty( $GLOBALS['stylepress_render'] ) ) { + foreach ( $categories as $category ) { + if ( ! $category['render_section'] ) { + continue; + } + if ( STYLEPRESS_DEBUG_OUTPUT ) { + if ( isset( $GLOBALS['stylepress_render']['styles'][ $category['slug'] ] ) ) { + if ( $GLOBALS['stylepress_render']['styles'][ $category['slug'] ] > 0 ) { + $template = get_post( $GLOBALS['stylepress_render']['styles'][ $category['slug'] ] ); + Debug::get_instance()->debug_message( 'Rendering template ' . esc_html( $template->post_title ) . ' (#' . $GLOBALS['stylepress_render']['styles'][ $category['slug'] ] . ') for section ' . $category['slug'] ); + } else { + Debug::get_instance()->debug_message( 'Blank template chosen for section ' . $category['slug'] ); + } + } else { + Debug::get_instance()->debug_message( 'No template chosen for section ' . $category['slug'] ); + } + } + if ( isset( $GLOBALS['stylepress_render']['styles'][ $category['slug'] ] ) ) { + if ( $GLOBALS['stylepress_render']['styles'][ $category['slug'] ] > 0 ) { + Render::get_instance()->render_content($GLOBALS['stylepress_render']['styles'][ $category['slug'] ]); + }else{ + // chose to render blank here. flag this inner section as blank if needed + if( ! empty( $category['inner'] ) ) { + $GLOBALS['stylepress_render']['has_done_inner_content'] = true; + } + } + } + if ( ! empty( $category['inner'] ) && empty( $GLOBALS['stylepress_render']['has_done_inner_content'] ) ) { + // todo: we may with to turn off this defualt behaviour for pages that don't want the default content displaying + // e.g. we got the first blog post content showing on archive page that had a stylepress-loop widget. + // this might be an issue for shops too + Debug::get_instance()->debug_message( 'Rendering default inner_content() from render.php' ); + if ( have_posts() ) { + the_post(); + the_content(); + } + } + } +} + +do_action( 'stylepress/after-render' ); +do_action( 'get_footer', 'stylepress' ); +wp_footer(); +?> + + + diff --git a/components/layout/layout.js b/components/layout/layout.js new file mode 100644 index 0000000..76e273a --- /dev/null +++ b/components/layout/layout.js @@ -0,0 +1 @@ +import './layout.scss'; diff --git a/components/layout/layout.php b/components/layout/layout.php new file mode 100644 index 0000000..f334fe0 --- /dev/null +++ b/components/layout/layout.php @@ -0,0 +1,112 @@ +get_all_page_types(); + $categories = \StylePress\Styles\Data::get_instance()->get_categories(); + $defaults_to_save = []; + + $user_provided_defaults = []; + $is_advanced_settings = ! empty( $_POST['stylepress_advanced'] ); + \StylePress\Core\Settings::get_instance()->set( 'stylepress_advanced', $is_advanced_settings ); + if ( $is_advanced_settings ) { + if ( isset( $_POST['default_style'] ) && is_array( $_POST['default_style'] ) ) { + $user_provided_defaults = $_POST['default_style']; + } + } else { + // simple styles. + if ( isset( $_POST['default_style_simple'] ) && is_array( $_POST['default_style_simple'] ) ) { + $user_provided_defaults = $_POST['default_style_simple']; + } + } + foreach ( $page_types as $page_type => $page_type_name ) { + $defaults_to_save[ $page_type ] = []; + if ( isset( $user_provided_defaults[ $page_type ] ) && is_array( $user_provided_defaults[ $page_type ] ) ) { + // check if user has disabled this type all together + if ( isset( $user_provided_defaults[ $page_type ][ '_disabled' ] ) ) { + $defaults_to_save[ $page_type ][ '_disabled' ] = 'disabled'; + } + // store defaults for each page type here. + foreach ( $categories as $category ) { + if ( isset( $user_provided_defaults[ $page_type ][ $category['slug'] ] ) ) { + $chosen_default = $user_provided_defaults[ $page_type ][ $category['slug'] ]; + $valid_answers = \StylePress\Styles\Data::get_instance()->get_all_styles( $category['slug'], true ); + if ( isset( $valid_answers[ $chosen_default ] ) ) { + $defaults_to_save[ $page_type ][ $category['slug'] ] = $chosen_default; + } + } + } + } + } + + foreach ( $defaults_to_save as $default_page_type => $default_styles ) { + if ( $default_page_type !== '_global' ) { + $defaults_to_save[ $default_page_type ] = array_merge( $defaults_to_save['_global'], $default_styles ); + } + } + + \StylePress\Core\Settings::get_instance()->set( 'stylepress_styles', $defaults_to_save ); + + wp_safe_redirect( admin_url( 'admin.php?page=' . self::PAGE_SLUG . '&saved' ) ); + exit; + } +} + diff --git a/components/layout/layout.scss b/components/layout/layout.scss new file mode 100644 index 0000000..64eb764 --- /dev/null +++ b/components/layout/layout.scss @@ -0,0 +1,118 @@ + +div.stylepress__layout--basic { + display: block; +} + +div.stylepress__layout--advanced { + display: none; +} + +#stylepress_advanced:checked ~ div.stylepress__layout--basic { + display: none; +} + +#stylepress_advanced:checked ~ div.stylepress__layout--advanced { + display: block; +} + +.stylepress__layout-page{ + width: 500px; + border: 3px solid #ccc; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + background: #FFF; +} +.stylepress__layout-pagesection{ + border-bottom: 1px solid #CCC; + padding: 20px 15px; + position:relative; + text-align: center; + &:last-child{ + border-bottom: 0; + } + label{ + position: absolute; + background: #f1f1f1; + border-radius: 5px; + top: 5px; + left: 5px; + padding: 4px 9px; + font-size: 12px; + } +} + +.stylepress-chrome{ + padding: 0; + text-align: center; + * { + box-sizing: border-box; + } + + /* Container for columns and the top "toolbar" */ + &-row { + padding: 10px; + background: #f1f1f1; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + display: flex; + justify-content: space-between; + } + + /* Create three unequal columns that floats next to each other */ + &-column { + } + + &-left { + width: 55px; + margin-right: auto; + margin-left: 0; + } + + &-right { + margin-right: 0; + margin-left: auto; + width: 20px; + } + + &-middle { + width: 200px; + } + + /* Clear floats after the columns */ + &-row:after { + content: ""; + display: table; + clear: both; + } + + /* Three dots */ + &-dot { + margin-top: 4px; + height: 12px; + width: 12px; + background-color: #bbb; + border-radius: 50%; + display: inline-block; + } + + /* Style the input field */ + &-addr { + width: 100%; + border-radius: 3px; + border: none; + background-color: white; + margin-top: -8px; + height: 25px; + color: #666; + padding: 5px; + } + + /* Three bars (hamburger menu) */ + &-bar { + width: 17px; + height: 3px; + background-color: #aaa; + margin: 3px 0; + display: block; + } +} diff --git a/components/layout/views/layout.php b/components/layout/views/layout.php new file mode 100644 index 0000000..7675262 --- /dev/null +++ b/components/layout/views/layout.php @@ -0,0 +1,161 @@ +get_default_styles(); +$categories = \StylePress\Styles\Data::get_instance()->get_categories(); +$page_types = \StylePress\Core\Settings::get_instance()->get_all_page_types(); + +?> + + +

Settings updated.

+ +
+ + +

This is the default style settings page. Here you can choose the default styles that will apply in each section of + your website.

+ + +
+ + + + + get( 'stylepress_advanced' ) ); ?>> + +
+ +
+
+
+
+ + + +
+
+ +
+
+
+ + + +
+
+
+
+ +
+ + + +
+ +
+ + + +
+
+ + + + + + + + + + + + + $page_type_name ) { ?> + + + + + + + + + + +
Page TypeDisableDefault
+ + + + > + + +
+ + + +
+
diff --git a/components/logging/debug.php b/components/logging/debug.php new file mode 100644 index 0000000..4b3281c --- /dev/null +++ b/components/logging/debug.php @@ -0,0 +1,29 @@ +'; + echo 'StylePress:   '; + echo $message; + echo ""; + } + } +} + diff --git a/components/php/classes/backend.php b/components/php/classes/backend.php new file mode 100644 index 0000000..762b998 --- /dev/null +++ b/components/php/classes/backend.php @@ -0,0 +1,384 @@ + admin_url( 'admin-ajax.php' ), + 'admin_nonce' => wp_create_nonce( 'stylepress-admin-nonce' ), + ) + ); + wp_enqueue_script( 'stylepress-admin' ); + + require_once STYLEPRESS_PATH . 'views/_help_text.php'; + + } + + private function _timestamp_script( $name, $src, $requirements = [] ) { + wp_enqueue_script( $name, STYLEPRESS_URI . $src, $requirements, STYLEPRESS_VERSION ); + } + + private function _timestamp_style( $name, $src, $requirements = [] ) { + wp_enqueue_style( $name, STYLEPRESS_URI . $src, $requirements, STYLEPRESS_VERSION ); + } + + public function get_config() { + return [ + 'ajaxurl' => admin_url( 'admin-ajax.php' ), + 'admin_nonce' => wp_create_nonce( 'stylepress-react' ), + ]; + } + + /** + * This is our callback for rendering our custom menu page. + * This page shows all our site styles and currently selected defaults. + * + * @since 2.0.0 + */ + public function default_styles_page_callback() { + + if ( isset( $_GET['style_id'] ) ) { + $this->content = $this->render_template( + 'admin/sections.php', [ + ] + ); + } else if ( isset( $_GET['remote_style_slug'] ) ) { + if ( isset( $_GET['import_step'] ) ) { + $this->content = $this->render_template( + 'admin/remote-style-import.php', [ + ] + ); + } else { + $this->content = $this->render_template( + 'admin/remote-style.php', [ + ] + ); + } + } else { + $this->content = $this->render_template( + 'admin/styles.php', [ + ] + ); + } + $this->header = $this->render_template( 'admin/header.php' ); + echo $this->render_template( 'wrapper.php' ); + } + + /** + * This is our callback for rendering our custom menu page. + * This page shows all our site styles and currently selected defaults. + * + * @since 2.0.0 + */ + public function settings_page_callback() { + $this->content = $this->render_template( + 'admin/settings.php', [ + ] + ); + $this->header = $this->render_template( 'admin/header.php' ); + echo $this->render_template( 'wrapper.php' ); + } + + + public function stylepress_new_style() { + // Check if our nonce is set. + if ( ! isset( $_POST['stylepress_new_style'] ) ) { // WPCS: input var okay. + return; + } + + // Verify that the nonce is valid. + if ( ! wp_verify_nonce( $_POST['stylepress_new_style'], 'stylepress_new_style' ) ) { // WPCS: sanitization ok. input var okay. + return; + } + + $new_style_name = stripslashes( sanitize_text_field( trim( $_POST['new_style_name'] ) ) ); + $new_category = sanitize_text_field( trim( $_POST['new_style_category'] ) ); + $new_style_parent = (int) $_POST['new_style_parent']; + + if ( ! $new_style_name ) { + wp_die( 'Please go back and enter a new style name' ); + } + + if ( ! $new_category ) { + wp_die( 'No category found' ); + } + + $post_id = wp_insert_post( [ + 'post_type' => Cpt::CPT, + 'post_status' => 'publish', + 'post_title' => $new_style_name, + 'post_parent' => $new_style_parent, + ], true ); + + if ( is_wp_error( $post_id ) || ! $post_id ) { + wp_die( 'Failed to create new style' ); + } + + wp_set_object_terms( $post_id, $new_category, STYLEPRESS_SLUG . '-cat', false ); + + if ( $new_category === 'theme_styles' ) { + // hack to allow Elementor Theme Style editor: + update_post_meta( $post_id, '_elementor_template_type', 'kit' ); + } + + wp_safe_redirect( admin_url( 'admin.php?page=' . self::STYLES_PAGE_SLUG . ( $new_style_parent ? '&style_id=' . $new_style_parent : '' ) . '&saved#cat-' . $new_category ) ); + exit; + + } + + public function stylepress_save() { + + // Check if our nonce is set. + if ( ! isset( $_POST['stylepress_save_options'] ) ) { // WPCS: input var okay. + return; + } + + // Verify that the nonce is valid. + if ( ! wp_verify_nonce( $_POST['stylepress_save_options'], 'stylepress_save_options' ) ) { // WPCS: sanitization ok. input var okay. + return; + } + + $page_types = Settings::get_instance()->get_all_page_types(); + $categories = Styles::get_instance()->get_categories(); + $defaults_to_save = []; + + $user_provided_defaults = []; + $is_advanced_settings = ! empty( $_POST['stylepress_advanced'] ); + Settings::get_instance()->set( 'stylepress_advanced', $is_advanced_settings ); + if ( $is_advanced_settings ) { + if ( isset( $_POST['default_style'] ) && is_array( $_POST['default_style'] ) ) { + $user_provided_defaults = $_POST['default_style']; + } + } else { + // simple styles. + if ( isset( $_POST['default_style_simple'] ) && is_array( $_POST['default_style_simple'] ) ) { + $user_provided_defaults = $_POST['default_style_simple']; + } + } + foreach ( $page_types as $page_type => $page_type_name ) { + $defaults_to_save[ $page_type ] = []; + if ( isset( $user_provided_defaults[ $page_type ] ) && is_array( $user_provided_defaults[ $page_type ] ) ) { + // store defaults for each page type here. + foreach ( $categories as $category ) { + if ( isset( $user_provided_defaults[ $page_type ][ $category['slug'] ] ) ) { + $chosen_default = $user_provided_defaults[ $page_type ][ $category['slug'] ]; + $valid_answers = Styles::get_instance()->get_all_styles( $category['slug'], true ); + if ( isset( $valid_answers[ $chosen_default ] ) ) { + $defaults_to_save[ $page_type ][ $category['slug'] ] = $chosen_default; + } + } + } + } + } + + foreach ( $defaults_to_save as $default_page_type => $default_styles ) { + if ( $default_page_type !== '_global' ) { + $defaults_to_save[ $default_page_type ] = array_merge( $defaults_to_save['_global'], $default_styles ); + } + } + + Settings::get_instance()->set( 'stylepress_styles', $defaults_to_save ); + + wp_safe_redirect( admin_url( 'admin.php?page=' . self::SETTINGS_PAGE_SLUG . '&saved' ) ); + exit; + + + } + + + /** + * Adds a meta box to every post type. + * + * @since 2.0.0 + */ + public function add_meta_box() { + + if ( Plugin::get_instance()->has_permission() ) { + $post_types = get_post_types(); + foreach ( $post_types as $post_type ) { + if ( ! in_array( $post_type, array( Styles::CPT, 'elementor_library' ), true ) ) { + add_meta_box( + 'stylepress_style_metabox', + __( 'StylePress', 'stylepress' ), + array( $this, 'meta_box_display' ), + $post_type, + 'side', + 'high' + ); + } + } + + } + + } + + /** + * This renders our metabox on most page/post types. + * + * @param \WP_Post $post Current post object. + * + * @since 2.0.0 + * + */ + public function meta_box_display( $post ) { + + if ( Plugin::get_instance()->has_permission( $post ) ) { + + include_once STYLEPRESS_PATH . 'metaboxes/post-meta-box.php'; + + } + } + + /** + * Saves our metabox details, which is the style for a particular page. + * + * @param int $post_id The post we're current saving. + * + * @since 2.0.0 + * + */ + public function save_meta_box( $post_id ) { + // Check if our nonce is set. + if ( ! isset( $_POST['stylepress_style_nonce'] ) ) { // WPCS: input var okay. + return; + } + + // Verify that the nonce is valid. + if ( ! wp_verify_nonce( $_POST['stylepress_style_nonce'], 'stylepress_style_nonce' ) ) { // WPCS: sanitization ok. input var okay. + return; + } + + // If this is an autosave, our form has not been submitted, so we don't want to do anything. + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { + return; + } + + if ( isset( $_POST['stylepress_style'] ) && is_array( $_POST['stylepress_style'] ) ) { // WPCS: sanitization ok. input var okay. + $default_styles = []; + foreach ( $_POST['stylepress_style'] as $page_type ) { + // sanitise each one. + } + update_post_meta( $post_id, 'stylepress_style', sanitize_text_field( $_POST['stylepress_style'] ) ); // WPCS: sanitization ok. input var okay. + } + + } + + +} + diff --git a/inc/template-functions.php b/components/php/classes/template-functions.php similarity index 51% rename from inc/template-functions.php rename to components/php/classes/template-functions.php index 64e2c8a..e3ceca3 100644 --- a/inc/template-functions.php +++ b/components/php/classes/template-functions.php @@ -2,17 +2,17 @@ /** * Template Functions * - * @package dtbaker-elementor + * @package stylepress * * (just the do_content hook for the elementor widget, maybe more later on) */ -defined( 'DTBAKER_ELEMENTOR_PATH' ) || exit; +namespace StylePress; +defined( 'STYLEPRESS_VERSION' ) || exit; - -if ( ! function_exists( 'dtbaker_elementor_page_content' ) ) { +if ( ! function_exists( 'stylepress_page_content' ) ) { /** * Renderes the_content() from our Elementor widget hook. @@ -20,21 +20,21 @@ * * @param array $settings Elementor settings from this particular widget. Empty for now but may contain settings down the track. */ -function dtbaker_elementor_page_content( $settings = array() ) { +function stylepress_page_content( $settings = array() ) { -$current_page_type = DtbakerElementorManager::get_instance()->get_current_page_type(); +$current_page_type = Plugin::get_instance()->get_current_page_type(); if ( ! isset( $GLOBALS['stylepress_template_turtles'] ) ) { $GLOBALS['stylepress_template_turtles'] = array(); } -\DtbakerElementorManager::get_instance()->debug_message( "template-functions.php: Rendering from stylepress/render-inner action hook " ); +\Plugin::get_instance()->debug_message( "template-functions.php: Rendering from stylepress/render-inner action hook " ); if ( count( $GLOBALS['stylepress_template_turtles'] ) ) { - \DtbakerElementorManager::get_instance()->debug_message( "template-functions.php: Nested inner content for " . $current_page_type . "." ); + \Plugin::get_instance()->debug_message( "template-functions.php: Nested inner content for " . $current_page_type . "." ); // save and restore global post entry while we do this. if ( isset( $GLOBALS['post'] ) ) { @@ -88,17 +88,16 @@ function dtbaker_elementor_page_content( $settings = array() ) { return; } - -\DtbakerElementorManager::get_instance()->debug_message( "template-functions.php: Current page type for inner content style lookup is: $current_page_type " ); +\Plugin::get_instance()->debug_message( "template-functions.php: Current page type for inner content style lookup is: $current_page_type " ); if(! empty( $GLOBALS['stylepress_render_this_template_inside'] )){ -// hook here on our header/footer callbacks to strip double rendered content. + // hook here on our header/footer callbacks to strip double rendered content. -$theme_hooks = apply_filters( 'stylepress_theme_hooks', array() ); + $theme_hooks = apply_filters( 'stylepress_theme_hooks', array() ); -if(! empty( $theme_hooks['before'] ) && ! empty( $theme_hooks['after'] )){ + if(! empty( $theme_hooks['before'] ) && ! empty( $theme_hooks['after'] )){ -ob_start(); + ob_start(); ?> class="no-js"> @@ -110,48 +109,48 @@ function dtbaker_elementor_page_content( $settings = array() ) { > -get_current_page_type(); -DtbakerElementorManager::get_instance()->debug_message( "render.php: Rendering full page output for page type '$page_type' in render.php using the style: " . ( - ! empty( $GLOBALS['our_elementor_template'] ) ? '' . esc_html( get_the_title( $GLOBALS['our_elementor_template'] ) ) . ' ' . $GLOBALS['our_elementor_template'] : 'NONE' - ) . '' ); + $page_type = Plugin::get_instance()->get_current_page_type(); + Plugin::get_instance()->debug_message( "render.php: Rendering full page output for page type '$page_type' in render.php using the style: " . ( + ! empty( $GLOBALS['our_elementor_template'] ) ? '' . esc_html( get_the_title( $GLOBALS['our_elementor_template'] ) ) . ' ' . $GLOBALS['our_elementor_template'] : 'NONE' + ) . '' ); -if ( DtbakerElementorManager::get_instance()->removing_theme_css ) { - DtbakerElementorManager::get_instance()->debug_message( "render.php: Removing the default theme CSS files" ); -} + if ( Plugin::get_instance()->removing_theme_css ) { + Plugin::get_instance()->debug_message( "render.php: Removing the default theme CSS files" ); + } -do_action( 'stylepress/before-render' ); -$GLOBALS['stylepressheader'] = ob_get_clean(); -ob_start(); // kill the theme header from the below include. -add_action( $theme_hooks['before'], function () { - $old_header = ob_get_clean(); // kill the header - ob_start(); // capture all inner theme output and render it here. -} ); -add_action( $theme_hooks['after'], function(){ -// we have to break out of the template rendering and continue to render the stylepress footer from here on in. -$inner = ob_get_clean(); // capture all inner -echo $inner; -// render out stylepress footer -ob_start(); -do_action( 'stylepress/after-render' ); -wp_footer(); -?> + do_action( 'stylepress/before-render' ); + $GLOBALS['stylepressheader'] = ob_get_clean(); + ob_start(); // kill the theme header from the below include. + add_action( $theme_hooks['before'], function () { + $old_header = ob_get_clean(); // kill the header + ob_start(); // capture all inner theme output and render it here. + } ); + add_action( $theme_hooks['after'], function(){ + // we have to break out of the template rendering and continue to render the stylepress footer from here on in. + $inner = ob_get_clean(); // capture all inner + echo $inner; + // render out stylepress footer + ob_start(); + do_action( 'stylepress/after-render' ); + wp_footer(); + ?> - '; @@ -164,7 +163,7 @@ function dtbaker_elementor_page_content( $settings = array() ) { $GLOBALS['stylepress_post_for_dynamic_fields'] = $post; $style_id = $GLOBALS['our_elementor_inner_template']; - $current_inner_style = (int) DtbakerElementorManager::get_instance()->get_page_inner_style( $post->ID ); + $current_inner_style = (int) Plugin::get_instance()->get_page_inner_style( $post->ID ); if ( $current_inner_style ) { // override default in loop. // hmm this might not work well in output of a blog. @@ -173,10 +172,10 @@ function dtbaker_elementor_page_content( $settings = array() ) { if ( $style_id > 0 ) { $GLOBALS['stylepress_template_turtles'][ $style_id ] = $style_id; - \DtbakerElementorManager::get_instance()->debug_message( "template-functions.php: Rendering style: $style_id " ); + \Plugin::get_instance()->debug_message( "template-functions.php: Rendering style: $style_id " ); echo Elementor\Plugin::instance()->frontend->get_builder_content( $style_id, false ); } else { - \DtbakerElementorManager::get_instance()->debug_message( "template-functions.php: Rendering plain content: $style_id " ); + \Plugin::get_instance()->debug_message( "template-functions.php: Rendering plain content: $style_id " ); // todo: handle inner theme output from here. the_content(); @@ -191,4 +190,4 @@ function dtbaker_elementor_page_content( $settings = array() ) { } } -add_action( 'stylepress/render-inner', 'dtbaker_elementor_page_content', 20 ); +add_action( 'stylepress/render-inner', 'stylepress_page_content', 20 ); diff --git a/components/php/classes/templates.php b/components/php/classes/templates.php new file mode 100644 index 0000000..e82cc76 --- /dev/null +++ b/components/php/classes/templates.php @@ -0,0 +1,39 @@ +query_vars['stylepress'] = $args; + load_template( $template_path, false ); + } + + } + +} + diff --git a/components/php/classes/tgm-plugin-activation.php b/components/php/classes/tgm-plugin-activation.php new file mode 100644 index 0000000..634b6ae --- /dev/null +++ b/components/php/classes/tgm-plugin-activation.php @@ -0,0 +1,3845 @@ +wp_version = $GLOBALS['wp_version']; + + // Announce that the class is ready, and pass the object (for advanced use). + do_action_ref_array( 'tgmpa_init', array( $this ) ); + + /* + * Load our text domain and allow for overloading the fall-back file. + * + * {@internal IMPORTANT! If this code changes, review the regex in the custom TGMPA + * generator on the website.}} + */ + add_action( 'init', array( $this, 'load_textdomain' ), 5 ); + add_filter( 'load_textdomain_mofile', array( $this, 'overload_textdomain_mofile' ), 10, 2 ); + + // When the rest of WP has loaded, kick-start the rest of the class. + add_action( 'init', array( $this, 'init' ) ); + } + + /** + * Magic method to (not) set protected properties from outside of this class. + * + * {@internal hackedihack... There is a serious bug in v2.3.2 - 2.3.6 where the `menu` property + * is being assigned rather than tested in a conditional, effectively rendering it useless. + * This 'hack' prevents this from happening.}} + * + * @see https://github.com/TGMPA/TGM-Plugin-Activation/blob/2.3.6/tgm-plugin-activation/class-tgm-plugin-activation.php#L1593 + * + * @since 2.5.2 + * + * @param string $name Name of an inaccessible property. + * @param mixed $value Value to assign to the property. + * @return void Silently fail to set the property when this is tried from outside of this class context. + * (Inside this class context, the __set() method if not used as there is direct access.) + */ + public function __set( $name, $value ) { + return; + } + + /** + * Magic method to get the value of a protected property outside of this class context. + * + * @since 2.5.2 + * + * @param string $name Name of an inaccessible property. + * @return mixed The property value. + */ + public function __get( $name ) { + return $this->{$name}; + } + + /** + * Initialise the interactions between this class and WordPress. + * + * Hooks in three new methods for the class: admin_menu, notices and styles. + * + * @since 2.0.0 + * + * @see TGM_Plugin_Activation::admin_menu() + * @see TGM_Plugin_Activation::notices() + * @see TGM_Plugin_Activation::styles() + */ + public function init() { + /** + * By default TGMPA only loads on the WP back-end and not in an Ajax call. Using this filter + * you can overrule that behaviour. + * + * @since 2.5.0 + * + * @param bool $load Whether or not TGMPA should load. + * Defaults to the return of `is_admin() && ! defined( 'DOING_AJAX' )`. + */ + if ( true !== apply_filters( 'tgmpa_load', ( is_admin() && ! defined( 'DOING_AJAX' ) ) ) ) { + return; + } + + // Load class strings. + $this->strings = array( + 'page_title' => __( 'Install Required Plugins', 'tgmpa' ), + 'menu_title' => __( 'Install Plugins', 'tgmpa' ), + /* translators: %s: plugin name. */ + 'installing' => __( 'Installing Plugin: %s', 'tgmpa' ), + /* translators: %s: plugin name. */ + 'updating' => __( 'Updating Plugin: %s', 'tgmpa' ), + 'oops' => __( 'Something went wrong with the plugin API.', 'tgmpa' ), + 'notice_can_install_required' => _n_noop( + /* translators: 1: plugin name(s). */ + 'This theme requires the following plugin: %1$s.', + 'This theme requires the following plugins: %1$s.', + 'tgmpa' + ), + 'notice_can_install_recommended' => _n_noop( + /* translators: 1: plugin name(s). */ + 'This theme recommends the following plugin: %1$s.', + 'This theme recommends the following plugins: %1$s.', + 'tgmpa' + ), + 'notice_ask_to_update' => _n_noop( + /* translators: 1: plugin name(s). */ + 'The following plugin needs to be updated to its latest version to ensure maximum compatibility with this theme: %1$s.', + 'The following plugins need to be updated to their latest version to ensure maximum compatibility with this theme: %1$s.', + 'tgmpa' + ), + 'notice_ask_to_update_maybe' => _n_noop( + /* translators: 1: plugin name(s). */ + 'There is an update available for: %1$s.', + 'There are updates available for the following plugins: %1$s.', + 'tgmpa' + ), + 'notice_can_activate_required' => _n_noop( + /* translators: 1: plugin name(s). */ + 'The following required plugin is currently inactive: %1$s.', + 'The following required plugins are currently inactive: %1$s.', + 'tgmpa' + ), + 'notice_can_activate_recommended' => _n_noop( + /* translators: 1: plugin name(s). */ + 'The following recommended plugin is currently inactive: %1$s.', + 'The following recommended plugins are currently inactive: %1$s.', + 'tgmpa' + ), + 'install_link' => _n_noop( + 'Begin installing plugin', + 'Begin installing plugins', + 'tgmpa' + ), + 'update_link' => _n_noop( + 'Begin updating plugin', + 'Begin updating plugins', + 'tgmpa' + ), + 'activate_link' => _n_noop( + 'Begin activating plugin', + 'Begin activating plugins', + 'tgmpa' + ), + 'return' => __( 'Return to Required Plugins Installer', 'tgmpa' ), + 'dashboard' => __( 'Return to the Dashboard', 'tgmpa' ), + 'plugin_activated' => __( 'Plugin activated successfully.', 'tgmpa' ), + 'activated_successfully' => __( 'The following plugin was activated successfully:', 'tgmpa' ), + /* translators: 1: plugin name. */ + 'plugin_already_active' => __( 'No action taken. Plugin %1$s was already active.', 'tgmpa' ), + /* translators: 1: plugin name. */ + 'plugin_needs_higher_version' => __( 'Plugin not activated. A higher version of %s is needed for this theme. Please update the plugin.', 'tgmpa' ), + /* translators: 1: dashboard link. */ + 'complete' => __( 'All plugins installed and activated successfully. %1$s', 'tgmpa' ), + 'dismiss' => __( 'Dismiss this notice', 'tgmpa' ), + 'notice_cannot_install_activate' => __( 'There are one or more required or recommended plugins to install, update or activate.', 'tgmpa' ), + 'contact_admin' => __( 'Please contact the administrator of this site for help.', 'tgmpa' ), + ); + + do_action( 'tgmpa_register' ); + + /* After this point, the plugins should be registered and the configuration set. */ + + // Proceed only if we have plugins to handle. + if ( empty( $this->plugins ) || ! is_array( $this->plugins ) ) { + return; + } + + // Set up the menu and notices if we still have outstanding actions. + if ( true !== $this->is_tgmpa_complete() ) { + // Sort the plugins. + array_multisort( $this->sort_order, SORT_ASC, $this->plugins ); + + add_action( 'admin_menu', array( $this, 'admin_menu' ) ); + add_action( 'admin_head', array( $this, 'dismiss' ) ); + + // Prevent the normal links from showing underneath a single install/update page. + add_filter( 'install_plugin_complete_actions', array( $this, 'actions' ) ); + add_filter( 'update_plugin_complete_actions', array( $this, 'actions' ) ); + + if ( $this->has_notices ) { + add_action( 'admin_notices', array( $this, 'notices' ) ); + add_action( 'admin_init', array( $this, 'admin_init' ), 1 ); + add_action( 'admin_enqueue_scripts', array( $this, 'thickbox' ) ); + } + } + + // If needed, filter plugin action links. + add_action( 'load-plugins.php', array( $this, 'add_plugin_action_link_filters' ), 1 ); + + // Make sure things get reset on switch theme. + add_action( 'switch_theme', array( $this, 'flush_plugins_cache' ) ); + + if ( $this->has_notices ) { + add_action( 'switch_theme', array( $this, 'update_dismiss' ) ); + } + + // Setup the force activation hook. + if ( true === $this->has_forced_activation ) { + add_action( 'admin_init', array( $this, 'force_activation' ) ); + } + + // Setup the force deactivation hook. + if ( true === $this->has_forced_deactivation ) { + add_action( 'switch_theme', array( $this, 'force_deactivation' ) ); + } + } + + /** + * Load translations. + * + * @since 2.6.0 + * + * (@internal Uses `load_theme_textdomain()` rather than `load_plugin_textdomain()` to + * get round the different ways of handling the path and deprecated notices being thrown + * and such. For plugins, the actual file name will be corrected by a filter.}} + * + * {@internal IMPORTANT! If this function changes, review the regex in the custom TGMPA + * generator on the website.}} + */ + public function load_textdomain() { + if ( is_textdomain_loaded( 'tgmpa' ) ) { + return; + } + + if ( false !== strpos( __FILE__, WP_PLUGIN_DIR ) || false !== strpos( __FILE__, WPMU_PLUGIN_DIR ) ) { + // Plugin, we'll need to adjust the file name. + add_action( 'load_textdomain_mofile', array( $this, 'correct_plugin_mofile' ), 10, 2 ); + load_theme_textdomain( 'tgmpa', dirname( __FILE__ ) . '/languages' ); + remove_action( 'load_textdomain_mofile', array( $this, 'correct_plugin_mofile' ), 10 ); + } else { + load_theme_textdomain( 'tgmpa', dirname( __FILE__ ) . '/languages' ); + } + } + + /** + * Correct the .mo file name for (must-use) plugins. + * + * Themese use `/path/{locale}.mo` while plugins use `/path/{text-domain}-{locale}.mo`. + * + * {@internal IMPORTANT! If this function changes, review the regex in the custom TGMPA + * generator on the website.}} + * + * @since 2.6.0 + * + * @param string $mofile Full path to the target mofile. + * @param string $domain The domain for which a language file is being loaded. + * @return string $mofile + */ + public function correct_plugin_mofile( $mofile, $domain ) { + // Exit early if not our domain (just in case). + if ( 'tgmpa' !== $domain ) { + return $mofile; + } + return preg_replace( '`/([a-z]{2}_[A-Z]{2}.mo)$`', '/tgmpa-$1', $mofile ); + } + + /** + * Potentially overload the fall-back translation file for the current language. + * + * WP, by default since WP 3.7, will load a local translation first and if none + * can be found, will try and find a translation in the /wp-content/languages/ directory. + * As this library is theme/plugin agnostic, translation files for TGMPA can exist both + * in the WP_LANG_DIR /plugins/ subdirectory as well as in the /themes/ subdirectory. + * + * This method makes sure both directories are checked. + * + * {@internal IMPORTANT! If this function changes, review the regex in the custom TGMPA + * generator on the website.}} + * + * @since 2.6.0 + * + * @param string $mofile Full path to the target mofile. + * @param string $domain The domain for which a language file is being loaded. + * @return string $mofile + */ + public function overload_textdomain_mofile( $mofile, $domain ) { + // Exit early if not our domain, not a WP_LANG_DIR load or if the file exists and is readable. + if ( 'tgmpa' !== $domain || false === strpos( $mofile, WP_LANG_DIR ) || @is_readable( $mofile ) ) { + return $mofile; + } + + // Current fallback file is not valid, let's try the alternative option. + if ( false !== strpos( $mofile, '/themes/' ) ) { + return str_replace( '/themes/', '/plugins/', $mofile ); + } elseif ( false !== strpos( $mofile, '/plugins/' ) ) { + return str_replace( '/plugins/', '/themes/', $mofile ); + } else { + return $mofile; + } + } + + /** + * Hook in plugin action link filters for the WP native plugins page. + * + * - Prevent activation of plugins which don't meet the minimum version requirements. + * - Prevent deactivation of force-activated plugins. + * - Add update notice if update available. + * + * @since 2.5.0 + */ + public function add_plugin_action_link_filters() { + foreach ( $this->plugins as $slug => $plugin ) { + if ( false === $this->can_plugin_activate( $slug ) ) { + add_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_activate' ), 20 ); + } + + if ( true === $plugin['force_activation'] ) { + add_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_deactivate' ), 20 ); + } + + if ( false !== $this->does_plugin_require_update( $slug ) ) { + add_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_update' ), 20 ); + } + } + } + + /** + * Remove the 'Activate' link on the WP native plugins page if the plugin does not meet the + * minimum version requirements. + * + * @since 2.5.0 + * + * @param array $actions Action links. + * @return array + */ + public function filter_plugin_action_links_activate( $actions ) { + unset( $actions['activate'] ); + + return $actions; + } + + /** + * Remove the 'Deactivate' link on the WP native plugins page if the plugin has been set to force activate. + * + * @since 2.5.0 + * + * @param array $actions Action links. + * @return array + */ + public function filter_plugin_action_links_deactivate( $actions ) { + unset( $actions['deactivate'] ); + + return $actions; + } + + /** + * Add a 'Requires update' link on the WP native plugins page if the plugin does not meet the + * minimum version requirements. + * + * @since 2.5.0 + * + * @param array $actions Action links. + * @return array + */ + public function filter_plugin_action_links_update( $actions ) { + $actions['update'] = sprintf( + '%3$s', + esc_url( $this->get_tgmpa_status_url( 'update' ) ), + esc_attr__( 'This plugin needs to be updated to be compatible with your theme.', 'tgmpa' ), + esc_html__( 'Update Required', 'tgmpa' ) + ); + + return $actions; + } + + /** + * Handles calls to show plugin information via links in the notices. + * + * We get the links in the admin notices to point to the TGMPA page, rather + * than the typical plugin-install.php file, so we can prepare everything + * beforehand. + * + * WP does not make it easy to show the plugin information in the thickbox - + * here we have to require a file that includes a function that does the + * main work of displaying it, enqueue some styles, set up some globals and + * finally call that function before exiting. + * + * Down right easy once you know how... + * + * Returns early if not the TGMPA page. + * + * @since 2.1.0 + * + * @global string $tab Used as iframe div class names, helps with styling + * @global string $body_id Used as the iframe body ID, helps with styling + * + * @return null Returns early if not the TGMPA page. + */ + public function admin_init() { + if ( ! $this->is_tgmpa_page() ) { + return; + } + + if ( isset( $_REQUEST['tab'] ) && 'plugin-information' === $_REQUEST['tab'] ) { + // Needed for install_plugin_information(). + require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; + + wp_enqueue_style( 'plugin-install' ); + + global $tab, $body_id; + $body_id = 'plugin-information'; + // @codingStandardsIgnoreStart + $tab = 'plugin-information'; + // @codingStandardsIgnoreEnd + + install_plugin_information(); + + exit; + } + } + + /** + * Enqueue thickbox scripts/styles for plugin info. + * + * Thickbox is not automatically included on all admin pages, so we must + * manually enqueue it for those pages. + * + * Thickbox is only loaded if the user has not dismissed the admin + * notice or if there are any plugins left to install and activate. + * + * @since 2.1.0 + */ + public function thickbox() { + if ( ! get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, true ) ) { + add_thickbox(); + } + } + + /** + * Adds submenu page if there are plugin actions to take. + * + * This method adds the submenu page letting users know that a required + * plugin needs to be installed. + * + * This page disappears once the plugin has been installed and activated. + * + * @since 1.0.0 + * + * @see TGM_Plugin_Activation::init() + * @see TGM_Plugin_Activation::install_plugins_page() + * + * @return null Return early if user lacks capability to install a plugin. + */ + public function admin_menu() { + // Make sure privileges are correct to see the page. + if ( ! current_user_can( 'install_plugins' ) ) { + return; + } + + $args = apply_filters( + 'tgmpa_admin_menu_args', + array( + 'parent_slug' => $this->parent_slug, // Parent Menu slug. + 'page_title' => $this->strings['page_title'], // Page title. + 'menu_title' => $this->strings['menu_title'], // Menu title. + 'capability' => $this->capability, // Capability. + 'menu_slug' => $this->menu, // Menu slug. + 'function' => array( $this, 'install_plugins_page' ), // Callback. + ) + ); + + $this->add_admin_menu( $args ); + } + + /** + * Add the menu item. + * + * {@internal IMPORTANT! If this function changes, review the regex in the custom TGMPA + * generator on the website.}} + * + * @since 2.5.0 + * + * @param array $args Menu item configuration. + */ + protected function add_admin_menu( array $args ) { + $this->page_hook = add_theme_page( $args['page_title'], $args['menu_title'], $args['capability'], $args['menu_slug'], $args['function'] ); + } + + /** + * Echoes plugin installation form. + * + * This method is the callback for the admin_menu method function. + * This displays the admin page and form area where the user can select to install and activate the plugin. + * Aborts early if we're processing a plugin installation action. + * + * @since 1.0.0 + * + * @return null Aborts early if we're processing a plugin installation action. + */ + public function install_plugins_page() { + // Store new instance of plugin table in object. + $plugin_table = new TGMPA_List_Table; + + // Return early if processing a plugin installation action. + if ( ( ( 'tgmpa-bulk-install' === $plugin_table->current_action() || 'tgmpa-bulk-update' === $plugin_table->current_action() ) && $plugin_table->process_bulk_actions() ) || $this->do_plugin_install() ) { + return; + } + + // Force refresh of available plugin information so we'll know about manual updates/deletes. + wp_clean_plugins_cache( false ); + + ?> +
+

+ prepare_items(); ?> + + message ) && is_string( $this->message ) ) { + echo wp_kses_post( $this->message ); + } + ?> + views(); ?> + +
+ + + display(); ?> +
+
+ sanitize_key( urldecode( $_GET['plugin'] ) ); + + if ( ! isset( $this->plugins[ $slug ] ) ) { + return false; + } + + // Was an install or upgrade action link clicked? + if ( ( isset( $_GET['tgmpa-install'] ) && 'install-plugin' === $_GET['tgmpa-install'] ) || ( isset( $_GET['tgmpa-update'] ) && 'update-plugin' === $_GET['tgmpa-update'] ) ) { + + $install_type = 'install'; + if ( isset( $_GET['tgmpa-update'] ) && 'update-plugin' === $_GET['tgmpa-update'] ) { + $install_type = 'update'; + } + + check_admin_referer( 'tgmpa-' . $install_type, 'tgmpa-nonce' ); + + // Pass necessary information via URL if WP_Filesystem is needed. + $url = wp_nonce_url( + add_query_arg( + array( + 'plugin' => urlencode( $slug ), + 'tgmpa-' . $install_type => $install_type . '-plugin', + ), + $this->get_tgmpa_url() + ), + 'tgmpa-' . $install_type, + 'tgmpa-nonce' + ); + + $method = ''; // Leave blank so WP_Filesystem can populate it as necessary. + + if ( false === ( $creds = request_filesystem_credentials( esc_url_raw( $url ), $method, false, false, array() ) ) ) { + return true; + } + + if ( ! WP_Filesystem( $creds ) ) { + request_filesystem_credentials( esc_url_raw( $url ), $method, true, false, array() ); // Setup WP_Filesystem. + return true; + } + + /* If we arrive here, we have the filesystem. */ + + // Prep variables for Plugin_Installer_Skin class. + $extra = array(); + $extra['slug'] = $slug; // Needed for potentially renaming of directory name. + $source = $this->get_download_url( $slug ); + $api = ( 'repo' === $this->plugins[ $slug ]['source_type'] ) ? $this->get_plugins_api( $slug ) : null; + $api = ( false !== $api ) ? $api : null; + + $url = add_query_arg( + array( + 'action' => $install_type . '-plugin', + 'plugin' => urlencode( $slug ), + ), + 'update.php' + ); + + if ( ! class_exists( 'Plugin_Upgrader', false ) ) { + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + } + + $title = ( 'update' === $install_type ) ? $this->strings['updating'] : $this->strings['installing']; + $skin_args = array( + 'type' => ( 'bundled' !== $this->plugins[ $slug ]['source_type'] ) ? 'web' : 'upload', + 'title' => sprintf( $title, $this->plugins[ $slug ]['name'] ), + 'url' => esc_url_raw( $url ), + 'nonce' => $install_type . '-plugin_' . $slug, + 'plugin' => '', + 'api' => $api, + 'extra' => $extra, + ); + unset( $title ); + + if ( 'update' === $install_type ) { + $skin_args['plugin'] = $this->plugins[ $slug ]['file_path']; + $skin = new Plugin_Upgrader_Skin( $skin_args ); + } else { + $skin = new Plugin_Installer_Skin( $skin_args ); + } + + // Create a new instance of Plugin_Upgrader. + $upgrader = new Plugin_Upgrader( $skin ); + + // Perform the action and install the plugin from the $source urldecode(). + add_filter( 'upgrader_source_selection', array( $this, 'maybe_adjust_source_dir' ), 1, 3 ); + + if ( 'update' === $install_type ) { + // Inject our info into the update transient. + $to_inject = array( $slug => $this->plugins[ $slug ] ); + $to_inject[ $slug ]['source'] = $source; + $this->inject_update_info( $to_inject ); + + $upgrader->upgrade( $this->plugins[ $slug ]['file_path'] ); + } else { + $upgrader->install( $source ); + } + + remove_filter( 'upgrader_source_selection', array( $this, 'maybe_adjust_source_dir' ), 1 ); + + // Make sure we have the correct file path now the plugin is installed/updated. + $this->populate_file_path( $slug ); + + // Only activate plugins if the config option is set to true and the plugin isn't + // already active (upgrade). + if ( $this->is_automatic && ! $this->is_plugin_active( $slug ) ) { + $plugin_activate = $upgrader->plugin_info(); // Grab the plugin info from the Plugin_Upgrader method. + if ( false === $this->activate_single_plugin( $plugin_activate, $slug, true ) ) { + return true; // Finish execution of the function early as we encountered an error. + } + } + + $this->show_tgmpa_version(); + + // Display message based on if all plugins are now active or not. + if ( $this->is_tgmpa_complete() ) { + echo '

', sprintf( esc_html( $this->strings['complete'] ), '' . esc_html__( 'Return to the Dashboard', 'tgmpa' ) . '' ), '

'; + echo ''; + } else { + echo '

', esc_html( $this->strings['return'] ), '

'; + } + + return true; + } elseif ( isset( $this->plugins[ $slug ]['file_path'], $_GET['tgmpa-activate'] ) && 'activate-plugin' === $_GET['tgmpa-activate'] ) { + // Activate action link was clicked. + check_admin_referer( 'tgmpa-activate', 'tgmpa-nonce' ); + + if ( false === $this->activate_single_plugin( $this->plugins[ $slug ]['file_path'], $slug ) ) { + return true; // Finish execution of the function early as we encountered an error. + } + } + + return false; + } + + /** + * Inject information into the 'update_plugins' site transient as WP checks that before running an update. + * + * @since 2.5.0 + * + * @param array $plugins The plugin information for the plugins which are to be updated. + */ + public function inject_update_info( $plugins ) { + $repo_updates = get_site_transient( 'update_plugins' ); + + if ( ! is_object( $repo_updates ) ) { + $repo_updates = new stdClass; + } + + foreach ( $plugins as $slug => $plugin ) { + $file_path = $plugin['file_path']; + + if ( empty( $repo_updates->response[ $file_path ] ) ) { + $repo_updates->response[ $file_path ] = new stdClass; + } + + // We only really need to set package, but let's do all we can in case WP changes something. + $repo_updates->response[ $file_path ]->slug = $slug; + $repo_updates->response[ $file_path ]->plugin = $file_path; + $repo_updates->response[ $file_path ]->new_version = $plugin['version']; + $repo_updates->response[ $file_path ]->package = $plugin['source']; + if ( empty( $repo_updates->response[ $file_path ]->url ) && ! empty( $plugin['external_url'] ) ) { + $repo_updates->response[ $file_path ]->url = $plugin['external_url']; + } + } + + set_site_transient( 'update_plugins', $repo_updates ); + } + + /** + * Adjust the plugin directory name if necessary. + * + * The final destination directory of a plugin is based on the subdirectory name found in the + * (un)zipped source. In some cases - most notably GitHub repository plugin downloads -, this + * subdirectory name is not the same as the expected slug and the plugin will not be recognized + * as installed. This is fixed by adjusting the temporary unzipped source subdirectory name to + * the expected plugin slug. + * + * @since 2.5.0 + * + * @param string $source Path to upgrade/zip-file-name.tmp/subdirectory/. + * @param string $remote_source Path to upgrade/zip-file-name.tmp. + * @param \WP_Upgrader $upgrader Instance of the upgrader which installs the plugin. + * @return string $source + */ + public function maybe_adjust_source_dir( $source, $remote_source, $upgrader ) { + if ( ! $this->is_tgmpa_page() || ! is_object( $GLOBALS['wp_filesystem'] ) ) { + return $source; + } + + // Check for single file plugins. + $source_files = array_keys( $GLOBALS['wp_filesystem']->dirlist( $remote_source ) ); + if ( 1 === count( $source_files ) && false === $GLOBALS['wp_filesystem']->is_dir( $source ) ) { + return $source; + } + + // Multi-file plugin, let's see if the directory is correctly named. + $desired_slug = ''; + + // Figure out what the slug is supposed to be. + if ( false === $upgrader->bulk && ! empty( $upgrader->skin->options['extra']['slug'] ) ) { + $desired_slug = $upgrader->skin->options['extra']['slug']; + } else { + // Bulk installer contains less info, so fall back on the info registered here. + foreach ( $this->plugins as $slug => $plugin ) { + if ( ! empty( $upgrader->skin->plugin_names[ $upgrader->skin->i ] ) && $plugin['name'] === $upgrader->skin->plugin_names[ $upgrader->skin->i ] ) { + $desired_slug = $slug; + break; + } + } + unset( $slug, $plugin ); + } + + if ( ! empty( $desired_slug ) ) { + $subdir_name = untrailingslashit( str_replace( trailingslashit( $remote_source ), '', $source ) ); + + if ( ! empty( $subdir_name ) && $subdir_name !== $desired_slug ) { + $from_path = untrailingslashit( $source ); + $to_path = trailingslashit( $remote_source ) . $desired_slug; + + if ( true === $GLOBALS['wp_filesystem']->move( $from_path, $to_path ) ) { + return trailingslashit( $to_path ); + } else { + return new WP_Error( 'rename_failed', esc_html__( 'The remote plugin package does not contain a folder with the desired slug and renaming did not work.', 'tgmpa' ) . ' ' . esc_html__( 'Please contact the plugin provider and ask them to package their plugin according to the WordPress guidelines.', 'tgmpa' ), array( 'found' => $subdir_name, 'expected' => $desired_slug ) ); + } + } elseif ( empty( $subdir_name ) ) { + return new WP_Error( 'packaged_wrong', esc_html__( 'The remote plugin package consists of more than one file, but the files are not packaged in a folder.', 'tgmpa' ) . ' ' . esc_html__( 'Please contact the plugin provider and ask them to package their plugin according to the WordPress guidelines.', 'tgmpa' ), array( 'found' => $subdir_name, 'expected' => $desired_slug ) ); + } + } + + return $source; + } + + /** + * Activate a single plugin and send feedback about the result to the screen. + * + * @since 2.5.0 + * + * @param string $file_path Path within wp-plugins/ to main plugin file. + * @param string $slug Plugin slug. + * @param bool $automatic Whether this is an automatic activation after an install. Defaults to false. + * This determines the styling of the output messages. + * @return bool False if an error was encountered, true otherwise. + */ + protected function activate_single_plugin( $file_path, $slug, $automatic = false ) { + if ( $this->can_plugin_activate( $slug ) ) { + $activate = activate_plugin( $file_path ); + + if ( is_wp_error( $activate ) ) { + echo '

', wp_kses_post( $activate->get_error_message() ), '

', + '

', esc_html( $this->strings['return'] ), '

'; + + return false; // End it here if there is an error with activation. + } else { + if ( ! $automatic ) { + // Make sure message doesn't display again if bulk activation is performed + // immediately after a single activation. + if ( ! isset( $_POST['action'] ) ) { // WPCS: CSRF OK. + echo '

', esc_html( $this->strings['activated_successfully'] ), ' ', esc_html( $this->plugins[ $slug ]['name'] ), '.

'; + } + } else { + // Simpler message layout for use on the plugin install page. + echo '

', esc_html( $this->strings['plugin_activated'] ), '

'; + } + } + } elseif ( $this->is_plugin_active( $slug ) ) { + // No simpler message format provided as this message should never be encountered + // on the plugin install page. + echo '

', + sprintf( + esc_html( $this->strings['plugin_already_active'] ), + '' . esc_html( $this->plugins[ $slug ]['name'] ) . '' + ), + '

'; + } elseif ( $this->does_plugin_require_update( $slug ) ) { + if ( ! $automatic ) { + // Make sure message doesn't display again if bulk activation is performed + // immediately after a single activation. + if ( ! isset( $_POST['action'] ) ) { // WPCS: CSRF OK. + echo '

', + sprintf( + esc_html( $this->strings['plugin_needs_higher_version'] ), + '' . esc_html( $this->plugins[ $slug ]['name'] ) . '' + ), + '

'; + } + } else { + // Simpler message layout for use on the plugin install page. + echo '

', sprintf( esc_html( $this->strings['plugin_needs_higher_version'] ), esc_html( $this->plugins[ $slug ]['name'] ) ), '

'; + } + } + + return true; + } + + /** + * Echoes required plugin notice. + * + * Outputs a message telling users that a specific plugin is required for + * their theme. If appropriate, it includes a link to the form page where + * users can install and activate the plugin. + * + * Returns early if we're on the Install page. + * + * @since 1.0.0 + * + * @global object $current_screen + * + * @return null Returns early if we're on the Install page. + */ + public function notices() { + // Remove nag on the install page / Return early if the nag message has been dismissed or user < author. + if ( ( $this->is_tgmpa_page() || $this->is_core_update_page() ) || get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, true ) || ! current_user_can( apply_filters( 'tgmpa_show_admin_notice_capability', 'publish_posts' ) ) ) { + return; + } + + // Store for the plugin slugs by message type. + $message = array(); + + // Initialize counters used to determine plurality of action link texts. + $install_link_count = 0; + $update_link_count = 0; + $activate_link_count = 0; + $total_required_action_count = 0; + + foreach ( $this->plugins as $slug => $plugin ) { + if ( $this->is_plugin_active( $slug ) && false === $this->does_plugin_have_update( $slug ) ) { + continue; + } + + if ( ! $this->is_plugin_installed( $slug ) ) { + if ( current_user_can( 'install_plugins' ) ) { + $install_link_count++; + + if ( true === $plugin['required'] ) { + $message['notice_can_install_required'][] = $slug; + } else { + $message['notice_can_install_recommended'][] = $slug; + } + } + if ( true === $plugin['required'] ) { + $total_required_action_count++; + } + } else { + if ( ! $this->is_plugin_active( $slug ) && $this->can_plugin_activate( $slug ) ) { + if ( current_user_can( 'activate_plugins' ) ) { + $activate_link_count++; + + if ( true === $plugin['required'] ) { + $message['notice_can_activate_required'][] = $slug; + } else { + $message['notice_can_activate_recommended'][] = $slug; + } + } + if ( true === $plugin['required'] ) { + $total_required_action_count++; + } + } + + if ( $this->does_plugin_require_update( $slug ) || false !== $this->does_plugin_have_update( $slug ) ) { + + if ( current_user_can( 'update_plugins' ) ) { + $update_link_count++; + + if ( $this->does_plugin_require_update( $slug ) ) { + $message['notice_ask_to_update'][] = $slug; + } elseif ( false !== $this->does_plugin_have_update( $slug ) ) { + $message['notice_ask_to_update_maybe'][] = $slug; + } + } + if ( true === $plugin['required'] ) { + $total_required_action_count++; + } + } + } + } + unset( $slug, $plugin ); + + // If we have notices to display, we move forward. + if ( ! empty( $message ) || $total_required_action_count > 0 ) { + krsort( $message ); // Sort messages. + $rendered = ''; + + // As add_settings_error() wraps the final message in a

and as the final message can't be + // filtered, using

's in our html would render invalid html output. + $line_template = '%s' . "\n"; + + if ( ! current_user_can( 'activate_plugins' ) && ! current_user_can( 'install_plugins' ) && ! current_user_can( 'update_plugins' ) ) { + $rendered = esc_html( $this->strings['notice_cannot_install_activate'] ) . ' ' . esc_html( $this->strings['contact_admin'] ); + $rendered .= $this->create_user_action_links_for_notice( 0, 0, 0, $line_template ); + } else { + + // If dismissable is false and a message is set, output it now. + if ( ! $this->dismissable && ! empty( $this->dismiss_msg ) ) { + $rendered .= sprintf( $line_template, wp_kses_post( $this->dismiss_msg ) ); + } + + // Render the individual message lines for the notice. + foreach ( $message as $type => $plugin_group ) { + $linked_plugins = array(); + + // Get the external info link for a plugin if one is available. + foreach ( $plugin_group as $plugin_slug ) { + $linked_plugins[] = $this->get_info_link( $plugin_slug ); + } + unset( $plugin_slug ); + + $count = count( $plugin_group ); + $linked_plugins = array_map( array( 'TGMPA_Utils', 'wrap_in_em' ), $linked_plugins ); + $last_plugin = array_pop( $linked_plugins ); // Pop off last name to prep for readability. + $imploded = empty( $linked_plugins ) ? $last_plugin : ( implode( ', ', $linked_plugins ) . ' ' . esc_html_x( 'and', 'plugin A *and* plugin B', 'tgmpa' ) . ' ' . $last_plugin ); + + $rendered .= sprintf( + $line_template, + sprintf( + translate_nooped_plural( $this->strings[ $type ], $count, 'tgmpa' ), + $imploded, + $count + ) + ); + + } + unset( $type, $plugin_group, $linked_plugins, $count, $last_plugin, $imploded ); + + $rendered .= $this->create_user_action_links_for_notice( $install_link_count, $update_link_count, $activate_link_count, $line_template ); + } + + // Register the nag messages and prepare them to be processed. + add_settings_error( 'tgmpa', 'tgmpa', $rendered, $this->get_admin_notice_class() ); + } + + // Admin options pages already output settings_errors, so this is to avoid duplication. + if ( 'options-general' !== $GLOBALS['current_screen']->parent_base ) { + $this->display_settings_errors(); + } + } + + /** + * Generate the user action links for the admin notice. + * + * @since 2.6.0 + * + * @param int $install_count Number of plugins to install. + * @param int $update_count Number of plugins to update. + * @param int $activate_count Number of plugins to activate. + * @param int $line_template Template for the HTML tag to output a line. + * @return string Action links. + */ + protected function create_user_action_links_for_notice( $install_count, $update_count, $activate_count, $line_template ) { + // Setup action links. + $action_links = array( + 'install' => '', + 'update' => '', + 'activate' => '', + 'dismiss' => $this->dismissable ? '' . esc_html( $this->strings['dismiss'] ) . '' : '', + ); + + $link_template = '%1$s'; + + if ( current_user_can( 'install_plugins' ) ) { + if ( $install_count > 0 ) { + $action_links['install'] = sprintf( + $link_template, + translate_nooped_plural( $this->strings['install_link'], $install_count, 'tgmpa' ), + esc_url( $this->get_tgmpa_status_url( 'install' ) ) + ); + } + if ( $update_count > 0 ) { + $action_links['update'] = sprintf( + $link_template, + translate_nooped_plural( $this->strings['update_link'], $update_count, 'tgmpa' ), + esc_url( $this->get_tgmpa_status_url( 'update' ) ) + ); + } + } + + if ( current_user_can( 'activate_plugins' ) && $activate_count > 0 ) { + $action_links['activate'] = sprintf( + $link_template, + translate_nooped_plural( $this->strings['activate_link'], $activate_count, 'tgmpa' ), + esc_url( $this->get_tgmpa_status_url( 'activate' ) ) + ); + } + + $action_links = apply_filters( 'tgmpa_notice_action_links', $action_links ); + + $action_links = array_filter( (array) $action_links ); // Remove any empty array items. + + if ( ! empty( $action_links ) ) { + $action_links = sprintf( $line_template, implode( ' | ', $action_links ) ); + return apply_filters( 'tgmpa_notice_rendered_action_links', $action_links ); + } else { + return ''; + } + } + + /** + * Get admin notice class. + * + * Work around all the changes to the various admin notice classes between WP 4.4 and 3.7 + * (lowest supported version by TGMPA). + * + * @since 2.6.0 + * + * @return string + */ + protected function get_admin_notice_class() { + if ( ! empty( $this->strings['nag_type'] ) ) { + return sanitize_html_class( strtolower( $this->strings['nag_type'] ) ); + } else { + if ( version_compare( $this->wp_version, '4.2', '>=' ) ) { + return 'notice-warning'; + } elseif ( version_compare( $this->wp_version, '4.1', '>=' ) ) { + return 'notice'; + } else { + return 'updated'; + } + } + } + + /** + * Display settings errors and remove those which have been displayed to avoid duplicate messages showing + * + * @since 2.5.0 + */ + protected function display_settings_errors() { + global $wp_settings_errors; + + settings_errors( 'tgmpa' ); + + foreach ( (array) $wp_settings_errors as $key => $details ) { + if ( 'tgmpa' === $details['setting'] ) { + unset( $wp_settings_errors[ $key ] ); + break; + } + } + } + + /** + * Register dismissal of admin notices. + * + * Acts on the dismiss link in the admin nag messages. + * If clicked, the admin notice disappears and will no longer be visible to this user. + * + * @since 2.1.0 + */ + public function dismiss() { + if ( isset( $_GET['tgmpa-dismiss'] ) && check_admin_referer( 'tgmpa-dismiss-' . get_current_user_id() ) ) { + update_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, 1 ); + } + } + + /** + * Add individual plugin to our collection of plugins. + * + * If the required keys are not set or the plugin has already + * been registered, the plugin is not added. + * + * @since 2.0.0 + * + * @param array|null $plugin Array of plugin arguments or null if invalid argument. + * @return null Return early if incorrect argument. + */ + public function register( $plugin ) { + if ( empty( $plugin['slug'] ) || empty( $plugin['name'] ) ) { + return; + } + + if ( empty( $plugin['slug'] ) || ! is_string( $plugin['slug'] ) || isset( $this->plugins[ $plugin['slug'] ] ) ) { + return; + } + + $defaults = array( + 'name' => '', // String + 'slug' => '', // String + 'source' => 'repo', // String + 'required' => false, // Boolean + 'version' => '', // String + 'force_activation' => false, // Boolean + 'force_deactivation' => false, // Boolean + 'external_url' => '', // String + 'is_callable' => '', // String|Array. + ); + + // Prepare the received data. + $plugin = wp_parse_args( $plugin, $defaults ); + + // Standardize the received slug. + $plugin['slug'] = $this->sanitize_key( $plugin['slug'] ); + + // Forgive users for using string versions of booleans or floats for version number. + $plugin['version'] = (string) $plugin['version']; + $plugin['source'] = empty( $plugin['source'] ) ? 'repo' : $plugin['source']; + $plugin['required'] = TGMPA_Utils::validate_bool( $plugin['required'] ); + $plugin['force_activation'] = TGMPA_Utils::validate_bool( $plugin['force_activation'] ); + $plugin['force_deactivation'] = TGMPA_Utils::validate_bool( $plugin['force_deactivation'] ); + + // Enrich the received data. + $plugin['file_path'] = $this->_get_plugin_basename_from_slug( $plugin['slug'] ); + $plugin['source_type'] = $this->get_plugin_source_type( $plugin['source'] ); + + // Set the class properties. + $this->plugins[ $plugin['slug'] ] = $plugin; + $this->sort_order[ $plugin['slug'] ] = $plugin['name']; + + // Should we add the force activation hook ? + if ( true === $plugin['force_activation'] ) { + $this->has_forced_activation = true; + } + + // Should we add the force deactivation hook ? + if ( true === $plugin['force_deactivation'] ) { + $this->has_forced_deactivation = true; + } + } + + /** + * Determine what type of source the plugin comes from. + * + * @since 2.5.0 + * + * @param string $source The source of the plugin as provided, either empty (= WP repo), a file path + * (= bundled) or an external URL. + * @return string 'repo', 'external', or 'bundled' + */ + protected function get_plugin_source_type( $source ) { + if ( 'repo' === $source || preg_match( self::WP_REPO_REGEX, $source ) ) { + return 'repo'; + } elseif ( preg_match( self::IS_URL_REGEX, $source ) ) { + return 'external'; + } else { + return 'bundled'; + } + } + + /** + * Sanitizes a string key. + * + * Near duplicate of WP Core `sanitize_key()`. The difference is that uppercase characters *are* + * allowed, so as not to break upgrade paths from non-standard bundled plugins using uppercase + * characters in the plugin directory path/slug. Silly them. + * + * @see https://developer.wordpress.org/reference/hooks/sanitize_key/ + * + * @since 2.5.0 + * + * @param string $key String key. + * @return string Sanitized key + */ + public function sanitize_key( $key ) { + $raw_key = $key; + $key = preg_replace( '`[^A-Za-z0-9_-]`', '', $key ); + + /** + * Filter a sanitized key string. + * + * @since 2.5.0 + * + * @param string $key Sanitized key. + * @param string $raw_key The key prior to sanitization. + */ + return apply_filters( 'tgmpa_sanitize_key', $key, $raw_key ); + } + + /** + * Amend default configuration settings. + * + * @since 2.0.0 + * + * @param array $config Array of config options to pass as class properties. + */ + public function config( $config ) { + $keys = array( + 'id', + 'default_path', + 'has_notices', + 'dismissable', + 'dismiss_msg', + 'menu', + 'parent_slug', + 'capability', + 'is_automatic', + 'message', + 'strings', + ); + + foreach ( $keys as $key ) { + if ( isset( $config[ $key ] ) ) { + if ( is_array( $config[ $key ] ) ) { + $this->$key = array_merge( $this->$key, $config[ $key ] ); + } else { + $this->$key = $config[ $key ]; + } + } + } + } + + /** + * Amend action link after plugin installation. + * + * @since 2.0.0 + * + * @param array $install_actions Existing array of actions. + * @return false|array Amended array of actions. + */ + public function actions( $install_actions ) { + // Remove action links on the TGMPA install page. + if ( $this->is_tgmpa_page() ) { + return false; + } + + return $install_actions; + } + + /** + * Flushes the plugins cache on theme switch to prevent stale entries + * from remaining in the plugin table. + * + * @since 2.4.0 + * + * @param bool $clear_update_cache Optional. Whether to clear the Plugin updates cache. + * Parameter added in v2.5.0. + */ + public function flush_plugins_cache( $clear_update_cache = true ) { + wp_clean_plugins_cache( $clear_update_cache ); + } + + /** + * Set file_path key for each installed plugin. + * + * @since 2.1.0 + * + * @param string $plugin_slug Optional. If set, only (re-)populates the file path for that specific plugin. + * Parameter added in v2.5.0. + */ + public function populate_file_path( $plugin_slug = '' ) { + if ( ! empty( $plugin_slug ) && is_string( $plugin_slug ) && isset( $this->plugins[ $plugin_slug ] ) ) { + $this->plugins[ $plugin_slug ]['file_path'] = $this->_get_plugin_basename_from_slug( $plugin_slug ); + } else { + // Add file_path key for all plugins. + foreach ( $this->plugins as $slug => $values ) { + $this->plugins[ $slug ]['file_path'] = $this->_get_plugin_basename_from_slug( $slug ); + } + } + } + + /** + * Helper function to extract the file path of the plugin file from the + * plugin slug, if the plugin is installed. + * + * @since 2.0.0 + * + * @param string $slug Plugin slug (typically folder name) as provided by the developer. + * @return string Either file path for plugin if installed, or just the plugin slug. + */ + protected function _get_plugin_basename_from_slug( $slug ) { + $keys = array_keys( $this->get_plugins() ); + + foreach ( $keys as $key ) { + if ( preg_match( '|^' . $slug . '/|', $key ) ) { + return $key; + } + } + + return $slug; + } + + /** + * Retrieve plugin data, given the plugin name. + * + * Loops through the registered plugins looking for $name. If it finds it, + * it returns the $data from that plugin. Otherwise, returns false. + * + * @since 2.1.0 + * + * @param string $name Name of the plugin, as it was registered. + * @param string $data Optional. Array key of plugin data to return. Default is slug. + * @return string|boolean Plugin slug if found, false otherwise. + */ + public function _get_plugin_data_from_name( $name, $data = 'slug' ) { + foreach ( $this->plugins as $values ) { + if ( $name === $values['name'] && isset( $values[ $data ] ) ) { + return $values[ $data ]; + } + } + + return false; + } + + /** + * Retrieve the download URL for a package. + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return string Plugin download URL or path to local file or empty string if undetermined. + */ + public function get_download_url( $slug ) { + $dl_source = ''; + + switch ( $this->plugins[ $slug ]['source_type'] ) { + case 'repo': + return $this->get_wp_repo_download_url( $slug ); + case 'external': + return $this->plugins[ $slug ]['source']; + case 'bundled': + return $this->default_path . $this->plugins[ $slug ]['source']; + } + + return $dl_source; // Should never happen. + } + + /** + * Retrieve the download URL for a WP repo package. + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return string Plugin download URL. + */ + protected function get_wp_repo_download_url( $slug ) { + $source = ''; + $api = $this->get_plugins_api( $slug ); + + if ( false !== $api && isset( $api->download_link ) ) { + $source = $api->download_link; + } + + return $source; + } + + /** + * Try to grab information from WordPress API. + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return object Plugins_api response object on success, WP_Error on failure. + */ + protected function get_plugins_api( $slug ) { + static $api = array(); // Cache received responses. + + if ( ! isset( $api[ $slug ] ) ) { + if ( ! function_exists( 'plugins_api' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; + } + + $response = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'sections' => false ) ) ); + + $api[ $slug ] = false; + + if ( is_wp_error( $response ) ) { + wp_die( esc_html( $this->strings['oops'] ) ); + } else { + $api[ $slug ] = $response; + } + } + + return $api[ $slug ]; + } + + /** + * Retrieve a link to a plugin information page. + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return string Fully formed html link to a plugin information page if available + * or the plugin name if not. + */ + public function get_info_link( $slug ) { + if ( ! empty( $this->plugins[ $slug ]['external_url'] ) && preg_match( self::IS_URL_REGEX, $this->plugins[ $slug ]['external_url'] ) ) { + $link = sprintf( + '%2$s', + esc_url( $this->plugins[ $slug ]['external_url'] ), + esc_html( $this->plugins[ $slug ]['name'] ) + ); + } elseif ( 'repo' === $this->plugins[ $slug ]['source_type'] ) { + $url = add_query_arg( + array( + 'tab' => 'plugin-information', + 'plugin' => urlencode( $slug ), + 'TB_iframe' => 'true', + 'width' => '640', + 'height' => '500', + ), + self_admin_url( 'plugin-install.php' ) + ); + + $link = sprintf( + '%2$s', + esc_url( $url ), + esc_html( $this->plugins[ $slug ]['name'] ) + ); + } else { + $link = esc_html( $this->plugins[ $slug ]['name'] ); // No hyperlink. + } + + return $link; + } + + /** + * Determine if we're on the TGMPA Install page. + * + * @since 2.1.0 + * + * @return boolean True when on the TGMPA page, false otherwise. + */ + protected function is_tgmpa_page() { + return isset( $_GET['page'] ) && $this->menu === $_GET['page']; + } + + /** + * Determine if we're on a WP Core installation/upgrade page. + * + * @since 2.6.0 + * + * @return boolean True when on a WP Core installation/upgrade page, false otherwise. + */ + protected function is_core_update_page() { + // Current screen is not always available, most notably on the customizer screen. + if ( ! function_exists( 'get_current_screen' ) ) { + return false; + } + + $screen = get_current_screen(); + + if ( 'update-core' === $screen->base ) { + // Core update screen. + return true; + } elseif ( 'plugins' === $screen->base && ! empty( $_POST['action'] ) ) { // WPCS: CSRF ok. + // Plugins bulk update screen. + return true; + } elseif ( 'update' === $screen->base && ! empty( $_POST['action'] ) ) { // WPCS: CSRF ok. + // Individual updates (ajax call). + return true; + } + + return false; + } + + /** + * Retrieve the URL to the TGMPA Install page. + * + * I.e. depending on the config settings passed something along the lines of: + * http://example.com/wp-admin/themes.php?page=tgmpa-install-plugins + * + * @since 2.5.0 + * + * @return string Properly encoded URL (not escaped). + */ + public function get_tgmpa_url() { + static $url; + + if ( ! isset( $url ) ) { + $parent = $this->parent_slug; + if ( false === strpos( $parent, '.php' ) ) { + $parent = 'admin.php'; + } + $url = add_query_arg( + array( + 'page' => urlencode( $this->menu ), + ), + self_admin_url( $parent ) + ); + } + + return $url; + } + + /** + * Retrieve the URL to the TGMPA Install page for a specific plugin status (view). + * + * I.e. depending on the config settings passed something along the lines of: + * http://example.com/wp-admin/themes.php?page=tgmpa-install-plugins&plugin_status=install + * + * @since 2.5.0 + * + * @param string $status Plugin status - either 'install', 'update' or 'activate'. + * @return string Properly encoded URL (not escaped). + */ + public function get_tgmpa_status_url( $status ) { + return add_query_arg( + array( + 'plugin_status' => urlencode( $status ), + ), + $this->get_tgmpa_url() + ); + } + + /** + * Determine whether there are open actions for plugins registered with TGMPA. + * + * @since 2.5.0 + * + * @return bool True if complete, i.e. no outstanding actions. False otherwise. + */ + public function is_tgmpa_complete() { + $complete = true; + foreach ( $this->plugins as $slug => $plugin ) { + if ( ! $this->is_plugin_active( $slug ) || false !== $this->does_plugin_have_update( $slug ) ) { + $complete = false; + break; + } + } + + return $complete; + } + + /** + * Check if a plugin is installed. Does not take must-use plugins into account. + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return bool True if installed, false otherwise. + */ + public function is_plugin_installed( $slug ) { + $installed_plugins = $this->get_plugins(); // Retrieve a list of all installed plugins (WP cached). + + return ( ! empty( $installed_plugins[ $this->plugins[ $slug ]['file_path'] ] ) ); + } + + /** + * Check if a plugin is active. + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return bool True if active, false otherwise. + */ + public function is_plugin_active( $slug ) { + return ( ( ! empty( $this->plugins[ $slug ]['is_callable'] ) && is_callable( $this->plugins[ $slug ]['is_callable'] ) ) || is_plugin_active( $this->plugins[ $slug ]['file_path'] ) ); + } + + /** + * Check if a plugin can be updated, i.e. if we have information on the minimum WP version required + * available, check whether the current install meets them. + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return bool True if OK to update, false otherwise. + */ + public function can_plugin_update( $slug ) { + // We currently can't get reliable info on non-WP-repo plugins - issue #380. + if ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) { + return true; + } + + $api = $this->get_plugins_api( $slug ); + + if ( false !== $api && isset( $api->requires ) ) { + return version_compare( $this->wp_version, $api->requires, '>=' ); + } + + // No usable info received from the plugins API, presume we can update. + return true; + } + + /** + * Check to see if the plugin is 'updatetable', i.e. installed, with an update available + * and no WP version requirements blocking it. + * + * @since 2.6.0 + * + * @param string $slug Plugin slug. + * @return bool True if OK to proceed with update, false otherwise. + */ + public function is_plugin_updatetable( $slug ) { + if ( ! $this->is_plugin_installed( $slug ) ) { + return false; + } else { + return ( false !== $this->does_plugin_have_update( $slug ) && $this->can_plugin_update( $slug ) ); + } + } + + /** + * Check if a plugin can be activated, i.e. is not currently active and meets the minimum + * plugin version requirements set in TGMPA (if any). + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return bool True if OK to activate, false otherwise. + */ + public function can_plugin_activate( $slug ) { + return ( ! $this->is_plugin_active( $slug ) && ! $this->does_plugin_require_update( $slug ) ); + } + + /** + * Retrieve the version number of an installed plugin. + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return string Version number as string or an empty string if the plugin is not installed + * or version unknown (plugins which don't comply with the plugin header standard). + */ + public function get_installed_version( $slug ) { + $installed_plugins = $this->get_plugins(); // Retrieve a list of all installed plugins (WP cached). + + if ( ! empty( $installed_plugins[ $this->plugins[ $slug ]['file_path'] ]['Version'] ) ) { + return $installed_plugins[ $this->plugins[ $slug ]['file_path'] ]['Version']; + } + + return ''; + } + + /** + * Check whether a plugin complies with the minimum version requirements. + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return bool True when a plugin needs to be updated, otherwise false. + */ + public function does_plugin_require_update( $slug ) { + $installed_version = $this->get_installed_version( $slug ); + $minimum_version = $this->plugins[ $slug ]['version']; + + return version_compare( $minimum_version, $installed_version, '>' ); + } + + /** + * Check whether there is an update available for a plugin. + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return false|string Version number string of the available update or false if no update available. + */ + public function does_plugin_have_update( $slug ) { + // Presume bundled and external plugins will point to a package which meets the minimum required version. + if ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) { + if ( $this->does_plugin_require_update( $slug ) ) { + return $this->plugins[ $slug ]['version']; + } + + return false; + } + + $repo_updates = get_site_transient( 'update_plugins' ); + + if ( isset( $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->new_version ) ) { + return $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->new_version; + } + + return false; + } + + /** + * Retrieve potential upgrade notice for a plugin. + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return string The upgrade notice or an empty string if no message was available or provided. + */ + public function get_upgrade_notice( $slug ) { + // We currently can't get reliable info on non-WP-repo plugins - issue #380. + if ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) { + return ''; + } + + $repo_updates = get_site_transient( 'update_plugins' ); + + if ( ! empty( $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->upgrade_notice ) ) { + return $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->upgrade_notice; + } + + return ''; + } + + /** + * Wrapper around the core WP get_plugins function, making sure it's actually available. + * + * @since 2.5.0 + * + * @param string $plugin_folder Optional. Relative path to single plugin folder. + * @return array Array of installed plugins with plugin information. + */ + public function get_plugins( $plugin_folder = '' ) { + if ( ! function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + return get_plugins( $plugin_folder ); + } + + /** + * Delete dismissable nag option when theme is switched. + * + * This ensures that the user(s) is/are again reminded via nag of required + * and/or recommended plugins if they re-activate the theme. + * + * @since 2.1.1 + */ + public function update_dismiss() { + delete_metadata( 'user', null, 'tgmpa_dismissed_notice_' . $this->id, null, true ); + } + + /** + * Forces plugin activation if the parameter 'force_activation' is + * set to true. + * + * This allows theme authors to specify certain plugins that must be + * active at all times while using the current theme. + * + * Please take special care when using this parameter as it has the + * potential to be harmful if not used correctly. Setting this parameter + * to true will not allow the specified plugin to be deactivated unless + * the user switches themes. + * + * @since 2.2.0 + */ + public function force_activation() { + foreach ( $this->plugins as $slug => $plugin ) { + if ( true === $plugin['force_activation'] ) { + if ( ! $this->is_plugin_installed( $slug ) ) { + // Oops, plugin isn't there so iterate to next condition. + continue; + } elseif ( $this->can_plugin_activate( $slug ) ) { + // There we go, activate the plugin. + activate_plugin( $plugin['file_path'] ); + } + } + } + } + + /** + * Forces plugin deactivation if the parameter 'force_deactivation' + * is set to true and adds the plugin to the 'recently active' plugins list. + * + * This allows theme authors to specify certain plugins that must be + * deactivated upon switching from the current theme to another. + * + * Please take special care when using this parameter as it has the + * potential to be harmful if not used correctly. + * + * @since 2.2.0 + */ + public function force_deactivation() { + $deactivated = array(); + + foreach ( $this->plugins as $slug => $plugin ) { + /* + * Only proceed forward if the parameter is set to true and plugin is active + * as a 'normal' (not must-use) plugin. + */ + if ( true === $plugin['force_deactivation'] && is_plugin_active( $plugin['file_path'] ) ) { + deactivate_plugins( $plugin['file_path'] ); + $deactivated[ $plugin['file_path'] ] = time(); + } + } + + if ( ! empty( $deactivated ) ) { + update_option( 'recently_activated', $deactivated + (array) get_option( 'recently_activated' ) ); + } + } + + /** + * Echo the current TGMPA version number to the page. + * + * @since 2.5.0 + */ + public function show_tgmpa_version() { + echo '

', + esc_html( + sprintf( + /* translators: %s: version number */ + __( 'TGMPA v%s', 'tgmpa' ), + self::TGMPA_VERSION + ) + ), + '

'; + } + + /** + * Returns the singleton instance of the class. + * + * @since 2.4.0 + * + * @return \TGM_Plugin_Activation The TGM_Plugin_Activation object. + */ + public static function get_instance() { + if ( ! isset( self::$instance ) && ! ( self::$instance instanceof self ) ) { + self::$instance = new self(); + } + + return self::$instance; + } + } + + if ( ! function_exists( 'load_tgm_plugin_activation' ) ) { + /** + * Ensure only one instance of the class is ever invoked. + * + * @since 2.5.0 + */ + function load_tgm_plugin_activation() { + $GLOBALS['tgmpa'] = TGM_Plugin_Activation::get_instance(); + } + } + + if ( did_action( 'plugins_loaded' ) ) { + load_tgm_plugin_activation(); + } else { + add_action( 'plugins_loaded', 'load_tgm_plugin_activation' ); + } +} + +if ( ! function_exists( 'tgmpa' ) ) { + /** + * Helper function to register a collection of required plugins. + * + * @since 2.0.0 + * @api + * + * @param array $plugins An array of plugin arrays. + * @param array $config Optional. An array of configuration values. + */ + function tgmpa( $plugins, $config = array() ) { + $instance = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); + + foreach ( $plugins as $plugin ) { + call_user_func( array( $instance, 'register' ), $plugin ); + } + + if ( ! empty( $config ) && is_array( $config ) ) { + // Send out notices for deprecated arguments passed. + if ( isset( $config['notices'] ) ) { + _deprecated_argument( __FUNCTION__, '2.2.0', 'The `notices` config parameter was renamed to `has_notices` in TGMPA 2.2.0. Please adjust your configuration.' ); + if ( ! isset( $config['has_notices'] ) ) { + $config['has_notices'] = $config['notices']; + } + } + + if ( isset( $config['parent_menu_slug'] ) ) { + _deprecated_argument( __FUNCTION__, '2.4.0', 'The `parent_menu_slug` config parameter was removed in TGMPA 2.4.0. In TGMPA 2.5.0 an alternative was (re-)introduced. Please adjust your configuration. For more information visit the website: http://tgmpluginactivation.com/configuration/#h-configuration-options.' ); + } + if ( isset( $config['parent_url_slug'] ) ) { + _deprecated_argument( __FUNCTION__, '2.4.0', 'The `parent_url_slug` config parameter was removed in TGMPA 2.4.0. In TGMPA 2.5.0 an alternative was (re-)introduced. Please adjust your configuration. For more information visit the website: http://tgmpluginactivation.com/configuration/#h-configuration-options.' ); + } + + call_user_func( array( $instance, 'config' ), $config ); + } + } +} + +/** + * WP_List_Table isn't always available. If it isn't available, + * we load it here. + * + * @since 2.2.0 + */ +if ( ! class_exists( 'WP_List_Table' ) ) { + require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; +} + +if ( ! class_exists( 'TGMPA_List_Table' ) ) { + + /** + * List table class for handling plugins. + * + * Extends the WP_List_Table class to provide a future-compatible + * way of listing out all required/recommended plugins. + * + * Gives users an interface similar to the Plugin Administration + * area with similar (albeit stripped down) capabilities. + * + * This class also allows for the bulk install of plugins. + * + * @since 2.2.0 + * + * @package TGM-Plugin-Activation + * @author Thomas Griffin + * @author Gary Jones + */ + class TGMPA_List_Table extends WP_List_Table { + /** + * TGMPA instance. + * + * @since 2.5.0 + * + * @var object + */ + protected $tgmpa; + + /** + * The currently chosen view. + * + * @since 2.5.0 + * + * @var string One of: 'all', 'install', 'update', 'activate' + */ + public $view_context = 'all'; + + /** + * The plugin counts for the various views. + * + * @since 2.5.0 + * + * @var array + */ + protected $view_totals = array( + 'all' => 0, + 'install' => 0, + 'update' => 0, + 'activate' => 0, + ); + + /** + * References parent constructor and sets defaults for class. + * + * @since 2.2.0 + */ + public function __construct() { + $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); + + parent::__construct( + array( + 'singular' => 'plugin', + 'plural' => 'plugins', + 'ajax' => false, + ) + ); + + if ( isset( $_REQUEST['plugin_status'] ) && in_array( $_REQUEST['plugin_status'], array( 'install', 'update', 'activate' ), true ) ) { + $this->view_context = sanitize_key( $_REQUEST['plugin_status'] ); + } + + add_filter( 'tgmpa_table_data_items', array( $this, 'sort_table_items' ) ); + } + + /** + * Get a list of CSS classes for the tag. + * + * Overruled to prevent the 'plural' argument from being added. + * + * @since 2.5.0 + * + * @return array CSS classnames. + */ + public function get_table_classes() { + return array( 'widefat', 'fixed' ); + } + + /** + * Gathers and renames all of our plugin information to be used by WP_List_Table to create our table. + * + * @since 2.2.0 + * + * @return array $table_data Information for use in table. + */ + protected function _gather_plugin_data() { + // Load thickbox for plugin links. + $this->tgmpa->admin_init(); + $this->tgmpa->thickbox(); + + // Categorize the plugins which have open actions. + $plugins = $this->categorize_plugins_to_views(); + + // Set the counts for the view links. + $this->set_view_totals( $plugins ); + + // Prep variables for use and grab list of all installed plugins. + $table_data = array(); + $i = 0; + + // Redirect to the 'all' view if no plugins were found for the selected view context. + if ( empty( $plugins[ $this->view_context ] ) ) { + $this->view_context = 'all'; + } + + foreach ( $plugins[ $this->view_context ] as $slug => $plugin ) { + $table_data[ $i ]['sanitized_plugin'] = $plugin['name']; + $table_data[ $i ]['slug'] = $slug; + $table_data[ $i ]['plugin'] = '' . $this->tgmpa->get_info_link( $slug ) . ''; + $table_data[ $i ]['source'] = $this->get_plugin_source_type_text( $plugin['source_type'] ); + $table_data[ $i ]['type'] = $this->get_plugin_advise_type_text( $plugin['required'] ); + $table_data[ $i ]['status'] = $this->get_plugin_status_text( $slug ); + $table_data[ $i ]['installed_version'] = $this->tgmpa->get_installed_version( $slug ); + $table_data[ $i ]['minimum_version'] = $plugin['version']; + $table_data[ $i ]['available_version'] = $this->tgmpa->does_plugin_have_update( $slug ); + + // Prep the upgrade notice info. + $upgrade_notice = $this->tgmpa->get_upgrade_notice( $slug ); + if ( ! empty( $upgrade_notice ) ) { + $table_data[ $i ]['upgrade_notice'] = $upgrade_notice; + + add_action( "tgmpa_after_plugin_row_{$slug}", array( $this, 'wp_plugin_update_row' ), 10, 2 ); + } + + $table_data[ $i ] = apply_filters( 'tgmpa_table_data_item', $table_data[ $i ], $plugin ); + + $i++; + } + + return $table_data; + } + + /** + * Categorize the plugins which have open actions into views for the TGMPA page. + * + * @since 2.5.0 + */ + protected function categorize_plugins_to_views() { + $plugins = array( + 'all' => array(), // Meaning: all plugins which still have open actions. + 'install' => array(), + 'update' => array(), + 'activate' => array(), + ); + + foreach ( $this->tgmpa->plugins as $slug => $plugin ) { + if ( $this->tgmpa->is_plugin_active( $slug ) && false === $this->tgmpa->does_plugin_have_update( $slug ) ) { + // No need to display plugins if they are installed, up-to-date and active. + continue; + } else { + $plugins['all'][ $slug ] = $plugin; + + if ( ! $this->tgmpa->is_plugin_installed( $slug ) ) { + $plugins['install'][ $slug ] = $plugin; + } else { + if ( false !== $this->tgmpa->does_plugin_have_update( $slug ) ) { + $plugins['update'][ $slug ] = $plugin; + } + + if ( $this->tgmpa->can_plugin_activate( $slug ) ) { + $plugins['activate'][ $slug ] = $plugin; + } + } + } + } + + return $plugins; + } + + /** + * Set the counts for the view links. + * + * @since 2.5.0 + * + * @param array $plugins Plugins order by view. + */ + protected function set_view_totals( $plugins ) { + foreach ( $plugins as $type => $list ) { + $this->view_totals[ $type ] = count( $list ); + } + } + + /** + * Get the plugin required/recommended text string. + * + * @since 2.5.0 + * + * @param string $required Plugin required setting. + * @return string + */ + protected function get_plugin_advise_type_text( $required ) { + if ( true === $required ) { + return __( 'Required', 'tgmpa' ); + } + + return __( 'Recommended', 'tgmpa' ); + } + + /** + * Get the plugin source type text string. + * + * @since 2.5.0 + * + * @param string $type Plugin type. + * @return string + */ + protected function get_plugin_source_type_text( $type ) { + $string = ''; + + switch ( $type ) { + case 'repo': + $string = __( 'WordPress Repository', 'tgmpa' ); + break; + case 'external': + $string = __( 'External Source', 'tgmpa' ); + break; + case 'bundled': + $string = __( 'Pre-Packaged', 'tgmpa' ); + break; + } + + return $string; + } + + /** + * Determine the plugin status message. + * + * @since 2.5.0 + * + * @param string $slug Plugin slug. + * @return string + */ + protected function get_plugin_status_text( $slug ) { + if ( ! $this->tgmpa->is_plugin_installed( $slug ) ) { + return __( 'Not Installed', 'tgmpa' ); + } + + if ( ! $this->tgmpa->is_plugin_active( $slug ) ) { + $install_status = __( 'Installed But Not Activated', 'tgmpa' ); + } else { + $install_status = __( 'Active', 'tgmpa' ); + } + + $update_status = ''; + + if ( $this->tgmpa->does_plugin_require_update( $slug ) && false === $this->tgmpa->does_plugin_have_update( $slug ) ) { + $update_status = __( 'Required Update not Available', 'tgmpa' ); + + } elseif ( $this->tgmpa->does_plugin_require_update( $slug ) ) { + $update_status = __( 'Requires Update', 'tgmpa' ); + + } elseif ( false !== $this->tgmpa->does_plugin_have_update( $slug ) ) { + $update_status = __( 'Update recommended', 'tgmpa' ); + } + + if ( '' === $update_status ) { + return $install_status; + } + + return sprintf( + /* translators: 1: install status, 2: update status */ + _x( '%1$s, %2$s', 'Install/Update Status', 'tgmpa' ), + $install_status, + $update_status + ); + } + + /** + * Sort plugins by Required/Recommended type and by alphabetical plugin name within each type. + * + * @since 2.5.0 + * + * @param array $items Prepared table items. + * @return array Sorted table items. + */ + public function sort_table_items( $items ) { + $type = array(); + $name = array(); + + foreach ( $items as $i => $plugin ) { + $type[ $i ] = $plugin['type']; // Required / recommended. + $name[ $i ] = $plugin['sanitized_plugin']; + } + + array_multisort( $type, SORT_DESC, $name, SORT_ASC, $items ); + + return $items; + } + + /** + * Get an associative array ( id => link ) of the views available on this table. + * + * @since 2.5.0 + * + * @return array + */ + public function get_views() { + $status_links = array(); + + foreach ( $this->view_totals as $type => $count ) { + if ( $count < 1 ) { + continue; + } + + switch ( $type ) { + case 'all': + /* translators: 1: number of plugins. */ + $text = _nx( 'All (%s)', 'All (%s)', $count, 'plugins', 'tgmpa' ); + break; + case 'install': + /* translators: 1: number of plugins. */ + $text = _n( 'To Install (%s)', 'To Install (%s)', $count, 'tgmpa' ); + break; + case 'update': + /* translators: 1: number of plugins. */ + $text = _n( 'Update Available (%s)', 'Update Available (%s)', $count, 'tgmpa' ); + break; + case 'activate': + /* translators: 1: number of plugins. */ + $text = _n( 'To Activate (%s)', 'To Activate (%s)', $count, 'tgmpa' ); + break; + default: + $text = ''; + break; + } + + if ( ! empty( $text ) ) { + + $status_links[ $type ] = sprintf( + '%s', + esc_url( $this->tgmpa->get_tgmpa_status_url( $type ) ), + ( $type === $this->view_context ) ? ' class="current"' : '', + sprintf( $text, number_format_i18n( $count ) ) + ); + } + } + + return $status_links; + } + + /** + * Create default columns to display important plugin information + * like type, action and status. + * + * @since 2.2.0 + * + * @param array $item Array of item data. + * @param string $column_name The name of the column. + * @return string + */ + public function column_default( $item, $column_name ) { + return $item[ $column_name ]; + } + + /** + * Required for bulk installing. + * + * Adds a checkbox for each plugin. + * + * @since 2.2.0 + * + * @param array $item Array of item data. + * @return string The input checkbox with all necessary info. + */ + public function column_cb( $item ) { + return sprintf( + '', + esc_attr( $this->_args['singular'] ), + esc_attr( $item['slug'] ), + esc_attr( $item['sanitized_plugin'] ) + ); + } + + /** + * Create default title column along with the action links. + * + * @since 2.2.0 + * + * @param array $item Array of item data. + * @return string The plugin name and action links. + */ + public function column_plugin( $item ) { + return sprintf( + '%1$s %2$s', + $item['plugin'], + $this->row_actions( $this->get_row_actions( $item ), true ) + ); + } + + /** + * Create version information column. + * + * @since 2.5.0 + * + * @param array $item Array of item data. + * @return string HTML-formatted version information. + */ + public function column_version( $item ) { + $output = array(); + + if ( $this->tgmpa->is_plugin_installed( $item['slug'] ) ) { + $installed = ! empty( $item['installed_version'] ) ? $item['installed_version'] : _x( 'unknown', 'as in: "version nr unknown"', 'tgmpa' ); + + $color = ''; + if ( ! empty( $item['minimum_version'] ) && $this->tgmpa->does_plugin_require_update( $item['slug'] ) ) { + $color = ' color: #ff0000; font-weight: bold;'; + } + + $output[] = sprintf( + '

%2$s' . __( 'Installed version:', 'tgmpa' ) . '

', + $color, + $installed + ); + } + + if ( ! empty( $item['minimum_version'] ) ) { + $output[] = sprintf( + '

%1$s' . __( 'Minimum required version:', 'tgmpa' ) . '

', + $item['minimum_version'] + ); + } + + if ( ! empty( $item['available_version'] ) ) { + $color = ''; + if ( ! empty( $item['minimum_version'] ) && version_compare( $item['available_version'], $item['minimum_version'], '>=' ) ) { + $color = ' color: #71C671; font-weight: bold;'; + } + + $output[] = sprintf( + '

%2$s' . __( 'Available version:', 'tgmpa' ) . '

', + $color, + $item['available_version'] + ); + } + + if ( empty( $output ) ) { + return ' '; // Let's not break the table layout. + } else { + return implode( "\n", $output ); + } + } + + /** + * Sets default message within the plugins table if no plugins + * are left for interaction. + * + * Hides the menu item to prevent the user from clicking and + * getting a permissions error. + * + * @since 2.2.0 + */ + public function no_items() { + echo esc_html__( 'No plugins to install, update or activate.', 'tgmpa' ) . ' ' . esc_html__( 'Return to the Dashboard', 'tgmpa' ) . ''; + echo ''; + } + + /** + * Output all the column information within the table. + * + * @since 2.2.0 + * + * @return array $columns The column names. + */ + public function get_columns() { + $columns = array( + 'cb' => '', + 'plugin' => __( 'Plugin', 'tgmpa' ), + 'source' => __( 'Source', 'tgmpa' ), + 'type' => __( 'Type', 'tgmpa' ), + ); + + if ( 'all' === $this->view_context || 'update' === $this->view_context ) { + $columns['version'] = __( 'Version', 'tgmpa' ); + $columns['status'] = __( 'Status', 'tgmpa' ); + } + + return apply_filters( 'tgmpa_table_columns', $columns ); + } + + /** + * Get name of default primary column + * + * @since 2.5.0 / WP 4.3+ compatibility + * @access protected + * + * @return string + */ + protected function get_default_primary_column_name() { + return 'plugin'; + } + + /** + * Get the name of the primary column. + * + * @since 2.5.0 / WP 4.3+ compatibility + * @access protected + * + * @return string The name of the primary column. + */ + protected function get_primary_column_name() { + if ( method_exists( 'WP_List_Table', 'get_primary_column_name' ) ) { + return parent::get_primary_column_name(); + } else { + return $this->get_default_primary_column_name(); + } + } + + /** + * Get the actions which are relevant for a specific plugin row. + * + * @since 2.5.0 + * + * @param array $item Array of item data. + * @return array Array with relevant action links. + */ + protected function get_row_actions( $item ) { + $actions = array(); + $action_links = array(); + + // Display the 'Install' action link if the plugin is not yet available. + if ( ! $this->tgmpa->is_plugin_installed( $item['slug'] ) ) { + /* translators: %2$s: plugin name in screen reader markup */ + $actions['install'] = __( 'Install %2$s', 'tgmpa' ); + } else { + // Display the 'Update' action link if an update is available and WP complies with plugin minimum. + if ( false !== $this->tgmpa->does_plugin_have_update( $item['slug'] ) && $this->tgmpa->can_plugin_update( $item['slug'] ) ) { + /* translators: %2$s: plugin name in screen reader markup */ + $actions['update'] = __( 'Update %2$s', 'tgmpa' ); + } + + // Display the 'Activate' action link, but only if the plugin meets the minimum version. + if ( $this->tgmpa->can_plugin_activate( $item['slug'] ) ) { + /* translators: %2$s: plugin name in screen reader markup */ + $actions['activate'] = __( 'Activate %2$s', 'tgmpa' ); + } + } + + // Create the actual links. + foreach ( $actions as $action => $text ) { + $nonce_url = wp_nonce_url( + add_query_arg( + array( + 'plugin' => urlencode( $item['slug'] ), + 'tgmpa-' . $action => $action . '-plugin', + ), + $this->tgmpa->get_tgmpa_url() + ), + 'tgmpa-' . $action, + 'tgmpa-nonce' + ); + + $action_links[ $action ] = sprintf( + '' . esc_html( $text ) . '', // $text contains the second placeholder. + esc_url( $nonce_url ), + '' . esc_html( $item['sanitized_plugin'] ) . '' + ); + } + + $prefix = ( defined( 'WP_NETWORK_ADMIN' ) && WP_NETWORK_ADMIN ) ? 'network_admin_' : ''; + return apply_filters( "tgmpa_{$prefix}plugin_action_links", array_filter( $action_links ), $item['slug'], $item, $this->view_context ); + } + + /** + * Generates content for a single row of the table. + * + * @since 2.5.0 + * + * @param object $item The current item. + */ + public function single_row( $item ) { + parent::single_row( $item ); + + /** + * Fires after each specific row in the TGMPA Plugins list table. + * + * The dynamic portion of the hook name, `$item['slug']`, refers to the slug + * for the plugin. + * + * @since 2.5.0 + */ + do_action( "tgmpa_after_plugin_row_{$item['slug']}", $item['slug'], $item, $this->view_context ); + } + + /** + * Show the upgrade notice below a plugin row if there is one. + * + * @since 2.5.0 + * + * @see /wp-admin/includes/update.php + * + * @param string $slug Plugin slug. + * @param array $item The information available in this table row. + * @return null Return early if upgrade notice is empty. + */ + public function wp_plugin_update_row( $slug, $item ) { + if ( empty( $item['upgrade_notice'] ) ) { + return; + } + + echo ' + + + '; + } + + /** + * Extra controls to be displayed between bulk actions and pagination. + * + * @since 2.5.0 + * + * @param string $which 'top' or 'bottom' table navigation. + */ + public function extra_tablenav( $which ) { + if ( 'bottom' === $which ) { + $this->tgmpa->show_tgmpa_version(); + } + } + + /** + * Defines the bulk actions for handling registered plugins. + * + * @since 2.2.0 + * + * @return array $actions The bulk actions for the plugin install table. + */ + public function get_bulk_actions() { + + $actions = array(); + + if ( 'update' !== $this->view_context && 'activate' !== $this->view_context ) { + if ( current_user_can( 'install_plugins' ) ) { + $actions['tgmpa-bulk-install'] = __( 'Install', 'tgmpa' ); + } + } + + if ( 'install' !== $this->view_context ) { + if ( current_user_can( 'update_plugins' ) ) { + $actions['tgmpa-bulk-update'] = __( 'Update', 'tgmpa' ); + } + if ( current_user_can( 'activate_plugins' ) ) { + $actions['tgmpa-bulk-activate'] = __( 'Activate', 'tgmpa' ); + } + } + + return $actions; + } + + /** + * Processes bulk installation and activation actions. + * + * The bulk installation process looks for the $_POST information and passes that + * through if a user has to use WP_Filesystem to enter their credentials. + * + * @since 2.2.0 + */ + public function process_bulk_actions() { + // Bulk installation process. + if ( 'tgmpa-bulk-install' === $this->current_action() || 'tgmpa-bulk-update' === $this->current_action() ) { + + check_admin_referer( 'bulk-' . $this->_args['plural'] ); + + $install_type = 'install'; + if ( 'tgmpa-bulk-update' === $this->current_action() ) { + $install_type = 'update'; + } + + $plugins_to_install = array(); + + // Did user actually select any plugins to install/update ? + if ( empty( $_POST['plugin'] ) ) { + if ( 'install' === $install_type ) { + $message = __( 'No plugins were selected to be installed. No action taken.', 'tgmpa' ); + } else { + $message = __( 'No plugins were selected to be updated. No action taken.', 'tgmpa' ); + } + + echo '

', esc_html( $message ), '

'; + + return false; + } + + if ( is_array( $_POST['plugin'] ) ) { + $plugins_to_install = (array) $_POST['plugin']; + } elseif ( is_string( $_POST['plugin'] ) ) { + // Received via Filesystem page - un-flatten array (WP bug #19643). + $plugins_to_install = explode( ',', $_POST['plugin'] ); + } + + // Sanitize the received input. + $plugins_to_install = array_map( 'urldecode', $plugins_to_install ); + $plugins_to_install = array_map( array( $this->tgmpa, 'sanitize_key' ), $plugins_to_install ); + + // Validate the received input. + foreach ( $plugins_to_install as $key => $slug ) { + // Check if the plugin was registered with TGMPA and remove if not. + if ( ! isset( $this->tgmpa->plugins[ $slug ] ) ) { + unset( $plugins_to_install[ $key ] ); + continue; + } + + // For install: make sure this is a plugin we *can* install and not one already installed. + if ( 'install' === $install_type && true === $this->tgmpa->is_plugin_installed( $slug ) ) { + unset( $plugins_to_install[ $key ] ); + } + + // For updates: make sure this is a plugin we *can* update (update available and WP version ok). + if ( 'update' === $install_type && false === $this->tgmpa->is_plugin_updatetable( $slug ) ) { + unset( $plugins_to_install[ $key ] ); + } + } + + // No need to proceed further if we have no plugins to handle. + if ( empty( $plugins_to_install ) ) { + if ( 'install' === $install_type ) { + $message = __( 'No plugins are available to be installed at this time.', 'tgmpa' ); + } else { + $message = __( 'No plugins are available to be updated at this time.', 'tgmpa' ); + } + + echo '

', esc_html( $message ), '

'; + + return false; + } + + // Pass all necessary information if WP_Filesystem is needed. + $url = wp_nonce_url( + $this->tgmpa->get_tgmpa_url(), + 'bulk-' . $this->_args['plural'] + ); + + // Give validated data back to $_POST which is the only place the filesystem looks for extra fields. + $_POST['plugin'] = implode( ',', $plugins_to_install ); // Work around for WP bug #19643. + + $method = ''; // Leave blank so WP_Filesystem can populate it as necessary. + $fields = array_keys( $_POST ); // Extra fields to pass to WP_Filesystem. + + if ( false === ( $creds = request_filesystem_credentials( esc_url_raw( $url ), $method, false, false, $fields ) ) ) { + return true; // Stop the normal page form from displaying, credential request form will be shown. + } + + // Now we have some credentials, setup WP_Filesystem. + if ( ! WP_Filesystem( $creds ) ) { + // Our credentials were no good, ask the user for them again. + request_filesystem_credentials( esc_url_raw( $url ), $method, true, false, $fields ); + + return true; + } + + /* If we arrive here, we have the filesystem */ + + // Store all information in arrays since we are processing a bulk installation. + $names = array(); + $sources = array(); // Needed for installs. + $file_paths = array(); // Needed for upgrades. + $to_inject = array(); // Information to inject into the update_plugins transient. + + // Prepare the data for validated plugins for the install/upgrade. + foreach ( $plugins_to_install as $slug ) { + $name = $this->tgmpa->plugins[ $slug ]['name']; + $source = $this->tgmpa->get_download_url( $slug ); + + if ( ! empty( $name ) && ! empty( $source ) ) { + $names[] = $name; + + switch ( $install_type ) { + + case 'install': + $sources[] = $source; + break; + + case 'update': + $file_paths[] = $this->tgmpa->plugins[ $slug ]['file_path']; + $to_inject[ $slug ] = $this->tgmpa->plugins[ $slug ]; + $to_inject[ $slug ]['source'] = $source; + break; + } + } + } + unset( $slug, $name, $source ); + + // Create a new instance of TGMPA_Bulk_Installer. + $installer = new TGMPA_Bulk_Installer( + new TGMPA_Bulk_Installer_Skin( + array( + 'url' => esc_url_raw( $this->tgmpa->get_tgmpa_url() ), + 'nonce' => 'bulk-' . $this->_args['plural'], + 'names' => $names, + 'install_type' => $install_type, + ) + ) + ); + + // Wrap the install process with the appropriate HTML. + echo '
', + '

', esc_html( get_admin_page_title() ), '

+
'; + + // Process the bulk installation submissions. + add_filter( 'upgrader_source_selection', array( $this->tgmpa, 'maybe_adjust_source_dir' ), 1, 3 ); + + if ( 'tgmpa-bulk-update' === $this->current_action() ) { + // Inject our info into the update transient. + $this->tgmpa->inject_update_info( $to_inject ); + + $installer->bulk_upgrade( $file_paths ); + } else { + $installer->bulk_install( $sources ); + } + + remove_filter( 'upgrader_source_selection', array( $this->tgmpa, 'maybe_adjust_source_dir' ), 1 ); + + echo '
'; + + return true; + } + + // Bulk activation process. + if ( 'tgmpa-bulk-activate' === $this->current_action() ) { + check_admin_referer( 'bulk-' . $this->_args['plural'] ); + + // Did user actually select any plugins to activate ? + if ( empty( $_POST['plugin'] ) ) { + echo '

', esc_html__( 'No plugins were selected to be activated. No action taken.', 'tgmpa' ), '

'; + + return false; + } + + // Grab plugin data from $_POST. + $plugins = array(); + if ( isset( $_POST['plugin'] ) ) { + $plugins = array_map( 'urldecode', (array) $_POST['plugin'] ); + $plugins = array_map( array( $this->tgmpa, 'sanitize_key' ), $plugins ); + } + + $plugins_to_activate = array(); + $plugin_names = array(); + + // Grab the file paths for the selected & inactive plugins from the registration array. + foreach ( $plugins as $slug ) { + if ( $this->tgmpa->can_plugin_activate( $slug ) ) { + $plugins_to_activate[] = $this->tgmpa->plugins[ $slug ]['file_path']; + $plugin_names[] = $this->tgmpa->plugins[ $slug ]['name']; + } + } + unset( $slug ); + + // Return early if there are no plugins to activate. + if ( empty( $plugins_to_activate ) ) { + echo '

', esc_html__( 'No plugins are available to be activated at this time.', 'tgmpa' ), '

'; + + return false; + } + + // Now we are good to go - let's start activating plugins. + $activate = activate_plugins( $plugins_to_activate ); + + if ( is_wp_error( $activate ) ) { + echo '

', wp_kses_post( $activate->get_error_message() ), '

'; + } else { + $count = count( $plugin_names ); // Count so we can use _n function. + $plugin_names = array_map( array( 'TGMPA_Utils', 'wrap_in_strong' ), $plugin_names ); + $last_plugin = array_pop( $plugin_names ); // Pop off last name to prep for readability. + $imploded = empty( $plugin_names ) ? $last_plugin : ( implode( ', ', $plugin_names ) . ' ' . esc_html_x( 'and', 'plugin A *and* plugin B', 'tgmpa' ) . ' ' . $last_plugin ); + + printf( // WPCS: xss ok. + '

%1$s %2$s.

', + esc_html( _n( 'The following plugin was activated successfully:', 'The following plugins were activated successfully:', $count, 'tgmpa' ) ), + $imploded + ); + + // Update recently activated plugins option. + $recent = (array) get_option( 'recently_activated' ); + foreach ( $plugins_to_activate as $plugin => $time ) { + if ( isset( $recent[ $plugin ] ) ) { + unset( $recent[ $plugin ] ); + } + } + update_option( 'recently_activated', $recent ); + } + + unset( $_POST ); // Reset the $_POST variable in case user wants to perform one action after another. + + return true; + } + + return false; + } + + /** + * Prepares all of our information to be outputted into a usable table. + * + * @since 2.2.0 + */ + public function prepare_items() { + $columns = $this->get_columns(); // Get all necessary column information. + $hidden = array(); // No columns to hide, but we must set as an array. + $sortable = array(); // No reason to make sortable columns. + $primary = $this->get_primary_column_name(); // Column which has the row actions. + $this->_column_headers = array( $columns, $hidden, $sortable, $primary ); // Get all necessary column headers. + + // Process our bulk activations here. + if ( 'tgmpa-bulk-activate' === $this->current_action() ) { + $this->process_bulk_actions(); + } + + // Store all of our plugin data into $items array so WP_List_Table can use it. + $this->items = apply_filters( 'tgmpa_table_data_items', $this->_gather_plugin_data() ); + } + + /* *********** DEPRECATED METHODS *********** */ + + /** + * Retrieve plugin data, given the plugin name. + * + * @since 2.2.0 + * @deprecated 2.5.0 use {@see TGM_Plugin_Activation::_get_plugin_data_from_name()} instead. + * @see TGM_Plugin_Activation::_get_plugin_data_from_name() + * + * @param string $name Name of the plugin, as it was registered. + * @param string $data Optional. Array key of plugin data to return. Default is slug. + * @return string|boolean Plugin slug if found, false otherwise. + */ + protected function _get_plugin_data_from_name( $name, $data = 'slug' ) { + _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'TGM_Plugin_Activation::_get_plugin_data_from_name()' ); + + return $this->tgmpa->_get_plugin_data_from_name( $name, $data ); + } + } +} + + +if ( ! class_exists( 'TGM_Bulk_Installer' ) ) { + + /** + * Hack: Prevent TGMPA v2.4.1- bulk installer class from being loaded if 2.4.1- is loaded after 2.5+. + * + * @since 2.5.2 + * + * {@internal The TGMPA_Bulk_Installer class was originally called TGM_Bulk_Installer. + * For more information, see that class.}} + */ + class TGM_Bulk_Installer { + } +} +if ( ! class_exists( 'TGM_Bulk_Installer_Skin' ) ) { + + /** + * Hack: Prevent TGMPA v2.4.1- bulk installer skin class from being loaded if 2.4.1- is loaded after 2.5+. + * + * @since 2.5.2 + * + * {@internal The TGMPA_Bulk_Installer_Skin class was originally called TGM_Bulk_Installer_Skin. + * For more information, see that class.}} + */ + class TGM_Bulk_Installer_Skin { + } +} + +/** + * The WP_Upgrader file isn't always available. If it isn't available, + * we load it here. + * + * We check to make sure no action or activation keys are set so that WordPress + * does not try to re-include the class when processing upgrades or installs outside + * of the class. + * + * @since 2.2.0 + */ +add_action( 'admin_init', 'tgmpa_load_bulk_installer' ); +if ( ! function_exists( 'tgmpa_load_bulk_installer' ) ) { + /** + * Load bulk installer + */ + function tgmpa_load_bulk_installer() { + // Silently fail if 2.5+ is loaded *after* an older version. + if ( ! isset( $GLOBALS['tgmpa'] ) ) { + return; + } + + // Get TGMPA class instance. + $tgmpa_instance = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); + + if ( isset( $_GET['page'] ) && $tgmpa_instance->menu === $_GET['page'] ) { + if ( ! class_exists( 'Plugin_Upgrader', false ) ) { + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + } + + if ( ! class_exists( 'TGMPA_Bulk_Installer' ) ) { + + /** + * Installer class to handle bulk plugin installations. + * + * Extends WP_Upgrader and customizes to suit the installation of multiple + * plugins. + * + * @since 2.2.0 + * + * {@internal Since 2.5.0 the class is an extension of Plugin_Upgrader rather than WP_Upgrader.}} + * {@internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer to TGMPA_Bulk_Installer. + * This was done to prevent backward compatibility issues with v2.3.6.}} + * + * @package TGM-Plugin-Activation + * @author Thomas Griffin + * @author Gary Jones + */ + class TGMPA_Bulk_Installer extends Plugin_Upgrader { + /** + * Holds result of bulk plugin installation. + * + * @since 2.2.0 + * + * @var string + */ + public $result; + + /** + * Flag to check if bulk installation is occurring or not. + * + * @since 2.2.0 + * + * @var boolean + */ + public $bulk = false; + + /** + * TGMPA instance + * + * @since 2.5.0 + * + * @var object + */ + protected $tgmpa; + + /** + * Whether or not the destination directory needs to be cleared ( = on update). + * + * @since 2.5.0 + * + * @var bool + */ + protected $clear_destination = false; + + /** + * References parent constructor and sets defaults for class. + * + * @since 2.2.0 + * + * @param \Bulk_Upgrader_Skin|null $skin Installer skin. + */ + public function __construct( $skin = null ) { + // Get TGMPA class instance. + $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); + + parent::__construct( $skin ); + + if ( isset( $this->skin->options['install_type'] ) && 'update' === $this->skin->options['install_type'] ) { + $this->clear_destination = true; + } + + if ( $this->tgmpa->is_automatic ) { + $this->activate_strings(); + } + + add_action( 'upgrader_process_complete', array( $this->tgmpa, 'populate_file_path' ) ); + } + + /** + * Sets the correct activation strings for the installer skin to use. + * + * @since 2.2.0 + */ + public function activate_strings() { + $this->strings['activation_failed'] = __( 'Plugin activation failed.', 'tgmpa' ); + $this->strings['activation_success'] = __( 'Plugin activated successfully.', 'tgmpa' ); + } + + /** + * Performs the actual installation of each plugin. + * + * @since 2.2.0 + * + * @see WP_Upgrader::run() + * + * @param array $options The installation config options. + * @return null|array Return early if error, array of installation data on success. + */ + public function run( $options ) { + $result = parent::run( $options ); + + // Reset the strings in case we changed one during automatic activation. + if ( $this->tgmpa->is_automatic ) { + if ( 'update' === $this->skin->options['install_type'] ) { + $this->upgrade_strings(); + } else { + $this->install_strings(); + } + } + + return $result; + } + + /** + * Processes the bulk installation of plugins. + * + * @since 2.2.0 + * + * {@internal This is basically a near identical copy of the WP Core + * Plugin_Upgrader::bulk_upgrade() method, with minor adjustments to deal with + * new installs instead of upgrades. + * For ease of future synchronizations, the adjustments are clearly commented, but no other + * comments are added. Code style has been made to comply.}} + * + * @see Plugin_Upgrader::bulk_upgrade() + * @see https://core.trac.wordpress.org/browser/tags/4.2.1/src/wp-admin/includes/class-wp-upgrader.php#L838 + * (@internal Last synced: Dec 31st 2015 against https://core.trac.wordpress.org/browser/trunk?rev=36134}} + * + * @param array $plugins The plugin sources needed for installation. + * @param array $args Arbitrary passed extra arguments. + * @return array|false Install confirmation messages on success, false on failure. + */ + public function bulk_install( $plugins, $args = array() ) { + // [TGMPA + ] Hook auto-activation in. + add_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); + + $defaults = array( + 'clear_update_cache' => true, + ); + $parsed_args = wp_parse_args( $args, $defaults ); + + $this->init(); + $this->bulk = true; + + $this->install_strings(); // [TGMPA + ] adjusted. + + /* [TGMPA - ] $current = get_site_transient( 'update_plugins' ); */ + + /* [TGMPA - ] add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4); */ + + $this->skin->header(); + + // Connect to the Filesystem first. + $res = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) ); + if ( ! $res ) { + $this->skin->footer(); + return false; + } + + $this->skin->bulk_header(); + + /* + * Only start maintenance mode if: + * - running Multisite and there are one or more plugins specified, OR + * - a plugin with an update available is currently active. + * @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible. + */ + $maintenance = ( is_multisite() && ! empty( $plugins ) ); + + /* + [TGMPA - ] + foreach ( $plugins as $plugin ) + $maintenance = $maintenance || ( is_plugin_active( $plugin ) && isset( $current->response[ $plugin] ) ); + */ + if ( $maintenance ) { + $this->maintenance_mode( true ); + } + + $results = array(); + + $this->update_count = count( $plugins ); + $this->update_current = 0; + foreach ( $plugins as $plugin ) { + $this->update_current++; + + /* + [TGMPA - ] + $this->skin->plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true); + + if ( !isset( $current->response[ $plugin ] ) ) { + $this->skin->set_result('up_to_date'); + $this->skin->before(); + $this->skin->feedback('up_to_date'); + $this->skin->after(); + $results[$plugin] = true; + continue; + } + + // Get the URL to the zip file. + $r = $current->response[ $plugin ]; + + $this->skin->plugin_active = is_plugin_active($plugin); + */ + + $result = $this->run( + array( + 'package' => $plugin, // [TGMPA + ] adjusted. + 'destination' => WP_PLUGIN_DIR, + 'clear_destination' => false, // [TGMPA + ] adjusted. + 'clear_working' => true, + 'is_multi' => true, + 'hook_extra' => array( + 'plugin' => $plugin, + ), + ) + ); + + $results[ $plugin ] = $this->result; + + // Prevent credentials auth screen from displaying multiple times. + if ( false === $result ) { + break; + } + } //end foreach $plugins + + $this->maintenance_mode( false ); + + /** + * Fires when the bulk upgrader process is complete. + * + * @since WP 3.6.0 / TGMPA 2.5.0 + * + * @param Plugin_Upgrader $this Plugin_Upgrader instance. In other contexts, $this, might + * be a Theme_Upgrader or Core_Upgrade instance. + * @param array $data { + * Array of bulk item update data. + * + * @type string $action Type of action. Default 'update'. + * @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'. + * @type bool $bulk Whether the update process is a bulk update. Default true. + * @type array $packages Array of plugin, theme, or core packages to update. + * } + */ + do_action( 'upgrader_process_complete', $this, array( + 'action' => 'install', // [TGMPA + ] adjusted. + 'type' => 'plugin', + 'bulk' => true, + 'plugins' => $plugins, + ) ); + + $this->skin->bulk_footer(); + + $this->skin->footer(); + + // Cleanup our hooks, in case something else does a upgrade on this connection. + /* [TGMPA - ] remove_filter('upgrader_clear_destination', array($this, 'delete_old_plugin')); */ + + // [TGMPA + ] Remove our auto-activation hook. + remove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); + + // Force refresh of plugin update information. + wp_clean_plugins_cache( $parsed_args['clear_update_cache'] ); + + return $results; + } + + /** + * Handle a bulk upgrade request. + * + * @since 2.5.0 + * + * @see Plugin_Upgrader::bulk_upgrade() + * + * @param array $plugins The local WP file_path's of the plugins which should be upgraded. + * @param array $args Arbitrary passed extra arguments. + * @return string|bool Install confirmation messages on success, false on failure. + */ + public function bulk_upgrade( $plugins, $args = array() ) { + + add_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); + + $result = parent::bulk_upgrade( $plugins, $args ); + + remove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); + + return $result; + } + + /** + * Abuse a filter to auto-activate plugins after installation. + * + * Hooked into the 'upgrader_post_install' filter hook. + * + * @since 2.5.0 + * + * @param bool $bool The value we need to give back (true). + * @return bool + */ + public function auto_activate( $bool ) { + // Only process the activation of installed plugins if the automatic flag is set to true. + if ( $this->tgmpa->is_automatic ) { + // Flush plugins cache so the headers of the newly installed plugins will be read correctly. + wp_clean_plugins_cache(); + + // Get the installed plugin file. + $plugin_info = $this->plugin_info(); + + // Don't try to activate on upgrade of active plugin as WP will do this already. + if ( ! is_plugin_active( $plugin_info ) ) { + $activate = activate_plugin( $plugin_info ); + + // Adjust the success string based on the activation result. + $this->strings['process_success'] = $this->strings['process_success'] . "
\n"; + + if ( is_wp_error( $activate ) ) { + $this->skin->error( $activate ); + $this->strings['process_success'] .= $this->strings['activation_failed']; + } else { + $this->strings['process_success'] .= $this->strings['activation_success']; + } + } + } + + return $bool; + } + } + } + + if ( ! class_exists( 'TGMPA_Bulk_Installer_Skin' ) ) { + + /** + * Installer skin to set strings for the bulk plugin installations.. + * + * Extends Bulk_Upgrader_Skin and customizes to suit the installation of multiple + * plugins. + * + * @since 2.2.0 + * + * {@internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer_Skin to + * TGMPA_Bulk_Installer_Skin. + * This was done to prevent backward compatibility issues with v2.3.6.}} + * + * @see https://core.trac.wordpress.org/browser/trunk/src/wp-admin/includes/class-wp-upgrader-skins.php + * + * @package TGM-Plugin-Activation + * @author Thomas Griffin + * @author Gary Jones + */ + class TGMPA_Bulk_Installer_Skin extends Bulk_Upgrader_Skin { + /** + * Holds plugin info for each individual plugin installation. + * + * @since 2.2.0 + * + * @var array + */ + public $plugin_info = array(); + + /** + * Holds names of plugins that are undergoing bulk installations. + * + * @since 2.2.0 + * + * @var array + */ + public $plugin_names = array(); + + /** + * Integer to use for iteration through each plugin installation. + * + * @since 2.2.0 + * + * @var integer + */ + public $i = 0; + + /** + * TGMPA instance + * + * @since 2.5.0 + * + * @var object + */ + protected $tgmpa; + + /** + * Constructor. Parses default args with new ones and extracts them for use. + * + * @since 2.2.0 + * + * @param array $args Arguments to pass for use within the class. + */ + public function __construct( $args = array() ) { + // Get TGMPA class instance. + $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); + + // Parse default and new args. + $defaults = array( + 'url' => '', + 'nonce' => '', + 'names' => array(), + 'install_type' => 'install', + ); + $args = wp_parse_args( $args, $defaults ); + + // Set plugin names to $this->plugin_names property. + $this->plugin_names = $args['names']; + + // Extract the new args. + parent::__construct( $args ); + } + + /** + * Sets install skin strings for each individual plugin. + * + * Checks to see if the automatic activation flag is set and uses the + * the proper strings accordingly. + * + * @since 2.2.0 + */ + public function add_strings() { + if ( 'update' === $this->options['install_type'] ) { + parent::add_strings(); + /* translators: 1: plugin name, 2: action number 3: total number of actions. */ + $this->upgrader->strings['skin_before_update_header'] = __( 'Updating Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); + } else { + /* translators: 1: plugin name, 2: error message. */ + $this->upgrader->strings['skin_update_failed_error'] = __( 'An error occurred while installing %1$s: %2$s.', 'tgmpa' ); + /* translators: 1: plugin name. */ + $this->upgrader->strings['skin_update_failed'] = __( 'The installation of %1$s failed.', 'tgmpa' ); + + if ( $this->tgmpa->is_automatic ) { + // Automatic activation strings. + $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation and activation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' ); + /* translators: 1: plugin name. */ + $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed and activated successfully.', 'tgmpa' ) . ' ' . esc_html__( 'Show Details', 'tgmpa' ) . '.'; + $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations and activations have been completed.', 'tgmpa' ); + /* translators: 1: plugin name, 2: action number 3: total number of actions. */ + $this->upgrader->strings['skin_before_update_header'] = __( 'Installing and Activating Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); + } else { + // Default installation strings. + $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' ); + /* translators: 1: plugin name. */ + $this->upgrader->strings['skin_update_successful'] = esc_html__( '%1$s installed successfully.', 'tgmpa' ) . ' ' . esc_html__( 'Show Details', 'tgmpa' ) . '.'; + $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations have been completed.', 'tgmpa' ); + /* translators: 1: plugin name, 2: action number 3: total number of actions. */ + $this->upgrader->strings['skin_before_update_header'] = __( 'Installing Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); + } + } + } + + /** + * Outputs the header strings and necessary JS before each plugin installation. + * + * @since 2.2.0 + * + * @param string $title Unused in this implementation. + */ + public function before( $title = '' ) { + if ( empty( $title ) ) { + $title = esc_html( $this->plugin_names[ $this->i ] ); + } + parent::before( $title ); + } + + /** + * Outputs the footer strings and necessary JS after each plugin installation. + * + * Checks for any errors and outputs them if they exist, else output + * success strings. + * + * @since 2.2.0 + * + * @param string $title Unused in this implementation. + */ + public function after( $title = '' ) { + if ( empty( $title ) ) { + $title = esc_html( $this->plugin_names[ $this->i ] ); + } + parent::after( $title ); + + $this->i++; + } + + /** + * Outputs links after bulk plugin installation is complete. + * + * @since 2.2.0 + */ + public function bulk_footer() { + // Serve up the string to say installations (and possibly activations) are complete. + parent::bulk_footer(); + + // Flush plugins cache so we can make sure that the installed plugins list is always up to date. + wp_clean_plugins_cache(); + + $this->tgmpa->show_tgmpa_version(); + + // Display message based on if all plugins are now active or not. + $update_actions = array(); + + if ( $this->tgmpa->is_tgmpa_complete() ) { + // All plugins are active, so we display the complete string and hide the menu to protect users. + echo ''; + $update_actions['dashboard'] = sprintf( + esc_html( $this->tgmpa->strings['complete'] ), + '' . esc_html__( 'Return to the Dashboard', 'tgmpa' ) . '' + ); + } else { + $update_actions['tgmpa_page'] = '' . esc_html( $this->tgmpa->strings['return'] ) . ''; + } + + /** + * Filter the list of action links available following bulk plugin installs/updates. + * + * @since 2.5.0 + * + * @param array $update_actions Array of plugin action links. + * @param array $plugin_info Array of information for the last-handled plugin. + */ + $update_actions = apply_filters( 'tgmpa_update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info ); + + if ( ! empty( $update_actions ) ) { + $this->feedback( implode( ' | ', (array) $update_actions ) ); + } + } + + /* *********** DEPRECATED METHODS *********** */ + + /** + * Flush header output buffer. + * + * @since 2.2.0 + * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead + * @see Bulk_Upgrader_Skin::flush_output() + */ + public function before_flush_output() { + _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' ); + $this->flush_output(); + } + + /** + * Flush footer output buffer and iterate $this->i to make sure the + * installation strings reference the correct plugin. + * + * @since 2.2.0 + * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead + * @see Bulk_Upgrader_Skin::flush_output() + */ + public function after_flush_output() { + _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' ); + $this->flush_output(); + $this->i++; + } + } + } + } + } +} + +if ( ! class_exists( 'TGMPA_Utils' ) ) { + + /** + * Generic utilities for TGMPA. + * + * All methods are static, poor-dev name-spacing class wrapper. + * + * Class was called TGM_Utils in 2.5.0 but renamed TGMPA_Utils in 2.5.1 as this was conflicting with Soliloquy. + * + * @since 2.5.0 + * + * @package TGM-Plugin-Activation + * @author Juliette Reinders Folmer + */ + class TGMPA_Utils { + /** + * Whether the PHP filter extension is enabled. + * + * @see http://php.net/book.filter + * + * @since 2.5.0 + * + * @static + * + * @var bool $has_filters True is the extension is enabled. + */ + public static $has_filters; + + /** + * Wrap an arbitrary string in tags. Meant to be used in combination with array_map(). + * + * @since 2.5.0 + * + * @static + * + * @param string $string Text to be wrapped. + * @return string + */ + public static function wrap_in_em( $string ) { + return '' . wp_kses_post( $string ) . ''; + } + + /** + * Wrap an arbitrary string in tags. Meant to be used in combination with array_map(). + * + * @since 2.5.0 + * + * @static + * + * @param string $string Text to be wrapped. + * @return string + */ + public static function wrap_in_strong( $string ) { + return '' . wp_kses_post( $string ) . ''; + } + + /** + * Helper function: Validate a value as boolean + * + * @since 2.5.0 + * + * @static + * + * @param mixed $value Arbitrary value. + * @return bool + */ + public static function validate_bool( $value ) { + if ( ! isset( self::$has_filters ) ) { + self::$has_filters = extension_loaded( 'filter' ); + } + + if ( self::$has_filters ) { + return filter_var( $value, FILTER_VALIDATE_BOOLEAN ); + } else { + return self::emulate_filter_bool( $value ); + } + } + + /** + * Helper function: Cast a value to bool + * + * @since 2.5.0 + * + * @static + * + * @param mixed $value Value to cast. + * @return bool + */ + protected static function emulate_filter_bool( $value ) { + // @codingStandardsIgnoreStart + static $true = array( + '1', + 'true', 'True', 'TRUE', + 'y', 'Y', + 'yes', 'Yes', 'YES', + 'on', 'On', 'ON', + ); + static $false = array( + '0', + 'false', 'False', 'FALSE', + 'n', 'N', + 'no', 'No', 'NO', + 'off', 'Off', 'OFF', + ); + // @codingStandardsIgnoreEnd + + if ( is_bool( $value ) ) { + return $value; + } elseif ( is_int( $value ) && ( 0 === $value || 1 === $value ) ) { + return (bool) $value; + } elseif ( ( is_float( $value ) && ! is_nan( $value ) ) && ( (float) 0 === $value || (float) 1 === $value ) ) { + return (bool) $value; + } elseif ( is_string( $value ) ) { + $value = trim( $value ); + if ( in_array( $value, $true, true ) ) { + return true; + } elseif ( in_array( $value, $false, true ) ) { + return false; + } else { + return false; + } + } + + return false; + } + } // End of class TGMPA_Utils +} // End of class_exists wrapper diff --git a/components/php/views/export.php b/components/php/views/export.php new file mode 100644 index 0000000..25709eb --- /dev/null +++ b/components/php/views/export.php @@ -0,0 +1,19 @@ + + +
+

:

+
+
+ + diff --git a/components/php/views/header.php b/components/php/views/header.php new file mode 100644 index 0000000..29d8a34 --- /dev/null +++ b/components/php/views/header.php @@ -0,0 +1,30 @@ + + diff --git a/components/php/views/import/step1.php b/components/php/views/import/step1.php new file mode 100644 index 0000000..5fa5097 --- /dev/null +++ b/components/php/views/import/step1.php @@ -0,0 +1,17 @@ +get_remote_style_data($remote_style_slug); +if(!$remote_style){ + wp_die('Invalid style'); +} diff --git a/components/php/views/react.php b/components/php/views/react.php new file mode 100644 index 0000000..f22f928 --- /dev/null +++ b/components/php/views/react.php @@ -0,0 +1,11 @@ +get_config(); + +?> + +
diff --git a/components/php/views/remote-style-import.php b/components/php/views/remote-style-import.php new file mode 100644 index 0000000..e557f35 --- /dev/null +++ b/components/php/views/remote-style-import.php @@ -0,0 +1,33 @@ +get_remote_style_data($remote_style_slug); +if(!$remote_style){ + wp_die('Invalid style'); +} + + +?> + +
+
+

Style:

+ Importing... +
+
+ + diff --git a/components/php/views/wrapper.php b/components/php/views/wrapper.php new file mode 100644 index 0000000..7f0bd94 --- /dev/null +++ b/components/php/views/wrapper.php @@ -0,0 +1,17 @@ + + +
+ header; ?> +
+ render_template( 'notices/advertisement.php' ); ?> +
+ content; ?> +
+
+
diff --git a/components/remote-styles/remote-styles.php b/components/remote-styles/remote-styles.php new file mode 100644 index 0000000..e37a76c --- /dev/null +++ b/components/remote-styles/remote-styles.php @@ -0,0 +1,37 @@ +post_type === self::CPT && $post->post_parent === 0 ) { + remove_post_type_support( self::CPT, 'editor' ); + + return false; + } + + return $use_block_editor; + } + + /** + * Here is our magical custom post type that stores all our site wide styles. + * + * @since 2.0.0 + */ + public function register_custom_post_type() { + + $labels = array( + 'name' => 'Styles', + 'singular_name' => 'Style', + 'menu_name' => 'StylePress', + 'parent_item_colon' => 'Parent Style:', + 'all_items' => 'All Styles', + 'view_item' => 'View Style', + 'add_new_item' => 'Add New Style', + 'add_new' => 'New Style', + 'edit_item' => 'Edit Style', + 'update_item' => 'Update Style', + 'search_items' => 'Search Styles', + 'not_found' => 'No Styles found', + 'not_found_in_trash' => 'No Styles found in Trash', + ); + + $args = array( + 'description' => 'Styles', + 'labels' => $labels, + 'supports' => array( + 'title', + 'author', + 'thumbnail', + 'elementor', + 'page-attributes', + 'revisions', + 'editor' + ), + 'taxonomies' => array(), + 'hierarchical' => true, + 'public' => defined( 'STYLEPRESS_ALLOW_EXPORT' ) && STYLEPRESS_ALLOW_EXPORT, + 'show_in_menu' => defined( 'STYLEPRESS_ALLOW_EXPORT' ) && STYLEPRESS_ALLOW_EXPORT, + 'show_in_nav_menus' => true, + 'exclude_from_search' => true, + 'menu_position' => 36, + 'menu_icon' => 'dashicons-star-filled', + 'can_export' => true, + 'has_archive' => false, + 'publicly_queryable' => true, + 'rewrite' => false, + 'capability_type' => 'post', + 'map_meta_cap' => true, + 'show_in_rest' => true, + ); + + register_post_type( self::CPT, $args ); + + register_taxonomy( + STYLEPRESS_SLUG . '-cat', + self::CPT, + array( + 'hierarchical' => true, + 'label' => 'Category', + 'show_in_rest' => true, + ) + ); + + } + + /** + * Adds a meta box to every post type. + * + * @since 2.0.0 + * + * @var \WP_Post $post The current displayed post. + */ + public function edit_form_after_title( $post ) { + + if ( self::CPT === $post->post_type ) { + + $parent = $post->post_parent ? (int) $post->post_parent : ( ! empty( $_GET['post_parent'] ) ? (int) $_GET['post_parent'] : false ); + ?> +
+ +
+ +
+
+ 10, + 'slug' => 'header', + 'title' => 'Header', + 'plural' => 'Headers', + 'description' => 'These are the header designs for this style.', + 'global_selector' => true, + 'render_section' => true, + ]; + $stylepress_categories[] = [ + 'order' => 20, + 'slug' => 'hero', + 'title' => 'Hero', + 'plural' => 'Heros', + 'description' => 'These are the hero designs for this style.', + 'global_selector' => true, + 'render_section' => true, + ]; + $stylepress_categories[] = [ + 'order' => 30, + 'slug' => 'page_body', + 'title' => 'Page Body', + 'plural' => 'Page Body', + 'inner' => true, + 'description' => 'These are the page body layouts for this style.', + 'global_selector' => true, + 'render_section' => true, + ]; + $stylepress_categories[] = [ + 'order' => 40, + 'slug' => 'footer', + 'title' => 'Footer', + 'plural' => 'Footers', + 'description' => 'These are the footer designs for this style.', + 'global_selector' => true, + 'render_section' => true, + ]; +// $stylepress_categories[] = [ +// 'order' => 50, +// 'slug' => 'theme_styles', +// 'title' => 'Theme Style', +// 'plural' => 'Theme Styles', +// 'description' => 'These are global theme styles that apply to all elements on the page (i.e. link color).', +// 'global_selector' => true, +// 'render_section' => false, +// 'is_elementor_kit_style' => true, +// ]; + $stylepress_categories[] = [ + 'order' => 60, + 'slug' => 'demo_content', + 'title' => 'Demo Content', + 'plural' => 'Demo Content', + 'description' => 'These are demo content that can be inserted through out the website.', + 'global_selector' => false, + 'render_section' => false, + ]; + + return apply_filters( 'stylepress_categories', $stylepress_categories ); + } + + public function get_all_styles( $category_slug = false, $include_empty = false, $parent_id = false ) { + $styles = array(); + $args = array( + 'post_type' => Cpt::CPT, + 'post_status' => 'publish', + 'posts_per_page' => - 1, + 'ignore_sticky_posts' => 1, + 'suppress_filters' => false, + 'order' => 'ASC', + 'orderby' => 'title', + ); + if ( $parent_id !== false ) { + $args['post_parent'] = (int) $parent_id; + } + if ( $category_slug ) { + $args['tax_query'] = array( + array( + 'taxonomy' => STYLEPRESS_SLUG . '-cat', + 'field' => 'slug', + 'terms' => $category_slug, + ) + ); + } + $posts_array = get_posts( $args ); + foreach ( $posts_array as $style ) { + if ( $parent_id === false && $style->post_parent ) { + $parent = get_post( $style->post_parent ); + $style->post_title = $parent->post_title . ' > ' . $style->post_title; + } + $styles[ $style->ID ] = $style->post_title; + } + + if ( $include_empty ) { + $styles = [ - 1 => '(Blank)' ] + $styles; + } + + return $styles; + } + + /** + * Returns a URL used to edit a particular design. + * + * @param int $design_id the design we want to edit. + * + * @return string + * @since 2.0.0 + * + */ + public function get_design_edit_url( $design_id ) { + // if this is an "Elementor" style then we use the Elementor edit page url, otherwise default to the standard WP edit post link + if ( \StylePress\Elementor\Integration::is_elementor_active() ) { + return \StylePress\Elementor\Integration::edit_url_for_design( $design_id ); + } + + return get_edit_post_link( $design_id, 'edit' ); + } + + /** + * This lets us query what the currently selected page template is for a particular post ID + * We use the other function to get the defaults for non-page-ID posts (like archive etc..) + * + * @param int $post_id Current post ID we're querying. + * + * @return array + * @since 2.0.0 + * + */ + public function get_page_styles( $post_id ) { + $current_option = get_post_meta( $post_id, 'stylepress_style', true ); + + if ( ! is_array( $current_option ) ) { + $current_option = []; + } + + return $current_option; + } + + /** + * Works out what template is currently selected for the current page/post/archive/search/404 etc. + * Copied from my Widget Area Manager plugin + * + * @return int + * @since 2.0.0 + * + */ + public function get_default_styles() { + + $style_settings = \StylePress\Core\Settings::get_instance()->get( 'stylepress_styles' ); + if ( ! $style_settings || ! is_array( $style_settings ) ) { + $style_settings = []; + } + + $categories = $this->get_categories(); + foreach ( $categories as $category ) { + if ( ! isset( $style_settings[ $category['slug'] ] ) ) { + $style_settings[ $category['slug'] ] = false; + } + } + + return $style_settings; + + } + + + // Todo: we need this for categories and 404 etc.. + public function is_stylpress_enabled( $post ) { + if ( $post && $post->ID ) { + $template = get_post_meta( $post->ID, '_wp_page_template', true ); + if ( $template && $template !== 'default' ) { + return [ + 'enabled' => false, + 'reason' => 'StylePress disabled due to a custom template assigned to this page. Please remove the custom page template if you wish to use StylePress on this page.', + ]; + } + } + + return [ + 'enabled' => true, + ]; + } + + + public function something() { + + global $post; + + if ( ! $ignore_override ) { + + if ( is_home() || is_front_page() ) { + if ( 'page' == get_option( 'show_on_front' ) ) { + $home_page_id = false; + if ( is_front_page() ) { + $home_page_id = get_option( 'page_on_front' ); + } else { + $home_page_id = get_option( 'page_for_posts' ); + } + if ( $home_page_id ) { + $style = (int) $this->get_page_template( $home_page_id ); + if ( STYLEPRESS_OUTER_USE_THEME === $style ) { + return $style; // Use theme by default. + } else if ( $style > 0 ) { + return apply_filters( 'stylepress_current_style', $style ); + } + } + } + } + if ( is_single() || is_page() || is_attachment() ) { + // see if we have a custom style applied + if ( $post && $post->ID ) { + $style = (int) $this->get_page_template( $post->ID ); + if ( STYLEPRESS_OUTER_USE_THEME === $style ) { + return $style; // Use theme by default. + } else if ( $style > 0 ) { + return apply_filters( 'stylepress_current_style', $style ); + } + } + } + } + + // check for defaults for this page type + $page_type = Plugin::get_instance()->get_current_page_type(); + if ( $page_type && ! empty( $style_settings['defaults'][ $page_type ] ) ) { + return apply_filters( 'stylepress_current_style', $style_settings['defaults'][ $page_type ] ); + } + // otherwise check for site wide default: + if ( ! empty( $style_settings['defaults']['_global'] ) ) { + return apply_filters( 'stylepress_current_style', $style_settings['defaults']['_global'] ); + } + + // otherwise return nothing, so we fallback to default standard theme + return false; + + } +} diff --git a/components/styles/styles.js b/components/styles/styles.js new file mode 100644 index 0000000..e39aaa1 --- /dev/null +++ b/components/styles/styles.js @@ -0,0 +1 @@ +import './styles.scss'; diff --git a/components/styles/styles.php b/components/styles/styles.php new file mode 100644 index 0000000..3e7e4e6 --- /dev/null +++ b/components/styles/styles.php @@ -0,0 +1,104 @@ + Cpt::CPT, + 'post_status' => 'publish', + 'post_title' => $new_style_name, + 'post_parent' => $new_style_parent, + ], true ); + + if ( is_wp_error( $post_id ) || ! $post_id ) { + wp_die( 'Failed to create new style' ); + } + + wp_set_object_terms( $post_id, $new_category, STYLEPRESS_SLUG . '-cat', false ); + + if ( $new_category === 'theme_styles' ) { + // hack to allow Elementor Theme Style editor: + update_post_meta( $post_id, '_elementor_template_type', 'kit' ); + } + + wp_safe_redirect( admin_url( 'admin.php?page=' . self::STYLES_PAGE_SLUG . ( $new_style_parent ? '&style_id=' . $new_style_parent : '' ) . '&saved#cat-' . $new_category ) ); + exit; + + } +} + diff --git a/components/styles/styles.scss b/components/styles/styles.scss new file mode 100644 index 0000000..20f0243 --- /dev/null +++ b/components/styles/styles.scss @@ -0,0 +1,157 @@ + +.stylepress__category { + +} + +.stylepress__category-header { + background: #FFF; + padding: 15px 20px; + position: relative; + margin: 0 0 30px; + + &:before { + position: absolute; + left: 0; + content: ''; + display: block; + top: 0; + bottom: 0; + width: 4px; + background: #e6e6e6 + } + + span { + font-weight: bold; + display: block; + padding: 0 0 5px; + } + + small { + font-weight: normal; + display: block; + } +} + +.stylepress__main { + margin-top: 40px; +} + + +.stylepress__category-content { + display: flex; + flex-wrap: wrap; +} + + +.stylepress__style { + width: 100%; + padding: 0 20px; + box-sizing: border-box; + + @media (min-width: 768px) { + width: 50%; + } + + @media (min-width: 1200px) { + width: 25%; + } +} + +.stylepress__style-inner { + margin-bottom: 20px; + cursor: pointer; + position: relative; + border: 1px solid #ddd; + box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.1); + box-sizing: border-box; + + .stylepress__style-thumb { + display: block; + overflow: hidden; + position: relative; + height: 150px; + background-color: #FFF; + background-position: center; + background-size: contain; + background-repeat: no-repeat; + + } + + .theme-usage { + padding: 6px 0 6px 12px; + font-size: 12px; + background-color: #fafafa; + text-overflow: ellipsis; + min-height: 18px; + + &.style-description { + height: auto; + } + + a { + text-decoration: none; + color: #444; + } + } + h3.stylepress__style-name { + font-size: 15px; + position: relative; + font-weight: 600; + height: 18px; + margin: 0; + padding: 15px; + box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1); + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + background-color: #fafafa; + color: #23282d; + + small { + font-weight: normal; + font-size: 12px; + color: #CCC; + } + + a { + color: #23282d; + text-decoration: none; + } + } + + .stylepress__style-action { + position: absolute; + bottom: 0; + right: 0; + height: 38px; + padding: 9px 10px 0 10px; + background: rgba(244, 244, 244, 0.7); + border-left: 1px solid rgba(0, 0, 0, 0.05); + } + +} +.stylepress__style--new{ + position: relative; + .stylepress__style-inner{ + opacity: 0.3; + transition: opacity 0.3s; + border: 1px dashed #a2a2a2; + &:hover{ + opacity: 1; + } + } + + h3.stylepress__style-name { + padding: 0; + height: 48px; + } + .stylepress__style-name-input{ + position: absolute; + background: transparent; + padding: 4px 12px; + line-height: 40px; + font-size: 15px; + border: 0; + } + +} diff --git a/components/styles/views/remote_style_preview.php b/components/styles/views/remote_style_preview.php new file mode 100644 index 0000000..a946887 --- /dev/null +++ b/components/styles/views/remote_style_preview.php @@ -0,0 +1,37 @@ +get_remote_style_data($remote_style_slug); +if(!$remote_style){ + wp_die('Invalid style'); +} + +?> + +
+
+

Style:

+ +

+ + + +

+
+
+ + diff --git a/components/styles/views/single_style.php b/components/styles/views/single_style.php new file mode 100644 index 0000000..bd91f4d --- /dev/null +++ b/components/styles/views/single_style.php @@ -0,0 +1,144 @@ +get_categories(); +$parent_style_id = isset( $_GET['style_id'] ) ? (int) $_GET['style_id'] : 0; +$parent_style = false; +if ( $parent_style_id ) { + $parent_style = get_post( $parent_style_id ); +} +if ( ! $parent_style || $parent_style->post_type !== Cpt::CPT ) { + wp_die( 'Invalid parent style' ); +} +?> + +
+
+

Style: post_title ); ?>

+

Builder: (todo)

+ Style Preview Graphic +

Below are a list of designs included within this style.

+
+ +
+ +

+ + +

+
+ get_all_styles( $category['slug'], false, $parent_style_id ); + // $designs[] = 'asdf'; + foreach ( $designs as $design_id => $design ) { + ?> +
+
+ + + + 'stylepress_style', + 'post_parent' => $design_id, + 'post_status' => 'any', + 'posts_per_page' => - 1, + 'ignore_sticky_posts' => 1, + ); + $posts_array = get_posts( $args ); + + foreach ( $page_types as $post_type => $post_type_title ) { + if ( $settings && ! empty( $settings['defaults'][ $post_type ] ) && (int) $settings['defaults'][ $post_type ] === (int) $design_id ) { + $used[ $post_type ] = $post_type_title; + } + // check if any of the child posts are used in this particular post type. + foreach ( $posts_array as $post_array ) { + if ( $settings && ! empty( $settings['defaults'][ $post_type ] ) && (int) $settings['defaults'][ $post_type ] === (int) $post_array->ID ) { + $used[ $post_type ] = $post_type_title; + } + } + // todo: query what custom pages have a different style overview + } + + ?> + + + +

+ +
+ + + +
+
+ +
+ + + +
+ +
+ + + + + +
+ +
+
+ +

+ +

+ +
+ +
+
+ +
+ + + +
+
+ + + +
diff --git a/components/styles/views/styles_overview.php b/components/styles/views/styles_overview.php new file mode 100644 index 0000000..d84da20 --- /dev/null +++ b/components/styles/views/styles_overview.php @@ -0,0 +1,117 @@ + + +
+
+

+ Your Styles + These are the page styles which can be applied to your website pages. + +

+
+ get_all_styles( $category ); + foreach ( $designs as $design_id => $design ) { + ?> +
+
+ + +

+
+ + + +
+
+ +
+ + +
+ +
+ + + + + +
+ +
+
+ +

+ +

+ +
+ +
+
+ +
+ + + +
+
+ + +
+

+ Available Styles + These are the available default styles, choose one to import into the website. + +

+
+ get_all_remote_styles(); + foreach ( $designs as $design_id => $design ) { + ?> +
+
+ + +

+
+ + + +
+
+ +
+ +
+
+ + +
diff --git a/components/wizard/ajax.php b/components/wizard/ajax.php new file mode 100644 index 0000000..3e77f64 --- /dev/null +++ b/components/wizard/ajax.php @@ -0,0 +1,49 @@ +can_run_setup_wizard()) { + wp_send_json_error( esc_html__( 'Failed to import remote style', 'stylepress' ) ); + } + + $remote_style_slug = isset( $_GET['remote_style_slug'] ) ? $_GET['remote_style_slug'] : false; + if ( ! $remote_style_slug ) { + wp_send_json_error( esc_html__('Invalid remote style, please go back and try again', 'stylepress' ) ); + } + $remote_style_data = Remote_Styles::get_instance()->get_remote_style_data( $remote_style_slug ); + if ( ! $remote_style_data ) { + wp_send_json_error( esc_html__('Invalid remote style data, please go back and try again' , 'stylepress' )); + } + $is_already_installed = Remote_Styles::get_instance()->is_remote_style_imported( $remote_style_slug ); + + wp_send_json_success('Imported successfully'); + } + + +} diff --git a/components/wizard/complete.php b/components/wizard/complete.php new file mode 100644 index 0000000..1c0945f --- /dev/null +++ b/components/wizard/complete.php @@ -0,0 +1,26 @@ + 1 || count( $pages ) > 3 ) { + return true; + } + + return false; + } + + public function content_default_get() { + + $content = array(); + + // find out what content is in our default json file. + $available_content = array(); // $this->get_json( 'default.json' ); + foreach ( $available_content as $post_type => $post_data ) { + if ( count( $post_data ) ) { + $first = current( $post_data ); + $post_type_title = ! empty( $first['type_title'] ) ? $first['type_title'] : ucwords( $post_type ) . 's'; + if ( $post_type_title == 'Navigation Menu Items' ) { + $post_type_title = 'Navigation'; + } + $content[ $post_type ] = array( + 'title' => $post_type_title, + 'description' => sprintf( esc_html__( 'This will create default %s as seen in the demo.' ), $post_type_title ), + 'pending' => esc_html__( 'Pending.' ), + 'installing' => esc_html__( 'Installing.' ), + 'success' => esc_html__( 'Success.' ), + 'install_callback' => array( $this, '_content_install_type' ), + 'checked' => $this->is_possible_upgrade() ? 0 : 1, + // dont check if already have content installed. + ); + } + } + + $content['settings'] = array( + 'title' => esc_html__( 'Settings' ), + 'description' => esc_html__( 'Configure default settings.' ), + 'pending' => esc_html__( 'Pending.' ), + 'installing' => esc_html__( 'Installing Default Settings.' ), + 'success' => esc_html__( 'Success.' ), + 'install_callback' => array( $this, '_content_install_settings' ), + 'checked' => $this->is_possible_upgrade() ? 0 : 1, + // dont check if already have content installed. + ); + + $content = apply_filters( 'stylepress_setup_wizard_content', $content, $this ); + + return $content; + + } + + + public function view() { + include __DIR__ . '/views/content.php'; + } + +} diff --git a/components/wizard/import.php b/components/wizard/import.php new file mode 100644 index 0000000..389954b --- /dev/null +++ b/components/wizard/import.php @@ -0,0 +1,36 @@ +get_remote_style_data( $remote_style_slug ); + if ( ! $remote_style_data ) { + esc_html_e( 'Invalid remote style data, please go back and try again', 'stylepress' ); + return false; + } + $is_already_installed = Remote_Styles::get_instance()->is_remote_style_imported( $remote_style_slug ); + + include __DIR__ . '/views/import.php'; + } +} diff --git a/components/wizard/import_controller.js b/components/wizard/import_controller.js new file mode 100644 index 0000000..25b6c18 --- /dev/null +++ b/components/wizard/import_controller.js @@ -0,0 +1,12 @@ +import { Controller } from 'stimulus'; + +export default class extends Controller { + static values = { + styleSlug: String, + styleData: Object + } + connect() { + console.log( 'connected', this.styleSlugValue ); + console.log( 'connected2', this.styleDataValue ); + } +} diff --git a/components/wizard/introduction.php b/components/wizard/introduction.php new file mode 100644 index 0000000..f247b8f --- /dev/null +++ b/components/wizard/introduction.php @@ -0,0 +1,24 @@ += $li.length ) { + + // finished all plugins! + complete(); + } + } + + return { + init: function( btn ) { + $( '.stylepress-wizard-plugins' ).addClass( 'installing' ); + complete = function() { + loading_content(); + + //window.location.href=btn.href; + }; + find_next(); + } + }; + } + + function ContentManager() { + + var complete; + var items_completed = 0; + var current_item = ''; + var $current_node; + var current_item_hash = ''; + + function ajax_callback( response ) { + if ( 'object' == typeof response && 'undefined' != typeof response.message ) { + $current_node.find( 'span' ).text( response.message ); + if ( 'undefined' != typeof response.url ) { + + // we have an ajax url action to perform. + if ( response.hash === current_item_hash ) { + $current_node.find( 'span' ).text( 'failed' ); + find_next(); + } else { + current_item_hash = response.hash; + jQuery.post( response.url, response, ajax_callback ).fail( ajax_callback ); // recuurrssionnnnn + } + } else if ( 'undefined' != typeof response.done ) { + + // finished processing this plugin, move onto next + find_next(); + } else { + + // error processing this plugin + find_next(); + } + } else { + + // error - try again with next plugin + $current_node.find( 'span' ).text( 'ajax error' ); + find_next(); + } + } + + function process_current() { + if ( current_item ) { + + var $check = $current_node.find( 'input:checkbox' ); + if ( $check.is( ':checked' ) ) { + console.log( 'Doing 2 ' + current_item ); + + // process htis one! + jQuery.post( stylepress_wizard.ajaxurl, { + action: 'stylepress_setup_content', + wpnonce: stylepress_wizard.wpnonce, + content: current_item + }, ajax_callback ).fail( ajax_callback ); + } else { + $current_node.find( 'span' ).text( 'Skipping' ); + setTimeout( find_next, 300 ); + } + } + } + function find_next() { + var do_next = false; + if ( $current_node ) { + if ( ! $current_node.data( 'done_item' ) ) { + items_completed++; + $current_node.data( 'done_item', 1 ); + } + $current_node.find( '.spinner' ).css( 'visibility', 'hidden' ); + } + var $items = $( 'tr.stylepress_default_content' ); + var $enabled_items = $( 'tr.stylepress_default_content input:checked' ); + $items.each( function() { + if ( '' === current_item || do_next ) { + current_item = $( this ).data( 'content' ); + $current_node = $( this ); + process_current(); + do_next = false; + } else if ( $( this ).data( 'content' ) === current_item ) { + do_next = true; + } + }); + if ( items_completed >= $items.length ) { + + // finished all items! + complete(); + } + } + + return { + init: function( btn ) { + $( '.stylepress-pages' ).addClass( 'installing' ); + $( '.stylepress-pages' ).find( 'input' ).prop( 'disabled', true ); + complete = function() { + loading_content(); + window.location.href = btn.href; + }; + find_next(); + } + }; + } + + /** + * Callback function for the 'click' event of the 'Set Footer Image' + * anchor in its meta box. + * + * Displays the media uploader for selecting an image. + * + * @since 0.1.0 + */ + function renderMediaUploader() { + 'use strict'; + + var file_frame, attachment; + + if ( undefined !== file_frame ) { + file_frame.open(); + return; + } + + file_frame = wp.media.frames.file_frame = wp.media({ + title: 'Upload Logo', //jQuery( this ).data( 'uploader_title' ), + button: { + text: 'Select Logo' //jQuery( this ).data( 'uploader_button_text' ) + }, + multiple: false // Set to true to allow multiple files to be selected + }); + + // When an image is selected, run a callback. + file_frame.on( 'select', function() { + + // We set multiple to false so only get one image from the uploader + attachment = file_frame.state().get( 'selection' ).first().toJSON(); + + jQuery( '.site-logo' ).attr( 'src', attachment.url ); + jQuery( '#new_logo_id' ).val( attachment.id ); + + // Do something with attachment.id and/or attachment.url here + }); + + // Now display the actual file_frame + file_frame.open(); + + } + + return { + init: function() { + t = this; + $( window_loaded ); + }, + callback: function( func ) { + console.log( func ); + console.log( this ); + } + }; + +}( jQuery ) ); + + +EnvatoWizard.init(); diff --git a/components/wizard/plugins.php b/components/wizard/plugins.php new file mode 100644 index 0000000..3d4605e --- /dev/null +++ b/components/wizard/plugins.php @@ -0,0 +1,25 @@ +get_all_remote_styles(); + include __DIR__ . '/views/style.php'; + } + +} diff --git a/components/wizard/style_controller.js b/components/wizard/style_controller.js new file mode 100644 index 0000000..4020150 --- /dev/null +++ b/components/wizard/style_controller.js @@ -0,0 +1,37 @@ +import { Controller } from 'stimulus'; + +export default class extends Controller { + static values = { + styleSlug: String + } + static targets = [ 'styleSelector' ] + + connect() { + const wizardManager = this.application.controllers.find( controller => 'wizard' === controller.context.identifier ); + wizardManager.registerStepRequirement( this.checkStep.bind( this ) ); + } + + checkStep() { + return new Promise( ( resolve, reject ) => { + if ( ! this.styleSlugValue ) { + reject( 'Please select a style' ); + } + resolve({ + args: { + remote_style_slug: this.styleSlugValue + } + }); + }); + } + + setStyle( e ) { + this.styleSlugValue = e.currentTarget.getAttribute( 'data-style' ); + for ( const style of this.styleSelectorTargets ) { + if ( style.getAttribute( 'data-style' ) === this.styleSlugValue ) { + style.classList.add( 'stylepress-setup-wizard__style--current' ); + } else { + style.classList.remove( 'stylepress-setup-wizard__style--current' ); + } + } + } +} diff --git a/components/wizard/views/content.php b/components/wizard/views/content.php new file mode 100644 index 0000000..409d128 --- /dev/null +++ b/components/wizard/views/content.php @@ -0,0 +1,44 @@ + +

+
+ is_possible_upgrade() ) { ?> +

+ +

', '' ); ?>

+ +
+
', + esc_html__( 'Upgrade message from the plugin author:', 'tgmpa' ), + ' ', wp_kses_data( $item['upgrade_notice'] ), ' +
+
+ + + + + + + + + + content_default_get() as $slug => $default ) { ?> + + + + + + + + +
+ > + + +
+
+ diff --git a/components/wizard/views/import.php b/components/wizard/views/import.php new file mode 100644 index 0000000..cbf5eb3 --- /dev/null +++ b/components/wizard/views/import.php @@ -0,0 +1,28 @@ + +

+

+
+ +

+ +
+ +
diff --git a/components/wizard/views/introduction.php b/components/wizard/views/introduction.php new file mode 100644 index 0000000..367783e --- /dev/null +++ b/components/wizard/views/introduction.php @@ -0,0 +1,18 @@ + +

+

+

+ +

+

+ +

+

+ +layout slider here diff --git a/components/wizard/views/plugins.php b/components/wizard/views/plugins.php new file mode 100644 index 0000000..1f3c3ab --- /dev/null +++ b/components/wizard/views/plugins.php @@ -0,0 +1,43 @@ + +

+
+ +

+
    + $plugin ) { ?> +
  • + + + +
    +
  • + +
+ ' . esc_html_e( 'Good news! All plugins are already installed and up to date. Please continue.' ) . '

'; + } ?> + +

+
diff --git a/components/wizard/views/ready.php b/components/wizard/views/ready.php new file mode 100644 index 0000000..ba35649 --- /dev/null +++ b/components/wizard/views/ready.php @@ -0,0 +1,59 @@ + + + + +

+ +

Congratulations! The theme has been activated and your website is ready. Login to your WordPress + dashboard to make changes and modify any of the default content to suit your needs.

+

Please come back and leave a 5-star rating + if you are happy with this theme.
Follow @dtbaker + on Twitter to see updates. Thanks!

+ +
+
+

+
    +
  • +
  • +
  • +
  • +
+
+
+

+
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
diff --git a/components/wizard/views/style.php b/components/wizard/views/style.php new file mode 100644 index 0000000..6955f74 --- /dev/null +++ b/components/wizard/views/style.php @@ -0,0 +1,22 @@ + +

+

+
+ $style_data ) { + ?> +
+
+ <?php echo esc_attr( $style_data['title'] ); ?> +
+ +
+
+ +
diff --git a/components/wizard/views/support.php b/components/wizard/views/support.php new file mode 100644 index 0000000..0000883 --- /dev/null +++ b/components/wizard/views/support.php @@ -0,0 +1,35 @@ + + +

Help and Support

+

This theme comes with 6 months item support from purchase date (with the option to extend this period). + This license allows you to use this theme on a single website. Please purchase an additional license to + use this theme on another website.

+

Item Support can be accessed from http://dtbaker.net/envato/ + and includes:

+
    +
  • Availability of the author to answer questions
  • +
  • Answering technical questions about item features
  • +
  • Assistance with reported bugs and issues
  • +
  • Help with bundled 3rd party plugins
  • +
+ +

Item Support DOES NOT Include:

+
    +
  • Customization services (this is available through Envato Studio) +
  • +
  • Installation services (this is available through Envato Studio) +
  • +
  • Help and Support for non-bundled 3rd party plugins (i.e. plugins you install yourself later on)
  • +
+

More details about item support can be found in the ThemeForest Item Support Polity.

+ diff --git a/components/wizard/views/wrapper.php b/components/wizard/views/wrapper.php new file mode 100644 index 0000000..a3b81c8 --- /dev/null +++ b/components/wizard/views/wrapper.php @@ -0,0 +1,59 @@ + +
+
    + $step ) { + if ( $step_key === 'introduction' ) { + continue; + } + $step_classname = ''; + if( $step_key === $this->current_step ) $step_classname = 'active'; + else if( array_search( $this->current_step, $step_keys ) > array_search( $step_key, $step_keys ) ) $step_classname = 'done'; + ?> +
  1. + +
  2. + +
+ +
+
+
+
+ step_output(); + ?> +
+
+ + + + + + + +
+
diff --git a/components/wizard/wizard.js b/components/wizard/wizard.js new file mode 100644 index 0000000..de68a01 --- /dev/null +++ b/components/wizard/wizard.js @@ -0,0 +1,7 @@ +import { Application } from 'stimulus'; +import { definitionsFromContext } from 'stimulus/webpack-helpers'; +import './wizard.scss'; + +const application = Application.start(); +const context = require.context( './', true, /\.js$/ ); +application.load( definitionsFromContext( context ) ); diff --git a/components/wizard/wizard.php b/components/wizard/wizard.php new file mode 100644 index 0000000..355c423 --- /dev/null +++ b/components/wizard/wizard.php @@ -0,0 +1,180 @@ +get_steps(); + if ( isset( $steps[ $_GET['step'] ] ) ) { + $this->current_step = $_GET['step']; + } + Import::get_instance(); + Style::get_instance(); + } + } + + public function add_top_level_menu(){ + if(\StylePress\Core\Permissions::get_instance()->can_run_setup_wizard()) { + add_menu_page( + __( 'StylePress', 'stylepress' ), + __( 'StylePress', 'stylepress' ), + 'manage_options', + self::PAGE_SLUG, + array( + $this, + 'wizard_page_callback', + ), + STYLEPRESS_URI . 'src/images/icon.png' + ); + // hack to remove default submenu + $page = add_submenu_page( + self::PAGE_SLUG, + __( 'Setup Wizard', 'stylepress' ), + __( 'Setup Wizard', 'stylepress' ), + 'manage_options', + self::PAGE_SLUG, + array( + $this, + 'wizard_page_callback' + ) + ); + add_action( 'admin_print_styles-' . $page, array( $this, 'wizard_ui_page_assets' ) ); + + return self::PAGE_SLUG; + } + } + + public function wizard_ui_page_assets () { + wp_enqueue_style( 'stylepress-wizard', STYLEPRESS_URI . 'build/assets/wizard.css', false, STYLEPRESS_VERSION ); + wp_enqueue_script( 'stylepress-wizard', STYLEPRESS_URI . 'build/assets/wizard.js', [], STYLEPRESS_VERSION ); + + // Add contextual help contents + ob_start(); + ?> +

Getting Started

+
    +
  1. Test
  2. +
  3. Test
  4. +
  5. Test
  6. +
  7. Test
  8. +
+ add_help_tab( array( + 'id' => 'stylepress-help', + 'title' => __( 'Getting Started', 'stylepress' ), + 'content' => $help_customize, + ) ); + } + + + /** + * This is our callback for rendering our custom menu page. + * This page shows all our site styles and currently selected defaults. + * + * @since 2.0.0 + */ + public function wizard_page_callback() { + $output_steps = $this->get_steps(); + $step_keys = array_keys( $output_steps ); + include_once __DIR__ .'/views/wrapper.php'; + } + + + public function get_steps() { + static $steps = array(); + if(count($steps)){ + // get_steps() can be expensive so be sure to memoize the result + return $steps; + } + $steps['introduction'] = array( + 'name' => esc_html__( 'Introduction' ), + 'view' => array( Introduction::get_instance(), 'view' ), + 'handler' => '', + ); + $steps['style'] = array( + 'name' => esc_html__( 'Style' ), + 'view' => array( Style::get_instance(), 'view' ), + 'handler' => '', + ); + $steps['import'] = array( + 'name' => esc_html__( 'Import' ), + 'view' => array( Import::get_instance(), 'view' ), + 'handler' => '', + ); + $steps['plugins'] = array( + 'name' => esc_html__( 'Plugins' ), + 'view' => array( Plugins::get_instance(), 'view' ), + 'handler' => '', + ); + $steps['layout'] = array( + 'name' => esc_html__( 'Layout' ), + 'view' => array( Layout::get_instance(), 'view' ), + 'handler' => '', + ); + $steps['content'] = array( + 'name' => esc_html__( 'Content' ), + 'view' => array( Content::get_instance(), 'view' ), + 'handler' => '', + ); + $steps['complete'] = array( + 'name' => esc_html__( 'Complete' ), + 'view' => array( Complete::get_instance(), 'view' ), + 'handler' => '', + ); + + $steps = apply_filters( 'stylepress_setup_wizard_steps', $steps, $this ); + + return $steps; + } + + public function step_output() { + $steps = $this->get_steps(); + if ( $this->current_step && isset( $steps[ $this->current_step ] ) ) { + call_user_func( $steps[ $this->current_step ]['view'] ); + } + } + + public function get_step_link( $step ) { + return add_query_arg( 'step', $step, admin_url( 'admin.php?page=' . self::PAGE_SLUG) ); + } + + public function get_next_step_link() { + $keys = array_keys( $this->get_steps() ); + $link = admin_url( '' ); + $next_step = array_search( $this->current_step, $keys ) + 1; + if(isset($keys[ $next_step ])) { + $link = $this->get_step_link( $keys[ $next_step ] ); + } + return $link; + } + + public function get_prev_step_link() { + $keys = array_keys( $this->get_steps() ); + $link = admin_url( '' ); + $prev_step = array_search( $this->current_step, $keys ) - 1; + if(isset($keys[ $prev_step ])) { + $link = $this->get_step_link( $keys[ $prev_step ] ); + } + return $link; + } +} + diff --git a/components/wizard/wizard.scss b/components/wizard/wizard.scss new file mode 100644 index 0000000..6e9b667 --- /dev/null +++ b/components/wizard/wizard.scss @@ -0,0 +1,103 @@ +.stylepress-setup-wizard { + margin: 20px auto; + max-width: 800px; + + &__steps { + padding: 0 0 24px; + margin: 0; + list-style: none; + overflow: hidden; + color: #ccc; + width: 100%; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + + li { + width: 20%; + float: left; + padding: 0 0 .8em; + margin: 0; + text-align: center; + position: relative; + border-bottom: 4px solid #ccc; + line-height: 1.4em; + + &:before { + content: ""; + border: 4px solid #ccc; + border-radius: 100%; + width: 4px; + height: 4px; + position: absolute; + bottom: 0; + left: 50%; + margin-left: -6px; + margin-bottom: -8px; + background: #fff + } + + a { + text-decoration: none; + } + + &.active { + border-color: #0091cd; + color: #0091cd; + + a { + color: #0091cd + } + + &:before { + border-color: #0091cd + } + } + + &.done { + border-color: #0091cd; + color: #0091cd; + + a { + color: #0091cd + } + + &:before { + border-color: #0091cd; + background: #0091cd + } + } + } + } + + &__content { + box-shadow: 0 1px 3px rgba(0, 0, 0, .13); + padding: 20px; + background: #fff; + } + + &__actions { + padding: 10px; + margin: 0 10px; + display: flex; + justify-content: space-between; + } + + &__styles { + display: flex; + flex-wrap: wrap; + } + + &__style { + cursor: pointer; + display: flex; + padding: 10px; + margin: 0 10px 10px 0; + text-align: center; + + &--current { + background: rgba(0, 0, 0, 0.25); + border-radius: 5px; + } + } +} diff --git a/components/wizard/wizard_controller.js b/components/wizard/wizard_controller.js new file mode 100644 index 0000000..e0d7429 --- /dev/null +++ b/components/wizard/wizard_controller.js @@ -0,0 +1,67 @@ +import { Controller } from 'stimulus'; +import loadingButton from 'lib/loading_button'; + +export default class extends Controller { + static values = { + step: String, + nextUrl: String, + prevUrl: String, + ajaxEndpoint: String, + ajaxNonce: String + } + + static targets = [ 'errorMessage', 'nextButton', 'backButton' ] + + connect() { + this.stepRequirements = []; + this.setupNavButtons(); + } + + setErrorMessage( message ) { + this.errorMessageTarget.innerText = message; + } + + clearErrorMessage() { + this.errorMessageTarget.innerText = ''; + } + + registerStepRequirement( callback ) { + this.stepRequirements.push( callback ); + } + + setupNavButtons() { + const nextStepUrl = this.nextUrlValue; + const prevStepUrl = this.prevUrlValue; + this.nextButtonTarget.addEventListener( 'click', ( e ) => { + e.preventDefault(); + this.clearErrorMessage(); + const button = loadingButton( this.nextButtonTarget ); + const requirementPromises = this.stepRequirements.map( callback => { + return callback(); + }); + Promise.all( requirementPromises ) + .then( ( results ) => { + let nextStepUrlWithQueryParams = nextStepUrl; + results.forEach( result => { + if ( result.args ) { + for ( const [ key, value ] of Object.entries( result.args ) ) { + nextStepUrlWithQueryParams = `${nextStepUrlWithQueryParams}&${key}=${value}`; + } + } + }); + window.location.href = nextStepUrlWithQueryParams; + }) + .catch( ( err ) => { + this.setErrorMessage( err.toString() ); + button.done(); + }); + return false; + }); + this.backButtonTarget.addEventListener( 'click', function( e ) { + e.preventDefault(); + loadingButton( this.backButtonTarget ); + window.location.href = prevStepUrl; + return false; + }); + } +} diff --git a/elementor.json b/elementor.json index 3b5c191..8cc5de8 100644 --- a/elementor.json +++ b/elementor.json @@ -9,8 +9,8 @@ "default": "full", "options": { "full": "Large", - "dtbwp_gallery_square": "Square", - "dtbwp_gallery_rounded": "Rounded", + "stylepress_gallery_square": "Square", + "stylepress_gallery_rounded": "Rounded", "thumbnail": "Thumbnail" }, "prefix_class": "stylepress-image-size-" @@ -18,7 +18,7 @@ { "element": "heading", "appendto": "stylepress_title_style", - "name": "dtbaker_title_under", + "name": "stylepress_title_under", "title": "Title Underline", "type": "select", "default": "underline", @@ -46,4 +46,4 @@ "prefix_class": "stylepress-section-color-" } ] -} \ No newline at end of file +} diff --git a/extensions/cf7/cf7.class.php b/extensions/cf7/cf7.class.php new file mode 100644 index 0000000..35c73d4 --- /dev/null +++ b/extensions/cf7/cf7.class.php @@ -0,0 +1,626 @@ +start_controls_section( + 'premium_section_wpcf7_form', + [ + 'label' => __( 'Contact Form', 'premium-addons-for-elementor' ) + ] + ); + + + $this->add_control( + 'premium_wpcf7_form', + [ + 'label' => __( 'Select Your Contact Form', 'premium-addons-for-elementor' ), + 'label_block' => true, + 'type' => Controls_Manager::SELECT, + 'options' => $this->premium_contact_form(), + ] + ); + + + $this->end_controls_section(); + + $this->start_controls_section('premium_wpcf7_fields', + [ + 'label' => __('Fields', 'premium-addons-for-elementor'), + ]); + + $this->add_control('premium_wpcf7_fields_heading', + [ + 'label' => __('Width', 'premium-addons-for-elementor'), + 'type' => Controls_Manager::HEADING + ]); + + $this->add_responsive_control( + 'premium_elements_input_width', + [ + 'label' => __( 'Input Field', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', '%' ], + 'range' => [ + 'px' => [ + 'min' => 10, + 'max' => 1200, + ], + 'em' => [ + 'min' => 1, + 'max' => 80, + ], + ], + 'default' => [ + 'size' => 100, + 'unit' => '%' + ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-text' => 'width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'premium_elements_textarea_width', + [ + 'label' => __( 'Text Area', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', '%' ], + 'range' => [ + 'px' => [ + 'min' => 10, + 'max' => 1200, + ], + 'em' => [ + 'min' => 1, + 'max' => 80, + ], + ], + 'default' => [ + 'size' => 100, + 'unit' => '%' + ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container textarea.wpcf7-textarea' => 'width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control('premium_wpcf7_fields_height_heading', + [ + 'label' => __('Height', 'premium-addons-for-elementor'), + 'type' => Controls_Manager::HEADING + ]); + + $this->add_responsive_control( + 'premium_elements_input_height', + [ + 'label' => __( 'Input Field', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em' ], + 'range' => [ + 'px' => [ + 'min' => 10, + 'max' => 500, + ], + 'em' => [ + 'min' => 1, + 'max' => 40, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-text' => 'height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'premium_elements_textarea_height', + [ + 'label' => __( 'Text Area', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em' ], + 'range' => [ + 'px' => [ + 'min' => 10, + 'max' => 1200, + ], + 'em' => [ + 'min' => 1, + 'max' => 80, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container textarea.wpcf7-textarea' => 'height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section('premium_wpcf7_button', + [ + 'label' => __('Button', 'premium-addons-for-elementor'), + ]); + + /*Button Width*/ + $this->add_responsive_control( + 'premium_elements_button_width', + [ + 'label' => __( 'Width', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', '%' ], + 'range' => [ + 'px' => [ + 'min' => 10, + 'max' => 1200, + ], + 'em' => [ + 'min' => 1, + 'max' => 80, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-submit' => 'width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + /*Button Height*/ + $this->add_responsive_control( + 'premium_elements_button_height', + [ + 'label' => __( 'Height', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em' ], + 'range' => [ + 'px' => [ + 'min' => 10, + 'max' => 500, + ], + 'em' => [ + 'min' => 1, + 'max' => 40, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-submit' => 'height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_contact_form_styles', + [ + 'label' => __( 'Form', 'premium-addons-for-elementor' ), + 'tab' => Controls_Manager::TAB_STYLE + ] + ); + $this->add_control( + 'premium_elements_input_background', + [ + 'label' => __( 'Input Field Background', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-text, {{WRAPPER}} .premium-elements-contact-form-container textarea.wpcf7-textarea' => 'background: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'premium_elements_input_padding', + [ + 'label' => __( 'Padding', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', 'em', '%' ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-text, {{WRAPPER}} .premium-elements-contact-form-container textarea.wpcf7-textarea' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'premium_elements_input_border', + 'selector' => '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-text, {{WRAPPER}} .premium-elements-contact-form-container textarea.wpcf7-textarea', + ] + ); + + $this->add_responsive_control( + 'premium_elements_input_border_radius', + [ + 'label' => __( 'Border Radius', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px' ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-text, {{WRAPPER}} .premium-elements-contact-form-container textarea.wpcf7-textarea' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'premium_elements_input_margin', + [ + 'label' => __( 'Margin', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', 'em', '%' ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-text, {{WRAPPER}} .premium-elements-contact-form-container textarea.wpcf7-textarea' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'premium_elements_input_focus', + [ + 'label' => __( 'Focus Border Color', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-text:focus, {{WRAPPER}} .premium-elements-contact-form-container textarea.wpcf7-textarea:focus' => 'border-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'premium_elements_input_focus_border_animation', + [ + 'label' => __( 'Focus Border Animation', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::SELECT, + 'options' => array( + 'premium_border_animation1' => 'On', + 'premium_border_animation2' => 'Off', + ), + 'default' => 'premium_border_animation2', + ] + ); + + $this->add_control( + 'premium_elements_input_focus_border_color', + [ + 'label' => __( 'Focus Line Color', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::COLOR, + 'condition' => [ + 'premium_elements_input_focus_border_animation' => 'premium_border_animation1' + ], + 'selectors' => [ + '{{WRAPPER}} .premium_border_animation1 .wpcf7-span.is-focused::after' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'input_button_shadow', + 'selector' => '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-text, {{WRAPPER}} .premium-elements-contact-form-container textarea.wpcf7-textarea', + ] + ); + + + $this->end_controls_section(); + + + $this->start_controls_section( + 'section_contact_form_typography', + [ + 'label' => __( 'Labels', 'premium-addons-for-elementor' ), + 'tab' => Controls_Manager::TAB_STYLE + ] + ); + + + $this->add_control( + 'premium_elements_heading_default', + [ + 'type' => Controls_Manager::HEADING, + 'label' => __( 'Default Typography', 'premium-addons-for-elementor' ), + ] + ); + + $this->add_control( + 'premium_elements_contact_form_color', + [ + 'label' => __( 'Default Font Color', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::COLOR, + 'scheme' => [ + 'type' => Scheme_Color::get_type(), + 'value' => Scheme_Color::COLOR_1, + ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container, {{WRAPPER}} .premium-elements-contact-form-container label' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'premium_elements_contact_form_default_typography', + 'scheme' => Scheme_Typography::TYPOGRAPHY_1, + 'selector' => '{{WRAPPER}} .premium-elements-contact-form-container', + ] + ); + + $this->add_control( + 'premium_elements_heading_input', + [ + 'type' => Controls_Manager::HEADING, + 'label' => __( 'Input Typography', 'premium-addons-for-elementor' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'premium_elements_contact_form_field_color', + [ + 'label' => __( 'Input Text Color', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::COLOR, + 'scheme' => [ + 'type' => Scheme_Color::get_type(), + 'value' => Scheme_Color::COLOR_1, + ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-text, {{WRAPPER}} .premium-elements-contact-form-container textarea.wpcf7-textarea' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'premium_elements_contact_form_field_typography', + 'scheme' => Scheme_Typography::TYPOGRAPHY_1, + 'selector' => '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-text, {{WRAPPER}} .premium-elements-contact-form-container textarea.wpcf7-textarea', + ] + ); + + + $this->add_control( + 'premium_elements_contact_form_placeholder_color', + [ + 'label' => __( 'Placeholder Color', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container ::-webkit-input-placeholder' => 'color: {{VALUE}};', + '{{WRAPPER}} .premium-elements-contact-form-container ::-moz-placeholder' => 'color: {{VALUE}};', + '{{WRAPPER}} .premium-elements-contact-form-container ::-ms-input-placeholder' => 'color: {{VALUE}};', + ], + ] + ); + + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_contact_form_submit_button_styles', + [ + 'label' => __( 'Button', 'premium-addons-for-elementor' ), + 'tab' => Controls_Manager::TAB_STYLE + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'section_title_premium_btn_typography', + 'scheme' => Scheme_Typography::TYPOGRAPHY_1, + 'selector' => '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-submit', + ] + ); + + $this->add_responsive_control( + 'section_title_premium_btn_padding', + [ + 'label' => __( 'Padding', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', 'em', '%' ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-submit' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + + + $this->start_controls_tabs( 'premium_elements_button_tabs' ); + + $this->start_controls_tab( 'normal', [ 'label' => __( 'Normal', 'premium-addons-for-elementor' ) ] ); + + $this->add_control( + 'premium_elements_button_text_color', + [ + 'label' => __( 'Text Color', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-submit' => 'color: {{VALUE}};', + ], + ] + ); + + + + $this->add_control( + 'premium_elements_button_background_color', + [ + 'label' => __( 'Background Color', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::COLOR, + 'scheme' => [ + 'type' => Scheme_Color::get_type(), + 'value' => Scheme_Color::COLOR_1, + ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-submit' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'premium_elements_btn_border', + 'selector' => '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-submit', + ] + ); + + $this->add_responsive_control( + 'premium_elements_btn_border_radius', + [ + 'label' => __( 'Border Radius', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-submit' => 'border-radius: {{SIZE}}px;', + ], + ] + ); + + + + $this->end_controls_tab(); + + $this->start_controls_tab( 'premium_elements_hover', [ 'label' => __( 'Hover', 'premium-addons-for-elementor' ) ] ); + + $this->add_control( + 'premium_elements_button_hover_text_color', + [ + 'label' => __( 'Text Color', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-submit:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'premium_elements_button_hover_background_color', + [ + 'label' => __( 'Background Color', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-submit:hover' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'premium_elements_button_hover_border_color', + [ + 'label' => __( 'Border Color', 'premium-addons-for-elementor' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-submit:hover' => 'border-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'button_box_shadow', + 'selector' => '{{WRAPPER}} .premium-elements-contact-form-container input.wpcf7-submit', + ] + ); + + + $this->end_controls_section(); + + + } + + protected function premium_contact_form( ) { + + if ( ! class_exists( 'WPCF7_ContactForm' ) ) { + return array(); + } + + $forms = \WPCF7_ContactForm::find( array( + 'orderby' => 'title', + 'order' => 'ASC', + ) ); + + if ( empty( $forms ) ) { + return array(); + } + + $result = array(); + + foreach ( $forms as $item ) { + $key = sprintf( '%1$s::%2$s', $item->id(), $item->title() ); + $result[ $key ] = $item->title(); + } + + return $result; + } + protected function render() { + + $settings = $this->get_settings(); + + + if ( ! empty( $settings['premium_wpcf7_form'] ) ) {?> + +
+ + +
+ +
    get_replace_fields(); foreach ( $available_callbacks as $key => $title ) { ?>
  • {{}}
  • @@ -113,8 +114,8 @@ function stylepress_dynamic_before_render( $widget ) { if ( $widget->get_name() === 'section' || $widget->get_name() === 'column' ) { $settings = $widget->get_active_settings(); if ( ! empty( $settings['stylepress_enable_dynamic_bg'] ) && $settings['stylepress_enable_dynamic_bg'] === 'yes' ) { - require_once DTBAKER_ELEMENTOR_PATH . 'extensions/dynamic-field/class.dynamic-field.php'; - $dyno_generator = \DtbakerDynamicField::get_instance(); + require_once STYLEPRESS_PATH . 'extensions/dynamic-field/class.dynamic-field.php'; + $dyno_generator = StylePressDynamicField::get_instance(); $image_url = $dyno_generator->post_thumbnail(); if ( $image_url ) { $widget->add_render_attribute( '_wrapper', 'style', 'background-image: url("' . esc_url( $image_url ) . '") !important;' ); @@ -157,8 +158,8 @@ function stylepress_dynamic_before_render( $widget ) { $do_link = true; break; } - require_once DTBAKER_ELEMENTOR_PATH . 'extensions/dynamic-field/class.dynamic-field.php'; - $dyno_generator = \DtbakerDynamicField::get_instance(); + require_once STYLEPRESS_PATH . 'extensions/dynamic-field/class.dynamic-field.php'; + $dyno_generator = StylePressDynamicField::get_instance(); // $available_callbacks = $dyno_generator->get_replace_fields(); foreach ( $fields as $field ) { @@ -206,9 +207,9 @@ function stylepress_dynamic_before_render( $widget ) { /* // print_r($settings); //$widget->set_settings($key,$val); - if ( ! empty( $settings['dtbaker_modal_content'] ) ) { + if ( ! empty( $settings['stylepress_modal_content'] ) ) { - $popup_template = (int)$settings['dtbaker_modal_content']; + $popup_template = (int)$settings['stylepress_modal_content']; $width = '400px'; if ( ! empty( $settings['modal_width'] ) ) { $width = $settings['modal_width']['size'] . $settings['modal_width']['unit']; @@ -242,10 +243,10 @@ function stylepress_dynamic_before_render( $widget ) { } foreach ( $supported_widgets as $widget_name => $widget_options ) { - add_action( 'elementor/element/' . $widget_name . '/' . $widget_options['section'] . '/after_section_end', 'stylepress_register_dynamics', 10, 2 ); + add_action( 'elementor/element/' . $widget_name . '/' . $widget_options['section'] . '/after_section_end', 'StylePress\stylepress_register_dynamics', 10, 2 ); } -add_action( 'elementor/frontend/widget/before_render', 'stylepress_dynamic_before_render', 10, 1 ); -add_action( 'elementor/frontend/element/before_render', 'stylepress_dynamic_before_render', 10, 1 ); +add_action( 'elementor/frontend/widget/before_render', 'StylePress\stylepress_dynamic_before_render', 10, 1 ); +add_action( 'elementor/frontend/element/before_render', 'StylePress\stylepress_dynamic_before_render', 10, 1 ); // dynamic background image on certain elements. -add_action( 'elementor/element/section/section_background/before_section_end', 'stylepress_register_dynamic_background', 10, 2 ); \ No newline at end of file +add_action( 'elementor/element/section/section_background/before_section_end', 'StylePress\stylepress_register_dynamic_background', 10, 2 ); \ No newline at end of file diff --git a/extensions/dynamic-field/widget.dynamic-field.php b/extensions/dynamic-field/widget.dynamic-field.php index c21e36d..660b6d0 100644 --- a/extensions/dynamic-field/widget.dynamic-field.php +++ b/extensions/dynamic-field/widget.dynamic-field.php @@ -2,7 +2,7 @@ /** * WordPress Nav Menu Widget * - * @package dtbaker-elementor + * @package stylepress */ namespace Elementor; @@ -15,11 +15,11 @@ /** * Creates our custom Elementor widget * - * Class Widget_Dtbaker_WP_Menu + * Class Widget_stylepress_WP_Menu * * @package Elementor */ -class Widget_Dtbaker_Dynamic_Field extends Widget_Base { +class Widget_stylepress_Dynamic_Field extends Widget_Base { /** * Get Widgets name @@ -27,7 +27,7 @@ class Widget_Dtbaker_Dynamic_Field extends Widget_Base { * @return string */ public function get_name() { - return 'dtbaker_dynamic'; + return 'stylepress_dynamic'; } /** @@ -41,12 +41,12 @@ public function get_title() { /** * Get the current icon for display on frontend. - * The extra 'dtbaker-elementor-widget' class is styled differently in frontend.css + * The extra 'stylepress-widget' class is styled differently in frontend.css * * @return string */ public function get_icon() { - return 'dtbaker-stylepress-elementor-widget'; + return 'stylepress-elementor-widget'; } /** @@ -55,7 +55,7 @@ public function get_icon() { * @return array */ public function get_categories() { - return [ 'dtbaker-elementor' ]; + return [ 'stylepress' ]; } /** @@ -73,7 +73,7 @@ public function show_in_panel() { protected function _register_controls() { $this->start_controls_section( - 'section_dtbaker_wp_menu', + 'section_stylepress_wp_menu', [ 'label' => __( 'Dynamic Field', 'stylepress' ), ] @@ -111,7 +111,7 @@ protected function _register_controls() { 'type' => Controls_Manager::RAW_HTML, 'separator' => 'none', 'show_label' => false, - 'raw' => '
    ', + 'raw' => '
    ', ] ); @@ -129,7 +129,7 @@ protected function _register_controls() { $this->end_controls_section(); - do_action( 'dtbaker_wp_menu_elementor_controls', $this ); + do_action( 'stylepress_wp_menu_elementor_controls', $this ); } @@ -181,8 +181,8 @@ protected function render() { $callback = $settings['dynamic_html']; } if ( $callback ) { - require_once DTBAKER_ELEMENTOR_PATH . 'extensions/dynamic-field/class.dynamic-field.php'; - $dyno_generator = \DtbakerDynamicField::get_instance(); + require_once STYLEPRESS_PATH . 'extensions/dynamic-field/class.dynamic-field.php'; + $dyno_generator = StylePressDynamicField::get_instance(); if ( preg_match_all( '#\{\{([a-z_]+)\}\}#imsU', $callback, $matches ) ) { foreach ( $matches[1] as $key => $field ) { @@ -202,7 +202,7 @@ protected function render() { */ protected function content_template() { ?> -
    +
    {{Dynamic Field Here}}
    widgets_manager->register_widget_type( new Widget_Dtbaker_Dynamic_Field() ); \ No newline at end of file +Plugin::instance()->widgets_manager->register_widget_type( new Widget_stylepress_Dynamic_Field() ); \ No newline at end of file diff --git a/extensions/email-subscribe/email-subscribe.php b/extensions/email-subscribe/email-subscribe.php index eae5cef..06c9871 100644 --- a/extensions/email-subscribe/email-subscribe.php +++ b/extensions/email-subscribe/email-subscribe.php @@ -1,19 +1,19 @@ admin_url( 'admin-ajax.php' ) ) ); wp_enqueue_script( 'stylepress-email-script' ); } ); // todo: option these out in 'Add-Ons' section -require_once DTBAKER_ELEMENTOR_PATH . 'extensions/email-subscribe/widget.email-subscribe.php'; +require_once STYLEPRESS_PATH . 'extensions/email-subscribe/widget.email-subscribe.php'; add_action( 'wp_ajax_stylepress_email_sub', function () { diff --git a/extensions/email-subscribe/subscribe.js b/extensions/email-subscribe/subscribe.js index 5481e50..a34c979 100644 --- a/extensions/email-subscribe/subscribe.js +++ b/extensions/email-subscribe/subscribe.js @@ -1,47 +1,47 @@ /** * Frontend Elementor Tweaks * - * @package dtbaker-elementor + * @package stylepress */ -(function ($) { +( function( $ ) { function do_email_subscribe() { - var $parent = $(this).parent(); - var elm = $parent.data('elm'); - var post = $parent.data('post'); - var email = $parent.find('.stylepress-subscribe-email').val(); - $parent.find('.stylepress-email-status').text(''); - $parent.addClass('submitting'); - - $.post(stylepress_email.ajax_url, { + var $parent = $( this ).parent(); + var elm = $parent.data( 'elm' ); + var post = $parent.data( 'post' ); + var email = $parent.find( '.stylepress-subscribe-email' ).val(); + $parent.find( '.stylepress-email-status' ).text( '' ); + $parent.addClass( 'submitting' ); + + $.post( stylepress_email.ajax_url, { 'action': 'stylepress_email_sub', 'email': email, 'post': post, 'elm': elm - }, function (response) { + }, function( response ) { - $parent.removeClass('submitting').addClass('submitted'); - if (response && response.success) { - $parent.addClass('success'); + $parent.removeClass( 'submitting' ).addClass( 'submitted' ); + if ( response && response.success ) { + $parent.addClass( 'success' ); } else { - $parent.addClass('failure'); + $parent.addClass( 'failure' ); } - if (response && response.data) { - $parent.find('.stylepress-email-status').text(response.data); + if ( response && response.data ) { + $parent.find( '.stylepress-email-status' ).text( response.data ); } - }, 'json'); + }, 'json' ); } - $(function () { - $('.stylepress-subscribe-send').click(do_email_subscribe); - $('.stylepress-subscribe-email').on('keyup', function (event) { - if (event.keyCode == 13) { - do_email_subscribe.call(this); + $( function() { + $( '.stylepress-subscribe-send' ).click( do_email_subscribe ); + $( '.stylepress-subscribe-email' ).on( 'keyup', function( event ) { + if ( 13 == event.keyCode ) { + do_email_subscribe.call( this ); } }); }); -})(jQuery); +}( jQuery ) ); diff --git a/extensions/email-subscribe/widget.email-subscribe.php b/extensions/email-subscribe/widget.email-subscribe.php index 93a0045..cd40e65 100644 --- a/extensions/email-subscribe/widget.email-subscribe.php +++ b/extensions/email-subscribe/widget.email-subscribe.php @@ -2,7 +2,7 @@ /** * WordPress Nav Menu Widget * - * @package dtbaker-elementor + * @package stylepress */ namespace Elementor; @@ -15,11 +15,11 @@ /** * Creates our custom Elementor widget * - * Class Widget_Dtbaker_WP_Menu + * Class Widget_stylepress_WP_Menu * * @package Elementor */ -class Widget_Dtbaker_Email_Subscribe extends Widget_Base { +class Widget_stylepress_Email_Subscribe extends Widget_Base { /** @@ -42,12 +42,12 @@ public function get_title() { /** * Get the current icon for display on frontend. - * The extra 'dtbaker-elementor-widget' class is styled differently in frontend.css + * The extra 'stylepress-widget' class is styled differently in frontend.css * * @return string */ public function get_icon() { - return 'dtbaker-stylepress-elementor-widget'; + return 'stylepress-elementor-widget'; } /** @@ -56,7 +56,7 @@ public function get_icon() { * @return array */ public function get_categories() { - return [ 'dtbaker-elementor' ]; + return [ 'stylepress' ]; } /** @@ -74,7 +74,7 @@ public function show_in_panel() { protected function _register_controls() { $this->start_controls_section( - 'section_dtbaker_wp_menu', + 'section_stylepress_wp_menu', [ 'label' => __( 'Email Subscribe', 'stylepress' ), ] @@ -234,4 +234,4 @@ protected function content_template() { } -Plugin::instance()->widgets_manager->register_widget_type( new Widget_Dtbaker_Email_Subscribe() ); \ No newline at end of file +Plugin::instance()->widgets_manager->register_widget_type( new Widget_stylepress_Email_Subscribe() ); \ No newline at end of file diff --git a/extensions/form/form-fields.php b/extensions/form/form-fields.php index d778386..22f7461 100644 --- a/extensions/form/form-fields.php +++ b/extensions/form/form-fields.php @@ -1,16 +1,16 @@ (description
    '; return inputField; @@ -28,4 +29,4 @@ }); -})(jQuery); \ No newline at end of file +}( jQuery ) ); diff --git a/extensions/form/frontend.js b/extensions/form/frontend.js index 25e2cf2..2e075f6 100644 --- a/extensions/form/frontend.js +++ b/extensions/form/frontend.js @@ -1,16 +1,17 @@ function stylepress_datepicker() { - if (jQuery.fn.datepicker) { - jQuery(".stylepress-datepicker").removeAttr('id').datepicker({ + if ( jQuery.fn.datepicker ) { + jQuery( '.stylepress-datepicker' ).removeAttr( 'id' ).datepicker({ + //comment the beforeShow handler if you want to see the ugly overlay - beforeShow: function () { - setTimeout(function () { - jQuery('.ui-datepicker').css('z-index', 999999); - }, 0); + beforeShow: function() { + setTimeout( function() { + jQuery( '.ui-datepicker' ).css( 'z-index', 999999 ); + }, 0 ); } }); } } -jQuery(document).ready(function ($) { +jQuery( document ).ready( function( $ ) { stylepress_datepicker(); -}); \ No newline at end of file +}); diff --git a/extensions/google-maps/google-maps.php b/extensions/google-maps/google-maps.php index 3a767b9..92a64ca 100644 --- a/extensions/google-maps/google-maps.php +++ b/extensions/google-maps/google-maps.php @@ -2,24 +2,25 @@ /** - * Class dtbaker_Widget_Google_Map and dtbaker_Shortcode_Google_Map + * Class stylepress_Widget_Google_Map and stylepress_Shortcode_Google_Map * Easily create a Google Map on any WordPress post/page (with an insert map button). * Easily create a Google Map in any Widget Area. - * Author: dtbaker@gmail.com + * Author: stylepress@gmail.com * Copyright 2014 */ +namespace StylePress; -defined( 'DTBAKER_ELEMENTOR_PATH' ) || exit; +defined( 'STYLEPRESS_PATH' ) || exit; add_action( 'wp_enqueue_scripts', function () { // ?libraries=places - wp_register_script( 'googlemaps', 'https://maps.googleapis.com/maps/api/js?key=' . esc_attr( get_option( 'google_maps_api_key', 'AIzaSyBsnYWO4SSibatp0SjsU9D2aZ6urI-_cJ8' ) ) . '&sensor=false', false, '3' ); + wp_register_script( 'googlemaps', 'https://maps.googleapis.com/maps/api/js?key=' . esc_attr( get_option( 'google_maps_api_key', '' ) ) . '&sensor=false', false, '3' ); - wp_register_style( 'stylepress-google-map', DTBAKER_ELEMENTOR_URI . 'extensions/google-maps/google-maps.css' ); + wp_register_style( 'stylepress-google-map', STYLEPRESS_URI . 'extensions/google-maps/google-maps.css' ); if ( isset( $_GET['elementor'] ) || isset( $_GET['elementor-preview'] ) ) { //\Elementor\Plugin::$instance->editor->is_edit_mode()){ wp_enqueue_script( 'googlemaps' ); @@ -29,16 +30,16 @@ } ); -$widget_file = DTBAKER_ELEMENTOR_PATH . 'extensions/google-maps/widget.google-map.php'; +$widget_file = STYLEPRESS_PATH . 'extensions/google-maps/widget.google-map.php'; //$template_file = locate_template( $widget_file ); //if ( $template_file && is_readable( $template_file ) ) { require_once $widget_file; -add_action( 'customize_register', 'stylepress_register_google_maps_customize_control' ); +add_action( 'customize_register', 'StylePress\stylepress_register_google_maps_customize_control' ); function stylepress_register_google_maps_customize_control() { - class stylepress_Google_Maps_Custom_Text_Control extends WP_Customize_Control { + class stylepress_Google_Maps_Custom_Text_Control extends \WP_Customize_Control { public $type = 'google_maps_customtext'; public $extra = ''; // we add this for the extra description @@ -52,7 +53,7 @@ public function render_content() { } } -class stylepress_dtbaker_Widget_Google_Map extends WP_Widget { +class stylepress_Widget_Google_Map extends \WP_Widget { /** constructor */ function __construct() { $widget_ops = array( @@ -68,8 +69,8 @@ function widget( $args, $instance ) { echo $before_widget; echo $title ? ( $before_title . $title . $after_title ) : ''; // fire our shortcode below to generate map output. - $shortcode = dtbaker_Shortcode_Google_Map::get_instance(); - echo $shortcode->dtbaker_shortcode_gmap( $instance, isset( $instance['innercontent'] ) ? $instance['innercontent'] : '' ); + $shortcode = StylePress_Shortcode_Google_Map::get_instance(); + echo $shortcode->stylepress_shortcode_gmap( $instance, isset( $instance['innercontent'] ) ? $instance['innercontent'] : '' ); echo $after_widget; } @@ -88,7 +89,7 @@ function form( $instance ) {

    fields as $field ) { ?>

    @@ -293,7 +296,7 @@ function codeAddress() { return preg_replace( "#\s+#", ' ', ob_get_clean() ); } - // copied from dtbaker location plugin + // copied from stylepress location plugin public static function get_map_styles( $type, $atts = array() ) { if ( ! empty( $atts['mapstyle'] ) ) { @@ -354,7 +357,7 @@ public static function get_map_styles( $type, $atts = array() ) { ), ), ); - $styles = apply_filters( 'dtbaker_google_map_styles', $styles ); + $styles = apply_filters( 'stylepress_google_map_styles', $styles ); switch ( $type ) { case 'js': $js_array = array(); @@ -438,6 +441,6 @@ public static function get_map_styles( $type, $atts = array() ) { ); } -stylepress_dtbaker_Shortcode_Google_Map::get_instance()->init(); +StylePress_Shortcode_Google_Map::get_instance()->init(); diff --git a/extensions/google-maps/widget.google-map.php b/extensions/google-maps/widget.google-map.php index eb4db64..dd23235 100644 --- a/extensions/google-maps/widget.google-map.php +++ b/extensions/google-maps/widget.google-map.php @@ -6,7 +6,7 @@ exit; } // Exit if accessed directly -class StylePress_Google_Map extends Widget_Base { +class StylePress_Custom_Google_Map extends Widget_Base { public function get_name() { return 'stylepress-google-map'; @@ -22,12 +22,12 @@ public function get_script_depends() { /** * Get the current icon for display on frontend. - * The extra 'dtbaker-elementor-widget' class is styled differently in frontend.css + * The extra 'stylepress-widget' class is styled differently in frontend.css * * @return string */ public function get_icon() { - return 'dtbaker-stylepress-elementor-widget'; + return 'stylepress-elementor-widget'; } @@ -37,7 +37,7 @@ public function get_icon() { * @return array */ public function get_categories() { - return [ 'dtbaker-elementor' ]; + return [ 'stylepress' ]; } /** @@ -144,6 +144,16 @@ protected function _register_controls() { ] ); + if ( ! get_option( 'google_maps_api_key', '' ) ) { + $this->add_control( + 'maps_api_key', + [ + 'label' => sprintf( __( 'Important Please click here to enter a Google Maps API Key in the Customizer. A Google Maps API key is required for maps to generate correctly.', 'stylepress' ), admin_url( '/customize.php?autofocus[section]=stylepress_google_map' ) ), + 'type' => Controls_Manager::RAW_HTML, + ] + ); + } + $this->end_controls_section(); @@ -239,7 +249,7 @@ protected function _register_controls() { $this->end_controls_section(); - do_action( 'dtbaker_wp_menu_elementor_controls', $this ); + do_action( 'stylepress_wp_menu_elementor_controls', $this ); } protected function render() { @@ -247,7 +257,7 @@ protected function render() { $instance = $this->get_settings(); $shortcode = '[stylepress_google_map '; - foreach ( \stylepress_dtbaker_Shortcode_Google_Map::get_instance()->fields as $field ) { + foreach ( \StylePress\StylePress_Shortcode_Google_Map::get_instance()->fields as $field ) { $value = isset( $instance[ $field['name'] ] ) ? $instance[ $field['name'] ] : $field['default']; if ( $field['name'] == 'mapstyle' ) { $value = str_replace( '[', '[', $value ); @@ -269,11 +279,11 @@ protected function render() { protected function content_template() { ?> -
    +
    The Google Map Will Appear Here
    widgets_manager->register_widget_type( new StylePress_Google_Map() ); \ No newline at end of file +Plugin::instance()->widgets_manager->register_widget_type( new StylePress_Custom_Google_Map() ); \ No newline at end of file diff --git a/extensions/inner-content/inner-content.php b/extensions/inner-content/inner-content.php new file mode 100644 index 0000000..11584d2 --- /dev/null +++ b/extensions/inner-content/inner-content.php @@ -0,0 +1,118 @@ +is_editing_internal_content_page(); + + } + + /** + * This registers our controls for the widget. Currently there are none but we may add options down the track. + */ + protected function _register_controls() { + + $this->start_controls_section( + 'section_stylepress_wp_menu', + [ + 'label' => __( 'Inner Content', 'stylepress' ), + ] + ); + + + $this->end_controls_section(); + + } + + + /** + * Render our custom menu onto the page. + */ + protected function render() { + if ( ! empty( $GLOBALS['stylepress_render']['has_done_inner_content'] ) ) { + return; + } + $editing_this_template = false; + if ( Plugin::$instance->editor->is_edit_mode() || Plugin::$instance->preview->is_preview_mode() ) { + $post = get_post(); + if ( $post->post_type === \StylePress\Styles::CPT ) { + $editing_this_template = true; + } + } + if ( ! $editing_this_template ) { + //$settings = $this->get_settings(); + if ( ! is_404() ) { + \StylePress\Plugin::get_instance()->debug_message( 'Rendering inner_content() from Widget' ); + if ( have_posts() ) { + the_post(); + the_content(); + } + $GLOBALS['stylepress_render']['has_done_inner_content'] = true; + } + } else { + $this->content_template(); + } + } + + /** + * This is outputted while rending the page. + */ + protected function content_template() { + ?> +
    + Your Page Content Will Appear Here +
    + widgets_manager->register_widget_type( new Stylepress_Inner_Content() ); + diff --git a/extensions/modal-popup/popup.css b/extensions/modal-popup/css/modal-popup.css similarity index 100% rename from extensions/modal-popup/popup.css rename to extensions/modal-popup/css/modal-popup.css diff --git a/extensions/modal-popup/popup.less b/extensions/modal-popup/css/modal-popup.less similarity index 100% rename from extensions/modal-popup/popup.less rename to extensions/modal-popup/css/modal-popup.less diff --git a/extensions/modal-popup/elementor.url-control.php b/extensions/modal-popup/elementor.url-control.php index 2b200fc..8bf100b 100644 --- a/extensions/modal-popup/elementor.url-control.php +++ b/extensions/modal-popup/elementor.url-control.php @@ -19,9 +19,9 @@ * @param bool $show_external Whether to show the 'Is External' button * Default true * - * @since 1.0.0 + * @since 2.0.0 */ -class StylePress_Control_URL extends Control_Base_Multiple { +class StylePress_Custom_Control_URL extends Control_Base_Multiple { public function get_type() { return 'url'; diff --git a/extensions/modal-popup/popup.js b/extensions/modal-popup/js/modal-popup.js similarity index 51% rename from extensions/modal-popup/popup.js rename to extensions/modal-popup/js/modal-popup.js index 666d8a7..55e9caa 100644 --- a/extensions/modal-popup/popup.js +++ b/extensions/modal-popup/js/modal-popup.js @@ -1,11 +1,11 @@ /** * Payment pay * - * @package dtbaker-elementor + * @package stylepress */ -(function ($) { +( function( $ ) { var $dialog = false; var current_modal = {}; @@ -13,71 +13,74 @@ function close_slideins() { - $(document).off('keyup.stylepressmodal'); - $('body').removeClass('showing_side_menu'); - $('#stylepressslideinstyles').remove(); + $( document ).off( 'keyup.stylepressmodal' ); + $( 'body' ).removeClass( 'showing_side_menu' ); + $( '#stylepressslideinstyles' ).remove(); $current_slidein = null; } - function show_slidein(slideinid) { - $slidein = $('.stylepress_slide_in_menu[data-id="' + slideinid + '"]'); - if ($slidein.length) { + function show_slidein( slideinid ) { + $slidein = $( '.stylepress_slide_in_menu[data-id="' + slideinid + '"]' ); + if ( $slidein.length ) { // console.log($current_slidein); // console.log($slidein); // console.log($current_slidein == $slidein); - if ($current_slidein && $current_slidein[0] == $slidein[0]) { + if ( $current_slidein && $current_slidein[0] == $slidein[0]) { close_slideins(); return; } close_slideins(); $current_slidein = $slidein; - $(document).on('keyup.stylepressmodal', function (e) { - if (e.keyCode == 27) { // escape key maps to keycode `27` + $( document ).on( 'keyup.stylepressmodal', function( e ) { + if ( 27 == e.keyCode ) { // escape key maps to keycode `27` close_slideins(); } }); var size = $slidein.outerWidth(); + // var size = parseInt($slidein.data('size')); // if(!size)size = 400; // $('head').append(''); // account for sidebar padding // size += 60; - $('head').append(''); - $('.stylepress_slide_in_menu').removeClass('shown'); - $slidein.addClass('shown'); - $('body').addClass('showing_side_menu'); + $( 'head' ).append( '' ); + $( '.stylepress_slide_in_menu' ).removeClass( 'shown' ); + $slidein.addClass( 'shown' ); + $( 'body' ).addClass( 'showing_side_menu' ); } else { - alert('Slide in failure'); + alert( 'Slide in failure' ); } } function open_popup() { - if (typeof current_modal.display != 'undefined' && current_modal.display == 1) { + if ( 'undefined' != typeof current_modal.display && 1 == current_modal.display ) { + // we're showing a slide in - show_slidein(current_modal.id); + show_slidein( current_modal.id ); return; } + // todo: push/pop active dialogs to support multiple. - if ($dialog) { - $dialog.dialog('close'); + if ( $dialog ) { + $dialog.dialog( 'close' ); } - $dialog = $('#stylepress-modal-pop-' + current_modal.id); + $dialog = $( '#stylepress-modal-pop-' + current_modal.id ); var width = '500px'; - if (typeof current_modal.settings != 'undefined' && typeof current_modal.settings.modal_width != 'undefined') { + if ( 'undefined' != typeof current_modal.settings && 'undefined' != typeof current_modal.settings.modal_width ) { width = current_modal.settings.modal_width; - } else if (typeof current_modal.width != 'undefined') { + } else if ( 'undefined' != typeof current_modal.width ) { width = current_modal.width; } - var px = parseInt(width); - if (px > window.innerWidth) { - width = (window.innerWidth - 20); - width = width + "px"; + var px = parseInt( width ); + if ( px > window.innerWidth ) { + width = ( window.innerWidth - 20 ); + width = width + 'px'; } $dialog.dialog({ @@ -91,19 +94,20 @@ resizable: false, closeOnEscape: true, position: { - my: "center", - at: "center", + my: 'center', + at: 'center', of: window }, - open: function () { + open: function() { + // close dialog by clicking the overlay behind it - $dialog.find('.ui-widget-overlay').bind('click', function () { - $dialog.dialog('close'); + $dialog.find( '.ui-widget-overlay' ).bind( 'click', function() { + $dialog.dialog( 'close' ); }); - var $wrapper = $dialog.parents('.stylepress-modal'); - var currentTop = parseInt($wrapper.css('top')); - if (currentTop <= 130) { - $wrapper.css('top', '130px'); + var $wrapper = $dialog.parents( '.stylepress-modal' ); + var currentTop = parseInt( $wrapper.css( 'top' ) ); + if ( 130 >= currentTop ) { + $wrapper.css( 'top', '130px' ); } // stylepress_datepicker(); @@ -126,18 +130,19 @@ }, 'html');*/ }, - create: function () { + create: function() { + // style fix for WordPress admin - $dialog.find('.ui-dialog-titlebar-close').addClass('ui-button'); + $dialog.find( '.ui-dialog-titlebar-close' ).addClass( 'ui-button' ); } }); } - $('body').on('click', '.elementor-widget-stylepress_modal_button, .elementor-widget-button, .elementor-widget-icon-box', function (e) { + $( 'body' ).on( 'click', '.elementor-widget-stylepress_modal_button, .elementor-widget-button, .elementor-widget-icon-box', function( e ) { - var data = $(this).data('stylepressmodal'); - if (data) { + var data = $( this ).data( 'stylepressmodal' ); + if ( data ) { var postdata = { id: data.id, //$(this).data('id'), settings: data @@ -148,26 +153,26 @@ return false; } }); - $('body').on('click', 'a[data-stylepressmodal]', function (e) { - var postdata = $(this).data('stylepressmodal'); + $( 'body' ).on( 'click', 'a[data-stylepressmodal]', function( e ) { + var postdata = $( this ).data( 'stylepressmodal' ); e.preventDefault(); current_modal = postdata; open_popup(); return false; }); - $('body').on('click', '.ui-widget-overlay', function () { - if ($dialog) { - $dialog.dialog('close'); + $( 'body' ).on( 'click', '.ui-widget-overlay', function() { + if ( $dialog ) { + $dialog.dialog( 'close' ); } }); - $('body').on('click', '.close_sidebar', function (e) { + $( 'body' ).on( 'click', '.close_sidebar', function( e ) { e.preventDefault(); close_slideins(); return false; }); -})(jQuery); +}( jQuery ) ); diff --git a/extensions/modal-popup/modal-popup.php b/extensions/modal-popup/modal-popup.php index 2f292c3..40bd40f 100644 --- a/extensions/modal-popup/modal-popup.php +++ b/extensions/modal-popup/modal-popup.php @@ -2,11 +2,12 @@ /** * WordPress Nav Menu Widget * - * @package dtbaker-elementor + * @package stylepress */ +namespace StylePress; -defined( 'DTBAKER_ELEMENTOR_PATH' ) || exit; +defined( 'STYLEPRESS_PATH' ) || exit; $control_id = \Elementor\Controls_Manager::URL; @@ -14,18 +15,18 @@ $control = $elementor->controls_manager->get_control( $control_id ); if ( $control ) { //StylePress_Control_URL - require_once DTBAKER_ELEMENTOR_PATH . 'extensions/modal-popup/elementor.url-control.php'; + require_once STYLEPRESS_PATH . 'extensions/modal-popup/elementor.url-control.php'; - $class_name = 'Elementor\StylePress_Control_URL'; + $class_name = 'Elementor\StylePress_Custom_Control_URL'; $elementor->controls_manager->register_control( $control_id, new $class_name() ); } add_action( 'wp_enqueue_scripts', function () { - wp_register_script( 'stylepress-modal-popup', DTBAKER_ELEMENTOR_URI . 'extensions/modal-popup/popup.js', array( 'jquery' ), DTBAKER_ELEMENTOR_VERSION, true ); + wp_register_script( 'stylepress-modal-popup', STYLEPRESS_URI . 'extensions/modal-popup/js/modal-popup.js', array( 'jquery' ), STYLEPRESS_VERSION, true ); wp_localize_script( 'stylepress-modal-popup', 'stylepress_modal', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) ); - wp_register_style( 'stylepress-modal-button', DTBAKER_ELEMENTOR_URI . 'extensions/modal-popup/popup.css' ); + wp_register_style( 'stylepress-modal-button', STYLEPRESS_URI . 'extensions/modal-popup/css/modal-popup.css' ); } ); add_filter( 'stylepress_modal_link', function ( $link, $popup_template, $options = array() ) { @@ -61,7 +62,7 @@ // EDIT: ajax not used any more, we render template straight on page. // if(!empty($_POST['modal']['id']) && !empty($_POST['modal']['settings'])){ - $modal_id = !empty($_POST['modal']['settings']['dtbaker_modal_content']) ? (int)$_POST['modal']['settings']['dtbaker_modal_content'] : 0; + $modal_id = !empty($_POST['modal']['settings']['stylepress_modal_content']) ? (int)$_POST['modal']['settings']['stylepress_modal_content'] : 0; $modal_hash = !empty($_POST['modal']['settings']['stylepress_modal_hash']) ? $_POST['modal']['settings']['stylepress_modal_hash'] : 0; if($modal_id && $modal_hash && wp_verify_nonce($modal_hash, 'open_modal_' . $modal_id)){ ?> @@ -81,7 +82,7 @@ // function stylepress_modal_button_before_render( $widget ) { - $enabled = array( 'button', 'dtbaker_wp_menu', ); + $enabled = array( 'button', 'stylepress_wp_menu', ); if ( in_array( $widget->get_name(), $enabled ) ) { $settings = $widget->get_active_settings(); if ( ! empty( $settings['link']['stylepress_template'] ) ) { @@ -99,7 +100,7 @@ function stylepress_modal_button_before_render( $widget ) { case 'button': $widget->add_render_attribute( 'button', $data_attr['key'], $data_attr['val'] ); break; - case 'dtbaker_wp_menu': + case 'stylepress_wp_menu': $widget->add_render_attribute( 'link', $data_attr['key'], $data_attr['val'] ); break; } @@ -160,7 +161,7 @@ function stylepress_modal_button_hack( $widget, $args ){ } $widget->add_control( - 'dtbaker_modal_content', + 'stylepress_modal_content', [ 'label' => __( 'Choose Modal Content', 'elementor-pro' ), 'type' => \Elementor\Controls_Manager::SELECT, @@ -171,7 +172,7 @@ function stylepress_modal_button_hack( $widget, $args ){ ] ); $widget->add_control( - 'dtbaker_modal_style', + 'stylepress_modal_style', [ 'label' => __( 'Display Style', 'elementor-pro' ), 'type' => \Elementor\Controls_Manager::SELECT, @@ -217,19 +218,19 @@ function stylepress_modal_button_hack( $widget, $args ){ } ); add_action( 'stylepress/after-render', function () { echo '
    '; - include DTBAKER_ELEMENTOR_PATH . 'extensions/modal-popup/slide-in.php'; + include STYLEPRESS_PATH . 'extensions/modal-popup/slide-in.php'; } ); add_action( 'stylepress/modal-popups', function () { // if there is no before/after render - include DTBAKER_ELEMENTOR_PATH . 'extensions/modal-popup/slide-in.php'; + include STYLEPRESS_PATH . 'extensions/modal-popup/slide-in.php'; } ); //add_action( 'elementor/element/stylepress_modal_button/section_button/after_section_end', 'stylepress_modal_button_hack' , 10 , 2); //add_action( 'elementor/element/button/section_button/after_section_end', 'stylepress_modal_button_hack' , 10 , 2); //add_action( 'elementor/element/icon-box/section_icon/after_section_end', 'stylepress_modal_button_hack' , 10 , 2); -add_action( 'elementor/frontend/widget/before_render', 'stylepress_modal_button_before_render', 10, 1 ); +add_action( 'elementor/frontend/widget/before_render', 'StylePress\stylepress_modal_button_before_render', 10, 1 ); diff --git a/extensions/page-slider/css/page-slider.css b/extensions/page-slider/css/page-slider.css index 9c5ea76..a544967 100644 --- a/extensions/page-slider/css/page-slider.css +++ b/extensions/page-slider/css/page-slider.css @@ -6,12 +6,12 @@ display: block; } } -.elementor-page-carousel-icons .page-carousel-icon-wrapper .elementor-dtbaker-page-slider-icons { +.elementor-page-carousel-icons .page-carousel-icon-wrapper .elementor-stylepress-page-slider-icons { display: table; width: 100%; table-layout: fixed; } -.elementor-page-carousel-icons .page-carousel-icon-wrapper .elementor-dtbaker-page-slider-icons > div { +.elementor-page-carousel-icons .page-carousel-icon-wrapper .elementor-stylepress-page-slider-icons > div { cursor: pointer; display: table-cell; width: 1%; @@ -21,10 +21,10 @@ background: #EFEFEF; transition: background-color 300ms linear; } -.elementor-page-carousel-icons .page-carousel-icon-wrapper .elementor-dtbaker-page-slider-icons > div.current { +.elementor-page-carousel-icons .page-carousel-icon-wrapper .elementor-stylepress-page-slider-icons > div.current { background: #FFF; } -.elementor-page-carousel-icons .page-carousel-icon-wrapper .elementor-dtbaker-page-slider-icons > div h4 { +.elementor-page-carousel-icons .page-carousel-icon-wrapper .elementor-stylepress-page-slider-icons > div h4 { margin: 0; padding: 0; font-weight: normal; diff --git a/extensions/page-slider/css/page-slider.less b/extensions/page-slider/css/page-slider.less index df9659c..6f7d4a7 100644 --- a/extensions/page-slider/css/page-slider.less +++ b/extensions/page-slider/css/page-slider.less @@ -4,7 +4,7 @@ display: block; } .page-carousel-icon-wrapper { - .elementor-dtbaker-page-slider-icons { + .elementor-stylepress-page-slider-icons { display: table; width: 100%; table-layout: fixed; diff --git a/extensions/page-slider/dtbaker-page-slider.php b/extensions/page-slider/dtbaker-page-slider.php deleted file mode 100644 index 9005051..0000000 --- a/extensions/page-slider/dtbaker-page-slider.php +++ /dev/null @@ -1,23 +0,0 @@ -frontend->apply_builder_in_content( $page_html ); // maybe do a set_option get_option hack to prevent fatal errors on elementor attempts? @@ -598,7 +608,7 @@ protected function render() { 'arrows' => $show_arrows, 'dots' => $show_dots, 'rtl' => $is_rtl, - 'dtbaker_type' => ! empty( $instance['dtbaker_slider_type'] ) ? $instance['dtbaker_slider_type'] : '', + 'stylepress_type' => ! empty( $instance['stylepress_slider_type'] ) ? $instance['stylepress_slider_type'] : '', ]; $carousel_classes = [ 'elementor-page-carousel' ]; @@ -622,7 +632,7 @@ protected function render() { esc_html_e( 'Page Slider Here:' ); echo implode( '', $slides ); } else { - if ( ! empty( $instance['dtbaker_slider_type'] ) && 'icons' === $instance['dtbaker_slider_type'] ) { + if ( ! empty( $instance['stylepress_slider_type'] ) && 'icons' === $instance['stylepress_slider_type'] ) { $carousel_classes [] = 'inner-content-width'; } @@ -635,7 +645,7 @@ protected function render() { $page ) { $post_id = (int) str_replace( 'p.', '', $page['page'] ); @@ -652,7 +662,7 @@ protected function render() { ?>