Version Description
Download this release
Release Info
Developer | Nikschavan |
Plugin | Astra Starter Sites |
Version | 1.3.2 |
Comparing to | |
See all releases |
Code changes from version 1.3.1 to 1.3.2
- astra-sites.php +54 -54
- inc/assets/css/admin.css +650 -650
- inc/assets/css/install-theme.css +21 -0
- inc/assets/js/admin-page.js +1814 -1814
- inc/assets/js/astra-sites-api.js +64 -64
- inc/assets/js/astra-sites-notices.js +20 -20
- inc/assets/js/eventsource.js +673 -673
- inc/assets/js/eventsource.min.js +5 -5
- inc/assets/js/install-theme.js +108 -0
- inc/assets/js/node_modules/whatwg-fetch/LICENSE +20 -0
- inc/assets/js/node_modules/whatwg-fetch/README.md +334 -0
- inc/assets/js/node_modules/whatwg-fetch/dist/fetch.umd.js +531 -0
- inc/assets/js/node_modules/whatwg-fetch/dist/fetch.umd.js.flow +119 -0
- inc/assets/js/node_modules/whatwg-fetch/fetch.js +516 -0
- inc/assets/js/node_modules/whatwg-fetch/fetch.js.flow +119 -0
- inc/assets/js/node_modules/whatwg-fetch/package.json +73 -0
- inc/assets/js/render-grid.js +596 -596
- inc/classes/class-astra-sites.php +581 -518
- inc/importers/batch-processing/helpers/class-wp-async-request.php +164 -164
- inc/importers/batch-processing/helpers/class-wp-background-process.php +513 -513
- inc/importers/class-widgets-importer.php +278 -278
- inc/importers/wxr-importer/class-logger.php +139 -139
- inc/importers/wxr-importer/class-wp-importer-logger-serversentevents.php +43 -43
- inc/importers/wxr-importer/class-wxr-import-info.php +20 -20
- inc/importers/wxr-importer/class-wxr-importer.php +2300 -2300
- languages/astra-sites.pot +795 -774
- readme.txt +301 -298
astra-sites.php
CHANGED
@@ -1,54 +1,54 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Plugin Name: Astra Starter Sites – Elementor, Beaver Builder & Gutenberg Templates
|
4 |
-
* Plugin URI: http://www.wpastra.com/pro/
|
5 |
-
* Description: Import free sites build with Astra theme.
|
6 |
-
* Version: 1.3.
|
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 |
-
if ( ! defined( 'ASTRA_SITES_NAME' ) ) {
|
18 |
-
define( 'ASTRA_SITES_NAME', __( 'Astra Sites', 'astra-sites' ) );
|
19 |
-
}
|
20 |
-
|
21 |
-
if ( ! defined( 'ASTRA_SITES_VER' ) ) {
|
22 |
-
define( 'ASTRA_SITES_VER', '1.3.
|
23 |
-
}
|
24 |
-
|
25 |
-
if ( ! defined( 'ASTRA_SITES_FILE' ) ) {
|
26 |
-
define( 'ASTRA_SITES_FILE', __FILE__ );
|
27 |
-
}
|
28 |
-
|
29 |
-
if ( ! defined( 'ASTRA_SITES_BASE' ) ) {
|
30 |
-
define( 'ASTRA_SITES_BASE', plugin_basename( ASTRA_SITES_FILE ) );
|
31 |
-
}
|
32 |
-
|
33 |
-
if ( ! defined( 'ASTRA_SITES_DIR' ) ) {
|
34 |
-
define( 'ASTRA_SITES_DIR', plugin_dir_path( ASTRA_SITES_FILE ) );
|
35 |
-
}
|
36 |
-
|
37 |
-
if ( ! defined( 'ASTRA_SITES_URI' ) ) {
|
38 |
-
define( 'ASTRA_SITES_URI', plugins_url( '/', ASTRA_SITES_FILE ) );
|
39 |
-
}
|
40 |
-
|
41 |
-
if ( ! function_exists( 'astra_sites_setup' ) ) :
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Astra Sites Setup
|
45 |
-
*
|
46 |
-
* @since 1.0.5
|
47 |
-
*/
|
48 |
-
function astra_sites_setup() {
|
49 |
-
require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites.php';
|
50 |
-
}
|
51 |
-
|
52 |
-
add_action( 'plugins_loaded', 'astra_sites_setup' );
|
53 |
-
|
54 |
-
endif;
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin Name: Astra Starter Sites – Elementor, Beaver Builder & Gutenberg Templates
|
4 |
+
* Plugin URI: http://www.wpastra.com/pro/
|
5 |
+
* Description: Import free sites build with Astra theme.
|
6 |
+
* Version: 1.3.2
|
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 |
+
if ( ! defined( 'ASTRA_SITES_NAME' ) ) {
|
18 |
+
define( 'ASTRA_SITES_NAME', __( 'Astra Sites', 'astra-sites' ) );
|
19 |
+
}
|
20 |
+
|
21 |
+
if ( ! defined( 'ASTRA_SITES_VER' ) ) {
|
22 |
+
define( 'ASTRA_SITES_VER', '1.3.2' );
|
23 |
+
}
|
24 |
+
|
25 |
+
if ( ! defined( 'ASTRA_SITES_FILE' ) ) {
|
26 |
+
define( 'ASTRA_SITES_FILE', __FILE__ );
|
27 |
+
}
|
28 |
+
|
29 |
+
if ( ! defined( 'ASTRA_SITES_BASE' ) ) {
|
30 |
+
define( 'ASTRA_SITES_BASE', plugin_basename( ASTRA_SITES_FILE ) );
|
31 |
+
}
|
32 |
+
|
33 |
+
if ( ! defined( 'ASTRA_SITES_DIR' ) ) {
|
34 |
+
define( 'ASTRA_SITES_DIR', plugin_dir_path( ASTRA_SITES_FILE ) );
|
35 |
+
}
|
36 |
+
|
37 |
+
if ( ! defined( 'ASTRA_SITES_URI' ) ) {
|
38 |
+
define( 'ASTRA_SITES_URI', plugins_url( '/', ASTRA_SITES_FILE ) );
|
39 |
+
}
|
40 |
+
|
41 |
+
if ( ! function_exists( 'astra_sites_setup' ) ) :
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Astra Sites Setup
|
45 |
+
*
|
46 |
+
* @since 1.0.5
|
47 |
+
*/
|
48 |
+
function astra_sites_setup() {
|
49 |
+
require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites.php';
|
50 |
+
}
|
51 |
+
|
52 |
+
add_action( 'plugins_loaded', 'astra_sites_setup' );
|
53 |
+
|
54 |
+
endif;
|
inc/assets/css/admin.css
CHANGED
@@ -1,651 +1,651 @@
|
|
1 |
-
.wrap .status,
|
2 |
-
.wrap .site-type {
|
3 |
-
position: absolute;
|
4 |
-
z-index: 1;
|
5 |
-
color: #fff;
|
6 |
-
padding: 0.5em 1em;
|
7 |
-
top: -0.5em;
|
8 |
-
text-transform: uppercase;
|
9 |
-
}
|
10 |
-
.wrap .status,
|
11 |
-
.wrap .site-type.premium {
|
12 |
-
background: #0073aa;
|
13 |
-
}
|
14 |
-
.wrap .status {
|
15 |
-
left: -0.5em;
|
16 |
-
}
|
17 |
-
.wrap .site-type.premium {
|
18 |
-
right: -0.5em;
|
19 |
-
}
|
20 |
-
|
21 |
-
.wrap .status.publish,
|
22 |
-
.wrap .site-type.free {
|
23 |
-
display: none;
|
24 |
-
}
|
25 |
-
|
26 |
-
.install-theme-info .site-type {
|
27 |
-
display: none;
|
28 |
-
}
|
29 |
-
|
30 |
-
.theme {
|
31 |
-
position: relative;
|
32 |
-
}
|
33 |
-
.wrap .astra-sites-preview .site-type.premium {
|
34 |
-
display: block;
|
35 |
-
display: none;
|
36 |
-
position: relative;
|
37 |
-
margin: 0.5em 0em 1em 0em;
|
38 |
-
top: 0;
|
39 |
-
left: 0;
|
40 |
-
text-align: center;
|
41 |
-
}
|
42 |
-
|
43 |
-
.theme-details-read-more.open {
|
44 |
-
margin: 0.5em 0 0 0;
|
45 |
-
}
|
46 |
-
|
47 |
-
.astra-sites-preview .theme-screenshot {
|
48 |
-
width: 100%;
|
49 |
-
}
|
50 |
-
|
51 |
-
.install-theme-info .site-type.premium {
|
52 |
-
display: none;
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Required Plugins
|
57 |
-
*/
|
58 |
-
.required-plugins.loading {
|
59 |
-
text-align: center;
|
60 |
-
}
|
61 |
-
.required-plugins button {
|
62 |
-
float: right;
|
63 |
-
}
|
64 |
-
.required-plugins .plugin-card {
|
65 |
-
float: none;
|
66 |
-
width: 100%;
|
67 |
-
border: none;
|
68 |
-
margin: 0 0 0.8em 0;
|
69 |
-
display: flex;
|
70 |
-
justify-content: space-between;
|
71 |
-
align-items: center;
|
72 |
-
transition: background ease 0.8s;
|
73 |
-
}
|
74 |
-
.required-plugins .plugin-card.plugin-card-update-failed {
|
75 |
-
flex-wrap: wrap;
|
76 |
-
}
|
77 |
-
.required-plugins .spinner {
|
78 |
-
float: none;
|
79 |
-
margin: 0;
|
80 |
-
}
|
81 |
-
|
82 |
-
.expanded .wp-full-overlay-footer {
|
83 |
-
height: 111px;
|
84 |
-
}
|
85 |
-
|
86 |
-
.wp-full-overlay-footer .view-site,
|
87 |
-
.wp-full-overlay-footer .go-pro,
|
88 |
-
.wp-full-overlay-footer .astra-demo-import {
|
89 |
-
width: 100%;
|
90 |
-
text-align: center;
|
91 |
-
}
|
92 |
-
|
93 |
-
.wp-core-ui .wp-full-overlay-footer .button.button-hero,
|
94 |
-
.wp-core-ui .wp-full-overlay-footer .button-group.button-hero .button {
|
95 |
-
padding: 0 10px 1px;
|
96 |
-
}
|
97 |
-
|
98 |
-
.wp-full-overlay-footer .installing:before {
|
99 |
-
vertical-align: text-bottom;
|
100 |
-
}
|
101 |
-
|
102 |
-
.astra-sites-advanced-options-wrap h4 {
|
103 |
-
margin: 1em 0 0.5em 0;
|
104 |
-
padding: 0.5em 0;
|
105 |
-
transition: all ease 0.3s;
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* Read more link
|
110 |
-
*/
|
111 |
-
.wp-core-ui .theme-details-read-more:focus,
|
112 |
-
.wp-core-ui .theme-details-read-more:hover {
|
113 |
-
outline: none;
|
114 |
-
box-shadow: none;
|
115 |
-
}
|
116 |
-
.wp-core-ui .theme-details-read-more {
|
117 |
-
margin: 10px 0;
|
118 |
-
display: none;
|
119 |
-
text-decoration: none;
|
120 |
-
}
|
121 |
-
|
122 |
-
/**
|
123 |
-
* Go pro.
|
124 |
-
*/
|
125 |
-
.wp-core-ui .go-pro.button[disabled] {
|
126 |
-
background-color: #fcb92c !important;
|
127 |
-
color: white !important;
|
128 |
-
box-shadow: 1px 0 #eab23a !important;
|
129 |
-
text-shadow: 1px 0 #6b4e13 !important;
|
130 |
-
border-color: #e2a932 !important;
|
131 |
-
cursor: pointer;
|
132 |
-
}
|
133 |
-
.wp-core-ui .view-site .dashicons,
|
134 |
-
.wp-core-ui .go-pro .dashicons {
|
135 |
-
font-size: 1rem;
|
136 |
-
vertical-align: middle;
|
137 |
-
}
|
138 |
-
|
139 |
-
/**
|
140 |
-
* Errors
|
141 |
-
*/
|
142 |
-
.plugin-card-update-failed .notice {
|
143 |
-
margin-top: 1.5em;
|
144 |
-
}
|
145 |
-
|
146 |
-
.no-themes {
|
147 |
-
margin-top: 40px;
|
148 |
-
}
|
149 |
-
|
150 |
-
.no-themes p {
|
151 |
-
font-size: 15px;
|
152 |
-
}
|
153 |
-
|
154 |
-
.no-themes .left-margin {
|
155 |
-
margin-left: 30px;
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
*
|
160 |
-
*/
|
161 |
-
.astra-sites-preview .wp-full-overlay-sidebar-content {
|
162 |
-
bottom: 100px;
|
163 |
-
}
|
164 |
-
|
165 |
-
.footer-import-button-wrap {
|
166 |
-
padding: 10px 20px;
|
167 |
-
}
|
168 |
-
|
169 |
-
.footer-import-button-wrap .button {
|
170 |
-
margin: 0;
|
171 |
-
}
|
172 |
-
|
173 |
-
.astra-sites-preview.expanded .wp-full-overlay-footer {
|
174 |
-
left: initial;
|
175 |
-
}
|
176 |
-
|
177 |
-
/**
|
178 |
-
* Menu Page
|
179 |
-
*/
|
180 |
-
.astra-sites-title {
|
181 |
-
float: left;
|
182 |
-
font-size: 23px;
|
183 |
-
font-weight: 400;
|
184 |
-
margin: 0 0 6px 0px;
|
185 |
-
padding: 0;
|
186 |
-
line-height: 29px;
|
187 |
-
}
|
188 |
-
|
189 |
-
#astra-sites-menu-page {
|
190 |
-
margin-top: 10px;
|
191 |
-
}
|
192 |
-
|
193 |
-
/**
|
194 |
-
* API Error
|
195 |
-
*/
|
196 |
-
.astra-api-error {
|
197 |
-
margin: 0 0 0.5em 0;
|
198 |
-
}
|
199 |
-
|
200 |
-
/**
|
201 |
-
* Grid
|
202 |
-
*/
|
203 |
-
.wp-filter .search-form {
|
204 |
-
margin-left: 1em;
|
205 |
-
}
|
206 |
-
.wp-filter .search-form input[type="search"] {
|
207 |
-
width: 200px;
|
208 |
-
font-size: 13px;
|
209 |
-
padding: 5px 10px;
|
210 |
-
}
|
211 |
-
.section-left {
|
212 |
-
display: inline-block;
|
213 |
-
}
|
214 |
-
.section-right {
|
215 |
-
float: right;
|
216 |
-
}
|
217 |
-
.filter-count {
|
218 |
-
min-width: 3em;
|
219 |
-
}
|
220 |
-
.astra-site-preview-on {
|
221 |
-
overflow: hidden;
|
222 |
-
}
|
223 |
-
|
224 |
-
.appearance_page_astra-sites .notice {
|
225 |
-
margin-left: 0;
|
226 |
-
width: auto;
|
227 |
-
float: none;
|
228 |
-
}
|
229 |
-
.filters-wrap {
|
230 |
-
display: inline-block;
|
231 |
-
}
|
232 |
-
.spinner-wrap {
|
233 |
-
text-align: center;
|
234 |
-
}
|
235 |
-
.spinner-wrap .spinner {
|
236 |
-
float: none;
|
237 |
-
}
|
238 |
-
.hide-me {
|
239 |
-
display: none !important;
|
240 |
-
}
|
241 |
-
#astra-sites-admin {
|
242 |
-
height: 100vh;
|
243 |
-
}
|
244 |
-
.install-theme-info > .notice {
|
245 |
-
margin: 5px 0 10px 0;
|
246 |
-
}
|
247 |
-
|
248 |
-
.astra-sites-suggestions:before {
|
249 |
-
border: 5px dashed #ccc;
|
250 |
-
position: absolute;
|
251 |
-
left: 0;
|
252 |
-
right: 0;
|
253 |
-
top: 0;
|
254 |
-
bottom: 0px;
|
255 |
-
}
|
256 |
-
|
257 |
-
.astra-sites-suggestions {
|
258 |
-
min-height: 280px;
|
259 |
-
border: none !important;
|
260 |
-
}
|
261 |
-
|
262 |
-
.astra-sites-suggestions a {
|
263 |
-
border: none;
|
264 |
-
outline: none;
|
265 |
-
}
|
266 |
-
|
267 |
-
.astra-sites-suggestions .inner {
|
268 |
-
border: 6px solid #24282e !important;
|
269 |
-
padding: 27% 10% 50% 10%;
|
270 |
-
text-align: center;
|
271 |
-
position: absolute;
|
272 |
-
left: 0;
|
273 |
-
right: 0;
|
274 |
-
top: 0;
|
275 |
-
background: #33383d;
|
276 |
-
bottom: 0;
|
277 |
-
color: #eee;
|
278 |
-
cursor: auto;
|
279 |
-
}
|
280 |
-
|
281 |
-
.astra-sites-suggestions .inner a {
|
282 |
-
color: #00b9eb;
|
283 |
-
}
|
284 |
-
|
285 |
-
.astra-sites-suggestions p {
|
286 |
-
font-size: 1rem;
|
287 |
-
margin: 0;
|
288 |
-
}
|
289 |
-
|
290 |
-
.astra-notice {
|
291 |
-
margin: 2em 2em 0em 0em;
|
292 |
-
}
|
293 |
-
|
294 |
-
.no-themes .description {
|
295 |
-
display: block;
|
296 |
-
}
|
297 |
-
|
298 |
-
/**
|
299 |
-
* Responsive Button UI
|
300 |
-
*/
|
301 |
-
.astra-sites-preview .wp-full-overlay-footer .devices button.active:before,
|
302 |
-
.astra-sites-preview .wp-full-overlay-footer .devices button:hover:before {
|
303 |
-
color: #0073aa;
|
304 |
-
}
|
305 |
-
.astra-sites-preview .wp-full-overlay-footer .devices button:before {
|
306 |
-
color: #c1c1c1;
|
307 |
-
}
|
308 |
-
.astra-sites-preview .wp-full-overlay-footer .devices button:hover {
|
309 |
-
background-color: transparent;
|
310 |
-
}
|
311 |
-
.astra-sites-preview .wp-full-overlay-footer .devices button {
|
312 |
-
border: none;
|
313 |
-
}
|
314 |
-
.astra-sites-preview .wp-full-overlay-footer .devices button:focus,
|
315 |
-
.astra-sites-preview .wp-full-overlay-footer .devices button.active:hover {
|
316 |
-
border-bottom-color: transparent;
|
317 |
-
background-color: transparent;
|
318 |
-
}
|
319 |
-
.not-click-able {
|
320 |
-
pointer-events: none !important;
|
321 |
-
}
|
322 |
-
body.page-builder-selected .select-page-builder,
|
323 |
-
body.loading-content .select-page-builder {
|
324 |
-
display: none;
|
325 |
-
}
|
326 |
-
.select-page-builder .up-arrow {
|
327 |
-
-webkit-transform: rotate(90deg);
|
328 |
-
-moz-transform: rotate(90deg);
|
329 |
-
-ms-transform: rotate(90deg);
|
330 |
-
transform: rotate(90deg);
|
331 |
-
display: inline-block;
|
332 |
-
font-size: 1.5em;
|
333 |
-
color: #797979;
|
334 |
-
vertical-align: middle;
|
335 |
-
margin-right: 10px;
|
336 |
-
-webkit-transition: all linear 0.6s;
|
337 |
-
-moz-transition: all linear 0.6s;
|
338 |
-
-ms-transition: all linear 0.6s;
|
339 |
-
transition: all linear 0.6s;
|
340 |
-
-webkit-animation-duration: 1s;
|
341 |
-
animation-duration: 1s;
|
342 |
-
-webkit-animation-fill-mode: both;
|
343 |
-
animation-fill-mode: both;
|
344 |
-
-webkit-animation-timing-function: ease-in-out;
|
345 |
-
animation-timing-function: ease-in-out;
|
346 |
-
animation-iteration-count: infinite;
|
347 |
-
-webkit-animation-iteration-count: infinite;
|
348 |
-
animation-name: bounce;
|
349 |
-
-moz-animation-name: bounce;
|
350 |
-
}
|
351 |
-
.select-page-builder {
|
352 |
-
margin-left: 6em;
|
353 |
-
}
|
354 |
-
|
355 |
-
.select-page-builder img {
|
356 |
-
max-width: 100%;
|
357 |
-
}
|
358 |
-
|
359 |
-
.select-page-builder .note-wrap {
|
360 |
-
position: absolute;
|
361 |
-
padding: 40px 0;
|
362 |
-
margin-left: 170px;
|
363 |
-
right: 0;
|
364 |
-
left: 0;
|
365 |
-
}
|
366 |
-
|
367 |
-
.select-page-builder h3 {
|
368 |
-
margin: 0;
|
369 |
-
font-size: 2em;
|
370 |
-
}
|
371 |
-
.select-page-builder {
|
372 |
-
margin: -20px 0 0 -5px;
|
373 |
-
position: absolute;
|
374 |
-
}
|
375 |
-
.select-page-builder .note {
|
376 |
-
margin-left: 1.5em;
|
377 |
-
}
|
378 |
-
|
379 |
-
@keyframes bounce {
|
380 |
-
0%,
|
381 |
-
100%,
|
382 |
-
20%,
|
383 |
-
50%,
|
384 |
-
80% {
|
385 |
-
-webkit-transform: translateY(-0px) rotate(90deg);
|
386 |
-
-moz-transform: translateY(-0px) rotate(90deg);
|
387 |
-
-ms-transform: translateY(-0px) rotate(90deg);
|
388 |
-
transform: translateY(-0px) rotate(90deg);
|
389 |
-
}
|
390 |
-
40% {
|
391 |
-
-webkit-transform: translateY(-2px) rotate(90deg);
|
392 |
-
-moz-transform: translateY(-2px) rotate(90deg);
|
393 |
-
-ms-transform: translateY(-2px) rotate(90deg);
|
394 |
-
transform: translateY(-2px) rotate(90deg);
|
395 |
-
}
|
396 |
-
60% {
|
397 |
-
-webkit-transform: translateY(-1px) rotate(90deg);
|
398 |
-
-moz-transform: translateY(-1px) rotate(90deg);
|
399 |
-
-ms-transform: translateY(-1px) rotate(90deg);
|
400 |
-
transform: translateY(-1px) rotate(90deg);
|
401 |
-
}
|
402 |
-
}
|
403 |
-
|
404 |
-
/**
|
405 |
-
* Processing Animation
|
406 |
-
*/
|
407 |
-
.astra-demo-import.disabled {
|
408 |
-
pointer-events: none;
|
409 |
-
}
|
410 |
-
.astra-demo-import.button.updating-message:before,
|
411 |
-
.astra-demo-import.button.installing:before {
|
412 |
-
-webkit-animation: cssAnimation .72s ease infinite;
|
413 |
-
-moz-animation: cssAnimation .72s ease infinite;
|
414 |
-
-o-animation: cssAnimation .72s ease infinite;
|
415 |
-
-ms-animation: cssAnimation .72s ease infinite;
|
416 |
-
animation: cssAnimation .72s ease infinite;
|
417 |
-
}
|
418 |
-
|
419 |
-
@-webkit-keyframes cssAnimation {
|
420 |
-
from {
|
421 |
-
-webkit-transform: rotate(0);
|
422 |
-
-moz-transform: rotate(0);
|
423 |
-
-o-transform: rotate(0);
|
424 |
-
-ms-transform: rotate(0);
|
425 |
-
transform: rotate(0);
|
426 |
-
}
|
427 |
-
to {
|
428 |
-
-webkit-transform: rotate(360deg);
|
429 |
-
-moz-transform: rotate(360deg);
|
430 |
-
-o-transform: rotate(360deg);
|
431 |
-
-ms-transform: rotate(360deg);
|
432 |
-
transform: rotate(360deg);
|
433 |
-
}
|
434 |
-
}
|
435 |
-
@-moz-keyframes cssAnimation {
|
436 |
-
from {
|
437 |
-
-webkit-transform: rotate(0);
|
438 |
-
-moz-transform: rotate(0);
|
439 |
-
-o-transform: rotate(0);
|
440 |
-
-ms-transform: rotate(0);
|
441 |
-
transform: rotate(0);
|
442 |
-
}
|
443 |
-
to {
|
444 |
-
-webkit-transform: rotate(360deg);
|
445 |
-
-moz-transform: rotate(360deg);
|
446 |
-
-o-transform: rotate(360deg);
|
447 |
-
-ms-transform: rotate(360deg);
|
448 |
-
transform: rotate(360deg);
|
449 |
-
}
|
450 |
-
}
|
451 |
-
@-o-keyframes cssAnimation {
|
452 |
-
from {
|
453 |
-
-webkit-transform: rotate(0);
|
454 |
-
-moz-transform: rotate(0);
|
455 |
-
-o-transform: rotate(0);
|
456 |
-
-ms-transform: rotate(0);
|
457 |
-
transform: rotate(0);
|
458 |
-
}
|
459 |
-
to {
|
460 |
-
-webkit-transform: rotate(360deg);
|
461 |
-
-moz-transform: rotate(360deg);
|
462 |
-
-o-transform: rotate(360deg);
|
463 |
-
-ms-transform: rotate(360deg);
|
464 |
-
transform: rotate(360deg);
|
465 |
-
}
|
466 |
-
}
|
467 |
-
|
468 |
-
#astra-sites-filters {
|
469 |
-
display: inline-block;
|
470 |
-
width: 100%;
|
471 |
-
}
|
472 |
-
|
473 |
-
.astra-site-down {
|
474 |
-
padding: 1em 2em;
|
475 |
-
margin-top: 1em;
|
476 |
-
}
|
477 |
-
|
478 |
-
#astra-sites-menu-page .nav-tab-wrapper {
|
479 |
-
border: none;
|
480 |
-
}
|
481 |
-
|
482 |
-
#astra-sites-filters .wp-filter {
|
483 |
-
margin-top: 0;
|
484 |
-
}
|
485 |
-
|
486 |
-
/**
|
487 |
-
* Welcome Screen
|
488 |
-
*/
|
489 |
-
.astra-sites-welcome {
|
490 |
-
padding: 10em 0;
|
491 |
-
text-align: center;
|
492 |
-
}
|
493 |
-
.astra-sites-welcome .inner {
|
494 |
-
margin: 0 auto;
|
495 |
-
display: inline-block;
|
496 |
-
max-width: 700px;
|
497 |
-
background: #fff;
|
498 |
-
padding: 3em;
|
499 |
-
}
|
500 |
-
|
501 |
-
.astra-sites-welcome h1 {
|
502 |
-
font-size: 2.5em;
|
503 |
-
margin-bottom: 1em;
|
504 |
-
}
|
505 |
-
|
506 |
-
.astra-sites-welcome p.description {
|
507 |
-
font-size: 1rem;
|
508 |
-
margin-bottom: 2em;
|
509 |
-
}
|
510 |
-
|
511 |
-
.astra-sites-welcome select {
|
512 |
-
padding: 5px;
|
513 |
-
height: 100%;
|
514 |
-
}
|
515 |
-
|
516 |
-
.astra-sites-welcome p.submit {
|
517 |
-
text-align: center;
|
518 |
-
margin: 0;
|
519 |
-
padding: 0;
|
520 |
-
margin-left: .5em;
|
521 |
-
}
|
522 |
-
|
523 |
-
.astra-sites-welcome .fields {
|
524 |
-
display: flex;
|
525 |
-
vertical-align: middle;
|
526 |
-
align-items: center;
|
527 |
-
justify-content: center;
|
528 |
-
}
|
529 |
-
|
530 |
-
.astra-sites-welcome #submit {
|
531 |
-
line-height: 1;
|
532 |
-
padding: .5rem 1rem;
|
533 |
-
height: auto;
|
534 |
-
}
|
535 |
-
|
536 |
-
.astra-site-page-builder {
|
537 |
-
opacity: 0;
|
538 |
-
visibility: hidden;
|
539 |
-
}
|
540 |
-
|
541 |
-
.required-plugins-list {
|
542 |
-
margin-left: 2em;
|
543 |
-
margin-top: .5em;
|
544 |
-
margin-bottom: .5em;
|
545 |
-
list-style-type: disc;
|
546 |
-
}
|
547 |
-
|
548 |
-
.required-plugins-list .plugin-card {
|
549 |
-
background: transparent;
|
550 |
-
border: none;
|
551 |
-
margin: 0;
|
552 |
-
line-height: 2;
|
553 |
-
float: none;
|
554 |
-
width: 100%;
|
555 |
-
}
|
556 |
-
|
557 |
-
.required-plugins-list .spinner {
|
558 |
-
float: none;
|
559 |
-
margin: 0;
|
560 |
-
}
|
561 |
-
|
562 |
-
#astra-site-import-process-wrap {
|
563 |
-
display: flex;
|
564 |
-
align-items: center;
|
565 |
-
margin-top: -2px;
|
566 |
-
z-index: 999999;
|
567 |
-
position: relative;
|
568 |
-
border-radius: 3px;
|
569 |
-
overflow: hidden;
|
570 |
-
}
|
571 |
-
#astra-site-import-process-wrap progress {
|
572 |
-
padding: 0px;
|
573 |
-
border: 0 none;
|
574 |
-
background: #0085bd;
|
575 |
-
border-radius: 5px;
|
576 |
-
height: 4px;
|
577 |
-
flex: 1;
|
578 |
-
}
|
579 |
-
|
580 |
-
#astra-site-import-process-wrap progress::-webkit-progress-value {
|
581 |
-
background: #00679b;
|
582 |
-
}
|
583 |
-
#astra-site-import-process-wrap progress::-webkit-progress-bar {
|
584 |
-
background: transparent;
|
585 |
-
}
|
586 |
-
|
587 |
-
.theme-browser .theme .site-preview > .theme-screenshot {
|
588 |
-
transition: all ease-in-out 3s;
|
589 |
-
background-position: center top;
|
590 |
-
background-size: cover;
|
591 |
-
background-repeat: no-repeat;
|
592 |
-
}
|
593 |
-
.theme-browser .theme .site-preview > .theme-screenshot:hover {
|
594 |
-
background-position: center bottom;
|
595 |
-
background-size: cover;
|
596 |
-
}
|
597 |
-
|
598 |
-
.astra-sites-tooltip-icon {
|
599 |
-
cursor: pointer;
|
600 |
-
}
|
601 |
-
|
602 |
-
.astra-sites-tooltip-icon .dashicons {
|
603 |
-
color: #5d5d5d;
|
604 |
-
font-size: 18px;
|
605 |
-
}
|
606 |
-
|
607 |
-
#astra-sites-welcome-form-inline {
|
608 |
-
position: absolute;
|
609 |
-
right: 1em;
|
610 |
-
top: 0;
|
611 |
-
border-radius: 0;
|
612 |
-
line-height: 1.7;
|
613 |
-
padding: 0px 5px 2px 5px;
|
614 |
-
outline: 2px solid transparent;
|
615 |
-
outline-offset: 0;
|
616 |
-
background: #fafafa;
|
617 |
-
border: 1px solid #ccc;
|
618 |
-
color: #72777c;
|
619 |
-
font-weight: normal;
|
620 |
-
font-size: 10px;
|
621 |
-
font-size: 13px;
|
622 |
-
line-height: 26px;
|
623 |
-
height: 28px;
|
624 |
-
cursor: pointer;
|
625 |
-
}
|
626 |
-
|
627 |
-
#astra-sites-welcome-form-inline select,
|
628 |
-
#astra-sites-welcome-form-inline select:focus {
|
629 |
-
border: none;
|
630 |
-
outline: none;
|
631 |
-
box-shadow: none;
|
632 |
-
color: #72777c;
|
633 |
-
}
|
634 |
-
|
635 |
-
#astra-sites-menu-page .wp-full-overlay-main:before {
|
636 |
-
content: '';
|
637 |
-
display: none;
|
638 |
-
}
|
639 |
-
|
640 |
-
.theme-screenshot-wrap {
|
641 |
-
overflow: hidden;
|
642 |
-
max-height: 300px;
|
643 |
-
margin: 15px 0;
|
644 |
-
border: 1px solid #ccc;
|
645 |
-
}
|
646 |
-
|
647 |
-
.astra-sites-preview .install-theme-info .theme-screenshot {
|
648 |
-
width: 100%;
|
649 |
-
border: none;
|
650 |
-
margin: 0;
|
651 |
Â
}
|
1 |
+
.wrap .status,
|
2 |
+
.wrap .site-type {
|
3 |
+
position: absolute;
|
4 |
+
z-index: 1;
|
5 |
+
color: #fff;
|
6 |
+
padding: 0.5em 1em;
|
7 |
+
top: -0.5em;
|
8 |
+
text-transform: uppercase;
|
9 |
+
}
|
10 |
+
.wrap .status,
|
11 |
+
.wrap .site-type.premium {
|
12 |
+
background: #0073aa;
|
13 |
+
}
|
14 |
+
.wrap .status {
|
15 |
+
left: -0.5em;
|
16 |
+
}
|
17 |
+
.wrap .site-type.premium {
|
18 |
+
right: -0.5em;
|
19 |
+
}
|
20 |
+
|
21 |
+
.wrap .status.publish,
|
22 |
+
.wrap .site-type.free {
|
23 |
+
display: none;
|
24 |
+
}
|
25 |
+
|
26 |
+
.install-theme-info .site-type {
|
27 |
+
display: none;
|
28 |
+
}
|
29 |
+
|
30 |
+
.theme {
|
31 |
+
position: relative;
|
32 |
+
}
|
33 |
+
.wrap .astra-sites-preview .site-type.premium {
|
34 |
+
display: block;
|
35 |
+
display: none;
|
36 |
+
position: relative;
|
37 |
+
margin: 0.5em 0em 1em 0em;
|
38 |
+
top: 0;
|
39 |
+
left: 0;
|
40 |
+
text-align: center;
|
41 |
+
}
|
42 |
+
|
43 |
+
.theme-details-read-more.open {
|
44 |
+
margin: 0.5em 0 0 0;
|
45 |
+
}
|
46 |
+
|
47 |
+
.astra-sites-preview .theme-screenshot {
|
48 |
+
width: 100%;
|
49 |
+
}
|
50 |
+
|
51 |
+
.install-theme-info .site-type.premium {
|
52 |
+
display: none;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Required Plugins
|
57 |
+
*/
|
58 |
+
.required-plugins.loading {
|
59 |
+
text-align: center;
|
60 |
+
}
|
61 |
+
.required-plugins button {
|
62 |
+
float: right;
|
63 |
+
}
|
64 |
+
.required-plugins .plugin-card {
|
65 |
+
float: none;
|
66 |
+
width: 100%;
|
67 |
+
border: none;
|
68 |
+
margin: 0 0 0.8em 0;
|
69 |
+
display: flex;
|
70 |
+
justify-content: space-between;
|
71 |
+
align-items: center;
|
72 |
+
transition: background ease 0.8s;
|
73 |
+
}
|
74 |
+
.required-plugins .plugin-card.plugin-card-update-failed {
|
75 |
+
flex-wrap: wrap;
|
76 |
+
}
|
77 |
+
.required-plugins .spinner {
|
78 |
+
float: none;
|
79 |
+
margin: 0;
|
80 |
+
}
|
81 |
+
|
82 |
+
.expanded .wp-full-overlay-footer {
|
83 |
+
height: 111px;
|
84 |
+
}
|
85 |
+
|
86 |
+
.wp-full-overlay-footer .view-site,
|
87 |
+
.wp-full-overlay-footer .go-pro,
|
88 |
+
.wp-full-overlay-footer .astra-demo-import {
|
89 |
+
width: 100%;
|
90 |
+
text-align: center;
|
91 |
+
}
|
92 |
+
|
93 |
+
.wp-core-ui .wp-full-overlay-footer .button.button-hero,
|
94 |
+
.wp-core-ui .wp-full-overlay-footer .button-group.button-hero .button {
|
95 |
+
padding: 0 10px 1px;
|
96 |
+
}
|
97 |
+
|
98 |
+
.wp-full-overlay-footer .installing:before {
|
99 |
+
vertical-align: text-bottom;
|
100 |
+
}
|
101 |
+
|
102 |
+
.astra-sites-advanced-options-wrap h4 {
|
103 |
+
margin: 1em 0 0.5em 0;
|
104 |
+
padding: 0.5em 0;
|
105 |
+
transition: all ease 0.3s;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Read more link
|
110 |
+
*/
|
111 |
+
.wp-core-ui .theme-details-read-more:focus,
|
112 |
+
.wp-core-ui .theme-details-read-more:hover {
|
113 |
+
outline: none;
|
114 |
+
box-shadow: none;
|
115 |
+
}
|
116 |
+
.wp-core-ui .theme-details-read-more {
|
117 |
+
margin: 10px 0;
|
118 |
+
display: none;
|
119 |
+
text-decoration: none;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Go pro.
|
124 |
+
*/
|
125 |
+
.wp-core-ui .go-pro.button[disabled] {
|
126 |
+
background-color: #fcb92c !important;
|
127 |
+
color: white !important;
|
128 |
+
box-shadow: 1px 0 #eab23a !important;
|
129 |
+
text-shadow: 1px 0 #6b4e13 !important;
|
130 |
+
border-color: #e2a932 !important;
|
131 |
+
cursor: pointer;
|
132 |
+
}
|
133 |
+
.wp-core-ui .view-site .dashicons,
|
134 |
+
.wp-core-ui .go-pro .dashicons {
|
135 |
+
font-size: 1rem;
|
136 |
+
vertical-align: middle;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Errors
|
141 |
+
*/
|
142 |
+
.plugin-card-update-failed .notice {
|
143 |
+
margin-top: 1.5em;
|
144 |
+
}
|
145 |
+
|
146 |
+
.no-themes {
|
147 |
+
margin-top: 40px;
|
148 |
+
}
|
149 |
+
|
150 |
+
.no-themes p {
|
151 |
+
font-size: 15px;
|
152 |
+
}
|
153 |
+
|
154 |
+
.no-themes .left-margin {
|
155 |
+
margin-left: 30px;
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
*
|
160 |
+
*/
|
161 |
+
.astra-sites-preview .wp-full-overlay-sidebar-content {
|
162 |
+
bottom: 100px;
|
163 |
+
}
|
164 |
+
|
165 |
+
.footer-import-button-wrap {
|
166 |
+
padding: 10px 20px;
|
167 |
+
}
|
168 |
+
|
169 |
+
.footer-import-button-wrap .button {
|
170 |
+
margin: 0;
|
171 |
+
}
|
172 |
+
|
173 |
+
.astra-sites-preview.expanded .wp-full-overlay-footer {
|
174 |
+
left: initial;
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Menu Page
|
179 |
+
*/
|
180 |
+
.astra-sites-title {
|
181 |
+
float: left;
|
182 |
+
font-size: 23px;
|
183 |
+
font-weight: 400;
|
184 |
+
margin: 0 0 6px 0px;
|
185 |
+
padding: 0;
|
186 |
+
line-height: 29px;
|
187 |
+
}
|
188 |
+
|
189 |
+
#astra-sites-menu-page {
|
190 |
+
margin-top: 10px;
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* API Error
|
195 |
+
*/
|
196 |
+
.astra-api-error {
|
197 |
+
margin: 0 0 0.5em 0;
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Grid
|
202 |
+
*/
|
203 |
+
.wp-filter .search-form {
|
204 |
+
margin-left: 1em;
|
205 |
+
}
|
206 |
+
.wp-filter .search-form input[type="search"] {
|
207 |
+
width: 200px;
|
208 |
+
font-size: 13px;
|
209 |
+
padding: 5px 10px;
|
210 |
+
}
|
211 |
+
.section-left {
|
212 |
+
display: inline-block;
|
213 |
+
}
|
214 |
+
.section-right {
|
215 |
+
float: right;
|
216 |
+
}
|
217 |
+
.filter-count {
|
218 |
+
min-width: 3em;
|
219 |
+
}
|
220 |
+
.astra-site-preview-on {
|
221 |
+
overflow: hidden;
|
222 |
+
}
|
223 |
+
|
224 |
+
.appearance_page_astra-sites .notice {
|
225 |
+
margin-left: 0;
|
226 |
+
width: auto;
|
227 |
+
float: none;
|
228 |
+
}
|
229 |
+
.filters-wrap {
|
230 |
+
display: inline-block;
|
231 |
+
}
|
232 |
+
.spinner-wrap {
|
233 |
+
text-align: center;
|
234 |
+
}
|
235 |
+
.spinner-wrap .spinner {
|
236 |
+
float: none;
|
237 |
+
}
|
238 |
+
.hide-me {
|
239 |
+
display: none !important;
|
240 |
+
}
|
241 |
+
#astra-sites-admin {
|
242 |
+
height: 100vh;
|
243 |
+
}
|
244 |
+
.install-theme-info > .notice {
|
245 |
+
margin: 5px 0 10px 0;
|
246 |
+
}
|
247 |
+
|
248 |
+
.astra-sites-suggestions:before {
|
249 |
+
border: 5px dashed #ccc;
|
250 |
+
position: absolute;
|
251 |
+
left: 0;
|
252 |
+
right: 0;
|
253 |
+
top: 0;
|
254 |
+
bottom: 0px;
|
255 |
+
}
|
256 |
+
|
257 |
+
.astra-sites-suggestions {
|
258 |
+
min-height: 280px;
|
259 |
+
border: none !important;
|
260 |
+
}
|
261 |
+
|
262 |
+
.astra-sites-suggestions a {
|
263 |
+
border: none;
|
264 |
+
outline: none;
|
265 |
+
}
|
266 |
+
|
267 |
+
.astra-sites-suggestions .inner {
|
268 |
+
border: 6px solid #24282e !important;
|
269 |
+
padding: 27% 10% 50% 10%;
|
270 |
+
text-align: center;
|
271 |
+
position: absolute;
|
272 |
+
left: 0;
|
273 |
+
right: 0;
|
274 |
+
top: 0;
|
275 |
+
background: #33383d;
|
276 |
+
bottom: 0;
|
277 |
+
color: #eee;
|
278 |
+
cursor: auto;
|
279 |
+
}
|
280 |
+
|
281 |
+
.astra-sites-suggestions .inner a {
|
282 |
+
color: #00b9eb;
|
283 |
+
}
|
284 |
+
|
285 |
+
.astra-sites-suggestions p {
|
286 |
+
font-size: 1rem;
|
287 |
+
margin: 0;
|
288 |
+
}
|
289 |
+
|
290 |
+
.astra-notice {
|
291 |
+
margin: 2em 2em 0em 0em;
|
292 |
+
}
|
293 |
+
|
294 |
+
.no-themes .description {
|
295 |
+
display: block;
|
296 |
+
}
|
297 |
+
|
298 |
+
/**
|
299 |
+
* Responsive Button UI
|
300 |
+
*/
|
301 |
+
.astra-sites-preview .wp-full-overlay-footer .devices button.active:before,
|
302 |
+
.astra-sites-preview .wp-full-overlay-footer .devices button:hover:before {
|
303 |
+
color: #0073aa;
|
304 |
+
}
|
305 |
+
.astra-sites-preview .wp-full-overlay-footer .devices button:before {
|
306 |
+
color: #c1c1c1;
|
307 |
+
}
|
308 |
+
.astra-sites-preview .wp-full-overlay-footer .devices button:hover {
|
309 |
+
background-color: transparent;
|
310 |
+
}
|
311 |
+
.astra-sites-preview .wp-full-overlay-footer .devices button {
|
312 |
+
border: none;
|
313 |
+
}
|
314 |
+
.astra-sites-preview .wp-full-overlay-footer .devices button:focus,
|
315 |
+
.astra-sites-preview .wp-full-overlay-footer .devices button.active:hover {
|
316 |
+
border-bottom-color: transparent;
|
317 |
+
background-color: transparent;
|
318 |
+
}
|
319 |
+
.not-click-able {
|
320 |
+
pointer-events: none !important;
|
321 |
+
}
|
322 |
+
body.page-builder-selected .select-page-builder,
|
323 |
+
body.loading-content .select-page-builder {
|
324 |
+
display: none;
|
325 |
+
}
|
326 |
+
.select-page-builder .up-arrow {
|
327 |
+
-webkit-transform: rotate(90deg);
|
328 |
+
-moz-transform: rotate(90deg);
|
329 |
+
-ms-transform: rotate(90deg);
|
330 |
+
transform: rotate(90deg);
|
331 |
+
display: inline-block;
|
332 |
+
font-size: 1.5em;
|
333 |
+
color: #797979;
|
334 |
+
vertical-align: middle;
|
335 |
+
margin-right: 10px;
|
336 |
+
-webkit-transition: all linear 0.6s;
|
337 |
+
-moz-transition: all linear 0.6s;
|
338 |
+
-ms-transition: all linear 0.6s;
|
339 |
+
transition: all linear 0.6s;
|
340 |
+
-webkit-animation-duration: 1s;
|
341 |
+
animation-duration: 1s;
|
342 |
+
-webkit-animation-fill-mode: both;
|
343 |
+
animation-fill-mode: both;
|
344 |
+
-webkit-animation-timing-function: ease-in-out;
|
345 |
+
animation-timing-function: ease-in-out;
|
346 |
+
animation-iteration-count: infinite;
|
347 |
+
-webkit-animation-iteration-count: infinite;
|
348 |
+
animation-name: bounce;
|
349 |
+
-moz-animation-name: bounce;
|
350 |
+
}
|
351 |
+
.select-page-builder {
|
352 |
+
margin-left: 6em;
|
353 |
+
}
|
354 |
+
|
355 |
+
.select-page-builder img {
|
356 |
+
max-width: 100%;
|
357 |
+
}
|
358 |
+
|
359 |
+
.select-page-builder .note-wrap {
|
360 |
+
position: absolute;
|
361 |
+
padding: 40px 0;
|
362 |
+
margin-left: 170px;
|
363 |
+
right: 0;
|
364 |
+
left: 0;
|
365 |
+
}
|
366 |
+
|
367 |
+
.select-page-builder h3 {
|
368 |
+
margin: 0;
|
369 |
+
font-size: 2em;
|
370 |
+
}
|
371 |
+
.select-page-builder {
|
372 |
+
margin: -20px 0 0 -5px;
|
373 |
+
position: absolute;
|
374 |
+
}
|
375 |
+
.select-page-builder .note {
|
376 |
+
margin-left: 1.5em;
|
377 |
+
}
|
378 |
+
|
379 |
+
@keyframes bounce {
|
380 |
+
0%,
|
381 |
+
100%,
|
382 |
+
20%,
|
383 |
+
50%,
|
384 |
+
80% {
|
385 |
+
-webkit-transform: translateY(-0px) rotate(90deg);
|
386 |
+
-moz-transform: translateY(-0px) rotate(90deg);
|
387 |
+
-ms-transform: translateY(-0px) rotate(90deg);
|
388 |
+
transform: translateY(-0px) rotate(90deg);
|
389 |
+
}
|
390 |
+
40% {
|
391 |
+
-webkit-transform: translateY(-2px) rotate(90deg);
|
392 |
+
-moz-transform: translateY(-2px) rotate(90deg);
|
393 |
+
-ms-transform: translateY(-2px) rotate(90deg);
|
394 |
+
transform: translateY(-2px) rotate(90deg);
|
395 |
+
}
|
396 |
+
60% {
|
397 |
+
-webkit-transform: translateY(-1px) rotate(90deg);
|
398 |
+
-moz-transform: translateY(-1px) rotate(90deg);
|
399 |
+
-ms-transform: translateY(-1px) rotate(90deg);
|
400 |
+
transform: translateY(-1px) rotate(90deg);
|
401 |
+
}
|
402 |
+
}
|
403 |
+
|
404 |
+
/**
|
405 |
+
* Processing Animation
|
406 |
+
*/
|
407 |
+
.astra-demo-import.disabled {
|
408 |
+
pointer-events: none;
|
409 |
+
}
|
410 |
+
.astra-demo-import.button.updating-message:before,
|
411 |
+
.astra-demo-import.button.installing:before {
|
412 |
+
-webkit-animation: cssAnimation .72s ease infinite;
|
413 |
+
-moz-animation: cssAnimation .72s ease infinite;
|
414 |
+
-o-animation: cssAnimation .72s ease infinite;
|
415 |
+
-ms-animation: cssAnimation .72s ease infinite;
|
416 |
+
animation: cssAnimation .72s ease infinite;
|
417 |
+
}
|
418 |
+
|
419 |
+
@-webkit-keyframes cssAnimation {
|
420 |
+
from {
|
421 |
+
-webkit-transform: rotate(0);
|
422 |
+
-moz-transform: rotate(0);
|
423 |
+
-o-transform: rotate(0);
|
424 |
+
-ms-transform: rotate(0);
|
425 |
+
transform: rotate(0);
|
426 |
+
}
|
427 |
+
to {
|
428 |
+
-webkit-transform: rotate(360deg);
|
429 |
+
-moz-transform: rotate(360deg);
|
430 |
+
-o-transform: rotate(360deg);
|
431 |
+
-ms-transform: rotate(360deg);
|
432 |
+
transform: rotate(360deg);
|
433 |
+
}
|
434 |
+
}
|
435 |
+
@-moz-keyframes cssAnimation {
|
436 |
+
from {
|
437 |
+
-webkit-transform: rotate(0);
|
438 |
+
-moz-transform: rotate(0);
|
439 |
+
-o-transform: rotate(0);
|
440 |
+
-ms-transform: rotate(0);
|
441 |
+
transform: rotate(0);
|
442 |
+
}
|
443 |
+
to {
|
444 |
+
-webkit-transform: rotate(360deg);
|
445 |
+
-moz-transform: rotate(360deg);
|
446 |
+
-o-transform: rotate(360deg);
|
447 |
+
-ms-transform: rotate(360deg);
|
448 |
+
transform: rotate(360deg);
|
449 |
+
}
|
450 |
+
}
|
451 |
+
@-o-keyframes cssAnimation {
|
452 |
+
from {
|
453 |
+
-webkit-transform: rotate(0);
|
454 |
+
-moz-transform: rotate(0);
|
455 |
+
-o-transform: rotate(0);
|
456 |
+
-ms-transform: rotate(0);
|
457 |
+
transform: rotate(0);
|
458 |
+
}
|
459 |
+
to {
|
460 |
+
-webkit-transform: rotate(360deg);
|
461 |
+
-moz-transform: rotate(360deg);
|
462 |
+
-o-transform: rotate(360deg);
|
463 |
+
-ms-transform: rotate(360deg);
|
464 |
+
transform: rotate(360deg);
|
465 |
+
}
|
466 |
+
}
|
467 |
+
|
468 |
+
#astra-sites-filters {
|
469 |
+
display: inline-block;
|
470 |
+
width: 100%;
|
471 |
+
}
|
472 |
+
|
473 |
+
.astra-site-down {
|
474 |
+
padding: 1em 2em;
|
475 |
+
margin-top: 1em;
|
476 |
+
}
|
477 |
+
|
478 |
+
#astra-sites-menu-page .nav-tab-wrapper {
|
479 |
+
border: none;
|
480 |
+
}
|
481 |
+
|
482 |
+
#astra-sites-filters .wp-filter {
|
483 |
+
margin-top: 0;
|
484 |
+
}
|
485 |
+
|
486 |
+
/**
|
487 |
+
* Welcome Screen
|
488 |
+
*/
|
489 |
+
.astra-sites-welcome {
|
490 |
+
padding: 10em 0;
|
491 |
+
text-align: center;
|
492 |
+
}
|
493 |
+
.astra-sites-welcome .inner {
|
494 |
+
margin: 0 auto;
|
495 |
+
display: inline-block;
|
496 |
+
max-width: 700px;
|
497 |
+
background: #fff;
|
498 |
+
padding: 3em;
|
499 |
+
}
|
500 |
+
|
501 |
+
.astra-sites-welcome h1 {
|
502 |
+
font-size: 2.5em;
|
503 |
+
margin-bottom: 1em;
|
504 |
+
}
|
505 |
+
|
506 |
+
.astra-sites-welcome p.description {
|
507 |
+
font-size: 1rem;
|
508 |
+
margin-bottom: 2em;
|
509 |
+
}
|
510 |
+
|
511 |
+
.astra-sites-welcome select {
|
512 |
+
padding: 5px;
|
513 |
+
height: 100%;
|
514 |
+
}
|
515 |
+
|
516 |
+
.astra-sites-welcome p.submit {
|
517 |
+
text-align: center;
|
518 |
+
margin: 0;
|
519 |
+
padding: 0;
|
520 |
+
margin-left: .5em;
|
521 |
+
}
|
522 |
+
|
523 |
+
.astra-sites-welcome .fields {
|
524 |
+
display: flex;
|
525 |
+
vertical-align: middle;
|
526 |
+
align-items: center;
|
527 |
+
justify-content: center;
|
528 |
+
}
|
529 |
+
|
530 |
+
.astra-sites-welcome #submit {
|
531 |
+
line-height: 1;
|
532 |
+
padding: .5rem 1rem;
|
533 |
+
height: auto;
|
534 |
+
}
|
535 |
+
|
536 |
+
.astra-site-page-builder {
|
537 |
+
opacity: 0;
|
538 |
+
visibility: hidden;
|
539 |
+
}
|
540 |
+
|
541 |
+
.required-plugins-list {
|
542 |
+
margin-left: 2em;
|
543 |
+
margin-top: .5em;
|
544 |
+
margin-bottom: .5em;
|
545 |
+
list-style-type: disc;
|
546 |
+
}
|
547 |
+
|
548 |
+
.required-plugins-list .plugin-card {
|
549 |
+
background: transparent;
|
550 |
+
border: none;
|
551 |
+
margin: 0;
|
552 |
+
line-height: 2;
|
553 |
+
float: none;
|
554 |
+
width: 100%;
|
555 |
+
}
|
556 |
+
|
557 |
+
.required-plugins-list .spinner {
|
558 |
+
float: none;
|
559 |
+
margin: 0;
|
560 |
+
}
|
561 |
+
|
562 |
+
#astra-site-import-process-wrap {
|
563 |
+
display: flex;
|
564 |
+
align-items: center;
|
565 |
+
margin-top: -2px;
|
566 |
+
z-index: 999999;
|
567 |
+
position: relative;
|
568 |
+
border-radius: 3px;
|
569 |
+
overflow: hidden;
|
570 |
+
}
|
571 |
+
#astra-site-import-process-wrap progress {
|
572 |
+
padding: 0px;
|
573 |
+
border: 0 none;
|
574 |
+
background: #0085bd;
|
575 |
+
border-radius: 5px;
|
576 |
+
height: 4px;
|
577 |
+
flex: 1;
|
578 |
+
}
|
579 |
+
|
580 |
+
#astra-site-import-process-wrap progress::-webkit-progress-value {
|
581 |
+
background: #00679b;
|
582 |
+
}
|
583 |
+
#astra-site-import-process-wrap progress::-webkit-progress-bar {
|
584 |
+
background: transparent;
|
585 |
+
}
|
586 |
+
|
587 |
+
.theme-browser .theme .site-preview > .theme-screenshot {
|
588 |
+
transition: all ease-in-out 3s;
|
589 |
+
background-position: center top;
|
590 |
+
background-size: cover;
|
591 |
+
background-repeat: no-repeat;
|
592 |
+
}
|
593 |
+
.theme-browser .theme .site-preview > .theme-screenshot:hover {
|
594 |
+
background-position: center bottom;
|
595 |
+
background-size: cover;
|
596 |
+
}
|
597 |
+
|
598 |
+
.astra-sites-tooltip-icon {
|
599 |
+
cursor: pointer;
|
600 |
+
}
|
601 |
+
|
602 |
+
.astra-sites-tooltip-icon .dashicons {
|
603 |
+
color: #5d5d5d;
|
604 |
+
font-size: 18px;
|
605 |
+
}
|
606 |
+
|
607 |
+
#astra-sites-welcome-form-inline {
|
608 |
+
position: absolute;
|
609 |
+
right: 1em;
|
610 |
+
top: 0;
|
611 |
+
border-radius: 0;
|
612 |
+
line-height: 1.7;
|
613 |
+
padding: 0px 5px 2px 5px;
|
614 |
+
outline: 2px solid transparent;
|
615 |
+
outline-offset: 0;
|
616 |
+
background: #fafafa;
|
617 |
+
border: 1px solid #ccc;
|
618 |
+
color: #72777c;
|
619 |
+
font-weight: normal;
|
620 |
+
font-size: 10px;
|
621 |
+
font-size: 13px;
|
622 |
+
line-height: 26px;
|
623 |
+
height: 28px;
|
624 |
+
cursor: pointer;
|
625 |
+
}
|
626 |
+
|
627 |
+
#astra-sites-welcome-form-inline select,
|
628 |
+
#astra-sites-welcome-form-inline select:focus {
|
629 |
+
border: none;
|
630 |
+
outline: none;
|
631 |
+
box-shadow: none;
|
632 |
+
color: #72777c;
|
633 |
+
}
|
634 |
+
|
635 |
+
#astra-sites-menu-page .wp-full-overlay-main:before {
|
636 |
+
content: '';
|
637 |
+
display: none;
|
638 |
+
}
|
639 |
+
|
640 |
+
.theme-screenshot-wrap {
|
641 |
+
overflow: hidden;
|
642 |
+
max-height: 300px;
|
643 |
+
margin: 15px 0;
|
644 |
+
border: 1px solid #ccc;
|
645 |
+
}
|
646 |
+
|
647 |
+
.astra-sites-preview .install-theme-info .theme-screenshot {
|
648 |
+
width: 100%;
|
649 |
+
border: none;
|
650 |
+
margin: 0;
|
651 |
Â
}
|
inc/assets/css/install-theme.css
ADDED
@@ -0,0 +1,21 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
.processing:before {
|
2 |
+
margin: 0 3px 0px 0px;
|
3 |
+
}
|
4 |
+
.processing:before {
|
5 |
+
animation: rotation 2s infinite linear;
|
6 |
+
}
|
7 |
+
.processing:before {
|
8 |
+
color: #f56e28;
|
9 |
+
content: "\f463";
|
10 |
+
}
|
11 |
+
.processing:before {
|
12 |
+
display: inline-block;
|
13 |
+
font: normal 20px/1 dashicons;
|
14 |
+
-webkit-font-smoothing: antialiased;
|
15 |
+
-moz-osx-font-smoothing: grayscale;
|
16 |
+
vertical-align: top;
|
17 |
+
}
|
18 |
+
#astra-theme-activation-nag a {
|
19 |
+
box-shadow: none;
|
20 |
+
outline: none;
|
21 |
+
}
|
inc/assets/js/admin-page.js
CHANGED
@@ -1,1815 +1,1815 @@
|
|
1 |
-
/**
|
2 |
-
* AJAX Request Queue
|
3 |
-
*
|
4 |
-
* - add()
|
5 |
-
* - remove()
|
6 |
-
* - run()
|
7 |
-
* - stop()
|
8 |
-
*
|
9 |
-
* @since 1.0.0
|
10 |
-
*/
|
11 |
-
var AstraSitesAjaxQueue = (function() {
|
12 |
-
|
13 |
-
var requests = [];
|
14 |
-
|
15 |
-
return {
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Add AJAX request
|
19 |
-
*
|
20 |
-
* @since 1.0.0
|
21 |
-
*/
|
22 |
-
add: function(opt) {
|
23 |
-
requests.push(opt);
|
24 |
-
},
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Remove AJAX request
|
28 |
-
*
|
29 |
-
* @since 1.0.0
|
30 |
-
*/
|
31 |
-
remove: function(opt) {
|
32 |
-
if( jQuery.inArray(opt, requests) > -1 )
|
33 |
-
requests.splice($.inArray(opt, requests), 1);
|
34 |
-
},
|
35 |
-
|
36 |
-
/**
|
37 |
-
* Run / Process AJAX request
|
38 |
-
*
|
39 |
-
* @since 1.0.0
|
40 |
-
*/
|
41 |
-
run: function() {
|
42 |
-
var self = this,
|
43 |
-
oriSuc;
|
44 |
-
|
45 |
-
if( requests.length ) {
|
46 |
-
oriSuc = requests[0].complete;
|
47 |
-
|
48 |
-
requests[0].complete = function() {
|
49 |
-
if( typeof(oriSuc) === 'function' ) oriSuc();
|
50 |
-
requests.shift();
|
51 |
-
self.run.apply(self, []);
|
52 |
-
};
|
53 |
-
|
54 |
-
jQuery.ajax(requests[0]);
|
55 |
-
|
56 |
-
} else {
|
57 |
-
|
58 |
-
self.tid = setTimeout(function() {
|
59 |
-
self.run.apply(self, []);
|
60 |
-
}, 1000);
|
61 |
-
}
|
62 |
-
},
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Stop AJAX request
|
66 |
-
*
|
67 |
-
* @since 1.0.0
|
68 |
-
*/
|
69 |
-
stop: function() {
|
70 |
-
|
71 |
-
requests = [];
|
72 |
-
clearTimeout(this.tid);
|
73 |
-
}
|
74 |
-
};
|
75 |
-
|
76 |
-
}());
|
77 |
-
|
78 |
-
(function($){
|
79 |
-
|
80 |
-
var AstraSSEImport = {
|
81 |
-
complete: {
|
82 |
-
posts: 0,
|
83 |
-
media: 0,
|
84 |
-
users: 0,
|
85 |
-
comments: 0,
|
86 |
-
terms: 0,
|
87 |
-
},
|
88 |
-
|
89 |
-
updateDelta: function (type, delta) {
|
90 |
-
this.complete[ type ] += delta;
|
91 |
-
|
92 |
-
var self = this;
|
93 |
-
requestAnimationFrame(function () {
|
94 |
-
self.render();
|
95 |
-
});
|
96 |
-
},
|
97 |
-
updateProgress: function ( type, complete, total ) {
|
98 |
-
var text = complete + '/' + total;
|
99 |
-
|
100 |
-
if( 'undefined' !== type && 'undefined' !== text ) {
|
101 |
-
total = parseInt( total, 10 );
|
102 |
-
if ( 0 === total || isNaN( total ) ) {
|
103 |
-
total = 1;
|
104 |
-
}
|
105 |
-
var percent = parseInt( complete, 10 ) / total;
|
106 |
-
var progress = Math.round( percent * 100 ) + '%';
|
107 |
-
var progress_bar = percent * 100;
|
108 |
-
|
109 |
-
if( progress_bar <= 100 ) {
|
110 |
-
document.getElementById( 'astra-site-import-process' ).value = progress_bar;
|
111 |
-
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingXML + ' '+progress );
|
112 |
-
}
|
113 |
-
}
|
114 |
-
},
|
115 |
-
render: function () {
|
116 |
-
var types = Object.keys( this.complete );
|
117 |
-
var complete = 0;
|
118 |
-
var total = 0;
|
119 |
-
|
120 |
-
|
121 |
-
for (var i = types.length - 1; i >= 0; i--) {
|
122 |
-
var type = types[i];
|
123 |
-
this.updateProgress( type, this.complete[ type ], this.data.count[ type ] );
|
124 |
-
|
125 |
-
complete += this.complete[ type ];
|
126 |
-
total += this.data.count[ type ];
|
127 |
-
}
|
128 |
-
|
129 |
-
this.updateProgress( 'total', complete, total );
|
130 |
-
}
|
131 |
-
};
|
132 |
-
|
133 |
-
AstraSitesAdmin = {
|
134 |
-
|
135 |
-
reset_remaining_posts: 0,
|
136 |
-
reset_remaining_wp_forms: 0,
|
137 |
-
reset_remaining_terms: 0,
|
138 |
-
reset_processed_posts: 0,
|
139 |
-
reset_processed_wp_forms: 0,
|
140 |
-
reset_processed_terms: 0,
|
141 |
-
site_imported_data: null,
|
142 |
-
|
143 |
-
backup_taken: false,
|
144 |
-
|
145 |
-
current_site: [],
|
146 |
-
current_screen: '',
|
147 |
-
|
148 |
-
templateData: {},
|
149 |
-
|
150 |
-
log_file : '',
|
151 |
-
customizer_data : '',
|
152 |
-
wxr_url : '',
|
153 |
-
wpforms_url : '',
|
154 |
-
options_data : '',
|
155 |
-
widgets_data : '',
|
156 |
-
|
157 |
-
init: function()
|
158 |
-
{
|
159 |
-
this._resetPagedCount();
|
160 |
-
this._bind();
|
161 |
-
},
|
162 |
-
|
163 |
-
/**
|
164 |
-
* Debugging.
|
165 |
-
*
|
166 |
-
* @param {mixed} data Mixed data.
|
167 |
-
*/
|
168 |
-
_log: function( data ) {
|
169 |
-
|
170 |
-
if( astraSitesAdmin.debug ) {
|
171 |
-
|
172 |
-
var date = new Date();
|
173 |
-
var time = date.toLocaleTimeString();
|
174 |
-
|
175 |
-
if (typeof data == 'object') {
|
176 |
-
console.log('%c ' + JSON.stringify( data ) + ' ' + time, 'background: #ededed; color: #444');
|
177 |
-
} else {
|
178 |
-
console.log('%c ' + data + ' ' + time, 'background: #ededed; color: #444');
|
179 |
-
}
|
180 |
-
|
181 |
-
|
182 |
-
}
|
183 |
-
},
|
184 |
-
|
185 |
-
/**
|
186 |
-
* Binds events for the Astra Sites.
|
187 |
-
*
|
188 |
-
* @since 1.0.0
|
189 |
-
* @access private
|
190 |
-
* @method _bind
|
191 |
-
*/
|
192 |
-
_bind: function()
|
193 |
-
{
|
194 |
-
$( document ).on( 'click' , '.astra-sites-reset-data .checkbox', AstraSitesAdmin._toggle_reset_notice );
|
195 |
-
$( document ).on('change' , '#astra-sites-welcome-form-inline select', AstraSitesAdmin._change_page_builder);
|
196 |
-
$( document ).on('click' , '.astra-sites-tooltip-icon', AstraSitesAdmin._toggle_tooltip);
|
197 |
-
$( document ).on('click' , '.astra-sites-advanced-options-button', AstraSitesAdmin._toggle_advanced_options);
|
198 |
-
|
199 |
-
$( document ).on('click' , '.astra-import-settings', AstraSitesAdmin._import_settings);
|
200 |
-
$( document ).on('click' , '.devices button', AstraSitesAdmin._previewDevice);
|
201 |
-
$( document ).on('click' , '.theme-browser .theme-screenshot, .theme-browser .more-details, .theme-browser .install-theme-preview', AstraSitesAdmin._preview);
|
202 |
-
$( document ).on('click' , '.next-theme', AstraSitesAdmin._nextTheme);
|
203 |
-
$( document ).on('click' , '.previous-theme', AstraSitesAdmin._previousTheme);
|
204 |
-
$( document ).on('click' , '.collapse-sidebar', AstraSitesAdmin._collapse);
|
205 |
-
$( document ).on('click' , '.astra-demo-import', AstraSitesAdmin._importDemo);
|
206 |
-
|
207 |
-
$( document ).on('astra-sites-install-and-activate-required-plugins-done' , AstraSitesAdmin._process_import );
|
208 |
-
|
209 |
-
$( document ).on('click' , '.install-now', AstraSitesAdmin._installNow);
|
210 |
-
$( document ).on('click' , '.close-full-overlay', AstraSitesAdmin._fullOverlay);
|
211 |
-
$( document ).on('click' , '.activate-now', AstraSitesAdmin._activateNow);
|
212 |
-
$( document ).on('wp-plugin-installing' , AstraSitesAdmin._pluginInstalling);
|
213 |
-
$( document ).on('wp-plugin-install-error' , AstraSitesAdmin._installError);
|
214 |
-
$( document ).on('wp-plugin-install-success' , AstraSitesAdmin._installSuccess);
|
215 |
-
|
216 |
-
$( document ).on( 'astra-sites-import-set-site-data-done' , AstraSitesAdmin._resetData );
|
217 |
-
$( document ).on( 'astra-sites-reset-data' , AstraSitesAdmin._backup_before_rest_options );
|
218 |
-
$( document ).on( 'astra-sites-backup-settings-before-reset-done' , AstraSitesAdmin._reset_customizer_data );
|
219 |
-
$( document ).on( 'astra-sites-reset-customizer-data-done' , AstraSitesAdmin._reset_site_options );
|
220 |
-
$( document ).on( 'astra-sites-reset-site-options-done' , AstraSitesAdmin._reset_widgets_data );
|
221 |
-
$( document ).on( 'astra-sites-reset-widgets-data-done' , AstraSitesAdmin._reset_terms );
|
222 |
-
$( document ).on( 'astra-sites-delete-terms-done' , AstraSitesAdmin._reset_wp_forms );
|
223 |
-
$( document ).on( 'astra-sites-delete-wp-forms-done' , AstraSitesAdmin._reset_posts );
|
224 |
-
|
225 |
-
$( document ).on('astra-sites-reset-data-done' , AstraSitesAdmin._recheck_backup_options );
|
226 |
-
$( document ).on('astra-sites-backup-settings-done' , AstraSitesAdmin._importWPForms );
|
227 |
-
$( document ).on('astra-sites-import-wpforms-done' , AstraSitesAdmin._importCustomizerSettings );
|
228 |
-
$( document ).on('astra-sites-import-customizer-settings-done' , AstraSitesAdmin._importXML );
|
229 |
-
$( document ).on('astra-sites-import-xml-done' , AstraSitesAdmin._importSiteOptions );
|
230 |
-
$( document ).on('astra-sites-import-options-done' , AstraSitesAdmin._importWidgets );
|
231 |
-
$( document ).on('astra-sites-import-widgets-done' , AstraSitesAdmin._importEnd );
|
232 |
-
|
233 |
-
},
|
234 |
-
|
235 |
-
_change_page_builder: function() {
|
236 |
-
$(this).closest('form').submit();
|
237 |
-
},
|
238 |
-
|
239 |
-
_toggle_tooltip: function( event ) {
|
240 |
-
event.preventDefault();
|
241 |
-
var tip_id = $( this ).data('tip-id') || '';
|
242 |
-
if( tip_id && $( '#' + tip_id ).length ) {
|
243 |
-
$( '#' + tip_id ).toggle();
|
244 |
-
}
|
245 |
-
},
|
246 |
-
|
247 |
-
_toggle_advanced_options: function( event ) {
|
248 |
-
event.preventDefault();
|
249 |
-
$('.astra-sites-advanced-options').toggle();
|
250 |
-
},
|
251 |
-
|
252 |
-
_resetData: function( event ) {
|
253 |
-
event.preventDefault();
|
254 |
-
|
255 |
-
if ( $( '.astra-sites-reset-data' ).find('.checkbox').is(':checked') ) {
|
256 |
-
$(document).trigger( 'astra-sites-reset-data' );
|
257 |
-
} else {
|
258 |
-
$(document).trigger( 'astra-sites-reset-data-done' );
|
259 |
-
}
|
260 |
-
},
|
261 |
-
|
262 |
-
_reset_customizer_data() {
|
263 |
-
$.ajax({
|
264 |
-
url : astraSitesAdmin.ajaxurl,
|
265 |
-
type : 'POST',
|
266 |
-
data : {
|
267 |
-
action : 'astra-sites-reset-customizer-data'
|
268 |
-
},
|
269 |
-
beforeSend: function() {
|
270 |
-
AstraSitesAdmin._log( 'Reseting Customizer Data' );
|
271 |
-
$('.button-hero.astra-demo-import').text( 'Reseting Customizer Data' );
|
272 |
-
},
|
273 |
-
})
|
274 |
-
.fail(function( jqXHR ){
|
275 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
276 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
277 |
-
})
|
278 |
-
.done(function ( data ) {
|
279 |
-
$(document).trigger( 'astra-sites-reset-customizer-data-done' );
|
280 |
-
});
|
281 |
-
},
|
282 |
-
|
283 |
-
_reset_site_options: function() {
|
284 |
-
// Site Options.
|
285 |
-
$.ajax({
|
286 |
-
url : astraSitesAdmin.ajaxurl,
|
287 |
-
type : 'POST',
|
288 |
-
data : {
|
289 |
-
action : 'astra-sites-reset-site-options'
|
290 |
-
},
|
291 |
-
beforeSend: function() {
|
292 |
-
AstraSitesAdmin._log( 'Reseting Site Options' );
|
293 |
-
$('.button-hero.astra-demo-import').text( 'Reseting Site Options' );
|
294 |
-
},
|
295 |
-
})
|
296 |
-
.fail(function( jqXHR ){
|
297 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
298 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
299 |
-
})
|
300 |
-
.done(function ( data ) {
|
301 |
-
|
302 |
-
|
303 |
-
$(document).trigger( 'astra-sites-reset-site-options-done' );
|
304 |
-
});
|
305 |
-
},
|
306 |
-
|
307 |
-
_reset_widgets_data: function() {
|
308 |
-
// Widgets.
|
309 |
-
$.ajax({
|
310 |
-
url : astraSitesAdmin.ajaxurl,
|
311 |
-
type : 'POST',
|
312 |
-
data : {
|
313 |
-
action : 'astra-sites-reset-widgets-data'
|
314 |
-
},
|
315 |
-
beforeSend: function() {
|
316 |
-
AstraSitesAdmin._log( 'Reseting Widgets' );
|
317 |
-
$('.button-hero.astra-demo-import').text( 'Reseting Widgets' );
|
318 |
-
},
|
319 |
-
})
|
320 |
-
.fail(function( jqXHR ){
|
321 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
322 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
323 |
-
})
|
324 |
-
.done(function ( data ) {
|
325 |
-
AstraSitesAdmin._log( data );
|
326 |
-
$(document).trigger( 'astra-sites-reset-widgets-data-done' );
|
327 |
-
});
|
328 |
-
},
|
329 |
-
|
330 |
-
_reset_posts: function() {
|
331 |
-
if( AstraSitesAdmin.site_imported_data['reset_posts'].length ) {
|
332 |
-
|
333 |
-
AstraSitesAdmin.reset_remaining_posts = AstraSitesAdmin.site_imported_data['reset_posts'].length;
|
334 |
-
|
335 |
-
// Delete all posts.
|
336 |
-
// AstraSitesAjaxQueue.stop();
|
337 |
-
// AstraSitesAjaxQueue.run();
|
338 |
-
|
339 |
-
$.each( AstraSitesAdmin.site_imported_data['reset_posts'], function(index, post_id) {
|
340 |
-
AstraSitesAjaxQueue.add({
|
341 |
-
url: astraSitesAdmin.ajaxurl,
|
342 |
-
type: 'POST',
|
343 |
-
data: {
|
344 |
-
action : 'astra-sites-delete-posts',
|
345 |
-
post_id : post_id,
|
346 |
-
},
|
347 |
-
success: function( result ){
|
348 |
-
|
349 |
-
if( AstraSitesAdmin.reset_processed_posts < AstraSitesAdmin.site_imported_data['reset_posts'].length ) {
|
350 |
-
AstraSitesAdmin.reset_processed_posts+=1;
|
351 |
-
}
|
352 |
-
|
353 |
-
$('.button-hero.astra-demo-import').text( 'Deleting Item ' + AstraSitesAdmin.reset_processed_posts + ' of ' + AstraSitesAdmin.site_imported_data['reset_posts'].length );
|
354 |
-
AstraSitesAdmin.reset_remaining_posts-=1;
|
355 |
-
if( 0 == AstraSitesAdmin.reset_remaining_posts ) {
|
356 |
-
$(document).trigger( 'astra-sites-delete-posts-done' );
|
357 |
-
$(document).trigger( 'astra-sites-reset-data-done' );
|
358 |
-
}
|
359 |
-
}
|
360 |
-
});
|
361 |
-
});
|
362 |
-
AstraSitesAjaxQueue.run();
|
363 |
-
|
364 |
-
} else {
|
365 |
-
$(document).trigger( 'astra-sites-delete-posts-done' );
|
366 |
-
$(document).trigger( 'astra-sites-reset-data-done' );
|
367 |
-
}
|
368 |
-
},
|
369 |
-
|
370 |
-
_reset_wp_forms: function() {
|
371 |
-
|
372 |
-
AstraSitesAdmin._log( AstraSitesAdmin.site_imported_data['reset_wp_forms'] );
|
373 |
-
AstraSitesAdmin._log( AstraSitesAdmin.site_imported_data['reset_wp_forms'].length );
|
374 |
-
|
375 |
-
if( AstraSitesAdmin.site_imported_data['reset_wp_forms'].length ) {
|
376 |
-
AstraSitesAdmin.reset_remaining_wp_forms = AstraSitesAdmin.site_imported_data['reset_wp_forms'].length;
|
377 |
-
|
378 |
-
$.each( AstraSitesAdmin.site_imported_data['reset_wp_forms'], function(index, post_id) {
|
379 |
-
AstraSitesAdmin._log( 'WP Form ID: ' + post_id );
|
380 |
-
AstraSitesAjaxQueue.add({
|
381 |
-
url: astraSitesAdmin.ajaxurl,
|
382 |
-
type: 'POST',
|
383 |
-
data: {
|
384 |
-
action : 'astra-sites-delete-wp-forms',
|
385 |
-
post_id : post_id,
|
386 |
-
},
|
387 |
-
success: function( result ){
|
388 |
-
AstraSitesAdmin._log( 'WP Forms Results' );
|
389 |
-
AstraSitesAdmin._log( result );
|
390 |
-
if( AstraSitesAdmin.reset_processed_wp_forms < AstraSitesAdmin.site_imported_data['reset_wp_forms'].length ) {
|
391 |
-
AstraSitesAdmin.reset_processed_wp_forms+=1;
|
392 |
-
}
|
393 |
-
|
394 |
-
$('.button-hero.astra-demo-import').text( 'Deleting Form ' + AstraSitesAdmin.reset_processed_wp_forms + ' of ' + AstraSitesAdmin.site_imported_data['reset_wp_forms'].length );
|
395 |
-
AstraSitesAdmin.reset_remaining_wp_forms-=1;
|
396 |
-
if( 0 == AstraSitesAdmin.reset_remaining_wp_forms ) {
|
397 |
-
$(document).trigger( 'astra-sites-delete-wp-forms-done' );
|
398 |
-
}
|
399 |
-
}
|
400 |
-
});
|
401 |
-
});
|
402 |
-
AstraSitesAjaxQueue.run();
|
403 |
-
|
404 |
-
} else {
|
405 |
-
$(document).trigger( 'astra-sites-delete-wp-forms-done' );
|
406 |
-
}
|
407 |
-
},
|
408 |
-
|
409 |
-
|
410 |
-
_reset_terms: function() {
|
411 |
-
|
412 |
-
AstraSitesAdmin._log( AstraSitesAdmin.site_imported_data['reset_terms'] );
|
413 |
-
AstraSitesAdmin._log( AstraSitesAdmin.site_imported_data['reset_terms'].length );
|
414 |
-
|
415 |
-
if( AstraSitesAdmin.site_imported_data['reset_terms'].length ) {
|
416 |
-
AstraSitesAdmin.reset_remaining_terms = AstraSitesAdmin.site_imported_data['reset_terms'].length;
|
417 |
-
|
418 |
-
$.each( AstraSitesAdmin.site_imported_data['reset_terms'], function(index, term_id) {
|
419 |
-
AstraSitesAjaxQueue.add({
|
420 |
-
url: astraSitesAdmin.ajaxurl,
|
421 |
-
type: 'POST',
|
422 |
-
data: {
|
423 |
-
action : 'astra-sites-delete-terms',
|
424 |
-
term_id : term_id,
|
425 |
-
},
|
426 |
-
success: function( result ){
|
427 |
-
if( AstraSitesAdmin.reset_processed_terms < AstraSitesAdmin.site_imported_data['reset_terms'].length ) {
|
428 |
-
AstraSitesAdmin.reset_processed_terms+=1;
|
429 |
-
}
|
430 |
-
AstraSitesAdmin._log( result );
|
431 |
-
$('.button-hero.astra-demo-import').text( 'Deleting Term ' + AstraSitesAdmin.reset_processed_terms + ' of ' + AstraSitesAdmin.site_imported_data['reset_terms'].length );
|
432 |
-
AstraSitesAdmin.reset_remaining_terms-=1;
|
433 |
-
AstraSitesAdmin._log( AstraSitesAdmin.reset_remaining_terms );
|
434 |
-
if( 0 == AstraSitesAdmin.reset_remaining_terms ) {
|
435 |
-
$(document).trigger( 'astra-sites-delete-terms-done' );
|
436 |
-
}
|
437 |
-
}
|
438 |
-
});
|
439 |
-
});
|
440 |
-
AstraSitesAjaxQueue.run();
|
441 |
-
|
442 |
-
} else {
|
443 |
-
$(document).trigger( 'astra-sites-delete-terms-done' );
|
444 |
-
}
|
445 |
-
|
446 |
-
},
|
447 |
-
|
448 |
-
_toggle_reset_notice: function() {
|
449 |
-
if ( $( this ).is(':checked') ) {
|
450 |
-
$('#astra-sites-tooltip-reset-data').show();
|
451 |
-
} else {
|
452 |
-
$('#astra-sites-tooltip-reset-data').hide();
|
453 |
-
}
|
454 |
-
},
|
455 |
-
|
456 |
-
_backup_before_rest_options: function() {
|
457 |
-
AstraSitesAdmin._backupOptions( 'astra-sites-backup-settings-before-reset-done' );
|
458 |
-
AstraSitesAdmin.backup_taken = true;
|
459 |
-
},
|
460 |
-
|
461 |
-
_recheck_backup_options: function() {
|
462 |
-
AstraSitesAdmin._backupOptions( 'astra-sites-backup-settings-done' );
|
463 |
-
AstraSitesAdmin.backup_taken = true;
|
464 |
-
},
|
465 |
-
|
466 |
-
_backupOptions: function( trigger_name ) {
|
467 |
-
$.ajax({
|
468 |
-
url : astraSitesAdmin.ajaxurl,
|
469 |
-
type : 'POST',
|
470 |
-
data : {
|
471 |
-
action : 'astra-sites-backup-settings',
|
472 |
-
},
|
473 |
-
beforeSend: function() {
|
474 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importWPForms );
|
475 |
-
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.backupCustomizer );
|
476 |
-
},
|
477 |
-
})
|
478 |
-
.fail(function( jqXHR ){
|
479 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText );
|
480 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
481 |
-
})
|
482 |
-
.done(function ( data ) {
|
483 |
-
|
484 |
-
// 1. Pass - Import Customizer Options.
|
485 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.backupCustomizerSuccess );
|
486 |
-
|
487 |
-
// Custom trigger.
|
488 |
-
$(document).trigger( trigger_name );
|
489 |
-
});
|
490 |
-
},
|
491 |
-
|
492 |
-
_import_settings: function( event ) {
|
493 |
-
event.preventDefault();
|
494 |
-
|
495 |
-
var btn = $(this);
|
496 |
-
|
497 |
-
btn.addClass('updating-message');
|
498 |
-
|
499 |
-
|
500 |
-
$.ajax({
|
501 |
-
url : astraSitesAdmin.ajaxurl,
|
502 |
-
type : 'POST',
|
503 |
-
dataType: 'json',
|
504 |
-
data : {
|
505 |
-
action : 'astra-sites-import-customizer-settings',
|
506 |
-
customizer_data : AstraSitesAdmin.current_site['astra-site-customizer-data'],
|
507 |
-
},
|
508 |
-
beforeSend: function() {
|
509 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importCustomizer );
|
510 |
-
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingCustomizer );
|
511 |
-
},
|
512 |
-
})
|
513 |
-
.fail(function( jqXHR ){
|
514 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
515 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
516 |
-
})
|
517 |
-
.done(function ( customizer_data ) {
|
518 |
-
|
519 |
-
btn.removeClass( 'updating-message' );
|
520 |
-
|
521 |
-
// 1. Fail - Import Customizer Options.
|
522 |
-
if( false === customizer_data.success ) {
|
523 |
-
AstraSitesAdmin._importFailMessage( customizer_data.data );
|
524 |
-
AstraSitesAdmin._log( customizer_data.data );
|
525 |
-
} else {
|
526 |
-
|
527 |
-
// 1. Pass - Import Customizer Options.
|
528 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importCustomizerSuccess );
|
529 |
-
|
530 |
-
$(document).trigger( 'astra-sites-import-customizer-settings-done' );
|
531 |
-
}
|
532 |
-
});
|
533 |
-
},
|
534 |
-
|
535 |
-
/**
|
536 |
-
* 5. Import Complete.
|
537 |
-
*/
|
538 |
-
_importEnd: function( event ) {
|
539 |
-
|
540 |
-
$.ajax({
|
541 |
-
url : astraSitesAdmin.ajaxurl,
|
542 |
-
type : 'POST',
|
543 |
-
dataType: 'json',
|
544 |
-
data : {
|
545 |
-
action : 'astra-sites-import-end',
|
546 |
-
},
|
547 |
-
beforeSend: function() {
|
548 |
-
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importComplete );
|
549 |
-
}
|
550 |
-
})
|
551 |
-
.fail(function( jqXHR ){
|
552 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
553 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
554 |
-
})
|
555 |
-
.done(function ( data ) {
|
556 |
-
|
557 |
-
// 5. Fail - Import Complete.
|
558 |
-
if( false === data.success ) {
|
559 |
-
AstraSitesAdmin._importFailMessage( data.data );
|
560 |
-
AstraSitesAdmin._log( data.data );
|
561 |
-
} else {
|
562 |
-
|
563 |
-
$('body').removeClass('importing-site');
|
564 |
-
$('.previous-theme, .next-theme').removeClass('disabled');
|
565 |
-
|
566 |
-
// 5. Pass - Import Complete.
|
567 |
-
AstraSitesAdmin._importSuccessMessage();
|
568 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.success + ' ' + astraSitesAdmin.siteURL );
|
569 |
-
}
|
570 |
-
});
|
571 |
-
},
|
572 |
-
|
573 |
-
/**
|
574 |
-
* 4. Import Widgets.
|
575 |
-
*/
|
576 |
-
_importWidgets: function( event ) {
|
577 |
-
if ( AstraSitesAdmin._is_process_widgets() ) {
|
578 |
-
$.ajax({
|
579 |
-
url : astraSitesAdmin.ajaxurl,
|
580 |
-
type : 'POST',
|
581 |
-
dataType: 'json',
|
582 |
-
data : {
|
583 |
-
action : 'astra-sites-import-widgets',
|
584 |
-
widgets_data : AstraSitesAdmin.widgets_data,
|
585 |
-
},
|
586 |
-
beforeSend: function() {
|
587 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importWidgets );
|
588 |
-
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingWidgets );
|
589 |
-
},
|
590 |
-
})
|
591 |
-
.fail(function( jqXHR ){
|
592 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText );
|
593 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
594 |
-
})
|
595 |
-
.done(function ( widgets_data ) {
|
596 |
-
|
597 |
-
// 4. Fail - Import Widgets.
|
598 |
-
if( false === widgets_data.success ) {
|
599 |
-
AstraSitesAdmin._importFailMessage( widgets_data.data );
|
600 |
-
AstraSitesAdmin._log( widgets_data.data );
|
601 |
-
|
602 |
-
} else {
|
603 |
-
|
604 |
-
// 4. Pass - Import Widgets.
|
605 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importWidgetsSuccess );
|
606 |
-
$(document).trigger( 'astra-sites-import-widgets-done' );
|
607 |
-
}
|
608 |
-
});
|
609 |
-
} else {
|
610 |
-
$(document).trigger( 'astra-sites-import-widgets-done' );
|
611 |
-
}
|
612 |
-
},
|
613 |
-
|
614 |
-
/**
|
615 |
-
* 3. Import Site Options.
|
616 |
-
*/
|
617 |
-
_importSiteOptions: function( event ) {
|
618 |
-
|
619 |
-
if ( AstraSitesAdmin._is_process_xml() ) {
|
620 |
-
$.ajax({
|
621 |
-
url : astraSitesAdmin.ajaxurl,
|
622 |
-
type : 'POST',
|
623 |
-
dataType: 'json',
|
624 |
-
data : {
|
625 |
-
action : 'astra-sites-import-options',
|
626 |
-
options_data : AstraSitesAdmin.options_data,
|
627 |
-
},
|
628 |
-
beforeSend: function() {
|
629 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importOptions );
|
630 |
-
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingOptions );
|
631 |
-
$('.astra-demo-import .percent').html('');
|
632 |
-
},
|
633 |
-
})
|
634 |
-
.fail(function( jqXHR ){
|
635 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText );
|
636 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
637 |
-
})
|
638 |
-
.done(function ( options_data ) {
|
639 |
-
|
640 |
-
// 3. Fail - Import Site Options.
|
641 |
-
if( false === options_data.success ) {
|
642 |
-
AstraSitesAdmin._log( options_data );
|
643 |
-
AstraSitesAdmin._importFailMessage( options_data.data );
|
644 |
-
AstraSitesAdmin._log( options_data.data );
|
645 |
-
|
646 |
-
} else {
|
647 |
-
|
648 |
-
// 3. Pass - Import Site Options.
|
649 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importOptionsSuccess );
|
650 |
-
$(document).trigger( 'astra-sites-import-options-done' );
|
651 |
-
}
|
652 |
-
});
|
653 |
-
} else {
|
654 |
-
$(document).trigger( 'astra-sites-import-options-done' );
|
655 |
-
}
|
656 |
-
},
|
657 |
-
|
658 |
-
/**
|
659 |
-
* 2. Prepare XML Data.
|
660 |
-
*/
|
661 |
-
_importXML: function() {
|
662 |
-
|
663 |
-
if ( AstraSitesAdmin._is_process_xml() ) {
|
664 |
-
$.ajax({
|
665 |
-
url : astraSitesAdmin.ajaxurl,
|
666 |
-
type : 'POST',
|
667 |
-
dataType: 'json',
|
668 |
-
data : {
|
669 |
-
action : 'astra-sites-import-prepare-xml',
|
670 |
-
wxr_url : AstraSitesAdmin.current_site['astra-site-wxr-path'],
|
671 |
-
},
|
672 |
-
beforeSend: function() {
|
673 |
-
$('#astra-site-import-process-wrap').show();
|
674 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importXMLPrepare );
|
675 |
-
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importXMLPreparing );
|
676 |
-
},
|
677 |
-
})
|
678 |
-
.fail(function( jqXHR ){
|
679 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText );
|
680 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
681 |
-
})
|
682 |
-
.done(function ( xml_data ) {
|
683 |
-
|
684 |
-
|
685 |
-
// 2. Fail - Prepare XML Data.
|
686 |
-
if( false === xml_data.success ) {
|
687 |
-
AstraSitesAdmin._log( xml_data );
|
688 |
-
var error_msg = xml_data.data.error || xml_data.data;
|
689 |
-
AstraSitesAdmin._importFailMessage( error_msg );
|
690 |
-
AstraSitesAdmin._log( error_msg );
|
691 |
-
|
692 |
-
} else {
|
693 |
-
|
694 |
-
// 2. Pass - Prepare XML Data.
|
695 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importXMLPrepareSuccess );
|
696 |
-
|
697 |
-
// Import XML though Event Source.
|
698 |
-
AstraSSEImport.data = xml_data.data;
|
699 |
-
AstraSSEImport.render();
|
700 |
-
|
701 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importXML );
|
702 |
-
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingXML );
|
703 |
-
|
704 |
-
var evtSource = new EventSource( AstraSSEImport.data.url );
|
705 |
-
evtSource.onmessage = function ( message ) {
|
706 |
-
var data = JSON.parse( message.data );
|
707 |
-
switch ( data.action ) {
|
708 |
-
case 'updateDelta':
|
709 |
-
AstraSSEImport.updateDelta( data.type, data.delta );
|
710 |
-
break;
|
711 |
-
|
712 |
-
case 'complete':
|
713 |
-
evtSource.close();
|
714 |
-
|
715 |
-
// 2. Pass - Import XML though "Source Event".
|
716 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importXMLSuccess );
|
717 |
-
AstraSitesAdmin._log( '----- SSE - XML import Complete -----' );
|
718 |
-
|
719 |
-
document.getElementById( 'astra-site-import-process' ).value = 100;
|
720 |
-
|
721 |
-
|
722 |
-
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingXML + ' (100%)' );
|
723 |
-
|
724 |
-
$('#astra-site-import-process-wrap').hide();
|
725 |
-
|
726 |
-
$(document).trigger( 'astra-sites-import-xml-done' );
|
727 |
-
|
728 |
-
break;
|
729 |
-
}
|
730 |
-
};
|
731 |
-
evtSource.addEventListener( 'log', function ( message ) {
|
732 |
-
var data = JSON.parse( message.data );
|
733 |
-
AstraSitesAdmin._log( data.level + ' ' + data.message );
|
734 |
-
});
|
735 |
-
}
|
736 |
-
});
|
737 |
-
} else {
|
738 |
-
$(document).trigger( 'astra-sites-import-xml-done' );
|
739 |
-
}
|
740 |
-
|
741 |
-
|
742 |
-
},
|
743 |
-
|
744 |
-
_is_process_xml: function() {
|
745 |
-
if ( $( '.astra-sites-import-xml' ).find('.checkbox').is(':checked') ) {
|
746 |
-
return true;
|
747 |
-
}
|
748 |
-
return false;
|
749 |
-
},
|
750 |
-
|
751 |
-
_is_process_customizer: function() {
|
752 |
-
if ( $( '.astra-sites-import-customizer' ).find('.checkbox').is(':checked') ) {
|
753 |
-
return true;
|
754 |
-
}
|
755 |
-
return false;
|
756 |
-
},
|
757 |
-
|
758 |
-
_is_process_widgets: function() {
|
759 |
-
if ( $( '.astra-sites-import-widgets' ).find('.checkbox').is(':checked') ) {
|
760 |
-
return true;
|
761 |
-
}
|
762 |
-
return false;
|
763 |
-
},
|
764 |
-
|
765 |
-
/**
|
766 |
-
* 1. Import WPForms Options.
|
767 |
-
*/
|
768 |
-
_importWPForms: function( event ) {
|
769 |
-
if ( AstraSitesAdmin._is_process_customizer() ) {
|
770 |
-
$.ajax({
|
771 |
-
url : astraSitesAdmin.ajaxurl,
|
772 |
-
type : 'POST',
|
773 |
-
dataType: 'json',
|
774 |
-
data : {
|
775 |
-
action : 'astra-sites-import-wpforms',
|
776 |
-
wpforms_url : AstraSitesAdmin.wpforms_url,
|
777 |
-
},
|
778 |
-
beforeSend: function() {
|
779 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importWPForms );
|
780 |
-
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingWPForms );
|
781 |
-
},
|
782 |
-
})
|
783 |
-
.fail(function( jqXHR ){
|
784 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText );
|
785 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
786 |
-
})
|
787 |
-
.done(function ( forms ) {
|
788 |
-
|
789 |
-
// 1. Fail - Import WPForms Options.
|
790 |
-
if( false === forms.success ) {
|
791 |
-
AstraSitesAdmin._importFailMessage( forms.data );
|
792 |
-
AstraSitesAdmin._log( forms.data );
|
793 |
-
} else {
|
794 |
-
|
795 |
-
// 1. Pass - Import Customizer Options.
|
796 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importWPFormsSuccess );
|
797 |
-
|
798 |
-
$(document).trigger( 'astra-sites-import-wpforms-done' );
|
799 |
-
}
|
800 |
-
});
|
801 |
-
} else {
|
802 |
-
$(document).trigger( 'astra-sites-import-wpforms-done' );
|
803 |
-
}
|
804 |
-
},
|
805 |
-
|
806 |
-
/**
|
807 |
-
* 1. Import Customizer Options.
|
808 |
-
*/
|
809 |
-
_importCustomizerSettings: function( event ) {
|
810 |
-
if ( AstraSitesAdmin._is_process_customizer() ) {
|
811 |
-
$.ajax({
|
812 |
-
url : astraSitesAdmin.ajaxurl,
|
813 |
-
type : 'POST',
|
814 |
-
dataType: 'json',
|
815 |
-
data : {
|
816 |
-
action : 'astra-sites-import-customizer-settings',
|
817 |
-
customizer_data : AstraSitesAdmin.customizer_data,
|
818 |
-
},
|
819 |
-
beforeSend: function() {
|
820 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importCustomizer );
|
821 |
-
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingCustomizer );
|
822 |
-
},
|
823 |
-
})
|
824 |
-
.fail(function( jqXHR ){
|
825 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText );
|
826 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
827 |
-
})
|
828 |
-
.done(function ( customizer_data ) {
|
829 |
-
|
830 |
-
// 1. Fail - Import Customizer Options.
|
831 |
-
if( false === customizer_data.success ) {
|
832 |
-
AstraSitesAdmin._importFailMessage( customizer_data.data );
|
833 |
-
AstraSitesAdmin._log( customizer_data.data );
|
834 |
-
} else {
|
835 |
-
|
836 |
-
// 1. Pass - Import Customizer Options.
|
837 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importCustomizerSuccess );
|
838 |
-
|
839 |
-
$(document).trigger( 'astra-sites-import-customizer-settings-done' );
|
840 |
-
}
|
841 |
-
});
|
842 |
-
} else {
|
843 |
-
$(document).trigger( 'astra-sites-import-customizer-settings-done' );
|
844 |
-
}
|
845 |
-
|
846 |
-
},
|
847 |
-
|
848 |
-
/**
|
849 |
-
* Import Success Button.
|
850 |
-
*
|
851 |
-
* @param {string} data Error message.
|
852 |
-
*/
|
853 |
-
_importSuccessMessage: function() {
|
854 |
-
|
855 |
-
$('.astra-demo-import').removeClass('updating-message installing')
|
856 |
-
.removeAttr('data-import')
|
857 |
-
.addClass('view-site')
|
858 |
-
.removeClass('astra-demo-import')
|
859 |
-
.text( astraSitesAdmin.strings.viewSite )
|
860 |
-
.attr('target', '_blank')
|
861 |
-
.append('<i class="dashicons dashicons-external"></i>')
|
862 |
-
.attr('href', astraSitesAdmin.siteURL );
|
863 |
-
},
|
864 |
-
|
865 |
-
/**
|
866 |
-
* Preview Device
|
867 |
-
*/
|
868 |
-
_previewDevice: function( event ) {
|
869 |
-
var device = $( event.currentTarget ).data( 'device' );
|
870 |
-
|
871 |
-
$('.theme-install-overlay')
|
872 |
-
.removeClass( 'preview-desktop preview-tablet preview-mobile' )
|
873 |
-
.addClass( 'preview-' + device )
|
874 |
-
.data( 'current-preview-device', device );
|
875 |
-
|
876 |
-
AstraSitesAdmin._tooglePreviewDeviceButtons( device );
|
877 |
-
},
|
878 |
-
|
879 |
-
/**
|
880 |
-
* Toggle Preview Buttons
|
881 |
-
*/
|
882 |
-
_tooglePreviewDeviceButtons: function( newDevice ) {
|
883 |
-
var $devices = $( '.wp-full-overlay-footer .devices' );
|
884 |
-
|
885 |
-
$devices.find( 'button' )
|
886 |
-
.removeClass( 'active' )
|
887 |
-
.attr( 'aria-pressed', false );
|
888 |
-
|
889 |
-
$devices.find( 'button.preview-' + newDevice )
|
890 |
-
.addClass( 'active' )
|
891 |
-
.attr( 'aria-pressed', true );
|
892 |
-
},
|
893 |
-
|
894 |
-
/**
|
895 |
-
* Import Error Button.
|
896 |
-
*
|
897 |
-
* @param {string} data Error message.
|
898 |
-
*/
|
899 |
-
_importFailMessage: function( message, from ) {
|
900 |
-
|
901 |
-
$('.astra-demo-import')
|
902 |
-
.addClass('go-pro button-primary')
|
903 |
-
.removeClass('updating-message installing')
|
904 |
-
.removeAttr('data-import')
|
905 |
-
.attr('target', '_blank')
|
906 |
-
.append('<i class="dashicons dashicons-external"></i>')
|
907 |
-
.removeClass('astra-demo-import');
|
908 |
-
|
909 |
-
// Add the doc link due to import log file not generated.
|
910 |
-
if( 'undefined' === from ) {
|
911 |
-
|
912 |
-
$('.wp-full-overlay-header .go-pro').text( astraSitesAdmin.strings.importFailedBtnSmall );
|
913 |
-
$('.wp-full-overlay-footer .go-pro').text( astraSitesAdmin.strings.importFailedBtnLarge );
|
914 |
-
$('.go-pro').attr('href', astraSitesAdmin.log.serverConfiguration );
|
915 |
-
|
916 |
-
// Add the import log file link.
|
917 |
-
} else {
|
918 |
-
|
919 |
-
$('.wp-full-overlay-header .go-pro').text( astraSitesAdmin.strings.importFailBtn );
|
920 |
-
$('.wp-full-overlay-footer .go-pro').text( astraSitesAdmin.strings.importFailBtnLarge )
|
921 |
-
|
922 |
-
// Add the import log file link.
|
923 |
-
if( 'undefined' !== AstraSitesAdmin.log_file_url ) {
|
924 |
-
$('.go-pro').attr('href', AstraSitesAdmin.log_file_url );
|
925 |
-
} else {
|
926 |
-
$('.go-pro').attr('href', astraSitesAdmin.log.serverConfiguration );
|
927 |
-
}
|
928 |
-
}
|
929 |
-
|
930 |
-
var output = '<div class="astra-api-error notice notice-error notice-alt is-dismissible">';
|
931 |
-
output += ' <p>'+message+'</p>';
|
932 |
-
output += ' <button type="button" class="notice-dismiss">';
|
933 |
-
output += ' <span class="screen-reader-text">'+commonL10n.dismiss+'</span>';
|
934 |
-
output += ' </button>';
|
935 |
-
output += '</div>';
|
936 |
-
|
937 |
-
// Fail Notice.
|
938 |
-
$('.install-theme-info').append( output );
|
939 |
-
|
940 |
-
|
941 |
-
// !important to add trigger.
|
942 |
-
// Which reinitialize the dismiss error message events.
|
943 |
-
$(document).trigger('wp-updates-notice-added');
|
944 |
-
},
|
945 |
-
|
946 |
-
|
947 |
-
/**
|
948 |
-
* Install Now
|
949 |
-
*/
|
950 |
-
_installNow: function(event)
|
951 |
-
{
|
952 |
-
event.preventDefault();
|
953 |
-
|
954 |
-
var $button = jQuery( event.target ),
|
955 |
-
$document = jQuery(document);
|
956 |
-
|
957 |
-
if ( $button.hasClass( 'updating-message' ) || $button.hasClass( 'button-disabled' ) ) {
|
958 |
-
return;
|
959 |
-
}
|
960 |
-
|
961 |
-
if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.ajaxLocked ) {
|
962 |
-
wp.updates.requestFilesystemCredentials( event );
|
963 |
-
|
964 |
-
$document.on( 'credential-modal-cancel', function() {
|
965 |
-
var $message = $( '.install-now.updating-message' );
|
966 |
-
|
967 |
-
$message
|
968 |
-
.removeClass( 'updating-message' )
|
969 |
-
.text( wp.updates.l10n.installNow );
|
970 |
-
|
971 |
-
wp.a11y.speak( wp.updates.l10n.updateCancel, 'polite' );
|
972 |
-
} );
|
973 |
-
}
|
974 |
-
|
975 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.installingPlugin + ' ' + $button.data( 'slug' ) );
|
976 |
-
|
977 |
-
wp.updates.installPlugin( {
|
978 |
-
slug: $button.data( 'slug' )
|
979 |
-
} );
|
980 |
-
},
|
981 |
-
|
982 |
-
/**
|
983 |
-
* Install Success
|
984 |
-
*/
|
985 |
-
_installSuccess: function( event, response ) {
|
986 |
-
|
987 |
-
event.preventDefault();
|
988 |
-
|
989 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.installed + ' ' + response.slug );
|
990 |
-
|
991 |
-
var $siteOptions = $( '.wp-full-overlay-header').find('.astra-site-options').val();
|
992 |
-
var $enabledExtensions = $( '.wp-full-overlay-header').find('.astra-enabled-extensions').val();
|
993 |
-
|
994 |
-
// Transform the 'Install' button into an 'Activate' button.
|
995 |
-
var $init = $( '.plugin-card-' + response.slug ).data('init');
|
996 |
-
|
997 |
-
// Reset not installed plugins list.
|
998 |
-
var pluginsList = astraSitesAdmin.requiredPlugins.notinstalled;
|
999 |
-
astraSitesAdmin.requiredPlugins.notinstalled = AstraSitesAdmin._removePluginFromQueue( response.slug, pluginsList );
|
1000 |
-
|
1001 |
-
// WordPress adds "Activate" button after waiting for 1000ms. So we will run our activation after that.
|
1002 |
-
setTimeout( function() {
|
1003 |
-
|
1004 |
-
$.ajax({
|
1005 |
-
url: astraSitesAdmin.ajaxurl,
|
1006 |
-
type: 'POST',
|
1007 |
-
data: {
|
1008 |
-
'action' : 'astra-required-plugin-activate',
|
1009 |
-
'init' : $init,
|
1010 |
-
'options' : $siteOptions,
|
1011 |
-
'enabledExtensions' : $enabledExtensions,
|
1012 |
-
},
|
1013 |
-
})
|
1014 |
-
.done(function (result) {
|
1015 |
-
|
1016 |
-
if( result.success ) {
|
1017 |
-
|
1018 |
-
var pluginsList = astraSitesAdmin.requiredPlugins.inactive;
|
1019 |
-
|
1020 |
-
// Reset not installed plugins list.
|
1021 |
-
astraSitesAdmin.requiredPlugins.inactive = AstraSitesAdmin._removePluginFromQueue( response.slug, pluginsList );
|
1022 |
-
|
1023 |
-
// Enable Demo Import Button
|
1024 |
-
AstraSitesAdmin._enable_demo_import_button();
|
1025 |
-
|
1026 |
-
}
|
1027 |
-
});
|
1028 |
-
|
1029 |
-
}, 1200 );
|
1030 |
-
|
1031 |
-
},
|
1032 |
-
|
1033 |
-
/**
|
1034 |
-
* Plugin Installation Error.
|
1035 |
-
*/
|
1036 |
-
_installError: function( event, response ) {
|
1037 |
-
|
1038 |
-
var $card = $( '.plugin-card-' + response.slug );
|
1039 |
-
|
1040 |
-
AstraSitesAdmin._log( response.errorMessage + ' ' + response.slug );
|
1041 |
-
|
1042 |
-
$card
|
1043 |
-
.removeClass( 'button-primary' )
|
1044 |
-
.addClass( 'disabled' )
|
1045 |
-
.html( wp.updates.l10n.installFailedShort );
|
1046 |
-
|
1047 |
-
AstraSitesAdmin._importFailMessage( response.errorMessage );
|
1048 |
-
},
|
1049 |
-
|
1050 |
-
/**
|
1051 |
-
* Installing Plugin
|
1052 |
-
*/
|
1053 |
-
_pluginInstalling: function(event, args) {
|
1054 |
-
event.preventDefault();
|
1055 |
-
|
1056 |
-
var $card = $( '.plugin-card-' + args.slug );
|
1057 |
-
|
1058 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.installingPlugin + ' ' + args.slug );
|
1059 |
-
|
1060 |
-
$card.addClass('updating-message');
|
1061 |
-
|
1062 |
-
},
|
1063 |
-
|
1064 |
-
/**
|
1065 |
-
* Render Demo Preview
|
1066 |
-
*/
|
1067 |
-
_activateNow: function( eventn ) {
|
1068 |
-
|
1069 |
-
event.preventDefault();
|
1070 |
-
|
1071 |
-
var $button = jQuery( event.target ),
|
1072 |
-
$init = $button.data( 'init' ),
|
1073 |
-
$slug = $button.data( 'slug' );
|
1074 |
-
|
1075 |
-
if ( $button.hasClass( 'updating-message' ) || $button.hasClass( 'button-disabled' ) ) {
|
1076 |
-
return;
|
1077 |
-
}
|
1078 |
-
|
1079 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.activating + ' ' + $slug );
|
1080 |
-
|
1081 |
-
$button.addClass('updating-message button-primary')
|
1082 |
-
.html( astraSitesAdmin.strings.btnActivating );
|
1083 |
-
|
1084 |
-
var $siteOptions = jQuery( '.wp-full-overlay-header').find('.astra-site-options').val();
|
1085 |
-
var $enabledExtensions = jQuery( '.wp-full-overlay-header').find('.astra-enabled-extensions').val();
|
1086 |
-
|
1087 |
-
$.ajax({
|
1088 |
-
url: astraSitesAdmin.ajaxurl,
|
1089 |
-
type: 'POST',
|
1090 |
-
data: {
|
1091 |
-
'action' : 'astra-required-plugin-activate',
|
1092 |
-
'init' : $init,
|
1093 |
-
'options' : $siteOptions,
|
1094 |
-
'enabledExtensions' : $enabledExtensions,
|
1095 |
-
},
|
1096 |
-
})
|
1097 |
-
.done(function (result) {
|
1098 |
-
|
1099 |
-
if( result.success ) {
|
1100 |
-
|
1101 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.activated + ' ' + $slug );
|
1102 |
-
|
1103 |
-
var pluginsList = astraSitesAdmin.requiredPlugins.inactive;
|
1104 |
-
|
1105 |
-
// Reset not installed plugins list.
|
1106 |
-
astraSitesAdmin.requiredPlugins.inactive = AstraSitesAdmin._removePluginFromQueue( $slug, pluginsList );
|
1107 |
-
|
1108 |
-
$button.removeClass( 'button-primary install-now activate-now updating-message' )
|
1109 |
-
.attr('disabled', 'disabled')
|
1110 |
-
.addClass('disabled')
|
1111 |
-
.text( astraSitesAdmin.strings.btnActive );
|
1112 |
-
|
1113 |
-
// Enable Demo Import Button
|
1114 |
-
AstraSitesAdmin._enable_demo_import_button();
|
1115 |
-
|
1116 |
-
}
|
1117 |
-
|
1118 |
-
})
|
1119 |
-
.fail(function () {
|
1120 |
-
});
|
1121 |
-
|
1122 |
-
},
|
1123 |
-
|
1124 |
-
/**
|
1125 |
-
* Full Overlay
|
1126 |
-
*/
|
1127 |
-
_fullOverlay: function (event) {
|
1128 |
-
event.preventDefault();
|
1129 |
-
|
1130 |
-
// Import process is started?
|
1131 |
-
// And Closing the window? Then showing the warning confirm message.
|
1132 |
-
if( $('body').hasClass('importing-site') && ! confirm( astraSitesAdmin.strings.warningBeforeCloseWindow ) ) {
|
1133 |
-
return;
|
1134 |
-
}
|
1135 |
-
|
1136 |
-
$('body').removeClass('importing-site');
|
1137 |
-
$('.previous-theme, .next-theme').removeClass('disabled');
|
1138 |
-
$('.theme-install-overlay').css('display', 'none');
|
1139 |
-
$('.theme-install-overlay').remove();
|
1140 |
-
$('.theme-preview-on').removeClass('theme-preview-on');
|
1141 |
-
$('html').removeClass('astra-site-preview-on');
|
1142 |
-
},
|
1143 |
-
|
1144 |
-
/**
|
1145 |
-
* Bulk Plugin Active & Install
|
1146 |
-
*/
|
1147 |
-
_bulkPluginInstallActivate: function()
|
1148 |
-
{
|
1149 |
-
if( 0 === astraSitesAdmin.requiredPlugins.length ) {
|
1150 |
-
return;
|
1151 |
-
}
|
1152 |
-
|
1153 |
-
var not_installed = astraSitesAdmin.requiredPlugins.notinstalled || '';
|
1154 |
-
var activate_plugins = astraSitesAdmin.requiredPlugins.inactive || '';
|
1155 |
-
|
1156 |
-
// First Install Bulk.
|
1157 |
-
if( not_installed.length > 0 ) {
|
1158 |
-
AstraSitesAdmin._installAllPlugins( not_installed );
|
1159 |
-
}
|
1160 |
-
|
1161 |
-
// Second Activate Bulk.
|
1162 |
-
if( activate_plugins.length > 0 ) {
|
1163 |
-
AstraSitesAdmin._activateAllPlugins( activate_plugins );
|
1164 |
-
}
|
1165 |
-
|
1166 |
-
if( activate_plugins.length <= 0 && not_installed.length <= 0 ) {
|
1167 |
-
AstraSitesAdmin._enable_demo_import_button();
|
1168 |
-
}
|
1169 |
-
|
1170 |
-
},
|
1171 |
-
|
1172 |
-
/**
|
1173 |
-
* Activate All Plugins.
|
1174 |
-
*/
|
1175 |
-
_activateAllPlugins: function( activate_plugins ) {
|
1176 |
-
|
1177 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.bulkActivation );
|
1178 |
-
|
1179 |
-
$.each( activate_plugins, function(index, single_plugin) {
|
1180 |
-
|
1181 |
-
var $card = $( '.plugin-card-' + single_plugin.slug ),
|
1182 |
-
$siteOptions = $( '.wp-full-overlay-header').find('.astra-site-options').val(),
|
1183 |
-
$enabledExtensions = $( '.wp-full-overlay-header').find('.astra-enabled-extensions').val();
|
1184 |
-
|
1185 |
-
AstraSitesAjaxQueue.add({
|
1186 |
-
url: astraSitesAdmin.ajaxurl,
|
1187 |
-
type: 'POST',
|
1188 |
-
data: {
|
1189 |
-
'action' : 'astra-required-plugin-activate',
|
1190 |
-
'init' : single_plugin.init,
|
1191 |
-
'options' : $siteOptions,
|
1192 |
-
'enabledExtensions' : $enabledExtensions,
|
1193 |
-
},
|
1194 |
-
success: function( result ){
|
1195 |
-
|
1196 |
-
if( result.success ) {
|
1197 |
-
|
1198 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.activate + ' ' + single_plugin.slug );
|
1199 |
-
|
1200 |
-
var pluginsList = astraSitesAdmin.requiredPlugins.inactive;
|
1201 |
-
|
1202 |
-
// Reset not installed plugins list.
|
1203 |
-
astraSitesAdmin.requiredPlugins.inactive = AstraSitesAdmin._removePluginFromQueue( single_plugin.slug, pluginsList );
|
1204 |
-
|
1205 |
-
// Enable Demo Import Button
|
1206 |
-
AstraSitesAdmin._enable_demo_import_button();
|
1207 |
-
} else {
|
1208 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.activationError + ' - ' + single_plugin.slug );
|
1209 |
-
}
|
1210 |
-
}
|
1211 |
-
});
|
1212 |
-
});
|
1213 |
-
AstraSitesAjaxQueue.run();
|
1214 |
-
},
|
1215 |
-
|
1216 |
-
/**
|
1217 |
-
* Install All Plugins.
|
1218 |
-
*/
|
1219 |
-
_installAllPlugins: function( not_installed ) {
|
1220 |
-
|
1221 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.bulkInstall );
|
1222 |
-
|
1223 |
-
$.each( not_installed, function(index, single_plugin) {
|
1224 |
-
|
1225 |
-
var $card = $( '.plugin-card-' + single_plugin.slug );
|
1226 |
-
|
1227 |
-
// Add each plugin activate request in Ajax queue.
|
1228 |
-
// @see wp-admin/js/updates.js
|
1229 |
-
wp.updates.queue.push( {
|
1230 |
-
action: 'install-plugin', // Required action.
|
1231 |
-
data: {
|
1232 |
-
slug: single_plugin.slug
|
1233 |
-
}
|
1234 |
-
} );
|
1235 |
-
});
|
1236 |
-
|
1237 |
-
// Required to set queue.
|
1238 |
-
wp.updates.queueChecker();
|
1239 |
-
},
|
1240 |
-
|
1241 |
-
/**
|
1242 |
-
* Fires when a nav item is clicked.
|
1243 |
-
*
|
1244 |
-
* @since 1.0
|
1245 |
-
* @access private
|
1246 |
-
* @method _importDemo
|
1247 |
-
*/
|
1248 |
-
_importDemo: function(event) {
|
1249 |
-
event.preventDefault();
|
1250 |
-
|
1251 |
-
var disabled = $(this).attr('data-import');
|
1252 |
-
|
1253 |
-
if ( typeof disabled !== 'undefined' && disabled === 'disabled' || $this.hasClass('disabled') ) {
|
1254 |
-
|
1255 |
-
$('.astra-demo-import').addClass('updating-message installing')
|
1256 |
-
.text( wp.updates.l10n.installing );
|
1257 |
-
|
1258 |
-
/**
|
1259 |
-
* Process Bulk Plugin Install & Activate
|
1260 |
-
*/
|
1261 |
-
AstraSitesAdmin._bulkPluginInstallActivate();
|
1262 |
-
}
|
1263 |
-
},
|
1264 |
-
|
1265 |
-
_process_import() {
|
1266 |
-
|
1267 |
-
var $theme = $('.astra-sites-preview').find('.wp-full-overlay-header'),
|
1268 |
-
apiURL = $theme.data('demo-api') || '';
|
1269 |
-
|
1270 |
-
$('body').addClass('importing-site');
|
1271 |
-
$('.previous-theme, .next-theme').addClass('disabled');
|
1272 |
-
|
1273 |
-
// Remove all notices before import start.
|
1274 |
-
$('.install-theme-info > .notice').remove();
|
1275 |
-
|
1276 |
-
$('.astra-demo-import').attr('data-import', 'disabled')
|
1277 |
-
.addClass('updating-message installing')
|
1278 |
-
.text( astraSitesAdmin.strings.importingDemo );
|
1279 |
-
|
1280 |
-
// Site Import by API URL.
|
1281 |
-
if( apiURL ) {
|
1282 |
-
AstraSitesAdmin._importSite( apiURL );
|
1283 |
-
}
|
1284 |
-
|
1285 |
-
},
|
1286 |
-
|
1287 |
-
/**
|
1288 |
-
* Start Import Process by API URL.
|
1289 |
-
*
|
1290 |
-
* @param {string} apiURL Site API URL.
|
1291 |
-
*/
|
1292 |
-
_importSite: function( apiURL ) {
|
1293 |
-
|
1294 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.api + ' : ' + apiURL );
|
1295 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.importing );
|
1296 |
-
|
1297 |
-
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.gettingData );
|
1298 |
-
|
1299 |
-
// 1. Request Site Import
|
1300 |
-
$.ajax({
|
1301 |
-
url : astraSitesAdmin.ajaxurl,
|
1302 |
-
type : 'POST',
|
1303 |
-
dataType: 'json',
|
1304 |
-
data : {
|
1305 |
-
'action' : 'astra-sites-import-set-site-data',
|
1306 |
-
'api_url' : apiURL,
|
1307 |
-
},
|
1308 |
-
})
|
1309 |
-
.fail(function( jqXHR ){
|
1310 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
1311 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
1312 |
-
})
|
1313 |
-
.done(function ( demo_data ) {
|
1314 |
-
|
1315 |
-
// 1. Fail - Request Site Import
|
1316 |
-
if( false === demo_data.success ) {
|
1317 |
-
|
1318 |
-
AstraSitesAdmin._importFailMessage( demo_data.data );
|
1319 |
-
|
1320 |
-
} else {
|
1321 |
-
|
1322 |
-
// Set log file URL.
|
1323 |
-
if( 'log_file' in demo_data.data ){
|
1324 |
-
AstraSitesAdmin.log_file_url = decodeURIComponent( demo_data.data.log_file ) || '';
|
1325 |
-
}
|
1326 |
-
|
1327 |
-
// 1. Pass - Request Site Import
|
1328 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.processingRequest );
|
1329 |
-
|
1330 |
-
AstraSitesAdmin.customizer_data = JSON.stringify( demo_data.data['astra-site-customizer-data'] ) || '';
|
1331 |
-
AstraSitesAdmin.wxr_url = encodeURI( demo_data.data['astra-site-wxr-path'] ) || '';
|
1332 |
-
AstraSitesAdmin.wpforms_url = encodeURI( demo_data.data['astra-site-wpforms-path'] ) || '';
|
1333 |
-
AstraSitesAdmin.options_data = JSON.stringify( demo_data.data['astra-site-options-data'] ) || '';
|
1334 |
-
AstraSitesAdmin.widgets_data = JSON.stringify( demo_data.data['astra-site-widgets-data'] ) || '';
|
1335 |
-
|
1336 |
-
$(document).trigger( 'astra-sites-import-set-site-data-done' );
|
1337 |
-
}
|
1338 |
-
|
1339 |
-
});
|
1340 |
-
|
1341 |
-
},
|
1342 |
-
|
1343 |
-
/**
|
1344 |
-
* Collapse Sidebar.
|
1345 |
-
*/
|
1346 |
-
_collapse: function() {
|
1347 |
-
event.preventDefault();
|
1348 |
-
|
1349 |
-
overlay = jQuery('.wp-full-overlay');
|
1350 |
-
|
1351 |
-
if (overlay.hasClass('expanded')) {
|
1352 |
-
overlay.removeClass('expanded');
|
1353 |
-
overlay.addClass('collapsed');
|
1354 |
-
return;
|
1355 |
-
}
|
1356 |
-
|
1357 |
-
if (overlay.hasClass('collapsed')) {
|
1358 |
-
overlay.removeClass('collapsed');
|
1359 |
-
overlay.addClass('expanded');
|
1360 |
-
return;
|
1361 |
-
}
|
1362 |
-
},
|
1363 |
-
|
1364 |
-
/**
|
1365 |
-
* Previous Theme.
|
1366 |
-
*/
|
1367 |
-
_previousTheme: function (event) {
|
1368 |
-
event.preventDefault();
|
1369 |
-
|
1370 |
-
currentDemo = jQuery('.theme-preview-on');
|
1371 |
-
currentDemo.removeClass('theme-preview-on');
|
1372 |
-
prevDemo = currentDemo.prev('.theme');
|
1373 |
-
prevDemo.addClass('theme-preview-on');
|
1374 |
-
|
1375 |
-
var site_id = $(this).parents('.wp-full-overlay-header').data('demo-id') || '';
|
1376 |
-
|
1377 |
-
if( AstraSitesAPI._stored_data ) {
|
1378 |
-
var site_data = AstraSitesAdmin._get_site_details( site_id );
|
1379 |
-
|
1380 |
-
|
1381 |
-
if( site_data ) {
|
1382 |
-
// Set current site details.
|
1383 |
-
AstraSitesAdmin.current_site = site_data;
|
1384 |
-
}
|
1385 |
-
}
|
1386 |
-
|
1387 |
-
AstraSitesAdmin._renderDemoPreview(prevDemo);
|
1388 |
-
},
|
1389 |
-
|
1390 |
-
/**
|
1391 |
-
* Next Theme.
|
1392 |
-
*/
|
1393 |
-
_nextTheme: function (event) {
|
1394 |
-
event.preventDefault();
|
1395 |
-
currentDemo = jQuery('.theme-preview-on')
|
1396 |
-
currentDemo.removeClass('theme-preview-on');
|
1397 |
-
nextDemo = currentDemo.next('.theme');
|
1398 |
-
nextDemo.addClass('theme-preview-on');
|
1399 |
-
|
1400 |
-
var site_id = $(this).parents('.wp-full-overlay-header').data('demo-id') || '';
|
1401 |
-
|
1402 |
-
if( AstraSitesAPI._stored_data ) {
|
1403 |
-
var site_data = AstraSitesAdmin._get_site_details( site_id );
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
if( site_data ) {
|
1408 |
-
// Set current site details.
|
1409 |
-
AstraSitesAdmin.current_site = site_data;
|
1410 |
-
}
|
1411 |
-
}
|
1412 |
-
|
1413 |
-
AstraSitesAdmin._renderDemoPreview( nextDemo );
|
1414 |
-
},
|
1415 |
-
|
1416 |
-
_set_current_screen: function( screen ) {
|
1417 |
-
AstraSitesAdmin.current_screen = screen;
|
1418 |
-
var old_screen = $('.astra-sites-preview').attr( 'screen' ) || '';
|
1419 |
-
|
1420 |
-
|
1421 |
-
if( old_screen ) {
|
1422 |
-
$('.astra-sites-preview').removeClass( 'screen-' + old_screen );
|
1423 |
-
}
|
1424 |
-
|
1425 |
-
$('.astra-sites-preview').attr( 'screen', screen );
|
1426 |
-
$('.astra-sites-preview').addClass( 'screen-' + screen );
|
1427 |
-
},
|
1428 |
-
|
1429 |
-
/**
|
1430 |
-
* Individual Site Preview
|
1431 |
-
*
|
1432 |
-
* On click on image, more link & preview button.
|
1433 |
-
*/
|
1434 |
-
_preview: function( event ) {
|
1435 |
-
|
1436 |
-
event.preventDefault();
|
1437 |
-
|
1438 |
-
var site_id = $(this).parents('.site-single').data('demo-id') || '';
|
1439 |
-
|
1440 |
-
if( AstraSitesAPI._stored_data ) {
|
1441 |
-
var site_data = AstraSitesAdmin._get_site_details( site_id );
|
1442 |
-
|
1443 |
-
if( site_data ) {
|
1444 |
-
// Set current site details.
|
1445 |
-
AstraSitesAdmin.current_site = site_data;
|
1446 |
-
|
1447 |
-
// Set current screen.
|
1448 |
-
AstraSitesAdmin._set_current_screen( 'get-started' );
|
1449 |
-
}
|
1450 |
-
}
|
1451 |
-
|
1452 |
-
var self = $(this).parents('.theme');
|
1453 |
-
self.addClass('theme-preview-on');
|
1454 |
-
|
1455 |
-
$('html').addClass('astra-site-preview-on');
|
1456 |
-
|
1457 |
-
AstraSitesAdmin._renderDemoPreview( self );
|
1458 |
-
},
|
1459 |
-
|
1460 |
-
_get_site_details: function( site_id ) {
|
1461 |
-
var all_sites = AstraSitesAPI._stored_data['astra-sites'] || [];
|
1462 |
-
|
1463 |
-
if( ! all_sites ) {
|
1464 |
-
return false;
|
1465 |
-
}
|
1466 |
-
|
1467 |
-
var single_site = all_sites.filter(function (site) { return site.id == site_id });
|
1468 |
-
if( ! single_site ) {
|
1469 |
-
return false;
|
1470 |
-
}
|
1471 |
-
|
1472 |
-
if( ! $.isArray( single_site ) ) {
|
1473 |
-
return false;
|
1474 |
-
}
|
1475 |
-
|
1476 |
-
return single_site[0];
|
1477 |
-
},
|
1478 |
-
|
1479 |
-
/**
|
1480 |
-
* Check Next Previous Buttons.
|
1481 |
-
*/
|
1482 |
-
_checkNextPrevButtons: function() {
|
1483 |
-
currentDemo = jQuery('.theme-preview-on');
|
1484 |
-
nextDemo = currentDemo.nextAll('.theme').length;
|
1485 |
-
prevDemo = currentDemo.prevAll('.theme').length;
|
1486 |
-
|
1487 |
-
if (nextDemo == 0) {
|
1488 |
-
jQuery('.next-theme').addClass('disabled');
|
1489 |
-
} else if (nextDemo != 0) {
|
1490 |
-
jQuery('.next-theme').removeClass('disabled');
|
1491 |
-
}
|
1492 |
-
|
1493 |
-
if (prevDemo == 0) {
|
1494 |
-
jQuery('.previous-theme').addClass('disabled');
|
1495 |
-
} else if (prevDemo != 0) {
|
1496 |
-
jQuery('.previous-theme').removeClass('disabled');
|
1497 |
-
}
|
1498 |
-
|
1499 |
-
return;
|
1500 |
-
},
|
1501 |
-
|
1502 |
-
/**
|
1503 |
-
* Render Demo Preview
|
1504 |
-
*/
|
1505 |
-
_renderDemoPreview: function(anchor) {
|
1506 |
-
|
1507 |
-
var demoId = anchor.data('demo-id') || '',
|
1508 |
-
apiURL = anchor.data('demo-api') || '',
|
1509 |
-
demoType = anchor.data('demo-type') || '',
|
1510 |
-
demoURL = anchor.data('demo-url') || '',
|
1511 |
-
screenshot = anchor.data('screenshot') || '',
|
1512 |
-
demo_name = anchor.data('demo-name') || '',
|
1513 |
-
demo_slug = anchor.data('demo-slug') || '',
|
1514 |
-
content = anchor.data('content') || '',
|
1515 |
-
requiredPlugins = anchor.data('required-plugins') || '',
|
1516 |
-
astraSiteOptions = anchor.find('.astra-site-options').val() || '';
|
1517 |
-
astraEnabledExtensions = anchor.find('.astra-enabled-extensions').val() || '';
|
1518 |
-
|
1519 |
-
AstraSitesAdmin._log( astraSitesAdmin.log.preview + ' "' + demo_name + '" URL : ' + demoURL );
|
1520 |
-
|
1521 |
-
|
1522 |
-
var template = wp.template('astra-site-preview');
|
1523 |
-
|
1524 |
-
templateData = [{
|
1525 |
-
id : demoId,
|
1526 |
-
astra_demo_type : demoType,
|
1527 |
-
astra_demo_url : demoURL,
|
1528 |
-
demo_api : apiURL,
|
1529 |
-
screenshot : screenshot,
|
1530 |
-
demo_name : demo_name,
|
1531 |
-
slug : demo_slug,
|
1532 |
-
content : content,
|
1533 |
-
required_plugins : JSON.stringify(requiredPlugins),
|
1534 |
-
astra_site_options : astraSiteOptions,
|
1535 |
-
astra_enabled_extensions : astraEnabledExtensions,
|
1536 |
-
}];
|
1537 |
-
|
1538 |
-
// return;
|
1539 |
-
|
1540 |
-
// delete any earlier fullscreen preview before we render new one.
|
1541 |
-
$('.theme-install-overlay').remove();
|
1542 |
-
|
1543 |
-
$('#astra-sites-menu-page').append(template(templateData[0]));
|
1544 |
-
$('.theme-install-overlay').css('display', 'block');
|
1545 |
-
AstraSitesAdmin._checkNextPrevButtons();
|
1546 |
-
|
1547 |
-
var desc = $('.theme-details');
|
1548 |
-
var descHeight = parseInt( desc.outerHeight() );
|
1549 |
-
var descBtn = $('.theme-details-read-more');
|
1550 |
-
|
1551 |
-
// Check is site imported recently and set flag.
|
1552 |
-
$.ajax({
|
1553 |
-
url : astraSitesAdmin.ajaxurl,
|
1554 |
-
type : 'POST',
|
1555 |
-
data : {
|
1556 |
-
action : 'astra-sites-set-reset-data',
|
1557 |
-
},
|
1558 |
-
})
|
1559 |
-
.done(function ( response ) {
|
1560 |
-
AstraSitesAdmin._log( response );
|
1561 |
-
if( response.success ) {
|
1562 |
-
AstraSitesAdmin.site_imported_data = response.data;
|
1563 |
-
}
|
1564 |
-
});
|
1565 |
-
|
1566 |
-
if( $.isArray( requiredPlugins ) ) {
|
1567 |
-
|
1568 |
-
if( descHeight >= 55 ) {
|
1569 |
-
|
1570 |
-
// Show button.
|
1571 |
-
descBtn.css( 'display', 'inline-block' );
|
1572 |
-
|
1573 |
-
// Set height upto 3 line.
|
1574 |
-
desc.css( 'height', 57 );
|
1575 |
-
|
1576 |
-
// Button Click.
|
1577 |
-
descBtn.click(function(event) {
|
1578 |
-
|
1579 |
-
if( descBtn.hasClass('open') ) {
|
1580 |
-
desc.animate({ height: 57 },
|
1581 |
-
300, function() {
|
1582 |
-
descBtn.removeClass('open');
|
1583 |
-
descBtn.html( astraSitesAdmin.strings.DescExpand );
|
1584 |
-
});
|
1585 |
-
} else {
|
1586 |
-
desc.animate({ height: descHeight },
|
1587 |
-
300, function() {
|
1588 |
-
descBtn.addClass('open');
|
1589 |
-
descBtn.html( astraSitesAdmin.strings.DescCollapse );
|
1590 |
-
});
|
1591 |
-
}
|
1592 |
-
|
1593 |
-
});
|
1594 |
-
}
|
1595 |
-
|
1596 |
-
// or
|
1597 |
-
var $pluginsFilter = $( '#plugin-filter' ),
|
1598 |
-
data = {
|
1599 |
-
action : 'astra-required-plugins',
|
1600 |
-
_ajax_nonce : astraSitesAdmin._ajax_nonce,
|
1601 |
-
required_plugins : requiredPlugins
|
1602 |
-
};
|
1603 |
-
|
1604 |
-
// Add disabled class from import button.
|
1605 |
-
$('.astra-demo-import')
|
1606 |
-
.addClass('disabled not-click-able')
|
1607 |
-
.removeAttr('data-import');
|
1608 |
-
|
1609 |
-
$('.required-plugins').addClass('loading').html('<span class="spinner is-active"></span>');
|
1610 |
-
|
1611 |
-
// Required Required.
|
1612 |
-
$.ajax({
|
1613 |
-
url : astraSitesAdmin.ajaxurl,
|
1614 |
-
type : 'POST',
|
1615 |
-
data : data,
|
1616 |
-
})
|
1617 |
-
.fail(function( jqXHR ){
|
1618 |
-
|
1619 |
-
// Remove loader.
|
1620 |
-
$('.required-plugins').removeClass('loading').html('');
|
1621 |
-
|
1622 |
-
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText, 'plugins' );
|
1623 |
-
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
1624 |
-
})
|
1625 |
-
.done(function ( response ) {
|
1626 |
-
|
1627 |
-
|
1628 |
-
// Release disabled class from import button.
|
1629 |
-
$('.astra-demo-import')
|
1630 |
-
.removeClass('disabled not-click-able')
|
1631 |
-
.attr('data-import', 'disabled');
|
1632 |
-
|
1633 |
-
// Remove loader.
|
1634 |
-
$('.required-plugins').removeClass('loading').html('');
|
1635 |
-
$('.required-plugins-list').html('');
|
1636 |
-
|
1637 |
-
/**
|
1638 |
-
* Count remaining plugins.
|
1639 |
-
* @type number
|
1640 |
-
*/
|
1641 |
-
var remaining_plugins = 0;
|
1642 |
-
|
1643 |
-
/**
|
1644 |
-
* Not Installed
|
1645 |
-
*
|
1646 |
-
* List of not installed required plugins.
|
1647 |
-
*/
|
1648 |
-
if ( typeof response.data.notinstalled !== 'undefined' ) {
|
1649 |
-
|
1650 |
-
// Add not have installed plugins count.
|
1651 |
-
remaining_plugins += parseInt( response.data.notinstalled.length );
|
1652 |
-
|
1653 |
-
$( response.data.notinstalled ).each(function( index, plugin ) {
|
1654 |
-
$('.required-plugins-list').append('<li class="plugin-card plugin-card-'+plugin.slug+'" data-slug="'+plugin.slug+'" data-init="'+plugin.init+'">'+plugin.name+'</li>');
|
1655 |
-
});
|
1656 |
-
}
|
1657 |
-
|
1658 |
-
/**
|
1659 |
-
* Inactive
|
1660 |
-
*
|
1661 |
-
* List of not inactive required plugins.
|
1662 |
-
*/
|
1663 |
-
if ( typeof response.data.inactive !== 'undefined' ) {
|
1664 |
-
|
1665 |
-
// Add inactive plugins count.
|
1666 |
-
remaining_plugins += parseInt( response.data.inactive.length );
|
1667 |
-
|
1668 |
-
$( response.data.inactive ).each(function( index, plugin ) {
|
1669 |
-
$('.required-plugins-list').append('<li class="plugin-card plugin-card-'+plugin.slug+'" data-slug="'+plugin.slug+'" data-init="'+plugin.init+'">'+plugin.name+'</li>');
|
1670 |
-
});
|
1671 |
-
}
|
1672 |
-
|
1673 |
-
/**
|
1674 |
-
* Active
|
1675 |
-
*
|
1676 |
-
* List of not active required plugins.
|
1677 |
-
*/
|
1678 |
-
if ( typeof response.data.active !== 'undefined' ) {
|
1679 |
-
|
1680 |
-
$( response.data.active ).each(function( index, plugin ) {
|
1681 |
-
$('.required-plugins-list').append('<li class="plugin-card plugin-card-'+plugin.slug+'" data-slug="'+plugin.slug+'" data-init="'+plugin.init+'">'+plugin.name+'</li>');
|
1682 |
-
});
|
1683 |
-
}
|
1684 |
-
|
1685 |
-
/**
|
1686 |
-
* Enable Demo Import Button
|
1687 |
-
* @type number
|
1688 |
-
*/
|
1689 |
-
astraSitesAdmin.requiredPlugins = response.data;
|
1690 |
-
});
|
1691 |
-
|
1692 |
-
} else {
|
1693 |
-
|
1694 |
-
// Enable Demo Import Button
|
1695 |
-
AstraSitesAdmin._enable_demo_import_button( demoType );
|
1696 |
-
$('.astra-sites-advanced-options-wrap').remove();
|
1697 |
-
}
|
1698 |
-
|
1699 |
-
return;
|
1700 |
-
},
|
1701 |
-
|
1702 |
-
/**
|
1703 |
-
* Enable Demo Import Button.
|
1704 |
-
*/
|
1705 |
-
_enable_demo_import_button: function( type ) {
|
1706 |
-
|
1707 |
-
type = ( undefined !== type ) ? type : 'free';
|
1708 |
-
|
1709 |
-
$('.install-theme-info .theme-details .site-description').remove();
|
1710 |
-
|
1711 |
-
switch( type ) {
|
1712 |
-
|
1713 |
-
case 'free':
|
1714 |
-
|
1715 |
-
var notinstalled = astraSitesAdmin.requiredPlugins.notinstalled || 0;
|
1716 |
-
var inactive = astraSitesAdmin.requiredPlugins.inactive || 0;
|
1717 |
-
|
1718 |
-
if( notinstalled.length === inactive.length ) {
|
1719 |
-
|
1720 |
-
// XML reader not available notice.
|
1721 |
-
if( astraSitesAdmin.XMLReaderDisabled ) {
|
1722 |
-
if( ! $('.install-theme-info .astra-sites-xml-notice').length ) {
|
1723 |
-
$('.install-theme-info').prepend( astraSitesAdmin.strings.warningXMLReader );
|
1724 |
-
}
|
1725 |
-
$('.astra-demo-import')
|
1726 |
-
.removeClass('installing updating-message')
|
1727 |
-
.addClass('disabled')
|
1728 |
-
.text( astraSitesAdmin.strings.importDemo );
|
1729 |
-
} else {
|
1730 |
-
$(document).trigger( 'astra-sites-install-and-activate-required-plugins-done' );
|
1731 |
-
}
|
1732 |
-
}
|
1733 |
-
|
1734 |
-
break;
|
1735 |
-
|
1736 |
-
case 'upgrade':
|
1737 |
-
var demo_slug = $('.wp-full-overlay-header').attr('data-demo-slug');
|
1738 |
-
|
1739 |
-
$('.astra-demo-import')
|
1740 |
-
.addClass('go-pro button-primary')
|
1741 |
-
.removeClass('astra-demo-import')
|
1742 |
-
.attr('target', '_blank')
|
1743 |
-
.attr('href', astraSitesAdmin.getUpgradeURL + demo_slug )
|
1744 |
-
.text( astraSitesAdmin.getUpgradeText )
|
1745 |
-
.append('<i class="dashicons dashicons-external"></i>');
|
1746 |
-
|
1747 |
-
break;
|
1748 |
-
|
1749 |
-
default:
|
1750 |
-
var demo_slug = $('.wp-full-overlay-header').attr('data-demo-slug');
|
1751 |
-
|
1752 |
-
$('.astra-demo-import')
|
1753 |
-
.addClass('go-pro button-primary')
|
1754 |
-
.removeClass('astra-demo-import')
|
1755 |
-
.attr('target', '_blank')
|
1756 |
-
.attr('href', astraSitesAdmin.getProURL )
|
1757 |
-
.text( astraSitesAdmin.getProText )
|
1758 |
-
.append('<i class="dashicons dashicons-external"></i>');
|
1759 |
-
|
1760 |
-
if( false == astraSitesAdmin.isWhiteLabeled ) {
|
1761 |
-
if( astraSitesAdmin.isPro ) {
|
1762 |
-
$('.install-theme-info .theme-details').prepend( wp.template('astra-sites-pro-inactive-site-description') );
|
1763 |
-
} else {
|
1764 |
-
$('.install-theme-info .theme-details').prepend( wp.template('astra-sites-pro-site-description') );
|
1765 |
-
}
|
1766 |
-
}
|
1767 |
-
|
1768 |
-
break;
|
1769 |
-
}
|
1770 |
-
|
1771 |
-
},
|
1772 |
-
|
1773 |
-
/**
|
1774 |
-
* Update Page Count.
|
1775 |
-
*/
|
1776 |
-
_updatedPagedCount: function() {
|
1777 |
-
paged = parseInt(jQuery('body').attr('data-astra-demo-paged'));
|
1778 |
-
jQuery('body').attr('data-astra-demo-paged', paged + 1);
|
1779 |
-
window.setTimeout(function () {
|
1780 |
-
jQuery('body').data('scrolling', false);
|
1781 |
-
}, 800);
|
1782 |
-
},
|
1783 |
-
|
1784 |
-
/**
|
1785 |
-
* Reset Page Count.
|
1786 |
-
*/
|
1787 |
-
_resetPagedCount: function() {
|
1788 |
-
|
1789 |
-
$('body').addClass('loading-content');
|
1790 |
-
$('body').attr('data-astra-demo-last-request', '1');
|
1791 |
-
$('body').attr('data-astra-demo-paged', '1');
|
1792 |
-
$('body').attr('data-astra-demo-search', '');
|
1793 |
-
$('body').attr('data-scrolling', false);
|
1794 |
-
|
1795 |
-
},
|
1796 |
-
|
1797 |
-
/**
|
1798 |
-
* Remove plugin from the queue.
|
1799 |
-
*/
|
1800 |
-
_removePluginFromQueue: function( removeItem, pluginsList ) {
|
1801 |
-
return jQuery.grep(pluginsList, function( value ) {
|
1802 |
-
return value.slug != removeItem;
|
1803 |
-
});
|
1804 |
-
}
|
1805 |
-
|
1806 |
-
};
|
1807 |
-
|
1808 |
-
/**
|
1809 |
-
* Initialize AstraSitesAdmin
|
1810 |
-
*/
|
1811 |
-
$(function(){
|
1812 |
-
AstraSitesAdmin.init();
|
1813 |
-
});
|
1814 |
-
|
1815 |
Â
})(jQuery);
|
1 |
+
/**
|
2 |
+
* AJAX Request Queue
|
3 |
+
*
|
4 |
+
* - add()
|
5 |
+
* - remove()
|
6 |
+
* - run()
|
7 |
+
* - stop()
|
8 |
+
*
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
var AstraSitesAjaxQueue = (function() {
|
12 |
+
|
13 |
+
var requests = [];
|
14 |
+
|
15 |
+
return {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Add AJAX request
|
19 |
+
*
|
20 |
+
* @since 1.0.0
|
21 |
+
*/
|
22 |
+
add: function(opt) {
|
23 |
+
requests.push(opt);
|
24 |
+
},
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Remove AJAX request
|
28 |
+
*
|
29 |
+
* @since 1.0.0
|
30 |
+
*/
|
31 |
+
remove: function(opt) {
|
32 |
+
if( jQuery.inArray(opt, requests) > -1 )
|
33 |
+
requests.splice($.inArray(opt, requests), 1);
|
34 |
+
},
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Run / Process AJAX request
|
38 |
+
*
|
39 |
+
* @since 1.0.0
|
40 |
+
*/
|
41 |
+
run: function() {
|
42 |
+
var self = this,
|
43 |
+
oriSuc;
|
44 |
+
|
45 |
+
if( requests.length ) {
|
46 |
+
oriSuc = requests[0].complete;
|
47 |
+
|
48 |
+
requests[0].complete = function() {
|
49 |
+
if( typeof(oriSuc) === 'function' ) oriSuc();
|
50 |
+
requests.shift();
|
51 |
+
self.run.apply(self, []);
|
52 |
+
};
|
53 |
+
|
54 |
+
jQuery.ajax(requests[0]);
|
55 |
+
|
56 |
+
} else {
|
57 |
+
|
58 |
+
self.tid = setTimeout(function() {
|
59 |
+
self.run.apply(self, []);
|
60 |
+
}, 1000);
|
61 |
+
}
|
62 |
+
},
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Stop AJAX request
|
66 |
+
*
|
67 |
+
* @since 1.0.0
|
68 |
+
*/
|
69 |
+
stop: function() {
|
70 |
+
|
71 |
+
requests = [];
|
72 |
+
clearTimeout(this.tid);
|
73 |
+
}
|
74 |
+
};
|
75 |
+
|
76 |
+
}());
|
77 |
+
|
78 |
+
(function($){
|
79 |
+
|
80 |
+
var AstraSSEImport = {
|
81 |
+
complete: {
|
82 |
+
posts: 0,
|
83 |
+
media: 0,
|
84 |
+
users: 0,
|
85 |
+
comments: 0,
|
86 |
+
terms: 0,
|
87 |
+
},
|
88 |
+
|
89 |
+
updateDelta: function (type, delta) {
|
90 |
+
this.complete[ type ] += delta;
|
91 |
+
|
92 |
+
var self = this;
|
93 |
+
requestAnimationFrame(function () {
|
94 |
+
self.render();
|
95 |
+
});
|
96 |
+
},
|
97 |
+
updateProgress: function ( type, complete, total ) {
|
98 |
+
var text = complete + '/' + total;
|
99 |
+
|
100 |
+
if( 'undefined' !== type && 'undefined' !== text ) {
|
101 |
+
total = parseInt( total, 10 );
|
102 |
+
if ( 0 === total || isNaN( total ) ) {
|
103 |
+
total = 1;
|
104 |
+
}
|
105 |
+
var percent = parseInt( complete, 10 ) / total;
|
106 |
+
var progress = Math.round( percent * 100 ) + '%';
|
107 |
+
var progress_bar = percent * 100;
|
108 |
+
|
109 |
+
if( progress_bar <= 100 ) {
|
110 |
+
document.getElementById( 'astra-site-import-process' ).value = progress_bar;
|
111 |
+
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingXML + ' '+progress );
|
112 |
+
}
|
113 |
+
}
|
114 |
+
},
|
115 |
+
render: function () {
|
116 |
+
var types = Object.keys( this.complete );
|
117 |
+
var complete = 0;
|
118 |
+
var total = 0;
|
119 |
+
|
120 |
+
|
121 |
+
for (var i = types.length - 1; i >= 0; i--) {
|
122 |
+
var type = types[i];
|
123 |
+
this.updateProgress( type, this.complete[ type ], this.data.count[ type ] );
|
124 |
+
|
125 |
+
complete += this.complete[ type ];
|
126 |
+
total += this.data.count[ type ];
|
127 |
+
}
|
128 |
+
|
129 |
+
this.updateProgress( 'total', complete, total );
|
130 |
+
}
|
131 |
+
};
|
132 |
+
|
133 |
+
AstraSitesAdmin = {
|
134 |
+
|
135 |
+
reset_remaining_posts: 0,
|
136 |
+
reset_remaining_wp_forms: 0,
|
137 |
+
reset_remaining_terms: 0,
|
138 |
+
reset_processed_posts: 0,
|
139 |
+
reset_processed_wp_forms: 0,
|
140 |
+
reset_processed_terms: 0,
|
141 |
+
site_imported_data: null,
|
142 |
+
|
143 |
+
backup_taken: false,
|
144 |
+
|
145 |
+
current_site: [],
|
146 |
+
current_screen: '',
|
147 |
+
|
148 |
+
templateData: {},
|
149 |
+
|
150 |
+
log_file : '',
|
151 |
+
customizer_data : '',
|
152 |
+
wxr_url : '',
|
153 |
+
wpforms_url : '',
|
154 |
+
options_data : '',
|
155 |
+
widgets_data : '',
|
156 |
+
|
157 |
+
init: function()
|
158 |
+
{
|
159 |
+
this._resetPagedCount();
|
160 |
+
this._bind();
|
161 |
+
},
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Debugging.
|
165 |
+
*
|
166 |
+
* @param {mixed} data Mixed data.
|
167 |
+
*/
|
168 |
+
_log: function( data ) {
|
169 |
+
|
170 |
+
if( astraSitesAdmin.debug ) {
|
171 |
+
|
172 |
+
var date = new Date();
|
173 |
+
var time = date.toLocaleTimeString();
|
174 |
+
|
175 |
+
if (typeof data == 'object') {
|
176 |
+
console.log('%c ' + JSON.stringify( data ) + ' ' + time, 'background: #ededed; color: #444');
|
177 |
+
} else {
|
178 |
+
console.log('%c ' + data + ' ' + time, 'background: #ededed; color: #444');
|
179 |
+
}
|
180 |
+
|
181 |
+
|
182 |
+
}
|
183 |
+
},
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Binds events for the Astra Sites.
|
187 |
+
*
|
188 |
+
* @since 1.0.0
|
189 |
+
* @access private
|
190 |
+
* @method _bind
|
191 |
+
*/
|
192 |
+
_bind: function()
|
193 |
+
{
|
194 |
+
$( document ).on( 'click' , '.astra-sites-reset-data .checkbox', AstraSitesAdmin._toggle_reset_notice );
|
195 |
+
$( document ).on('change' , '#astra-sites-welcome-form-inline select', AstraSitesAdmin._change_page_builder);
|
196 |
+
$( document ).on('click' , '.astra-sites-tooltip-icon', AstraSitesAdmin._toggle_tooltip);
|
197 |
+
$( document ).on('click' , '.astra-sites-advanced-options-button', AstraSitesAdmin._toggle_advanced_options);
|
198 |
+
|
199 |
+
$( document ).on('click' , '.astra-import-settings', AstraSitesAdmin._import_settings);
|
200 |
+
$( document ).on('click' , '.devices button', AstraSitesAdmin._previewDevice);
|
201 |
+
$( document ).on('click' , '.theme-browser .theme-screenshot, .theme-browser .more-details, .theme-browser .install-theme-preview', AstraSitesAdmin._preview);
|
202 |
+
$( document ).on('click' , '.next-theme', AstraSitesAdmin._nextTheme);
|
203 |
+
$( document ).on('click' , '.previous-theme', AstraSitesAdmin._previousTheme);
|
204 |
+
$( document ).on('click' , '.collapse-sidebar', AstraSitesAdmin._collapse);
|
205 |
+
$( document ).on('click' , '.astra-demo-import', AstraSitesAdmin._importDemo);
|
206 |
+
|
207 |
+
$( document ).on('astra-sites-install-and-activate-required-plugins-done' , AstraSitesAdmin._process_import );
|
208 |
+
|
209 |
+
$( document ).on('click' , '.install-now', AstraSitesAdmin._installNow);
|
210 |
+
$( document ).on('click' , '.close-full-overlay', AstraSitesAdmin._fullOverlay);
|
211 |
+
$( document ).on('click' , '.activate-now', AstraSitesAdmin._activateNow);
|
212 |
+
$( document ).on('wp-plugin-installing' , AstraSitesAdmin._pluginInstalling);
|
213 |
+
$( document ).on('wp-plugin-install-error' , AstraSitesAdmin._installError);
|
214 |
+
$( document ).on('wp-plugin-install-success' , AstraSitesAdmin._installSuccess);
|
215 |
+
|
216 |
+
$( document ).on( 'astra-sites-import-set-site-data-done' , AstraSitesAdmin._resetData );
|
217 |
+
$( document ).on( 'astra-sites-reset-data' , AstraSitesAdmin._backup_before_rest_options );
|
218 |
+
$( document ).on( 'astra-sites-backup-settings-before-reset-done' , AstraSitesAdmin._reset_customizer_data );
|
219 |
+
$( document ).on( 'astra-sites-reset-customizer-data-done' , AstraSitesAdmin._reset_site_options );
|
220 |
+
$( document ).on( 'astra-sites-reset-site-options-done' , AstraSitesAdmin._reset_widgets_data );
|
221 |
+
$( document ).on( 'astra-sites-reset-widgets-data-done' , AstraSitesAdmin._reset_terms );
|
222 |
+
$( document ).on( 'astra-sites-delete-terms-done' , AstraSitesAdmin._reset_wp_forms );
|
223 |
+
$( document ).on( 'astra-sites-delete-wp-forms-done' , AstraSitesAdmin._reset_posts );
|
224 |
+
|
225 |
+
$( document ).on('astra-sites-reset-data-done' , AstraSitesAdmin._recheck_backup_options );
|
226 |
+
$( document ).on('astra-sites-backup-settings-done' , AstraSitesAdmin._importWPForms );
|
227 |
+
$( document ).on('astra-sites-import-wpforms-done' , AstraSitesAdmin._importCustomizerSettings );
|
228 |
+
$( document ).on('astra-sites-import-customizer-settings-done' , AstraSitesAdmin._importXML );
|
229 |
+
$( document ).on('astra-sites-import-xml-done' , AstraSitesAdmin._importSiteOptions );
|
230 |
+
$( document ).on('astra-sites-import-options-done' , AstraSitesAdmin._importWidgets );
|
231 |
+
$( document ).on('astra-sites-import-widgets-done' , AstraSitesAdmin._importEnd );
|
232 |
+
|
233 |
+
},
|
234 |
+
|
235 |
+
_change_page_builder: function() {
|
236 |
+
$(this).closest('form').submit();
|
237 |
+
},
|
238 |
+
|
239 |
+
_toggle_tooltip: function( event ) {
|
240 |
+
event.preventDefault();
|
241 |
+
var tip_id = $( this ).data('tip-id') || '';
|
242 |
+
if( tip_id && $( '#' + tip_id ).length ) {
|
243 |
+
$( '#' + tip_id ).toggle();
|
244 |
+
}
|
245 |
+
},
|
246 |
+
|
247 |
+
_toggle_advanced_options: function( event ) {
|
248 |
+
event.preventDefault();
|
249 |
+
$('.astra-sites-advanced-options').toggle();
|
250 |
+
},
|
251 |
+
|
252 |
+
_resetData: function( event ) {
|
253 |
+
event.preventDefault();
|
254 |
+
|
255 |
+
if ( $( '.astra-sites-reset-data' ).find('.checkbox').is(':checked') ) {
|
256 |
+
$(document).trigger( 'astra-sites-reset-data' );
|
257 |
+
} else {
|
258 |
+
$(document).trigger( 'astra-sites-reset-data-done' );
|
259 |
+
}
|
260 |
+
},
|
261 |
+
|
262 |
+
_reset_customizer_data() {
|
263 |
+
$.ajax({
|
264 |
+
url : astraSitesAdmin.ajaxurl,
|
265 |
+
type : 'POST',
|
266 |
+
data : {
|
267 |
+
action : 'astra-sites-reset-customizer-data'
|
268 |
+
},
|
269 |
+
beforeSend: function() {
|
270 |
+
AstraSitesAdmin._log( 'Reseting Customizer Data' );
|
271 |
+
$('.button-hero.astra-demo-import').text( 'Reseting Customizer Data' );
|
272 |
+
},
|
273 |
+
})
|
274 |
+
.fail(function( jqXHR ){
|
275 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
276 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
277 |
+
})
|
278 |
+
.done(function ( data ) {
|
279 |
+
$(document).trigger( 'astra-sites-reset-customizer-data-done' );
|
280 |
+
});
|
281 |
+
},
|
282 |
+
|
283 |
+
_reset_site_options: function() {
|
284 |
+
// Site Options.
|
285 |
+
$.ajax({
|
286 |
+
url : astraSitesAdmin.ajaxurl,
|
287 |
+
type : 'POST',
|
288 |
+
data : {
|
289 |
+
action : 'astra-sites-reset-site-options'
|
290 |
+
},
|
291 |
+
beforeSend: function() {
|
292 |
+
AstraSitesAdmin._log( 'Reseting Site Options' );
|
293 |
+
$('.button-hero.astra-demo-import').text( 'Reseting Site Options' );
|
294 |
+
},
|
295 |
+
})
|
296 |
+
.fail(function( jqXHR ){
|
297 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
298 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
299 |
+
})
|
300 |
+
.done(function ( data ) {
|
301 |
+
|
302 |
+
|
303 |
+
$(document).trigger( 'astra-sites-reset-site-options-done' );
|
304 |
+
});
|
305 |
+
},
|
306 |
+
|
307 |
+
_reset_widgets_data: function() {
|
308 |
+
// Widgets.
|
309 |
+
$.ajax({
|
310 |
+
url : astraSitesAdmin.ajaxurl,
|
311 |
+
type : 'POST',
|
312 |
+
data : {
|
313 |
+
action : 'astra-sites-reset-widgets-data'
|
314 |
+
},
|
315 |
+
beforeSend: function() {
|
316 |
+
AstraSitesAdmin._log( 'Reseting Widgets' );
|
317 |
+
$('.button-hero.astra-demo-import').text( 'Reseting Widgets' );
|
318 |
+
},
|
319 |
+
})
|
320 |
+
.fail(function( jqXHR ){
|
321 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
322 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
323 |
+
})
|
324 |
+
.done(function ( data ) {
|
325 |
+
AstraSitesAdmin._log( data );
|
326 |
+
$(document).trigger( 'astra-sites-reset-widgets-data-done' );
|
327 |
+
});
|
328 |
+
},
|
329 |
+
|
330 |
+
_reset_posts: function() {
|
331 |
+
if( AstraSitesAdmin.site_imported_data['reset_posts'].length ) {
|
332 |
+
|
333 |
+
AstraSitesAdmin.reset_remaining_posts = AstraSitesAdmin.site_imported_data['reset_posts'].length;
|
334 |
+
|
335 |
+
// Delete all posts.
|
336 |
+
// AstraSitesAjaxQueue.stop();
|
337 |
+
// AstraSitesAjaxQueue.run();
|
338 |
+
|
339 |
+
$.each( AstraSitesAdmin.site_imported_data['reset_posts'], function(index, post_id) {
|
340 |
+
AstraSitesAjaxQueue.add({
|
341 |
+
url: astraSitesAdmin.ajaxurl,
|
342 |
+
type: 'POST',
|
343 |
+
data: {
|
344 |
+
action : 'astra-sites-delete-posts',
|
345 |
+
post_id : post_id,
|
346 |
+
},
|
347 |
+
success: function( result ){
|
348 |
+
|
349 |
+
if( AstraSitesAdmin.reset_processed_posts < AstraSitesAdmin.site_imported_data['reset_posts'].length ) {
|
350 |
+
AstraSitesAdmin.reset_processed_posts+=1;
|
351 |
+
}
|
352 |
+
|
353 |
+
$('.button-hero.astra-demo-import').text( 'Deleting Item ' + AstraSitesAdmin.reset_processed_posts + ' of ' + AstraSitesAdmin.site_imported_data['reset_posts'].length );
|
354 |
+
AstraSitesAdmin.reset_remaining_posts-=1;
|
355 |
+
if( 0 == AstraSitesAdmin.reset_remaining_posts ) {
|
356 |
+
$(document).trigger( 'astra-sites-delete-posts-done' );
|
357 |
+
$(document).trigger( 'astra-sites-reset-data-done' );
|
358 |
+
}
|
359 |
+
}
|
360 |
+
});
|
361 |
+
});
|
362 |
+
AstraSitesAjaxQueue.run();
|
363 |
+
|
364 |
+
} else {
|
365 |
+
$(document).trigger( 'astra-sites-delete-posts-done' );
|
366 |
+
$(document).trigger( 'astra-sites-reset-data-done' );
|
367 |
+
}
|
368 |
+
},
|
369 |
+
|
370 |
+
_reset_wp_forms: function() {
|
371 |
+
|
372 |
+
AstraSitesAdmin._log( AstraSitesAdmin.site_imported_data['reset_wp_forms'] );
|
373 |
+
AstraSitesAdmin._log( AstraSitesAdmin.site_imported_data['reset_wp_forms'].length );
|
374 |
+
|
375 |
+
if( AstraSitesAdmin.site_imported_data['reset_wp_forms'].length ) {
|
376 |
+
AstraSitesAdmin.reset_remaining_wp_forms = AstraSitesAdmin.site_imported_data['reset_wp_forms'].length;
|
377 |
+
|
378 |
+
$.each( AstraSitesAdmin.site_imported_data['reset_wp_forms'], function(index, post_id) {
|
379 |
+
AstraSitesAdmin._log( 'WP Form ID: ' + post_id );
|
380 |
+
AstraSitesAjaxQueue.add({
|
381 |
+
url: astraSitesAdmin.ajaxurl,
|
382 |
+
type: 'POST',
|
383 |
+
data: {
|
384 |
+
action : 'astra-sites-delete-wp-forms',
|
385 |
+
post_id : post_id,
|
386 |
+
},
|
387 |
+
success: function( result ){
|
388 |
+
AstraSitesAdmin._log( 'WP Forms Results' );
|
389 |
+
AstraSitesAdmin._log( result );
|
390 |
+
if( AstraSitesAdmin.reset_processed_wp_forms < AstraSitesAdmin.site_imported_data['reset_wp_forms'].length ) {
|
391 |
+
AstraSitesAdmin.reset_processed_wp_forms+=1;
|
392 |
+
}
|
393 |
+
|
394 |
+
$('.button-hero.astra-demo-import').text( 'Deleting Form ' + AstraSitesAdmin.reset_processed_wp_forms + ' of ' + AstraSitesAdmin.site_imported_data['reset_wp_forms'].length );
|
395 |
+
AstraSitesAdmin.reset_remaining_wp_forms-=1;
|
396 |
+
if( 0 == AstraSitesAdmin.reset_remaining_wp_forms ) {
|
397 |
+
$(document).trigger( 'astra-sites-delete-wp-forms-done' );
|
398 |
+
}
|
399 |
+
}
|
400 |
+
});
|
401 |
+
});
|
402 |
+
AstraSitesAjaxQueue.run();
|
403 |
+
|
404 |
+
} else {
|
405 |
+
$(document).trigger( 'astra-sites-delete-wp-forms-done' );
|
406 |
+
}
|
407 |
+
},
|
408 |
+
|
409 |
+
|
410 |
+
_reset_terms: function() {
|
411 |
+
|
412 |
+
AstraSitesAdmin._log( AstraSitesAdmin.site_imported_data['reset_terms'] );
|
413 |
+
AstraSitesAdmin._log( AstraSitesAdmin.site_imported_data['reset_terms'].length );
|
414 |
+
|
415 |
+
if( AstraSitesAdmin.site_imported_data['reset_terms'].length ) {
|
416 |
+
AstraSitesAdmin.reset_remaining_terms = AstraSitesAdmin.site_imported_data['reset_terms'].length;
|
417 |
+
|
418 |
+
$.each( AstraSitesAdmin.site_imported_data['reset_terms'], function(index, term_id) {
|
419 |
+
AstraSitesAjaxQueue.add({
|
420 |
+
url: astraSitesAdmin.ajaxurl,
|
421 |
+
type: 'POST',
|
422 |
+
data: {
|
423 |
+
action : 'astra-sites-delete-terms',
|
424 |
+
term_id : term_id,
|
425 |
+
},
|
426 |
+
success: function( result ){
|
427 |
+
if( AstraSitesAdmin.reset_processed_terms < AstraSitesAdmin.site_imported_data['reset_terms'].length ) {
|
428 |
+
AstraSitesAdmin.reset_processed_terms+=1;
|
429 |
+
}
|
430 |
+
AstraSitesAdmin._log( result );
|
431 |
+
$('.button-hero.astra-demo-import').text( 'Deleting Term ' + AstraSitesAdmin.reset_processed_terms + ' of ' + AstraSitesAdmin.site_imported_data['reset_terms'].length );
|
432 |
+
AstraSitesAdmin.reset_remaining_terms-=1;
|
433 |
+
AstraSitesAdmin._log( AstraSitesAdmin.reset_remaining_terms );
|
434 |
+
if( 0 == AstraSitesAdmin.reset_remaining_terms ) {
|
435 |
+
$(document).trigger( 'astra-sites-delete-terms-done' );
|
436 |
+
}
|
437 |
+
}
|
438 |
+
});
|
439 |
+
});
|
440 |
+
AstraSitesAjaxQueue.run();
|
441 |
+
|
442 |
+
} else {
|
443 |
+
$(document).trigger( 'astra-sites-delete-terms-done' );
|
444 |
+
}
|
445 |
+
|
446 |
+
},
|
447 |
+
|
448 |
+
_toggle_reset_notice: function() {
|
449 |
+
if ( $( this ).is(':checked') ) {
|
450 |
+
$('#astra-sites-tooltip-reset-data').show();
|
451 |
+
} else {
|
452 |
+
$('#astra-sites-tooltip-reset-data').hide();
|
453 |
+
}
|
454 |
+
},
|
455 |
+
|
456 |
+
_backup_before_rest_options: function() {
|
457 |
+
AstraSitesAdmin._backupOptions( 'astra-sites-backup-settings-before-reset-done' );
|
458 |
+
AstraSitesAdmin.backup_taken = true;
|
459 |
+
},
|
460 |
+
|
461 |
+
_recheck_backup_options: function() {
|
462 |
+
AstraSitesAdmin._backupOptions( 'astra-sites-backup-settings-done' );
|
463 |
+
AstraSitesAdmin.backup_taken = true;
|
464 |
+
},
|
465 |
+
|
466 |
+
_backupOptions: function( trigger_name ) {
|
467 |
+
$.ajax({
|
468 |
+
url : astraSitesAdmin.ajaxurl,
|
469 |
+
type : 'POST',
|
470 |
+
data : {
|
471 |
+
action : 'astra-sites-backup-settings',
|
472 |
+
},
|
473 |
+
beforeSend: function() {
|
474 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importWPForms );
|
475 |
+
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.backupCustomizer );
|
476 |
+
},
|
477 |
+
})
|
478 |
+
.fail(function( jqXHR ){
|
479 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText );
|
480 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
481 |
+
})
|
482 |
+
.done(function ( data ) {
|
483 |
+
|
484 |
+
// 1. Pass - Import Customizer Options.
|
485 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.backupCustomizerSuccess );
|
486 |
+
|
487 |
+
// Custom trigger.
|
488 |
+
$(document).trigger( trigger_name );
|
489 |
+
});
|
490 |
+
},
|
491 |
+
|
492 |
+
_import_settings: function( event ) {
|
493 |
+
event.preventDefault();
|
494 |
+
|
495 |
+
var btn = $(this);
|
496 |
+
|
497 |
+
btn.addClass('updating-message');
|
498 |
+
|
499 |
+
|
500 |
+
$.ajax({
|
501 |
+
url : astraSitesAdmin.ajaxurl,
|
502 |
+
type : 'POST',
|
503 |
+
dataType: 'json',
|
504 |
+
data : {
|
505 |
+
action : 'astra-sites-import-customizer-settings',
|
506 |
+
customizer_data : AstraSitesAdmin.current_site['astra-site-customizer-data'],
|
507 |
+
},
|
508 |
+
beforeSend: function() {
|
509 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importCustomizer );
|
510 |
+
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingCustomizer );
|
511 |
+
},
|
512 |
+
})
|
513 |
+
.fail(function( jqXHR ){
|
514 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
515 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
516 |
+
})
|
517 |
+
.done(function ( customizer_data ) {
|
518 |
+
|
519 |
+
btn.removeClass( 'updating-message' );
|
520 |
+
|
521 |
+
// 1. Fail - Import Customizer Options.
|
522 |
+
if( false === customizer_data.success ) {
|
523 |
+
AstraSitesAdmin._importFailMessage( customizer_data.data );
|
524 |
+
AstraSitesAdmin._log( customizer_data.data );
|
525 |
+
} else {
|
526 |
+
|
527 |
+
// 1. Pass - Import Customizer Options.
|
528 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importCustomizerSuccess );
|
529 |
+
|
530 |
+
$(document).trigger( 'astra-sites-import-customizer-settings-done' );
|
531 |
+
}
|
532 |
+
});
|
533 |
+
},
|
534 |
+
|
535 |
+
/**
|
536 |
+
* 5. Import Complete.
|
537 |
+
*/
|
538 |
+
_importEnd: function( event ) {
|
539 |
+
|
540 |
+
$.ajax({
|
541 |
+
url : astraSitesAdmin.ajaxurl,
|
542 |
+
type : 'POST',
|
543 |
+
dataType: 'json',
|
544 |
+
data : {
|
545 |
+
action : 'astra-sites-import-end',
|
546 |
+
},
|
547 |
+
beforeSend: function() {
|
548 |
+
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importComplete );
|
549 |
+
}
|
550 |
+
})
|
551 |
+
.fail(function( jqXHR ){
|
552 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
553 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
554 |
+
})
|
555 |
+
.done(function ( data ) {
|
556 |
+
|
557 |
+
// 5. Fail - Import Complete.
|
558 |
+
if( false === data.success ) {
|
559 |
+
AstraSitesAdmin._importFailMessage( data.data );
|
560 |
+
AstraSitesAdmin._log( data.data );
|
561 |
+
} else {
|
562 |
+
|
563 |
+
$('body').removeClass('importing-site');
|
564 |
+
$('.previous-theme, .next-theme').removeClass('disabled');
|
565 |
+
|
566 |
+
// 5. Pass - Import Complete.
|
567 |
+
AstraSitesAdmin._importSuccessMessage();
|
568 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.success + ' ' + astraSitesAdmin.siteURL );
|
569 |
+
}
|
570 |
+
});
|
571 |
+
},
|
572 |
+
|
573 |
+
/**
|
574 |
+
* 4. Import Widgets.
|
575 |
+
*/
|
576 |
+
_importWidgets: function( event ) {
|
577 |
+
if ( AstraSitesAdmin._is_process_widgets() ) {
|
578 |
+
$.ajax({
|
579 |
+
url : astraSitesAdmin.ajaxurl,
|
580 |
+
type : 'POST',
|
581 |
+
dataType: 'json',
|
582 |
+
data : {
|
583 |
+
action : 'astra-sites-import-widgets',
|
584 |
+
widgets_data : AstraSitesAdmin.widgets_data,
|
585 |
+
},
|
586 |
+
beforeSend: function() {
|
587 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importWidgets );
|
588 |
+
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingWidgets );
|
589 |
+
},
|
590 |
+
})
|
591 |
+
.fail(function( jqXHR ){
|
592 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText );
|
593 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
594 |
+
})
|
595 |
+
.done(function ( widgets_data ) {
|
596 |
+
|
597 |
+
// 4. Fail - Import Widgets.
|
598 |
+
if( false === widgets_data.success ) {
|
599 |
+
AstraSitesAdmin._importFailMessage( widgets_data.data );
|
600 |
+
AstraSitesAdmin._log( widgets_data.data );
|
601 |
+
|
602 |
+
} else {
|
603 |
+
|
604 |
+
// 4. Pass - Import Widgets.
|
605 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importWidgetsSuccess );
|
606 |
+
$(document).trigger( 'astra-sites-import-widgets-done' );
|
607 |
+
}
|
608 |
+
});
|
609 |
+
} else {
|
610 |
+
$(document).trigger( 'astra-sites-import-widgets-done' );
|
611 |
+
}
|
612 |
+
},
|
613 |
+
|
614 |
+
/**
|
615 |
+
* 3. Import Site Options.
|
616 |
+
*/
|
617 |
+
_importSiteOptions: function( event ) {
|
618 |
+
|
619 |
+
if ( AstraSitesAdmin._is_process_xml() ) {
|
620 |
+
$.ajax({
|
621 |
+
url : astraSitesAdmin.ajaxurl,
|
622 |
+
type : 'POST',
|
623 |
+
dataType: 'json',
|
624 |
+
data : {
|
625 |
+
action : 'astra-sites-import-options',
|
626 |
+
options_data : AstraSitesAdmin.options_data,
|
627 |
+
},
|
628 |
+
beforeSend: function() {
|
629 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importOptions );
|
630 |
+
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingOptions );
|
631 |
+
$('.astra-demo-import .percent').html('');
|
632 |
+
},
|
633 |
+
})
|
634 |
+
.fail(function( jqXHR ){
|
635 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText );
|
636 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
637 |
+
})
|
638 |
+
.done(function ( options_data ) {
|
639 |
+
|
640 |
+
// 3. Fail - Import Site Options.
|
641 |
+
if( false === options_data.success ) {
|
642 |
+
AstraSitesAdmin._log( options_data );
|
643 |
+
AstraSitesAdmin._importFailMessage( options_data.data );
|
644 |
+
AstraSitesAdmin._log( options_data.data );
|
645 |
+
|
646 |
+
} else {
|
647 |
+
|
648 |
+
// 3. Pass - Import Site Options.
|
649 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importOptionsSuccess );
|
650 |
+
$(document).trigger( 'astra-sites-import-options-done' );
|
651 |
+
}
|
652 |
+
});
|
653 |
+
} else {
|
654 |
+
$(document).trigger( 'astra-sites-import-options-done' );
|
655 |
+
}
|
656 |
+
},
|
657 |
+
|
658 |
+
/**
|
659 |
+
* 2. Prepare XML Data.
|
660 |
+
*/
|
661 |
+
_importXML: function() {
|
662 |
+
|
663 |
+
if ( AstraSitesAdmin._is_process_xml() ) {
|
664 |
+
$.ajax({
|
665 |
+
url : astraSitesAdmin.ajaxurl,
|
666 |
+
type : 'POST',
|
667 |
+
dataType: 'json',
|
668 |
+
data : {
|
669 |
+
action : 'astra-sites-import-prepare-xml',
|
670 |
+
wxr_url : AstraSitesAdmin.current_site['astra-site-wxr-path'],
|
671 |
+
},
|
672 |
+
beforeSend: function() {
|
673 |
+
$('#astra-site-import-process-wrap').show();
|
674 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importXMLPrepare );
|
675 |
+
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importXMLPreparing );
|
676 |
+
},
|
677 |
+
})
|
678 |
+
.fail(function( jqXHR ){
|
679 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText );
|
680 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
681 |
+
})
|
682 |
+
.done(function ( xml_data ) {
|
683 |
+
|
684 |
+
|
685 |
+
// 2. Fail - Prepare XML Data.
|
686 |
+
if( false === xml_data.success ) {
|
687 |
+
AstraSitesAdmin._log( xml_data );
|
688 |
+
var error_msg = xml_data.data.error || xml_data.data;
|
689 |
+
AstraSitesAdmin._importFailMessage( error_msg );
|
690 |
+
AstraSitesAdmin._log( error_msg );
|
691 |
+
|
692 |
+
} else {
|
693 |
+
|
694 |
+
// 2. Pass - Prepare XML Data.
|
695 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importXMLPrepareSuccess );
|
696 |
+
|
697 |
+
// Import XML though Event Source.
|
698 |
+
AstraSSEImport.data = xml_data.data;
|
699 |
+
AstraSSEImport.render();
|
700 |
+
|
701 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importXML );
|
702 |
+
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingXML );
|
703 |
+
|
704 |
+
var evtSource = new EventSource( AstraSSEImport.data.url );
|
705 |
+
evtSource.onmessage = function ( message ) {
|
706 |
+
var data = JSON.parse( message.data );
|
707 |
+
switch ( data.action ) {
|
708 |
+
case 'updateDelta':
|
709 |
+
AstraSSEImport.updateDelta( data.type, data.delta );
|
710 |
+
break;
|
711 |
+
|
712 |
+
case 'complete':
|
713 |
+
evtSource.close();
|
714 |
+
|
715 |
+
// 2. Pass - Import XML though "Source Event".
|
716 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importXMLSuccess );
|
717 |
+
AstraSitesAdmin._log( '----- SSE - XML import Complete -----' );
|
718 |
+
|
719 |
+
document.getElementById( 'astra-site-import-process' ).value = 100;
|
720 |
+
|
721 |
+
|
722 |
+
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingXML + ' (100%)' );
|
723 |
+
|
724 |
+
$('#astra-site-import-process-wrap').hide();
|
725 |
+
|
726 |
+
$(document).trigger( 'astra-sites-import-xml-done' );
|
727 |
+
|
728 |
+
break;
|
729 |
+
}
|
730 |
+
};
|
731 |
+
evtSource.addEventListener( 'log', function ( message ) {
|
732 |
+
var data = JSON.parse( message.data );
|
733 |
+
AstraSitesAdmin._log( data.level + ' ' + data.message );
|
734 |
+
});
|
735 |
+
}
|
736 |
+
});
|
737 |
+
} else {
|
738 |
+
$(document).trigger( 'astra-sites-import-xml-done' );
|
739 |
+
}
|
740 |
+
|
741 |
+
|
742 |
+
},
|
743 |
+
|
744 |
+
_is_process_xml: function() {
|
745 |
+
if ( $( '.astra-sites-import-xml' ).find('.checkbox').is(':checked') ) {
|
746 |
+
return true;
|
747 |
+
}
|
748 |
+
return false;
|
749 |
+
},
|
750 |
+
|
751 |
+
_is_process_customizer: function() {
|
752 |
+
if ( $( '.astra-sites-import-customizer' ).find('.checkbox').is(':checked') ) {
|
753 |
+
return true;
|
754 |
+
}
|
755 |
+
return false;
|
756 |
+
},
|
757 |
+
|
758 |
+
_is_process_widgets: function() {
|
759 |
+
if ( $( '.astra-sites-import-widgets' ).find('.checkbox').is(':checked') ) {
|
760 |
+
return true;
|
761 |
+
}
|
762 |
+
return false;
|
763 |
+
},
|
764 |
+
|
765 |
+
/**
|
766 |
+
* 1. Import WPForms Options.
|
767 |
+
*/
|
768 |
+
_importWPForms: function( event ) {
|
769 |
+
if ( AstraSitesAdmin._is_process_customizer() ) {
|
770 |
+
$.ajax({
|
771 |
+
url : astraSitesAdmin.ajaxurl,
|
772 |
+
type : 'POST',
|
773 |
+
dataType: 'json',
|
774 |
+
data : {
|
775 |
+
action : 'astra-sites-import-wpforms',
|
776 |
+
wpforms_url : AstraSitesAdmin.wpforms_url,
|
777 |
+
},
|
778 |
+
beforeSend: function() {
|
779 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importWPForms );
|
780 |
+
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingWPForms );
|
781 |
+
},
|
782 |
+
})
|
783 |
+
.fail(function( jqXHR ){
|
784 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText );
|
785 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
786 |
+
})
|
787 |
+
.done(function ( forms ) {
|
788 |
+
|
789 |
+
// 1. Fail - Import WPForms Options.
|
790 |
+
if( false === forms.success ) {
|
791 |
+
AstraSitesAdmin._importFailMessage( forms.data );
|
792 |
+
AstraSitesAdmin._log( forms.data );
|
793 |
+
} else {
|
794 |
+
|
795 |
+
// 1. Pass - Import Customizer Options.
|
796 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importWPFormsSuccess );
|
797 |
+
|
798 |
+
$(document).trigger( 'astra-sites-import-wpforms-done' );
|
799 |
+
}
|
800 |
+
});
|
801 |
+
} else {
|
802 |
+
$(document).trigger( 'astra-sites-import-wpforms-done' );
|
803 |
+
}
|
804 |
+
},
|
805 |
+
|
806 |
+
/**
|
807 |
+
* 1. Import Customizer Options.
|
808 |
+
*/
|
809 |
+
_importCustomizerSettings: function( event ) {
|
810 |
+
if ( AstraSitesAdmin._is_process_customizer() ) {
|
811 |
+
$.ajax({
|
812 |
+
url : astraSitesAdmin.ajaxurl,
|
813 |
+
type : 'POST',
|
814 |
+
dataType: 'json',
|
815 |
+
data : {
|
816 |
+
action : 'astra-sites-import-customizer-settings',
|
817 |
+
customizer_data : AstraSitesAdmin.customizer_data,
|
818 |
+
},
|
819 |
+
beforeSend: function() {
|
820 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importCustomizer );
|
821 |
+
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.importingCustomizer );
|
822 |
+
},
|
823 |
+
})
|
824 |
+
.fail(function( jqXHR ){
|
825 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText );
|
826 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
827 |
+
})
|
828 |
+
.done(function ( customizer_data ) {
|
829 |
+
|
830 |
+
// 1. Fail - Import Customizer Options.
|
831 |
+
if( false === customizer_data.success ) {
|
832 |
+
AstraSitesAdmin._importFailMessage( customizer_data.data );
|
833 |
+
AstraSitesAdmin._log( customizer_data.data );
|
834 |
+
} else {
|
835 |
+
|
836 |
+
// 1. Pass - Import Customizer Options.
|
837 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importCustomizerSuccess );
|
838 |
+
|
839 |
+
$(document).trigger( 'astra-sites-import-customizer-settings-done' );
|
840 |
+
}
|
841 |
+
});
|
842 |
+
} else {
|
843 |
+
$(document).trigger( 'astra-sites-import-customizer-settings-done' );
|
844 |
+
}
|
845 |
+
|
846 |
+
},
|
847 |
+
|
848 |
+
/**
|
849 |
+
* Import Success Button.
|
850 |
+
*
|
851 |
+
* @param {string} data Error message.
|
852 |
+
*/
|
853 |
+
_importSuccessMessage: function() {
|
854 |
+
|
855 |
+
$('.astra-demo-import').removeClass('updating-message installing')
|
856 |
+
.removeAttr('data-import')
|
857 |
+
.addClass('view-site')
|
858 |
+
.removeClass('astra-demo-import')
|
859 |
+
.text( astraSitesAdmin.strings.viewSite )
|
860 |
+
.attr('target', '_blank')
|
861 |
+
.append('<i class="dashicons dashicons-external"></i>')
|
862 |
+
.attr('href', astraSitesAdmin.siteURL );
|
863 |
+
},
|
864 |
+
|
865 |
+
/**
|
866 |
+
* Preview Device
|
867 |
+
*/
|
868 |
+
_previewDevice: function( event ) {
|
869 |
+
var device = $( event.currentTarget ).data( 'device' );
|
870 |
+
|
871 |
+
$('.theme-install-overlay')
|
872 |
+
.removeClass( 'preview-desktop preview-tablet preview-mobile' )
|
873 |
+
.addClass( 'preview-' + device )
|
874 |
+
.data( 'current-preview-device', device );
|
875 |
+
|
876 |
+
AstraSitesAdmin._tooglePreviewDeviceButtons( device );
|
877 |
+
},
|
878 |
+
|
879 |
+
/**
|
880 |
+
* Toggle Preview Buttons
|
881 |
+
*/
|
882 |
+
_tooglePreviewDeviceButtons: function( newDevice ) {
|
883 |
+
var $devices = $( '.wp-full-overlay-footer .devices' );
|
884 |
+
|
885 |
+
$devices.find( 'button' )
|
886 |
+
.removeClass( 'active' )
|
887 |
+
.attr( 'aria-pressed', false );
|
888 |
+
|
889 |
+
$devices.find( 'button.preview-' + newDevice )
|
890 |
+
.addClass( 'active' )
|
891 |
+
.attr( 'aria-pressed', true );
|
892 |
+
},
|
893 |
+
|
894 |
+
/**
|
895 |
+
* Import Error Button.
|
896 |
+
*
|
897 |
+
* @param {string} data Error message.
|
898 |
+
*/
|
899 |
+
_importFailMessage: function( message, from ) {
|
900 |
+
|
901 |
+
$('.astra-demo-import')
|
902 |
+
.addClass('go-pro button-primary')
|
903 |
+
.removeClass('updating-message installing')
|
904 |
+
.removeAttr('data-import')
|
905 |
+
.attr('target', '_blank')
|
906 |
+
.append('<i class="dashicons dashicons-external"></i>')
|
907 |
+
.removeClass('astra-demo-import');
|
908 |
+
|
909 |
+
// Add the doc link due to import log file not generated.
|
910 |
+
if( 'undefined' === from ) {
|
911 |
+
|
912 |
+
$('.wp-full-overlay-header .go-pro').text( astraSitesAdmin.strings.importFailedBtnSmall );
|
913 |
+
$('.wp-full-overlay-footer .go-pro').text( astraSitesAdmin.strings.importFailedBtnLarge );
|
914 |
+
$('.go-pro').attr('href', astraSitesAdmin.log.serverConfiguration );
|
915 |
+
|
916 |
+
// Add the import log file link.
|
917 |
+
} else {
|
918 |
+
|
919 |
+
$('.wp-full-overlay-header .go-pro').text( astraSitesAdmin.strings.importFailBtn );
|
920 |
+
$('.wp-full-overlay-footer .go-pro').text( astraSitesAdmin.strings.importFailBtnLarge )
|
921 |
+
|
922 |
+
// Add the import log file link.
|
923 |
+
if( 'undefined' !== AstraSitesAdmin.log_file_url ) {
|
924 |
+
$('.go-pro').attr('href', AstraSitesAdmin.log_file_url );
|
925 |
+
} else {
|
926 |
+
$('.go-pro').attr('href', astraSitesAdmin.log.serverConfiguration );
|
927 |
+
}
|
928 |
+
}
|
929 |
+
|
930 |
+
var output = '<div class="astra-api-error notice notice-error notice-alt is-dismissible">';
|
931 |
+
output += ' <p>'+message+'</p>';
|
932 |
+
output += ' <button type="button" class="notice-dismiss">';
|
933 |
+
output += ' <span class="screen-reader-text">'+commonL10n.dismiss+'</span>';
|
934 |
+
output += ' </button>';
|
935 |
+
output += '</div>';
|
936 |
+
|
937 |
+
// Fail Notice.
|
938 |
+
$('.install-theme-info').append( output );
|
939 |
+
|
940 |
+
|
941 |
+
// !important to add trigger.
|
942 |
+
// Which reinitialize the dismiss error message events.
|
943 |
+
$(document).trigger('wp-updates-notice-added');
|
944 |
+
},
|
945 |
+
|
946 |
+
|
947 |
+
/**
|
948 |
+
* Install Now
|
949 |
+
*/
|
950 |
+
_installNow: function(event)
|
951 |
+
{
|
952 |
+
event.preventDefault();
|
953 |
+
|
954 |
+
var $button = jQuery( event.target ),
|
955 |
+
$document = jQuery(document);
|
956 |
+
|
957 |
+
if ( $button.hasClass( 'updating-message' ) || $button.hasClass( 'button-disabled' ) ) {
|
958 |
+
return;
|
959 |
+
}
|
960 |
+
|
961 |
+
if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.ajaxLocked ) {
|
962 |
+
wp.updates.requestFilesystemCredentials( event );
|
963 |
+
|
964 |
+
$document.on( 'credential-modal-cancel', function() {
|
965 |
+
var $message = $( '.install-now.updating-message' );
|
966 |
+
|
967 |
+
$message
|
968 |
+
.removeClass( 'updating-message' )
|
969 |
+
.text( wp.updates.l10n.installNow );
|
970 |
+
|
971 |
+
wp.a11y.speak( wp.updates.l10n.updateCancel, 'polite' );
|
972 |
+
} );
|
973 |
+
}
|
974 |
+
|
975 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.installingPlugin + ' ' + $button.data( 'slug' ) );
|
976 |
+
|
977 |
+
wp.updates.installPlugin( {
|
978 |
+
slug: $button.data( 'slug' )
|
979 |
+
} );
|
980 |
+
},
|
981 |
+
|
982 |
+
/**
|
983 |
+
* Install Success
|
984 |
+
*/
|
985 |
+
_installSuccess: function( event, response ) {
|
986 |
+
|
987 |
+
event.preventDefault();
|
988 |
+
|
989 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.installed + ' ' + response.slug );
|
990 |
+
|
991 |
+
var $siteOptions = $( '.wp-full-overlay-header').find('.astra-site-options').val();
|
992 |
+
var $enabledExtensions = $( '.wp-full-overlay-header').find('.astra-enabled-extensions').val();
|
993 |
+
|
994 |
+
// Transform the 'Install' button into an 'Activate' button.
|
995 |
+
var $init = $( '.plugin-card-' + response.slug ).data('init');
|
996 |
+
|
997 |
+
// Reset not installed plugins list.
|
998 |
+
var pluginsList = astraSitesAdmin.requiredPlugins.notinstalled;
|
999 |
+
astraSitesAdmin.requiredPlugins.notinstalled = AstraSitesAdmin._removePluginFromQueue( response.slug, pluginsList );
|
1000 |
+
|
1001 |
+
// WordPress adds "Activate" button after waiting for 1000ms. So we will run our activation after that.
|
1002 |
+
setTimeout( function() {
|
1003 |
+
|
1004 |
+
$.ajax({
|
1005 |
+
url: astraSitesAdmin.ajaxurl,
|
1006 |
+
type: 'POST',
|
1007 |
+
data: {
|
1008 |
+
'action' : 'astra-required-plugin-activate',
|
1009 |
+
'init' : $init,
|
1010 |
+
'options' : $siteOptions,
|
1011 |
+
'enabledExtensions' : $enabledExtensions,
|
1012 |
+
},
|
1013 |
+
})
|
1014 |
+
.done(function (result) {
|
1015 |
+
|
1016 |
+
if( result.success ) {
|
1017 |
+
|
1018 |
+
var pluginsList = astraSitesAdmin.requiredPlugins.inactive;
|
1019 |
+
|
1020 |
+
// Reset not installed plugins list.
|
1021 |
+
astraSitesAdmin.requiredPlugins.inactive = AstraSitesAdmin._removePluginFromQueue( response.slug, pluginsList );
|
1022 |
+
|
1023 |
+
// Enable Demo Import Button
|
1024 |
+
AstraSitesAdmin._enable_demo_import_button();
|
1025 |
+
|
1026 |
+
}
|
1027 |
+
});
|
1028 |
+
|
1029 |
+
}, 1200 );
|
1030 |
+
|
1031 |
+
},
|
1032 |
+
|
1033 |
+
/**
|
1034 |
+
* Plugin Installation Error.
|
1035 |
+
*/
|
1036 |
+
_installError: function( event, response ) {
|
1037 |
+
|
1038 |
+
var $card = $( '.plugin-card-' + response.slug );
|
1039 |
+
|
1040 |
+
AstraSitesAdmin._log( response.errorMessage + ' ' + response.slug );
|
1041 |
+
|
1042 |
+
$card
|
1043 |
+
.removeClass( 'button-primary' )
|
1044 |
+
.addClass( 'disabled' )
|
1045 |
+
.html( wp.updates.l10n.installFailedShort );
|
1046 |
+
|
1047 |
+
AstraSitesAdmin._importFailMessage( response.errorMessage );
|
1048 |
+
},
|
1049 |
+
|
1050 |
+
/**
|
1051 |
+
* Installing Plugin
|
1052 |
+
*/
|
1053 |
+
_pluginInstalling: function(event, args) {
|
1054 |
+
event.preventDefault();
|
1055 |
+
|
1056 |
+
var $card = $( '.plugin-card-' + args.slug );
|
1057 |
+
|
1058 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.installingPlugin + ' ' + args.slug );
|
1059 |
+
|
1060 |
+
$card.addClass('updating-message');
|
1061 |
+
|
1062 |
+
},
|
1063 |
+
|
1064 |
+
/**
|
1065 |
+
* Render Demo Preview
|
1066 |
+
*/
|
1067 |
+
_activateNow: function( eventn ) {
|
1068 |
+
|
1069 |
+
event.preventDefault();
|
1070 |
+
|
1071 |
+
var $button = jQuery( event.target ),
|
1072 |
+
$init = $button.data( 'init' ),
|
1073 |
+
$slug = $button.data( 'slug' );
|
1074 |
+
|
1075 |
+
if ( $button.hasClass( 'updating-message' ) || $button.hasClass( 'button-disabled' ) ) {
|
1076 |
+
return;
|
1077 |
+
}
|
1078 |
+
|
1079 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.activating + ' ' + $slug );
|
1080 |
+
|
1081 |
+
$button.addClass('updating-message button-primary')
|
1082 |
+
.html( astraSitesAdmin.strings.btnActivating );
|
1083 |
+
|
1084 |
+
var $siteOptions = jQuery( '.wp-full-overlay-header').find('.astra-site-options').val();
|
1085 |
+
var $enabledExtensions = jQuery( '.wp-full-overlay-header').find('.astra-enabled-extensions').val();
|
1086 |
+
|
1087 |
+
$.ajax({
|
1088 |
+
url: astraSitesAdmin.ajaxurl,
|
1089 |
+
type: 'POST',
|
1090 |
+
data: {
|
1091 |
+
'action' : 'astra-required-plugin-activate',
|
1092 |
+
'init' : $init,
|
1093 |
+
'options' : $siteOptions,
|
1094 |
+
'enabledExtensions' : $enabledExtensions,
|
1095 |
+
},
|
1096 |
+
})
|
1097 |
+
.done(function (result) {
|
1098 |
+
|
1099 |
+
if( result.success ) {
|
1100 |
+
|
1101 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.activated + ' ' + $slug );
|
1102 |
+
|
1103 |
+
var pluginsList = astraSitesAdmin.requiredPlugins.inactive;
|
1104 |
+
|
1105 |
+
// Reset not installed plugins list.
|
1106 |
+
astraSitesAdmin.requiredPlugins.inactive = AstraSitesAdmin._removePluginFromQueue( $slug, pluginsList );
|
1107 |
+
|
1108 |
+
$button.removeClass( 'button-primary install-now activate-now updating-message' )
|
1109 |
+
.attr('disabled', 'disabled')
|
1110 |
+
.addClass('disabled')
|
1111 |
+
.text( astraSitesAdmin.strings.btnActive );
|
1112 |
+
|
1113 |
+
// Enable Demo Import Button
|
1114 |
+
AstraSitesAdmin._enable_demo_import_button();
|
1115 |
+
|
1116 |
+
}
|
1117 |
+
|
1118 |
+
})
|
1119 |
+
.fail(function () {
|
1120 |
+
});
|
1121 |
+
|
1122 |
+
},
|
1123 |
+
|
1124 |
+
/**
|
1125 |
+
* Full Overlay
|
1126 |
+
*/
|
1127 |
+
_fullOverlay: function (event) {
|
1128 |
+
event.preventDefault();
|
1129 |
+
|
1130 |
+
// Import process is started?
|
1131 |
+
// And Closing the window? Then showing the warning confirm message.
|
1132 |
+
if( $('body').hasClass('importing-site') && ! confirm( astraSitesAdmin.strings.warningBeforeCloseWindow ) ) {
|
1133 |
+
return;
|
1134 |
+
}
|
1135 |
+
|
1136 |
+
$('body').removeClass('importing-site');
|
1137 |
+
$('.previous-theme, .next-theme').removeClass('disabled');
|
1138 |
+
$('.theme-install-overlay').css('display', 'none');
|
1139 |
+
$('.theme-install-overlay').remove();
|
1140 |
+
$('.theme-preview-on').removeClass('theme-preview-on');
|
1141 |
+
$('html').removeClass('astra-site-preview-on');
|
1142 |
+
},
|
1143 |
+
|
1144 |
+
/**
|
1145 |
+
* Bulk Plugin Active & Install
|
1146 |
+
*/
|
1147 |
+
_bulkPluginInstallActivate: function()
|
1148 |
+
{
|
1149 |
+
if( 0 === astraSitesAdmin.requiredPlugins.length ) {
|
1150 |
+
return;
|
1151 |
+
}
|
1152 |
+
|
1153 |
+
var not_installed = astraSitesAdmin.requiredPlugins.notinstalled || '';
|
1154 |
+
var activate_plugins = astraSitesAdmin.requiredPlugins.inactive || '';
|
1155 |
+
|
1156 |
+
// First Install Bulk.
|
1157 |
+
if( not_installed.length > 0 ) {
|
1158 |
+
AstraSitesAdmin._installAllPlugins( not_installed );
|
1159 |
+
}
|
1160 |
+
|
1161 |
+
// Second Activate Bulk.
|
1162 |
+
if( activate_plugins.length > 0 ) {
|
1163 |
+
AstraSitesAdmin._activateAllPlugins( activate_plugins );
|
1164 |
+
}
|
1165 |
+
|
1166 |
+
if( activate_plugins.length <= 0 && not_installed.length <= 0 ) {
|
1167 |
+
AstraSitesAdmin._enable_demo_import_button();
|
1168 |
+
}
|
1169 |
+
|
1170 |
+
},
|
1171 |
+
|
1172 |
+
/**
|
1173 |
+
* Activate All Plugins.
|
1174 |
+
*/
|
1175 |
+
_activateAllPlugins: function( activate_plugins ) {
|
1176 |
+
|
1177 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.bulkActivation );
|
1178 |
+
|
1179 |
+
$.each( activate_plugins, function(index, single_plugin) {
|
1180 |
+
|
1181 |
+
var $card = $( '.plugin-card-' + single_plugin.slug ),
|
1182 |
+
$siteOptions = $( '.wp-full-overlay-header').find('.astra-site-options').val(),
|
1183 |
+
$enabledExtensions = $( '.wp-full-overlay-header').find('.astra-enabled-extensions').val();
|
1184 |
+
|
1185 |
+
AstraSitesAjaxQueue.add({
|
1186 |
+
url: astraSitesAdmin.ajaxurl,
|
1187 |
+
type: 'POST',
|
1188 |
+
data: {
|
1189 |
+
'action' : 'astra-required-plugin-activate',
|
1190 |
+
'init' : single_plugin.init,
|
1191 |
+
'options' : $siteOptions,
|
1192 |
+
'enabledExtensions' : $enabledExtensions,
|
1193 |
+
},
|
1194 |
+
success: function( result ){
|
1195 |
+
|
1196 |
+
if( result.success ) {
|
1197 |
+
|
1198 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.activate + ' ' + single_plugin.slug );
|
1199 |
+
|
1200 |
+
var pluginsList = astraSitesAdmin.requiredPlugins.inactive;
|
1201 |
+
|
1202 |
+
// Reset not installed plugins list.
|
1203 |
+
astraSitesAdmin.requiredPlugins.inactive = AstraSitesAdmin._removePluginFromQueue( single_plugin.slug, pluginsList );
|
1204 |
+
|
1205 |
+
// Enable Demo Import Button
|
1206 |
+
AstraSitesAdmin._enable_demo_import_button();
|
1207 |
+
} else {
|
1208 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.activationError + ' - ' + single_plugin.slug );
|
1209 |
+
}
|
1210 |
+
}
|
1211 |
+
});
|
1212 |
+
});
|
1213 |
+
AstraSitesAjaxQueue.run();
|
1214 |
+
},
|
1215 |
+
|
1216 |
+
/**
|
1217 |
+
* Install All Plugins.
|
1218 |
+
*/
|
1219 |
+
_installAllPlugins: function( not_installed ) {
|
1220 |
+
|
1221 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.bulkInstall );
|
1222 |
+
|
1223 |
+
$.each( not_installed, function(index, single_plugin) {
|
1224 |
+
|
1225 |
+
var $card = $( '.plugin-card-' + single_plugin.slug );
|
1226 |
+
|
1227 |
+
// Add each plugin activate request in Ajax queue.
|
1228 |
+
// @see wp-admin/js/updates.js
|
1229 |
+
wp.updates.queue.push( {
|
1230 |
+
action: 'install-plugin', // Required action.
|
1231 |
+
data: {
|
1232 |
+
slug: single_plugin.slug
|
1233 |
+
}
|
1234 |
+
} );
|
1235 |
+
});
|
1236 |
+
|
1237 |
+
// Required to set queue.
|
1238 |
+
wp.updates.queueChecker();
|
1239 |
+
},
|
1240 |
+
|
1241 |
+
/**
|
1242 |
+
* Fires when a nav item is clicked.
|
1243 |
+
*
|
1244 |
+
* @since 1.0
|
1245 |
+
* @access private
|
1246 |
+
* @method _importDemo
|
1247 |
+
*/
|
1248 |
+
_importDemo: function(event) {
|
1249 |
+
event.preventDefault();
|
1250 |
+
|
1251 |
+
var disabled = $(this).attr('data-import');
|
1252 |
+
|
1253 |
+
if ( typeof disabled !== 'undefined' && disabled === 'disabled' || $this.hasClass('disabled') ) {
|
1254 |
+
|
1255 |
+
$('.astra-demo-import').addClass('updating-message installing')
|
1256 |
+
.text( wp.updates.l10n.installing );
|
1257 |
+
|
1258 |
+
/**
|
1259 |
+
* Process Bulk Plugin Install & Activate
|
1260 |
+
*/
|
1261 |
+
AstraSitesAdmin._bulkPluginInstallActivate();
|
1262 |
+
}
|
1263 |
+
},
|
1264 |
+
|
1265 |
+
_process_import() {
|
1266 |
+
|
1267 |
+
var $theme = $('.astra-sites-preview').find('.wp-full-overlay-header'),
|
1268 |
+
apiURL = $theme.data('demo-api') || '';
|
1269 |
+
|
1270 |
+
$('body').addClass('importing-site');
|
1271 |
+
$('.previous-theme, .next-theme').addClass('disabled');
|
1272 |
+
|
1273 |
+
// Remove all notices before import start.
|
1274 |
+
$('.install-theme-info > .notice').remove();
|
1275 |
+
|
1276 |
+
$('.astra-demo-import').attr('data-import', 'disabled')
|
1277 |
+
.addClass('updating-message installing')
|
1278 |
+
.text( astraSitesAdmin.strings.importingDemo );
|
1279 |
+
|
1280 |
+
// Site Import by API URL.
|
1281 |
+
if( apiURL ) {
|
1282 |
+
AstraSitesAdmin._importSite( apiURL );
|
1283 |
+
}
|
1284 |
+
|
1285 |
+
},
|
1286 |
+
|
1287 |
+
/**
|
1288 |
+
* Start Import Process by API URL.
|
1289 |
+
*
|
1290 |
+
* @param {string} apiURL Site API URL.
|
1291 |
+
*/
|
1292 |
+
_importSite: function( apiURL ) {
|
1293 |
+
|
1294 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.api + ' : ' + apiURL );
|
1295 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.importing );
|
1296 |
+
|
1297 |
+
$('.button-hero.astra-demo-import').text( astraSitesAdmin.log.gettingData );
|
1298 |
+
|
1299 |
+
// 1. Request Site Import
|
1300 |
+
$.ajax({
|
1301 |
+
url : astraSitesAdmin.ajaxurl,
|
1302 |
+
type : 'POST',
|
1303 |
+
dataType: 'json',
|
1304 |
+
data : {
|
1305 |
+
'action' : 'astra-sites-import-set-site-data',
|
1306 |
+
'api_url' : apiURL,
|
1307 |
+
},
|
1308 |
+
})
|
1309 |
+
.fail(function( jqXHR ){
|
1310 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
1311 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText + ' ' + jqXHR.statusText );
|
1312 |
+
})
|
1313 |
+
.done(function ( demo_data ) {
|
1314 |
+
|
1315 |
+
// 1. Fail - Request Site Import
|
1316 |
+
if( false === demo_data.success ) {
|
1317 |
+
|
1318 |
+
AstraSitesAdmin._importFailMessage( demo_data.data );
|
1319 |
+
|
1320 |
+
} else {
|
1321 |
+
|
1322 |
+
// Set log file URL.
|
1323 |
+
if( 'log_file' in demo_data.data ){
|
1324 |
+
AstraSitesAdmin.log_file_url = decodeURIComponent( demo_data.data.log_file ) || '';
|
1325 |
+
}
|
1326 |
+
|
1327 |
+
// 1. Pass - Request Site Import
|
1328 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.processingRequest );
|
1329 |
+
|
1330 |
+
AstraSitesAdmin.customizer_data = JSON.stringify( demo_data.data['astra-site-customizer-data'] ) || '';
|
1331 |
+
AstraSitesAdmin.wxr_url = encodeURI( demo_data.data['astra-site-wxr-path'] ) || '';
|
1332 |
+
AstraSitesAdmin.wpforms_url = encodeURI( demo_data.data['astra-site-wpforms-path'] ) || '';
|
1333 |
+
AstraSitesAdmin.options_data = JSON.stringify( demo_data.data['astra-site-options-data'] ) || '';
|
1334 |
+
AstraSitesAdmin.widgets_data = JSON.stringify( demo_data.data['astra-site-widgets-data'] ) || '';
|
1335 |
+
|
1336 |
+
$(document).trigger( 'astra-sites-import-set-site-data-done' );
|
1337 |
+
}
|
1338 |
+
|
1339 |
+
});
|
1340 |
+
|
1341 |
+
},
|
1342 |
+
|
1343 |
+
/**
|
1344 |
+
* Collapse Sidebar.
|
1345 |
+
*/
|
1346 |
+
_collapse: function() {
|
1347 |
+
event.preventDefault();
|
1348 |
+
|
1349 |
+
overlay = jQuery('.wp-full-overlay');
|
1350 |
+
|
1351 |
+
if (overlay.hasClass('expanded')) {
|
1352 |
+
overlay.removeClass('expanded');
|
1353 |
+
overlay.addClass('collapsed');
|
1354 |
+
return;
|
1355 |
+
}
|
1356 |
+
|
1357 |
+
if (overlay.hasClass('collapsed')) {
|
1358 |
+
overlay.removeClass('collapsed');
|
1359 |
+
overlay.addClass('expanded');
|
1360 |
+
return;
|
1361 |
+
}
|
1362 |
+
},
|
1363 |
+
|
1364 |
+
/**
|
1365 |
+
* Previous Theme.
|
1366 |
+
*/
|
1367 |
+
_previousTheme: function (event) {
|
1368 |
+
event.preventDefault();
|
1369 |
+
|
1370 |
+
currentDemo = jQuery('.theme-preview-on');
|
1371 |
+
currentDemo.removeClass('theme-preview-on');
|
1372 |
+
prevDemo = currentDemo.prev('.theme');
|
1373 |
+
prevDemo.addClass('theme-preview-on');
|
1374 |
+
|
1375 |
+
var site_id = $(this).parents('.wp-full-overlay-header').data('demo-id') || '';
|
1376 |
+
|
1377 |
+
if( AstraSitesAPI._stored_data ) {
|
1378 |
+
var site_data = AstraSitesAdmin._get_site_details( site_id );
|
1379 |
+
|
1380 |
+
|
1381 |
+
if( site_data ) {
|
1382 |
+
// Set current site details.
|
1383 |
+
AstraSitesAdmin.current_site = site_data;
|
1384 |
+
}
|
1385 |
+
}
|
1386 |
+
|
1387 |
+
AstraSitesAdmin._renderDemoPreview(prevDemo);
|
1388 |
+
},
|
1389 |
+
|
1390 |
+
/**
|
1391 |
+
* Next Theme.
|
1392 |
+
*/
|
1393 |
+
_nextTheme: function (event) {
|
1394 |
+
event.preventDefault();
|
1395 |
+
currentDemo = jQuery('.theme-preview-on')
|
1396 |
+
currentDemo.removeClass('theme-preview-on');
|
1397 |
+
nextDemo = currentDemo.next('.theme');
|
1398 |
+
nextDemo.addClass('theme-preview-on');
|
1399 |
+
|
1400 |
+
var site_id = $(this).parents('.wp-full-overlay-header').data('demo-id') || '';
|
1401 |
+
|
1402 |
+
if( AstraSitesAPI._stored_data ) {
|
1403 |
+
var site_data = AstraSitesAdmin._get_site_details( site_id );
|
1404 |
+
|
1405 |
+
|
1406 |
+
|
1407 |
+
if( site_data ) {
|
1408 |
+
// Set current site details.
|
1409 |
+
AstraSitesAdmin.current_site = site_data;
|
1410 |
+
}
|
1411 |
+
}
|
1412 |
+
|
1413 |
+
AstraSitesAdmin._renderDemoPreview( nextDemo );
|
1414 |
+
},
|
1415 |
+
|
1416 |
+
_set_current_screen: function( screen ) {
|
1417 |
+
AstraSitesAdmin.current_screen = screen;
|
1418 |
+
var old_screen = $('.astra-sites-preview').attr( 'screen' ) || '';
|
1419 |
+
|
1420 |
+
|
1421 |
+
if( old_screen ) {
|
1422 |
+
$('.astra-sites-preview').removeClass( 'screen-' + old_screen );
|
1423 |
+
}
|
1424 |
+
|
1425 |
+
$('.astra-sites-preview').attr( 'screen', screen );
|
1426 |
+
$('.astra-sites-preview').addClass( 'screen-' + screen );
|
1427 |
+
},
|
1428 |
+
|
1429 |
+
/**
|
1430 |
+
* Individual Site Preview
|
1431 |
+
*
|
1432 |
+
* On click on image, more link & preview button.
|
1433 |
+
*/
|
1434 |
+
_preview: function( event ) {
|
1435 |
+
|
1436 |
+
event.preventDefault();
|
1437 |
+
|
1438 |
+
var site_id = $(this).parents('.site-single').data('demo-id') || '';
|
1439 |
+
|
1440 |
+
if( AstraSitesAPI._stored_data ) {
|
1441 |
+
var site_data = AstraSitesAdmin._get_site_details( site_id );
|
1442 |
+
|
1443 |
+
if( site_data ) {
|
1444 |
+
// Set current site details.
|
1445 |
+
AstraSitesAdmin.current_site = site_data;
|
1446 |
+
|
1447 |
+
// Set current screen.
|
1448 |
+
AstraSitesAdmin._set_current_screen( 'get-started' );
|
1449 |
+
}
|
1450 |
+
}
|
1451 |
+
|
1452 |
+
var self = $(this).parents('.theme');
|
1453 |
+
self.addClass('theme-preview-on');
|
1454 |
+
|
1455 |
+
$('html').addClass('astra-site-preview-on');
|
1456 |
+
|
1457 |
+
AstraSitesAdmin._renderDemoPreview( self );
|
1458 |
+
},
|
1459 |
+
|
1460 |
+
_get_site_details: function( site_id ) {
|
1461 |
+
var all_sites = AstraSitesAPI._stored_data['astra-sites'] || [];
|
1462 |
+
|
1463 |
+
if( ! all_sites ) {
|
1464 |
+
return false;
|
1465 |
+
}
|
1466 |
+
|
1467 |
+
var single_site = all_sites.filter(function (site) { return site.id == site_id });
|
1468 |
+
if( ! single_site ) {
|
1469 |
+
return false;
|
1470 |
+
}
|
1471 |
+
|
1472 |
+
if( ! $.isArray( single_site ) ) {
|
1473 |
+
return false;
|
1474 |
+
}
|
1475 |
+
|
1476 |
+
return single_site[0];
|
1477 |
+
},
|
1478 |
+
|
1479 |
+
/**
|
1480 |
+
* Check Next Previous Buttons.
|
1481 |
+
*/
|
1482 |
+
_checkNextPrevButtons: function() {
|
1483 |
+
currentDemo = jQuery('.theme-preview-on');
|
1484 |
+
nextDemo = currentDemo.nextAll('.theme').length;
|
1485 |
+
prevDemo = currentDemo.prevAll('.theme').length;
|
1486 |
+
|
1487 |
+
if (nextDemo == 0) {
|
1488 |
+
jQuery('.next-theme').addClass('disabled');
|
1489 |
+
} else if (nextDemo != 0) {
|
1490 |
+
jQuery('.next-theme').removeClass('disabled');
|
1491 |
+
}
|
1492 |
+
|
1493 |
+
if (prevDemo == 0) {
|
1494 |
+
jQuery('.previous-theme').addClass('disabled');
|
1495 |
+
} else if (prevDemo != 0) {
|
1496 |
+
jQuery('.previous-theme').removeClass('disabled');
|
1497 |
+
}
|
1498 |
+
|
1499 |
+
return;
|
1500 |
+
},
|
1501 |
+
|
1502 |
+
/**
|
1503 |
+
* Render Demo Preview
|
1504 |
+
*/
|
1505 |
+
_renderDemoPreview: function(anchor) {
|
1506 |
+
|
1507 |
+
var demoId = anchor.data('demo-id') || '',
|
1508 |
+
apiURL = anchor.data('demo-api') || '',
|
1509 |
+
demoType = anchor.data('demo-type') || '',
|
1510 |
+
demoURL = anchor.data('demo-url') || '',
|
1511 |
+
screenshot = anchor.data('screenshot') || '',
|
1512 |
+
demo_name = anchor.data('demo-name') || '',
|
1513 |
+
demo_slug = anchor.data('demo-slug') || '',
|
1514 |
+
content = anchor.data('content') || '',
|
1515 |
+
requiredPlugins = anchor.data('required-plugins') || '',
|
1516 |
+
astraSiteOptions = anchor.find('.astra-site-options').val() || '';
|
1517 |
+
astraEnabledExtensions = anchor.find('.astra-enabled-extensions').val() || '';
|
1518 |
+
|
1519 |
+
AstraSitesAdmin._log( astraSitesAdmin.log.preview + ' "' + demo_name + '" URL : ' + demoURL );
|
1520 |
+
|
1521 |
+
|
1522 |
+
var template = wp.template('astra-site-preview');
|
1523 |
+
|
1524 |
+
templateData = [{
|
1525 |
+
id : demoId,
|
1526 |
+
astra_demo_type : demoType,
|
1527 |
+
astra_demo_url : demoURL,
|
1528 |
+
demo_api : apiURL,
|
1529 |
+
screenshot : screenshot,
|
1530 |
+
demo_name : demo_name,
|
1531 |
+
slug : demo_slug,
|
1532 |
+
content : content,
|
1533 |
+
required_plugins : JSON.stringify(requiredPlugins),
|
1534 |
+
astra_site_options : astraSiteOptions,
|
1535 |
+
astra_enabled_extensions : astraEnabledExtensions,
|
1536 |
+
}];
|
1537 |
+
|
1538 |
+
// return;
|
1539 |
+
|
1540 |
+
// delete any earlier fullscreen preview before we render new one.
|
1541 |
+
$('.theme-install-overlay').remove();
|
1542 |
+
|
1543 |
+
$('#astra-sites-menu-page').append(template(templateData[0]));
|
1544 |
+
$('.theme-install-overlay').css('display', 'block');
|
1545 |
+
AstraSitesAdmin._checkNextPrevButtons();
|
1546 |
+
|
1547 |
+
var desc = $('.theme-details');
|
1548 |
+
var descHeight = parseInt( desc.outerHeight() );
|
1549 |
+
var descBtn = $('.theme-details-read-more');
|
1550 |
+
|
1551 |
+
// Check is site imported recently and set flag.
|
1552 |
+
$.ajax({
|
1553 |
+
url : astraSitesAdmin.ajaxurl,
|
1554 |
+
type : 'POST',
|
1555 |
+
data : {
|
1556 |
+
action : 'astra-sites-set-reset-data',
|
1557 |
+
},
|
1558 |
+
})
|
1559 |
+
.done(function ( response ) {
|
1560 |
+
AstraSitesAdmin._log( response );
|
1561 |
+
if( response.success ) {
|
1562 |
+
AstraSitesAdmin.site_imported_data = response.data;
|
1563 |
+
}
|
1564 |
+
});
|
1565 |
+
|
1566 |
+
if( $.isArray( requiredPlugins ) ) {
|
1567 |
+
|
1568 |
+
if( descHeight >= 55 ) {
|
1569 |
+
|
1570 |
+
// Show button.
|
1571 |
+
descBtn.css( 'display', 'inline-block' );
|
1572 |
+
|
1573 |
+
// Set height upto 3 line.
|
1574 |
+
desc.css( 'height', 57 );
|
1575 |
+
|
1576 |
+
// Button Click.
|
1577 |
+
descBtn.click(function(event) {
|
1578 |
+
|
1579 |
+
if( descBtn.hasClass('open') ) {
|
1580 |
+
desc.animate({ height: 57 },
|
1581 |
+
300, function() {
|
1582 |
+
descBtn.removeClass('open');
|
1583 |
+
descBtn.html( astraSitesAdmin.strings.DescExpand );
|
1584 |
+
});
|
1585 |
+
} else {
|
1586 |
+
desc.animate({ height: descHeight },
|
1587 |
+
300, function() {
|
1588 |
+
descBtn.addClass('open');
|
1589 |
+
descBtn.html( astraSitesAdmin.strings.DescCollapse );
|
1590 |
+
});
|
1591 |
+
}
|
1592 |
+
|
1593 |
+
});
|
1594 |
+
}
|
1595 |
+
|
1596 |
+
// or
|
1597 |
+
var $pluginsFilter = $( '#plugin-filter' ),
|
1598 |
+
data = {
|
1599 |
+
action : 'astra-required-plugins',
|
1600 |
+
_ajax_nonce : astraSitesAdmin._ajax_nonce,
|
1601 |
+
required_plugins : requiredPlugins
|
1602 |
+
};
|
1603 |
+
|
1604 |
+
// Add disabled class from import button.
|
1605 |
+
$('.astra-demo-import')
|
1606 |
+
.addClass('disabled not-click-able')
|
1607 |
+
.removeAttr('data-import');
|
1608 |
+
|
1609 |
+
$('.required-plugins').addClass('loading').html('<span class="spinner is-active"></span>');
|
1610 |
+
|
1611 |
+
// Required Required.
|
1612 |
+
$.ajax({
|
1613 |
+
url : astraSitesAdmin.ajaxurl,
|
1614 |
+
type : 'POST',
|
1615 |
+
data : data,
|
1616 |
+
})
|
1617 |
+
.fail(function( jqXHR ){
|
1618 |
+
|
1619 |
+
// Remove loader.
|
1620 |
+
$('.required-plugins').removeClass('loading').html('');
|
1621 |
+
|
1622 |
+
AstraSitesAdmin._importFailMessage( jqXHR.status + ' ' + jqXHR.responseText, 'plugins' );
|
1623 |
+
AstraSitesAdmin._log( jqXHR.status + ' ' + jqXHR.responseText );
|
1624 |
+
})
|
1625 |
+
.done(function ( response ) {
|
1626 |
+
|
1627 |
+
|
1628 |
+
// Release disabled class from import button.
|
1629 |
+
$('.astra-demo-import')
|
1630 |
+
.removeClass('disabled not-click-able')
|
1631 |
+
.attr('data-import', 'disabled');
|
1632 |
+
|
1633 |
+
// Remove loader.
|
1634 |
+
$('.required-plugins').removeClass('loading').html('');
|
1635 |
+
$('.required-plugins-list').html('');
|
1636 |
+
|
1637 |
+
/**
|
1638 |
+
* Count remaining plugins.
|
1639 |
+
* @type number
|
1640 |
+
*/
|
1641 |
+
var remaining_plugins = 0;
|
1642 |
+
|
1643 |
+
/**
|
1644 |
+
* Not Installed
|
1645 |
+
*
|
1646 |
+
* List of not installed required plugins.
|
1647 |
+
*/
|
1648 |
+
if ( typeof response.data.notinstalled !== 'undefined' ) {
|
1649 |
+
|
1650 |
+
// Add not have installed plugins count.
|
1651 |
+
remaining_plugins += parseInt( response.data.notinstalled.length );
|
1652 |
+
|
1653 |
+
$( response.data.notinstalled ).each(function( index, plugin ) {
|
1654 |
+
$('.required-plugins-list').append('<li class="plugin-card plugin-card-'+plugin.slug+'" data-slug="'+plugin.slug+'" data-init="'+plugin.init+'">'+plugin.name+'</li>');
|
1655 |
+
});
|
1656 |
+
}
|
1657 |
+
|
1658 |
+
/**
|
1659 |
+
* Inactive
|
1660 |
+
*
|
1661 |
+
* List of not inactive required plugins.
|
1662 |
+
*/
|
1663 |
+
if ( typeof response.data.inactive !== 'undefined' ) {
|
1664 |
+
|
1665 |
+
// Add inactive plugins count.
|
1666 |
+
remaining_plugins += parseInt( response.data.inactive.length );
|
1667 |
+
|
1668 |
+
$( response.data.inactive ).each(function( index, plugin ) {
|
1669 |
+
$('.required-plugins-list').append('<li class="plugin-card plugin-card-'+plugin.slug+'" data-slug="'+plugin.slug+'" data-init="'+plugin.init+'">'+plugin.name+'</li>');
|
1670 |
+
});
|
1671 |
+
}
|
1672 |
+
|
1673 |
+
/**
|
1674 |
+
* Active
|
1675 |
+
*
|
1676 |
+
* List of not active required plugins.
|
1677 |
+
*/
|
1678 |
+
if ( typeof response.data.active !== 'undefined' ) {
|
1679 |
+
|
1680 |
+
$( response.data.active ).each(function( index, plugin ) {
|
1681 |
+
$('.required-plugins-list').append('<li class="plugin-card plugin-card-'+plugin.slug+'" data-slug="'+plugin.slug+'" data-init="'+plugin.init+'">'+plugin.name+'</li>');
|
1682 |
+
});
|
1683 |
+
}
|
1684 |
+
|
1685 |
+
/**
|
1686 |
+
* Enable Demo Import Button
|
1687 |
+
* @type number
|
1688 |
+
*/
|
1689 |
+
astraSitesAdmin.requiredPlugins = response.data;
|
1690 |
+
});
|
1691 |
+
|
1692 |
+
} else {
|
1693 |
+
|
1694 |
+
// Enable Demo Import Button
|
1695 |
+
AstraSitesAdmin._enable_demo_import_button( demoType );
|
1696 |
+
$('.astra-sites-advanced-options-wrap').remove();
|
1697 |
+
}
|
1698 |
+
|
1699 |
+
return;
|
1700 |
+
},
|
1701 |
+
|
1702 |
+
/**
|
1703 |
+
* Enable Demo Import Button.
|
1704 |
+
*/
|
1705 |
+
_enable_demo_import_button: function( type ) {
|
1706 |
+
|
1707 |
+
type = ( undefined !== type ) ? type : 'free';
|
1708 |
+
|
1709 |
+
$('.install-theme-info .theme-details .site-description').remove();
|
1710 |
+
|
1711 |
+
switch( type ) {
|
1712 |
+
|
1713 |
+
case 'free':
|
1714 |
+
|
1715 |
+
var notinstalled = astraSitesAdmin.requiredPlugins.notinstalled || 0;
|
1716 |
+
var inactive = astraSitesAdmin.requiredPlugins.inactive || 0;
|
1717 |
+
|
1718 |
+
if( notinstalled.length === inactive.length ) {
|
1719 |
+
|
1720 |
+
// XML reader not available notice.
|
1721 |
+
if( astraSitesAdmin.XMLReaderDisabled ) {
|
1722 |
+
if( ! $('.install-theme-info .astra-sites-xml-notice').length ) {
|
1723 |
+
$('.install-theme-info').prepend( astraSitesAdmin.strings.warningXMLReader );
|
1724 |
+
}
|
1725 |
+
$('.astra-demo-import')
|
1726 |
+
.removeClass('installing updating-message')
|
1727 |
+
.addClass('disabled')
|
1728 |
+
.text( astraSitesAdmin.strings.importDemo );
|
1729 |
+
} else {
|
1730 |
+
$(document).trigger( 'astra-sites-install-and-activate-required-plugins-done' );
|
1731 |
+
}
|
1732 |
+
}
|
1733 |
+
|
1734 |
+
break;
|
1735 |
+
|
1736 |
+
case 'upgrade':
|
1737 |
+
var demo_slug = $('.wp-full-overlay-header').attr('data-demo-slug');
|
1738 |
+
|
1739 |
+
$('.astra-demo-import')
|
1740 |
+
.addClass('go-pro button-primary')
|
1741 |
+
.removeClass('astra-demo-import')
|
1742 |
+
.attr('target', '_blank')
|
1743 |
+
.attr('href', astraSitesAdmin.getUpgradeURL + demo_slug )
|
1744 |
+
.text( astraSitesAdmin.getUpgradeText )
|
1745 |
+
.append('<i class="dashicons dashicons-external"></i>');
|
1746 |
+
|
1747 |
+
break;
|
1748 |
+
|
1749 |
+
default:
|
1750 |
+
var demo_slug = $('.wp-full-overlay-header').attr('data-demo-slug');
|
1751 |
+
|
1752 |
+
$('.astra-demo-import')
|
1753 |
+
.addClass('go-pro button-primary')
|
1754 |
+
.removeClass('astra-demo-import')
|
1755 |
+
.attr('target', '_blank')
|
1756 |
+
.attr('href', astraSitesAdmin.getProURL )
|
1757 |
+
.text( astraSitesAdmin.getProText )
|
1758 |
+
.append('<i class="dashicons dashicons-external"></i>');
|
1759 |
+
|
1760 |
+
if( false == astraSitesAdmin.isWhiteLabeled ) {
|
1761 |
+
if( astraSitesAdmin.isPro ) {
|
1762 |
+
$('.install-theme-info .theme-details').prepend( wp.template('astra-sites-pro-inactive-site-description') );
|
1763 |
+
} else {
|
1764 |
+
$('.install-theme-info .theme-details').prepend( wp.template('astra-sites-pro-site-description') );
|
1765 |
+
}
|
1766 |
+
}
|
1767 |
+
|
1768 |
+
break;
|
1769 |
+
}
|
1770 |
+
|
1771 |
+
},
|
1772 |
+
|
1773 |
+
/**
|
1774 |
+
* Update Page Count.
|
1775 |
+
*/
|
1776 |
+
_updatedPagedCount: function() {
|
1777 |
+
paged = parseInt(jQuery('body').attr('data-astra-demo-paged'));
|
1778 |
+
jQuery('body').attr('data-astra-demo-paged', paged + 1);
|
1779 |
+
window.setTimeout(function () {
|
1780 |
+
jQuery('body').data('scrolling', false);
|
1781 |
+
}, 800);
|
1782 |
+
},
|
1783 |
+
|
1784 |
+
/**
|
1785 |
+
* Reset Page Count.
|
1786 |
+
*/
|
1787 |
+
_resetPagedCount: function() {
|
1788 |
+
|
1789 |
+
$('body').addClass('loading-content');
|
1790 |
+
$('body').attr('data-astra-demo-last-request', '1');
|
1791 |
+
$('body').attr('data-astra-demo-paged', '1');
|
1792 |
+
$('body').attr('data-astra-demo-search', '');
|
1793 |
+
$('body').attr('data-scrolling', false);
|
1794 |
+
|
1795 |
+
},
|
1796 |
+
|
1797 |
+
/**
|
1798 |
+
* Remove plugin from the queue.
|
1799 |
+
*/
|
1800 |
+
_removePluginFromQueue: function( removeItem, pluginsList ) {
|
1801 |
+
return jQuery.grep(pluginsList, function( value ) {
|
1802 |
+
return value.slug != removeItem;
|
1803 |
+
});
|
1804 |
+
}
|
1805 |
+
|
1806 |
+
};
|
1807 |
+
|
1808 |
+
/**
|
1809 |
+
* Initialize AstraSitesAdmin
|
1810 |
+
*/
|
1811 |
+
$(function(){
|
1812 |
+
AstraSitesAdmin.init();
|
1813 |
+
});
|
1814 |
+
|
1815 |
Â
})(jQuery);
|
inc/assets/js/astra-sites-api.js
CHANGED
@@ -1,65 +1,65 @@
|
|
1 |
-
(function($){
|
2 |
-
|
3 |
-
AstraSitesAPI = {
|
4 |
-
|
5 |
-
_api_url : astraSitesApi.ApiURL,
|
6 |
-
_stored_data : {
|
7 |
-
'astra-site-category' : [],
|
8 |
-
'astra-site-page-builder': [],
|
9 |
-
'astra-sites' : [],
|
10 |
-
},
|
11 |
-
|
12 |
-
/**
|
13 |
-
* API Request
|
14 |
-
*/
|
15 |
-
_api_request: function( args ) {
|
16 |
-
|
17 |
-
// Set API Request Data.
|
18 |
-
var data = {
|
19 |
-
url: AstraSitesAPI._api_url + args.slug,
|
20 |
-
};
|
21 |
-
|
22 |
-
if( astraRenderGrid.headers ) {
|
23 |
-
data.headers = astraRenderGrid.headers;
|
24 |
-
}
|
25 |
-
|
26 |
-
$.ajax( data )
|
27 |
-
.done(function( items, status, XHR ) {
|
28 |
-
|
29 |
-
if( 'success' === status && XHR.getResponseHeader('x-wp-total') ) {
|
30 |
-
|
31 |
-
if( args.id ) {
|
32 |
-
AstraSitesAPI._stored_data[ args.id ] = $.merge( AstraSitesAPI._stored_data[ args.id ], items );
|
33 |
-
}
|
34 |
-
|
35 |
-
var data = {
|
36 |
-
args : args,
|
37 |
-
items : items,
|
38 |
-
items_count : XHR.getResponseHeader('x-wp-total') || 0,
|
39 |
-
};
|
40 |
-
|
41 |
-
if( 'undefined' !== args.trigger && '' !== args.trigger ) {
|
42 |
-
$(document).trigger( args.trigger, [data] );
|
43 |
-
}
|
44 |
-
|
45 |
-
} else {
|
46 |
-
$(document).trigger( 'astra-sites-api-request-error' );
|
47 |
-
}
|
48 |
-
|
49 |
-
})
|
50 |
-
.fail(function( jqXHR, textStatus ) {
|
51 |
-
|
52 |
-
$(document).trigger( 'astra-sites-api-request-fail', [jqXHR, textStatus, args] );
|
53 |
-
|
54 |
-
})
|
55 |
-
.always(function() {
|
56 |
-
|
57 |
-
$(document).trigger( 'astra-sites-api-request-always' );
|
58 |
-
|
59 |
-
});
|
60 |
-
|
61 |
-
},
|
62 |
-
|
63 |
-
};
|
64 |
-
|
65 |
Â
})(jQuery);
|
1 |
+
(function($){
|
2 |
+
|
3 |
+
AstraSitesAPI = {
|
4 |
+
|
5 |
+
_api_url : astraSitesApi.ApiURL,
|
6 |
+
_stored_data : {
|
7 |
+
'astra-site-category' : [],
|
8 |
+
'astra-site-page-builder': [],
|
9 |
+
'astra-sites' : [],
|
10 |
+
},
|
11 |
+
|
12 |
+
/**
|
13 |
+
* API Request
|
14 |
+
*/
|
15 |
+
_api_request: function( args ) {
|
16 |
+
|
17 |
+
// Set API Request Data.
|
18 |
+
var data = {
|
19 |
+
url: AstraSitesAPI._api_url + args.slug,
|
20 |
+
};
|
21 |
+
|
22 |
+
if( astraRenderGrid.headers ) {
|
23 |
+
data.headers = astraRenderGrid.headers;
|
24 |
+
}
|
25 |
+
|
26 |
+
$.ajax( data )
|
27 |
+
.done(function( items, status, XHR ) {
|
28 |
+
|
29 |
+
if( 'success' === status && XHR.getResponseHeader('x-wp-total') ) {
|
30 |
+
|
31 |
+
if( args.id ) {
|
32 |
+
AstraSitesAPI._stored_data[ args.id ] = $.merge( AstraSitesAPI._stored_data[ args.id ], items );
|
33 |
+
}
|
34 |
+
|
35 |
+
var data = {
|
36 |
+
args : args,
|
37 |
+
items : items,
|
38 |
+
items_count : XHR.getResponseHeader('x-wp-total') || 0,
|
39 |
+
};
|
40 |
+
|
41 |
+
if( 'undefined' !== args.trigger && '' !== args.trigger ) {
|
42 |
+
$(document).trigger( args.trigger, [data] );
|
43 |
+
}
|
44 |
+
|
45 |
+
} else {
|
46 |
+
$(document).trigger( 'astra-sites-api-request-error' );
|
47 |
+
}
|
48 |
+
|
49 |
+
})
|
50 |
+
.fail(function( jqXHR, textStatus ) {
|
51 |
+
|
52 |
+
$(document).trigger( 'astra-sites-api-request-fail', [jqXHR, textStatus, args] );
|
53 |
+
|
54 |
+
})
|
55 |
+
.always(function() {
|
56 |
+
|
57 |
+
$(document).trigger( 'astra-sites-api-request-always' );
|
58 |
+
|
59 |
+
});
|
60 |
+
|
61 |
+
},
|
62 |
+
|
63 |
+
};
|
64 |
+
|
65 |
Â
})(jQuery);
|
inc/assets/js/astra-sites-notices.js
CHANGED
@@ -1,21 +1,21 @@
|
|
1 |
-
jQuery(document).ready(function ($) {
|
2 |
-
|
3 |
-
jQuery( '.astra-notice.is-dismissible .notice-dismiss' ).on( 'click', function() {
|
4 |
-
var $id = jQuery( this ).attr( 'id' ) || '';
|
5 |
-
var $time = jQuery( this ).attr( 'dismissible-time' ) || '';
|
6 |
-
var $meta = jQuery( this ).attr( 'dismissible-meta' ) || '';
|
7 |
-
|
8 |
-
jQuery.ajax({
|
9 |
-
url: ajaxurl,
|
10 |
-
type: 'POST',
|
11 |
-
data: {
|
12 |
-
action : 'astra-notices',
|
13 |
-
id : $id,
|
14 |
-
meta : $meta,
|
15 |
-
time : $time,
|
16 |
-
},
|
17 |
-
});
|
18 |
-
|
19 |
-
});
|
20 |
-
|
21 |
Â
});
|
1 |
+
jQuery(document).ready(function ($) {
|
2 |
+
|
3 |
+
jQuery( '.astra-notice.is-dismissible .notice-dismiss' ).on( 'click', function() {
|
4 |
+
var $id = jQuery( this ).attr( 'id' ) || '';
|
5 |
+
var $time = jQuery( this ).attr( 'dismissible-time' ) || '';
|
6 |
+
var $meta = jQuery( this ).attr( 'dismissible-meta' ) || '';
|
7 |
+
|
8 |
+
jQuery.ajax({
|
9 |
+
url: ajaxurl,
|
10 |
+
type: 'POST',
|
11 |
+
data: {
|
12 |
+
action : 'astra-notices',
|
13 |
+
id : $id,
|
14 |
+
meta : $meta,
|
15 |
+
time : $time,
|
16 |
+
},
|
17 |
+
});
|
18 |
+
|
19 |
+
});
|
20 |
+
|
21 |
Â
});
|
inc/assets/js/eventsource.js
CHANGED
@@ -1,673 +1,673 @@
|
|
1 |
-
/** @license
|
2 |
-
* eventsource.js
|
3 |
-
* Available under MIT License (MIT)
|
4 |
-
* https://github.com/Yaffle/EventSource/
|
5 |
-
*/
|
6 |
-
|
7 |
-
/*jslint indent: 2, vars: true, plusplus: true */
|
8 |
-
/*global setTimeout, clearTimeout */
|
9 |
-
|
10 |
-
(function (global) {
|
11 |
-
"use strict";
|
12 |
-
|
13 |
-
var setTimeout = global.setTimeout;
|
14 |
-
var clearTimeout = global.clearTimeout;
|
15 |
-
var XMLHttpRequest = global.XMLHttpRequest;
|
16 |
-
var XDomainRequest = global.XDomainRequest;
|
17 |
-
var NativeEventSource = global.EventSource;
|
18 |
-
var document = global.document;
|
19 |
-
|
20 |
-
if (Object.create == null) {
|
21 |
-
Object.create = function (C) {
|
22 |
-
function F(){}
|
23 |
-
F.prototype = C;
|
24 |
-
return new F();
|
25 |
-
};
|
26 |
-
}
|
27 |
-
|
28 |
-
var k = function () {
|
29 |
-
};
|
30 |
-
|
31 |
-
function XHRWrapper(xhr) {
|
32 |
-
this.withCredentials = false;
|
33 |
-
this.responseType = "";
|
34 |
-
this.readyState = 0;
|
35 |
-
this.status = 0;
|
36 |
-
this.statusText = "";
|
37 |
-
this.responseText = "";
|
38 |
-
this.onprogress = k;
|
39 |
-
this.onreadystatechange = k;
|
40 |
-
this._contentType = "";
|
41 |
-
this._xhr = xhr;
|
42 |
-
this._sendTimeout = 0;
|
43 |
-
this._abort = k;
|
44 |
-
}
|
45 |
-
|
46 |
-
XHRWrapper.prototype.open = function (method, url) {
|
47 |
-
this._abort(true);
|
48 |
-
|
49 |
-
var that = this;
|
50 |
-
var xhr = this._xhr;
|
51 |
-
var state = 1;
|
52 |
-
var timeout = 0;
|
53 |
-
|
54 |
-
this._abort = function (silent) {
|
55 |
-
if (that._sendTimeout !== 0) {
|
56 |
-
clearTimeout(that._sendTimeout);
|
57 |
-
that._sendTimeout = 0;
|
58 |
-
}
|
59 |
-
if (state === 1 || state === 2 || state === 3) {
|
60 |
-
state = 4;
|
61 |
-
xhr.onload = k;
|
62 |
-
xhr.onerror = k;
|
63 |
-
xhr.onabort = k;
|
64 |
-
xhr.onprogress = k;
|
65 |
-
xhr.onreadystatechange = k;
|
66 |
-
// IE 8 - 9: XDomainRequest#abort() does not fire any event
|
67 |
-
// Opera < 10: XMLHttpRequest#abort() does not fire any event
|
68 |
-
xhr.abort();
|
69 |
-
if (timeout !== 0) {
|
70 |
-
clearTimeout(timeout);
|
71 |
-
timeout = 0;
|
72 |
-
}
|
73 |
-
if (!silent) {
|
74 |
-
that.readyState = 4;
|
75 |
-
that.onreadystatechange();
|
76 |
-
}
|
77 |
-
}
|
78 |
-
state = 0;
|
79 |
-
};
|
80 |
-
|
81 |
-
var onStart = function () {
|
82 |
-
if (state === 1) {
|
83 |
-
//state = 2;
|
84 |
-
var status = 0;
|
85 |
-
var statusText = "";
|
86 |
-
var contentType = undefined;
|
87 |
-
if (!("contentType" in xhr)) {
|
88 |
-
try {
|
89 |
-
status = xhr.status;
|
90 |
-
statusText = xhr.statusText;
|
91 |
-
contentType = xhr.getResponseHeader("Content-Type");
|
92 |
-
} catch (error) {
|
93 |
-
// IE < 10 throws exception for `xhr.status` when xhr.readyState === 2 || xhr.readyState === 3
|
94 |
-
// Opera < 11 throws exception for `xhr.status` when xhr.readyState === 2
|
95 |
-
// https://bugs.webkit.org/show_bug.cgi?id=29121
|
96 |
-
status = 0;
|
97 |
-
statusText = "";
|
98 |
-
contentType = undefined;
|
99 |
-
// Firefox < 14, Chrome ?, Safari ?
|
100 |
-
// https://bugs.webkit.org/show_bug.cgi?id=29658
|
101 |
-
// https://bugs.webkit.org/show_bug.cgi?id=77854
|
102 |
-
}
|
103 |
-
} else {
|
104 |
-
status = 200;
|
105 |
-
statusText = "OK";
|
106 |
-
contentType = xhr.contentType;
|
107 |
-
}
|
108 |
-
if (status !== 0) {
|
109 |
-
state = 2;
|
110 |
-
that.readyState = 2;
|
111 |
-
that.status = status;
|
112 |
-
that.statusText = statusText;
|
113 |
-
that._contentType = contentType;
|
114 |
-
that.onreadystatechange();
|
115 |
-
}
|
116 |
-
}
|
117 |
-
};
|
118 |
-
var onProgress = function () {
|
119 |
-
onStart();
|
120 |
-
if (state === 2 || state === 3) {
|
121 |
-
state = 3;
|
122 |
-
var responseText = "";
|
123 |
-
try {
|
124 |
-
responseText = xhr.responseText;
|
125 |
-
} catch (error) {
|
126 |
-
// IE 8 - 9 with XMLHttpRequest
|
127 |
-
}
|
128 |
-
that.readyState = 3;
|
129 |
-
that.responseText = responseText;
|
130 |
-
that.onprogress();
|
131 |
-
}
|
132 |
-
};
|
133 |
-
var onFinish = function () {
|
134 |
-
// Firefox 52 fires "readystatechange" (xhr.readyState === 4) without final "readystatechange" (xhr.readyState === 3)
|
135 |
-
// IE 8 fires "onload" without "onprogress"
|
136 |
-
onProgress();
|
137 |
-
if (state === 1 || state === 2 || state === 3) {
|
138 |
-
state = 4;
|
139 |
-
if (timeout !== 0) {
|
140 |
-
clearTimeout(timeout);
|
141 |
-
timeout = 0;
|
142 |
-
}
|
143 |
-
that.readyState = 4;
|
144 |
-
that.onreadystatechange();
|
145 |
-
}
|
146 |
-
};
|
147 |
-
var onReadyStateChange = function () {
|
148 |
-
if (xhr != undefined) { // Opera 12
|
149 |
-
if (xhr.readyState === 4) {
|
150 |
-
onFinish();
|
151 |
-
} else if (xhr.readyState === 3) {
|
152 |
-
onProgress();
|
153 |
-
} else if (xhr.readyState === 2) {
|
154 |
-
onStart();
|
155 |
-
}
|
156 |
-
}
|
157 |
-
};
|
158 |
-
var onTimeout = function () {
|
159 |
-
timeout = setTimeout(function () {
|
160 |
-
onTimeout();
|
161 |
-
}, 500);
|
162 |
-
if (xhr.readyState === 3) {
|
163 |
-
onProgress();
|
164 |
-
}
|
165 |
-
};
|
166 |
-
|
167 |
-
// XDomainRequest#abort removes onprogress, onerror, onload
|
168 |
-
xhr.onload = onFinish;
|
169 |
-
xhr.onerror = onFinish;
|
170 |
-
// improper fix to match Firefox behaviour, but it is better than just ignore abort
|
171 |
-
// see https://bugzilla.mozilla.org/show_bug.cgi?id=768596
|
172 |
-
// https://bugzilla.mozilla.org/show_bug.cgi?id=880200
|
173 |
-
// https://code.google.com/p/chromium/issues/detail?id=153570
|
174 |
-
// IE 8 fires "onload" without "onprogress
|
175 |
-
xhr.onabort = onFinish;
|
176 |
-
|
177 |
-
// https://bugzilla.mozilla.org/show_bug.cgi?id=736723
|
178 |
-
if (!("sendAsBinary" in XMLHttpRequest.prototype) && !("mozAnon" in XMLHttpRequest.prototype)) {
|
179 |
-
xhr.onprogress = onProgress;
|
180 |
-
}
|
181 |
-
|
182 |
-
// IE 8 - 9 (XMLHTTPRequest)
|
183 |
-
// Opera < 12
|
184 |
-
// Firefox < 3.5
|
185 |
-
// Firefox 3.5 - 3.6 - ? < 9.0
|
186 |
-
// onprogress is not fired sometimes or delayed
|
187 |
-
// see also #64
|
188 |
-
xhr.onreadystatechange = onReadyStateChange;
|
189 |
-
|
190 |
-
if ("contentType" in xhr) {
|
191 |
-
url += (url.indexOf("?", 0) === -1 ? "?" : "&") + "padding=true";
|
192 |
-
}
|
193 |
-
xhr.open(method, url, true);
|
194 |
-
|
195 |
-
if ("readyState" in xhr) {
|
196 |
-
// workaround for Opera 12 issue with "progress" events
|
197 |
-
// #91
|
198 |
-
timeout = setTimeout(function () {
|
199 |
-
onTimeout();
|
200 |
-
}, 0);
|
201 |
-
}
|
202 |
-
};
|
203 |
-
XHRWrapper.prototype.abort = function () {
|
204 |
-
this._abort(false);
|
205 |
-
};
|
206 |
-
XHRWrapper.prototype.getResponseHeader = function (name) {
|
207 |
-
return this._contentType;
|
208 |
-
};
|
209 |
-
XHRWrapper.prototype.setRequestHeader = function (name, value) {
|
210 |
-
var xhr = this._xhr;
|
211 |
-
if ("setRequestHeader" in xhr) {
|
212 |
-
xhr.setRequestHeader(name, value);
|
213 |
-
}
|
214 |
-
};
|
215 |
-
XHRWrapper.prototype.send = function () {
|
216 |
-
// loading indicator in Safari < ? (6), Chrome < 14, Firefox
|
217 |
-
if (!("ontimeout" in XMLHttpRequest.prototype) &&
|
218 |
-
document != undefined &&
|
219 |
-
document.readyState != undefined &&
|
220 |
-
document.readyState !== "complete") {
|
221 |
-
var that = this;
|
222 |
-
that._sendTimeout = setTimeout(function () {
|
223 |
-
that._sendTimeout = 0;
|
224 |
-
that.send();
|
225 |
-
}, 4);
|
226 |
-
return;
|
227 |
-
}
|
228 |
-
|
229 |
-
var xhr = this._xhr;
|
230 |
-
// withCredentials should be set after "open" for Safari and Chrome (< 19 ?)
|
231 |
-
xhr.withCredentials = this.withCredentials;
|
232 |
-
xhr.responseType = this.responseType;
|
233 |
-
try {
|
234 |
-
// xhr.send(); throws "Not enough arguments" in Firefox 3.0
|
235 |
-
xhr.send(undefined);
|
236 |
-
} catch (error1) {
|
237 |
-
// Safari 5.1.7, Opera 12
|
238 |
-
throw error1;
|
239 |
-
}
|
240 |
-
};
|
241 |
-
|
242 |
-
function XHRTransport(xhr) {
|
243 |
-
this._xhr = new XHRWrapper(xhr);
|
244 |
-
}
|
245 |
-
|
246 |
-
XHRTransport.prototype.open = function (onStartCallback, onProgressCallback, onFinishCallback, url, withCredentials, headers) {
|
247 |
-
var xhr = this._xhr;
|
248 |
-
xhr.open("GET", url);
|
249 |
-
var offset = 0;
|
250 |
-
xhr.onprogress = function () {
|
251 |
-
var responseText = xhr.responseText;
|
252 |
-
var chunk = responseText.slice(offset);
|
253 |
-
offset += chunk.length;
|
254 |
-
onProgressCallback(chunk);
|
255 |
-
};
|
256 |
-
xhr.onreadystatechange = function () {
|
257 |
-
if (xhr.readyState === 2) {
|
258 |
-
var status = xhr.status;
|
259 |
-
var statusText = xhr.statusText;
|
260 |
-
var contentType = xhr.getResponseHeader("Content-Type");
|
261 |
-
onStartCallback(status, statusText, contentType);
|
262 |
-
} else if (xhr.readyState === 4) {
|
263 |
-
onFinishCallback();
|
264 |
-
}
|
265 |
-
};
|
266 |
-
xhr.withCredentials = withCredentials;
|
267 |
-
xhr.responseType = "text";
|
268 |
-
for (var name in headers) {
|
269 |
-
if (Object.prototype.hasOwnProperty.call(headers, name)) {
|
270 |
-
xhr.setRequestHeader(name, headers[name]);
|
271 |
-
}
|
272 |
-
}
|
273 |
-
xhr.send();
|
274 |
-
};
|
275 |
-
|
276 |
-
XHRTransport.prototype.cancel = function () {
|
277 |
-
var xhr = this._xhr;
|
278 |
-
xhr.abort();
|
279 |
-
};
|
280 |
-
|
281 |
-
function EventTarget() {
|
282 |
-
this._listeners = Object.create(null);
|
283 |
-
}
|
284 |
-
|
285 |
-
function throwError(e) {
|
286 |
-
setTimeout(function () {
|
287 |
-
throw e;
|
288 |
-
}, 0);
|
289 |
-
}
|
290 |
-
|
291 |
-
EventTarget.prototype.dispatchEvent = function (event) {
|
292 |
-
event.target = this;
|
293 |
-
var typeListeners = this._listeners[event.type];
|
294 |
-
if (typeListeners != undefined) {
|
295 |
-
var length = typeListeners.length;
|
296 |
-
for (var i = 0; i < length; i += 1) {
|
297 |
-
var listener = typeListeners[i];
|
298 |
-
try {
|
299 |
-
if (typeof listener.handleEvent === "function") {
|
300 |
-
listener.handleEvent(event);
|
301 |
-
} else {
|
302 |
-
listener.call(this, event);
|
303 |
-
}
|
304 |
-
} catch (e) {
|
305 |
-
throwError(e);
|
306 |
-
}
|
307 |
-
}
|
308 |
-
}
|
309 |
-
};
|
310 |
-
EventTarget.prototype.addEventListener = function (type, listener) {
|
311 |
-
type = String(type);
|
312 |
-
var listeners = this._listeners;
|
313 |
-
var typeListeners = listeners[type];
|
314 |
-
if (typeListeners == undefined) {
|
315 |
-
typeListeners = [];
|
316 |
-
listeners[type] = typeListeners;
|
317 |
-
}
|
318 |
-
var found = false;
|
319 |
-
for (var i = 0; i < typeListeners.length; i += 1) {
|
320 |
-
if (typeListeners[i] === listener) {
|
321 |
-
found = true;
|
322 |
-
}
|
323 |
-
}
|
324 |
-
if (!found) {
|
325 |
-
typeListeners.push(listener);
|
326 |
-
}
|
327 |
-
};
|
328 |
-
EventTarget.prototype.removeEventListener = function (type, listener) {
|
329 |
-
type = String(type);
|
330 |
-
var listeners = this._listeners;
|
331 |
-
var typeListeners = listeners[type];
|
332 |
-
if (typeListeners != undefined) {
|
333 |
-
var filtered = [];
|
334 |
-
for (var i = 0; i < typeListeners.length; i += 1) {
|
335 |
-
if (typeListeners[i] !== listener) {
|
336 |
-
filtered.push(typeListeners[i]);
|
337 |
-
}
|
338 |
-
}
|
339 |
-
if (filtered.length === 0) {
|
340 |
-
delete listeners[type];
|
341 |
-
} else {
|
342 |
-
listeners[type] = filtered;
|
343 |
-
}
|
344 |
-
}
|
345 |
-
};
|
346 |
-
|
347 |
-
function Event(type) {
|
348 |
-
this.type = type;
|
349 |
-
this.target = undefined;
|
350 |
-
}
|
351 |
-
|
352 |
-
function MessageEvent(type, options) {
|
353 |
-
Event.call(this, type);
|
354 |
-
this.data = options.data;
|
355 |
-
this.lastEventId = options.lastEventId;
|
356 |
-
}
|
357 |
-
|
358 |
-
MessageEvent.prototype = Object.create(Event.prototype);
|
359 |
-
|
360 |
-
var WAITING = -1;
|
361 |
-
var CONNECTING = 0;
|
362 |
-
var OPEN = 1;
|
363 |
-
var CLOSED = 2;
|
364 |
-
|
365 |
-
var AFTER_CR = -1;
|
366 |
-
var FIELD_START = 0;
|
367 |
-
var FIELD = 1;
|
368 |
-
var VALUE_START = 2;
|
369 |
-
var VALUE = 3;
|
370 |
-
|
371 |
-
var contentTypeRegExp = /^text\/event\-stream;?(\s*charset\=utf\-8)?$/i;
|
372 |
-
|
373 |
-
var MINIMUM_DURATION = 1000;
|
374 |
-
var MAXIMUM_DURATION = 18000000;
|
375 |
-
|
376 |
-
var parseDuration = function (value, def) {
|
377 |
-
var n = parseInt(value, 10);
|
378 |
-
if (n !== n) {
|
379 |
-
n = def;
|
380 |
-
}
|
381 |
-
return clampDuration(n);
|
382 |
-
};
|
383 |
-
var clampDuration = function (n) {
|
384 |
-
return Math.min(Math.max(n, MINIMUM_DURATION), MAXIMUM_DURATION);
|
385 |
-
};
|
386 |
-
|
387 |
-
var fire = function (that, f, event) {
|
388 |
-
try {
|
389 |
-
if (typeof f === "function") {
|
390 |
-
f.call(that, event);
|
391 |
-
}
|
392 |
-
} catch (e) {
|
393 |
-
throwError(e);
|
394 |
-
}
|
395 |
-
};
|
396 |
-
|
397 |
-
function EventSourcePolyfill(url, options) {
|
398 |
-
EventTarget.call(this);
|
399 |
-
|
400 |
-
this.onopen = undefined;
|
401 |
-
this.onmessage = undefined;
|
402 |
-
this.onerror = undefined;
|
403 |
-
|
404 |
-
this.url = undefined;
|
405 |
-
this.readyState = undefined;
|
406 |
-
this.withCredentials = undefined;
|
407 |
-
|
408 |
-
this._close = undefined;
|
409 |
-
|
410 |
-
start(this, url, options);
|
411 |
-
}
|
412 |
-
|
413 |
-
function start(es, url, options) {
|
414 |
-
url = String(url);
|
415 |
-
var withCredentials = options != undefined && Boolean(options.withCredentials);
|
416 |
-
|
417 |
-
var initialRetry = clampDuration(1000);
|
418 |
-
var heartbeatTimeout = clampDuration(45000);
|
419 |
-
|
420 |
-
var lastEventId = "";
|
421 |
-
var retry = initialRetry;
|
422 |
-
var wasActivity = false;
|
423 |
-
var headers = options != undefined && options.headers != undefined ? JSON.parse(JSON.stringify(options.headers)) : undefined;
|
424 |
-
var CurrentTransport = options != undefined && options.Transport != undefined ? options.Transport : (XDomainRequest != undefined ? XDomainRequest : XMLHttpRequest);
|
425 |
-
var transport = new XHRTransport(new CurrentTransport());
|
426 |
-
var timeout = 0;
|
427 |
-
var currentState = WAITING;
|
428 |
-
var dataBuffer = "";
|
429 |
-
var lastEventIdBuffer = "";
|
430 |
-
var eventTypeBuffer = "";
|
431 |
-
|
432 |
-
var textBuffer = "";
|
433 |
-
var state = FIELD_START;
|
434 |
-
var fieldStart = 0;
|
435 |
-
var valueStart = 0;
|
436 |
-
|
437 |
-
var onStart = function (status, statusText, contentType) {
|
438 |
-
if (currentState === CONNECTING) {
|
439 |
-
if (status === 200 && contentType != undefined && contentTypeRegExp.test(contentType)) {
|
440 |
-
currentState = OPEN;
|
441 |
-
wasActivity = true;
|
442 |
-
retry = initialRetry;
|
443 |
-
es.readyState = OPEN;
|
444 |
-
var event = new Event("open");
|
445 |
-
es.dispatchEvent(event);
|
446 |
-
fire(es, es.onopen, event);
|
447 |
-
} else {
|
448 |
-
var message = "";
|
449 |
-
if (status !== 200) {
|
450 |
-
if (statusText) {
|
451 |
-
statusText = statusText.replace(/\s+/g, " ");
|
452 |
-
}
|
453 |
-
message = "EventSource's response has a status " + status + " " + statusText + " that is not 200. Aborting the connection.";
|
454 |
-
} else {
|
455 |
-
message = "EventSource's response has a Content-Type specifying an unsupported type: " + (contentType == undefined ? "-" : contentType.replace(/\s+/g, " ")) + ". Aborting the connection.";
|
456 |
-
}
|
457 |
-
throwError(new Error(message));
|
458 |
-
close();
|
459 |
-
var event = new Event("error");
|
460 |
-
es.dispatchEvent(event);
|
461 |
-
fire(es, es.onerror, event);
|
462 |
-
}
|
463 |
-
}
|
464 |
-
};
|
465 |
-
|
466 |
-
var onProgress = function (textChunk) {
|
467 |
-
if (currentState === OPEN) {
|
468 |
-
var n = -1;
|
469 |
-
for (var i = 0; i < textChunk.length; i += 1) {
|
470 |
-
var c = textChunk.charCodeAt(i);
|
471 |
-
if (c === "\n".charCodeAt(0) || c === "\r".charCodeAt(0)) {
|
472 |
-
n = i;
|
473 |
-
}
|
474 |
-
}
|
475 |
-
var chunk = (n !== -1 ? textBuffer : "") + textChunk.slice(0, n + 1);
|
476 |
-
textBuffer = (n === -1 ? textBuffer : "") + textChunk.slice(n + 1);
|
477 |
-
if (chunk !== "") {
|
478 |
-
wasActivity = true;
|
479 |
-
}
|
480 |
-
for (var position = 0; position < chunk.length; position += 1) {
|
481 |
-
var c = chunk.charCodeAt(position);
|
482 |
-
if (state === AFTER_CR && c === "\n".charCodeAt(0)) {
|
483 |
-
state = FIELD_START;
|
484 |
-
} else {
|
485 |
-
if (state === AFTER_CR) {
|
486 |
-
state = FIELD_START;
|
487 |
-
}
|
488 |
-
if (c === "\r".charCodeAt(0) || c === "\n".charCodeAt(0)) {
|
489 |
-
if (state !== FIELD_START) {
|
490 |
-
if (state === FIELD) {
|
491 |
-
valueStart = position + 1;
|
492 |
-
}
|
493 |
-
var field = chunk.slice(fieldStart, valueStart - 1);
|
494 |
-
var value = chunk.slice(valueStart + (valueStart < position && chunk.charCodeAt(valueStart) === " ".charCodeAt(0) ? 1 : 0), position);
|
495 |
-
if (field === "data") {
|
496 |
-
dataBuffer += "\n";
|
497 |
-
dataBuffer += value;
|
498 |
-
} else if (field === "id") {
|
499 |
-
lastEventIdBuffer = value;
|
500 |
-
} else if (field === "event") {
|
501 |
-
eventTypeBuffer = value;
|
502 |
-
} else if (field === "retry") {
|
503 |
-
initialRetry = parseDuration(value, initialRetry);
|
504 |
-
retry = initialRetry;
|
505 |
-
} else if (field === "heartbeatTimeout") {
|
506 |
-
heartbeatTimeout = parseDuration(value, heartbeatTimeout);
|
507 |
-
if (timeout !== 0) {
|
508 |
-
clearTimeout(timeout);
|
509 |
-
timeout = setTimeout(function () {
|
510 |
-
onTimeout();
|
511 |
-
}, heartbeatTimeout);
|
512 |
-
}
|
513 |
-
}
|
514 |
-
}
|
515 |
-
if (state === FIELD_START) {
|
516 |
-
if (dataBuffer !== "") {
|
517 |
-
lastEventId = lastEventIdBuffer;
|
518 |
-
if (eventTypeBuffer === "") {
|
519 |
-
eventTypeBuffer = "message";
|
520 |
-
}
|
521 |
-
var event = new MessageEvent(eventTypeBuffer, {
|
522 |
-
data: dataBuffer.slice(1),
|
523 |
-
lastEventId: lastEventIdBuffer
|
524 |
-
});
|
525 |
-
es.dispatchEvent(event);
|
526 |
-
if (eventTypeBuffer === "message") {
|
527 |
-
fire(es, es.onmessage, event);
|
528 |
-
}
|
529 |
-
if (currentState === CLOSED) {
|
530 |
-
return;
|
531 |
-
}
|
532 |
-
}
|
533 |
-
dataBuffer = "";
|
534 |
-
eventTypeBuffer = "";
|
535 |
-
}
|
536 |
-
state = c === "\r".charCodeAt(0) ? AFTER_CR : FIELD_START;
|
537 |
-
} else {
|
538 |
-
if (state === FIELD_START) {
|
539 |
-
fieldStart = position;
|
540 |
-
state = FIELD;
|
541 |
-
}
|
542 |
-
if (state === FIELD) {
|
543 |
-
if (c === ":".charCodeAt(0)) {
|
544 |
-
valueStart = position + 1;
|
545 |
-
state = VALUE_START;
|
546 |
-
}
|
547 |
-
} else if (state === VALUE_START) {
|
548 |
-
state = VALUE;
|
549 |
-
}
|
550 |
-
}
|
551 |
-
}
|
552 |
-
}
|
553 |
-
}
|
554 |
-
};
|
555 |
-
|
556 |
-
var onFinish = function () {
|
557 |
-
if (currentState === OPEN || currentState === CONNECTING) {
|
558 |
-
currentState = WAITING;
|
559 |
-
if (timeout !== 0) {
|
560 |
-
clearTimeout(timeout);
|
561 |
-
timeout = 0;
|
562 |
-
}
|
563 |
-
timeout = setTimeout(function () {
|
564 |
-
onTimeout();
|
565 |
-
}, retry);
|
566 |
-
retry = clampDuration(Math.min(initialRetry * 16, retry * 2));
|
567 |
-
|
568 |
-
es.readyState = CONNECTING;
|
569 |
-
var event = new Event("error");
|
570 |
-
es.dispatchEvent(event);
|
571 |
-
fire(es, es.onerror, event);
|
572 |
-
}
|
573 |
-
};
|
574 |
-
|
575 |
-
var close = function () {
|
576 |
-
currentState = CLOSED;
|
577 |
-
transport.cancel();
|
578 |
-
if (timeout !== 0) {
|
579 |
-
clearTimeout(timeout);
|
580 |
-
timeout = 0;
|
581 |
-
}
|
582 |
-
es.readyState = CLOSED;
|
583 |
-
};
|
584 |
-
|
585 |
-
var onTimeout = function () {
|
586 |
-
timeout = 0;
|
587 |
-
|
588 |
-
if (currentState !== WAITING) {
|
589 |
-
if (!wasActivity) {
|
590 |
-
throwError(new Error("No activity within " + heartbeatTimeout + " milliseconds. Reconnecting."));
|
591 |
-
transport.cancel();
|
592 |
-
} else {
|
593 |
-
wasActivity = false;
|
594 |
-
timeout = setTimeout(function () {
|
595 |
-
onTimeout();
|
596 |
-
}, heartbeatTimeout);
|
597 |
-
}
|
598 |
-
return;
|
599 |
-
}
|
600 |
-
|
601 |
-
wasActivity = false;
|
602 |
-
timeout = setTimeout(function () {
|
603 |
-
onTimeout();
|
604 |
-
}, heartbeatTimeout);
|
605 |
-
|
606 |
-
currentState = CONNECTING;
|
607 |
-
dataBuffer = "";
|
608 |
-
eventTypeBuffer = "";
|
609 |
-
lastEventIdBuffer = lastEventId;
|
610 |
-
textBuffer = "";
|
611 |
-
fieldStart = 0;
|
612 |
-
valueStart = 0;
|
613 |
-
state = FIELD_START;
|
614 |
-
|
615 |
-
// https://bugzilla.mozilla.org/show_bug.cgi?id=428916
|
616 |
-
// Request header field Last-Event-ID is not allowed by Access-Control-Allow-Headers.
|
617 |
-
var requestURL = url;
|
618 |
-
if (url.slice(0, 5) !== "data:" &&
|
619 |
-
url.slice(0, 5) !== "blob:") {
|
620 |
-
requestURL = url + (url.indexOf("?", 0) === -1 ? "?" : "&") + "lastEventId=" + encodeURIComponent(lastEventId);
|
621 |
-
}
|
622 |
-
var requestHeaders = {};
|
623 |
-
requestHeaders["Accept"] = "text/event-stream";
|
624 |
-
if (headers != undefined) {
|
625 |
-
for (var name in headers) {
|
626 |
-
if (Object.prototype.hasOwnProperty.call(headers, name)) {
|
627 |
-
requestHeaders[name] = headers[name];
|
628 |
-
}
|
629 |
-
}
|
630 |
-
}
|
631 |
-
try {
|
632 |
-
transport.open(onStart, onProgress, onFinish, requestURL, withCredentials, requestHeaders);
|
633 |
-
} catch (error) {
|
634 |
-
close();
|
635 |
-
throw error;
|
636 |
-
}
|
637 |
-
};
|
638 |
-
|
639 |
-
es.url = url;
|
640 |
-
es.readyState = CONNECTING;
|
641 |
-
es.withCredentials = withCredentials;
|
642 |
-
es._close = close;
|
643 |
-
|
644 |
-
onTimeout();
|
645 |
-
}
|
646 |
-
|
647 |
-
EventSourcePolyfill.prototype = Object.create(EventTarget.prototype);
|
648 |
-
EventSourcePolyfill.prototype.CONNECTING = CONNECTING;
|
649 |
-
EventSourcePolyfill.prototype.OPEN = OPEN;
|
650 |
-
EventSourcePolyfill.prototype.CLOSED = CLOSED;
|
651 |
-
EventSourcePolyfill.prototype.close = function () {
|
652 |
-
this._close();
|
653 |
-
};
|
654 |
-
|
655 |
-
EventSourcePolyfill.CONNECTING = CONNECTING;
|
656 |
-
EventSourcePolyfill.OPEN = OPEN;
|
657 |
-
EventSourcePolyfill.CLOSED = CLOSED;
|
658 |
-
EventSourcePolyfill.prototype.withCredentials = undefined;
|
659 |
-
|
660 |
-
global.EventSourcePolyfill = EventSourcePolyfill;
|
661 |
-
global.NativeEventSource = NativeEventSource;
|
662 |
-
|
663 |
-
if (XMLHttpRequest != undefined && (NativeEventSource == undefined || !("withCredentials" in NativeEventSource.prototype))) {
|
664 |
-
// Why replace a native EventSource ?
|
665 |
-
// https://bugzilla.mozilla.org/show_bug.cgi?id=444328
|
666 |
-
// https://bugzilla.mozilla.org/show_bug.cgi?id=831392
|
667 |
-
// https://code.google.com/p/chromium/issues/detail?id=260144
|
668 |
-
// https://code.google.com/p/chromium/issues/detail?id=225654
|
669 |
-
// ...
|
670 |
-
global.EventSource = EventSourcePolyfill;
|
671 |
-
}
|
672 |
-
|
673 |
-
}(typeof window !== 'undefined' ? window : this));
|
1 |
+
/** @license
|
2 |
+
* eventsource.js
|
3 |
+
* Available under MIT License (MIT)
|
4 |
+
* https://github.com/Yaffle/EventSource/
|
5 |
+
*/
|
6 |
+
|
7 |
+
/*jslint indent: 2, vars: true, plusplus: true */
|
8 |
+
/*global setTimeout, clearTimeout */
|
9 |
+
|
10 |
+
(function (global) {
|
11 |
+
"use strict";
|
12 |
+
|
13 |
+
var setTimeout = global.setTimeout;
|
14 |
+
var clearTimeout = global.clearTimeout;
|
15 |
+
var XMLHttpRequest = global.XMLHttpRequest;
|
16 |
+
var XDomainRequest = global.XDomainRequest;
|
17 |
+
var NativeEventSource = global.EventSource;
|
18 |
+
var document = global.document;
|
19 |
+
|
20 |
+
if (Object.create == null) {
|
21 |
+
Object.create = function (C) {
|
22 |
+
function F(){}
|
23 |
+
F.prototype = C;
|
24 |
+
return new F();
|
25 |
+
};
|
26 |
+
}
|
27 |
+
|
28 |
+
var k = function () {
|
29 |
+
};
|
30 |
+
|
31 |
+
function XHRWrapper(xhr) {
|
32 |
+
this.withCredentials = false;
|
33 |
+
this.responseType = "";
|
34 |
+
this.readyState = 0;
|
35 |
+
this.status = 0;
|
36 |
+
this.statusText = "";
|
37 |
+
this.responseText = "";
|
38 |
+
this.onprogress = k;
|
39 |
+
this.onreadystatechange = k;
|
40 |
+
this._contentType = "";
|
41 |
+
this._xhr = xhr;
|
42 |
+
this._sendTimeout = 0;
|
43 |
+
this._abort = k;
|
44 |
+
}
|
45 |
+
|
46 |
+
XHRWrapper.prototype.open = function (method, url) {
|
47 |
+
this._abort(true);
|
48 |
+
|
49 |
+
var that = this;
|
50 |
+
var xhr = this._xhr;
|
51 |
+
var state = 1;
|
52 |
+
var timeout = 0;
|
53 |
+
|
54 |
+
this._abort = function (silent) {
|
55 |
+
if (that._sendTimeout !== 0) {
|
56 |
+
clearTimeout(that._sendTimeout);
|
57 |
+
that._sendTimeout = 0;
|
58 |
+
}
|
59 |
+
if (state === 1 || state === 2 || state === 3) {
|
60 |
+
state = 4;
|
61 |
+
xhr.onload = k;
|
62 |
+
xhr.onerror = k;
|
63 |
+
xhr.onabort = k;
|
64 |
+
xhr.onprogress = k;
|
65 |
+
xhr.onreadystatechange = k;
|
66 |
+
// IE 8 - 9: XDomainRequest#abort() does not fire any event
|
67 |
+
// Opera < 10: XMLHttpRequest#abort() does not fire any event
|
68 |
+
xhr.abort();
|
69 |
+
if (timeout !== 0) {
|
70 |
+
clearTimeout(timeout);
|
71 |
+
timeout = 0;
|
72 |
+
}
|
73 |
+
if (!silent) {
|
74 |
+
that.readyState = 4;
|
75 |
+
that.onreadystatechange();
|
76 |
+
}
|
77 |
+
}
|
78 |
+
state = 0;
|
79 |
+
};
|
80 |
+
|
81 |
+
var onStart = function () {
|
82 |
+
if (state === 1) {
|
83 |
+
//state = 2;
|
84 |
+
var status = 0;
|
85 |
+
var statusText = "";
|
86 |
+
var contentType = undefined;
|
87 |
+
if (!("contentType" in xhr)) {
|
88 |
+
try {
|
89 |
+
status = xhr.status;
|
90 |
+
statusText = xhr.statusText;
|
91 |
+
contentType = xhr.getResponseHeader("Content-Type");
|
92 |
+
} catch (error) {
|
93 |
+
// IE < 10 throws exception for `xhr.status` when xhr.readyState === 2 || xhr.readyState === 3
|
94 |
+
// Opera < 11 throws exception for `xhr.status` when xhr.readyState === 2
|
95 |
+
// https://bugs.webkit.org/show_bug.cgi?id=29121
|
96 |
+
status = 0;
|
97 |
+
statusText = "";
|
98 |
+
contentType = undefined;
|
99 |
+
// Firefox < 14, Chrome ?, Safari ?
|
100 |
+
// https://bugs.webkit.org/show_bug.cgi?id=29658
|
101 |
+
// https://bugs.webkit.org/show_bug.cgi?id=77854
|
102 |
+
}
|
103 |
+
} else {
|
104 |
+
status = 200;
|
105 |
+
statusText = "OK";
|
106 |
+
contentType = xhr.contentType;
|
107 |
+
}
|
108 |
+
if (status !== 0) {
|
109 |
+
state = 2;
|
110 |
+
that.readyState = 2;
|
111 |
+
that.status = status;
|
112 |
+
that.statusText = statusText;
|
113 |
+
that._contentType = contentType;
|
114 |
+
that.onreadystatechange();
|
115 |
+
}
|
116 |
+
}
|
117 |
+
};
|
118 |
+
var onProgress = function () {
|
119 |
+
onStart();
|
120 |
+
if (state === 2 || state === 3) {
|
121 |
+
state = 3;
|
122 |
+
var responseText = "";
|
123 |
+
try {
|
124 |
+
responseText = xhr.responseText;
|
125 |
+
} catch (error) {
|
126 |
+
// IE 8 - 9 with XMLHttpRequest
|
127 |
+
}
|
128 |
+
that.readyState = 3;
|
129 |
+
that.responseText = responseText;
|
130 |
+
that.onprogress();
|
131 |
+
}
|
132 |
+
};
|
133 |
+
var onFinish = function () {
|
134 |
+
// Firefox 52 fires "readystatechange" (xhr.readyState === 4) without final "readystatechange" (xhr.readyState === 3)
|
135 |
+
// IE 8 fires "onload" without "onprogress"
|
136 |
+
onProgress();
|
137 |
+
if (state === 1 || state === 2 || state === 3) {
|
138 |
+
state = 4;
|
139 |
+
if (timeout !== 0) {
|
140 |
+
clearTimeout(timeout);
|
141 |
+
timeout = 0;
|
142 |
+
}
|
143 |
+
that.readyState = 4;
|
144 |
+
that.onreadystatechange();
|
145 |
+
}
|
146 |
+
};
|
147 |
+
var onReadyStateChange = function () {
|
148 |
+
if (xhr != undefined) { // Opera 12
|
149 |
+
if (xhr.readyState === 4) {
|
150 |
+
onFinish();
|
151 |
+
} else if (xhr.readyState === 3) {
|
152 |
+
onProgress();
|
153 |
+
} else if (xhr.readyState === 2) {
|
154 |
+
onStart();
|
155 |
+
}
|
156 |
+
}
|
157 |
+
};
|
158 |
+
var onTimeout = function () {
|
159 |
+
timeout = setTimeout(function () {
|
160 |
+
onTimeout();
|
161 |
+
}, 500);
|
162 |
+
if (xhr.readyState === 3) {
|
163 |
+
onProgress();
|
164 |
+
}
|
165 |
+
};
|
166 |
+
|
167 |
+
// XDomainRequest#abort removes onprogress, onerror, onload
|
168 |
+
xhr.onload = onFinish;
|
169 |
+
xhr.onerror = onFinish;
|
170 |
+
// improper fix to match Firefox behaviour, but it is better than just ignore abort
|
171 |
+
// see https://bugzilla.mozilla.org/show_bug.cgi?id=768596
|
172 |
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=880200
|
173 |
+
// https://code.google.com/p/chromium/issues/detail?id=153570
|
174 |
+
// IE 8 fires "onload" without "onprogress
|
175 |
+
xhr.onabort = onFinish;
|
176 |
+
|
177 |
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=736723
|
178 |
+
if (!("sendAsBinary" in XMLHttpRequest.prototype) && !("mozAnon" in XMLHttpRequest.prototype)) {
|
179 |
+
xhr.onprogress = onProgress;
|
180 |
+
}
|
181 |
+
|
182 |
+
// IE 8 - 9 (XMLHTTPRequest)
|
183 |
+
// Opera < 12
|
184 |
+
// Firefox < 3.5
|
185 |
+
// Firefox 3.5 - 3.6 - ? < 9.0
|
186 |
+
// onprogress is not fired sometimes or delayed
|
187 |
+
// see also #64
|
188 |
+
xhr.onreadystatechange = onReadyStateChange;
|
189 |
+
|
190 |
+
if ("contentType" in xhr) {
|
191 |
+
url += (url.indexOf("?", 0) === -1 ? "?" : "&") + "padding=true";
|
192 |
+
}
|
193 |
+
xhr.open(method, url, true);
|
194 |
+
|
195 |
+
if ("readyState" in xhr) {
|
196 |
+
// workaround for Opera 12 issue with "progress" events
|
197 |
+
// #91
|
198 |
+
timeout = setTimeout(function () {
|
199 |
+
onTimeout();
|
200 |
+
}, 0);
|
201 |
+
}
|
202 |
+
};
|
203 |
+
XHRWrapper.prototype.abort = function () {
|
204 |
+
this._abort(false);
|
205 |
+
};
|
206 |
+
XHRWrapper.prototype.getResponseHeader = function (name) {
|
207 |
+
return this._contentType;
|
208 |
+
};
|
209 |
+
XHRWrapper.prototype.setRequestHeader = function (name, value) {
|
210 |
+
var xhr = this._xhr;
|
211 |
+
if ("setRequestHeader" in xhr) {
|
212 |
+
xhr.setRequestHeader(name, value);
|
213 |
+
}
|
214 |
+
};
|
215 |
+
XHRWrapper.prototype.send = function () {
|
216 |
+
// loading indicator in Safari < ? (6), Chrome < 14, Firefox
|
217 |
+
if (!("ontimeout" in XMLHttpRequest.prototype) &&
|
218 |
+
document != undefined &&
|
219 |
+
document.readyState != undefined &&
|
220 |
+
document.readyState !== "complete") {
|
221 |
+
var that = this;
|
222 |
+
that._sendTimeout = setTimeout(function () {
|
223 |
+
that._sendTimeout = 0;
|
224 |
+
that.send();
|
225 |
+
}, 4);
|
226 |
+
return;
|
227 |
+
}
|
228 |
+
|
229 |
+
var xhr = this._xhr;
|
230 |
+
// withCredentials should be set after "open" for Safari and Chrome (< 19 ?)
|
231 |
+
xhr.withCredentials = this.withCredentials;
|
232 |
+
xhr.responseType = this.responseType;
|
233 |
+
try {
|
234 |
+
// xhr.send(); throws "Not enough arguments" in Firefox 3.0
|
235 |
+
xhr.send(undefined);
|
236 |
+
} catch (error1) {
|
237 |
+
// Safari 5.1.7, Opera 12
|
238 |
+
throw error1;
|
239 |
+
}
|
240 |
+
};
|
241 |
+
|
242 |
+
function XHRTransport(xhr) {
|
243 |
+
this._xhr = new XHRWrapper(xhr);
|
244 |
+
}
|
245 |
+
|
246 |
+
XHRTransport.prototype.open = function (onStartCallback, onProgressCallback, onFinishCallback, url, withCredentials, headers) {
|
247 |
+
var xhr = this._xhr;
|
248 |
+
xhr.open("GET", url);
|
249 |
+
var offset = 0;
|
250 |
+
xhr.onprogress = function () {
|
251 |
+
var responseText = xhr.responseText;
|
252 |
+
var chunk = responseText.slice(offset);
|
253 |
+
offset += chunk.length;
|
254 |
+
onProgressCallback(chunk);
|
255 |
+
};
|
256 |
+
xhr.onreadystatechange = function () {
|
257 |
+
if (xhr.readyState === 2) {
|
258 |
+
var status = xhr.status;
|
259 |
+
var statusText = xhr.statusText;
|
260 |
+
var contentType = xhr.getResponseHeader("Content-Type");
|
261 |
+
onStartCallback(status, statusText, contentType);
|
262 |
+
} else if (xhr.readyState === 4) {
|
263 |
+
onFinishCallback();
|
264 |
+
}
|
265 |
+
};
|
266 |
+
xhr.withCredentials = withCredentials;
|
267 |
+
xhr.responseType = "text";
|
268 |
+
for (var name in headers) {
|
269 |
+
if (Object.prototype.hasOwnProperty.call(headers, name)) {
|
270 |
+
xhr.setRequestHeader(name, headers[name]);
|
271 |
+
}
|
272 |
+
}
|
273 |
+
xhr.send();
|
274 |
+
};
|
275 |
+
|
276 |
+
XHRTransport.prototype.cancel = function () {
|
277 |
+
var xhr = this._xhr;
|
278 |
+
xhr.abort();
|
279 |
+
};
|
280 |
+
|
281 |
+
function EventTarget() {
|
282 |
+
this._listeners = Object.create(null);
|
283 |
+
}
|
284 |
+
|
285 |
+
function throwError(e) {
|
286 |
+
setTimeout(function () {
|
287 |
+
throw e;
|
288 |
+
}, 0);
|
289 |
+
}
|
290 |
+
|
291 |
+
EventTarget.prototype.dispatchEvent = function (event) {
|
292 |
+
event.target = this;
|
293 |
+
var typeListeners = this._listeners[event.type];
|
294 |
+
if (typeListeners != undefined) {
|
295 |
+
var length = typeListeners.length;
|
296 |
+
for (var i = 0; i < length; i += 1) {
|
297 |
+
var listener = typeListeners[i];
|
298 |
+
try {
|
299 |
+
if (typeof listener.handleEvent === "function") {
|
300 |
+
listener.handleEvent(event);
|
301 |
+
} else {
|
302 |
+
listener.call(this, event);
|
303 |
+
}
|
304 |
+
} catch (e) {
|
305 |
+
throwError(e);
|
306 |
+
}
|
307 |
+
}
|
308 |
+
}
|
309 |
+
};
|
310 |
+
EventTarget.prototype.addEventListener = function (type, listener) {
|
311 |
+
type = String(type);
|
312 |
+
var listeners = this._listeners;
|
313 |
+
var typeListeners = listeners[type];
|
314 |
+
if (typeListeners == undefined) {
|
315 |
+
typeListeners = [];
|
316 |
+
listeners[type] = typeListeners;
|
317 |
+
}
|
318 |
+
var found = false;
|
319 |
+
for (var i = 0; i < typeListeners.length; i += 1) {
|
320 |
+
if (typeListeners[i] === listener) {
|
321 |
+
found = true;
|
322 |
+
}
|
323 |
+
}
|
324 |
+
if (!found) {
|
325 |
+
typeListeners.push(listener);
|
326 |
+
}
|
327 |
+
};
|
328 |
+
EventTarget.prototype.removeEventListener = function (type, listener) {
|
329 |
+
type = String(type);
|
330 |
+
var listeners = this._listeners;
|
331 |
+
var typeListeners = listeners[type];
|
332 |
+
if (typeListeners != undefined) {
|
333 |
+
var filtered = [];
|
334 |
+
for (var i = 0; i < typeListeners.length; i += 1) {
|
335 |
+
if (typeListeners[i] !== listener) {
|
336 |
+
filtered.push(typeListeners[i]);
|
337 |
+
}
|
338 |
+
}
|
339 |
+
if (filtered.length === 0) {
|
340 |
+
delete listeners[type];
|
341 |
+
} else {
|
342 |
+
listeners[type] = filtered;
|
343 |
+
}
|
344 |
+
}
|
345 |
+
};
|
346 |
+
|
347 |
+
function Event(type) {
|
348 |
+
this.type = type;
|
349 |
+
this.target = undefined;
|
350 |
+
}
|
351 |
+
|
352 |
+
function MessageEvent(type, options) {
|
353 |
+
Event.call(this, type);
|
354 |
+
this.data = options.data;
|
355 |
+
this.lastEventId = options.lastEventId;
|
356 |
+
}
|
357 |
+
|
358 |
+
MessageEvent.prototype = Object.create(Event.prototype);
|
359 |
+
|
360 |
+
var WAITING = -1;
|
361 |
+
var CONNECTING = 0;
|
362 |
+
var OPEN = 1;
|
363 |
+
var CLOSED = 2;
|
364 |
+
|
365 |
+
var AFTER_CR = -1;
|
366 |
+
var FIELD_START = 0;
|
367 |
+
var FIELD = 1;
|
368 |
+
var VALUE_START = 2;
|
369 |
+
var VALUE = 3;
|
370 |
+
|
371 |
+
var contentTypeRegExp = /^text\/event\-stream;?(\s*charset\=utf\-8)?$/i;
|
372 |
+
|
373 |
+
var MINIMUM_DURATION = 1000;
|
374 |
+
var MAXIMUM_DURATION = 18000000;
|
375 |
+
|
376 |
+
var parseDuration = function (value, def) {
|
377 |
+
var n = parseInt(value, 10);
|
378 |
+
if (n !== n) {
|
379 |
+
n = def;
|
380 |
+
}
|
381 |
+
return clampDuration(n);
|
382 |
+
};
|
383 |
+
var clampDuration = function (n) {
|
384 |
+
return Math.min(Math.max(n, MINIMUM_DURATION), MAXIMUM_DURATION);
|
385 |
+
};
|
386 |
+
|
387 |
+
var fire = function (that, f, event) {
|
388 |
+
try {
|
389 |
+
if (typeof f === "function") {
|
390 |
+
f.call(that, event);
|
391 |
+
}
|
392 |
+
} catch (e) {
|
393 |
+
throwError(e);
|
394 |
+
}
|
395 |
+
};
|
396 |
+
|
397 |
+
function EventSourcePolyfill(url, options) {
|
398 |
+
EventTarget.call(this);
|
399 |
+
|
400 |
+
this.onopen = undefined;
|
401 |
+
this.onmessage = undefined;
|
402 |
+
this.onerror = undefined;
|
403 |
+
|
404 |
+
this.url = undefined;
|
405 |
+
this.readyState = undefined;
|
406 |
+
this.withCredentials = undefined;
|
407 |
+
|
408 |
+
this._close = undefined;
|
409 |
+
|
410 |
+
start(this, url, options);
|
411 |
+
}
|
412 |
+
|
413 |
+
function start(es, url, options) {
|
414 |
+
url = String(url);
|
415 |
+
var withCredentials = options != undefined && Boolean(options.withCredentials);
|
416 |
+
|
417 |
+
var initialRetry = clampDuration(1000);
|
418 |
+
var heartbeatTimeout = clampDuration(45000);
|
419 |
+
|
420 |
+
var lastEventId = "";
|
421 |
+
var retry = initialRetry;
|
422 |
+
var wasActivity = false;
|
423 |
+
var headers = options != undefined && options.headers != undefined ? JSON.parse(JSON.stringify(options.headers)) : undefined;
|
424 |
+
var CurrentTransport = options != undefined && options.Transport != undefined ? options.Transport : (XDomainRequest != undefined ? XDomainRequest : XMLHttpRequest);
|
425 |
+
var transport = new XHRTransport(new CurrentTransport());
|
426 |
+
var timeout = 0;
|
427 |
+
var currentState = WAITING;
|
428 |
+
var dataBuffer = "";
|
429 |
+
var lastEventIdBuffer = "";
|
430 |
+
var eventTypeBuffer = "";
|
431 |
+
|
432 |
+
var textBuffer = "";
|
433 |
+
var state = FIELD_START;
|
434 |
+
var fieldStart = 0;
|
435 |
+
var valueStart = 0;
|
436 |
+
|
437 |
+
var onStart = function (status, statusText, contentType) {
|
438 |
+
if (currentState === CONNECTING) {
|
439 |
+
if (status === 200 && contentType != undefined && contentTypeRegExp.test(contentType)) {
|
440 |
+
currentState = OPEN;
|
441 |
+
wasActivity = true;
|
442 |
+
retry = initialRetry;
|
443 |
+
es.readyState = OPEN;
|
444 |
+
var event = new Event("open");
|
445 |
+
es.dispatchEvent(event);
|
446 |
+
fire(es, es.onopen, event);
|
447 |
+
} else {
|
448 |
+
var message = "";
|
449 |
+
if (status !== 200) {
|
450 |
+
if (statusText) {
|
451 |
+
statusText = statusText.replace(/\s+/g, " ");
|
452 |
+
}
|
453 |
+
message = "EventSource's response has a status " + status + " " + statusText + " that is not 200. Aborting the connection.";
|
454 |
+
} else {
|
455 |
+
message = "EventSource's response has a Content-Type specifying an unsupported type: " + (contentType == undefined ? "-" : contentType.replace(/\s+/g, " ")) + ". Aborting the connection.";
|
456 |
+
}
|
457 |
+
throwError(new Error(message));
|
458 |
+
close();
|
459 |
+
var event = new Event("error");
|
460 |
+
es.dispatchEvent(event);
|
461 |
+
fire(es, es.onerror, event);
|
462 |
+
}
|
463 |
+
}
|
464 |
+
};
|
465 |
+
|
466 |
+
var onProgress = function (textChunk) {
|
467 |
+
if (currentState === OPEN) {
|
468 |
+
var n = -1;
|
469 |
+
for (var i = 0; i < textChunk.length; i += 1) {
|
470 |
+
var c = textChunk.charCodeAt(i);
|
471 |
+
if (c === "\n".charCodeAt(0) || c === "\r".charCodeAt(0)) {
|
472 |
+
n = i;
|
473 |
+
}
|
474 |
+
}
|
475 |
+
var chunk = (n !== -1 ? textBuffer : "") + textChunk.slice(0, n + 1);
|
476 |
+
textBuffer = (n === -1 ? textBuffer : "") + textChunk.slice(n + 1);
|
477 |
+
if (chunk !== "") {
|
478 |
+
wasActivity = true;
|
479 |
+
}
|
480 |
+
for (var position = 0; position < chunk.length; position += 1) {
|
481 |
+
var c = chunk.charCodeAt(position);
|
482 |
+
if (state === AFTER_CR && c === "\n".charCodeAt(0)) {
|
483 |
+
state = FIELD_START;
|
484 |
+
} else {
|
485 |
+
if (state === AFTER_CR) {
|
486 |
+
state = FIELD_START;
|
487 |
+
}
|
488 |
+
if (c === "\r".charCodeAt(0) || c === "\n".charCodeAt(0)) {
|
489 |
+
if (state !== FIELD_START) {
|
490 |
+
if (state === FIELD) {
|
491 |
+
valueStart = position + 1;
|
492 |
+
}
|
493 |
+
var field = chunk.slice(fieldStart, valueStart - 1);
|
494 |
+
var value = chunk.slice(valueStart + (valueStart < position && chunk.charCodeAt(valueStart) === " ".charCodeAt(0) ? 1 : 0), position);
|
495 |
+
if (field === "data") {
|
496 |
+
dataBuffer += "\n";
|
497 |
+
dataBuffer += value;
|
498 |
+
} else if (field === "id") {
|
499 |
+
lastEventIdBuffer = value;
|
500 |
+
} else if (field === "event") {
|
501 |
+
eventTypeBuffer = value;
|
502 |
+
} else if (field === "retry") {
|
503 |
+
initialRetry = parseDuration(value, initialRetry);
|
504 |
+
retry = initialRetry;
|
505 |
+
} else if (field === "heartbeatTimeout") {
|
506 |
+
heartbeatTimeout = parseDuration(value, heartbeatTimeout);
|
507 |
+
if (timeout !== 0) {
|
508 |
+
clearTimeout(timeout);
|
509 |
+
timeout = setTimeout(function () {
|
510 |
+
onTimeout();
|
511 |
+
}, heartbeatTimeout);
|
512 |
+
}
|
513 |
+
}
|
514 |
+
}
|
515 |
+
if (state === FIELD_START) {
|
516 |
+
if (dataBuffer !== "") {
|
517 |
+
lastEventId = lastEventIdBuffer;
|
518 |
+
if (eventTypeBuffer === "") {
|
519 |
+
eventTypeBuffer = "message";
|
520 |
+
}
|
521 |
+
var event = new MessageEvent(eventTypeBuffer, {
|
522 |
+
data: dataBuffer.slice(1),
|
523 |
+
lastEventId: lastEventIdBuffer
|
524 |
+
});
|
525 |
+
es.dispatchEvent(event);
|
526 |
+
if (eventTypeBuffer === "message") {
|
527 |
+
fire(es, es.onmessage, event);
|
528 |
+
}
|
529 |
+
if (currentState === CLOSED) {
|
530 |
+
return;
|
531 |
+
}
|
532 |
+
}
|
533 |
+
dataBuffer = "";
|
534 |
+
eventTypeBuffer = "";
|
535 |
+
}
|
536 |
+
state = c === "\r".charCodeAt(0) ? AFTER_CR : FIELD_START;
|
537 |
+
} else {
|
538 |
+
if (state === FIELD_START) {
|
539 |
+
fieldStart = position;
|
540 |
+
state = FIELD;
|
541 |
+
}
|
542 |
+
if (state === FIELD) {
|
543 |
+
if (c === ":".charCodeAt(0)) {
|
544 |
+
valueStart = position + 1;
|
545 |
+
state = VALUE_START;
|
546 |
+
}
|
547 |
+
} else if (state === VALUE_START) {
|
548 |
+
state = VALUE;
|
549 |
+
}
|
550 |
+
}
|
551 |
+
}
|
552 |
+
}
|
553 |
+
}
|
554 |
+
};
|
555 |
+
|
556 |
+
var onFinish = function () {
|
557 |
+
if (currentState === OPEN || currentState === CONNECTING) {
|
558 |
+
currentState = WAITING;
|
559 |
+
if (timeout !== 0) {
|
560 |
+
clearTimeout(timeout);
|
561 |
+
timeout = 0;
|
562 |
+
}
|
563 |
+
timeout = setTimeout(function () {
|
564 |
+
onTimeout();
|
565 |
+
}, retry);
|
566 |
+
retry = clampDuration(Math.min(initialRetry * 16, retry * 2));
|
567 |
+
|
568 |
+
es.readyState = CONNECTING;
|
569 |
+
var event = new Event("error");
|
570 |
+
es.dispatchEvent(event);
|
571 |
+
fire(es, es.onerror, event);
|
572 |
+
}
|
573 |
+
};
|
574 |
+
|
575 |
+
var close = function () {
|
576 |
+
currentState = CLOSED;
|
577 |
+
transport.cancel();
|
578 |
+
if (timeout !== 0) {
|
579 |
+
clearTimeout(timeout);
|
580 |
+
timeout = 0;
|
581 |
+
}
|
582 |
+
es.readyState = CLOSED;
|
583 |
+
};
|
584 |
+
|
585 |
+
var onTimeout = function () {
|
586 |
+
timeout = 0;
|
587 |
+
|
588 |
+
if (currentState !== WAITING) {
|
589 |
+
if (!wasActivity) {
|
590 |
+
throwError(new Error("No activity within " + heartbeatTimeout + " milliseconds. Reconnecting."));
|
591 |
+
transport.cancel();
|
592 |
+
} else {
|
593 |
+
wasActivity = false;
|
594 |
+
timeout = setTimeout(function () {
|
595 |
+
onTimeout();
|
596 |
+
}, heartbeatTimeout);
|
597 |
+
}
|
598 |
+
return;
|
599 |
+
}
|
600 |
+
|
601 |
+
wasActivity = false;
|
602 |
+
timeout = setTimeout(function () {
|
603 |
+
onTimeout();
|
604 |
+
}, heartbeatTimeout);
|
605 |
+
|
606 |
+
currentState = CONNECTING;
|
607 |
+
dataBuffer = "";
|
608 |
+
eventTypeBuffer = "";
|
609 |
+
lastEventIdBuffer = lastEventId;
|
610 |
+
textBuffer = "";
|
611 |
+
fieldStart = 0;
|
612 |
+
valueStart = 0;
|
613 |
+
state = FIELD_START;
|
614 |
+
|
615 |
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=428916
|
616 |
+
// Request header field Last-Event-ID is not allowed by Access-Control-Allow-Headers.
|
617 |
+
var requestURL = url;
|
618 |
+
if (url.slice(0, 5) !== "data:" &&
|
619 |
+
url.slice(0, 5) !== "blob:") {
|
620 |
+
requestURL = url + (url.indexOf("?", 0) === -1 ? "?" : "&") + "lastEventId=" + encodeURIComponent(lastEventId);
|
621 |
+
}
|
622 |
+
var requestHeaders = {};
|
623 |
+
requestHeaders["Accept"] = "text/event-stream";
|
624 |
+
if (headers != undefined) {
|
625 |
+
for (var name in headers) {
|
626 |
+
if (Object.prototype.hasOwnProperty.call(headers, name)) {
|
627 |
+
requestHeaders[name] = headers[name];
|
628 |
+
}
|
629 |
+
}
|
630 |
+
}
|
631 |
+
try {
|
632 |
+
transport.open(onStart, onProgress, onFinish, requestURL, withCredentials, requestHeaders);
|
633 |
+
} catch (error) {
|
634 |
+
close();
|
635 |
+
throw error;
|
636 |
+
}
|
637 |
+
};
|
638 |
+
|
639 |
+
es.url = url;
|
640 |
+
es.readyState = CONNECTING;
|
641 |
+
es.withCredentials = withCredentials;
|
642 |
+
es._close = close;
|
643 |
+
|
644 |
+
onTimeout();
|
645 |
+
}
|
646 |
+
|
647 |
+
EventSourcePolyfill.prototype = Object.create(EventTarget.prototype);
|
648 |
+
EventSourcePolyfill.prototype.CONNECTING = CONNECTING;
|
649 |
+
EventSourcePolyfill.prototype.OPEN = OPEN;
|
650 |
+
EventSourcePolyfill.prototype.CLOSED = CLOSED;
|
651 |
+
EventSourcePolyfill.prototype.close = function () {
|
652 |
+
this._close();
|
653 |
+
};
|
654 |
+
|
655 |
+
EventSourcePolyfill.CONNECTING = CONNECTING;
|
656 |
+
EventSourcePolyfill.OPEN = OPEN;
|
657 |
+
EventSourcePolyfill.CLOSED = CLOSED;
|
658 |
+
EventSourcePolyfill.prototype.withCredentials = undefined;
|
659 |
+
|
660 |
+
global.EventSourcePolyfill = EventSourcePolyfill;
|
661 |
+
global.NativeEventSource = NativeEventSource;
|
662 |
+
|
663 |
+
if (XMLHttpRequest != undefined && (NativeEventSource == undefined || !("withCredentials" in NativeEventSource.prototype))) {
|
664 |
+
// Why replace a native EventSource ?
|
665 |
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=444328
|
666 |
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=831392
|
667 |
+
// https://code.google.com/p/chromium/issues/detail?id=260144
|
668 |
+
// https://code.google.com/p/chromium/issues/detail?id=225654
|
669 |
+
// ...
|
670 |
+
global.EventSource = EventSourcePolyfill;
|
671 |
+
}
|
672 |
+
|
673 |
+
}(typeof window !== 'undefined' ? window : this));
|
inc/assets/js/eventsource.min.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
-
/** @license
|
2 |
-
* eventsource.js
|
3 |
-
* Available under MIT License (MIT)
|
4 |
-
* https://github.com/Yaffle/EventSource/
|
5 |
-
*/
|
6 |
Â
!function(a){"use strict";function b(a){this.withCredentials=!1,this.responseType="",this.readyState=0,this.status=0,this.statusText="",this.responseText="",this.onprogress=p,this.onreadystatechange=p,this._contentType="",this._xhr=a,this._sendTimeout=0,this._abort=p}function c(a){this._xhr=new b(a)}function d(){this._listeners=Object.create(null)}function e(a){j(function(){throw a},0)}function f(a){this.type=a,this.target=void 0}function g(a,b){f.call(this,a),this.data=b.data,this.lastEventId=b.lastEventId}function h(a,b){d.call(this),this.onopen=void 0,this.onmessage=void 0,this.onerror=void 0,this.url=void 0,this.readyState=void 0,this.withCredentials=void 0,this._close=void 0,i(this,a,b)}function i(a,b,d){b=String(b);var h=void 0!=d&&Boolean(d.withCredentials),i=D(1e3),n=D(45e3),o="",p=i,A=!1,B=void 0!=d&&void 0!=d.headers?JSON.parse(JSON.stringify(d.headers)):void 0,F=void 0!=d&&void 0!=d.Transport?d.Transport:void 0!=m?m:l,G=new c(new F),H=0,I=q,J="",K="",L="",M="",N=v,O=0,P=0,Q=function(b,c,d){if(I===r)if(200===b&&void 0!=d&&z.test(d)){I=s,A=!0,p=i,a.readyState=s;var g=new f("open");a.dispatchEvent(g),E(a,a.onopen,g)}else{var h="";200!==b?(c&&(c=c.replace(/\s+/g," ")),h="EventSource's response has a status "+b+" "+c+" that is not 200. Aborting the connection."):h="EventSource's response has a Content-Type specifying an unsupported type: "+(void 0==d?"-":d.replace(/\s+/g," "))+". Aborting the connection.",e(new Error(h)),T();var g=new f("error");a.dispatchEvent(g),E(a,a.onerror,g)}},R=function(b){if(I===s){for(var c=-1,d=0;d<b.length;d+=1){var e=b.charCodeAt(d);(e==="\n".charCodeAt(0)||e==="\r".charCodeAt(0))&&(c=d)}var f=(-1!==c?M:"")+b.slice(0,c+1);M=(-1===c?M:"")+b.slice(c+1),""!==f&&(A=!0);for(var h=0;h<f.length;h+=1){var e=f.charCodeAt(h);if(N===u&&e==="\n".charCodeAt(0))N=v;else if(N===u&&(N=v),e==="\r".charCodeAt(0)||e==="\n".charCodeAt(0)){if(N!==v){N===w&&(P=h+1);var l=f.slice(O,P-1),m=f.slice(P+(h>P&&f.charCodeAt(P)===" ".charCodeAt(0)?1:0),h);"data"===l?(J+="\n",J+=m):"id"===l?K=m:"event"===l?L=m:"retry"===l?(i=C(m,i),p=i):"heartbeatTimeout"===l&&(n=C(m,n),0!==H&&(k(H),H=j(function(){U()},n)))}if(N===v){if(""!==J){o=K,""===L&&(L="message");var q=new g(L,{data:J.slice(1),lastEventId:K});if(a.dispatchEvent(q),"message"===L&&E(a,a.onmessage,q),I===t)return}J="",L=""}N=e==="\r".charCodeAt(0)?u:v}else N===v&&(O=h,N=w),N===w?e===":".charCodeAt(0)&&(P=h+1,N=x):N===x&&(N=y)}}},S=function(){if(I===s||I===r){I=q,0!==H&&(k(H),H=0),H=j(function(){U()},p),p=D(Math.min(16*i,2*p)),a.readyState=r;var b=new f("error");a.dispatchEvent(b),E(a,a.onerror,b)}},T=function(){I=t,G.cancel(),0!==H&&(k(H),H=0),a.readyState=t},U=function(){if(H=0,I!==q)return void(A?(A=!1,H=j(function(){U()},n)):(e(new Error("No activity within "+n+" milliseconds. Reconnecting.")),G.cancel()));A=!1,H=j(function(){U()},n),I=r,J="",L="",K=o,M="",O=0,P=0,N=v;var a=b;"data:"!==b.slice(0,5)&&"blob:"!==b.slice(0,5)&&(a=b+(-1===b.indexOf("?",0)?"?":"&")+"lastEventId="+encodeURIComponent(o));var c={};if(c.Accept="text/event-stream",void 0!=B)for(var d in B)Object.prototype.hasOwnProperty.call(B,d)&&(c[d]=B[d]);try{G.open(Q,R,S,a,h,c)}catch(f){throw T(),f}};a.url=b,a.readyState=r,a.withCredentials=h,a._close=T,U()}var j=a.setTimeout,k=a.clearTimeout,l=a.XMLHttpRequest,m=a.XDomainRequest,n=a.EventSource,o=a.document;null==Object.create&&(Object.create=function(a){function b(){}return b.prototype=a,new b});var p=function(){};b.prototype.open=function(a,b){this._abort(!0);var c=this,d=this._xhr,e=1,f=0;this._abort=function(a){0!==c._sendTimeout&&(k(c._sendTimeout),c._sendTimeout=0),(1===e||2===e||3===e)&&(e=4,d.onload=p,d.onerror=p,d.onabort=p,d.onprogress=p,d.onreadystatechange=p,d.abort(),0!==f&&(k(f),f=0),a||(c.readyState=4,c.onreadystatechange())),e=0};var g=function(){if(1===e){var a=0,b="",f=void 0;if("contentType"in d)a=200,b="OK",f=d.contentType;else try{a=d.status,b=d.statusText,f=d.getResponseHeader("Content-Type")}catch(g){a=0,b="",f=void 0}0!==a&&(e=2,c.readyState=2,c.status=a,c.statusText=b,c._contentType=f,c.onreadystatechange())}},h=function(){if(g(),2===e||3===e){e=3;var a="";try{a=d.responseText}catch(b){}c.readyState=3,c.responseText=a,c.onprogress()}},i=function(){h(),(1===e||2===e||3===e)&&(e=4,0!==f&&(k(f),f=0),c.readyState=4,c.onreadystatechange())},m=function(){void 0!=d&&(4===d.readyState?i():3===d.readyState?h():2===d.readyState&&g())},n=function(){f=j(function(){n()},500),3===d.readyState&&h()};d.onload=i,d.onerror=i,d.onabort=i,"sendAsBinary"in l.prototype||"mozAnon"in l.prototype||(d.onprogress=h),d.onreadystatechange=m,"contentType"in d&&(b+=(-1===b.indexOf("?",0)?"?":"&")+"padding=true"),d.open(a,b,!0),"readyState"in d&&(f=j(function(){n()},0))},b.prototype.abort=function(){this._abort(!1)},b.prototype.getResponseHeader=function(a){return this._contentType},b.prototype.setRequestHeader=function(a,b){var c=this._xhr;"setRequestHeader"in c&&c.setRequestHeader(a,b)},b.prototype.send=function(){if(!("ontimeout"in l.prototype)&&void 0!=o&&void 0!=o.readyState&&"complete"!==o.readyState){var a=this;return void(a._sendTimeout=j(function(){a._sendTimeout=0,a.send()},4))}var b=this._xhr;b.withCredentials=this.withCredentials,b.responseType=this.responseType;try{b.send(void 0)}catch(c){throw c}},c.prototype.open=function(a,b,c,d,e,f){var g=this._xhr;g.open("GET",d);var h=0;g.onprogress=function(){var a=g.responseText,c=a.slice(h);h+=c.length,b(c)},g.onreadystatechange=function(){if(2===g.readyState){var b=g.status,d=g.statusText,e=g.getResponseHeader("Content-Type");a(b,d,e)}else 4===g.readyState&&c()},g.withCredentials=e,g.responseType="text";for(var i in f)Object.prototype.hasOwnProperty.call(f,i)&&g.setRequestHeader(i,f[i]);g.send()},c.prototype.cancel=function(){var a=this._xhr;a.abort()},d.prototype.dispatchEvent=function(a){a.target=this;var b=this._listeners[a.type];if(void 0!=b)for(var c=b.length,d=0;c>d;d+=1){var f=b[d];try{"function"==typeof f.handleEvent?f.handleEvent(a):f.call(this,a)}catch(g){e(g)}}},d.prototype.addEventListener=function(a,b){a=String(a);var c=this._listeners,d=c[a];void 0==d&&(d=[],c[a]=d);for(var e=!1,f=0;f<d.length;f+=1)d[f]===b&&(e=!0);e||d.push(b)},d.prototype.removeEventListener=function(a,b){a=String(a);var c=this._listeners,d=c[a];if(void 0!=d){for(var e=[],f=0;f<d.length;f+=1)d[f]!==b&&e.push(d[f]);0===e.length?delete c[a]:c[a]=e}},g.prototype=Object.create(f.prototype);var q=-1,r=0,s=1,t=2,u=-1,v=0,w=1,x=2,y=3,z=/^text\/event\-stream;?(\s*charset\=utf\-8)?$/i,A=1e3,B=18e6,C=function(a,b){var c=parseInt(a,10);return c!==c&&(c=b),D(c)},D=function(a){return Math.min(Math.max(a,A),B)},E=function(a,b,c){try{"function"==typeof b&&b.call(a,c)}catch(d){e(d)}};h.prototype=Object.create(d.prototype),h.prototype.CONNECTING=r,h.prototype.OPEN=s,h.prototype.CLOSED=t,h.prototype.close=function(){this._close()},h.CONNECTING=r,h.OPEN=s,h.CLOSED=t,h.prototype.withCredentials=void 0,a.EventSourcePolyfill=h,a.NativeEventSource=n,void 0==l||void 0!=n&&"withCredentials"in n.prototype||(a.EventSource=h)}("undefined"!=typeof window?window:this);
|
1 |
+
/** @license
|
2 |
+
* eventsource.js
|
3 |
+
* Available under MIT License (MIT)
|
4 |
+
* https://github.com/Yaffle/EventSource/
|
5 |
+
*/
|
6 |
Â
!function(a){"use strict";function b(a){this.withCredentials=!1,this.responseType="",this.readyState=0,this.status=0,this.statusText="",this.responseText="",this.onprogress=p,this.onreadystatechange=p,this._contentType="",this._xhr=a,this._sendTimeout=0,this._abort=p}function c(a){this._xhr=new b(a)}function d(){this._listeners=Object.create(null)}function e(a){j(function(){throw a},0)}function f(a){this.type=a,this.target=void 0}function g(a,b){f.call(this,a),this.data=b.data,this.lastEventId=b.lastEventId}function h(a,b){d.call(this),this.onopen=void 0,this.onmessage=void 0,this.onerror=void 0,this.url=void 0,this.readyState=void 0,this.withCredentials=void 0,this._close=void 0,i(this,a,b)}function i(a,b,d){b=String(b);var h=void 0!=d&&Boolean(d.withCredentials),i=D(1e3),n=D(45e3),o="",p=i,A=!1,B=void 0!=d&&void 0!=d.headers?JSON.parse(JSON.stringify(d.headers)):void 0,F=void 0!=d&&void 0!=d.Transport?d.Transport:void 0!=m?m:l,G=new c(new F),H=0,I=q,J="",K="",L="",M="",N=v,O=0,P=0,Q=function(b,c,d){if(I===r)if(200===b&&void 0!=d&&z.test(d)){I=s,A=!0,p=i,a.readyState=s;var g=new f("open");a.dispatchEvent(g),E(a,a.onopen,g)}else{var h="";200!==b?(c&&(c=c.replace(/\s+/g," ")),h="EventSource's response has a status "+b+" "+c+" that is not 200. Aborting the connection."):h="EventSource's response has a Content-Type specifying an unsupported type: "+(void 0==d?"-":d.replace(/\s+/g," "))+". Aborting the connection.",e(new Error(h)),T();var g=new f("error");a.dispatchEvent(g),E(a,a.onerror,g)}},R=function(b){if(I===s){for(var c=-1,d=0;d<b.length;d+=1){var e=b.charCodeAt(d);(e==="\n".charCodeAt(0)||e==="\r".charCodeAt(0))&&(c=d)}var f=(-1!==c?M:"")+b.slice(0,c+1);M=(-1===c?M:"")+b.slice(c+1),""!==f&&(A=!0);for(var h=0;h<f.length;h+=1){var e=f.charCodeAt(h);if(N===u&&e==="\n".charCodeAt(0))N=v;else if(N===u&&(N=v),e==="\r".charCodeAt(0)||e==="\n".charCodeAt(0)){if(N!==v){N===w&&(P=h+1);var l=f.slice(O,P-1),m=f.slice(P+(h>P&&f.charCodeAt(P)===" ".charCodeAt(0)?1:0),h);"data"===l?(J+="\n",J+=m):"id"===l?K=m:"event"===l?L=m:"retry"===l?(i=C(m,i),p=i):"heartbeatTimeout"===l&&(n=C(m,n),0!==H&&(k(H),H=j(function(){U()},n)))}if(N===v){if(""!==J){o=K,""===L&&(L="message");var q=new g(L,{data:J.slice(1),lastEventId:K});if(a.dispatchEvent(q),"message"===L&&E(a,a.onmessage,q),I===t)return}J="",L=""}N=e==="\r".charCodeAt(0)?u:v}else N===v&&(O=h,N=w),N===w?e===":".charCodeAt(0)&&(P=h+1,N=x):N===x&&(N=y)}}},S=function(){if(I===s||I===r){I=q,0!==H&&(k(H),H=0),H=j(function(){U()},p),p=D(Math.min(16*i,2*p)),a.readyState=r;var b=new f("error");a.dispatchEvent(b),E(a,a.onerror,b)}},T=function(){I=t,G.cancel(),0!==H&&(k(H),H=0),a.readyState=t},U=function(){if(H=0,I!==q)return void(A?(A=!1,H=j(function(){U()},n)):(e(new Error("No activity within "+n+" milliseconds. Reconnecting.")),G.cancel()));A=!1,H=j(function(){U()},n),I=r,J="",L="",K=o,M="",O=0,P=0,N=v;var a=b;"data:"!==b.slice(0,5)&&"blob:"!==b.slice(0,5)&&(a=b+(-1===b.indexOf("?",0)?"?":"&")+"lastEventId="+encodeURIComponent(o));var c={};if(c.Accept="text/event-stream",void 0!=B)for(var d in B)Object.prototype.hasOwnProperty.call(B,d)&&(c[d]=B[d]);try{G.open(Q,R,S,a,h,c)}catch(f){throw T(),f}};a.url=b,a.readyState=r,a.withCredentials=h,a._close=T,U()}var j=a.setTimeout,k=a.clearTimeout,l=a.XMLHttpRequest,m=a.XDomainRequest,n=a.EventSource,o=a.document;null==Object.create&&(Object.create=function(a){function b(){}return b.prototype=a,new b});var p=function(){};b.prototype.open=function(a,b){this._abort(!0);var c=this,d=this._xhr,e=1,f=0;this._abort=function(a){0!==c._sendTimeout&&(k(c._sendTimeout),c._sendTimeout=0),(1===e||2===e||3===e)&&(e=4,d.onload=p,d.onerror=p,d.onabort=p,d.onprogress=p,d.onreadystatechange=p,d.abort(),0!==f&&(k(f),f=0),a||(c.readyState=4,c.onreadystatechange())),e=0};var g=function(){if(1===e){var a=0,b="",f=void 0;if("contentType"in d)a=200,b="OK",f=d.contentType;else try{a=d.status,b=d.statusText,f=d.getResponseHeader("Content-Type")}catch(g){a=0,b="",f=void 0}0!==a&&(e=2,c.readyState=2,c.status=a,c.statusText=b,c._contentType=f,c.onreadystatechange())}},h=function(){if(g(),2===e||3===e){e=3;var a="";try{a=d.responseText}catch(b){}c.readyState=3,c.responseText=a,c.onprogress()}},i=function(){h(),(1===e||2===e||3===e)&&(e=4,0!==f&&(k(f),f=0),c.readyState=4,c.onreadystatechange())},m=function(){void 0!=d&&(4===d.readyState?i():3===d.readyState?h():2===d.readyState&&g())},n=function(){f=j(function(){n()},500),3===d.readyState&&h()};d.onload=i,d.onerror=i,d.onabort=i,"sendAsBinary"in l.prototype||"mozAnon"in l.prototype||(d.onprogress=h),d.onreadystatechange=m,"contentType"in d&&(b+=(-1===b.indexOf("?",0)?"?":"&")+"padding=true"),d.open(a,b,!0),"readyState"in d&&(f=j(function(){n()},0))},b.prototype.abort=function(){this._abort(!1)},b.prototype.getResponseHeader=function(a){return this._contentType},b.prototype.setRequestHeader=function(a,b){var c=this._xhr;"setRequestHeader"in c&&c.setRequestHeader(a,b)},b.prototype.send=function(){if(!("ontimeout"in l.prototype)&&void 0!=o&&void 0!=o.readyState&&"complete"!==o.readyState){var a=this;return void(a._sendTimeout=j(function(){a._sendTimeout=0,a.send()},4))}var b=this._xhr;b.withCredentials=this.withCredentials,b.responseType=this.responseType;try{b.send(void 0)}catch(c){throw c}},c.prototype.open=function(a,b,c,d,e,f){var g=this._xhr;g.open("GET",d);var h=0;g.onprogress=function(){var a=g.responseText,c=a.slice(h);h+=c.length,b(c)},g.onreadystatechange=function(){if(2===g.readyState){var b=g.status,d=g.statusText,e=g.getResponseHeader("Content-Type");a(b,d,e)}else 4===g.readyState&&c()},g.withCredentials=e,g.responseType="text";for(var i in f)Object.prototype.hasOwnProperty.call(f,i)&&g.setRequestHeader(i,f[i]);g.send()},c.prototype.cancel=function(){var a=this._xhr;a.abort()},d.prototype.dispatchEvent=function(a){a.target=this;var b=this._listeners[a.type];if(void 0!=b)for(var c=b.length,d=0;c>d;d+=1){var f=b[d];try{"function"==typeof f.handleEvent?f.handleEvent(a):f.call(this,a)}catch(g){e(g)}}},d.prototype.addEventListener=function(a,b){a=String(a);var c=this._listeners,d=c[a];void 0==d&&(d=[],c[a]=d);for(var e=!1,f=0;f<d.length;f+=1)d[f]===b&&(e=!0);e||d.push(b)},d.prototype.removeEventListener=function(a,b){a=String(a);var c=this._listeners,d=c[a];if(void 0!=d){for(var e=[],f=0;f<d.length;f+=1)d[f]!==b&&e.push(d[f]);0===e.length?delete c[a]:c[a]=e}},g.prototype=Object.create(f.prototype);var q=-1,r=0,s=1,t=2,u=-1,v=0,w=1,x=2,y=3,z=/^text\/event\-stream;?(\s*charset\=utf\-8)?$/i,A=1e3,B=18e6,C=function(a,b){var c=parseInt(a,10);return c!==c&&(c=b),D(c)},D=function(a){return Math.min(Math.max(a,A),B)},E=function(a,b,c){try{"function"==typeof b&&b.call(a,c)}catch(d){e(d)}};h.prototype=Object.create(d.prototype),h.prototype.CONNECTING=r,h.prototype.OPEN=s,h.prototype.CLOSED=t,h.prototype.close=function(){this._close()},h.CONNECTING=r,h.OPEN=s,h.CLOSED=t,h.prototype.withCredentials=void 0,a.EventSourcePolyfill=h,a.NativeEventSource=n,void 0==l||void 0!=n&&"withCredentials"in n.prototype||(a.EventSource=h)}("undefined"!=typeof window?window:this);
|
inc/assets/js/install-theme.js
ADDED
@@ -0,0 +1,108 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
(function($){
|
2 |
+
|
3 |
+
AstraSitesInstallTheme = {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Init
|
7 |
+
*/
|
8 |
+
init: function() {
|
9 |
+
this._bind();
|
10 |
+
},
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Binds events for the Astra Sites.
|
14 |
+
*
|
15 |
+
* @since 1.3.2
|
16 |
+
*
|
17 |
+
* @access private
|
18 |
+
* @method _bind
|
19 |
+
*/
|
20 |
+
_bind: function()
|
21 |
+
{
|
22 |
+
$( document ).on( 'click', '.astra-sites-theme-not-installed', AstraSitesInstallTheme._install_and_activate );
|
23 |
+
$( document ).on( 'click', '.astra-sites-theme-installed-but-inactive', AstraSitesInstallTheme._activateTheme );
|
24 |
+
$( document ).on('wp-theme-install-success' , AstraSitesInstallTheme._activateTheme);
|
25 |
+
},
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Activate Theme
|
29 |
+
*
|
30 |
+
* @since 1.3.2
|
31 |
+
*/
|
32 |
+
_activateTheme: function( event, response ) {
|
33 |
+
event.preventDefault();
|
34 |
+
|
35 |
+
$('#astra-theme-activation-nag a').addClass('processing');
|
36 |
+
|
37 |
+
if( response ) {
|
38 |
+
$('#astra-theme-activation-nag a').text( AstraSitesInstallThemeVars.installed );
|
39 |
+
} else {
|
40 |
+
$('#astra-theme-activation-nag a').text( AstraSitesInstallThemeVars.activating );
|
41 |
+
}
|
42 |
+
|
43 |
+
// WordPress adds "Activate" button after waiting for 1000ms. So we will run our activation after that.
|
44 |
+
setTimeout( function() {
|
45 |
+
|
46 |
+
$.ajax({
|
47 |
+
url: AstraSitesInstallThemeVars.ajaxurl,
|
48 |
+
type: 'POST',
|
49 |
+
data: {
|
50 |
+
'action' : 'astra-sites-activate-theme'
|
51 |
+
},
|
52 |
+
})
|
53 |
+
.done(function (result) {
|
54 |
+
if( result.success ) {
|
55 |
+
$('#astra-theme-activation-nag a').text( AstraSitesInstallThemeVars.activated );
|
56 |
+
|
57 |
+
setTimeout(function() {
|
58 |
+
location.reload();
|
59 |
+
}, 1000);
|
60 |
+
}
|
61 |
+
|
62 |
+
});
|
63 |
+
|
64 |
+
}, 3000 );
|
65 |
+
|
66 |
+
},
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Install and activate
|
70 |
+
*
|
71 |
+
* @since 1.3.2
|
72 |
+
*
|
73 |
+
* @param {object} event Current event.
|
74 |
+
* @return void
|
75 |
+
*/
|
76 |
+
_install_and_activate: function(event ) {
|
77 |
+
event.preventDefault();
|
78 |
+
var theme_slug = $(this).data('theme-slug') || '';
|
79 |
+
console.log( theme_slug );
|
80 |
+
console.log( 'yes' );
|
81 |
+
|
82 |
+
var btn = $( event.target );
|
83 |
+
|
84 |
+
if ( btn.hasClass( 'processing' ) ) {
|
85 |
+
return;
|
86 |
+
}
|
87 |
+
|
88 |
+
btn.text( AstraSitesInstallThemeVars.installing ).addClass('processing');
|
89 |
+
|
90 |
+
if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.ajaxLocked ) {
|
91 |
+
wp.updates.requestFilesystemCredentials( event );
|
92 |
+
}
|
93 |
+
|
94 |
+
wp.updates.installTheme( {
|
95 |
+
slug: theme_slug
|
96 |
+
});
|
97 |
+
}
|
98 |
+
|
99 |
+
};
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Initialize
|
103 |
+
*/
|
104 |
+
$(function(){
|
105 |
+
AstraSitesInstallTheme.init();
|
106 |
+
});
|
107 |
+
|
108 |
+
})(jQuery);
|
inc/assets/js/node_modules/whatwg-fetch/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
Copyright (c) 2014-2016 GitHub, Inc.
|
2 |
+
|
3 |
+
Permission is hereby granted, free of charge, to any person obtaining
|
4 |
+
a copy of this software and associated documentation files (the
|
5 |
+
"Software"), to deal in the Software without restriction, including
|
6 |
+
without limitation the rights to use, copy, modify, merge, publish,
|
7 |
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8 |
+
permit persons to whom the Software is furnished to do so, subject to
|
9 |
+
the following conditions:
|
10 |
+
|
11 |
+
The above copyright notice and this permission notice shall be
|
12 |
+
included in all copies or substantial portions of the Software.
|
13 |
+
|
14 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15 |
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16 |
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17 |
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18 |
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19 |
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20 |
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
inc/assets/js/node_modules/whatwg-fetch/README.md
ADDED
@@ -0,0 +1,334 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
# window.fetch polyfill
|
2 |
+
|
3 |
+
The `fetch()` function is a Promise-based mechanism for programmatically making
|
4 |
+
web requests in the browser. This project is a polyfill that implements a subset
|
5 |
+
of the standard [Fetch specification][], enough to make `fetch` a viable
|
6 |
+
replacement for most uses of XMLHttpRequest in traditional web applications.
|
7 |
+
|
8 |
+
## Table of Contents
|
9 |
+
|
10 |
+
* [Read this first](#read-this-first)
|
11 |
+
* [Installation](#installation)
|
12 |
+
* [Usage](#usage)
|
13 |
+
* [Importing](#importing)
|
14 |
+
* [HTML](#html)
|
15 |
+
* [JSON](#json)
|
16 |
+
* [Response metadata](#response-metadata)
|
17 |
+
* [Post form](#post-form)
|
18 |
+
* [Post JSON](#post-json)
|
19 |
+
* [File upload](#file-upload)
|
20 |
+
* [Caveats](#caveats)
|
21 |
+
* [Handling HTTP error statuses](#handling-http-error-statuses)
|
22 |
+
* [Sending cookies](#sending-cookies)
|
23 |
+
* [Receiving cookies](#receiving-cookies)
|
24 |
+
* [Obtaining the Response URL](#obtaining-the-response-url)
|
25 |
+
* [Aborting requests](#aborting-requests)
|
26 |
+
* [Browser Support](#browser-support)
|
27 |
+
|
28 |
+
## Read this first
|
29 |
+
|
30 |
+
* If you believe you found a bug with how `fetch` behaves in your browser,
|
31 |
+
please **don't open an issue in this repository** unless you are testing in
|
32 |
+
an old version of a browser that doesn't support `window.fetch` natively.
|
33 |
+
This project is a _polyfill_, and since all modern browsers now implement the
|
34 |
+
`fetch` function natively, **no code from this project** actually takes any
|
35 |
+
effect there. See [Browser support](#browser-support) for detailed
|
36 |
+
information.
|
37 |
+
|
38 |
+
* If you have trouble **making a request to another domain** (a different
|
39 |
+
subdomain or port number also constitutes another domain), please familiarize
|
40 |
+
yourself with all the intricacies and limitations of [CORS][] requests.
|
41 |
+
Because CORS requires participation of the server by implementing specific
|
42 |
+
HTTP response headers, it is often nontrivial to set up or debug. CORS is
|
43 |
+
exclusively handled by the browser's internal mechanisms which this polyfill
|
44 |
+
cannot influence.
|
45 |
+
|
46 |
+
* This project **doesn't work under Node.js environments**. It's meant for web
|
47 |
+
browsers only. You should ensure that your application doesn't try to package
|
48 |
+
and run this on the server.
|
49 |
+
|
50 |
+
* If you have an idea for a new feature of `fetch`, **submit your feature
|
51 |
+
requests** to the [specification's repository](https://github.com/whatwg/fetch/issues).
|
52 |
+
We only add features and APIs that are part of the [Fetch specification][].
|
53 |
+
|
54 |
+
## Installation
|
55 |
+
|
56 |
+
```
|
57 |
+
npm install whatwg-fetch --save
|
58 |
+
```
|
59 |
+
|
60 |
+
You will also need a Promise polyfill for [older browsers](http://caniuse.com/#feat=promises).
|
61 |
+
We recommend [taylorhakes/promise-polyfill](https://github.com/taylorhakes/promise-polyfill)
|
62 |
+
for its small size and Promises/A+ compatibility.
|
63 |
+
|
64 |
+
## Usage
|
65 |
+
|
66 |
+
For a more comprehensive API reference that this polyfill supports, refer to
|
67 |
+
https://github.github.io/fetch/.
|
68 |
+
|
69 |
+
### Importing
|
70 |
+
|
71 |
+
Importing will automatically polyfill `window.fetch` and related APIs:
|
72 |
+
|
73 |
+
```javascript
|
74 |
+
import 'whatwg-fetch'
|
75 |
+
|
76 |
+
window.fetch(...)
|
77 |
+
```
|
78 |
+
|
79 |
+
If for some reason you need to access the polyfill implementation, it is
|
80 |
+
available via exports:
|
81 |
+
|
82 |
+
```javascript
|
83 |
+
import {fetch as fetchPolyfill} from 'whatwg-fetch'
|
84 |
+
|
85 |
+
window.fetch(...) // use native browser version
|
86 |
+
fetchPolyfill(...) // use polyfill implementation
|
87 |
+
```
|
88 |
+
|
89 |
+
This approach can be used to, for example, use [abort
|
90 |
+
functionality](#aborting-requests) in browsers that implement a native but
|
91 |
+
outdated version of fetch that doesn't support aborting.
|
92 |
+
|
93 |
+
For use with webpack, add this package in the `entry` configuration option
|
94 |
+
before your application entry point:
|
95 |
+
|
96 |
+
```javascript
|
97 |
+
entry: ['whatwg-fetch', ...]
|
98 |
+
```
|
99 |
+
|
100 |
+
### HTML
|
101 |
+
|
102 |
+
```javascript
|
103 |
+
fetch('/users.html')
|
104 |
+
.then(function(response) {
|
105 |
+
return response.text()
|
106 |
+
}).then(function(body) {
|
107 |
+
document.body.innerHTML = body
|
108 |
+
})
|
109 |
+
```
|
110 |
+
|
111 |
+
### JSON
|
112 |
+
|
113 |
+
```javascript
|
114 |
+
fetch('/users.json')
|
115 |
+
.then(function(response) {
|
116 |
+
return response.json()
|
117 |
+
}).then(function(json) {
|
118 |
+
console.log('parsed json', json)
|
119 |
+
}).catch(function(ex) {
|
120 |
+
console.log('parsing failed', ex)
|
121 |
+
})
|
122 |
+
```
|
123 |
+
|
124 |
+
### Response metadata
|
125 |
+
|
126 |
+
```javascript
|
127 |
+
fetch('/users.json').then(function(response) {
|
128 |
+
console.log(response.headers.get('Content-Type'))
|
129 |
+
console.log(response.headers.get('Date'))
|
130 |
+
console.log(response.status)
|
131 |
+
console.log(response.statusText)
|
132 |
+
})
|
133 |
+
```
|
134 |
+
|
135 |
+
### Post form
|
136 |
+
|
137 |
+
```javascript
|
138 |
+
var form = document.querySelector('form')
|
139 |
+
|
140 |
+
fetch('/users', {
|
141 |
+
method: 'POST',
|
142 |
+
body: new FormData(form)
|
143 |
+
})
|
144 |
+
```
|
145 |
+
|
146 |
+
### Post JSON
|
147 |
+
|
148 |
+
```javascript
|
149 |
+
fetch('/users', {
|
150 |
+
method: 'POST',
|
151 |
+
headers: {
|
152 |
+
'Content-Type': 'application/json'
|
153 |
+
},
|
154 |
+
body: JSON.stringify({
|
155 |
+
name: 'Hubot',
|
156 |
+
login: 'hubot',
|
157 |
+
})
|
158 |
+
})
|
159 |
+
```
|
160 |
+
|
161 |
+
### File upload
|
162 |
+
|
163 |
+
```javascript
|
164 |
+
var input = document.querySelector('input[type="file"]')
|
165 |
+
|
166 |
+
var data = new FormData()
|
167 |
+
data.append('file', input.files[0])
|
168 |
+
data.append('user', 'hubot')
|
169 |
+
|
170 |
+
fetch('/avatars', {
|
171 |
+
method: 'POST',
|
172 |
+
body: data
|
173 |
+
})
|
174 |
+
```
|
175 |
+
|
176 |
+
### Caveats
|
177 |
+
|
178 |
+
* The Promise returned from `fetch()` **won't reject on HTTP error status**
|
179 |
+
even if the response is an HTTP 404 or 500. Instead, it will resolve normally,
|
180 |
+
and it will only reject on network failure or if anything prevented the
|
181 |
+
request from completing.
|
182 |
+
|
183 |
+
* For maximum browser compatibility when it comes to sending & receiving
|
184 |
+
cookies, always supply the `credentials: 'same-origin'` option instead of
|
185 |
+
relying on the default. See [Sending cookies](#sending-cookies).
|
186 |
+
|
187 |
+
#### Handling HTTP error statuses
|
188 |
+
|
189 |
+
To have `fetch` Promise reject on HTTP error statuses, i.e. on any non-2xx
|
190 |
+
status, define a custom response handler:
|
191 |
+
|
192 |
+
```javascript
|
193 |
+
function checkStatus(response) {
|
194 |
+
if (response.status >= 200 && response.status < 300) {
|
195 |
+
return response
|
196 |
+
} else {
|
197 |
+
var error = new Error(response.statusText)
|
198 |
+
error.response = response
|
199 |
+
throw error
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
function parseJSON(response) {
|
204 |
+
return response.json()
|
205 |
+
}
|
206 |
+
|
207 |
+
fetch('/users')
|
208 |
+
.then(checkStatus)
|
209 |
+
.then(parseJSON)
|
210 |
+
.then(function(data) {
|
211 |
+
console.log('request succeeded with JSON response', data)
|
212 |
+
}).catch(function(error) {
|
213 |
+
console.log('request failed', error)
|
214 |
+
})
|
215 |
+
```
|
216 |
+
|
217 |
+
#### Sending cookies
|
218 |
+
|
219 |
+
For [CORS][] requests, use `credentials: 'include'` to allow sending credentials
|
220 |
+
to other domains:
|
221 |
+
|
222 |
+
```javascript
|
223 |
+
fetch('https://example.com:1234/users', {
|
224 |
+
credentials: 'include'
|
225 |
+
})
|
226 |
+
```
|
227 |
+
|
228 |
+
To disable sending or receiving cookies for requests to any domain, including
|
229 |
+
the current one, use the "omit" value:
|
230 |
+
|
231 |
+
```javascript
|
232 |
+
fetch('/users', {
|
233 |
+
credentials: 'omit'
|
234 |
+
})
|
235 |
+
```
|
236 |
+
|
237 |
+
The default value for `credentials` is "same-origin".
|
238 |
+
|
239 |
+
The default for `credentials` wasn't always the same, though. The following
|
240 |
+
versions of browsers implemented an older version of the fetch specification
|
241 |
+
where the default was "omit":
|
242 |
+
|
243 |
+
* Firefox 39-60
|
244 |
+
* Chrome 42-67
|
245 |
+
* Safari 10.1-11.1.2
|
246 |
+
|
247 |
+
If you target these browsers, it's advisable to always specify `credentials:
|
248 |
+
'same-origin'` explicitly with all fetch requests instead of relying on the
|
249 |
+
default:
|
250 |
+
|
251 |
+
```javascript
|
252 |
+
fetch('/users', {
|
253 |
+
credentials: 'same-origin'
|
254 |
+
})
|
255 |
+
```
|
256 |
+
|
257 |
+
#### Receiving cookies
|
258 |
+
|
259 |
+
As with XMLHttpRequest, the `Set-Cookie` response header returned from the
|
260 |
+
server is a [forbidden header name][] and therefore can't be programmatically
|
261 |
+
read with `response.headers.get()`. Instead, it's the browser's responsibility
|
262 |
+
to handle new cookies being set (if applicable to the current URL). Unless they
|
263 |
+
are HTTP-only, new cookies will be available through `document.cookie`.
|
264 |
+
|
265 |
+
#### Obtaining the Response URL
|
266 |
+
|
267 |
+
Due to limitations of XMLHttpRequest, the `response.url` value might not be
|
268 |
+
reliable after HTTP redirects on older browsers.
|
269 |
+
|
270 |
+
The solution is to configure the server to set the response HTTP header
|
271 |
+
`X-Request-URL` to the current URL after any redirect that might have happened.
|
272 |
+
It should be safe to set it unconditionally.
|
273 |
+
|
274 |
+
``` ruby
|
275 |
+
# Ruby on Rails controller example
|
276 |
+
response.headers['X-Request-URL'] = request.url
|
277 |
+
```
|
278 |
+
|
279 |
+
This server workaround is necessary if you need reliable `response.url` in
|
280 |
+
Firefox < 32, Chrome < 37, Safari, or IE.
|
281 |
+
|
282 |
+
#### Aborting requests
|
283 |
+
|
284 |
+
This polyfill supports
|
285 |
+
[the abortable fetch API](https://developers.google.com/web/updates/2017/09/abortable-fetch).
|
286 |
+
However, aborting a fetch requires use of two additional DOM APIs:
|
287 |
+
[AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) and
|
288 |
+
[AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
|
289 |
+
Typically, browsers that do not support fetch will also not support
|
290 |
+
AbortController or AbortSignal. Consequently, you will need to include
|
291 |
+
[an additional polyfill](https://github.com/mo/abortcontroller-polyfill#readme)
|
292 |
+
for these APIs to abort fetches:
|
293 |
+
|
294 |
+
```js
|
295 |
+
import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'
|
296 |
+
import {fetch} from 'whatwg-fetch'
|
297 |
+
|
298 |
+
// use native browser implementation if it supports aborting
|
299 |
+
const abortableFetch = ('signal' in new Request('')) ? window.fetch : fetch
|
300 |
+
|
301 |
+
const controller = new AbortController()
|
302 |
+
|
303 |
+
abortableFetch('/avatars', {
|
304 |
+
signal: controller.signal
|
305 |
+
}).catch(function(ex) {
|
306 |
+
if (ex.name === 'AbortError') {
|
307 |
+
console.log('request aborted')
|
308 |
+
}
|
309 |
+
})
|
310 |
+
|
311 |
+
// some time later...
|
312 |
+
controller.abort()
|
313 |
+
```
|
314 |
+
|
315 |
+
## Browser Support
|
316 |
+
|
317 |
+
- Chrome
|
318 |
+
- Firefox
|
319 |
+
- Safari 6.1+
|
320 |
+
- Internet Explorer 10+
|
321 |
+
|
322 |
+
Note: modern browsers such as Chrome, Firefox, Microsoft Edge, and Safari contain native
|
323 |
+
implementations of `window.fetch`, therefore the code from this polyfill doesn't
|
324 |
+
have any effect on those browsers. If you believe you've encountered an error
|
325 |
+
with how `window.fetch` is implemented in any of these browsers, you should file
|
326 |
+
an issue with that browser vendor instead of this project.
|
327 |
+
|
328 |
+
|
329 |
+
[fetch specification]: https://fetch.spec.whatwg.org
|
330 |
+
[cors]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
|
331 |
+
"Cross-origin resource sharing"
|
332 |
+
[csrf]: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
|
333 |
+
"Cross-site request forgery"
|
334 |
+
[forbidden header name]: https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name
|
inc/assets/js/node_modules/whatwg-fetch/dist/fetch.umd.js
ADDED
@@ -0,0 +1,531 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
(function (global, factory) {
|
2 |
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
3 |
+
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
4 |
+
(factory((global.WHATWGFetch = {})));
|
5 |
+
}(this, (function (exports) { 'use strict';
|
6 |
+
|
7 |
+
var support = {
|
8 |
+
searchParams: 'URLSearchParams' in self,
|
9 |
+
iterable: 'Symbol' in self && 'iterator' in Symbol,
|
10 |
+
blob:
|
11 |
+
'FileReader' in self &&
|
12 |
+
'Blob' in self &&
|
13 |
+
(function() {
|
14 |
+
try {
|
15 |
+
new Blob();
|
16 |
+
return true
|
17 |
+
} catch (e) {
|
18 |
+
return false
|
19 |
+
}
|
20 |
+
})(),
|
21 |
+
formData: 'FormData' in self,
|
22 |
+
arrayBuffer: 'ArrayBuffer' in self
|
23 |
+
};
|
24 |
+
|
25 |
+
function isDataView(obj) {
|
26 |
+
return obj && DataView.prototype.isPrototypeOf(obj)
|
27 |
+
}
|
28 |
+
|
29 |
+
if (support.arrayBuffer) {
|
30 |
+
var viewClasses = [
|
31 |
+
'[object Int8Array]',
|
32 |
+
'[object Uint8Array]',
|
33 |
+
'[object Uint8ClampedArray]',
|
34 |
+
'[object Int16Array]',
|
35 |
+
'[object Uint16Array]',
|
36 |
+
'[object Int32Array]',
|
37 |
+
'[object Uint32Array]',
|
38 |
+
'[object Float32Array]',
|
39 |
+
'[object Float64Array]'
|
40 |
+
];
|
41 |
+
|
42 |
+
var isArrayBufferView =
|
43 |
+
ArrayBuffer.isView ||
|
44 |
+
function(obj) {
|
45 |
+
return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
|
46 |
+
};
|
47 |
+
}
|
48 |
+
|
49 |
+
function normalizeName(name) {
|
50 |
+
if (typeof name !== 'string') {
|
51 |
+
name = String(name);
|
52 |
+
}
|
53 |
+
if (/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(name)) {
|
54 |
+
throw new TypeError('Invalid character in header field name')
|
55 |
+
}
|
56 |
+
return name.toLowerCase()
|
57 |
+
}
|
58 |
+
|
59 |
+
function normalizeValue(value) {
|
60 |
+
if (typeof value !== 'string') {
|
61 |
+
value = String(value);
|
62 |
+
}
|
63 |
+
return value
|
64 |
+
}
|
65 |
+
|
66 |
+
// Build a destructive iterator for the value list
|
67 |
+
function iteratorFor(items) {
|
68 |
+
var iterator = {
|
69 |
+
next: function() {
|
70 |
+
var value = items.shift();
|
71 |
+
return {done: value === undefined, value: value}
|
72 |
+
}
|
73 |
+
};
|
74 |
+
|
75 |
+
if (support.iterable) {
|
76 |
+
iterator[Symbol.iterator] = function() {
|
77 |
+
return iterator
|
78 |
+
};
|
79 |
+
}
|
80 |
+
|
81 |
+
return iterator
|
82 |
+
}
|
83 |
+
|
84 |
+
function Headers(headers) {
|
85 |
+
this.map = {};
|
86 |
+
|
87 |
+
if (headers instanceof Headers) {
|
88 |
+
headers.forEach(function(value, name) {
|
89 |
+
this.append(name, value);
|
90 |
+
}, this);
|
91 |
+
} else if (Array.isArray(headers)) {
|
92 |
+
headers.forEach(function(header) {
|
93 |
+
this.append(header[0], header[1]);
|
94 |
+
}, this);
|
95 |
+
} else if (headers) {
|
96 |
+
Object.getOwnPropertyNames(headers).forEach(function(name) {
|
97 |
+
this.append(name, headers[name]);
|
98 |
+
}, this);
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
Headers.prototype.append = function(name, value) {
|
103 |
+
name = normalizeName(name);
|
104 |
+
value = normalizeValue(value);
|
105 |
+
var oldValue = this.map[name];
|
106 |
+
this.map[name] = oldValue ? oldValue + ', ' + value : value;
|
107 |
+
};
|
108 |
+
|
109 |
+
Headers.prototype['delete'] = function(name) {
|
110 |
+
delete this.map[normalizeName(name)];
|
111 |
+
};
|
112 |
+
|
113 |
+
Headers.prototype.get = function(name) {
|
114 |
+
name = normalizeName(name);
|
115 |
+
return this.has(name) ? this.map[name] : null
|
116 |
+
};
|
117 |
+
|
118 |
+
Headers.prototype.has = function(name) {
|
119 |
+
return this.map.hasOwnProperty(normalizeName(name))
|
120 |
+
};
|
121 |
+
|
122 |
+
Headers.prototype.set = function(name, value) {
|
123 |
+
this.map[normalizeName(name)] = normalizeValue(value);
|
124 |
+
};
|
125 |
+
|
126 |
+
Headers.prototype.forEach = function(callback, thisArg) {
|
127 |
+
for (var name in this.map) {
|
128 |
+
if (this.map.hasOwnProperty(name)) {
|
129 |
+
callback.call(thisArg, this.map[name], name, this);
|
130 |
+
}
|
131 |
+
}
|
132 |
+
};
|
133 |
+
|
134 |
+
Headers.prototype.keys = function() {
|
135 |
+
var items = [];
|
136 |
+
this.forEach(function(value, name) {
|
137 |
+
items.push(name);
|
138 |
+
});
|
139 |
+
return iteratorFor(items)
|
140 |
+
};
|
141 |
+
|
142 |
+
Headers.prototype.values = function() {
|
143 |
+
var items = [];
|
144 |
+
this.forEach(function(value) {
|
145 |
+
items.push(value);
|
146 |
+
});
|
147 |
+
return iteratorFor(items)
|
148 |
+
};
|
149 |
+
|
150 |
+
Headers.prototype.entries = function() {
|
151 |
+
var items = [];
|
152 |
+
this.forEach(function(value, name) {
|
153 |
+
items.push([name, value]);
|
154 |
+
});
|
155 |
+
return iteratorFor(items)
|
156 |
+
};
|
157 |
+
|
158 |
+
if (support.iterable) {
|
159 |
+
Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
|
160 |
+
}
|
161 |
+
|
162 |
+
function consumed(body) {
|
163 |
+
if (body.bodyUsed) {
|
164 |
+
return Promise.reject(new TypeError('Already read'))
|
165 |
+
}
|
166 |
+
body.bodyUsed = true;
|
167 |
+
}
|
168 |
+
|
169 |
+
function fileReaderReady(reader) {
|
170 |
+
return new Promise(function(resolve, reject) {
|
171 |
+
reader.onload = function() {
|
172 |
+
resolve(reader.result);
|
173 |
+
};
|
174 |
+
reader.onerror = function() {
|
175 |
+
reject(reader.error);
|
176 |
+
};
|
177 |
+
})
|
178 |
+
}
|
179 |
+
|
180 |
+
function readBlobAsArrayBuffer(blob) {
|
181 |
+
var reader = new FileReader();
|
182 |
+
var promise = fileReaderReady(reader);
|
183 |
+
reader.readAsArrayBuffer(blob);
|
184 |
+
return promise
|
185 |
+
}
|
186 |
+
|
187 |
+
function readBlobAsText(blob) {
|
188 |
+
var reader = new FileReader();
|
189 |
+
var promise = fileReaderReady(reader);
|
190 |
+
reader.readAsText(blob);
|
191 |
+
return promise
|
192 |
+
}
|
193 |
+
|
194 |
+
function readArrayBufferAsText(buf) {
|
195 |
+
var view = new Uint8Array(buf);
|
196 |
+
var chars = new Array(view.length);
|
197 |
+
|
198 |
+
for (var i = 0; i < view.length; i++) {
|
199 |
+
chars[i] = String.fromCharCode(view[i]);
|
200 |
+
}
|
201 |
+
return chars.join('')
|
202 |
+
}
|
203 |
+
|
204 |
+
function bufferClone(buf) {
|
205 |
+
if (buf.slice) {
|
206 |
+
return buf.slice(0)
|
207 |
+
} else {
|
208 |
+
var view = new Uint8Array(buf.byteLength);
|
209 |
+
view.set(new Uint8Array(buf));
|
210 |
+
return view.buffer
|
211 |
+
}
|
212 |
+
}
|
213 |
+
|
214 |
+
function Body() {
|
215 |
+
this.bodyUsed = false;
|
216 |
+
|
217 |
+
this._initBody = function(body) {
|
218 |
+
this._bodyInit = body;
|
219 |
+
if (!body) {
|
220 |
+
this._bodyText = '';
|
221 |
+
} else if (typeof body === 'string') {
|
222 |
+
this._bodyText = body;
|
223 |
+
} else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
|
224 |
+
this._bodyBlob = body;
|
225 |
+
} else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
|
226 |
+
this._bodyFormData = body;
|
227 |
+
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
|
228 |
+
this._bodyText = body.toString();
|
229 |
+
} else if (support.arrayBuffer && support.blob && isDataView(body)) {
|
230 |
+
this._bodyArrayBuffer = bufferClone(body.buffer);
|
231 |
+
// IE 10-11 can't handle a DataView body.
|
232 |
+
this._bodyInit = new Blob([this._bodyArrayBuffer]);
|
233 |
+
} else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
|
234 |
+
this._bodyArrayBuffer = bufferClone(body);
|
235 |
+
} else {
|
236 |
+
this._bodyText = body = Object.prototype.toString.call(body);
|
237 |
+
}
|
238 |
+
|
239 |
+
if (!this.headers.get('content-type')) {
|
240 |
+
if (typeof body === 'string') {
|
241 |
+
this.headers.set('content-type', 'text/plain;charset=UTF-8');
|
242 |
+
} else if (this._bodyBlob && this._bodyBlob.type) {
|
243 |
+
this.headers.set('content-type', this._bodyBlob.type);
|
244 |
+
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
|
245 |
+
this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
|
246 |
+
}
|
247 |
+
}
|
248 |
+
};
|
249 |
+
|
250 |
+
if (support.blob) {
|
251 |
+
this.blob = function() {
|
252 |
+
var rejected = consumed(this);
|
253 |
+
if (rejected) {
|
254 |
+
return rejected
|
255 |
+
}
|
256 |
+
|
257 |
+
if (this._bodyBlob) {
|
258 |
+
return Promise.resolve(this._bodyBlob)
|
259 |
+
} else if (this._bodyArrayBuffer) {
|
260 |
+
return Promise.resolve(new Blob([this._bodyArrayBuffer]))
|
261 |
+
} else if (this._bodyFormData) {
|
262 |
+
throw new Error('could not read FormData body as blob')
|
263 |
+
} else {
|
264 |
+
return Promise.resolve(new Blob([this._bodyText]))
|
265 |
+
}
|
266 |
+
};
|
267 |
+
|
268 |
+
this.arrayBuffer = function() {
|
269 |
+
if (this._bodyArrayBuffer) {
|
270 |
+
return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
|
271 |
+
} else {
|
272 |
+
return this.blob().then(readBlobAsArrayBuffer)
|
273 |
+
}
|
274 |
+
};
|
275 |
+
}
|
276 |
+
|
277 |
+
this.text = function() {
|
278 |
+
var rejected = consumed(this);
|
279 |
+
if (rejected) {
|
280 |
+
return rejected
|
281 |
+
}
|
282 |
+
|
283 |
+
if (this._bodyBlob) {
|
284 |
+
return readBlobAsText(this._bodyBlob)
|
285 |
+
} else if (this._bodyArrayBuffer) {
|
286 |
+
return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
|
287 |
+
} else if (this._bodyFormData) {
|
288 |
+
throw new Error('could not read FormData body as text')
|
289 |
+
} else {
|
290 |
+
return Promise.resolve(this._bodyText)
|
291 |
+
}
|
292 |
+
};
|
293 |
+
|
294 |
+
if (support.formData) {
|
295 |
+
this.formData = function() {
|
296 |
+
return this.text().then(decode)
|
297 |
+
};
|
298 |
+
}
|
299 |
+
|
300 |
+
this.json = function() {
|
301 |
+
return this.text().then(JSON.parse)
|
302 |
+
};
|
303 |
+
|
304 |
+
return this
|
305 |
+
}
|
306 |
+
|
307 |
+
// HTTP methods whose capitalization should be normalized
|
308 |
+
var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'];
|
309 |
+
|
310 |
+
function normalizeMethod(method) {
|
311 |
+
var upcased = method.toUpperCase();
|
312 |
+
return methods.indexOf(upcased) > -1 ? upcased : method
|
313 |
+
}
|
314 |
+
|
315 |
+
function Request(input, options) {
|
316 |
+
options = options || {};
|
317 |
+
var body = options.body;
|
318 |
+
|
319 |
+
if (input instanceof Request) {
|
320 |
+
if (input.bodyUsed) {
|
321 |
+
throw new TypeError('Already read')
|
322 |
+
}
|
323 |
+
this.url = input.url;
|
324 |
+
this.credentials = input.credentials;
|
325 |
+
if (!options.headers) {
|
326 |
+
this.headers = new Headers(input.headers);
|
327 |
+
}
|
328 |
+
this.method = input.method;
|
329 |
+
this.mode = input.mode;
|
330 |
+
this.signal = input.signal;
|
331 |
+
if (!body && input._bodyInit != null) {
|
332 |
+
body = input._bodyInit;
|
333 |
+
input.bodyUsed = true;
|
334 |
+
}
|
335 |
+
} else {
|
336 |
+
this.url = String(input);
|
337 |
+
}
|
338 |
+
|
339 |
+
this.credentials = options.credentials || this.credentials || 'same-origin';
|
340 |
+
if (options.headers || !this.headers) {
|
341 |
+
this.headers = new Headers(options.headers);
|
342 |
+
}
|
343 |
+
this.method = normalizeMethod(options.method || this.method || 'GET');
|
344 |
+
this.mode = options.mode || this.mode || null;
|
345 |
+
this.signal = options.signal || this.signal;
|
346 |
+
this.referrer = null;
|
347 |
+
|
348 |
+
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
|
349 |
+
throw new TypeError('Body not allowed for GET or HEAD requests')
|
350 |
+
}
|
351 |
+
this._initBody(body);
|
352 |
+
}
|
353 |
+
|
354 |
+
Request.prototype.clone = function() {
|
355 |
+
return new Request(this, {body: this._bodyInit})
|
356 |
+
};
|
357 |
+
|
358 |
+
function decode(body) {
|
359 |
+
var form = new FormData();
|
360 |
+
body
|
361 |
+
.trim()
|
362 |
+
.split('&')
|
363 |
+
.forEach(function(bytes) {
|
364 |
+
if (bytes) {
|
365 |
+
var split = bytes.split('=');
|
366 |
+
var name = split.shift().replace(/\+/g, ' ');
|
367 |
+
var value = split.join('=').replace(/\+/g, ' ');
|
368 |
+
form.append(decodeURIComponent(name), decodeURIComponent(value));
|
369 |
+
}
|
370 |
+
});
|
371 |
+
return form
|
372 |
+
}
|
373 |
+
|
374 |
+
function parseHeaders(rawHeaders) {
|
375 |
+
var headers = new Headers();
|
376 |
+
// Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
|
377 |
+
// https://tools.ietf.org/html/rfc7230#section-3.2
|
378 |
+
var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ');
|
379 |
+
preProcessedHeaders.split(/\r?\n/).forEach(function(line) {
|
380 |
+
var parts = line.split(':');
|
381 |
+
var key = parts.shift().trim();
|
382 |
+
if (key) {
|
383 |
+
var value = parts.join(':').trim();
|
384 |
+
headers.append(key, value);
|
385 |
+
}
|
386 |
+
});
|
387 |
+
return headers
|
388 |
+
}
|
389 |
+
|
390 |
+
Body.call(Request.prototype);
|
391 |
+
|
392 |
+
function Response(bodyInit, options) {
|
393 |
+
if (!options) {
|
394 |
+
options = {};
|
395 |
+
}
|
396 |
+
|
397 |
+
this.type = 'default';
|
398 |
+
this.status = options.status === undefined ? 200 : options.status;
|
399 |
+
this.ok = this.status >= 200 && this.status < 300;
|
400 |
+
this.statusText = 'statusText' in options ? options.statusText : 'OK';
|
401 |
+
this.headers = new Headers(options.headers);
|
402 |
+
this.url = options.url || '';
|
403 |
+
this._initBody(bodyInit);
|
404 |
+
}
|
405 |
+
|
406 |
+
Body.call(Response.prototype);
|
407 |
+
|
408 |
+
Response.prototype.clone = function() {
|
409 |
+
return new Response(this._bodyInit, {
|
410 |
+
status: this.status,
|
411 |
+
statusText: this.statusText,
|
412 |
+
headers: new Headers(this.headers),
|
413 |
+
url: this.url
|
414 |
+
})
|
415 |
+
};
|
416 |
+
|
417 |
+
Response.error = function() {
|
418 |
+
var response = new Response(null, {status: 0, statusText: ''});
|
419 |
+
response.type = 'error';
|
420 |
+
return response
|
421 |
+
};
|
422 |
+
|
423 |
+
var redirectStatuses = [301, 302, 303, 307, 308];
|
424 |
+
|
425 |
+
Response.redirect = function(url, status) {
|
426 |
+
if (redirectStatuses.indexOf(status) === -1) {
|
427 |
+
throw new RangeError('Invalid status code')
|
428 |
+
}
|
429 |
+
|
430 |
+
return new Response(null, {status: status, headers: {location: url}})
|
431 |
+
};
|
432 |
+
|
433 |
+
exports.DOMException = self.DOMException;
|
434 |
+
try {
|
435 |
+
new exports.DOMException();
|
436 |
+
} catch (err) {
|
437 |
+
exports.DOMException = function(message, name) {
|
438 |
+
this.message = message;
|
439 |
+
this.name = name;
|
440 |
+
var error = Error(message);
|
441 |
+
this.stack = error.stack;
|
442 |
+
};
|
443 |
+
exports.DOMException.prototype = Object.create(Error.prototype);
|
444 |
+
exports.DOMException.prototype.constructor = exports.DOMException;
|
445 |
+
}
|
446 |
+
|
447 |
+
function fetch(input, init) {
|
448 |
+
return new Promise(function(resolve, reject) {
|
449 |
+
var request = new Request(input, init);
|
450 |
+
|
451 |
+
if (request.signal && request.signal.aborted) {
|
452 |
+
return reject(new exports.DOMException('Aborted', 'AbortError'))
|
453 |
+
}
|
454 |
+
|
455 |
+
var xhr = new XMLHttpRequest();
|
456 |
+
|
457 |
+
function abortXhr() {
|
458 |
+
xhr.abort();
|
459 |
+
}
|
460 |
+
|
461 |
+
xhr.onload = function() {
|
462 |
+
var options = {
|
463 |
+
status: xhr.status,
|
464 |
+
statusText: xhr.statusText,
|
465 |
+
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
|
466 |
+
};
|
467 |
+
options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');
|
468 |
+
var body = 'response' in xhr ? xhr.response : xhr.responseText;
|
469 |
+
resolve(new Response(body, options));
|
470 |
+
};
|
471 |
+
|
472 |
+
xhr.onerror = function() {
|
473 |
+
reject(new TypeError('Network request failed'));
|
474 |
+
};
|
475 |
+
|
476 |
+
xhr.ontimeout = function() {
|
477 |
+
reject(new TypeError('Network request failed'));
|
478 |
+
};
|
479 |
+
|
480 |
+
xhr.onabort = function() {
|
481 |
+
reject(new exports.DOMException('Aborted', 'AbortError'));
|
482 |
+
};
|
483 |
+
|
484 |
+
xhr.open(request.method, request.url, true);
|
485 |
+
|
486 |
+
if (request.credentials === 'include') {
|
487 |
+
xhr.withCredentials = true;
|
488 |
+
} else if (request.credentials === 'omit') {
|
489 |
+
xhr.withCredentials = false;
|
490 |
+
}
|
491 |
+
|
492 |
+
if ('responseType' in xhr && support.blob) {
|
493 |
+
xhr.responseType = 'blob';
|
494 |
+
}
|
495 |
+
|
496 |
+
request.headers.forEach(function(value, name) {
|
497 |
+
xhr.setRequestHeader(name, value);
|
498 |
+
});
|
499 |
+
|
500 |
+
if (request.signal) {
|
501 |
+
request.signal.addEventListener('abort', abortXhr);
|
502 |
+
|
503 |
+
xhr.onreadystatechange = function() {
|
504 |
+
// DONE (success or failure)
|
505 |
+
if (xhr.readyState === 4) {
|
506 |
+
request.signal.removeEventListener('abort', abortXhr);
|
507 |
+
}
|
508 |
+
};
|
509 |
+
}
|
510 |
+
|
511 |
+
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);
|
512 |
+
})
|
513 |
+
}
|
514 |
+
|
515 |
+
fetch.polyfill = true;
|
516 |
+
|
517 |
+
if (!self.fetch) {
|
518 |
+
self.fetch = fetch;
|
519 |
+
self.Headers = Headers;
|
520 |
+
self.Request = Request;
|
521 |
+
self.Response = Response;
|
522 |
+
}
|
523 |
+
|
524 |
+
exports.Headers = Headers;
|
525 |
+
exports.Request = Request;
|
526 |
+
exports.Response = Response;
|
527 |
+
exports.fetch = fetch;
|
528 |
+
|
529 |
+
Object.defineProperty(exports, '__esModule', { value: true });
|
530 |
+
|
531 |
+
})));
|
inc/assets/js/node_modules/whatwg-fetch/dist/fetch.umd.js.flow
ADDED
@@ -0,0 +1,119 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
/* @flow strict */
|
2 |
+
|
3 |
+
type CredentialsType = 'omit' | 'same-origin' | 'include'
|
4 |
+
|
5 |
+
type ResponseType = 'default' | 'error'
|
6 |
+
|
7 |
+
type BodyInit = string | URLSearchParams | FormData | Blob | ArrayBuffer | $ArrayBufferView
|
8 |
+
|
9 |
+
type RequestInfo = Request | URL | string
|
10 |
+
|
11 |
+
type RequestOptions = {|
|
12 |
+
body?: ?BodyInit;
|
13 |
+
|
14 |
+
credentials?: CredentialsType;
|
15 |
+
headers?: HeadersInit;
|
16 |
+
method?: string;
|
17 |
+
mode?: string;
|
18 |
+
referrer?: string;
|
19 |
+
signal?: ?AbortSignal;
|
20 |
+
|}
|
21 |
+
|
22 |
+
type ResponseOptions = {|
|
23 |
+
status?: number;
|
24 |
+
statusText?: string;
|
25 |
+
headers?: HeadersInit;
|
26 |
+
|}
|
27 |
+
|
28 |
+
type HeadersInit = Headers | {[string]: string}
|
29 |
+
|
30 |
+
// https://github.com/facebook/flow/blob/f68b89a5012bd995ab3509e7a41b7325045c4045/lib/bom.js#L902-L914
|
31 |
+
declare class Headers {
|
32 |
+
@@iterator(): Iterator<[string, string]>;
|
33 |
+
constructor(init?: HeadersInit): void;
|
34 |
+
append(name: string, value: string): void;
|
35 |
+
delete(name: string): void;
|
36 |
+
entries(): Iterator<[string, string]>;
|
37 |
+
forEach((value: string, name: string, headers: Headers) => any, thisArg?: any): void;
|
38 |
+
get(name: string): null | string;
|
39 |
+
has(name: string): boolean;
|
40 |
+
keys(): Iterator<string>;
|
41 |
+
set(name: string, value: string): void;
|
42 |
+
values(): Iterator<string>;
|
43 |
+
}
|
44 |
+
|
45 |
+
// https://github.com/facebook/flow/pull/6548
|
46 |
+
interface AbortSignal {
|
47 |
+
aborted: boolean;
|
48 |
+
addEventListener(type: string, listener: (Event) => mixed, options?: EventListenerOptionsOrUseCapture): void;
|
49 |
+
removeEventListener(type: string, listener: (Event) => mixed, options?: EventListenerOptionsOrUseCapture): void;
|
50 |
+
}
|
51 |
+
|
52 |
+
// https://github.com/facebook/flow/blob/f68b89a5012bd995ab3509e7a41b7325045c4045/lib/bom.js#L994-L1018
|
53 |
+
// unsupported in polyfill:
|
54 |
+
// - cache
|
55 |
+
// - integrity
|
56 |
+
// - redirect
|
57 |
+
// - referrerPolicy
|
58 |
+
declare class Request {
|
59 |
+
constructor(input: RequestInfo, init?: RequestOptions): void;
|
60 |
+
clone(): Request;
|
61 |
+
|
62 |
+
url: string;
|
63 |
+
|
64 |
+
credentials: CredentialsType;
|
65 |
+
headers: Headers;
|
66 |
+
method: string;
|
67 |
+
mode: ModeType;
|
68 |
+
referrer: string;
|
69 |
+
signal: ?AbortSignal;
|
70 |
+
|
71 |
+
// Body methods and attributes
|
72 |
+
bodyUsed: boolean;
|
73 |
+
|
74 |
+
arrayBuffer(): Promise<ArrayBuffer>;
|
75 |
+
blob(): Promise<Blob>;
|
76 |
+
formData(): Promise<FormData>;
|
77 |
+
json(): Promise<any>;
|
78 |
+
text(): Promise<string>;
|
79 |
+
}
|
80 |
+
|
81 |
+
// https://github.com/facebook/flow/blob/f68b89a5012bd995ab3509e7a41b7325045c4045/lib/bom.js#L968-L992
|
82 |
+
// unsupported in polyfill:
|
83 |
+
// - body
|
84 |
+
// - redirected
|
85 |
+
// - trailer
|
86 |
+
declare class Response {
|
87 |
+
constructor(input?: ?BodyInit, init?: ResponseOptions): void;
|
88 |
+
clone(): Response;
|
89 |
+
static error(): Response;
|
90 |
+
static redirect(url: string, status?: number): Response;
|
91 |
+
|
92 |
+
type: ResponseType;
|
93 |
+
url: string;
|
94 |
+
ok: boolean;
|
95 |
+
status: number;
|
96 |
+
statusText: string;
|
97 |
+
headers: Headers;
|
98 |
+
|
99 |
+
// Body methods and attributes
|
100 |
+
bodyUsed: boolean;
|
101 |
+
|
102 |
+
arrayBuffer(): Promise<ArrayBuffer>;
|
103 |
+
blob(): Promise<Blob>;
|
104 |
+
formData(): Promise<FormData>;
|
105 |
+
json(): Promise<any>;
|
106 |
+
text(): Promise<string>;
|
107 |
+
}
|
108 |
+
|
109 |
+
declare class DOMException extends Error {
|
110 |
+
constructor(message?: string, name?: string): void;
|
111 |
+
}
|
112 |
+
|
113 |
+
declare module.exports: {
|
114 |
+
fetch(input: RequestInfo, init?: RequestOptions): Promise<Response>;
|
115 |
+
Headers: typeof Headers;
|
116 |
+
Request: typeof Request;
|
117 |
+
Response: typeof Response;
|
118 |
+
DOMException: typeof DOMException;
|
119 |
+
}
|
inc/assets/js/node_modules/whatwg-fetch/fetch.js
ADDED
@@ -0,0 +1,516 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
var support = {
|
2 |
+
searchParams: 'URLSearchParams' in self,
|
3 |
+
iterable: 'Symbol' in self && 'iterator' in Symbol,
|
4 |
+
blob:
|
5 |
+
'FileReader' in self &&
|
6 |
+
'Blob' in self &&
|
7 |
+
(function() {
|
8 |
+
try {
|
9 |
+
new Blob()
|
10 |
+
return true
|
11 |
+
} catch (e) {
|
12 |
+
return false
|
13 |
+
}
|
14 |
+
})(),
|
15 |
+
formData: 'FormData' in self,
|
16 |
+
arrayBuffer: 'ArrayBuffer' in self
|
17 |
+
}
|
18 |
+
|
19 |
+
function isDataView(obj) {
|
20 |
+
return obj && DataView.prototype.isPrototypeOf(obj)
|
21 |
+
}
|
22 |
+
|
23 |
+
if (support.arrayBuffer) {
|
24 |
+
var viewClasses = [
|
25 |
+
'[object Int8Array]',
|
26 |
+
'[object Uint8Array]',
|
27 |
+
'[object Uint8ClampedArray]',
|
28 |
+
'[object Int16Array]',
|
29 |
+
'[object Uint16Array]',
|
30 |
+
'[object Int32Array]',
|
31 |
+
'[object Uint32Array]',
|
32 |
+
'[object Float32Array]',
|
33 |
+
'[object Float64Array]'
|
34 |
+
]
|
35 |
+
|
36 |
+
var isArrayBufferView =
|
37 |
+
ArrayBuffer.isView ||
|
38 |
+
function(obj) {
|
39 |
+
return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
function normalizeName(name) {
|
44 |
+
if (typeof name !== 'string') {
|
45 |
+
name = String(name)
|
46 |
+
}
|
47 |
+
if (/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(name)) {
|
48 |
+
throw new TypeError('Invalid character in header field name')
|
49 |
+
}
|
50 |
+
return name.toLowerCase()
|
51 |
+
}
|
52 |
+
|
53 |
+
function normalizeValue(value) {
|
54 |
+
if (typeof value !== 'string') {
|
55 |
+
value = String(value)
|
56 |
+
}
|
57 |
+
return value
|
58 |
+
}
|
59 |
+
|
60 |
+
// Build a destructive iterator for the value list
|
61 |
+
function iteratorFor(items) {
|
62 |
+
var iterator = {
|
63 |
+
next: function() {
|
64 |
+
var value = items.shift()
|
65 |
+
return {done: value === undefined, value: value}
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
if (support.iterable) {
|
70 |
+
iterator[Symbol.iterator] = function() {
|
71 |
+
return iterator
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
+
return iterator
|
76 |
+
}
|
77 |
+
|
78 |
+
export function Headers(headers) {
|
79 |
+
this.map = {}
|
80 |
+
|
81 |
+
if (headers instanceof Headers) {
|
82 |
+
headers.forEach(function(value, name) {
|
83 |
+
this.append(name, value)
|
84 |
+
}, this)
|
85 |
+
} else if (Array.isArray(headers)) {
|
86 |
+
headers.forEach(function(header) {
|
87 |
+
this.append(header[0], header[1])
|
88 |
+
}, this)
|
89 |
+
} else if (headers) {
|
90 |
+
Object.getOwnPropertyNames(headers).forEach(function(name) {
|
91 |
+
this.append(name, headers[name])
|
92 |
+
}, this)
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
Headers.prototype.append = function(name, value) {
|
97 |
+
name = normalizeName(name)
|
98 |
+
value = normalizeValue(value)
|
99 |
+
var oldValue = this.map[name]
|
100 |
+
this.map[name] = oldValue ? oldValue + ', ' + value : value
|
101 |
+
}
|
102 |
+
|
103 |
+
Headers.prototype['delete'] = function(name) {
|
104 |
+
delete this.map[normalizeName(name)]
|
105 |
+
}
|
106 |
+
|
107 |
+
Headers.prototype.get = function(name) {
|
108 |
+
name = normalizeName(name)
|
109 |
+
return this.has(name) ? this.map[name] : null
|
110 |
+
}
|
111 |
+
|
112 |
+
Headers.prototype.has = function(name) {
|
113 |
+
return this.map.hasOwnProperty(normalizeName(name))
|
114 |
+
}
|
115 |
+
|
116 |
+
Headers.prototype.set = function(name, value) {
|
117 |
+
this.map[normalizeName(name)] = normalizeValue(value)
|
118 |
+
}
|
119 |
+
|
120 |
+
Headers.prototype.forEach = function(callback, thisArg) {
|
121 |
+
for (var name in this.map) {
|
122 |
+
if (this.map.hasOwnProperty(name)) {
|
123 |
+
callback.call(thisArg, this.map[name], name, this)
|
124 |
+
}
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
Headers.prototype.keys = function() {
|
129 |
+
var items = []
|
130 |
+
this.forEach(function(value, name) {
|
131 |
+
items.push(name)
|
132 |
+
})
|
133 |
+
return iteratorFor(items)
|
134 |
+
}
|
135 |
+
|
136 |
+
Headers.prototype.values = function() {
|
137 |
+
var items = []
|
138 |
+
this.forEach(function(value) {
|
139 |
+
items.push(value)
|
140 |
+
})
|
141 |
+
return iteratorFor(items)
|
142 |
+
}
|
143 |
+
|
144 |
+
Headers.prototype.entries = function() {
|
145 |
+
var items = []
|
146 |
+
this.forEach(function(value, name) {
|
147 |
+
items.push([name, value])
|
148 |
+
})
|
149 |
+
return iteratorFor(items)
|
150 |
+
}
|
151 |
+
|
152 |
+
if (support.iterable) {
|
153 |
+
Headers.prototype[Symbol.iterator] = Headers.prototype.entries
|
154 |
+
}
|
155 |
+
|
156 |
+
function consumed(body) {
|
157 |
+
if (body.bodyUsed) {
|
158 |
+
return Promise.reject(new TypeError('Already read'))
|
159 |
+
}
|
160 |
+
body.bodyUsed = true
|
161 |
+
}
|
162 |
+
|
163 |
+
function fileReaderReady(reader) {
|
164 |
+
return new Promise(function(resolve, reject) {
|
165 |
+
reader.onload = function() {
|
166 |
+
resolve(reader.result)
|
167 |
+
}
|
168 |
+
reader.onerror = function() {
|
169 |
+
reject(reader.error)
|
170 |
+
}
|
171 |
+
})
|
172 |
+
}
|
173 |
+
|
174 |
+
function readBlobAsArrayBuffer(blob) {
|
175 |
+
var reader = new FileReader()
|
176 |
+
var promise = fileReaderReady(reader)
|
177 |
+
reader.readAsArrayBuffer(blob)
|
178 |
+
return promise
|
179 |
+
}
|
180 |
+
|
181 |
+
function readBlobAsText(blob) {
|
182 |
+
var reader = new FileReader()
|
183 |
+
var promise = fileReaderReady(reader)
|
184 |
+
reader.readAsText(blob)
|
185 |
+
return promise
|
186 |
+
}
|
187 |
+
|
188 |
+
function readArrayBufferAsText(buf) {
|
189 |
+
var view = new Uint8Array(buf)
|
190 |
+
var chars = new Array(view.length)
|
191 |
+
|
192 |
+
for (var i = 0; i < view.length; i++) {
|
193 |
+
chars[i] = String.fromCharCode(view[i])
|
194 |
+
}
|
195 |
+
return chars.join('')
|
196 |
+
}
|
197 |
+
|
198 |
+
function bufferClone(buf) {
|
199 |
+
if (buf.slice) {
|
200 |
+
return buf.slice(0)
|
201 |
+
} else {
|
202 |
+
var view = new Uint8Array(buf.byteLength)
|
203 |
+
view.set(new Uint8Array(buf))
|
204 |
+
return view.buffer
|
205 |
+
}
|
206 |
+
}
|
207 |
+
|
208 |
+
function Body() {
|
209 |
+
this.bodyUsed = false
|
210 |
+
|
211 |
+
this._initBody = function(body) {
|
212 |
+
this._bodyInit = body
|
213 |
+
if (!body) {
|
214 |
+
this._bodyText = ''
|
215 |
+
} else if (typeof body === 'string') {
|
216 |
+
this._bodyText = body
|
217 |
+
} else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
|
218 |
+
this._bodyBlob = body
|
219 |
+
} else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
|
220 |
+
this._bodyFormData = body
|
221 |
+
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
|
222 |
+
this._bodyText = body.toString()
|
223 |
+
} else if (support.arrayBuffer && support.blob && isDataView(body)) {
|
224 |
+
this._bodyArrayBuffer = bufferClone(body.buffer)
|
225 |
+
// IE 10-11 can't handle a DataView body.
|
226 |
+
this._bodyInit = new Blob([this._bodyArrayBuffer])
|
227 |
+
} else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
|
228 |
+
this._bodyArrayBuffer = bufferClone(body)
|
229 |
+
} else {
|
230 |
+
this._bodyText = body = Object.prototype.toString.call(body)
|
231 |
+
}
|
232 |
+
|
233 |
+
if (!this.headers.get('content-type')) {
|
234 |
+
if (typeof body === 'string') {
|
235 |
+
this.headers.set('content-type', 'text/plain;charset=UTF-8')
|
236 |
+
} else if (this._bodyBlob && this._bodyBlob.type) {
|
237 |
+
this.headers.set('content-type', this._bodyBlob.type)
|
238 |
+
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
|
239 |
+
this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8')
|
240 |
+
}
|
241 |
+
}
|
242 |
+
}
|
243 |
+
|
244 |
+
if (support.blob) {
|
245 |
+
this.blob = function() {
|
246 |
+
var rejected = consumed(this)
|
247 |
+
if (rejected) {
|
248 |
+
return rejected
|
249 |
+
}
|
250 |
+
|
251 |
+
if (this._bodyBlob) {
|
252 |
+
return Promise.resolve(this._bodyBlob)
|
253 |
+
} else if (this._bodyArrayBuffer) {
|
254 |
+
return Promise.resolve(new Blob([this._bodyArrayBuffer]))
|
255 |
+
} else if (this._bodyFormData) {
|
256 |
+
throw new Error('could not read FormData body as blob')
|
257 |
+
} else {
|
258 |
+
return Promise.resolve(new Blob([this._bodyText]))
|
259 |
+
}
|
260 |
+
}
|
261 |
+
|
262 |
+
this.arrayBuffer = function() {
|
263 |
+
if (this._bodyArrayBuffer) {
|
264 |
+
return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
|
265 |
+
} else {
|
266 |
+
return this.blob().then(readBlobAsArrayBuffer)
|
267 |
+
}
|
268 |
+
}
|
269 |
+
}
|
270 |
+
|
271 |
+
this.text = function() {
|
272 |
+
var rejected = consumed(this)
|
273 |
+
if (rejected) {
|
274 |
+
return rejected
|
275 |
+
}
|
276 |
+
|
277 |
+
if (this._bodyBlob) {
|
278 |
+
return readBlobAsText(this._bodyBlob)
|
279 |
+
} else if (this._bodyArrayBuffer) {
|
280 |
+
return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
|
281 |
+
} else if (this._bodyFormData) {
|
282 |
+
throw new Error('could not read FormData body as text')
|
283 |
+
} else {
|
284 |
+
return Promise.resolve(this._bodyText)
|
285 |
+
}
|
286 |
+
}
|
287 |
+
|
288 |
+
if (support.formData) {
|
289 |
+
this.formData = function() {
|
290 |
+
return this.text().then(decode)
|
291 |
+
}
|
292 |
+
}
|
293 |
+
|
294 |
+
this.json = function() {
|
295 |
+
return this.text().then(JSON.parse)
|
296 |
+
}
|
297 |
+
|
298 |
+
return this
|
299 |
+
}
|
300 |
+
|
301 |
+
// HTTP methods whose capitalization should be normalized
|
302 |
+
var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']
|
303 |
+
|
304 |
+
function normalizeMethod(method) {
|
305 |
+
var upcased = method.toUpperCase()
|
306 |
+
return methods.indexOf(upcased) > -1 ? upcased : method
|
307 |
+
}
|
308 |
+
|
309 |
+
export function Request(input, options) {
|
310 |
+
options = options || {}
|
311 |
+
var body = options.body
|
312 |
+
|
313 |
+
if (input instanceof Request) {
|
314 |
+
if (input.bodyUsed) {
|
315 |
+
throw new TypeError('Already read')
|
316 |
+
}
|
317 |
+
this.url = input.url
|
318 |
+
this.credentials = input.credentials
|
319 |
+
if (!options.headers) {
|
320 |
+
this.headers = new Headers(input.headers)
|
321 |
+
}
|
322 |
+
this.method = input.method
|
323 |
+
this.mode = input.mode
|
324 |
+
this.signal = input.signal
|
325 |
+
if (!body && input._bodyInit != null) {
|
326 |
+
body = input._bodyInit
|
327 |
+
input.bodyUsed = true
|
328 |
+
}
|
329 |
+
} else {
|
330 |
+
this.url = String(input)
|
331 |
+
}
|
332 |
+
|
333 |
+
this.credentials = options.credentials || this.credentials || 'same-origin'
|
334 |
+
if (options.headers || !this.headers) {
|
335 |
+
this.headers = new Headers(options.headers)
|
336 |
+
}
|
337 |
+
this.method = normalizeMethod(options.method || this.method || 'GET')
|
338 |
+
this.mode = options.mode || this.mode || null
|
339 |
+
this.signal = options.signal || this.signal
|
340 |
+
this.referrer = null
|
341 |
+
|
342 |
+
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
|
343 |
+
throw new TypeError('Body not allowed for GET or HEAD requests')
|
344 |
+
}
|
345 |
+
this._initBody(body)
|
346 |
+
}
|
347 |
+
|
348 |
+
Request.prototype.clone = function() {
|
349 |
+
return new Request(this, {body: this._bodyInit})
|
350 |
+
}
|
351 |
+
|
352 |
+
function decode(body) {
|
353 |
+
var form = new FormData()
|
354 |
+
body
|
355 |
+
.trim()
|
356 |
+
.split('&')
|
357 |
+
.forEach(function(bytes) {
|
358 |
+
if (bytes) {
|
359 |
+
var split = bytes.split('=')
|
360 |
+
var name = split.shift().replace(/\+/g, ' ')
|
361 |
+
var value = split.join('=').replace(/\+/g, ' ')
|
362 |
+
form.append(decodeURIComponent(name), decodeURIComponent(value))
|
363 |
+
}
|
364 |
+
})
|
365 |
+
return form
|
366 |
+
}
|
367 |
+
|
368 |
+
function parseHeaders(rawHeaders) {
|
369 |
+
var headers = new Headers()
|
370 |
+
// Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
|
371 |
+
// https://tools.ietf.org/html/rfc7230#section-3.2
|
372 |
+
var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ')
|
373 |
+
preProcessedHeaders.split(/\r?\n/).forEach(function(line) {
|
374 |
+
var parts = line.split(':')
|
375 |
+
var key = parts.shift().trim()
|
376 |
+
if (key) {
|
377 |
+
var value = parts.join(':').trim()
|
378 |
+
headers.append(key, value)
|
379 |
+
}
|
380 |
+
})
|
381 |
+
return headers
|
382 |
+
}
|
383 |
+
|
384 |
+
Body.call(Request.prototype)
|
385 |
+
|
386 |
+
export function Response(bodyInit, options) {
|
387 |
+
if (!options) {
|
388 |
+
options = {}
|
389 |
+
}
|
390 |
+
|
391 |
+
this.type = 'default'
|
392 |
+
this.status = options.status === undefined ? 200 : options.status
|
393 |
+
this.ok = this.status >= 200 && this.status < 300
|
394 |
+
this.statusText = 'statusText' in options ? options.statusText : 'OK'
|
395 |
+
this.headers = new Headers(options.headers)
|
396 |
+
this.url = options.url || ''
|
397 |
+
this._initBody(bodyInit)
|
398 |
+
}
|
399 |
+
|
400 |
+
Body.call(Response.prototype)
|
401 |
+
|
402 |
+
Response.prototype.clone = function() {
|
403 |
+
return new Response(this._bodyInit, {
|
404 |
+
status: this.status,
|
405 |
+
statusText: this.statusText,
|
406 |
+
headers: new Headers(this.headers),
|
407 |
+
url: this.url
|
408 |
+
})
|
409 |
+
}
|
410 |
+
|
411 |
+
Response.error = function() {
|
412 |
+
var response = new Response(null, {status: 0, statusText: ''})
|
413 |
+
response.type = 'error'
|
414 |
+
return response
|
415 |
+
}
|
416 |
+
|
417 |
+
var redirectStatuses = [301, 302, 303, 307, 308]
|
418 |
+
|
419 |
+
Response.redirect = function(url, status) {
|
420 |
+
if (redirectStatuses.indexOf(status) === -1) {
|
421 |
+
throw new RangeError('Invalid status code')
|
422 |
+
}
|
423 |
+
|
424 |
+
return new Response(null, {status: status, headers: {location: url}})
|
425 |
+
}
|
426 |
+
|
427 |
+
export var DOMException = self.DOMException
|
428 |
+
try {
|
429 |
+
new DOMException()
|
430 |
+
} catch (err) {
|
431 |
+
DOMException = function(message, name) {
|
432 |
+
this.message = message
|
433 |
+
this.name = name
|
434 |
+
var error = Error(message)
|
435 |
+
this.stack = error.stack
|
436 |
+
}
|
437 |
+
DOMException.prototype = Object.create(Error.prototype)
|
438 |
+
DOMException.prototype.constructor = DOMException
|
439 |
+
}
|
440 |
+
|
441 |
+
export function fetch(input, init) {
|
442 |
+
return new Promise(function(resolve, reject) {
|
443 |
+
var request = new Request(input, init)
|
444 |
+
|
445 |
+
if (request.signal && request.signal.aborted) {
|
446 |
+
return reject(new DOMException('Aborted', 'AbortError'))
|
447 |
+
}
|
448 |
+
|
449 |
+
var xhr = new XMLHttpRequest()
|
450 |
+
|
451 |
+
function abortXhr() {
|
452 |
+
xhr.abort()
|
453 |
+
}
|
454 |
+
|
455 |
+
xhr.onload = function() {
|
456 |
+
var options = {
|
457 |
+
status: xhr.status,
|
458 |
+
statusText: xhr.statusText,
|
459 |
+
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
|
460 |
+
}
|
461 |
+
options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL')
|
462 |
+
var body = 'response' in xhr ? xhr.response : xhr.responseText
|
463 |
+
resolve(new Response(body, options))
|
464 |
+
}
|
465 |
+
|
466 |
+
xhr.onerror = function() {
|
467 |
+
reject(new TypeError('Network request failed'))
|
468 |
+
}
|
469 |
+
|
470 |
+
xhr.ontimeout = function() {
|
471 |
+
reject(new TypeError('Network request failed'))
|
472 |
+
}
|
473 |
+
|
474 |
+
xhr.onabort = function() {
|
475 |
+
reject(new DOMException('Aborted', 'AbortError'))
|
476 |
+
}
|
477 |
+
|
478 |
+
xhr.open(request.method, request.url, true)
|
479 |
+
|
480 |
+
if (request.credentials === 'include') {
|
481 |
+
xhr.withCredentials = true
|
482 |
+
} else if (request.credentials === 'omit') {
|
483 |
+
xhr.withCredentials = false
|
484 |
+
}
|
485 |
+
|
486 |
+
if ('responseType' in xhr && support.blob) {
|
487 |
+
xhr.responseType = 'blob'
|
488 |
+
}
|
489 |
+
|
490 |
+
request.headers.forEach(function(value, name) {
|
491 |
+
xhr.setRequestHeader(name, value)
|
492 |
+
})
|
493 |
+
|
494 |
+
if (request.signal) {
|
495 |
+
request.signal.addEventListener('abort', abortXhr)
|
496 |
+
|
497 |
+
xhr.onreadystatechange = function() {
|
498 |
+
// DONE (success or failure)
|
499 |
+
if (xhr.readyState === 4) {
|
500 |
+
request.signal.removeEventListener('abort', abortXhr)
|
501 |
+
}
|
502 |
+
}
|
503 |
+
}
|
504 |
+
|
505 |
+
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
|
506 |
+
})
|
507 |
+
}
|
508 |
+
|
509 |
+
fetch.polyfill = true
|
510 |
+
|
511 |
+
if (!self.fetch) {
|
512 |
+
self.fetch = fetch
|
513 |
+
self.Headers = Headers
|
514 |
+
self.Request = Request
|
515 |
+
self.Response = Response
|
516 |
+
}
|
inc/assets/js/node_modules/whatwg-fetch/fetch.js.flow
ADDED
@@ -0,0 +1,119 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
/* @flow strict */
|
2 |
+
|
3 |
+
type CredentialsType = 'omit' | 'same-origin' | 'include'
|
4 |
+
|
5 |
+
type ResponseType = 'default' | 'error'
|
6 |
+
|
7 |
+
type BodyInit = string | URLSearchParams | FormData | Blob | ArrayBuffer | $ArrayBufferView
|
8 |
+
|
9 |
+
type RequestInfo = Request | URL | string
|
10 |
+
|
11 |
+
type RequestOptions = {|
|
12 |
+
body?: ?BodyInit;
|
13 |
+
|
14 |
+
credentials?: CredentialsType;
|
15 |
+
headers?: HeadersInit;
|
16 |
+
method?: string;
|
17 |
+
mode?: string;
|
18 |
+
referrer?: string;
|
19 |
+
signal?: ?AbortSignal;
|
20 |
+
|}
|
21 |
+
|
22 |
+
type ResponseOptions = {|
|
23 |
+
status?: number;
|
24 |
+
statusText?: string;
|
25 |
+
headers?: HeadersInit;
|
26 |
+
|}
|
27 |
+
|
28 |
+
type HeadersInit = Headers | {[string]: string}
|
29 |
+
|
30 |
+
// https://github.com/facebook/flow/blob/f68b89a5012bd995ab3509e7a41b7325045c4045/lib/bom.js#L902-L914
|
31 |
+
declare class Headers {
|
32 |
+
@@iterator(): Iterator<[string, string]>;
|
33 |
+
constructor(init?: HeadersInit): void;
|
34 |
+
append(name: string, value: string): void;
|
35 |
+
delete(name: string): void;
|
36 |
+
entries(): Iterator<[string, string]>;
|
37 |
+
forEach((value: string, name: string, headers: Headers) => any, thisArg?: any): void;
|
38 |
+
get(name: string): null | string;
|
39 |
+
has(name: string): boolean;
|
40 |
+
keys(): Iterator<string>;
|
41 |
+
set(name: string, value: string): void;
|
42 |
+
values(): Iterator<string>;
|
43 |
+
}
|
44 |
+
|
45 |
+
// https://github.com/facebook/flow/pull/6548
|
46 |
+
interface AbortSignal {
|
47 |
+
aborted: boolean;
|
48 |
+
addEventListener(type: string, listener: (Event) => mixed, options?: EventListenerOptionsOrUseCapture): void;
|
49 |
+
removeEventListener(type: string, listener: (Event) => mixed, options?: EventListenerOptionsOrUseCapture): void;
|
50 |
+
}
|
51 |
+
|
52 |
+
// https://github.com/facebook/flow/blob/f68b89a5012bd995ab3509e7a41b7325045c4045/lib/bom.js#L994-L1018
|
53 |
+
// unsupported in polyfill:
|
54 |
+
// - cache
|
55 |
+
// - integrity
|
56 |
+
// - redirect
|
57 |
+
// - referrerPolicy
|
58 |
+
declare class Request {
|
59 |
+
constructor(input: RequestInfo, init?: RequestOptions): void;
|
60 |
+
clone(): Request;
|
61 |
+
|
62 |
+
url: string;
|
63 |
+
|
64 |
+
credentials: CredentialsType;
|
65 |
+
headers: Headers;
|
66 |
+
method: string;
|
67 |
+
mode: ModeType;
|
68 |
+
referrer: string;
|
69 |
+
signal: ?AbortSignal;
|
70 |
+
|
71 |
+
// Body methods and attributes
|
72 |
+
bodyUsed: boolean;
|
73 |
+
|
74 |
+
arrayBuffer(): Promise<ArrayBuffer>;
|
75 |
+
blob(): Promise<Blob>;
|
76 |
+
formData(): Promise<FormData>;
|
77 |
+
json(): Promise<any>;
|
78 |
+
text(): Promise<string>;
|
79 |
+
}
|
80 |
+
|
81 |
+
// https://github.com/facebook/flow/blob/f68b89a5012bd995ab3509e7a41b7325045c4045/lib/bom.js#L968-L992
|
82 |
+
// unsupported in polyfill:
|
83 |
+
// - body
|
84 |
+
// - redirected
|
85 |
+
// - trailer
|
86 |
+
declare class Response {
|
87 |
+
constructor(input?: ?BodyInit, init?: ResponseOptions): void;
|
88 |
+
clone(): Response;
|
89 |
+
static error(): Response;
|
90 |
+
static redirect(url: string, status?: number): Response;
|
91 |
+
|
92 |
+
type: ResponseType;
|
93 |
+
url: string;
|
94 |
+
ok: boolean;
|
95 |
+
status: number;
|
96 |
+
statusText: string;
|
97 |
+
headers: Headers;
|
98 |
+
|
99 |
+
// Body methods and attributes
|
100 |
+
bodyUsed: boolean;
|
101 |
+
|
102 |
+
arrayBuffer(): Promise<ArrayBuffer>;
|
103 |
+
blob(): Promise<Blob>;
|
104 |
+
formData(): Promise<FormData>;
|
105 |
+
json(): Promise<any>;
|
106 |
+
text(): Promise<string>;
|
107 |
+
}
|
108 |
+
|
109 |
+
declare class DOMException extends Error {
|
110 |
+
constructor(message?: string, name?: string): void;
|
111 |
+
}
|
112 |
+
|
113 |
+
declare module.exports: {
|
114 |
+
fetch(input: RequestInfo, init?: RequestOptions): Promise<Response>;
|
115 |
+
Headers: typeof Headers;
|
116 |
+
Request: typeof Request;
|
117 |
+
Response: typeof Response;
|
118 |
+
DOMException: typeof DOMException;
|
119 |
+
}
|
inc/assets/js/node_modules/whatwg-fetch/package.json
ADDED
@@ -0,0 +1,73 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
{
|
2 |
+
"_from": "whatwg-fetch",
|
3 |
+
"_id": "whatwg-fetch@3.0.0",
|
4 |
+
"_inBundle": false,
|
5 |
+
"_integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==",
|
6 |
+
"_location": "/whatwg-fetch",
|
7 |
+
"_phantomChildren": {},
|
8 |
+
"_requested": {
|
9 |
+
"type": "tag",
|
10 |
+
"registry": true,
|
11 |
+
"raw": "whatwg-fetch",
|
12 |
+
"name": "whatwg-fetch",
|
13 |
+
"escapedName": "whatwg-fetch",
|
14 |
+
"rawSpec": "",
|
15 |
+
"saveSpec": null,
|
16 |
+
"fetchSpec": "latest"
|
17 |
+
},
|
18 |
+
"_requiredBy": [
|
19 |
+
"#USER",
|
20 |
+
"/"
|
21 |
+
],
|
22 |
+
"_resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
|
23 |
+
"_shasum": "fc804e458cc460009b1a2b966bc8817d2578aefb",
|
24 |
+
"_spec": "whatwg-fetch",
|
25 |
+
"_where": "C:\\xampp\\htdocs\\tutorials\\js-fetch",
|
26 |
+
"bugs": {
|
27 |
+
"url": "https://github.com/github/fetch/issues"
|
28 |
+
},
|
29 |
+
"bundleDependencies": false,
|
30 |
+
"deprecated": false,
|
31 |
+
"description": "A window.fetch polyfill.",
|
32 |
+
"devDependencies": {
|
33 |
+
"abortcontroller-polyfill": "^1.1.9",
|
34 |
+
"chai": "^4.1.2",
|
35 |
+
"eslint": "^4.19.1",
|
36 |
+
"eslint-plugin-github": "^1.0.0",
|
37 |
+
"karma": "^3.0.0",
|
38 |
+
"karma-chai": "^0.1.0",
|
39 |
+
"karma-chrome-launcher": "^2.2.0",
|
40 |
+
"karma-detect-browsers": "^2.3.2",
|
41 |
+
"karma-firefox-launcher": "^1.1.0",
|
42 |
+
"karma-mocha": "^1.3.0",
|
43 |
+
"karma-safari-launcher": "^1.0.0",
|
44 |
+
"karma-safaritechpreview-launcher": "0.0.6",
|
45 |
+
"mocha": "^4.0.1",
|
46 |
+
"promise-polyfill": "6.0.2",
|
47 |
+
"rollup": "^0.59.1",
|
48 |
+
"url-search-params": "0.6.1"
|
49 |
+
},
|
50 |
+
"files": [
|
51 |
+
"LICENSE",
|
52 |
+
"dist/fetch.umd.js",
|
53 |
+
"dist/fetch.umd.js.flow",
|
54 |
+
"fetch.js",
|
55 |
+
"fetch.js.flow"
|
56 |
+
],
|
57 |
+
"homepage": "https://github.com/github/fetch#readme",
|
58 |
+
"license": "MIT",
|
59 |
+
"main": "./dist/fetch.umd.js",
|
60 |
+
"module": "./fetch.js",
|
61 |
+
"name": "whatwg-fetch",
|
62 |
+
"repository": {
|
63 |
+
"type": "git",
|
64 |
+
"url": "git+https://github.com/github/fetch.git"
|
65 |
+
},
|
66 |
+
"scripts": {
|
67 |
+
"karma": "karma start ./test/karma.config.js --no-single-run --auto-watch",
|
68 |
+
"prepare": "make dist/fetch.umd.js dist/fetch.umd.js.flow",
|
69 |
+
"pretest": "make",
|
70 |
+
"test": "karma start ./test/karma.config.js && karma start ./test/karma-worker.config.js"
|
71 |
+
},
|
72 |
+
"version": "3.0.0"
|
73 |
+
}
|
inc/assets/js/render-grid.js
CHANGED
@@ -1,597 +1,597 @@
|
|
1 |
-
(function($){
|
2 |
-
|
3 |
-
AstraRender = {
|
4 |
-
|
5 |
-
_ref : null,
|
6 |
-
|
7 |
-
/**
|
8 |
-
* _api_params = {
|
9 |
-
* 'search' : '',
|
10 |
-
* 'per_page' : '',
|
11 |
-
* 'astra-site-category' : '',
|
12 |
-
* 'astra-site-page-builder' : '',
|
13 |
-
* 'page' : '',
|
14 |
-
* };
|
15 |
-
*
|
16 |
-
* E.g. per_page=<page-id>&astra-site-category=<category-ids>&astra-site-page-builder=<page-builder-ids>&page=<page>
|
17 |
-
*/
|
18 |
-
_api_params : {},
|
19 |
-
_breakpoint : 768,
|
20 |
-
_has_default_page_builder : false,
|
21 |
-
|
22 |
-
init: function()
|
23 |
-
{
|
24 |
-
this._resetPagedCount();
|
25 |
-
this._bind();
|
26 |
-
this._loadPageBuilders();
|
27 |
-
},
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Binds events for the Astra Sites.
|
31 |
-
*
|
32 |
-
* @since 1.0.0
|
33 |
-
* @access private
|
34 |
-
* @method _bind
|
35 |
-
*/
|
36 |
-
_bind: function()
|
37 |
-
{
|
38 |
-
$( document ).on('astra-sites-api-request-error' , AstraRender._addSuggestionBox );
|
39 |
-
$( document ).on('astra-sites-api-request-fail' , AstraRender._addSuggestionBox );
|
40 |
-
$( document ).on('astra-api-post-loaded-on-scroll' , AstraRender._reinitGridScrolled );
|
41 |
-
$( document ).on('astra-api-post-loaded' , AstraRender._reinitGrid );
|
42 |
-
$( document ).on('astra-api-page-builder-loaded' , AstraRender._addPageBuilders );
|
43 |
-
$( document ).on('astra-api-category-loaded' , AstraRender._loadFirstGrid );
|
44 |
-
|
45 |
-
// Event's for API request.
|
46 |
-
$( document ).on('click' , '.filter-links a', AstraRender._filterClick );
|
47 |
-
$( document ).on('keyup input' , '#wp-filter-search-input', AstraRender._search );
|
48 |
-
$( document ).on('scroll' , AstraRender._scroll );
|
49 |
-
$( document ).on('astra-sites-api-request-fail', AstraRender._site_unreachable );
|
50 |
-
},
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Website is Down
|
54 |
-
*
|
55 |
-
* @since 1.2.11
|
56 |
-
* @return null
|
57 |
-
*/
|
58 |
-
_site_unreachable: function( event, jqXHR, textStatus, args ) {
|
59 |
-
event.preventDefault();
|
60 |
-
if ( 'astra-site-page-builder' === args.id ) {
|
61 |
-
$('#astra-sites-admin').html( wp.template('astra-site-down') )
|
62 |
-
}
|
63 |
-
},
|
64 |
-
|
65 |
-
/**
|
66 |
-
* On Filter Clicked
|
67 |
-
*
|
68 |
-
* Prepare Before API Request:
|
69 |
-
* - Empty search input field to avoid search term on filter click.
|
70 |
-
* - Remove Inline Height
|
71 |
-
* - Added 'hide-me' class to hide the 'No more sites!' string.
|
72 |
-
* - Added 'loading-content' for body.
|
73 |
-
* - Show spinner.
|
74 |
-
*/
|
75 |
-
_filterClick: function( event ) {
|
76 |
-
|
77 |
-
event.preventDefault();
|
78 |
-
|
79 |
-
if( $( this ).parents('.astra-site-category').length && ! $('body').hasClass('page-builder-selected') ) {
|
80 |
-
return;
|
81 |
-
}
|
82 |
-
|
83 |
-
$(this).parents('.filter-links').find('a').removeClass('current');
|
84 |
-
$(this).addClass('current');
|
85 |
-
|
86 |
-
// Prepare Before Search.
|
87 |
-
$('.no-more-demos').addClass('hide-me');
|
88 |
-
$('.astra-sites-suggestions').remove();
|
89 |
-
|
90 |
-
// Empty the search input only click on category filter not on page builder filter.
|
91 |
-
if( $(this).parents('.filter-links').hasClass('astra-site-category') ) {
|
92 |
-
$('#wp-filter-search-input').val('');
|
93 |
-
}
|
94 |
-
$('#astra-sites').hide().css('height', '');
|
95 |
-
|
96 |
-
$('body').addClass('loading-content');
|
97 |
-
$('#astra-sites-admin').find('.spinner').removeClass('hide-me');
|
98 |
-
|
99 |
-
// Show sites.
|
100 |
-
AstraRender._showSites();
|
101 |
-
},
|
102 |
-
|
103 |
-
/**
|
104 |
-
* Search Site.
|
105 |
-
*
|
106 |
-
* Prepare Before API Request:
|
107 |
-
* - Remove Inline Height
|
108 |
-
* - Added 'hide-me' class to hide the 'No more sites!' string.
|
109 |
-
* - Added 'loading-content' for body.
|
110 |
-
* - Show spinner.
|
111 |
-
*/
|
112 |
-
_search: function() {
|
113 |
-
|
114 |
-
if( ! $('body').hasClass('page-builder-selected') ) {
|
115 |
-
return;
|
116 |
-
}
|
117 |
-
|
118 |
-
$this = jQuery('#wp-filter-search-input').val();
|
119 |
-
|
120 |
-
// Prepare Before Search.
|
121 |
-
$('#astra-sites').hide().css('height', '');
|
122 |
-
$('.no-more-demos').addClass('hide-me');
|
123 |
-
$('.astra-sites-suggestions').remove();
|
124 |
-
|
125 |
-
$('body').addClass('loading-content');
|
126 |
-
$('#astra-sites-admin').find('.spinner').removeClass('hide-me');
|
127 |
-
|
128 |
-
window.clearTimeout(AstraRender._ref);
|
129 |
-
AstraRender._ref = window.setTimeout(function () {
|
130 |
-
AstraRender._ref = null;
|
131 |
-
|
132 |
-
AstraRender._resetPagedCount();
|
133 |
-
jQuery('body').addClass('loading-content');
|
134 |
-
jQuery('body').attr('data-astra-demo-search', $this);
|
135 |
-
|
136 |
-
AstraRender._showSites();
|
137 |
-
|
138 |
-
}, 500);
|
139 |
-
|
140 |
-
},
|
141 |
-
|
142 |
-
/**
|
143 |
-
* On Scroll
|
144 |
-
*/
|
145 |
-
_scroll: function(event) {
|
146 |
-
|
147 |
-
if( ! $('body').hasClass('page-builder-selected') ) {
|
148 |
-
return;
|
149 |
-
}
|
150 |
-
|
151 |
-
if( ! $('body').hasClass('listed-all-sites') ) {
|
152 |
-
|
153 |
-
var scrollDistance = jQuery(window).scrollTop();
|
154 |
-
|
155 |
-
var themesBottom = Math.abs(jQuery(window).height() - jQuery('#astra-sites').offset().top - jQuery('#astra-sites').height());
|
156 |
-
themesBottom = themesBottom - 100;
|
157 |
-
|
158 |
-
ajaxLoading = jQuery('body').data('scrolling');
|
159 |
-
|
160 |
-
if (scrollDistance > themesBottom && ajaxLoading == false) {
|
161 |
-
AstraRender._updatedPagedCount();
|
162 |
-
|
163 |
-
if( ! $('#astra-sites .no-themes').length ) {
|
164 |
-
$('#astra-sites-admin').find('.spinner').addClass('is-active');
|
165 |
-
}
|
166 |
-
|
167 |
-
jQuery('body').data('scrolling', true);
|
168 |
-
|
169 |
-
/**
|
170 |
-
* @see _reinitGridScrolled() which called in trigger 'astra-api-post-loaded-on-scroll'
|
171 |
-
*/
|
172 |
-
AstraRender._showSites( false, 'astra-api-post-loaded-on-scroll' );
|
173 |
-
}
|
174 |
-
}
|
175 |
-
},
|
176 |
-
|
177 |
-
_apiAddParam_status: function() {
|
178 |
-
if( astraRenderGrid.sites && astraRenderGrid.sites.status ) {
|
179 |
-
AstraRender._api_params['status'] = astraRenderGrid.sites.status;
|
180 |
-
}
|
181 |
-
},
|
182 |
-
|
183 |
-
// Add 'search'
|
184 |
-
_apiAddParam_search: function() {
|
185 |
-
var search_val = jQuery('#wp-filter-search-input').val() || '';
|
186 |
-
if( '' !== search_val ) {
|
187 |
-
AstraRender._api_params['search'] = search_val;
|
188 |
-
}
|
189 |
-
},
|
190 |
-
|
191 |
-
_apiAddParam_per_page: function() {
|
192 |
-
// Add 'per_page'
|
193 |
-
var per_page_val = 15;
|
194 |
-
if( astraRenderGrid.sites && astraRenderGrid.sites["par-page"] ) {
|
195 |
-
per_page_val = parseInt( astraRenderGrid.sites["par-page"] );
|
196 |
-
}
|
197 |
-
AstraRender._api_params['per_page'] = per_page_val;
|
198 |
-
},
|
199 |
-
|
200 |
-
_apiAddParam_astra_site_category: function() {
|
201 |
-
// Add 'astra-site-category'
|
202 |
-
var selected_category_id = jQuery('.filter-links.astra-site-category').find('.current').data('group') || '';
|
203 |
-
if( '' !== selected_category_id && 'all' !== selected_category_id ) {
|
204 |
-
AstraRender._api_params['astra-site-category'] = selected_category_id;
|
205 |
-
} else if( astraRenderGrid.sites && astraRenderGrid['categories'].include ) {
|
206 |
-
if( AstraRender._isArray( astraRenderGrid['categories'].include ) ) {
|
207 |
-
AstraRender._api_params['astra-site-category'] = astraRenderGrid['categories'].include.join(',');
|
208 |
-
} else {
|
209 |
-
AstraRender._api_params['astra-site-category'] = astraRenderGrid['categories'].include;
|
210 |
-
}
|
211 |
-
}
|
212 |
-
},
|
213 |
-
|
214 |
-
_apiAddParam_astra_site_page_builder: function() {
|
215 |
-
// Add 'astra-site-page-builder'
|
216 |
-
var selected_page_builder_id = jQuery('.filter-links.astra-site-page-builder').find('.current').data('group') || '';
|
217 |
-
if( '' !== selected_page_builder_id && 'all' !== selected_page_builder_id ) {
|
218 |
-
AstraRender._api_params['astra-site-page-builder'] = selected_page_builder_id;
|
219 |
-
} else if( astraRenderGrid.sites && astraRenderGrid['page-builders'].include ) {
|
220 |
-
if( AstraRender._isArray( astraRenderGrid['page-builders'].include ) ) {
|
221 |
-
AstraRender._api_params['astra-site-page-builder'] = astraRenderGrid['page-builders'].include.join(',');
|
222 |
-
} else {
|
223 |
-
AstraRender._api_params['astra-site-page-builder'] = astraRenderGrid['page-builders'].include;
|
224 |
-
}
|
225 |
-
}
|
226 |
-
},
|
227 |
-
|
228 |
-
_apiAddParam_page: function() {
|
229 |
-
// Add 'page'
|
230 |
-
var page_val = parseInt(jQuery('body').attr('data-astra-demo-paged')) || 1;
|
231 |
-
AstraRender._api_params['page'] = page_val;
|
232 |
-
},
|
233 |
-
|
234 |
-
_apiAddParam_purchase_key: function() {
|
235 |
-
if( astraRenderGrid.sites && astraRenderGrid.sites.purchase_key ) {
|
236 |
-
AstraRender._api_params['purchase_key'] = astraRenderGrid.sites.purchase_key;
|
237 |
-
}
|
238 |
-
},
|
239 |
-
|
240 |
-
_apiAddParam_site_url: function() {
|
241 |
-
if( astraRenderGrid.sites && astraRenderGrid.sites.site_url ) {
|
242 |
-
AstraRender._api_params['site_url'] = astraRenderGrid.sites.site_url;
|
243 |
-
}
|
244 |
-
},
|
245 |
-
|
246 |
-
/**
|
247 |
-
* Show Sites
|
248 |
-
*
|
249 |
-
* Params E.g. per_page=<page-id>&astra-site-category=<category-ids>&astra-site-page-builder=<page-builder-ids>&page=<page>
|
250 |
-
*
|
251 |
-
* @param {Boolean} resetPagedCount Reset Paged Count.
|
252 |
-
* @param {String} trigger Filtered Trigger.
|
253 |
-
*/
|
254 |
-
_showSites: function( resetPagedCount, trigger ) {
|
255 |
-
|
256 |
-
if( undefined === resetPagedCount ) {
|
257 |
-
resetPagedCount = true
|
258 |
-
}
|
259 |
-
|
260 |
-
if( undefined === trigger ) {
|
261 |
-
trigger = 'astra-api-post-loaded';
|
262 |
-
}
|
263 |
-
|
264 |
-
if( resetPagedCount ) {
|
265 |
-
AstraRender._resetPagedCount();
|
266 |
-
}
|
267 |
-
|
268 |
-
// Add Params for API request.
|
269 |
-
AstraRender._api_params = {};
|
270 |
-
|
271 |
-
AstraRender._apiAddParam_status();
|
272 |
-
AstraRender._apiAddParam_search();
|
273 |
-
AstraRender._apiAddParam_per_page();
|
274 |
-
AstraRender._apiAddParam_astra_site_category();
|
275 |
-
AstraRender._apiAddParam_astra_site_page_builder();
|
276 |
-
AstraRender._apiAddParam_page();
|
277 |
-
AstraRender._apiAddParam_site_url();
|
278 |
-
AstraRender._apiAddParam_purchase_key();
|
279 |
-
|
280 |
-
// API Request.
|
281 |
-
var api_post = {
|
282 |
-
id: 'astra-sites',
|
283 |
-
slug: 'astra-sites?' + decodeURIComponent( $.param( AstraRender._api_params ) ),
|
284 |
-
trigger: trigger,
|
285 |
-
};
|
286 |
-
|
287 |
-
AstraSitesAPI._api_request( api_post );
|
288 |
-
|
289 |
-
},
|
290 |
-
|
291 |
-
/**
|
292 |
-
* Get Category Params
|
293 |
-
*
|
294 |
-
* @since 1.2.4
|
295 |
-
* @param {string} category_slug Category Slug.
|
296 |
-
* @return {mixed} Add `include=<category-ids>` in API request.
|
297 |
-
*/
|
298 |
-
_getPageBuilderParams: function()
|
299 |
-
{
|
300 |
-
var _params = {};
|
301 |
-
|
302 |
-
if( astraRenderGrid.default_page_builder ) {
|
303 |
-
_params['search'] = astraRenderGrid.default_page_builder;
|
304 |
-
}
|
305 |
-
|
306 |
-
if( astraRenderGrid.sites && astraRenderGrid.sites.purchase_key ) {
|
307 |
-
_params['purchase_key'] = astraRenderGrid.sites.purchase_key;
|
308 |
-
}
|
309 |
-
|
310 |
-
if( astraRenderGrid.sites && astraRenderGrid.sites.site_url ) {
|
311 |
-
_params['site_url'] = astraRenderGrid.sites.site_url;
|
312 |
-
}
|
313 |
-
|
314 |
-
if( astraRenderGrid.sites && astraRenderGrid['page-builders'].include ) {
|
315 |
-
if( AstraRender._isArray( astraRenderGrid['page-builders'].include ) ) {
|
316 |
-
_params['include'] = astraRenderGrid['page-builders'].include.join(',');
|
317 |
-
} else {
|
318 |
-
_params['include'] = astraRenderGrid['page-builders'].include;
|
319 |
-
}
|
320 |
-
}
|
321 |
-
|
322 |
-
var decoded_params = decodeURIComponent( $.param( _params ) );
|
323 |
-
|
324 |
-
if( decoded_params.length ) {
|
325 |
-
return '/?' + decoded_params;
|
326 |
-
}
|
327 |
-
|
328 |
-
return '/';
|
329 |
-
},
|
330 |
-
|
331 |
-
/**
|
332 |
-
* Get Category Params
|
333 |
-
*
|
334 |
-
* @param {string} category_slug Category Slug.
|
335 |
-
* @return {mixed} Add `include=<category-ids>` in API request.
|
336 |
-
*/
|
337 |
-
_getCategoryParams: function( category_slug ) {
|
338 |
-
|
339 |
-
var _params = {};
|
340 |
-
|
341 |
-
if( astraRenderGrid.sites && astraRenderGrid['categories'].include ) {
|
342 |
-
if( AstraRender._isArray( astraRenderGrid['categories'].include ) ) {
|
343 |
-
_params['include'] = astraRenderGrid['categories'].include.join(',');
|
344 |
-
} else {
|
345 |
-
_params['include'] = astraRenderGrid['categories'].include;
|
346 |
-
}
|
347 |
-
}
|
348 |
-
|
349 |
-
var decoded_params = decodeURIComponent( $.param( _params ) );
|
350 |
-
|
351 |
-
if( decoded_params.length ) {
|
352 |
-
return '/?' + decoded_params;
|
353 |
-
}
|
354 |
-
|
355 |
-
return '/';
|
356 |
-
},
|
357 |
-
|
358 |
-
/**
|
359 |
-
* Get All Select Status
|
360 |
-
*
|
361 |
-
* @param {string} category_slug Category Slug.
|
362 |
-
* @return {boolean} Return true/false.
|
363 |
-
*/
|
364 |
-
_getCategoryAllSelectStatus: function( category_slug ) {
|
365 |
-
|
366 |
-
// Has category?
|
367 |
-
if( category_slug in astraRenderGrid.settings ) {
|
368 |
-
|
369 |
-
// Has `all` in stored list?
|
370 |
-
if( $.inArray('all', astraRenderGrid.settings[ category_slug ]) === -1 ) {
|
371 |
-
return false;
|
372 |
-
}
|
373 |
-
}
|
374 |
-
|
375 |
-
return true;
|
376 |
-
},
|
377 |
-
|
378 |
-
/**
|
379 |
-
* Show Filters
|
380 |
-
*/
|
381 |
-
_loadPageBuilders: function() {
|
382 |
-
|
383 |
-
/**
|
384 |
-
* Page Builder
|
385 |
-
*/
|
386 |
-
var category_slug = 'astra-site-page-builder';
|
387 |
-
var category = {
|
388 |
-
slug : category_slug + AstraRender._getPageBuilderParams(),
|
389 |
-
id : category_slug,
|
390 |
-
class : category_slug,
|
391 |
-
trigger : 'astra-api-page-builder-loaded',
|
392 |
-
wrapper_class : 'filter-links',
|
393 |
-
show_all : false,
|
394 |
-
};
|
395 |
-
|
396 |
-
AstraSitesAPI._api_request( category );
|
397 |
-
},
|
398 |
-
|
399 |
-
/**
|
400 |
-
* Load First Grid.
|
401 |
-
*
|
402 |
-
* This is triggered after all category loaded.
|
403 |
-
*
|
404 |
-
* @param {object} event Event Object.
|
405 |
-
*/
|
406 |
-
_loadFirstGrid: function( event, data ) {
|
407 |
-
|
408 |
-
event.preventDefault();
|
409 |
-
|
410 |
-
if( $('#' + data.args.id).length ) {
|
411 |
-
var template = wp.template('astra-site-filters');
|
412 |
-
$('#' + data.args.id).html(template( data ));
|
413 |
-
|
414 |
-
if( 'true' === $('body').attr( 'data-default-page-builder-selected' ) ) {
|
415 |
-
$('#' + data.args.id).find('li:first a').addClass('current');
|
416 |
-
AstraRender._showSites();
|
417 |
-
} else {
|
418 |
-
$('body').removeClass('loading-content');
|
419 |
-
if( ! $('#astra-sites-admin .astra-site-select-page-builder').length ) {
|
420 |
-
$('#astra-sites-admin').append( wp.template( 'astra-site-select-page-builder' ) );
|
421 |
-
}
|
422 |
-
}
|
423 |
-
} else {
|
424 |
-
AstraRender._showSites();
|
425 |
-
}
|
426 |
-
|
427 |
-
},
|
428 |
-
|
429 |
-
/**
|
430 |
-
* Append filters.
|
431 |
-
*
|
432 |
-
* @param {object} event Object.
|
433 |
-
* @param {object} data API response data.
|
434 |
-
*/
|
435 |
-
_addPageBuilders: function( event, data ) {
|
436 |
-
event.preventDefault();
|
437 |
-
|
438 |
-
if( $('#' + data.args.id).length ) {
|
439 |
-
var template = wp.template('astra-site-filters');
|
440 |
-
$('#' + data.args.id).html(template( data ));
|
441 |
-
|
442 |
-
if( 1 === parseInt( data.items_count ) ) {
|
443 |
-
$('body').attr( 'data-default-page-builder-selected', true );
|
444 |
-
$('#' + data.args.id).find('li:first a').addClass('current');
|
445 |
-
}
|
446 |
-
}
|
447 |
-
|
448 |
-
/**
|
449 |
-
* Categories
|
450 |
-
*/
|
451 |
-
var category_slug = 'astra-site-category';
|
452 |
-
var category = {
|
453 |
-
slug : category_slug + AstraRender._getCategoryParams( category_slug ),
|
454 |
-
id : category_slug,
|
455 |
-
class : category_slug,
|
456 |
-
trigger : 'astra-api-category-loaded',
|
457 |
-
wrapper_class : 'filter-links',
|
458 |
-
show_all : AstraRender._getCategoryAllSelectStatus( category_slug ),
|
459 |
-
};
|
460 |
-
|
461 |
-
AstraSitesAPI._api_request( category );
|
462 |
-
|
463 |
-
},
|
464 |
-
|
465 |
-
|
466 |
-
/**
|
467 |
-
* Append sites on scroll.
|
468 |
-
*
|
469 |
-
* @param {object} event Object.
|
470 |
-
* @param {object} data API response data.
|
471 |
-
*/
|
472 |
-
_reinitGridScrolled: function( event, data ) {
|
473 |
-
|
474 |
-
var template = wp.template('astra-sites-list');
|
475 |
-
|
476 |
-
if( data.items.length > 0 ) {
|
477 |
-
|
478 |
-
$('body').removeClass( 'loading-content' );
|
479 |
-
$('.filter-count .count').text( data.items_count );
|
480 |
-
|
481 |
-
setTimeout(function() {
|
482 |
-
jQuery('#astra-sites').append(template( data ));
|
483 |
-
|
484 |
-
AstraRender._imagesLoaded();
|
485 |
-
}, 800);
|
486 |
-
} else {
|
487 |
-
$('body').addClass('listed-all-sites');
|
488 |
-
}
|
489 |
-
|
490 |
-
},
|
491 |
-
|
492 |
-
/**
|
493 |
-
* Update Astra sites list.
|
494 |
-
*
|
495 |
-
* @param {object} event Object.
|
496 |
-
* @param {object} data API response data.
|
497 |
-
*/
|
498 |
-
_reinitGrid: function( event, data ) {
|
499 |
-
|
500 |
-
var template = wp.template('astra-sites-list');
|
501 |
-
|
502 |
-
$('body').addClass( 'page-builder-selected' );
|
503 |
-
$('body').removeClass( 'loading-content' );
|
504 |
-
$('.filter-count .count').text( data.items_count );
|
505 |
-
|
506 |
-
jQuery('body').attr('data-astra-demo-last-request', data.items_count);
|
507 |
-
|
508 |
-
jQuery('#astra-sites').show().html(template( data ));
|
509 |
-
|
510 |
-
AstraRender._imagesLoaded();
|
511 |
-
|
512 |
-
$('#astra-sites-admin').find('.spinner').removeClass('is-active');
|
513 |
-
|
514 |
-
if( data.items_count <= 0 ) {
|
515 |
-
$('#astra-sites-admin').find('.spinner').removeClass('is-active');
|
516 |
-
$('.no-more-demos').addClass('hide-me');
|
517 |
-
$('.astra-sites-suggestions').remove();
|
518 |
-
|
519 |
-
} else {
|
520 |
-
$('body').removeClass('listed-all-sites');
|
521 |
-
}
|
522 |
-
|
523 |
-
|
524 |
-
},
|
525 |
-
|
526 |
-
/**
|
527 |
-
* Check image loaded with function `imagesLoaded()`
|
528 |
-
*/
|
529 |
-
_imagesLoaded: function() {
|
530 |
-
|
531 |
-
var self = jQuery('#sites-filter.execute-only-one-time a');
|
532 |
-
|
533 |
-
$('.astra-sites-grid').imagesLoaded()
|
534 |
-
.always( function( instance ) {
|
535 |
-
if( jQuery( window ).outerWidth() > AstraRender._breakpoint ) {
|
536 |
-
// $('#astra-sites').masonry('reload');
|
537 |
-
}
|
538 |
-
|
539 |
-
$('#astra-sites-admin').find('.spinner').removeClass('is-active');
|
540 |
-
})
|
541 |
-
.progress( function( instance, image ) {
|
542 |
-
var result = image.isLoaded ? 'loaded' : 'broken';
|
543 |
-
});
|
544 |
-
|
545 |
-
},
|
546 |
-
|
547 |
-
/**
|
548 |
-
* Add Suggestion Box
|
549 |
-
*/
|
550 |
-
_addSuggestionBox: function() {
|
551 |
-
$('#astra-sites-admin').find('.spinner').removeClass('is-active').addClass('hide-me');
|
552 |
-
|
553 |
-
$('#astra-sites-admin').find('.no-more-demos').removeClass('hide-me');
|
554 |
-
var template = wp.template('astra-sites-suggestions');
|
555 |
-
if( ! $( '.astra-sites-suggestions').length ) {
|
556 |
-
$('#astra-sites').append( template );
|
557 |
-
}
|
558 |
-
},
|
559 |
-
|
560 |
-
/**
|
561 |
-
* Update Page Count.
|
562 |
-
*/
|
563 |
-
_updatedPagedCount: function() {
|
564 |
-
paged = parseInt(jQuery('body').attr('data-astra-demo-paged'));
|
565 |
-
jQuery('body').attr('data-astra-demo-paged', paged + 1);
|
566 |
-
window.setTimeout(function () {
|
567 |
-
jQuery('body').data('scrolling', false);
|
568 |
-
}, 800);
|
569 |
-
},
|
570 |
-
|
571 |
-
/**
|
572 |
-
* Reset Page Count.
|
573 |
-
*/
|
574 |
-
_resetPagedCount: function() {
|
575 |
-
|
576 |
-
jQuery('body').attr('data-astra-demo-last-request', '1');
|
577 |
-
jQuery('body').attr('data-astra-demo-paged', '1');
|
578 |
-
jQuery('body').attr('data-astra-demo-search', '');
|
579 |
-
jQuery('body').attr('data-scrolling', false);
|
580 |
-
|
581 |
-
},
|
582 |
-
|
583 |
-
// Returns if a value is an array
|
584 |
-
_isArray: function(value) {
|
585 |
-
return value && typeof value === 'object' && value.constructor === Array;
|
586 |
-
}
|
587 |
-
|
588 |
-
};
|
589 |
-
|
590 |
-
/**
|
591 |
-
* Initialize AstraRender
|
592 |
-
*/
|
593 |
-
$(function(){
|
594 |
-
AstraRender.init();
|
595 |
-
});
|
596 |
-
|
597 |
Â
})(jQuery);
|
1 |
+
(function($){
|
2 |
+
|
3 |
+
AstraRender = {
|
4 |
+
|
5 |
+
_ref : null,
|
6 |
+
|
7 |
+
/**
|
8 |
+
* _api_params = {
|
9 |
+
* 'search' : '',
|
10 |
+
* 'per_page' : '',
|
11 |
+
* 'astra-site-category' : '',
|
12 |
+
* 'astra-site-page-builder' : '',
|
13 |
+
* 'page' : '',
|
14 |
+
* };
|
15 |
+
*
|
16 |
+
* E.g. per_page=<page-id>&astra-site-category=<category-ids>&astra-site-page-builder=<page-builder-ids>&page=<page>
|
17 |
+
*/
|
18 |
+
_api_params : {},
|
19 |
+
_breakpoint : 768,
|
20 |
+
_has_default_page_builder : false,
|
21 |
+
|
22 |
+
init: function()
|
23 |
+
{
|
24 |
+
this._resetPagedCount();
|
25 |
+
this._bind();
|
26 |
+
this._loadPageBuilders();
|
27 |
+
},
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Binds events for the Astra Sites.
|
31 |
+
*
|
32 |
+
* @since 1.0.0
|
33 |
+
* @access private
|
34 |
+
* @method _bind
|
35 |
+
*/
|
36 |
+
_bind: function()
|
37 |
+
{
|
38 |
+
$( document ).on('astra-sites-api-request-error' , AstraRender._addSuggestionBox );
|
39 |
+
$( document ).on('astra-sites-api-request-fail' , AstraRender._addSuggestionBox );
|
40 |
+
$( document ).on('astra-api-post-loaded-on-scroll' , AstraRender._reinitGridScrolled );
|
41 |
+
$( document ).on('astra-api-post-loaded' , AstraRender._reinitGrid );
|
42 |
+
$( document ).on('astra-api-page-builder-loaded' , AstraRender._addPageBuilders );
|
43 |
+
$( document ).on('astra-api-category-loaded' , AstraRender._loadFirstGrid );
|
44 |
+
|
45 |
+
// Event's for API request.
|
46 |
+
$( document ).on('click' , '.filter-links a', AstraRender._filterClick );
|
47 |
+
$( document ).on('keyup input' , '#wp-filter-search-input', AstraRender._search );
|
48 |
+
$( document ).on('scroll' , AstraRender._scroll );
|
49 |
+
$( document ).on('astra-sites-api-request-fail', AstraRender._site_unreachable );
|
50 |
+
},
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Website is Down
|
54 |
+
*
|
55 |
+
* @since 1.2.11
|
56 |
+
* @return null
|
57 |
+
*/
|
58 |
+
_site_unreachable: function( event, jqXHR, textStatus, args ) {
|
59 |
+
event.preventDefault();
|
60 |
+
if ( 'astra-site-page-builder' === args.id ) {
|
61 |
+
$('#astra-sites-admin').html( wp.template('astra-site-down') )
|
62 |
+
}
|
63 |
+
},
|
64 |
+
|
65 |
+
/**
|
66 |
+
* On Filter Clicked
|
67 |
+
*
|
68 |
+
* Prepare Before API Request:
|
69 |
+
* - Empty search input field to avoid search term on filter click.
|
70 |
+
* - Remove Inline Height
|
71 |
+
* - Added 'hide-me' class to hide the 'No more sites!' string.
|
72 |
+
* - Added 'loading-content' for body.
|
73 |
+
* - Show spinner.
|
74 |
+
*/
|
75 |
+
_filterClick: function( event ) {
|
76 |
+
|
77 |
+
event.preventDefault();
|
78 |
+
|
79 |
+
if( $( this ).parents('.astra-site-category').length && ! $('body').hasClass('page-builder-selected') ) {
|
80 |
+
return;
|
81 |
+
}
|
82 |
+
|
83 |
+
$(this).parents('.filter-links').find('a').removeClass('current');
|
84 |
+
$(this).addClass('current');
|
85 |
+
|
86 |
+
// Prepare Before Search.
|
87 |
+
$('.no-more-demos').addClass('hide-me');
|
88 |
+
$('.astra-sites-suggestions').remove();
|
89 |
+
|
90 |
+
// Empty the search input only click on category filter not on page builder filter.
|
91 |
+
if( $(this).parents('.filter-links').hasClass('astra-site-category') ) {
|
92 |
+
$('#wp-filter-search-input').val('');
|
93 |
+
}
|
94 |
+
$('#astra-sites').hide().css('height', '');
|
95 |
+
|
96 |
+
$('body').addClass('loading-content');
|
97 |
+
$('#astra-sites-admin').find('.spinner').removeClass('hide-me');
|
98 |
+
|
99 |
+
// Show sites.
|
100 |
+
AstraRender._showSites();
|
101 |
+
},
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Search Site.
|
105 |
+
*
|
106 |
+
* Prepare Before API Request:
|
107 |
+
* - Remove Inline Height
|
108 |
+
* - Added 'hide-me' class to hide the 'No more sites!' string.
|
109 |
+
* - Added 'loading-content' for body.
|
110 |
+
* - Show spinner.
|
111 |
+
*/
|
112 |
+
_search: function() {
|
113 |
+
|
114 |
+
if( ! $('body').hasClass('page-builder-selected') ) {
|
115 |
+
return;
|
116 |
+
}
|
117 |
+
|
118 |
+
$this = jQuery('#wp-filter-search-input').val();
|
119 |
+
|
120 |
+
// Prepare Before Search.
|
121 |
+
$('#astra-sites').hide().css('height', '');
|
122 |
+
$('.no-more-demos').addClass('hide-me');
|
123 |
+
$('.astra-sites-suggestions').remove();
|
124 |
+
|
125 |
+
$('body').addClass('loading-content');
|
126 |
+
$('#astra-sites-admin').find('.spinner').removeClass('hide-me');
|
127 |
+
|
128 |
+
window.clearTimeout(AstraRender._ref);
|
129 |
+
AstraRender._ref = window.setTimeout(function () {
|
130 |
+
AstraRender._ref = null;
|
131 |
+
|
132 |
+
AstraRender._resetPagedCount();
|
133 |
+
jQuery('body').addClass('loading-content');
|
134 |
+
jQuery('body').attr('data-astra-demo-search', $this);
|
135 |
+
|
136 |
+
AstraRender._showSites();
|
137 |
+
|
138 |
+
}, 500);
|
139 |
+
|
140 |
+
},
|
141 |
+
|
142 |
+
/**
|
143 |
+
* On Scroll
|
144 |
+
*/
|
145 |
+
_scroll: function(event) {
|
146 |
+
|
147 |
+
if( ! $('body').hasClass('page-builder-selected') ) {
|
148 |
+
return;
|
149 |
+
}
|
150 |
+
|
151 |
+
if( ! $('body').hasClass('listed-all-sites') ) {
|
152 |
+
|
153 |
+
var scrollDistance = jQuery(window).scrollTop();
|
154 |
+
|
155 |
+
var themesBottom = Math.abs(jQuery(window).height() - jQuery('#astra-sites').offset().top - jQuery('#astra-sites').height());
|
156 |
+
themesBottom = themesBottom - 100;
|
157 |
+
|
158 |
+
ajaxLoading = jQuery('body').data('scrolling');
|
159 |
+
|
160 |
+
if (scrollDistance > themesBottom && ajaxLoading == false) {
|
161 |
+
AstraRender._updatedPagedCount();
|
162 |
+
|
163 |
+
if( ! $('#astra-sites .no-themes').length ) {
|
164 |
+
$('#astra-sites-admin').find('.spinner').addClass('is-active');
|
165 |
+
}
|
166 |
+
|
167 |
+
jQuery('body').data('scrolling', true);
|
168 |
+
|
169 |
+
/**
|
170 |
+
* @see _reinitGridScrolled() which called in trigger 'astra-api-post-loaded-on-scroll'
|
171 |
+
*/
|
172 |
+
AstraRender._showSites( false, 'astra-api-post-loaded-on-scroll' );
|
173 |
+
}
|
174 |
+
}
|
175 |
+
},
|
176 |
+
|
177 |
+
_apiAddParam_status: function() {
|
178 |
+
if( astraRenderGrid.sites && astraRenderGrid.sites.status ) {
|
179 |
+
AstraRender._api_params['status'] = astraRenderGrid.sites.status;
|
180 |
+
}
|
181 |
+
},
|
182 |
+
|
183 |
+
// Add 'search'
|
184 |
+
_apiAddParam_search: function() {
|
185 |
+
var search_val = jQuery('#wp-filter-search-input').val() || '';
|
186 |
+
if( '' !== search_val ) {
|
187 |
+
AstraRender._api_params['search'] = search_val;
|
188 |
+
}
|
189 |
+
},
|
190 |
+
|
191 |
+
_apiAddParam_per_page: function() {
|
192 |
+
// Add 'per_page'
|
193 |
+
var per_page_val = 15;
|
194 |
+
if( astraRenderGrid.sites && astraRenderGrid.sites["par-page"] ) {
|
195 |
+
per_page_val = parseInt( astraRenderGrid.sites["par-page"] );
|
196 |
+
}
|
197 |
+
AstraRender._api_params['per_page'] = per_page_val;
|
198 |
+
},
|
199 |
+
|
200 |
+
_apiAddParam_astra_site_category: function() {
|
201 |
+
// Add 'astra-site-category'
|
202 |
+
var selected_category_id = jQuery('.filter-links.astra-site-category').find('.current').data('group') || '';
|
203 |
+
if( '' !== selected_category_id && 'all' !== selected_category_id ) {
|
204 |
+
AstraRender._api_params['astra-site-category'] = selected_category_id;
|
205 |
+
} else if( astraRenderGrid.sites && astraRenderGrid['categories'].include ) {
|
206 |
+
if( AstraRender._isArray( astraRenderGrid['categories'].include ) ) {
|
207 |
+
AstraRender._api_params['astra-site-category'] = astraRenderGrid['categories'].include.join(',');
|
208 |
+
} else {
|
209 |
+
AstraRender._api_params['astra-site-category'] = astraRenderGrid['categories'].include;
|
210 |
+
}
|
211 |
+
}
|
212 |
+
},
|
213 |
+
|
214 |
+
_apiAddParam_astra_site_page_builder: function() {
|
215 |
+
// Add 'astra-site-page-builder'
|
216 |
+
var selected_page_builder_id = jQuery('.filter-links.astra-site-page-builder').find('.current').data('group') || '';
|
217 |
+
if( '' !== selected_page_builder_id && 'all' !== selected_page_builder_id ) {
|
218 |
+
AstraRender._api_params['astra-site-page-builder'] = selected_page_builder_id;
|
219 |
+
} else if( astraRenderGrid.sites && astraRenderGrid['page-builders'].include ) {
|
220 |
+
if( AstraRender._isArray( astraRenderGrid['page-builders'].include ) ) {
|
221 |
+
AstraRender._api_params['astra-site-page-builder'] = astraRenderGrid['page-builders'].include.join(',');
|
222 |
+
} else {
|
223 |
+
AstraRender._api_params['astra-site-page-builder'] = astraRenderGrid['page-builders'].include;
|
224 |
+
}
|
225 |
+
}
|
226 |
+
},
|
227 |
+
|
228 |
+
_apiAddParam_page: function() {
|
229 |
+
// Add 'page'
|
230 |
+
var page_val = parseInt(jQuery('body').attr('data-astra-demo-paged')) || 1;
|
231 |
+
AstraRender._api_params['page'] = page_val;
|
232 |
+
},
|
233 |
+
|
234 |
+
_apiAddParam_purchase_key: function() {
|
235 |
+
if( astraRenderGrid.sites && astraRenderGrid.sites.purchase_key ) {
|
236 |
+
AstraRender._api_params['purchase_key'] = astraRenderGrid.sites.purchase_key;
|
237 |
+
}
|
238 |
+
},
|
239 |
+
|
240 |
+
_apiAddParam_site_url: function() {
|
241 |
+
if( astraRenderGrid.sites && astraRenderGrid.sites.site_url ) {
|
242 |
+
AstraRender._api_params['site_url'] = astraRenderGrid.sites.site_url;
|
243 |
+
}
|
244 |
+
},
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Show Sites
|
248 |
+
*
|
249 |
+
* Params E.g. per_page=<page-id>&astra-site-category=<category-ids>&astra-site-page-builder=<page-builder-ids>&page=<page>
|
250 |
+
*
|
251 |
+
* @param {Boolean} resetPagedCount Reset Paged Count.
|
252 |
+
* @param {String} trigger Filtered Trigger.
|
253 |
+
*/
|
254 |
+
_showSites: function( resetPagedCount, trigger ) {
|
255 |
+
|
256 |
+
if( undefined === resetPagedCount ) {
|
257 |
+
resetPagedCount = true
|
258 |
+
}
|
259 |
+
|
260 |
+
if( undefined === trigger ) {
|
261 |
+
trigger = 'astra-api-post-loaded';
|
262 |
+
}
|
263 |
+
|
264 |
+
if( resetPagedCount ) {
|
265 |
+
AstraRender._resetPagedCount();
|
266 |
+
}
|
267 |
+
|
268 |
+
// Add Params for API request.
|
269 |
+
AstraRender._api_params = {};
|
270 |
+
|
271 |
+
AstraRender._apiAddParam_status();
|
272 |
+
AstraRender._apiAddParam_search();
|
273 |
+
AstraRender._apiAddParam_per_page();
|
274 |
+
AstraRender._apiAddParam_astra_site_category();
|
275 |
+
AstraRender._apiAddParam_astra_site_page_builder();
|
276 |
+
AstraRender._apiAddParam_page();
|
277 |
+
AstraRender._apiAddParam_site_url();
|
278 |
+
AstraRender._apiAddParam_purchase_key();
|
279 |
+
|
280 |
+
// API Request.
|
281 |
+
var api_post = {
|
282 |
+
id: 'astra-sites',
|
283 |
+
slug: 'astra-sites?' + decodeURIComponent( $.param( AstraRender._api_params ) ),
|
284 |
+
trigger: trigger,
|
285 |
+
};
|
286 |
+
|
287 |
+
AstraSitesAPI._api_request( api_post );
|
288 |
+
|
289 |
+
},
|
290 |
+
|
291 |
+
/**
|
292 |
+
* Get Category Params
|
293 |
+
*
|
294 |
+
* @since 1.2.4
|
295 |
+
* @param {string} category_slug Category Slug.
|
296 |
+
* @return {mixed} Add `include=<category-ids>` in API request.
|
297 |
+
*/
|
298 |
+
_getPageBuilderParams: function()
|
299 |
+
{
|
300 |
+
var _params = {};
|
301 |
+
|
302 |
+
if( astraRenderGrid.default_page_builder ) {
|
303 |
+
_params['search'] = astraRenderGrid.default_page_builder;
|
304 |
+
}
|
305 |
+
|
306 |
+
if( astraRenderGrid.sites && astraRenderGrid.sites.purchase_key ) {
|
307 |
+
_params['purchase_key'] = astraRenderGrid.sites.purchase_key;
|
308 |
+
}
|
309 |
+
|
310 |
+
if( astraRenderGrid.sites && astraRenderGrid.sites.site_url ) {
|
311 |
+
_params['site_url'] = astraRenderGrid.sites.site_url;
|
312 |
+
}
|
313 |
+
|
314 |
+
if( astraRenderGrid.sites && astraRenderGrid['page-builders'].include ) {
|
315 |
+
if( AstraRender._isArray( astraRenderGrid['page-builders'].include ) ) {
|
316 |
+
_params['include'] = astraRenderGrid['page-builders'].include.join(',');
|
317 |
+
} else {
|
318 |
+
_params['include'] = astraRenderGrid['page-builders'].include;
|
319 |
+
}
|
320 |
+
}
|
321 |
+
|
322 |
+
var decoded_params = decodeURIComponent( $.param( _params ) );
|
323 |
+
|
324 |
+
if( decoded_params.length ) {
|
325 |
+
return '/?' + decoded_params;
|
326 |
+
}
|
327 |
+
|
328 |
+
return '/';
|
329 |
+
},
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Get Category Params
|
333 |
+
*
|
334 |
+
* @param {string} category_slug Category Slug.
|
335 |
+
* @return {mixed} Add `include=<category-ids>` in API request.
|
336 |
+
*/
|
337 |
+
_getCategoryParams: function( category_slug ) {
|
338 |
+
|
339 |
+
var _params = {};
|
340 |
+
|
341 |
+
if( astraRenderGrid.sites && astraRenderGrid['categories'].include ) {
|
342 |
+
if( AstraRender._isArray( astraRenderGrid['categories'].include ) ) {
|
343 |
+
_params['include'] = astraRenderGrid['categories'].include.join(',');
|
344 |
+
} else {
|
345 |
+
_params['include'] = astraRenderGrid['categories'].include;
|
346 |
+
}
|
347 |
+
}
|
348 |
+
|
349 |
+
var decoded_params = decodeURIComponent( $.param( _params ) );
|
350 |
+
|
351 |
+
if( decoded_params.length ) {
|
352 |
+
return '/?' + decoded_params;
|
353 |
+
}
|
354 |
+
|
355 |
+
return '/';
|
356 |
+
},
|
357 |
+
|
358 |
+
/**
|
359 |
+
* Get All Select Status
|
360 |
+
*
|
361 |
+
* @param {string} category_slug Category Slug.
|
362 |
+
* @return {boolean} Return true/false.
|
363 |
+
*/
|
364 |
+
_getCategoryAllSelectStatus: function( category_slug ) {
|
365 |
+
|
366 |
+
// Has category?
|
367 |
+
if( category_slug in astraRenderGrid.settings ) {
|
368 |
+
|
369 |
+
// Has `all` in stored list?
|
370 |
+
if( $.inArray('all', astraRenderGrid.settings[ category_slug ]) === -1 ) {
|
371 |
+
return false;
|
372 |
+
}
|
373 |
+
}
|
374 |
+
|
375 |
+
return true;
|
376 |
+
},
|
377 |
+
|
378 |
+
/**
|
379 |
+
* Show Filters
|
380 |
+
*/
|
381 |
+
_loadPageBuilders: function() {
|
382 |
+
|
383 |
+
/**
|
384 |
+
* Page Builder
|
385 |
+
*/
|
386 |
+
var category_slug = 'astra-site-page-builder';
|
387 |
+
var category = {
|
388 |
+
slug : category_slug + AstraRender._getPageBuilderParams(),
|
389 |
+
id : category_slug,
|
390 |
+
class : category_slug,
|
391 |
+
trigger : 'astra-api-page-builder-loaded',
|
392 |
+
wrapper_class : 'filter-links',
|
393 |
+
show_all : false,
|
394 |
+
};
|
395 |
+
|
396 |
+
AstraSitesAPI._api_request( category );
|
397 |
+
},
|
398 |
+
|
399 |
+
/**
|
400 |
+
* Load First Grid.
|
401 |
+
*
|
402 |
+
* This is triggered after all category loaded.
|
403 |
+
*
|
404 |
+
* @param {object} event Event Object.
|
405 |
+
*/
|
406 |
+
_loadFirstGrid: function( event, data ) {
|
407 |
+
|
408 |
+
event.preventDefault();
|
409 |
+
|
410 |
+
if( $('#' + data.args.id).length ) {
|
411 |
+
var template = wp.template('astra-site-filters');
|
412 |
+
$('#' + data.args.id).html(template( data ));
|
413 |
+
|
414 |
+
if( 'true' === $('body').attr( 'data-default-page-builder-selected' ) ) {
|
415 |
+
$('#' + data.args.id).find('li:first a').addClass('current');
|
416 |
+
AstraRender._showSites();
|
417 |
+
} else {
|
418 |
+
$('body').removeClass('loading-content');
|
419 |
+
if( ! $('#astra-sites-admin .astra-site-select-page-builder').length ) {
|
420 |
+
$('#astra-sites-admin').append( wp.template( 'astra-site-select-page-builder' ) );
|
421 |
+
}
|
422 |
+
}
|
423 |
+
} else {
|
424 |
+
AstraRender._showSites();
|
425 |
+
}
|
426 |
+
|
427 |
+
},
|
428 |
+
|
429 |
+
/**
|
430 |
+
* Append filters.
|
431 |
+
*
|
432 |
+
* @param {object} event Object.
|
433 |
+
* @param {object} data API response data.
|
434 |
+
*/
|
435 |
+
_addPageBuilders: function( event, data ) {
|
436 |
+
event.preventDefault();
|
437 |
+
|
438 |
+
if( $('#' + data.args.id).length ) {
|
439 |
+
var template = wp.template('astra-site-filters');
|
440 |
+
$('#' + data.args.id).html(template( data ));
|
441 |
+
|
442 |
+
if( 1 === parseInt( data.items_count ) ) {
|
443 |
+
$('body').attr( 'data-default-page-builder-selected', true );
|
444 |
+
$('#' + data.args.id).find('li:first a').addClass('current');
|
445 |
+
}
|
446 |
+
}
|
447 |
+
|
448 |
+
/**
|
449 |
+
* Categories
|
450 |
+
*/
|
451 |
+
var category_slug = 'astra-site-category';
|
452 |
+
var category = {
|
453 |
+
slug : category_slug + AstraRender._getCategoryParams( category_slug ),
|
454 |
+
id : category_slug,
|
455 |
+
class : category_slug,
|
456 |
+
trigger : 'astra-api-category-loaded',
|
457 |
+
wrapper_class : 'filter-links',
|
458 |
+
show_all : AstraRender._getCategoryAllSelectStatus( category_slug ),
|
459 |
+
};
|
460 |
+
|
461 |
+
AstraSitesAPI._api_request( category );
|
462 |
+
|
463 |
+
},
|
464 |
+
|
465 |
+
|
466 |
+
/**
|
467 |
+
* Append sites on scroll.
|
468 |
+
*
|
469 |
+
* @param {object} event Object.
|
470 |
+
* @param {object} data API response data.
|
471 |
+
*/
|
472 |
+
_reinitGridScrolled: function( event, data ) {
|
473 |
+
|
474 |
+
var template = wp.template('astra-sites-list');
|
475 |
+
|
476 |
+
if( data.items.length > 0 ) {
|
477 |
+
|
478 |
+
$('body').removeClass( 'loading-content' );
|
479 |
+
$('.filter-count .count').text( data.items_count );
|
480 |
+
|
481 |
+
setTimeout(function() {
|
482 |
+
jQuery('#astra-sites').append(template( data ));
|
483 |
+
|
484 |
+
AstraRender._imagesLoaded();
|
485 |
+
}, 800);
|
486 |
+
} else {
|
487 |
+
$('body').addClass('listed-all-sites');
|
488 |
+
}
|
489 |
+
|
490 |
+
},
|
491 |
+
|
492 |
+
/**
|
493 |
+
* Update Astra sites list.
|
494 |
+
*
|
495 |
+
* @param {object} event Object.
|
496 |
+
* @param {object} data API response data.
|
497 |
+
*/
|
498 |
+
_reinitGrid: function( event, data ) {
|
499 |
+
|
500 |
+
var template = wp.template('astra-sites-list');
|
501 |
+
|
502 |
+
$('body').addClass( 'page-builder-selected' );
|
503 |
+
$('body').removeClass( 'loading-content' );
|
504 |
+
$('.filter-count .count').text( data.items_count );
|
505 |
+
|
506 |
+
jQuery('body').attr('data-astra-demo-last-request', data.items_count);
|
507 |
+
|
508 |
+
jQuery('#astra-sites').show().html(template( data ));
|
509 |
+
|
510 |
+
AstraRender._imagesLoaded();
|
511 |
+
|
512 |
+
$('#astra-sites-admin').find('.spinner').removeClass('is-active');
|
513 |
+
|
514 |
+
if( data.items_count <= 0 ) {
|
515 |
+
$('#astra-sites-admin').find('.spinner').removeClass('is-active');
|
516 |
+
$('.no-more-demos').addClass('hide-me');
|
517 |
+
$('.astra-sites-suggestions').remove();
|
518 |
+
|
519 |
+
} else {
|
520 |
+
$('body').removeClass('listed-all-sites');
|
521 |
+
}
|
522 |
+
|
523 |
+
|
524 |
+
},
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Check image loaded with function `imagesLoaded()`
|
528 |
+
*/
|
529 |
+
_imagesLoaded: function() {
|
530 |
+
|
531 |
+
var self = jQuery('#sites-filter.execute-only-one-time a');
|
532 |
+
|
533 |
+
$('.astra-sites-grid').imagesLoaded()
|
534 |
+
.always( function( instance ) {
|
535 |
+
if( jQuery( window ).outerWidth() > AstraRender._breakpoint ) {
|
536 |
+
// $('#astra-sites').masonry('reload');
|
537 |
+
}
|
538 |
+
|
539 |
+
$('#astra-sites-admin').find('.spinner').removeClass('is-active');
|
540 |
+
})
|
541 |
+
.progress( function( instance, image ) {
|
542 |
+
var result = image.isLoaded ? 'loaded' : 'broken';
|
543 |
+
});
|
544 |
+
|
545 |
+
},
|
546 |
+
|
547 |
+
/**
|
548 |
+
* Add Suggestion Box
|
549 |
+
*/
|
550 |
+
_addSuggestionBox: function() {
|
551 |
+
$('#astra-sites-admin').find('.spinner').removeClass('is-active').addClass('hide-me');
|
552 |
+
|
553 |
+
$('#astra-sites-admin').find('.no-more-demos').removeClass('hide-me');
|
554 |
+
var template = wp.template('astra-sites-suggestions');
|
555 |
+
if( ! $( '.astra-sites-suggestions').length ) {
|
556 |
+
$('#astra-sites').append( template );
|
557 |
+
}
|
558 |
+
},
|
559 |
+
|
560 |
+
/**
|
561 |
+
* Update Page Count.
|
562 |
+
*/
|
563 |
+
_updatedPagedCount: function() {
|
564 |
+
paged = parseInt(jQuery('body').attr('data-astra-demo-paged'));
|
565 |
+
jQuery('body').attr('data-astra-demo-paged', paged + 1);
|
566 |
+
window.setTimeout(function () {
|
567 |
+
jQuery('body').data('scrolling', false);
|
568 |
+
}, 800);
|
569 |
+
},
|
570 |
+
|
571 |
+
/**
|
572 |
+
* Reset Page Count.
|
573 |
+
*/
|
574 |
+
_resetPagedCount: function() {
|
575 |
+
|
576 |
+
jQuery('body').attr('data-astra-demo-last-request', '1');
|
577 |
+
jQuery('body').attr('data-astra-demo-paged', '1');
|
578 |
+
jQuery('body').attr('data-astra-demo-search', '');
|
579 |
+
jQuery('body').attr('data-scrolling', false);
|
580 |
+
|
581 |
+
},
|
582 |
+
|
583 |
+
// Returns if a value is an array
|
584 |
+
_isArray: function(value) {
|
585 |
+
return value && typeof value === 'object' && value.constructor === Array;
|
586 |
+
}
|
587 |
+
|
588 |
+
};
|
589 |
+
|
590 |
+
/**
|
591 |
+
* Initialize AstraRender
|
592 |
+
*/
|
593 |
+
$(function(){
|
594 |
+
AstraRender.init();
|
595 |
+
});
|
596 |
+
|
597 |
Â
})(jQuery);
|
inc/classes/class-astra-sites.php
CHANGED
@@ -1,518 +1,581 @@
|
|
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 get_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 |
-
self::set_api_url();
|
57 |
-
|
58 |
-
$this->includes();
|
59 |
-
|
60 |
-
add_action( 'admin_notices', array( $this, 'add_notice' ), 1 );
|
61 |
-
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
62 |
-
add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
|
63 |
-
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue' ) );
|
64 |
-
|
65 |
-
// AJAX.
|
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 |
-
add_action( 'wp_ajax_astra-sites-backup-settings', array( $this, 'backup_settings' ) );
|
69 |
-
add_action( 'wp_ajax_astra-sites-set-reset-data', array( $this, 'set_reset_data' ) );
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
}
|
102 |
-
|
103 |
-
$
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
}
|
136 |
-
|
137 |
-
/**
|
138 |
-
*
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
*
|
163 |
-
*
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
)
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
*
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
*
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
'
|
253 |
-
'
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
$data
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
'
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
'
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
),
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
'
|
362 |
-
'
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
'
|
381 |
-
'
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
*
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
*
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
$
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
'
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 get_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 |
+
self::set_api_url();
|
57 |
+
|
58 |
+
$this->includes();
|
59 |
+
|
60 |
+
add_action( 'admin_notices', array( $this, 'add_notice' ), 1 );
|
61 |
+
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
62 |
+
add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
|
63 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue' ) );
|
64 |
+
|
65 |
+
// AJAX.
|
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 |
+
add_action( 'wp_ajax_astra-sites-backup-settings', array( $this, 'backup_settings' ) );
|
69 |
+
add_action( 'wp_ajax_astra-sites-set-reset-data', array( $this, 'set_reset_data' ) );
|
70 |
+
add_action( 'wp_ajax_astra-sites-activate-theme', array( $this, 'activate_theme' ) );
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Activate theme
|
75 |
+
*
|
76 |
+
* @since 1.3.2
|
77 |
+
* @return void
|
78 |
+
*/
|
79 |
+
function activate_theme() {
|
80 |
+
|
81 |
+
switch_theme( 'astra' );
|
82 |
+
|
83 |
+
wp_send_json_success(
|
84 |
+
array(
|
85 |
+
'success' => true,
|
86 |
+
'message' => __( 'Theme Successfully Activated', 'astra-sites' ),
|
87 |
+
)
|
88 |
+
);
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Set reset data
|
93 |
+
*/
|
94 |
+
function set_reset_data() {
|
95 |
+
if ( ! current_user_can( 'manage_options' ) ) {
|
96 |
+
return;
|
97 |
+
}
|
98 |
+
|
99 |
+
global $wpdb;
|
100 |
+
|
101 |
+
$post_ids = $wpdb->get_col( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='_astra_sites_imported_post'" );
|
102 |
+
$form_ids = $wpdb->get_col( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='_astra_sites_imported_wp_forms'" );
|
103 |
+
$term_ids = $wpdb->get_col( "SELECT term_id FROM {$wpdb->termmeta} WHERE meta_key='_astra_sites_imported_term'" );
|
104 |
+
|
105 |
+
wp_send_json_success(
|
106 |
+
array(
|
107 |
+
'reset_posts' => $post_ids,
|
108 |
+
'reset_wp_forms' => $form_ids,
|
109 |
+
'reset_terms' => $term_ids,
|
110 |
+
)
|
111 |
+
);
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Backup our existing settings.
|
116 |
+
*/
|
117 |
+
function backup_settings() {
|
118 |
+
if ( ! current_user_can( 'manage_options' ) ) {
|
119 |
+
return;
|
120 |
+
}
|
121 |
+
|
122 |
+
$file_name = 'astra-sites-backup-' . date( 'd-M-Y-h-i-s' ) . '.json';
|
123 |
+
$old_settings = get_option( 'astra-settings', array() );
|
124 |
+
$upload_dir = Astra_Sites_Importer_Log::get_instance()->log_dir();
|
125 |
+
$upload_path = trailingslashit( $upload_dir['path'] );
|
126 |
+
$log_file = $upload_path . $file_name;
|
127 |
+
$file_system = Astra_Sites_Importer_Log::get_instance()->get_filesystem();
|
128 |
+
|
129 |
+
// If file system fails? Then take a backup in site option.
|
130 |
+
if ( false == $file_system->put_contents( $log_file, json_encode( $old_settings ), FS_CHMOD_FILE ) ) {
|
131 |
+
update_option( 'astra_sites_' . $file_name, $old_settings );
|
132 |
+
}
|
133 |
+
|
134 |
+
wp_send_json_success();
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Add Admin Notice.
|
139 |
+
*/
|
140 |
+
function add_notice() {
|
141 |
+
|
142 |
+
$theme_status = 'astra-sites-theme-' . $this->get_theme_status();
|
143 |
+
|
144 |
+
Astra_Sites_Notices::add_notice(
|
145 |
+
array(
|
146 |
+
'id' => 'astra-theme-activation-nag',
|
147 |
+
'type' => 'error',
|
148 |
+
'show_if' => ( ! defined( 'ASTRA_THEME_SETTINGS' ) ) ? true : false,
|
149 |
+
/* translators: 1: theme.php file*/
|
150 |
+
'message' => sprintf( __( 'Astra Theme needs to be active for you to use currently installed "%1$s" plugin. <a href="#" class="%3$s" data-theme-slug="astra">Install & Activate Now</a>', 'astra-sites' ), ASTRA_SITES_NAME, esc_url( admin_url( 'themes.php?theme=astra' ) ), $theme_status ),
|
151 |
+
'dismissible' => true,
|
152 |
+
'dismissible-time' => WEEK_IN_SECONDS,
|
153 |
+
)
|
154 |
+
);
|
155 |
+
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Get theme install, active or inactive status.
|
160 |
+
*
|
161 |
+
* @since 1.3.2
|
162 |
+
*
|
163 |
+
* @return string Theme status
|
164 |
+
*/
|
165 |
+
function get_theme_status() {
|
166 |
+
|
167 |
+
$theme = wp_get_theme();
|
168 |
+
|
169 |
+
// Theme installed and activate.
|
170 |
+
if ( 'Astra' == $theme->name || 'Astra' == $theme->parent_theme ) {
|
171 |
+
return 'installed-and-active';
|
172 |
+
}
|
173 |
+
|
174 |
+
// Theme installed but not activate.
|
175 |
+
foreach ( (array) wp_get_themes() as $theme_dir => $theme ) {
|
176 |
+
if ( 'Astra' == $theme->name || 'Astra' == $theme->parent_theme ) {
|
177 |
+
return 'installed-but-inactive';
|
178 |
+
}
|
179 |
+
}
|
180 |
+
|
181 |
+
return 'not-installed';
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Loads textdomain for the plugin.
|
186 |
+
*
|
187 |
+
* @since 1.0.1
|
188 |
+
*/
|
189 |
+
function load_textdomain() {
|
190 |
+
load_plugin_textdomain( 'astra-sites' );
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* Admin Notices
|
195 |
+
*
|
196 |
+
* @since 1.0.5
|
197 |
+
* @return void
|
198 |
+
*/
|
199 |
+
function admin_notices() {
|
200 |
+
|
201 |
+
if ( ! defined( 'ASTRA_THEME_SETTINGS' ) ) {
|
202 |
+
return;
|
203 |
+
}
|
204 |
+
|
205 |
+
add_action( 'plugin_action_links_' . ASTRA_SITES_BASE, array( $this, 'action_links' ) );
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Show action links on the plugin screen.
|
210 |
+
*
|
211 |
+
* @param mixed $links Plugin Action links.
|
212 |
+
* @return array
|
213 |
+
*/
|
214 |
+
function action_links( $links ) {
|
215 |
+
$action_links = array(
|
216 |
+
'settings' => '<a href="' . admin_url( 'themes.php?page=astra-sites' ) . '" aria-label="' . esc_attr__( 'See Library', 'astra-sites' ) . '">' . esc_html__( 'See Library', 'astra-sites' ) . '</a>',
|
217 |
+
);
|
218 |
+
|
219 |
+
return array_merge( $action_links, $links );
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Setter for $api_url
|
224 |
+
*
|
225 |
+
* @since 1.0.0
|
226 |
+
*/
|
227 |
+
public static function set_api_url() {
|
228 |
+
|
229 |
+
self::$api_url = apply_filters( 'astra_sites_api_url', 'https://websitedemos.net/wp-json/wp/v2/' );
|
230 |
+
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Enqueue admin scripts.
|
235 |
+
*
|
236 |
+
* @since 1.3.2 Added 'install-theme.js' to install and activate theme.
|
237 |
+
* @since 1.0.5 Added 'getUpgradeText' and 'getUpgradeURL' localize variables.
|
238 |
+
*
|
239 |
+
* @since 1.0.0
|
240 |
+
*
|
241 |
+
* @param string $hook Current hook name.
|
242 |
+
* @return void
|
243 |
+
*/
|
244 |
+
public function admin_enqueue( $hook = '' ) {
|
245 |
+
|
246 |
+
wp_enqueue_script( 'astra-sites-install-theme', ASTRA_SITES_URI . 'inc/assets/js/install-theme.js', array( 'jquery', 'updates' ), ASTRA_SITES_VER, true );
|
247 |
+
wp_enqueue_style( 'astra-sites-install-theme', ASTRA_SITES_URI . 'inc/assets/css/install-theme.css', null, ASTRA_SITES_VER, 'all' );
|
248 |
+
|
249 |
+
$data = apply_filters(
|
250 |
+
'astra_sites_install_theme_localize_vars',
|
251 |
+
array(
|
252 |
+
'installed' => __( 'Installed! Activating..', 'astra-sites' ),
|
253 |
+
'activating' => __( 'Activating..', 'astra-sites' ),
|
254 |
+
'activated' => __( 'Activated! Reloading..', 'astra-sites' ),
|
255 |
+
'installing' => __( 'Installing..', 'astra-sites' ),
|
256 |
+
'ajaxurl' => esc_url( admin_url( 'admin-ajax.php' ) ),
|
257 |
+
)
|
258 |
+
);
|
259 |
+
wp_localize_script( 'astra-sites-install-theme', 'AstraSitesInstallThemeVars', $data );
|
260 |
+
|
261 |
+
if ( 'appearance_page_astra-sites' !== $hook ) {
|
262 |
+
return;
|
263 |
+
}
|
264 |
+
|
265 |
+
global $is_IE, $is_edge;
|
266 |
+
|
267 |
+
if ( $is_IE || $is_edge ) {
|
268 |
+
wp_enqueue_script( 'astra-sites-eventsource', ASTRA_SITES_URI . 'inc/assets/js/eventsource.min.js', array( 'jquery', 'wp-util', 'updates' ), ASTRA_SITES_VER, true );
|
269 |
+
}
|
270 |
+
|
271 |
+
// API.
|
272 |
+
wp_register_script( 'astra-sites-api', ASTRA_SITES_URI . 'inc/assets/js/astra-sites-api.js', array( 'jquery' ), ASTRA_SITES_VER, true );
|
273 |
+
|
274 |
+
// Admin Page.
|
275 |
+
wp_enqueue_style( 'astra-sites-admin', ASTRA_SITES_URI . 'inc/assets/css/admin.css', ASTRA_SITES_VER, true );
|
276 |
+
wp_enqueue_script( 'astra-sites-admin-page', ASTRA_SITES_URI . 'inc/assets/js/admin-page.js', array( 'jquery', 'wp-util', 'updates' ), ASTRA_SITES_VER, true );
|
277 |
+
wp_enqueue_script( 'astra-sites-render-grid', ASTRA_SITES_URI . 'inc/assets/js/render-grid.js', array( 'wp-util', 'astra-sites-api', 'imagesloaded', 'jquery' ), ASTRA_SITES_VER, true );
|
278 |
+
|
279 |
+
$data = apply_filters(
|
280 |
+
'astra_sites_localize_vars',
|
281 |
+
array(
|
282 |
+
'ApiURL' => self::$api_url,
|
283 |
+
'filters' => array(
|
284 |
+
'page_builder' => array(
|
285 |
+
'title' => __( 'Page Builder', 'astra-sites' ),
|
286 |
+
'slug' => 'astra-site-page-builder',
|
287 |
+
'trigger' => 'astra-api-category-loaded',
|
288 |
+
),
|
289 |
+
'categories' => array(
|
290 |
+
'title' => __( 'Categories', 'astra-sites' ),
|
291 |
+
'slug' => 'astra-site-category',
|
292 |
+
'trigger' => 'astra-api-category-loaded',
|
293 |
+
),
|
294 |
+
),
|
295 |
+
)
|
296 |
+
);
|
297 |
+
wp_localize_script( 'astra-sites-api', 'astraSitesApi', $data );
|
298 |
+
|
299 |
+
// Use this for premium demos.
|
300 |
+
$request_params = apply_filters(
|
301 |
+
'astra_sites_api_params',
|
302 |
+
array(
|
303 |
+
'purchase_key' => '',
|
304 |
+
'site_url' => '',
|
305 |
+
'par-page' => 15,
|
306 |
+
)
|
307 |
+
);
|
308 |
+
|
309 |
+
$data = apply_filters(
|
310 |
+
'astra_sites_render_localize_vars',
|
311 |
+
array(
|
312 |
+
'sites' => $request_params,
|
313 |
+
'page-builders' => array(),
|
314 |
+
'categories' => array(),
|
315 |
+
'settings' => array(),
|
316 |
+
'default_page_builder' => Astra_Sites_Page::get_instance()->get_setting( 'page_builder' ),
|
317 |
+
)
|
318 |
+
);
|
319 |
+
|
320 |
+
wp_localize_script( 'astra-sites-render-grid', 'astraRenderGrid', $data );
|
321 |
+
|
322 |
+
$data = apply_filters(
|
323 |
+
'astra_sites_localize_vars',
|
324 |
+
array(
|
325 |
+
'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false,
|
326 |
+
'isPro' => defined( 'ASTRA_PRO_SITES_NAME' ) ? true : false,
|
327 |
+
'isWhiteLabeled' => Astra_Sites_White_Label::get_instance()->is_white_labeled(),
|
328 |
+
'ajaxurl' => esc_url( admin_url( 'admin-ajax.php' ) ),
|
329 |
+
'siteURL' => site_url(),
|
330 |
+
'getProText' => __( 'Get Agency Bundle', 'astra-sites' ),
|
331 |
+
'getProURL' => esc_url( 'https://wpastra.com/agency/?utm_source=demo-import-panel&utm_campaign=astra-sites&utm_medium=wp-dashboard' ),
|
332 |
+
'getUpgradeText' => __( 'Upgrade', 'astra-sites' ),
|
333 |
+
'getUpgradeURL' => esc_url( 'https://wpastra.com/agency/?utm_source=demo-import-panel&utm_campaign=astra-sites&utm_medium=wp-dashboard' ),
|
334 |
+
'_ajax_nonce' => wp_create_nonce( 'astra-sites' ),
|
335 |
+
'requiredPlugins' => array(),
|
336 |
+
'XMLReaderDisabled' => ! class_exists( 'XMLReader' ) ? true : false,
|
337 |
+
'strings' => array(
|
338 |
+
/* translators: %s are HTML tags. */
|
339 |
+
'warningXMLReader' => sprintf( __( '%1$sRequired XMLReader PHP extension is missing on your server!%2$sAstra Sites import requires XMLReader extension to be installed. Please contact your web hosting provider and ask them to install and activate the XMLReader PHP extension.', 'astra-sites' ), '<div class="notice astra-sites-xml-notice notice-error"><p><b>', '</b></p><p>', '</p></div>' ),
|
340 |
+
'warningBeforeCloseWindow' => __( 'Warning! Astra Site Import process is not complete. Don\'t close the window until import process complete. Do you still want to leave the window?', 'astra-sites' ),
|
341 |
+
'importFailedBtnSmall' => __( 'Error!', 'astra-sites' ),
|
342 |
+
'importFailedBtnLarge' => __( 'Error! Read Possibilities.', 'astra-sites' ),
|
343 |
+
'importFailedURL' => esc_url( 'https://wpastra.com/docs/?p=1314&utm_source=demo-import-panel&utm_campaign=astra-sites&utm_medium=import-failed' ),
|
344 |
+
'viewSite' => __( 'Done! View Site', 'astra-sites' ),
|
345 |
+
'btnActivating' => __( 'Activating', 'astra-sites' ) . '…',
|
346 |
+
'btnActive' => __( 'Active', 'astra-sites' ),
|
347 |
+
'importFailBtn' => __( 'Import failed.', 'astra-sites' ),
|
348 |
+
'importFailBtnLarge' => __( 'Import failed. See error log.', 'astra-sites' ),
|
349 |
+
'importDemo' => __( 'Import This Site', 'astra-sites' ),
|
350 |
+
'importingDemo' => __( 'Importing..', 'astra-sites' ),
|
351 |
+
'DescExpand' => __( 'Read more', 'astra-sites' ) . '…',
|
352 |
+
'DescCollapse' => __( 'Hide', 'astra-sites' ),
|
353 |
+
'responseError' => __( 'There was a problem receiving a response from server.', 'astra-sites' ),
|
354 |
+
'searchNoFound' => __( 'No Demos found, Try a different search.', 'astra-sites' ),
|
355 |
+
),
|
356 |
+
'log' => array(
|
357 |
+
'installingPlugin' => __( 'Installing plugin ', 'astra-sites' ),
|
358 |
+
'installed' => __( 'Successfully plugin installed!', 'astra-sites' ),
|
359 |
+
'activating' => __( 'Activating plugin ', 'astra-sites' ),
|
360 |
+
'activated' => __( 'Successfully plugin activated ', 'astra-sites' ),
|
361 |
+
'bulkActivation' => __( 'Bulk plugin activation...', 'astra-sites' ),
|
362 |
+
'activate' => __( 'Successfully plugin activate - ', 'astra-sites' ),
|
363 |
+
'activationError' => __( 'Error! While activating plugin - ', 'astra-sites' ),
|
364 |
+
'bulkInstall' => __( 'Bulk plugin installation...', 'astra-sites' ),
|
365 |
+
'api' => __( 'Site API ', 'astra-sites' ),
|
366 |
+
'importing' => __( 'Importing..', 'astra-sites' ),
|
367 |
+
'processingRequest' => __( 'Processing requests...', 'astra-sites' ),
|
368 |
+
'importCustomizer' => __( '2) Importing "Customizer Settings"...', 'astra-sites' ),
|
369 |
+
'importCustomizerSuccess' => __( 'Successfully imported customizer settings!', 'astra-sites' ),
|
370 |
+
'importWPForms' => __( '3) Importing "Contact Forms"...', 'astra-sites' ),
|
371 |
+
'importWPFormsSuccess' => __( 'Successfully imported Contact Forms!', 'astra-sites' ),
|
372 |
+
'importXMLPrepare' => __( '4) Preparing "XML" Data...', 'astra-sites' ),
|
373 |
+
'importXMLPrepareSuccess' => __( 'Successfully set XML data!', 'astra-sites' ),
|
374 |
+
'importXML' => __( '5) Importing "XML"...', 'astra-sites' ),
|
375 |
+
'importXMLSuccess' => __( 'Successfully imported XML!', 'astra-sites' ),
|
376 |
+
'importOptions' => __( '6) Importing "Options"...', 'astra-sites' ),
|
377 |
+
'importOptionsSuccess' => __( 'Successfully imported Options!', 'astra-sites' ),
|
378 |
+
'importWidgets' => __( '7) Importing "Widgets"...', 'astra-sites' ),
|
379 |
+
'importWidgetsSuccess' => __( 'Successfully imported Widgets!', 'astra-sites' ),
|
380 |
+
'serverConfiguration' => esc_url( 'https://wpastra.com/docs/?p=1314&utm_source=demo-import-panel&utm_campaign=import-error&utm_medium=wp-dashboard' ),
|
381 |
+
'success' => __( 'Site imported successfully! visit : ', 'astra-sites' ),
|
382 |
+
'gettingData' => __( 'Getting Site Information..', 'astra-sites' ),
|
383 |
+
'importingCustomizer' => __( 'Importing Customizer Settings..', 'astra-sites' ),
|
384 |
+
'importingWPForms' => __( 'Importing Contact Forms..', 'astra-sites' ),
|
385 |
+
'importXMLPreparing' => __( 'Setting up import data..', 'astra-sites' ),
|
386 |
+
'importingXML' => __( 'Importing Content..', 'astra-sites' ),
|
387 |
+
'importingOptions' => __( 'Importing Site Options..', 'astra-sites' ),
|
388 |
+
'importingWidgets' => __( 'Importing Widgets..', 'astra-sites' ),
|
389 |
+
'importComplete' => __( 'Import Complete..', 'astra-sites' ),
|
390 |
+
'preview' => __( 'Previewing ', 'astra-sites' ),
|
391 |
+
'importLogText' => __( 'See Error Log →', 'astra-sites' ),
|
392 |
+
),
|
393 |
+
)
|
394 |
+
);
|
395 |
+
|
396 |
+
wp_localize_script( 'astra-sites-admin-page', 'astraSitesAdmin', $data );
|
397 |
+
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Load all the required files in the importer.
|
402 |
+
*
|
403 |
+
* @since 1.0.0
|
404 |
+
*/
|
405 |
+
private function includes() {
|
406 |
+
|
407 |
+
require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-notices.php';
|
408 |
+
require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-page.php';
|
409 |
+
require_once ASTRA_SITES_DIR . 'inc/classes/compatibility/class-astra-sites-compatibility.php';
|
410 |
+
require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-white-label.php';
|
411 |
+
require_once ASTRA_SITES_DIR . 'inc/classes/class-astra-sites-importer.php';
|
412 |
+
}
|
413 |
+
|
414 |
+
/**
|
415 |
+
* Required Plugin Activate
|
416 |
+
*
|
417 |
+
* @since 1.0.0
|
418 |
+
*/
|
419 |
+
public function required_plugin_activate() {
|
420 |
+
|
421 |
+
if ( ! current_user_can( 'install_plugins' ) || ! isset( $_POST['init'] ) || ! $_POST['init'] ) {
|
422 |
+
wp_send_json_error(
|
423 |
+
array(
|
424 |
+
'success' => false,
|
425 |
+
'message' => __( 'No plugin specified', 'astra-sites' ),
|
426 |
+
)
|
427 |
+
);
|
428 |
+
}
|
429 |
+
|
430 |
+
$data = array();
|
431 |
+
$plugin_init = ( isset( $_POST['init'] ) ) ? esc_attr( $_POST['init'] ) : '';
|
432 |
+
$astra_site_options = ( isset( $_POST['options'] ) ) ? json_decode( stripslashes( $_POST['options'] ) ) : '';
|
433 |
+
$enabled_extensions = ( isset( $_POST['enabledExtensions'] ) ) ? json_decode( stripslashes( $_POST['enabledExtensions'] ) ) : '';
|
434 |
+
|
435 |
+
$data['astra_site_options'] = $astra_site_options;
|
436 |
+
$data['enabled_extensions'] = $enabled_extensions;
|
437 |
+
|
438 |
+
$activate = activate_plugin( $plugin_init, '', false, true );
|
439 |
+
|
440 |
+
if ( is_wp_error( $activate ) ) {
|
441 |
+
wp_send_json_error(
|
442 |
+
array(
|
443 |
+
'success' => false,
|
444 |
+
'message' => $activate->get_error_message(),
|
445 |
+
)
|
446 |
+
);
|
447 |
+
}
|
448 |
+
|
449 |
+
do_action( 'astra_sites_after_plugin_activation', $plugin_init, $data );
|
450 |
+
|
451 |
+
wp_send_json_success(
|
452 |
+
array(
|
453 |
+
'success' => true,
|
454 |
+
'message' => __( 'Plugin Successfully Activated', 'astra-sites' ),
|
455 |
+
)
|
456 |
+
);
|
457 |
+
|
458 |
+
}
|
459 |
+
|
460 |
+
/**
|
461 |
+
* Required Plugin
|
462 |
+
*
|
463 |
+
* @since 1.0.0
|
464 |
+
* @return void
|
465 |
+
*/
|
466 |
+
public function required_plugin() {
|
467 |
+
|
468 |
+
// Verify Nonce.
|
469 |
+
check_ajax_referer( 'astra-sites', '_ajax_nonce' );
|
470 |
+
|
471 |
+
$response = array(
|
472 |
+
'active' => array(),
|
473 |
+
'inactive' => array(),
|
474 |
+
'notinstalled' => array(),
|
475 |
+
);
|
476 |
+
|
477 |
+
if ( ! current_user_can( 'customize' ) ) {
|
478 |
+
wp_send_json_error( $response );
|
479 |
+
}
|
480 |
+
|
481 |
+
$required_plugins = ( isset( $_POST['required_plugins'] ) ) ? $_POST['required_plugins'] : array();
|
482 |
+
|
483 |
+
if ( count( $required_plugins ) > 0 ) {
|
484 |
+
foreach ( $required_plugins as $key => $plugin ) {
|
485 |
+
|
486 |
+
/**
|
487 |
+
* Has Pro Version Support?
|
488 |
+
* And
|
489 |
+
* Is Pro Version Installed?
|
490 |
+
*/
|
491 |
+
$plugin_pro = self::pro_plugin_exist( $plugin['init'] );
|
492 |
+
if ( $plugin_pro ) {
|
493 |
+
|
494 |
+
// Pro - Active.
|
495 |
+
if ( is_plugin_active( $plugin_pro['init'] ) ) {
|
496 |
+
$response['active'][] = $plugin_pro;
|
497 |
+
|
498 |
+
// Pro - Inactive.
|
499 |
+
} else {
|
500 |
+
$response['inactive'][] = $plugin_pro;
|
501 |
+
}
|
502 |
+
} else {
|
503 |
+
|
504 |
+
// Lite - Installed but Inactive.
|
505 |
+
if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin['init'] ) && is_plugin_inactive( $plugin['init'] ) ) {
|
506 |
+
|
507 |
+
$response['inactive'][] = $plugin;
|
508 |
+
|
509 |
+
// Lite - Not Installed.
|
510 |
+
} elseif ( ! file_exists( WP_PLUGIN_DIR . '/' . $plugin['init'] ) ) {
|
511 |
+
|
512 |
+
$response['notinstalled'][] = $plugin;
|
513 |
+
|
514 |
+
// Lite - Active.
|
515 |
+
} else {
|
516 |
+
$response['active'][] = $plugin;
|
517 |
+
}
|
518 |
+
}
|
519 |
+
}
|
520 |
+
}
|
521 |
+
|
522 |
+
// Send response.
|
523 |
+
wp_send_json_success( $response );
|
524 |
+
}
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Has Pro Version Support?
|
528 |
+
* And
|
529 |
+
* Is Pro Version Installed?
|
530 |
+
*
|
531 |
+
* Check Pro plugin version exist of requested plugin lite version.
|
532 |
+
*
|
533 |
+
* Eg. If plugin 'BB Lite Version' required to import demo. Then we check the 'BB Agency Version' is exist?
|
534 |
+
* If yes then we only 'Activate' Agency Version. [We couldn't install agency version.]
|
535 |
+
* Else we 'Activate' or 'Install' Lite Version.
|
536 |
+
*
|
537 |
+
* @since 1.0.1
|
538 |
+
*
|
539 |
+
* @param string $lite_version Lite version init file.
|
540 |
+
* @return mixed Return false if not installed or not supported by us
|
541 |
+
* else return 'Pro' version details.
|
542 |
+
*/
|
543 |
+
public static function pro_plugin_exist( $lite_version = '' ) {
|
544 |
+
|
545 |
+
// Lite init => Pro init.
|
546 |
+
$plugins = apply_filters(
|
547 |
+
'astra_sites_pro_plugin_exist',
|
548 |
+
array(
|
549 |
+
'beaver-builder-lite-version/fl-builder.php' => array(
|
550 |
+
'slug' => 'bb-plugin',
|
551 |
+
'init' => 'bb-plugin/fl-builder.php',
|
552 |
+
'name' => 'Beaver Builder Plugin',
|
553 |
+
),
|
554 |
+
'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php' => array(
|
555 |
+
'slug' => 'bb-ultimate-addon',
|
556 |
+
'init' => 'bb-ultimate-addon/bb-ultimate-addon.php',
|
557 |
+
'name' => 'Ultimate Addon for Beaver Builder',
|
558 |
+
),
|
559 |
+
),
|
560 |
+
$lite_version
|
561 |
+
);
|
562 |
+
|
563 |
+
if ( isset( $plugins[ $lite_version ] ) ) {
|
564 |
+
|
565 |
+
// Pro plugin directory exist?
|
566 |
+
if ( file_exists( WP_PLUGIN_DIR . '/' . $plugins[ $lite_version ]['init'] ) ) {
|
567 |
+
return $plugins[ $lite_version ];
|
568 |
+
}
|
569 |
+
}
|
570 |
+
|
571 |
+
return false;
|
572 |
+
}
|
573 |
+
|
574 |
+
}
|
575 |
+
|
576 |
+
/**
|
577 |
+
* Kicking this off by calling 'get_instance()' method
|
578 |
+
*/
|
579 |
+
Astra_Sites::get_instance();
|
580 |
+
|
581 |
+
endif;
|
inc/importers/batch-processing/helpers/class-wp-async-request.php
CHANGED
@@ -1,164 +1,164 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WP Async Request
|
4 |
-
*
|
5 |
-
* @see https://github.com/A5hleyRich/wp-background-processing/
|
6 |
-
* @package WP-Background-Processing
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! class_exists( 'WP_Async_Request' ) ) {
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Abstract WP_Async_Request class.
|
13 |
-
*
|
14 |
-
* @abstract
|
15 |
-
*/
|
16 |
-
abstract class WP_Async_Request {
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Prefix
|
20 |
-
*
|
21 |
-
* (default value: 'wp')
|
22 |
-
*
|
23 |
-
* @var string
|
24 |
-
* @access protected
|
25 |
-
*/
|
26 |
-
protected $prefix = 'wp';
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Action
|
30 |
-
*
|
31 |
-
* (default value: 'async_request')
|
32 |
-
*
|
33 |
-
* @var string
|
34 |
-
* @access protected
|
35 |
-
*/
|
36 |
-
protected $action = 'async_request';
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Identifier
|
40 |
-
*
|
41 |
-
* @var mixed
|
42 |
-
* @access protected
|
43 |
-
*/
|
44 |
-
protected $identifier;
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Data
|
48 |
-
*
|
49 |
-
* (default value: array())
|
50 |
-
*
|
51 |
-
* @var array
|
52 |
-
* @access protected
|
53 |
-
*/
|
54 |
-
protected $data = array();
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Initiate new async request
|
58 |
-
*/
|
59 |
-
public function __construct() {
|
60 |
-
$this->identifier = $this->prefix . '_' . $this->action;
|
61 |
-
|
62 |
-
add_action( 'wp_ajax_' . $this->identifier, array( $this, 'maybe_handle' ) );
|
63 |
-
add_action( 'wp_ajax_nopriv_' . $this->identifier, array( $this, 'maybe_handle' ) );
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Set data used during the request
|
68 |
-
*
|
69 |
-
* @param array $data Data.
|
70 |
-
*
|
71 |
-
* @return $this
|
72 |
-
*/
|
73 |
-
public function data( $data ) {
|
74 |
-
$this->data = $data;
|
75 |
-
|
76 |
-
return $this;
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Dispatch the async request
|
81 |
-
*
|
82 |
-
* @return array|WP_Error
|
83 |
-
*/
|
84 |
-
public function dispatch() {
|
85 |
-
$url = add_query_arg( $this->get_query_args(), $this->get_query_url() );
|
86 |
-
$args = $this->get_post_args();
|
87 |
-
|
88 |
-
return wp_remote_post( esc_url_raw( $url ), $args );
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Get query args
|
93 |
-
*
|
94 |
-
* @return array
|
95 |
-
*/
|
96 |
-
protected function get_query_args() {
|
97 |
-
if ( property_exists( $this, 'query_args' ) ) {
|
98 |
-
return $this->query_args;
|
99 |
-
}
|
100 |
-
|
101 |
-
return array(
|
102 |
-
'action' => $this->identifier,
|
103 |
-
'nonce' => wp_create_nonce( $this->identifier ),
|
104 |
-
);
|
105 |
-
}
|
106 |
-
|
107 |
-
/**
|
108 |
-
* Get query URL
|
109 |
-
*
|
110 |
-
* @return string
|
111 |
-
*/
|
112 |
-
protected function get_query_url() {
|
113 |
-
if ( property_exists( $this, 'query_url' ) ) {
|
114 |
-
return $this->query_url;
|
115 |
-
}
|
116 |
-
|
117 |
-
return admin_url( 'admin-ajax.php' );
|
118 |
-
}
|
119 |
-
|
120 |
-
/**
|
121 |
-
* Get post args
|
122 |
-
*
|
123 |
-
* @return array
|
124 |
-
*/
|
125 |
-
protected function get_post_args() {
|
126 |
-
if ( property_exists( $this, 'post_args' ) ) {
|
127 |
-
return $this->post_args;
|
128 |
-
}
|
129 |
-
|
130 |
-
return array(
|
131 |
-
'timeout' => 0.01,
|
132 |
-
'blocking' => false,
|
133 |
-
'body' => $this->data,
|
134 |
-
'cookies' => $_COOKIE,
|
135 |
-
'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
|
136 |
-
);
|
137 |
-
}
|
138 |
-
|
139 |
-
/**
|
140 |
-
* Maybe handle
|
141 |
-
*
|
142 |
-
* Check for correct nonce and pass to handler.
|
143 |
-
*/
|
144 |
-
public function maybe_handle() {
|
145 |
-
// Don't lock up other requests while processing.
|
146 |
-
session_write_close();
|
147 |
-
|
148 |
-
check_ajax_referer( $this->identifier, 'nonce' );
|
149 |
-
|
150 |
-
$this->handle();
|
151 |
-
|
152 |
-
wp_die();
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* Handle
|
157 |
-
*
|
158 |
-
* Override this method to perform any actions required
|
159 |
-
* during the async request.
|
160 |
-
*/
|
161 |
-
abstract protected function handle();
|
162 |
-
|
163 |
-
}
|
164 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WP Async Request
|
4 |
+
*
|
5 |
+
* @see https://github.com/A5hleyRich/wp-background-processing/
|
6 |
+
* @package WP-Background-Processing
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! class_exists( 'WP_Async_Request' ) ) {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Abstract WP_Async_Request class.
|
13 |
+
*
|
14 |
+
* @abstract
|
15 |
+
*/
|
16 |
+
abstract class WP_Async_Request {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Prefix
|
20 |
+
*
|
21 |
+
* (default value: 'wp')
|
22 |
+
*
|
23 |
+
* @var string
|
24 |
+
* @access protected
|
25 |
+
*/
|
26 |
+
protected $prefix = 'wp';
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Action
|
30 |
+
*
|
31 |
+
* (default value: 'async_request')
|
32 |
+
*
|
33 |
+
* @var string
|
34 |
+
* @access protected
|
35 |
+
*/
|
36 |
+
protected $action = 'async_request';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Identifier
|
40 |
+
*
|
41 |
+
* @var mixed
|
42 |
+
* @access protected
|
43 |
+
*/
|
44 |
+
protected $identifier;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Data
|
48 |
+
*
|
49 |
+
* (default value: array())
|
50 |
+
*
|
51 |
+
* @var array
|
52 |
+
* @access protected
|
53 |
+
*/
|
54 |
+
protected $data = array();
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Initiate new async request
|
58 |
+
*/
|
59 |
+
public function __construct() {
|
60 |
+
$this->identifier = $this->prefix . '_' . $this->action;
|
61 |
+
|
62 |
+
add_action( 'wp_ajax_' . $this->identifier, array( $this, 'maybe_handle' ) );
|
63 |
+
add_action( 'wp_ajax_nopriv_' . $this->identifier, array( $this, 'maybe_handle' ) );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Set data used during the request
|
68 |
+
*
|
69 |
+
* @param array $data Data.
|
70 |
+
*
|
71 |
+
* @return $this
|
72 |
+
*/
|
73 |
+
public function data( $data ) {
|
74 |
+
$this->data = $data;
|
75 |
+
|
76 |
+
return $this;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Dispatch the async request
|
81 |
+
*
|
82 |
+
* @return array|WP_Error
|
83 |
+
*/
|
84 |
+
public function dispatch() {
|
85 |
+
$url = add_query_arg( $this->get_query_args(), $this->get_query_url() );
|
86 |
+
$args = $this->get_post_args();
|
87 |
+
|
88 |
+
return wp_remote_post( esc_url_raw( $url ), $args );
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Get query args
|
93 |
+
*
|
94 |
+
* @return array
|
95 |
+
*/
|
96 |
+
protected function get_query_args() {
|
97 |
+
if ( property_exists( $this, 'query_args' ) ) {
|
98 |
+
return $this->query_args;
|
99 |
+
}
|
100 |
+
|
101 |
+
return array(
|
102 |
+
'action' => $this->identifier,
|
103 |
+
'nonce' => wp_create_nonce( $this->identifier ),
|
104 |
+
);
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Get query URL
|
109 |
+
*
|
110 |
+
* @return string
|
111 |
+
*/
|
112 |
+
protected function get_query_url() {
|
113 |
+
if ( property_exists( $this, 'query_url' ) ) {
|
114 |
+
return $this->query_url;
|
115 |
+
}
|
116 |
+
|
117 |
+
return admin_url( 'admin-ajax.php' );
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Get post args
|
122 |
+
*
|
123 |
+
* @return array
|
124 |
+
*/
|
125 |
+
protected function get_post_args() {
|
126 |
+
if ( property_exists( $this, 'post_args' ) ) {
|
127 |
+
return $this->post_args;
|
128 |
+
}
|
129 |
+
|
130 |
+
return array(
|
131 |
+
'timeout' => 0.01,
|
132 |
+
'blocking' => false,
|
133 |
+
'body' => $this->data,
|
134 |
+
'cookies' => $_COOKIE,
|
135 |
+
'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
|
136 |
+
);
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Maybe handle
|
141 |
+
*
|
142 |
+
* Check for correct nonce and pass to handler.
|
143 |
+
*/
|
144 |
+
public function maybe_handle() {
|
145 |
+
// Don't lock up other requests while processing.
|
146 |
+
session_write_close();
|
147 |
+
|
148 |
+
check_ajax_referer( $this->identifier, 'nonce' );
|
149 |
+
|
150 |
+
$this->handle();
|
151 |
+
|
152 |
+
wp_die();
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Handle
|
157 |
+
*
|
158 |
+
* Override this method to perform any actions required
|
159 |
+
* during the async request.
|
160 |
+
*/
|
161 |
+
abstract protected function handle();
|
162 |
+
|
163 |
+
}
|
164 |
+
}
|
inc/importers/batch-processing/helpers/class-wp-background-process.php
CHANGED
@@ -1,513 +1,513 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WP Background Process
|
4 |
-
*
|
5 |
-
* @see https://github.com/A5hleyRich/wp-background-processing/
|
6 |
-
* @package WP-Background-Processing
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! class_exists( 'WP_Background_Process' ) ) {
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Abstract WP_Background_Process class.
|
13 |
-
*
|
14 |
-
* @abstract
|
15 |
-
* @extends WP_Async_Request
|
16 |
-
*/
|
17 |
-
abstract class WP_Background_Process extends WP_Async_Request {
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Action
|
21 |
-
*
|
22 |
-
* (default value: 'background_process')
|
23 |
-
*
|
24 |
-
* @var string
|
25 |
-
* @access protected
|
26 |
-
*/
|
27 |
-
protected $action = 'background_process';
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Start time of current process.
|
31 |
-
*
|
32 |
-
* (default value: 0)
|
33 |
-
*
|
34 |
-
* @var int
|
35 |
-
* @access protected
|
36 |
-
*/
|
37 |
-
protected $start_time = 0;
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Cron_hook_identifier
|
41 |
-
*
|
42 |
-
* @var mixed
|
43 |
-
* @access protected
|
44 |
-
*/
|
45 |
-
protected $cron_hook_identifier;
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Cron_interval_identifier
|
49 |
-
*
|
50 |
-
* @var mixed
|
51 |
-
* @access protected
|
52 |
-
*/
|
53 |
-
protected $cron_interval_identifier;
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Initiate new background process
|
57 |
-
*/
|
58 |
-
public function __construct() {
|
59 |
-
parent::__construct();
|
60 |
-
|
61 |
-
$this->cron_hook_identifier = $this->identifier . '_cron';
|
62 |
-
$this->cron_interval_identifier = $this->identifier . '_cron_interval';
|
63 |
-
|
64 |
-
add_action( $this->cron_hook_identifier, array( $this, 'handle_cron_healthcheck' ) );
|
65 |
-
add_filter( 'cron_schedules', array( $this, 'schedule_cron_healthcheck' ) );
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Dispatch
|
70 |
-
*
|
71 |
-
* @return mixed dispatch event.
|
72 |
-
*/
|
73 |
-
public function dispatch() {
|
74 |
-
// Schedule the cron healthcheck.
|
75 |
-
$this->schedule_event();
|
76 |
-
|
77 |
-
// Perform remote post.
|
78 |
-
return parent::dispatch();
|
79 |
-
}
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Push to queue
|
83 |
-
*
|
84 |
-
* @param mixed $data Data.
|
85 |
-
*
|
86 |
-
* @return $this
|
87 |
-
*/
|
88 |
-
public function push_to_queue( $data ) {
|
89 |
-
$this->data[] = $data;
|
90 |
-
|
91 |
-
return $this;
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* Save queue
|
96 |
-
*
|
97 |
-
* @return $this
|
98 |
-
*/
|
99 |
-
public function save() {
|
100 |
-
$key = $this->generate_key();
|
101 |
-
|
102 |
-
if ( ! empty( $this->data ) ) {
|
103 |
-
update_site_option( $key, $this->data );
|
104 |
-
}
|
105 |
-
|
106 |
-
return $this;
|
107 |
-
}
|
108 |
-
|
109 |
-
/**
|
110 |
-
* Update queue
|
111 |
-
*
|
112 |
-
* @param string $key Key.
|
113 |
-
* @param array $data Data.
|
114 |
-
*
|
115 |
-
* @return $this
|
116 |
-
*/
|
117 |
-
public function update( $key, $data ) {
|
118 |
-
if ( ! empty( $data ) ) {
|
119 |
-
update_site_option( $key, $data );
|
120 |
-
}
|
121 |
-
|
122 |
-
return $this;
|
123 |
-
}
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Delete queue
|
127 |
-
*
|
128 |
-
* @param string $key Key.
|
129 |
-
*
|
130 |
-
* @return $this
|
131 |
-
*/
|
132 |
-
public function delete( $key ) {
|
133 |
-
delete_site_option( $key );
|
134 |
-
|
135 |
-
return $this;
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* Generate key
|
140 |
-
*
|
141 |
-
* Generates a unique key based on microtime. Queue items are
|
142 |
-
* given a unique key so that they can be merged upon save.
|
143 |
-
*
|
144 |
-
* @param int $length Length.
|
145 |
-
*
|
146 |
-
* @return string
|
147 |
-
*/
|
148 |
-
protected function generate_key( $length = 64 ) {
|
149 |
-
$unique = md5( microtime() . rand() );
|
150 |
-
$prepend = $this->identifier . '_batch_';
|
151 |
-
|
152 |
-
return substr( $prepend . $unique, 0, $length );
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* Maybe process queue
|
157 |
-
*
|
158 |
-
* Checks whether data exists within the queue and that
|
159 |
-
* the process is not already running.
|
160 |
-
*/
|
161 |
-
public function maybe_handle() {
|
162 |
-
// Don't lock up other requests while processing.
|
163 |
-
session_write_close();
|
164 |
-
|
165 |
-
if ( $this->is_process_running() ) {
|
166 |
-
// Background process already running.
|
167 |
-
wp_die();
|
168 |
-
}
|
169 |
-
|
170 |
-
if ( $this->is_queue_empty() ) {
|
171 |
-
// No data to process.
|
172 |
-
wp_die();
|
173 |
-
}
|
174 |
-
|
175 |
-
check_ajax_referer( $this->identifier, 'nonce' );
|
176 |
-
|
177 |
-
$this->handle();
|
178 |
-
|
179 |
-
wp_die();
|
180 |
-
}
|
181 |
-
|
182 |
-
/**
|
183 |
-
* Is queue empty
|
184 |
-
*
|
185 |
-
* @return bool
|
186 |
-
*/
|
187 |
-
protected function is_queue_empty() {
|
188 |
-
global $wpdb;
|
189 |
-
|
190 |
-
$table = $wpdb->options;
|
191 |
-
$column = 'option_name';
|
192 |
-
|
193 |
-
if ( is_multisite() ) {
|
194 |
-
$table = $wpdb->sitemeta;
|
195 |
-
$column = 'meta_key';
|
196 |
-
}
|
197 |
-
|
198 |
-
$key = $this->identifier . '_batch_%';
|
199 |
-
|
200 |
-
$count = $wpdb->get_var(
|
201 |
-
$wpdb->prepare(
|
202 |
-
"
|
203 |
-
SELECT COUNT(*)
|
204 |
-
FROM {$table}
|
205 |
-
WHERE {$column} LIKE %s
|
206 |
-
", $key
|
207 |
-
)
|
208 |
-
);
|
209 |
-
|
210 |
-
return ( $count > 0 ) ? false : true;
|
211 |
-
}
|
212 |
-
|
213 |
-
/**
|
214 |
-
* Is process running
|
215 |
-
*
|
216 |
-
* Check whether the current process is already running
|
217 |
-
* in a background process.
|
218 |
-
*/
|
219 |
-
protected function is_process_running() {
|
220 |
-
if ( get_site_transient( $this->identifier . '_process_lock' ) ) {
|
221 |
-
// Process already running.
|
222 |
-
return true;
|
223 |
-
}
|
224 |
-
|
225 |
-
return false;
|
226 |
-
}
|
227 |
-
|
228 |
-
/**
|
229 |
-
* Lock process
|
230 |
-
*
|
231 |
-
* Lock the process so that multiple instances can't run simultaneously.
|
232 |
-
* Override if applicable, but the duration should be greater than that
|
233 |
-
* defined in the time_exceeded() method.
|
234 |
-
*/
|
235 |
-
protected function lock_process() {
|
236 |
-
$this->start_time = time(); // Set start time of current process.
|
237 |
-
|
238 |
-
$lock_duration = ( property_exists( $this, 'queue_lock_time' ) ) ? $this->queue_lock_time : 60; // 1 minute
|
239 |
-
$lock_duration = apply_filters( $this->identifier . '_queue_lock_time', $lock_duration );
|
240 |
-
|
241 |
-
set_site_transient( $this->identifier . '_process_lock', microtime(), $lock_duration );
|
242 |
-
}
|
243 |
-
|
244 |
-
/**
|
245 |
-
* Unlock process
|
246 |
-
*
|
247 |
-
* Unlock the process so that other instances can spawn.
|
248 |
-
*
|
249 |
-
* @return $this
|
250 |
-
*/
|
251 |
-
protected function unlock_process() {
|
252 |
-
delete_site_transient( $this->identifier . '_process_lock' );
|
253 |
-
|
254 |
-
return $this;
|
255 |
-
}
|
256 |
-
|
257 |
-
/**
|
258 |
-
* Get batch
|
259 |
-
*
|
260 |
-
* @return stdClass Return the first batch from the queue
|
261 |
-
*/
|
262 |
-
protected function get_batch() {
|
263 |
-
global $wpdb;
|
264 |
-
|
265 |
-
$table = $wpdb->options;
|
266 |
-
$column = 'option_name';
|
267 |
-
$key_column = 'option_id';
|
268 |
-
$value_column = 'option_value';
|
269 |
-
|
270 |
-
if ( is_multisite() ) {
|
271 |
-
$table = $wpdb->sitemeta;
|
272 |
-
$column = 'meta_key';
|
273 |
-
$key_column = 'meta_id';
|
274 |
-
$value_column = 'meta_value';
|
275 |
-
}
|
276 |
-
|
277 |
-
$key = $this->identifier . '_batch_%';
|
278 |
-
|
279 |
-
$query = $wpdb->get_row(
|
280 |
-
$wpdb->prepare(
|
281 |
-
"
|
282 |
-
SELECT *
|
283 |
-
FROM {$table}
|
284 |
-
WHERE {$column} LIKE %s
|
285 |
-
ORDER BY {$key_column} ASC
|
286 |
-
LIMIT 1
|
287 |
-
", $key
|
288 |
-
)
|
289 |
-
);
|
290 |
-
|
291 |
-
$batch = new stdClass();
|
292 |
-
$batch->key = $query->$column;
|
293 |
-
$batch->data = maybe_unserialize( $query->$value_column );
|
294 |
-
|
295 |
-
return $batch;
|
296 |
-
}
|
297 |
-
|
298 |
-
/**
|
299 |
-
* Handle
|
300 |
-
*
|
301 |
-
* Pass each queue item to the task handler, while remaining
|
302 |
-
* within server memory and time limit constraints.
|
303 |
-
*/
|
304 |
-
protected function handle() {
|
305 |
-
$this->lock_process();
|
306 |
-
|
307 |
-
do {
|
308 |
-
$batch = $this->get_batch();
|
309 |
-
|
310 |
-
foreach ( $batch->data as $key => $value ) {
|
311 |
-
$task = $this->task( $value );
|
312 |
-
|
313 |
-
if ( false !== $task ) {
|
314 |
-
$batch->data[ $key ] = $task;
|
315 |
-
} else {
|
316 |
-
unset( $batch->data[ $key ] );
|
317 |
-
}
|
318 |
-
|
319 |
-
if ( $this->time_exceeded() || $this->memory_exceeded() ) {
|
320 |
-
// Batch limits reached.
|
321 |
-
break;
|
322 |
-
}
|
323 |
-
}
|
324 |
-
|
325 |
-
// Update or delete current batch.
|
326 |
-
if ( ! empty( $batch->data ) ) {
|
327 |
-
$this->update( $batch->key, $batch->data );
|
328 |
-
} else {
|
329 |
-
$this->delete( $batch->key );
|
330 |
-
}
|
331 |
-
} while ( ! $this->time_exceeded() && ! $this->memory_exceeded() && ! $this->is_queue_empty() );
|
332 |
-
|
333 |
-
$this->unlock_process();
|
334 |
-
|
335 |
-
// Start next batch or complete process.
|
336 |
-
if ( ! $this->is_queue_empty() ) {
|
337 |
-
$this->dispatch();
|
338 |
-
} else {
|
339 |
-
$this->complete();
|
340 |
-
}
|
341 |
-
|
342 |
-
wp_die();
|
343 |
-
}
|
344 |
-
|
345 |
-
/**
|
346 |
-
* Memory exceeded
|
347 |
-
*
|
348 |
-
* Ensures the batch process never exceeds 90%
|
349 |
-
* of the maximum WordPress memory.
|
350 |
-
*
|
351 |
-
* @return bool
|
352 |
-
*/
|
353 |
-
protected function memory_exceeded() {
|
354 |
-
$memory_limit = $this->get_memory_limit() * 0.9; // 90% of max memory
|
355 |
-
$current_memory = memory_get_usage( true );
|
356 |
-
$return = false;
|
357 |
-
|
358 |
-
if ( $current_memory >= $memory_limit ) {
|
359 |
-
$return = true;
|
360 |
-
}
|
361 |
-
|
362 |
-
return apply_filters( $this->identifier . '_memory_exceeded', $return );
|
363 |
-
}
|
364 |
-
|
365 |
-
/**
|
366 |
-
* Get memory limit
|
367 |
-
*
|
368 |
-
* @return int
|
369 |
-
*/
|
370 |
-
protected function get_memory_limit() {
|
371 |
-
if ( function_exists( 'ini_get' ) ) {
|
372 |
-
$memory_limit = ini_get( 'memory_limit' );
|
373 |
-
} else {
|
374 |
-
// Sensible default.
|
375 |
-
$memory_limit = '128M';
|
376 |
-
}
|
377 |
-
|
378 |
-
if ( ! $memory_limit || -1 === $memory_limit ) {
|
379 |
-
// Unlimited, set to 32GB.
|
380 |
-
$memory_limit = '32000M';
|
381 |
-
}
|
382 |
-
|
383 |
-
return intval( $memory_limit ) * 1024 * 1024;
|
384 |
-
}
|
385 |
-
|
386 |
-
/**
|
387 |
-
* Time exceeded.
|
388 |
-
*
|
389 |
-
* Ensures the batch never exceeds a sensible time limit.
|
390 |
-
* A timeout limit of 30s is common on shared hosting.
|
391 |
-
*
|
392 |
-
* @return bool
|
393 |
-
*/
|
394 |
-
protected function time_exceeded() {
|
395 |
-
$finish = $this->start_time + apply_filters( $this->identifier . '_default_time_limit', 20 ); // 20 seconds
|
396 |
-
$return = false;
|
397 |
-
|
398 |
-
if ( time() >= $finish ) {
|
399 |
-
$return = true;
|
400 |
-
}
|
401 |
-
|
402 |
-
return apply_filters( $this->identifier . '_time_exceeded', $return );
|
403 |
-
}
|
404 |
-
|
405 |
-
/**
|
406 |
-
* Complete.
|
407 |
-
*
|
408 |
-
* Override if applicable, but ensure that the below actions are
|
409 |
-
* performed, or, call parent::complete().
|
410 |
-
*/
|
411 |
-
protected function complete() {
|
412 |
-
// Unschedule the cron healthcheck.
|
413 |
-
$this->clear_scheduled_event();
|
414 |
-
}
|
415 |
-
|
416 |
-
/**
|
417 |
-
* Schedule cron healthcheck
|
418 |
-
*
|
419 |
-
* @access public
|
420 |
-
* @param mixed $schedules Schedules.
|
421 |
-
* @return mixed
|
422 |
-
*/
|
423 |
-
public function schedule_cron_healthcheck( $schedules ) {
|
424 |
-
$interval = apply_filters( $this->identifier . '_cron_interval', 5 );
|
425 |
-
|
426 |
-
if ( property_exists( $this, 'cron_interval' ) ) {
|
427 |
-
$interval = apply_filters( $this->identifier . '_cron_interval', $this->cron_interval_identifier );
|
428 |
-
}
|
429 |
-
|
430 |
-
// Adds every 5 minutes to the existing schedules.
|
431 |
-
$schedules[ $this->identifier . '_cron_interval' ] = array(
|
432 |
-
'interval' => MINUTE_IN_SECONDS * $interval,
|
433 |
-
'display' => sprintf( __( 'Every %d Minutes', 'astra-sites' ), $interval ),
|
434 |
-
);
|
435 |
-
|
436 |
-
return $schedules;
|
437 |
-
}
|
438 |
-
|
439 |
-
/**
|
440 |
-
* Handle cron healthcheck
|
441 |
-
*
|
442 |
-
* Restart the background process if not already running
|
443 |
-
* and data exists in the queue.
|
444 |
-
*/
|
445 |
-
public function handle_cron_healthcheck() {
|
446 |
-
if ( $this->is_process_running() ) {
|
447 |
-
// Background process already running.
|
448 |
-
exit;
|
449 |
-
}
|
450 |
-
|
451 |
-
if ( $this->is_queue_empty() ) {
|
452 |
-
// No data to process.
|
453 |
-
$this->clear_scheduled_event();
|
454 |
-
exit;
|
455 |
-
}
|
456 |
-
|
457 |
-
$this->handle();
|
458 |
-
|
459 |
-
exit;
|
460 |
-
}
|
461 |
-
|
462 |
-
/**
|
463 |
-
* Schedule event
|
464 |
-
*/
|
465 |
-
protected function schedule_event() {
|
466 |
-
if ( ! wp_next_scheduled( $this->cron_hook_identifier ) ) {
|
467 |
-
wp_schedule_event( time(), $this->cron_interval_identifier, $this->cron_hook_identifier );
|
468 |
-
}
|
469 |
-
}
|
470 |
-
|
471 |
-
/**
|
472 |
-
* Clear scheduled event
|
473 |
-
*/
|
474 |
-
protected function clear_scheduled_event() {
|
475 |
-
$timestamp = wp_next_scheduled( $this->cron_hook_identifier );
|
476 |
-
|
477 |
-
if ( $timestamp ) {
|
478 |
-
wp_unschedule_event( $timestamp, $this->cron_hook_identifier );
|
479 |
-
}
|
480 |
-
}
|
481 |
-
|
482 |
-
/**
|
483 |
-
* Cancel Process
|
484 |
-
*
|
485 |
-
* Stop processing queue items, clear cronjob and delete batch.
|
486 |
-
*/
|
487 |
-
public function cancel_process() {
|
488 |
-
if ( ! $this->is_queue_empty() ) {
|
489 |
-
$batch = $this->get_batch();
|
490 |
-
|
491 |
-
$this->delete( $batch->key );
|
492 |
-
|
493 |
-
wp_clear_scheduled_hook( $this->cron_hook_identifier );
|
494 |
-
}
|
495 |
-
|
496 |
-
}
|
497 |
-
|
498 |
-
/**
|
499 |
-
* Task
|
500 |
-
*
|
501 |
-
* Override this method to perform any actions required on each
|
502 |
-
* queue item. Return the modified item for further processing
|
503 |
-
* in the next pass through. Or, return false to remove the
|
504 |
-
* item from the queue.
|
505 |
-
*
|
506 |
-
* @param mixed $item Queue item to iterate over.
|
507 |
-
*
|
508 |
-
* @return mixed
|
509 |
-
*/
|
510 |
-
abstract protected function task( $item );
|
511 |
-
|
512 |
-
}
|
513 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WP Background Process
|
4 |
+
*
|
5 |
+
* @see https://github.com/A5hleyRich/wp-background-processing/
|
6 |
+
* @package WP-Background-Processing
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! class_exists( 'WP_Background_Process' ) ) {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Abstract WP_Background_Process class.
|
13 |
+
*
|
14 |
+
* @abstract
|
15 |
+
* @extends WP_Async_Request
|
16 |
+
*/
|
17 |
+
abstract class WP_Background_Process extends WP_Async_Request {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Action
|
21 |
+
*
|
22 |
+
* (default value: 'background_process')
|
23 |
+
*
|
24 |
+
* @var string
|
25 |
+
* @access protected
|
26 |
+
*/
|
27 |
+
protected $action = 'background_process';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Start time of current process.
|
31 |
+
*
|
32 |
+
* (default value: 0)
|
33 |
+
*
|
34 |
+
* @var int
|
35 |
+
* @access protected
|
36 |
+
*/
|
37 |
+
protected $start_time = 0;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Cron_hook_identifier
|
41 |
+
*
|
42 |
+
* @var mixed
|
43 |
+
* @access protected
|
44 |
+
*/
|
45 |
+
protected $cron_hook_identifier;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Cron_interval_identifier
|
49 |
+
*
|
50 |
+
* @var mixed
|
51 |
+
* @access protected
|
52 |
+
*/
|
53 |
+
protected $cron_interval_identifier;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Initiate new background process
|
57 |
+
*/
|
58 |
+
public function __construct() {
|
59 |
+
parent::__construct();
|
60 |
+
|
61 |
+
$this->cron_hook_identifier = $this->identifier . '_cron';
|
62 |
+
$this->cron_interval_identifier = $this->identifier . '_cron_interval';
|
63 |
+
|
64 |
+
add_action( $this->cron_hook_identifier, array( $this, 'handle_cron_healthcheck' ) );
|
65 |
+
add_filter( 'cron_schedules', array( $this, 'schedule_cron_healthcheck' ) );
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Dispatch
|
70 |
+
*
|
71 |
+
* @return mixed dispatch event.
|
72 |
+
*/
|
73 |
+
public function dispatch() {
|
74 |
+
// Schedule the cron healthcheck.
|
75 |
+
$this->schedule_event();
|
76 |
+
|
77 |
+
// Perform remote post.
|
78 |
+
return parent::dispatch();
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Push to queue
|
83 |
+
*
|
84 |
+
* @param mixed $data Data.
|
85 |
+
*
|
86 |
+
* @return $this
|
87 |
+
*/
|
88 |
+
public function push_to_queue( $data ) {
|
89 |
+
$this->data[] = $data;
|
90 |
+
|
91 |
+
return $this;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Save queue
|
96 |
+
*
|
97 |
+
* @return $this
|
98 |
+
*/
|
99 |
+
public function save() {
|
100 |
+
$key = $this->generate_key();
|
101 |
+
|
102 |
+
if ( ! empty( $this->data ) ) {
|
103 |
+
update_site_option( $key, $this->data );
|
104 |
+
}
|
105 |
+
|
106 |
+
return $this;
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Update queue
|
111 |
+
*
|
112 |
+
* @param string $key Key.
|
113 |
+
* @param array $data Data.
|
114 |
+
*
|
115 |
+
* @return $this
|
116 |
+
*/
|
117 |
+
public function update( $key, $data ) {
|
118 |
+
if ( ! empty( $data ) ) {
|
119 |
+
update_site_option( $key, $data );
|
120 |
+
}
|
121 |
+
|
122 |
+
return $this;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Delete queue
|
127 |
+
*
|
128 |
+
* @param string $key Key.
|
129 |
+
*
|
130 |
+
* @return $this
|
131 |
+
*/
|
132 |
+
public function delete( $key ) {
|
133 |
+
delete_site_option( $key );
|
134 |
+
|
135 |
+
return $this;
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Generate key
|
140 |
+
*
|
141 |
+
* Generates a unique key based on microtime. Queue items are
|
142 |
+
* given a unique key so that they can be merged upon save.
|
143 |
+
*
|
144 |
+
* @param int $length Length.
|
145 |
+
*
|
146 |
+
* @return string
|
147 |
+
*/
|
148 |
+
protected function generate_key( $length = 64 ) {
|
149 |
+
$unique = md5( microtime() . rand() );
|
150 |
+
$prepend = $this->identifier . '_batch_';
|
151 |
+
|
152 |
+
return substr( $prepend . $unique, 0, $length );
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Maybe process queue
|
157 |
+
*
|
158 |
+
* Checks whether data exists within the queue and that
|
159 |
+
* the process is not already running.
|
160 |
+
*/
|
161 |
+
public function maybe_handle() {
|
162 |
+
// Don't lock up other requests while processing.
|
163 |
+
session_write_close();
|
164 |
+
|
165 |
+
if ( $this->is_process_running() ) {
|
166 |
+
// Background process already running.
|
167 |
+
wp_die();
|
168 |
+
}
|
169 |
+
|
170 |
+
if ( $this->is_queue_empty() ) {
|
171 |
+
// No data to process.
|
172 |
+
wp_die();
|
173 |
+
}
|
174 |
+
|
175 |
+
check_ajax_referer( $this->identifier, 'nonce' );
|
176 |
+
|
177 |
+
$this->handle();
|
178 |
+
|
179 |
+
wp_die();
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Is queue empty
|
184 |
+
*
|
185 |
+
* @return bool
|
186 |
+
*/
|
187 |
+
protected function is_queue_empty() {
|
188 |
+
global $wpdb;
|
189 |
+
|
190 |
+
$table = $wpdb->options;
|
191 |
+
$column = 'option_name';
|
192 |
+
|
193 |
+
if ( is_multisite() ) {
|
194 |
+
$table = $wpdb->sitemeta;
|
195 |
+
$column = 'meta_key';
|
196 |
+
}
|
197 |
+
|
198 |
+
$key = $this->identifier . '_batch_%';
|
199 |
+
|
200 |
+
$count = $wpdb->get_var(
|
201 |
+
$wpdb->prepare(
|
202 |
+
"
|
203 |
+
SELECT COUNT(*)
|
204 |
+
FROM {$table}
|
205 |
+
WHERE {$column} LIKE %s
|
206 |
+
", $key
|
207 |
+
)
|
208 |
+
);
|
209 |
+
|
210 |
+
return ( $count > 0 ) ? false : true;
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Is process running
|
215 |
+
*
|
216 |
+
* Check whether the current process is already running
|
217 |
+
* in a background process.
|
218 |
+
*/
|
219 |
+
protected function is_process_running() {
|
220 |
+
if ( get_site_transient( $this->identifier . '_process_lock' ) ) {
|
221 |
+
// Process already running.
|
222 |
+
return true;
|
223 |
+
}
|
224 |
+
|
225 |
+
return false;
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Lock process
|
230 |
+
*
|
231 |
+
* Lock the process so that multiple instances can't run simultaneously.
|
232 |
+
* Override if applicable, but the duration should be greater than that
|
233 |
+
* defined in the time_exceeded() method.
|
234 |
+
*/
|
235 |
+
protected function lock_process() {
|
236 |
+
$this->start_time = time(); // Set start time of current process.
|
237 |
+
|
238 |
+
$lock_duration = ( property_exists( $this, 'queue_lock_time' ) ) ? $this->queue_lock_time : 60; // 1 minute
|
239 |
+
$lock_duration = apply_filters( $this->identifier . '_queue_lock_time', $lock_duration );
|
240 |
+
|
241 |
+
set_site_transient( $this->identifier . '_process_lock', microtime(), $lock_duration );
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Unlock process
|
246 |
+
*
|
247 |
+
* Unlock the process so that other instances can spawn.
|
248 |
+
*
|
249 |
+
* @return $this
|
250 |
+
*/
|
251 |
+
protected function unlock_process() {
|
252 |
+
delete_site_transient( $this->identifier . '_process_lock' );
|
253 |
+
|
254 |
+
return $this;
|
255 |
+
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* Get batch
|
259 |
+
*
|
260 |
+
* @return stdClass Return the first batch from the queue
|
261 |
+
*/
|
262 |
+
protected function get_batch() {
|
263 |
+
global $wpdb;
|
264 |
+
|
265 |
+
$table = $wpdb->options;
|
266 |
+
$column = 'option_name';
|
267 |
+
$key_column = 'option_id';
|
268 |
+
$value_column = 'option_value';
|
269 |
+
|
270 |
+
if ( is_multisite() ) {
|
271 |
+
$table = $wpdb->sitemeta;
|
272 |
+
$column = 'meta_key';
|
273 |
+
$key_column = 'meta_id';
|
274 |
+
$value_column = 'meta_value';
|
275 |
+
}
|
276 |
+
|
277 |
+
$key = $this->identifier . '_batch_%';
|
278 |
+
|
279 |
+
$query = $wpdb->get_row(
|
280 |
+
$wpdb->prepare(
|
281 |
+
"
|
282 |
+
SELECT *
|
283 |
+
FROM {$table}
|
284 |
+
WHERE {$column} LIKE %s
|
285 |
+
ORDER BY {$key_column} ASC
|
286 |
+
LIMIT 1
|
287 |
+
", $key
|
288 |
+
)
|
289 |
+
);
|
290 |
+
|
291 |
+
$batch = new stdClass();
|
292 |
+
$batch->key = $query->$column;
|
293 |
+
$batch->data = maybe_unserialize( $query->$value_column );
|
294 |
+
|
295 |
+
return $batch;
|
296 |
+
}
|
297 |
+
|
298 |
+
/**
|
299 |
+
* Handle
|
300 |
+
*
|
301 |
+
* Pass each queue item to the task handler, while remaining
|
302 |
+
* within server memory and time limit constraints.
|
303 |
+
*/
|
304 |
+
protected function handle() {
|
305 |
+
$this->lock_process();
|
306 |
+
|
307 |
+
do {
|
308 |
+
$batch = $this->get_batch();
|
309 |
+
|
310 |
+
foreach ( $batch->data as $key => $value ) {
|
311 |
+
$task = $this->task( $value );
|
312 |
+
|
313 |
+
if ( false !== $task ) {
|
314 |
+
$batch->data[ $key ] = $task;
|
315 |
+
} else {
|
316 |
+
unset( $batch->data[ $key ] );
|
317 |
+
}
|
318 |
+
|
319 |
+
if ( $this->time_exceeded() || $this->memory_exceeded() ) {
|
320 |
+
// Batch limits reached.
|
321 |
+
break;
|
322 |
+
}
|
323 |
+
}
|
324 |
+
|
325 |
+
// Update or delete current batch.
|
326 |
+
if ( ! empty( $batch->data ) ) {
|
327 |
+
$this->update( $batch->key, $batch->data );
|
328 |
+
} else {
|
329 |
+
$this->delete( $batch->key );
|
330 |
+
}
|
331 |
+
} while ( ! $this->time_exceeded() && ! $this->memory_exceeded() && ! $this->is_queue_empty() );
|
332 |
+
|
333 |
+
$this->unlock_process();
|
334 |
+
|
335 |
+
// Start next batch or complete process.
|
336 |
+
if ( ! $this->is_queue_empty() ) {
|
337 |
+
$this->dispatch();
|
338 |
+
} else {
|
339 |
+
$this->complete();
|
340 |
+
}
|
341 |
+
|
342 |
+
wp_die();
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Memory exceeded
|
347 |
+
*
|
348 |
+
* Ensures the batch process never exceeds 90%
|
349 |
+
* of the maximum WordPress memory.
|
350 |
+
*
|
351 |
+
* @return bool
|
352 |
+
*/
|
353 |
+
protected function memory_exceeded() {
|
354 |
+
$memory_limit = $this->get_memory_limit() * 0.9; // 90% of max memory
|
355 |
+
$current_memory = memory_get_usage( true );
|
356 |
+
$return = false;
|
357 |
+
|
358 |
+
if ( $current_memory >= $memory_limit ) {
|
359 |
+
$return = true;
|
360 |
+
}
|
361 |
+
|
362 |
+
return apply_filters( $this->identifier . '_memory_exceeded', $return );
|
363 |
+
}
|
364 |
+
|
365 |
+
/**
|
366 |
+
* Get memory limit
|
367 |
+
*
|
368 |
+
* @return int
|
369 |
+
*/
|
370 |
+
protected function get_memory_limit() {
|
371 |
+
if ( function_exists( 'ini_get' ) ) {
|
372 |
+
$memory_limit = ini_get( 'memory_limit' );
|
373 |
+
} else {
|
374 |
+
// Sensible default.
|
375 |
+
$memory_limit = '128M';
|
376 |
+
}
|
377 |
+
|
378 |
+
if ( ! $memory_limit || -1 === $memory_limit ) {
|
379 |
+
// Unlimited, set to 32GB.
|
380 |
+
$memory_limit = '32000M';
|
381 |
+
}
|
382 |
+
|
383 |
+
return intval( $memory_limit ) * 1024 * 1024;
|
384 |
+
}
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Time exceeded.
|
388 |
+
*
|
389 |
+
* Ensures the batch never exceeds a sensible time limit.
|
390 |
+
* A timeout limit of 30s is common on shared hosting.
|
391 |
+
*
|
392 |
+
* @return bool
|
393 |
+
*/
|
394 |
+
protected function time_exceeded() {
|
395 |
+
$finish = $this->start_time + apply_filters( $this->identifier . '_default_time_limit', 20 ); // 20 seconds
|
396 |
+
$return = false;
|
397 |
+
|
398 |
+
if ( time() >= $finish ) {
|
399 |
+
$return = true;
|
400 |
+
}
|
401 |
+
|
402 |
+
return apply_filters( $this->identifier . '_time_exceeded', $return );
|
403 |
+
}
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Complete.
|
407 |
+
*
|
408 |
+
* Override if applicable, but ensure that the below actions are
|
409 |
+
* performed, or, call parent::complete().
|
410 |
+
*/
|
411 |
+
protected function complete() {
|
412 |
+
// Unschedule the cron healthcheck.
|
413 |
+
$this->clear_scheduled_event();
|
414 |
+
}
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Schedule cron healthcheck
|
418 |
+
*
|
419 |
+
* @access public
|
420 |
+
* @param mixed $schedules Schedules.
|
421 |
+
* @return mixed
|
422 |
+
*/
|
423 |
+
public function schedule_cron_healthcheck( $schedules ) {
|
424 |
+
$interval = apply_filters( $this->identifier . '_cron_interval', 5 );
|
425 |
+
|
426 |
+
if ( property_exists( $this, 'cron_interval' ) ) {
|
427 |
+
$interval = apply_filters( $this->identifier . '_cron_interval', $this->cron_interval_identifier );
|
428 |
+
}
|
429 |
+
|
430 |
+
// Adds every 5 minutes to the existing schedules.
|
431 |
+
$schedules[ $this->identifier . '_cron_interval' ] = array(
|
432 |
+
'interval' => MINUTE_IN_SECONDS * $interval,
|
433 |
+
'display' => sprintf( __( 'Every %d Minutes', 'astra-sites' ), $interval ),
|
434 |
+
);
|
435 |
+
|
436 |
+
return $schedules;
|
437 |
+
}
|
438 |
+
|
439 |
+
/**
|
440 |
+
* Handle cron healthcheck
|
441 |
+
*
|
442 |
+
* Restart the background process if not already running
|
443 |
+
* and data exists in the queue.
|
444 |
+
*/
|
445 |
+
public function handle_cron_healthcheck() {
|
446 |
+
if ( $this->is_process_running() ) {
|
447 |
+
// Background process already running.
|
448 |
+
exit;
|
449 |
+
}
|
450 |
+
|
451 |
+
if ( $this->is_queue_empty() ) {
|
452 |
+
// No data to process.
|
453 |
+
$this->clear_scheduled_event();
|
454 |
+
exit;
|
455 |
+
}
|
456 |
+
|
457 |
+
$this->handle();
|
458 |
+
|
459 |
+
exit;
|
460 |
+
}
|
461 |
+
|
462 |
+
/**
|
463 |
+
* Schedule event
|
464 |
+
*/
|
465 |
+
protected function schedule_event() {
|
466 |
+
if ( ! wp_next_scheduled( $this->cron_hook_identifier ) ) {
|
467 |
+
wp_schedule_event( time(), $this->cron_interval_identifier, $this->cron_hook_identifier );
|
468 |
+
}
|
469 |
+
}
|
470 |
+
|
471 |
+
/**
|
472 |
+
* Clear scheduled event
|
473 |
+
*/
|
474 |
+
protected function clear_scheduled_event() {
|
475 |
+
$timestamp = wp_next_scheduled( $this->cron_hook_identifier );
|
476 |
+
|
477 |
+
if ( $timestamp ) {
|
478 |
+
wp_unschedule_event( $timestamp, $this->cron_hook_identifier );
|
479 |
+
}
|
480 |
+
}
|
481 |
+
|
482 |
+
/**
|
483 |
+
* Cancel Process
|
484 |
+
*
|
485 |
+
* Stop processing queue items, clear cronjob and delete batch.
|
486 |
+
*/
|
487 |
+
public function cancel_process() {
|
488 |
+
if ( ! $this->is_queue_empty() ) {
|
489 |
+
$batch = $this->get_batch();
|
490 |
+
|
491 |
+
$this->delete( $batch->key );
|
492 |
+
|
493 |
+
wp_clear_scheduled_hook( $this->cron_hook_identifier );
|
494 |
+
}
|
495 |
+
|
496 |
+
}
|
497 |
+
|
498 |
+
/**
|
499 |
+
* Task
|
500 |
+
*
|
501 |
+
* Override this method to perform any actions required on each
|
502 |
+
* queue item. Return the modified item for further processing
|
503 |
+
* in the next pass through. Or, return false to remove the
|
504 |
+
* item from the queue.
|
505 |
+
*
|
506 |
+
* @param mixed $item Queue item to iterate over.
|
507 |
+
*
|
508 |
+
* @return mixed
|
509 |
+
*/
|
510 |
+
abstract protected function task( $item );
|
511 |
+
|
512 |
+
}
|
513 |
+
}
|
inc/importers/class-widgets-importer.php
CHANGED
@@ -1,278 +1,278 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Widget Data exporter class.
|
4 |
-
*
|
5 |
-
* @package Astra Addon
|
6 |
-
* @see - https://wordpress.org/plugins/widget-importer-exporter/
|
7 |
-
*/
|
8 |
-
|
9 |
-
defined( 'ABSPATH' ) or exit;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Widget Data exporter class.
|
13 |
-
*
|
14 |
-
* @see - https://wordpress.org/plugins/widget-importer-exporter/
|
15 |
-
*/
|
16 |
-
class Astra_Widget_Importer {
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Instance of Astra_Widget_Importer
|
20 |
-
*
|
21 |
-
* @var Astra_Widget_Importer
|
22 |
-
*/
|
23 |
-
private static $_instance = null;
|
24 |
-
|
25 |
-
public static function instance() {
|
26 |
-
|
27 |
-
if ( ! isset( self::$_instance ) ) {
|
28 |
-
self::$_instance = new self;
|
29 |
-
}
|
30 |
-
|
31 |
-
return self::$_instance;
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Available widgets
|
36 |
-
*
|
37 |
-
* Gather site's widgets into array with ID base, name, etc.
|
38 |
-
* Used by export and import functions.
|
39 |
-
*
|
40 |
-
* @since 0.4
|
41 |
-
* @global array $wp_registered_widget_updates
|
42 |
-
* @return array Widget information
|
43 |
-
*/
|
44 |
-
function wie_available_widgets() {
|
45 |
-
|
46 |
-
global $wp_registered_widget_controls;
|
47 |
-
|
48 |
-
$widget_controls = $wp_registered_widget_controls;
|
49 |
-
|
50 |
-
$available_widgets = array();
|
51 |
-
|
52 |
-
foreach ( $widget_controls as $widget ) {
|
53 |
-
|
54 |
-
if ( ! empty( $widget['id_base'] ) && ! isset( $available_widgets[ $widget['id_base'] ] ) ) { // no dupes
|
55 |
-
|
56 |
-
$available_widgets[ $widget['id_base'] ]['id_base'] = $widget['id_base'];
|
57 |
-
$available_widgets[ $widget['id_base'] ]['name'] = $widget['name'];
|
58 |
-
|
59 |
-
}
|
60 |
-
}
|
61 |
-
|
62 |
-
return apply_filters( 'wie_available_widgets', $available_widgets );
|
63 |
-
}
|
64 |
-
|
65 |
-
/**
|
66 |
-
* Import widget JSON data
|
67 |
-
*
|
68 |
-
* @since 0.4
|
69 |
-
* @global array $wp_registered_sidebars
|
70 |
-
*
|
71 |
-
* @param object $data JSON widget data from .wie file
|
72 |
-
*
|
73 |
-
* @return array Results array
|
74 |
-
*/
|
75 |
-
function import_widgets_data( $data ) {
|
76 |
-
|
77 |
-
global $wp_registered_sidebars;
|
78 |
-
|
79 |
-
// Have valid data?
|
80 |
-
// If no data or could not decode
|
81 |
-
if ( empty( $data ) || ! is_object( $data ) ) {
|
82 |
-
wp_die(
|
83 |
-
esc_html__( 'Import data could not be read. Please try a different file.', 'astra-sites' ),
|
84 |
-
'',
|
85 |
-
array(
|
86 |
-
'back_link' => true,
|
87 |
-
)
|
88 |
-
);
|
89 |
-
}
|
90 |
-
|
91 |
-
// Hook before import
|
92 |
-
do_action( 'wie_before_import' );
|
93 |
-
$data = apply_filters( 'wie_import_data', $data );
|
94 |
-
|
95 |
-
// Get all available widgets site supports
|
96 |
-
$available_widgets = $this->wie_available_widgets();
|
97 |
-
|
98 |
-
// Get all existing widget instances
|
99 |
-
$widget_instances = array();
|
100 |
-
foreach ( $available_widgets as $widget_data ) {
|
101 |
-
$widget_instances[ $widget_data['id_base'] ] = get_option( 'widget_' . $widget_data['id_base'] );
|
102 |
-
}
|
103 |
-
|
104 |
-
// Begin results
|
105 |
-
$results = array();
|
106 |
-
|
107 |
-
// Loop import data's sidebars
|
108 |
-
foreach ( $data as $sidebar_id => $widgets ) {
|
109 |
-
|
110 |
-
// Skip inactive widgets
|
111 |
-
// (should not be in export file)
|
112 |
-
if ( 'wp_inactive_widgets' == $sidebar_id ) {
|
113 |
-
continue;
|
114 |
-
}
|
115 |
-
|
116 |
-
// Check if sidebar is available on this site
|
117 |
-
// Otherwise add widgets to inactive, and say so
|
118 |
-
if ( isset( $wp_registered_sidebars[ $sidebar_id ] ) ) {
|
119 |
-
$sidebar_available = true;
|
120 |
-
$use_sidebar_id = $sidebar_id;
|
121 |
-
$sidebar_message_type = 'success';
|
122 |
-
$sidebar_message = '';
|
123 |
-
} else {
|
124 |
-
$sidebar_available = false;
|
125 |
-
$use_sidebar_id = 'wp_inactive_widgets'; // add to inactive if sidebar does not exist in theme
|
126 |
-
$sidebar_message_type = 'error';
|
127 |
-
$sidebar_message = esc_html__( 'Widget area does not exist in theme (using Inactive)', 'astra-sites' );
|
128 |
-
}
|
129 |
-
|
130 |
-
// Result for sidebar
|
131 |
-
$results[ $sidebar_id ]['name'] = ! empty( $wp_registered_sidebars[ $sidebar_id ]['name'] ) ? $wp_registered_sidebars[ $sidebar_id ]['name'] : $sidebar_id; // sidebar name if theme supports it; otherwise ID
|
132 |
-
$results[ $sidebar_id ]['message_type'] = $sidebar_message_type;
|
133 |
-
$results[ $sidebar_id ]['message'] = $sidebar_message;
|
134 |
-
$results[ $sidebar_id ]['widgets'] = array();
|
135 |
-
|
136 |
-
// Loop widgets
|
137 |
-
foreach ( $widgets as $widget_instance_id => $widget ) {
|
138 |
-
|
139 |
-
$fail = false;
|
140 |
-
|
141 |
-
// Get id_base (remove -# from end) and instance ID number
|
142 |
-
$id_base = preg_replace( '/-[0-9]+$/', '', $widget_instance_id );
|
143 |
-
$instance_id_number = str_replace( $id_base . '-', '', $widget_instance_id );
|
144 |
-
|
145 |
-
// Does site support this widget?
|
146 |
-
if ( ! $fail && ! isset( $available_widgets[ $id_base ] ) ) {
|
147 |
-
$fail = true;
|
148 |
-
$widget_message_type = 'error';
|
149 |
-
$widget_message = esc_html__( 'Site does not support widget', 'astra-sites' ); // explain why widget not imported
|
150 |
-
}
|
151 |
-
|
152 |
-
// Filter to modify settings object before conversion to array and import
|
153 |
-
// Leave this filter here for backwards compatibility with manipulating objects (before conversion to array below)
|
154 |
-
// Ideally the newer wie_widget_settings_array below will be used instead of this
|
155 |
-
$widget = apply_filters( 'wie_widget_settings', $widget ); // object
|
156 |
-
|
157 |
-
// Convert multidimensional objects to multidimensional arrays
|
158 |
-
// Some plugins like Jetpack Widget Visibility store settings as multidimensional arrays
|
159 |
-
// Without this, they are imported as objects and cause fatal error on Widgets page
|
160 |
-
// If this creates problems for plugins that do actually intend settings in objects then may need to consider other approach: https://wordpress.org/support/topic/problem-with-array-of-arrays
|
161 |
-
// It is probably much more likely that arrays are used than objects, however
|
162 |
-
$widget = json_decode( wp_json_encode( $widget ), true );
|
163 |
-
|
164 |
-
// Filter to modify settings array
|
165 |
-
// This is preferred over the older wie_widget_settings filter above
|
166 |
-
// Do before identical check because changes may make it identical to end result (such as URL replacements)
|
167 |
-
$widget = apply_filters( 'wie_widget_settings_array', $widget );
|
168 |
-
|
169 |
-
// Does widget with identical settings already exist in same sidebar?
|
170 |
-
if ( ! $fail && isset( $widget_instances[ $id_base ] ) ) {
|
171 |
-
|
172 |
-
// Get existing widgets in this sidebar
|
173 |
-
$sidebars_widgets = get_option( 'sidebars_widgets' );
|
174 |
-
$sidebar_widgets = isset( $sidebars_widgets[ $use_sidebar_id ] ) ? $sidebars_widgets[ $use_sidebar_id ] : array(); // check Inactive if that's where will go
|
175 |
-
|
176 |
-
// Loop widgets with ID base
|
177 |
-
$single_widget_instances = ! empty( $widget_instances[ $id_base ] ) ? $widget_instances[ $id_base ] : array();
|
178 |
-
foreach ( $single_widget_instances as $check_id => $check_widget ) {
|
179 |
-
|
180 |
-
// Is widget in same sidebar and has identical settings?
|
181 |
-
if ( in_array( "$id_base-$check_id", $sidebar_widgets ) && (array) $widget == $check_widget ) {
|
182 |
-
|
183 |
-
$fail = true;
|
184 |
-
$widget_message_type = 'warning';
|
185 |
-
$widget_message = esc_html__( 'Widget already exists', 'astra-sites' ); // explain why widget not imported
|
186 |
-
|
187 |
-
break;
|
188 |
-
|
189 |
-
}
|
190 |
-
}
|
191 |
-
}
|
192 |
-
|
193 |
-
// No failure
|
194 |
-
if ( ! $fail ) {
|
195 |
-
|
196 |
-
// Add widget instance
|
197 |
-
$single_widget_instances = get_option( 'widget_' . $id_base ); // all instances for that widget ID base, get fresh every time
|
198 |
-
$single_widget_instances = ! empty( $single_widget_instances ) ? $single_widget_instances : array(
|
199 |
-
'_multiwidget' => 1,
|
200 |
-
); // start fresh if have to
|
201 |
-
$single_widget_instances[] = $widget; // add it
|
202 |
-
|
203 |
-
// Get the key it was given
|
204 |
-
end( $single_widget_instances );
|
205 |
-
$new_instance_id_number = key( $single_widget_instances );
|
206 |
-
|
207 |
-
// If key is 0, make it 1
|
208 |
-
// When 0, an issue can occur where adding a widget causes data from other widget to load, and the widget doesn't stick (reload wipes it)
|
209 |
-
if ( '0' === strval( $new_instance_id_number ) ) {
|
210 |
-
$new_instance_id_number = 1;
|
211 |
-
$single_widget_instances[ $new_instance_id_number ] = $single_widget_instances[0];
|
212 |
-
unset( $single_widget_instances[0] );
|
213 |
-
}
|
214 |
-
|
215 |
-
// Move _multiwidget to end of array for uniformity
|
216 |
-
if ( isset( $single_widget_instances['_multiwidget'] ) ) {
|
217 |
-
$multiwidget = $single_widget_instances['_multiwidget'];
|
218 |
-
unset( $single_widget_instances['_multiwidget'] );
|
219 |
-
$single_widget_instances['_multiwidget'] = $multiwidget;
|
220 |
-
}
|
221 |
-
|
222 |
-
// Update option with new widget
|
223 |
-
$result = update_option( 'widget_' . $id_base, $single_widget_instances );
|
224 |
-
|
225 |
-
// Assign widget instance to sidebar
|
226 |
-
$sidebars_widgets = get_option( 'sidebars_widgets' ); // which sidebars have which widgets, get fresh every time
|
227 |
-
|
228 |
-
// Avoid rarely fatal error when the option is an empty string
|
229 |
-
// https://github.com/churchthemes/widget-importer-exporter/pull/11
|
230 |
-
if ( ! $sidebars_widgets ) {
|
231 |
-
$sidebars_widgets = array();
|
232 |
-
}
|
233 |
-
|
234 |
-
$new_instance_id = $id_base . '-' . $new_instance_id_number; // use ID number from new widget instance
|
235 |
-
$sidebars_widgets[ $use_sidebar_id ][] = $new_instance_id; // add new instance to sidebar
|
236 |
-
update_option( 'sidebars_widgets', $sidebars_widgets ); // save the amended data
|
237 |
-
|
238 |
-
// After widget import action
|
239 |
-
$after_widget_import = array(
|
240 |
-
'sidebar' => $use_sidebar_id,
|
241 |
-
'sidebar_old' => $sidebar_id,
|
242 |
-
'widget' => $widget,
|
243 |
-
'widget_type' => $id_base,
|
244 |
-
'widget_id' => $new_instance_id,
|
245 |
-
'widget_id_old' => $widget_instance_id,
|
246 |
-
'widget_id_num' => $new_instance_id_number,
|
247 |
-
'widget_id_num_old' => $instance_id_number,
|
248 |
-
);
|
249 |
-
do_action( 'wie_after_widget_import', $after_widget_import );
|
250 |
-
|
251 |
-
// Success message
|
252 |
-
if ( $sidebar_available ) {
|
253 |
-
$widget_message_type = 'success';
|
254 |
-
$widget_message = esc_html__( 'Imported', 'astra-sites' );
|
255 |
-
} else {
|
256 |
-
$widget_message_type = 'warning';
|
257 |
-
$widget_message = esc_html__( 'Imported to Inactive', 'astra-sites' );
|
258 |
-
}
|
259 |
-
}// End if().
|
260 |
-
|
261 |
-
// Result for widget instance
|
262 |
-
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['name'] = isset( $available_widgets[ $id_base ]['name'] ) ? $available_widgets[ $id_base ]['name'] : $id_base; // widget name or ID if name not available (not supported by site)
|
263 |
-
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['title'] = ! empty( $widget['title'] ) ? $widget['title'] : esc_html__( 'No Title', 'astra-sites' ); // show "No Title" if widget instance is untitled
|
264 |
-
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['message_type'] = $widget_message_type;
|
265 |
-
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['message'] = $widget_message;
|
266 |
-
|
267 |
-
}// End foreach().
|
268 |
-
}// End foreach().
|
269 |
-
|
270 |
-
// Hook after import
|
271 |
-
do_action( 'wie_after_import' );
|
272 |
-
|
273 |
-
// Return results
|
274 |
-
return apply_filters( 'wie_import_results', $results );
|
275 |
-
|
276 |
-
}
|
277 |
-
|
278 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Widget Data exporter class.
|
4 |
+
*
|
5 |
+
* @package Astra Addon
|
6 |
+
* @see - https://wordpress.org/plugins/widget-importer-exporter/
|
7 |
+
*/
|
8 |
+
|
9 |
+
defined( 'ABSPATH' ) or exit;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Widget Data exporter class.
|
13 |
+
*
|
14 |
+
* @see - https://wordpress.org/plugins/widget-importer-exporter/
|
15 |
+
*/
|
16 |
+
class Astra_Widget_Importer {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Instance of Astra_Widget_Importer
|
20 |
+
*
|
21 |
+
* @var Astra_Widget_Importer
|
22 |
+
*/
|
23 |
+
private static $_instance = null;
|
24 |
+
|
25 |
+
public static function instance() {
|
26 |
+
|
27 |
+
if ( ! isset( self::$_instance ) ) {
|
28 |
+
self::$_instance = new self;
|
29 |
+
}
|
30 |
+
|
31 |
+
return self::$_instance;
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Available widgets
|
36 |
+
*
|
37 |
+
* Gather site's widgets into array with ID base, name, etc.
|
38 |
+
* Used by export and import functions.
|
39 |
+
*
|
40 |
+
* @since 0.4
|
41 |
+
* @global array $wp_registered_widget_updates
|
42 |
+
* @return array Widget information
|
43 |
+
*/
|
44 |
+
function wie_available_widgets() {
|
45 |
+
|
46 |
+
global $wp_registered_widget_controls;
|
47 |
+
|
48 |
+
$widget_controls = $wp_registered_widget_controls;
|
49 |
+
|
50 |
+
$available_widgets = array();
|
51 |
+
|
52 |
+
foreach ( $widget_controls as $widget ) {
|
53 |
+
|
54 |
+
if ( ! empty( $widget['id_base'] ) && ! isset( $available_widgets[ $widget['id_base'] ] ) ) { // no dupes
|
55 |
+
|
56 |
+
$available_widgets[ $widget['id_base'] ]['id_base'] = $widget['id_base'];
|
57 |
+
$available_widgets[ $widget['id_base'] ]['name'] = $widget['name'];
|
58 |
+
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
return apply_filters( 'wie_available_widgets', $available_widgets );
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Import widget JSON data
|
67 |
+
*
|
68 |
+
* @since 0.4
|
69 |
+
* @global array $wp_registered_sidebars
|
70 |
+
*
|
71 |
+
* @param object $data JSON widget data from .wie file
|
72 |
+
*
|
73 |
+
* @return array Results array
|
74 |
+
*/
|
75 |
+
function import_widgets_data( $data ) {
|
76 |
+
|
77 |
+
global $wp_registered_sidebars;
|
78 |
+
|
79 |
+
// Have valid data?
|
80 |
+
// If no data or could not decode
|
81 |
+
if ( empty( $data ) || ! is_object( $data ) ) {
|
82 |
+
wp_die(
|
83 |
+
esc_html__( 'Import data could not be read. Please try a different file.', 'astra-sites' ),
|
84 |
+
'',
|
85 |
+
array(
|
86 |
+
'back_link' => true,
|
87 |
+
)
|
88 |
+
);
|
89 |
+
}
|
90 |
+
|
91 |
+
// Hook before import
|
92 |
+
do_action( 'wie_before_import' );
|
93 |
+
$data = apply_filters( 'wie_import_data', $data );
|
94 |
+
|
95 |
+
// Get all available widgets site supports
|
96 |
+
$available_widgets = $this->wie_available_widgets();
|
97 |
+
|
98 |
+
// Get all existing widget instances
|
99 |
+
$widget_instances = array();
|
100 |
+
foreach ( $available_widgets as $widget_data ) {
|
101 |
+
$widget_instances[ $widget_data['id_base'] ] = get_option( 'widget_' . $widget_data['id_base'] );
|
102 |
+
}
|
103 |
+
|
104 |
+
// Begin results
|
105 |
+
$results = array();
|
106 |
+
|
107 |
+
// Loop import data's sidebars
|
108 |
+
foreach ( $data as $sidebar_id => $widgets ) {
|
109 |
+
|
110 |
+
// Skip inactive widgets
|
111 |
+
// (should not be in export file)
|
112 |
+
if ( 'wp_inactive_widgets' == $sidebar_id ) {
|
113 |
+
continue;
|
114 |
+
}
|
115 |
+
|
116 |
+
// Check if sidebar is available on this site
|
117 |
+
// Otherwise add widgets to inactive, and say so
|
118 |
+
if ( isset( $wp_registered_sidebars[ $sidebar_id ] ) ) {
|
119 |
+
$sidebar_available = true;
|
120 |
+
$use_sidebar_id = $sidebar_id;
|
121 |
+
$sidebar_message_type = 'success';
|
122 |
+
$sidebar_message = '';
|
123 |
+
} else {
|
124 |
+
$sidebar_available = false;
|
125 |
+
$use_sidebar_id = 'wp_inactive_widgets'; // add to inactive if sidebar does not exist in theme
|
126 |
+
$sidebar_message_type = 'error';
|
127 |
+
$sidebar_message = esc_html__( 'Widget area does not exist in theme (using Inactive)', 'astra-sites' );
|
128 |
+
}
|
129 |
+
|
130 |
+
// Result for sidebar
|
131 |
+
$results[ $sidebar_id ]['name'] = ! empty( $wp_registered_sidebars[ $sidebar_id ]['name'] ) ? $wp_registered_sidebars[ $sidebar_id ]['name'] : $sidebar_id; // sidebar name if theme supports it; otherwise ID
|
132 |
+
$results[ $sidebar_id ]['message_type'] = $sidebar_message_type;
|
133 |
+
$results[ $sidebar_id ]['message'] = $sidebar_message;
|
134 |
+
$results[ $sidebar_id ]['widgets'] = array();
|
135 |
+
|
136 |
+
// Loop widgets
|
137 |
+
foreach ( $widgets as $widget_instance_id => $widget ) {
|
138 |
+
|
139 |
+
$fail = false;
|
140 |
+
|
141 |
+
// Get id_base (remove -# from end) and instance ID number
|
142 |
+
$id_base = preg_replace( '/-[0-9]+$/', '', $widget_instance_id );
|
143 |
+
$instance_id_number = str_replace( $id_base . '-', '', $widget_instance_id );
|
144 |
+
|
145 |
+
// Does site support this widget?
|
146 |
+
if ( ! $fail && ! isset( $available_widgets[ $id_base ] ) ) {
|
147 |
+
$fail = true;
|
148 |
+
$widget_message_type = 'error';
|
149 |
+
$widget_message = esc_html__( 'Site does not support widget', 'astra-sites' ); // explain why widget not imported
|
150 |
+
}
|
151 |
+
|
152 |
+
// Filter to modify settings object before conversion to array and import
|
153 |
+
// Leave this filter here for backwards compatibility with manipulating objects (before conversion to array below)
|
154 |
+
// Ideally the newer wie_widget_settings_array below will be used instead of this
|
155 |
+
$widget = apply_filters( 'wie_widget_settings', $widget ); // object
|
156 |
+
|
157 |
+
// Convert multidimensional objects to multidimensional arrays
|
158 |
+
// Some plugins like Jetpack Widget Visibility store settings as multidimensional arrays
|
159 |
+
// Without this, they are imported as objects and cause fatal error on Widgets page
|
160 |
+
// If this creates problems for plugins that do actually intend settings in objects then may need to consider other approach: https://wordpress.org/support/topic/problem-with-array-of-arrays
|
161 |
+
// It is probably much more likely that arrays are used than objects, however
|
162 |
+
$widget = json_decode( wp_json_encode( $widget ), true );
|
163 |
+
|
164 |
+
// Filter to modify settings array
|
165 |
+
// This is preferred over the older wie_widget_settings filter above
|
166 |
+
// Do before identical check because changes may make it identical to end result (such as URL replacements)
|
167 |
+
$widget = apply_filters( 'wie_widget_settings_array', $widget );
|
168 |
+
|
169 |
+
// Does widget with identical settings already exist in same sidebar?
|
170 |
+
if ( ! $fail && isset( $widget_instances[ $id_base ] ) ) {
|
171 |
+
|
172 |
+
// Get existing widgets in this sidebar
|
173 |
+
$sidebars_widgets = get_option( 'sidebars_widgets' );
|
174 |
+
$sidebar_widgets = isset( $sidebars_widgets[ $use_sidebar_id ] ) ? $sidebars_widgets[ $use_sidebar_id ] : array(); // check Inactive if that's where will go
|
175 |
+
|
176 |
+
// Loop widgets with ID base
|
177 |
+
$single_widget_instances = ! empty( $widget_instances[ $id_base ] ) ? $widget_instances[ $id_base ] : array();
|
178 |
+
foreach ( $single_widget_instances as $check_id => $check_widget ) {
|
179 |
+
|
180 |
+
// Is widget in same sidebar and has identical settings?
|
181 |
+
if ( in_array( "$id_base-$check_id", $sidebar_widgets ) && (array) $widget == $check_widget ) {
|
182 |
+
|
183 |
+
$fail = true;
|
184 |
+
$widget_message_type = 'warning';
|
185 |
+
$widget_message = esc_html__( 'Widget already exists', 'astra-sites' ); // explain why widget not imported
|
186 |
+
|
187 |
+
break;
|
188 |
+
|
189 |
+
}
|
190 |
+
}
|
191 |
+
}
|
192 |
+
|
193 |
+
// No failure
|
194 |
+
if ( ! $fail ) {
|
195 |
+
|
196 |
+
// Add widget instance
|
197 |
+
$single_widget_instances = get_option( 'widget_' . $id_base ); // all instances for that widget ID base, get fresh every time
|
198 |
+
$single_widget_instances = ! empty( $single_widget_instances ) ? $single_widget_instances : array(
|
199 |
+
'_multiwidget' => 1,
|
200 |
+
); // start fresh if have to
|
201 |
+
$single_widget_instances[] = $widget; // add it
|
202 |
+
|
203 |
+
// Get the key it was given
|
204 |
+
end( $single_widget_instances );
|
205 |
+
$new_instance_id_number = key( $single_widget_instances );
|
206 |
+
|
207 |
+
// If key is 0, make it 1
|
208 |
+
// When 0, an issue can occur where adding a widget causes data from other widget to load, and the widget doesn't stick (reload wipes it)
|
209 |
+
if ( '0' === strval( $new_instance_id_number ) ) {
|
210 |
+
$new_instance_id_number = 1;
|
211 |
+
$single_widget_instances[ $new_instance_id_number ] = $single_widget_instances[0];
|
212 |
+
unset( $single_widget_instances[0] );
|
213 |
+
}
|
214 |
+
|
215 |
+
// Move _multiwidget to end of array for uniformity
|
216 |
+
if ( isset( $single_widget_instances['_multiwidget'] ) ) {
|
217 |
+
$multiwidget = $single_widget_instances['_multiwidget'];
|
218 |
+
unset( $single_widget_instances['_multiwidget'] );
|
219 |
+
$single_widget_instances['_multiwidget'] = $multiwidget;
|
220 |
+
}
|
221 |
+
|
222 |
+
// Update option with new widget
|
223 |
+
$result = update_option( 'widget_' . $id_base, $single_widget_instances );
|
224 |
+
|
225 |
+
// Assign widget instance to sidebar
|
226 |
+
$sidebars_widgets = get_option( 'sidebars_widgets' ); // which sidebars have which widgets, get fresh every time
|
227 |
+
|
228 |
+
// Avoid rarely fatal error when the option is an empty string
|
229 |
+
// https://github.com/churchthemes/widget-importer-exporter/pull/11
|
230 |
+
if ( ! $sidebars_widgets ) {
|
231 |
+
$sidebars_widgets = array();
|
232 |
+
}
|
233 |
+
|
234 |
+
$new_instance_id = $id_base . '-' . $new_instance_id_number; // use ID number from new widget instance
|
235 |
+
$sidebars_widgets[ $use_sidebar_id ][] = $new_instance_id; // add new instance to sidebar
|
236 |
+
update_option( 'sidebars_widgets', $sidebars_widgets ); // save the amended data
|
237 |
+
|
238 |
+
// After widget import action
|
239 |
+
$after_widget_import = array(
|
240 |
+
'sidebar' => $use_sidebar_id,
|
241 |
+
'sidebar_old' => $sidebar_id,
|
242 |
+
'widget' => $widget,
|
243 |
+
'widget_type' => $id_base,
|
244 |
+
'widget_id' => $new_instance_id,
|
245 |
+
'widget_id_old' => $widget_instance_id,
|
246 |
+
'widget_id_num' => $new_instance_id_number,
|
247 |
+
'widget_id_num_old' => $instance_id_number,
|
248 |
+
);
|
249 |
+
do_action( 'wie_after_widget_import', $after_widget_import );
|
250 |
+
|
251 |
+
// Success message
|
252 |
+
if ( $sidebar_available ) {
|
253 |
+
$widget_message_type = 'success';
|
254 |
+
$widget_message = esc_html__( 'Imported', 'astra-sites' );
|
255 |
+
} else {
|
256 |
+
$widget_message_type = 'warning';
|
257 |
+
$widget_message = esc_html__( 'Imported to Inactive', 'astra-sites' );
|
258 |
+
}
|
259 |
+
}// End if().
|
260 |
+
|
261 |
+
// Result for widget instance
|
262 |
+
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['name'] = isset( $available_widgets[ $id_base ]['name'] ) ? $available_widgets[ $id_base ]['name'] : $id_base; // widget name or ID if name not available (not supported by site)
|
263 |
+
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['title'] = ! empty( $widget['title'] ) ? $widget['title'] : esc_html__( 'No Title', 'astra-sites' ); // show "No Title" if widget instance is untitled
|
264 |
+
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['message_type'] = $widget_message_type;
|
265 |
+
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['message'] = $widget_message;
|
266 |
+
|
267 |
+
}// End foreach().
|
268 |
+
}// End foreach().
|
269 |
+
|
270 |
+
// Hook after import
|
271 |
+
do_action( 'wie_after_import' );
|
272 |
+
|
273 |
+
// Return results
|
274 |
+
return apply_filters( 'wie_import_results', $results );
|
275 |
+
|
276 |
+
}
|
277 |
+
|
278 |
+
}
|
inc/importers/wxr-importer/class-logger.php
CHANGED
@@ -1,139 +1,139 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Describes a logger instance
|
5 |
-
*
|
6 |
-
* Based on PSR-3: http://www.php-fig.org/psr/psr-3/
|
7 |
-
*
|
8 |
-
* The message MUST be a string or object implementing __toString().
|
9 |
-
*
|
10 |
-
* The message MAY contain placeholders in the form: {foo} where foo
|
11 |
-
* will be replaced by the context data in key "foo".
|
12 |
-
*
|
13 |
-
* The context array can contain arbitrary data, the only assumption that
|
14 |
-
* can be made by implementors is that if an Exception instance is given
|
15 |
-
* to produce a stack trace, it MUST be in a key named "exception".
|
16 |
-
*
|
17 |
-
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
|
18 |
-
* for the full interface specification.
|
19 |
-
*/
|
20 |
-
if( ! class_exists( 'WP_Importer_Logger' ) ) :
|
21 |
-
class WP_Importer_Logger {
|
22 |
-
/**
|
23 |
-
* System is unusable.
|
24 |
-
*
|
25 |
-
* @param string $message
|
26 |
-
* @param array $context
|
27 |
-
* @return null
|
28 |
-
*/
|
29 |
-
public function emergency( $message, array $context = array() ) {
|
30 |
-
return $this->log( 'emergency', $message, $context );
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Action must be taken immediately.
|
35 |
-
*
|
36 |
-
* Example: Entire website down, database unavailable, etc. This should
|
37 |
-
* trigger the SMS alerts and wake you up.
|
38 |
-
*
|
39 |
-
* @param string $message
|
40 |
-
* @param array $context
|
41 |
-
* @return null
|
42 |
-
*/
|
43 |
-
public function alert( $message, array $context = array() ) {
|
44 |
-
return $this->log( 'alert', $message, $context );
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Critical conditions.
|
49 |
-
*
|
50 |
-
* Example: Application component unavailable, unexpected exception.
|
51 |
-
*
|
52 |
-
* @param string $message
|
53 |
-
* @param array $context
|
54 |
-
* @return null
|
55 |
-
*/
|
56 |
-
public function critical( $message, array $context = array() ) {
|
57 |
-
return $this->log( 'critical', $message, $context );
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Runtime errors that do not require immediate action but should typically
|
62 |
-
* be logged and monitored.
|
63 |
-
*
|
64 |
-
* @param string $message
|
65 |
-
* @param array $context
|
66 |
-
* @return null
|
67 |
-
*/
|
68 |
-
public function error( $message, array $context = array() ) {
|
69 |
-
return $this->log( 'error', $message, $context );
|
70 |
-
}
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Exceptional occurrences that are not errors.
|
74 |
-
*
|
75 |
-
* Example: Use of deprecated APIs, poor use of an API, undesirable things
|
76 |
-
* that are not necessarily wrong.
|
77 |
-
*
|
78 |
-
* @param string $message
|
79 |
-
* @param array $context
|
80 |
-
* @return null
|
81 |
-
*/
|
82 |
-
public function warning( $message, array $context = array() ) {
|
83 |
-
return $this->log( 'warning', $message, $context );
|
84 |
-
}
|
85 |
-
|
86 |
-
/**
|
87 |
-
* Normal but significant events.
|
88 |
-
*
|
89 |
-
* @param string $message
|
90 |
-
* @param array $context
|
91 |
-
* @return null
|
92 |
-
*/
|
93 |
-
public function notice( $message, array $context = array() ) {
|
94 |
-
return $this->log( 'notice', $message, $context );
|
95 |
-
}
|
96 |
-
|
97 |
-
/**
|
98 |
-
* Interesting events.
|
99 |
-
*
|
100 |
-
* Example: User logs in, SQL logs.
|
101 |
-
*
|
102 |
-
* @param string $message
|
103 |
-
* @param array $context
|
104 |
-
* @return null
|
105 |
-
*/
|
106 |
-
public function info( $message, array $context = array() ) {
|
107 |
-
return $this->log( 'info', $message, $context );
|
108 |
-
}
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Detailed debug information.
|
112 |
-
*
|
113 |
-
* @param string $message
|
114 |
-
* @param array $context
|
115 |
-
* @return null
|
116 |
-
*/
|
117 |
-
public function debug( $message, array $context = array() ) {
|
118 |
-
return $this->log( 'debug', $message, $context );
|
119 |
-
}
|
120 |
-
|
121 |
-
/**
|
122 |
-
* Logs with an arbitrary level.
|
123 |
-
*
|
124 |
-
* @param mixed $level
|
125 |
-
* @param string $message
|
126 |
-
* @param array $context
|
127 |
-
* @return null
|
128 |
-
*/
|
129 |
-
public function log( $level, $message, array $context = array() ) {
|
130 |
-
|
131 |
-
$this->messages[] = array(
|
132 |
-
'timestamp' => time(),
|
133 |
-
'level' => $level,
|
134 |
-
'message' => $message,
|
135 |
-
'context' => $context,
|
136 |
-
);
|
137 |
-
}
|
138 |
-
}
|
139 |
-
endif;
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Describes a logger instance
|
5 |
+
*
|
6 |
+
* Based on PSR-3: http://www.php-fig.org/psr/psr-3/
|
7 |
+
*
|
8 |
+
* The message MUST be a string or object implementing __toString().
|
9 |
+
*
|
10 |
+
* The message MAY contain placeholders in the form: {foo} where foo
|
11 |
+
* will be replaced by the context data in key "foo".
|
12 |
+
*
|
13 |
+
* The context array can contain arbitrary data, the only assumption that
|
14 |
+
* can be made by implementors is that if an Exception instance is given
|
15 |
+
* to produce a stack trace, it MUST be in a key named "exception".
|
16 |
+
*
|
17 |
+
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
|
18 |
+
* for the full interface specification.
|
19 |
+
*/
|
20 |
+
if( ! class_exists( 'WP_Importer_Logger' ) ) :
|
21 |
+
class WP_Importer_Logger {
|
22 |
+
/**
|
23 |
+
* System is unusable.
|
24 |
+
*
|
25 |
+
* @param string $message
|
26 |
+
* @param array $context
|
27 |
+
* @return null
|
28 |
+
*/
|
29 |
+
public function emergency( $message, array $context = array() ) {
|
30 |
+
return $this->log( 'emergency', $message, $context );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Action must be taken immediately.
|
35 |
+
*
|
36 |
+
* Example: Entire website down, database unavailable, etc. This should
|
37 |
+
* trigger the SMS alerts and wake you up.
|
38 |
+
*
|
39 |
+
* @param string $message
|
40 |
+
* @param array $context
|
41 |
+
* @return null
|
42 |
+
*/
|
43 |
+
public function alert( $message, array $context = array() ) {
|
44 |
+
return $this->log( 'alert', $message, $context );
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Critical conditions.
|
49 |
+
*
|
50 |
+
* Example: Application component unavailable, unexpected exception.
|
51 |
+
*
|
52 |
+
* @param string $message
|
53 |
+
* @param array $context
|
54 |
+
* @return null
|
55 |
+
*/
|
56 |
+
public function critical( $message, array $context = array() ) {
|
57 |
+
return $this->log( 'critical', $message, $context );
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Runtime errors that do not require immediate action but should typically
|
62 |
+
* be logged and monitored.
|
63 |
+
*
|
64 |
+
* @param string $message
|
65 |
+
* @param array $context
|
66 |
+
* @return null
|
67 |
+
*/
|
68 |
+
public function error( $message, array $context = array() ) {
|
69 |
+
return $this->log( 'error', $message, $context );
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Exceptional occurrences that are not errors.
|
74 |
+
*
|
75 |
+
* Example: Use of deprecated APIs, poor use of an API, undesirable things
|
76 |
+
* that are not necessarily wrong.
|
77 |
+
*
|
78 |
+
* @param string $message
|
79 |
+
* @param array $context
|
80 |
+
* @return null
|
81 |
+
*/
|
82 |
+
public function warning( $message, array $context = array() ) {
|
83 |
+
return $this->log( 'warning', $message, $context );
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Normal but significant events.
|
88 |
+
*
|
89 |
+
* @param string $message
|
90 |
+
* @param array $context
|
91 |
+
* @return null
|
92 |
+
*/
|
93 |
+
public function notice( $message, array $context = array() ) {
|
94 |
+
return $this->log( 'notice', $message, $context );
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Interesting events.
|
99 |
+
*
|
100 |
+
* Example: User logs in, SQL logs.
|
101 |
+
*
|
102 |
+
* @param string $message
|
103 |
+
* @param array $context
|
104 |
+
* @return null
|
105 |
+
*/
|
106 |
+
public function info( $message, array $context = array() ) {
|
107 |
+
return $this->log( 'info', $message, $context );
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Detailed debug information.
|
112 |
+
*
|
113 |
+
* @param string $message
|
114 |
+
* @param array $context
|
115 |
+
* @return null
|
116 |
+
*/
|
117 |
+
public function debug( $message, array $context = array() ) {
|
118 |
+
return $this->log( 'debug', $message, $context );
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Logs with an arbitrary level.
|
123 |
+
*
|
124 |
+
* @param mixed $level
|
125 |
+
* @param string $message
|
126 |
+
* @param array $context
|
127 |
+
* @return null
|
128 |
+
*/
|
129 |
+
public function log( $level, $message, array $context = array() ) {
|
130 |
+
|
131 |
+
$this->messages[] = array(
|
132 |
+
'timestamp' => time(),
|
133 |
+
'level' => $level,
|
134 |
+
'message' => $message,
|
135 |
+
'context' => $context,
|
136 |
+
);
|
137 |
+
}
|
138 |
+
}
|
139 |
+
endif;
|
inc/importers/wxr-importer/class-wp-importer-logger-serversentevents.php
CHANGED
@@ -1,43 +1,43 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( ! class_exists( 'WP_Importer_Logger_ServerSentEvents' ) && class_exists( 'WP_Importer_Logger' ) ) {
|
4 |
-
|
5 |
-
class WP_Importer_Logger_ServerSentEvents extends WP_Importer_Logger {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Logs with an arbitrary level.
|
9 |
-
*
|
10 |
-
* @param mixed $level
|
11 |
-
* @param string $message
|
12 |
-
* @param array $context
|
13 |
-
* @return null
|
14 |
-
*/
|
15 |
-
public function log( $level, $message, array $context = array() ) {
|
16 |
-
|
17 |
-
$data = compact( 'level', 'message' );
|
18 |
-
|
19 |
-
switch ( $level ) {
|
20 |
-
case 'emergency':
|
21 |
-
case 'alert':
|
22 |
-
case 'critical':
|
23 |
-
case 'error':
|
24 |
-
case 'warning':
|
25 |
-
case 'notice':
|
26 |
-
case 'info':
|
27 |
-
echo "event: log\n";
|
28 |
-
echo 'data: ' . wp_json_encode( $data ) . "\n\n";
|
29 |
-
flush();
|
30 |
-
break;
|
31 |
-
|
32 |
-
case 'debug':
|
33 |
-
if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
|
34 |
-
echo "event: log\n";
|
35 |
-
echo 'data: ' . wp_json_encode( $data ) . "\n\n";
|
36 |
-
flush();
|
37 |
-
break;
|
38 |
-
}
|
39 |
-
break;
|
40 |
-
}
|
41 |
-
}
|
42 |
-
}
|
43 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! class_exists( 'WP_Importer_Logger_ServerSentEvents' ) && class_exists( 'WP_Importer_Logger' ) ) {
|
4 |
+
|
5 |
+
class WP_Importer_Logger_ServerSentEvents extends WP_Importer_Logger {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Logs with an arbitrary level.
|
9 |
+
*
|
10 |
+
* @param mixed $level
|
11 |
+
* @param string $message
|
12 |
+
* @param array $context
|
13 |
+
* @return null
|
14 |
+
*/
|
15 |
+
public function log( $level, $message, array $context = array() ) {
|
16 |
+
|
17 |
+
$data = compact( 'level', 'message' );
|
18 |
+
|
19 |
+
switch ( $level ) {
|
20 |
+
case 'emergency':
|
21 |
+
case 'alert':
|
22 |
+
case 'critical':
|
23 |
+
case 'error':
|
24 |
+
case 'warning':
|
25 |
+
case 'notice':
|
26 |
+
case 'info':
|
27 |
+
echo "event: log\n";
|
28 |
+
echo 'data: ' . wp_json_encode( $data ) . "\n\n";
|
29 |
+
flush();
|
30 |
+
break;
|
31 |
+
|
32 |
+
case 'debug':
|
33 |
+
if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
|
34 |
+
echo "event: log\n";
|
35 |
+
echo 'data: ' . wp_json_encode( $data ) . "\n\n";
|
36 |
+
flush();
|
37 |
+
break;
|
38 |
+
}
|
39 |
+
break;
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
43 |
+
}
|
inc/importers/wxr-importer/class-wxr-import-info.php
CHANGED
@@ -1,21 +1,21 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( ! class_exists( 'WXR_Import_Info' ) ) {
|
4 |
-
|
5 |
-
class WXR_Import_Info {
|
6 |
-
public $home;
|
7 |
-
public $siteurl;
|
8 |
-
|
9 |
-
public $title;
|
10 |
-
|
11 |
-
public $users = array();
|
12 |
-
public $post_count = 0;
|
13 |
-
public $media_count = 0;
|
14 |
-
public $comment_count = 0;
|
15 |
-
public $term_count = 0;
|
16 |
-
|
17 |
-
public $generator = '';
|
18 |
-
public $version;
|
19 |
-
}
|
20 |
-
|
21 |
Â
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! class_exists( 'WXR_Import_Info' ) ) {
|
4 |
+
|
5 |
+
class WXR_Import_Info {
|
6 |
+
public $home;
|
7 |
+
public $siteurl;
|
8 |
+
|
9 |
+
public $title;
|
10 |
+
|
11 |
+
public $users = array();
|
12 |
+
public $post_count = 0;
|
13 |
+
public $media_count = 0;
|
14 |
+
public $comment_count = 0;
|
15 |
+
public $term_count = 0;
|
16 |
+
|
17 |
+
public $generator = '';
|
18 |
+
public $version;
|
19 |
+
}
|
20 |
+
|
21 |
Â
}
|
inc/importers/wxr-importer/class-wxr-importer.php
CHANGED
@@ -1,2301 +1,2301 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if( ! class_exists( 'WXR_Importer' ) && class_exists( 'WP_Importer' ) ) :
|
4 |
-
class WXR_Importer extends WP_Importer {
|
5 |
-
/**
|
6 |
-
* Maximum supported WXR version
|
7 |
-
*/
|
8 |
-
const MAX_WXR_VERSION = 1.2;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Regular expression for checking if a post references an attachment
|
12 |
-
*
|
13 |
-
* Note: This is a quick, weak check just to exclude text-only posts. More
|
14 |
-
* vigorous checking is done later to verify.
|
15 |
-
*/
|
16 |
-
const REGEX_HAS_ATTACHMENT_REFS = '!
|
17 |
-
(
|
18 |
-
# Match anything with an image or attachment class
|
19 |
-
class=[\'"].*?\b(wp-image-\d+|attachment-[\w\-]+)\b
|
20 |
-
|
|
21 |
-
# Match anything that looks like an upload URL
|
22 |
-
src=[\'"][^\'"]*(
|
23 |
-
[0-9]{4}/[0-9]{2}/[^\'"]+\.(jpg|jpeg|png|gif)
|
24 |
-
|
|
25 |
-
content/uploads[^\'"]+
|
26 |
-
)[\'"]
|
27 |
-
)!ix';
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Version of WXR we're importing.
|
31 |
-
*
|
32 |
-
* Defaults to 1.0 for compatibility. Typically overridden by a
|
33 |
-
* `<wp:wxr_version>` tag at the start of the file.
|
34 |
-
*
|
35 |
-
* @var string
|
36 |
-
*/
|
37 |
-
protected $version = '1.0';
|
38 |
-
|
39 |
-
// information to import from WXR file
|
40 |
-
protected $categories = array();
|
41 |
-
protected $tags = array();
|
42 |
-
protected $base_url = '';
|
43 |
-
|
44 |
-
// TODO: REMOVE THESE
|
45 |
-
protected $processed_terms = array();
|
46 |
-
protected $processed_posts = array();
|
47 |
-
protected $processed_menu_items = array();
|
48 |
-
protected $menu_item_orphans = array();
|
49 |
-
protected $missing_menu_items = array();
|
50 |
-
|
51 |
-
// NEW STYLE
|
52 |
-
protected $mapping = array();
|
53 |
-
protected $requires_remapping = array();
|
54 |
-
protected $exists = array();
|
55 |
-
protected $user_slug_override = array();
|
56 |
-
|
57 |
-
protected $url_remap = array();
|
58 |
-
protected $featured_images = array();
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Logger instance.
|
62 |
-
*
|
63 |
-
* @var WP_Importer_Logger
|
64 |
-
*/
|
65 |
-
protected $logger;
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Constructor
|
69 |
-
*
|
70 |
-
* @param array $options {
|
71 |
-
* @var bool $prefill_existing_posts Should we prefill `post_exists` calls? (True prefills and uses more memory, false checks once per imported post and takes longer. Default is true.)
|
72 |
-
* @var bool $prefill_existing_comments Should we prefill `comment_exists` calls? (True prefills and uses more memory, false checks once per imported comment and takes longer. Default is true.)
|
73 |
-
* @var bool $prefill_existing_terms Should we prefill `term_exists` calls? (True prefills and uses more memory, false checks once per imported term and takes longer. Default is true.)
|
74 |
-
* @var bool $update_attachment_guids Should attachment GUIDs be updated to the new URL? (True updates the GUID, which keeps compatibility with v1, false doesn't update, and allows deduplication and reimporting. Default is false.)
|
75 |
-
* @var bool $fetch_attachments Fetch attachments from the remote server. (True fetches and creates attachment posts, false skips attachments. Default is false.)
|
76 |
-
* @var bool $aggressive_url_search Should we search/replace for URLs aggressively? (True searches all posts' content for old URLs and replaces, false checks for `<img class="wp-image-*">` only. Default is false.)
|
77 |
-
* @var int $default_author User ID to use if author is missing or invalid. (Default is null, which leaves posts unassigned.)
|
78 |
-
* }
|
79 |
-
*/
|
80 |
-
public function __construct( $options = array() ) {
|
81 |
-
// Initialize some important variables
|
82 |
-
$empty_types = array(
|
83 |
-
'post' => array(),
|
84 |
-
'comment' => array(),
|
85 |
-
'term' => array(),
|
86 |
-
'user' => array(),
|
87 |
-
);
|
88 |
-
|
89 |
-
$this->mapping = $empty_types;
|
90 |
-
$this->mapping['user_slug'] = array();
|
91 |
-
$this->mapping['term_id'] = array();
|
92 |
-
$this->requires_remapping = $empty_types;
|
93 |
-
$this->exists = $empty_types;
|
94 |
-
|
95 |
-
$this->options = wp_parse_args( $options, array(
|
96 |
-
'prefill_existing_posts' => true,
|
97 |
-
'prefill_existing_comments' => true,
|
98 |
-
'prefill_existing_terms' => true,
|
99 |
-
'update_attachment_guids' => false,
|
100 |
-
'fetch_attachments' => false,
|
101 |
-
'aggressive_url_search' => false,
|
102 |
-
'default_author' => null,
|
103 |
-
) );
|
104 |
-
}
|
105 |
-
|
106 |
-
public function set_logger( $logger ) {
|
107 |
-
$this->logger = $logger;
|
108 |
-
}
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Get a stream reader for the file.
|
112 |
-
*
|
113 |
-
* @param string $file Path to the XML file.
|
114 |
-
* @return XMLReader|WP_Error Reader instance on success, error otherwise.
|
115 |
-
*/
|
116 |
-
protected function get_reader( $file ) {
|
117 |
-
// Avoid loading external entities for security
|
118 |
-
$old_value = null;
|
119 |
-
if ( function_exists( 'libxml_disable_entity_loader' ) ) {
|
120 |
-
// $old_value = libxml_disable_entity_loader( true );
|
121 |
-
}
|
122 |
-
|
123 |
-
$reader = new XMLReader();
|
124 |
-
$status = $reader->open( $file );
|
125 |
-
|
126 |
-
if ( ! is_null( $old_value ) ) {
|
127 |
-
// libxml_disable_entity_loader( $old_value );
|
128 |
-
}
|
129 |
-
|
130 |
-
if ( ! $status ) {
|
131 |
-
return new WP_Error( 'wxr_importer.cannot_parse', __( 'Could not open the file for parsing', 'wordpress-importer' ) );
|
132 |
-
}
|
133 |
-
|
134 |
-
return $reader;
|
135 |
-
}
|
136 |
-
|
137 |
-
/**
|
138 |
-
* The main controller for the actual import stage.
|
139 |
-
*
|
140 |
-
* @param string $file Path to the WXR file for importing
|
141 |
-
*/
|
142 |
-
public function get_preliminary_information( $file ) {
|
143 |
-
// Let's run the actual importer now, woot
|
144 |
-
$reader = $this->get_reader( $file );
|
145 |
-
if ( is_wp_error( $reader ) ) {
|
146 |
-
return $reader;
|
147 |
-
}
|
148 |
-
|
149 |
-
// Set the version to compatibility mode first
|
150 |
-
$this->version = '1.0';
|
151 |
-
|
152 |
-
// Start parsing!
|
153 |
-
$data = new WXR_Import_Info();
|
154 |
-
while ( $reader->read() ) {
|
155 |
-
// Only deal with element opens
|
156 |
-
if ( $reader->nodeType !== XMLReader::ELEMENT ) {
|
157 |
-
continue;
|
158 |
-
}
|
159 |
-
|
160 |
-
switch ( $reader->name ) {
|
161 |
-
case 'wp:wxr_version':
|
162 |
-
// Upgrade to the correct version
|
163 |
-
$this->version = $reader->readString();
|
164 |
-
|
165 |
-
if ( version_compare( $this->version, self::MAX_WXR_VERSION, '>' ) ) {
|
166 |
-
$this->logger->warning( sprintf(
|
167 |
-
__( 'This WXR file (version %1$s) is newer than the importer (version %2$s) and may not be supported. Please consider updating.', 'wordpress-importer' ),
|
168 |
-
$this->version,
|
169 |
-
self::MAX_WXR_VERSION
|
170 |
-
) );
|
171 |
-
}
|
172 |
-
|
173 |
-
// Handled everything in this node, move on to the next
|
174 |
-
$reader->next();
|
175 |
-
break;
|
176 |
-
|
177 |
-
case 'generator':
|
178 |
-
$data->generator = $reader->readString();
|
179 |
-
$reader->next();
|
180 |
-
break;
|
181 |
-
|
182 |
-
case 'title':
|
183 |
-
$data->title = $reader->readString();
|
184 |
-
$reader->next();
|
185 |
-
break;
|
186 |
-
|
187 |
-
case 'wp:base_site_url':
|
188 |
-
$data->siteurl = $reader->readString();
|
189 |
-
$reader->next();
|
190 |
-
break;
|
191 |
-
|
192 |
-
case 'wp:base_blog_url':
|
193 |
-
$data->home = $reader->readString();
|
194 |
-
$reader->next();
|
195 |
-
break;
|
196 |
-
|
197 |
-
case 'wp:author':
|
198 |
-
$node = $reader->expand();
|
199 |
-
|
200 |
-
$parsed = $this->parse_author_node( $node );
|
201 |
-
if ( is_wp_error( $parsed ) ) {
|
202 |
-
$this->log_error( $parsed );
|
203 |
-
|
204 |
-
// Skip the rest of this post
|
205 |
-
$reader->next();
|
206 |
-
break;
|
207 |
-
}
|
208 |
-
|
209 |
-
$data->users[] = $parsed;
|
210 |
-
|
211 |
-
// Handled everything in this node, move on to the next
|
212 |
-
$reader->next();
|
213 |
-
break;
|
214 |
-
|
215 |
-
case 'item':
|
216 |
-
$node = $reader->expand();
|
217 |
-
$parsed = $this->parse_post_node( $node );
|
218 |
-
if ( is_wp_error( $parsed ) ) {
|
219 |
-
$this->log_error( $parsed );
|
220 |
-
|
221 |
-
// Skip the rest of this post
|
222 |
-
$reader->next();
|
223 |
-
break;
|
224 |
-
}
|
225 |
-
|
226 |
-
if ( $parsed['data']['post_type'] === 'attachment' ) {
|
227 |
-
$data->media_count++;
|
228 |
-
} else {
|
229 |
-
$data->post_count++;
|
230 |
-
}
|
231 |
-
$data->comment_count += count( $parsed['comments'] );
|
232 |
-
|
233 |
-
// Handled everything in this node, move on to the next
|
234 |
-
$reader->next();
|
235 |
-
break;
|
236 |
-
|
237 |
-
case 'wp:category':
|
238 |
-
case 'wp:tag':
|
239 |
-
case 'wp:term':
|
240 |
-
$data->term_count++;
|
241 |
-
|
242 |
-
// Handled everything in this node, move on to the next
|
243 |
-
$reader->next();
|
244 |
-
break;
|
245 |
-
}// End switch().
|
246 |
-
}// End while().
|
247 |
-
|
248 |
-
$data->version = $this->version;
|
249 |
-
|
250 |
-
return $data;
|
251 |
-
}
|
252 |
-
|
253 |
-
/**
|
254 |
-
* The main controller for the actual import stage.
|
255 |
-
*
|
256 |
-
* @param string $file Path to the WXR file for importing
|
257 |
-
*/
|
258 |
-
public function parse_authors( $file ) {
|
259 |
-
// Let's run the actual importer now, woot
|
260 |
-
$reader = $this->get_reader( $file );
|
261 |
-
if ( is_wp_error( $reader ) ) {
|
262 |
-
return $reader;
|
263 |
-
}
|
264 |
-
|
265 |
-
// Set the version to compatibility mode first
|
266 |
-
$this->version = '1.0';
|
267 |
-
|
268 |
-
// Start parsing!
|
269 |
-
$authors = array();
|
270 |
-
while ( $reader->read() ) {
|
271 |
-
// Only deal with element opens
|
272 |
-
if ( $reader->nodeType !== XMLReader::ELEMENT ) {
|
273 |
-
continue;
|
274 |
-
}
|
275 |
-
|
276 |
-
switch ( $reader->name ) {
|
277 |
-
case 'wp:wxr_version':
|
278 |
-
// Upgrade to the correct version
|
279 |
-
$this->version = $reader->readString();
|
280 |
-
|
281 |
-
if ( version_compare( $this->version, self::MAX_WXR_VERSION, '>' ) ) {
|
282 |
-
$this->logger->warning( sprintf(
|
283 |
-
__( 'This WXR file (version %1$s) is newer than the importer (version %2$s) and may not be supported. Please consider updating.', 'wordpress-importer' ),
|
284 |
-
$this->version,
|
285 |
-
self::MAX_WXR_VERSION
|
286 |
-
) );
|
287 |
-
}
|
288 |
-
|
289 |
-
// Handled everything in this node, move on to the next
|
290 |
-
$reader->next();
|
291 |
-
break;
|
292 |
-
|
293 |
-
case 'wp:author':
|
294 |
-
$node = $reader->expand();
|
295 |
-
|
296 |
-
$parsed = $this->parse_author_node( $node );
|
297 |
-
if ( is_wp_error( $parsed ) ) {
|
298 |
-
$this->log_error( $parsed );
|
299 |
-
|
300 |
-
// Skip the rest of this post
|
301 |
-
$reader->next();
|
302 |
-
break;
|
303 |
-
}
|
304 |
-
|
305 |
-
$authors[] = $parsed;
|
306 |
-
|
307 |
-
// Handled everything in this node, move on to the next
|
308 |
-
$reader->next();
|
309 |
-
break;
|
310 |
-
}
|
311 |
-
}// End while().
|
312 |
-
|
313 |
-
return $authors;
|
314 |
-
}
|
315 |
-
|
316 |
-
/**
|
317 |
-
* The main controller for the actual import stage.
|
318 |
-
*
|
319 |
-
* @param string $file Path to the WXR file for importing
|
320 |
-
*/
|
321 |
-
public function import( $file ) {
|
322 |
-
add_filter( 'import_post_meta_key', array( $this, 'is_valid_meta_key' ) );
|
323 |
-
add_filter( 'http_request_timeout', array( &$this, 'bump_request_timeout' ) );
|
324 |
-
|
325 |
-
$result = $this->import_start( $file );
|
326 |
-
if ( is_wp_error( $result ) ) {
|
327 |
-
return $result;
|
328 |
-
}
|
329 |
-
|
330 |
-
// Let's run the actual importer now, woot
|
331 |
-
$reader = $this->get_reader( $file );
|
332 |
-
if ( is_wp_error( $reader ) ) {
|
333 |
-
return $reader;
|
334 |
-
}
|
335 |
-
|
336 |
-
// Set the version to compatibility mode first
|
337 |
-
$this->version = '1.0';
|
338 |
-
|
339 |
-
// Reset other variables
|
340 |
-
$this->base_url = '';
|
341 |
-
|
342 |
-
// Start parsing!
|
343 |
-
while ( $reader->read() ) {
|
344 |
-
// Only deal with element opens
|
345 |
-
if ( $reader->nodeType !== XMLReader::ELEMENT ) {
|
346 |
-
continue;
|
347 |
-
}
|
348 |
-
|
349 |
-
switch ( $reader->name ) {
|
350 |
-
case 'wp:wxr_version':
|
351 |
-
// Upgrade to the correct version
|
352 |
-
$this->version = $reader->readString();
|
353 |
-
|
354 |
-
if ( version_compare( $this->version, self::MAX_WXR_VERSION, '>' ) ) {
|
355 |
-
$this->logger->warning( sprintf(
|
356 |
-
__( 'This WXR file (version %1$s) is newer than the importer (version %2$s) and may not be supported. Please consider updating.', 'wordpress-importer' ),
|
357 |
-
$this->version,
|
358 |
-
self::MAX_WXR_VERSION
|
359 |
-
) );
|
360 |
-
}
|
361 |
-
|
362 |
-
// Handled everything in this node, move on to the next
|
363 |
-
$reader->next();
|
364 |
-
break;
|
365 |
-
|
366 |
-
case 'wp:base_site_url':
|
367 |
-
$this->base_url = $reader->readString();
|
368 |
-
|
369 |
-
// Handled everything in this node, move on to the next
|
370 |
-
$reader->next();
|
371 |
-
break;
|
372 |
-
|
373 |
-
case 'item':
|
374 |
-
$node = $reader->expand();
|
375 |
-
$parsed = $this->parse_post_node( $node );
|
376 |
-
if ( is_wp_error( $parsed ) ) {
|
377 |
-
$this->log_error( $parsed );
|
378 |
-
|
379 |
-
// Skip the rest of this post
|
380 |
-
$reader->next();
|
381 |
-
break;
|
382 |
-
}
|
383 |
-
|
384 |
-
$this->process_post( $parsed['data'], $parsed['meta'], $parsed['comments'], $parsed['terms'] );
|
385 |
-
|
386 |
-
// Handled everything in this node, move on to the next
|
387 |
-
$reader->next();
|
388 |
-
break;
|
389 |
-
|
390 |
-
case 'wp:author':
|
391 |
-
$node = $reader->expand();
|
392 |
-
|
393 |
-
$parsed = $this->parse_author_node( $node );
|
394 |
-
if ( is_wp_error( $parsed ) ) {
|
395 |
-
$this->log_error( $parsed );
|
396 |
-
|
397 |
-
// Skip the rest of this post
|
398 |
-
$reader->next();
|
399 |
-
break;
|
400 |
-
}
|
401 |
-
|
402 |
-
$status = $this->process_author( $parsed['data'], $parsed['meta'] );
|
403 |
-
if ( is_wp_error( $status ) ) {
|
404 |
-
$this->log_error( $status );
|
405 |
-
}
|
406 |
-
|
407 |
-
// Handled everything in this node, move on to the next
|
408 |
-
$reader->next();
|
409 |
-
break;
|
410 |
-
|
411 |
-
case 'wp:category':
|
412 |
-
$node = $reader->expand();
|
413 |
-
|
414 |
-
$parsed = $this->parse_term_node( $node, 'category' );
|
415 |
-
if ( is_wp_error( $parsed ) ) {
|
416 |
-
$this->log_error( $parsed );
|
417 |
-
|
418 |
-
// Skip the rest of this post
|
419 |
-
$reader->next();
|
420 |
-
break;
|
421 |
-
}
|
422 |
-
|
423 |
-
$status = $this->process_term( $parsed['data'], $parsed['meta'] );
|
424 |
-
|
425 |
-
// Handled everything in this node, move on to the next
|
426 |
-
$reader->next();
|
427 |
-
break;
|
428 |
-
|
429 |
-
case 'wp:tag':
|
430 |
-
$node = $reader->expand();
|
431 |
-
|
432 |
-
$parsed = $this->parse_term_node( $node, 'tag' );
|
433 |
-
if ( is_wp_error( $parsed ) ) {
|
434 |
-
$this->log_error( $parsed );
|
435 |
-
|
436 |
-
// Skip the rest of this post
|
437 |
-
$reader->next();
|
438 |
-
break;
|
439 |
-
}
|
440 |
-
|
441 |
-
$status = $this->process_term( $parsed['data'], $parsed['meta'] );
|
442 |
-
|
443 |
-
// Handled everything in this node, move on to the next
|
444 |
-
$reader->next();
|
445 |
-
break;
|
446 |
-
|
447 |
-
case 'wp:term':
|
448 |
-
$node = $reader->expand();
|
449 |
-
|
450 |
-
$parsed = $this->parse_term_node( $node );
|
451 |
-
if ( is_wp_error( $parsed ) ) {
|
452 |
-
$this->log_error( $parsed );
|
453 |
-
|
454 |
-
// Skip the rest of this post
|
455 |
-
$reader->next();
|
456 |
-
break;
|
457 |
-
}
|
458 |
-
|
459 |
-
$status = $this->process_term( $parsed['data'], $parsed['meta'] );
|
460 |
-
|
461 |
-
// Handled everything in this node, move on to the next
|
462 |
-
$reader->next();
|
463 |
-
break;
|
464 |
-
|
465 |
-
default:
|
466 |
-
// Skip this node, probably handled by something already
|
467 |
-
break;
|
468 |
-
}// End switch().
|
469 |
-
}// End while().
|
470 |
-
|
471 |
-
// Now that we've done the main processing, do any required
|
472 |
-
// post-processing and remapping.
|
473 |
-
$this->post_process();
|
474 |
-
|
475 |
-
if ( $this->options['aggressive_url_search'] ) {
|
476 |
-
$this->replace_attachment_urls_in_content();
|
477 |
-
}
|
478 |
-
// $this->remap_featured_images();
|
479 |
-
$this->import_end();
|
480 |
-
}
|
481 |
-
|
482 |
-
/**
|
483 |
-
* Log an error instance to the logger.
|
484 |
-
*
|
485 |
-
* @param WP_Error $error Error instance to log.
|
486 |
-
*/
|
487 |
-
protected function log_error( WP_Error $error ) {
|
488 |
-
$this->logger->warning( $error->get_error_message() );
|
489 |
-
|
490 |
-
// Log the data as debug info too
|
491 |
-
$data = $error->get_error_data();
|
492 |
-
if ( ! empty( $data ) ) {
|
493 |
-
$this->logger->debug( var_export( $data, true ) );
|
494 |
-
}
|
495 |
-
}
|
496 |
-
|
497 |
-
/**
|
498 |
-
* Parses the WXR file and prepares us for the task of processing parsed data
|
499 |
-
*
|
500 |
-
* @param string $file Path to the WXR file for importing
|
501 |
-
*/
|
502 |
-
protected function import_start( $file ) {
|
503 |
-
if ( ! is_file( $file ) ) {
|
504 |
-
return new WP_Error( 'wxr_importer.file_missing', __( 'The file does not exist, please try again.', 'wordpress-importer' ) );
|
505 |
-
}
|
506 |
-
|
507 |
-
// Suspend bunches of stuff in WP core
|
508 |
-
wp_defer_term_counting( true );
|
509 |
-
wp_defer_comment_counting( true );
|
510 |
-
wp_suspend_cache_invalidation( true );
|
511 |
-
|
512 |
-
// Prefill exists calls if told to
|
513 |
-
if ( $this->options['prefill_existing_posts'] ) {
|
514 |
-
$this->prefill_existing_posts();
|
515 |
-
}
|
516 |
-
if ( $this->options['prefill_existing_comments'] ) {
|
517 |
-
$this->prefill_existing_comments();
|
518 |
-
}
|
519 |
-
if ( $this->options['prefill_existing_terms'] ) {
|
520 |
-
$this->prefill_existing_terms();
|
521 |
-
}
|
522 |
-
|
523 |
-
/**
|
524 |
-
* Begin the import.
|
525 |
-
*
|
526 |
-
* Fires before the import process has begun. If you need to suspend
|
527 |
-
* caching or heavy processing on hooks, do so here.
|
528 |
-
*/
|
529 |
-
do_action( 'import_start' );
|
530 |
-
}
|
531 |
-
|
532 |
-
/**
|
533 |
-
* Performs post-import cleanup of files and the cache
|
534 |
-
*/
|
535 |
-
protected function import_end() {
|
536 |
-
// Re-enable stuff in core
|
537 |
-
wp_suspend_cache_invalidation( false );
|
538 |
-
wp_cache_flush();
|
539 |
-
foreach ( get_taxonomies() as $tax ) {
|
540 |
-
delete_option( "{$tax}_children" );
|
541 |
-
_get_term_hierarchy( $tax );
|
542 |
-
}
|
543 |
-
|
544 |
-
wp_defer_term_counting( false );
|
545 |
-
wp_defer_comment_counting( false );
|
546 |
-
|
547 |
-
/**
|
548 |
-
* Complete the import.
|
549 |
-
*
|
550 |
-
* Fires after the import process has finished. If you need to update
|
551 |
-
* your cache or re-enable processing, do so here.
|
552 |
-
*/
|
553 |
-
do_action( 'import_end' );
|
554 |
-
}
|
555 |
-
|
556 |
-
/**
|
557 |
-
* Set the user mapping.
|
558 |
-
*
|
559 |
-
* @param array $mapping List of map arrays (containing `old_slug`, `old_id`, `new_id`)
|
560 |
-
*/
|
561 |
-
public function set_user_mapping( $mapping ) {
|
562 |
-
foreach ( $mapping as $map ) {
|
563 |
-
if ( empty( $map['old_slug'] ) || empty( $map['old_id'] ) || empty( $map['new_id'] ) ) {
|
564 |
-
$this->logger->warning( __( 'Invalid author mapping', 'wordpress-importer' ) );
|
565 |
-
$this->logger->debug( var_export( $map, true ) );
|
566 |
-
continue;
|
567 |
-
}
|
568 |
-
|
569 |
-
$old_slug = $map['old_slug'];
|
570 |
-
$old_id = $map['old_id'];
|
571 |
-
$new_id = $map['new_id'];
|
572 |
-
|
573 |
-
$this->mapping['user'][ $old_id ] = $new_id;
|
574 |
-
$this->mapping['user_slug'][ $old_slug ] = $new_id;
|
575 |
-
}
|
576 |
-
}
|
577 |
-
|
578 |
-
/**
|
579 |
-
* Set the user slug overrides.
|
580 |
-
*
|
581 |
-
* Allows overriding the slug in the import with a custom/renamed version.
|
582 |
-
*
|
583 |
-
* @param string[] $overrides Map of old slug to new slug.
|
584 |
-
*/
|
585 |
-
public function set_user_slug_overrides( $overrides ) {
|
586 |
-
foreach ( $overrides as $original => $renamed ) {
|
587 |
-
$this->user_slug_override[ $original ] = $renamed;
|
588 |
-
}
|
589 |
-
}
|
590 |
-
|
591 |
-
/**
|
592 |
-
* Parse a post node into post data.
|
593 |
-
*
|
594 |
-
* @param DOMElement $node Parent node of post data (typically `item`).
|
595 |
-
* @return array|WP_Error Post data array on success, error otherwise.
|
596 |
-
*/
|
597 |
-
protected function parse_post_node( $node ) {
|
598 |
-
$data = array();
|
599 |
-
$meta = array();
|
600 |
-
$comments = array();
|
601 |
-
$terms = array();
|
602 |
-
|
603 |
-
foreach ( $node->childNodes as $child ) {
|
604 |
-
// We only care about child elements
|
605 |
-
if ( $child->nodeType !== XML_ELEMENT_NODE ) {
|
606 |
-
continue;
|
607 |
-
}
|
608 |
-
|
609 |
-
switch ( $child->tagName ) {
|
610 |
-
case 'wp:post_type':
|
611 |
-
$data['post_type'] = $child->textContent;
|
612 |
-
break;
|
613 |
-
|
614 |
-
case 'title':
|
615 |
-
$data['post_title'] = $child->textContent;
|
616 |
-
break;
|
617 |
-
|
618 |
-
case 'guid':
|
619 |
-
$data['guid'] = $child->textContent;
|
620 |
-
break;
|
621 |
-
|
622 |
-
case 'dc:creator':
|
623 |
-
$data['post_author'] = $child->textContent;
|
624 |
-
break;
|
625 |
-
|
626 |
-
case 'content:encoded':
|
627 |
-
$data['post_content'] = $child->textContent;
|
628 |
-
break;
|
629 |
-
|
630 |
-
case 'excerpt:encoded':
|
631 |
-
$data['post_excerpt'] = $child->textContent;
|
632 |
-
break;
|
633 |
-
|
634 |
-
case 'wp:post_id':
|
635 |
-
$data['post_id'] = $child->textContent;
|
636 |
-
break;
|
637 |
-
|
638 |
-
case 'wp:post_date':
|
639 |
-
$data['post_date'] = $child->textContent;
|
640 |
-
break;
|
641 |
-
|
642 |
-
case 'wp:post_date_gmt':
|
643 |
-
$data['post_date_gmt'] = $child->textContent;
|
644 |
-
break;
|
645 |
-
|
646 |
-
case 'wp:comment_status':
|
647 |
-
$data['comment_status'] = $child->textContent;
|
648 |
-
break;
|
649 |
-
|
650 |
-
case 'wp:ping_status':
|
651 |
-
$data['ping_status'] = $child->textContent;
|
652 |
-
break;
|
653 |
-
|
654 |
-
case 'wp:post_name':
|
655 |
-
$data['post_name'] = $child->textContent;
|
656 |
-
break;
|
657 |
-
|
658 |
-
case 'wp:status':
|
659 |
-
$data['post_status'] = $child->textContent;
|
660 |
-
|
661 |
-
if ( $data['post_status'] === 'auto-draft' ) {
|
662 |
-
// Bail now
|
663 |
-
return new WP_Error(
|
664 |
-
'wxr_importer.post.cannot_import_draft',
|
665 |
-
__( 'Cannot import auto-draft posts' ),
|
666 |
-
$data
|
667 |
-
);
|
668 |
-
}
|
669 |
-
break;
|
670 |
-
|
671 |
-
case 'wp:post_parent':
|
672 |
-
$data['post_parent'] = $child->textContent;
|
673 |
-
break;
|
674 |
-
|
675 |
-
case 'wp:menu_order':
|
676 |
-
$data['menu_order'] = $child->textContent;
|
677 |
-
break;
|
678 |
-
|
679 |
-
case 'wp:post_password':
|
680 |
-
$data['post_password'] = $child->textContent;
|
681 |
-
break;
|
682 |
-
|
683 |
-
case 'wp:is_sticky':
|
684 |
-
$data['is_sticky'] = $child->textContent;
|
685 |
-
break;
|
686 |
-
|
687 |
-
case 'wp:attachment_url':
|
688 |
-
$data['attachment_url'] = $child->textContent;
|
689 |
-
break;
|
690 |
-
|
691 |
-
case 'wp:postmeta':
|
692 |
-
$meta_item = $this->parse_meta_node( $child );
|
693 |
-
if ( ! empty( $meta_item ) ) {
|
694 |
-
$meta[] = $meta_item;
|
695 |
-
}
|
696 |
-
break;
|
697 |
-
|
698 |
-
case 'wp:comment':
|
699 |
-
$comment_item = $this->parse_comment_node( $child );
|
700 |
-
if ( ! empty( $comment_item ) ) {
|
701 |
-
$comments[] = $comment_item;
|
702 |
-
}
|
703 |
-
break;
|
704 |
-
|
705 |
-
case 'category':
|
706 |
-
$term_item = $this->parse_category_node( $child );
|
707 |
-
if ( ! empty( $term_item ) ) {
|
708 |
-
$terms[] = $term_item;
|
709 |
-
}
|
710 |
-
break;
|
711 |
-
}// End switch().
|
712 |
-
}// End foreach().
|
713 |
-
|
714 |
-
return compact( 'data', 'meta', 'comments', 'terms' );
|
715 |
-
}
|
716 |
-
|
717 |
-
/**
|
718 |
-
* Create new posts based on import information
|
719 |
-
*
|
720 |
-
* Posts marked as having a parent which doesn't exist will become top level items.
|
721 |
-
* Doesn't create a new post if: the post type doesn't exist, the given post ID
|
722 |
-
* is already noted as imported or a post with the same title and date already exists.
|
723 |
-
* Note that new/updated terms, comments and meta are imported for the last of the above.
|
724 |
-
*/
|
725 |
-
protected function process_post( $data, $meta, $comments, $terms ) {
|
726 |
-
/**
|
727 |
-
* Pre-process post data.
|
728 |
-
*
|
729 |
-
* @param array $data Post data. (Return empty to skip.)
|
730 |
-
* @param array $meta Meta data.
|
731 |
-
* @param array $comments Comments on the post.
|
732 |
-
* @param array $terms Terms on the post.
|
733 |
-
*/
|
734 |
-
$data = apply_filters( 'wxr_importer.pre_process.post', $data, $meta, $comments, $terms );
|
735 |
-
if ( empty( $data ) ) {
|
736 |
-
return false;
|
737 |
-
}
|
738 |
-
|
739 |
-
$original_id = isset( $data['post_id'] ) ? (int) $data['post_id'] : 0;
|
740 |
-
$parent_id = isset( $data['post_parent'] ) ? (int) $data['post_parent'] : 0;
|
741 |
-
$author_id = isset( $data['post_author'] ) ? (int) $data['post_author'] : 0;
|
742 |
-
|
743 |
-
// Have we already processed this?
|
744 |
-
if ( isset( $this->mapping['post'][ $original_id ] ) ) {
|
745 |
-
return;
|
746 |
-
}
|
747 |
-
|
748 |
-
$post_type_object = get_post_type_object( $data['post_type'] );
|
749 |
-
|
750 |
-
// Is this type even valid?
|
751 |
-
if ( ! $post_type_object ) {
|
752 |
-
$this->logger->warning( sprintf(
|
753 |
-
__( 'Failed to import "%1$s": Invalid post type %2$s', 'wordpress-importer' ),
|
754 |
-
$data['post_title'],
|
755 |
-
$data['post_type']
|
756 |
-
) );
|
757 |
-
return false;
|
758 |
-
}
|
759 |
-
|
760 |
-
$post_exists = $this->post_exists( $data );
|
761 |
-
if ( $post_exists ) {
|
762 |
-
$this->logger->info( sprintf(
|
763 |
-
__( '%1$s "%2$s" already exists.', 'wordpress-importer' ),
|
764 |
-
$post_type_object->labels->singular_name,
|
765 |
-
$data['post_title']
|
766 |
-
) );
|
767 |
-
|
768 |
-
/**
|
769 |
-
* Post processing already imported.
|
770 |
-
*
|
771 |
-
* @param array $data Raw data imported for the post.
|
772 |
-
*/
|
773 |
-
do_action( 'wxr_importer.process_already_imported.post', $data );
|
774 |
-
|
775 |
-
// Even though this post already exists, new comments might need importing
|
776 |
-
$this->process_comments( $comments, $original_id, $data, $post_exists );
|
777 |
-
|
778 |
-
return false;
|
779 |
-
}
|
780 |
-
|
781 |
-
// Map the parent post, or mark it as one we need to fix
|
782 |
-
$requires_remapping = false;
|
783 |
-
if ( $parent_id ) {
|
784 |
-
if ( isset( $this->mapping['post'][ $parent_id ] ) ) {
|
785 |
-
$data['post_parent'] = $this->mapping['post'][ $parent_id ];
|
786 |
-
} else {
|
787 |
-
$meta[] = array(
|
788 |
-
'key' => '_wxr_import_parent',
|
789 |
-
'value' => $parent_id,
|
790 |
-
);
|
791 |
-
$requires_remapping = true;
|
792 |
-
|
793 |
-
$data['post_parent'] = 0;
|
794 |
-
}
|
795 |
-
}
|
796 |
-
|
797 |
-
// Map the author, or mark it as one we need to fix
|
798 |
-
$author = sanitize_user( $data['post_author'], true );
|
799 |
-
if ( empty( $author ) ) {
|
800 |
-
// Missing or invalid author, use default if available.
|
801 |
-
$data['post_author'] = $this->options['default_author'];
|
802 |
-
} elseif ( isset( $this->mapping['user_slug'][ $author ] ) ) {
|
803 |
-
$data['post_author'] = $this->mapping['user_slug'][ $author ];
|
804 |
-
} else {
|
805 |
-
$meta[] = array(
|
806 |
-
'key' => '_wxr_import_user_slug',
|
807 |
-
'value' => $author,
|
808 |
-
);
|
809 |
-
$requires_remapping = true;
|
810 |
-
|
811 |
-
$data['post_author'] = (int) get_current_user_id();
|
812 |
-
}
|
813 |
-
|
814 |
-
// Does the post look like it contains attachment images?
|
815 |
-
if ( preg_match( self::REGEX_HAS_ATTACHMENT_REFS, $data['post_content'] ) ) {
|
816 |
-
$meta[] = array(
|
817 |
-
'key' => '_wxr_import_has_attachment_refs',
|
818 |
-
'value' => true,
|
819 |
-
);
|
820 |
-
$requires_remapping = true;
|
821 |
-
}
|
822 |
-
|
823 |
-
// Whitelist to just the keys we allow
|
824 |
-
$postdata = array(
|
825 |
-
'import_id' => $data['post_id'],
|
826 |
-
);
|
827 |
-
$allowed = array(
|
828 |
-
'post_author' => true,
|
829 |
-
'post_date' => true,
|
830 |
-
'post_date_gmt' => true,
|
831 |
-
'post_content' => true,
|
832 |
-
'post_excerpt' => true,
|
833 |
-
'post_title' => true,
|
834 |
-
'post_status' => true,
|
835 |
-
'post_name' => true,
|
836 |
-
'comment_status' => true,
|
837 |
-
'ping_status' => true,
|
838 |
-
'guid' => true,
|
839 |
-
'post_parent' => true,
|
840 |
-
'menu_order' => true,
|
841 |
-
'post_type' => true,
|
842 |
-
'post_password' => true,
|
843 |
-
);
|
844 |
-
foreach ( $data as $key => $value ) {
|
845 |
-
if ( ! isset( $allowed[ $key ] ) ) {
|
846 |
-
continue;
|
847 |
-
}
|
848 |
-
|
849 |
-
$postdata[ $key ] = $data[ $key ];
|
850 |
-
}
|
851 |
-
|
852 |
-
$postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $data );
|
853 |
-
|
854 |
-
if ( 'attachment' === $postdata['post_type'] ) {
|
855 |
-
if ( ! $this->options['fetch_attachments'] ) {
|
856 |
-
$this->logger->notice( sprintf(
|
857 |
-
__( 'Skipping attachment "%s", fetching attachments disabled' ),
|
858 |
-
$data['post_title']
|
859 |
-
) );
|
860 |
-
/**
|
861 |
-
* Post processing skipped.
|
862 |
-
*
|
863 |
-
* @param array $data Raw data imported for the post.
|
864 |
-
* @param array $meta Raw meta data, already processed by {@see process_post_meta}.
|
865 |
-
*/
|
866 |
-
do_action( 'wxr_importer.process_skipped.post', $data, $meta );
|
867 |
-
return false;
|
868 |
-
}
|
869 |
-
$remote_url = ! empty( $data['attachment_url'] ) ? $data['attachment_url'] : $data['guid'];
|
870 |
-
$post_id = $this->process_attachment( $postdata, $meta, $remote_url );
|
871 |
-
} else {
|
872 |
-
$post_id = wp_insert_post( $postdata, true );
|
873 |
-
do_action( 'wp_import_insert_post', $post_id, $original_id, $postdata, $data );
|
874 |
-
}
|
875 |
-
|
876 |
-
if ( is_wp_error( $post_id ) ) {
|
877 |
-
$this->logger->error( sprintf(
|
878 |
-
__( 'Failed to import "%1$s" (%2$s)', 'wordpress-importer' ),
|
879 |
-
$data['post_title'],
|
880 |
-
$post_type_object->labels->singular_name
|
881 |
-
) );
|
882 |
-
$this->logger->debug( $post_id->get_error_message() );
|
883 |
-
|
884 |
-
/**
|
885 |
-
* Post processing failed.
|
886 |
-
*
|
887 |
-
* @param WP_Error $post_id Error object.
|
888 |
-
* @param array $data Raw data imported for the post.
|
889 |
-
* @param array $meta Raw meta data, already processed by {@see process_post_meta}.
|
890 |
-
* @param array $comments Raw comment data, already processed by {@see process_comments}.
|
891 |
-
* @param array $terms Raw term data, already processed.
|
892 |
-
*/
|
893 |
-
do_action( 'wxr_importer.process_failed.post', $post_id, $data, $meta, $comments, $terms );
|
894 |
-
return false;
|
895 |
-
}
|
896 |
-
|
897 |
-
// Ensure stickiness is handled correctly too
|
898 |
-
if ( $data['is_sticky'] === '1' ) {
|
899 |
-
stick_post( $post_id );
|
900 |
-
}
|
901 |
-
|
902 |
-
// map pre-import ID to local ID
|
903 |
-
$this->mapping['post'][ $original_id ] = (int) $post_id;
|
904 |
-
if ( $requires_remapping ) {
|
905 |
-
$this->requires_remapping['post'][ $post_id ] = true;
|
906 |
-
}
|
907 |
-
$this->mark_post_exists( $data, $post_id );
|
908 |
-
|
909 |
-
$this->logger->info( sprintf(
|
910 |
-
__( 'Imported "%1$s" (%2$s)', 'wordpress-importer' ),
|
911 |
-
$data['post_title'],
|
912 |
-
$post_type_object->labels->singular_name
|
913 |
-
) );
|
914 |
-
$this->logger->debug( sprintf(
|
915 |
-
__( 'Post %1$d remapped to %2$d', 'wordpress-importer' ),
|
916 |
-
$original_id,
|
917 |
-
$post_id
|
918 |
-
) );
|
919 |
-
|
920 |
-
// Handle the terms too
|
921 |
-
$terms = apply_filters( 'wp_import_post_terms', $terms, $post_id, $data );
|
922 |
-
|
923 |
-
if ( ! empty( $terms ) ) {
|
924 |
-
$term_ids = array();
|
925 |
-
foreach ( $terms as $term ) {
|
926 |
-
$taxonomy = $term['taxonomy'];
|
927 |
-
$key = sha1( $taxonomy . ':' . $term['slug'] );
|
928 |
-
|
929 |
-
if ( isset( $this->mapping['term'][ $key ] ) ) {
|
930 |
-
$term_ids[ $taxonomy ][] = (int) $this->mapping['term'][ $key ];
|
931 |
-
} else {
|
932 |
-
$meta[] = array(
|
933 |
-
'key' => '_wxr_import_term',
|
934 |
-
'value' => $term,
|
935 |
-
);
|
936 |
-
$requires_remapping = true;
|
937 |
-
}
|
938 |
-
}
|
939 |
-
|
940 |
-
foreach ( $term_ids as $tax => $ids ) {
|
941 |
-
$tt_ids = wp_set_post_terms( $post_id, $ids, $tax );
|
942 |
-
do_action( 'wp_import_set_post_terms', $tt_ids, $ids, $tax, $post_id, $data );
|
943 |
-
}
|
944 |
-
}
|
945 |
-
|
946 |
-
$this->process_comments( $comments, $post_id, $data );
|
947 |
-
$this->process_post_meta( $meta, $post_id, $data );
|
948 |
-
|
949 |
-
if ( 'nav_menu_item' === $data['post_type'] ) {
|
950 |
-
$this->process_menu_item_meta( $post_id, $data, $meta );
|
951 |
-
}
|
952 |
-
|
953 |
-
/**
|
954 |
-
* Post processing completed.
|
955 |
-
*
|
956 |
-
* @param int $post_id New post ID.
|
957 |
-
* @param array $data Raw data imported for the post.
|
958 |
-
* @param array $meta Raw meta data, already processed by {@see process_post_meta}.
|
959 |
-
* @param array $comments Raw comment data, already processed by {@see process_comments}.
|
960 |
-
* @param array $terms Raw term data, already processed.
|
961 |
-
*/
|
962 |
-
do_action( 'wxr_importer.processed.post', $post_id, $data, $meta, $comments, $terms );
|
963 |
-
}
|
964 |
-
|
965 |
-
/**
|
966 |
-
* Attempt to create a new menu item from import data
|
967 |
-
*
|
968 |
-
* Fails for draft, orphaned menu items and those without an associated nav_menu
|
969 |
-
* or an invalid nav_menu term. If the post type or term object which the menu item
|
970 |
-
* represents doesn't exist then the menu item will not be imported (waits until the
|
971 |
-
* end of the import to retry again before discarding).
|
972 |
-
*
|
973 |
-
* @param array $item Menu item details from WXR file
|
974 |
-
*/
|
975 |
-
protected function process_menu_item_meta( $post_id, $data, $meta ) {
|
976 |
-
|
977 |
-
$item_type = get_post_meta( $post_id, '_menu_item_type', true );
|
978 |
-
$original_object_id = get_post_meta( $post_id, '_menu_item_object_id', true );
|
979 |
-
$object_id = null;
|
980 |
-
|
981 |
-
$this->logger->debug( sprintf( 'Processing menu item %s', $item_type ) );
|
982 |
-
|
983 |
-
$requires_remapping = false;
|
984 |
-
switch ( $item_type ) {
|
985 |
-
case 'taxonomy':
|
986 |
-
if ( isset( $this->mapping['term_id'][ $original_object_id ] ) ) {
|
987 |
-
$object_id = $this->mapping['term_id'][ $original_object_id ];
|
988 |
-
} else {
|
989 |
-
add_post_meta( $post_id, '_wxr_import_menu_item', wp_slash( $original_object_id ) );
|
990 |
-
$requires_remapping = true;
|
991 |
-
}
|
992 |
-
break;
|
993 |
-
|
994 |
-
case 'post_type':
|
995 |
-
if ( isset( $this->mapping['post'][ $original_object_id ] ) ) {
|
996 |
-
$object_id = $this->mapping['post'][ $original_object_id ];
|
997 |
-
} else {
|
998 |
-
add_post_meta( $post_id, '_wxr_import_menu_item', wp_slash( $original_object_id ) );
|
999 |
-
$requires_remapping = true;
|
1000 |
-
}
|
1001 |
-
break;
|
1002 |
-
|
1003 |
-
case 'custom':
|
1004 |
-
// Custom refers to itself, wonderfully easy.
|
1005 |
-
$object_id = $post_id;
|
1006 |
-
break;
|
1007 |
-
|
1008 |
-
default:
|
1009 |
-
// associated object is missing or not imported yet, we'll retry later
|
1010 |
-
$this->missing_menu_items[] = $item;
|
1011 |
-
$this->logger->debug( 'Unknown menu item type' );
|
1012 |
-
break;
|
1013 |
-
}
|
1014 |
-
|
1015 |
-
if ( $requires_remapping ) {
|
1016 |
-
$this->requires_remapping['post'][ $post_id ] = true;
|
1017 |
-
}
|
1018 |
-
|
1019 |
-
if ( empty( $object_id ) ) {
|
1020 |
-
// Nothing needed here.
|
1021 |
-
return;
|
1022 |
-
}
|
1023 |
-
|
1024 |
-
$this->logger->debug( sprintf( 'Menu item %d mapped to %d', $original_object_id, $object_id ) );
|
1025 |
-
update_post_meta( $post_id, '_menu_item_object_id', wp_slash( $object_id ) );
|
1026 |
-
}
|
1027 |
-
|
1028 |
-
/**
|
1029 |
-
* If fetching attachments is enabled then attempt to create a new attachment
|
1030 |
-
*
|
1031 |
-
* @param array $post Attachment post details from WXR
|
1032 |
-
* @param string $url URL to fetch attachment from
|
1033 |
-
* @return int|WP_Error Post ID on success, WP_Error otherwise
|
1034 |
-
*/
|
1035 |
-
protected function process_attachment( $post, $meta, $remote_url ) {
|
1036 |
-
// try to use _wp_attached file for upload folder placement to ensure the same location as the export site
|
1037 |
-
// e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload()
|
1038 |
-
$post['upload_date'] = $post['post_date'];
|
1039 |
-
foreach ( $meta as $meta_item ) {
|
1040 |
-
if ( $meta_item['key'] !== '_wp_attached_file' ) {
|
1041 |
-
continue;
|
1042 |
-
}
|
1043 |
-
|
1044 |
-
if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta_item['value'], $matches ) ) {
|
1045 |
-
$post['upload_date'] = $matches[0];
|
1046 |
-
}
|
1047 |
-
break;
|
1048 |
-
}
|
1049 |
-
|
1050 |
-
// if the URL is absolute, but does not contain address, then upload it assuming base_site_url
|
1051 |
-
if ( preg_match( '|^/[\w\W]+$|', $remote_url ) ) {
|
1052 |
-
$remote_url = rtrim( $this->base_url, '/' ) . $remote_url;
|
1053 |
-
}
|
1054 |
-
|
1055 |
-
$upload = $this->fetch_remote_file( $remote_url, $post );
|
1056 |
-
if ( is_wp_error( $upload ) ) {
|
1057 |
-
return $upload;
|
1058 |
-
}
|
1059 |
-
|
1060 |
-
$info = wp_check_filetype( $upload['file'] );
|
1061 |
-
if ( ! $info ) {
|
1062 |
-
return new WP_Error( 'attachment_processing_error', __( 'Invalid file type', 'wordpress-importer' ) );
|
1063 |
-
}
|
1064 |
-
|
1065 |
-
$post['post_mime_type'] = $info['type'];
|
1066 |
-
|
1067 |
-
// WP really likes using the GUID for display. Allow updating it.
|
1068 |
-
// See https://core.trac.wordpress.org/ticket/33386
|
1069 |
-
if ( $this->options['update_attachment_guids'] ) {
|
1070 |
-
$post['guid'] = $upload['url'];
|
1071 |
-
}
|
1072 |
-
|
1073 |
-
// as per wp-admin/includes/upload.php
|
1074 |
-
$post_id = wp_insert_attachment( $post, $upload['file'] );
|
1075 |
-
if ( is_wp_error( $post_id ) ) {
|
1076 |
-
return $post_id;
|
1077 |
-
}
|
1078 |
-
|
1079 |
-
$attachment_metadata = wp_generate_attachment_metadata( $post_id, $upload['file'] );
|
1080 |
-
wp_update_attachment_metadata( $post_id, $attachment_metadata );
|
1081 |
-
|
1082 |
-
// Map this image URL later if we need to
|
1083 |
-
$this->url_remap[ $remote_url ] = $upload['url'];
|
1084 |
-
|
1085 |
-
// If we have a HTTPS URL, ensure the HTTP URL gets replaced too
|
1086 |
-
if ( substr( $remote_url, 0, 8 ) === 'https://' ) {
|
1087 |
-
$insecure_url = 'http' . substr( $remote_url, 5 );
|
1088 |
-
$this->url_remap[ $insecure_url ] = $upload['url'];
|
1089 |
-
}
|
1090 |
-
|
1091 |
-
if ( $this->options['aggressive_url_search'] ) {
|
1092 |
-
// remap resized image URLs, works by stripping the extension and remapping the URL stub.
|
1093 |
-
/*
|
1094 |
-
if ( preg_match( '!^image/!', $info['type'] ) ) {
|
1095 |
-
$parts = pathinfo( $remote_url );
|
1096 |
-
$name = basename( $parts['basename'], ".{$parts['extension']}" ); // PATHINFO_FILENAME in PHP 5.2
|
1097 |
-
|
1098 |
-
$parts_new = pathinfo( $upload['url'] );
|
1099 |
-
$name_new = basename( $parts_new['basename'], ".{$parts_new['extension']}" );
|
1100 |
-
|
1101 |
-
$this->url_remap[$parts['dirname'] . '/' . $name] = $parts_new['dirname'] . '/' . $name_new;
|
1102 |
-
}*/
|
1103 |
-
}
|
1104 |
-
|
1105 |
-
return $post_id;
|
1106 |
-
}
|
1107 |
-
|
1108 |
-
/**
|
1109 |
-
* Parse a meta node into meta data.
|
1110 |
-
*
|
1111 |
-
* @param DOMElement $node Parent node of meta data (typically `wp:postmeta` or `wp:commentmeta`).
|
1112 |
-
* @return array|null Meta data array on success, or null on error.
|
1113 |
-
*/
|
1114 |
-
protected function parse_meta_node( $node ) {
|
1115 |
-
foreach ( $node->childNodes as $child ) {
|
1116 |
-
// We only care about child elements
|
1117 |
-
if ( $child->nodeType !== XML_ELEMENT_NODE ) {
|
1118 |
-
continue;
|
1119 |
-
}
|
1120 |
-
|
1121 |
-
switch ( $child->tagName ) {
|
1122 |
-
case 'wp:meta_key':
|
1123 |
-
$key = $child->textContent;
|
1124 |
-
break;
|
1125 |
-
|
1126 |
-
case 'wp:meta_value':
|
1127 |
-
$value = $child->textContent;
|
1128 |
-
break;
|
1129 |
-
}
|
1130 |
-
}
|
1131 |
-
|
1132 |
-
if ( empty( $key ) || empty( $value ) ) {
|
1133 |
-
return null;
|
1134 |
-
}
|
1135 |
-
|
1136 |
-
return compact( 'key', 'value' );
|
1137 |
-
}
|
1138 |
-
|
1139 |
-
/**
|
1140 |
-
* Process and import post meta items.
|
1141 |
-
*
|
1142 |
-
* @param array $meta List of meta data arrays
|
1143 |
-
* @param int $post_id Post to associate with
|
1144 |
-
* @param array $post Post data
|
1145 |
-
* @return int|WP_Error Number of meta items imported on success, error otherwise.
|
1146 |
-
*/
|
1147 |
-
protected function process_post_meta( $meta, $post_id, $post ) {
|
1148 |
-
if ( empty( $meta ) ) {
|
1149 |
-
return true;
|
1150 |
-
}
|
1151 |
-
|
1152 |
-
foreach ( $meta as $meta_item ) {
|
1153 |
-
/**
|
1154 |
-
* Pre-process post meta data.
|
1155 |
-
*
|
1156 |
-
* @param array $meta_item Meta data. (Return empty to skip.)
|
1157 |
-
* @param int $post_id Post the meta is attached to.
|
1158 |
-
*/
|
1159 |
-
$meta_item = apply_filters( 'wxr_importer.pre_process.post_meta', $meta_item, $post_id );
|
1160 |
-
if ( empty( $meta_item ) ) {
|
1161 |
-
return false;
|
1162 |
-
}
|
1163 |
-
|
1164 |
-
$key = apply_filters( 'import_post_meta_key', $meta_item['key'], $post_id, $post );
|
1165 |
-
$value = false;
|
1166 |
-
|
1167 |
-
if ( '_edit_last' === $key ) {
|
1168 |
-
$value = intval( $meta_item['value'] );
|
1169 |
-
if ( ! isset( $this->mapping['user'][ $value ] ) ) {
|
1170 |
-
// Skip!
|
1171 |
-
continue;
|
1172 |
-
}
|
1173 |
-
|
1174 |
-
$value = $this->mapping['user'][ $value ];
|
1175 |
-
}
|
1176 |
-
|
1177 |
-
if ( $key ) {
|
1178 |
-
// export gets meta straight from the DB so could have a serialized string
|
1179 |
-
if ( ! $value ) {
|
1180 |
-
$value = maybe_unserialize( $meta_item['value'] );
|
1181 |
-
}
|
1182 |
-
|
1183 |
-
add_post_meta( $post_id, $key, $value );
|
1184 |
-
do_action( 'import_post_meta', $post_id, $key, $value );
|
1185 |
-
|
1186 |
-
// if the post has a featured image, take note of this in case of remap
|
1187 |
-
if ( '_thumbnail_id' === $key ) {
|
1188 |
-
$this->featured_images[ $post_id ] = (int) $value;
|
1189 |
-
}
|
1190 |
-
}
|
1191 |
-
}// End foreach().
|
1192 |
-
|
1193 |
-
return true;
|
1194 |
-
}
|
1195 |
-
|
1196 |
-
/**
|
1197 |
-
* Parse a comment node into comment data.
|
1198 |
-
*
|
1199 |
-
* @param DOMElement $node Parent node of comment data (typically `wp:comment`).
|
1200 |
-
* @return array Comment data array.
|
1201 |
-
*/
|
1202 |
-
protected function parse_comment_node( $node ) {
|
1203 |
-
$data = array(
|
1204 |
-
'commentmeta' => array(),
|
1205 |
-
);
|
1206 |
-
|
1207 |
-
foreach ( $node->childNodes as $child ) {
|
1208 |
-
// We only care about child elements
|
1209 |
-
if ( $child->nodeType !== XML_ELEMENT_NODE ) {
|
1210 |
-
continue;
|
1211 |
-
}
|
1212 |
-
|
1213 |
-
switch ( $child->tagName ) {
|
1214 |
-
case 'wp:comment_id':
|
1215 |
-
$data['comment_id'] = $child->textContent;
|
1216 |
-
break;
|
1217 |
-
case 'wp:comment_author':
|
1218 |
-
$data['comment_author'] = $child->textContent;
|
1219 |
-
break;
|
1220 |
-
|
1221 |
-
case 'wp:comment_author_email':
|
1222 |
-
$data['comment_author_email'] = $child->textContent;
|
1223 |
-
break;
|
1224 |
-
|
1225 |
-
case 'wp:comment_author_IP':
|
1226 |
-
$data['comment_author_IP'] = $child->textContent;
|
1227 |
-
break;
|
1228 |
-
|
1229 |
-
case 'wp:comment_author_url':
|
1230 |
-
$data['comment_author_url'] = $child->textContent;
|
1231 |
-
break;
|
1232 |
-
|
1233 |
-
case 'wp:comment_user_id':
|
1234 |
-
$data['comment_user_id'] = $child->textContent;
|
1235 |
-
break;
|
1236 |
-
|
1237 |
-
case 'wp:comment_date':
|
1238 |
-
$data['comment_date'] = $child->textContent;
|
1239 |
-
break;
|
1240 |
-
|
1241 |
-
case 'wp:comment_date_gmt':
|
1242 |
-
$data['comment_date_gmt'] = $child->textContent;
|
1243 |
-
break;
|
1244 |
-
|
1245 |
-
case 'wp:comment_content':
|
1246 |
-
$data['comment_content'] = $child->textContent;
|
1247 |
-
break;
|
1248 |
-
|
1249 |
-
case 'wp:comment_approved':
|
1250 |
-
$data['comment_approved'] = $child->textContent;
|
1251 |
-
break;
|
1252 |
-
|
1253 |
-
case 'wp:comment_type':
|
1254 |
-
$data['comment_type'] = $child->textContent;
|
1255 |
-
break;
|
1256 |
-
|
1257 |
-
case 'wp:comment_parent':
|
1258 |
-
$data['comment_parent'] = $child->textContent;
|
1259 |
-
break;
|
1260 |
-
|
1261 |
-
case 'wp:commentmeta':
|
1262 |
-
$meta_item = $this->parse_meta_node( $child );
|
1263 |
-
if ( ! empty( $meta_item ) ) {
|
1264 |
-
$data['commentmeta'][] = $meta_item;
|
1265 |
-
}
|
1266 |
-
break;
|
1267 |
-
}// End switch().
|
1268 |
-
}// End foreach().
|
1269 |
-
|
1270 |
-
return $data;
|
1271 |
-
}
|
1272 |
-
|
1273 |
-
/**
|
1274 |
-
* Process and import comment data.
|
1275 |
-
*
|
1276 |
-
* @param array $comments List of comment data arrays.
|
1277 |
-
* @param int $post_id Post to associate with.
|
1278 |
-
* @param array $post Post data.
|
1279 |
-
* @return int|WP_Error Number of comments imported on success, error otherwise.
|
1280 |
-
*/
|
1281 |
-
protected function process_comments( $comments, $post_id, $post, $post_exists = false ) {
|
1282 |
-
|
1283 |
-
$comments = apply_filters( 'wp_import_post_comments', $comments, $post_id, $post );
|
1284 |
-
if ( empty( $comments ) ) {
|
1285 |
-
return 0;
|
1286 |
-
}
|
1287 |
-
|
1288 |
-
$num_comments = 0;
|
1289 |
-
|
1290 |
-
// Sort by ID to avoid excessive remapping later
|
1291 |
-
usort( $comments, array( $this, 'sort_comments_by_id' ) );
|
1292 |
-
|
1293 |
-
foreach ( $comments as $key => $comment ) {
|
1294 |
-
/**
|
1295 |
-
* Pre-process comment data
|
1296 |
-
*
|
1297 |
-
* @param array $comment Comment data. (Return empty to skip.)
|
1298 |
-
* @param int $post_id Post the comment is attached to.
|
1299 |
-
*/
|
1300 |
-
$comment = apply_filters( 'wxr_importer.pre_process.comment', $comment, $post_id );
|
1301 |
-
if ( empty( $comment ) ) {
|
1302 |
-
return false;
|
1303 |
-
}
|
1304 |
-
|
1305 |
-
$original_id = isset( $comment['comment_id'] ) ? (int) $comment['comment_id'] : 0;
|
1306 |
-
$parent_id = isset( $comment['comment_parent'] ) ? (int) $comment['comment_parent'] : 0;
|
1307 |
-
$author_id = isset( $comment['comment_user_id'] ) ? (int) $comment['comment_user_id'] : 0;
|
1308 |
-
|
1309 |
-
// if this is a new post we can skip the comment_exists() check
|
1310 |
-
// TODO: Check comment_exists for performance
|
1311 |
-
if ( $post_exists ) {
|
1312 |
-
$existing = $this->comment_exists( $comment );
|
1313 |
-
if ( $existing ) {
|
1314 |
-
|
1315 |
-
/**
|
1316 |
-
* Comment processing already imported.
|
1317 |
-
*
|
1318 |
-
* @param array $comment Raw data imported for the comment.
|
1319 |
-
*/
|
1320 |
-
do_action( 'wxr_importer.process_already_imported.comment', $comment );
|
1321 |
-
|
1322 |
-
$this->mapping['comment'][ $original_id ] = $existing;
|
1323 |
-
continue;
|
1324 |
-
}
|
1325 |
-
}
|
1326 |
-
|
1327 |
-
// Remove meta from the main array
|
1328 |
-
$meta = isset( $comment['commentmeta'] ) ? $comment['commentmeta'] : array();
|
1329 |
-
unset( $comment['commentmeta'] );
|
1330 |
-
|
1331 |
-
// Map the parent comment, or mark it as one we need to fix
|
1332 |
-
$requires_remapping = false;
|
1333 |
-
if ( $parent_id ) {
|
1334 |
-
if ( isset( $this->mapping['comment'][ $parent_id ] ) ) {
|
1335 |
-
$comment['comment_parent'] = $this->mapping['comment'][ $parent_id ];
|
1336 |
-
} else {
|
1337 |
-
// Prepare for remapping later
|
1338 |
-
$meta[] = array(
|
1339 |
-
'key' => '_wxr_import_parent',
|
1340 |
-
'value' => $parent_id,
|
1341 |
-
);
|
1342 |
-
$requires_remapping = true;
|
1343 |
-
|
1344 |
-
// Wipe the parent for now
|
1345 |
-
$comment['comment_parent'] = 0;
|
1346 |
-
}
|
1347 |
-
}
|
1348 |
-
|
1349 |
-
// Map the author, or mark it as one we need to fix
|
1350 |
-
if ( $author_id ) {
|
1351 |
-
if ( isset( $this->mapping['user'][ $author_id ] ) ) {
|
1352 |
-
$comment['user_id'] = $this->mapping['user'][ $author_id ];
|
1353 |
-
} else {
|
1354 |
-
// Prepare for remapping later
|
1355 |
-
$meta[] = array(
|
1356 |
-
'key' => '_wxr_import_user',
|
1357 |
-
'value' => $author_id,
|
1358 |
-
);
|
1359 |
-
$requires_remapping = true;
|
1360 |
-
|
1361 |
-
// Wipe the user for now
|
1362 |
-
$comment['user_id'] = 0;
|
1363 |
-
}
|
1364 |
-
}
|
1365 |
-
|
1366 |
-
// Run standard core filters
|
1367 |
-
$comment['comment_post_ID'] = $post_id;
|
1368 |
-
$comment = wp_filter_comment( $comment );
|
1369 |
-
|
1370 |
-
// wp_insert_comment expects slashed data
|
1371 |
-
$comment_id = wp_insert_comment( wp_slash( $comment ) );
|
1372 |
-
$this->mapping['comment'][ $original_id ] = $comment_id;
|
1373 |
-
if ( $requires_remapping ) {
|
1374 |
-
$this->requires_remapping['comment'][ $comment_id ] = true;
|
1375 |
-
}
|
1376 |
-
$this->mark_comment_exists( $comment, $comment_id );
|
1377 |
-
|
1378 |
-
/**
|
1379 |
-
* Comment has been imported.
|
1380 |
-
*
|
1381 |
-
* @param int $comment_id New comment ID
|
1382 |
-
* @param array $comment Comment inserted (`comment_id` item refers to the original ID)
|
1383 |
-
* @param int $post_id Post parent of the comment
|
1384 |
-
* @param array $post Post data
|
1385 |
-
*/
|
1386 |
-
do_action( 'wp_import_insert_comment', $comment_id, $comment, $post_id, $post );
|
1387 |
-
|
1388 |
-
// Process the meta items
|
1389 |
-
foreach ( $meta as $meta_item ) {
|
1390 |
-
$value = maybe_unserialize( $meta_item['value'] );
|
1391 |
-
add_comment_meta( $comment_id, wp_slash( $meta_item['key'] ), wp_slash( $value ) );
|
1392 |
-
}
|
1393 |
-
|
1394 |
-
/**
|
1395 |
-
* Post processing completed.
|
1396 |
-
*
|
1397 |
-
* @param int $post_id New post ID.
|
1398 |
-
* @param array $comment Raw data imported for the comment.
|
1399 |
-
* @param array $meta Raw meta data, already processed by {@see process_post_meta}.
|
1400 |
-
* @param array $post_id Parent post ID.
|
1401 |
-
*/
|
1402 |
-
do_action( 'wxr_importer.processed.comment', $comment_id, $comment, $meta, $post_id );
|
1403 |
-
|
1404 |
-
$num_comments++;
|
1405 |
-
}// End foreach().
|
1406 |
-
|
1407 |
-
return $num_comments;
|
1408 |
-
}
|
1409 |
-
|
1410 |
-
protected function parse_category_node( $node ) {
|
1411 |
-
$data = array(
|
1412 |
-
// Default taxonomy to "category", since this is a `<category>` tag
|
1413 |
-
'taxonomy' => 'category',
|
1414 |
-
);
|
1415 |
-
$meta = array();
|
1416 |
-
|
1417 |
-
if ( $node->hasAttribute( 'domain' ) ) {
|
1418 |
-
$data['taxonomy'] = $node->getAttribute( 'domain' );
|
1419 |
-
}
|
1420 |
-
if ( $node->hasAttribute( 'nicename' ) ) {
|
1421 |
-
$data['slug'] = $node->getAttribute( 'nicename' );
|
1422 |
-
}
|
1423 |
-
|
1424 |
-
$data['name'] = $node->textContent;
|
1425 |
-
|
1426 |
-
if ( empty( $data['slug'] ) ) {
|
1427 |
-
return null;
|
1428 |
-
}
|
1429 |
-
|
1430 |
-
// Just for extra compatibility
|
1431 |
-
if ( $data['taxonomy'] === 'tag' ) {
|
1432 |
-
$data['taxonomy'] = 'post_tag';
|
1433 |
-
}
|
1434 |
-
|
1435 |
-
return $data;
|
1436 |
-
}
|
1437 |
-
|
1438 |
-
/**
|
1439 |
-
* Callback for `usort` to sort comments by ID
|
1440 |
-
*
|
1441 |
-
* @param array $a Comment data for the first comment
|
1442 |
-
* @param array $b Comment data for the second comment
|
1443 |
-
* @return int
|
1444 |
-
*/
|
1445 |
-
public static function sort_comments_by_id( $a, $b ) {
|
1446 |
-
if ( empty( $a['comment_id'] ) ) {
|
1447 |
-
return 1;
|
1448 |
-
}
|
1449 |
-
|
1450 |
-
if ( empty( $b['comment_id'] ) ) {
|
1451 |
-
return -1;
|
1452 |
-
}
|
1453 |
-
|
1454 |
-
return $a['comment_id'] - $b['comment_id'];
|
1455 |
-
}
|
1456 |
-
|
1457 |
-
protected function parse_author_node( $node ) {
|
1458 |
-
$data = array();
|
1459 |
-
$meta = array();
|
1460 |
-
foreach ( $node->childNodes as $child ) {
|
1461 |
-
// We only care about child elements
|
1462 |
-
if ( $child->nodeType !== XML_ELEMENT_NODE ) {
|
1463 |
-
continue;
|
1464 |
-
}
|
1465 |
-
|
1466 |
-
switch ( $child->tagName ) {
|
1467 |
-
case 'wp:author_login':
|
1468 |
-
$data['user_login'] = $child->textContent;
|
1469 |
-
break;
|
1470 |
-
|
1471 |
-
case 'wp:author_id':
|
1472 |
-
$data['ID'] = $child->textContent;
|
1473 |
-
break;
|
1474 |
-
|
1475 |
-
case 'wp:author_email':
|
1476 |
-
$data['user_email'] = $child->textContent;
|
1477 |
-
break;
|
1478 |
-
|
1479 |
-
case 'wp:author_display_name':
|
1480 |
-
$data['display_name'] = $child->textContent;
|
1481 |
-
break;
|
1482 |
-
|
1483 |
-
case 'wp:author_first_name':
|
1484 |
-
$data['first_name'] = $child->textContent;
|
1485 |
-
break;
|
1486 |
-
|
1487 |
-
case 'wp:author_last_name':
|
1488 |
-
$data['last_name'] = $child->textContent;
|
1489 |
-
break;
|
1490 |
-
}
|
1491 |
-
}
|
1492 |
-
|
1493 |
-
return compact( 'data', 'meta' );
|
1494 |
-
}
|
1495 |
-
|
1496 |
-
protected function process_author( $data, $meta ) {
|
1497 |
-
/**
|
1498 |
-
* Pre-process user data.
|
1499 |
-
*
|
1500 |
-
* @param array $data User data. (Return empty to skip.)
|
1501 |
-
* @param array $meta Meta data.
|
1502 |
-
*/
|
1503 |
-
$data = apply_filters( 'wxr_importer.pre_process.user', $data, $meta );
|
1504 |
-
if ( empty( $data ) ) {
|
1505 |
-
return false;
|
1506 |
-
}
|
1507 |
-
|
1508 |
-
// Have we already handled this user?
|
1509 |
-
$original_id = isset( $data['ID'] ) ? $data['ID'] : 0;
|
1510 |
-
$original_slug = $data['user_login'];
|
1511 |
-
|
1512 |
-
if ( isset( $this->mapping['user'][ $original_id ] ) ) {
|
1513 |
-
$existing = $this->mapping['user'][ $original_id ];
|
1514 |
-
|
1515 |
-
// Note the slug mapping if we need to too
|
1516 |
-
if ( ! isset( $this->mapping['user_slug'][ $original_slug ] ) ) {
|
1517 |
-
$this->mapping['user_slug'][ $original_slug ] = $existing;
|
1518 |
-
}
|
1519 |
-
|
1520 |
-
return false;
|
1521 |
-
}
|
1522 |
-
|
1523 |
-
if ( isset( $this->mapping['user_slug'][ $original_slug ] ) ) {
|
1524 |
-
$existing = $this->mapping['user_slug'][ $original_slug ];
|
1525 |
-
|
1526 |
-
// Ensure we note the mapping too
|
1527 |
-
$this->mapping['user'][ $original_id ] = $existing;
|
1528 |
-
|
1529 |
-
return false;
|
1530 |
-
}
|
1531 |
-
|
1532 |
-
// Allow overriding the user's slug
|
1533 |
-
$login = $original_slug;
|
1534 |
-
if ( isset( $this->user_slug_override[ $login ] ) ) {
|
1535 |
-
$login = $this->user_slug_override[ $login ];
|
1536 |
-
}
|
1537 |
-
|
1538 |
-
$userdata = array(
|
1539 |
-
'user_login' => sanitize_user( $login, true ),
|
1540 |
-
'user_pass' => wp_generate_password(),
|
1541 |
-
);
|
1542 |
-
|
1543 |
-
$allowed = array(
|
1544 |
-
'user_email' => true,
|
1545 |
-
'display_name' => true,
|
1546 |
-
'first_name' => true,
|
1547 |
-
'last_name' => true,
|
1548 |
-
);
|
1549 |
-
foreach ( $data as $key => $value ) {
|
1550 |
-
if ( ! isset( $allowed[ $key ] ) ) {
|
1551 |
-
continue;
|
1552 |
-
}
|
1553 |
-
|
1554 |
-
$userdata[ $key ] = $data[ $key ];
|
1555 |
-
}
|
1556 |
-
|
1557 |
-
$user_id = wp_insert_user( wp_slash( $userdata ) );
|
1558 |
-
if ( is_wp_error( $user_id ) ) {
|
1559 |
-
$this->logger->error( sprintf(
|
1560 |
-
__( 'Failed to import user "%s"', 'wordpress-importer' ),
|
1561 |
-
$userdata['user_login']
|
1562 |
-
) );
|
1563 |
-
$this->logger->debug( $user_id->get_error_message() );
|
1564 |
-
|
1565 |
-
/**
|
1566 |
-
* User processing failed.
|
1567 |
-
*
|
1568 |
-
* @param WP_Error $user_id Error object.
|
1569 |
-
* @param array $userdata Raw data imported for the user.
|
1570 |
-
*/
|
1571 |
-
do_action( 'wxr_importer.process_failed.user', $user_id, $userdata );
|
1572 |
-
return false;
|
1573 |
-
}
|
1574 |
-
|
1575 |
-
if ( $original_id ) {
|
1576 |
-
$this->mapping['user'][ $original_id ] = $user_id;
|
1577 |
-
}
|
1578 |
-
$this->mapping['user_slug'][ $original_slug ] = $user_id;
|
1579 |
-
|
1580 |
-
$this->logger->info( sprintf(
|
1581 |
-
__( 'Imported user "%s"', 'wordpress-importer' ),
|
1582 |
-
$userdata['user_login']
|
1583 |
-
) );
|
1584 |
-
$this->logger->debug( sprintf(
|
1585 |
-
__( 'User %1$d remapped to %2$d', 'wordpress-importer' ),
|
1586 |
-
$original_id,
|
1587 |
-
$user_id
|
1588 |
-
) );
|
1589 |
-
|
1590 |
-
// TODO: Implement meta handling once WXR includes it
|
1591 |
-
/**
|
1592 |
-
* User processing completed.
|
1593 |
-
*
|
1594 |
-
* @param int $user_id New user ID.
|
1595 |
-
* @param array $userdata Raw data imported for the user.
|
1596 |
-
*/
|
1597 |
-
do_action( 'wxr_importer.processed.user', $user_id, $userdata );
|
1598 |
-
}
|
1599 |
-
|
1600 |
-
protected function parse_term_node( $node, $type = 'term' ) {
|
1601 |
-
$data = array();
|
1602 |
-
$meta = array();
|
1603 |
-
|
1604 |
-
$tag_name = array(
|
1605 |
-
'id' => 'wp:term_id',
|
1606 |
-
'taxonomy' => 'wp:term_taxonomy',
|
1607 |
-
'slug' => 'wp:term_slug',
|
1608 |
-
'parent' => 'wp:term_parent',
|
1609 |
-
'name' => 'wp:term_name',
|
1610 |
-
'description' => 'wp:term_description',
|
1611 |
-
);
|
1612 |
-
$taxonomy = null;
|
1613 |
-
|
1614 |
-
// Special casing!
|
1615 |
-
switch ( $type ) {
|
1616 |
-
case 'category':
|
1617 |
-
$tag_name['slug'] = 'wp:category_nicename';
|
1618 |
-
$tag_name['parent'] = 'wp:category_parent';
|
1619 |
-
$tag_name['name'] = 'wp:cat_name';
|
1620 |
-
$tag_name['description'] = 'wp:category_description';
|
1621 |
-
$tag_name['taxonomy'] = null;
|
1622 |
-
|
1623 |
-
$data['taxonomy'] = 'category';
|
1624 |
-
break;
|
1625 |
-
|
1626 |
-
case 'tag':
|
1627 |
-
$tag_name['slug'] = 'wp:tag_slug';
|
1628 |
-
$tag_name['parent'] = null;
|
1629 |
-
$tag_name['name'] = 'wp:tag_name';
|
1630 |
-
$tag_name['description'] = 'wp:tag_description';
|
1631 |
-
$tag_name['taxonomy'] = null;
|
1632 |
-
|
1633 |
-
$data['taxonomy'] = 'post_tag';
|
1634 |
-
break;
|
1635 |
-
}
|
1636 |
-
|
1637 |
-
foreach ( $node->childNodes as $child ) {
|
1638 |
-
// We only care about child elements
|
1639 |
-
if ( $child->nodeType !== XML_ELEMENT_NODE ) {
|
1640 |
-
continue;
|
1641 |
-
}
|
1642 |
-
|
1643 |
-
$key = array_search( $child->tagName, $tag_name );
|
1644 |
-
if ( $key ) {
|
1645 |
-
$data[ $key ] = $child->textContent;
|
1646 |
-
}
|
1647 |
-
}
|
1648 |
-
|
1649 |
-
if ( empty( $data['taxonomy'] ) ) {
|
1650 |
-
return null;
|
1651 |
-
}
|
1652 |
-
|
1653 |
-
// Compatibility with WXR 1.0
|
1654 |
-
if ( $data['taxonomy'] === 'tag' ) {
|
1655 |
-
$data['taxonomy'] = 'post_tag';
|
1656 |
-
}
|
1657 |
-
|
1658 |
-
return compact( 'data', 'meta' );
|
1659 |
-
}
|
1660 |
-
|
1661 |
-
protected function process_term( $data, $meta ) {
|
1662 |
-
/**
|
1663 |
-
* Pre-process term data.
|
1664 |
-
*
|
1665 |
-
* @param array $data Term data. (Return empty to skip.)
|
1666 |
-
* @param array $meta Meta data.
|
1667 |
-
*/
|
1668 |
-
$data = apply_filters( 'wxr_importer.pre_process.term', $data, $meta );
|
1669 |
-
if ( empty( $data ) ) {
|
1670 |
-
return false;
|
1671 |
-
}
|
1672 |
-
|
1673 |
-
$original_id = isset( $data['id'] ) ? (int) $data['id'] : 0;
|
1674 |
-
$parent_id = isset( $data['parent'] ) ? (int) $data['parent'] : 0;
|
1675 |
-
|
1676 |
-
$mapping_key = sha1( $data['taxonomy'] . ':' . $data['slug'] );
|
1677 |
-
$existing = $this->term_exists( $data );
|
1678 |
-
if ( $existing ) {
|
1679 |
-
|
1680 |
-
/**
|
1681 |
-
* Term processing already imported.
|
1682 |
-
*
|
1683 |
-
* @param array $data Raw data imported for the term.
|
1684 |
-
*/
|
1685 |
-
do_action( 'wxr_importer.process_already_imported.term', $data );
|
1686 |
-
|
1687 |
-
$this->mapping['term'][ $mapping_key ] = $existing;
|
1688 |
-
$this->mapping['term_id'][ $original_id ] = $existing;
|
1689 |
-
return false;
|
1690 |
-
}
|
1691 |
-
|
1692 |
-
// WP really likes to repeat itself in export files
|
1693 |
-
if ( isset( $this->mapping['term'][ $mapping_key ] ) ) {
|
1694 |
-
return false;
|
1695 |
-
}
|
1696 |
-
|
1697 |
-
$termdata = array();
|
1698 |
-
$allowed = array(
|
1699 |
-
'slug' => true,
|
1700 |
-
'description' => true,
|
1701 |
-
);
|
1702 |
-
|
1703 |
-
// Map the parent comment, or mark it as one we need to fix
|
1704 |
-
// TODO: add parent mapping and remapping
|
1705 |
-
/*
|
1706 |
-
$requires_remapping = false;
|
1707 |
-
if ( $parent_id ) {
|
1708 |
-
if ( isset( $this->mapping['term'][ $parent_id ] ) ) {
|
1709 |
-
$data['parent'] = $this->mapping['term'][ $parent_id ];
|
1710 |
-
} else {
|
1711 |
-
// Prepare for remapping later
|
1712 |
-
$meta[] = array( 'key' => '_wxr_import_parent', 'value' => $parent_id );
|
1713 |
-
$requires_remapping = true;
|
1714 |
-
|
1715 |
-
// Wipe the parent for now
|
1716 |
-
$data['parent'] = 0;
|
1717 |
-
}
|
1718 |
-
}*/
|
1719 |
-
|
1720 |
-
foreach ( $data as $key => $value ) {
|
1721 |
-
if ( ! isset( $allowed[ $key ] ) ) {
|
1722 |
-
continue;
|
1723 |
-
}
|
1724 |
-
|
1725 |
-
$termdata[ $key ] = $data[ $key ];
|
1726 |
-
}
|
1727 |
-
|
1728 |
-
$result = wp_insert_term( $data['name'], $data['taxonomy'], $termdata );
|
1729 |
-
if ( is_wp_error( $result ) ) {
|
1730 |
-
$this->logger->warning( sprintf(
|
1731 |
-
__( 'Failed to import %1$s %2$s', 'wordpress-importer' ),
|
1732 |
-
$data['taxonomy'],
|
1733 |
-
$data['name']
|
1734 |
-
) );
|
1735 |
-
$this->logger->debug( $result->get_error_message() );
|
1736 |
-
do_action( 'wp_import_insert_term_failed', $result, $data );
|
1737 |
-
|
1738 |
-
/**
|
1739 |
-
* Term processing failed.
|
1740 |
-
*
|
1741 |
-
* @param WP_Error $result Error object.
|
1742 |
-
* @param array $data Raw data imported for the term.
|
1743 |
-
* @param array $meta Meta data supplied for the term.
|
1744 |
-
*/
|
1745 |
-
do_action( 'wxr_importer.process_failed.term', $result, $data, $meta );
|
1746 |
-
return false;
|
1747 |
-
}
|
1748 |
-
|
1749 |
-
$term_id = $result['term_id'];
|
1750 |
-
|
1751 |
-
$this->mapping['term'][ $mapping_key ] = $term_id;
|
1752 |
-
$this->mapping['term_id'][ $original_id ] = $term_id;
|
1753 |
-
|
1754 |
-
$this->logger->info( sprintf(
|
1755 |
-
__( 'Imported "%1$s" (%2$s)', 'wordpress-importer' ),
|
1756 |
-
$data['name'],
|
1757 |
-
$data['taxonomy']
|
1758 |
-
) );
|
1759 |
-
$this->logger->debug( sprintf(
|
1760 |
-
__( 'Term %1$d remapped to %2$d', 'wordpress-importer' ),
|
1761 |
-
$original_id,
|
1762 |
-
$term_id
|
1763 |
-
) );
|
1764 |
-
|
1765 |
-
do_action( 'wp_import_insert_term', $term_id, $data );
|
1766 |
-
|
1767 |
-
/**
|
1768 |
-
* Term processing completed.
|
1769 |
-
*
|
1770 |
-
* @param int $term_id New term ID.
|
1771 |
-
* @param array $data Raw data imported for the term.
|
1772 |
-
*/
|
1773 |
-
do_action( 'wxr_importer.processed.term', $term_id, $data );
|
1774 |
-
}
|
1775 |
-
|
1776 |
-
/**
|
1777 |
-
* Attempt to download a remote file attachment
|
1778 |
-
*
|
1779 |
-
* @param string $url URL of item to fetch
|
1780 |
-
* @param array $post Attachment details
|
1781 |
-
* @return array|WP_Error Local file location details on success, WP_Error otherwise
|
1782 |
-
*/
|
1783 |
-
protected function fetch_remote_file( $url, $post ) {
|
1784 |
-
// extract the file name and extension from the url
|
1785 |
-
$file_name = basename( $url );
|
1786 |
-
|
1787 |
-
// get placeholder file in the upload dir with a unique, sanitized filename
|
1788 |
-
$upload = wp_upload_bits( $file_name, 0, '', $post['upload_date'] );
|
1789 |
-
if ( $upload['error'] ) {
|
1790 |
-
return new WP_Error( 'upload_dir_error', $upload['error'] );
|
1791 |
-
}
|
1792 |
-
|
1793 |
-
// fetch the remote url and write it to the placeholder file
|
1794 |
-
$response = wp_remote_get( $url, array(
|
1795 |
-
'stream' => true,
|
1796 |
-
'filename' => $upload['file'],
|
1797 |
-
) );
|
1798 |
-
|
1799 |
-
// request failed
|
1800 |
-
if ( is_wp_error( $response ) ) {
|
1801 |
-
unlink( $upload['file'] );
|
1802 |
-
return $response;
|
1803 |
-
}
|
1804 |
-
|
1805 |
-
$code = (int) wp_remote_retrieve_response_code( $response );
|
1806 |
-
|
1807 |
-
// make sure the fetch was successful
|
1808 |
-
if ( $code !== 200 ) {
|
1809 |
-
unlink( $upload['file'] );
|
1810 |
-
return new WP_Error(
|
1811 |
-
'import_file_error',
|
1812 |
-
sprintf(
|
1813 |
-
__( 'Remote server returned %1$d %2$s for %3$s', 'wordpress-importer' ),
|
1814 |
-
$code,
|
1815 |
-
get_status_header_desc( $code ),
|
1816 |
-
$url
|
1817 |
-
)
|
1818 |
-
);
|
1819 |
-
}
|
1820 |
-
|
1821 |
-
$filesize = filesize( $upload['file'] );
|
1822 |
-
$headers = wp_remote_retrieve_headers( $response );
|
1823 |
-
|
1824 |
-
if ( isset( $headers['content-length'] ) && $filesize !== (int) $headers['content-length'] ) {
|
1825 |
-
unlink( $upload['file'] );
|
1826 |
-
return new WP_Error( 'import_file_error', __( 'Remote file is incorrect size', 'wordpress-importer' ) );
|
1827 |
-
}
|
1828 |
-
|
1829 |
-
if ( 0 === $filesize ) {
|
1830 |
-
unlink( $upload['file'] );
|
1831 |
-
return new WP_Error( 'import_file_error', __( 'Zero size file downloaded', 'wordpress-importer' ) );
|
1832 |
-
}
|
1833 |
-
|
1834 |
-
$max_size = (int) $this->max_attachment_size();
|
1835 |
-
if ( ! empty( $max_size ) && $filesize > $max_size ) {
|
1836 |
-
unlink( $upload['file'] );
|
1837 |
-
$message = sprintf( __( 'Remote file is too large, limit is %s', 'wordpress-importer' ), size_format( $max_size ) );
|
1838 |
-
return new WP_Error( 'import_file_error', $message );
|
1839 |
-
}
|
1840 |
-
|
1841 |
-
return $upload;
|
1842 |
-
}
|
1843 |
-
|
1844 |
-
protected function post_process() {
|
1845 |
-
// Time to tackle any left-over bits
|
1846 |
-
if ( ! empty( $this->requires_remapping['post'] ) ) {
|
1847 |
-
$this->post_process_posts( $this->requires_remapping['post'] );
|
1848 |
-
}
|
1849 |
-
if ( ! empty( $this->requires_remapping['comment'] ) ) {
|
1850 |
-
$this->post_process_comments( $this->requires_remapping['comment'] );
|
1851 |
-
}
|
1852 |
-
}
|
1853 |
-
|
1854 |
-
protected function post_process_posts( $todo ) {
|
1855 |
-
foreach ( $todo as $post_id => $_ ) {
|
1856 |
-
$this->logger->debug( sprintf(
|
1857 |
-
// Note: title intentionally not used to skip extra processing
|
1858 |
-
// for when debug logging is off
|
1859 |
-
__( 'Running post-processing for post %d', 'wordpress-importer' ),
|
1860 |
-
$post_id
|
1861 |
-
) );
|
1862 |
-
|
1863 |
-
$data = array();
|
1864 |
-
|
1865 |
-
$parent_id = get_post_meta( $post_id, '_wxr_import_parent', true );
|
1866 |
-
if ( ! empty( $parent_id ) ) {
|
1867 |
-
// Have we imported the parent now?
|
1868 |
-
if ( isset( $this->mapping['post'][ $parent_id ] ) ) {
|
1869 |
-
$data['post_parent'] = $this->mapping['post'][ $parent_id ];
|
1870 |
-
} else {
|
1871 |
-
$this->logger->warning( sprintf(
|
1872 |
-
__( 'Could not find the post parent for "%1$s" (post #%2$d)', 'wordpress-importer' ),
|
1873 |
-
get_the_title( $post_id ),
|
1874 |
-
$post_id
|
1875 |
-
) );
|
1876 |
-
$this->logger->debug( sprintf(
|
1877 |
-
__( 'Post %1$d was imported with parent %2$d, but could not be found', 'wordpress-importer' ),
|
1878 |
-
$post_id,
|
1879 |
-
$parent_id
|
1880 |
-
) );
|
1881 |
-
}
|
1882 |
-
}
|
1883 |
-
|
1884 |
-
$author_slug = get_post_meta( $post_id, '_wxr_import_user_slug', true );
|
1885 |
-
if ( ! empty( $author_slug ) ) {
|
1886 |
-
// Have we imported the user now?
|
1887 |
-
if ( isset( $this->mapping['user_slug'][ $author_slug ] ) ) {
|
1888 |
-
$data['post_author'] = $this->mapping['user_slug'][ $author_slug ];
|
1889 |
-
} else {
|
1890 |
-
$this->logger->warning( sprintf(
|
1891 |
-
__( 'Could not find the author for "%1$s" (post #%2$d)', 'wordpress-importer' ),
|
1892 |
-
get_the_title( $post_id ),
|
1893 |
-
$post_id
|
1894 |
-
) );
|
1895 |
-
$this->logger->debug( sprintf(
|
1896 |
-
__( 'Post %1$d was imported with author "%2$s", but could not be found', 'wordpress-importer' ),
|
1897 |
-
$post_id,
|
1898 |
-
$author_slug
|
1899 |
-
) );
|
1900 |
-
}
|
1901 |
-
}
|
1902 |
-
|
1903 |
-
$has_attachments = get_post_meta( $post_id, '_wxr_import_has_attachment_refs', true );
|
1904 |
-
if ( ! empty( $has_attachments ) ) {
|
1905 |
-
$post = get_post( $post_id );
|
1906 |
-
$content = $post->post_content;
|
1907 |
-
|
1908 |
-
// Replace all the URLs we've got
|
1909 |
-
$new_content = str_replace( array_keys( $this->url_remap ), $this->url_remap, $content );
|
1910 |
-
if ( $new_content !== $content ) {
|
1911 |
-
$data['post_content'] = $new_content;
|
1912 |
-
}
|
1913 |
-
}
|
1914 |
-
|
1915 |
-
if ( get_post_type( $post_id ) === 'nav_menu_item' ) {
|
1916 |
-
$this->post_process_menu_item( $post_id );
|
1917 |
-
}
|
1918 |
-
|
1919 |
-
// Do we have updates to make?
|
1920 |
-
if ( empty( $data ) ) {
|
1921 |
-
$this->logger->debug( sprintf(
|
1922 |
-
__( 'Post %d was marked for post-processing, but none was required.', 'wordpress-importer' ),
|
1923 |
-
$post_id
|
1924 |
-
) );
|
1925 |
-
continue;
|
1926 |
-
}
|
1927 |
-
|
1928 |
-
// Run the update
|
1929 |
-
$data['ID'] = $post_id;
|
1930 |
-
$result = wp_update_post( $data, true );
|
1931 |
-
if ( is_wp_error( $result ) ) {
|
1932 |
-
$this->logger->warning( sprintf(
|
1933 |
-
__( 'Could not update "%1$s" (post #%2$d) with mapped data', 'wordpress-importer' ),
|
1934 |
-
get_the_title( $post_id ),
|
1935 |
-
$post_id
|
1936 |
-
) );
|
1937 |
-
$this->logger->debug( $result->get_error_message() );
|
1938 |
-
continue;
|
1939 |
-
}
|
1940 |
-
|
1941 |
-
// Clear out our temporary meta keys
|
1942 |
-
delete_post_meta( $post_id, '_wxr_import_parent' );
|
1943 |
-
delete_post_meta( $post_id, '_wxr_import_user_slug' );
|
1944 |
-
delete_post_meta( $post_id, '_wxr_import_has_attachment_refs' );
|
1945 |
-
}// End foreach().
|
1946 |
-
}
|
1947 |
-
|
1948 |
-
protected function post_process_menu_item( $post_id ) {
|
1949 |
-
$menu_object_id = get_post_meta( $post_id, '_wxr_import_menu_item', true );
|
1950 |
-
if ( empty( $menu_object_id ) ) {
|
1951 |
-
// No processing needed!
|
1952 |
-
return;
|
1953 |
-
}
|
1954 |
-
|
1955 |
-
$menu_item_type = get_post_meta( $post_id, '_menu_item_type', true );
|
1956 |
-
switch ( $menu_item_type ) {
|
1957 |
-
case 'taxonomy':
|
1958 |
-
if ( isset( $this->mapping['term_id'][ $menu_object_id ] ) ) {
|
1959 |
-
$menu_object = $this->mapping['term_id'][ $menu_object_id ];
|
1960 |
-
}
|
1961 |
-
break;
|
1962 |
-
|
1963 |
-
case 'post_type':
|
1964 |
-
if ( isset( $this->mapping['post'][ $menu_object_id ] ) ) {
|
1965 |
-
$menu_object = $this->mapping['post'][ $menu_object_id ];
|
1966 |
-
}
|
1967 |
-
break;
|
1968 |
-
|
1969 |
-
default:
|
1970 |
-
// Cannot handle this.
|
1971 |
-
return;
|
1972 |
-
}
|
1973 |
-
|
1974 |
-
if ( ! empty( $menu_object ) ) {
|
1975 |
-
update_post_meta( $post_id, '_menu_item_object_id', wp_slash( $menu_object ) );
|
1976 |
-
} else {
|
1977 |
-
$this->logger->warning( sprintf(
|
1978 |
-
__( 'Could not find the menu object for "%1$s" (post #%2$d)', 'wordpress-importer' ),
|
1979 |
-
get_the_title( $post_id ),
|
1980 |
-
$post_id
|
1981 |
-
) );
|
1982 |
-
$this->logger->debug( sprintf(
|
1983 |
-
__( 'Post %1$d was imported with object "%2$d" of type "%3$s", but could not be found', 'wordpress-importer' ),
|
1984 |
-
$post_id,
|
1985 |
-
$menu_object_id,
|
1986 |
-
$menu_item_type
|
1987 |
-
) );
|
1988 |
-
}
|
1989 |
-
|
1990 |
-
delete_post_meta( $post_id, '_wxr_import_menu_item' );
|
1991 |
-
}
|
1992 |
-
|
1993 |
-
|
1994 |
-
protected function post_process_comments( $todo ) {
|
1995 |
-
foreach ( $todo as $comment_id => $_ ) {
|
1996 |
-
$data = array();
|
1997 |
-
|
1998 |
-
$parent_id = get_comment_meta( $comment_id, '_wxr_import_parent', true );
|
1999 |
-
if ( ! empty( $parent_id ) ) {
|
2000 |
-
// Have we imported the parent now?
|
2001 |
-
if ( isset( $this->mapping['comment'][ $parent_id ] ) ) {
|
2002 |
-
$data['comment_parent'] = $this->mapping['comment'][ $parent_id ];
|
2003 |
-
} else {
|
2004 |
-
$this->logger->warning( sprintf(
|
2005 |
-
__( 'Could not find the comment parent for comment #%d', 'wordpress-importer' ),
|
2006 |
-
$comment_id
|
2007 |
-
) );
|
2008 |
-
$this->logger->debug( sprintf(
|
2009 |
-
__( 'Comment %1$d was imported with parent %2$d, but could not be found', 'wordpress-importer' ),
|
2010 |
-
$comment_id,
|
2011 |
-
$parent_id
|
2012 |
-
) );
|
2013 |
-
}
|
2014 |
-
}
|
2015 |
-
|
2016 |
-
$author_id = get_comment_meta( $comment_id, '_wxr_import_user', true );
|
2017 |
-
if ( ! empty( $author_id ) ) {
|
2018 |
-
// Have we imported the user now?
|
2019 |
-
if ( isset( $this->mapping['user'][ $author_id ] ) ) {
|
2020 |
-
$data['user_id'] = $this->mapping['user'][ $author_id ];
|
2021 |
-
} else {
|
2022 |
-
$this->logger->warning( sprintf(
|
2023 |
-
__( 'Could not find the author for comment #%d', 'wordpress-importer' ),
|
2024 |
-
$comment_id
|
2025 |
-
) );
|
2026 |
-
$this->logger->debug( sprintf(
|
2027 |
-
__( 'Comment %1$d was imported with author %2$d, but could not be found', 'wordpress-importer' ),
|
2028 |
-
$comment_id,
|
2029 |
-
$author_id
|
2030 |
-
) );
|
2031 |
-
}
|
2032 |
-
}
|
2033 |
-
|
2034 |
-
// Do we have updates to make?
|
2035 |
-
if ( empty( $data ) ) {
|
2036 |
-
continue;
|
2037 |
-
}
|
2038 |
-
|
2039 |
-
// Run the update
|
2040 |
-
$data['comment_ID'] = $comment_ID;
|
2041 |
-
$result = wp_update_comment( wp_slash( $data ) );
|
2042 |
-
if ( empty( $result ) ) {
|
2043 |
-
$this->logger->warning( sprintf(
|
2044 |
-
__( 'Could not update comment #%d with mapped data', 'wordpress-importer' ),
|
2045 |
-
$comment_id
|
2046 |
-
) );
|
2047 |
-
continue;
|
2048 |
-
}
|
2049 |
-
|
2050 |
-
// Clear out our temporary meta keys
|
2051 |
-
delete_comment_meta( $comment_id, '_wxr_import_parent' );
|
2052 |
-
delete_comment_meta( $comment_id, '_wxr_import_user' );
|
2053 |
-
}// End foreach().
|
2054 |
-
}
|
2055 |
-
|
2056 |
-
/**
|
2057 |
-
* Use stored mapping information to update old attachment URLs
|
2058 |
-
*/
|
2059 |
-
protected function replace_attachment_urls_in_content() {
|
2060 |
-
global $wpdb;
|
2061 |
-
// make sure we do the longest urls first, in case one is a substring of another
|
2062 |
-
uksort( $this->url_remap, array( $this, 'cmpr_strlen' ) );
|
2063 |
-
|
2064 |
-
foreach ( $this->url_remap as $from_url => $to_url ) {
|
2065 |
-
// remap urls in post_content
|
2066 |
-
$query = $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url );
|
2067 |
-
$wpdb->query( $query );
|
2068 |
-
|
2069 |
-
// remap enclosure urls
|
2070 |
-
$query = $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s) WHERE meta_key='enclosure'", $from_url, $to_url );
|
2071 |
-
$result = $wpdb->query( $query );
|
2072 |
-
}
|
2073 |
-
}
|
2074 |
-
|
2075 |
-
/**
|
2076 |
-
* Update _thumbnail_id meta to new, imported attachment IDs
|
2077 |
-
*/
|
2078 |
-
function remap_featured_images() {
|
2079 |
-
// cycle through posts that have a featured image
|
2080 |
-
foreach ( $this->featured_images as $post_id => $value ) {
|
2081 |
-
if ( isset( $this->processed_posts[ $value ] ) ) {
|
2082 |
-
$new_id = $this->processed_posts[ $value ];
|
2083 |
-
|
2084 |
-
// only update if there's a difference
|
2085 |
-
if ( $new_id !== $value ) {
|
2086 |
-
update_post_meta( $post_id, '_thumbnail_id', $new_id );
|
2087 |
-
}
|
2088 |
-
}
|
2089 |
-
}
|
2090 |
-
}
|
2091 |
-
|
2092 |
-
/**
|
2093 |
-
* Decide if the given meta key maps to information we will want to import
|
2094 |
-
*
|
2095 |
-
* @param string $key The meta key to check
|
2096 |
-
* @return string|bool The key if we do want to import, false if not
|
2097 |
-
*/
|
2098 |
-
public function is_valid_meta_key( $key ) {
|
2099 |
-
// skip attachment metadata since we'll regenerate it from scratch
|
2100 |
-
// skip _edit_lock as not relevant for import
|
2101 |
-
if ( in_array( $key, array( '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock' ) ) ) {
|
2102 |
-
return false;
|
2103 |
-
}
|
2104 |
-
|
2105 |
-
return $key;
|
2106 |
-
}
|
2107 |
-
|
2108 |
-
/**
|
2109 |
-
* Decide what the maximum file size for downloaded attachments is.
|
2110 |
-
* Default is 0 (unlimited), can be filtered via import_attachment_size_limit
|
2111 |
-
*
|
2112 |
-
* @return int Maximum attachment file size to import
|
2113 |
-
*/
|
2114 |
-
protected function max_attachment_size() {
|
2115 |
-
return apply_filters( 'import_attachment_size_limit', 0 );
|
2116 |
-
}
|
2117 |
-
|
2118 |
-
/**
|
2119 |
-
* Added to http_request_timeout filter to force timeout at 60 seconds during import
|
2120 |
-
*
|
2121 |
-
* @access protected
|
2122 |
-
* @return int 60
|
2123 |
-
*/
|
2124 |
-
function bump_request_timeout( $val ) {
|
2125 |
-
return 60;
|
2126 |
-
}
|
2127 |
-
|
2128 |
-
// return the difference in length between two strings
|
2129 |
-
function cmpr_strlen( $a, $b ) {
|
2130 |
-
return strlen( $b ) - strlen( $a );
|
2131 |
-
}
|
2132 |
-
|
2133 |
-
/**
|
2134 |
-
* Prefill existing post data.
|
2135 |
-
*
|
2136 |
-
* This preloads all GUIDs into memory, allowing us to avoid hitting the
|
2137 |
-
* database when we need to check for existence. With larger imports, this
|
2138 |
-
* becomes prohibitively slow to perform SELECT queries on each.
|
2139 |
-
*
|
2140 |
-
* By preloading all this data into memory, it's a constant-time lookup in
|
2141 |
-
* PHP instead. However, this does use a lot more memory, so for sites doing
|
2142 |
-
* small imports onto a large site, it may be a better tradeoff to use
|
2143 |
-
* on-the-fly checking instead.
|
2144 |
-
*/
|
2145 |
-
protected function prefill_existing_posts() {
|
2146 |
-
global $wpdb;
|
2147 |
-
$posts = $wpdb->get_results( "SELECT ID, guid FROM {$wpdb->posts}" );
|
2148 |
-
|
2149 |
-
foreach ( $posts as $item ) {
|
2150 |
-
$this->exists['post'][ $item->guid ] = $item->ID;
|
2151 |
-
}
|
2152 |
-
}
|
2153 |
-
|
2154 |
-
/**
|
2155 |
-
* Does the post exist?
|
2156 |
-
*
|
2157 |
-
* @param array $data Post data to check against.
|
2158 |
-
* @return int|bool Existing post ID if it exists, false otherwise.
|
2159 |
-
*/
|
2160 |
-
protected function post_exists( $data ) {
|
2161 |
-
// Constant-time lookup if we prefilled
|
2162 |
-
$exists_key = $data['guid'];
|
2163 |
-
|
2164 |
-
if ( $this->options['prefill_existing_posts'] ) {
|
2165 |
-
return isset( $this->exists['post'][ $exists_key ] ) ? $this->exists['post'][ $exists_key ] : false;
|
2166 |
-
}
|
2167 |
-
|
2168 |
-
// No prefilling, but might have already handled it
|
2169 |
-
if ( isset( $this->exists['post'][ $exists_key ] ) ) {
|
2170 |
-
return $this->exists['post'][ $exists_key ];
|
2171 |
-
}
|
2172 |
-
|
2173 |
-
// Still nothing, try post_exists, and cache it
|
2174 |
-
$exists = post_exists( $data['post_title'], $data['post_content'], $data['post_date'] );
|
2175 |
-
$this->exists['post'][ $exists_key ] = $exists;
|
2176 |
-
|
2177 |
-
return $exists;
|
2178 |
-
}
|
2179 |
-
|
2180 |
-
/**
|
2181 |
-
* Mark the post as existing.
|
2182 |
-
*
|
2183 |
-
* @param array $data Post data to mark as existing.
|
2184 |
-
* @param int $post_id Post ID.
|
2185 |
-
*/
|
2186 |
-
protected function mark_post_exists( $data, $post_id ) {
|
2187 |
-
$exists_key = $data['guid'];
|
2188 |
-
$this->exists['post'][ $exists_key ] = $post_id;
|
2189 |
-
}
|
2190 |
-
|
2191 |
-
/**
|
2192 |
-
* Prefill existing comment data.
|
2193 |
-
*
|
2194 |
-
* @see self::prefill_existing_posts() for justification of why this exists.
|
2195 |
-
*/
|
2196 |
-
protected function prefill_existing_comments() {
|
2197 |
-
global $wpdb;
|
2198 |
-
$posts = $wpdb->get_results( "SELECT comment_ID, comment_author, comment_date FROM {$wpdb->comments}" );
|
2199 |
-
|
2200 |
-
foreach ( $posts as $item ) {
|
2201 |
-
$exists_key = sha1( $item->comment_author . ':' . $item->comment_date );
|
2202 |
-
$this->exists['comment'][ $exists_key ] = $item->comment_ID;
|
2203 |
-
}
|
2204 |
-
}
|
2205 |
-
|
2206 |
-
/**
|
2207 |
-
* Does the comment exist?
|
2208 |
-
*
|
2209 |
-
* @param array $data Comment data to check against.
|
2210 |
-
* @return int|bool Existing comment ID if it exists, false otherwise.
|
2211 |
-
*/
|
2212 |
-
protected function comment_exists( $data ) {
|
2213 |
-
$exists_key = sha1( $data['comment_author'] . ':' . $data['comment_date'] );
|
2214 |
-
|
2215 |
-
// Constant-time lookup if we prefilled
|
2216 |
-
if ( $this->options['prefill_existing_comments'] ) {
|
2217 |
-
return isset( $this->exists['comment'][ $exists_key ] ) ? $this->exists['comment'][ $exists_key ] : false;
|
2218 |
-
}
|
2219 |
-
|
2220 |
-
// No prefilling, but might have already handled it
|
2221 |
-
if ( isset( $this->exists['comment'][ $exists_key ] ) ) {
|
2222 |
-
return $this->exists['comment'][ $exists_key ];
|
2223 |
-
}
|
2224 |
-
|
2225 |
-
// Still nothing, try comment_exists, and cache it
|
2226 |
-
$exists = comment_exists( $data['comment_author'], $data['comment_date'] );
|
2227 |
-
$this->exists['comment'][ $exists_key ] = $exists;
|
2228 |
-
|
2229 |
-
return $exists;
|
2230 |
-
}
|
2231 |
-
|
2232 |
-
/**
|
2233 |
-
* Mark the comment as existing.
|
2234 |
-
*
|
2235 |
-
* @param array $data Comment data to mark as existing.
|
2236 |
-
* @param int $comment_id Comment ID.
|
2237 |
-
*/
|
2238 |
-
protected function mark_comment_exists( $data, $comment_id ) {
|
2239 |
-
$exists_key = sha1( $data['comment_author'] . ':' . $data['comment_date'] );
|
2240 |
-
$this->exists['comment'][ $exists_key ] = $comment_id;
|
2241 |
-
}
|
2242 |
-
|
2243 |
-
/**
|
2244 |
-
* Prefill existing term data.
|
2245 |
-
*
|
2246 |
-
* @see self::prefill_existing_posts() for justification of why this exists.
|
2247 |
-
*/
|
2248 |
-
protected function prefill_existing_terms() {
|
2249 |
-
global $wpdb;
|
2250 |
-
$query = "SELECT t.term_id, tt.taxonomy, t.slug FROM {$wpdb->terms} AS t";
|
2251 |
-
$query .= " JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id";
|
2252 |
-
$terms = $wpdb->get_results( $query );
|
2253 |
-
|
2254 |
-
foreach ( $terms as $item ) {
|
2255 |
-
$exists_key = sha1( $item->taxonomy . ':' . $item->slug );
|
2256 |
-
$this->exists['term'][ $exists_key ] = $item->term_id;
|
2257 |
-
}
|
2258 |
-
}
|
2259 |
-
|
2260 |
-
/**
|
2261 |
-
* Does the term exist?
|
2262 |
-
*
|
2263 |
-
* @param array $data Term data to check against.
|
2264 |
-
* @return int|bool Existing term ID if it exists, false otherwise.
|
2265 |
-
*/
|
2266 |
-
protected function term_exists( $data ) {
|
2267 |
-
$exists_key = sha1( $data['taxonomy'] . ':' . $data['slug'] );
|
2268 |
-
|
2269 |
-
// Constant-time lookup if we prefilled
|
2270 |
-
if ( $this->options['prefill_existing_terms'] ) {
|
2271 |
-
return isset( $this->exists['term'][ $exists_key ] ) ? $this->exists['term'][ $exists_key ] : false;
|
2272 |
-
}
|
2273 |
-
|
2274 |
-
// No prefilling, but might have already handled it
|
2275 |
-
if ( isset( $this->exists['term'][ $exists_key ] ) ) {
|
2276 |
-
return $this->exists['term'][ $exists_key ];
|
2277 |
-
}
|
2278 |
-
|
2279 |
-
// Still nothing, try comment_exists, and cache it
|
2280 |
-
$exists = term_exists( $data['slug'], $data['taxonomy'] );
|
2281 |
-
if ( is_array( $exists ) ) {
|
2282 |
-
$exists = $exists['term_id'];
|
2283 |
-
}
|
2284 |
-
|
2285 |
-
$this->exists['term'][ $exists_key ] = $exists;
|
2286 |
-
|
2287 |
-
return $exists;
|
2288 |
-
}
|
2289 |
-
|
2290 |
-
/**
|
2291 |
-
* Mark the term as existing.
|
2292 |
-
*
|
2293 |
-
* @param array $data Term data to mark as existing.
|
2294 |
-
* @param int $term_id Term ID.
|
2295 |
-
*/
|
2296 |
-
protected function mark_term_exists( $data, $term_id ) {
|
2297 |
-
$exists_key = sha1( $data['taxonomy'] . ':' . $data['slug'] );
|
2298 |
-
$this->exists['term'][ $exists_key ] = $term_id;
|
2299 |
-
}
|
2300 |
-
}
|
2301 |
Â
endif;
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if( ! class_exists( 'WXR_Importer' ) && class_exists( 'WP_Importer' ) ) :
|
4 |
+
class WXR_Importer extends WP_Importer {
|
5 |
+
/**
|
6 |
+
* Maximum supported WXR version
|
7 |
+
*/
|
8 |
+
const MAX_WXR_VERSION = 1.2;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Regular expression for checking if a post references an attachment
|
12 |
+
*
|
13 |
+
* Note: This is a quick, weak check just to exclude text-only posts. More
|
14 |
+
* vigorous checking is done later to verify.
|
15 |
+
*/
|
16 |
+
const REGEX_HAS_ATTACHMENT_REFS = '!
|
17 |
+
(
|
18 |
+
# Match anything with an image or attachment class
|
19 |
+
class=[\'"].*?\b(wp-image-\d+|attachment-[\w\-]+)\b
|
20 |
+
|
|
21 |
+
# Match anything that looks like an upload URL
|
22 |
+
src=[\'"][^\'"]*(
|
23 |
+
[0-9]{4}/[0-9]{2}/[^\'"]+\.(jpg|jpeg|png|gif)
|
24 |
+
|
|
25 |
+
content/uploads[^\'"]+
|
26 |
+
)[\'"]
|
27 |
+
)!ix';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Version of WXR we're importing.
|
31 |
+
*
|
32 |
+
* Defaults to 1.0 for compatibility. Typically overridden by a
|
33 |
+
* `<wp:wxr_version>` tag at the start of the file.
|
34 |
+
*
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
protected $version = '1.0';
|
38 |
+
|
39 |
+
// information to import from WXR file
|
40 |
+
protected $categories = array();
|
41 |
+
protected $tags = array();
|
42 |
+
protected $base_url = '';
|
43 |
+
|
44 |
+
// TODO: REMOVE THESE
|
45 |
+
protected $processed_terms = array();
|
46 |
+
protected $processed_posts = array();
|
47 |
+
protected $processed_menu_items = array();
|
48 |
+
protected $menu_item_orphans = array();
|
49 |
+
protected $missing_menu_items = array();
|
50 |
+
|
51 |
+
// NEW STYLE
|
52 |
+
protected $mapping = array();
|
53 |
+
protected $requires_remapping = array();
|
54 |
+
protected $exists = array();
|
55 |
+
protected $user_slug_override = array();
|
56 |
+
|
57 |
+
protected $url_remap = array();
|
58 |
+
protected $featured_images = array();
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Logger instance.
|
62 |
+
*
|
63 |
+
* @var WP_Importer_Logger
|
64 |
+
*/
|
65 |
+
protected $logger;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Constructor
|
69 |
+
*
|
70 |
+
* @param array $options {
|
71 |
+
* @var bool $prefill_existing_posts Should we prefill `post_exists` calls? (True prefills and uses more memory, false checks once per imported post and takes longer. Default is true.)
|
72 |
+
* @var bool $prefill_existing_comments Should we prefill `comment_exists` calls? (True prefills and uses more memory, false checks once per imported comment and takes longer. Default is true.)
|
73 |
+
* @var bool $prefill_existing_terms Should we prefill `term_exists` calls? (True prefills and uses more memory, false checks once per imported term and takes longer. Default is true.)
|
74 |
+
* @var bool $update_attachment_guids Should attachment GUIDs be updated to the new URL? (True updates the GUID, which keeps compatibility with v1, false doesn't update, and allows deduplication and reimporting. Default is false.)
|
75 |
+
* @var bool $fetch_attachments Fetch attachments from the remote server. (True fetches and creates attachment posts, false skips attachments. Default is false.)
|
76 |
+
* @var bool $aggressive_url_search Should we search/replace for URLs aggressively? (True searches all posts' content for old URLs and replaces, false checks for `<img class="wp-image-*">` only. Default is false.)
|
77 |
+
* @var int $default_author User ID to use if author is missing or invalid. (Default is null, which leaves posts unassigned.)
|
78 |
+
* }
|
79 |
+
*/
|
80 |
+
public function __construct( $options = array() ) {
|
81 |
+
// Initialize some important variables
|
82 |
+
$empty_types = array(
|
83 |
+
'post' => array(),
|
84 |
+
'comment' => array(),
|
85 |
+
'term' => array(),
|
86 |
+
'user' => array(),
|
87 |
+
);
|
88 |
+
|
89 |
+
$this->mapping = $empty_types;
|
90 |
+
$this->mapping['user_slug'] = array();
|
91 |
+
$this->mapping['term_id'] = array();
|
92 |
+
$this->requires_remapping = $empty_types;
|
93 |
+
$this->exists = $empty_types;
|
94 |
+
|
95 |
+
$this->options = wp_parse_args( $options, array(
|
96 |
+
'prefill_existing_posts' => true,
|
97 |
+
'prefill_existing_comments' => true,
|
98 |
+
'prefill_existing_terms' => true,
|
99 |
+
'update_attachment_guids' => false,
|
100 |
+
'fetch_attachments' => false,
|
101 |
+
'aggressive_url_search' => false,
|
102 |
+
'default_author' => null,
|
103 |
+
) );
|
104 |
+
}
|
105 |
+
|
106 |
+
public function set_logger( $logger ) {
|
107 |
+
$this->logger = $logger;
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Get a stream reader for the file.
|
112 |
+
*
|
113 |
+
* @param string $file Path to the XML file.
|
114 |
+
* @return XMLReader|WP_Error Reader instance on success, error otherwise.
|
115 |
+
*/
|
116 |
+
protected function get_reader( $file ) {
|
117 |
+
// Avoid loading external entities for security
|
118 |
+
$old_value = null;
|
119 |
+
if ( function_exists( 'libxml_disable_entity_loader' ) ) {
|
120 |
+
// $old_value = libxml_disable_entity_loader( true );
|
121 |
+
}
|
122 |
+
|
123 |
+
$reader = new XMLReader();
|
124 |
+
$status = $reader->open( $file );
|
125 |
+
|
126 |
+
if ( ! is_null( $old_value ) ) {
|
127 |
+
// libxml_disable_entity_loader( $old_value );
|
128 |
+
}
|
129 |
+
|
130 |
+
if ( ! $status ) {
|
131 |
+
return new WP_Error( 'wxr_importer.cannot_parse', __( 'Could not open the file for parsing', 'wordpress-importer' ) );
|
132 |
+
}
|
133 |
+
|
134 |
+
return $reader;
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* The main controller for the actual import stage.
|
139 |
+
*
|
140 |
+
* @param string $file Path to the WXR file for importing
|
141 |
+
*/
|
142 |
+
public function get_preliminary_information( $file ) {
|
143 |
+
// Let's run the actual importer now, woot
|
144 |
+
$reader = $this->get_reader( $file );
|
145 |
+
if ( is_wp_error( $reader ) ) {
|
146 |
+
return $reader;
|
147 |
+
}
|
148 |
+
|
149 |
+
// Set the version to compatibility mode first
|
150 |
+
$this->version = '1.0';
|
151 |
+
|
152 |
+
// Start parsing!
|
153 |
+
$data = new WXR_Import_Info();
|
154 |
+
while ( $reader->read() ) {
|
155 |
+
// Only deal with element opens
|
156 |
+
if ( $reader->nodeType !== XMLReader::ELEMENT ) {
|
157 |
+
continue;
|
158 |
+
}
|
159 |
+
|
160 |
+
switch ( $reader->name ) {
|
161 |
+
case 'wp:wxr_version':
|
162 |
+
// Upgrade to the correct version
|
163 |
+
$this->version = $reader->readString();
|
164 |
+
|
165 |
+
if ( version_compare( $this->version, self::MAX_WXR_VERSION, '>' ) ) {
|
166 |
+
$this->logger->warning( sprintf(
|
167 |
+
__( 'This WXR file (version %1$s) is newer than the importer (version %2$s) and may not be supported. Please consider updating.', 'wordpress-importer' ),
|
168 |
+
$this->version,
|
169 |
+
self::MAX_WXR_VERSION
|
170 |
+
) );
|
171 |
+
}
|
172 |
+
|
173 |
+
// Handled everything in this node, move on to the next
|
174 |
+
$reader->next();
|
175 |
+
break;
|
176 |
+
|
177 |
+
case 'generator':
|
178 |
+
$data->generator = $reader->readString();
|
179 |
+
$reader->next();
|
180 |
+
break;
|
181 |
+
|
182 |
+
case 'title':
|
183 |
+
$data->title = $reader->readString();
|
184 |
+
$reader->next();
|
185 |
+
break;
|
186 |
+
|
187 |
+
case 'wp:base_site_url':
|
188 |
+
$data->siteurl = $reader->readString();
|
189 |
+
$reader->next();
|
190 |
+
break;
|
191 |
+
|
192 |
+
case 'wp:base_blog_url':
|
193 |
+
$data->home = $reader->readString();
|
194 |
+
$reader->next();
|
195 |
+
break;
|
196 |
+
|
197 |
+
case 'wp:author':
|
198 |
+
$node = $reader->expand();
|
199 |
+
|
200 |
+
$parsed = $this->parse_author_node( $node );
|
201 |
+
if ( is_wp_error( $parsed ) ) {
|
202 |
+
$this->log_error( $parsed );
|
203 |
+
|
204 |
+
// Skip the rest of this post
|
205 |
+
$reader->next();
|
206 |
+
break;
|
207 |
+
}
|
208 |
+
|
209 |
+
$data->users[] = $parsed;
|
210 |
+
|
211 |
+
// Handled everything in this node, move on to the next
|
212 |
+
$reader->next();
|
213 |
+
break;
|
214 |
+
|
215 |
+
case 'item':
|
216 |
+
$node = $reader->expand();
|
217 |
+
$parsed = $this->parse_post_node( $node );
|
218 |
+
if ( is_wp_error( $parsed ) ) {
|
219 |
+
$this->log_error( $parsed );
|
220 |
+
|
221 |
+
// Skip the rest of this post
|
222 |
+
$reader->next();
|
223 |
+
break;
|
224 |
+
}
|
225 |
+
|
226 |
+
if ( $parsed['data']['post_type'] === 'attachment' ) {
|
227 |
+
$data->media_count++;
|
228 |
+
} else {
|
229 |
+
$data->post_count++;
|
230 |
+
}
|
231 |
+
$data->comment_count += count( $parsed['comments'] );
|
232 |
+
|
233 |
+
// Handled everything in this node, move on to the next
|
234 |
+
$reader->next();
|
235 |
+
break;
|
236 |
+
|
237 |
+
case 'wp:category':
|
238 |
+
case 'wp:tag':
|
239 |
+
case 'wp:term':
|
240 |
+
$data->term_count++;
|
241 |
+
|
242 |
+
// Handled everything in this node, move on to the next
|
243 |
+
$reader->next();
|
244 |
+
break;
|
245 |
+
}// End switch().
|
246 |
+
}// End while().
|
247 |
+
|
248 |
+
$data->version = $this->version;
|
249 |
+
|
250 |
+
return $data;
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* The main controller for the actual import stage.
|
255 |
+
*
|
256 |
+
* @param string $file Path to the WXR file for importing
|
257 |
+
*/
|
258 |
+
public function parse_authors( $file ) {
|
259 |
+
// Let's run the actual importer now, woot
|
260 |
+
$reader = $this->get_reader( $file );
|
261 |
+
if ( is_wp_error( $reader ) ) {
|
262 |
+
return $reader;
|
263 |
+
}
|
264 |
+
|
265 |
+
// Set the version to compatibility mode first
|
266 |
+
$this->version = '1.0';
|
267 |
+
|
268 |
+
// Start parsing!
|
269 |
+
$authors = array();
|
270 |
+
while ( $reader->read() ) {
|
271 |
+
// Only deal with element opens
|
272 |
+
if ( $reader->nodeType !== XMLReader::ELEMENT ) {
|
273 |
+
continue;
|
274 |
+
}
|
275 |
+
|
276 |
+
switch ( $reader->name ) {
|
277 |
+
case 'wp:wxr_version':
|
278 |
+
// Upgrade to the correct version
|
279 |
+
$this->version = $reader->readString();
|
280 |
+
|
281 |
+
if ( version_compare( $this->version, self::MAX_WXR_VERSION, '>' ) ) {
|
282 |
+
$this->logger->warning( sprintf(
|
283 |
+
__( 'This WXR file (version %1$s) is newer than the importer (version %2$s) and may not be supported. Please consider updating.', 'wordpress-importer' ),
|
284 |
+
$this->version,
|
285 |
+
self::MAX_WXR_VERSION
|
286 |
+
) );
|
287 |
+
}
|
288 |
+
|
289 |
+
// Handled everything in this node, move on to the next
|
290 |
+
$reader->next();
|
291 |
+
break;
|
292 |
+
|
293 |
+
case 'wp:author':
|
294 |
+
$node = $reader->expand();
|
295 |
+
|
296 |
+
$parsed = $this->parse_author_node( $node );
|
297 |
+
if ( is_wp_error( $parsed ) ) {
|
298 |
+
$this->log_error( $parsed );
|
299 |
+
|
300 |
+
// Skip the rest of this post
|
301 |
+
$reader->next();
|
302 |
+
break;
|
303 |
+
}
|
304 |
+
|
305 |
+
$authors[] = $parsed;
|
306 |
+
|
307 |
+
// Handled everything in this node, move on to the next
|
308 |
+
$reader->next();
|
309 |
+
break;
|
310 |
+
}
|
311 |
+
}// End while().
|
312 |
+
|
313 |
+
return $authors;
|
314 |
+
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* The main controller for the actual import stage.
|
318 |
+
*
|
319 |
+
* @param string $file Path to the WXR file for importing
|
320 |
+
*/
|
321 |
+
public function import( $file ) {
|
322 |
+
add_filter( 'import_post_meta_key', array( $this, 'is_valid_meta_key' ) );
|
323 |
+
add_filter( 'http_request_timeout', array( &$this, 'bump_request_timeout' ) );
|
324 |
+
|
325 |
+
$result = $this->import_start( $file );
|
326 |
+
if ( is_wp_error( $result ) ) {
|
327 |
+
return $result;
|
328 |
+
}
|
329 |
+
|
330 |
+
// Let's run the actual importer now, woot
|
331 |
+
$reader = $this->get_reader( $file );
|
332 |
+
if ( is_wp_error( $reader ) ) {
|
333 |
+
return $reader;
|
334 |
+
}
|
335 |
+
|
336 |
+
// Set the version to compatibility mode first
|
337 |
+
$this->version = '1.0';
|
338 |
+
|
339 |
+
// Reset other variables
|
340 |
+
$this->base_url = '';
|
341 |
+
|
342 |
+
// Start parsing!
|
343 |
+
while ( $reader->read() ) {
|
344 |
+
// Only deal with element opens
|
345 |
+
if ( $reader->nodeType !== XMLReader::ELEMENT ) {
|
346 |
+
continue;
|
347 |
+
}
|
348 |
+
|
349 |
+
switch ( $reader->name ) {
|
350 |
+
case 'wp:wxr_version':
|
351 |
+
// Upgrade to the correct version
|
352 |
+
$this->version = $reader->readString();
|
353 |
+
|
354 |
+
if ( version_compare( $this->version, self::MAX_WXR_VERSION, '>' ) ) {
|
355 |
+
$this->logger->warning( sprintf(
|
356 |
+
__( 'This WXR file (version %1$s) is newer than the importer (version %2$s) and may not be supported. Please consider updating.', 'wordpress-importer' ),
|
357 |
+
$this->version,
|
358 |
+
self::MAX_WXR_VERSION
|
359 |
+
) );
|
360 |
+
}
|
361 |
+
|
362 |
+
// Handled everything in this node, move on to the next
|
363 |
+
$reader->next();
|
364 |
+
break;
|
365 |
+
|
366 |
+
case 'wp:base_site_url':
|
367 |
+
$this->base_url = $reader->readString();
|
368 |
+
|
369 |
+
// Handled everything in this node, move on to the next
|
370 |
+
$reader->next();
|
371 |
+
break;
|
372 |
+
|
373 |
+
case 'item':
|
374 |
+
$node = $reader->expand();
|
375 |
+
$parsed = $this->parse_post_node( $node );
|
376 |
+
if ( is_wp_error( $parsed ) ) {
|
377 |
+
$this->log_error( $parsed );
|
378 |
+
|
379 |
+
// Skip the rest of this post
|
380 |
+
$reader->next();
|
381 |
+
break;
|
382 |
+
}
|
383 |
+
|
384 |
+
$this->process_post( $parsed['data'], $parsed['meta'], $parsed['comments'], $parsed['terms'] );
|
385 |
+
|
386 |
+
// Handled everything in this node, move on to the next
|
387 |
+
$reader->next();
|
388 |
+
break;
|
389 |
+
|
390 |
+
case 'wp:author':
|
391 |
+
$node = $reader->expand();
|
392 |
+
|
393 |
+
$parsed = $this->parse_author_node( $node );
|
394 |
+
if ( is_wp_error( $parsed ) ) {
|
395 |
+
$this->log_error( $parsed );
|
396 |
+
|
397 |
+
// Skip the rest of this post
|
398 |
+
$reader->next();
|
399 |
+
break;
|
400 |
+
}
|
401 |
+
|
402 |
+
$status = $this->process_author( $parsed['data'], $parsed['meta'] );
|
403 |
+
if ( is_wp_error( $status ) ) {
|
404 |
+
$this->log_error( $status );
|
405 |
+
}
|
406 |
+
|
407 |
+
// Handled everything in this node, move on to the next
|
408 |
+
$reader->next();
|
409 |
+
break;
|
410 |
+
|
411 |
+
case 'wp:category':
|
412 |
+
$node = $reader->expand();
|
413 |
+
|
414 |
+
$parsed = $this->parse_term_node( $node, 'category' );
|
415 |
+
if ( is_wp_error( $parsed ) ) {
|
416 |
+
$this->log_error( $parsed );
|
417 |
+
|
418 |
+
// Skip the rest of this post
|
419 |
+
$reader->next();
|
420 |
+
break;
|
421 |
+
}
|
422 |
+
|
423 |
+
$status = $this->process_term( $parsed['data'], $parsed['meta'] );
|
424 |
+
|
425 |
+
// Handled everything in this node, move on to the next
|
426 |
+
$reader->next();
|
427 |
+
break;
|
428 |
+
|
429 |
+
case 'wp:tag':
|
430 |
+
$node = $reader->expand();
|
431 |
+
|
432 |
+
$parsed = $this->parse_term_node( $node, 'tag' );
|
433 |
+
if ( is_wp_error( $parsed ) ) {
|
434 |
+
$this->log_error( $parsed );
|
435 |
+
|
436 |
+
// Skip the rest of this post
|
437 |
+
$reader->next();
|
438 |
+
break;
|
439 |
+
}
|
440 |
+
|
441 |
+
$status = $this->process_term( $parsed['data'], $parsed['meta'] );
|
442 |
+
|
443 |
+
// Handled everything in this node, move on to the next
|
444 |
+
$reader->next();
|
445 |
+
break;
|
446 |
+
|
447 |
+
case 'wp:term':
|
448 |
+
$node = $reader->expand();
|
449 |
+
|
450 |
+
$parsed = $this->parse_term_node( $node );
|
451 |
+
if ( is_wp_error( $parsed ) ) {
|
452 |
+
$this->log_error( $parsed );
|
453 |
+
|
454 |
+
// Skip the rest of this post
|
455 |
+
$reader->next();
|
456 |
+
break;
|
457 |
+
}
|
458 |
+
|
459 |
+
$status = $this->process_term( $parsed['data'], $parsed['meta'] );
|
460 |
+
|
461 |
+
// Handled everything in this node, move on to the next
|
462 |
+
$reader->next();
|
463 |
+
break;
|
464 |
+
|
465 |
+
default:
|
466 |
+
// Skip this node, probably handled by something already
|
467 |
+
break;
|
468 |
+
}// End switch().
|
469 |
+
}// End while().
|
470 |
+
|
471 |
+
// Now that we've done the main processing, do any required
|
472 |
+
// post-processing and remapping.
|
473 |
+
$this->post_process();
|
474 |
+
|
475 |
+
if ( $this->options['aggressive_url_search'] ) {
|
476 |
+
$this->replace_attachment_urls_in_content();
|
477 |
+
}
|
478 |
+
// $this->remap_featured_images();
|
479 |
+
$this->import_end();
|
480 |
+
}
|
481 |
+
|
482 |
+
/**
|
483 |
+
* Log an error instance to the logger.
|
484 |
+
*
|
485 |
+
* @param WP_Error $error Error instance to log.
|
486 |
+
*/
|
487 |
+
protected function log_error( WP_Error $error ) {
|
488 |
+
$this->logger->warning( $error->get_error_message() );
|
489 |
+
|
490 |
+
// Log the data as debug info too
|
491 |
+
$data = $error->get_error_data();
|
492 |
+
if ( ! empty( $data ) ) {
|
493 |
+
$this->logger->debug( var_export( $data, true ) );
|
494 |
+
}
|
495 |
+
}
|
496 |
+
|
497 |
+
/**
|
498 |
+
* Parses the WXR file and prepares us for the task of processing parsed data
|
499 |
+
*
|
500 |
+
* @param string $file Path to the WXR file for importing
|
501 |
+
*/
|
502 |
+
protected function import_start( $file ) {
|
503 |
+
if ( ! is_file( $file ) ) {
|
504 |
+
return new WP_Error( 'wxr_importer.file_missing', __( 'The file does not exist, please try again.', 'wordpress-importer' ) );
|
505 |
+
}
|
506 |
+
|
507 |
+
// Suspend bunches of stuff in WP core
|
508 |
+
wp_defer_term_counting( true );
|
509 |
+
wp_defer_comment_counting( true );
|
510 |
+
wp_suspend_cache_invalidation( true );
|
511 |
+
|
512 |
+
// Prefill exists calls if told to
|
513 |
+
if ( $this->options['prefill_existing_posts'] ) {
|
514 |
+
$this->prefill_existing_posts();
|
515 |
+
}
|
516 |
+
if ( $this->options['prefill_existing_comments'] ) {
|
517 |
+
$this->prefill_existing_comments();
|
518 |
+
}
|
519 |
+
if ( $this->options['prefill_existing_terms'] ) {
|
520 |
+
$this->prefill_existing_terms();
|
521 |
+
}
|
522 |
+
|
523 |
+
/**
|
524 |
+
* Begin the import.
|
525 |
+
*
|
526 |
+
* Fires before the import process has begun. If you need to suspend
|
527 |
+
* caching or heavy processing on hooks, do so here.
|
528 |
+
*/
|
529 |
+
do_action( 'import_start' );
|
530 |
+
}
|
531 |
+
|
532 |
+
/**
|
533 |
+
* Performs post-import cleanup of files and the cache
|
534 |
+
*/
|
535 |
+
protected function import_end() {
|
536 |
+
// Re-enable stuff in core
|
537 |
+
wp_suspend_cache_invalidation( false );
|
538 |
+
wp_cache_flush();
|
539 |
+
foreach ( get_taxonomies() as $tax ) {
|
540 |
+
delete_option( "{$tax}_children" );
|
541 |
+
_get_term_hierarchy( $tax );
|
542 |
+
}
|
543 |
+
|
544 |
+
wp_defer_term_counting( false );
|
545 |
+
wp_defer_comment_counting( false );
|
546 |
+
|
547 |
+
/**
|
548 |
+
* Complete the import.
|
549 |
+
*
|
550 |
+
* Fires after the import process has finished. If you need to update
|
551 |
+
* your cache or re-enable processing, do so here.
|
552 |
+
*/
|
553 |
+
do_action( 'import_end' );
|
554 |
+
}
|
555 |
+
|
556 |
+
/**
|
557 |
+
* Set the user mapping.
|
558 |
+
*
|
559 |
+
* @param array $mapping List of map arrays (containing `old_slug`, `old_id`, `new_id`)
|
560 |
+
*/
|
561 |
+
public function set_user_mapping( $mapping ) {
|
562 |
+
foreach ( $mapping as $map ) {
|
563 |
+
if ( empty( $map['old_slug'] ) || empty( $map['old_id'] ) || empty( $map['new_id'] ) ) {
|
564 |
+
$this->logger->warning( __( 'Invalid author mapping', 'wordpress-importer' ) );
|
565 |
+
$this->logger->debug( var_export( $map, true ) );
|
566 |
+
continue;
|
567 |
+
}
|
568 |
+
|
569 |
+
$old_slug = $map['old_slug'];
|
570 |
+
$old_id = $map['old_id'];
|
571 |
+
$new_id = $map['new_id'];
|
572 |
+
|
573 |
+
$this->mapping['user'][ $old_id ] = $new_id;
|
574 |
+
$this->mapping['user_slug'][ $old_slug ] = $new_id;
|
575 |
+
}
|
576 |
+
}
|
577 |
+
|
578 |
+
/**
|
579 |
+
* Set the user slug overrides.
|
580 |
+
*
|
581 |
+
* Allows overriding the slug in the import with a custom/renamed version.
|
582 |
+
*
|
583 |
+
* @param string[] $overrides Map of old slug to new slug.
|
584 |
+
*/
|
585 |
+
public function set_user_slug_overrides( $overrides ) {
|
586 |
+
foreach ( $overrides as $original => $renamed ) {
|
587 |
+
$this->user_slug_override[ $original ] = $renamed;
|
588 |
+
}
|
589 |
+
}
|
590 |
+
|
591 |
+
/**
|
592 |
+
* Parse a post node into post data.
|
593 |
+
*
|
594 |
+
* @param DOMElement $node Parent node of post data (typically `item`).
|
595 |
+
* @return array|WP_Error Post data array on success, error otherwise.
|
596 |
+
*/
|
597 |
+
protected function parse_post_node( $node ) {
|
598 |
+
$data = array();
|
599 |
+
$meta = array();
|
600 |
+
$comments = array();
|
601 |
+
$terms = array();
|
602 |
+
|
603 |
+
foreach ( $node->childNodes as $child ) {
|
604 |
+
// We only care about child elements
|
605 |
+
if ( $child->nodeType !== XML_ELEMENT_NODE ) {
|
606 |
+
continue;
|
607 |
+
}
|
608 |
+
|
609 |
+
switch ( $child->tagName ) {
|
610 |
+
case 'wp:post_type':
|
611 |
+
$data['post_type'] = $child->textContent;
|
612 |
+
break;
|
613 |
+
|
614 |
+
case 'title':
|
615 |
+
$data['post_title'] = $child->textContent;
|
616 |
+
break;
|
617 |
+
|
618 |
+
case 'guid':
|
619 |
+
$data['guid'] = $child->textContent;
|
620 |
+
break;
|
621 |
+
|
622 |
+
case 'dc:creator':
|
623 |
+
$data['post_author'] = $child->textContent;
|
624 |
+
break;
|
625 |
+
|
626 |
+
case 'content:encoded':
|
627 |
+
$data['post_content'] = $child->textContent;
|
628 |
+
break;
|
629 |
+
|
630 |
+
case 'excerpt:encoded':
|
631 |
+
$data['post_excerpt'] = $child->textContent;
|
632 |
+
break;
|
633 |
+
|
634 |
+
case 'wp:post_id':
|
635 |
+
$data['post_id'] = $child->textContent;
|
636 |
+
break;
|
637 |
+
|
638 |
+
case 'wp:post_date':
|
639 |
+
$data['post_date'] = $child->textContent;
|
640 |
+
break;
|
641 |
+
|
642 |
+
case 'wp:post_date_gmt':
|
643 |
+
$data['post_date_gmt'] = $child->textContent;
|
644 |
+
break;
|
645 |
+
|
646 |
+
case 'wp:comment_status':
|
647 |
+
$data['comment_status'] = $child->textContent;
|
648 |
+
break;
|
649 |
+
|
650 |
+
case 'wp:ping_status':
|
651 |
+
$data['ping_status'] = $child->textContent;
|
652 |
+
break;
|
653 |
+
|
654 |
+
case 'wp:post_name':
|
655 |
+
$data['post_name'] = $child->textContent;
|
656 |
+
break;
|
657 |
+
|
658 |
+
case 'wp:status':
|
659 |
+
$data['post_status'] = $child->textContent;
|
660 |
+
|
661 |
+
if ( $data['post_status'] === 'auto-draft' ) {
|
662 |
+
// Bail now
|
663 |
+
return new WP_Error(
|
664 |
+
'wxr_importer.post.cannot_import_draft',
|
665 |
+
__( 'Cannot import auto-draft posts' ),
|
666 |
+
$data
|
667 |
+
);
|
668 |
+
}
|
669 |
+
break;
|
670 |
+
|
671 |
+
case 'wp:post_parent':
|
672 |
+
$data['post_parent'] = $child->textContent;
|
673 |
+
break;
|
674 |
+
|
675 |
+
case 'wp:menu_order':
|
676 |
+
$data['menu_order'] = $child->textContent;
|
677 |
+
break;
|
678 |
+
|
679 |
+
case 'wp:post_password':
|
680 |
+
$data['post_password'] = $child->textContent;
|
681 |
+
break;
|
682 |
+
|
683 |
+
case 'wp:is_sticky':
|
684 |
+
$data['is_sticky'] = $child->textContent;
|
685 |
+
break;
|
686 |
+
|
687 |
+
case 'wp:attachment_url':
|
688 |
+
$data['attachment_url'] = $child->textContent;
|
689 |
+
break;
|
690 |
+
|
691 |
+
case 'wp:postmeta':
|
692 |
+
$meta_item = $this->parse_meta_node( $child );
|
693 |
+
if ( ! empty( $meta_item ) ) {
|
694 |
+
$meta[] = $meta_item;
|
695 |
+
}
|
696 |
+
break;
|
697 |
+
|
698 |
+
case 'wp:comment':
|
699 |
+
$comment_item = $this->parse_comment_node( $child );
|
700 |
+
if ( ! empty( $comment_item ) ) {
|
701 |
+
$comments[] = $comment_item;
|
702 |
+
}
|
703 |
+
break;
|
704 |
+
|
705 |
+
case 'category':
|
706 |
+
$term_item = $this->parse_category_node( $child );
|
707 |
+
if ( ! empty( $term_item ) ) {
|
708 |
+
$terms[] = $term_item;
|
709 |
+
}
|
710 |
+
break;
|
711 |
+
}// End switch().
|
712 |
+
}// End foreach().
|
713 |
+
|
714 |
+
return compact( 'data', 'meta', 'comments', 'terms' );
|
715 |
+
}
|
716 |
+
|
717 |
+
/**
|
718 |
+
* Create new posts based on import information
|
719 |
+
*
|
720 |
+
* Posts marked as having a parent which doesn't exist will become top level items.
|
721 |
+
* Doesn't create a new post if: the post type doesn't exist, the given post ID
|
722 |
+
* is already noted as imported or a post with the same title and date already exists.
|
723 |
+
* Note that new/updated terms, comments and meta are imported for the last of the above.
|
724 |
+
*/
|
725 |
+
protected function process_post( $data, $meta, $comments, $terms ) {
|
726 |
+
/**
|
727 |
+
* Pre-process post data.
|
728 |
+
*
|
729 |
+
* @param array $data Post data. (Return empty to skip.)
|
730 |
+
* @param array $meta Meta data.
|
731 |
+
* @param array $comments Comments on the post.
|
732 |
+
* @param array $terms Terms on the post.
|
733 |
+
*/
|
734 |
+
$data = apply_filters( 'wxr_importer.pre_process.post', $data, $meta, $comments, $terms );
|
735 |
+
if ( empty( $data ) ) {
|
736 |
+
return false;
|
737 |
+
}
|
738 |
+
|
739 |
+
$original_id = isset( $data['post_id'] ) ? (int) $data['post_id'] : 0;
|
740 |
+
$parent_id = isset( $data['post_parent'] ) ? (int) $data['post_parent'] : 0;
|
741 |
+
$author_id = isset( $data['post_author'] ) ? (int) $data['post_author'] : 0;
|
742 |
+
|
743 |
+
// Have we already processed this?
|
744 |
+
if ( isset( $this->mapping['post'][ $original_id ] ) ) {
|
745 |
+
return;
|
746 |
+
}
|
747 |
+
|
748 |
+
$post_type_object = get_post_type_object( $data['post_type'] );
|
749 |
+
|
750 |
+
// Is this type even valid?
|
751 |
+
if ( ! $post_type_object ) {
|
752 |
+
$this->logger->warning( sprintf(
|
753 |
+
__( 'Failed to import "%1$s": Invalid post type %2$s', 'wordpress-importer' ),
|
754 |
+
$data['post_title'],
|
755 |
+
$data['post_type']
|
756 |
+
) );
|
757 |
+
return false;
|
758 |
+
}
|
759 |
+
|
760 |
+
$post_exists = $this->post_exists( $data );
|
761 |
+
if ( $post_exists ) {
|
762 |
+
$this->logger->info( sprintf(
|
763 |
+
__( '%1$s "%2$s" already exists.', 'wordpress-importer' ),
|
764 |
+
$post_type_object->labels->singular_name,
|
765 |
+
$data['post_title']
|
766 |
+
) );
|
767 |
+
|
768 |
+
/**
|
769 |
+
* Post processing already imported.
|
770 |
+
*
|
771 |
+
* @param array $data Raw data imported for the post.
|
772 |
+
*/
|
773 |
+
do_action( 'wxr_importer.process_already_imported.post', $data );
|
774 |
+
|
775 |
+
// Even though this post already exists, new comments might need importing
|
776 |
+
$this->process_comments( $comments, $original_id, $data, $post_exists );
|
777 |
+
|
778 |
+
return false;
|
779 |
+
}
|
780 |
+
|
781 |
+
// Map the parent post, or mark it as one we need to fix
|
782 |
+
$requires_remapping = false;
|
783 |
+
if ( $parent_id ) {
|
784 |
+
if ( isset( $this->mapping['post'][ $parent_id ] ) ) {
|
785 |
+
$data['post_parent'] = $this->mapping['post'][ $parent_id ];
|
786 |
+
} else {
|
787 |
+
$meta[] = array(
|
788 |
+
'key' => '_wxr_import_parent',
|
789 |
+
'value' => $parent_id,
|
790 |
+
);
|
791 |
+
$requires_remapping = true;
|
792 |
+
|
793 |
+
$data['post_parent'] = 0;
|
794 |
+
}
|
795 |
+
}
|
796 |
+
|
797 |
+
// Map the author, or mark it as one we need to fix
|
798 |
+
$author = sanitize_user( $data['post_author'], true );
|
799 |
+
if ( empty( $author ) ) {
|
800 |
+
// Missing or invalid author, use default if available.
|
801 |
+
$data['post_author'] = $this->options['default_author'];
|
802 |
+
} elseif ( isset( $this->mapping['user_slug'][ $author ] ) ) {
|
803 |
+
$data['post_author'] = $this->mapping['user_slug'][ $author ];
|
804 |
+
} else {
|
805 |
+
$meta[] = array(
|
806 |
+
'key' => '_wxr_import_user_slug',
|
807 |
+
'value' => $author,
|
808 |
+
);
|
809 |
+
$requires_remapping = true;
|
810 |
+
|
811 |
+
$data['post_author'] = (int) get_current_user_id();
|
812 |
+
}
|
813 |
+
|
814 |
+
// Does the post look like it contains attachment images?
|
815 |
+
if ( preg_match( self::REGEX_HAS_ATTACHMENT_REFS, $data['post_content'] ) ) {
|
816 |
+
$meta[] = array(
|
817 |
+
'key' => '_wxr_import_has_attachment_refs',
|
818 |
+
'value' => true,
|
819 |
+
);
|
820 |
+
$requires_remapping = true;
|
821 |
+
}
|
822 |
+
|
823 |
+
// Whitelist to just the keys we allow
|
824 |
+
$postdata = array(
|
825 |
+
'import_id' => $data['post_id'],
|
826 |
+
);
|
827 |
+
$allowed = array(
|
828 |
+
'post_author' => true,
|
829 |
+
'post_date' => true,
|
830 |
+
'post_date_gmt' => true,
|
831 |
+
'post_content' => true,
|
832 |
+
'post_excerpt' => true,
|
833 |
+
'post_title' => true,
|
834 |
+
'post_status' => true,
|
835 |
+
'post_name' => true,
|
836 |
+
'comment_status' => true,
|
837 |
+
'ping_status' => true,
|
838 |
+
'guid' => true,
|
839 |
+
'post_parent' => true,
|
840 |
+
'menu_order' => true,
|
841 |
+
'post_type' => true,
|
842 |
+
'post_password' => true,
|
843 |
+
);
|
844 |
+
foreach ( $data as $key => $value ) {
|
845 |
+
if ( ! isset( $allowed[ $key ] ) ) {
|
846 |
+
continue;
|
847 |
+
}
|
848 |
+
|
849 |
+
$postdata[ $key ] = $data[ $key ];
|
850 |
+
}
|
851 |
+
|
852 |
+
$postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $data );
|
853 |
+
|
854 |
+
if ( 'attachment' === $postdata['post_type'] ) {
|
855 |
+
if ( ! $this->options['fetch_attachments'] ) {
|
856 |
+
$this->logger->notice( sprintf(
|
857 |
+
__( 'Skipping attachment "%s", fetching attachments disabled' ),
|
858 |
+
$data['post_title']
|
859 |
+
) );
|
860 |
+
/**
|
861 |
+
* Post processing skipped.
|
862 |
+
*
|
863 |
+
* @param array $data Raw data imported for the post.
|
864 |
+
* @param array $meta Raw meta data, already processed by {@see process_post_meta}.
|
865 |
+
*/
|
866 |
+
do_action( 'wxr_importer.process_skipped.post', $data, $meta );
|
867 |
+
return false;
|
868 |
+
}
|
869 |
+
$remote_url = ! empty( $data['attachment_url'] ) ? $data['attachment_url'] : $data['guid'];
|
870 |
+
$post_id = $this->process_attachment( $postdata, $meta, $remote_url );
|
871 |
+
} else {
|
872 |
+
$post_id = wp_insert_post( $postdata, true );
|
873 |
+
do_action( 'wp_import_insert_post', $post_id, $original_id, $postdata, $data );
|
874 |
+
}
|
875 |
+
|
876 |
+
if ( is_wp_error( $post_id ) ) {
|
877 |
+
$this->logger->error( sprintf(
|
878 |
+
__( 'Failed to import "%1$s" (%2$s)', 'wordpress-importer' ),
|
879 |
+
$data['post_title'],
|
880 |
+
$post_type_object->labels->singular_name
|
881 |
+
) );
|
882 |
+
$this->logger->debug( $post_id->get_error_message() );
|
883 |
+
|
884 |
+
/**
|
885 |
+
* Post processing failed.
|
886 |
+
*
|
887 |
+
* @param WP_Error $post_id Error object.
|
888 |
+
* @param array $data Raw data imported for the post.
|
889 |
+
* @param array $meta Raw meta data, already processed by {@see process_post_meta}.
|
890 |
+
* @param array $comments Raw comment data, already processed by {@see process_comments}.
|
891 |
+
* @param array $terms Raw term data, already processed.
|
892 |
+
*/
|
893 |
+
do_action( 'wxr_importer.process_failed.post', $post_id, $data, $meta, $comments, $terms );
|
894 |
+
return false;
|
895 |
+
}
|
896 |
+
|
897 |
+
// Ensure stickiness is handled correctly too
|
898 |
+
if ( $data['is_sticky'] === '1' ) {
|
899 |
+
stick_post( $post_id );
|
900 |
+
}
|
901 |
+
|
902 |
+
// map pre-import ID to local ID
|
903 |
+
$this->mapping['post'][ $original_id ] = (int) $post_id;
|
904 |
+
if ( $requires_remapping ) {
|
905 |
+
$this->requires_remapping['post'][ $post_id ] = true;
|
906 |
+
}
|
907 |
+
$this->mark_post_exists( $data, $post_id );
|
908 |
+
|
909 |
+
$this->logger->info( sprintf(
|
910 |
+
__( 'Imported "%1$s" (%2$s)', 'wordpress-importer' ),
|
911 |
+
$data['post_title'],
|
912 |
+
$post_type_object->labels->singular_name
|
913 |
+
) );
|
914 |
+
$this->logger->debug( sprintf(
|
915 |
+
__( 'Post %1$d remapped to %2$d', 'wordpress-importer' ),
|
916 |
+
$original_id,
|
917 |
+
$post_id
|
918 |
+
) );
|
919 |
+
|
920 |
+
// Handle the terms too
|
921 |
+
$terms = apply_filters( 'wp_import_post_terms', $terms, $post_id, $data );
|
922 |
+
|
923 |
+
if ( ! empty( $terms ) ) {
|
924 |
+
$term_ids = array();
|
925 |
+
foreach ( $terms as $term ) {
|
926 |
+
$taxonomy = $term['taxonomy'];
|
927 |
+
$key = sha1( $taxonomy . ':' . $term['slug'] );
|
928 |
+
|
929 |
+
if ( isset( $this->mapping['term'][ $key ] ) ) {
|
930 |
+
$term_ids[ $taxonomy ][] = (int) $this->mapping['term'][ $key ];
|
931 |
+
} else {
|
932 |
+
$meta[] = array(
|
933 |
+
'key' => '_wxr_import_term',
|
934 |
+
'value' => $term,
|
935 |
+
);
|
936 |
+
$requires_remapping = true;
|
937 |
+
}
|
938 |
+
}
|
939 |
+
|
940 |
+
foreach ( $term_ids as $tax => $ids ) {
|
941 |
+
$tt_ids = wp_set_post_terms( $post_id, $ids, $tax );
|
942 |
+
do_action( 'wp_import_set_post_terms', $tt_ids, $ids, $tax, $post_id, $data );
|
943 |
+
}
|
944 |
+
}
|
945 |
+
|
946 |
+
$this->process_comments( $comments, $post_id, $data );
|
947 |
+
$this->process_post_meta( $meta, $post_id, $data );
|
948 |
+
|
949 |
+
if ( 'nav_menu_item' === $data['post_type'] ) {
|
950 |
+
$this->process_menu_item_meta( $post_id, $data, $meta );
|
951 |
+
}
|
952 |
+
|
953 |
+
/**
|
954 |
+
* Post processing completed.
|
955 |
+
*
|
956 |
+
* @param int $post_id New post ID.
|
957 |
+
* @param array $data Raw data imported for the post.
|
958 |
+
* @param array $meta Raw meta data, already processed by {@see process_post_meta}.
|
959 |
+
* @param array $comments Raw comment data, already processed by {@see process_comments}.
|
960 |
+
* @param array $terms Raw term data, already processed.
|
961 |
+
*/
|
962 |
+
do_action( 'wxr_importer.processed.post', $post_id, $data, $meta, $comments, $terms );
|
963 |
+
}
|
964 |
+
|
965 |
+
/**
|
966 |
+
* Attempt to create a new menu item from import data
|
967 |
+
*
|
968 |
+
* Fails for draft, orphaned menu items and those without an associated nav_menu
|
969 |
+
* or an invalid nav_menu term. If the post type or term object which the menu item
|
970 |
+
* represents doesn't exist then the menu item will not be imported (waits until the
|
971 |
+
* end of the import to retry again before discarding).
|
972 |
+
*
|
973 |
+
* @param array $item Menu item details from WXR file
|
974 |
+
*/
|
975 |
+
protected function process_menu_item_meta( $post_id, $data, $meta ) {
|
976 |
+
|
977 |
+
$item_type = get_post_meta( $post_id, '_menu_item_type', true );
|
978 |
+
$original_object_id = get_post_meta( $post_id, '_menu_item_object_id', true );
|
979 |
+
$object_id = null;
|
980 |
+
|
981 |
+
$this->logger->debug( sprintf( 'Processing menu item %s', $item_type ) );
|
982 |
+
|
983 |
+
$requires_remapping = false;
|
984 |
+
switch ( $item_type ) {
|
985 |
+
case 'taxonomy':
|
986 |
+
if ( isset( $this->mapping['term_id'][ $original_object_id ] ) ) {
|
987 |
+
$object_id = $this->mapping['term_id'][ $original_object_id ];
|
988 |
+
} else {
|
989 |
+
add_post_meta( $post_id, '_wxr_import_menu_item', wp_slash( $original_object_id ) );
|
990 |
+
$requires_remapping = true;
|
991 |
+
}
|
992 |
+
break;
|
993 |
+
|
994 |
+
case 'post_type':
|
995 |
+
if ( isset( $this->mapping['post'][ $original_object_id ] ) ) {
|
996 |
+
$object_id = $this->mapping['post'][ $original_object_id ];
|
997 |
+
} else {
|
998 |
+
add_post_meta( $post_id, '_wxr_import_menu_item', wp_slash( $original_object_id ) );
|
999 |
+
$requires_remapping = true;
|
1000 |
+
}
|
1001 |
+
break;
|
1002 |
+
|
1003 |
+
case 'custom':
|
1004 |
+
// Custom refers to itself, wonderfully easy.
|
1005 |
+
$object_id = $post_id;
|
1006 |
+
break;
|
1007 |
+
|
1008 |
+
default:
|
1009 |
+
// associated object is missing or not imported yet, we'll retry later
|
1010 |
+
$this->missing_menu_items[] = $item;
|
1011 |
+
$this->logger->debug( 'Unknown menu item type' );
|
1012 |
+
break;
|
1013 |
+
}
|
1014 |
+
|
1015 |
+
if ( $requires_remapping ) {
|
1016 |
+
$this->requires_remapping['post'][ $post_id ] = true;
|
1017 |
+
}
|
1018 |
+
|
1019 |
+
if ( empty( $object_id ) ) {
|
1020 |
+
// Nothing needed here.
|
1021 |
+
return;
|
1022 |
+
}
|
1023 |
+
|
1024 |
+
$this->logger->debug( sprintf( 'Menu item %d mapped to %d', $original_object_id, $object_id ) );
|
1025 |
+
update_post_meta( $post_id, '_menu_item_object_id', wp_slash( $object_id ) );
|
1026 |
+
}
|
1027 |
+
|
1028 |
+
/**
|
1029 |
+
* If fetching attachments is enabled then attempt to create a new attachment
|
1030 |
+
*
|
1031 |
+
* @param array $post Attachment post details from WXR
|
1032 |
+
* @param string $url URL to fetch attachment from
|
1033 |
+
* @return int|WP_Error Post ID on success, WP_Error otherwise
|
1034 |
+
*/
|
1035 |
+
protected function process_attachment( $post, $meta, $remote_url ) {
|
1036 |
+
// try to use _wp_attached file for upload folder placement to ensure the same location as the export site
|
1037 |
+
// e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload()
|
1038 |
+
$post['upload_date'] = $post['post_date'];
|
1039 |
+
foreach ( $meta as $meta_item ) {
|
1040 |
+
if ( $meta_item['key'] !== '_wp_attached_file' ) {
|
1041 |
+
continue;
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta_item['value'], $matches ) ) {
|
1045 |
+
$post['upload_date'] = $matches[0];
|
1046 |
+
}
|
1047 |
+
break;
|
1048 |
+
}
|
1049 |
+
|
1050 |
+
// if the URL is absolute, but does not contain address, then upload it assuming base_site_url
|
1051 |
+
if ( preg_match( '|^/[\w\W]+$|', $remote_url ) ) {
|
1052 |
+
$remote_url = rtrim( $this->base_url, '/' ) . $remote_url;
|
1053 |
+
}
|
1054 |
+
|
1055 |
+
$upload = $this->fetch_remote_file( $remote_url, $post );
|
1056 |
+
if ( is_wp_error( $upload ) ) {
|
1057 |
+
return $upload;
|
1058 |
+
}
|
1059 |
+
|
1060 |
+
$info = wp_check_filetype( $upload['file'] );
|
1061 |
+
if ( ! $info ) {
|
1062 |
+
return new WP_Error( 'attachment_processing_error', __( 'Invalid file type', 'wordpress-importer' ) );
|
1063 |
+
}
|
1064 |
+
|
1065 |
+
$post['post_mime_type'] = $info['type'];
|
1066 |
+
|
1067 |
+
// WP really likes using the GUID for display. Allow updating it.
|
1068 |
+
// See https://core.trac.wordpress.org/ticket/33386
|
1069 |
+
if ( $this->options['update_attachment_guids'] ) {
|
1070 |
+
$post['guid'] = $upload['url'];
|
1071 |
+
}
|
1072 |
+
|
1073 |
+
// as per wp-admin/includes/upload.php
|
1074 |
+
$post_id = wp_insert_attachment( $post, $upload['file'] );
|
1075 |
+
if ( is_wp_error( $post_id ) ) {
|
1076 |
+
return $post_id;
|
1077 |
+
}
|
1078 |
+
|
1079 |
+
$attachment_metadata = wp_generate_attachment_metadata( $post_id, $upload['file'] );
|
1080 |
+
wp_update_attachment_metadata( $post_id, $attachment_metadata );
|
1081 |
+
|
1082 |
+
// Map this image URL later if we need to
|
1083 |
+
$this->url_remap[ $remote_url ] = $upload['url'];
|
1084 |
+
|
1085 |
+
// If we have a HTTPS URL, ensure the HTTP URL gets replaced too
|
1086 |
+
if ( substr( $remote_url, 0, 8 ) === 'https://' ) {
|
1087 |
+
$insecure_url = 'http' . substr( $remote_url, 5 );
|
1088 |
+
$this->url_remap[ $insecure_url ] = $upload['url'];
|
1089 |
+
}
|
1090 |
+
|
1091 |
+
if ( $this->options['aggressive_url_search'] ) {
|
1092 |
+
// remap resized image URLs, works by stripping the extension and remapping the URL stub.
|
1093 |
+
/*
|
1094 |
+
if ( preg_match( '!^image/!', $info['type'] ) ) {
|
1095 |
+
$parts = pathinfo( $remote_url );
|
1096 |
+
$name = basename( $parts['basename'], ".{$parts['extension']}" ); // PATHINFO_FILENAME in PHP 5.2
|
1097 |
+
|
1098 |
+
$parts_new = pathinfo( $upload['url'] );
|
1099 |
+
$name_new = basename( $parts_new['basename'], ".{$parts_new['extension']}" );
|
1100 |
+
|
1101 |
+
$this->url_remap[$parts['dirname'] . '/' . $name] = $parts_new['dirname'] . '/' . $name_new;
|
1102 |
+
}*/
|
1103 |
+
}
|
1104 |
+
|
1105 |
+
return $post_id;
|
1106 |
+
}
|
1107 |
+
|
1108 |
+
/**
|
1109 |
+
* Parse a meta node into meta data.
|
1110 |
+
*
|
1111 |
+
* @param DOMElement $node Parent node of meta data (typically `wp:postmeta` or `wp:commentmeta`).
|
1112 |
+
* @return array|null Meta data array on success, or null on error.
|
1113 |
+
*/
|
1114 |
+
protected function parse_meta_node( $node ) {
|
1115 |
+
foreach ( $node->childNodes as $child ) {
|
1116 |
+
// We only care about child elements
|
1117 |
+
if ( $child->nodeType !== XML_ELEMENT_NODE ) {
|
1118 |
+
continue;
|
1119 |
+
}
|
1120 |
+
|
1121 |
+
switch ( $child->tagName ) {
|
1122 |
+
case 'wp:meta_key':
|
1123 |
+
$key = $child->textContent;
|
1124 |
+
break;
|
1125 |
+
|
1126 |
+
case 'wp:meta_value':
|
1127 |
+
$value = $child->textContent;
|
1128 |
+
break;
|
1129 |
+
}
|
1130 |
+
}
|
1131 |
+
|
1132 |
+
if ( empty( $key ) || empty( $value ) ) {
|
1133 |
+
return null;
|
1134 |
+
}
|
1135 |
+
|
1136 |
+
return compact( 'key', 'value' );
|
1137 |
+
}
|
1138 |
+
|
1139 |
+
/**
|
1140 |
+
* Process and import post meta items.
|
1141 |
+
*
|
1142 |
+
* @param array $meta List of meta data arrays
|
1143 |
+
* @param int $post_id Post to associate with
|
1144 |
+
* @param array $post Post data
|
1145 |
+
* @return int|WP_Error Number of meta items imported on success, error otherwise.
|
1146 |
+
*/
|
1147 |
+
protected function process_post_meta( $meta, $post_id, $post ) {
|
1148 |
+
if ( empty( $meta ) ) {
|
1149 |
+
return true;
|
1150 |
+
}
|
1151 |
+
|
1152 |
+
foreach ( $meta as $meta_item ) {
|
1153 |
+
/**
|
1154 |
+
* Pre-process post meta data.
|
1155 |
+
*
|
1156 |
+
* @param array $meta_item Meta data. (Return empty to skip.)
|
1157 |
+
* @param int $post_id Post the meta is attached to.
|
1158 |
+
*/
|
1159 |
+
$meta_item = apply_filters( 'wxr_importer.pre_process.post_meta', $meta_item, $post_id );
|
1160 |
+
if ( empty( $meta_item ) ) {
|
1161 |
+
return false;
|
1162 |
+
}
|
1163 |
+
|
1164 |
+
$key = apply_filters( 'import_post_meta_key', $meta_item['key'], $post_id, $post );
|
1165 |
+
$value = false;
|
1166 |
+
|
1167 |
+
if ( '_edit_last' === $key ) {
|
1168 |
+
$value = intval( $meta_item['value'] );
|
1169 |
+
if ( ! isset( $this->mapping['user'][ $value ] ) ) {
|
1170 |
+
// Skip!
|
1171 |
+
continue;
|
1172 |
+
}
|
1173 |
+
|
1174 |
+
$value = $this->mapping['user'][ $value ];
|
1175 |
+
}
|
1176 |
+
|
1177 |
+
if ( $key ) {
|
1178 |
+
// export gets meta straight from the DB so could have a serialized string
|
1179 |
+
if ( ! $value ) {
|
1180 |
+
$value = maybe_unserialize( $meta_item['value'] );
|
1181 |
+
}
|
1182 |
+
|
1183 |
+
add_post_meta( $post_id, $key, $value );
|
1184 |
+
do_action( 'import_post_meta', $post_id, $key, $value );
|
1185 |
+
|
1186 |
+
// if the post has a featured image, take note of this in case of remap
|
1187 |
+
if ( '_thumbnail_id' === $key ) {
|
1188 |
+
$this->featured_images[ $post_id ] = (int) $value;
|
1189 |
+
}
|
1190 |
+
}
|
1191 |
+
}// End foreach().
|
1192 |
+
|
1193 |
+
return true;
|
1194 |
+
}
|
1195 |
+
|
1196 |
+
/**
|
1197 |
+
* Parse a comment node into comment data.
|
1198 |
+
*
|
1199 |
+
* @param DOMElement $node Parent node of comment data (typically `wp:comment`).
|
1200 |
+
* @return array Comment data array.
|
1201 |
+
*/
|
1202 |
+
protected function parse_comment_node( $node ) {
|
1203 |
+
$data = array(
|
1204 |
+
'commentmeta' => array(),
|
1205 |
+
);
|
1206 |
+
|
1207 |
+
foreach ( $node->childNodes as $child ) {
|
1208 |
+
// We only care about child elements
|
1209 |
+
if ( $child->nodeType !== XML_ELEMENT_NODE ) {
|
1210 |
+
continue;
|
1211 |
+
}
|
1212 |
+
|
1213 |
+
switch ( $child->tagName ) {
|
1214 |
+
case 'wp:comment_id':
|
1215 |
+
$data['comment_id'] = $child->textContent;
|
1216 |
+
break;
|
1217 |
+
case 'wp:comment_author':
|
1218 |
+
$data['comment_author'] = $child->textContent;
|
1219 |
+
break;
|
1220 |
+
|
1221 |
+
case 'wp:comment_author_email':
|
1222 |
+
$data['comment_author_email'] = $child->textContent;
|
1223 |
+
break;
|
1224 |
+
|
1225 |
+
case 'wp:comment_author_IP':
|
1226 |
+
$data['comment_author_IP'] = $child->textContent;
|
1227 |
+
break;
|
1228 |
+
|
1229 |
+
case 'wp:comment_author_url':
|
1230 |
+
$data['comment_author_url'] = $child->textContent;
|
1231 |
+
break;
|
1232 |
+
|
1233 |
+
case 'wp:comment_user_id':
|
1234 |
+
$data['comment_user_id'] = $child->textContent;
|
1235 |
+
break;
|
1236 |
+
|
1237 |
+
case 'wp:comment_date':
|
1238 |
+
$data['comment_date'] = $child->textContent;
|
1239 |
+
break;
|
1240 |
+
|
1241 |
+
case 'wp:comment_date_gmt':
|
1242 |
+
$data['comment_date_gmt'] = $child->textContent;
|
1243 |
+
break;
|
1244 |
+
|
1245 |
+
case 'wp:comment_content':
|
1246 |
+
$data['comment_content'] = $child->textContent;
|
1247 |
+
break;
|
1248 |
+
|
1249 |
+
case 'wp:comment_approved':
|
1250 |
+
$data['comment_approved'] = $child->textContent;
|
1251 |
+
break;
|
1252 |
+
|
1253 |
+
case 'wp:comment_type':
|
1254 |
+
$data['comment_type'] = $child->textContent;
|
1255 |
+
break;
|
1256 |
+
|
1257 |
+
case 'wp:comment_parent':
|
1258 |
+
$data['comment_parent'] = $child->textContent;
|
1259 |
+
break;
|
1260 |
+
|
1261 |
+
case 'wp:commentmeta':
|
1262 |
+
$meta_item = $this->parse_meta_node( $child );
|
1263 |
+
if ( ! empty( $meta_item ) ) {
|
1264 |
+
$data['commentmeta'][] = $meta_item;
|
1265 |
+
}
|
1266 |
+
break;
|
1267 |
+
}// End switch().
|
1268 |
+
}// End foreach().
|
1269 |
+
|
1270 |
+
return $data;
|
1271 |
+
}
|
1272 |
+
|
1273 |
+
/**
|
1274 |
+
* Process and import comment data.
|
1275 |
+
*
|
1276 |
+
* @param array $comments List of comment data arrays.
|
1277 |
+
* @param int $post_id Post to associate with.
|
1278 |
+
* @param array $post Post data.
|
1279 |
+
* @return int|WP_Error Number of comments imported on success, error otherwise.
|
1280 |
+
*/
|
1281 |
+
protected function process_comments( $comments, $post_id, $post, $post_exists = false ) {
|
1282 |
+
|
1283 |
+
$comments = apply_filters( 'wp_import_post_comments', $comments, $post_id, $post );
|
1284 |
+
if ( empty( $comments ) ) {
|
1285 |
+
return 0;
|
1286 |
+
}
|
1287 |
+
|
1288 |
+
$num_comments = 0;
|
1289 |
+
|
1290 |
+
// Sort by ID to avoid excessive remapping later
|
1291 |
+
usort( $comments, array( $this, 'sort_comments_by_id' ) );
|
1292 |
+
|
1293 |
+
foreach ( $comments as $key => $comment ) {
|
1294 |
+
/**
|
1295 |
+
* Pre-process comment data
|
1296 |
+
*
|
1297 |
+
* @param array $comment Comment data. (Return empty to skip.)
|
1298 |
+
* @param int $post_id Post the comment is attached to.
|
1299 |
+
*/
|
1300 |
+
$comment = apply_filters( 'wxr_importer.pre_process.comment', $comment, $post_id );
|
1301 |
+
if ( empty( $comment ) ) {
|
1302 |
+
return false;
|
1303 |
+
}
|
1304 |
+
|
1305 |
+
$original_id = isset( $comment['comment_id'] ) ? (int) $comment['comment_id'] : 0;
|
1306 |
+
$parent_id = isset( $comment['comment_parent'] ) ? (int) $comment['comment_parent'] : 0;
|
1307 |
+
$author_id = isset( $comment['comment_user_id'] ) ? (int) $comment['comment_user_id'] : 0;
|
1308 |
+
|
1309 |
+
// if this is a new post we can skip the comment_exists() check
|
1310 |
+
// TODO: Check comment_exists for performance
|
1311 |
+
if ( $post_exists ) {
|
1312 |
+
$existing = $this->comment_exists( $comment );
|
1313 |
+
if ( $existing ) {
|
1314 |
+
|
1315 |
+
/**
|
1316 |
+
* Comment processing already imported.
|
1317 |
+
*
|
1318 |
+
* @param array $comment Raw data imported for the comment.
|
1319 |
+
*/
|
1320 |
+
do_action( 'wxr_importer.process_already_imported.comment', $comment );
|
1321 |
+
|
1322 |
+
$this->mapping['comment'][ $original_id ] = $existing;
|
1323 |
+
continue;
|
1324 |
+
}
|
1325 |
+
}
|
1326 |
+
|
1327 |
+
// Remove meta from the main array
|
1328 |
+
$meta = isset( $comment['commentmeta'] ) ? $comment['commentmeta'] : array();
|
1329 |
+
unset( $comment['commentmeta'] );
|
1330 |
+
|
1331 |
+
// Map the parent comment, or mark it as one we need to fix
|
1332 |
+
$requires_remapping = false;
|
1333 |
+
if ( $parent_id ) {
|
1334 |
+
if ( isset( $this->mapping['comment'][ $parent_id ] ) ) {
|
1335 |
+
$comment['comment_parent'] = $this->mapping['comment'][ $parent_id ];
|
1336 |
+
} else {
|
1337 |
+
// Prepare for remapping later
|
1338 |
+
$meta[] = array(
|
1339 |
+
'key' => '_wxr_import_parent',
|
1340 |
+
'value' => $parent_id,
|
1341 |
+
);
|
1342 |
+
$requires_remapping = true;
|
1343 |
+
|
1344 |
+
// Wipe the parent for now
|
1345 |
+
$comment['comment_parent'] = 0;
|
1346 |
+
}
|
1347 |
+
}
|
1348 |
+
|
1349 |
+
// Map the author, or mark it as one we need to fix
|
1350 |
+
if ( $author_id ) {
|
1351 |
+
if ( isset( $this->mapping['user'][ $author_id ] ) ) {
|
1352 |
+
$comment['user_id'] = $this->mapping['user'][ $author_id ];
|
1353 |
+
} else {
|
1354 |
+
// Prepare for remapping later
|
1355 |
+
$meta[] = array(
|
1356 |
+
'key' => '_wxr_import_user',
|
1357 |
+
'value' => $author_id,
|
1358 |
+
);
|
1359 |
+
$requires_remapping = true;
|
1360 |
+
|
1361 |
+
// Wipe the user for now
|
1362 |
+
$comment['user_id'] = 0;
|
1363 |
+
}
|
1364 |
+
}
|
1365 |
+
|
1366 |
+
// Run standard core filters
|
1367 |
+
$comment['comment_post_ID'] = $post_id;
|
1368 |
+
$comment = wp_filter_comment( $comment );
|
1369 |
+
|
1370 |
+
// wp_insert_comment expects slashed data
|
1371 |
+
$comment_id = wp_insert_comment( wp_slash( $comment ) );
|
1372 |
+
$this->mapping['comment'][ $original_id ] = $comment_id;
|
1373 |
+
if ( $requires_remapping ) {
|
1374 |
+
$this->requires_remapping['comment'][ $comment_id ] = true;
|
1375 |
+
}
|
1376 |
+
$this->mark_comment_exists( $comment, $comment_id );
|
1377 |
+
|
1378 |
+
/**
|
1379 |
+
* Comment has been imported.
|
1380 |
+
*
|
1381 |
+
* @param int $comment_id New comment ID
|
1382 |
+
* @param array $comment Comment inserted (`comment_id` item refers to the original ID)
|
1383 |
+
* @param int $post_id Post parent of the comment
|
1384 |
+
* @param array $post Post data
|
1385 |
+
*/
|
1386 |
+
do_action( 'wp_import_insert_comment', $comment_id, $comment, $post_id, $post );
|
1387 |
+
|
1388 |
+
// Process the meta items
|
1389 |
+
foreach ( $meta as $meta_item ) {
|
1390 |
+
$value = maybe_unserialize( $meta_item['value'] );
|
1391 |
+
add_comment_meta( $comment_id, wp_slash( $meta_item['key'] ), wp_slash( $value ) );
|
1392 |
+
}
|
1393 |
+
|
1394 |
+
/**
|
1395 |
+
* Post processing completed.
|
1396 |
+
*
|
1397 |
+
* @param int $post_id New post ID.
|
1398 |
+
* @param array $comment Raw data imported for the comment.
|
1399 |
+
* @param array $meta Raw meta data, already processed by {@see process_post_meta}.
|
1400 |
+
* @param array $post_id Parent post ID.
|
1401 |
+
*/
|
1402 |
+
do_action( 'wxr_importer.processed.comment', $comment_id, $comment, $meta, $post_id );
|
1403 |
+
|
1404 |
+
$num_comments++;
|
1405 |
+
}// End foreach().
|
1406 |
+
|
1407 |
+
return $num_comments;
|
1408 |
+
}
|
1409 |
+
|
1410 |
+
protected function parse_category_node( $node ) {
|
1411 |
+
$data = array(
|
1412 |
+
// Default taxonomy to "category", since this is a `<category>` tag
|
1413 |
+
'taxonomy' => 'category',
|
1414 |
+
);
|
1415 |
+
$meta = array();
|
1416 |
+
|
1417 |
+
if ( $node->hasAttribute( 'domain' ) ) {
|
1418 |
+
$data['taxonomy'] = $node->getAttribute( 'domain' );
|
1419 |
+
}
|
1420 |
+
if ( $node->hasAttribute( 'nicename' ) ) {
|
1421 |
+
$data['slug'] = $node->getAttribute( 'nicename' );
|
1422 |
+
}
|
1423 |
+
|
1424 |
+
$data['name'] = $node->textContent;
|
1425 |
+
|
1426 |
+
if ( empty( $data['slug'] ) ) {
|
1427 |
+
return null;
|
1428 |
+
}
|
1429 |
+
|
1430 |
+
// Just for extra compatibility
|
1431 |
+
if ( $data['taxonomy'] === 'tag' ) {
|
1432 |
+
$data['taxonomy'] = 'post_tag';
|
1433 |
+
}
|
1434 |
+
|
1435 |
+
return $data;
|
1436 |
+
}
|
1437 |
+
|
1438 |
+
/**
|
1439 |
+
* Callback for `usort` to sort comments by ID
|
1440 |
+
*
|
1441 |
+
* @param array $a Comment data for the first comment
|
1442 |
+
* @param array $b Comment data for the second comment
|
1443 |
+
* @return int
|
1444 |
+
*/
|
1445 |
+
public static function sort_comments_by_id( $a, $b ) {
|
1446 |
+
if ( empty( $a['comment_id'] ) ) {
|
1447 |
+
return 1;
|
1448 |
+
}
|
1449 |
+
|
1450 |
+
if ( empty( $b['comment_id'] ) ) {
|
1451 |
+
return -1;
|
1452 |
+
}
|
1453 |
+
|
1454 |
+
return $a['comment_id'] - $b['comment_id'];
|
1455 |
+
}
|
1456 |
+
|
1457 |
+
protected function parse_author_node( $node ) {
|
1458 |
+
$data = array();
|
1459 |
+
$meta = array();
|
1460 |
+
foreach ( $node->childNodes as $child ) {
|
1461 |
+
// We only care about child elements
|
1462 |
+
if ( $child->nodeType !== XML_ELEMENT_NODE ) {
|
1463 |
+
continue;
|
1464 |
+
}
|
1465 |
+
|
1466 |
+
switch ( $child->tagName ) {
|
1467 |
+
case 'wp:author_login':
|
1468 |
+
$data['user_login'] = $child->textContent;
|
1469 |
+
break;
|
1470 |
+
|
1471 |
+
case 'wp:author_id':
|
1472 |
+
$data['ID'] = $child->textContent;
|
1473 |
+
break;
|
1474 |
+
|
1475 |
+
case 'wp:author_email':
|
1476 |
+
$data['user_email'] = $child->textContent;
|
1477 |
+
break;
|
1478 |
+
|
1479 |
+
case 'wp:author_display_name':
|
1480 |
+
$data['display_name'] = $child->textContent;
|
1481 |
+
break;
|
1482 |
+
|
1483 |
+
case 'wp:author_first_name':
|
1484 |
+
$data['first_name'] = $child->textContent;
|
1485 |
+
break;
|
1486 |
+
|
1487 |
+
case 'wp:author_last_name':
|
1488 |
+
$data['last_name'] = $child->textContent;
|
1489 |
+
break;
|
1490 |
+
}
|
1491 |
+
}
|
1492 |
+
|
1493 |
+
return compact( 'data', 'meta' );
|
1494 |
+
}
|
1495 |
+
|
1496 |
+
protected function process_author( $data, $meta ) {
|
1497 |
+
/**
|
1498 |
+
* Pre-process user data.
|
1499 |
+
*
|
1500 |
+
* @param array $data User data. (Return empty to skip.)
|
1501 |
+
* @param array $meta Meta data.
|
1502 |
+
*/
|
1503 |
+
$data = apply_filters( 'wxr_importer.pre_process.user', $data, $meta );
|
1504 |
+
if ( empty( $data ) ) {
|
1505 |
+
return false;
|
1506 |
+
}
|
1507 |
+
|
1508 |
+
// Have we already handled this user?
|
1509 |
+
$original_id = isset( $data['ID'] ) ? $data['ID'] : 0;
|
1510 |
+
$original_slug = $data['user_login'];
|
1511 |
+
|
1512 |
+
if ( isset( $this->mapping['user'][ $original_id ] ) ) {
|
1513 |
+
$existing = $this->mapping['user'][ $original_id ];
|
1514 |
+
|
1515 |
+
// Note the slug mapping if we need to too
|
1516 |
+
if ( ! isset( $this->mapping['user_slug'][ $original_slug ] ) ) {
|
1517 |
+
$this->mapping['user_slug'][ $original_slug ] = $existing;
|
1518 |
+
}
|
1519 |
+
|
1520 |
+
return false;
|
1521 |
+
}
|
1522 |
+
|
1523 |
+
if ( isset( $this->mapping['user_slug'][ $original_slug ] ) ) {
|
1524 |
+
$existing = $this->mapping['user_slug'][ $original_slug ];
|
1525 |
+
|
1526 |
+
// Ensure we note the mapping too
|
1527 |
+
$this->mapping['user'][ $original_id ] = $existing;
|
1528 |
+
|
1529 |
+
return false;
|
1530 |
+
}
|
1531 |
+
|
1532 |
+
// Allow overriding the user's slug
|
1533 |
+
$login = $original_slug;
|
1534 |
+
if ( isset( $this->user_slug_override[ $login ] ) ) {
|
1535 |
+
$login = $this->user_slug_override[ $login ];
|
1536 |
+
}
|
1537 |
+
|
1538 |
+
$userdata = array(
|
1539 |
+
'user_login' => sanitize_user( $login, true ),
|
1540 |
+
'user_pass' => wp_generate_password(),
|
1541 |
+
);
|
1542 |
+
|
1543 |
+
$allowed = array(
|
1544 |
+
'user_email' => true,
|
1545 |
+
'display_name' => true,
|
1546 |
+
'first_name' => true,
|
1547 |
+
'last_name' => true,
|
1548 |
+
);
|
1549 |
+
foreach ( $data as $key => $value ) {
|
1550 |
+
if ( ! isset( $allowed[ $key ] ) ) {
|
1551 |
+
continue;
|
1552 |
+
}
|
1553 |
+
|
1554 |
+
$userdata[ $key ] = $data[ $key ];
|
1555 |
+
}
|
1556 |
+
|
1557 |
+
$user_id = wp_insert_user( wp_slash( $userdata ) );
|
1558 |
+
if ( is_wp_error( $user_id ) ) {
|
1559 |
+
$this->logger->error( sprintf(
|
1560 |
+
__( 'Failed to import user "%s"', 'wordpress-importer' ),
|
1561 |
+
$userdata['user_login']
|
1562 |
+
) );
|
1563 |
+
$this->logger->debug( $user_id->get_error_message() );
|
1564 |
+
|
1565 |
+
/**
|
1566 |
+
* User processing failed.
|
1567 |
+
*
|
1568 |
+
* @param WP_Error $user_id Error object.
|
1569 |
+
* @param array $userdata Raw data imported for the user.
|
1570 |
+
*/
|
1571 |
+
do_action( 'wxr_importer.process_failed.user', $user_id, $userdata );
|
1572 |
+
return false;
|
1573 |
+
}
|
1574 |
+
|
1575 |
+
if ( $original_id ) {
|
1576 |
+
$this->mapping['user'][ $original_id ] = $user_id;
|
1577 |
+
}
|
1578 |
+
$this->mapping['user_slug'][ $original_slug ] = $user_id;
|
1579 |
+
|
1580 |
+
$this->logger->info( sprintf(
|
1581 |
+
__( 'Imported user "%s"', 'wordpress-importer' ),
|
1582 |
+
$userdata['user_login']
|
1583 |
+
) );
|
1584 |
+
$this->logger->debug( sprintf(
|
1585 |
+
__( 'User %1$d remapped to %2$d', 'wordpress-importer' ),
|
1586 |
+
$original_id,
|
1587 |
+
$user_id
|
1588 |
+
) );
|
1589 |
+
|
1590 |
+
// TODO: Implement meta handling once WXR includes it
|
1591 |
+
/**
|
1592 |
+
* User processing completed.
|
1593 |
+
*
|
1594 |
+
* @param int $user_id New user ID.
|
1595 |
+
* @param array $userdata Raw data imported for the user.
|
1596 |
+
*/
|
1597 |
+
do_action( 'wxr_importer.processed.user', $user_id, $userdata );
|
1598 |
+
}
|
1599 |
+
|
1600 |
+
protected function parse_term_node( $node, $type = 'term' ) {
|
1601 |
+
$data = array();
|
1602 |
+
$meta = array();
|
1603 |
+
|
1604 |
+
$tag_name = array(
|
1605 |
+
'id' => 'wp:term_id',
|
1606 |
+
'taxonomy' => 'wp:term_taxonomy',
|
1607 |
+
'slug' => 'wp:term_slug',
|
1608 |
+
'parent' => 'wp:term_parent',
|
1609 |
+
'name' => 'wp:term_name',
|
1610 |
+
'description' => 'wp:term_description',
|
1611 |
+
);
|
1612 |
+
$taxonomy = null;
|
1613 |
+
|
1614 |
+
// Special casing!
|
1615 |
+
switch ( $type ) {
|
1616 |
+
case 'category':
|
1617 |
+
$tag_name['slug'] = 'wp:category_nicename';
|
1618 |
+
$tag_name['parent'] = 'wp:category_parent';
|
1619 |
+
$tag_name['name'] = 'wp:cat_name';
|
1620 |
+
$tag_name['description'] = 'wp:category_description';
|
1621 |
+
$tag_name['taxonomy'] = null;
|
1622 |
+
|
1623 |
+
$data['taxonomy'] = 'category';
|
1624 |
+
break;
|
1625 |
+
|
1626 |
+
case 'tag':
|
1627 |
+
$tag_name['slug'] = 'wp:tag_slug';
|
1628 |
+
$tag_name['parent'] = null;
|
1629 |
+
$tag_name['name'] = 'wp:tag_name';
|
1630 |
+
$tag_name['description'] = 'wp:tag_description';
|
1631 |
+
$tag_name['taxonomy'] = null;
|
1632 |
+
|
1633 |
+
$data['taxonomy'] = 'post_tag';
|
1634 |
+
break;
|
1635 |
+
}
|
1636 |
+
|
1637 |
+
foreach ( $node->childNodes as $child ) {
|
1638 |
+
// We only care about child elements
|
1639 |
+
if ( $child->nodeType !== XML_ELEMENT_NODE ) {
|
1640 |
+
continue;
|
1641 |
+
}
|
1642 |
+
|
1643 |
+
$key = array_search( $child->tagName, $tag_name );
|
1644 |
+
if ( $key ) {
|
1645 |
+
$data[ $key ] = $child->textContent;
|
1646 |
+
}
|
1647 |
+
}
|
1648 |
+
|
1649 |
+
if ( empty( $data['taxonomy'] ) ) {
|
1650 |
+
return null;
|
1651 |
+
}
|
1652 |
+
|
1653 |
+
// Compatibility with WXR 1.0
|
1654 |
+
if ( $data['taxonomy'] === 'tag' ) {
|
1655 |
+
$data['taxonomy'] = 'post_tag';
|
1656 |
+
}
|
1657 |
+
|
1658 |
+
return compact( 'data', 'meta' );
|
1659 |
+
}
|
1660 |
+
|
1661 |
+
protected function process_term( $data, $meta ) {
|
1662 |
+
/**
|
1663 |
+
* Pre-process term data.
|
1664 |
+
*
|
1665 |
+
* @param array $data Term data. (Return empty to skip.)
|
1666 |
+
* @param array $meta Meta data.
|
1667 |
+
*/
|
1668 |
+
$data = apply_filters( 'wxr_importer.pre_process.term', $data, $meta );
|
1669 |
+
if ( empty( $data ) ) {
|
1670 |
+
return false;
|
1671 |
+
}
|
1672 |
+
|
1673 |
+
$original_id = isset( $data['id'] ) ? (int) $data['id'] : 0;
|
1674 |
+
$parent_id = isset( $data['parent'] ) ? (int) $data['parent'] : 0;
|
1675 |
+
|
1676 |
+
$mapping_key = sha1( $data['taxonomy'] . ':' . $data['slug'] );
|
1677 |
+
$existing = $this->term_exists( $data );
|
1678 |
+
if ( $existing ) {
|
1679 |
+
|
1680 |
+
/**
|
1681 |
+
* Term processing already imported.
|
1682 |
+
*
|
1683 |
+
* @param array $data Raw data imported for the term.
|
1684 |
+
*/
|
1685 |
+
do_action( 'wxr_importer.process_already_imported.term', $data );
|
1686 |
+
|
1687 |
+
$this->mapping['term'][ $mapping_key ] = $existing;
|
1688 |
+
$this->mapping['term_id'][ $original_id ] = $existing;
|
1689 |
+
return false;
|
1690 |
+
}
|
1691 |
+
|
1692 |
+
// WP really likes to repeat itself in export files
|
1693 |
+
if ( isset( $this->mapping['term'][ $mapping_key ] ) ) {
|
1694 |
+
return false;
|
1695 |
+
}
|
1696 |
+
|
1697 |
+
$termdata = array();
|
1698 |
+
$allowed = array(
|
1699 |
+
'slug' => true,
|
1700 |
+
'description' => true,
|
1701 |
+
);
|
1702 |
+
|
1703 |
+
// Map the parent comment, or mark it as one we need to fix
|
1704 |
+
// TODO: add parent mapping and remapping
|
1705 |
+
/*
|
1706 |
+
$requires_remapping = false;
|
1707 |
+
if ( $parent_id ) {
|
1708 |
+
if ( isset( $this->mapping['term'][ $parent_id ] ) ) {
|
1709 |
+
$data['parent'] = $this->mapping['term'][ $parent_id ];
|
1710 |
+
} else {
|
1711 |
+
// Prepare for remapping later
|
1712 |
+
$meta[] = array( 'key' => '_wxr_import_parent', 'value' => $parent_id );
|
1713 |
+
$requires_remapping = true;
|
1714 |
+
|
1715 |
+
// Wipe the parent for now
|
1716 |
+
$data['parent'] = 0;
|
1717 |
+
}
|
1718 |
+
}*/
|
1719 |
+
|
1720 |
+
foreach ( $data as $key => $value ) {
|
1721 |
+
if ( ! isset( $allowed[ $key ] ) ) {
|
1722 |
+
continue;
|
1723 |
+
}
|
1724 |
+
|
1725 |
+
$termdata[ $key ] = $data[ $key ];
|
1726 |
+
}
|
1727 |
+
|
1728 |
+
$result = wp_insert_term( $data['name'], $data['taxonomy'], $termdata );
|
1729 |
+
if ( is_wp_error( $result ) ) {
|
1730 |
+
$this->logger->warning( sprintf(
|
1731 |
+
__( 'Failed to import %1$s %2$s', 'wordpress-importer' ),
|
1732 |
+
$data['taxonomy'],
|
1733 |
+
$data['name']
|
1734 |
+
) );
|
1735 |
+
$this->logger->debug( $result->get_error_message() );
|
1736 |
+
do_action( 'wp_import_insert_term_failed', $result, $data );
|
1737 |
+
|
1738 |
+
/**
|
1739 |
+
* Term processing failed.
|
1740 |
+
*
|
1741 |
+
* @param WP_Error $result Error object.
|
1742 |
+
* @param array $data Raw data imported for the term.
|
1743 |
+
* @param array $meta Meta data supplied for the term.
|
1744 |
+
*/
|
1745 |
+
do_action( 'wxr_importer.process_failed.term', $result, $data, $meta );
|
1746 |
+
return false;
|
1747 |
+
}
|
1748 |
+
|
1749 |
+
$term_id = $result['term_id'];
|
1750 |
+
|
1751 |
+
$this->mapping['term'][ $mapping_key ] = $term_id;
|
1752 |
+
$this->mapping['term_id'][ $original_id ] = $term_id;
|
1753 |
+
|
1754 |
+
$this->logger->info( sprintf(
|
1755 |
+
__( 'Imported "%1$s" (%2$s)', 'wordpress-importer' ),
|
1756 |
+
$data['name'],
|
1757 |
+
$data['taxonomy']
|
1758 |
+
) );
|
1759 |
+
$this->logger->debug( sprintf(
|
1760 |
+
__( 'Term %1$d remapped to %2$d', 'wordpress-importer' ),
|
1761 |
+
$original_id,
|
1762 |
+
$term_id
|
1763 |
+
) );
|
1764 |
+
|
1765 |
+
do_action( 'wp_import_insert_term', $term_id, $data );
|
1766 |
+
|
1767 |
+
/**
|
1768 |
+
* Term processing completed.
|
1769 |
+
*
|
1770 |
+
* @param int $term_id New term ID.
|
1771 |
+
* @param array $data Raw data imported for the term.
|
1772 |
+
*/
|
1773 |
+
do_action( 'wxr_importer.processed.term', $term_id, $data );
|
1774 |
+
}
|
1775 |
+
|
1776 |
+
/**
|
1777 |
+
* Attempt to download a remote file attachment
|
1778 |
+
*
|
1779 |
+
* @param string $url URL of item to fetch
|
1780 |
+
* @param array $post Attachment details
|
1781 |
+
* @return array|WP_Error Local file location details on success, WP_Error otherwise
|
1782 |
+
*/
|
1783 |
+
protected function fetch_remote_file( $url, $post ) {
|
1784 |
+
// extract the file name and extension from the url
|
1785 |
+
$file_name = basename( $url );
|
1786 |
+
|
1787 |
+
// get placeholder file in the upload dir with a unique, sanitized filename
|
1788 |
+
$upload = wp_upload_bits( $file_name, 0, '', $post['upload_date'] );
|
1789 |
+
if ( $upload['error'] ) {
|
1790 |
+
return new WP_Error( 'upload_dir_error', $upload['error'] );
|
1791 |
+
}
|
1792 |
+
|
1793 |
+
// fetch the remote url and write it to the placeholder file
|
1794 |
+
$response = wp_remote_get( $url, array(
|
1795 |
+
'stream' => true,
|
1796 |
+
'filename' => $upload['file'],
|
1797 |
+
) );
|
1798 |
+
|
1799 |
+
// request failed
|
1800 |
+
if ( is_wp_error( $response ) ) {
|
1801 |
+
unlink( $upload['file'] );
|
1802 |
+
return $response;
|
1803 |
+
}
|
1804 |
+
|
1805 |
+
$code = (int) wp_remote_retrieve_response_code( $response );
|
1806 |
+
|
1807 |
+
// make sure the fetch was successful
|
1808 |
+
if ( $code !== 200 ) {
|
1809 |
+
unlink( $upload['file'] );
|
1810 |
+
return new WP_Error(
|
1811 |
+
'import_file_error',
|
1812 |
+
sprintf(
|
1813 |
+
__( 'Remote server returned %1$d %2$s for %3$s', 'wordpress-importer' ),
|
1814 |
+
$code,
|
1815 |
+
get_status_header_desc( $code ),
|
1816 |
+
$url
|
1817 |
+
)
|
1818 |
+
);
|
1819 |
+
}
|
1820 |
+
|
1821 |
+
$filesize = filesize( $upload['file'] );
|
1822 |
+
$headers = wp_remote_retrieve_headers( $response );
|
1823 |
+
|
1824 |
+
if ( isset( $headers['content-length'] ) && $filesize !== (int) $headers['content-length'] ) {
|
1825 |
+
unlink( $upload['file'] );
|
1826 |
+
return new WP_Error( 'import_file_error', __( 'Remote file is incorrect size', 'wordpress-importer' ) );
|
1827 |
+
}
|
1828 |
+
|
1829 |
+
if ( 0 === $filesize ) {
|
1830 |
+
unlink( $upload['file'] );
|
1831 |
+
return new WP_Error( 'import_file_error', __( 'Zero size file downloaded', 'wordpress-importer' ) );
|
1832 |
+
}
|
1833 |
+
|
1834 |
+
$max_size = (int) $this->max_attachment_size();
|
1835 |
+
if ( ! empty( $max_size ) && $filesize > $max_size ) {
|
1836 |
+
unlink( $upload['file'] );
|
1837 |
+
$message = sprintf( __( 'Remote file is too large, limit is %s', 'wordpress-importer' ), size_format( $max_size ) );
|
1838 |
+
return new WP_Error( 'import_file_error', $message );
|
1839 |
+
}
|
1840 |
+
|
1841 |
+
return $upload;
|
1842 |
+
}
|
1843 |
+
|
1844 |
+
protected function post_process() {
|
1845 |
+
// Time to tackle any left-over bits
|
1846 |
+
if ( ! empty( $this->requires_remapping['post'] ) ) {
|
1847 |
+
$this->post_process_posts( $this->requires_remapping['post'] );
|
1848 |
+
}
|
1849 |
+
if ( ! empty( $this->requires_remapping['comment'] ) ) {
|
1850 |
+
$this->post_process_comments( $this->requires_remapping['comment'] );
|
1851 |
+
}
|
1852 |
+
}
|
1853 |
+
|
1854 |
+
protected function post_process_posts( $todo ) {
|
1855 |
+
foreach ( $todo as $post_id => $_ ) {
|
1856 |
+
$this->logger->debug( sprintf(
|
1857 |
+
// Note: title intentionally not used to skip extra processing
|
1858 |
+
// for when debug logging is off
|
1859 |
+
__( 'Running post-processing for post %d', 'wordpress-importer' ),
|
1860 |
+
$post_id
|
1861 |
+
) );
|
1862 |
+
|
1863 |
+
$data = array();
|
1864 |
+
|
1865 |
+
$parent_id = get_post_meta( $post_id, '_wxr_import_parent', true );
|
1866 |
+
if ( ! empty( $parent_id ) ) {
|
1867 |
+
// Have we imported the parent now?
|
1868 |
+
if ( isset( $this->mapping['post'][ $parent_id ] ) ) {
|
1869 |
+
$data['post_parent'] = $this->mapping['post'][ $parent_id ];
|
1870 |
+
} else {
|
1871 |
+
$this->logger->warning( sprintf(
|
1872 |
+
__( 'Could not find the post parent for "%1$s" (post #%2$d)', 'wordpress-importer' ),
|
1873 |
+
get_the_title( $post_id ),
|
1874 |
+
$post_id
|
1875 |
+
) );
|
1876 |
+
$this->logger->debug( sprintf(
|
1877 |
+
__( 'Post %1$d was imported with parent %2$d, but could not be found', 'wordpress-importer' ),
|
1878 |
+
$post_id,
|
1879 |
+
$parent_id
|
1880 |
+
) );
|
1881 |
+
}
|
1882 |
+
}
|
1883 |
+
|
1884 |
+
$author_slug = get_post_meta( $post_id, '_wxr_import_user_slug', true );
|
1885 |
+
if ( ! empty( $author_slug ) ) {
|
1886 |
+
// Have we imported the user now?
|
1887 |
+
if ( isset( $this->mapping['user_slug'][ $author_slug ] ) ) {
|
1888 |
+
$data['post_author'] = $this->mapping['user_slug'][ $author_slug ];
|
1889 |
+
} else {
|
1890 |
+
$this->logger->warning( sprintf(
|
1891 |
+
__( 'Could not find the author for "%1$s" (post #%2$d)', 'wordpress-importer' ),
|
1892 |
+
get_the_title( $post_id ),
|
1893 |
+
$post_id
|
1894 |
+
) );
|
1895 |
+
$this->logger->debug( sprintf(
|
1896 |
+
__( 'Post %1$d was imported with author "%2$s", but could not be found', 'wordpress-importer' ),
|
1897 |
+
$post_id,
|
1898 |
+
$author_slug
|
1899 |
+
) );
|
1900 |
+
}
|
1901 |
+
}
|
1902 |
+
|
1903 |
+
$has_attachments = get_post_meta( $post_id, '_wxr_import_has_attachment_refs', true );
|
1904 |
+
if ( ! empty( $has_attachments ) ) {
|
1905 |
+
$post = get_post( $post_id );
|
1906 |
+
$content = $post->post_content;
|
1907 |
+
|
1908 |
+
// Replace all the URLs we've got
|
1909 |
+
$new_content = str_replace( array_keys( $this->url_remap ), $this->url_remap, $content );
|
1910 |
+
if ( $new_content !== $content ) {
|
1911 |
+
$data['post_content'] = $new_content;
|
1912 |
+
}
|
1913 |
+
}
|
1914 |
+
|
1915 |
+
if ( get_post_type( $post_id ) === 'nav_menu_item' ) {
|
1916 |
+
$this->post_process_menu_item( $post_id );
|
1917 |
+
}
|
1918 |
+
|
1919 |
+
// Do we have updates to make?
|
1920 |
+
if ( empty( $data ) ) {
|
1921 |
+
$this->logger->debug( sprintf(
|
1922 |
+
__( 'Post %d was marked for post-processing, but none was required.', 'wordpress-importer' ),
|
1923 |
+
$post_id
|
1924 |
+
) );
|
1925 |
+
continue;
|
1926 |
+
}
|
1927 |
+
|
1928 |
+
// Run the update
|
1929 |
+
$data['ID'] = $post_id;
|
1930 |
+
$result = wp_update_post( $data, true );
|
1931 |
+
if ( is_wp_error( $result ) ) {
|
1932 |
+
$this->logger->warning( sprintf(
|
1933 |
+
__( 'Could not update "%1$s" (post #%2$d) with mapped data', 'wordpress-importer' ),
|
1934 |
+
get_the_title( $post_id ),
|
1935 |
+
$post_id
|
1936 |
+
) );
|
1937 |
+
$this->logger->debug( $result->get_error_message() );
|
1938 |
+
continue;
|
1939 |
+
}
|
1940 |
+
|
1941 |
+
// Clear out our temporary meta keys
|
1942 |
+
delete_post_meta( $post_id, '_wxr_import_parent' );
|
1943 |
+
delete_post_meta( $post_id, '_wxr_import_user_slug' );
|
1944 |
+
delete_post_meta( $post_id, '_wxr_import_has_attachment_refs' );
|
1945 |
+
}// End foreach().
|
1946 |
+
}
|
1947 |
+
|
1948 |
+
protected function post_process_menu_item( $post_id ) {
|
1949 |
+
$menu_object_id = get_post_meta( $post_id, '_wxr_import_menu_item', true );
|
1950 |
+
if ( empty( $menu_object_id ) ) {
|
1951 |
+
// No processing needed!
|
1952 |
+
return;
|
1953 |
+
}
|
1954 |
+
|
1955 |
+
$menu_item_type = get_post_meta( $post_id, '_menu_item_type', true );
|
1956 |
+
switch ( $menu_item_type ) {
|
1957 |
+
case 'taxonomy':
|
1958 |
+
if ( isset( $this->mapping['term_id'][ $menu_object_id ] ) ) {
|
1959 |
+
$menu_object = $this->mapping['term_id'][ $menu_object_id ];
|
1960 |
+
}
|
1961 |
+
break;
|
1962 |
+
|
1963 |
+
case 'post_type':
|
1964 |
+
if ( isset( $this->mapping['post'][ $menu_object_id ] ) ) {
|
1965 |
+
$menu_object = $this->mapping['post'][ $menu_object_id ];
|
1966 |
+
}
|
1967 |
+
break;
|
1968 |
+
|
1969 |
+
default:
|
1970 |
+
// Cannot handle this.
|
1971 |
+
return;
|
1972 |
+
}
|
1973 |
+
|
1974 |
+
if ( ! empty( $menu_object ) ) {
|
1975 |
+
update_post_meta( $post_id, '_menu_item_object_id', wp_slash( $menu_object ) );
|
1976 |
+
} else {
|
1977 |
+
$this->logger->warning( sprintf(
|
1978 |
+
__( 'Could not find the menu object for "%1$s" (post #%2$d)', 'wordpress-importer' ),
|
1979 |
+
get_the_title( $post_id ),
|
1980 |
+
$post_id
|
1981 |
+
) );
|
1982 |
+
$this->logger->debug( sprintf(
|
1983 |
+
__( 'Post %1$d was imported with object "%2$d" of type "%3$s", but could not be found', 'wordpress-importer' ),
|
1984 |
+
$post_id,
|
1985 |
+
$menu_object_id,
|
1986 |
+
$menu_item_type
|
1987 |
+
) );
|
1988 |
+
}
|
1989 |
+
|
1990 |
+
delete_post_meta( $post_id, '_wxr_import_menu_item' );
|
1991 |
+
}
|
1992 |
+
|
1993 |
+
|
1994 |
+
protected function post_process_comments( $todo ) {
|
1995 |
+
foreach ( $todo as $comment_id => $_ ) {
|
1996 |
+
$data = array();
|
1997 |
+
|
1998 |
+
$parent_id = get_comment_meta( $comment_id, '_wxr_import_parent', true );
|
1999 |
+
if ( ! empty( $parent_id ) ) {
|
2000 |
+
// Have we imported the parent now?
|
2001 |
+
if ( isset( $this->mapping['comment'][ $parent_id ] ) ) {
|
2002 |
+
$data['comment_parent'] = $this->mapping['comment'][ $parent_id ];
|
2003 |
+
} else {
|
2004 |
+
$this->logger->warning( sprintf(
|
2005 |
+
__( 'Could not find the comment parent for comment #%d', 'wordpress-importer' ),
|
2006 |
+
$comment_id
|
2007 |
+
) );
|
2008 |
+
$this->logger->debug( sprintf(
|
2009 |
+
__( 'Comment %1$d was imported with parent %2$d, but could not be found', 'wordpress-importer' ),
|
2010 |
+
$comment_id,
|
2011 |
+
$parent_id
|
2012 |
+
) );
|
2013 |
+
}
|
2014 |
+
}
|
2015 |
+
|
2016 |
+
$author_id = get_comment_meta( $comment_id, '_wxr_import_user', true );
|
2017 |
+
if ( ! empty( $author_id ) ) {
|
2018 |
+
// Have we imported the user now?
|
2019 |
+
if ( isset( $this->mapping['user'][ $author_id ] ) ) {
|
2020 |
+
$data['user_id'] = $this->mapping['user'][ $author_id ];
|
2021 |
+
} else {
|
2022 |
+
$this->logger->warning( sprintf(
|
2023 |
+
__( 'Could not find the author for comment #%d', 'wordpress-importer' ),
|
2024 |
+
$comment_id
|
2025 |
+
) );
|
2026 |
+
$this->logger->debug( sprintf(
|
2027 |
+
__( 'Comment %1$d was imported with author %2$d, but could not be found', 'wordpress-importer' ),
|
2028 |
+
$comment_id,
|
2029 |
+
$author_id
|
2030 |
+
) );
|
2031 |
+
}
|
2032 |
+
}
|
2033 |
+
|
2034 |
+
// Do we have updates to make?
|
2035 |
+
if ( empty( $data ) ) {
|
2036 |
+
continue;
|
2037 |
+
}
|
2038 |
+
|
2039 |
+
// Run the update
|
2040 |
+
$data['comment_ID'] = $comment_ID;
|
2041 |
+
$result = wp_update_comment( wp_slash( $data ) );
|
2042 |
+
if ( empty( $result ) ) {
|
2043 |
+
$this->logger->warning( sprintf(
|
2044 |
+
__( 'Could not update comment #%d with mapped data', 'wordpress-importer' ),
|
2045 |
+
$comment_id
|
2046 |
+
) );
|
2047 |
+
continue;
|
2048 |
+
}
|
2049 |
+
|
2050 |
+
// Clear out our temporary meta keys
|
2051 |
+
delete_comment_meta( $comment_id, '_wxr_import_parent' );
|
2052 |
+
delete_comment_meta( $comment_id, '_wxr_import_user' );
|
2053 |
+
}// End foreach().
|
2054 |
+
}
|
2055 |
+
|
2056 |
+
/**
|
2057 |
+
* Use stored mapping information to update old attachment URLs
|
2058 |
+
*/
|
2059 |
+
protected function replace_attachment_urls_in_content() {
|
2060 |
+
global $wpdb;
|
2061 |
+
// make sure we do the longest urls first, in case one is a substring of another
|
2062 |
+
uksort( $this->url_remap, array( $this, 'cmpr_strlen' ) );
|
2063 |
+
|
2064 |
+
foreach ( $this->url_remap as $from_url => $to_url ) {
|
2065 |
+
// remap urls in post_content
|
2066 |
+
$query = $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url );
|
2067 |
+
$wpdb->query( $query );
|
2068 |
+
|
2069 |
+
// remap enclosure urls
|
2070 |
+
$query = $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s) WHERE meta_key='enclosure'", $from_url, $to_url );
|
2071 |
+
$result = $wpdb->query( $query );
|
2072 |
+
}
|
2073 |
+
}
|
2074 |
+
|
2075 |
+
/**
|
2076 |
+
* Update _thumbnail_id meta to new, imported attachment IDs
|
2077 |
+
*/
|
2078 |
+
function remap_featured_images() {
|
2079 |
+
// cycle through posts that have a featured image
|
2080 |
+
foreach ( $this->featured_images as $post_id => $value ) {
|
2081 |
+
if ( isset( $this->processed_posts[ $value ] ) ) {
|
2082 |
+
$new_id = $this->processed_posts[ $value ];
|
2083 |
+
|
2084 |
+
// only update if there's a difference
|
2085 |
+
if ( $new_id !== $value ) {
|
2086 |
+
update_post_meta( $post_id, '_thumbnail_id', $new_id );
|
2087 |
+
}
|
2088 |
+
}
|
2089 |
+
}
|
2090 |
+
}
|
2091 |
+
|
2092 |
+
/**
|
2093 |
+
* Decide if the given meta key maps to information we will want to import
|
2094 |
+
*
|
2095 |
+
* @param string $key The meta key to check
|
2096 |
+
* @return string|bool The key if we do want to import, false if not
|
2097 |
+
*/
|
2098 |
+
public function is_valid_meta_key( $key ) {
|
2099 |
+
// skip attachment metadata since we'll regenerate it from scratch
|
2100 |
+
// skip _edit_lock as not relevant for import
|
2101 |
+
if ( in_array( $key, array( '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock' ) ) ) {
|
2102 |
+
return false;
|
2103 |
+
}
|
2104 |
+
|
2105 |
+
return $key;
|
2106 |
+
}
|
2107 |
+
|
2108 |
+
/**
|
2109 |
+
* Decide what the maximum file size for downloaded attachments is.
|
2110 |
+
* Default is 0 (unlimited), can be filtered via import_attachment_size_limit
|
2111 |
+
*
|
2112 |
+
* @return int Maximum attachment file size to import
|
2113 |
+
*/
|
2114 |
+
protected function max_attachment_size() {
|
2115 |
+
return apply_filters( 'import_attachment_size_limit', 0 );
|
2116 |
+
}
|
2117 |
+
|
2118 |
+
/**
|
2119 |
+
* Added to http_request_timeout filter to force timeout at 60 seconds during import
|
2120 |
+
*
|
2121 |
+
* @access protected
|
2122 |
+
* @return int 60
|
2123 |
+
*/
|
2124 |
+
function bump_request_timeout( $val ) {
|
2125 |
+
return 60;
|
2126 |
+
}
|
2127 |
+
|
2128 |
+
// return the difference in length between two strings
|
2129 |
+
function cmpr_strlen( $a, $b ) {
|
2130 |
+
return strlen( $b ) - strlen( $a );
|
2131 |
+
}
|
2132 |
+
|
2133 |
+
/**
|
2134 |
+
* Prefill existing post data.
|
2135 |
+
*
|
2136 |
+
* This preloads all GUIDs into memory, allowing us to avoid hitting the
|
2137 |
+
* database when we need to check for existence. With larger imports, this
|
2138 |
+
* becomes prohibitively slow to perform SELECT queries on each.
|
2139 |
+
*
|
2140 |
+
* By preloading all this data into memory, it's a constant-time lookup in
|
2141 |
+
* PHP instead. However, this does use a lot more memory, so for sites doing
|
2142 |
+
* small imports onto a large site, it may be a better tradeoff to use
|
2143 |
+
* on-the-fly checking instead.
|
2144 |
+
*/
|
2145 |
+
protected function prefill_existing_posts() {
|
2146 |
+
global $wpdb;
|
2147 |
+
$posts = $wpdb->get_results( "SELECT ID, guid FROM {$wpdb->posts}" );
|
2148 |
+
|
2149 |
+
foreach ( $posts as $item ) {
|
2150 |
+
$this->exists['post'][ $item->guid ] = $item->ID;
|
2151 |
+
}
|
2152 |
+
}
|
2153 |
+
|
2154 |
+
/**
|
2155 |
+
* Does the post exist?
|
2156 |
+
*
|
2157 |
+
* @param array $data Post data to check against.
|
2158 |
+
* @return int|bool Existing post ID if it exists, false otherwise.
|
2159 |
+
*/
|
2160 |
+
protected function post_exists( $data ) {
|
2161 |
+
// Constant-time lookup if we prefilled
|
2162 |
+
$exists_key = $data['guid'];
|
2163 |
+
|
2164 |
+
if ( $this->options['prefill_existing_posts'] ) {
|
2165 |
+
return isset( $this->exists['post'][ $exists_key ] ) ? $this->exists['post'][ $exists_key ] : false;
|
2166 |
+
}
|
2167 |
+
|
2168 |
+
// No prefilling, but might have already handled it
|
2169 |
+
if ( isset( $this->exists['post'][ $exists_key ] ) ) {
|
2170 |
+
return $this->exists['post'][ $exists_key ];
|
2171 |
+
}
|
2172 |
+
|
2173 |
+
// Still nothing, try post_exists, and cache it
|
2174 |
+
$exists = post_exists( $data['post_title'], $data['post_content'], $data['post_date'] );
|
2175 |
+
$this->exists['post'][ $exists_key ] = $exists;
|
2176 |
+
|
2177 |
+
return $exists;
|
2178 |
+
}
|
2179 |
+
|
2180 |
+
/**
|
2181 |
+
* Mark the post as existing.
|
2182 |
+
*
|
2183 |
+
* @param array $data Post data to mark as existing.
|
2184 |
+
* @param int $post_id Post ID.
|
2185 |
+
*/
|
2186 |
+
protected function mark_post_exists( $data, $post_id ) {
|
2187 |
+
$exists_key = $data['guid'];
|
2188 |
+
$this->exists['post'][ $exists_key ] = $post_id;
|
2189 |
+
}
|
2190 |
+
|
2191 |
+
/**
|
2192 |
+
* Prefill existing comment data.
|
2193 |
+
*
|
2194 |
+
* @see self::prefill_existing_posts() for justification of why this exists.
|
2195 |
+
*/
|
2196 |
+
protected function prefill_existing_comments() {
|
2197 |
+
global $wpdb;
|
2198 |
+
$posts = $wpdb->get_results( "SELECT comment_ID, comment_author, comment_date FROM {$wpdb->comments}" );
|
2199 |
+
|
2200 |
+
foreach ( $posts as $item ) {
|
2201 |
+
$exists_key = sha1( $item->comment_author . ':' . $item->comment_date );
|
2202 |
+
$this->exists['comment'][ $exists_key ] = $item->comment_ID;
|
2203 |
+
}
|
2204 |
+
}
|
2205 |
+
|
2206 |
+
/**
|
2207 |
+
* Does the comment exist?
|
2208 |
+
*
|
2209 |
+
* @param array $data Comment data to check against.
|
2210 |
+
* @return int|bool Existing comment ID if it exists, false otherwise.
|
2211 |
+
*/
|
2212 |
+
protected function comment_exists( $data ) {
|
2213 |
+
$exists_key = sha1( $data['comment_author'] . ':' . $data['comment_date'] );
|
2214 |
+
|
2215 |
+
// Constant-time lookup if we prefilled
|
2216 |
+
if ( $this->options['prefill_existing_comments'] ) {
|
2217 |
+
return isset( $this->exists['comment'][ $exists_key ] ) ? $this->exists['comment'][ $exists_key ] : false;
|
2218 |
+
}
|
2219 |
+
|
2220 |
+
// No prefilling, but might have already handled it
|
2221 |
+
if ( isset( $this->exists['comment'][ $exists_key ] ) ) {
|
2222 |
+
return $this->exists['comment'][ $exists_key ];
|
2223 |
+
}
|
2224 |
+
|
2225 |
+
// Still nothing, try comment_exists, and cache it
|
2226 |
+
$exists = comment_exists( $data['comment_author'], $data['comment_date'] );
|
2227 |
+
$this->exists['comment'][ $exists_key ] = $exists;
|
2228 |
+
|
2229 |
+
return $exists;
|
2230 |
+
}
|
2231 |
+
|
2232 |
+
/**
|
2233 |
+
* Mark the comment as existing.
|
2234 |
+
*
|
2235 |
+
* @param array $data Comment data to mark as existing.
|
2236 |
+
* @param int $comment_id Comment ID.
|
2237 |
+
*/
|
2238 |
+
protected function mark_comment_exists( $data, $comment_id ) {
|
2239 |
+
$exists_key = sha1( $data['comment_author'] . ':' . $data['comment_date'] );
|
2240 |
+
$this->exists['comment'][ $exists_key ] = $comment_id;
|
2241 |
+
}
|
2242 |
+
|
2243 |
+
/**
|
2244 |
+
* Prefill existing term data.
|
2245 |
+
*
|
2246 |
+
* @see self::prefill_existing_posts() for justification of why this exists.
|
2247 |
+
*/
|
2248 |
+
protected function prefill_existing_terms() {
|
2249 |
+
global $wpdb;
|
2250 |
+
$query = "SELECT t.term_id, tt.taxonomy, t.slug FROM {$wpdb->terms} AS t";
|
2251 |
+
$query .= " JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id";
|
2252 |
+
$terms = $wpdb->get_results( $query );
|
2253 |
+
|
2254 |
+
foreach ( $terms as $item ) {
|
2255 |
+
$exists_key = sha1( $item->taxonomy . ':' . $item->slug );
|
2256 |
+
$this->exists['term'][ $exists_key ] = $item->term_id;
|
2257 |
+
}
|
2258 |
+
}
|
2259 |
+
|
2260 |
+
/**
|
2261 |
+
* Does the term exist?
|
2262 |
+
*
|
2263 |
+
* @param array $data Term data to check against.
|
2264 |
+
* @return int|bool Existing term ID if it exists, false otherwise.
|
2265 |
+
*/
|
2266 |
+
protected function term_exists( $data ) {
|
2267 |
+
$exists_key = sha1( $data['taxonomy'] . ':' . $data['slug'] );
|
2268 |
+
|
2269 |
+
// Constant-time lookup if we prefilled
|
2270 |
+
if ( $this->options['prefill_existing_terms'] ) {
|
2271 |
+
return isset( $this->exists['term'][ $exists_key ] ) ? $this->exists['term'][ $exists_key ] : false;
|
2272 |
+
}
|
2273 |
+
|
2274 |
+
// No prefilling, but might have already handled it
|
2275 |
+
if ( isset( $this->exists['term'][ $exists_key ] ) ) {
|
2276 |
+
return $this->exists['term'][ $exists_key ];
|
2277 |
+
}
|
2278 |
+
|
2279 |
+
// Still nothing, try comment_exists, and cache it
|
2280 |
+
$exists = term_exists( $data['slug'], $data['taxonomy'] );
|
2281 |
+
if ( is_array( $exists ) ) {
|
2282 |
+
$exists = $exists['term_id'];
|
2283 |
+
}
|
2284 |
+
|
2285 |
+
$this->exists['term'][ $exists_key ] = $exists;
|
2286 |
+
|
2287 |
+
return $exists;
|
2288 |
+
}
|
2289 |
+
|
2290 |
+
/**
|
2291 |
+
* Mark the term as existing.
|
2292 |
+
*
|
2293 |
+
* @param array $data Term data to mark as existing.
|
2294 |
+
* @param int $term_id Term ID.
|
2295 |
+
*/
|
2296 |
+
protected function mark_term_exists( $data, $term_id ) {
|
2297 |
+
$exists_key = sha1( $data['taxonomy'] . ':' . $data['slug'] );
|
2298 |
+
$this->exists['term'][ $exists_key ] = $term_id;
|
2299 |
+
}
|
2300 |
+
}
|
2301 |
Â
endif;
|
languages/astra-sites.pot
CHANGED
@@ -1,775 +1,796 @@
|
|
1 |
-
# Copyright (C) 2019 Brainstorm Force
|
2 |
-
# This file is distributed under the same license as the Astra Starter Sites – Elementor, Beaver Builder & Gutenberg Templates package.
|
3 |
-
msgid ""
|
4 |
-
msgstr ""
|
5 |
-
"Project-Id-Version: Astra Starter Sites – Elementor, Beaver Builder & "
|
6 |
-
"Gutenberg Templates 1.3.
|
7 |
-
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/astra-sites\n"
|
8 |
-
"POT-Creation-Date: 2019-
|
9 |
-
"MIME-Version: 1.0\n"
|
10 |
-
"Content-Type: text/plain; charset=utf-8\n"
|
11 |
-
"Content-Transfer-Encoding: 8bit\n"
|
12 |
-
"PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
|
13 |
-
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14 |
-
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15 |
-
"Language: en\n"
|
16 |
-
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
17 |
-
"X-Poedit-Country: United States\n"
|
18 |
-
"X-Poedit-SourceCharset: UTF-8\n"
|
19 |
-
"X-Poedit-KeywordsList: "
|
20 |
-
"__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
|
21 |
-
"attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
|
22 |
-
"X-Poedit-Basepath: ../\n"
|
23 |
-
"X-Poedit-SearchPath-0: .\n"
|
24 |
-
"X-Poedit-Bookmarks: \n"
|
25 |
-
"X-Textdomain-Support: yes\n"
|
26 |
-
"X-Generator: grunt-wp-i18n1.0.0\n"
|
27 |
-
|
28 |
-
#: astra-sites.php:18 inc/classes/class-astra-sites-page.php:319
|
29 |
-
msgid "Astra Sites"
|
30 |
-
msgstr ""
|
31 |
-
|
32 |
-
#: inc/classes/class-astra-sites-importer-log.php:443
|
33 |
-
msgid "Enabled"
|
34 |
-
msgstr ""
|
35 |
-
|
36 |
-
#: inc/classes/class-astra-sites-importer-log.php:446
|
37 |
-
msgid "Disabled"
|
38 |
-
msgstr ""
|
39 |
-
|
40 |
-
#: inc/classes/class-astra-sites-importer-log.php:531
|
41 |
-
#: inc/classes/class-astra-sites-importer-log.php:588
|
42 |
-
msgid "Yes"
|
43 |
-
msgstr ""
|
44 |
-
|
45 |
-
#: inc/classes/class-astra-sites-importer-log.php:534
|
46 |
-
#: inc/classes/class-astra-sites-importer-log.php:591
|
47 |
-
msgid "No"
|
48 |
-
msgstr ""
|
49 |
-
|
50 |
-
#: inc/classes/class-astra-sites-importer.php:98
|
51 |
-
msgid "You have not \"customize\" access to import the Astra site."
|
52 |
-
msgstr ""
|
53 |
-
|
54 |
-
#: inc/classes/class-astra-sites-importer.php:122
|
55 |
-
msgid "Request site API URL is empty. Try again!"
|
56 |
-
msgstr ""
|
57 |
-
|
58 |
-
#: inc/classes/class-astra-sites-importer.php:223
|
59 |
-
msgid "Customizer data is empty!"
|
60 |
-
msgstr ""
|
61 |
-
|
62 |
-
#: inc/classes/class-astra-sites-importer.php:237
|
63 |
-
msgid ""
|
64 |
-
"If XMLReader is not available, it imports all other settings and only skips "
|
65 |
-
"XML import. This creates an incomplete website. We should bail early and "
|
66 |
-
"not import anything if this is not present."
|
67 |
-
msgstr ""
|
68 |
-
|
69 |
-
#: inc/classes/class-astra-sites-importer.php:255
|
70 |
-
msgid "There was an error downloading the XML file."
|
71 |
-
msgstr ""
|
72 |
-
|
73 |
-
#: inc/classes/class-astra-sites-importer.php:261
|
74 |
-
msgid "Invalid site XML file!"
|
75 |
-
msgstr ""
|
76 |
-
|
77 |
-
#: inc/classes/class-astra-sites-importer.php:290
|
78 |
-
msgid "Site options are empty!"
|
79 |
-
msgstr ""
|
80 |
-
|
81 |
-
#: inc/classes/class-astra-sites-importer.php:321
|
82 |
-
msgid "Widget data is empty!"
|
83 |
-
msgstr ""
|
84 |
-
|
85 |
-
#: inc/classes/class-astra-sites-importer.php:522
|
86 |
-
#. translators: %s is the post ID
|
87 |
-
msgid "Post ID %s deleted!"
|
88 |
-
msgstr ""
|
89 |
-
|
90 |
-
#: inc/classes/class-astra-sites-importer.php:541
|
91 |
-
#. translators: %s is the form ID
|
92 |
-
msgid "Form ID %s deleted!"
|
93 |
-
msgstr ""
|
94 |
-
|
95 |
-
#: inc/classes/class-astra-sites-importer.php:563
|
96 |
-
#. translators: %s is the term ID
|
97 |
-
msgid "Term ID %s deleted!"
|
98 |
-
msgstr ""
|
99 |
-
|
100 |
-
#: inc/classes/class-astra-sites-page.php:156
|
101 |
-
msgid "Required XMLReader PHP extension is missing on your server!"
|
102 |
-
msgstr ""
|
103 |
-
|
104 |
-
#: inc/classes/class-astra-sites-page.php:158
|
105 |
-
#. translators: %s is the white label name.
|
106 |
-
msgid ""
|
107 |
-
"%s import requires XMLReader extension to be installed. Please contact your "
|
108 |
-
"web hosting provider and ask them to install and activate the XMLReader PHP "
|
109 |
-
"extension."
|
110 |
-
msgstr ""
|
111 |
-
|
112 |
-
#: inc/classes/class-astra-sites-page.php:220
|
113 |
-
msgid "Settings saved successfully."
|
114 |
-
msgstr ""
|
115 |
-
|
116 |
-
#: inc/classes/class-astra-sites-page.php:235
|
117 |
-
#: inc/classes/class-astra-sites-page.php:256
|
118 |
-
msgid "Block Editor (Gutenberg)"
|
119 |
-
msgstr ""
|
120 |
-
|
121 |
-
#: inc/classes/class-astra-sites-page.php:236
|
122 |
-
#: inc/classes/class-astra-sites-page.php:257
|
123 |
-
msgid "Elementor"
|
124 |
-
msgstr ""
|
125 |
-
|
126 |
-
#: inc/classes/class-astra-sites-page.php:237
|
127 |
-
#: inc/classes/class-astra-sites-page.php:258
|
128 |
-
msgid "Beaver Builder"
|
129 |
-
msgstr ""
|
130 |
-
|
131 |
-
#: inc/classes/class-astra-sites-page.php:238
|
132 |
-
#: inc/classes/class-astra-sites-page.php:259
|
133 |
-
msgid "Brizy"
|
134 |
-
msgstr ""
|
135 |
-
|
136 |
-
#: inc/classes/class-astra-sites-page.php:240 inc/includes/admin-page.php:141
|
137 |
-
msgid "Next"
|
138 |
-
msgstr ""
|
139 |
-
|
140 |
-
#: inc/classes/class-astra-sites-page.php:249
|
141 |
-
msgid "Astra Starter Sites - Your Library of 100+ Ready Templates!"
|
142 |
-
msgstr ""
|
143 |
-
|
144 |
-
#: inc/classes/class-astra-sites-white-label.php:187
|
145 |
-
#. translators: %1$s product name
|
146 |
-
msgid "%1$s Branding"
|
147 |
-
msgstr ""
|
148 |
-
|
149 |
-
#: inc/classes/class-astra-sites.php:
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
msgid ""
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
"
|
183 |
-
msgstr ""
|
184 |
-
|
185 |
-
#: inc/classes/class-astra-sites.php:
|
186 |
-
msgid ""
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
#: inc/importers/
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
#: inc/importers/wxr-importer/class-wxr-importer.php:
|
461 |
-
msgid "
|
462 |
-
msgstr ""
|
463 |
-
|
464 |
-
#: inc/importers/wxr-importer/class-wxr-importer.php:
|
465 |
-
msgid "
|
466 |
-
msgstr ""
|
467 |
-
|
468 |
-
#: inc/importers/wxr-importer/class-wxr-importer.php:
|
469 |
-
msgid "
|
470 |
-
msgstr ""
|
471 |
-
|
472 |
-
#: inc/importers/wxr-importer/class-wxr-importer.php:
|
473 |
-
msgid "
|
474 |
-
msgstr ""
|
475 |
-
|
476 |
-
#: inc/importers/wxr-importer/class-wxr-importer.php:
|
477 |
-
msgid "
|
478 |
-
msgstr ""
|
479 |
-
|
480 |
-
#: inc/importers/wxr-importer/class-wxr-importer.php:
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
"
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
msgid ""
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
"
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
msgstr ""
|
612 |
-
|
613 |
-
#: inc/includes/admin-page.php:
|
614 |
-
msgid "
|
615 |
-
msgstr ""
|
616 |
-
|
617 |
-
#: inc/includes/admin-page.php:
|
618 |
-
msgid "
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
msgstr ""
|
629 |
-
|
630 |
-
#: inc/includes/admin-page.php:
|
631 |
-
msgid "
|
632 |
-
msgstr ""
|
633 |
-
|
634 |
-
#: inc/includes/admin-page.php:
|
635 |
-
msgid "
|
636 |
-
msgstr ""
|
637 |
-
|
638 |
-
#: inc/includes/admin-page.php:
|
639 |
-
msgid ""
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
msgstr ""
|
645 |
-
|
646 |
-
#: inc/includes/admin-page.php:
|
647 |
-
|
648 |
-
"
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
msgid ""
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
"
|
697 |
-
msgstr ""
|
698 |
-
|
699 |
-
#: inc/includes/admin-page.php:
|
700 |
-
msgid ""
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
"
|
711 |
-
"
|
712 |
-
msgstr ""
|
713 |
-
|
714 |
-
#: inc/includes/admin-page.php:
|
715 |
-
msgid "
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
#.
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
775 |
Â
msgstr ""
|
1 |
+
# Copyright (C) 2019 Brainstorm Force
|
2 |
+
# This file is distributed under the same license as the Astra Starter Sites – Elementor, Beaver Builder & Gutenberg Templates package.
|
3 |
+
msgid ""
|
4 |
+
msgstr ""
|
5 |
+
"Project-Id-Version: Astra Starter Sites – Elementor, Beaver Builder & "
|
6 |
+
"Gutenberg Templates 1.3.2\n"
|
7 |
+
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/astra-sites\n"
|
8 |
+
"POT-Creation-Date: 2019-04-01 08:04:16+00:00\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=utf-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
|
13 |
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14 |
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15 |
+
"Language: en\n"
|
16 |
+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
17 |
+
"X-Poedit-Country: United States\n"
|
18 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
19 |
+
"X-Poedit-KeywordsList: "
|
20 |
+
"__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
|
21 |
+
"attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
|
22 |
+
"X-Poedit-Basepath: ../\n"
|
23 |
+
"X-Poedit-SearchPath-0: .\n"
|
24 |
+
"X-Poedit-Bookmarks: \n"
|
25 |
+
"X-Textdomain-Support: yes\n"
|
26 |
+
"X-Generator: grunt-wp-i18n1.0.0\n"
|
27 |
+
|
28 |
+
#: astra-sites.php:18 inc/classes/class-astra-sites-page.php:319
|
29 |
+
msgid "Astra Sites"
|
30 |
+
msgstr ""
|
31 |
+
|
32 |
+
#: inc/classes/class-astra-sites-importer-log.php:443
|
33 |
+
msgid "Enabled"
|
34 |
+
msgstr ""
|
35 |
+
|
36 |
+
#: inc/classes/class-astra-sites-importer-log.php:446
|
37 |
+
msgid "Disabled"
|
38 |
+
msgstr ""
|
39 |
+
|
40 |
+
#: inc/classes/class-astra-sites-importer-log.php:531
|
41 |
+
#: inc/classes/class-astra-sites-importer-log.php:588
|
42 |
+
msgid "Yes"
|
43 |
+
msgstr ""
|
44 |
+
|
45 |
+
#: inc/classes/class-astra-sites-importer-log.php:534
|
46 |
+
#: inc/classes/class-astra-sites-importer-log.php:591
|
47 |
+
msgid "No"
|
48 |
+
msgstr ""
|
49 |
+
|
50 |
+
#: inc/classes/class-astra-sites-importer.php:98
|
51 |
+
msgid "You have not \"customize\" access to import the Astra site."
|
52 |
+
msgstr ""
|
53 |
+
|
54 |
+
#: inc/classes/class-astra-sites-importer.php:122
|
55 |
+
msgid "Request site API URL is empty. Try again!"
|
56 |
+
msgstr ""
|
57 |
+
|
58 |
+
#: inc/classes/class-astra-sites-importer.php:223
|
59 |
+
msgid "Customizer data is empty!"
|
60 |
+
msgstr ""
|
61 |
+
|
62 |
+
#: inc/classes/class-astra-sites-importer.php:237
|
63 |
+
msgid ""
|
64 |
+
"If XMLReader is not available, it imports all other settings and only skips "
|
65 |
+
"XML import. This creates an incomplete website. We should bail early and "
|
66 |
+
"not import anything if this is not present."
|
67 |
+
msgstr ""
|
68 |
+
|
69 |
+
#: inc/classes/class-astra-sites-importer.php:255
|
70 |
+
msgid "There was an error downloading the XML file."
|
71 |
+
msgstr ""
|
72 |
+
|
73 |
+
#: inc/classes/class-astra-sites-importer.php:261
|
74 |
+
msgid "Invalid site XML file!"
|
75 |
+
msgstr ""
|
76 |
+
|
77 |
+
#: inc/classes/class-astra-sites-importer.php:290
|
78 |
+
msgid "Site options are empty!"
|
79 |
+
msgstr ""
|
80 |
+
|
81 |
+
#: inc/classes/class-astra-sites-importer.php:321
|
82 |
+
msgid "Widget data is empty!"
|
83 |
+
msgstr ""
|
84 |
+
|
85 |
+
#: inc/classes/class-astra-sites-importer.php:522
|
86 |
+
#. translators: %s is the post ID
|
87 |
+
msgid "Post ID %s deleted!"
|
88 |
+
msgstr ""
|
89 |
+
|
90 |
+
#: inc/classes/class-astra-sites-importer.php:541
|
91 |
+
#. translators: %s is the form ID
|
92 |
+
msgid "Form ID %s deleted!"
|
93 |
+
msgstr ""
|
94 |
+
|
95 |
+
#: inc/classes/class-astra-sites-importer.php:563
|
96 |
+
#. translators: %s is the term ID
|
97 |
+
msgid "Term ID %s deleted!"
|
98 |
+
msgstr ""
|
99 |
+
|
100 |
+
#: inc/classes/class-astra-sites-page.php:156
|
101 |
+
msgid "Required XMLReader PHP extension is missing on your server!"
|
102 |
+
msgstr ""
|
103 |
+
|
104 |
+
#: inc/classes/class-astra-sites-page.php:158
|
105 |
+
#. translators: %s is the white label name.
|
106 |
+
msgid ""
|
107 |
+
"%s import requires XMLReader extension to be installed. Please contact your "
|
108 |
+
"web hosting provider and ask them to install and activate the XMLReader PHP "
|
109 |
+
"extension."
|
110 |
+
msgstr ""
|
111 |
+
|
112 |
+
#: inc/classes/class-astra-sites-page.php:220
|
113 |
+
msgid "Settings saved successfully."
|
114 |
+
msgstr ""
|
115 |
+
|
116 |
+
#: inc/classes/class-astra-sites-page.php:235
|
117 |
+
#: inc/classes/class-astra-sites-page.php:256
|
118 |
+
msgid "Block Editor (Gutenberg)"
|
119 |
+
msgstr ""
|
120 |
+
|
121 |
+
#: inc/classes/class-astra-sites-page.php:236
|
122 |
+
#: inc/classes/class-astra-sites-page.php:257
|
123 |
+
msgid "Elementor"
|
124 |
+
msgstr ""
|
125 |
+
|
126 |
+
#: inc/classes/class-astra-sites-page.php:237
|
127 |
+
#: inc/classes/class-astra-sites-page.php:258
|
128 |
+
msgid "Beaver Builder"
|
129 |
+
msgstr ""
|
130 |
+
|
131 |
+
#: inc/classes/class-astra-sites-page.php:238
|
132 |
+
#: inc/classes/class-astra-sites-page.php:259
|
133 |
+
msgid "Brizy"
|
134 |
+
msgstr ""
|
135 |
+
|
136 |
+
#: inc/classes/class-astra-sites-page.php:240 inc/includes/admin-page.php:141
|
137 |
+
msgid "Next"
|
138 |
+
msgstr ""
|
139 |
+
|
140 |
+
#: inc/classes/class-astra-sites-page.php:249
|
141 |
+
msgid "Astra Starter Sites - Your Library of 100+ Ready Templates!"
|
142 |
+
msgstr ""
|
143 |
+
|
144 |
+
#: inc/classes/class-astra-sites-white-label.php:187
|
145 |
+
#. translators: %1$s product name
|
146 |
+
msgid "%1$s Branding"
|
147 |
+
msgstr ""
|
148 |
+
|
149 |
+
#: inc/classes/class-astra-sites.php:86
|
150 |
+
msgid "Theme Successfully Activated"
|
151 |
+
msgstr ""
|
152 |
+
|
153 |
+
#: inc/classes/class-astra-sites.php:150
|
154 |
+
#. translators: 1: theme.php file
|
155 |
+
msgid ""
|
156 |
+
"Astra Theme needs to be active for you to use currently installed \"%1$s\" "
|
157 |
+
"plugin. <a href=\"#\" class=\"%3$s\" data-theme-slug=\"astra\">Install & "
|
158 |
+
"Activate Now</a>"
|
159 |
+
msgstr ""
|
160 |
+
|
161 |
+
#: inc/classes/class-astra-sites.php:216
|
162 |
+
msgid "See Library"
|
163 |
+
msgstr ""
|
164 |
+
|
165 |
+
#: inc/classes/class-astra-sites.php:252
|
166 |
+
msgid "Installed! Activating.."
|
167 |
+
msgstr ""
|
168 |
+
|
169 |
+
#: inc/classes/class-astra-sites.php:253
|
170 |
+
msgid "Activating.."
|
171 |
+
msgstr ""
|
172 |
+
|
173 |
+
#: inc/classes/class-astra-sites.php:254
|
174 |
+
msgid "Activated! Reloading.."
|
175 |
+
msgstr ""
|
176 |
+
|
177 |
+
#: inc/classes/class-astra-sites.php:255
|
178 |
+
msgid "Installing.."
|
179 |
+
msgstr ""
|
180 |
+
|
181 |
+
#: inc/classes/class-astra-sites.php:285
|
182 |
+
msgid "Page Builder"
|
183 |
+
msgstr ""
|
184 |
+
|
185 |
+
#: inc/classes/class-astra-sites.php:290
|
186 |
+
msgid "Categories"
|
187 |
+
msgstr ""
|
188 |
+
|
189 |
+
#: inc/classes/class-astra-sites.php:330
|
190 |
+
msgid "Get Agency Bundle"
|
191 |
+
msgstr ""
|
192 |
+
|
193 |
+
#: inc/classes/class-astra-sites.php:332
|
194 |
+
msgid "Upgrade"
|
195 |
+
msgstr ""
|
196 |
+
|
197 |
+
#: inc/classes/class-astra-sites.php:339
|
198 |
+
#. translators: %s are HTML tags.
|
199 |
+
msgid ""
|
200 |
+
"%1$sRequired XMLReader PHP extension is missing on your server!%2$sAstra "
|
201 |
+
"Sites import requires XMLReader extension to be installed. Please contact "
|
202 |
+
"your web hosting provider and ask them to install and activate the "
|
203 |
+
"XMLReader PHP extension."
|
204 |
+
msgstr ""
|
205 |
+
|
206 |
+
#: inc/classes/class-astra-sites.php:340
|
207 |
+
msgid ""
|
208 |
+
"Warning! Astra Site Import process is not complete. Don't close the window "
|
209 |
+
"until import process complete. Do you still want to leave the window?"
|
210 |
+
msgstr ""
|
211 |
+
|
212 |
+
#: inc/classes/class-astra-sites.php:341
|
213 |
+
msgid "Error!"
|
214 |
+
msgstr ""
|
215 |
+
|
216 |
+
#: inc/classes/class-astra-sites.php:342
|
217 |
+
msgid "Error! Read Possibilities."
|
218 |
+
msgstr ""
|
219 |
+
|
220 |
+
#: inc/classes/class-astra-sites.php:344
|
221 |
+
msgid "Done! View Site"
|
222 |
+
msgstr ""
|
223 |
+
|
224 |
+
#: inc/classes/class-astra-sites.php:345
|
225 |
+
msgid "Activating"
|
226 |
+
msgstr ""
|
227 |
+
|
228 |
+
#: inc/classes/class-astra-sites.php:346
|
229 |
+
msgid "Active"
|
230 |
+
msgstr ""
|
231 |
+
|
232 |
+
#: inc/classes/class-astra-sites.php:347
|
233 |
+
msgid "Import failed."
|
234 |
+
msgstr ""
|
235 |
+
|
236 |
+
#: inc/classes/class-astra-sites.php:348
|
237 |
+
msgid "Import failed. See error log."
|
238 |
+
msgstr ""
|
239 |
+
|
240 |
+
#: inc/classes/class-astra-sites.php:349
|
241 |
+
msgid "Import This Site"
|
242 |
+
msgstr ""
|
243 |
+
|
244 |
+
#: inc/classes/class-astra-sites.php:350 inc/classes/class-astra-sites.php:366
|
245 |
+
msgid "Importing.."
|
246 |
+
msgstr ""
|
247 |
+
|
248 |
+
#: inc/classes/class-astra-sites.php:351 inc/includes/admin-page.php:161
|
249 |
+
msgid "Read more"
|
250 |
+
msgstr ""
|
251 |
+
|
252 |
+
#: inc/classes/class-astra-sites.php:352
|
253 |
+
msgid "Hide"
|
254 |
+
msgstr ""
|
255 |
+
|
256 |
+
#: inc/classes/class-astra-sites.php:353
|
257 |
+
msgid "There was a problem receiving a response from server."
|
258 |
+
msgstr ""
|
259 |
+
|
260 |
+
#: inc/classes/class-astra-sites.php:354 inc/includes/admin-page.php:374
|
261 |
+
msgid "No Demos found, Try a different search."
|
262 |
+
msgstr ""
|
263 |
+
|
264 |
+
#: inc/classes/class-astra-sites.php:357
|
265 |
+
msgid "Installing plugin "
|
266 |
+
msgstr ""
|
267 |
+
|
268 |
+
#: inc/classes/class-astra-sites.php:358
|
269 |
+
msgid "Successfully plugin installed!"
|
270 |
+
msgstr ""
|
271 |
+
|
272 |
+
#: inc/classes/class-astra-sites.php:359
|
273 |
+
msgid "Activating plugin "
|
274 |
+
msgstr ""
|
275 |
+
|
276 |
+
#: inc/classes/class-astra-sites.php:360
|
277 |
+
msgid "Successfully plugin activated "
|
278 |
+
msgstr ""
|
279 |
+
|
280 |
+
#: inc/classes/class-astra-sites.php:361
|
281 |
+
msgid "Bulk plugin activation..."
|
282 |
+
msgstr ""
|
283 |
+
|
284 |
+
#: inc/classes/class-astra-sites.php:362
|
285 |
+
msgid "Successfully plugin activate - "
|
286 |
+
msgstr ""
|
287 |
+
|
288 |
+
#: inc/classes/class-astra-sites.php:363
|
289 |
+
msgid "Error! While activating plugin - "
|
290 |
+
msgstr ""
|
291 |
+
|
292 |
+
#: inc/classes/class-astra-sites.php:364
|
293 |
+
msgid "Bulk plugin installation..."
|
294 |
+
msgstr ""
|
295 |
+
|
296 |
+
#: inc/classes/class-astra-sites.php:365
|
297 |
+
msgid "Site API "
|
298 |
+
msgstr ""
|
299 |
+
|
300 |
+
#: inc/classes/class-astra-sites.php:367
|
301 |
+
msgid "Processing requests..."
|
302 |
+
msgstr ""
|
303 |
+
|
304 |
+
#: inc/classes/class-astra-sites.php:368
|
305 |
+
msgid "2) Importing \"Customizer Settings\"..."
|
306 |
+
msgstr ""
|
307 |
+
|
308 |
+
#: inc/classes/class-astra-sites.php:369
|
309 |
+
msgid "Successfully imported customizer settings!"
|
310 |
+
msgstr ""
|
311 |
+
|
312 |
+
#: inc/classes/class-astra-sites.php:370
|
313 |
+
msgid "3) Importing \"Contact Forms\"..."
|
314 |
+
msgstr ""
|
315 |
+
|
316 |
+
#: inc/classes/class-astra-sites.php:371
|
317 |
+
msgid "Successfully imported Contact Forms!"
|
318 |
+
msgstr ""
|
319 |
+
|
320 |
+
#: inc/classes/class-astra-sites.php:372
|
321 |
+
msgid "4) Preparing \"XML\" Data..."
|
322 |
+
msgstr ""
|
323 |
+
|
324 |
+
#: inc/classes/class-astra-sites.php:373
|
325 |
+
msgid "Successfully set XML data!"
|
326 |
+
msgstr ""
|
327 |
+
|
328 |
+
#: inc/classes/class-astra-sites.php:374
|
329 |
+
msgid "5) Importing \"XML\"..."
|
330 |
+
msgstr ""
|
331 |
+
|
332 |
+
#: inc/classes/class-astra-sites.php:375
|
333 |
+
msgid "Successfully imported XML!"
|
334 |
+
msgstr ""
|
335 |
+
|
336 |
+
#: inc/classes/class-astra-sites.php:376
|
337 |
+
msgid "6) Importing \"Options\"..."
|
338 |
+
msgstr ""
|
339 |
+
|
340 |
+
#: inc/classes/class-astra-sites.php:377
|
341 |
+
msgid "Successfully imported Options!"
|
342 |
+
msgstr ""
|
343 |
+
|
344 |
+
#: inc/classes/class-astra-sites.php:378
|
345 |
+
msgid "7) Importing \"Widgets\"..."
|
346 |
+
msgstr ""
|
347 |
+
|
348 |
+
#: inc/classes/class-astra-sites.php:379
|
349 |
+
msgid "Successfully imported Widgets!"
|
350 |
+
msgstr ""
|
351 |
+
|
352 |
+
#: inc/classes/class-astra-sites.php:381
|
353 |
+
msgid "Site imported successfully! visit : "
|
354 |
+
msgstr ""
|
355 |
+
|
356 |
+
#: inc/classes/class-astra-sites.php:382
|
357 |
+
msgid "Getting Site Information.."
|
358 |
+
msgstr ""
|
359 |
+
|
360 |
+
#: inc/classes/class-astra-sites.php:383
|
361 |
+
msgid "Importing Customizer Settings.."
|
362 |
+
msgstr ""
|
363 |
+
|
364 |
+
#: inc/classes/class-astra-sites.php:384
|
365 |
+
msgid "Importing Contact Forms.."
|
366 |
+
msgstr ""
|
367 |
+
|
368 |
+
#: inc/classes/class-astra-sites.php:385
|
369 |
+
msgid "Setting up import data.."
|
370 |
+
msgstr ""
|
371 |
+
|
372 |
+
#: inc/classes/class-astra-sites.php:386
|
373 |
+
msgid "Importing Content.."
|
374 |
+
msgstr ""
|
375 |
+
|
376 |
+
#: inc/classes/class-astra-sites.php:387
|
377 |
+
msgid "Importing Site Options.."
|
378 |
+
msgstr ""
|
379 |
+
|
380 |
+
#: inc/classes/class-astra-sites.php:388
|
381 |
+
msgid "Importing Widgets.."
|
382 |
+
msgstr ""
|
383 |
+
|
384 |
+
#: inc/classes/class-astra-sites.php:389
|
385 |
+
msgid "Import Complete.."
|
386 |
+
msgstr ""
|
387 |
+
|
388 |
+
#: inc/classes/class-astra-sites.php:390
|
389 |
+
msgid "Previewing "
|
390 |
+
msgstr ""
|
391 |
+
|
392 |
+
#: inc/classes/class-astra-sites.php:391
|
393 |
+
msgid "See Error Log →"
|
394 |
+
msgstr ""
|
395 |
+
|
396 |
+
#: inc/classes/class-astra-sites.php:425
|
397 |
+
msgid "No plugin specified"
|
398 |
+
msgstr ""
|
399 |
+
|
400 |
+
#: inc/classes/class-astra-sites.php:454
|
401 |
+
msgid "Plugin Successfully Activated"
|
402 |
+
msgstr ""
|
403 |
+
|
404 |
+
#: inc/importers/batch-processing/helpers/class-wp-background-process.php:433
|
405 |
+
msgid "Every %d Minutes"
|
406 |
+
msgstr ""
|
407 |
+
|
408 |
+
#: inc/importers/class-widgets-importer.php:83
|
409 |
+
msgid "Import data could not be read. Please try a different file."
|
410 |
+
msgstr ""
|
411 |
+
|
412 |
+
#: inc/importers/class-widgets-importer.php:127
|
413 |
+
msgid "Widget area does not exist in theme (using Inactive)"
|
414 |
+
msgstr ""
|
415 |
+
|
416 |
+
#: inc/importers/class-widgets-importer.php:149
|
417 |
+
msgid "Site does not support widget"
|
418 |
+
msgstr ""
|
419 |
+
|
420 |
+
#: inc/importers/class-widgets-importer.php:185
|
421 |
+
msgid "Widget already exists"
|
422 |
+
msgstr ""
|
423 |
+
|
424 |
+
#: inc/importers/class-widgets-importer.php:254
|
425 |
+
msgid "Imported"
|
426 |
+
msgstr ""
|
427 |
+
|
428 |
+
#: inc/importers/class-widgets-importer.php:257
|
429 |
+
msgid "Imported to Inactive"
|
430 |
+
msgstr ""
|
431 |
+
|
432 |
+
#: inc/importers/class-widgets-importer.php:263
|
433 |
+
msgid "No Title"
|
434 |
+
msgstr ""
|
435 |
+
|
436 |
+
#: inc/importers/wxr-importer/class-astra-wxr-importer.php:302
|
437 |
+
msgid "Import complete!"
|
438 |
+
msgstr ""
|
439 |
+
|
440 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:131
|
441 |
+
msgid "Could not open the file for parsing"
|
442 |
+
msgstr ""
|
443 |
+
|
444 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:167
|
445 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:283
|
446 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:356
|
447 |
+
msgid ""
|
448 |
+
"This WXR file (version %1$s) is newer than the importer (version %2$s) and "
|
449 |
+
"may not be supported. Please consider updating."
|
450 |
+
msgstr ""
|
451 |
+
|
452 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:504
|
453 |
+
msgid "The file does not exist, please try again."
|
454 |
+
msgstr ""
|
455 |
+
|
456 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:564
|
457 |
+
msgid "Invalid author mapping"
|
458 |
+
msgstr ""
|
459 |
+
|
460 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:665
|
461 |
+
msgid "Cannot import auto-draft posts"
|
462 |
+
msgstr ""
|
463 |
+
|
464 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:753
|
465 |
+
msgid "Failed to import \"%1$s\": Invalid post type %2$s"
|
466 |
+
msgstr ""
|
467 |
+
|
468 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:763
|
469 |
+
msgid "%1$s \"%2$s\" already exists."
|
470 |
+
msgstr ""
|
471 |
+
|
472 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:857
|
473 |
+
msgid "Skipping attachment \"%s\", fetching attachments disabled"
|
474 |
+
msgstr ""
|
475 |
+
|
476 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:878
|
477 |
+
msgid "Failed to import \"%1$s\" (%2$s)"
|
478 |
+
msgstr ""
|
479 |
+
|
480 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:910
|
481 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1755
|
482 |
+
msgid "Imported \"%1$s\" (%2$s)"
|
483 |
+
msgstr ""
|
484 |
+
|
485 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:915
|
486 |
+
msgid "Post %1$d remapped to %2$d"
|
487 |
+
msgstr ""
|
488 |
+
|
489 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1062
|
490 |
+
msgid "Invalid file type"
|
491 |
+
msgstr ""
|
492 |
+
|
493 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1560
|
494 |
+
msgid "Failed to import user \"%s\""
|
495 |
+
msgstr ""
|
496 |
+
|
497 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1581
|
498 |
+
msgid "Imported user \"%s\""
|
499 |
+
msgstr ""
|
500 |
+
|
501 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1585
|
502 |
+
msgid "User %1$d remapped to %2$d"
|
503 |
+
msgstr ""
|
504 |
+
|
505 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1731
|
506 |
+
msgid "Failed to import %1$s %2$s"
|
507 |
+
msgstr ""
|
508 |
+
|
509 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1760
|
510 |
+
msgid "Term %1$d remapped to %2$d"
|
511 |
+
msgstr ""
|
512 |
+
|
513 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1813
|
514 |
+
msgid "Remote server returned %1$d %2$s for %3$s"
|
515 |
+
msgstr ""
|
516 |
+
|
517 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1826
|
518 |
+
msgid "Remote file is incorrect size"
|
519 |
+
msgstr ""
|
520 |
+
|
521 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1831
|
522 |
+
msgid "Zero size file downloaded"
|
523 |
+
msgstr ""
|
524 |
+
|
525 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1837
|
526 |
+
msgid "Remote file is too large, limit is %s"
|
527 |
+
msgstr ""
|
528 |
+
|
529 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1859
|
530 |
+
msgid "Running post-processing for post %d"
|
531 |
+
msgstr ""
|
532 |
+
|
533 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1872
|
534 |
+
msgid "Could not find the post parent for \"%1$s\" (post #%2$d)"
|
535 |
+
msgstr ""
|
536 |
+
|
537 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1877
|
538 |
+
msgid "Post %1$d was imported with parent %2$d, but could not be found"
|
539 |
+
msgstr ""
|
540 |
+
|
541 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1891
|
542 |
+
msgid "Could not find the author for \"%1$s\" (post #%2$d)"
|
543 |
+
msgstr ""
|
544 |
+
|
545 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1896
|
546 |
+
msgid "Post %1$d was imported with author \"%2$s\", but could not be found"
|
547 |
+
msgstr ""
|
548 |
+
|
549 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1922
|
550 |
+
msgid "Post %d was marked for post-processing, but none was required."
|
551 |
+
msgstr ""
|
552 |
+
|
553 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1933
|
554 |
+
msgid "Could not update \"%1$s\" (post #%2$d) with mapped data"
|
555 |
+
msgstr ""
|
556 |
+
|
557 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1978
|
558 |
+
msgid "Could not find the menu object for \"%1$s\" (post #%2$d)"
|
559 |
+
msgstr ""
|
560 |
+
|
561 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:1983
|
562 |
+
msgid ""
|
563 |
+
"Post %1$d was imported with object \"%2$d\" of type \"%3$s\", but could not "
|
564 |
+
"be found"
|
565 |
+
msgstr ""
|
566 |
+
|
567 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:2005
|
568 |
+
msgid "Could not find the comment parent for comment #%d"
|
569 |
+
msgstr ""
|
570 |
+
|
571 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:2009
|
572 |
+
msgid "Comment %1$d was imported with parent %2$d, but could not be found"
|
573 |
+
msgstr ""
|
574 |
+
|
575 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:2023
|
576 |
+
msgid "Could not find the author for comment #%d"
|
577 |
+
msgstr ""
|
578 |
+
|
579 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:2027
|
580 |
+
msgid "Comment %1$d was imported with author %2$d, but could not be found"
|
581 |
+
msgstr ""
|
582 |
+
|
583 |
+
#: inc/importers/wxr-importer/class-wxr-importer.php:2044
|
584 |
+
msgid "Could not update comment #%d with mapped data"
|
585 |
+
msgstr ""
|
586 |
+
|
587 |
+
#: inc/includes/admin-page.php:41
|
588 |
+
msgid "Search Sites"
|
589 |
+
msgstr ""
|
590 |
+
|
591 |
+
#: inc/includes/admin-page.php:42
|
592 |
+
msgid "Search Sites..."
|
593 |
+
msgstr ""
|
594 |
+
|
595 |
+
#: inc/includes/admin-page.php:71
|
596 |
+
msgid "Liked this demo?"
|
597 |
+
msgstr ""
|
598 |
+
|
599 |
+
#: inc/includes/admin-page.php:75
|
600 |
+
#. translators: %s is pricing page link
|
601 |
+
msgid ""
|
602 |
+
"It is a premium website demo which is available only with the Agency "
|
603 |
+
"Bundles <a href=\"%s\" target=\"_blank\">Buy Now!</a>"
|
604 |
+
msgstr ""
|
605 |
+
|
606 |
+
#: inc/includes/admin-page.php:81
|
607 |
+
#. translators: %s is article link
|
608 |
+
msgid ""
|
609 |
+
"Already own an Agency Bundle? Read an article to know how you can <a "
|
610 |
+
"href=\"%s\" target=\"_blank\">import a premium website demo</a>."
|
611 |
+
msgstr ""
|
612 |
+
|
613 |
+
#: inc/includes/admin-page.php:92
|
614 |
+
msgid "You are just 2 minutes away from importing this demo!"
|
615 |
+
msgstr ""
|
616 |
+
|
617 |
+
#: inc/includes/admin-page.php:93
|
618 |
+
msgid ""
|
619 |
+
"It is a premium website demo and you need to activate the license to access "
|
620 |
+
"it."
|
621 |
+
msgstr ""
|
622 |
+
|
623 |
+
#: inc/includes/admin-page.php:97
|
624 |
+
#. translators: %s is article link
|
625 |
+
msgid ""
|
626 |
+
"Learn how you can <a href=\"%s\" target=\"_blank\">activate the license</a> "
|
627 |
+
"of the Astra Premium Sites plugin."
|
628 |
+
msgstr ""
|
629 |
+
|
630 |
+
#: inc/includes/admin-page.php:112
|
631 |
+
msgid "Select Your Favorite Page Builder"
|
632 |
+
msgstr ""
|
633 |
+
|
634 |
+
#: inc/includes/admin-page.php:115
|
635 |
+
msgid "Sites List.."
|
636 |
+
msgstr ""
|
637 |
+
|
638 |
+
#: inc/includes/admin-page.php:139
|
639 |
+
msgid "Close"
|
640 |
+
msgstr ""
|
641 |
+
|
642 |
+
#: inc/includes/admin-page.php:140
|
643 |
+
msgid "Previous"
|
644 |
+
msgstr ""
|
645 |
+
|
646 |
+
#: inc/includes/admin-page.php:142 inc/includes/admin-page.php:143
|
647 |
+
#: inc/includes/admin-page.php:223 inc/includes/admin-page.php:231
|
648 |
+
msgid "Import Site"
|
649 |
+
msgstr ""
|
650 |
+
|
651 |
+
#: inc/includes/admin-page.php:165
|
652 |
+
msgid "Plugins Used in This Starter Site"
|
653 |
+
msgstr ""
|
654 |
+
|
655 |
+
#: inc/includes/admin-page.php:167
|
656 |
+
msgid "These plugins will be installed when you import this site."
|
657 |
+
msgstr ""
|
658 |
+
|
659 |
+
#: inc/includes/admin-page.php:179
|
660 |
+
msgid ""
|
661 |
+
"Customizer is what gives a design to the website; and selecting this option "
|
662 |
+
"replaces your current design with a new one. <br/>Backup of current "
|
663 |
+
"customizer settings will be stored in \"wp-content/astra-sites\" directory, "
|
664 |
+
"just in case if you want to restore it later."
|
665 |
+
msgstr ""
|
666 |
+
|
667 |
+
#: inc/includes/admin-page.php:188
|
668 |
+
msgid ""
|
669 |
+
"Selecting this option will import dummy pages, posts, images and menus. If "
|
670 |
+
"you do not want to import dummy content, please uncheck this option."
|
671 |
+
msgstr ""
|
672 |
+
|
673 |
+
#: inc/includes/admin-page.php:204
|
674 |
+
msgid ""
|
675 |
+
"WARNING: Selecting this option will delete data from your current website. "
|
676 |
+
"Choose this option only if this is intended."
|
677 |
+
msgstr ""
|
678 |
+
|
679 |
+
#: inc/includes/admin-page.php:209
|
680 |
+
msgid "Advanced Options"
|
681 |
+
msgstr ""
|
682 |
+
|
683 |
+
#: inc/includes/admin-page.php:214
|
684 |
+
msgid "Required Plugins"
|
685 |
+
msgstr ""
|
686 |
+
|
687 |
+
#: inc/includes/admin-page.php:237
|
688 |
+
msgid "Collapse"
|
689 |
+
msgstr ""
|
690 |
+
|
691 |
+
#: inc/includes/admin-page.php:243
|
692 |
+
msgid "Enter desktop preview mode"
|
693 |
+
msgstr ""
|
694 |
+
|
695 |
+
#: inc/includes/admin-page.php:246
|
696 |
+
msgid "Enter tablet preview mode"
|
697 |
+
msgstr ""
|
698 |
+
|
699 |
+
#: inc/includes/admin-page.php:249
|
700 |
+
msgid "Enter mobile preview mode"
|
701 |
+
msgstr ""
|
702 |
+
|
703 |
+
#: inc/includes/admin-page.php:257 inc/includes/admin-page.php:366
|
704 |
+
msgid "Preview"
|
705 |
+
msgstr ""
|
706 |
+
|
707 |
+
#: inc/includes/admin-page.php:272
|
708 |
+
#. translators: %1$s & %2$s are a Demo API URL
|
709 |
+
msgid ""
|
710 |
+
"<p> It seems the demo data server, <i><a href=\"%1$s\">%2$s</a></i> is "
|
711 |
+
"unreachable from your site.</p>"
|
712 |
+
msgstr ""
|
713 |
+
|
714 |
+
#: inc/includes/admin-page.php:274
|
715 |
+
msgid ""
|
716 |
+
"<p class=\"left-margin\"> 1. Sometimes, simple page reload fixes any "
|
717 |
+
"temporary issues. No kidding!</p>"
|
718 |
+
msgstr ""
|
719 |
+
|
720 |
+
#: inc/includes/admin-page.php:276
|
721 |
+
msgid ""
|
722 |
+
"<p class=\"left-margin\"> 2. If that does not work, you will need to talk "
|
723 |
+
"to your server administrator and check if demo server is being blocked by "
|
724 |
+
"the firewall!</p>"
|
725 |
+
msgstr ""
|
726 |
+
|
727 |
+
#: inc/includes/admin-page.php:279
|
728 |
+
#. translators: %1$s is a support link
|
729 |
+
msgid ""
|
730 |
+
"<p>If that does not help, please open up a <a href=\"%1$s\" "
|
731 |
+
"target=\"_blank\">Support Ticket</a> and we will be glad take a closer look "
|
732 |
+
"for you.</p>"
|
733 |
+
msgstr ""
|
734 |
+
|
735 |
+
#: inc/includes/admin-page.php:291
|
736 |
+
msgid "Under Maintenance.."
|
737 |
+
msgstr ""
|
738 |
+
|
739 |
+
#: inc/includes/admin-page.php:292
|
740 |
+
msgid ""
|
741 |
+
"If you are seeing this message, most likely our servers are under routine "
|
742 |
+
"maintenance and we will be back shortly. "
|
743 |
+
msgstr ""
|
744 |
+
|
745 |
+
#: inc/includes/admin-page.php:293
|
746 |
+
msgid ""
|
747 |
+
"In rare case, it is possible your website is having trouble connecting with "
|
748 |
+
"ours. If you need help, please feel free to get in touch with us from our "
|
749 |
+
"website."
|
750 |
+
msgstr ""
|
751 |
+
|
752 |
+
#: inc/includes/admin-page.php:378 inc/includes/admin-page.php:396
|
753 |
+
#. translators: %1$s External Link
|
754 |
+
msgid ""
|
755 |
+
"Don't see a site that you would like to import?<br><a target=\"_blank\" "
|
756 |
+
"href=\"%1$s\">Please suggest us!</a>"
|
757 |
+
msgstr ""
|
758 |
+
|
759 |
+
#: inc/includes/white-label.php:29
|
760 |
+
msgid "Plugin Name:"
|
761 |
+
msgstr ""
|
762 |
+
|
763 |
+
#: inc/includes/white-label.php:34
|
764 |
+
msgid "Plugin Description:"
|
765 |
+
msgstr ""
|
766 |
+
|
767 |
+
#. Plugin Name of the plugin/theme
|
768 |
+
msgid "Astra Starter Sites – Elementor, Beaver Builder & Gutenberg Templates"
|
769 |
+
msgstr ""
|
770 |
+
|
771 |
+
#. Plugin URI of the plugin/theme
|
772 |
+
msgid "http://www.wpastra.com/pro/"
|
773 |
+
msgstr ""
|
774 |
+
|
775 |
+
#. Description of the plugin/theme
|
776 |
+
msgid "Import free sites build with Astra theme."
|
777 |
+
msgstr ""
|
778 |
+
|
779 |
+
#. Author of the plugin/theme
|
780 |
+
msgid "Brainstorm Force"
|
781 |
+
msgstr ""
|
782 |
+
|
783 |
+
#. Author URI of the plugin/theme
|
784 |
+
msgid "http://www.brainstormforce.com"
|
785 |
+
msgstr ""
|
786 |
+
|
787 |
+
#: inc/classes/class-astra-sites-importer-log.php:464
|
788 |
+
#. translators: %1$s Memory Limit, %2$s Recommended memory limit.
|
789 |
+
msgctxt "Recommended Memory Limit"
|
790 |
+
msgid "Current memory limit %1$s. We recommend setting memory to at least %2$s."
|
791 |
+
msgstr ""
|
792 |
+
|
793 |
+
#: inc/classes/class-astra-sites-importer-log.php:545
|
794 |
+
msgctxt "PHP Version"
|
795 |
+
msgid "We recommend to use php 5.4 or higher"
|
796 |
Â
msgstr ""
|
readme.txt
CHANGED
@@ -1,298 +1,301 @@
|
|
1 |
-
=== Astra Starter Sites – Elementor, Beaver Builder & Gutenberg Templates ===
|
2 |
-
Contributors: brainstormforce
|
3 |
-
Donate link: https://wpastra.com/pro/
|
4 |
-
Tags: Elementor,Beaver Builder,Templates,Gutenberg,Astra Starter Sites
|
5 |
-
Requires at least: 4.4
|
6 |
-
Requires PHP: 5.3
|
7 |
-
Tested up to: 5.1
|
8 |
-
Stable tag: 1.3.
|
9 |
-
License: GPLv2 or later
|
10 |
-
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
-
|
12 |
-
The growing library of 90+ ready-to-use free website templates built for Elementor, Beaver Builder page builder and the default WordPress editor Gutenberg.
|
13 |
-
|
14 |
-
== Description ==
|
15 |
-
|
16 |
-
= FREE TEMPLATES FOR ELEMENTOR, BEAVER BUILDER AND GUTENBERG =
|
17 |
-
|
18 |
-
Create professional designed pixel perfect websites in minutes with the Astra Starter Sites plugin.
|
19 |
-
|
20 |
-
This plugin gives you access to 90+ pre-made full website demos for your favorite page builder such as Elementor, Beaver Builder, Brizy and the WordPress default editor Gutenberg.
|
21 |
-
|
22 |
-
All you need to do is select the demo that suits your needs, import, tweak and go live!
|
23 |
-
|
24 |
-
> I love the fact that the Astra Starter Sites plugin comes with dozens of pre-built sites that were built using Elementor and that can be used to create a full website with one click. - Ben Pines, CMO at Elementor
|
25 |
-
|
26 |
-
> Astra Sites allows anyone to have a beautiful website in under 5 minutes while using all open source software. The theme is free, the plugin is free, it’s almost unbelievable. You have to see it with your own eyes. - Adam Preiser, WPCrafter
|
27 |
-
|
28 |
-
= GET A WEBSITE LIVE IN 5 CLICKS! =
|
29 |
-
|
30 |
-
1.Install and activate Astra Starter Sites Plugin
|
31 |
-
2.Pick a website demo that suits your needs
|
32 |
-
3.Install required plugins with a single click
|
33 |
-
4.Import the website
|
34 |
-
5.Done!
|
35 |
-
|
36 |
-
= FULL WEBSITE TEMPLATES FOR =
|
37 |
-
|
38 |
-
Businesses like restaurants, lawyers, agencies, interior designers, artist shops, brandstore, pet services, charity, plumber, dental clinic, construction, fitness trainer, gardening, makeup artist and a lot more. You can take a look at all of them built with different page builders.
|
39 |
-
|
40 |
-
- [Elementor Free Website Templates](https://wpastra.com/ready-websites/?page-builder=elementor&category=free)
|
41 |
-
- [Beaver Builder Free Website Templates](https://wpastra.com/ready-websites/?page-builder=beaver-builder&category=free)
|
42 |
-
- [Gutenberg Free Website Templates](https://wpastra.com/ready-websites/?page-builder=gutenberg&category=free)
|
43 |
-
- [Brizy Free Website Templates](https://wpastra.com/ready-websites/?page-builder=brizy&category=free)
|
44 |
-
|
45 |
-
You can extend this library with premium ready-to-use website demos by purchasing one of the Agency Bundles, i.e. either the Mini Agency Bundle or the Agency Bundle.
|
46 |
-
|
47 |
-
= WHY PEOPLE LOVE THE ASTRA THEME? =
|
48 |
-
|
49 |
-
Over 200,000+ users are empowering their websites with Astra! From beginners to industry experts, everyone is loving Astra for its performance and ease of use.
|
50 |
-
|
51 |
-
= Here are a few reasons why they love Astra - =
|
52 |
-
|
53 |
-
**Faster Performance** - Built with speed and performance in mind, Astra follows the best coding standards and lets you build faster loading and better performing websites.
|
54 |
-
|
55 |
-
**Easy Customization** - With all the settings managed through the customizer, Astra keeps it simple and gives you lots of options to customize everything with a few clicks.
|
56 |
-
|
57 |
-
**Pixel Perfect Design** - Astra reduces your design time by giving you pixel-perfect FREE ready-to-use websites demos within a huge library of starter sites.
|
58 |
-
|
59 |
-
**Deeper Integrations** - Astra works seamlessly with all WooCommerce plugins, LifterLMS, LearnDash etc. This means that you can create and beautify eCommerce websites and those that offer online courses in minutes.
|
60 |
-
|
61 |
-
Fetch the website, tweak images and content and go live!
|
62 |
-
|
63 |
-
Use this imported site as a base for your project and don't waste time starting from scratch!
|
64 |
-
|
65 |
-
_<a href="https://wpastra.com/ready-websites/?utm_source=wp-repo&utm_medium=link&utm_campaign=readme">See list of all available sites to import »</a>_
|
66 |
-
|
67 |
-
#### Video Walkthrough by Adam from WPCrafter:
|
68 |
-
[youtube https://www.youtube.com/watch?v=zYbz-jxE9_Q]
|
69 |
-
|
70 |
-
== Installation ==
|
71 |
-
|
72 |
-
1. Upload the plugin files to the `/wp-content/plugins/astra-sites` directory, or install the plugin through the WordPress plugins screen directly.
|
73 |
-
2. Activate the plugin through the 'Plugins' screen in WordPress.
|
74 |
-
3. Navigate to Appearance -> Astra Sites to preview and import sites.
|
75 |
-
|
76 |
-
== Frequently Asked Questions ==
|
77 |
-
|
78 |
-
= Will the Astra Starter Sites work with my theme? =
|
79 |
-
|
80 |
-
All the website demos are built using the Astra theme. Therefore, in order to use the Astra Starter Sites plugin and import a ready-to-use website, you will need to have the Astra theme installed.
|
81 |
-
|
82 |
-
= Are all the starter sites free? =
|
83 |
-
|
84 |
-
You get over 90+ FREE ready-to-use websites as of now. There are many more premium website demos that can be accessed when you purchase one of our Agency Bundles.
|
85 |
-
|
86 |
-
= How can I import and install the starter sites? =
|
87 |
-
|
88 |
-
Here is an article that will help you [install and import Astra starter sites](https://wpastra.com/docs/installing-importing-astra-sites/?utm_source=wp-repo&utm_medium=link&utm_campaign=readme) on your website.
|
89 |
-
|
90 |
-
|
91 |
-
= Can I import a website demo on an existing website? =
|
92 |
-
|
93 |
-
It is recommended to install and import a website demo on a fresh WordPress installation or a blank website to avoid overriding of settings and page design.
|
94 |
-
|
95 |
-
= Can I deactivate the Astra Starter Sites plugin after importing a website? =
|
96 |
-
|
97 |
-
Yes! The Astra Strater Sites plugin acts as a medium through which you can import and install a website from our cloud server. Once you have the website at your end, you can go ahead and deactivate the plugin.
|
98 |
-
|
99 |
-
= Do I need to install any other plugin before importing a website? =
|
100 |
-
|
101 |
-
You just need to activate the Astra theme and import the website through the Astra Starter Sites plugin. During the process of importing, you will come across a step in which you can install necessary plugins with one click.
|
102 |
-
|
103 |
-
= Will you add more website demos? =
|
104 |
-
|
105 |
-
Yes! We are working on many more free website demos built using Elementor, Beaver Builder, Gutenberg and Brizy.
|
106 |
-
|
107 |
-
= What if I do not find a website for the topic I am looking for? =
|
108 |
-
|
109 |
-
We are open to suggestions and would love to work on topics that our users are looking out for. Please feel free to drop your suggestions through the form [here](https://wpastra.com/sites-suggestions/?utm_source=wp-repo&utm_medium=link&utm_campaign=readme).
|
110 |
-
|
111 |
-
|
112 |
-
== Screenshots ==
|
113 |
-
|
114 |
-
1. Select the page builder of your choice.
|
115 |
-
2. Browse through available Astra sites and select the site that you like.
|
116 |
-
3. Click the import site button to start the import process.
|
117 |
-
|
118 |
-
== Changelog ==
|
119 |
-
|
120 |
-
v1.3.
|
121 |
-
- Improvement:
|
122 |
-
|
123 |
-
v1.3.
|
124 |
-
-
|
125 |
-
|
126 |
-
-
|
127 |
-
- New:
|
128 |
-
|
129 |
-
|
130 |
-
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
- Improvement: Added
|
135 |
-
|
136 |
-
v1.2.
|
137 |
-
- Improvement:
|
138 |
-
|
139 |
-
-
|
140 |
-
|
141 |
-
|
142 |
-
- Fix:
|
143 |
-
|
144 |
-
v1.2.
|
145 |
-
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
- Fix:
|
150 |
-
|
151 |
-
v1.2.
|
152 |
-
- Fix:
|
153 |
-
|
154 |
-
v1.2.
|
155 |
-
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
-
|
164 |
-
|
165 |
-
v1.2.
|
166 |
-
- Fix:
|
167 |
-
|
168 |
-
v1.2.
|
169 |
-
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
- Improvement:
|
174 |
-
|
175 |
-
-
|
176 |
-
-
|
177 |
-
|
178 |
-
|
179 |
-
- Fix:
|
180 |
-
|
181 |
-
v1.2.
|
182 |
-
-
|
183 |
-
|
184 |
-
v1.2.
|
185 |
-
- Improvement:
|
186 |
-
|
187 |
-
v1.
|
188 |
-
-
|
189 |
-
|
190 |
-
v1.1.
|
191 |
-
-
|
192 |
-
|
193 |
-
-
|
194 |
-
|
195 |
-
|
196 |
-
-
|
197 |
-
|
198 |
-
v1.1.
|
199 |
-
-
|
200 |
-
|
201 |
-
-
|
202 |
-
-
|
203 |
-
|
204 |
-
|
205 |
-
-
|
206 |
-
|
207 |
-
v1.1.
|
208 |
-
-
|
209 |
-
|
210 |
-
-
|
211 |
-
|
212 |
-
|
213 |
-
-
|
214 |
-
|
215 |
-
v1.1.
|
216 |
-
-
|
217 |
-
|
218 |
-
v1.1.
|
219 |
-
-
|
220 |
-
|
221 |
-
v1.1.
|
222 |
-
- New:
|
223 |
-
|
224 |
-
|
225 |
-
-
|
226 |
-
-
|
227 |
-
-
|
228 |
-
|
229 |
-
|
230 |
-
-
|
231 |
-
|
232 |
-
-
|
233 |
-
-
|
234 |
-
-
|
235 |
-
-
|
236 |
-
|
237 |
-
|
238 |
-
-
|
239 |
-
|
240 |
-
v1.0.
|
241 |
-
- New:
|
242 |
-
|
243 |
-
-
|
244 |
-
|
245 |
-
|
246 |
-
-
|
247 |
-
|
248 |
-
|
249 |
-
-
|
250 |
-
-
|
251 |
-
|
252 |
-
|
253 |
-
-
|
254 |
-
|
255 |
-
-
|
256 |
-
|
257 |
-
|
258 |
-
-
|
259 |
-
|
260 |
-
v1.0.
|
261 |
-
-
|
262 |
-
|
263 |
-
-
|
264 |
-
|
265 |
-
|
266 |
-
-
|
267 |
-
|
268 |
-
v1.0.
|
269 |
-
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
-
|
274 |
-
|
275 |
-
-
|
276 |
-
|
277 |
-
|
278 |
-
-
|
279 |
-
|
280 |
-
-
|
281 |
-
|
282 |
-
|
283 |
-
-
|
284 |
-
|
285 |
-
v1.0.
|
286 |
-
- Fix:
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
-
|
291 |
-
|
292 |
-
|
293 |
-
-
|
294 |
-
-
|
295 |
-
-
|
296 |
-
|
297 |
-
|
298 |
-
-
|
Â
|
|
Â
|
|
Â
|
1 |
+
=== Astra Starter Sites – Elementor, Beaver Builder & Gutenberg Templates ===
|
2 |
+
Contributors: brainstormforce
|
3 |
+
Donate link: https://wpastra.com/pro/
|
4 |
+
Tags: Elementor,Beaver Builder,Templates,Gutenberg,Astra Starter Sites
|
5 |
+
Requires at least: 4.4
|
6 |
+
Requires PHP: 5.3
|
7 |
+
Tested up to: 5.1
|
8 |
+
Stable tag: 1.3.2
|
9 |
+
License: GPLv2 or later
|
10 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
+
|
12 |
+
The growing library of 90+ ready-to-use free website templates built for Elementor, Beaver Builder page builder and the default WordPress editor Gutenberg.
|
13 |
+
|
14 |
+
== Description ==
|
15 |
+
|
16 |
+
= FREE TEMPLATES FOR ELEMENTOR, BEAVER BUILDER AND GUTENBERG =
|
17 |
+
|
18 |
+
Create professional designed pixel perfect websites in minutes with the Astra Starter Sites plugin.
|
19 |
+
|
20 |
+
This plugin gives you access to 90+ pre-made full website demos for your favorite page builder such as Elementor, Beaver Builder, Brizy and the WordPress default editor Gutenberg.
|
21 |
+
|
22 |
+
All you need to do is select the demo that suits your needs, import, tweak and go live!
|
23 |
+
|
24 |
+
> I love the fact that the Astra Starter Sites plugin comes with dozens of pre-built sites that were built using Elementor and that can be used to create a full website with one click. - Ben Pines, CMO at Elementor
|
25 |
+
|
26 |
+
> Astra Sites allows anyone to have a beautiful website in under 5 minutes while using all open source software. The theme is free, the plugin is free, it’s almost unbelievable. You have to see it with your own eyes. - Adam Preiser, WPCrafter
|
27 |
+
|
28 |
+
= GET A WEBSITE LIVE IN 5 CLICKS! =
|
29 |
+
|
30 |
+
1.Install and activate Astra Starter Sites Plugin
|
31 |
+
2.Pick a website demo that suits your needs
|
32 |
+
3.Install required plugins with a single click
|
33 |
+
4.Import the website
|
34 |
+
5.Done!
|
35 |
+
|
36 |
+
= FULL WEBSITE TEMPLATES FOR =
|
37 |
+
|
38 |
+
Businesses like restaurants, lawyers, agencies, interior designers, artist shops, brandstore, pet services, charity, plumber, dental clinic, construction, fitness trainer, gardening, makeup artist and a lot more. You can take a look at all of them built with different page builders.
|
39 |
+
|
40 |
+
- [Elementor Free Website Templates](https://wpastra.com/ready-websites/?page-builder=elementor&category=free)
|
41 |
+
- [Beaver Builder Free Website Templates](https://wpastra.com/ready-websites/?page-builder=beaver-builder&category=free)
|
42 |
+
- [Gutenberg Free Website Templates](https://wpastra.com/ready-websites/?page-builder=gutenberg&category=free)
|
43 |
+
- [Brizy Free Website Templates](https://wpastra.com/ready-websites/?page-builder=brizy&category=free)
|
44 |
+
|
45 |
+
You can extend this library with premium ready-to-use website demos by purchasing one of the Agency Bundles, i.e. either the Mini Agency Bundle or the Agency Bundle.
|
46 |
+
|
47 |
+
= WHY PEOPLE LOVE THE ASTRA THEME? =
|
48 |
+
|
49 |
+
Over 200,000+ users are empowering their websites with Astra! From beginners to industry experts, everyone is loving Astra for its performance and ease of use.
|
50 |
+
|
51 |
+
= Here are a few reasons why they love Astra - =
|
52 |
+
|
53 |
+
**Faster Performance** - Built with speed and performance in mind, Astra follows the best coding standards and lets you build faster loading and better performing websites.
|
54 |
+
|
55 |
+
**Easy Customization** - With all the settings managed through the customizer, Astra keeps it simple and gives you lots of options to customize everything with a few clicks.
|
56 |
+
|
57 |
+
**Pixel Perfect Design** - Astra reduces your design time by giving you pixel-perfect FREE ready-to-use websites demos within a huge library of starter sites.
|
58 |
+
|
59 |
+
**Deeper Integrations** - Astra works seamlessly with all WooCommerce plugins, LifterLMS, LearnDash etc. This means that you can create and beautify eCommerce websites and those that offer online courses in minutes.
|
60 |
+
|
61 |
+
Fetch the website, tweak images and content and go live!
|
62 |
+
|
63 |
+
Use this imported site as a base for your project and don't waste time starting from scratch!
|
64 |
+
|
65 |
+
_<a href="https://wpastra.com/ready-websites/?utm_source=wp-repo&utm_medium=link&utm_campaign=readme">See list of all available sites to import »</a>_
|
66 |
+
|
67 |
+
#### Video Walkthrough by Adam from WPCrafter:
|
68 |
+
[youtube https://www.youtube.com/watch?v=zYbz-jxE9_Q]
|
69 |
+
|
70 |
+
== Installation ==
|
71 |
+
|
72 |
+
1. Upload the plugin files to the `/wp-content/plugins/astra-sites` directory, or install the plugin through the WordPress plugins screen directly.
|
73 |
+
2. Activate the plugin through the 'Plugins' screen in WordPress.
|
74 |
+
3. Navigate to Appearance -> Astra Sites to preview and import sites.
|
75 |
+
|
76 |
+
== Frequently Asked Questions ==
|
77 |
+
|
78 |
+
= Will the Astra Starter Sites work with my theme? =
|
79 |
+
|
80 |
+
All the website demos are built using the Astra theme. Therefore, in order to use the Astra Starter Sites plugin and import a ready-to-use website, you will need to have the Astra theme installed.
|
81 |
+
|
82 |
+
= Are all the starter sites free? =
|
83 |
+
|
84 |
+
You get over 90+ FREE ready-to-use websites as of now. There are many more premium website demos that can be accessed when you purchase one of our Agency Bundles.
|
85 |
+
|
86 |
+
= How can I import and install the starter sites? =
|
87 |
+
|
88 |
+
Here is an article that will help you [install and import Astra starter sites](https://wpastra.com/docs/installing-importing-astra-sites/?utm_source=wp-repo&utm_medium=link&utm_campaign=readme) on your website.
|
89 |
+
|
90 |
+
|
91 |
+
= Can I import a website demo on an existing website? =
|
92 |
+
|
93 |
+
It is recommended to install and import a website demo on a fresh WordPress installation or a blank website to avoid overriding of settings and page design.
|
94 |
+
|
95 |
+
= Can I deactivate the Astra Starter Sites plugin after importing a website? =
|
96 |
+
|
97 |
+
Yes! The Astra Strater Sites plugin acts as a medium through which you can import and install a website from our cloud server. Once you have the website at your end, you can go ahead and deactivate the plugin.
|
98 |
+
|
99 |
+
= Do I need to install any other plugin before importing a website? =
|
100 |
+
|
101 |
+
You just need to activate the Astra theme and import the website through the Astra Starter Sites plugin. During the process of importing, you will come across a step in which you can install necessary plugins with one click.
|
102 |
+
|
103 |
+
= Will you add more website demos? =
|
104 |
+
|
105 |
+
Yes! We are working on many more free website demos built using Elementor, Beaver Builder, Gutenberg and Brizy.
|
106 |
+
|
107 |
+
= What if I do not find a website for the topic I am looking for? =
|
108 |
+
|
109 |
+
We are open to suggestions and would love to work on topics that our users are looking out for. Please feel free to drop your suggestions through the form [here](https://wpastra.com/sites-suggestions/?utm_source=wp-repo&utm_medium=link&utm_campaign=readme).
|
110 |
+
|
111 |
+
|
112 |
+
== Screenshots ==
|
113 |
+
|
114 |
+
1. Select the page builder of your choice.
|
115 |
+
2. Browse through available Astra sites and select the site that you like.
|
116 |
+
3. Click the import site button to start the import process.
|
117 |
+
|
118 |
+
== Changelog ==
|
119 |
+
|
120 |
+
v1.3.2 - 1-April-2019
|
121 |
+
- Improvement: One click install and activate Astra theme on click on admin notice.
|
122 |
+
|
123 |
+
v1.3.1 - 28-March-2019
|
124 |
+
- Improvement: Set the max height for the website image from the website preview window.
|
125 |
+
|
126 |
+
v1.3.0 - 26-March-2019
|
127 |
+
- New: Improve the user experience by removing unnecessary steps required in importing a site. Now an Astra site can be imported with just one click.
|
128 |
+
- New: Display page builder selection only once on the first load of Astra Sites.
|
129 |
+
- New: Take a backup of customizer options before importing new settings.
|
130 |
+
- New: Allow to reset the previously imported site when importing multiple Astra sites.
|
131 |
+
|
132 |
+
v1.2.15 - 14-March-2019
|
133 |
+
- Improvement: Admin page UI improvements.
|
134 |
+
- Improvement: Added filter `astra_sites_page_title` to change the page title.
|
135 |
+
|
136 |
+
v1.2.14 - 13-March-2019
|
137 |
+
- Improvement: Added support for the WPForms plugin.
|
138 |
+
|
139 |
+
v1.2.13 - 12-March-2019
|
140 |
+
- Improvement: Improved logic to download images in the Elementor templates.
|
141 |
+
- Improvement: Added description of the Agency sites when license is not activated.
|
142 |
+
- Fix: Incorrect images was set after batch process complete.
|
143 |
+
|
144 |
+
v1.2.12 - 29-Jan-2019
|
145 |
+
- Fix: Gutenberg render markup is invalid due to encoded characterless e.g. <, > are decoded into HTML tag.
|
146 |
+
|
147 |
+
v1.2.11 - 24-Jan-2019
|
148 |
+
- Improvement: Display a maintenance message if the Astra Sites API is unreachable.
|
149 |
+
- Fix: EventSource abort the import process if default charset is not UTF-8.
|
150 |
+
|
151 |
+
v1.2.10 - 4-Jan-2019
|
152 |
+
- Fix: Astra Sites not accessible due to incorrect query parameters.
|
153 |
+
|
154 |
+
v1.2.9 - 17-Dec-2018
|
155 |
+
- Fix: XML not import due to getting different MIME file types on different PHP versions.
|
156 |
+
|
157 |
+
v1.2.8 - 14-Dec-2018
|
158 |
+
- Improvement: Added admin notice if XMLReader is not installed. XMLReader is required to import the XML of the website.
|
159 |
+
- Fix: XML not import due to improved verification of MIME file types in WordPress v5.0.1.
|
160 |
+
|
161 |
+
v1.2.7 - 12-July-2018
|
162 |
+
- Improvement: Added page builder and category filter support to show selected page builder with selected categories.
|
163 |
+
- Improvement: Added filter `astra_sites_show_filters` to enable/disable the filter list from admin page.
|
164 |
+
|
165 |
+
v1.2.6 - 9-July-2018
|
166 |
+
- Fix: We have added `wp_slash` to normalize the Elementor post meta. Elementor have also normalize it. So, We have avoided `wp_slash` while importing sites.
|
167 |
+
|
168 |
+
v1.2.5 - 5-July-2018
|
169 |
+
- Fix: Normalize Elementor post meta by using `wp_slash` to avoid the unslashing data.
|
170 |
+
|
171 |
+
v1.2.4 - 29-June-2018
|
172 |
+
- Improvement: Removed custom license validation form and used Graupi in-build license validation form.
|
173 |
+
- Improvement: Set default page builders depends on the packaged purchase.
|
174 |
+
|
175 |
+
v1.2.3 - 13-June-2018
|
176 |
+
- Improvement: Added windows EDGE browser support for importing the sites.
|
177 |
+
- Improvement: The log file was not created if server does not support the file handling functions.
|
178 |
+
- Fix: Load WXR importer on init to avoid redirect loop when loading WooCommerce importer.
|
179 |
+
- Fix: Clear the Astra Pro plugin cache after site import.
|
180 |
+
|
181 |
+
v1.2.2 - 26-March-2018
|
182 |
+
- Fix: Correctly load the Elementor Pro 2.0 compatibility class for beta versions.
|
183 |
+
|
184 |
+
v1.2.1 - 23-March-2018
|
185 |
+
- Improvement: Clear the Astra Pro plugin cache after site import.
|
186 |
+
|
187 |
+
v1.2.0 - 22-March-2018
|
188 |
+
- Improvement: Added compatibility for Elemetor version 2.0.0. Older versions throw the PHP warning for function process_element_export_import_content().
|
189 |
+
|
190 |
+
v1.1.9 - 12-March-2018
|
191 |
+
- Fix: String `Select Your Favorite Page Builder` jerk while loading the sites.
|
192 |
+
|
193 |
+
v1.1.8 - 5-March-2018
|
194 |
+
- Improvements: Updated processing button animation while installation/activating plugin and importing site.
|
195 |
+
- Improvements: Updated suggestion box message.
|
196 |
+
- Fix: PHP fatal errors for WXR importer classes `WXR_Import_Info`, `WXR_Importer`, `WP_Importer_Logger_ServerSentEvents` and `WP_Importer_Logger`.
|
197 |
+
|
198 |
+
v1.1.7 - 2-February-2018
|
199 |
+
- Improvements: Some users reported confusion in the default option of choosing page builder. We have made UX improvements so users now must select the Page Builder first before selecting any website.
|
200 |
+
|
201 |
+
v1.1.6 - 22-January-2018
|
202 |
+
- New: Added filter `astra_sites_xml_import_options` to change the XML import options.
|
203 |
+
- Fix: Astra Pro plugin 'Custom Layouts' & 'Page Headers' not setting right display location due to different page, tax, category ids.
|
204 |
+
- Fix: WooCommerce shop, checkout cart page ids not setting issue.
|
205 |
+
- Fix: After site import updated demo url from the nav menus.
|
206 |
+
|
207 |
+
v1.1.5 - 11-January-2018
|
208 |
+
- New: Added SVG file support for importing the SVG images.
|
209 |
+
|
210 |
+
v1.1.4 - 28-Dec-2017
|
211 |
+
- Improvement: Importing WooCommerce product category images.
|
212 |
+
- Improvement: Retain WooCommerce cart, checkout & my account pages when importing the ready WooCommerce sites.
|
213 |
+
- Fix: Disabled WooCommerce plugin setup wizard after plugin install & activate.
|
214 |
+
|
215 |
+
v1.1.3 - 20-Dec-2017
|
216 |
+
- Improvement: Retain WooCommerce shop page when importing the ready WooCommerce sites.
|
217 |
+
|
218 |
+
v1.1.2 - 24-Nov-2017
|
219 |
+
- Fix: Handling plugin installation errors.
|
220 |
+
|
221 |
+
v1.1.1 - 23-Nov-2017
|
222 |
+
- New: Change the api url for Astra sites to https://websitedemos.net/ from https://sites.wpastra.com/
|
223 |
+
|
224 |
+
v1.1.0 - 21-Nov-2017
|
225 |
+
- New: Import the site content using Event Source (SSE) which ensures faithful imports.
|
226 |
+
- New: Divided the site import process in separate AJAX calls to reduce the possibility of timeouts.
|
227 |
+
- New: Generated the import log file. It will be displayed in the UI if the import fails.
|
228 |
+
- Improvement: Validate all the possible errors.
|
229 |
+
- Improvement: Updated Astra sites HTML grid structure for WordPress v4.9 compatibility.
|
230 |
+
- Enhancement: Updated plugin name from Astra Sites - Lite with Astra Starter Sites.
|
231 |
+
|
232 |
+
v1.0.14 - 9-Nov-2017
|
233 |
+
- New: All the linked images on the Astra Sites will be downloaded to your site, No more loading images from external URLs.
|
234 |
+
- New: Added suggestion box at as the last column in when listing sites so that you can add a suggest the sites you want.
|
235 |
+
- New: Added site responsive preview buttons.
|
236 |
+
- Improvement: Search string will not be removed when switching the page builder when scrolling through sites.
|
237 |
+
- Improvement: Loading 15 sites instead of 6 Astra sites in the first load.
|
238 |
+
- Improvement: Removed LazyLoad which is not useful in admin back-end for showing Astra Sites.
|
239 |
+
|
240 |
+
v1.0.13 - 9-Oct-2017
|
241 |
+
- New: Browsing the Astra Sites in the Admin panel is not faster with JS rendering.
|
242 |
+
|
243 |
+
v1.0.12 - 29-Sept-2017
|
244 |
+
- New: Added White Label support from <a href="https://wpastra.com/pro/">Astra Pro</a>.
|
245 |
+
- Improvement: Don't display sites from both the page builders in the same view.
|
246 |
+
- Fix: Astra Sites admin area not working in the Firefox.
|
247 |
+
|
248 |
+
v1.0.11 - 22-Sept-2017
|
249 |
+
- New: Single click Install & activate required plugins.
|
250 |
+
- New: Added filter `astra_sites_menu_item` for adding extra tabs in admin page.
|
251 |
+
- New: Added back image import feature for `elementor` page builder. In batch image import we import all images from astra site into client site.
|
252 |
+
- Improvement: Updated JS code with object prototype.
|
253 |
+
- Fix: Screen bounce on retina devices.
|
254 |
+
|
255 |
+
v1.0.10 - 11-Sept-2017
|
256 |
+
- Improvement: Added support for retina logo import.
|
257 |
+
- Fix: Site logo image not displayed in customizer.
|
258 |
+
- Fix: Updated `Astra Agency` purchase link.
|
259 |
+
|
260 |
+
v1.0.9 - 8-Sept-2017
|
261 |
+
- New: Added page builder categories for listing sites as per page builder.
|
262 |
+
|
263 |
+
v1.0.8 - 6-Sept-2017
|
264 |
+
- Fix: Beaver Builder option import.
|
265 |
+
- Enhancement: Disabled dismiss-able notice visible once for each user.
|
266 |
+
- Enhancement: Showing error message for for user who have not `manage_plugins` capability.
|
267 |
+
|
268 |
+
v1.0.7 - 1-Sept-2017
|
269 |
+
- Fix: Custom Menu widget not setting imported widget.
|
270 |
+
|
271 |
+
v1.0.6 - 30-Aug-2017
|
272 |
+
- New: Addd custom menu for Astra Sites.
|
273 |
+
- Fix: Validate site options before storing in database.
|
274 |
+
|
275 |
+
v1.0.5 - 29-Aug-2017
|
276 |
+
- New: Added filter `astra_sites_api_args` for adding extra arguments in api call.
|
277 |
+
- Enhancement: Plugin name updated from `Astra Sites` with `Astra Free Sites`.
|
278 |
+
- Fix: PHP error while ignoring users.
|
279 |
+
|
280 |
+
v1.0.4 - 21-Aug-2017
|
281 |
+
- New: Added filter `astra_sites_api_params` for adding extra params in api call.
|
282 |
+
- New: Added filter `astra_sites_api_args` for adding extra arguments in api call.
|
283 |
+
- New: Added filter `astra_sites_category_hide_empty` for showing categories which are not set for any site.
|
284 |
+
|
285 |
+
v1.0.3 - 11-Aug-2017
|
286 |
+
- Fix: Avoided Astra users from site import process.
|
287 |
+
|
288 |
+
v1.0.2 - 09-Aug-2017
|
289 |
+
- Fix: Listing appropriate next and previous Astra sites.
|
290 |
+
- Enhancement: Listing Astra sites though AJAX API call.
|
291 |
+
|
292 |
+
v1.0.1 - 04-Aug-2017
|
293 |
+
- New: Added Elementor plugin options support.
|
294 |
+
- New: Added Customizer CSS support.
|
295 |
+
- Enhancement: Avoided Lite Plugin version if Pro version is Installed. Now added support for Beaver Builder Plugin (Lite Version).
|
296 |
+
- Enhancement: Astra sites API call validated before import.
|
297 |
+
- Enhancement: Site logo imported from Astra sites.
|
298 |
+
- Fix: Bug where widgets created with SiteOrigin plugin were not being imported.
|
299 |
+
|
300 |
+
v1.0.0
|
301 |
+
- Initial release
|