Jupiter X Core - Version 1.8.0

Version Description

Download this release

Release Info

Developer artbees
Plugin Icon wp plugin Jupiter X Core
Version 1.8.0
Comparing to
See all releases

Code changes from version 1.6.1 to 1.8.0

includes/control-panel/functions.php CHANGED
@@ -12,6 +12,8 @@
12
  */
13
  add_action( 'jupiterx_control_panel_init', function() {
14
  jupiterx_core()->load_files( [
 
 
15
  'control-panel/class-image-sizes',
16
  'control-panel/class-settings',
17
  'control-panel/install-template',
12
  */
13
  add_action( 'jupiterx_control_panel_init', function() {
14
  jupiterx_core()->load_files( [
15
+ 'control-panel/includes/class-helpers',
16
+ 'control-panel/includes/class-filesystem',
17
  'control-panel/class-image-sizes',
18
  'control-panel/class-settings',
19
  'control-panel/install-template',
includes/control-panel/includes/class-filesystem.php ADDED
@@ -0,0 +1,613 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class helper as wrapper of built-in WP wp_filesystem object
5
+ *
6
+ * @version 1.0.0
7
+ * @author Sofyan Sitorus <sofyan@artbees.net>
8
+ *
9
+ * @since 5.7
10
+ */
11
+
12
+ require_once ABSPATH . 'wp-admin/includes/file.php';
13
+ require_once ABSPATH . 'wp-admin/includes/template.php';
14
+ require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
15
+
16
+
17
+ if ( ! class_exists( 'JupiterX_Filesystem' ) ) {
18
+
19
+ /**
20
+ * Filesystem class.
21
+ *
22
+ * @since 1.7.0
23
+ */
24
+ class JupiterX_Filesystem {
25
+
26
+ /**
27
+ * @var array
28
+ */
29
+ private $options = [];
30
+
31
+ /**
32
+ * @var array
33
+ */
34
+ public $errors = [];
35
+
36
+ /**
37
+ * @var null
38
+ */
39
+ public $wp_filesystem = null;
40
+
41
+ /**
42
+ * @var array
43
+ */
44
+ private $creds_data = [];
45
+
46
+ /**
47
+ * @var boolean
48
+ */
49
+ private $initialized = false;
50
+
51
+ /**
52
+ * Constructor
53
+ *
54
+ * @param (array) $args The arguments for the object options. Default: []
55
+ * @param (boolean) $init Whether to initialise the object instantly. Default: false.
56
+ * @param (boolean) $force Whether to force create new instance of $wp_filesystem object. Default: false.
57
+ */
58
+ public function __construct( $args = [], $init = false, $force = false ) {
59
+ $this->errors = new WP_Error();
60
+
61
+ $args = wp_parse_args(
62
+ (array) $args, [
63
+ 'form_post' => '', // (string) The URL to post the form to. Default: ''.
64
+ 'type' => '', // (string) Chosen type of filesystem. Default: ''.
65
+ 'error' => false, // (boolean) Whether the current request has failed to connect. Default: false.
66
+ 'context' => '', // (string) Full path to the directory that is tested for being writable. Default: WP_CONTENT_DIR.
67
+ 'extra_fields' => null, // (array) Extra POST fields in array key value pair format. Default: null.
68
+ 'allow_relaxed_file_ownership' => false, // (boolean) Whether to allow Group/World writable. Default: false.
69
+ 'override' => true, // (boolean) Whether to override some built-in function with custom function. Default: true.
70
+ ]
71
+ );
72
+
73
+ foreach ( $args as $key => $value ) {
74
+ $this->setOption( $key, $value );
75
+ }
76
+
77
+ if ( $init ) {
78
+ $this->init( $force );
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Initialize the wp_filesystem object
84
+ *
85
+ * @param (boolean) $force Whether to force create new instance of $wp_filesystem object. Default: false.
86
+ * @return boolean
87
+ */
88
+ public function init( $force = false ) {
89
+
90
+ global $wp_filesystem;
91
+
92
+ $this->initialized = true;
93
+
94
+ if ( ! $force && $wp_filesystem && $wp_filesystem instanceof WP_Filesystem_Base ) {
95
+
96
+ $this->wp_filesystem = $wp_filesystem;
97
+ return true;
98
+
99
+ } else {
100
+
101
+ $this->creds_data = request_filesystem_credentials(
102
+ $this->getOption( 'form_post' ),
103
+ $this->getOption( 'type' ),
104
+ $this->getOption( 'error' ),
105
+ $this->getOption( 'context' ),
106
+ $this->getOption( 'extra_fields' ),
107
+ $this->getOption( 'allow_relaxed_file_ownership' )
108
+ );
109
+
110
+ if ( ! WP_Filesystem( $this->creds_data, $this->getOption( 'context' ), $this->getOption( 'allow_relaxed_file_ownership' ) ) ) {
111
+
112
+ if ( isset( $wp_filesystem->errors ) && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
113
+ $this->add_error( $wp_filesystem->errors->get_error_code(), $wp_filesystem->errors->get_error_message(), $wp_filesystem->errors->get_error_data() );
114
+ } else {
115
+ $this->add_error( 'unable_to_connect_to_filesystem', __( 'Unable to connect to the filesystem. Please confirm your credentials.', 'jupiterx' ), $this->creds_data );
116
+ }
117
+
118
+ return false;
119
+ } else {
120
+
121
+ $this->wp_filesystem = $wp_filesystem;
122
+
123
+ return true;
124
+ }
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Magic method to call the wp_filesystem method
130
+ *
131
+ * @param string $method
132
+ * @param array $args
133
+ * @return mixed
134
+ * @see wp-admin/includes/class-wp-filesystem-base.php for complete methods available
135
+ */
136
+ public function __call( $method, $args ) {
137
+
138
+ // Try to initialize the wp_filesystem object
139
+ if ( ! $this->initialized ) {
140
+ $this->init();
141
+ }
142
+
143
+ // Stop execution if wp_filesystem objetc is empty
144
+ if ( ! $this->wp_filesystem || ! $this->wp_filesystem instanceof WP_Filesystem_Base ) {
145
+ return false;
146
+ }
147
+
148
+ // Do the magic, Abracadabra...!
149
+ switch ( $method ) {
150
+ case 'mkdir':
151
+ case 'put_contents':
152
+ case 'copy':
153
+ case 'is_writable':
154
+ if ( $this->getOption( 'override' ) ) {
155
+ $result = call_user_func_array( [ $this, $method . '_override' ], $args );
156
+ } else {
157
+ $result = call_user_func_array( [ $this->wp_filesystem, $method ], $args );
158
+ }
159
+
160
+ break;
161
+
162
+ case 'unzip':
163
+ $result = call_user_func_array( [ $this, $method . '_custom' ], $args );
164
+
165
+ break;
166
+
167
+ default:
168
+ if ( ! is_callable( [ $this->wp_filesystem, $method ] ) ) {
169
+ $this->add_error( 'invalid_wp_filesystem_method_' . $method, __( 'Invalid method for $wp_filesystem object!', 'jupiterx' ) );
170
+ $result = false;
171
+ } else {
172
+ $result = call_user_func_array( [ $this->wp_filesystem, $method ], $args );
173
+ }
174
+
175
+ break;
176
+ }
177
+
178
+ $this->setErrors();
179
+
180
+ return $result;
181
+ }
182
+
183
+ /**
184
+ * Create directory recursively
185
+ *
186
+ * @param (string) $path
187
+ * @param (boolean) $chmod
188
+ * @param (boolean) $chown
189
+ * @param (boolean) $chgrp
190
+ * @return boolean
191
+ */
192
+ private function mkdir_override( $path, $chmod = false, $chown = false, $chgrp = false ) {
193
+ // Check if $path already exists
194
+ if ( $this->is_dir( $path ) ) {
195
+ return true;
196
+ } else {
197
+
198
+ // If file exists has same name with directory, delete it
199
+ if ( $this->exists( $path ) ) {
200
+ $this->delete( $path );
201
+ }
202
+
203
+ $path = str_replace( '\\', '/', $path );
204
+
205
+ // Split path as folder chunks.
206
+ $folders = explode( '/', trim( $path, '/' ) );
207
+
208
+ $path_prefix = str_replace( implode( '/', $folders ), '', rtrim( $path, '/' ) );
209
+
210
+ if ( $folders ) {
211
+ $new_folders = [];
212
+
213
+ // Check directories nested, create new if not exixts.
214
+ foreach ( $folders as $folder ) {
215
+ $new_folders[] = trim( $folder, '/' );
216
+ $new_folder = $path_prefix . implode( '/', $new_folders );
217
+
218
+ // Ignore folders outside open_basedir.
219
+ if ( $this->is_open_basedir_restricted( $new_folder ) ) {
220
+ continue;
221
+ }
222
+
223
+ // Skip if $new_folder already exists
224
+ if ( $this->is_dir( $new_folder ) ) {
225
+ continue;
226
+ }
227
+
228
+ // If file exists has same name with $new_folder, delete it
229
+ if ( $this->exists( $new_folder ) ) {
230
+ $this->delete( $new_folder );
231
+ }
232
+
233
+ // Create the $new_folder
234
+ if ( ! $this->wp_filesystem->mkdir( $new_folder, $chmod, $chown, $chgrp ) ) {
235
+ $this->add_error( 'can_not_create_directory', sprintf( __( 'Can\'t create directory %s', 'jupiterx' ), $new_folder ) );
236
+ return false;
237
+ }
238
+ }
239
+ }
240
+ return true;
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Write contents to a file
246
+ *
247
+ * @param (string) $file
248
+ * @param (string) $contents
249
+ * @param (boolean) $mode
250
+ * @return boolean
251
+ */
252
+ private function put_contents_override( $file, $contents, $mode = false ) {
253
+
254
+ if ( $this->is_dir( $file ) ) {
255
+ $this->add_error( 'directory_exists_has_same_name', sprintf( __( 'A directory exists has same name %s', 'jupiterx' ), $new_folder ) );
256
+ return false;
257
+ }
258
+
259
+ $path = dirname( $file );
260
+
261
+ if ( ! $this->is_dir( $path ) ) {
262
+ $this->mkdir( $path );
263
+ }
264
+
265
+ return $this->wp_filesystem->put_contents( $file, $contents, $mode );
266
+ }
267
+
268
+ /**
269
+ * Copy file
270
+ *
271
+ * @param (string) $source
272
+ * @param (string) $destination
273
+ * @param (boolean) $overwrite
274
+ * @param (boolean) $mode
275
+ * @return boolean
276
+ */
277
+ private function copy_override( $source, $destination, $overwrite = true, $mode = false ) {
278
+ if ( ! $overwrite && $this->exists( $destination ) ) {
279
+ $this->add_error( 'file_already_exists', sprintf( __( 'File already exists %s', 'jupiterx' ), $new_folder ) );
280
+ return false;
281
+ }
282
+
283
+ if ( ! $this->exists( $source ) ) {
284
+ $this->add_error( 'copy_source_file_not_exists', sprintf( __( 'Copy source file not exists: %s', 'jupiterx' ), $source ) );
285
+ return false;
286
+ }
287
+
288
+ if ( ! $this->is_file( $source ) ) {
289
+ $this->add_error( 'copy_source_file_not_valid', sprintf( __( 'Copy source file not valid: %s', 'jupiterx' ), $source ) );
290
+ return false;
291
+ }
292
+
293
+ if ( ! $this->is_readable( $source ) ) {
294
+ $this->add_error( 'copy_source_file_not_readable', sprintf( __( 'Copy source file not readable: %s', 'jupiterx' ), $source ) );
295
+ return false;
296
+ }
297
+
298
+ $content = $this->get_contents( $source );
299
+
300
+ if ( false === $content ) {
301
+ return false;
302
+ }
303
+
304
+ return $this->put_contents( $destination, $content, $mode );
305
+ }
306
+
307
+ /**
308
+ * Check if file or directory is writable
309
+ *
310
+ * @param (string) $file
311
+ * @return boolean
312
+ */
313
+ private function is_writable_override( $file ) {
314
+
315
+ if ( $this->is_dir( $file ) ) {
316
+ $temp_file = trailingslashit( $file ) . time() . '-' . uniqid() . '.tmp';
317
+
318
+ $this->put_contents( $temp_file, '' );
319
+
320
+ $is_writable = $this->wp_filesystem->is_writable( $temp_file );
321
+
322
+ $this->delete( $temp_file );
323
+
324
+ return $is_writable;
325
+ } else {
326
+ // Create the file if not exists
327
+ if ( ! $this->exists( $file ) ) {
328
+ $this->put_contents( $file, '' );
329
+ }
330
+ return $this->wp_filesystem->is_writable( $file );
331
+ }
332
+ }
333
+
334
+ /**
335
+ * Create zip file of a folder and paste to a destination.
336
+ *
337
+ * @since 1.0.3
338
+ *
339
+ * @param string $folder Target folder to zip.
340
+ * @param string $destination Destination to save the zip.
341
+ * @param string $enclose Enclose all files inside a folder name.
342
+ *
343
+ * @return boolean Zipping status.
344
+ */
345
+ public function zip_folder( $folder, $destination, $enclose ) {
346
+ if ( ! $this->exists( $folder ) ) {
347
+ return false;
348
+ }
349
+
350
+ $temp_file = tempnam( WP_CONTENT_DIR, 'zip' );
351
+
352
+ $zip = new ZipArchive();
353
+
354
+ $zip->open( $temp_file );
355
+
356
+ $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $folder ) );
357
+
358
+ foreach ( $files as $name => $file ) {
359
+ if ( $file->isDir() ) {
360
+ continue;
361
+ }
362
+
363
+ $file_path = $file->getRealPath();
364
+
365
+ $relative_path = substr( $file_path, strlen( $folder ) + 1 );
366
+
367
+ if ( ! empty( $enclose ) ) {
368
+ $relative_path = $enclose . '/' . $relative_path;
369
+ }
370
+
371
+ $zip->addFile( $file_path, $relative_path );
372
+ }
373
+
374
+ $zip->close();
375
+
376
+ // Copy the temp file to directory.
377
+ $this->copy( $temp_file, $destination );
378
+
379
+ // Delete temp file.
380
+ $this->delete( $temp_file );
381
+
382
+ // Check to make sure the file exists.
383
+ return $this->exists( $destination );
384
+ }
385
+
386
+ /**
387
+ * Extract zip file.
388
+ *
389
+ * @param [type] $source The source zip file.
390
+ * @param [type] $destination The destination path.
391
+ * @return [type] [description]
392
+ */
393
+ public function unzip_custom( $source, $destination ) {
394
+ if ( ! $this->exists( $source ) ) {
395
+ $this->add_error( 'zip_source_file_not_exists', sprintf( __( 'Zip source file not exists: %s', 'jupiterx' ), $source ) );
396
+ return false;
397
+ }
398
+
399
+ if ( ! $this->is_file( $source ) ) {
400
+ $this->add_error( 'zip_source_file_not_valid', sprintf( __( 'Zip source file not valid: %s', 'jupiterx' ), $source ) );
401
+ return false;
402
+ }
403
+
404
+ if ( ! $this->is_readable( $source ) ) {
405
+ $this->add_error( 'zip_source_file_not_readable', sprintf( __( 'Zip source file not readable: %s', 'jupiterx' ), $source ) );
406
+ return false;
407
+ }
408
+
409
+ // Check $destination is valid
410
+ if ( ! $this->is_dir( $destination ) ) {
411
+
412
+ // If file exists has same name with $destination, delete it
413
+ if ( $this->exists( $destination ) ) {
414
+ $this->delete( $destination );
415
+ }
416
+
417
+ // Try create new $destination path
418
+ if ( ! $this->mkdir( $destination ) ) {
419
+ $this->add_error( 'fail_create_unzip_destination_directory', sprintf( __( 'Failed to create unzip destination directory: %s', 'jupiterx' ), $destination ) );
420
+ return false;
421
+ }
422
+ }
423
+
424
+ // Check $destination is writable
425
+ if ( ! $this->is_writable( $destination ) ) {
426
+ $this->add_error( 'unzip_destination_not_writable', sprintf( __( 'Unzip destination is not writable: %s', 'jupiterx' ), $destination ) );
427
+ return false;
428
+ }
429
+
430
+ global $wp_filesystem;
431
+
432
+ $wp_filesystem = $this->wp_filesystem;
433
+
434
+ $unzip_file = unzip_file( $source, $destination );
435
+
436
+ if ( is_wp_error( $unzip_file ) ) {
437
+ $this->add_error( $unzip_file->get_error_code(), $unzip_file->get_error_message() );
438
+ return false;
439
+ } elseif ( ! $unzip_file ) {
440
+ $this->add_error( 'failed_unzipping_file', sprintf( __( 'Failed unzipping file: %s', 'jupiterx' ), $source ) );
441
+ return false;
442
+ }
443
+ return true;
444
+ }
445
+
446
+ /**
447
+ * Set options data
448
+ *
449
+ * @param (string) $key
450
+ * @param (string) $value
451
+ * @return void
452
+ */
453
+ public function setOption( $key, $value ) {
454
+ switch ( $key ) {
455
+ case 'context':
456
+ if ( ! empty( $value ) ) {
457
+ $value = is_dir( $value ) ? $value : dirname( $value );
458
+ $value = untrailingslashit( $value );
459
+ }
460
+ break;
461
+ }
462
+ $this->options[ $key ] = $value;
463
+ }
464
+
465
+ /**
466
+ * Get options data
467
+ *
468
+ * @param (string) $key
469
+ * @param (null|string) $default
470
+ * @return mixed
471
+ */
472
+ public function getOption( $key = null, $default = null ) {
473
+ if ( null === $key ) {
474
+ return $this->options;
475
+ } else {
476
+ return isset( $this->options[ $key ] ) ? $this->options[ $key ] : $default;
477
+ }
478
+ }
479
+
480
+ /**
481
+ * Delete options data
482
+ *
483
+ * @param (string) $key
484
+ * @return void
485
+ */
486
+ public function deleteOption( $key ) {
487
+ unset( $this->options[ $key ] );
488
+ }
489
+
490
+ /**
491
+ * Set errors data taken from the wp_filesystem errors
492
+ *
493
+ * @return void
494
+ */
495
+ private function setErrors() {
496
+ if ( isset( $this->wp_filesystem->errors ) && is_wp_error( $this->wp_filesystem->errors ) && $this->wp_filesystem->errors->get_error_code() ) {
497
+ $this->add_error( $this->wp_filesystem->errors->get_error_code(), $this->wp_filesystem->errors->get_error_message() );
498
+ }
499
+ }
500
+
501
+ /**
502
+ * Get current connection method
503
+ *
504
+ * @return mixed
505
+ */
506
+ public function getConnectionMethod() {
507
+ return isset( $this->wp_filesystem->method ) ? $this->wp_filesystem->method : false;
508
+ }
509
+
510
+ /**
511
+ * Get credentials data
512
+ *
513
+ * @return mixed
514
+ */
515
+ public function getCredsData() {
516
+ return $this->creds_data;
517
+ }
518
+
519
+ /**
520
+ * Get all errors
521
+ *
522
+ * @return object Will return the WP_Error object
523
+ */
524
+ public function get_errors() {
525
+ return $this->errors;
526
+ }
527
+
528
+ /**
529
+ * Retrieve all error codes
530
+ *
531
+ * @return array
532
+ */
533
+ public function get_error_codes() {
534
+ return $this->errors->get_error_codes();
535
+ }
536
+
537
+ /**
538
+ * Retrieve first error code available
539
+ *
540
+ * @return string, int or Empty if there is no error codes
541
+ */
542
+ public function get_error_code() {
543
+ return $this->errors->get_error_code();
544
+ }
545
+
546
+ /**
547
+ * Retrieve all error messages or error messages matching code
548
+ *
549
+ * @param (string) $code
550
+ * @return array
551
+ */
552
+ public function get_error_messages( $code = '' ) {
553
+ return $this->errors->get_error_messages( $code );
554
+ }
555
+
556
+ /**
557
+ * Get the first error message available or error message matching code
558
+ *
559
+ * @param (string) $code
560
+ * @return string
561
+ */
562
+ public function get_error_message( $code = '' ) {
563
+ return $this->errors->get_error_message( $code );
564
+ }
565
+
566
+ /**
567
+ * Append more error messages to list of error messages.
568
+ *
569
+ * @param (string) $code
570
+ * @param (string) $message
571
+ * @param (array) $data
572
+ * @return void
573
+ */
574
+ public function add_error( $code, $message, $data = '' ) {
575
+ // Log the error
576
+ if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
577
+ error_log( 'JupiterX_Filesystem Error Code: ' . $code );
578
+ error_log( 'JupiterX_Filesystem Error Message: ' . $message );
579
+ if ( $data && ! is_resource( $data ) ) {
580
+ error_log( 'JupiterX_Filesystem Error Data: ' . wp_json_encode( $data ) );
581
+ }
582
+ }
583
+ $this->errors->add( $code, $message, $data );
584
+ }
585
+
586
+ /**
587
+ * Check path is outside open_basedir paths.
588
+ *
589
+ * @param string $path
590
+ * @return boolean
591
+ */
592
+ public function is_open_basedir_restricted( $path ) {
593
+ $open_basedir_paths = ini_get('open_basedir');
594
+
595
+ if ( empty( $open_basedir_paths ) ) {
596
+ return false;
597
+ }
598
+
599
+ $open_basedir_paths = explode( PATH_SEPARATOR, $open_basedir_paths );
600
+
601
+ foreach ( $open_basedir_paths as $open_basedir_path ) {
602
+ if (
603
+ strpos( $open_basedir_path, $path ) === 0 &&
604
+ $open_basedir_path !== $path
605
+ ) {
606
+ return true;
607
+ }
608
+ }
609
+
610
+ return false;
611
+ }
612
+ }
613
+ }
includes/control-panel/includes/class-helpers.php ADDED
@@ -0,0 +1,506 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! class_exists( 'JupiterX_Control_Panel_Helpers' ) ) {
3
+ /**
4
+ * Helper functions class.
5
+ *
6
+ * @since 1.7.0
7
+ */
8
+ class JupiterX_Control_Panel_Helpers {
9
+
10
+ /**
11
+ * Method that is resposible to unzip compress files .
12
+ * it used native WordPress functions.
13
+ *
14
+ * @since 1.0.0
15
+ * @author Artbees <info@artbees.net>
16
+ *
17
+ * @param str $zip_path compress file absolute path.
18
+ * @param str $dest_path Where should it be uncompressed.
19
+ *
20
+ * @return bool will return boolean status of action
21
+ */
22
+ public static function un_zip( $zip_path, $dest_path ) {
23
+
24
+ $zip_path = realpath( $zip_path );
25
+ $dest_path = realpath( $dest_path );
26
+
27
+ $jupiterx_filesystem = new JupiterX_Filesystem(
28
+ array(
29
+ 'context' => $dest_path,
30
+ )
31
+ );
32
+
33
+ if ( $jupiterx_filesystem->get_error_code() ) {
34
+ throw new Exception( $jupiterx_filesystem->get_error_message() );
35
+ return false;
36
+ }
37
+
38
+ if ( ! $jupiterx_filesystem->exists( $zip_path ) ) {
39
+ throw new Exception( __( 'Zip file that you are looking for is not exist', 'jupiterx' ) );
40
+ return false;
41
+ }
42
+
43
+ if ( ! $jupiterx_filesystem->exists( $dest_path ) ) {
44
+ if ( ! $jupiterx_filesystem->mkdir( $dest_path ) ) {
45
+ throw new Exception( __( 'Unzip destination path not exist', 'jupiterx' ) );
46
+ return false;
47
+ }
48
+ }
49
+
50
+ if ( ! $jupiterx_filesystem->is_writable( $dest_path ) ) {
51
+ throw new Exception( __( 'Unzip destination is not writable , Please resolve this issue first.', 'jupiterx' ) );
52
+ return false;
53
+ }
54
+
55
+ $unzipfile = unzip_file( $zip_path, $dest_path );
56
+ if ( is_wp_error( $unzipfile ) ) {
57
+ throw new Exception( $unzipfile->get_error_message(), 1 );
58
+ return false;
59
+ }
60
+ return true;
61
+ }
62
+ /**
63
+ * You can create a directory using this helper , it will check the dest directory for if its writable or not then
64
+ * try to create new one
65
+ *
66
+ * @since 1.0.0
67
+ * @author Artbees <info@artbees.net>
68
+ *
69
+ * @param str $path path of directory that need to be created.
70
+ * @param int $perm permission of new directory , default is : 0775.
71
+ *
72
+ * @return bool will return boolean status of action , all message is setted to $this->message()
73
+ */
74
+ public static function check_perm_and_create( $path, $perm = 0775 ) {
75
+
76
+ $jupiterx_filesystem = new JupiterX_Filesystem(
77
+ array(
78
+ 'context' => $path,
79
+ )
80
+ );
81
+
82
+ if ( $jupiterx_filesystem->get_error_code() ) {
83
+ throw new Exception( $jupiterx_filesystem->get_error_message() );
84
+ return false;
85
+ }
86
+
87
+ if ( $jupiterx_filesystem->exists( $path ) ) {
88
+ if ( ! $jupiterx_filesystem->is_writable( $path ) ) {
89
+ throw new Exception( sprintf( __( '%s directory is not writable', 'jupiterx' ), $path ) );
90
+ return false;
91
+ }
92
+ return true;
93
+ } else {
94
+ if ( ! $jupiterx_filesystem->mkdir( $path, $perm ) ) {
95
+ throw new Exception( sprintf( __( 'Can\'t create directory %s', 'jupiterx' ), $path ) );
96
+ return false;
97
+ }
98
+ return true;
99
+ }
100
+ }
101
+ /**
102
+ * This method is resposible to download file from url and save it on server.
103
+ * it will check if curl is available or not and then decide to use curl or file_get_content
104
+ *
105
+ * @since 1.0.0
106
+ * @author Artbees <info@artbees.net>
107
+ *
108
+ * @param string $url url of file (http://yahoo.com/test-plugin.zip).
109
+ * @param string $file_name name of the fire that should be create at destination directory.
110
+ * @param string $dest_directory absolute path of directory that file save on it.
111
+ *
112
+ * @return bool will return action status
113
+ */
114
+ public static function upload_from_url( $url, $file_name, $dest_directory, $remote_args = [] ) {
115
+ set_time_limit( 0 );
116
+
117
+ try {
118
+ self::check_perm_and_create( $dest_directory );
119
+ } catch ( Exception $e ) {
120
+ throw new Exception( sprintf( __( 'Destination directory is not ready for upload . {%s}', 'jupiterx' ), $dest_directory ) );
121
+ return false;
122
+ }
123
+
124
+
125
+ $response = wp_remote_get( $url, array_merge( [ 'timeout' => 120 ], $remote_args ) );
126
+
127
+ if ( is_wp_error( $response ) ) {
128
+ throw new Exception( $response->get_error_message() );
129
+ return false;
130
+ }
131
+
132
+ $response_body = wp_remote_retrieve_body( $response );
133
+
134
+ if ( is_wp_error( $response_body ) ) {
135
+ throw new Exception( $response_body->get_error_message() );
136
+ return false;
137
+ }
138
+
139
+ $jupiterx_filesystem = new JupiterX_Filesystem(
140
+ array(
141
+ 'context' => $dest_directory,
142
+ )
143
+ );
144
+
145
+ if ( $jupiterx_filesystem->get_error_code() ) {
146
+ throw new Exception( $jupiterx_filesystem->get_error_message() );
147
+ return false;
148
+ }
149
+
150
+ if ( ! $jupiterx_filesystem->put_contents( $dest_directory . $file_name, $response_body ) ) {
151
+ throw new Exception( sprintf( __( "Can't write file to {%s}", 'jupiterx' ), $dest_directory . $file_name ) );
152
+ return false;
153
+ }
154
+
155
+ return $dest_directory . $file_name;
156
+ }
157
+
158
+ /**
159
+ * This method is resposible to delete a directory or file.
160
+ * if the path is pointing to a directory it will remove all the includes file recursivly and then remove directory at last step
161
+ * if the path is pointing to a file it will remove it
162
+ *
163
+ * @since 1.0.0
164
+ * @author Artbees <info@artbees.net>
165
+ *
166
+ * @param str $dir for example (/var/www/jupiter/wp-content/plugins).
167
+ *
168
+ * @return bool true or false
169
+ */
170
+ public static function delete_file_and_dir( $dir ) {
171
+
172
+ if ( empty( $dir ) == true || strlen( $dir ) < 2 ) {
173
+ return false;
174
+ }
175
+
176
+ $dir = realpath( $dir );
177
+
178
+ $jupiterx_filesystem = new JupiterX_Filesystem(
179
+ array(
180
+ 'context' => $dir,
181
+ )
182
+ );
183
+
184
+ if ( $jupiterx_filesystem->get_error_code() ) {
185
+ return false;
186
+ }
187
+
188
+ if ( ! $jupiterx_filesystem->exists( $dir ) ) {
189
+ return true;
190
+ }
191
+
192
+ if ( $jupiterx_filesystem->is_dir( $dir ) ) {
193
+ return $jupiterx_filesystem->rmdir( $dir, true );
194
+ } else {
195
+ return $jupiterx_filesystem->delete( $dir );
196
+ }
197
+
198
+ }
199
+
200
+
201
+ /**
202
+ * Prevents cache.
203
+ * Deletes cache files and transients.
204
+ *
205
+ * @since 1.0.0
206
+ */
207
+
208
+ public static function prevent_cache_plugins() {
209
+ if ( function_exists( 'w3tc_pgcache_flush' ) ) {
210
+ w3tc_pgcache_flush();
211
+ // W3 Total Cache: Page cache flushed.
212
+ } elseif ( function_exists( 'wp_cache_clear_cache' ) ) {
213
+ wp_cache_clear_cache();
214
+ // WP Super Cache: Page cache cleared.
215
+ } elseif ( function_exists( 'rocket_clean_domain' ) ) {
216
+ rocket_clean_domain();
217
+ // WP Rocket: Domain cache purged.
218
+ }
219
+
220
+ if ( ! defined( 'DONOTCACHEPAGE' ) ) {
221
+ define( 'DONOTCACHEPAGE', true );
222
+ }
223
+
224
+ if ( ! defined( 'DONOTCACHCEOBJECT' ) ) {
225
+ define( 'DONOTCACHCEOBJECT', true );
226
+ }
227
+
228
+ if ( ! defined( 'DONOTMINIFY' ) ) {
229
+ define( 'DONOTMINIFY', true );
230
+ }
231
+
232
+ if ( ! defined( 'DONOTCACHEDB' ) ) {
233
+ define( 'DONOTCACHEDB', true );
234
+ }
235
+
236
+ if ( ! defined( 'DONOTCDN' ) ) {
237
+ define( 'DONOTCDN', true );
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Safely and securely get file from server.
243
+ * It attempts to read file using WordPress native file read functions
244
+ * If it fails, we use wp_remote_get. if the site is ssl enabled, we try to convert it http as some servers may fail to get file
245
+ *
246
+ * @author Artbees <info@artbees.net>
247
+ *
248
+ * @param $file_url string its directory URL.
249
+ * @param $file_dir string its directory Path.
250
+ *
251
+ * @return $wp_file_body string
252
+ */
253
+ public static function getFileBody( $file_uri, $file_dir ) {
254
+
255
+ $wp_remote_get_file_body = '';
256
+ $file_dir = realpath( $file_dir );
257
+
258
+ $jupiterx_filesystem = new JupiterX_Filesystem(
259
+ array(
260
+ 'context' => $file_dir,
261
+ )
262
+ );
263
+
264
+ if ( $jupiterx_filesystem->get_error_code() ) {
265
+ throw new Exception( $jupiterx_filesystem->get_error_message() );
266
+ return false;
267
+ }
268
+
269
+ $wp_get_file_body = $jupiterx_filesystem->get_contents( $file_dir );
270
+ if ( false == $wp_get_file_body ) {
271
+ $wp_remote_get_file = wp_remote_get( $file_uri );
272
+
273
+ if ( is_array( $wp_remote_get_file ) && array_key_exists( 'body', $wp_remote_get_file ) ) {
274
+ $wp_remote_get_file_body = $wp_remote_get_file['body'];
275
+
276
+ } elseif ( is_numeric( strpos( $file_uri, 'https://' ) ) ) {
277
+
278
+ $file_uri = str_replace( 'https://', 'http://', $file_uri );
279
+ $wp_remote_get_file = wp_remote_get( $file_uri );
280
+
281
+ if ( ! is_array( $wp_remote_get_file ) || ! array_key_exists( 'body', $wp_remote_get_file ) ) {
282
+ throw new Exception( __( 'SSL connection error. Code: template-assets-get', 'jupiterx' ) );
283
+ return false;
284
+ }
285
+
286
+ $wp_remote_get_file_body = $wp_remote_get_file['body'];
287
+ }
288
+
289
+ $wp_file_body = $wp_remote_get_file_body;
290
+
291
+ } else {
292
+ $wp_file_body = $wp_get_file_body;
293
+ }
294
+ return $wp_file_body;
295
+ }
296
+
297
+ /**
298
+ * Check if the request is done through a localhost.
299
+ *
300
+ * @author Artbees <info@artbees.net>
301
+ *
302
+ * @return boolean
303
+ */
304
+ public static function is_localhost() {
305
+ return ('127.0.0.1' == $_SERVER['REMOTE_ADDR'] || 'localhost' == $_SERVER['REMOTE_ADDR'] || '::1' == $_SERVER['REMOTE_ADDR']) ? 1 : 0;
306
+ }
307
+
308
+ /**
309
+ * Convert alphabetical bit size to numericals
310
+ *
311
+ * @author Artbees <info@artbees.net>
312
+ *
313
+ * @return number
314
+ */
315
+ public static function let_to_num( $size ) {
316
+ $l = substr( $size, -1 );
317
+ $ret = substr( $size, 0, -1 );
318
+
319
+ switch ( strtoupper( $l ) ) {
320
+ case 'P':
321
+ $ret *= 1024;
322
+ case 'T':
323
+ $ret *= 1024;
324
+ case 'G':
325
+ $ret *= 1024;
326
+ case 'M':
327
+ $ret *= 1024;
328
+ case 'K':
329
+ $ret *= 1024;
330
+ }
331
+
332
+ return $ret;
333
+ }
334
+
335
+ /**
336
+ * Convert boolean value to a string value (e.g. from true to 'true')
337
+ *
338
+ * @author Artbees <info@artbees.net>
339
+ *
340
+ * @return String
341
+ */
342
+ public static function make_bool_string( $var ) {
343
+ if ( false == $var || 'false' == $var || 0 == $var || '0' == $var || '' == $var || empty( $var ) ) {
344
+ return 'false';
345
+ }
346
+ return 'true';
347
+ }
348
+
349
+ /**
350
+ * It will create a compress file from list of files
351
+ *
352
+ * @author Artbees <info@artbees.net>
353
+ *
354
+ * @param array $files for example : array('preload-images/5.jpg','kwicks/ringo.gif','rod.jpg','reddit.gif');.
355
+ * @param string $destination name of the file or full address of destination for example : my-archive.zip.
356
+ * @param boolean $overwrite if destionation exist , should it overwrite the compress file ?.
357
+ *
358
+ * @return boolean true if completed and false if something goes wrong
359
+ */
360
+ public static function zip( $files = array(), $destination = '', $overwrite = false ) {
361
+
362
+ $jupiterx_filesystem = new JupiterX_Filesystem(
363
+ array(
364
+ 'context' => $destination,
365
+ )
366
+ );
367
+
368
+ if ( $jupiterx_filesystem->get_error_code() ) {
369
+ return false;
370
+ }
371
+
372
+ // if the zip file already exists and overwrite is false, return false.
373
+ if ( $jupiterx_filesystem->exists( $destination ) && ! $overwrite ) {
374
+ return false;
375
+ }
376
+
377
+ $valid_files = array();
378
+
379
+ // if files were passed in...
380
+ if ( is_array( $files ) ) {
381
+ // cycle through each file.
382
+ foreach ( $files as $file_name => $file_path ) {
383
+ // make sure the file exists.
384
+ if ( $jupiterx_filesystem->exists( $file_path ) ) {
385
+ $valid_files[ $file_name ] = $file_path;
386
+ }
387
+ }
388
+ }
389
+ // if we have good files...
390
+ if ( count( $valid_files ) ) {
391
+
392
+ $temp_file = tempnam( sys_get_temp_dir(), 'zip' );
393
+
394
+ if ( class_exists( 'ZipArchive', false ) ) {
395
+ $zip = new ZipArchive();
396
+
397
+ // Try open the temp file.
398
+ $zip->open( $temp_file );
399
+
400
+ // add the files to archive.
401
+ foreach ( $valid_files as $file_name => $file_path ) {
402
+ $zip->addFile( $file_path, $file_name );
403
+ }
404
+
405
+ // close the zip -- done!
406
+ $zip->close();
407
+
408
+ } else {
409
+
410
+ mbstring_binary_safe_encoding();
411
+
412
+ require_once ABSPATH . 'wp-admin/includes/class-pclzip.php';
413
+
414
+ $zip = new PclZip( $temp_file );
415
+
416
+ foreach ( $valid_files as $file_name => $file_path ) {
417
+ $zip->create( $file_path, $file_name );
418
+ }
419
+
420
+ reset_mbstring_encoding();
421
+ }
422
+
423
+ // add the files to archive.
424
+ foreach ( $valid_files as $file_name => $file_path ) {
425
+ $zip->addFile( $file_path, $file_name );
426
+ }
427
+
428
+ // debug
429
+ // echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status;
430
+ // close the zip -- done!
431
+ $zip->close();
432
+
433
+ // Copy the temp file to destination.
434
+ $jupiterx_filesystem->copy( $temp_file, $destination, true, 0644 );
435
+
436
+ // Try delete the temp file.
437
+ $jupiterx_filesystem->delete( $temp_file );
438
+
439
+ // check to make sure the file exists.
440
+ return $jupiterx_filesystem->exists( $destination );
441
+
442
+ }
443
+ return false;
444
+ }
445
+
446
+ public static function search_multdim( $array, $key, $value ) {
447
+ return (array_search( $value, array_column( $array, $key ) ));
448
+ }
449
+ /**
450
+ * It will check wether wordpress-importer plugin is exist in plugin directory or not.
451
+ * if exist it will return the WordPress importer file
452
+ * if not it will use jupiter version
453
+ *
454
+ * @author Artbees <info@artbees.net>
455
+ * @copyright Artbees LTD (c)
456
+ * @link https://artbees.net
457
+ * @since Version 5.5
458
+ */
459
+ public static function include_wordpress_importer() {
460
+
461
+ if ( ! class_exists( 'WP_Importer' ) ) {
462
+ defined( 'WP_LOAD_IMPORTERS' ) || define( 'WP_LOAD_IMPORTERS', true );
463
+ include ABSPATH . '/wp-admin/includes/class-wp-importer.php';
464
+ }
465
+
466
+ if ( ! class_exists( 'WXR_Importer' ) ) {
467
+ include JUPITERX_CONTROL_PANEL_PATH . 'includes/importer/class-logger.php';
468
+ include JUPITERX_CONTROL_PANEL_PATH . 'includes/importer/class-logger-serversentevents.php';
469
+ include JUPITERX_CONTROL_PANEL_PATH . 'includes/importer/class-wxr-import-info.php';
470
+ include JUPITERX_CONTROL_PANEL_PATH . 'includes/importer/class-wxr-importer.php';
471
+ }
472
+
473
+ if ( ! class_exists( 'JupiterX_Importer' ) ) {
474
+ include JUPITERX_CONTROL_PANEL_PATH . 'includes/importer/class-jupiterx-importer.php';
475
+ }
476
+
477
+ return true;
478
+ }
479
+ /**
480
+ * It will return permission of directory
481
+ *
482
+ * @author Artbees <info@artbees.net>
483
+ *
484
+ * @param string $path Full path of directory.
485
+ *
486
+ * @return int
487
+ */
488
+ public static function get_perm( $path ) {
489
+ return substr( sprintf( '%o', fileperms( ABSPATH . $path ) ), -4 );
490
+ }
491
+
492
+ /**
493
+ * Convert Bytes to MegaBytes.
494
+ *
495
+ * @access public
496
+ * @static
497
+ * @since 1.10.0
498
+ *
499
+ * @param [type] $bytes
500
+ * @return void
501
+ */
502
+ public static function bytes_to_mb( $bytes ) {
503
+ return round( $bytes / ( 1024 * 1024 ), 2 );
504
+ }
505
+ }
506
+ }
includes/control-panel/install-template.php CHANGED
@@ -644,7 +644,9 @@ if ( ! class_exists( 'JupiterX_Control_Panel_Install_Template' ) ) {
644
 
645
  $template_plugins[] = 'advanced-custom-fields';
646
 
647
- $template_plugins = array_diff( $template_plugins, ['jupiterx-pro'] );
 
 
648
 
649
  foreach ( $template_plugins as $slug ) {
650
 
@@ -685,8 +687,6 @@ if ( ! class_exists( 'JupiterX_Control_Panel_Install_Template' ) ) {
685
 
686
  $template_plugins[] = 'advanced-custom-fields';
687
 
688
- $template_plugins = array_diff( $template_plugins, ['jupiterx-pro'] );
689
-
690
  $actions['activate'] = [
691
  'url' => $tgmpa_url,
692
  'plugin' => $template_plugins,
644
 
645
  $template_plugins[] = 'advanced-custom-fields';
646
 
647
+ $template_plugins = array_diff( $template_plugins, ['jupiterx-pro', 'advanced-custom-fields-pro'] );
648
+
649
+ $template_plugins[] = 'advanced-custom-fields';
650
 
651
  foreach ( $template_plugins as $slug ) {
652
 
687
 
688
  $template_plugins[] = 'advanced-custom-fields';
689
 
 
 
690
  $actions['activate'] = [
691
  'url' => $tgmpa_url,
692
  'plugin' => $template_plugins,
includes/control-panel/views/settings.php CHANGED
@@ -41,6 +41,25 @@ if ( ! JUPITERX_CONTROL_PANEL_SETTINGS ) {
41
  <small class="form-text text-muted"><?php esc_html_e( 'Enable cache busting technique.', 'jupiterx-core' ); ?></small>
42
  </div>
43
  <?php do_action( 'jupiterx_control_panel_after_theme_settings' ); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  <?php if ( jupiterx_is_premium() && class_exists( 'Jupiter_Donut' ) ) : ?>
45
  <div class="col-md-12"><hr></div>
46
  <h5 class="col-md-12 mb-3">Donut Plugin</h5>
41
  <small class="form-text text-muted"><?php esc_html_e( 'Enable cache busting technique.', 'jupiterx-core' ); ?></small>
42
  </div>
43
  <?php do_action( 'jupiterx_control_panel_after_theme_settings' ); ?>
44
+ <div class="col-md-12"><hr></div>
45
+ <div class="form-group col-md-12">
46
+ <label class="m-0"><?php esc_html_e( 'Custom Post Types', 'jupiterx-core' ); ?></label>
47
+ <small class="form-text text-muted mb-2"><?php esc_html_e( 'Enable Jupiter features (customizer, meta options, etc.) for these post types.', 'jupiterx-core' ); ?></small>
48
+ <input type="hidden" name="jupiterx_post_types" value="">
49
+ <?php $post_types = jupiterx_get_custom_post_types( 'objects' ); ?>
50
+ <?php if ( ! empty( $post_types ) ) : ?>
51
+ <?php foreach ( $post_types as $id => $post_type ) : ?>
52
+ <?php echo '<div class="custom-control custom-checkbox">'; ?>
53
+ <?php echo '<input type="checkbox" class="custom-control-input" name="jupiterx_post_types[]" ' . ( ( in_array( $post_type->name, get_option( 'jupiterx_post_types' ), true ) ) ? 'checked="checked"' : '' ) . ' value="' . esc_attr( $post_type->name ) . '" id="jupiterx_post_type_' . esc_attr( $post_type->name ) . '">'; ?>
54
+ <?php echo '<label class="custom-control-label" for="jupiterx_post_type_' . esc_attr( $post_type->name ) . '">' . $post_type->label . '</label>'; ?>
55
+ <?php echo '</div>'; ?>
56
+ <?php endforeach; ?>
57
+ <?php else : ?>
58
+ <div class="jupiterx-settings-no-post-type">
59
+ <i class="jupiterx-icon-info-circle"></i><?php esc_html_e( 'No custom post type was found.', 'jupiterx-core' ); ?>
60
+ </div>
61
+ <?php endif; ?>
62
+ </div>
63
  <?php if ( jupiterx_is_premium() && class_exists( 'Jupiter_Donut' ) ) : ?>
64
  <div class="col-md-12"><hr></div>
65
  <h5 class="col-md-12 mb-3">Donut Plugin</h5>
includes/dashboard/widgets/class-overview.php CHANGED
@@ -251,9 +251,9 @@ class JupiterX_Overview_Widget {
251
 
252
  if ( function_exists( 'jupiterx_is_pro' ) && ! jupiterx_is_pro() ) {
253
  $links['upgrade'] = [
254
- 'title' => esc_html__( 'Upgrade', 'jupiterx-core' ),
255
- 'link' => add_query_arg( 'page', 'jupiterx_upgrade', admin_url() ),
256
- 'class' => 'jupiterx-upgrade-modal-trigger',
257
  ];
258
  }
259
 
@@ -262,7 +262,7 @@ class JupiterX_Overview_Widget {
262
  <ul>
263
  <?php foreach ( $links as $link_slug => $link ) : ?>
264
  <li class="jupiterx-admin-widget-overview-footer-<?php echo esc_attr( $link_slug ); ?>">
265
- <a href="<?php echo esc_url( $link['link'] ); ?>" <?php echo isset( $link['class'] ) ? 'class="' . esc_attr( $link['class'] ) . '"' : ''; ?> <?php echo isset( $link['target'] ) ? 'target="' . esc_attr( $link['target'] ) . '"' : ''; ?> data-upgrade-link="https://themeforest.net/item/jupiter-multipurpose-responsive-theme/5177775?ref=artbees&utm_source=DashboardNewsUpdatesWidgetUpgradeLink&utm_medium=AdminUpgradePopup&utm_campaign=FreeJupiterXAdminUpgradeCampaign">
266
  <?php echo esc_html( $link['title'] ); ?>
267
  <span class="screen-reader-text"><?php esc_html_e( '(opens in a new window)', 'jupiterx-core' ); ?></span>
268
  <span aria-hidden="true" class="dashicons dashicons-external"></span>
251
 
252
  if ( function_exists( 'jupiterx_is_pro' ) && ! jupiterx_is_pro() ) {
253
  $links['upgrade'] = [
254
+ 'title' => __( 'Upgrade', 'jupiterx-core' ),
255
+ 'link' => 'https://themeforest.net/item/jupiter-multipurpose-responsive-theme/5177775?ref=artbees&utm_source=DashboardNewsUpdatesWidgetUpgradeLink&utm_medium=AdminUpgradePopup&utm_campaign=FreeJupiterXAdminUpgradeCampaign',
256
+ 'target' => '_blank',
257
  ];
258
  }
259
 
262
  <ul>
263
  <?php foreach ( $links as $link_slug => $link ) : ?>
264
  <li class="jupiterx-admin-widget-overview-footer-<?php echo esc_attr( $link_slug ); ?>">
265
+ <a href="<?php echo esc_url( $link['link'] ); ?>" <?php echo isset( $link['class'] ) ? 'class="' . esc_attr( $link['class'] ) . '"' : ''; ?> <?php echo isset( $link['target'] ) ? 'target="' . esc_attr( $link['target'] ) . '"' : ''; ?>>
266
  <?php echo esc_html( $link['title'] ); ?>
267
  <span class="screen-reader-text"><?php esc_html_e( '(opens in a new window)', 'jupiterx-core' ); ?></span>
268
  <span aria-hidden="true" class="dashicons dashicons-external"></span>
jupiterx-core.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Jupiter X Core
4
  * Plugin URI: https://jupiterx.com
5
  * Description: Jupiter X Core
6
- * Version: 1.6.1
7
  * Author: Artbees
8
  * Author URI: https://artbees.net
9
  * Text Domain: jupiterx-core
3
  * Plugin Name: Jupiter X Core
4
  * Plugin URI: https://jupiterx.com
5
  * Description: Jupiter X Core
6
+ * Version: 1.8.0
7
  * Author: Artbees
8
  * Author URI: https://artbees.net
9
  * Text Domain: jupiterx-core
languages/jupiterx-core.pot CHANGED
@@ -85,51 +85,51 @@ msgstr ""
85
  msgid "Settings saved successfully."
86
  msgstr ""
87
 
88
- #: includes/control-panel/functions.php:28
89
  msgid "Get started:"
90
  msgstr ""
91
 
92
- #: includes/control-panel/functions.php:42
93
  msgid "SVG Support"
94
  msgstr ""
95
 
96
- #: includes/control-panel/functions.php:50
97
  msgid "Enable this option to upload SVG to WordPress Media Library."
98
  msgstr ""
99
 
100
- #: includes/control-panel/functions.php:57
101
  msgid "Google Analytics ID"
102
  msgstr ""
103
 
104
- #: includes/control-panel/functions.php:58
105
  msgid "Adding Google Analytics code into Jupiter X"
106
  msgstr ""
107
 
108
- #: includes/control-panel/functions.php:62
109
  msgid "IP Anonymization"
110
  msgstr ""
111
 
112
- #: includes/control-panel/functions.php:68
113
  msgid "Enable IP Anonymization for Google Analytics."
114
  msgstr ""
115
 
116
- #: includes/control-panel/functions.php:71
117
  msgid "Adobe Fonts Project ID"
118
  msgstr ""
119
 
120
- #: includes/control-panel/functions.php:72
121
  msgid "Using Adobe fonts (formerly Typekit) in Jupiter X"
122
  msgstr ""
123
 
124
  #. translators: %s: html
125
  #. translators: %s: html
126
- #: includes/control-panel/functions.php:80, includes/control-panel/functions.php:96
127
  msgid "Tracking Codes After %s Tag"
128
  msgstr ""
129
 
130
  #. translators: %s: html
131
  #. translators: %s: html
132
- #: includes/control-panel/functions.php:88, includes/control-panel/functions.php:104
133
  msgid "Tracking Codes Before %s Tag"
134
  msgstr ""
135
 
@@ -716,39 +716,51 @@ msgstr ""
716
  msgid "Enable cache busting technique."
717
  msgstr ""
718
 
719
- #: includes/control-panel/views/settings.php:48
 
 
 
 
 
 
 
 
 
 
 
 
720
  msgid "Twitter Consumer Key"
721
  msgstr ""
722
 
723
- #: includes/control-panel/views/settings.php:52
724
  msgid "Twitter Consumer Secret"
725
  msgstr ""
726
 
727
- #: includes/control-panel/views/settings.php:56
728
  msgid "Twitter Access Token"
729
  msgstr ""
730
 
731
- #: includes/control-panel/views/settings.php:60
732
  msgid "Twitter Access Token Secret"
733
  msgstr ""
734
 
735
- #: includes/control-panel/views/settings.php:64
736
  msgid "MailChimp API Key"
737
  msgstr ""
738
 
739
- #: includes/control-panel/views/settings.php:68
740
  msgid "Mailchimp List ID"
741
  msgstr ""
742
 
743
- #: includes/control-panel/views/settings.php:72
744
  msgid "Google Maps API Key"
745
  msgstr ""
746
 
747
- #: includes/control-panel/views/settings.php:78
748
  msgid "Save Settings"
749
  msgstr ""
750
 
751
- #: includes/control-panel/views/settings.php:79
752
  msgid "Saving..."
753
  msgstr ""
754
 
85
  msgid "Settings saved successfully."
86
  msgstr ""
87
 
88
+ #: includes/control-panel/functions.php:30
89
  msgid "Get started:"
90
  msgstr ""
91
 
92
+ #: includes/control-panel/functions.php:44
93
  msgid "SVG Support"
94
  msgstr ""
95
 
96
+ #: includes/control-panel/functions.php:52
97
  msgid "Enable this option to upload SVG to WordPress Media Library."
98
  msgstr ""
99
 
100
+ #: includes/control-panel/functions.php:59
101
  msgid "Google Analytics ID"
102
  msgstr ""
103
 
104
+ #: includes/control-panel/functions.php:60
105
  msgid "Adding Google Analytics code into Jupiter X"
106
  msgstr ""
107
 
108
+ #: includes/control-panel/functions.php:64
109
  msgid "IP Anonymization"
110
  msgstr ""
111
 
112
+ #: includes/control-panel/functions.php:70
113
  msgid "Enable IP Anonymization for Google Analytics."
114
  msgstr ""
115
 
116
+ #: includes/control-panel/functions.php:73
117
  msgid "Adobe Fonts Project ID"
118
  msgstr ""
119
 
120
+ #: includes/control-panel/functions.php:74
121
  msgid "Using Adobe fonts (formerly Typekit) in Jupiter X"
122
  msgstr ""
123
 
124
  #. translators: %s: html
125
  #. translators: %s: html
126
+ #: includes/control-panel/functions.php:82, includes/control-panel/functions.php:98
127
  msgid "Tracking Codes After %s Tag"
128
  msgstr ""
129
 
130
  #. translators: %s: html
131
  #. translators: %s: html
132
+ #: includes/control-panel/functions.php:90, includes/control-panel/functions.php:106
133
  msgid "Tracking Codes Before %s Tag"
134
  msgstr ""
135
 
716
  msgid "Enable cache busting technique."
717
  msgstr ""
718
 
719
+ #: includes/control-panel/views/settings.php:46
720
+ msgid "Custom Post Types"
721
+ msgstr ""
722
+
723
+ #: includes/control-panel/views/settings.php:47
724
+ msgid "Enable Jupiter features (customizer, meta options, etc.) for these post types."
725
+ msgstr ""
726
+
727
+ #: includes/control-panel/views/settings.php:59
728
+ msgid "No custom post type was found."
729
+ msgstr ""
730
+
731
+ #: includes/control-panel/views/settings.php:67
732
  msgid "Twitter Consumer Key"
733
  msgstr ""
734
 
735
+ #: includes/control-panel/views/settings.php:71
736
  msgid "Twitter Consumer Secret"
737
  msgstr ""
738
 
739
+ #: includes/control-panel/views/settings.php:75
740
  msgid "Twitter Access Token"
741
  msgstr ""
742
 
743
+ #: includes/control-panel/views/settings.php:79
744
  msgid "Twitter Access Token Secret"
745
  msgstr ""
746
 
747
+ #: includes/control-panel/views/settings.php:83
748
  msgid "MailChimp API Key"
749
  msgstr ""
750
 
751
+ #: includes/control-panel/views/settings.php:87
752
  msgid "Mailchimp List ID"
753
  msgstr ""
754
 
755
+ #: includes/control-panel/views/settings.php:91
756
  msgid "Google Maps API Key"
757
  msgstr ""
758
 
759
+ #: includes/control-panel/views/settings.php:97
760
  msgid "Save Settings"
761
  msgstr ""
762
 
763
+ #: includes/control-panel/views/settings.php:98
764
  msgid "Saving..."
765
  msgstr ""
766
 
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: artbees
3
  Tags: jupiter, jupiterx
4
  Requires at least: 4.7
5
  Tested up to: 5.2
6
- Stable tag: 1.6.1
7
  Requires PHP: 5.6
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
@@ -20,6 +20,10 @@ Core functionalities for Jupiter X theme.
20
  2. Activate the plugin through the 'Plugins' menu in WordPress.
21
 
22
  == Changelog ==
 
 
 
 
23
 
24
- = 1.0.0 =
25
  * Initial release
3
  Tags: jupiter, jupiterx
4
  Requires at least: 4.7
5
  Tested up to: 5.2
6
+ Stable tag: 1.8.0
7
  Requires PHP: 5.6
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
20
  2. Activate the plugin through the 'Plugins' menu in WordPress.
21
 
22
  == Changelog ==
23
+
24
+ = 1.7.0 =
25
+ * Template installation improvement.
26
+ * Dashboard widget improvement.
27
 
28
+ = 1.7.0 =
29
  * Initial release