Astra Starter Sites - Version 1.0.0

Version Description

Download this release

Release Info

Developer Nikschavan
Plugin Icon Astra Starter Sites
Version 1.0.0
Comparing to
See all releases

Version 1.0.0

admin/class-astra-sites-admin.php ADDED
@@ -0,0 +1,82 @@
1
+ <?php
2
+ /**
3
+ * Astra Demo Importer Admin
4
+ *
5
+ * @package Astra Addon
6
+ */
7
+
8
+ defined( 'ABSPATH' ) or exit;
9
+
10
+ /**
11
+ * Astra Demo Importer Admin
12
+ *
13
+ * @since 1.0.0
14
+ */
15
+ class Astra_Sites_Admin {
16
+
17
+ /**
18
+ * Instance of Astra_Sites_Admin
19
+ *
20
+ * @since 1.0.0
21
+ * @var Astra_Sites_Admin
22
+ */
23
+ private static $_instance = null;
24
+
25
+ /**
26
+ * Instanciate Astra_Sites_Admin
27
+ *
28
+ * @since 1.0.0
29
+ * @return (Object) Astra_Sites_Admin
30
+ */
31
+ public static function instance() {
32
+ if ( ! isset( self::$_instance ) ) {
33
+ self::$_instance = new self;
34
+ }
35
+
36
+ return self::$_instance;
37
+ }
38
+
39
+ /**
40
+ * Constructor
41
+ *
42
+ * @since 1.0.0
43
+ */
44
+ private function __construct() {
45
+
46
+ add_filter( 'astra_menu_options', array( $this, 'menu' ) );
47
+ add_action( 'astra_menu_astra_sites_action', array( $this, 'view_demos' ) );
48
+
49
+ }
50
+
51
+ /**
52
+ * Register admin menu for demo importer
53
+ *
54
+ * @since 1.0.0
55
+ *
56
+ * @param (Array) $actions Previously registered tabs menus.
57
+ *
58
+ * @return (Array) registered tabs menus in Astra menu.
59
+ */
60
+ public function menu( $actions ) {
61
+
62
+ $actions['astra-sites'] = array(
63
+ 'label' => __( 'Astra Sites', 'astra-sites' ),
64
+ 'show' => ! is_network_admin(),
65
+ );
66
+
67
+ return $actions;
68
+ }
69
+
70
+ /**
71
+ * View Astra Sites
72
+ *
73
+ * @since 1.0.0
74
+ */
75
+ public function view_demos() {
76
+
77
+ include ASTRA_SITES_DIR . 'admin/view-astra-sites.php';
78
+ }
79
+
80
+ }
81
+
82
+ Astra_Sites_Admin::instance();
admin/view-astra-sites.php ADDED
@@ -0,0 +1,228 @@
1
+ <?php
2
+ /**
3
+ * Astra Demo View.
4
+ *
5
+ * @package Astra Addon
6
+ */
7
+
8
+ defined( 'ABSPATH' ) or exit;
9
+
10
+ // Enqueue scripts.
11
+ wp_enqueue_script( 'astra-sites-admin' );
12
+ wp_enqueue_style( 'astra-sites-admin' );
13
+
14
+ // Load demo importer markup.
15
+ $all_demos = Astra_Sites::get_astra_all_demos();
16
+
17
+ do_action( 'astra_sites_before_site_grid', $all_demos );
18
+
19
+ if ( count( $all_demos ) > 0 ) {
20
+
21
+ /**
22
+ * Initial Demo List
23
+ *
24
+ * Generated though PHP
25
+ */
26
+ ?>
27
+ <div class="wrap">
28
+
29
+ <div class="wp-filter hide-if-no-js">
30
+
31
+ <ul class="filter-links">
32
+
33
+ <li><a href="#" data-sort="all" class="current" data-id="all"><?php esc_html_e( 'All', 'astra-sites' ); ?></a></li>
34
+
35
+ <?php foreach ( Astra_Sites::get_demo_categories() as $key => $category ) { ?>
36
+ <li>
37
+ <a href="#"
38
+ data-sort="<?php echo esc_attr( $category['slug'] ); ?>"
39
+ data-id="<?php echo esc_attr( $category['id'] ); ?>">
40
+ <?php echo esc_attr( $category['name'] ); ?>
41
+ </a>
42
+ </li>
43
+ <?php } ?>
44
+ </ul>
45
+
46
+ <div class="search-form">
47
+ <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'astra-sites' ); ?></label>
48
+ <input placeholder="<?php esc_attr_e( 'Search Sites...', 'astra-sites' ); ?>" type="search" aria-describedby="live-search-desc" id="wp-filter-search-input" class="wp-filter-search">
49
+ </div>
50
+
51
+ </div>
52
+
53
+ <span class="spinner"></span>
54
+
55
+ <div class="theme-browser rendered">
56
+ <div class="themes wp-clearfix">
57
+
58
+ <?php foreach ( $all_demos as $key => $demo ) { ?>
59
+
60
+ <div class="theme astra-theme" tabindex="0" aria-describedby="astra-theme-action astra-theme-name"
61
+ data-demo-id="<?php echo esc_attr( $demo['id'] ); ?>"
62
+ data-demo-type="<?php echo esc_attr( $demo['astra_demo_type'] ); ?>"
63
+ data-demo-url="<?php echo esc_url( $demo['astra_demo_url'] ); ?>"
64
+ data-demo-api="<?php echo esc_url( $demo['demo_api'] ); ?>"
65
+ data-screenshot="<?php echo esc_url( $demo['featured_image_url'] ); ?>"
66
+ data-demo-name="<?php echo esc_attr( $demo['title'] ); ?>"
67
+ data-demo-slug="<?php echo esc_attr( $demo['slug'] ); ?>"
68
+ data-content="<?php echo esc_attr( $demo['content'] ); ?>"
69
+ data-required-plugins="<?php echo esc_attr( $demo['required_plugins'] ); ?>">
70
+
71
+ <?php if ( 'premium' === $demo['astra_demo_type'] ) { ?>
72
+ <span class="demo-type <?php echo esc_attr( $demo['astra_demo_type'] ); ?>"><?php echo esc_attr( $demo['astra_demo_type'] ); ?></span>
73
+ <?php } ?>
74
+
75
+ <div class="theme-screenshot">
76
+ <?php if ( ! empty( $demo['featured_image_url'] ) ) { ?>
77
+ <img src="<?php echo esc_attr( $demo['featured_image_url'] ); ?>" alt="">
78
+ <?php } ?>
79
+ </div>
80
+
81
+ <a href="<?php echo esc_url( $demo['astra_demo_url'] ); ?>" target="_blank">
82
+ <span class="more-details" id="astra-theme-action"><?php esc_html_e( 'Details &amp; Preview', 'astra-sites' ); ?></span>
83
+ </a>
84
+
85
+ <h3 class="theme-name" id="astra-theme-name"><?php echo esc_attr( $demo['title'] ); ?></h3>
86
+ <div class="theme-actions">
87
+ <button class="button preview install-theme-preview"><?php esc_html_e( 'Preview', 'astra-sites' ); ?></button>
88
+ </div>
89
+ </div>
90
+
91
+ <?php } ?>
92
+
93
+ </div>
94
+ </div>
95
+
96
+ </div>
97
+
98
+ <?php
99
+ /**
100
+ * Regenerated Demo List
101
+ *
102
+ * Generated though JS after search demo, filter demo etc.
103
+ */
104
+ ?>
105
+ <script type="text/template" id="tmpl-astra-single-demo">
106
+ <div class="theme astra-theme" tabindex="0" aria-describedby="astra-theme-action astra-theme-name"
107
+ data-demo-id="{{{data.id}}}"
108
+ data-demo-type="{{{data.astra_demo_type}}}"
109
+ data-demo-url="{{{data.astra_demo_url}}}"
110
+ data-demo-api="{{{data.demo_api}}}"
111
+ data-demo-name="{{{data.demo_name}}}"
112
+ data-demo-slug="{{{data.slug}}}"
113
+ data-screenshot="{{{data.screenshot}}}"
114
+ data-content="{{{data.content}}}"
115
+ data-required-plugins="{{data.required_plugins}}">
116
+
117
+ <span class="demo-type {{{data.astra_demo_type}}}">{{{data.astra_demo_type}}}</span>
118
+
119
+ <div class="theme-screenshot">
120
+ <# if ( data.screenshot.length ) { #>
121
+ <img src="{{{data.screenshot}}}" alt="">
122
+ <# } #>
123
+ </div>
124
+
125
+ <a href="{{{data.astra_demo_url}}}" target="_blank">
126
+ <span class="more-details" id="astra-theme-action"><?php esc_html_e( 'Details &amp; Preview', 'astra-sites' ); ?></span>
127
+ </a>
128
+
129
+ <h3 class="theme-name" id="astra-theme-name">{{{data.demo_name}}}</h3>
130
+
131
+ <div class="theme-actions">
132
+ <button class="button preview install-theme-preview"><?php esc_html_e( 'Preview', 'astra-sites' ); ?></button>
133
+
134
+ </div>
135
+
136
+ </div>
137
+ </script>
138
+
139
+ <?php
140
+ /**
141
+ * Single Demo Preview
142
+ */
143
+ ?>
144
+ <script type="text/template" id="tmpl-astra-demo-preview">
145
+ <div class="astra-sites-preview theme-install-overlay wp-full-overlay expanded">
146
+ <div class="wp-full-overlay-sidebar">
147
+ <div class="wp-full-overlay-header"
148
+ data-demo-id="{{{data.id}}}"
149
+ data-demo-type="{{{data.astra_demo_type}}}"
150
+ data-demo-url="{{{data.astra_demo_url}}}"
151
+ data-demo-api="{{{data.demo_api}}}"
152
+ data-demo-name="{{{data.demo_name}}}"
153
+ data-demo-slug="{{{data.slug}}}"
154
+ data-screenshot="{{{data.screenshot}}}"
155
+ data-content="{{{data.content}}}"
156
+ data-required-plugins="{{data.required_plugins}}">
157
+ <button class="close-full-overlay"><span class="screen-reader-text"><?php esc_html_e( 'Close', 'astra-sites' ); ?></span></button>
158
+ <button class="previous-theme"><span class="screen-reader-text"><?php esc_html_e( 'Previous', 'astra-sites' ); ?></span></button>
159
+ <button class="next-theme"><span class="screen-reader-text"><?php esc_html_e( 'Next', 'astra-sites' ); ?></span></button>
160
+ <a class="button hide-if-no-customize astra-demo-import" href="#" data-import="disabled"><?php esc_html_e( 'Install Plugins', 'astra-sites' ); ?></a>
161
+
162
+ </div>
163
+ <div class="wp-full-overlay-sidebar-content">
164
+ <div class="install-theme-info">
165
+
166
+ <span class="demo-type {{{data.astra_demo_type}}}">{{{data.astra_demo_type}}}</span>
167
+ <h3 class="theme-name">{{{data.demo_name}}}</h3>
168
+
169
+ <# if ( data.screenshot.length ) { #>
170
+ <img class="theme-screenshot" src="{{{data.screenshot}}}" alt="">
171
+ <# } #>
172
+
173
+ <div class="theme-details">
174
+ {{{data.content}}}
175
+ </div>
176
+ <a href="#" class="theme-details-read-more"><?php _e( 'Read more', 'astra-sites' ); ?> &hellip;</a>
177
+
178
+ <div class="required-plugins-wrap">
179
+ <h4><?php _e( 'Required Plugins', 'astra-sites' ); ?> </h4>
180
+ <div class="required-plugins"></div>
181
+ </div>
182
+ </div>
183
+ </div>
184
+
185
+ <div class="wp-full-overlay-footer">
186
+ <div class="footer-import-button-wrap">
187
+ <a class="button button-hero hide-if-no-customize astra-demo-import" href="#" data-import="disabled">
188
+ <?php esc_html_e( 'Install Plugins', 'astra-sites' ); ?>
189
+ </a>
190
+ </div>
191
+ <button type="button" class="collapse-sidebar button" aria-expanded="true"
192
+ aria-label="Collapse Sidebar">
193
+ <span class="collapse-sidebar-arrow"></span>
194
+ <span class="collapse-sidebar-label"><?php esc_html_e( 'Collapse', 'astra-sites' ); ?></span>
195
+ </button>
196
+ </div>
197
+ </div>
198
+ <div class="wp-full-overlay-main">
199
+ <iframe src="{{{data.astra_demo_url}}}" title="<?php esc_attr_e( 'Preview', 'astra-sites' ); ?>"></iframe>
200
+ </div>
201
+ </div>
202
+ </script>
203
+
204
+ <?php
205
+
206
+ // Load demo importer welcome.
207
+ } else {
208
+ ?>
209
+ <div class="no-themes">
210
+ <?php
211
+
212
+ /* translators: %1$s & %2$s are a Demo API URL */
213
+ printf( __( '<p> It seems the demo data server, <i><a href="%1$s">%2$s</a></i> is unreachable from your site.</p>', 'astra-sites' ) , esc_url( Astra_Sites::$api_url ), esc_url( Astra_Sites::$api_url ) );
214
+
215
+ _e( '<p class="left-margin"> 1. Sometimes, simple page reload fixes any temporary issues. No kidding!</p>', 'astra-sites' );
216
+
217
+ _e( '<p class="left-margin"> 2. If that does not work, you will need to talk to your server administrator and check if demo server is being blocked by the firewall!</p>', 'astra-sites' );
218
+
219
+ /* translators: %1$s is a support link */
220
+ printf( __( '<p>If that does not help, please open up a <a href="%1$s" target="_blank">Support Ticket</a> and we will be glad take a closer look for you.</p>', 'astra-sites' ), esc_url( 'https://wpastra.com/support/' ) );
221
+ ?>
222
+
223
+ </div>
224
+ </p>
225
+ <?php
226
+ }// End if().
227
+
228
+ do_action( 'astra_sites_after_site_grid', $all_demos );
assets/css/admin.css ADDED
@@ -0,0 +1,164 @@
1
+ .theme-browser .theme.focus .theme-actions,
2
+ .theme-browser .theme:focus .theme-actions,
3
+ .theme-browser .theme:hover .theme-actions {
4
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
5
+ opacity: 1
6
+ }
7
+ .theme-browser .theme .theme-screenshot:after {
8
+ content: "";
9
+ display: block;
10
+ padding-top: 66.66666%
11
+ }
12
+
13
+ .wrap .demo-type {
14
+ position: absolute;
15
+ z-index: 1;
16
+ color: #fff;
17
+ padding: 0.5em 1em;
18
+ top: -0.5em;
19
+ left: -0.5em;
20
+ text-transform: uppercase;
21
+ }
22
+ .wrap .demo-type.premium {
23
+ background: #0073aa;
24
+ }
25
+ .wrap .demo-type.free {
26
+ display: none;
27
+ }
28
+
29
+ .theme {
30
+ position: relative;
31
+ }
32
+ .wrap .astra-sites-preview .demo-type.premium {
33
+ display: block;
34
+ display: none;
35
+ position: relative;
36
+ margin: 0.5em 0em 1em 0em;
37
+ top: 0;
38
+ left: 0;
39
+ text-align: center;
40
+ }
41
+
42
+ .theme-details-read-more.open {
43
+ margin: 0.5em 0 0 0;
44
+ }
45
+
46
+ .astra-sites-preview .theme-screenshot {
47
+ width: 100%;
48
+ }
49
+
50
+ /**
51
+ * Required Plugins
52
+ */
53
+ .required-plugins.loading {
54
+ text-align: center;
55
+ }
56
+ .required-plugins button {
57
+ float: right;
58
+ }
59
+ .required-plugins .plugin-card {
60
+ float: none;
61
+ width: 100%;
62
+ border: none;
63
+ margin: 0 0 0.8em 0;
64
+ display: flex;
65
+ justify-content: space-between;
66
+ align-items: center;
67
+ transition: background ease 0.8s;
68
+ }
69
+ .required-plugins .plugin-card.plugin-card-update-failed {
70
+ flex-wrap: wrap;
71
+ }
72
+ .required-plugins .spinner {
73
+ float: none;
74
+ }
75
+
76
+ .expanded .wp-full-overlay-footer {
77
+ height: 100px;
78
+ }
79
+
80
+ .wp-full-overlay-footer .view-site,
81
+ .wp-full-overlay-footer .go-pro,
82
+ .wp-full-overlay-footer .astra-demo-import {
83
+ width: 100%;
84
+ text-align: center;
85
+ }
86
+
87
+ .wp-full-overlay-footer .installing:before {
88
+ vertical-align: text-bottom;
89
+ }
90
+
91
+ .required-plugins-wrap h4 {
92
+ margin: 1em 0 0.5em 0;
93
+ padding: 0.5em 0;
94
+ transition: all ease 0.3s;
95
+ }
96
+
97
+ /**
98
+ * Read more link
99
+ */
100
+ .wp-core-ui .theme-details-read-more:focus,
101
+ .wp-core-ui .theme-details-read-more:hover {
102
+ outline: none;
103
+ box-shadow: none;
104
+ }
105
+ .wp-core-ui .theme-details-read-more {
106
+ margin: 10px 0;
107
+ display: none;
108
+ text-decoration: none;
109
+ }
110
+
111
+ /**
112
+ * Go pro.
113
+ */
114
+ .wp-core-ui .go-pro.button[disabled] {
115
+ background-color: #fcb92c !important;
116
+ color: white !important;
117
+ box-shadow: 1px 0 #eab23a !important;
118
+ text-shadow: 1px 0 #6b4e13 !important;
119
+ border-color: #e2a932 !important;
120
+ cursor: pointer;
121
+ }
122
+ .wp-core-ui .view-site .dashicons,
123
+ .wp-core-ui .go-pro .dashicons {
124
+ font-size: 1rem;
125
+ vertical-align: middle;
126
+ }
127
+
128
+ /**
129
+ * Errors
130
+ */
131
+ .plugin-card-update-failed .notice {
132
+ margin-top: 1.5em;
133
+ }
134
+
135
+ .no-themes {
136
+ margin-top: 40px;
137
+ }
138
+
139
+ .no-themes p {
140
+ font-size: 15px;
141
+ }
142
+
143
+ .no-themes .left-margin {
144
+ margin-left: 30px;
145
+ }
146
+
147
+ /**
148
+ *
149
+ */
150
+ .astra-sites-preview .wp-full-overlay-sidebar-content {
151
+ bottom: 100px;
152
+ }
153
+
154
+ .footer-import-button-wrap {
155
+ padding: 10px 20px;
156
+ }
157
+
158
+ .footer-import-button-wrap .button {
159
+ margin: 0;
160
+ }
161
+
162
+ .astra-sites-preview.expanded .wp-full-overlay-footer {
163
+ left: initial;
164
+ }
assets/js/admin.js ADDED
@@ -0,0 +1,694 @@
1
+ jQuery(document).ready(function ($) {
2
+ resetPagedCount();
3
+ });
4
+
5
+ /**
6
+ * Enable Demo Import Button.
7
+ */
8
+ function enable_demo_import_button( type = 'free' ) {
9
+
10
+ if( 'free' === type ) {
11
+
12
+ // Get initial required plugins count.
13
+ var remaining = parseInt( astraDemo.requiredPluginsCount ) || 0;
14
+
15
+ // Enable demo import button.
16
+ if( 0 >= remaining ) {
17
+
18
+ jQuery('.astra-demo-import')
19
+ .removeAttr('data-import')
20
+ .addClass('button-primary')
21
+ .text( astraDemo.strings.importDemo );
22
+ }
23
+ } else {
24
+
25
+ var demo_slug = jQuery('.wp-full-overlay-header').attr('data-demo-slug');
26
+
27
+ jQuery('.astra-demo-import')
28
+ .addClass('go-pro button-primary')
29
+ .removeClass('astra-demo-import')
30
+ .attr('target', '_blank')
31
+ .attr('href', astraDemo.getProURL + demo_slug )
32
+ .text( astraDemo.getProText )
33
+ .append('<i class="dashicons dashicons-external"></i>');
34
+ }
35
+ }
36
+
37
+ function resetPagedCount() {
38
+ categoryId = jQuery('.filter-links li .current').data('id');
39
+ jQuery('body').attr('data-astra-demo-paged', '1');
40
+ jQuery('body').attr('data-astra-site-category', categoryId);
41
+ jQuery('body').attr('data-astra-demo-search', '');
42
+ jQuery('body').attr('data-scrolling', false);
43
+ jQuery('body').attr( 'data-required-plugins', 0 )
44
+ }
45
+
46
+ function updatedPagedCount() {
47
+ paged = parseInt(jQuery('body').attr('data-astra-demo-paged'));
48
+ jQuery('body').attr('data-astra-demo-paged', paged + 1);
49
+ window.setTimeout(function () {
50
+ jQuery('body').data('scrolling', false);
51
+ }, 800);
52
+ }
53
+
54
+ jQuery(document).scroll(function (event) {
55
+ var scrollDistance = jQuery(window).scrollTop();
56
+
57
+ var themesBottom = Math.abs(jQuery(window).height() - jQuery('.themes').offset().top - jQuery('.themes').height());
58
+ themesBottom = themesBottom * 20 / 100;
59
+
60
+ ajaxLoading = jQuery('body').data('scrolling');
61
+
62
+ if (scrollDistance > themesBottom && ajaxLoading == false) {
63
+ updatedPagedCount();
64
+ jQuery('body').data('scrolling', true);
65
+ body = jQuery('body');
66
+ id = body.attr('data-astra-site-category');
67
+ search = body.attr('data-astra-demo-search');
68
+ paged = body.attr('data-astra-demo-paged');
69
+
70
+ if (search !== '') {
71
+ id = '';
72
+ } else {
73
+ search = '';
74
+ }
75
+
76
+ jQuery('.no-themes').remove();
77
+
78
+ jQuery.ajax({
79
+ url: astraDemo.ajaxurl,
80
+ type: 'POST',
81
+ dataType: 'json',
82
+ data: {
83
+ action: 'astra-list-sites',
84
+ id: id,
85
+ paged: paged,
86
+ search: search
87
+ },
88
+ })
89
+ .done(function (demos) {
90
+ jQuery('body').removeClass('loading-content');
91
+ renderDemoGrid(demos);
92
+ })
93
+ .fail(function () {
94
+ jQuery('body').removeClass('loading-content');
95
+ jQuery('.spinner').after('<p class="no-themes" style="display:block;">'+astraDemo.strings.responseError+'</p>');
96
+ });
97
+
98
+ }
99
+ });
100
+
101
+ /**
102
+ * Individual Site Preview
103
+ *
104
+ * On click on image, more link & preview button.
105
+ */
106
+ jQuery(document).on('click', '.theme-browser .theme-screenshot, .theme-browser .more-details, .theme-browser .install-theme-preview', function (event) {
107
+ event.preventDefault();
108
+
109
+ $this = jQuery(this).parents('.theme');
110
+ $this.addClass('theme-preview-on');
111
+
112
+ renderDemoPreview($this);
113
+ });
114
+
115
+ jQuery(document).on('click', '.close-full-overlay', function (event) {
116
+ event.preventDefault();
117
+
118
+ jQuery('.theme-install-overlay').css('display', 'none');
119
+ jQuery('.theme-install-overlay').remove();
120
+ jQuery('.theme-preview-on').removeClass('theme-preview-on');
121
+ });
122
+
123
+ jQuery(document).on('click', '.next-theme', function (event) {
124
+ event.preventDefault();
125
+ currentDemo = jQuery('.theme-preview-on')
126
+ currentDemo.removeClass('theme-preview-on');
127
+ nextDemo = currentDemo.nextAll('.theme');
128
+ nextDemo.addClass('theme-preview-on');
129
+
130
+ renderDemoPreview( nextDemo );
131
+
132
+ });
133
+
134
+ jQuery(document).on('click', '.previous-theme', function (event) {
135
+ event.preventDefault();
136
+
137
+ currentDemo = jQuery('.theme-preview-on');
138
+ currentDemo.removeClass('theme-preview-on');
139
+ prevDemo = currentDemo.prevAll('.theme');
140
+ prevDemo.addClass('theme-preview-on');
141
+
142
+ renderDemoPreview(prevDemo);
143
+ });
144
+
145
+ /**
146
+ * Click handler for plugin installs in plugin install view.
147
+ *
148
+ * @since 4.6.0
149
+ *
150
+ * @param {Event} event Event interface.
151
+ */
152
+ jQuery(document).on('click', '.install-now', function (event) {
153
+ event.preventDefault();
154
+
155
+ var $button = jQuery( event.target ),
156
+ $document = jQuery(document);
157
+
158
+ if ( $button.hasClass( 'updating-message' ) || $button.hasClass( 'button-disabled' ) ) {
159
+ return;
160
+ }
161
+
162
+ if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.ajaxLocked ) {
163
+ wp.updates.requestFilesystemCredentials( event );
164
+
165
+ $document.on( 'credential-modal-cancel', function() {
166
+ var $message = $( '.install-now.updating-message' );
167
+
168
+ $message
169
+ .removeClass( 'updating-message' )
170
+ .text( wp.updates.l10n.installNow );
171
+
172
+ wp.a11y.speak( wp.updates.l10n.updateCancel, 'polite' );
173
+ } );
174
+ }
175
+
176
+ wp.updates.installPlugin( {
177
+ slug: $button.data( 'slug' )
178
+ } );
179
+
180
+ } );
181
+
182
+ jQuery(document).on( 'wp-plugin-install-error', function( event, response ) {
183
+
184
+ var $message = jQuery( '.plugin-card-' + response.slug ).find( '.install-now' );
185
+
186
+ $message.removeClass( 'button-disabled' )
187
+ .addClass( 'button-primary' )
188
+ .html( wp.updates.l10n.installNow );
189
+
190
+ });
191
+
192
+ jQuery(document).on( 'wp-plugin-install-success', function( event, response ) {
193
+ event.preventDefault();
194
+
195
+ var $message = jQuery( '.plugin-card-' + response.slug ).find( '.install-now' );
196
+
197
+ // Transform the 'Install' button into an 'Activate' button.
198
+ var $init = $message.data('init');
199
+
200
+ $message.removeClass( 'install-now installed button-disabled updated-message' )
201
+ .addClass('updating-message')
202
+ .html( astraDemo.strings.btnActivating );
203
+
204
+ // WordPress adds "Activate" button after waiting for 1000ms. So we will run our activation after that.
205
+ setTimeout( function() {
206
+
207
+ jQuery.ajax({
208
+ url: astraDemo.ajaxurl,
209
+ type: 'POST',
210
+ dataType: 'json',
211
+ data: {
212
+ 'action' : 'astra-required-plugin-activate',
213
+ 'init' : $init
214
+ },
215
+ })
216
+ .done(function (result) {
217
+
218
+ if( result.success ) {
219
+ $message.removeClass( 'button-primary activate-now updating-message' )
220
+ .attr('disabled', 'disabled')
221
+ .addClass('disabled')
222
+ .text( astraDemo.strings.btnActive );
223
+
224
+ // Enable Demo Import Button
225
+ astraDemo.requiredPluginsCount--;
226
+ enable_demo_import_button();
227
+ }
228
+ });
229
+
230
+ }, 1000 );
231
+
232
+ });
233
+
234
+
235
+ /**
236
+ * Click handler for plugin installs in plugin install view.
237
+ *
238
+ * @since 4.6.0
239
+ *
240
+ * @param {Event} event Event interface.
241
+ */
242
+ jQuery(document).on('click', '.activate-now', function (event) {
243
+ event.preventDefault();
244
+
245
+ var $button = jQuery( event.target ),
246
+ $init = $button.data( 'init' );
247
+
248
+ if ( $button.hasClass( 'updating-message' ) || $button.hasClass( 'button-disabled' ) ) {
249
+ return;
250
+ }
251
+
252
+ $button.addClass( 'updating-message' )
253
+ .html( astraDemo.strings.btnActivating );
254
+
255
+ jQuery.ajax({
256
+ url: astraDemo.ajaxurl,
257
+ type: 'POST',
258
+ dataType: 'json',
259
+ data: {
260
+ 'action' : 'astra-required-plugin-activate',
261
+ 'init' : $init
262
+ },
263
+ })
264
+ .done(function (result) {
265
+
266
+ if( result.success ) {
267
+ $button.removeClass( 'button-primary activate-now updating-message' )
268
+ .attr('disabled', 'disabled')
269
+ .addClass('disabled')
270
+ .text( astraDemo.strings.btnActive );
271
+
272
+ // Enable Demo Import Button
273
+ astraDemo.requiredPluginsCount--;
274
+ enable_demo_import_button();
275
+ }
276
+
277
+ })
278
+ .fail(function () {
279
+ });
280
+
281
+ } );
282
+
283
+ function renderDemoPreview(anchor) {
284
+
285
+ var demoId = anchor.data('id') || '',
286
+ apiURL = anchor.data('demo-api') || '',
287
+ demoType = anchor.data('demo-type') || '',
288
+ demoURL = anchor.data('demo-url') || '',
289
+ screenshot = anchor.data('screenshot') || '',
290
+ demo_name = anchor.data('demo-name') || '',
291
+ demo_slug = anchor.data('demo-slug') || '',
292
+ content = anchor.data('content') || '',
293
+ requiredPlugins = anchor.data('required-plugins') || '';
294
+
295
+ var template = wp.template('astra-demo-preview');
296
+
297
+ templateData = [{
298
+ id : demoId,
299
+ astra_demo_type : demoType,
300
+ astra_demo_url : demoURL,
301
+ demo_api : apiURL,
302
+ screenshot : screenshot,
303
+ demo_name : demo_name,
304
+ slug : demo_slug,
305
+ content : content,
306
+ requiredPlugins : requiredPlugins
307
+ }];
308
+
309
+ // Initial set count.
310
+ astraDemo.requiredPluginsCount = requiredPlugins.length || 0;
311
+
312
+ // delete any earlier fullscreen preview before we render new one.
313
+ jQuery('.theme-install-overlay').remove();
314
+
315
+ jQuery('#ast-menu-page').append(template(templateData[0]));
316
+ jQuery('.theme-install-overlay').css('display', 'block');
317
+ checkNextPrevButtons();
318
+
319
+ var desc = jQuery('.theme-details');
320
+ var descHeight = parseInt( desc.outerHeight() );
321
+ var descBtn = jQuery('.theme-details-read-more');
322
+
323
+ if( 'free' === demoType && descHeight >= 55 ) {
324
+
325
+ // Show button.
326
+ descBtn.css( 'display', 'inline-block' );
327
+
328
+ // Set height upto 3 line.
329
+ desc.css( 'height', 57 );
330
+
331
+ // Button Click.
332
+ descBtn.click(function(event) {
333
+
334
+ if( descBtn.hasClass('open') ) {
335
+ desc.animate({ height: 57 },
336
+ 300, function() {
337
+ descBtn.removeClass('open');
338
+ descBtn.html( astraDemo.strings.DescExpand );
339
+ });
340
+ } else {
341
+ desc.animate({ height: descHeight },
342
+ 300, function() {
343
+ descBtn.addClass('open');
344
+ descBtn.html( astraDemo.strings.DescCollapse );
345
+ });
346
+ }
347
+
348
+ });
349
+ }
350
+
351
+ if( 'free' === demoType ) {
352
+
353
+ // or
354
+ var $pluginsFilter = jQuery( '#plugin-filter' ),
355
+ data = {
356
+ _ajax_nonce : astraDemo._ajax_nonce,
357
+ required_plugins : requiredPlugins
358
+ };
359
+
360
+ jQuery('.required-plugins').addClass('loading').html('<span class="spinner is-active"></span>');
361
+
362
+ wp.ajax.post( 'astra-required-plugins', data ).done( function( response ) {
363
+
364
+ // Remove loader.
365
+ jQuery('.required-plugins').removeClass('loading').html('');
366
+
367
+ /**
368
+ * Count remaining plugins.
369
+ * @type number
370
+ */
371
+ var remaining_plugins = 0;
372
+
373
+ /**
374
+ * Not Installed
375
+ *
376
+ * List of not installed required plugins.
377
+ */
378
+ if ( typeof response.notinstalled !== 'undefined' ) {
379
+
380
+ // Add not have installed plugins count.
381
+ remaining_plugins += parseInt( response.notinstalled.length );
382
+
383
+ jQuery( response.notinstalled ).each(function( index, plugin ) {
384
+
385
+ var output = '<div class="plugin-card ';
386
+ output += ' plugin-card-'+plugin.slug+'"';
387
+ output += ' data-slug="'+plugin.slug+'">';
388
+ output += ' <span class="title">'+plugin.name+'</span>';
389
+ output += ' <button class="button install-now"';
390
+ output += ' data-init="' + plugin.init + '"';
391
+ output += ' data-slug="' + plugin.slug + '"';
392
+ output += ' data-name="' + plugin.name + '">';
393
+ output += wp.updates.l10n.installNow;
394
+ output += ' </button>';
395
+ output += '</div>';
396
+
397
+ jQuery('.required-plugins').append(output);
398
+
399
+ });
400
+ }
401
+
402
+ /**
403
+ * Inactive
404
+ *
405
+ * List of not inactive required plugins.
406
+ */
407
+ if ( typeof response.inactive !== 'undefined' ) {
408
+
409
+ // Add inactive plugins count.
410
+ remaining_plugins += parseInt( response.inactive.length );
411
+
412
+ jQuery( response.inactive ).each(function( index, plugin ) {
413
+
414
+ var output = '<div class="plugin-card ';
415
+ output += ' plugin-card-'+plugin.slug+'"';
416
+ output += ' data-slug="'+plugin.slug+'">';
417
+ output += ' <span class="title">'+plugin.name+'</span>';
418
+
419
+ output += ' <button class="button activate-now button-primary"';
420
+ output += ' data-init="' + plugin.init + '">';
421
+ output += wp.updates.l10n.activatePlugin;
422
+ output += ' </button>';
423
+ output += '</div>';
424
+
425
+ jQuery('.required-plugins').append(output);
426
+
427
+ });
428
+ }
429
+
430
+ /**
431
+ * Active
432
+ *
433
+ * List of not active required plugins.
434
+ */
435
+ if ( typeof response.active !== 'undefined' ) {
436
+
437
+ jQuery( response.active ).each(function( index, plugin ) {
438
+
439
+ var output = '<div class="plugin-card ';
440
+ output += ' plugin-card-'+plugin.slug+'"';
441
+ output += ' data-slug="'+plugin.slug+'">';
442
+ output += ' <span class="title">'+plugin.name+'</span>';
443
+ output += ' <button class="button disabled"';
444
+ output += ' data-slug="' + plugin.slug + '"';
445
+ output += ' data-name="' + plugin.name + '">';
446
+ output += astraDemo.strings.btnActive;
447
+ output += ' </button>';
448
+ output += '</div>';
449
+
450
+ jQuery('.required-plugins').append(output);
451
+
452
+ });
453
+ }
454
+
455
+ /**
456
+ * Enable Demo Import Button
457
+ * @type number
458
+ */
459
+ astraDemo.requiredPluginsCount = remaining_plugins;
460
+ enable_demo_import_button();
461
+
462
+ } );
463
+
464
+ } else {
465
+
466
+ // Enable Demo Import Button
467
+ enable_demo_import_button( demoType );
468
+ jQuery('.required-plugins-wrap').remove();
469
+ }
470
+
471
+ return;
472
+ }
473
+
474
+ function checkNextPrevButtons() {
475
+ currentDemo = jQuery('.theme-preview-on');
476
+ nextDemo = currentDemo.nextAll('.theme').length;
477
+ prevDemo = currentDemo.prevAll('.theme').length;
478
+
479
+ if (nextDemo == 0) {
480
+ jQuery('.next-theme').addClass('disabled');
481
+ } else if (nextDemo != 0) {
482
+ jQuery('.next-theme').removeClass('disabled');
483
+ }
484
+
485
+ if (prevDemo == 0) {
486
+ jQuery('.previous-theme').addClass('disabled');
487
+ } else if (prevDemo != 0) {
488
+ jQuery('.previous-theme').removeClass('disabled');
489
+ }
490
+
491
+ return;
492
+ }
493
+
494
+ jQuery(document).on('click', '.filter-links li a', function (event) {
495
+ event.preventDefault();
496
+
497
+ $this = jQuery(this);
498
+ $this.parent('li').siblings().find('.current').removeClass('current');
499
+ $this.addClass('current');
500
+ slug = $this.data('sort');
501
+ id = $this.data('id');
502
+
503
+ resetPagedCount();
504
+ paged = parseInt(jQuery('body').attr('data-astra-demo-paged'));
505
+
506
+ if (slug == 'all') {
507
+ category = 'all';
508
+ } else {
509
+ category = slug;
510
+ }
511
+
512
+ jQuery('body').addClass('loading-content');
513
+ jQuery('.theme-browser .theme').remove();
514
+ jQuery('.no-themes').remove();
515
+ jQuery('#wp-filter-search-input').val('');
516
+
517
+ jQuery.ajax({
518
+ url: astraDemo.ajaxurl,
519
+ type: 'POST',
520
+ dataType: 'json',
521
+ data: {
522
+ action: 'astra-list-sites',
523
+ category: category,
524
+ id: id,
525
+ paged: paged,
526
+ },
527
+ })
528
+ .done(function (demos) {
529
+ jQuery('body').removeClass('loading-content');
530
+ renderDemoGrid(demos);
531
+ })
532
+ .fail(function () {
533
+ jQuery('body').removeClass('loading-content');
534
+ jQuery('.spinner').after('<p class="no-themes" style="display:block;">There was a problem receiving a response from server.</p>');
535
+ });
536
+
537
+ });
538
+
539
+ var ref;
540
+ jQuery(document).on('keyup input', '#wp-filter-search-input', function () {
541
+ $this = jQuery('#wp-filter-search-input').val();
542
+
543
+ id = '';
544
+ if ($this.length < 2) {
545
+ id = 'all';
546
+ }
547
+
548
+ window.clearTimeout(ref);
549
+ ref = window.setTimeout(function () {
550
+ ref = null;
551
+
552
+ resetPagedCount();
553
+ jQuery('body').addClass('loading-content');
554
+ jQuery('.theme-browser .theme').remove();
555
+ jQuery('.no-themes').remove();
556
+ jQuery('body').attr('data-astra-demo-search', $this);
557
+
558
+ jQuery.ajax({
559
+ url: astraDemo.ajaxurl,
560
+ type: 'POST',
561
+ dataType: 'json',
562
+ data: {
563
+ action: 'astra-list-sites',
564
+ search: $this,
565
+ id: id,
566
+ },
567
+ })
568
+ .done(function (demos) {
569
+ jQuery('.filter-links li a[data-id="all"]').addClass('current');
570
+ jQuery('.filter-links li a[data-id="all"]').parent('li').siblings().find('.current').removeClass('current');
571
+ jQuery('body').removeClass('loading-content');
572
+
573
+ if (demos.length > 0) {
574
+ renderDemoGrid(demos);
575
+ } else {
576
+ jQuery('.spinner').after('<p class="no-themes" style="display:block;">'+astraDemo.strings.searchNoFound+'</p>');
577
+ }
578
+
579
+ })
580
+ .fail(function () {
581
+ jQuery('body').removeClass('loading-content');
582
+ jQuery('.spinner').after('<p class="no-themes" style="display:block;">'+astraDemo.strings.responseError+'.</p>');
583
+ });
584
+
585
+ }, 500);
586
+
587
+ });
588
+
589
+ function renderDemoGrid(demos) {
590
+ jQuery.each(demos, function (index, demo) {
591
+
592
+ id = demo.id;
593
+ content = demo.content;
594
+ demo_api = demo.demo_api;
595
+ demo_name = demo.title;
596
+ demo_slug = demo.slug;
597
+ screenshot = demo.featured_image_url;
598
+ astra_demo_url = demo.astra_demo_url;
599
+ astra_demo_type = demo.astra_demo_type;
600
+ requiredPlugins = demo.required_plugins;
601
+
602
+ templateData = [{
603
+ id: id,
604
+ astra_demo_type: astra_demo_type,
605
+ astra_demo_url: astra_demo_url,
606
+ demo_api: demo_api,
607
+ screenshot: screenshot,
608
+ demo_name: demo_name,
609
+ slug: demo_slug,
610
+ content: content,
611
+ required_plugins: requiredPlugins
612
+ }]
613
+
614
+ var template = wp.template('astra-single-demo');
615
+ jQuery('.themes').append(template(templateData[0]));
616
+ });
617
+ }
618
+
619
+ jQuery(document).on('click', '.collapse-sidebar', function (event) {
620
+ event.preventDefault();
621
+
622
+ overlay = jQuery('.wp-full-overlay');
623
+
624
+ if (overlay.hasClass('expanded')) {
625
+ overlay.removeClass('expanded');
626
+ overlay.addClass('collapsed');
627
+ return;
628
+ }
629
+
630
+ if (overlay.hasClass('collapsed')) {
631
+ overlay.removeClass('collapsed');
632
+ overlay.addClass('expanded');
633
+ return;
634
+ }
635
+ });
636
+
637
+ jQuery(document).on('click', '.astra-demo-import', function (event) {
638
+ event.preventDefault();
639
+
640
+ var $this = jQuery(this),
641
+ disabled = $this.attr('data-import');
642
+
643
+ if ( typeof disabled !== 'undefined' && disabled === 'disabled' ) {
644
+
645
+ // Highlight required plugins list.
646
+ var pluginTitle = jQuery('.required-plugins-wrap h4');
647
+ pluginTitle.css({'background-color':'rgba(255, 235, 59, 0.20)'});
648
+ setTimeout(function() {
649
+ pluginTitle.css({'background-color':''});
650
+ }, 1000);
651
+
652
+ return;
653
+ }
654
+
655
+ // Proceed?
656
+ if( ! confirm( astraDemo.strings.importWarning ) ) {
657
+ return;
658
+ }
659
+
660
+ jQuery('.astra-demo-import').attr('data-import', 'disabled')
661
+ .addClass('updating-message installing')
662
+ .text('Importing Demo');
663
+
664
+ $this.closest('.theme').focus();
665
+
666
+ var $theme = $this.closest('.astra-sites-preview').find('.wp-full-overlay-header');
667
+
668
+ var apiURL = $theme.data('demo-api') || '';
669
+
670
+ jQuery.ajax({
671
+ url: astraDemo.ajaxurl,
672
+ type: 'POST',
673
+ dataType: 'json',
674
+ data: {
675
+ action: 'astra-import-demo',
676
+ api_url: apiURL
677
+ },
678
+ })
679
+ .done(function ( demos ) {
680
+
681
+ jQuery('.astra-demo-import').removeClass('updating-message installing')
682
+ .removeAttr('data-import')
683
+ .addClass('view-site')
684
+ .removeClass('astra-demo-import')
685
+ .text( astraDemo.strings.viewSite )
686
+ .attr('target', '_blank')
687
+ .append('<i class="dashicons dashicons-external"></i>')
688
+ .attr('href', astraDemo.siteURL );
689
+ })
690
+ .fail(function ( demos ) {
691
+ jQuery('.astra-demo-import').removeClass('updating-message installing').text('Error.');
692
+ });
693
+
694
+ });
astra-sites.php ADDED
@@ -0,0 +1,23 @@
1
+ <?php
2
+ /**
3
+ * Plugin Name: Astra Sites
4
+ * Plugin URI: http://www.wpastra.com/pro/
5
+ * Description: Import sites build with Astra theme.
6
+ * Version: 1.0.0
7
+ * Author: Brainstorm Force
8
+ * Author URI: http://www.brainstormforce.com
9
+ * Text Domain: astra-sites
10
+ *
11
+ * @package Astra Sites
12
+ */
13
+
14
+ /**
15
+ * Set constants.
16
+ */
17
+ define( 'ASTRA_SITES_VER', '1.0.0' );
18
+ define( 'ASTRA_SITES_FILE', __FILE__ );
19
+ define( 'ASTRA_SITES_BASE', plugin_basename( ASTRA_SITES_FILE ) );
20
+ define( 'ASTRA_SITES_DIR', plugin_dir_path( ASTRA_SITES_FILE ) );
21
+ define( 'ASTRA_SITES_URI', plugins_url( '/', ASTRA_SITES_FILE ) );
22
+
23
+ require_once ASTRA_SITES_DIR . 'classes/class-astra-sites.php';
classes/class-astra-sites.php ADDED
@@ -0,0 +1,631 @@
1
+ <?php
2
+ /**
3
+ * Astra Sites
4
+ *
5
+ * @since 1.0.0
6
+ * @package Astra Sites
7
+ */
8
+
9
+ defined( 'ABSPATH' ) or exit;
10
+
11
+ if ( ! class_exists( 'Astra_Sites' ) ) :
12
+
13
+ /**
14
+ * Astra_Sites
15
+ */
16
+ class Astra_Sites {
17
+
18
+ /**
19
+ * API URL which is used to get the response from.
20
+ *
21
+ * @since 1.0.0
22
+ * @var (String) URL
23
+ */
24
+ public static $api_url;
25
+
26
+ /**
27
+ * Instance of Astra_Sites
28
+ *
29
+ * @since 1.0.0
30
+ * @var (Object) Astra_Sites
31
+ */
32
+ private static $_instance = null;
33
+
34
+ /**
35
+ * Instance of Astra_Sites.
36
+ *
37
+ * @since 1.0.0
38
+ *
39
+ * @return object Class object.
40
+ */
41
+ public static function set_instance() {
42
+ if ( ! isset( self::$_instance ) ) {
43
+ self::$_instance = new self;
44
+ }
45
+
46
+ return self::$_instance;
47
+ }
48
+
49
+ /**
50
+ * Constructor.
51
+ *
52
+ * @since 1.0.0
53
+ */
54
+ private function __construct() {
55
+
56
+ add_action( 'admin_notices', array( $this, 'admin_notices' ) );
57
+
58
+ self::set_api_url();
59
+
60
+ $this->includes();
61
+
62
+ add_action( 'wp_enqueue_scripts', array( $this, 'admin_enqueue' ) );
63
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue' ) );
64
+ add_action( 'wp_ajax_astra-import-demo', array( $this, 'demo_ajax_import' ) );
65
+ add_action( 'wp_ajax_astra-list-sites', array( $this, 'list_demos' ) );
66
+ add_action( 'wp_ajax_astra-required-plugins', array( $this, 'required_plugin' ) );
67
+ add_action( 'wp_ajax_astra-required-plugin-activate', array( $this, 'required_plugin_activate' ) );
68
+ }
69
+
70
+ /**
71
+ * Admin Notices
72
+ *
73
+ * @since 1.0.0
74
+ * @return void
75
+ */
76
+ function admin_notices() {
77
+
78
+ if ( ! defined( 'ASTRA_THEME_SETTINGS' ) ) {
79
+ ?>
80
+ <div class="notice notice-error ast-active-notice is-dismissible">
81
+ <p>
82
+ <?php
83
+ printf(
84
+ /* translators: 1: theme.php file*/
85
+ __( 'Astra Theme needs to be active for you to use currently installed "Astra Sites" plugin. <a href="%1$s">Install & Activate Now</a>', 'astra-sites' ),
86
+ esc_url( admin_url( 'themes.php?theme=astra' ) )
87
+ );
88
+ ?>
89
+ </p>
90
+ </div>
91
+ <?php
92
+ return;
93
+ }
94
+
95
+ add_action( 'plugin_action_links_' . ASTRA_SITES_BASE, array( $this, 'action_links' ) );
96
+ }
97
+
98
+ /**
99
+ * Show action links on the plugin screen.
100
+ *
101
+ * @param mixed $links Plugin Action links.
102
+ * @return array
103
+ */
104
+ function action_links( $links ) {
105
+ $action_links = array(
106
+ 'settings' => '<a href="' . admin_url( 'themes.php?page=astra&action=astra-sites' ) . '" aria-label="' . esc_attr__( 'See Library', 'astra-sites' ) . '">' . esc_html__( 'See Library', 'astra-sites' ) . '</a>',
107
+ );
108
+
109
+ return array_merge( $action_links, $links );
110
+ }
111
+
112
+ /**
113
+ * Setter for $api_url
114
+ *
115
+ * @since 1.0.0
116
+ */
117
+ public static function set_api_url() {
118
+
119
+ self::$api_url = apply_filters( 'astra_demo_api_url', 'https://sites.wpastra.com/wp-json/wp/v2/' );
120
+
121
+ }
122
+
123
+ /**
124
+ * Returns the API URL that depending based on the category, search term and pagination.
125
+ *
126
+ * @since 1.0.0
127
+ *
128
+ * @param object $args Arguments for selecting correct list of demos.
129
+ * args->id = ID of the demo.
130
+ * $args->search = Search term used in the demo.
131
+ * @param string $page Page number for pagination.
132
+ *
133
+ * @return string URL that can be queried to return the demos.
134
+ */
135
+ public static function get_api_url( $args, $page = '1' ) {
136
+
137
+ $request_params = array(
138
+ 'page' => $page,
139
+ 'per_page' => '15',
140
+
141
+ // Use this for premium demos.
142
+ 'purchase_key' => '',
143
+ 'site_url' => '',
144
+ );
145
+
146
+ $args_search = isset( $args->search ) ? $args->search : '';
147
+ $args_id = isset( $args->id ) ? $args->id : '';
148
+
149
+ // Not Search?
150
+ if ( '' !== $args_search ) {
151
+ $request_params['search'] = $args_search;
152
+
153
+ // Not All?
154
+ } elseif ( 'all' != $args_id ) {
155
+ $request_params['astra-site-category'] = $args_id;
156
+ }
157
+
158
+ return add_query_arg( $request_params, self::$api_url . 'astra-sites' );
159
+ }
160
+
161
+ /**
162
+ * Returns the API URL for searching demos basedon taxanomies.
163
+ *
164
+ * @since 1.0.0
165
+ * @return (String) URL that can be queried to return the demos.
166
+ */
167
+ public static function get_taxanomy_api_url() {
168
+ return self::$api_url . 'astra-site-category/';
169
+ }
170
+
171
+ /**
172
+ * Enqueue admin scripts.
173
+ *
174
+ * @since 1.0.0
175
+ */
176
+ public function admin_enqueue() {
177
+
178
+ wp_register_script(
179
+ 'astra-sites-admin', ASTRA_SITES_URI . 'assets/js/admin.js', array(
180
+ 'jquery',
181
+ 'wp-util',
182
+ 'updates',
183
+ ), ASTRA_SITES_VER, true
184
+ );
185
+
186
+ wp_register_style( 'astra-sites-admin', ASTRA_SITES_URI . 'assets/css/admin.css', ASTRA_SITES_VER, true );
187
+
188
+ wp_localize_script(
189
+ 'astra-sites-admin', 'astraDemo', array(
190
+ 'ajaxurl' => esc_url( admin_url( 'admin-ajax.php' ) ),
191
+ 'siteURL' => site_url(),
192
+ 'getProText' => __( 'Purchase', 'astra-sites' ),
193
+ 'getProURL' => esc_url( 'https://wpastra.com/pro/?utm_source=demo-import-panel&utm_campaign=astra-sites&utm_medium=' ),
194
+ '_ajax_nonce' => wp_create_nonce( 'astra-sites' ),
195
+ 'requiredPluginsCount' => 0,
196
+ 'strings' => array(
197
+ 'viewSite' => __( 'Done! View Site', 'astra-sites' ),
198
+ 'btnActivating' => __( 'Activating', 'astra-sites' ) . '&hellip;',
199
+ 'btnActive' => __( 'Active', 'astra-sites' ),
200
+ 'importDemo' => __( 'Import This Site', 'astra-sites' ),
201
+ 'DescExpand' => __( 'Read more', 'astra-sites' ) . '&hellip;',
202
+ 'DescCollapse' => __( 'Hide', 'astra-sites' ),
203
+ 'responseError' => __( 'There was a problem receiving a response from server.', 'astra-sites' ),
204
+ 'searchNoFound' => __( 'No Demos found, Try a different search.', 'astra-sites' ),
205
+ 'importWarning' => __( "Executing Demo Import will make your site similar as ours. Please bear in mind -\n\n1. It is recommended to run import on a fresh WordPress installation.\n\n2. Importing site does not delete any pages or posts. However, it can overwrite your existing content.\n\n3. Copyrighted media will not be imported. Instead it will be replaced with placeholders.", 'astra-sites' ),
206
+ ),
207
+ )
208
+ );
209
+
210
+ }
211
+
212
+ /**
213
+ * Load all the required files in the importer.
214
+ *
215
+ * @since 1.0.0
216
+ */
217
+ private function includes() {
218
+
219
+ require_once ASTRA_SITES_DIR . 'admin/class-astra-sites-admin.php';
220
+
221
+ // Load the Importers.
222
+ require_once ASTRA_SITES_DIR . 'importers/class-astra-sites-helper.php';
223
+ require_once ASTRA_SITES_DIR . 'importers/class-widgets-importer.php';
224
+ require_once ASTRA_SITES_DIR . 'importers/class-astra-customizer-import.php';
225
+ require_once ASTRA_SITES_DIR . 'importers/wxr-importer/class-astra-wxr-importer.php';
226
+ require_once ASTRA_SITES_DIR . 'importers/class-astra-site-options-import.php';
227
+ }
228
+
229
+ /**
230
+ * Required Plugin Activate
231
+ *
232
+ * @since 1.0.0
233
+ */
234
+ public function required_plugin_activate() {
235
+
236
+ if ( ! current_user_can( 'install_plugins' ) || ! isset( $_POST['init'] ) || ! $_POST['init'] ) {
237
+ wp_send_json_error(
238
+ array(
239
+ 'success' => false,
240
+ 'message' => __( 'No plugin specified', 'astra-sites' ),
241
+ )
242
+ );
243
+ }
244
+
245
+ $plugin_init = esc_attr( $_POST['init'] );
246
+
247
+ $activate = activate_plugin( $plugin_init, '', false, true );
248
+
249
+ if ( is_wp_error( $activate ) ) {
250
+ wp_send_json_error(
251
+ array(
252
+ 'success' => false,
253
+ 'message' => $activate->get_error_message(),
254
+ )
255
+ );
256
+ }
257
+
258
+ wp_send_json_success(
259
+ array(
260
+ 'success' => true,
261
+ 'message' => __( 'Plugin Successfully Activated', 'astra-sites' ),
262
+ )
263
+ );
264
+
265
+ }
266
+
267
+ /**
268
+ * Required Plugin
269
+ *
270
+ * @since 1.0.0
271
+ * @return void
272
+ */
273
+ public function required_plugin() {
274
+
275
+ // Verify Nonce.
276
+ check_ajax_referer( 'astra-sites', '_ajax_nonce' );
277
+
278
+ $response = array(
279
+ 'active' => array(),
280
+ 'inactive' => array(),
281
+ 'notinstalled' => array(),
282
+ );
283
+
284
+ if ( ! current_user_can( 'customize' ) ) {
285
+ wp_send_json_error( $response );
286
+ }
287
+
288
+ $required_plugins = ( isset( $_POST['required_plugins'] ) ) ? $_POST['required_plugins'] : array();
289
+
290
+ if ( count( $required_plugins ) > 0 ) {
291
+ foreach ( $required_plugins as $key => $plugin ) {
292
+
293
+ // Inactive plugins.
294
+ if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin['init'] ) && is_plugin_inactive( $plugin['init'] ) ) {
295
+ $response['inactive'][] = $plugin;
296
+
297
+ // Not Installed plugins.
298
+ } elseif ( ! file_exists( WP_PLUGIN_DIR . '/' . $plugin['init'] ) ) {
299
+ $response['notinstalled'][] = $plugin;
300
+
301
+ // Active plugins.
302
+ } else {
303
+ $response['active'][] = $plugin;
304
+ }
305
+ }
306
+ }
307
+
308
+ // Send response.
309
+ wp_send_json_success( $response );
310
+ }
311
+
312
+ /**
313
+ * Ajax callback for demo import action.
314
+ *
315
+ * @since 1.0.0
316
+ */
317
+ public function demo_ajax_import() {
318
+
319
+ if ( ! current_user_can( 'customize' ) ) {
320
+ return;
321
+ }
322
+
323
+ $demo_api_uri = isset( $_POST['api_url'] ) ? esc_url( $_POST['api_url'] ) : '';
324
+ $this->import_demo( $demo_api_uri );
325
+
326
+ wp_die();
327
+ }
328
+
329
+ /**
330
+ * Ajax handler for retreiving the list of demos.
331
+ *
332
+ * @since 1.0.0
333
+ * @return (JSON) Json response retreived from the API.
334
+ */
335
+ public function list_demos() {
336
+
337
+ if ( ! current_user_can( 'customize' ) ) {
338
+ return;
339
+ }
340
+
341
+ $args = new stdClass();
342
+ $args->category = isset( $_POST['category'] ) ? esc_attr( $_POST['category'] ) : '';
343
+ $args->id = isset( $_POST['id'] ) ? esc_attr( $_POST['id'] ) : '';
344
+ $args->search = isset( $_POST['search'] ) ? esc_attr( $_POST['search'] ) : '';
345
+ $paged = isset( $_POST['paged'] ) ? esc_attr( $_POST['paged'] ) : '1';
346
+
347
+ return wp_send_json( self::get_astra_demos( $args, $paged ) );
348
+ }
349
+
350
+ /**
351
+ * Get the list of demos.
352
+ *
353
+ * @since 1.0.0
354
+ * @see admin/view-astra-sites.php
355
+ * @return (Array) Demos.
356
+ */
357
+ public static function get_astra_all_demos() {
358
+ $args = new stdClass();
359
+ $args->id = 'all';
360
+
361
+ return self::get_astra_demos( $args );
362
+ }
363
+
364
+ /**
365
+ * Import the demo.
366
+ *
367
+ * @since 1.0.0
368
+ *
369
+ * @param (String) $demo_api_uri API URL for the single demo.
370
+ */
371
+ public function import_demo( $demo_api_uri ) {
372
+
373
+ $demo_data = self::get_astra_single_demo( $demo_api_uri );
374
+
375
+ // Import Enabled Extensions.
376
+ $this->import_astra_enabled_extension( $demo_data['astra-enabled-extensions'] );
377
+
378
+ // Import Widgets data.
379
+ $this->import_widgets( $demo_data['astra-site-widgets-data'] );
380
+
381
+ // Import Customizer Settings.
382
+ $this->import_customizer_settings( $demo_data['astra-site-customizer-data'] );
383
+
384
+ // Import XML.
385
+ $this->import_wxr( $demo_data['astra-site-wxr-path'] );
386
+
387
+ // Import WordPress site options.
388
+ $this->import_site_options( $demo_data['astra-site-options-data'] );
389
+
390
+ // Import Custom 404 extension options.
391
+ $this->import_custom_404_extension_options( $demo_data['astra-custom-404'] );
392
+ }
393
+
394
+ /**
395
+ * Import widgets and assign to correct sidebars.
396
+ *
397
+ * @since 1.0.0
398
+ *
399
+ * @param (Object) $data Widgets data.
400
+ */
401
+ private function import_widgets( $data ) {
402
+
403
+ // bail if wiegets data is not available.
404
+ if ( null == $data ) {
405
+ return;
406
+ }
407
+
408
+ $widgets_importer = Astra_Widget_Importer::instance();
409
+ $widgets_importer->import_widgets_data( $data );
410
+ }
411
+
412
+ /**
413
+ * Import Customizer data.
414
+ *
415
+ * @since 1.0.0
416
+ *
417
+ * @param (Array) $customizer_data Customizer data for the demo to be imported.
418
+ */
419
+ private function import_customizer_settings( $customizer_data ) {
420
+ $customizer_import = Astra_Customizer_Import::instance();
421
+ $customizer_data = $customizer_import->import( $customizer_data );
422
+ }
423
+
424
+ /**
425
+ * Download and import the XML from the demo.
426
+ *
427
+ * @since 1.0.0
428
+ *
429
+ * @param (String) $wxr_url URL of the xml export of the demo to be imported.
430
+ */
431
+ private function import_wxr( $wxr_url ) {
432
+ $wxr_importer = Astra_WXR_Importer::instance();
433
+ $xml_path = $wxr_importer->download_xml( $wxr_url );
434
+ $wxr_importer->import_xml( $xml_path['file'] );
435
+ }
436
+
437
+ /**
438
+ * Import site options - Front Page, Menus, Blog page etc.
439
+ *
440
+ * @since 1.0.0
441
+ *
442
+ * @param (Array) $options Array of required site options from the demo.
443
+ */
444
+ private function import_site_options( $options ) {
445
+ $options_importer = Astra_Site_Options_Import::instance();
446
+ $options_importer->import_options( $options );
447
+ }
448
+
449
+ /**
450
+ * Import settings enabled astra extensions from the demo.
451
+ *
452
+ * @since 1.0.0
453
+ *
454
+ * @param (Array) $saved_extensions Array of enabled extensions.
455
+ */
456
+ private function import_astra_enabled_extension( $saved_extensions ) {
457
+ if ( is_callable( 'AST_Admin_Helper::update_admin_settings_option' ) ) {
458
+ AST_Admin_Helper::update_admin_settings_option( '_astra_ext_enabled_extensions', $saved_extensions );
459
+ }
460
+ }
461
+
462
+ /**
463
+ * Import custom 404 section.
464
+ *
465
+ * @since 1.0.0
466
+ *
467
+ * @param (Array) $options_404 404 Extensions settings from the demo.
468
+ */
469
+ private function import_custom_404_extension_options( $options_404 ) {
470
+ if ( is_callable( 'AST_Admin_Helper::update_admin_settings_option' ) ) {
471
+ AST_Admin_Helper::update_admin_settings_option( '_astra_ext_custom_404', $options_404 );
472
+ }
473
+ }
474
+
475
+ /**
476
+ * Get single demo.
477
+ *
478
+ * @since 1.0.0
479
+ *
480
+ * @param (String) $demo_api_uri API URL of a demo.
481
+ *
482
+ * @return (Array) $astra_demo_data demo data for the demo.
483
+ */
484
+ public static function get_astra_single_demo( $demo_api_uri ) {
485
+
486
+ // default values.
487
+ $remote_args = array();
488
+ $defaults = array(
489
+ 'id' => '',
490
+ 'astra-site-widgets-data' => '',
491
+ 'astra-site-customizer-data' => '',
492
+ 'astra-site-options-data' => '',
493
+ 'astra-site-wxr-path' => '',
494
+ 'astra-enabled-extensions' => '',
495
+ 'astra-custom-404' => '',
496
+ 'required-plugins' => '',
497
+ );
498
+
499
+ $api_args = array(
500
+ 'timeout' => 15,
501
+ );
502
+
503
+ $response = wp_remote_get( $demo_api_uri, $api_args );
504
+
505
+ if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
506
+ $result = json_decode( wp_remote_retrieve_body( $response ), true );
507
+ $remote_args['id'] = $result['id'];
508
+ $remote_args['astra-site-widgets-data'] = json_decode( $result['astra-site-widgets-data'] );
509
+ $remote_args['astra-site-customizer-data'] = $result['astra-site-customizer-data'];
510
+ $remote_args['astra-site-options-data'] = $result['astra-site-options-data'];
511
+ $remote_args['astra-site-wxr-path'] = $result['astra-site-wxr-path'];
512
+ $remote_args['astra-enabled-extensions'] = $result['astra-enabled-extensions'];
513
+ $remote_args['astra-custom-404'] = $result['astra-custom-404'];
514
+ $remote_args['required-plugins'] = $result['required-plugins'];
515
+ }
516
+
517
+ // Merge remote demo and defaults.
518
+ return wp_parse_args( $remote_args, $defaults );
519
+ }
520
+
521
+ /**
522
+ * Get astra demos.
523
+ *
524
+ * @since 1.0.0
525
+ *
526
+ * @param (Array) $args For selecting the demos (Search terms, pagination etc).
527
+ * @param (String) $paged Page number.
528
+ */
529
+ public static function get_astra_demos( $args, $paged = '1' ) {
530
+
531
+ $url = self::get_api_url( $args, $paged );
532
+
533
+ $astra_demos = array();
534
+
535
+ $api_args = array(
536
+ 'timeout' => 15,
537
+ );
538
+
539
+ $response = wp_remote_get( $url, $api_args );
540
+
541
+ if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
542
+ $result = json_decode( wp_remote_retrieve_body( $response ), true );
543
+
544
+ // If is array then proceed
545
+ // Else skip it.
546
+ if ( is_array( $result ) ) {
547
+
548
+ foreach ( $result as $key => $demo ) {
549
+
550
+ if ( ! isset( $demo['id'] ) ) {
551
+ continue;
552
+ }
553
+
554
+ $astra_demos[ $key ]['id'] = isset( $demo['id'] ) ? esc_attr( $demo['id'] ) : '';
555
+ $astra_demos[ $key ]['slug'] = isset( $demo['slug'] ) ? esc_attr( $demo['slug'] ) : '';
556
+ $astra_demos[ $key ]['date'] = isset( $demo['date'] ) ? esc_attr( $demo['date'] ) : '';
557
+ $astra_demos[ $key ]['astra_demo_type'] = isset( $demo['astra-site-type'] ) ? sanitize_key( $demo['astra-site-type'] ) : '';
558
+ $astra_demos[ $key ]['astra_demo_url'] = isset( $demo['astra-site-url'] ) ? esc_url( $demo['astra-site-url'] ) : '';
559
+ $astra_demos[ $key ]['title'] = isset( $demo['title']['rendered'] ) ? esc_attr( $demo['title']['rendered'] ) : '';
560
+ $astra_demos[ $key ]['featured_image_url'] = isset( $demo['featured-image-url'] ) ? esc_url( $demo['featured-image-url'] ) : '';
561
+ $astra_demos[ $key ]['demo_api'] = isset( $demo['_links']['self'][0]['href'] ) ? esc_url( $demo['_links']['self'][0]['href'] ) : self::get_api_url( new stdClass() ) . $demo['id'];
562
+ $astra_demos[ $key ]['content'] = isset( $demo['content']['rendered'] ) ? strip_tags( $demo['content']['rendered'] ) : '';
563
+ $astra_demos[ $key ]['required_plugins'] = isset( $demo['required-plugins'] ) ? json_encode( $demo['required-plugins'] ) : '';
564
+ }
565
+
566
+ // Free up memory by unsetting variables that are not required.
567
+ unset( $result );
568
+ unset( $response );
569
+ }
570
+ }
571
+
572
+ return $astra_demos;
573
+
574
+ }
575
+
576
+ /**
577
+ * Get demo categories.
578
+ *
579
+ * @since 1.0.0
580
+ * @return (Array) Array of demo categories.
581
+ */
582
+ public static function get_demo_categories() {
583
+ $categories = array();
584
+
585
+ $api_args = array(
586
+ 'timeout' => 15,
587
+ );
588
+
589
+ $response = wp_remote_get( self::get_taxanomy_api_url(), $api_args );
590
+
591
+ if ( ! is_wp_error( $response ) || 200 === wp_remote_retrieve_response_code( $response ) ) {
592
+ $result = json_decode( wp_remote_retrieve_body( $response ), true );
593
+
594
+ if ( array_key_exists( 'code', $result ) && 'rest_no_route' === $result['code'] ) {
595
+ return $categories;
596
+ }
597
+
598
+ // If is array then proceed
599
+ // Else skip it.
600
+ if ( is_array( $result ) ) {
601
+
602
+ foreach ( $result as $key => $category ) {
603
+ if ( 0 == $category['count'] ) {
604
+ continue;
605
+ }
606
+ $categories[ $key ]['id'] = $category['id'];
607
+ $categories[ $key ]['name'] = $category['name'];
608
+ $categories[ $key ]['slug'] = $category['slug'];
609
+ $categories[ $key ]['count'] = $category['count'];
610
+ $categories[ $key ]['link-category'] = $category['_links']['self'][0]['href'];
611
+ }
612
+
613
+ // Free up memory by unsetting variables that are not required.
614
+ unset( $result );
615
+ unset( $response );
616
+
617
+ }
618
+ }
619
+
620
+ return $categories;
621
+ }
622
+
623
+ }
624
+
625
+ /**
626
+ * Kicking this off by calling 'set_instance()' method
627
+ */
628
+ Astra_Sites::set_instance();
629
+
630
+ endif;
631
+
importers/class-astra-customizer-import.php ADDED
@@ -0,0 +1,51 @@
1
+ <?php
2
+ /**
3
+ * Customizer Data importer class.
4
+ *
5
+ * @since 1.0.0
6
+ * @package Astra Addon
7
+ */
8
+
9
+ defined( 'ABSPATH' ) or exit;
10
+
11
+ /**
12
+ * Customizer Data importer class.
13
+ *
14
+ * @since 1.0.0
15
+ */
16
+ class Astra_Customizer_Import {
17
+
18
+ /**
19
+ * Instance of Astra_Customizer_Import
20
+ *
21
+ * @since 1.0.0
22
+ * @var Astra_Customizer_Import
23
+ */
24
+ private static $_instance = null;
25
+
26
+ /**
27
+ * Instantiate Astra_Customizer_Import
28
+ *
29
+ * @since 1.0.0
30
+ * @return (Object) Astra_Customizer_Import
31
+ */
32
+ public static function instance() {
33
+
34
+ if ( ! isset( self::$_instance ) ) {
35
+ self::$_instance = new self;
36
+ }
37
+
38
+ return self::$_instance;
39
+ }
40
+
41
+ /**
42
+ * Import customizer options.
43
+ *
44
+ * @since 1.0.0
45
+ *
46
+ * @param (Array) $data customizer options from the demo.
47
+ */
48
+ public function import( $data ) {
49
+ update_option( 'astra-settings', $data );
50
+ }
51
+ }
importers/class-astra-site-options-import.php ADDED
@@ -0,0 +1,120 @@
1
+ <?php
2
+ /**
3
+ * Customizer Site options importer class.
4
+ *
5
+ * @since 1.0.0
6
+ * @package Astra Addon
7
+ */
8
+
9
+ defined( 'ABSPATH' ) or exit;
10
+
11
+ /**
12
+ * Customizer Site options importer class.
13
+ *
14
+ * @since 1.0.0
15
+ */
16
+ class Astra_Site_Options_Import {
17
+
18
+ /**
19
+ * Instance of Astra_Site_Options_Importer
20
+ *
21
+ * @since 1.0.0
22
+ * @var (Object) Astra_Site_Options_Importer
23
+ */
24
+ private static $_instance = null;
25
+
26
+ /**
27
+ * Instanciate Astra_Site_Options_Importer
28
+ *
29
+ * @since 1.0.0
30
+ * @return (Object) Astra_Site_Options_Importer
31
+ */
32
+ public static function instance() {
33
+ if ( ! isset( self::$_instance ) ) {
34
+ self::$_instance = new self();
35
+ }
36
+
37
+ return self::$_instance;
38
+ }
39
+
40
+ /**
41
+ * Import site options.
42
+ *
43
+ * @since 1.0.0
44
+ *
45
+ * @param (Array) $options Array of site options to be imported from the demo.
46
+ */
47
+ public function import_options( $options ) {
48
+ $show_on_front = $options['show_on_front'];
49
+ $page_on_front = get_page_by_title( $options['page_on_front'] );
50
+ $page_for_posts = get_page_by_title( $options['page_for_posts'] );
51
+ $siteorigin_widgets_active = $options['siteorigin_widgets_active'];
52
+
53
+ // Update site options.
54
+ update_option( 'show_on_front', $show_on_front );
55
+ update_option( 'page_on_front', $page_on_front->ID );
56
+ update_option( 'page_for_posts', $page_for_posts->ID );
57
+ update_option( 'siteorigin_widgets_active', $siteorigin_widgets_active );
58
+
59
+ $this->set_nav_menu_locations( $options['nav_menu_locations'] );
60
+
61
+ $this->insert_logo( $options['custom_logo'] );
62
+ }
63
+
64
+ /**
65
+ * In WP nav menu is stored as ( 'menu_location' => 'menu_id' );
66
+ * In export we send 'menu_slug' like ( 'menu_location' => 'menu_slug' );
67
+ * In import we set 'menu_id' from menu slug like ( 'menu_location' => 'menu_id' );
68
+ *
69
+ * @since 1.0.0
70
+ * @param array $nav_menu_locations Array of nav menu locations.
71
+ */
72
+ function set_nav_menu_locations( $nav_menu_locations = array() ) {
73
+
74
+ $menu_locations = array();
75
+
76
+ // Update menu locations.
77
+ foreach ( $nav_menu_locations as $menu => $value ) {
78
+
79
+ $term = get_term_by( 'slug', $value, 'nav_menu' );
80
+
81
+ if ( is_object( $term ) ) {
82
+ $menu_locations[ $menu ] = $term->term_id;
83
+ }
84
+ }
85
+
86
+ set_theme_mod( 'nav_menu_locations', $menu_locations );
87
+ }
88
+
89
+
90
+ /**
91
+ * Insert Logo By URL
92
+ *
93
+ * @since 1.0.0
94
+ * @param string $image_url Logo URL.
95
+ * @return void
96
+ */
97
+ function insert_logo( $image_url = '' ) {
98
+
99
+ // Download Site Logo Image.
100
+ $response = Astra_Sites_Helper::download_file( $image_url );
101
+
102
+ // Is Success?
103
+ if ( $response['success'] ) {
104
+
105
+ // Set attachment data.
106
+ $attachment = array(
107
+ 'post_mime_type' => $response['data']['type'],
108
+ 'post_title' => sanitize_file_name( basename( $image_url ) ),
109
+ 'post_content' => '',
110
+ 'post_status' => 'inherit',
111
+ );
112
+
113
+ // Create the attachment.
114
+ $attach_id = wp_insert_attachment( $attachment, $response['data']['file'] );
115
+
116
+ set_theme_mod( 'custom_logo', $attach_id );
117
+ }
118
+
119
+ }
120
+ }
importers/class-astra-sites-helper.php ADDED