Duplicator – WordPress Migration Plugin - Version 1.3.40.1

Version Description

Download this release

Release Info

Developer cory@lamle.org
Plugin Icon 128x128 Duplicator – WordPress Migration Plugin
Version 1.3.40.1
Comparing to
See all releases

Code changes from version 1.3.40 to 1.3.40.1

define.php CHANGED
@@ -5,8 +5,8 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
5
 
6
  if (function_exists('plugin_dir_url'))
7
  {
8
- define('DUPLICATOR_VERSION', '1.3.40');
9
- define('DUPLICATOR_VERSION_BUILD', '2020-11-14_09:00');
10
  define('DUPLICATOR_PLUGIN_URL', plugin_dir_url(__FILE__));
11
  define('DUPLICATOR_SITE_URL', get_site_url());
12
 
5
 
6
  if (function_exists('plugin_dir_url'))
7
  {
8
+ define('DUPLICATOR_VERSION', '1.3.40.1');
9
+ define('DUPLICATOR_VERSION_BUILD', '2020-12-14_09:00');
10
  define('DUPLICATOR_PLUGIN_URL', plugin_dir_url(__FILE__));
11
  define('DUPLICATOR_SITE_URL', get_site_url());
12
 
duplicator.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Duplicator
4
  Plugin URI: https://snapcreek.com/duplicator/duplicator-free/
5
  Description: Migrate and backup a copy of your WordPress files and database. Duplicate and move a site from one location to another quickly.
6
- Version: 1.3.40
7
  Author: Snap Creek
8
  Author URI: http://www.snapcreek.com/duplicator/
9
  Text Domain: duplicator
3
  Plugin Name: Duplicator
4
  Plugin URI: https://snapcreek.com/duplicator/duplicator-free/
5
  Description: Migrate and backup a copy of your WordPress files and database. Duplicate and move a site from one location to another quickly.
6
+ Version: 1.3.40.1
7
  Author: Snap Creek
8
  Author URI: http://www.snapcreek.com/duplicator/
9
  Text Domain: duplicator
installer/dup-installer/classes/utilities/class.u.notices.manager.php CHANGED
@@ -1,1251 +1,1252 @@
1
- <?php
2
- /**
3
- * Notice manager
4
- *
5
- * Standard: PSR-2
6
- * @link http://www.php-fig.org/psr/psr-2 Full Documentation
7
- *
8
- * @package SC\DUPX\U
9
- *
10
- */
11
- defined('ABSPATH') || defined('DUPXABSPATH') || exit;
12
-
13
- /**
14
- * Notice manager
15
- * singleton class
16
- */
17
- final class DUPX_NOTICE_MANAGER
18
- {
19
- const ADD_NORMAL = 0; // add notice in list
20
- const ADD_UNIQUE = 1; // add if unique id don't exists
21
- const ADD_UNIQUE_UPDATE = 2; // add or update notice unique id
22
- const ADD_UNIQUE_APPEND = 3; // append long msg
23
- const ADD_UNIQUE_APPEND_IF_EXISTS = 4; // append long msg if already exists item
24
- const ADD_UNIQUE_PREPEND = 5; // append long msg
25
- const ADD_UNIQUE_PREPEND_IF_EXISTS = 6; // prepend long msg if already exists item
26
- const DEFAULT_UNIQUE_ID_PREFIX = '__auto_unique_id__';
27
-
28
- private static $uniqueCountId = 0;
29
-
30
- /**
31
- *
32
- * @var DUPX_NOTICE_ITEM[]
33
- */
34
- private $nextStepNotices = array();
35
-
36
- /**
37
- *
38
- * @var DUPX_NOTICE_ITEM[]
39
- */
40
- private $finalReporNotices = array();
41
-
42
- /**
43
- *
44
- * @var DUPX_NOTICE_MANAGER
45
- */
46
- private static $instance = null;
47
-
48
- /**
49
- *
50
- * @var string
51
- */
52
- private $persistanceFile = null;
53
-
54
- /**
55
- *
56
- * @return DUPX_S_R_MANAGER
57
- */
58
- public static function getInstance()
59
- {
60
- if (is_null(self::$instance)) {
61
- self::$instance = new self();
62
- }
63
-
64
- return self::$instance;
65
- }
66
-
67
- private function __construct()
68
- {
69
- $this->persistanceFile = $GLOBALS["NOTICES_FILE_PATH"];
70
- $this->loadNotices();
71
- }
72
-
73
- /**
74
- * save notices from json file
75
- */
76
- public function saveNotices()
77
- {
78
- $notices = array(
79
- 'globalData' => array(
80
- 'uniqueCountId' => self::$uniqueCountId
81
- ),
82
- 'nextStep' => array(),
83
- 'finalReport' => array()
84
- );
85
-
86
- foreach ($this->nextStepNotices as $uniqueId => $notice) {
87
- $notices['nextStep'][$uniqueId] = $notice->toArray();
88
- }
89
-
90
- foreach ($this->finalReporNotices as $uniqueId => $notice) {
91
- $notices['finalReport'][$uniqueId] = $notice->toArray();
92
- }
93
-
94
- file_put_contents($this->persistanceFile, DupLiteSnapJsonU::wp_json_encode_pprint($notices));
95
- }
96
-
97
- /**
98
- * load notice from json file
99
- */
100
- private function loadNotices()
101
- {
102
- if (file_exists($this->persistanceFile)) {
103
- $json = file_get_contents($this->persistanceFile);
104
- $notices = json_decode($json, true);
105
-
106
- $this->nextStepNotices = array();
107
- $this->finalReporNotices = array();
108
-
109
- if (!empty($notices['nextStep'])) {
110
- foreach ($notices['nextStep'] as $uniqueId => $notice) {
111
- $this->nextStepNotices[$uniqueId] = DUPX_NOTICE_ITEM::getItemFromArray($notice);
112
- }
113
- }
114
-
115
- if (!empty($notices['finalReport'])) {
116
- foreach ($notices['finalReport'] as $uniqueId => $notice) {
117
- $this->finalReporNotices[$uniqueId] = DUPX_NOTICE_ITEM::getItemFromArray($notice);
118
- }
119
- }
120
-
121
- self::$uniqueCountId = $notices['globalData']['uniqueCountId'];
122
- } else {
123
- $this->resetNotices();
124
- }
125
- }
126
-
127
- /**
128
- * remove all notices and save reset file
129
- */
130
- public function resetNotices()
131
- {
132
- $this->nextStepNotices = array();
133
- $this->finalReporNotices = array();
134
- self::$uniqueCountId = 0;
135
- $this->saveNotices();
136
- }
137
-
138
- /**
139
- * return next step notice by id
140
- *
141
- * @param string $id
142
- * @return DUPX_NOTICE_ITEM
143
- */
144
- public function getNextStepNoticeById($id)
145
- {
146
- if (isset($this->nextStepNotices[$id])) {
147
- return $this->nextStepNotices[$id];
148
- } else {
149
- return null;
150
- }
151
- }
152
-
153
- /**
154
- * return last report notice by id
155
- *
156
- * @param string $id
157
- * @return DUPX_NOTICE_ITEM
158
- */
159
- public function getFinalReporNoticeById($id)
160
- {
161
- if (isset($this->finalReporNotices[$id])) {
162
- return $this->finalReporNotices[$id];
163
- } else {
164
- return null;
165
- }
166
- }
167
-
168
- /**
169
- *
170
- * @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
171
- * // if array must be [
172
- * 'shortMsg' => text,
173
- * 'level' => level,
174
- * 'longMsg' => html text,
175
- * 'sections' => sections list,
176
- * 'faqLink' => [
177
- * 'url' => external link
178
- * 'label' => link text if empty get external url link
179
- * ]
180
- * ]
181
- * @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
182
- * @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
183
- *
184
- * @return string // notice insert id
185
- *
186
- * @throws Exception
187
- */
188
- public function addBothNextAndFinalReportNotice($item, $mode = self::ADD_NORMAL, $uniqueId = null)
189
- {
190
- $this->addNextStepNotice($item, $mode, $uniqueId);
191
- $this->addFinalReportNotice($item, $mode, $uniqueId);
192
- }
193
-
194
- /**
195
- *
196
- * @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
197
- * // if array must be [
198
- * 'shortMsg' => text,
199
- * 'level' => level,
200
- * 'longMsg' => html text,
201
- * 'sections' => sections list,
202
- * 'faqLink' => [
203
- * 'url' => external link
204
- * 'label' => link text if empty get external url link
205
- * ]
206
- * ]
207
- * @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
208
- * @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
209
- *
210
- * @return string // notice insert id
211
- *
212
- * @throws Exception
213
- */
214
- public function addNextStepNotice($item, $mode = self::ADD_NORMAL, $uniqueId = null)
215
- {
216
- if (!is_array($item) && !($item instanceof DUPX_NOTICE_ITEM)) {
217
- throw new Exception('Invalid item param');
218
- }
219
- return self::addReportNoticeToList($this->nextStepNotices, $item, $mode, $uniqueId);
220
- }
221
-
222
- /**
223
- * addNextStepNotice wrapper to add simple message with error level
224
- *
225
- * @param string $message
226
- * @param int $level // warning level
227
- * @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
228
- * @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
229
- *
230
- * @return string // notice insert id
231
- *
232
- * @throws Exception
233
- */
234
- public function addNextStepNoticeMessage($message, $level = DUPX_NOTICE_ITEM::INFO, $mode = self::ADD_NORMAL, $uniqueId = null)
235
- {
236
- return $this->addNextStepNotice(array(
237
- 'shortMsg' => $message,
238
- 'level' => $level,
239
- ), $mode, $uniqueId);
240
- }
241
-
242
- /**
243
- *
244
- * @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
245
- * // if array must be [
246
- * 'shortMsg' => text,
247
- * 'level' => level,
248
- * 'longMsg' => html text,
249
- * 'sections' => sections list,
250
- * 'faqLink' => [
251
- * 'url' => external link
252
- * 'label' => link text if empty get external url link
253
- * ]
254
- * ]
255
- * @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
256
- * @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
257
- *
258
- * @return string // notice insert id
259
- *
260
- * @throws Exception
261
- */
262
- public function addFinalReportNotice($item, $mode = self::ADD_NORMAL, $uniqueId = null)
263
- {
264
- if (!is_array($item) && !($item instanceof DUPX_NOTICE_ITEM)) {
265
- throw new Exception('Invalid item param');
266
- }
267
- return self::addReportNoticeToList($this->finalReporNotices, $item, $mode, $uniqueId);
268
- }
269
-
270
- /**
271
- * addFinalReportNotice wrapper to add simple message with error level
272
- *
273
- * @param string $message
274
- * @param string|string[] $sections // message sections on final report
275
- * @param int $level // warning level
276
- * @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
277
- * @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
278
- *
279
- * @return string // notice insert id
280
- *
281
- * @throws Exception
282
- */
283
- public function addFinalReportNoticeMessage($message, $sections, $level = DUPX_NOTICE_ITEM::INFO, $mode = self::ADD_NORMAL, $uniqueId = null)
284
- {
285
- return $this->addFinalReportNotice(array(
286
- 'shortMsg' => $message,
287
- 'level' => $level,
288
- 'sections' => $sections,
289
- ), $mode, $uniqueId);
290
- }
291
-
292
- /**
293
- *
294
- * @param array $list
295
- * @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
296
- * // if array must be [
297
- * 'shortMsg' => text,
298
- * 'level' => level,
299
- * 'longMsg' => html text,
300
- * 'sections' => sections list,
301
- * 'faqLink' => [
302
- * 'url' => external link
303
- * 'label' => link text if empty get external url link
304
- * ]
305
- * ]
306
- * @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
307
- * @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
308
- *
309
- * @return string // notice insert id
310
- *
311
- * @throws Exception
312
- */
313
- private static function addReportNoticeToList(&$list, $item, $mode = self::ADD_NORMAL, $uniqueId = null)
314
- {
315
- switch ($mode) {
316
- case self::ADD_UNIQUE:
317
- if (empty($uniqueId)) {
318
- throw new Exception('uniqueId can\'t be empty');
319
- }
320
- if (isset($list[$uniqueId])) {
321
- return $uniqueId;
322
- }
323
- // no break -> continue on unique update
324
- case self::ADD_UNIQUE_UPDATE:
325
- if (empty($uniqueId)) {
326
- throw new Exception('uniqueId can\'t be empty');
327
- }
328
- $insertId = $uniqueId;
329
- break;
330
- case self::ADD_UNIQUE_APPEND_IF_EXISTS:
331
- if (empty($uniqueId)) {
332
- throw new Exception('uniqueId can\'t be empty');
333
- }
334
- if (!isset($list[$uniqueId])) {
335
- return false;
336
- }
337
- // no break
338
- case self::ADD_UNIQUE_APPEND:
339
- if (empty($uniqueId)) {
340
- throw new Exception('uniqueId can\'t be empty');
341
- }
342
- $insertId = $uniqueId;
343
- // if item id exist append long msg
344
- if (isset($list[$uniqueId])) {
345
- $tempObj = self::getObjFromParams($item);
346
- $list[$uniqueId]->longMsg .= $tempObj->longMsg;
347
- $item = $list[$uniqueId];
348
- }
349
- break;
350
- case self::ADD_UNIQUE_PREPEND_IF_EXISTS:
351
- if (empty($uniqueId)) {
352
- throw new Exception('uniqueId can\'t be empty');
353
- }
354
- if (!isset($list[$uniqueId])) {
355
- return false;
356
- }
357
- // no break
358
- case self::ADD_UNIQUE_PREPEND:
359
- if (empty($uniqueId)) {
360
- throw new Exception('uniqueId can\'t be empty');
361
- }
362
- $insertId = $uniqueId;
363
- // if item id exist append long msg
364
- if (isset($list[$uniqueId])) {
365
- $tempObj = self::getObjFromParams($item);
366
- $list[$uniqueId]->longMsg = $tempObj->longMsg.$list[$uniqueId]->longMsg;
367
- $item = $list[$uniqueId];
368
- }
369
- break;
370
- case self::ADD_NORMAL:
371
- default:
372
- if (empty($uniqueId)) {
373
- $insertId = self::getNewAutoUniqueId();
374
- } else {
375
- $insertId = $uniqueId;
376
- }
377
- }
378
-
379
- $list[$insertId] = self::getObjFromParams($item);
380
- return $insertId;
381
- }
382
-
383
- /**
384
- *
385
- * @param string|array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
386
- * // if array must be [
387
- * 'shortMsg' => text,
388
- * 'level' => level,
389
- * 'longMsg' => html text,
390
- * 'sections' => sections list,
391
- * 'faqLink' => [
392
- * 'url' => external link
393
- * 'label' => link text if empty get external url link
394
- * ]
395
- * ]
396
- * @param int $level message level considered only in the case where $item is a string.
397
- * @return \DUPX_NOTICE_ITEM
398
- *
399
- * @throws Exception
400
- */
401
- private static function getObjFromParams($item, $level = DUPX_NOTICE_ITEM::INFO)
402
- {
403
- if ($item instanceof DUPX_NOTICE_ITEM) {
404
- $newObj = $item;
405
- } else if (is_array($item)) {
406
- $newObj = DUPX_NOTICE_ITEM::getItemFromArray($item);
407
- } else if (is_string($item)) {
408
- $newObj = new DUPX_NOTICE_ITEM($item, $level);
409
- } else {
410
- throw new Exception('Notice input not valid');
411
- }
412
-
413
- return $newObj;
414
- }
415
-
416
- /**
417
- *
418
- * @param null|string $section if null is count global
419
- * @param int $level error level
420
- * @param string $operator > < >= <= = !=
421
- *
422
- * @return int
423
- */
424
- public function countFinalReportNotices($section = null, $level = DUPX_NOTICE_ITEM::INFO, $operator = '>=')
425
- {
426
- $result = 0;
427
- foreach ($this->finalReporNotices as $notice) {
428
- if (is_null($section) || in_array($section, $notice->sections)) {
429
- switch ($operator) {
430
- case '>=':
431
- $result += (int) ($notice->level >= $level);
432
- break;
433
- case '>':
434
- $result += (int) ($notice->level > $level);
435
- break;
436
- case '=':
437
- $result += (int) ($notice->level = $level);
438
- break;
439
- case '<=':
440
- $result += (int) ($notice->level <= $level);
441
- break;
442
- case '<':
443
- $result += (int) ($notice->level < $level);
444
- break;
445
- case '!=':
446
- $result += (int) ($notice->level != $level);
447
- break;
448
- }
449
- }
450
- }
451
- return $result;
452
- }
453
-
454
- /**
455
- * sort final report notice from priority and notice level
456
- */
457
- public function sortFinalReport()
458
- {
459
- uasort($this->finalReporNotices, 'DUPX_NOTICE_ITEM::sortNoticeForPriorityAndLevel');
460
- }
461
-
462
- /**
463
- * display final final report notice section
464
- *
465
- * @param string $section
466
- */
467
- public function displayFinalReport($section)
468
- {
469
- foreach ($this->finalReporNotices as $id => $notice) {
470
- if (in_array($section, $notice->sections)) {
471
- self::finalReportNotice($id, $notice);
472
- }
473
- }
474
- }
475
-
476
- /**
477
- *
478
- * @param string $section
479
- * @param string $title
480
- */
481
- public function displayFinalRepostSectionHtml($section, $title)
482
- {
483
- if ($this->haveSection($section)) {
484
- ?>
485
- <div id="report-section-<?php echo $section; ?>" class="section" >
486
- <div class="section-title" ><?php echo $title; ?></div>
487
- <div class="section-content">
488
- <?php
489
- $this->displayFinalReport($section);
490
- ?>
491
- </div>
492
- </div>
493
- <?php
494
- }
495
- }
496
-
497
- /**
498
- *
499
- * @param string $section
500
- * @return boolean
501
- */
502
- public function haveSection($section)
503
- {
504
- foreach ($this->finalReporNotices as $notice) {
505
- if (in_array($section, $notice->sections)) {
506
- return true;
507
- }
508
- }
509
- return false;
510
- }
511
-
512
- /**
513
- *
514
- * @param null|string $section if null is a global result
515
- *
516
- * @return int // returns the worst level found
517
- *
518
- */
519
- public function getSectionErrLevel($section = null)
520
- {
521
- $result = DUPX_NOTICE_ITEM::INFO;
522
-
523
- foreach ($this->finalReporNotices as $notice) {
524
- if (is_null($section) || in_array($section, $notice->sections)) {
525
- $result = max($result, $notice->level);
526
- }
527
- }
528
- return $result;
529
- }
530
-
531
- /**
532
- *
533
- * @param string $section
534
- * @param bool $echo
535
- * @return void|string
536
- */
537
- public function getSectionErrLevelHtml($section = null, $echo = true)
538
- {
539
- return self::getErrorLevelHtml($this->getSectionErrLevel($section), $echo);
540
- }
541
-
542
- /**
543
- * Displa next step notice message
544
- *
545
- * @param bool $deleteListAfterDisaply
546
- * @return void
547
- */
548
- public function displayStepMessages($deleteListAfterDisaply = true)
549
- {
550
- if (empty($this->nextStepNotices)) {
551
- return;
552
- }
553
- ?>
554
- <div id="step-messages">
555
- <?php
556
- foreach ($this->nextStepNotices as $notice) {
557
- self::stepMsg($notice);
558
- }
559
- ?>
560
- </div>
561
- <?php
562
- if ($deleteListAfterDisaply) {
563
- $this->nextStepNotices = array();
564
- $this->saveNotices();
565
- }
566
- }
567
-
568
- /**
569
- *
570
- * @param DUPX_NOTICE_ITEM $notice
571
- */
572
- private static function stepMsg($notice)
573
- {
574
- $classes = array(
575
- 'notice',
576
- 'next-step',
577
- self::getClassFromLevel($notice->level)
578
- );
579
- $haveContent = !empty($notice->faqLink) || !empty($notice->longMsg);
580
- ?>
581
- <div class="<?php echo implode(' ', $classes); ?>">
582
- <div class="title">
583
- <?php echo self::getNextStepLevelPrefixMessage($notice->level).': <b>'.htmlentities($notice->shortMsg).'</b>'; ?>
584
- </div>
585
- <?php if ($haveContent) { ?>
586
- <div class="title-separator" ></div>
587
- <?php
588
- ob_start();
589
- if (!empty($notice->faqLink)) {
590
- ?>
591
- See FAQ: <a href="<?php echo $notice->faqLink['url']; ?>" >
592
- <b><?php echo htmlentities(empty($notice->faqLink['label']) ? $notice->faqLink['url'] : $notice->faqLink['label']); ?></b>
593
- </a>
594
- <?php
595
- }
596
- if (!empty($notice->faqLink) && !empty($notice->longMsg)) {
597
- echo '<br><br>';
598
- }
599
- if (!empty($notice->longMsg)) {
600
- switch ($notice->longMsgMode) {
601
- case DUPX_NOTICE_ITEM::MSG_MODE_PRE:
602
- echo '<pre>'.htmlentities($notice->longMsg).'</pre>';
603
- break;
604
- case DUPX_NOTICE_ITEM::MSG_MODE_HTML:
605
- echo $notice->longMsg;
606
- break;
607
- case DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT:
608
- default:
609
- echo htmlentities($notice->longMsg);
610
- }
611
- }
612
- $longContent = ob_get_clean();
613
- DUPX_U_Html::getMoreContent($longContent, 'info', 200);
614
- }
615
- ?>
616
- </div>
617
- <?php
618
- }
619
-
620
- /**
621
- *
622
- * @param string $id
623
- * @param DUPX_NOTICE_ITEM $notice
624
- */
625
- private static function finalReportNotice($id, $notice)
626
- {
627
- $classes = array(
628
- 'notice-report',
629
- 'notice',
630
- self::getClassFromLevel($notice->level)
631
- );
632
- $haveContent = !empty($notice->faqLink) || !empty($notice->longMsg);
633
- $contentId = 'notice-content-'.$id;
634
- $iconClasses = $haveContent ? 'fa fa-caret-right' : 'fa fa-toggle-empty';
635
- $toggleLinkData = $haveContent ? 'data-type="toggle" data-target="#'.$contentId.'"' : '';
636
- ?>
637
- <div class="<?php echo implode(' ', $classes); ?>">
638
- <div class="title" <?php echo $toggleLinkData; ?>>
639
- <i class="<?php echo $iconClasses; ?>"></i> <?php echo htmlentities($notice->shortMsg); ?>
640
- </div>
641
- <?php
642
- if ($haveContent) {
643
- $infoClasses = array('info');
644
- if (!$notice->open) {
645
- $infoClasses[] = 'no-display';
646
- }
647
- ?>
648
- <div id="<?php echo $contentId; ?>" class="<?php echo implode(' ', $infoClasses); ?>" >
649
- <?php
650
- if (!empty($notice->faqLink)) {
651
- ?>
652
- <b>See FAQ</b>: <a href="<?php echo $notice->faqLink['url']; ?>" >
653
- <?php echo htmlentities(empty($notice->faqLink['label']) ? $notice->faqLink['url'] : $notice->faqLink['label']); ?>
654
- </a>
655
- <?php
656
- }
657
- if (!empty($notice->faqLink) && !empty($notice->longMsg)) {
658
- echo '<br><br>';
659
- }
660
- if (!empty($notice->longMsg)) {
661
- switch ($notice->longMsgMode) {
662
- case DUPX_NOTICE_ITEM::MSG_MODE_PRE:
663
- echo '<pre>'.htmlentities($notice->longMsg).'</pre>';
664
- break;
665
- case DUPX_NOTICE_ITEM::MSG_MODE_HTML:
666
- echo $notice->longMsg;
667
- break;
668
- case DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT:
669
- default:
670
- echo htmlentities($notice->longMsg);
671
- }
672
- }
673
- ?>
674
- </div>
675
- <?php
676
- }
677
- ?>
678
- </div>
679
- <?php
680
- }
681
-
682
- /**
683
- *
684
- * @param DUPX_NOTICE_ITEM $notice
685
- */
686
- private static function noticeToText($notice)
687
- {
688
- $result = '-----------------------'."\n".
689
- '['.self::getNextStepLevelPrefixMessage($notice->level, false).'] '.$notice->shortMsg;
690
-
691
- if (!empty($notice->sections)) {
692
- $result .= "\n\t".'SECTIONS: '.implode(',', $notice->sections);
693
- }
694
- if (!empty($notice->longMsg)) {
695
- $result .= "\n\t".'LONG MSG: '.$notice->longMsg;
696
- }
697
- return $result."\n";
698
- }
699
-
700
- public function nextStepLog()
701
- {
702
- if (!empty($this->nextStepNotices)) {
703
- DUPX_Log::info(
704
- '===================================='."\n".
705
- 'NEXT STEP NOTICES'."\n".
706
- '====================================');
707
- foreach ($this->nextStepNotices as $notice) {
708
- DUPX_Log::info(self::noticeToText($notice));
709
- }
710
- DUPX_Log::info(
711
- '====================================');
712
- }
713
- }
714
-
715
- public function finalReportLog($sections = array())
716
- {
717
- if (!empty($this->finalReporNotices)) {
718
- DUPX_Log::info(
719
- '===================================='."\n".
720
- 'FINAL REPORT NOTICES LIST'."\n".
721
- '====================================');
722
- foreach ($this->finalReporNotices as $notice) {
723
- if (count(array_intersect($notice->sections, $sections)) > 0) {
724
- DUPX_Log::info(self::noticeToText($notice));
725
- }
726
- }
727
- DUPX_Log::info(
728
- '====================================');
729
- }
730
- }
731
-
732
- /**
733
- * get html class from level
734
- *
735
- * @param int $level
736
- * @return string
737
- */
738
- private static function getClassFromLevel($level)
739
- {
740
- switch ($level) {
741
- case DUPX_NOTICE_ITEM::INFO:
742
- return 'l-info';
743
- case DUPX_NOTICE_ITEM::NOTICE:
744
- return 'l-notice';
745
- case DUPX_NOTICE_ITEM::SOFT_WARNING:
746
- return 'l-swarning';
747
- case DUPX_NOTICE_ITEM::HARD_WARNING:
748
- return 'l-hwarning';
749
- case DUPX_NOTICE_ITEM::CRITICAL:
750
- return 'l-critical';
751
- case DUPX_NOTICE_ITEM::FATAL:
752
- return 'l-fatal';
753
- }
754
- }
755
-
756
- /**
757
- * get level label from level
758
- *
759
- * @param int $level
760
- * @param bool $echo
761
- * @return type
762
- */
763
- public static function getErrorLevelHtml($level, $echo = true)
764
- {
765
- switch ($level) {
766
- case DUPX_NOTICE_ITEM::INFO:
767
- $label = 'good';
768
- break;
769
- case DUPX_NOTICE_ITEM::NOTICE:
770
- $label = 'good';
771
- break;
772
- case DUPX_NOTICE_ITEM::SOFT_WARNING:
773
- $label = 'warning';
774
- break;
775
- case DUPX_NOTICE_ITEM::HARD_WARNING:
776
- $label = 'warning';
777
- break;
778
- case DUPX_NOTICE_ITEM::CRITICAL:
779
- $label = 'critical error';
780
- break;
781
- case DUPX_NOTICE_ITEM::FATAL:
782
- $label = 'fatal error';
783
- break;
784
- default:
785
- return;
786
- }
787
- $classes = self::getClassFromLevel($level);
788
- ob_start();
789
- ?>
790
- <span class="notice-level-status <?php echo $classes; ?>"><?php echo $label; ?></span>
791
- <?php
792
- if ($echo) {
793
- ob_end_flush();
794
- } else {
795
- return ob_get_clean();
796
- }
797
- }
798
-
799
- /**
800
- * get next step message prefix
801
- *
802
- * @param int $level
803
- * @param bool $echo
804
- * @return string
805
- */
806
- public static function getNextStepLevelPrefixMessage($level, $echo = true)
807
- {
808
- switch ($level) {
809
- case DUPX_NOTICE_ITEM::INFO:
810
- $label = 'INFO';
811
- break;
812
- case DUPX_NOTICE_ITEM::NOTICE:
813
- $label = 'NOTICE';
814
- break;
815
- case DUPX_NOTICE_ITEM::SOFT_WARNING:
816
- $label = 'WARNING';
817
- break;
818
- case DUPX_NOTICE_ITEM::HARD_WARNING:
819
- $label = 'WARNING';
820
- break;
821
- case DUPX_NOTICE_ITEM::CRITICAL:
822
- $label = 'CRITICAL ERROR';
823
- break;
824
- case DUPX_NOTICE_ITEM::FATAL:
825
- $label = 'FATAL ERROR';
826
- break;
827
- default:
828
- return;
829
- }
830
-
831
- if ($echo) {
832
- echo $label;
833
- } else {
834
- return $label;
835
- }
836
- }
837
-
838
- /**
839
- * get unique id
840
- *
841
- * @return string
842
- */
843
- private static function getNewAutoUniqueId()
844
- {
845
- self::$uniqueCountId ++;
846
- return self::DEFAULT_UNIQUE_ID_PREFIX.self::$uniqueCountId;
847
- }
848
-
849
- /**
850
- * function for internal test
851
- *
852
- * display all messages levels
853
- */
854
- public static function testNextStepMessaesLevels()
855
- {
856
- $manager = self::getInstance();
857
- $manager->addNextStepNoticeMessage('Level info ('.DUPX_NOTICE_ITEM::INFO.')', DUPX_NOTICE_ITEM::INFO);
858
- $manager->addNextStepNoticeMessage('Level notice ('.DUPX_NOTICE_ITEM::NOTICE.')', DUPX_NOTICE_ITEM::NOTICE);
859
- $manager->addNextStepNoticeMessage('Level soft warning ('.DUPX_NOTICE_ITEM::SOFT_WARNING.')', DUPX_NOTICE_ITEM::SOFT_WARNING);
860
- $manager->addNextStepNoticeMessage('Level hard warning ('.DUPX_NOTICE_ITEM::HARD_WARNING.')', DUPX_NOTICE_ITEM::HARD_WARNING);
861
- $manager->addNextStepNoticeMessage('Level critical error ('.DUPX_NOTICE_ITEM::CRITICAL.')', DUPX_NOTICE_ITEM::CRITICAL);
862
- $manager->addNextStepNoticeMessage('Level fatal error ('.DUPX_NOTICE_ITEM::FATAL.')', DUPX_NOTICE_ITEM::FATAL);
863
- $manager->saveNotices();
864
- }
865
-
866
- /**
867
- * test function
868
- */
869
- public static function testNextStepFullMessageData()
870
- {
871
- $manager = self::getInstance();
872
- $longMsg = <<<LONGMSG
873
- <b>Formattend long text</b><br>
874
- <ul>
875
- <li>Proin dapibus mi eu erat pulvinar, id congue nisl egestas.</li>
876
- <li>Nunc venenatis eros et sapien ornare consequat.</li>
877
- <li>Mauris tincidunt est sit amet turpis placerat, a tristique dui porttitor.</li>
878
- <li>Etiam volutpat lectus quis risus molestie faucibus.</li>
879
- <li>Integer gravida eros sit amet sem viverra, a volutpat neque rutrum.</li>
880
- <li>Aenean varius ipsum vitae lorem tempus rhoncus.</li>
881
- </ul>
882
- LONGMSG;
883
- $manager->addNextStepNotice(array(
884
- 'shortMsg' => 'Full elements next step message MODE HTML',
885
- 'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
886
- 'longMsg' => $longMsg,
887
- 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
888
- 'faqLink' => array(
889
- 'url' => 'http://www.google.it',
890
- 'label' => 'google link'
891
- )
892
- ));
893
-
894
- $longMsg = <<<LONGMSG
895
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc a auctor erat, et lobortis libero.
896
- Suspendisse aliquet neque in massa posuere mollis. Donec venenatis finibus sapien in bibendum. Donec et ex massa.
897
-
898
- Aliquam venenatis dapibus tellus nec ullamcorper. Mauris ante velit, tincidunt sit amet egestas et, mattis non lorem. In semper ex ut velit suscipit,
899
- at luctus nunc dapibus. Etiam blandit maximus dapibus. Nullam eu porttitor augue. Suspendisse pulvinar, massa eget condimentum aliquet, dolor massa tempus dui, vel rhoncus tellus ligula non odio.
900
- Ut ac faucibus tellus, in lobortis odio.
901
- LONGMSG;
902
- $manager->addNextStepNotice(array(
903
- 'shortMsg' => 'Full elements next step message MODE PRE',
904
- 'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
905
- 'longMsg' => $longMsg,
906
- 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_PRE,
907
- 'faqLink' => array(
908
- 'url' => 'http://www.google.it',
909
- 'label' => 'google link'
910
- )
911
- ));
912
-
913
- $longMsg = <<<LONGMSG
914
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc a auctor erat, et lobortis libero.
915
- Suspendisse aliquet neque in massa posuere mollis. Donec venenatis finibus sapien in bibendum. Donec et ex massa.
916
-
917
- Aliquam venenatis dapibus tellus nec ullamcorper. Mauris ante velit, tincidunt sit amet egestas et, mattis non lorem. In semper ex ut velit suscipit,
918
- at luctus nunc dapibus. Etiam blandit maximus dapibus. Nullam eu porttitor augue. Suspendisse pulvinar, massa eget condimentum aliquet, dolor massa tempus dui, vel rhoncus tellus ligula non odio.
919
- Ut ac faucibus tellus, in lobortis odio.
920
- LONGMSG;
921
- $manager->addNextStepNotice(array(
922
- 'shortMsg' => 'Full elements next step message MODE DEFAULT',
923
- 'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
924
- 'longMsg' => $longMsg,
925
- 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT,
926
- 'faqLink' => array(
927
- 'url' => 'http://www.google.it',
928
- 'label' => 'google link'
929
- )
930
- ));
931
-
932
-
933
- $longMsg = <<<LONGMSG
934
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam cursus porttitor consectetur. Nunc faucibus elementum nisl nec ornare. Phasellus sit amet urna in diam ultricies ornare nec sit amet nibh. Nulla a aliquet leo. Quisque aliquet posuere lectus sit amet commodo. Nullam tempus enim eget urna rutrum egestas. Aliquam eget lorem nisl. Nulla tincidunt massa erat. Phasellus lectus tellus, mollis sit amet aliquam in, dapibus quis metus. Nunc venenatis nulla vitae convallis accumsan.
935
-
936
- Mauris eu ullamcorper metus. Aenean ultricies et turpis eget mollis. Aliquam auctor, elit scelerisque placerat pellentesque, quam augue fermentum lectus, vel pretium nisi justo sit amet ante. Donec blandit porttitor tempus. Duis vulputate nulla ut orci rutrum, et consectetur urna mollis. Sed at iaculis velit. Pellentesque id quam turpis. Curabitur eu ligula velit. Cras gravida, ipsum sed iaculis eleifend, mauris nunc posuere quam, vel blandit nisi justo congue ligula. Phasellus aliquam eu odio ac porttitor. Fusce dictum mollis turpis sit amet fringilla.
937
-
938
- Nulla eu ligula mauris. Fusce lobortis ligula elit, a interdum nibh pulvinar eu. Pellentesque rhoncus nec turpis id blandit. Morbi fringilla, justo non varius consequat, arcu ante efficitur ante, sit amet cursus lorem elit vel odio. Phasellus neque ligula, vehicula vel ipsum sed, volutpat dignissim eros. Curabitur at lacus id felis elementum auctor. Nullam ac tempus nisi. Phasellus nibh purus, aliquam nec purus ut, sodales lobortis nulla. Cras viverra dictum magna, ac malesuada nibh dictum ac. Mauris euismod, magna sit amet pretium posuere, ligula nibh ultrices tellus, sit amet pretium odio urna egestas justo. Suspendisse purus erat, eleifend sed magna in, efficitur interdum nibh.
939
-
940
- Vivamus nibh nunc, fermentum non tortor volutpat, consectetur vulputate velit. Phasellus lobortis, purus et faucibus mollis, metus eros viverra ante, sit amet euismod nibh est eu orci. Duis sodales cursus lacinia. Praesent laoreet ut ipsum ut interdum. Praesent venenatis massa vitae ligula consequat aliquet. Fusce in purus in odio molestie laoreet at ac augue. Fusce consectetur elit a magna mollis aliquet.
941
-
942
- Nulla eros nisi, dapibus eget diam vitae, tincidunt blandit odio. Fusce interdum tellus nec varius condimentum. Fusce non magna a purus sodales imperdiet sit amet vitae ligula. Quisque viverra leo sit amet mi egestas, et posuere nunc tincidunt. Suspendisse feugiat malesuada urna sed tincidunt. Morbi a urna sed magna volutpat pellentesque sit amet ac mauris. Nulla sed ultrices dui. Etiam massa arcu, tempor ut erat at, cursus malesuada ipsum. Duis sit amet felis dolor.
943
-
944
- Morbi gravida nisl nunc, vulputate iaculis risus vehicula non. Proin cursus, velit et laoreet consectetur, lacus libero sagittis lacus, quis accumsan odio lectus non erat. Aenean dolor lectus, euismod sit amet justo eget, dictum gravida nisl. Phasellus sed nunc non odio ullamcorper rhoncus non ut ipsum. Duis ante ligula, pellentesque sit amet imperdiet eget, congue vel dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Suspendisse luctus leo eget justo mollis, convallis convallis ex suscipit. Integer et justo eget odio lobortis sollicitudin. Pellentesque accumsan rhoncus augue, luctus suscipit ex accumsan nec. Maecenas lacinia consectetur risus at bibendum. Etiam venenatis purus lorem, sit amet elementum turpis tristique eu. Proin vulputate faucibus feugiat. Nunc vehicula congue odio consequat vulputate. Quisque bibendum augue id iaculis faucibus. Donec blandit cursus sem, eget accumsan orci commodo sed.
945
-
946
- Suspendisse iaculis est quam, sed scelerisque purus tincidunt non. Cras hendrerit ante turpis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse purus ipsum, rutrum id sem in, venenatis laoreet metus. Aliquam ac bibendum mauris. Cras egestas rhoncus est, sed lacinia nibh vestibulum id. Proin diam quam, sagittis congue molestie ac, rhoncus et mauris. Phasellus massa neque, ornare vel erat a, rutrum pharetra arcu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi et nulla eget massa auctor fermentum. Quisque maximus tellus sed cursus cursus. Ut vehicula erat at purus aliquet, quis imperdiet dui sagittis. Nullam eget quam leo.
947
-
948
- Nulla magna ipsum, congue nec dui ut, lacinia malesuada felis. Cras mattis metus non maximus venenatis. Aliquam euismod est vitae erat sollicitudin, at pellentesque augue sollicitudin. Curabitur euismod maximus cursus. In tortor dui, convallis sed sapien ac, varius congue metus. Nunc ullamcorper ac orci sit amet finibus. Vivamus molestie nibh vitae quam rhoncus, eu ultrices est molestie. Maecenas consectetur eu quam sit amet placerat.
949
-
950
- Curabitur ut fermentum mauris. Donec et congue nibh. Sed cursus elit sit amet convallis varius. Donec malesuada porta odio condimentum varius. Pellentesque ornare tempor ante, ut volutpat nulla lobortis sed. Nunc congue aliquet erat ac elementum. Quisque a ex sit amet turpis placerat sagittis eget ac ligula. Etiam in augue malesuada, aliquam est non, lacinia justo. Vivamus tincidunt dolor orci, id dignissim lorem maximus at. Vivamus ligula mauris, venenatis vel nibh id, lacinia ultrices ipsum. Mauris cursus, urna ac rutrum aliquet, risus ipsum tincidunt purus, sit amet blandit nunc sem sit amet nibh.
951
-
952
- Nam eleifend risus lacus, eu pharetra risus egestas eu. Maecenas hendrerit nisl in semper placerat. Vestibulum massa tellus, laoreet non euismod quis, sollicitudin id sapien. Morbi vel cursus metus. Aenean tincidunt nisi est, ut elementum est auctor id. Duis auctor elit leo, ac scelerisque risus suscipit et. Pellentesque lectus nisi, ultricies in elit sed, pulvinar iaculis massa. Morbi viverra eros mi, pretium facilisis neque egestas id. Curabitur non massa accumsan, porttitor sem vitae, ultricies lacus. Curabitur blandit nisl velit. Mauris sollicitudin ultricies purus sit amet placerat. Fusce ac neque sed leo venenatis laoreet ut non ex. Integer elementum rhoncus orci, eu maximus neque tempus eu. Curabitur euismod dignissim tellus, vitae lacinia metus. Mauris imperdiet metus vitae vulputate accumsan. Duis eget luctus nibh, sit amet finibus libero.
953
-
954
- LONGMSG;
955
- $manager->addNextStepNotice(array(
956
- 'shortMsg' => 'Full elements LONG LONG',
957
- 'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
958
- 'longMsg' => $longMsg,
959
- 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT,
960
- 'faqLink' => array(
961
- 'url' => 'http://www.google.it',
962
- 'label' => 'google link'
963
- )
964
- ));
965
-
966
-
967
-
968
-
969
- $manager->saveNotices();
970
- }
971
-
972
- /**
973
- * test function
974
- */
975
- public static function testFinalReporMessaesLevels()
976
- {
977
- $section = 'general';
978
-
979
- $manager = self::getInstance();
980
- $manager->addFinalReportNoticeMessage('Level info ('.DUPX_NOTICE_ITEM::INFO.')', $section, DUPX_NOTICE_ITEM::INFO, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_0');
981
- $manager->addFinalReportNoticeMessage('Level notice ('.DUPX_NOTICE_ITEM::NOTICE.')', $section, DUPX_NOTICE_ITEM::NOTICE, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_1');
982
- $manager->addFinalReportNoticeMessage('Level soft warning ('.DUPX_NOTICE_ITEM::SOFT_WARNING.')', $section, DUPX_NOTICE_ITEM::SOFT_WARNING, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_2');
983
- $manager->addFinalReportNoticeMessage('Level hard warning ('.DUPX_NOTICE_ITEM::HARD_WARNING.')', $section, DUPX_NOTICE_ITEM::HARD_WARNING, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_3');
984
- $manager->addFinalReportNoticeMessage('Level critical error ('.DUPX_NOTICE_ITEM::CRITICAL.')', $section, DUPX_NOTICE_ITEM::CRITICAL, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_4');
985
- $manager->addFinalReportNoticeMessage('Level fatal error ('.DUPX_NOTICE_ITEM::FATAL.')', $section, DUPX_NOTICE_ITEM::FATAL, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_5');
986
- $manager->saveNotices();
987
- }
988
-
989
- /**
990
- * test function
991
- */
992
- public static function testFinalReportFullMessages()
993
- {
994
- $section = 'general';
995
- $manager = self::getInstance();
996
-
997
- $longMsg = <<<LONGMSG
998
- <b>Formattend long text</b><br>
999
- <ul>
1000
- <li>Proin dapibus mi eu erat pulvinar, id congue nisl egestas.</li>
1001
- <li>Nunc venenatis eros et sapien ornare consequat.</li>
1002
- <li>Mauris tincidunt est sit amet turpis placerat, a tristique dui porttitor.</li>
1003
- <li>Etiam volutpat lectus quis risus molestie faucibus.</li>
1004
- <li>Integer gravida eros sit amet sem viverra, a volutpat neque rutrum.</li>
1005
- <li>Aenean varius ipsum vitae lorem tempus rhoncus.</li>
1006
- </ul>
1007
- LONGMSG;
1008
-
1009
- $manager->addFinalReportNotice(array(
1010
- 'shortMsg' => 'Full elements final report message',
1011
- 'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
1012
- 'longMsg' => $longMsg,
1013
- 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
1014
- 'sections' => $section,
1015
- 'faqLink' => array(
1016
- 'url' => 'http://www.google.it',
1017
- 'label' => 'google link'
1018
- )
1019
- ), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_full_1');
1020
-
1021
- $manager->addFinalReportNotice(array(
1022
- 'shortMsg' => 'Full elements final report message info high priority',
1023
- 'level' => DUPX_NOTICE_ITEM::INFO,
1024
- 'longMsg' => $longMsg,
1025
- 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
1026
- 'sections' => $section,
1027
- 'faqLink' => array(
1028
- 'url' => 'http://www.google.it',
1029
- 'label' => 'google link'
1030
- ),
1031
- 'priority' => 5
1032
- ), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_full_2');
1033
- $manager->saveNotices();
1034
- }
1035
-
1036
- private function __clone()
1037
- {
1038
-
1039
- }
1040
-
1041
- private function __wakeup()
1042
- {
1043
-
1044
- }
1045
- }
1046
-
1047
- class DUPX_NOTICE_ITEM
1048
- {
1049
- const INFO = 0;
1050
- const NOTICE = 1;
1051
- const SOFT_WARNING = 2;
1052
- const HARD_WARNING = 3;
1053
- const CRITICAL = 4;
1054
- const FATAL = 5;
1055
- const MSG_MODE_DEFAULT = 'def';
1056
- const MSG_MODE_HTML = 'html';
1057
- const MSG_MODE_PRE = 'pre';
1058
-
1059
- /**
1060
- *
1061
- * @var string text
1062
- */
1063
- public $shortMsg = '';
1064
-
1065
- /**
1066
- *
1067
- * @var string html text
1068
- */
1069
- public $longMsg = '';
1070
-
1071
- /**
1072
- *
1073
- * @var bool if true long msg can be html
1074
- */
1075
- public $longMsgMode = self::MSG_MODE_DEFAULT;
1076
-
1077
- /**
1078
- *
1079
- * @var null|array // null = no faq link
1080
- * array( 'label' => link text , 'url' => faq url)
1081
- */
1082
- public $faqLink = array(
1083
- 'label' => '',
1084
- 'url' => ''
1085
- );
1086
-
1087
- /**
1088
- *
1089
- * @var string[] notice sections for final report only
1090
- */
1091
- public $sections = array();
1092
-
1093
- /**
1094
- *
1095
- * @var int
1096
- */
1097
- public $level = self::NOTICE;
1098
-
1099
- /**
1100
- *
1101
- * @var int
1102
- */
1103
- public $priority = 10;
1104
-
1105
- /**
1106
- *
1107
- * @var bool if true notice start open. For final report only
1108
- */
1109
- public $open = false;
1110
-
1111
- /**
1112
- *
1113
- * @param string $shortMsg text
1114
- * @param int $level
1115
- * @param string $longMsg html text
1116
- * @param string|string[] $sections
1117
- * @param null|array $faqLink [
1118
- * 'url' => external link
1119
- * 'label' => link text if empty get external url link
1120
- * ]
1121
- * @param int priority
1122
- * @param bool open
1123
- * @param string longMsgMode MSG_MODE_DEFAULT | MSG_MODE_HTML | MSG_MODE_PRE
1124
- */
1125
- public function __construct($shortMsg, $level = self::INFO, $longMsg = '', $sections = array(), $faqLink = null, $priority = 10, $open = false, $longMsgMode = self::MSG_MODE_DEFAULT)
1126
- {
1127
- $this->shortMsg = (string) $shortMsg;
1128
- $this->level = (int) $level;
1129
- $this->longMsg = (string) $longMsg;
1130
- $this->sections = is_array($sections) ? $sections : array($sections);
1131
- $this->faqLink = $faqLink;
1132
- $this->priority = $priority;
1133
- $this->open = $open;
1134
- $this->longMsgMode = $longMsgMode;
1135
- }
1136
-
1137
- /**
1138
- *
1139
- * @return array [
1140
- * 'shortMsg' => text,
1141
- * 'level' => level,
1142
- * 'longMsg' => html text,
1143
- * 'sections' => string|string[],
1144
- * 'faqLink' => [
1145
- * 'url' => external link
1146
- * 'label' => link text if empty get external url link
1147
- * ]
1148
- * 'priority' => int low first
1149
- * 'open' => if true the tab is opene on final report
1150
- * 'longMsgMode'=> MSG_MODE_DEFAULT | MSG_MODE_HTML | MSG_MODE_PRE
1151
- * ]
1152
- */
1153
- public function toArray()
1154
- {
1155
- return array(
1156
- 'shortMsg' => $this->shortMsg,
1157
- 'level' => $this->level,
1158
- 'longMsg' => $this->longMsg,
1159
- 'sections' => $this->sections,
1160
- 'faqLink' => $this->faqLink,
1161
- 'priority' => $this->priority,
1162
- 'open' => $this->open,
1163
- 'longMsgMode' => $this->longMsgMode
1164
- );
1165
- }
1166
-
1167
- /**
1168
- *
1169
- * @return array [
1170
- * 'shortMsg' => text,
1171
- * 'level' => level,
1172
- * 'longMsg' => html text,
1173
- * 'sections' => string|string[],
1174
- * 'faqLink' => [
1175
- * 'url' => external link
1176
- * 'label' => link text if empty get external url link
1177
- * ],
1178
- * priority
1179
- * open
1180
- * longMsgMode
1181
- * ]
1182
- * @return DUPX_NOTICE_ITEM
1183
- */
1184
- public static function getItemFromArray($array)
1185
- {
1186
- if (isset($array['sections']) && !is_array($array['sections'])) {
1187
- if (empty($array['sections'])) {
1188
- $array['sections'] = array();
1189
- } else {
1190
- $array['sections'] = array($array['sections']);
1191
- }
1192
- }
1193
- $params = array_merge(self::getDefaultArrayParams(), $array);
1194
- $result = new self($params['shortMsg'], $params['level'], $params['longMsg'], $params['sections'], $params['faqLink'], $params['priority'], $params['open'], $params['longMsgMode']);
1195
- return $result;
1196
- }
1197
-
1198
- /**
1199
- *
1200
- * @return array [
1201
- * 'shortMsg' => text,
1202
- * 'level' => level,
1203
- * 'longMsg' => html text,
1204
- * 'sections' => string|string[],
1205
- * 'faqLink' => [
1206
- * 'url' => external link
1207
- * 'label' => link text if empty get external url link
1208
- * ],
1209
- * priority
1210
- * open
1211
- * longMsgMode
1212
- * ]
1213
- */
1214
- public static function getDefaultArrayParams()
1215
- {
1216
- return array(
1217
- 'shortMsg' => '',
1218
- 'level' => self::INFO,
1219
- 'longMsg' => '',
1220
- 'sections' => array(),
1221
- 'faqLink' => null,
1222
- 'priority' => 10,
1223
- 'open' => false,
1224
- 'longMsgMode' => self::MSG_MODE_DEFAULT
1225
- );
1226
- }
1227
-
1228
- /**
1229
- * before lower priority
1230
- * before highest level
1231
- *
1232
- * @param DUPX_NOTICE_ITEM $a
1233
- * @param DUPX_NOTICE_ITEM $b
1234
- */
1235
- public static function sortNoticeForPriorityAndLevel($a, $b)
1236
- {
1237
- if ($a->priority == $b->priority) {
1238
- if ($a->level == $b->level) {
1239
- return 0;
1240
- } else if ($a->level < $b->level) {
1241
- return 1;
1242
- } else {
1243
- return -1;
1244
- }
1245
- } else if ($a->priority < $b->priority) {
1246
- return -1;
1247
- } else {
1248
- return 1;
1249
- }
1250
- }
 
1251
  }
1
+ <?php
2
+ /**
3
+ * Notice manager
4
+ *
5
+ * Standard: PSR-2
6
+ * @link http://www.php-fig.org/psr/psr-2 Full Documentation
7
+ *
8
+ * @package SC\DUPX\U
9
+ *
10
+ */
11
+ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
12
+
13
+ /**
14
+ * Notice manager
15
+ * singleton class
16
+ */
17
+ final class DUPX_NOTICE_MANAGER
18
+ {
19
+ const ADD_NORMAL = 0; // add notice in list
20
+ const ADD_UNIQUE = 1; // add if unique id don't exists
21
+ const ADD_UNIQUE_UPDATE = 2; // add or update notice unique id
22
+ const ADD_UNIQUE_APPEND = 3; // append long msg
23
+ const ADD_UNIQUE_APPEND_IF_EXISTS = 4; // append long msg if already exists item
24
+ const ADD_UNIQUE_PREPEND = 5; // append long msg
25
+ const ADD_UNIQUE_PREPEND_IF_EXISTS = 6; // prepend long msg if already exists item
26
+ const DEFAULT_UNIQUE_ID_PREFIX = '__auto_unique_id__';
27
+
28
+ private static $uniqueCountId = 0;
29
+
30
+ /**
31
+ *
32
+ * @var DUPX_NOTICE_ITEM[]
33
+ */
34
+ private $nextStepNotices = array();
35
+
36
+ /**
37
+ *
38
+ * @var DUPX_NOTICE_ITEM[]
39
+ */
40
+ private $finalReporNotices = array();
41
+
42
+ /**
43
+ *
44
+ * @var DUPX_NOTICE_MANAGER
45
+ */
46
+ private static $instance = null;
47
+
48
+ /**
49
+ *
50
+ * @var string
51
+ */
52
+ private $persistanceFile = null;
53
+
54
+ /**
55
+ *
56
+ * @return DUPX_S_R_MANAGER
57
+ */
58
+ public static function getInstance()
59
+ {
60
+ if (is_null(self::$instance)) {
61
+ self::$instance = new self();
62
+ }
63
+
64
+ return self::$instance;
65
+ }
66
+
67
+ private function __construct()
68
+ {
69
+ $this->persistanceFile = $GLOBALS["NOTICES_FILE_PATH"];
70
+ $this->loadNotices();
71
+ }
72
+
73
+ /**
74
+ * save notices from json file
75
+ */
76
+ public function saveNotices()
77
+ {
78
+ $notices = array(
79
+ 'globalData' => array(
80
+ 'uniqueCountId' => self::$uniqueCountId
81
+ ),
82
+ 'nextStep' => array(),
83
+ 'finalReport' => array()
84
+ );
85
+
86
+ foreach ($this->nextStepNotices as $uniqueId => $notice) {
87
+ $notices['nextStep'][$uniqueId] = $notice->toArray();
88
+ }
89
+
90
+ foreach ($this->finalReporNotices as $uniqueId => $notice) {
91
+ $notices['finalReport'][$uniqueId] = $notice->toArray();
92
+ }
93
+
94
+ file_put_contents($this->persistanceFile, DupLiteSnapJsonU::wp_json_encode_pprint($notices));
95
+ }
96
+
97
+ /**
98
+ * load notice from json file
99
+ */
100
+ private function loadNotices()
101
+ {
102
+ if (file_exists($this->persistanceFile)) {
103
+ $json = file_get_contents($this->persistanceFile);
104
+ $notices = json_decode($json, true);
105
+
106
+ $this->nextStepNotices = array();
107
+ $this->finalReporNotices = array();
108
+
109
+ if (!empty($notices['nextStep'])) {
110
+ foreach ($notices['nextStep'] as $uniqueId => $notice) {
111
+ $this->nextStepNotices[$uniqueId] = DUPX_NOTICE_ITEM::getItemFromArray($notice);
112
+ }
113
+ }
114
+
115
+ if (!empty($notices['finalReport'])) {
116
+ foreach ($notices['finalReport'] as $uniqueId => $notice) {
117
+ $this->finalReporNotices[$uniqueId] = DUPX_NOTICE_ITEM::getItemFromArray($notice);
118
+ }
119
+ }
120
+
121
+ self::$uniqueCountId = $notices['globalData']['uniqueCountId'];
122
+ } else {
123
+ $this->resetNotices();
124
+ }
125
+ }
126
+
127
+ /**
128
+ * remove all notices and save reset file
129
+ */
130
+ public function resetNotices()
131
+ {
132
+ $this->nextStepNotices = array();
133
+ $this->finalReporNotices = array();
134
+ self::$uniqueCountId = 0;
135
+ $this->saveNotices();
136
+ }
137
+
138
+ /**
139
+ * return next step notice by id
140
+ *
141
+ * @param string $id
142
+ * @return DUPX_NOTICE_ITEM
143
+ */
144
+ public function getNextStepNoticeById($id)
145
+ {
146
+ if (isset($this->nextStepNotices[$id])) {
147
+ return $this->nextStepNotices[$id];
148
+ } else {
149
+ return null;
150
+ }
151
+ }
152
+
153
+ /**
154
+ * return last report notice by id
155
+ *
156
+ * @param string $id
157
+ * @return DUPX_NOTICE_ITEM
158
+ */
159
+ public function getFinalReporNoticeById($id)
160
+ {
161
+ if (isset($this->finalReporNotices[$id])) {
162
+ return $this->finalReporNotices[$id];
163
+ } else {
164
+ return null;
165
+ }
166
+ }
167
+
168
+ /**
169
+ *
170
+ * @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
171
+ * // if array must be [
172
+ * 'shortMsg' => text,
173
+ * 'level' => level,
174
+ * 'longMsg' => html text,
175
+ * 'sections' => sections list,
176
+ * 'faqLink' => [
177
+ * 'url' => external link
178
+ * 'label' => link text if empty get external url link
179
+ * ]
180
+ * ]
181
+ * @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
182
+ * @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
183
+ *
184
+ * @return string // notice insert id
185
+ *
186
+ * @throws Exception
187
+ */
188
+ public function addBothNextAndFinalReportNotice($item, $mode = self::ADD_NORMAL, $uniqueId = null)
189
+ {
190
+ $this->addNextStepNotice($item, $mode, $uniqueId);
191
+ $this->addFinalReportNotice($item, $mode, $uniqueId);
192
+ }
193
+
194
+ /**
195
+ *
196
+ * @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
197
+ * // if array must be [
198
+ * 'shortMsg' => text,
199
+ * 'level' => level,
200
+ * 'longMsg' => html text,
201
+ * 'sections' => sections list,
202
+ * 'faqLink' => [
203
+ * 'url' => external link
204
+ * 'label' => link text if empty get external url link
205
+ * ]
206
+ * ]
207
+ * @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
208
+ * @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
209
+ *
210
+ * @return string // notice insert id
211
+ *
212
+ * @throws Exception
213
+ */
214
+ public function addNextStepNotice($item, $mode = self::ADD_NORMAL, $uniqueId = null)
215
+ {
216
+ if (!is_array($item) && !($item instanceof DUPX_NOTICE_ITEM)) {
217
+ throw new Exception('Invalid item param');
218
+ }
219
+ return self::addReportNoticeToList($this->nextStepNotices, $item, $mode, $uniqueId);
220
+ }
221
+
222
+ /**
223
+ * addNextStepNotice wrapper to add simple message with error level
224
+ *
225
+ * @param string $message
226
+ * @param int $level // warning level
227
+ * @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
228
+ * @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
229
+ *
230
+ * @return string // notice insert id
231
+ *
232
+ * @throws Exception
233
+ */
234
+ public function addNextStepNoticeMessage($message, $level = DUPX_NOTICE_ITEM::INFO, $mode = self::ADD_NORMAL, $uniqueId = null)
235
+ {
236
+ return $this->addNextStepNotice(array(
237
+ 'shortMsg' => $message,
238
+ 'level' => $level,
239
+ ), $mode, $uniqueId);
240
+ }
241
+
242
+ /**
243
+ *
244
+ * @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
245
+ * // if array must be [
246
+ * 'shortMsg' => text,
247
+ * 'level' => level,
248
+ * 'longMsg' => html text,
249
+ * 'sections' => sections list,
250
+ * 'faqLink' => [
251
+ * 'url' => external link
252
+ * 'label' => link text if empty get external url link
253
+ * ]
254
+ * ]
255
+ * @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
256
+ * @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
257
+ *
258
+ * @return string // notice insert id
259
+ *
260
+ * @throws Exception
261
+ */
262
+ public function addFinalReportNotice($item, $mode = self::ADD_NORMAL, $uniqueId = null)
263
+ {
264
+ if (!is_array($item) && !($item instanceof DUPX_NOTICE_ITEM)) {
265
+ throw new Exception('Invalid item param');
266
+ }
267
+ return self::addReportNoticeToList($this->finalReporNotices, $item, $mode, $uniqueId);
268
+ }
269
+
270
+ /**
271
+ * addFinalReportNotice wrapper to add simple message with error level
272
+ *
273
+ * @param string $message
274
+ * @param string|string[] $sections // message sections on final report
275
+ * @param int $level // warning level
276
+ * @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
277
+ * @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
278
+ *
279
+ * @return string // notice insert id
280
+ *
281
+ * @throws Exception
282
+ */
283
+ public function addFinalReportNoticeMessage($message, $sections, $level = DUPX_NOTICE_ITEM::INFO, $mode = self::ADD_NORMAL, $uniqueId = null)
284
+ {
285
+ return $this->addFinalReportNotice(array(
286
+ 'shortMsg' => $message,
287
+ 'level' => $level,
288
+ 'sections' => $sections,
289
+ ), $mode, $uniqueId);
290
+ }
291
+
292
+ /**
293
+ *
294
+ * @param array $list
295
+ * @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
296
+ * // if array must be [
297
+ * 'shortMsg' => text,
298
+ * 'level' => level,
299
+ * 'longMsg' => html text,
300
+ * 'sections' => sections list,
301
+ * 'faqLink' => [
302
+ * 'url' => external link
303
+ * 'label' => link text if empty get external url link
304
+ * ]
305
+ * ]
306
+ * @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
307
+ * @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
308
+ *
309
+ * @return string // notice insert id
310
+ *
311
+ * @throws Exception
312
+ */
313
+ private static function addReportNoticeToList(&$list, $item, $mode = self::ADD_NORMAL, $uniqueId = null)
314
+ {
315
+ switch ($mode) {
316
+ case self::ADD_UNIQUE:
317
+ if (empty($uniqueId)) {
318
+ throw new Exception('uniqueId can\'t be empty');
319
+ }
320
+ if (isset($list[$uniqueId])) {
321
+ return $uniqueId;
322
+ }
323
+ // no break -> continue on unique update
324
+ case self::ADD_UNIQUE_UPDATE:
325
+ if (empty($uniqueId)) {
326
+ throw new Exception('uniqueId can\'t be empty');
327
+ }
328
+ $insertId = $uniqueId;
329
+ break;
330
+ case self::ADD_UNIQUE_APPEND_IF_EXISTS:
331
+ if (empty($uniqueId)) {
332
+ throw new Exception('uniqueId can\'t be empty');
333
+ }
334
+ if (!isset($list[$uniqueId])) {
335
+ return false;
336
+ }
337
+ // no break
338
+ case self::ADD_UNIQUE_APPEND:
339
+ if (empty($uniqueId)) {
340
+ throw new Exception('uniqueId can\'t be empty');
341
+ }
342
+ $insertId = $uniqueId;
343
+ // if item id exist append long msg
344
+ if (isset($list[$uniqueId])) {
345
+ $tempObj = self::getObjFromParams($item);
346
+ $list[$uniqueId]->longMsg .= $tempObj->longMsg;
347
+ $item = $list[$uniqueId];
348
+ }
349
+ break;
350
+ case self::ADD_UNIQUE_PREPEND_IF_EXISTS:
351
+ if (empty($uniqueId)) {
352
+ throw new Exception('uniqueId can\'t be empty');
353
+ }
354
+ if (!isset($list[$uniqueId])) {
355
+ return false;
356
+ }
357
+ // no break
358
+ case self::ADD_UNIQUE_PREPEND:
359
+ if (empty($uniqueId)) {
360
+ throw new Exception('uniqueId can\'t be empty');
361
+ }
362
+ $insertId = $uniqueId;
363
+ // if item id exist append long msg
364
+ if (isset($list[$uniqueId])) {
365
+ $tempObj = self::getObjFromParams($item);
366
+ $list[$uniqueId]->longMsg = $tempObj->longMsg.$list[$uniqueId]->longMsg;
367
+ $item = $list[$uniqueId];
368
+ }
369
+ break;
370
+ case self::ADD_NORMAL:
371
+ default:
372
+ if (empty($uniqueId)) {
373
+ $insertId = self::getNewAutoUniqueId();
374
+ } else {
375
+ $insertId = $uniqueId;
376
+ }
377
+ }
378
+
379
+ $list[$insertId] = self::getObjFromParams($item);
380
+ return $insertId;
381
+ }
382
+
383
+ /**
384
+ *
385
+ * @param string|array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
386
+ * // if array must be [
387
+ * 'shortMsg' => text,
388
+ * 'level' => level,
389
+ * 'longMsg' => html text,
390
+ * 'sections' => sections list,
391
+ * 'faqLink' => [
392
+ * 'url' => external link
393
+ * 'label' => link text if empty get external url link
394
+ * ]
395
+ * ]
396
+ * @param int $level message level considered only in the case where $item is a string.
397
+ * @return \DUPX_NOTICE_ITEM
398
+ *
399
+ * @throws Exception
400
+ */
401
+ private static function getObjFromParams($item, $level = DUPX_NOTICE_ITEM::INFO)
402
+ {
403
+ if ($item instanceof DUPX_NOTICE_ITEM) {
404
+ $newObj = $item;
405
+ } else if (is_array($item)) {
406
+ $newObj = DUPX_NOTICE_ITEM::getItemFromArray($item);
407
+ } else if (is_string($item)) {
408
+ $newObj = new DUPX_NOTICE_ITEM($item, $level);
409
+ } else {
410
+ throw new Exception('Notice input not valid');
411
+ }
412
+
413
+ return $newObj;
414
+ }
415
+
416
+ /**
417
+ *
418
+ * @param null|string $section if null is count global
419
+ * @param int $level error level
420
+ * @param string $operator > < >= <= = !=
421
+ *
422
+ * @return int
423
+ */
424
+ public function countFinalReportNotices($section = null, $level = DUPX_NOTICE_ITEM::INFO, $operator = '>=')
425
+ {
426
+ $result = 0;
427
+ foreach ($this->finalReporNotices as $notice) {
428
+ if (is_null($section) || in_array($section, $notice->sections)) {
429
+ switch ($operator) {
430
+ case '>=':
431
+ $result += (int) ($notice->level >= $level);
432
+ break;
433
+ case '>':
434
+ $result += (int) ($notice->level > $level);
435
+ break;
436
+ case '=':
437
+ $result += (int) ($notice->level = $level);
438
+ break;
439
+ case '<=':
440
+ $result += (int) ($notice->level <= $level);
441
+ break;
442
+ case '<':
443
+ $result += (int) ($notice->level < $level);
444
+ break;
445
+ case '!=':
446
+ $result += (int) ($notice->level != $level);
447
+ break;
448
+ }
449
+ }
450
+ }
451
+ return $result;
452
+ }
453
+
454
+ /**
455
+ * sort final report notice from priority and notice level
456
+ */
457
+ public function sortFinalReport()
458
+ {
459
+ uasort($this->finalReporNotices, 'DUPX_NOTICE_ITEM::sortNoticeForPriorityAndLevel');
460
+ }
461
+
462
+ /**
463
+ * display final final report notice section
464
+ *
465
+ * @param string $section
466
+ */
467
+ public function displayFinalReport($section)
468
+ {
469
+ foreach ($this->finalReporNotices as $id => $notice) {
470
+ if (in_array($section, $notice->sections)) {
471
+ self::finalReportNotice($id, $notice);
472
+ }
473
+ }
474
+ }
475
+
476
+ /**
477
+ *
478
+ * @param string $section
479
+ * @param string $title
480
+ */
481
+ public function displayFinalRepostSectionHtml($section, $title)
482
+ {
483
+ if ($this->haveSection($section)) {
484
+ ?>
485
+ <div id="report-section-<?php echo $section; ?>" class="section" >
486
+ <div class="section-title" ><?php echo $title; ?></div>
487
+ <div class="section-content">
488
+ <?php
489
+ $this->displayFinalReport($section);
490
+ ?>
491
+ </div>
492
+ </div>
493
+ <?php
494
+ }
495
+ }
496
+
497
+ /**
498
+ *
499
+ * @param string $section
500
+ * @return boolean
501
+ */
502
+ public function haveSection($section)
503
+ {
504
+ foreach ($this->finalReporNotices as $notice) {
505
+ if (in_array($section, $notice->sections)) {
506
+ return true;
507
+ }
508
+ }
509
+ return false;
510
+ }
511
+
512
+ /**
513
+ *
514
+ * @param null|string $section if null is a global result
515
+ *
516
+ * @return int // returns the worst level found
517
+ *
518
+ */
519
+ public function getSectionErrLevel($section = null)
520
+ {
521
+ $result = DUPX_NOTICE_ITEM::INFO;
522
+
523
+ foreach ($this->finalReporNotices as $notice) {
524
+ if (is_null($section) || in_array($section, $notice->sections)) {
525
+ $result = max($result, $notice->level);
526
+ }
527
+ }
528
+ return $result;
529
+ }
530
+
531
+ /**
532
+ *
533
+ * @param string $section
534
+ * @param bool $echo
535
+ * @return void|string
536
+ */
537
+ public function getSectionErrLevelHtml($section = null, $echo = true)
538
+ {
539
+ return self::getErrorLevelHtml($this->getSectionErrLevel($section), $echo);
540
+ }
541
+
542
+ /**
543
+ * Displa next step notice message
544
+ *
545
+ * @param bool $deleteListAfterDisaply
546
+ * @return void
547
+ */
548
+ public function displayStepMessages($deleteListAfterDisaply = true)
549
+ {
550
+ if (empty($this->nextStepNotices)) {
551
+ return;
552
+ }
553
+ ?>
554
+ <div id="step-messages">
555
+ <?php
556
+ foreach ($this->nextStepNotices as $notice) {
557
+ self::stepMsg($notice);
558
+ }
559
+ ?>
560
+ </div>
561
+ <?php
562
+ if ($deleteListAfterDisaply) {
563
+ $this->nextStepNotices = array();
564
+ $this->saveNotices();
565
+ }
566
+ }
567
+
568
+ /**
569
+ *
570
+ * @param DUPX_NOTICE_ITEM $notice
571
+ */
572
+ private static function stepMsg($notice)
573
+ {
574
+ $classes = array(
575
+ 'notice',
576
+ 'next-step',
577
+ self::getClassFromLevel($notice->level)
578
+ );
579
+ $haveContent = !empty($notice->faqLink) || !empty($notice->longMsg);
580
+ ?>
581
+ <div class="<?php echo implode(' ', $classes); ?>">
582
+ <div class="title">
583
+ <?php echo self::getNextStepLevelPrefixMessage($notice->level).': <b>'.htmlentities($notice->shortMsg).'</b>'; ?>
584
+ </div>
585
+ <?php if ($haveContent) { ?>
586
+ <div class="title-separator" ></div>
587
+ <?php
588
+ ob_start();
589
+ if (!empty($notice->faqLink)) {
590
+ ?>
591
+ See FAQ: <a href="<?php echo $notice->faqLink['url']; ?>" >
592
+ <b><?php echo htmlentities(empty($notice->faqLink['label']) ? $notice->faqLink['url'] : $notice->faqLink['label']); ?></b>
593
+ </a>
594
+ <?php
595
+ }
596
+ if (!empty($notice->faqLink) && !empty($notice->longMsg)) {
597
+ echo '<br><br>';
598
+ }
599
+ if (!empty($notice->longMsg)) {
600
+ switch ($notice->longMsgMode) {
601
+ case DUPX_NOTICE_ITEM::MSG_MODE_PRE:
602
+ echo '<pre>'.htmlentities($notice->longMsg).'</pre>';
603
+ break;
604
+ case DUPX_NOTICE_ITEM::MSG_MODE_HTML:
605
+ echo $notice->longMsg;
606
+ break;
607
+ case DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT:
608
+ default:
609
+ echo htmlentities($notice->longMsg);
610
+ }
611
+ }
612
+ $longContent = ob_get_clean();
613
+ DUPX_U_Html::getMoreContent($longContent, 'info', 200);
614
+ }
615
+ ?>
616
+ </div>
617
+ <?php
618
+ }
619
+
620
+ /**
621
+ *
622
+ * @param string $id
623
+ * @param DUPX_NOTICE_ITEM $notice
624
+ */
625
+ private static function finalReportNotice($id, $notice)
626
+ {
627
+ $classes = array(
628
+ 'notice-report',
629
+ 'notice',
630
+ self::getClassFromLevel($notice->level)
631
+ );
632
+ $haveContent = !empty($notice->faqLink) || !empty($notice->longMsg);
633
+ $contentId = 'notice-content-'.$id;
634
+ $iconClasses = $haveContent ? 'fa fa-caret-right' : 'fa fa-toggle-empty';
635
+ $toggleLinkData = $haveContent ? 'data-type="toggle" data-target="#'.$contentId.'"' : '';
636
+ ?>
637
+ <div class="<?php echo implode(' ', $classes); ?>">
638
+ <div class="title" <?php echo $toggleLinkData; ?>>
639
+ <i class="<?php echo $iconClasses; ?>"></i> <?php echo htmlentities($notice->shortMsg); ?>
640
+ </div>
641
+ <?php
642
+ if ($haveContent) {
643
+ $infoClasses = array('info');
644
+ if (!$notice->open) {
645
+ $infoClasses[] = 'no-display';
646
+ }
647
+ ?>
648
+ <div id="<?php echo $contentId; ?>" class="<?php echo implode(' ', $infoClasses); ?>" >
649
+ <?php
650
+ if (!empty($notice->faqLink)) {
651
+ ?>
652
+ <b>See FAQ</b>: <a href="<?php echo $notice->faqLink['url']; ?>" >
653
+ <?php echo htmlentities(empty($notice->faqLink['label']) ? $notice->faqLink['url'] : $notice->faqLink['label']); ?>
654
+ </a>
655
+ <?php
656
+ }
657
+ if (!empty($notice->faqLink) && !empty($notice->longMsg)) {
658
+ echo '<br><br>';
659
+ }
660
+ if (!empty($notice->longMsg)) {
661
+ switch ($notice->longMsgMode) {
662
+ case DUPX_NOTICE_ITEM::MSG_MODE_PRE:
663
+ echo '<pre>'.htmlentities($notice->longMsg).'</pre>';
664
+ break;
665
+ case DUPX_NOTICE_ITEM::MSG_MODE_HTML:
666
+ echo $notice->longMsg;
667
+ break;
668
+ case DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT:
669
+ default:
670
+ echo htmlentities($notice->longMsg);
671
+ }
672
+ }
673
+ ?>
674
+ </div>
675
+ <?php
676
+ }
677
+ ?>
678
+ </div>
679
+ <?php
680
+ }
681
+
682
+ /**
683
+ *
684
+ * @param DUPX_NOTICE_ITEM $notice
685
+ */
686
+ private static function noticeToText($notice)
687
+ {
688
+ $result = '-----------------------'."\n".
689
+ '['.self::getNextStepLevelPrefixMessage($notice->level, false).'] '.$notice->shortMsg;
690
+
691
+ if (!empty($notice->sections)) {
692
+ $result .= "\n\t".'SECTIONS: '.implode(',', $notice->sections);
693
+ }
694
+ if (!empty($notice->longMsg)) {
695
+ $result .= "\n\t".'LONG MSG: '.$notice->longMsg;
696
+ }
697
+ return $result."\n";
698
+ }
699
+
700
+ public function nextStepLog()
701
+ {
702
+ if (!empty($this->nextStepNotices)) {
703
+ DUPX_Log::info(
704
+ '===================================='."\n".
705
+ 'NEXT STEP NOTICES'."\n".
706
+ '====================================');
707
+ foreach ($this->nextStepNotices as $notice) {
708
+ DUPX_Log::info(self::noticeToText($notice));
709
+ }
710
+ DUPX_Log::info(
711
+ '====================================');
712
+ }
713
+ }
714
+
715
+ public function finalReportLog($sections = array())
716
+ {
717
+ if (!empty($this->finalReporNotices)) {
718
+ DUPX_Log::info(
719
+ '===================================='."\n".
720
+ 'FINAL REPORT NOTICES LIST'."\n".
721
+ '====================================');
722
+ foreach ($this->finalReporNotices as $notice) {
723
+ if (count(array_intersect($notice->sections, $sections)) > 0) {
724
+ DUPX_Log::info(self::noticeToText($notice));
725
+ }
726
+ }
727
+ DUPX_Log::info(
728
+ '====================================');
729
+ }
730
+ }
731
+
732
+ /**
733
+ * get html class from level
734
+ *
735
+ * @param int $level
736
+ * @return string
737
+ */
738
+ private static function getClassFromLevel($level)
739
+ {
740
+ switch ($level) {
741
+ case DUPX_NOTICE_ITEM::INFO:
742
+ return 'l-info';
743
+ case DUPX_NOTICE_ITEM::NOTICE:
744
+ return 'l-notice';
745
+ case DUPX_NOTICE_ITEM::SOFT_WARNING:
746
+ return 'l-swarning';
747
+ case DUPX_NOTICE_ITEM::HARD_WARNING:
748
+ return 'l-hwarning';
749
+ case DUPX_NOTICE_ITEM::CRITICAL:
750
+ return 'l-critical';
751
+ case DUPX_NOTICE_ITEM::FATAL:
752
+ return 'l-fatal';
753
+ }
754
+ }
755
+
756
+ /**
757
+ * get level label from level
758
+ *
759
+ * @param int $level
760
+ * @param bool $echo
761
+ * @return type
762
+ */
763
+ public static function getErrorLevelHtml($level, $echo = true)
764
+ {
765
+ switch ($level) {
766
+ case DUPX_NOTICE_ITEM::INFO:
767
+ $label = 'good';
768
+ break;
769
+ case DUPX_NOTICE_ITEM::NOTICE:
770
+ $label = 'good';
771
+ break;
772
+ case DUPX_NOTICE_ITEM::SOFT_WARNING:
773
+ $label = 'warning';
774
+ break;
775
+ case DUPX_NOTICE_ITEM::HARD_WARNING:
776
+ $label = 'warning';
777
+ break;
778
+ case DUPX_NOTICE_ITEM::CRITICAL:
779
+ $label = 'critical error';
780
+ break;
781
+ case DUPX_NOTICE_ITEM::FATAL:
782
+ $label = 'fatal error';
783
+ break;
784
+ default:
785
+ return;
786
+ }
787
+ $classes = self::getClassFromLevel($level);
788
+ ob_start();
789
+ ?>
790
+ <span class="notice-level-status <?php echo $classes; ?>"><?php echo $label; ?></span>
791
+ <?php
792
+ if ($echo) {
793
+ ob_end_flush();
794
+ } else {
795
+ return ob_get_clean();
796
+ }
797
+ }
798
+
799
+ /**
800
+ * get next step message prefix
801
+ *
802
+ * @param int $level
803
+ * @param bool $echo
804
+ * @return string
805
+ */
806
+ public static function getNextStepLevelPrefixMessage($level, $echo = true)
807
+ {
808
+ switch ($level) {
809
+ case DUPX_NOTICE_ITEM::INFO:
810
+ $label = 'INFO';
811
+ break;
812
+ case DUPX_NOTICE_ITEM::NOTICE:
813
+ $label = 'NOTICE';
814
+ break;
815
+ case DUPX_NOTICE_ITEM::SOFT_WARNING:
816
+ $label = 'WARNING';
817
+ break;
818
+ case DUPX_NOTICE_ITEM::HARD_WARNING:
819
+ $label = 'WARNING';
820
+ break;
821
+ case DUPX_NOTICE_ITEM::CRITICAL:
822
+ $label = 'CRITICAL ERROR';
823
+ break;
824
+ case DUPX_NOTICE_ITEM::FATAL:
825
+ $label = 'FATAL ERROR';
826
+ break;
827
+ default:
828
+ return;
829
+ }
830
+
831
+ if ($echo) {
832
+ echo $label;
833
+ } else {
834
+ return $label;
835
+ }
836
+ }
837
+
838
+ /**
839
+ * get unique id
840
+ *
841
+ * @return string
842
+ */
843
+ private static function getNewAutoUniqueId()
844
+ {
845
+ self::$uniqueCountId ++;
846
+ return self::DEFAULT_UNIQUE_ID_PREFIX.self::$uniqueCountId;
847
+ }
848
+
849
+ /**
850
+ * function for internal test
851
+ *
852
+ * display all messages levels
853
+ */
854
+ public static function testNextStepMessaesLevels()
855
+ {
856
+ $manager = self::getInstance();
857
+ $manager->addNextStepNoticeMessage('Level info ('.DUPX_NOTICE_ITEM::INFO.')', DUPX_NOTICE_ITEM::INFO);
858
+ $manager->addNextStepNoticeMessage('Level notice ('.DUPX_NOTICE_ITEM::NOTICE.')', DUPX_NOTICE_ITEM::NOTICE);
859
+ $manager->addNextStepNoticeMessage('Level soft warning ('.DUPX_NOTICE_ITEM::SOFT_WARNING.')', DUPX_NOTICE_ITEM::SOFT_WARNING);
860
+ $manager->addNextStepNoticeMessage('Level hard warning ('.DUPX_NOTICE_ITEM::HARD_WARNING.')', DUPX_NOTICE_ITEM::HARD_WARNING);
861
+ $manager->addNextStepNoticeMessage('Level critical error ('.DUPX_NOTICE_ITEM::CRITICAL.')', DUPX_NOTICE_ITEM::CRITICAL);
862
+ $manager->addNextStepNoticeMessage('Level fatal error ('.DUPX_NOTICE_ITEM::FATAL.')', DUPX_NOTICE_ITEM::FATAL);
863
+ $manager->saveNotices();
864
+ }
865
+
866
+ /**
867
+ * test function
868
+ */
869
+ public static function testNextStepFullMessageData()
870
+ {
871
+ $manager = self::getInstance();
872
+ $longMsg = <<<LONGMSG
873
+ <b>Formattend long text</b><br>
874
+ <ul>
875
+ <li>Proin dapibus mi eu erat pulvinar, id congue nisl egestas.</li>
876
+ <li>Nunc venenatis eros et sapien ornare consequat.</li>
877
+ <li>Mauris tincidunt est sit amet turpis placerat, a tristique dui porttitor.</li>
878
+ <li>Etiam volutpat lectus quis risus molestie faucibus.</li>
879
+ <li>Integer gravida eros sit amet sem viverra, a volutpat neque rutrum.</li>
880
+ <li>Aenean varius ipsum vitae lorem tempus rhoncus.</li>
881
+ </ul>
882
+ LONGMSG;
883
+ $manager->addNextStepNotice(array(
884
+ 'shortMsg' => 'Full elements next step message MODE HTML',
885
+ 'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
886
+ 'longMsg' => $longMsg,
887
+ 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
888
+ 'faqLink' => array(
889
+ 'url' => 'http://www.google.it',
890
+ 'label' => 'google link'
891
+ )
892
+ ));
893
+
894
+ $longMsg = <<<LONGMSG
895
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc a auctor erat, et lobortis libero.
896
+ Suspendisse aliquet neque in massa posuere mollis. Donec venenatis finibus sapien in bibendum. Donec et ex massa.
897
+
898
+ Aliquam venenatis dapibus tellus nec ullamcorper. Mauris ante velit, tincidunt sit amet egestas et, mattis non lorem. In semper ex ut velit suscipit,
899
+ at luctus nunc dapibus. Etiam blandit maximus dapibus. Nullam eu porttitor augue. Suspendisse pulvinar, massa eget condimentum aliquet, dolor massa tempus dui, vel rhoncus tellus ligula non odio.
900
+ Ut ac faucibus tellus, in lobortis odio.
901
+ LONGMSG;
902
+ $manager->addNextStepNotice(array(
903
+ 'shortMsg' => 'Full elements next step message MODE PRE',
904
+ 'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
905
+ 'longMsg' => $longMsg,
906
+ 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_PRE,
907
+ 'faqLink' => array(
908
+ 'url' => 'http://www.google.it',
909
+ 'label' => 'google link'
910
+ )
911
+ ));
912
+
913
+ $longMsg = <<<LONGMSG
914
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc a auctor erat, et lobortis libero.
915
+ Suspendisse aliquet neque in massa posuere mollis. Donec venenatis finibus sapien in bibendum. Donec et ex massa.
916
+
917
+ Aliquam venenatis dapibus tellus nec ullamcorper. Mauris ante velit, tincidunt sit amet egestas et, mattis non lorem. In semper ex ut velit suscipit,
918
+ at luctus nunc dapibus. Etiam blandit maximus dapibus. Nullam eu porttitor augue. Suspendisse pulvinar, massa eget condimentum aliquet, dolor massa tempus dui, vel rhoncus tellus ligula non odio.
919
+ Ut ac faucibus tellus, in lobortis odio.
920
+ LONGMSG;
921
+ $manager->addNextStepNotice(array(
922
+ 'shortMsg' => 'Full elements next step message MODE DEFAULT',
923
+ 'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
924
+ 'longMsg' => $longMsg,
925
+ 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT,
926
+ 'faqLink' => array(
927
+ 'url' => 'http://www.google.it',
928
+ 'label' => 'google link'
929
+ )
930
+ ));
931
+
932
+
933
+ $longMsg = <<<LONGMSG
934
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam cursus porttitor consectetur. Nunc faucibus elementum nisl nec ornare. Phasellus sit amet urna in diam ultricies ornare nec sit amet nibh. Nulla a aliquet leo. Quisque aliquet posuere lectus sit amet commodo. Nullam tempus enim eget urna rutrum egestas. Aliquam eget lorem nisl. Nulla tincidunt massa erat. Phasellus lectus tellus, mollis sit amet aliquam in, dapibus quis metus. Nunc venenatis nulla vitae convallis accumsan.
935
+
936
+ Mauris eu ullamcorper metus. Aenean ultricies et turpis eget mollis. Aliquam auctor, elit scelerisque placerat pellentesque, quam augue fermentum lectus, vel pretium nisi justo sit amet ante. Donec blandit porttitor tempus. Duis vulputate nulla ut orci rutrum, et consectetur urna mollis. Sed at iaculis velit. Pellentesque id quam turpis. Curabitur eu ligula velit. Cras gravida, ipsum sed iaculis eleifend, mauris nunc posuere quam, vel blandit nisi justo congue ligula. Phasellus aliquam eu odio ac porttitor. Fusce dictum mollis turpis sit amet fringilla.
937
+
938
+ Nulla eu ligula mauris. Fusce lobortis ligula elit, a interdum nibh pulvinar eu. Pellentesque rhoncus nec turpis id blandit. Morbi fringilla, justo non varius consequat, arcu ante efficitur ante, sit amet cursus lorem elit vel odio. Phasellus neque ligula, vehicula vel ipsum sed, volutpat dignissim eros. Curabitur at lacus id felis elementum auctor. Nullam ac tempus nisi. Phasellus nibh purus, aliquam nec purus ut, sodales lobortis nulla. Cras viverra dictum magna, ac malesuada nibh dictum ac. Mauris euismod, magna sit amet pretium posuere, ligula nibh ultrices tellus, sit amet pretium odio urna egestas justo. Suspendisse purus erat, eleifend sed magna in, efficitur interdum nibh.
939
+
940
+ Vivamus nibh nunc, fermentum non tortor volutpat, consectetur vulputate velit. Phasellus lobortis, purus et faucibus mollis, metus eros viverra ante, sit amet euismod nibh est eu orci. Duis sodales cursus lacinia. Praesent laoreet ut ipsum ut interdum. Praesent venenatis massa vitae ligula consequat aliquet. Fusce in purus in odio molestie laoreet at ac augue. Fusce consectetur elit a magna mollis aliquet.
941
+
942
+ Nulla eros nisi, dapibus eget diam vitae, tincidunt blandit odio. Fusce interdum tellus nec varius condimentum. Fusce non magna a purus sodales imperdiet sit amet vitae ligula. Quisque viverra leo sit amet mi egestas, et posuere nunc tincidunt. Suspendisse feugiat malesuada urna sed tincidunt. Morbi a urna sed magna volutpat pellentesque sit amet ac mauris. Nulla sed ultrices dui. Etiam massa arcu, tempor ut erat at, cursus malesuada ipsum. Duis sit amet felis dolor.
943
+
944
+ Morbi gravida nisl nunc, vulputate iaculis risus vehicula non. Proin cursus, velit et laoreet consectetur, lacus libero sagittis lacus, quis accumsan odio lectus non erat. Aenean dolor lectus, euismod sit amet justo eget, dictum gravida nisl. Phasellus sed nunc non odio ullamcorper rhoncus non ut ipsum. Duis ante ligula, pellentesque sit amet imperdiet eget, congue vel dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Suspendisse luctus leo eget justo mollis, convallis convallis ex suscipit. Integer et justo eget odio lobortis sollicitudin. Pellentesque accumsan rhoncus augue, luctus suscipit ex accumsan nec. Maecenas lacinia consectetur risus at bibendum. Etiam venenatis purus lorem, sit amet elementum turpis tristique eu. Proin vulputate faucibus feugiat. Nunc vehicula congue odio consequat vulputate. Quisque bibendum augue id iaculis faucibus. Donec blandit cursus sem, eget accumsan orci commodo sed.
945
+
946
+ Suspendisse iaculis est quam, sed scelerisque purus tincidunt non. Cras hendrerit ante turpis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse purus ipsum, rutrum id sem in, venenatis laoreet metus. Aliquam ac bibendum mauris. Cras egestas rhoncus est, sed lacinia nibh vestibulum id. Proin diam quam, sagittis congue molestie ac, rhoncus et mauris. Phasellus massa neque, ornare vel erat a, rutrum pharetra arcu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi et nulla eget massa auctor fermentum. Quisque maximus tellus sed cursus cursus. Ut vehicula erat at purus aliquet, quis imperdiet dui sagittis. Nullam eget quam leo.
947
+
948
+ Nulla magna ipsum, congue nec dui ut, lacinia malesuada felis. Cras mattis metus non maximus venenatis. Aliquam euismod est vitae erat sollicitudin, at pellentesque augue sollicitudin. Curabitur euismod maximus cursus. In tortor dui, convallis sed sapien ac, varius congue metus. Nunc ullamcorper ac orci sit amet finibus. Vivamus molestie nibh vitae quam rhoncus, eu ultrices est molestie. Maecenas consectetur eu quam sit amet placerat.
949
+
950
+ Curabitur ut fermentum mauris. Donec et congue nibh. Sed cursus elit sit amet convallis varius. Donec malesuada porta odio condimentum varius. Pellentesque ornare tempor ante, ut volutpat nulla lobortis sed. Nunc congue aliquet erat ac elementum. Quisque a ex sit amet turpis placerat sagittis eget ac ligula. Etiam in augue malesuada, aliquam est non, lacinia justo. Vivamus tincidunt dolor orci, id dignissim lorem maximus at. Vivamus ligula mauris, venenatis vel nibh id, lacinia ultrices ipsum. Mauris cursus, urna ac rutrum aliquet, risus ipsum tincidunt purus, sit amet blandit nunc sem sit amet nibh.
951
+
952
+ Nam eleifend risus lacus, eu pharetra risus egestas eu. Maecenas hendrerit nisl in semper placerat. Vestibulum massa tellus, laoreet non euismod quis, sollicitudin id sapien. Morbi vel cursus metus. Aenean tincidunt nisi est, ut elementum est auctor id. Duis auctor elit leo, ac scelerisque risus suscipit et. Pellentesque lectus nisi, ultricies in elit sed, pulvinar iaculis massa. Morbi viverra eros mi, pretium facilisis neque egestas id. Curabitur non massa accumsan, porttitor sem vitae, ultricies lacus. Curabitur blandit nisl velit. Mauris sollicitudin ultricies purus sit amet placerat. Fusce ac neque sed leo venenatis laoreet ut non ex. Integer elementum rhoncus orci, eu maximus neque tempus eu. Curabitur euismod dignissim tellus, vitae lacinia metus. Mauris imperdiet metus vitae vulputate accumsan. Duis eget luctus nibh, sit amet finibus libero.
953
+
954
+ LONGMSG;
955
+ $manager->addNextStepNotice(array(
956
+ 'shortMsg' => 'Full elements LONG LONG',
957
+ 'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
958
+ 'longMsg' => $longMsg,
959
+ 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT,
960
+ 'faqLink' => array(
961
+ 'url' => 'http://www.google.it',
962
+ 'label' => 'google link'
963
+ )
964
+ ));
965
+
966
+
967
+
968
+
969
+ $manager->saveNotices();
970
+ }
971
+
972
+ /**
973
+ * test function
974
+ */
975
+ public static function testFinalReporMessaesLevels()
976
+ {
977
+ $section = 'general';
978
+
979
+ $manager = self::getInstance();
980
+ $manager->addFinalReportNoticeMessage('Level info ('.DUPX_NOTICE_ITEM::INFO.')', $section, DUPX_NOTICE_ITEM::INFO, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_0');
981
+ $manager->addFinalReportNoticeMessage('Level notice ('.DUPX_NOTICE_ITEM::NOTICE.')', $section, DUPX_NOTICE_ITEM::NOTICE, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_1');
982
+ $manager->addFinalReportNoticeMessage('Level soft warning ('.DUPX_NOTICE_ITEM::SOFT_WARNING.')', $section, DUPX_NOTICE_ITEM::SOFT_WARNING, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_2');
983
+ $manager->addFinalReportNoticeMessage('Level hard warning ('.DUPX_NOTICE_ITEM::HARD_WARNING.')', $section, DUPX_NOTICE_ITEM::HARD_WARNING, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_3');
984
+ $manager->addFinalReportNoticeMessage('Level critical error ('.DUPX_NOTICE_ITEM::CRITICAL.')', $section, DUPX_NOTICE_ITEM::CRITICAL, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_4');
985
+ $manager->addFinalReportNoticeMessage('Level fatal error ('.DUPX_NOTICE_ITEM::FATAL.')', $section, DUPX_NOTICE_ITEM::FATAL, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_5');
986
+ $manager->saveNotices();
987
+ }
988
+
989
+ /**
990
+ * test function
991
+ */
992
+ public static function testFinalReportFullMessages()
993
+ {
994
+ $section = 'general';
995
+ $manager = self::getInstance();
996
+
997
+ $longMsg = <<<LONGMSG
998
+ <b>Formattend long text</b><br>
999
+ <ul>
1000
+ <li>Proin dapibus mi eu erat pulvinar, id congue nisl egestas.</li>
1001
+ <li>Nunc venenatis eros et sapien ornare consequat.</li>
1002
+ <li>Mauris tincidunt est sit amet turpis placerat, a tristique dui porttitor.</li>
1003
+ <li>Etiam volutpat lectus quis risus molestie faucibus.</li>
1004
+ <li>Integer gravida eros sit amet sem viverra, a volutpat neque rutrum.</li>
1005
+ <li>Aenean varius ipsum vitae lorem tempus rhoncus.</li>
1006
+ </ul>
1007
+ LONGMSG;
1008
+
1009
+ $manager->addFinalReportNotice(array(
1010
+ 'shortMsg' => 'Full elements final report message',
1011
+ 'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
1012
+ 'longMsg' => $longMsg,
1013
+ 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
1014
+ 'sections' => $section,
1015
+ 'faqLink' => array(
1016
+ 'url' => 'http://www.google.it',
1017
+ 'label' => 'google link'
1018
+ )
1019
+ ), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_full_1');
1020
+
1021
+ $manager->addFinalReportNotice(array(
1022
+ 'shortMsg' => 'Full elements final report message info high priority',
1023
+ 'level' => DUPX_NOTICE_ITEM::INFO,
1024
+ 'longMsg' => $longMsg,
1025
+ 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
1026
+ 'sections' => $section,
1027
+ 'faqLink' => array(
1028
+ 'url' => 'http://www.google.it',
1029
+ 'label' => 'google link'
1030
+ ),
1031
+ 'priority' => 5
1032
+ ), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_full_2');
1033
+ $manager->saveNotices();
1034
+ }
1035
+
1036
+ //PHP 8 Requires method to be public
1037
+ public function __wakeup()
1038
+ {
1039
+ }
1040
+
1041
+ private function __clone()
1042
+ {
1043
+
1044
+ }
1045
+
1046
+ }
1047
+
1048
+ class DUPX_NOTICE_ITEM
1049
+ {
1050
+ const INFO = 0;
1051
+ const NOTICE = 1;
1052
+ const SOFT_WARNING = 2;
1053
+ const HARD_WARNING = 3;
1054
+ const CRITICAL = 4;
1055
+ const FATAL = 5;
1056
+ const MSG_MODE_DEFAULT = 'def';
1057
+ const MSG_MODE_HTML = 'html';
1058
+ const MSG_MODE_PRE = 'pre';
1059
+
1060
+ /**
1061
+ *
1062
+ * @var string text
1063
+ */
1064
+ public $shortMsg = '';
1065
+
1066
+ /**
1067
+ *
1068
+ * @var string html text
1069
+ */
1070
+ public $longMsg = '';
1071
+
1072
+ /**
1073
+ *
1074
+ * @var bool if true long msg can be html
1075
+ */
1076
+ public $longMsgMode = self::MSG_MODE_DEFAULT;
1077
+
1078
+ /**
1079
+ *
1080
+ * @var null|array // null = no faq link
1081
+ * array( 'label' => link text , 'url' => faq url)
1082
+ */
1083
+ public $faqLink = array(
1084
+ 'label' => '',
1085
+ 'url' => ''
1086
+ );
1087
+
1088
+ /**
1089
+ *
1090
+ * @var string[] notice sections for final report only
1091
+ */
1092
+ public $sections = array();
1093
+
1094
+ /**
1095
+ *
1096
+ * @var int
1097
+ */
1098
+ public $level = self::NOTICE;
1099
+
1100
+ /**
1101
+ *
1102
+ * @var int
1103
+ */
1104
+ public $priority = 10;
1105
+
1106
+ /**
1107
+ *
1108
+ * @var bool if true notice start open. For final report only
1109
+ */
1110
+ public $open = false;
1111
+
1112
+ /**
1113
+ *
1114
+ * @param string $shortMsg text
1115
+ * @param int $level
1116
+ * @param string $longMsg html text
1117
+ * @param string|string[] $sections
1118
+ * @param null|array $faqLink [
1119
+ * 'url' => external link
1120
+ * 'label' => link text if empty get external url link
1121
+ * ]
1122
+ * @param int priority
1123
+ * @param bool open
1124
+ * @param string longMsgMode MSG_MODE_DEFAULT | MSG_MODE_HTML | MSG_MODE_PRE
1125
+ */
1126
+ public function __construct($shortMsg, $level = self::INFO, $longMsg = '', $sections = array(), $faqLink = null, $priority = 10, $open = false, $longMsgMode = self::MSG_MODE_DEFAULT)
1127
+ {
1128
+ $this->shortMsg = (string) $shortMsg;
1129
+ $this->level = (int) $level;
1130
+ $this->longMsg = (string) $longMsg;
1131
+ $this->sections = is_array($sections) ? $sections : array($sections);
1132
+ $this->faqLink = $faqLink;
1133
+ $this->priority = $priority;
1134
+ $this->open = $open;
1135
+ $this->longMsgMode = $longMsgMode;
1136
+ }
1137
+
1138
+ /**
1139
+ *
1140
+ * @return array [
1141
+ * 'shortMsg' => text,
1142
+ * 'level' => level,
1143
+ * 'longMsg' => html text,
1144
+ * 'sections' => string|string[],
1145
+ * 'faqLink' => [
1146
+ * 'url' => external link
1147
+ * 'label' => link text if empty get external url link
1148
+ * ]
1149
+ * 'priority' => int low first
1150
+ * 'open' => if true the tab is opene on final report
1151
+ * 'longMsgMode'=> MSG_MODE_DEFAULT | MSG_MODE_HTML | MSG_MODE_PRE
1152
+ * ]
1153
+ */
1154
+ public function toArray()
1155
+ {
1156
+ return array(
1157
+ 'shortMsg' => $this->shortMsg,
1158
+ 'level' => $this->level,
1159
+ 'longMsg' => $this->longMsg,
1160
+ 'sections' => $this->sections,
1161
+ 'faqLink' => $this->faqLink,
1162
+ 'priority' => $this->priority,
1163
+ 'open' => $this->open,
1164
+ 'longMsgMode' => $this->longMsgMode
1165
+ );
1166
+ }
1167
+
1168
+ /**
1169
+ *
1170
+ * @return array [
1171
+ * 'shortMsg' => text,
1172
+ * 'level' => level,
1173
+ * 'longMsg' => html text,
1174
+ * 'sections' => string|string[],
1175
+ * 'faqLink' => [
1176
+ * 'url' => external link
1177
+ * 'label' => link text if empty get external url link
1178
+ * ],
1179
+ * priority
1180
+ * open
1181
+ * longMsgMode
1182
+ * ]
1183
+ * @return DUPX_NOTICE_ITEM
1184
+ */
1185
+ public static function getItemFromArray($array)
1186
+ {
1187
+ if (isset($array['sections']) && !is_array($array['sections'])) {
1188
+ if (empty($array['sections'])) {
1189
+ $array['sections'] = array();
1190
+ } else {
1191
+ $array['sections'] = array($array['sections']);
1192
+ }
1193
+ }
1194
+ $params = array_merge(self::getDefaultArrayParams(), $array);
1195
+ $result = new self($params['shortMsg'], $params['level'], $params['longMsg'], $params['sections'], $params['faqLink'], $params['priority'], $params['open'], $params['longMsgMode']);
1196
+ return $result;
1197
+ }
1198
+
1199
+ /**
1200
+ *
1201
+ * @return array [
1202
+ * 'shortMsg' => text,
1203
+ * 'level' => level,
1204
+ * 'longMsg' => html text,
1205
+ * 'sections' => string|string[],
1206
+ * 'faqLink' => [
1207
+ * 'url' => external link
1208
+ * 'label' => link text if empty get external url link
1209
+ * ],
1210
+ * priority
1211
+ * open
1212
+ * longMsgMode
1213
+ * ]
1214
+ */
1215
+ public static function getDefaultArrayParams()
1216
+ {
1217
+ return array(
1218
+ 'shortMsg' => '',
1219
+ 'level' => self::INFO,
1220
+ 'longMsg' => '',
1221
+ 'sections' => array(),
1222
+ 'faqLink' => null,
1223
+ 'priority' => 10,
1224
+ 'open' => false,
1225
+ 'longMsgMode' => self::MSG_MODE_DEFAULT
1226
+ );
1227
+ }
1228
+
1229
+ /**
1230
+ * before lower priority
1231
+ * before highest level
1232
+ *
1233
+ * @param DUPX_NOTICE_ITEM $a
1234
+ * @param DUPX_NOTICE_ITEM $b
1235
+ */
1236
+ public static function sortNoticeForPriorityAndLevel($a, $b)
1237
+ {
1238
+ if ($a->priority == $b->priority) {
1239
+ if ($a->level == $b->level) {
1240
+ return 0;
1241
+ } else if ($a->level < $b->level) {
1242
+ return 1;
1243
+ } else {
1244
+ return -1;
1245
+ }
1246
+ } else if ($a->priority < $b->priority) {
1247
+ return -1;
1248
+ } else {
1249
+ return 1;
1250
+ }
1251
+ }
1252
  }
installer/dup-installer/classes/utilities/class.u.php CHANGED
@@ -1,1791 +1,1791 @@
1
- <?php
2
- defined('ABSPATH') || defined('DUPXABSPATH') || exit;
3
-
4
- /**
5
- * Various Static Utility methods for working with the installer
6
- *
7
- * Standard: PSR-2
8
- * @link http://www.php-fig.org/psr/psr-2 Full Documentation
9
- *
10
- * @package SC\DUPX\U
11
- *
12
- */
13
- class DUPX_U
14
- {
15
- public static $on_php_53_plus;
16
-
17
- public static function init()
18
- {
19
- self::$on_php_53_plus = version_compare(PHP_VERSION, '5.3.2', '>=');
20
- }
21
-
22
- /**
23
- * Adds a slash to the end of a file or directory path
24
- *
25
- * @param string $path A path
26
- *
27
- * @return string The original $path with a with '/' added to the end.
28
- */
29
- public static function addSlash($path)
30
- {
31
- $last_char = substr($path, strlen($path) - 1, 1);
32
- if ($last_char != '/') {
33
- $path .= '/';
34
- }
35
- return $path;
36
- }
37
-
38
- /**
39
- * Add replacement strings with encoding to $GLOBALS['REPLACE_LIST']
40
- *
41
- * @param string $search
42
- * @param string $replace
43
- *
44
- */
45
- public static function queueReplacementWithEncodings($search, $replace)
46
- {
47
- array_push($GLOBALS['REPLACE_LIST'], array('search' => $search, 'replace' => $replace));
48
-
49
- $search_json = str_replace('"', "", DupLiteSnapJsonU::wp_json_encode($search));
50
- $replace_json = str_replace('"', "", DupLiteSnapJsonU::wp_json_encode($replace));
51
-
52
- if ($search != $search_json) {
53
- array_push($GLOBALS['REPLACE_LIST'], array('search' => $search_json, 'replace' => $replace_json));
54
- }
55
-
56
- $search_urlencode = urlencode($search);
57
- $replace_urlencode = urlencode($replace);
58
-
59
- if ($search != $search_urlencode) {
60
- array_push($GLOBALS['REPLACE_LIST'], array('search' => $search_urlencode, 'replace' => $replace_urlencode));
61
- }
62
- }
63
-
64
- /**
65
- * Add replace strings to substitute old url to new url
66
- * 1) no protocol old url to no protocol new url (es. //www.hold.url => //www.new.url)
67
- * 2) wrong protocol new url to right protocol new url (es. http://www.new.url => https://www.new.url)
68
- *
69
- * @param string $old
70
- * @param string $new
71
- */
72
- public static function replacmentUrlOldToNew($old, $new)
73
- {
74
- //SEARCH WITH NO PROTOCOL: RAW "//"
75
- $url_old_raw = str_ireplace(array('http://', 'https://'), '//', $old);
76
- $url_new_raw = str_ireplace(array('http://', 'https://'), '//', $new);
77
- DUPX_U::queueReplacementWithEncodings($url_old_raw, $url_new_raw);
78
-
79
- //FORCE NEW PROTOCOL "//"
80
- $url_new_info = parse_url($new);
81
- $url_new_domain = $url_new_info['scheme'].'://'.$url_new_info['host'];
82
-
83
- if ($url_new_info['scheme'] == 'http') {
84
- $url_new_wrong_protocol = 'https://'.$url_new_info['host'];
85
- } else {
86
- $url_new_wrong_protocol = 'http://'.$url_new_info['host'];
87
- }
88
- DUPX_U::queueReplacementWithEncodings($url_new_wrong_protocol, $url_new_domain);
89
- }
90
-
91
- /**
92
- * Does one string contain other
93
- *
94
- * @param string $haystack The full string to search
95
- * @param string $needle The substring to search on
96
- *
97
- * @return bool Returns true if the $needle was found in the $haystack
98
- */
99
- public static function contains($haystack, $needle)
100
- {
101
- $pos = strpos($haystack, $needle);
102
- return ($pos !== false);
103
- }
104
-
105
- /**
106
- * Recursively copy files from one directory to another
107
- *
108
- * @param string $src - Source of files being moved
109
- * @param string $dest - Destination of files being moved
110
- * @param string $recursive recursively remove all items
111
- *
112
- * @return bool Returns true if all content was copied
113
- */
114
- public static function copyDirectory($src, $dest, $recursive = true)
115
- {
116
- //RSR TODO:Verify this logic
117
- $success = true;
118
-
119
- // If source is not a directory stop processing
120
- if (!is_dir($src)) {
121
- return false;
122
- }
123
-
124
- // If the destination directory does not exist create it
125
- if (!DupLiteSnapLibIOU::dirWriteCheckOrMkdir($dest, 'u+rwx')) {
126
- // If the destination directory could not be created stop processing
127
- return false;
128
- }
129
-
130
- // Open the source directory to read in files
131
- $iterator = new DirectoryIterator($src);
132
-
133
- foreach ($iterator as $file) {
134
- if ($file->isFile()) {
135
- $success = copy($file->getRealPath(), "$dest/".$file->getFilename());
136
- } else if (!$file->isDot() && $file->isDir() && $recursive) {
137
- $success = self::copyDirectory($file->getRealPath(), "$dest/$file", $recursive);
138
- }
139
-
140
- if (!$success) {
141
- break;
142
- }
143
- }
144
-
145
- return $success;
146
- }
147
-
148
- /**
149
- * Check to see if the internet is accessible
150
- *
151
- * Note: fsocketopen on windows doesn't seem to honor $timeout setting.
152
- *
153
- * @param string $url A url e.g without prefix "ajax.googleapis.com"
154
- * @param string $port A valid port number
155
- *
156
- * @return bool Returns true PHP can request the URL
157
- */
158
- public static function isURLActive($url, $port, $timeout = 5)
159
- {
160
- $exists = false;
161
- if (function_exists('get_headers')) {
162
- $url = is_integer($port) ? $url . ':' . $port : $url;
163
- DUPX_Handler::setMode(DUPX_Handler::MODE_OFF);
164
- if (DupLiteSnapLibUtil::wp_is_ini_value_changeable('default_socket_timeout')) {
165
- @ini_set("default_socket_timeout", $timeout);
166
- }
167
- $headers = @get_headers($url);
168
- DUPX_Handler::setMode();
169
- if (is_array($headers) && strpos($headers[0], '404') === false) {
170
- $exists = true;
171
- }
172
- } else {
173
- if (function_exists('fsockopen')) {
174
- if (DupLiteSnapLibUtil::wp_is_ini_value_changeable('default_socket_timeout')) {
175
- @ini_set("default_socket_timeout", $timeout);
176
- }
177
- $port = isset($port) && is_integer($port) ? $port : 80;
178
- $host = parse_url($url, PHP_URL_HOST);
179
- $connected = @fsockopen($host, $port, $errno, $errstr, $timeout); //website and port
180
- if ($connected) {
181
- @fclose($connected);
182
- $exists = true;
183
- }
184
- }
185
- }
186
- return $exists;
187
- }
188
-
189
- /**
190
- * move all folder content up to parent
191
- *
192
- * @param string $subFolderName full path
193
- * @param boolean $deleteSubFolder if true delete subFolder after moved all
194
- * @return boolean
195
- *
196
- */
197
- public static function moveUpfromSubFolder($subFolderName, $deleteSubFolder = false)
198
- {
199
- if (!is_dir($subFolderName)) {
200
- return false;
201
- }
202
-
203
- $parentFolder = dirname($subFolderName);
204
- if (!is_writable($parentFolder)) {
205
- return false;
206
- }
207
-
208
- $success = true;
209
- if (($subList = glob(rtrim($subFolderName, '/').'/*', GLOB_NOSORT)) === false) {
210
- DUPX_Log::info("Problem glob folder ".$subFolderName);
211
- return false;
212
- } else {
213
- foreach ($subList as $cName) {
214
- $destination = $parentFolder.'/'.basename($cName);
215
- if (file_exists($destination)) {
216
- $success = self::deletePath($destination);
217
- }
218
-
219
- if ($success) {
220
- $success = rename($cName, $destination);
221
- } else {
222
- break;
223
- }
224
- }
225
-
226
- if ($success && $deleteSubFolder) {
227
- $success = self::deleteDirectory($subFolderName, true);
228
- }
229
- }
230
-
231
- if (!$success) {
232
- DUPX_Log::info("Problem om moveUpfromSubFolder subFolder:".$subFolderName);
233
- }
234
-
235
- return $success;
236
- }
237
-
238
- /**
239
- * @param string $archive_filepath full path of zip archive
240
- *
241
- * @return boolean|string path of dup-installer folder of false if not found
242
- */
243
- public static function findDupInstallerFolder($archive_filepath)
244
- {
245
- $zipArchive = new ZipArchive();
246
- $result = false;
247
-
248
- if ($zipArchive->open($archive_filepath) === true) {
249
- for ($i = 0; $i < $zipArchive->numFiles; $i++) {
250
- $stat = $zipArchive->statIndex($i);
251
- $safePath = rtrim(self::setSafePath($stat['name']), '/');
252
- if (substr_count($safePath, '/') > 2) {
253
- continue;
254
- }
255
-
256
- $exploded = explode('/',$safePath);
257
- if (($dup_index = array_search('dup-installer' , $exploded)) !== false) {
258
- $result = implode('/' , array_slice($exploded , 0 , $dup_index));
259
- break;
260
- }
261
- }
262
- if ($zipArchive->close() !== true) {
263
- DUPX_Log::info("Can't close ziparchive:".$archive_filepath);
264
- return false;
265
- }
266
- } else {
267
- DUPX_Log::info("Can't open zip archive:".$archive_filepath);
268
- return false;
269
- }
270
-
271
- return $result;
272
- }
273
-
274
- /**
275
- * A safe method used to copy larger files
276
- *
277
- * @param string $source The path to the file being copied
278
- * @param string $destination The path to the file being made
279
- *
280
- * @return null
281
- */
282
- public static function copyFile($source, $destination)
283
- {
284
- $sp = fopen($source, 'r');
285
- $op = fopen($destination, 'w');
286
-
287
- while (!feof($sp)) {
288
- $buffer = fread($sp, 512); // use a buffer of 512 bytes
289
- fwrite($op, $buffer);
290
- }
291
- // close handles
292
- fclose($op);
293
- fclose($sp);
294
- }
295
-
296
- /**
297
- * Safely remove a directory and recursively if needed
298
- *
299
- * @param string $directory The full path to the directory to remove
300
- * @param string $recursive recursively remove all items
301
- *
302
- * @return bool Returns true if all content was removed
303
- */
304
- public static function deleteDirectory($directory, $recursive)
305
- {
306
- $success = true;
307
-
308
- $filenames = array_diff(scandir($directory), array('.', '..'));
309
-
310
- foreach ($filenames as $filename) {
311
- $fullPath = $directory.'/'.$filename;
312
-
313
- if (is_dir($fullPath)) {
314
- if ($recursive) {
315
- $success = self::deleteDirectory($fullPath, true);
316
- }
317
- } else {
318
- $success = @unlink($fullPath);
319
- if ($success === false) {
320
- DUPX_Log::info( __FUNCTION__.": Problem deleting file:".$fullPath);
321
- }
322
- }
323
-
324
- if ($success === false) {
325
- DUPX_Log::info("Problem deleting dir:".$directory);
326
- break;
327
- }
328
- }
329
-
330
- return $success && rmdir($directory);
331
- }
332
-
333
- /**
334
- * Safely remove a file or directory and recursively if needed
335
- *
336
- * @param string $directory The full path to the directory to remove
337
- *
338
- * @return bool Returns true if all content was removed
339
- */
340
- public static function deletePath($path)
341
- {
342
- $success = true;
343
-
344
- if (is_dir($path)) {
345
- $success = self::deleteDirectory($path, true);
346
- } else {
347
- $success = @unlink($path);
348
-
349
- if ($success === false) {
350
- DUPX_Log::info( __FUNCTION__.": Problem deleting file:".$path);
351
- }
352
- }
353
-
354
- return $success;
355
- }
356
-
357
- /**
358
- * Dumps a variable for debugging
359
- *
360
- * @param string $var The variable to view
361
- * @param bool $pretty Pretty print the var
362
- *
363
- * @return object A visual representation of an object
364
- */
365
- public static function dump($var, $pretty = false)
366
- {
367
- if ($pretty) {
368
- echo '<pre>';
369
- print_r($var);
370
- echo '</pre>';
371
- } else {
372
- print_r($var);
373
- }
374
- }
375
-
376
- public static function echoBool($val)
377
- {
378
- if($val) {
379
- echo 'true';
380
- } else {
381
- echo 'false';
382
- }
383
- }
384
-
385
- /**
386
- * Return a string with the elapsed time
387
- *
388
- * @see getMicrotime()
389
- *
390
- * @param mixed number $end The final time in the sequence to measure
391
- * @param mixed number $start The start time in the sequence to measure
392
- *
393
- * @return string The time elapsed from $start to $end
394
- */
395
- public static function elapsedTime($end, $start)
396
- {
397
- return sprintf("%.4f sec.", abs($end - $start));
398
- }
399
-
400
- /**
401
- * Returns 256 spaces
402
- *
403
- * PHP_SAPI for fcgi requires a data flush of at least 256
404
- * bytes every 40 seconds or else it forces a script halt
405
- *
406
- * @return string A series of 256 spaces ' '
407
- */
408
- public static function fcgiFlush()
409
- {
410
- echo(str_repeat(' ', 256));
411
- @flush();
412
- }
413
-
414
- /**
415
- * Returns the active plugins for the WordPress website in the package
416
- *
417
- * @param obj $dbh A database connection handle
418
- *
419
- * @return array $list A list of active plugins
420
- */
421
- public static function getActivePlugins($dbh)
422
- {
423
- // Standard WP installation
424
- $select = "option_value";
425
- $table = "options";
426
- $where = "option_name = 'active_plugins'";
427
-
428
-
429
- $query = @mysqli_query($dbh, "SELECT {$select} FROM `".mysqli_real_escape_string($dbh, $GLOBALS['DUPX_AC']->wp_tableprefix).mysqli_real_escape_string($dbh, $table)."` WHERE {$where} ");
430
- if ($query) {
431
- $row = @mysqli_fetch_array($query);
432
- $plugins_ser_str = stripslashes($row[0]);
433
- $all_plugins = unserialize($plugins_ser_str);
434
-
435
- // Return data properly
436
- if (is_array($all_plugins)) {
437
- return $all_plugins;
438
- }
439
- }
440
- return array();
441
- }
442
-
443
- /**
444
- * Get current microtime as a float. Method is used for simple profiling
445
- *
446
- * @see elapsedTime
447
- *
448
- * @return string A float in the form "msec sec", where sec is the number of seconds since the Unix epoch
449
- */
450
- public static function getMicrotime()
451
- {
452
- return microtime(true);
453
- }
454
-
455
- /**
456
- * Gets the size of a variable in memory
457
- *
458
- * @param $var A valid PHP variable
459
- *
460
- * @returns int The amount of memory the variable has consumed
461
- */
462
- public static function getVarSize($var)
463
- {
464
- $start_memory = memory_get_usage();
465
- $var = unserialize(serialize($var));
466
- return memory_get_usage() - $start_memory - PHP_INT_SIZE * 8;
467
- }
468
-
469
- /**
470
- * Is the string JSON
471
- *
472
- * @param string $string Any string blob
473
- *
474
- * @return bool Returns true if the string is JSON encoded
475
- */
476
- public static function isJSON($string)
477
- {
478
-
479
- return is_string($string) && is_array(json_decode($string, true)) ? true : false;
480
- }
481
-
482
- /**
483
- * Does a string have non ASCII characters
484
- *
485
- * @param string $string Any string blob
486
- *
487
- * @return bool Returns true if any non ASCII character is found in the blob
488
- */
489
- public static function isNonASCII($string)
490
- {
491
- return preg_match('/[^\x20-\x7f]/', $string);
492
- }
493
-
494
- /**
495
- * Is an object traversable
496
- *
497
- * @param object $obj The object to evaluate
498
- *
499
- * @return bool Returns true if the object can be looped over safely
500
- */
501
- public static function isTraversable($obj)
502
- {
503
- if (is_null($obj))
504
- return false;
505
-
506
- return (is_array($obj) || $obj instanceof Traversable);
507
- }
508
-
509
- /**
510
- * Is the server running Windows operating system
511
- *
512
- * @return bool Returns true if operating system is Windows
513
- *
514
- */
515
- public static function isWindows()
516
- {
517
- if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
518
- {
519
- return true;
520
- }
521
- return false;
522
- }
523
-
524
- /**
525
- * The characters that are special in the replacement value of preg_replace are not the
526
- * same characters that are special in the pattern. Allows for '$' to be safely passed.
527
- *
528
- * @param string $str The string to replace on
529
- */
530
- public static function pregReplacementQuote($str)
531
- {
532
- return preg_replace('/(\$|\\\\)(?=\d)/', '\\\\\1', $str);
533
- }
534
-
535
- /**
536
- * Display human readable byte sizes
537
- *
538
- * @param string $size The size in bytes
539
- *
540
- * @return string Human readable bytes such as 50MB, 1GB
541
- */
542
- public static function readableByteSize($size)
543
- {
544
- try {
545
- $units = array('B', 'KB', 'MB', 'GB', 'TB');
546
- for ($i = 0; $size >= 1024 && $i < 4; $i++)
547
- $size /= 1024;
548
- return round($size, 2).$units[$i];
549
- } catch (Exception $e) {
550
- return "n/a";
551
- }
552
- }
553
-
554
- /**
555
- * Converts shorthand memory notation value to bytes
556
- * From http://php.net/manual/en/function.ini-get.php
557
- *
558
- * @param $val Memory size shorthand notation string
559
- *
560
- * @return int Returns the numeric byte from 1MB to 1024
561
- */
562
- public static function returnBytes($val)
563
- {
564
- $val = trim($val);
565
- $last = strtolower($val[strlen($val) - 1]);
566
- $val = intval($val);
567
- switch ($last) {
568
- // The 'G' modifier is available since PHP 5.1.0
569
- case 'g':
570
- $val *= 1024;
571
- case 'm':
572
- $val *= 1024;
573
- case 'k':
574
- $val *= 1024;
575
- break;
576
- default :
577
- $val = null;
578
- }
579
- return $val;
580
- }
581
-
582
- /**
583
- * Filter the string to escape the quote
584
- *
585
- * @param string $val The value to escape quote
586
- *
587
- * @return string Returns the input value escaped
588
- */
589
- public static function safeQuote($val)
590
- {
591
- $val = addslashes($val);
592
- return $val;
593
- }
594
-
595
- /**
596
- * Makes path safe for any OS for PHP
597
- *
598
- * Paths should ALWAYS READ be "/"
599
- * uni: /home/path/file.txt
600
- * win: D:/home/path/file.txt
601
- *
602
- * @param string $path The path to make safe
603
- *
604
- * @return string The original $path with a with all slashes facing '/'.
605
- */
606
- public static function setSafePath($path)
607
- {
608
- return str_replace("\\", "/", $path);
609
- }
610
-
611
- /**
612
- * Looks for a list of strings in a string and returns each list item that is found
613
- *
614
- * @param array $list An array of strings to search for
615
- * @param string $haystack The string blob to search through
616
- *
617
- * @return array An array of strings from the $list array found in the $haystack
618
- */
619
- public static function getListValues($list, $haystack)
620
- {
621
- $found = array();
622
- foreach ($list as $var) {
623
- if (strstr($haystack, $var) !== false) {
624
- array_push($found, $var);
625
- }
626
- }
627
- return $found;
628
- }
629
-
630
- /**
631
- * Makes path unsafe for any OS for PHP used primarily to show default
632
- * Windows OS path standard
633
- *
634
- * @param string $path The path to make unsafe
635
- *
636
- * @return string The original $path with a with all slashes facing '\'.
637
- */
638
- public static function unsetSafePath($path)
639
- {
640
- return str_replace("/", "\\", $path);
641
- }
642
-
643
- /**
644
- * Check PHP version
645
- *
646
- * @param string $version PHP version we looking for
647
- *
648
- * @return boolean Returns true if version is same or above.
649
- */
650
- public static function isVersion($version)
651
- {
652
- return (version_compare(PHP_VERSION, $version) >= 0);
653
- }
654
-
655
- /**
656
- * Checks if ssl is enabled
657
- * @return bool
658
- */
659
- public static function is_ssl()
660
- {
661
- if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
662
- $_SERVER ['HTTPS'] = 'on';
663
- }
664
-
665
- if ( isset($_SERVER['HTTPS']) ) {
666
- if ( 'on' == strtolower($_SERVER['HTTPS']) )
667
- return true;
668
- if ( '1' == $_SERVER['HTTPS'] )
669
- return true;
670
- } elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
671
- return true;
672
- }
673
-
674
- return false;
675
- }
676
-
677
- /**
678
- * @param $url string The URL whichs domain you want to get
679
- * @return string The domain part of the given URL
680
- * www.myurl.co.uk => myurl.co.uk
681
- * www.google.com => google.com
682
- * my.test.myurl.co.uk => myurl.co.uk
683
- * www.myurl.localweb => myurl.localweb
684
- *
685
- */
686
- public static function getDomain($url)
687
- {
688
- $pieces = parse_url($url);
689
- $domain = isset($pieces['host']) ? $pieces['host'] : '';
690
- if (strpos($domain, ".") !== false) {
691
- if (preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs)) {
692
- return $regs['domain'];
693
- } else {
694
- $exDomain = explode('.', $domain);
695
- return implode('.', array_slice($exDomain, -2, 2));
696
- }
697
- } else {
698
- return $domain;
699
- }
700
- }
701
-
702
- // START ESCAPING AND SANITIZATION
703
- /**
704
- * Escaping for HTML blocks.
705
- *
706
- *
707
- * @param string $text
708
- * @return string
709
- */
710
- public static function esc_html( $text ) {
711
- $safe_text = DupLiteSnapJsonU::wp_check_invalid_utf8( $text );
712
- $safe_text = self::_wp_specialchars( $safe_text, ENT_QUOTES );
713
- /**
714
- * Filters a string cleaned and escaped for output in HTML.
715
- *
716
- * Text passed to esc_html() is stripped of invalid or special characters
717
- * before output.
718
- *
719
- * @param string $safe_text The text after it has been escaped.
720
- * @param string $text The text prior to being escaped.
721
- */
722
- return $safe_text;
723
- }
724
-
725
- /**
726
- * Escape single quotes, htmlspecialchar " < > &, and fix line endings.
727
- *
728
- * Escapes text strings for echoing in JS. It is intended to be used for inline JS
729
- * (in a tag attribute, for example onclick="..."). Note that the strings have to
730
- * be in single quotes. The {@see 'js_escape'} filter is also applied here.
731
- *
732
- *
733
- * @param string $text The text to be escaped.
734
- * @return string Escaped text.
735
- */
736
- public static function esc_js( $text ) {
737
- $safe_text = DupLiteSnapJsonU::wp_check_invalid_utf8( $text );
738
- $safe_text = self::_wp_specialchars( $safe_text, ENT_COMPAT );
739
- $safe_text = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes( $safe_text ) );
740
- $safe_text = str_replace( "\r", '', $safe_text );
741
- $safe_text = str_replace( "\n", '\\n', addslashes( $safe_text ) );
742
- /**
743
- * Filters a string cleaned and escaped for output in JavaScript.
744
- *
745
- * Text passed to esc_js() is stripped of invalid or special characters,
746
- * and properly slashed for output.
747
- *
748
- * @param string $safe_text The text after it has been escaped.
749
- * @param string $text The text prior to being escaped.
750
- */
751
- return $safe_text;
752
- }
753
-
754
- /**
755
- * Escaping for HTML attributes.
756
- *
757
- * @param string $text
758
- * @return string
759
- */
760
- public static function esc_attr( $text ) {
761
- $safe_text = DupLiteSnapJsonU::wp_check_invalid_utf8( $text );
762
- $safe_text = self::_wp_specialchars( $safe_text, ENT_QUOTES );
763
- /**
764
- * Filters a string cleaned and escaped for output in an HTML attribute.
765
- *
766
- * Text passed to esc_attr() is stripped of invalid or special characters
767
- * before output.
768
- *
769
- * @param string $safe_text The text after it has been escaped.
770
- * @param string $text The text prior to being escaped.
771
- */
772
- return $safe_text;
773
- }
774
-
775
- /**
776
- * Escaping for textarea values.
777
- *
778
- * @param string $text
779
- * @return string
780
- */
781
- public static function esc_textarea( $text )
782
- {
783
- $safe_text = htmlspecialchars( $text, ENT_QUOTES, 'UTF-8' );
784
- /**
785
- * Filters a string cleaned and escaped for output in a textarea element.
786
- *
787
- * @param string $safe_text The text after it has been escaped.
788
- * @param string $text The text prior to being escaped.
789
- */
790
- return $safe_text;
791
- }
792
-
793
- /**
794
- * Escape an HTML tag name.
795
- *
796
- * @param string $tag_name
797
- * @return string
798
- */
799
- function tag_escape( $tag_name ) {
800
- $safe_tag = strtolower( preg_replace('/[^a-zA-Z0-9_:]/', '', $tag_name) );
801
- /**
802
- * Filters a string cleaned and escaped for output as an HTML tag.
803
- *
804
- * @param string $safe_tag The tag name after it has been escaped.
805
- * @param string $tag_name The text before it was escaped.
806
- */
807
- return $safe_tag;
808
- }
809
-
810
- /**
811
- * Converts a number of special characters into their HTML entities.
812
- *
813
- * Specifically deals with: &, <, >, ", and '.
814
- *
815
- * $quote_style can be set to ENT_COMPAT to encode " to
816
- * &quot;, or ENT_QUOTES to do both. Default is ENT_NOQUOTES where no quotes are encoded.
817
- *
818
- * @access private
819
- *
820
- * @staticvar string $_charset
821
- *
822
- * @param string $string The text which is to be encoded.
823
- * @param int|string $quote_style Optional. Converts double quotes if set to ENT_COMPAT,
824
- * both single and double if set to ENT_QUOTES or none if set to ENT_NOQUOTES.
825
- * Also compatible with old values; converting single quotes if set to 'single',
826
- * double if set to 'double' or both if otherwise set.
827
- * Default is ENT_NOQUOTES.
828
- * @param string $charset Optional. The character encoding of the string. Default is false.
829
- * @param bool $double_encode Optional. Whether to encode existing html entities. Default is false.
830
- * @return string The encoded text with HTML entities.
831
- */
832
- public static function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) {
833
- $string = (string) $string;
834
-
835
- if ( 0 === strlen( $string ) )
836
- return '';
837
-
838
- // Don't bother if there are no specialchars - saves some processing
839
- if ( ! preg_match( '/[&<>"\']/', $string ) )
840
- return $string;
841
-
842
- // Account for the previous behaviour of the function when the $quote_style is not an accepted value
843
- if ( empty( $quote_style ) )
844
- $quote_style = ENT_NOQUOTES;
845
- elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) )
846
- $quote_style = ENT_QUOTES;
847
-
848
- // Store the site charset as a static to avoid multiple calls to wp_load_alloptions()
849
- if ( ! $charset ) {
850
- static $_charset = null;
851
- if ( ! isset( $_charset ) ) {
852
- $_charset = '';
853
- }
854
- $charset = $_charset;
855
- }
856
-
857
- if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) )
858
- $charset = 'UTF-8';
859
-
860
- $_quote_style = $quote_style;
861
-
862
- if ( $quote_style === 'double' ) {
863
- $quote_style = ENT_COMPAT;
864
- $_quote_style = ENT_COMPAT;
865
- } elseif ( $quote_style === 'single' ) {
866
- $quote_style = ENT_NOQUOTES;
867
- }
868
-
869
- if ( ! $double_encode ) {
870
- // Guarantee every &entity; is valid, convert &garbage; into &amp;garbage;
871
- // This is required for PHP < 5.4.0 because ENT_HTML401 flag is unavailable.
872
- $string = self::wp_kses_normalize_entities( $string );
873
- }
874
-
875
- $string = @htmlspecialchars( $string, $quote_style, $charset, $double_encode );
876
-
877
- // Back-compat.
878
- if ( 'single' === $_quote_style )
879
- $string = str_replace( "'", '&#039;', $string );
880
-
881
- return $string;
882
- }
883
-
884
- /**
885
- * Converts a number of HTML entities into their special characters.
886
- *
887
- * Specifically deals with: &, <, >, ", and '.
888
- *
889
- * $quote_style can be set to ENT_COMPAT to decode " entities,
890
- * or ENT_QUOTES to do both " and '. Default is ENT_NOQUOTES where no quotes are decoded.
891
- *
892
- * @param string $string The text which is to be decoded.
893
- * @param string|int $quote_style Optional. Converts double quotes if set to ENT_COMPAT,
894
- * both single and double if set to ENT_QUOTES or
895
- * none if set to ENT_NOQUOTES.
896
- * Also compatible with old _wp_specialchars() values;
897
- * converting single quotes if set to 'single',
898
- * double if set to 'double' or both if otherwise set.
899
- * Default is ENT_NOQUOTES.
900
- * @return string The decoded text without HTML entities.
901
- */
902
- public static function wp_specialchars_decode( $string, $quote_style = ENT_NOQUOTES ) {
903
- $string = (string) $string;
904
-
905
- if ( 0 === strlen( $string ) ) {
906
- return '';
907
- }
908
-
909
- // Don't bother if there are no entities - saves a lot of processing
910
- if ( strpos( $string, '&' ) === false ) {
911
- return $string;
912
- }
913
-
914
- // Match the previous behaviour of _wp_specialchars() when the $quote_style is not an accepted value
915
- if ( empty( $quote_style ) ) {
916
- $quote_style = ENT_NOQUOTES;
917
- } elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) {
918
- $quote_style = ENT_QUOTES;
919
- }
920
-
921
- // More complete than get_html_translation_table( HTML_SPECIALCHARS )
922
- $single = array( '&#039;' => '\'', '&#x27;' => '\'' );
923
- $single_preg = array( '/&#0*39;/' => '&#039;', '/&#x0*27;/i' => '&#x27;' );
924
- $double = array( '&quot;' => '"', '&#034;' => '"', '&#x22;' => '"' );
925
- $double_preg = array( '/&#0*34;/' => '&#034;', '/&#x0*22;/i' => '&#x22;' );
926
- $others = array( '&lt;' => '<', '&#060;' => '<', '&gt;' => '>', '&#062;' => '>', '&amp;' => '&', '&#038;' => '&', '&#x26;' => '&' );
927
- $others_preg = array( '/&#0*60;/' => '&#060;', '/&#0*62;/' => '&#062;', '/&#0*38;/' => '&#038;', '/&#x0*26;/i' => '&#x26;' );
928
-
929
- if ( $quote_style === ENT_QUOTES ) {
930
- $translation = array_merge( $single, $double, $others );
931
- $translation_preg = array_merge( $single_preg, $double_preg, $others_preg );
932
- } elseif ( $quote_style === ENT_COMPAT || $quote_style === 'double' ) {
933
- $translation = array_merge( $double, $others );
934
- $translation_preg = array_merge( $double_preg, $others_preg );
935
- } elseif ( $quote_style === 'single' ) {
936
- $translation = array_merge( $single, $others );
937
- $translation_preg = array_merge( $single_preg, $others_preg );
938
- } elseif ( $quote_style === ENT_NOQUOTES ) {
939
- $translation = $others;
940
- $translation_preg = $others_preg;
941
- }
942
-
943
- // Remove zero padding on numeric entities
944
- $string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string );
945
-
946
- // Replace characters according to translation table
947
- return strtr( $string, $translation );
948
- }
949
-
950
- /**
951
- * Perform a deep string replace operation to ensure the values in $search are no longer present
952
- *
953
- * Repeats the replacement operation until it no longer replaces anything so as to remove "nested" values
954
- * e.g. $subject = '%0%0%0DDD', $search ='%0D', $result ='' rather than the '%0%0DD' that
955
- * str_replace would return
956
- * @access private
957
- *
958
- * @param string|array $search The value being searched for, otherwise known as the needle.
959
- * An array may be used to designate multiple needles.
960
- * @param string $subject The string being searched and replaced on, otherwise known as the haystack.
961
- * @return string The string with the replaced svalues.
962
- */
963
- private static function _deep_replace( $search, $subject ) {
964
- $subject = (string) $subject;
965
-
966
- $count = 1;
967
- while ( $count ) {
968
- $subject = str_replace( $search, '', $subject, $count );
969
- }
970
-
971
- return $subject;
972
- }
973
-
974
- /**
975
- * Converts and fixes HTML entities.
976
- *
977
- * This function normalizes HTML entities. It will convert `AT&T` to the correct
978
- * `AT&amp;T`, `&#00058;` to `&#58;`, `&#XYZZY;` to `&amp;#XYZZY;` and so on.
979
- *
980
- * @param string $string Content to normalize entities
981
- * @return string Content with normalized entities
982
- */
983
- public static function wp_kses_normalize_entities($string)
984
- {
985
- // Disarm all entities by converting & to &amp;
986
- $string = str_replace('&', '&amp;', $string);
987
-
988
- // Change back the allowed entities in our entity whitelist
989
- $string = preg_replace_callback('/&amp;([A-Za-z]{2,8}[0-9]{0,2});/', array(__CLASS__, 'wp_kses_named_entities'), $string);
990
- $string = preg_replace_callback('/&amp;#(0*[0-9]{1,7});/', array(__CLASS__, 'wp_kses_normalize_entities2'), $string);
991
- $string = preg_replace_callback('/&amp;#[Xx](0*[0-9A-Fa-f]{1,6});/', array(__CLASS__, 'wp_kses_normalize_entities3'), $string);
992
-
993
- return $string;
994
- }
995
-
996
- /**
997
- * Callback for wp_kses_normalize_entities() regular expression.
998
- *
999
- * This function only accepts valid named entity references, which are finite,
1000
- * case-sensitive, and highly scrutinized by HTML and XML validators.
1001
- *
1002
- * @global array $allowedentitynames
1003
- *
1004
- * @param array $matches preg_replace_callback() matches array
1005
- * @return string Correctly encoded entity
1006
- */
1007
- public static function wp_kses_named_entities($matches) {
1008
- if ( empty($matches[1]) )
1009
- return '';
1010
-
1011
- $allowedentitynames = array(
1012
- 'nbsp', 'iexcl', 'cent', 'pound', 'curren', 'yen',
1013
- 'brvbar', 'sect', 'uml', 'copy', 'ordf', 'laquo',
1014
- 'not', 'shy', 'reg', 'macr', 'deg', 'plusmn',
1015
- 'acute', 'micro', 'para', 'middot', 'cedil', 'ordm',
1016
- 'raquo', 'iquest', 'Agrave', 'Aacute', 'Acirc', 'Atilde',
1017
- 'Auml', 'Aring', 'AElig', 'Ccedil', 'Egrave', 'Eacute',
1018
- 'Ecirc', 'Euml', 'Igrave', 'Iacute', 'Icirc', 'Iuml',
1019
- 'ETH', 'Ntilde', 'Ograve', 'Oacute', 'Ocirc', 'Otilde',
1020
- 'Ouml', 'times', 'Oslash', 'Ugrave', 'Uacute', 'Ucirc',
1021
- 'Uuml', 'Yacute', 'THORN', 'szlig', 'agrave', 'aacute',
1022
- 'acirc', 'atilde', 'auml', 'aring', 'aelig', 'ccedil',
1023
- 'egrave', 'eacute', 'ecirc', 'euml', 'igrave', 'iacute',
1024
- 'icirc', 'iuml', 'eth', 'ntilde', 'ograve', 'oacute',
1025
- 'ocirc', 'otilde', 'ouml', 'divide', 'oslash', 'ugrave',
1026
- 'uacute', 'ucirc', 'uuml', 'yacute', 'thorn', 'yuml',
1027
- 'quot', 'amp', 'lt', 'gt', 'apos', 'OElig',
1028
- 'oelig', 'Scaron', 'scaron', 'Yuml', 'circ', 'tilde',
1029
- 'ensp', 'emsp', 'thinsp', 'zwnj', 'zwj', 'lrm',
1030
- 'rlm', 'ndash', 'mdash', 'lsquo', 'rsquo', 'sbquo',
1031
- 'ldquo', 'rdquo', 'bdquo', 'dagger', 'Dagger', 'permil',
1032
- 'lsaquo', 'rsaquo', 'euro', 'fnof', 'Alpha', 'Beta',
1033
- 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta', 'Theta',
1034
- 'Iota', 'Kappa', 'Lambda', 'Mu', 'Nu', 'Xi',
1035
- 'Omicron', 'Pi', 'Rho', 'Sigma', 'Tau', 'Upsilon',
1036
- 'Phi', 'Chi', 'Psi', 'Omega', 'alpha', 'beta',
1037
- 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta',
1038
- 'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi',
1039
- 'omicron', 'pi', 'rho', 'sigmaf', 'sigma', 'tau',
1040
- 'upsilon', 'phi', 'chi', 'psi', 'omega', 'thetasym',
1041
- 'upsih', 'piv', 'bull', 'hellip', 'prime', 'Prime',
1042
- 'oline', 'frasl', 'weierp', 'image', 'real', 'trade',
1043
- 'alefsym', 'larr', 'uarr', 'rarr', 'darr', 'harr',
1044
- 'crarr', 'lArr', 'uArr', 'rArr', 'dArr', 'hArr',
1045
- 'forall', 'part', 'exist', 'empty', 'nabla', 'isin',
1046
- 'notin', 'ni', 'prod', 'sum', 'minus', 'lowast',
1047
- 'radic', 'prop', 'infin', 'ang', 'and', 'or',
1048
- 'cap', 'cup', 'int', 'sim', 'cong', 'asymp',
1049
- 'ne', 'equiv', 'le', 'ge', 'sub', 'sup',
1050
- 'nsub', 'sube', 'supe', 'oplus', 'otimes', 'perp',
1051
- 'sdot', 'lceil', 'rceil', 'lfloor', 'rfloor', 'lang',
1052
- 'rang', 'loz', 'spades', 'clubs', 'hearts', 'diams',
1053
- 'sup1', 'sup2', 'sup3', 'frac14', 'frac12', 'frac34',
1054
- 'there4',
1055
- );
1056
-
1057
- $i = $matches[1];
1058
- return ( ! in_array( $i, $allowedentitynames ) ) ? "&amp;$i;" : "&$i;";
1059
- }
1060
-
1061
-
1062
- /**
1063
- * Helper function to determine if a Unicode value is valid.
1064
- *
1065
- * @param int $i Unicode value
1066
- * @return bool True if the value was a valid Unicode number
1067
- */
1068
- public static function wp_valid_unicode($i) {
1069
- return ( $i == 0x9 || $i == 0xa || $i == 0xd ||
1070
- ($i >= 0x20 && $i <= 0xd7ff) ||
1071
- ($i >= 0xe000 && $i <= 0xfffd) ||
1072
- ($i >= 0x10000 && $i <= 0x10ffff) );
1073
- }
1074
-
1075
- /**
1076
- * Callback for wp_kses_normalize_entities() regular expression.
1077
- *
1078
- * This function helps wp_kses_normalize_entities() to only accept 16-bit
1079
- * values and nothing more for `&#number;` entities.
1080
- *
1081
- * @access private
1082
- *
1083
- * @param array $matches preg_replace_callback() matches array
1084
- * @return string Correctly encoded entity
1085
- */
1086
- public static function wp_kses_normalize_entities2($matches) {
1087
- if ( empty($matches[1]) )
1088
- return '';
1089
-
1090
- $i = $matches[1];
1091
- if (self::wp_valid_unicode($i)) {
1092
- $i = str_pad(ltrim($i,'0'), 3, '0', STR_PAD_LEFT);
1093
- $i = "&#$i;";
1094
- } else {
1095
- $i = "&amp;#$i;";
1096
- }
1097
-
1098
- return $i;
1099
- }
1100
-
1101
- /**
1102
- * Callback for wp_kses_normalize_entities() for regular expression.
1103
- *
1104
- * This function helps wp_kses_normalize_entities() to only accept valid Unicode
1105
- * numeric entities in hex form.
1106
- *
1107
- * @access private
1108
- *
1109
- * @param array $matches preg_replace_callback() matches array
1110
- * @return string Correctly encoded entity
1111
- */
1112
- public static function wp_kses_normalize_entities3($matches) {
1113
- if ( empty($matches[1]) )
1114
- return '';
1115
-
1116
- $hexchars = $matches[1];
1117
- return ( ! self::wp_valid_unicode( hexdec( $hexchars ) ) ) ? "&amp;#x$hexchars;" : '&#x'.ltrim($hexchars,'0').';';
1118
- }
1119
-
1120
- /**
1121
- * Retrieve a list of protocols to allow in HTML attributes.
1122
- *
1123
- * @since 3.3.0
1124
- * @since 4.3.0 Added 'webcal' to the protocols array.
1125
- * @since 4.7.0 Added 'urn' to the protocols array.
1126
- *
1127
- * @see wp_kses()
1128
- * @see esc_url()
1129
- *
1130
- * @staticvar array $protocols
1131
- *
1132
- * @return array Array of allowed protocols. Defaults to an array containing 'http', 'https',
1133
- * 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet',
1134
- * 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', and 'urn'.
1135
- */
1136
- public static function wp_allowed_protocols() {
1137
- static $protocols = array();
1138
-
1139
- if ( empty( $protocols ) ) {
1140
- $protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', 'urn' );
1141
- }
1142
-
1143
- return $protocols;
1144
- }
1145
-
1146
- /**
1147
- * Checks and cleans a URL.
1148
- *
1149
- * A number of characters are removed from the URL. If the URL is for displaying
1150
- * (the default behaviour) ampersands are also replaced. The {@see 'clean_url'} filter
1151
- * is applied to the returned cleaned URL.
1152
- *
1153
- * @since 2.8.0
1154
- *
1155
- * @param string $url The URL to be cleaned.
1156
- * @param array $protocols Optional. An array of acceptable protocols.
1157
- * Defaults to return value of wp_allowed_protocols()
1158
- * @param string $_context Private. Use esc_url_raw() for database usage.
1159
- * @return string The cleaned $url after the {@see 'clean_url'} filter is applied.
1160
- */
1161
- public static function esc_url( $url, $protocols = null, $_context = 'display' ) {
1162
- $original_url = $url;
1163
-
1164
- if ( '' == $url )
1165
- return $url;
1166
-
1167
- $url = str_replace( ' ', '%20', $url );
1168
- $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url);
1169
-
1170
- if ( '' === $url ) {
1171
- return $url;
1172
- }
1173
-
1174
- if ( 0 !== stripos( $url, 'mailto:' ) ) {
1175
- $strip = array('%0d', '%0a', '%0D', '%0A');
1176
- $url = self::_deep_replace($strip, $url);
1177
- }
1178
-
1179
- $url = str_replace(';//', '://', $url);
1180
- /* If the URL doesn't appear to contain a scheme, we
1181
- * presume it needs http:// prepended (unless a relative
1182
- * link starting with /, # or ? or a php file).
1183
- */
1184
- if ( strpos($url, ':') === false && ! in_array( $url[0], array( '/', '#', '?' ) ) &&
1185
- ! preg_match('/^[a-z0-9-]+?\.php/i', $url) )
1186
- $url = 'http://' . $url;
1187
-
1188
- // Replace ampersands and single quotes only when displaying.
1189
- if ( 'display' == $_context ) {
1190
- $url = self::wp_kses_normalize_entities( $url );
1191
- $url = str_replace( '&amp;', '&#038;', $url );
1192
- $url = str_replace( "'", '&#039;', $url );
1193
- }
1194
-
1195
- if ( ( false !== strpos( $url, '[' ) ) || ( false !== strpos( $url, ']' ) ) ) {
1196
-
1197
- $parsed = wp_parse_url( $url );
1198
- $front = '';
1199
-
1200
- if ( isset( $parsed['scheme'] ) ) {
1201
- $front .= $parsed['scheme'] . '://';
1202
- } elseif ( '/' === $url[0] ) {
1203
- $front .= '//';
1204
- }
1205
-
1206
- if ( isset( $parsed['user'] ) ) {
1207
- $front .= $parsed['user'];
1208
- }
1209
-
1210
- if ( isset( $parsed['pass'] ) ) {
1211
- $front .= ':' . $parsed['pass'];
1212
- }
1213
-
1214
- if ( isset( $parsed['user'] ) || isset( $parsed['pass'] ) ) {
1215
- $front .= '@';
1216
- }
1217
-
1218
- if ( isset( $parsed['host'] ) ) {
1219
- $front .= $parsed['host'];
1220
- }
1221
-
1222
- if ( isset( $parsed['port'] ) ) {
1223
- $front .= ':' . $parsed['port'];
1224
- }
1225
-
1226
- $end_dirty = str_replace( $front, '', $url );
1227
- $end_clean = str_replace( array( '[', ']' ), array( '%5B', '%5D' ), $end_dirty );
1228
- $url = str_replace( $end_dirty, $end_clean, $url );
1229
-
1230
- }
1231
-
1232
- if ( '/' === $url[0] ) {
1233
- $good_protocol_url = $url;
1234
- } else {
1235
- if ( ! is_array( $protocols ) )
1236
- $protocols = self::wp_allowed_protocols();
1237
- $good_protocol_url = self::wp_kses_bad_protocol( $url, $protocols );
1238
- if ( strtolower( $good_protocol_url ) != strtolower( $url ) )
1239
- return '';
1240
- }
1241
-
1242
- /**
1243
- * Filters a string cleaned and escaped for output as a URL.
1244
- *
1245
- * @since 2.3.0
1246
- *
1247
- * @param string $good_protocol_url The cleaned URL to be returned.
1248
- * @param string $original_url The URL prior to cleaning.
1249
- * @param string $_context If 'display', replace ampersands and single quotes only.
1250
- */
1251
- return $good_protocol_url;
1252
- }
1253
-
1254
-
1255
- /**
1256
- * Removes any invalid control characters in $string.
1257
- *
1258
- * Also removes any instance of the '\0' string.
1259
- *
1260
- * @param string $string
1261
- * @param array $options Set 'slash_zero' => 'keep' when '\0' is allowed. Default is 'remove'.
1262
- * @return string
1263
- */
1264
- public static function wp_kses_no_null( $string, $options = null ) {
1265
- if ( ! isset( $options['slash_zero'] ) ) {
1266
- $options = array( 'slash_zero' => 'remove' );
1267
- }
1268
-
1269
- $string = preg_replace( '/[\x00-\x08\x0B\x0C\x0E-\x1F]/', '', $string );
1270
- if ( 'remove' == $options['slash_zero'] ) {
1271
- $string = preg_replace( '/\\\\+0+/', '', $string );
1272
- }
1273
-
1274
- return $string;
1275
- }
1276
-
1277
-
1278
- /**
1279
- * Sanitize string from bad protocols.
1280
- *
1281
- * This function removes all non-allowed protocols from the beginning of
1282
- * $string. It ignores whitespace and the case of the letters, and it does
1283
- * understand HTML entities. It does its work in a while loop, so it won't be
1284
- * fooled by a string like "javascript:javascript:alert(57)".
1285
- *
1286
- * @param string $string Content to filter bad protocols from
1287
- * @param array $allowed_protocols Allowed protocols to keep
1288
- * @return string Filtered content
1289
- */
1290
- public static function wp_kses_bad_protocol($string, $allowed_protocols) {
1291
- $string = self::wp_kses_no_null($string);
1292
- $iterations = 0;
1293
-
1294
- do {
1295
- $original_string = $string;
1296
- $string = self::wp_kses_bad_protocol_once($string, $allowed_protocols);
1297
- } while ( $original_string != $string && ++$iterations < 6 );
1298
-
1299
- if ( $original_string != $string )
1300
- return '';
1301
-
1302
- return $string;
1303
- }
1304
-
1305
- /**
1306
- * Sanitizes content from bad protocols and other characters.
1307
- *
1308
- * This function searches for URL protocols at the beginning of $string, while
1309
- * handling whitespace and HTML entities.
1310
- *
1311
- * @param string $string Content to check for bad protocols
1312
- * @param string $allowed_protocols Allowed protocols
1313
- * @return string Sanitized content
1314
- */
1315
- public static function wp_kses_bad_protocol_once($string, $allowed_protocols, $count = 1 ) {
1316
- $string2 = preg_split( '/:|&#0*58;|&#x0*3a;/i', $string, 2 );
1317
- if ( isset($string2[1]) && ! preg_match('%/\?%', $string2[0]) ) {
1318
- $string = trim( $string2[1] );
1319
- $protocol = self::wp_kses_bad_protocol_once2( $string2[0], $allowed_protocols );
1320
- if ( 'feed:' == $protocol ) {
1321
- if ( $count > 2 )
1322
- return '';
1323
- $string = wp_kses_bad_protocol_once( $string, $allowed_protocols, ++$count );
1324
- if ( empty( $string ) )
1325
- return $string;
1326
- }
1327
- $string = $protocol . $string;
1328
- }
1329
-
1330
- return $string;
1331
- }
1332
-
1333
- /**
1334
- * Convert all entities to their character counterparts.
1335
- *
1336
- * This function decodes numeric HTML entities (`&#65;` and `&#x41;`).
1337
- * It doesn't do anything with other entities like &auml;, but we don't
1338
- * need them in the URL protocol whitelisting system anyway.
1339
- *
1340
- * @param string $string Content to change entities
1341
- * @return string Content after decoded entities
1342
- */
1343
- public static function wp_kses_decode_entities($string)
1344
- {
1345
- $string = preg_replace_callback('/&#([0-9]+);/', array(__CLASS__, '_wp_kses_decode_entities_chr'), $string);
1346
- $string = preg_replace_callback('/&#[Xx]([0-9A-Fa-f]+);/', array(__CLASS__, '_wp_kses_decode_entities_chr_hexdec'), $string);
1347
-
1348
- return $string;
1349
- }
1350
-
1351
- /**
1352
- * Regex callback for wp_kses_decode_entities()
1353
- *
1354
- * @param array $match preg match
1355
- * @return string
1356
- */
1357
- public static function _wp_kses_decode_entities_chr( $match ) {
1358
- return chr( $match[1] );
1359
- }
1360
-
1361
- /**
1362
- * Regex callback for wp_kses_decode_entities()
1363
- *
1364
- * @param array $match preg match
1365
- * @return string
1366
- */
1367
- public static function _wp_kses_decode_entities_chr_hexdec( $match ) {
1368
- return chr( hexdec( $match[1] ) );
1369
- }
1370
-
1371
- /**
1372
- * Callback for wp_kses_bad_protocol_once() regular expression.
1373
- *
1374
- * This function processes URL protocols, checks to see if they're in the
1375
- * white-list or not, and returns different data depending on the answer.
1376
- *
1377
- * @access private
1378
- *
1379
- * @param string $string URI scheme to check against the whitelist
1380
- * @param string $allowed_protocols Allowed protocols
1381
- * @return string Sanitized content
1382
- */
1383
- public static function wp_kses_bad_protocol_once2( $string, $allowed_protocols ) {
1384
- $string2 = self::wp_kses_decode_entities($string);
1385
- $string2 = preg_replace('/\s/', '', $string2);
1386
- $string2 = self::wp_kses_no_null($string2);
1387
- $string2 = strtolower($string2);
1388
-
1389
- $allowed = false;
1390
- foreach ( (array) $allowed_protocols as $one_protocol ) {
1391
- if ( strtolower($one_protocol) == $string2 ) {
1392
- $allowed = true;
1393
- break;
1394
- }
1395
- }
1396
-
1397
- if ($allowed)
1398
- return "$string2:";
1399
- else
1400
- return '';
1401
- }
1402
-
1403
- /**
1404
- * Performs esc_url() for database usage.
1405
- *
1406
- * @param string $url The URL to be cleaned.
1407
- * @param array $protocols An array of acceptable protocols.
1408
- * @return string The cleaned URL.
1409
- */
1410
- public static function esc_url_raw( $url, $protocols = null ) {
1411
- return self::esc_url( $url, $protocols, 'db' );
1412
- }
1413
-
1414
- // SANITIZE Functions
1415
-
1416
- /**
1417
- * Normalize EOL characters and strip duplicate whitespace.
1418
- *
1419
- * @param string $str The string to normalize.
1420
- * @return string The normalized string.
1421
- */
1422
- public static function normalize_whitespace( $str ) {
1423
- $str = trim( $str );
1424
- $str = str_replace( "\r", "\n", $str );
1425
- $str = preg_replace( array( '/\n+/', '/[ \t]+/' ), array( "\n", ' ' ), $str );
1426
- return $str;
1427
- }
1428
-
1429
- /**
1430
- * Properly strip all HTML tags including script and style
1431
- *
1432
- * This differs from strip_tags() because it removes the contents of
1433
- * the `<script>` and `<style>` tags. E.g. `strip_tags( '<script>something</script>' )`
1434
- * will return 'something'. wp_strip_all_tags will return ''
1435
- *
1436
- * @param string $string String containing HTML tags
1437
- * @param bool $remove_breaks Optional. Whether to remove left over line breaks and white space chars
1438
- * @return string The processed string.
1439
- */
1440
- public static function wp_strip_all_tags($string, $remove_breaks = false) {
1441
- $string = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $string );
1442
- $string = strip_tags($string);
1443
-
1444
- if ( $remove_breaks )
1445
- $string = preg_replace('/[\r\n\t ]+/', ' ', $string);
1446
-
1447
- return trim( $string );
1448
- }
1449
-
1450
- /**
1451
- * Sanitizes a string from user input or from the database.
1452
- *
1453
- * - Checks for invalid UTF-8,
1454
- * - Converts single `<` characters to entities
1455
- * - Strips all tags
1456
- * - Removes line breaks, tabs, and extra whitespace
1457
- * - Strips octets
1458
- *
1459
- * @see sanitize_textarea_field()
1460
- * @see wp_check_invalid_utf8()
1461
- * @see wp_strip_all_tags()
1462
- *
1463
- * @param string $str String to sanitize.
1464
- * @return string Sanitized string.
1465
- */
1466
- public static function sanitize_text_field( $str ) {
1467
- $filtered = self::_sanitize_text_fields( $str, false );
1468
-
1469
- /**
1470
- * Filters a sanitized text field string.
1471
- *
1472
- * @param string $filtered The sanitized string.
1473
- * @param string $str The string prior to being sanitized.
1474
- */
1475
- return $filtered;
1476
- }
1477
-
1478
- /**
1479
- * Sanitizes a multiline string from user input or from the database.
1480
- *
1481
- * The function is like sanitize_text_field(), but preserves
1482
- * new lines (\n) and other whitespace, which are legitimate
1483
- * input in textarea elements.
1484
- *
1485
- * @see sanitize_text_field()
1486
- *
1487
- * @since 4.7.0
1488
- *
1489
- * @param string $str String to sanitize.
1490
- * @return string Sanitized string.
1491
- */
1492
- public static function sanitize_textarea_field( $str ) {
1493
- $filtered = self::_sanitize_text_fields( $str, true );
1494
-
1495
- /**
1496
- * Filters a sanitized textarea field string.
1497
- *
1498
- * @since 4.7.0
1499
- *
1500
- * @param string $filtered The sanitized string.
1501
- * @param string $str The string prior to being sanitized.
1502
- */
1503
- return $filtered;
1504
- }
1505
-
1506
- /**
1507
- * Internal helper function to sanitize a string from user input or from the db
1508
- *
1509
- * @since 4.7.0
1510
- * @access private
1511
- *
1512
- * @param string $str String to sanitize.
1513
- * @param bool $keep_newlines optional Whether to keep newlines. Default: false.
1514
- * @return string Sanitized string.
1515
- */
1516
- public static function _sanitize_text_fields( $str, $keep_newlines = false ) {
1517
- $filtered = DupLiteSnapJsonU::wp_check_invalid_utf8( $str );
1518
-
1519
- if ( strpos($filtered, '<') !== false ) {
1520
- $filtered = self::wp_pre_kses_less_than( $filtered );
1521
- // This will strip extra whitespace for us.
1522
- $filtered = self::wp_strip_all_tags( $filtered, false );
1523
-
1524
- // Use html entities in a special case to make sure no later
1525
- // newline stripping stage could lead to a functional tag
1526
- $filtered = str_replace("<\n", "&lt;\n", $filtered);
1527
- }
1528
-
1529
- if ( ! $keep_newlines ) {
1530
- $filtered = preg_replace( '/[\r\n\t ]+/', ' ', $filtered );
1531
- }
1532
- $filtered = trim( $filtered );
1533
-
1534
- $found = false;
1535
- while ( preg_match('/%[a-f0-9]{2}/i', $filtered, $match) ) {
1536
- $filtered = str_replace($match[0], '', $filtered);
1537
- $found = true;
1538
- }
1539
-
1540
- if ( $found ) {
1541
- // Strip out the whitespace that may now exist after removing the octets.
1542
- $filtered = trim( preg_replace('/ +/', ' ', $filtered) );
1543
- }
1544
-
1545
- return $filtered;
1546
- }
1547
-
1548
- /**
1549
- * Convert lone less than signs.
1550
- *
1551
- * KSES already converts lone greater than signs.
1552
- *
1553
- * @param string $text Text to be converted.
1554
- * @return string Converted text.
1555
- */
1556
- public static function wp_pre_kses_less_than( $text ) {
1557
- return preg_replace_callback('%<[^>]*?((?=<)|>|$)%', array('self', 'wp_pre_kses_less_than_callback'), $text);
1558
- }
1559
-
1560
- /**
1561
- * Callback function used by preg_replace.
1562
- *
1563
- * @param array $matches Populated by matches to preg_replace.
1564
- * @return string The text returned after esc_html if needed.
1565
- */
1566
- public static function wp_pre_kses_less_than_callback( $matches ) {
1567
- if ( false === strpos($matches[0], '>') )
1568
- return self::esc_html($matches[0]);
1569
- return $matches[0];
1570
- }
1571
-
1572
-
1573
- /**
1574
- * Remove slashes from a string or array of strings.
1575
- *
1576
- * This should be used to remove slashes from data passed to core API that
1577
- * expects data to be unslashed.
1578
- *
1579
- * @since 3.6.0
1580
- *
1581
- * @param string|array $value String or array of strings to unslash.
1582
- * @return string|array Unslashed $value
1583
- */
1584
- public static function wp_unslash($value) {
1585
- return self::stripslashes_deep( $value );
1586
- }
1587
-
1588
- /**
1589
- * Navigates through an array, object, or scalar, and removes slashes from the values.
1590
- *
1591
- * @param mixed $value The value to be stripped.
1592
- * @return mixed Stripped value.
1593
- */
1594
- public static function stripslashes_deep($value) {
1595
- return self::map_deep($value, array('self', 'stripslashes_from_strings_only'));
1596
- }
1597
-
1598
- /**
1599
- * Maps a function to all non-iterable elements of an array or an object.
1600
- *
1601
- * This is similar to `array_walk_recursive()` but acts upon objects too.
1602
- *
1603
- * @since 4.4.0
1604
- *
1605
- * @param mixed $value The array, object, or scalar.
1606
- * @param callable $callback The function to map onto $value.
1607
- * @return mixed The value with the callback applied to all non-arrays and non-objects inside it.
1608
- */
1609
- public static function map_deep($value, $callback) {
1610
- if (is_array($value)) {
1611
- foreach ($value as $index => $item) {
1612
- $value[$index] = self::map_deep($item, $callback);
1613
- }
1614
- } elseif (is_object($value)) {
1615
- $object_vars = get_object_vars($value);
1616
- foreach ($object_vars as $property_name => $property_value) {
1617
- $value->$property_name = self::map_deep($property_value, $callback);
1618
- }
1619
- } else {
1620
- $value = call_user_func($callback, $value);
1621
- }
1622
-
1623
- return $value;
1624
- }
1625
-
1626
- /**
1627
- * Callback function for `stripslashes_deep()` which strips slashes from strings.
1628
- *
1629
- * @since 4.4.0
1630
- *
1631
- * @param mixed $value The array or string to be stripped.
1632
- * @return mixed $value The stripped value.
1633
- */
1634
- public static function stripslashes_from_strings_only($value) {
1635
- return is_string($value) ? stripslashes($value) : $value;
1636
- }
1637
-
1638
-
1639
- /**
1640
- * Normalize a filesystem path.
1641
- *
1642
- * On windows systems, replaces backslashes with forward slashes
1643
- * and forces upper-case drive letters.
1644
- * Allows for two leading slashes for Windows network shares, but
1645
- * ensures that all other duplicate slashes are reduced to a single.
1646
- *
1647
- * @param string $path Path to normalize.
1648
- * @return string Normalized path.
1649
- */
1650
- public static function wp_normalize_path( $path ) {
1651
- $wrapper = '';
1652
- if ( self::wp_is_stream( $path ) ) {
1653
- list( $wrapper, $path ) = explode( '://', $path, 2 );
1654
- $wrapper .= '://';
1655
- }
1656
-
1657
- // Standardise all paths to use /
1658
- $path = str_replace( '\\', '/', $path );
1659
-
1660
- // Replace multiple slashes down to a singular, allowing for network shares having two slashes.
1661
- $path = preg_replace( '|(?<=.)/+|', '/', $path );
1662
-
1663
- // Windows paths should uppercase the drive letter
1664
- if ( ':' === substr( $path, 1, 1 ) ) {
1665
- $path = ucfirst( $path );
1666
- }
1667
-
1668
- return $wrapper . $path;
1669
- }
1670
-
1671
- /**
1672
- * Test if a given path is a stream URL
1673
- *
1674
- * from wordpress function wp_is_stream
1675
- *
1676
- * @param string $path The resource path or URL.
1677
- * @return bool True if the path is a stream URL.
1678
- */
1679
- function wp_is_stream($path)
1680
- {
1681
- $scheme_separator = strpos($path, '://');
1682
-
1683
- if (false === $scheme_separator) {
1684
- // $path isn't a stream
1685
- return false;
1686
- }
1687
-
1688
- $stream = substr($path, 0, $scheme_separator);
1689
-
1690
- return in_array($stream, stream_get_wrappers(), true);
1691
- }
1692
-
1693
- /**
1694
- * Check if string is base64 encoded
1695
- *
1696
- * @param type $str
1697
- * @return boolean|str return false if isn't base64 string or decoded string
1698
- */
1699
- public static function is_base64($str)
1700
- {
1701
- // Check if there are valid base64 characters
1702
- if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $str)) {
1703
- return false;
1704
- }
1705
-
1706
- // Decode the string in strict mode and check the results
1707
- $decoded = base64_decode($str, true);
1708
- if (false === $decoded) {
1709
- return false;
1710
- }
1711
-
1712
- // Encode the string again
1713
- if (base64_encode($decoded) != $str) {
1714
- return false;
1715
- }
1716
-
1717
- return $decoded;
1718
- }
1719
-
1720
- /**
1721
- *
1722
- * @param array $matches
1723
- * @return string
1724
- */
1725
- public static function encodeUtf8CharFromRegexMatch($matches)
1726
- {
1727
- if (empty($matches) || !is_array($matches)) {
1728
- return '';
1729
- } else {
1730
- return json_decode('"'.$matches[0].'"');
1731
- }
1732
- }
1733
-
1734
- /**
1735
- * this function escape generic string to prevent security issue.
1736
- * Used to replace string in wp transformer
1737
- *
1738
- * for example
1739
- * abc'" become "abc'\""
1740
- *
1741
- * @param string $str input string
1742
- * @param bool $addQuote if true add " before and after string
1743
- * @return string
1744
- */
1745
- public static function getEscapedGenericString($str, $addQuote = true)
1746
- {
1747
- $result = DupLiteSnapJsonU::wp_json_encode(trim($str));
1748
- $result = str_replace(array('\/', '$'), array('/', '\\$'), $result);
1749
- $result = preg_replace_callback(
1750
- '/\\\\u[a-fA-F0-9]{4}/m', array(__CLASS__, 'encodeUtf8CharFromRegexMatch'), $result
1751
- );
1752
-
1753
- if (!$addQuote) {
1754
- $result = substr($result, 1 , strlen($result) -2);
1755
- }
1756
- return $result;
1757
- }
1758
-
1759
- /**
1760
- *
1761
- * @param array $input // es $_POST $_GET $_REQUEST
1762
- * @param string $key // key of array to check
1763
- * @param array $options // array('default' => null, default value to return if key don't exist
1764
- * 'trim' => false // if true trim sanitize value
1765
- * )
1766
- * @return type
1767
- */
1768
- public static function isset_sanitize($input, $key, $options = array())
1769
- {
1770
- $opt = array_merge(array('default' => null, 'trim' => false), $options);
1771
- if (isset($input[$key])) {
1772
- $result = DUPX_U::sanitize_text_field($input[$key]);
1773
- if ($opt['trim']) {
1774
- $result = trim($result);
1775
- }
1776
- return $result;
1777
- } else {
1778
- return $opt['default'];
1779
- }
1780
- }
1781
-
1782
- public static function boolToStr($input)
1783
- {
1784
- return $input ? 'true' : 'false';
1785
- }
1786
-
1787
- public static function boolToEnable($input)
1788
- {
1789
- return $input ? 'enable' : 'disable';
1790
- }
1791
  }
1
+ <?php
2
+ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
3
+
4
+ /**
5
+ * Various Static Utility methods for working with the installer
6
+ *
7
+ * Standard: PSR-2
8
+ * @link http://www.php-fig.org/psr/psr-2 Full Documentation
9
+ *
10
+ * @package SC\DUPX\U
11
+ *
12
+ */
13
+ class DUPX_U
14
+ {
15
+ public static $on_php_53_plus;
16
+
17
+ public static function init()
18
+ {
19
+ self::$on_php_53_plus = version_compare(PHP_VERSION, '5.3.2', '>=');
20
+ }
21
+
22
+ /**
23
+ * Adds a slash to the end of a file or directory path
24
+ *
25
+ * @param string $path A path
26
+ *
27
+ * @return string The original $path with a with '/' added to the end.
28
+ */
29
+ public static function addSlash($path)
30
+ {
31
+ $last_char = substr($path, strlen($path) - 1, 1);
32
+ if ($last_char != '/') {
33
+ $path .= '/';
34
+ }
35
+ return $path;
36
+ }
37
+
38
+ /**
39
+ * Add replacement strings with encoding to $GLOBALS['REPLACE_LIST']
40
+ *
41
+ * @param string $search
42
+ * @param string $replace
43
+ *
44
+ */
45
+ public static function queueReplacementWithEncodings($search, $replace)
46
+ {
47
+ array_push($GLOBALS['REPLACE_LIST'], array('search' => $search, 'replace' => $replace));
48
+
49
+ $search_json = str_replace('"', "", DupLiteSnapJsonU::wp_json_encode($search));
50
+ $replace_json = str_replace('"', "", DupLiteSnapJsonU::wp_json_encode($replace));
51
+
52
+ if ($search != $search_json) {
53
+ array_push($GLOBALS['REPLACE_LIST'], array('search' => $search_json, 'replace' => $replace_json));
54
+ }
55
+
56
+ $search_urlencode = urlencode($search);
57
+ $replace_urlencode = urlencode($replace);
58
+
59
+ if ($search != $search_urlencode) {
60
+ array_push($GLOBALS['REPLACE_LIST'], array('search' => $search_urlencode, 'replace' => $replace_urlencode));
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Add replace strings to substitute old url to new url
66
+ * 1) no protocol old url to no protocol new url (es. //www.hold.url => //www.new.url)
67
+ * 2) wrong protocol new url to right protocol new url (es. http://www.new.url => https://www.new.url)
68
+ *
69
+ * @param string $old
70
+ * @param string $new
71
+ */
72
+ public static function replacmentUrlOldToNew($old, $new)
73
+ {
74
+ //SEARCH WITH NO PROTOCOL: RAW "//"
75
+ $url_old_raw = str_ireplace(array('http://', 'https://'), '//', $old);
76
+ $url_new_raw = str_ireplace(array('http://', 'https://'), '//', $new);
77
+ DUPX_U::queueReplacementWithEncodings($url_old_raw, $url_new_raw);
78
+
79
+ //FORCE NEW PROTOCOL "//"
80
+ $url_new_info = parse_url($new);
81
+ $url_new_domain = $url_new_info['scheme'].'://'.$url_new_info['host'];
82
+
83
+ if ($url_new_info['scheme'] == 'http') {
84
+ $url_new_wrong_protocol = 'https://'.$url_new_info['host'];
85
+ } else {
86
+ $url_new_wrong_protocol = 'http://'.$url_new_info['host'];
87
+ }
88
+ DUPX_U::queueReplacementWithEncodings($url_new_wrong_protocol, $url_new_domain);
89
+ }
90
+
91
+ /**
92
+ * Does one string contain other
93
+ *
94
+ * @param string $haystack The full string to search
95
+ * @param string $needle The substring to search on
96
+ *
97
+ * @return bool Returns true if the $needle was found in the $haystack
98
+ */
99
+ public static function contains($haystack, $needle)
100
+ {
101
+ $pos = strpos($haystack, $needle);
102
+ return ($pos !== false);
103
+ }
104
+
105
+ /**
106
+ * Recursively copy files from one directory to another
107
+ *
108
+ * @param string $src - Source of files being moved
109
+ * @param string $dest - Destination of files being moved
110
+ * @param string $recursive recursively remove all items
111
+ *
112
+ * @return bool Returns true if all content was copied
113
+ */
114
+ public static function copyDirectory($src, $dest, $recursive = true)
115
+ {
116
+ //RSR TODO:Verify this logic
117
+ $success = true;
118
+
119
+ // If source is not a directory stop processing
120
+ if (!is_dir($src)) {
121
+ return false;
122
+ }
123
+
124
+ // If the destination directory does not exist create it
125
+ if (!DupLiteSnapLibIOU::dirWriteCheckOrMkdir($dest, 'u+rwx')) {
126
+ // If the destination directory could not be created stop processing
127
+ return false;
128
+ }
129
+
130
+ // Open the source directory to read in files
131
+ $iterator = new DirectoryIterator($src);
132
+
133
+ foreach ($iterator as $file) {
134
+ if ($file->isFile()) {
135
+ $success = copy($file->getRealPath(), "$dest/".$file->getFilename());
136
+ } else if (!$file->isDot() && $file->isDir() && $recursive) {
137
+ $success = self::copyDirectory($file->getRealPath(), "$dest/$file", $recursive);
138
+ }
139
+
140
+ if (!$success) {
141
+ break;
142
+ }
143
+ }
144
+
145
+ return $success;
146
+ }
147
+
148
+ /**
149
+ * Check to see if the internet is accessible
150
+ *
151
+ * Note: fsocketopen on windows doesn't seem to honor $timeout setting.
152
+ *
153
+ * @param string $url A url e.g without prefix "ajax.googleapis.com"
154
+ * @param string $port A valid port number
155
+ *
156
+ * @return bool Returns true PHP can request the URL
157
+ */
158
+ public static function isURLActive($url, $port, $timeout = 5)
159
+ {
160
+ $exists = false;
161
+ if (function_exists('get_headers')) {
162
+ $url = is_integer($port) ? $url . ':' . $port : $url;
163
+ DUPX_Handler::setMode(DUPX_Handler::MODE_OFF);
164
+ if (DupLiteSnapLibUtil::wp_is_ini_value_changeable('default_socket_timeout')) {
165
+ @ini_set("default_socket_timeout", $timeout);
166
+ }
167
+ $headers = @get_headers($url);
168
+ DUPX_Handler::setMode();
169
+ if (is_array($headers) && strpos($headers[0], '404') === false) {
170
+ $exists = true;
171
+ }
172
+ } else {
173
+ if (function_exists('fsockopen')) {
174
+ if (DupLiteSnapLibUtil::wp_is_ini_value_changeable('default_socket_timeout')) {
175
+ @ini_set("default_socket_timeout", $timeout);
176
+ }
177
+ $port = isset($port) && is_integer($port) ? $port : 80;
178
+ $host = parse_url($url, PHP_URL_HOST);
179
+ $connected = @fsockopen($host, $port, $errno, $errstr, $timeout); //website and port
180
+ if ($connected) {
181
+ @fclose($connected);
182
+ $exists = true;
183
+ }
184
+ }
185
+ }
186
+ return $exists;
187
+ }
188
+
189
+ /**
190
+ * move all folder content up to parent
191
+ *
192
+ * @param string $subFolderName full path
193
+ * @param boolean $deleteSubFolder if true delete subFolder after moved all
194
+ * @return boolean
195
+ *
196
+ */
197
+ public static function moveUpfromSubFolder($subFolderName, $deleteSubFolder = false)
198
+ {
199
+ if (!is_dir($subFolderName)) {
200
+ return false;
201
+ }
202
+
203
+ $parentFolder = dirname($subFolderName);
204
+ if (!is_writable($parentFolder)) {
205
+ return false;
206
+ }
207
+
208
+ $success = true;
209
+ if (($subList = glob(rtrim($subFolderName, '/').'/*', GLOB_NOSORT)) === false) {
210
+ DUPX_Log::info("Problem glob folder ".$subFolderName);
211
+ return false;
212
+ } else {
213
+ foreach ($subList as $cName) {
214
+ $destination = $parentFolder.'/'.basename($cName);
215
+ if (file_exists($destination)) {
216
+ $success = self::deletePath($destination);
217
+ }
218
+
219
+ if ($success) {
220
+ $success = rename($cName, $destination);
221
+ } else {
222
+ break;
223
+ }
224
+ }
225
+
226
+ if ($success && $deleteSubFolder) {
227
+ $success = self::deleteDirectory($subFolderName, true);
228
+ }
229
+ }
230
+
231
+ if (!$success) {
232
+ DUPX_Log::info("Problem om moveUpfromSubFolder subFolder:".$subFolderName);
233
+ }
234
+
235
+ return $success;
236
+ }
237
+
238
+ /**
239
+ * @param string $archive_filepath full path of zip archive
240
+ *
241
+ * @return boolean|string path of dup-installer folder of false if not found
242
+ */
243
+ public static function findDupInstallerFolder($archive_filepath)
244
+ {
245
+ $zipArchive = new ZipArchive();
246
+ $result = false;
247
+
248
+ if ($zipArchive->open($archive_filepath) === true) {
249
+ for ($i = 0; $i < $zipArchive->numFiles; $i++) {
250
+ $stat = $zipArchive->statIndex($i);
251
+ $safePath = rtrim(self::setSafePath($stat['name']), '/');
252
+ if (substr_count($safePath, '/') > 2) {
253
+ continue;
254
+ }
255
+
256
+ $exploded = explode('/',$safePath);
257
+ if (($dup_index = array_search('dup-installer' , $exploded)) !== false) {
258
+ $result = implode('/' , array_slice($exploded , 0 , $dup_index));
259
+ break;
260
+ }
261
+ }
262
+ if ($zipArchive->close() !== true) {
263
+ DUPX_Log::info("Can't close ziparchive:".$archive_filepath);
264
+ return false;
265
+ }
266
+ } else {
267
+ DUPX_Log::info("Can't open zip archive:".$archive_filepath);
268
+ return false;
269
+ }
270
+
271
+ return $result;
272
+ }
273
+
274
+ /**
275
+ * A safe method used to copy larger files
276
+ *
277
+ * @param string $source The path to the file being copied
278
+ * @param string $destination The path to the file being made
279
+ *
280
+ * @return null
281
+ */
282
+ public static function copyFile($source, $destination)
283
+ {
284
+ $sp = fopen($source, 'r');
285
+ $op = fopen($destination, 'w');
286
+
287
+ while (!feof($sp)) {
288
+ $buffer = fread($sp, 512); // use a buffer of 512 bytes
289
+ fwrite($op, $buffer);
290
+ }
291
+ // close handles
292
+ fclose($op);
293
+ fclose($sp);
294
+ }
295
+
296
+ /**
297
+ * Safely remove a directory and recursively if needed
298
+ *
299
+ * @param string $directory The full path to the directory to remove
300
+ * @param string $recursive recursively remove all items
301
+ *
302
+ * @return bool Returns true if all content was removed
303
+ */
304
+ public static function deleteDirectory($directory, $recursive)
305
+ {
306
+ $success = true;
307
+
308
+ $filenames = array_diff(scandir($directory), array('.', '..'));
309
+
310
+ foreach ($filenames as $filename) {
311
+ $fullPath = $directory.'/'.$filename;
312
+
313
+ if (is_dir($fullPath)) {
314
+ if ($recursive) {
315
+ $success = self::deleteDirectory($fullPath, true);
316
+ }
317
+ } else {
318
+ $success = @unlink($fullPath);
319
+ if ($success === false) {
320
+ DUPX_Log::info( __FUNCTION__.": Problem deleting file:".$fullPath);
321
+ }
322
+ }
323
+
324
+ if ($success === false) {
325
+ DUPX_Log::info("Problem deleting dir:".$directory);
326
+ break;
327
+ }
328
+ }
329
+
330
+ return $success && rmdir($directory);
331
+ }
332
+
333
+ /**
334
+ * Safely remove a file or directory and recursively if needed
335
+ *
336
+ * @param string $directory The full path to the directory to remove
337
+ *
338
+ * @return bool Returns true if all content was removed
339
+ */
340
+ public static function deletePath($path)
341
+ {
342
+ $success = true;
343
+
344
+ if (is_dir($path)) {
345
+ $success = self::deleteDirectory($path, true);
346
+ } else {
347
+ $success = @unlink($path);
348
+
349
+ if ($success === false) {
350
+ DUPX_Log::info( __FUNCTION__.": Problem deleting file:".$path);
351
+ }
352
+ }
353
+
354
+ return $success;
355
+ }
356
+
357
+ /**
358
+ * Dumps a variable for debugging
359
+ *
360
+ * @param string $var The variable to view
361
+ * @param bool $pretty Pretty print the var
362
+ *
363
+ * @return object A visual representation of an object
364
+ */
365
+ public static function dump($var, $pretty = false)
366
+ {
367
+ if ($pretty) {
368
+ echo '<pre>';
369
+ print_r($var);
370
+ echo '</pre>';
371
+ } else {
372
+ print_r($var);
373
+ }
374
+ }
375
+
376
+ public static function echoBool($val)
377
+ {
378
+ if($val) {
379
+ echo 'true';
380
+ } else {
381
+ echo 'false';
382
+ }
383
+ }
384
+
385
+ /**
386
+ * Return a string with the elapsed time
387
+ *
388
+ * @see getMicrotime()
389
+ *
390
+ * @param mixed number $end The final time in the sequence to measure
391
+ * @param mixed number $start The start time in the sequence to measure
392
+ *
393
+ * @return string The time elapsed from $start to $end
394
+ */
395
+ public static function elapsedTime($end, $start)
396
+ {
397
+ return sprintf("%.4f sec.", abs($end - $start));
398
+ }
399
+
400
+ /**
401
+ * Returns 256 spaces
402
+ *
403
+ * PHP_SAPI for fcgi requires a data flush of at least 256
404
+ * bytes every 40 seconds or else it forces a script halt
405
+ *
406
+ * @return string A series of 256 spaces ' '
407
+ */
408
+ public static function fcgiFlush()
409
+ {
410
+ echo(str_repeat(' ', 256));
411
+ @flush();
412
+ }
413
+
414
+ /**
415
+ * Returns the active plugins for the WordPress website in the package
416
+ *
417
+ * @param obj $dbh A database connection handle
418
+ *
419
+ * @return array $list A list of active plugins
420
+ */
421
+ public static function getActivePlugins($dbh)
422
+ {
423
+ // Standard WP installation
424
+ $select = "option_value";
425
+ $table = "options";
426
+ $where = "option_name = 'active_plugins'";
427
+
428
+
429
+ $query = @mysqli_query($dbh, "SELECT {$select} FROM `".mysqli_real_escape_string($dbh, $GLOBALS['DUPX_AC']->wp_tableprefix).mysqli_real_escape_string($dbh, $table)."` WHERE {$where} ");
430
+ if ($query) {
431
+ $row = @mysqli_fetch_array($query);
432
+ $plugins_ser_str = stripslashes($row[0]);
433
+ $all_plugins = unserialize($plugins_ser_str);
434
+
435
+ // Return data properly
436
+ if (is_array($all_plugins)) {
437
+ return $all_plugins;
438
+ }
439
+ }
440
+ return array();
441
+ }
442
+
443
+ /**
444
+ * Get current microtime as a float. Method is used for simple profiling
445
+ *
446
+ * @see elapsedTime
447
+ *
448
+ * @return string A float in the form "msec sec", where sec is the number of seconds since the Unix epoch
449
+ */
450
+ public static function getMicrotime()
451
+ {
452
+ return microtime(true);
453
+ }
454
+
455
+ /**
456
+ * Gets the size of a variable in memory
457
+ *
458
+ * @param $var A valid PHP variable
459
+ *
460
+ * @returns int The amount of memory the variable has consumed
461
+ */
462
+ public static function getVarSize($var)
463
+ {
464
+ $start_memory = memory_get_usage();
465
+ $var = unserialize(serialize($var));
466
+ return memory_get_usage() - $start_memory - PHP_INT_SIZE * 8;
467
+ }
468
+
469
+ /**
470
+ * Is the string JSON
471
+ *
472
+ * @param string $string Any string blob
473
+ *
474
+ * @return bool Returns true if the string is JSON encoded
475
+ */
476
+ public static function isJSON($string)
477
+ {
478
+
479
+ return is_string($string) && is_array(json_decode($string, true)) ? true : false;
480
+ }
481
+
482
+ /**
483
+ * Does a string have non ASCII characters
484
+ *
485
+ * @param string $string Any string blob
486
+ *
487
+ * @return bool Returns true if any non ASCII character is found in the blob
488
+ */
489
+ public static function isNonASCII($string)
490
+ {
491
+ return preg_match('/[^\x20-\x7f]/', $string);
492
+ }
493
+
494
+ /**
495
+ * Is an object traversable
496
+ *
497
+ * @param object $obj The object to evaluate
498
+ *
499
+ * @return bool Returns true if the object can be looped over safely
500
+ */
501
+ public static function isTraversable($obj)
502
+ {
503
+ if (is_null($obj))
504
+ return false;
505
+
506
+ return (is_array($obj) || $obj instanceof Traversable);
507
+ }
508
+
509
+ /**
510
+ * Is the server running Windows operating system
511
+ *
512
+ * @return bool Returns true if operating system is Windows
513
+ *
514
+ */
515
+ public static function isWindows()
516
+ {
517
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
518
+ {
519
+ return true;
520
+ }
521
+ return false;
522
+ }
523
+
524
+ /**
525
+ * The characters that are special in the replacement value of preg_replace are not the
526
+ * same characters that are special in the pattern. Allows for '$' to be safely passed.
527
+ *
528
+ * @param string $str The string to replace on
529
+ */
530
+ public static function pregReplacementQuote($str)
531
+ {
532
+ return preg_replace('/(\$|\\\\)(?=\d)/', '\\\\\1', $str);
533
+ }
534
+
535
+ /**
536
+ * Display human readable byte sizes
537
+ *
538
+ * @param string $size The size in bytes
539
+ *
540
+ * @return string Human readable bytes such as 50MB, 1GB
541
+ */
542
+ public static function readableByteSize($size)
543
+ {
544
+ try {
545
+ $units = array('B', 'KB', 'MB', 'GB', 'TB');
546
+ for ($i = 0; $size >= 1024 && $i < 4; $i++)
547
+ $size /= 1024;
548
+ return round($size, 2).$units[$i];
549
+ } catch (Exception $e) {
550
+ return "n/a";
551
+ }
552
+ }
553
+
554
+ /**
555
+ * Converts shorthand memory notation value to bytes
556
+ * From http://php.net/manual/en/function.ini-get.php
557
+ *
558
+ * @param $val Memory size shorthand notation string
559
+ *
560
+ * @return int Returns the numeric byte from 1MB to 1024
561
+ */
562
+ public static function returnBytes($val)
563
+ {
564
+ $val = trim($val);
565
+ $last = strtolower($val[strlen($val) - 1]);
566
+ $val = intval($val);
567
+ switch ($last) {
568
+ // The 'G' modifier is available since PHP 5.1.0
569
+ case 'g':
570
+ $val *= 1024;
571
+ case 'm':
572
+ $val *= 1024;
573
+ case 'k':
574
+ $val *= 1024;
575
+ break;
576
+ default :
577
+ $val = null;
578
+ }
579
+ return $val;
580
+ }
581
+
582
+ /**
583
+ * Filter the string to escape the quote
584
+ *
585
+ * @param string $val The value to escape quote
586
+ *
587
+ * @return string Returns the input value escaped
588
+ */
589
+ public static function safeQuote($val)
590
+ {
591
+ $val = addslashes($val);
592
+ return $val;
593
+ }
594
+
595
+ /**
596
+ * Makes path safe for any OS for PHP
597
+ *
598
+ * Paths should ALWAYS READ be "/"
599
+ * uni: /home/path/file.txt
600
+ * win: D:/home/path/file.txt
601
+ *
602
+ * @param string $path The path to make safe
603
+ *
604
+ * @return string The original $path with a with all slashes facing '/'.
605
+ */
606
+ public static function setSafePath($path)
607
+ {
608
+ return str_replace("\\", "/", $path);
609
+ }
610
+
611
+ /**
612
+ * Looks for a list of strings in a string and returns each list item that is found
613
+ *
614
+ * @param array $list An array of strings to search for
615
+ * @param string $haystack The string blob to search through
616
+ *
617
+ * @return array An array of strings from the $list array found in the $haystack
618
+ */
619
+ public static function getListValues($list, $haystack)
620
+ {
621
+ $found = array();
622
+ foreach ($list as $var) {
623
+ if (strstr($haystack, $var) !== false) {
624
+ array_push($found, $var);
625
+ }
626
+ }
627
+ return $found;
628
+ }
629
+
630
+ /**
631
+ * Makes path unsafe for any OS for PHP used primarily to show default
632
+ * Windows OS path standard
633
+ *
634
+ * @param string $path The path to make unsafe
635
+ *
636
+ * @return string The original $path with a with all slashes facing '\'.
637
+ */
638
+ public static function unsetSafePath($path)
639
+ {
640
+ return str_replace("/", "\\", $path);
641
+ }
642
+
643
+ /**
644
+ * Check PHP version
645
+ *
646
+ * @param string $version PHP version we looking for
647
+ *
648
+ * @return boolean Returns true if version is same or above.
649
+ */
650
+ public static function isVersion($version)
651
+ {
652
+ return (version_compare(PHP_VERSION, $version) >= 0);
653
+ }
654
+
655
+ /**
656
+ * Checks if ssl is enabled
657
+ * @return bool
658
+ */
659
+ public static function is_ssl()
660
+ {
661
+ if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
662
+ $_SERVER ['HTTPS'] = 'on';
663
+ }
664
+
665
+ if ( isset($_SERVER['HTTPS']) ) {
666
+ if ( 'on' == strtolower($_SERVER['HTTPS']) )
667
+ return true;
668
+ if ( '1' == $_SERVER['HTTPS'] )
669
+ return true;
670
+ } elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
671
+ return true;
672
+ }
673
+
674
+ return false;
675
+ }
676
+
677
+ /**
678
+ * @param $url string The URL whichs domain you want to get
679
+ * @return string The domain part of the given URL
680
+ * www.myurl.co.uk => myurl.co.uk
681
+ * www.google.com => google.com
682
+ * my.test.myurl.co.uk => myurl.co.uk
683
+ * www.myurl.localweb => myurl.localweb
684
+ *
685
+ */
686
+ public static function getDomain($url)
687
+ {
688
+ $pieces = parse_url($url);
689
+ $domain = isset($pieces['host']) ? $pieces['host'] : '';
690
+ if (strpos($domain, ".") !== false) {
691
+ if (preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs)) {
692
+ return $regs['domain'];
693
+ } else {
694
+ $exDomain = explode('.', $domain);
695
+ return implode('.', array_slice($exDomain, -2, 2));
696
+ }
697
+ } else {
698
+ return $domain;
699
+ }
700
+ }
701
+
702
+ // START ESCAPING AND SANITIZATION
703
+ /**
704
+ * Escaping for HTML blocks.
705
+ *
706
+ *
707
+ * @param string $text
708
+ * @return string
709
+ */
710
+ public static function esc_html( $text ) {
711
+ $safe_text = DupLiteSnapJsonU::wp_check_invalid_utf8( $text );
712
+ $safe_text = self::_wp_specialchars( $safe_text, ENT_QUOTES );
713
+ /**
714
+ * Filters a string cleaned and escaped for output in HTML.
715
+ *
716
+ * Text passed to esc_html() is stripped of invalid or special characters
717
+ * before output.
718
+ *
719
+ * @param string $safe_text The text after it has been escaped.
720
+ * @param string $text The text prior to being escaped.
721
+ */
722
+ return $safe_text;
723
+ }
724
+
725
+ /**
726
+ * Escape single quotes, htmlspecialchar " < > &, and fix line endings.
727
+ *
728
+ * Escapes text strings for echoing in JS. It is intended to be used for inline JS
729
+ * (in a tag attribute, for example onclick="..."). Note that the strings have to
730
+ * be in single quotes. The {@see 'js_escape'} filter is also applied here.
731
+ *
732
+ *
733
+ * @param string $text The text to be escaped.
734
+ * @return string Escaped text.
735
+ */
736
+ public static function esc_js( $text ) {
737
+ $safe_text = DupLiteSnapJsonU::wp_check_invalid_utf8( $text );
738
+ $safe_text = self::_wp_specialchars( $safe_text, ENT_COMPAT );
739
+ $safe_text = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes( $safe_text ) );
740
+ $safe_text = str_replace( "\r", '', $safe_text );
741
+ $safe_text = str_replace( "\n", '\\n', addslashes( $safe_text ) );
742
+ /**
743
+ * Filters a string cleaned and escaped for output in JavaScript.
744
+ *
745
+ * Text passed to esc_js() is stripped of invalid or special characters,
746
+ * and properly slashed for output.
747
+ *
748
+ * @param string $safe_text The text after it has been escaped.
749
+ * @param string $text The text prior to being escaped.
750
+ */
751
+ return $safe_text;
752
+ }
753
+
754
+ /**
755
+ * Escaping for HTML attributes.
756
+ *
757
+ * @param string $text
758
+ * @return string
759
+ */
760
+ public static function esc_attr( $text ) {
761
+ $safe_text = DupLiteSnapJsonU::wp_check_invalid_utf8( $text );
762
+ $safe_text = self::_wp_specialchars( $safe_text, ENT_QUOTES );
763
+ /**
764
+ * Filters a string cleaned and escaped for output in an HTML attribute.
765
+ *
766
+ * Text passed to esc_attr() is stripped of invalid or special characters
767
+ * before output.
768
+ *
769
+ * @param string $safe_text The text after it has been escaped.
770
+ * @param string $text The text prior to being escaped.
771
+ */
772
+ return $safe_text;
773
+ }
774
+
775
+ /**
776
+ * Escaping for textarea values.
777
+ *
778
+ * @param string $text
779
+ * @return string
780
+ */
781
+ public static function esc_textarea( $text )
782
+ {
783
+ $safe_text = htmlspecialchars( $text, ENT_QUOTES, 'UTF-8' );
784
+ /**
785
+ * Filters a string cleaned and escaped for output in a textarea element.
786
+ *
787
+ * @param string $safe_text The text after it has been escaped.
788
+ * @param string $text The text prior to being escaped.
789
+ */
790
+ return $safe_text;
791
+ }
792
+
793
+ /**
794
+ * Escape an HTML tag name.
795
+ *
796
+ * @param string $tag_name
797
+ * @return string
798
+ */
799
+ function tag_escape( $tag_name ) {
800
+ $safe_tag = strtolower( preg_replace('/[^a-zA-Z0-9_:]/', '', $tag_name) );
801
+ /**
802
+ * Filters a string cleaned and escaped for output as an HTML tag.
803
+ *
804
+ * @param string $safe_tag The tag name after it has been escaped.
805
+ * @param string $tag_name The text before it was escaped.
806
+ */
807
+ return $safe_tag;
808
+ }
809
+
810
+ /**
811
+ * Converts a number of special characters into their HTML entities.
812
+ *
813
+ * Specifically deals with: &, <, >, ", and '.
814
+ *
815
+ * $quote_style can be set to ENT_COMPAT to encode " to
816
+ * &quot;, or ENT_QUOTES to do both. Default is ENT_NOQUOTES where no quotes are encoded.
817
+ *
818
+ * @access private
819
+ *
820
+ * @staticvar string $_charset
821
+ *
822
+ * @param string $string The text which is to be encoded.
823
+ * @param int|string $quote_style Optional. Converts double quotes if set to ENT_COMPAT,
824
+ * both single and double if set to ENT_QUOTES or none if set to ENT_NOQUOTES.
825
+ * Also compatible with old values; converting single quotes if set to 'single',
826
+ * double if set to 'double' or both if otherwise set.
827
+ * Default is ENT_NOQUOTES.
828
+ * @param string $charset Optional. The character encoding of the string. Default is false.
829
+ * @param bool $double_encode Optional. Whether to encode existing html entities. Default is false.
830
+ * @return string The encoded text with HTML entities.
831
+ */
832
+ public static function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) {
833
+ $string = (string) $string;
834
+
835
+ if ( 0 === strlen( $string ) )
836
+ return '';
837
+
838
+ // Don't bother if there are no specialchars - saves some processing
839
+ if ( ! preg_match( '/[&<>"\']/', $string ) )
840
+ return $string;
841
+
842
+ // Account for the previous behaviour of the function when the $quote_style is not an accepted value
843
+ if ( empty( $quote_style ) )
844
+ $quote_style = ENT_NOQUOTES;
845
+ elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) )
846
+ $quote_style = ENT_QUOTES;
847
+
848
+ // Store the site charset as a static to avoid multiple calls to wp_load_alloptions()
849
+ if ( ! $charset ) {
850
+ static $_charset = null;
851
+ if ( ! isset( $_charset ) ) {
852
+ $_charset = '';
853
+ }
854
+ $charset = $_charset;
855
+ }
856
+
857
+ if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) )
858
+ $charset = 'UTF-8';
859
+
860
+ $_quote_style = $quote_style;
861
+
862
+ if ( $quote_style === 'double' ) {
863
+ $quote_style = ENT_COMPAT;
864
+ $_quote_style = ENT_COMPAT;
865
+ } elseif ( $quote_style === 'single' ) {
866
+ $quote_style = ENT_NOQUOTES;
867
+ }
868
+
869
+ if ( ! $double_encode ) {
870
+ // Guarantee every &entity; is valid, convert &garbage; into &amp;garbage;
871
+ // This is required for PHP < 5.4.0 because ENT_HTML401 flag is unavailable.
872
+ $string = self::wp_kses_normalize_entities( $string );
873
+ }
874
+
875
+ $string = @htmlspecialchars( $string, $quote_style, $charset, $double_encode );
876
+
877
+ // Back-compat.
878
+ if ( 'single' === $_quote_style )
879
+ $string = str_replace( "'", '&#039;', $string );
880
+
881
+ return $string;
882
+ }
883
+
884
+ /**
885
+ * Converts a number of HTML entities into their special characters.
886
+ *
887
+ * Specifically deals with: &, <, >, ", and '.
888
+ *
889
+ * $quote_style can be set to ENT_COMPAT to decode " entities,
890
+ * or ENT_QUOTES to do both " and '. Default is ENT_NOQUOTES where no quotes are decoded.
891
+ *
892
+ * @param string $string The text which is to be decoded.
893
+ * @param string|int $quote_style Optional. Converts double quotes if set to ENT_COMPAT,
894
+ * both single and double if set to ENT_QUOTES or
895
+ * none if set to ENT_NOQUOTES.
896
+ * Also compatible with old _wp_specialchars() values;
897
+ * converting single quotes if set to 'single',
898
+ * double if set to 'double' or both if otherwise set.
899
+ * Default is ENT_NOQUOTES.
900
+ * @return string The decoded text without HTML entities.
901
+ */
902
+ public static function wp_specialchars_decode( $string, $quote_style = ENT_NOQUOTES ) {
903
+ $string = (string) $string;
904
+
905
+ if ( 0 === strlen( $string ) ) {
906
+ return '';
907
+ }
908
+
909
+ // Don't bother if there are no entities - saves a lot of processing
910
+ if ( strpos( $string, '&' ) === false ) {
911
+ return $string;
912
+ }
913
+
914
+ // Match the previous behaviour of _wp_specialchars() when the $quote_style is not an accepted value
915
+ if ( empty( $quote_style ) ) {
916
+ $quote_style = ENT_NOQUOTES;
917
+ } elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) {
918
+ $quote_style = ENT_QUOTES;
919
+ }
920
+
921
+ // More complete than get_html_translation_table( HTML_SPECIALCHARS )
922
+ $single = array( '&#039;' => '\'', '&#x27;' => '\'' );
923
+ $single_preg = array( '/&#0*39;/' => '&#039;', '/&#x0*27;/i' => '&#x27;' );
924
+ $double = array( '&quot;' => '"', '&#034;' => '"', '&#x22;' => '"' );
925
+ $double_preg = array( '/&#0*34;/' => '&#034;', '/&#x0*22;/i' => '&#x22;' );
926
+ $others = array( '&lt;' => '<', '&#060;' => '<', '&gt;' => '>', '&#062;' => '>', '&amp;' => '&', '&#038;' => '&', '&#x26;' => '&' );
927
+ $others_preg = array( '/&#0*60;/' => '&#060;', '/&#0*62;/' => '&#062;', '/&#0*38;/' => '&#038;', '/&#x0*26;/i' => '&#x26;' );
928
+
929
+ if ( $quote_style === ENT_QUOTES ) {
930
+ $translation = array_merge( $single, $double, $others );
931
+ $translation_preg = array_merge( $single_preg, $double_preg, $others_preg );
932
+ } elseif ( $quote_style === ENT_COMPAT || $quote_style === 'double' ) {
933
+ $translation = array_merge( $double, $others );
934
+ $translation_preg = array_merge( $double_preg, $others_preg );
935
+ } elseif ( $quote_style === 'single' ) {
936
+ $translation = array_merge( $single, $others );
937
+ $translation_preg = array_merge( $single_preg, $others_preg );
938
+ } elseif ( $quote_style === ENT_NOQUOTES ) {
939
+ $translation = $others;
940
+ $translation_preg = $others_preg;
941
+ }
942
+
943
+ // Remove zero padding on numeric entities
944
+ $string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string );
945
+
946
+ // Replace characters according to translation table
947
+ return strtr( $string, $translation );
948
+ }
949
+
950
+ /**
951
+ * Perform a deep string replace operation to ensure the values in $search are no longer present
952
+ *
953
+ * Repeats the replacement operation until it no longer replaces anything so as to remove "nested" values
954
+ * e.g. $subject = '%0%0%0DDD', $search ='%0D', $result ='' rather than the '%0%0DD' that
955
+ * str_replace would return
956
+ * @access private
957
+ *
958
+ * @param string|array $search The value being searched for, otherwise known as the needle.
959
+ * An array may be used to designate multiple needles.
960
+ * @param string $subject The string being searched and replaced on, otherwise known as the haystack.
961
+ * @return string The string with the replaced svalues.
962
+ */
963
+ private static function _deep_replace( $search, $subject ) {
964
+ $subject = (string) $subject;
965
+
966
+ $count = 1;
967
+ while ( $count ) {
968
+ $subject = str_replace( $search, '', $subject, $count );
969
+ }
970
+
971
+ return $subject;
972
+ }
973
+
974
+ /**
975
+ * Converts and fixes HTML entities.
976
+ *
977
+ * This function normalizes HTML entities. It will convert `AT&T` to the correct
978
+ * `AT&amp;T`, `&#00058;` to `&#58;`, `&#XYZZY;` to `&amp;#XYZZY;` and so on.
979
+ *
980
+ * @param string $string Content to normalize entities
981
+ * @return string Content with normalized entities
982
+ */
983
+ public static function wp_kses_normalize_entities($string)
984
+ {
985
+ // Disarm all entities by converting & to &amp;
986
+ $string = str_replace('&', '&amp;', $string);
987
+
988
+ // Change back the allowed entities in our entity whitelist
989
+ $string = preg_replace_callback('/&amp;([A-Za-z]{2,8}[0-9]{0,2});/', array(__CLASS__, 'wp_kses_named_entities'), $string);
990
+ $string = preg_replace_callback('/&amp;#(0*[0-9]{1,7});/', array(__CLASS__, 'wp_kses_normalize_entities2'), $string);
991
+ $string = preg_replace_callback('/&amp;#[Xx](0*[0-9A-Fa-f]{1,6});/', array(__CLASS__, 'wp_kses_normalize_entities3'), $string);
992
+
993
+ return $string;
994
+ }
995
+
996
+ /**
997
+ * Callback for wp_kses_normalize_entities() regular expression.
998
+ *
999
+ * This function only accepts valid named entity references, which are finite,
1000
+ * case-sensitive, and highly scrutinized by HTML and XML validators.
1001
+ *
1002
+ * @global array $allowedentitynames
1003
+ *
1004
+ * @param array $matches preg_replace_callback() matches array
1005
+ * @return string Correctly encoded entity
1006
+ */
1007
+ public static function wp_kses_named_entities($matches) {
1008
+ if ( empty($matches[1]) )
1009
+ return '';
1010
+
1011
+ $allowedentitynames = array(
1012
+ 'nbsp', 'iexcl', 'cent', 'pound', 'curren', 'yen',
1013
+ 'brvbar', 'sect', 'uml', 'copy', 'ordf', 'laquo',
1014
+ 'not', 'shy', 'reg', 'macr', 'deg', 'plusmn',
1015
+ 'acute', 'micro', 'para', 'middot', 'cedil', 'ordm',
1016
+ 'raquo', 'iquest', 'Agrave', 'Aacute', 'Acirc', 'Atilde',
1017
+ 'Auml', 'Aring', 'AElig', 'Ccedil', 'Egrave', 'Eacute',
1018
+ 'Ecirc', 'Euml', 'Igrave', 'Iacute', 'Icirc', 'Iuml',
1019
+ 'ETH', 'Ntilde', 'Ograve', 'Oacute', 'Ocirc', 'Otilde',
1020
+ 'Ouml', 'times', 'Oslash', 'Ugrave', 'Uacute', 'Ucirc',
1021
+ 'Uuml', 'Yacute', 'THORN', 'szlig', 'agrave', 'aacute',
1022
+ 'acirc', 'atilde', 'auml', 'aring', 'aelig', 'ccedil',
1023
+ 'egrave', 'eacute', 'ecirc', 'euml', 'igrave', 'iacute',
1024
+ 'icirc', 'iuml', 'eth', 'ntilde', 'ograve', 'oacute',
1025
+ 'ocirc', 'otilde', 'ouml', 'divide', 'oslash', 'ugrave',
1026
+ 'uacute', 'ucirc', 'uuml', 'yacute', 'thorn', 'yuml',
1027
+ 'quot', 'amp', 'lt', 'gt', 'apos', 'OElig',
1028
+ 'oelig', 'Scaron', 'scaron', 'Yuml', 'circ', 'tilde',
1029
+ 'ensp', 'emsp', 'thinsp', 'zwnj', 'zwj', 'lrm',
1030
+ 'rlm', 'ndash', 'mdash', 'lsquo', 'rsquo', 'sbquo',
1031
+ 'ldquo', 'rdquo', 'bdquo', 'dagger', 'Dagger', 'permil',
1032
+ 'lsaquo', 'rsaquo', 'euro', 'fnof', 'Alpha', 'Beta',
1033
+ 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta', 'Theta',
1034
+ 'Iota', 'Kappa', 'Lambda', 'Mu', 'Nu', 'Xi',
1035
+ 'Omicron', 'Pi', 'Rho', 'Sigma', 'Tau', 'Upsilon',
1036
+ 'Phi', 'Chi', 'Psi', 'Omega', 'alpha', 'beta',
1037
+ 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta',
1038
+ 'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi',
1039
+ 'omicron', 'pi', 'rho', 'sigmaf', 'sigma', 'tau',
1040
+ 'upsilon', 'phi', 'chi', 'psi', 'omega', 'thetasym',
1041
+ 'upsih', 'piv', 'bull', 'hellip', 'prime', 'Prime',
1042
+ 'oline', 'frasl', 'weierp', 'image', 'real', 'trade',
1043
+ 'alefsym', 'larr', 'uarr', 'rarr', 'darr', 'harr',
1044
+ 'crarr', 'lArr', 'uArr', 'rArr', 'dArr', 'hArr',
1045
+ 'forall', 'part', 'exist', 'empty', 'nabla', 'isin',
1046
+ 'notin', 'ni', 'prod', 'sum', 'minus', 'lowast',
1047
+ 'radic', 'prop', 'infin', 'ang', 'and', 'or',
1048
+ 'cap', 'cup', 'int', 'sim', 'cong', 'asymp',
1049
+ 'ne', 'equiv', 'le', 'ge', 'sub', 'sup',
1050
+ 'nsub', 'sube', 'supe', 'oplus', 'otimes', 'perp',
1051
+ 'sdot', 'lceil', 'rceil', 'lfloor', 'rfloor', 'lang',
1052
+ 'rang', 'loz', 'spades', 'clubs', 'hearts', 'diams',
1053
+ 'sup1', 'sup2', 'sup3', 'frac14', 'frac12', 'frac34',
1054
+ 'there4',
1055
+ );
1056
+
1057
+ $i = $matches[1];
1058
+ return ( ! in_array( $i, $allowedentitynames ) ) ? "&amp;$i;" : "&$i;";
1059
+ }
1060
+
1061
+
1062
+ /**
1063
+ * Helper function to determine if a Unicode value is valid.
1064
+ *
1065
+ * @param int $i Unicode value
1066
+ * @return bool True if the value was a valid Unicode number
1067
+ */
1068
+ public static function wp_valid_unicode($i) {
1069
+ return ( $i == 0x9 || $i == 0xa || $i == 0xd ||
1070
+ ($i >= 0x20 && $i <= 0xd7ff) ||
1071
+ ($i >= 0xe000 && $i <= 0xfffd) ||
1072
+ ($i >= 0x10000 && $i <= 0x10ffff) );
1073
+ }
1074
+
1075
+ /**
1076
+ * Callback for wp_kses_normalize_entities() regular expression.
1077
+ *
1078
+ * This function helps wp_kses_normalize_entities() to only accept 16-bit
1079
+ * values and nothing more for `&#number;` entities.
1080
+ *
1081
+ * @access private
1082
+ *
1083
+ * @param array $matches preg_replace_callback() matches array
1084
+ * @return string Correctly encoded entity
1085
+ */
1086
+ public static function wp_kses_normalize_entities2($matches) {
1087
+ if ( empty($matches[1]) )
1088
+ return '';
1089
+
1090
+ $i = $matches[1];
1091
+ if (self::wp_valid_unicode($i)) {
1092
+ $i = str_pad(ltrim($i,'0'), 3, '0', STR_PAD_LEFT);
1093
+ $i = "&#$i;";
1094
+ } else {
1095
+ $i = "&amp;#$i;";
1096
+ }
1097
+
1098
+ return $i;
1099
+ }
1100
+
1101
+ /**
1102
+ * Callback for wp_kses_normalize_entities() for regular expression.
1103
+ *
1104
+ * This function helps wp_kses_normalize_entities() to only accept valid Unicode
1105
+ * numeric entities in hex form.
1106
+ *
1107
+ * @access private
1108
+ *
1109
+ * @param array $matches preg_replace_callback() matches array
1110
+ * @return string Correctly encoded entity
1111
+ */
1112
+ public static function wp_kses_normalize_entities3($matches) {
1113
+ if ( empty($matches[1]) )
1114
+ return '';
1115
+
1116
+ $hexchars = $matches[1];
1117
+ return ( ! self::wp_valid_unicode( hexdec( $hexchars ) ) ) ? "&amp;#x$hexchars;" : '&#x'.ltrim($hexchars,'0').';';
1118
+ }
1119
+
1120
+ /**
1121
+ * Retrieve a list of protocols to allow in HTML attributes.
1122
+ *
1123
+ * @since 3.3.0
1124
+ * @since 4.3.0 Added 'webcal' to the protocols array.
1125
+ * @since 4.7.0 Added 'urn' to the protocols array.
1126
+ *
1127
+ * @see wp_kses()
1128
+ * @see esc_url()
1129
+ *
1130
+ * @staticvar array $protocols
1131
+ *
1132
+ * @return array Array of allowed protocols. Defaults to an array containing 'http', 'https',
1133
+ * 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet',
1134
+ * 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', and 'urn'.
1135
+ */
1136
+ public static function wp_allowed_protocols() {
1137
+ static $protocols = array();
1138
+
1139
+ if ( empty( $protocols ) ) {
1140
+ $protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', 'urn' );
1141
+ }
1142
+
1143
+ return $protocols;
1144
+ }
1145
+
1146
+ /**
1147
+ * Checks and cleans a URL.
1148
+ *
1149
+ * A number of characters are removed from the URL. If the URL is for displaying
1150
+ * (the default behaviour) ampersands are also replaced. The {@see 'clean_url'} filter
1151
+ * is applied to the returned cleaned URL.
1152
+ *
1153
+ * @since 2.8.0
1154
+ *
1155
+ * @param string $url The URL to be cleaned.
1156
+ * @param array $protocols Optional. An array of acceptable protocols.
1157
+ * Defaults to return value of wp_allowed_protocols()
1158
+ * @param string $_context Private. Use esc_url_raw() for database usage.
1159
+ * @return string The cleaned $url after the {@see 'clean_url'} filter is applied.
1160
+ */
1161
+ public static function esc_url( $url, $protocols = null, $_context = 'display' ) {
1162
+ $original_url = $url;
1163
+
1164
+ if ( '' == $url )
1165
+ return $url;
1166
+
1167
+ $url = str_replace( ' ', '%20', $url );
1168
+ $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url);
1169
+
1170
+ if ( '' === $url ) {
1171
+ return $url;
1172
+ }
1173
+
1174
+ if ( 0 !== stripos( $url, 'mailto:' ) ) {
1175
+ $strip = array('%0d', '%0a', '%0D', '%0A');
1176
+ $url = self::_deep_replace($strip, $url);
1177
+ }
1178
+
1179
+ $url = str_replace(';//', '://', $url);
1180
+ /* If the URL doesn't appear to contain a scheme, we
1181
+ * presume it needs http:// prepended (unless a relative
1182
+ * link starting with /, # or ? or a php file).
1183
+ */
1184
+ if ( strpos($url, ':') === false && ! in_array( $url[0], array( '/', '#', '?' ) ) &&
1185
+ ! preg_match('/^[a-z0-9-]+?\.php/i', $url) )
1186
+ $url = 'http://' . $url;
1187
+
1188
+ // Replace ampersands and single quotes only when displaying.
1189
+ if ( 'display' == $_context ) {
1190
+ $url = self::wp_kses_normalize_entities( $url );
1191
+ $url = str_replace( '&amp;', '&#038;', $url );
1192
+ $url = str_replace( "'", '&#039;', $url );
1193
+ }
1194
+
1195
+ if ( ( false !== strpos( $url, '[' ) ) || ( false !== strpos( $url, ']' ) ) ) {
1196
+
1197
+ $parsed = wp_parse_url( $url );
1198
+ $front = '';
1199
+
1200
+ if ( isset( $parsed['scheme'] ) ) {
1201
+ $front .= $parsed['scheme'] . '://';
1202
+ } elseif ( '/' === $url[0] ) {
1203
+ $front .= '//';
1204
+ }
1205
+
1206
+ if ( isset( $parsed['user'] ) ) {
1207
+ $front .= $parsed['user'];
1208
+ }
1209
+
1210
+ if ( isset( $parsed['pass'] ) ) {
1211
+ $front .= ':' . $parsed['pass'];
1212
+ }
1213
+
1214
+ if ( isset( $parsed['user'] ) || isset( $parsed['pass'] ) ) {
1215
+ $front .= '@';
1216
+ }
1217
+
1218
+ if ( isset( $parsed['host'] ) ) {
1219
+ $front .= $parsed['host'];
1220
+ }
1221
+
1222
+ if ( isset( $parsed['port'] ) ) {
1223
+ $front .= ':' . $parsed['port'];
1224
+ }
1225
+
1226
+ $end_dirty = str_replace( $front, '', $url );
1227
+ $end_clean = str_replace( array( '[', ']' ), array( '%5B', '%5D' ), $end_dirty );
1228
+ $url = str_replace( $end_dirty, $end_clean, $url );
1229
+
1230
+ }
1231
+
1232
+ if ( '/' === $url[0] ) {
1233
+ $good_protocol_url = $url;
1234
+ } else {
1235
+ if ( ! is_array( $protocols ) )
1236
+ $protocols = self::wp_allowed_protocols();
1237
+ $good_protocol_url = self::wp_kses_bad_protocol( $url, $protocols );
1238
+ if ( strtolower( $good_protocol_url ) != strtolower( $url ) )
1239
+ return '';
1240
+ }
1241
+
1242
+ /**
1243
+ * Filters a string cleaned and escaped for output as a URL.
1244
+ *
1245
+ * @since 2.3.0
1246
+ *
1247
+ * @param string $good_protocol_url The cleaned URL to be returned.
1248
+ * @param string $original_url The URL prior to cleaning.
1249
+ * @param string $_context If 'display', replace ampersands and single quotes only.
1250
+ */
1251
+ return $good_protocol_url;
1252
+ }
1253
+
1254
+
1255
+ /**
1256
+ * Removes any invalid control characters in $string.
1257
+ *
1258
+ * Also removes any instance of the '\0' string.
1259
+ *
1260
+ * @param string $string
1261
+ * @param array $options Set 'slash_zero' => 'keep' when '\0' is allowed. Default is 'remove'.
1262
+ * @return string
1263
+ */
1264
+ public static function wp_kses_no_null( $string, $options = null ) {
1265
+ if ( ! isset( $options['slash_zero'] ) ) {
1266
+ $options = array( 'slash_zero' => 'remove' );
1267
+ }
1268
+
1269
+ $string = preg_replace( '/[\x00-\x08\x0B\x0C\x0E-\x1F]/', '', $string );
1270
+ if ( 'remove' == $options['slash_zero'] ) {
1271
+ $string = preg_replace( '/\\\\+0+/', '', $string );
1272
+ }
1273
+
1274
+ return $string;
1275
+ }
1276
+
1277
+
1278
+ /**
1279
+ * Sanitize string from bad protocols.
1280
+ *
1281
+ * This function removes all non-allowed protocols from the beginning of
1282
+ * $string. It ignores whitespace and the case of the letters, and it does
1283
+ * understand HTML entities. It does its work in a while loop, so it won't be
1284
+ * fooled by a string like "javascript:javascript:alert(57)".
1285
+ *
1286
+ * @param string $string Content to filter bad protocols from
1287
+ * @param array $allowed_protocols Allowed protocols to keep
1288
+ * @return string Filtered content
1289
+ */
1290
+ public static function wp_kses_bad_protocol($string, $allowed_protocols) {
1291
+ $string = self::wp_kses_no_null($string);
1292
+ $iterations = 0;
1293
+
1294
+ do {
1295
+ $original_string = $string;
1296
+ $string = self::wp_kses_bad_protocol_once($string, $allowed_protocols);
1297
+ } while ( $original_string != $string && ++$iterations < 6 );
1298
+
1299
+ if ( $original_string != $string )
1300
+ return '';
1301
+
1302
+ return $string;
1303
+ }
1304
+
1305
+ /**
1306
+ * Sanitizes content from bad protocols and other characters.
1307
+ *
1308
+ * This function searches for URL protocols at the beginning of $string, while
1309
+ * handling whitespace and HTML entities.
1310
+ *
1311
+ * @param string $string Content to check for bad protocols
1312
+ * @param string $allowed_protocols Allowed protocols
1313
+ * @return string Sanitized content
1314
+ */
1315
+ public static function wp_kses_bad_protocol_once($string, $allowed_protocols, $count = 1 ) {
1316
+ $string2 = preg_split( '/:|&#0*58;|&#x0*3a;/i', $string, 2 );
1317
+ if ( isset($string2[1]) && ! preg_match('%/\?%', $string2[0]) ) {
1318
+ $string = trim( $string2[1] );
1319
+ $protocol = self::wp_kses_bad_protocol_once2( $string2[0], $allowed_protocols );
1320
+ if ( 'feed:' == $protocol ) {
1321
+ if ( $count > 2 )
1322
+ return '';
1323
+ $string = wp_kses_bad_protocol_once( $string, $allowed_protocols, ++$count );
1324
+ if ( empty( $string ) )
1325
+ return $string;
1326
+ }
1327
+ $string = $protocol . $string;
1328
+ }
1329
+
1330
+ return $string;
1331
+ }
1332
+
1333
+ /**
1334
+ * Convert all entities to their character counterparts.
1335
+ *
1336
+ * This function decodes numeric HTML entities (`&#65;` and `&#x41;`).
1337
+ * It doesn't do anything with other entities like &auml;, but we don't
1338
+ * need them in the URL protocol whitelisting system anyway.
1339
+ *
1340
+ * @param string $string Content to change entities
1341
+ * @return string Content after decoded entities
1342
+ */
1343
+ public static function wp_kses_decode_entities($string)
1344
+ {
1345
+ $string = preg_replace_callback('/&#([0-9]+);/', array(__CLASS__, '_wp_kses_decode_entities_chr'), $string);
1346
+ $string = preg_replace_callback('/&#[Xx]([0-9A-Fa-f]+);/', array(__CLASS__, '_wp_kses_decode_entities_chr_hexdec'), $string);
1347
+
1348
+ return $string;
1349
+ }
1350
+
1351
+ /**
1352
+ * Regex callback for wp_kses_decode_entities()
1353
+ *
1354
+ * @param array $match preg match
1355
+ * @return string
1356
+ */
1357
+ public static function _wp_kses_decode_entities_chr( $match ) {
1358
+ return chr( $match[1] );
1359
+ }
1360
+
1361
+ /**
1362
+ * Regex callback for wp_kses_decode_entities()
1363
+ *
1364
+ * @param array $match preg match
1365
+ * @return string
1366
+ */
1367
+ public static function _wp_kses_decode_entities_chr_hexdec( $match ) {
1368
+ return chr( hexdec( $match[1] ) );
1369
+ }
1370
+
1371
+ /**
1372
+ * Callback for wp_kses_bad_protocol_once() regular expression.
1373
+ *
1374
+ * This function processes URL protocols, checks to see if they're in the
1375
+ * white-list or not, and returns different data depending on the answer.
1376
+ *
1377
+ * @access private
1378
+ *
1379
+ * @param string $string URI scheme to check against the whitelist
1380
+ * @param string $allowed_protocols Allowed protocols
1381
+ * @return string Sanitized content
1382
+ */
1383
+ public static function wp_kses_bad_protocol_once2( $string, $allowed_protocols ) {
1384
+ $string2 = self::wp_kses_decode_entities($string);
1385
+ $string2 = preg_replace('/\s/', '', $string2);
1386
+ $string2 = self::wp_kses_no_null($string2);
1387
+ $string2 = strtolower($string2);
1388
+
1389
+ $allowed = false;
1390
+ foreach ( (array) $allowed_protocols as $one_protocol ) {
1391
+ if ( strtolower($one_protocol) == $string2 ) {
1392
+ $allowed = true;
1393
+ break;
1394
+ }
1395
+ }
1396
+
1397
+ if ($allowed)
1398
+ return "$string2:";
1399
+ else
1400
+ return '';
1401
+ }
1402
+
1403
+ /**
1404
+ * Performs esc_url() for database usage.
1405
+ *
1406
+ * @param string $url The URL to be cleaned.
1407
+ * @param array $protocols An array of acceptable protocols.
1408
+ * @return string The cleaned URL.
1409
+ */
1410
+ public static function esc_url_raw( $url, $protocols = null ) {
1411
+ return self::esc_url( $url, $protocols, 'db' );
1412
+ }
1413
+
1414
+ // SANITIZE Functions
1415
+
1416
+ /**
1417
+ * Normalize EOL characters and strip duplicate whitespace.
1418
+ *
1419
+ * @param string $str The string to normalize.
1420
+ * @return string The normalized string.
1421
+ */
1422
+ public static function normalize_whitespace( $str ) {
1423
+ $str = trim( $str );
1424
+ $str = str_replace( "\r", "\n", $str );
1425
+ $str = preg_replace( array( '/\n+/', '/[ \t]+/' ), array( "\n", ' ' ), $str );
1426
+ return $str;
1427
+ }
1428
+
1429
+ /**
1430
+ * Properly strip all HTML tags including script and style
1431
+ *
1432
+ * This differs from strip_tags() because it removes the contents of
1433
+ * the `<script>` and `<style>` tags. E.g. `strip_tags( '<script>something</script>' )`
1434
+ * will return 'something'. wp_strip_all_tags will return ''
1435
+ *
1436
+ * @param string $string String containing HTML tags
1437
+ * @param bool $remove_breaks Optional. Whether to remove left over line breaks and white space chars
1438
+ * @return string The processed string.
1439
+ */
1440
+ public static function wp_strip_all_tags($string, $remove_breaks = false) {
1441
+ $string = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $string );
1442
+ $string = strip_tags($string);
1443
+
1444
+ if ( $remove_breaks )
1445
+ $string = preg_replace('/[\r\n\t ]+/', ' ', $string);
1446
+
1447
+ return trim( $string );
1448
+ }
1449
+
1450
+ /**
1451
+ * Sanitizes a string from user input or from the database.
1452
+ *
1453
+ * - Checks for invalid UTF-8,
1454
+ * - Converts single `<` characters to entities
1455
+ * - Strips all tags
1456
+ * - Removes line breaks, tabs, and extra whitespace
1457
+ * - Strips octets
1458
+ *
1459
+ * @see sanitize_textarea_field()
1460
+ * @see wp_check_invalid_utf8()
1461
+ * @see wp_strip_all_tags()
1462
+ *
1463
+ * @param string $str String to sanitize.
1464
+ * @return string Sanitized string.
1465
+ */
1466
+ public static function sanitize_text_field( $str ) {
1467
+ $filtered = self::_sanitize_text_fields( $str, false );
1468
+
1469
+ /**
1470
+ * Filters a sanitized text field string.
1471
+ *
1472
+ * @param string $filtered The sanitized string.
1473
+ * @param string $str The string prior to being sanitized.
1474
+ */
1475
+ return $filtered;
1476
+ }
1477
+
1478
+ /**
1479
+ * Sanitizes a multiline string from user input or from the database.
1480
+ *
1481
+ * The function is like sanitize_text_field(), but preserves
1482
+ * new lines (\n) and other whitespace, which are legitimate
1483
+ * input in textarea elements.
1484
+ *
1485
+ * @see sanitize_text_field()
1486
+ *
1487
+ * @since 4.7.0
1488
+ *
1489
+ * @param string $str String to sanitize.
1490
+ * @return string Sanitized string.
1491
+ */
1492
+ public static function sanitize_textarea_field( $str ) {
1493
+ $filtered = self::_sanitize_text_fields( $str, true );
1494
+
1495
+ /**
1496
+ * Filters a sanitized textarea field string.
1497
+ *
1498
+ * @since 4.7.0
1499
+ *
1500
+ * @param string $filtered The sanitized string.
1501
+ * @param string $str The string prior to being sanitized.
1502
+ */
1503
+ return $filtered;
1504
+ }
1505
+
1506
+ /**
1507
+ * Internal helper function to sanitize a string from user input or from the db
1508
+ *
1509
+ * @since 4.7.0
1510
+ * @access private
1511
+ *
1512
+ * @param string $str String to sanitize.
1513
+ * @param bool $keep_newlines optional Whether to keep newlines. Default: false.
1514
+ * @return string Sanitized string.
1515
+ */
1516
+ public static function _sanitize_text_fields( $str, $keep_newlines = false ) {
1517
+ $filtered = DupLiteSnapJsonU::wp_check_invalid_utf8( $str );
1518
+
1519
+ if ( strpos($filtered, '<') !== false ) {
1520
+ $filtered = self::wp_pre_kses_less_than( $filtered );
1521
+ // This will strip extra whitespace for us.
1522
+ $filtered = self::wp_strip_all_tags( $filtered, false );
1523
+
1524
+ // Use html entities in a special case to make sure no later
1525
+ // newline stripping stage could lead to a functional tag
1526
+ $filtered = str_replace("<\n", "&lt;\n", $filtered);
1527
+ }
1528
+
1529
+ if ( ! $keep_newlines ) {
1530
+ $filtered = preg_replace( '/[\r\n\t ]+/', ' ', $filtered );
1531
+ }
1532
+ $filtered = trim( $filtered );
1533
+
1534
+ $found = false;
1535
+ while ( preg_match('/%[a-f0-9]{2}/i', $filtered, $match) ) {
1536
+ $filtered = str_replace($match[0], '', $filtered);
1537
+ $found = true;
1538
+ }
1539
+
1540
+ if ( $found ) {
1541
+ // Strip out the whitespace that may now exist after removing the octets.
1542
+ $filtered = trim( preg_replace('/ +/', ' ', $filtered) );
1543
+ }
1544
+
1545
+ return $filtered;
1546
+ }
1547
+
1548
+ /**
1549
+ * Convert lone less than signs.
1550
+ *
1551
+ * KSES already converts lone greater than signs.
1552
+ *
1553
+ * @param string $text Text to be converted.
1554
+ * @return string Converted text.
1555
+ */
1556
+ public static function wp_pre_kses_less_than( $text ) {
1557
+ return preg_replace_callback('%<[^>]*?((?=<)|>|$)%', array('self', 'wp_pre_kses_less_than_callback'), $text);
1558
+ }
1559
+
1560
+ /**
1561
+ * Callback function used by preg_replace.
1562
+ *
1563
+ * @param array $matches Populated by matches to preg_replace.
1564
+ * @return string The text returned after esc_html if needed.
1565
+ */
1566
+ public static function wp_pre_kses_less_than_callback( $matches ) {
1567
+ if ( false === strpos($matches[0], '>') )
1568
+ return self::esc_html($matches[0]);
1569
+ return $matches[0];
1570
+ }
1571
+
1572
+
1573
+ /**
1574
+ * Remove slashes from a string or array of strings.
1575
+ *
1576
+ * This should be used to remove slashes from data passed to core API that
1577
+ * expects data to be unslashed.
1578
+ *
1579
+ * @since 3.6.0
1580
+ *
1581
+ * @param string|array $value String or array of strings to unslash.
1582
+ * @return string|array Unslashed $value
1583
+ */
1584
+ public static function wp_unslash($value) {
1585
+ return self::stripslashes_deep( $value );
1586
+ }
1587
+
1588
+ /**
1589
+ * Navigates through an array, object, or scalar, and removes slashes from the values.
1590
+ *
1591
+ * @param mixed $value The value to be stripped.
1592
+ * @return mixed Stripped value.
1593
+ */
1594
+ public static function stripslashes_deep($value) {
1595
+ return self::map_deep($value, array('self', 'stripslashes_from_strings_only'));
1596
+ }
1597
+
1598
+ /**
1599
+ * Maps a function to all non-iterable elements of an array or an object.
1600
+ *
1601
+ * This is similar to `array_walk_recursive()` but acts upon objects too.
1602
+ *
1603
+ * @since 4.4.0
1604
+ *
1605
+ * @param mixed $value The array, object, or scalar.
1606
+ * @param callable $callback The function to map onto $value.
1607
+ * @return mixed The value with the callback applied to all non-arrays and non-objects inside it.
1608
+ */
1609
+ public static function map_deep($value, $callback) {
1610
+ if (is_array($value)) {
1611
+ foreach ($value as $index => $item) {
1612
+ $value[$index] = self::map_deep($item, $callback);
1613
+ }
1614
+ } elseif (is_object($value)) {
1615
+ $object_vars = get_object_vars($value);
1616
+ foreach ($object_vars as $property_name => $property_value) {
1617
+ $value->$property_name = self::map_deep($property_value, $callback);
1618
+ }
1619
+ } else {
1620
+ $value = call_user_func($callback, $value);
1621
+ }
1622
+
1623
+ return $value;
1624
+ }
1625
+
1626
+ /**
1627
+ * Callback function for `stripslashes_deep()` which strips slashes from strings.
1628
+ *
1629
+ * @since 4.4.0
1630
+ *
1631
+ * @param mixed $value The array or string to be stripped.
1632
+ * @return mixed $value The stripped value.
1633
+ */
1634
+ public static function stripslashes_from_strings_only($value) {
1635
+ return is_string($value) ? stripslashes($value) : $value;
1636
+ }
1637
+
1638
+
1639
+ /**
1640
+ * Normalize a filesystem path.
1641
+ *
1642
+ * On windows systems, replaces backslashes with forward slashes
1643
+ * and forces upper-case drive letters.
1644
+ * Allows for two leading slashes for Windows network shares, but
1645
+ * ensures that all other duplicate slashes are reduced to a single.
1646
+ *
1647
+ * @param string $path Path to normalize.
1648
+ * @return string Normalized path.
1649
+ */
1650
+ public static function wp_normalize_path( $path ) {
1651
+ $wrapper = '';
1652
+ if ( self::wp_is_stream( $path ) ) {
1653
+ list( $wrapper, $path ) = explode( '://', $path, 2 );
1654
+ $wrapper .= '://';
1655
+ }
1656
+
1657
+ // Standardise all paths to use /
1658
+ $path = str_replace( '\\', '/', $path );
1659
+
1660
+ // Replace multiple slashes down to a singular, allowing for network shares having two slashes.
1661
+ $path = preg_replace( '|(?<=.)/+|', '/', $path );
1662
+
1663
+ // Windows paths should uppercase the drive letter
1664
+ if ( ':' === substr( $path, 1, 1 ) ) {
1665
+ $path = ucfirst( $path );
1666
+ }
1667
+
1668
+ return $wrapper . $path;
1669
+ }
1670
+
1671
+ /**
1672
+ * Test if a given path is a stream URL
1673
+ *
1674
+ * from wordpress function wp_is_stream
1675
+ *
1676
+ * @param string $path The resource path or URL.
1677
+ * @return bool True if the path is a stream URL.
1678
+ */
1679
+ public static function wp_is_stream($path)
1680
+ {
1681
+ $scheme_separator = strpos($path, '://');
1682
+
1683
+ if (false === $scheme_separator) {
1684
+ // $path isn't a stream
1685
+ return false;
1686
+ }
1687
+
1688
+ $stream = substr($path, 0, $scheme_separator);
1689
+
1690
+ return in_array($stream, stream_get_wrappers(), true);
1691
+ }
1692
+
1693
+ /**
1694
+ * Check if string is base64 encoded
1695
+ *
1696
+ * @param type $str
1697
+ * @return boolean|str return false if isn't base64 string or decoded string
1698
+ */
1699
+ public static function is_base64($str)
1700
+ {
1701
+ // Check if there are valid base64 characters
1702
+ if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $str)) {
1703
+ return false;
1704
+ }
1705
+
1706
+ // Decode the string in strict mode and check the results
1707
+ $decoded = base64_decode($str, true);
1708
+ if (false === $decoded) {
1709
+ return false;
1710
+ }
1711
+
1712
+ // Encode the string again
1713
+ if (base64_encode($decoded) != $str) {
1714
+ return false;
1715
+ }
1716
+
1717
+ return $decoded;
1718
+ }
1719
+
1720
+ /**
1721
+ *
1722
+ * @param array $matches
1723
+ * @return string
1724
+ */
1725
+ public static function encodeUtf8CharFromRegexMatch($matches)
1726
+ {
1727
+ if (empty($matches) || !is_array($matches)) {
1728
+ return '';
1729
+ } else {
1730
+ return json_decode('"'.$matches[0].'"');
1731
+ }
1732
+ }
1733
+
1734
+ /**
1735
+ * this function escape generic string to prevent security issue.
1736
+ * Used to replace string in wp transformer
1737
+ *
1738
+ * for example
1739
+ * abc'" become "abc'\""
1740
+ *
1741
+ * @param string $str input string
1742
+ * @param bool $addQuote if true add " before and after string
1743
+ * @return string
1744
+ */
1745
+ public static function getEscapedGenericString($str, $addQuote = true)
1746
+ {
1747
+ $result = DupLiteSnapJsonU::wp_json_encode(trim($str));
1748
+ $result = str_replace(array('\/', '$'), array('/', '\\$'), $result);
1749
+ $result = preg_replace_callback(
1750
+ '/\\\\u[a-fA-F0-9]{4}/m', array(__CLASS__, 'encodeUtf8CharFromRegexMatch'), $result
1751
+ );
1752
+
1753
+ if (!$addQuote) {
1754
+ $result = substr($result, 1 , strlen($result) -2);
1755
+ }
1756
+ return $result;
1757
+ }
1758
+
1759
+ /**
1760
+ *
1761
+ * @param array $input // es $_POST $_GET $_REQUEST
1762
+ * @param string $key // key of array to check
1763
+ * @param array $options // array('default' => null, default value to return if key don't exist
1764
+ * 'trim' => false // if true trim sanitize value
1765
+ * )
1766
+ * @return type
1767
+ */
1768
+ public static function isset_sanitize($input, $key, $options = array())
1769
+ {
1770
+ $opt = array_merge(array('default' => null, 'trim' => false), $options);
1771
+ if (isset($input[$key])) {
1772
+ $result = DUPX_U::sanitize_text_field($input[$key]);
1773
+ if ($opt['trim']) {
1774
+ $result = trim($result);
1775
+ }
1776
+ return $result;
1777
+ } else {
1778
+ return $opt['default'];
1779
+ }
1780
+ }
1781
+
1782
+ public static function boolToStr($input)
1783
+ {
1784
+ return $input ? 'true' : 'false';
1785
+ }
1786
+
1787
+ public static function boolToEnable($input)
1788
+ {
1789
+ return $input ? 'enable' : 'disable';
1790
+ }
1791
  }
installer/dup-installer/ctrls/ctrl.s2.dbinstall.php CHANGED
@@ -390,7 +390,7 @@ class DUPX_DBInstall
390
  while ($row = mysqli_fetch_row($result)) {
391
  $found_tables[] = $row[0];
392
  }
393
- if (count($found_tables) > 0) {
394
  mysqli_query($this->dbh, "SET FOREIGN_KEY_CHECKS = 0;");
395
  foreach ($found_tables as $table_name) {
396
  $sql = "DROP TABLE `".mysqli_real_escape_string($this->dbh, $this->post['dbname'])."`.`".mysqli_real_escape_string($this->dbh, $table_name)."`";
390
  while ($row = mysqli_fetch_row($result)) {
391
  $found_tables[] = $row[0];
392
  }
393
+ if ($found_tables != null && count($found_tables) > 0) {
394
  mysqli_query($this->dbh, "SET FOREIGN_KEY_CHECKS = 0;");
395
  foreach ($found_tables as $table_name) {
396
  $sql = "DROP TABLE `".mysqli_real_escape_string($this->dbh, $this->post['dbname'])."`.`".mysqli_real_escape_string($this->dbh, $table_name)."`";
installer/installer.tpl CHANGED
@@ -593,7 +593,7 @@ class DUPX_Bootstrap
593
  }
594
  }
595
 
596
- /**
597
  * Set the permissions of a single directory or file
598
  *
599
  * @param string $path The full path to the directory or file where perms will be set
@@ -601,17 +601,15 @@ class DUPX_Bootstrap
601
  *
602
  * @return bool Returns true if the permission was properly set
603
  */
604
- private function setPermsOnItem($path, $perms)
605
- {
606
- $result = self::chmod($path, $perms);
607
- $perms_display = decoct($perms);
608
- if ($result === false) {
609
- self::log("ERROR: Couldn't set permissions of $path to {$perms_display}<br/>");
610
- } else {
611
- self::log("Set permissions of $path to {$perms_display}<br/>");
612
- }
613
- return $result;
614
- }
615
 
616
  /**
617
  * Compare two strings and return html text which represts diff
593
  }
594
  }
595
 
596
+ /**
597
  * Set the permissions of a single directory or file
598
  *
599
  * @param string $path The full path to the directory or file where perms will be set
601
  *
602
  * @return bool Returns true if the permission was properly set
603
  */
604
+ private function setPermsOnItem($path, $perms)
605
+ {
606
+ if (($result = self::chmod($path, $perms)) === false) {
607
+ self::log("ERROR: Couldn't set permissions of $path<br/>");
608
+ } else {
609
+ self::log("Set permissions of $path<br/>");
610
+ }
611
+ return $result;
612
+ }
 
 
613
 
614
  /**
615
  * Compare two strings and return html text which represts diff
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: migration, backup, duplicate, move, migrate, restore, transfer, clone, aut
4
  Requires at least: 4.0
5
  Tested up to: 5.6
6
  Requires PHP: 5.2.17
7
- Stable tag: 1.3.40
8
  License: GPLv2
9
 
10
  WordPress migration and backups are much easier with Duplicator! Clone, backup, move and transfer an entire site from one location to another.
4
  Requires at least: 4.0
5
  Tested up to: 5.6
6
  Requires PHP: 5.2.17
7
+ Stable tag: 1.3.40.1
8
  License: GPLv2
9
 
10
  WordPress migration and backups are much easier with Duplicator! Clone, backup, move and transfer an entire site from one location to another.
views/settings/controller.php CHANGED
@@ -1,48 +1,48 @@
1
- <?php
2
- defined('ABSPATH') || defined('DUPXABSPATH') || exit;
3
-
4
- DUP_Handler::init_error_handler();
5
- DUP_Util::hasCapability('manage_options');
6
-
7
- global $wpdb;
8
-
9
- $dup_local_settings_path = dirname(__FILE__);
10
-
11
- //COMMON HEADER DISPLAY
12
- require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
13
- require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
14
- require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.ui.dialog.php');
15
- require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.ui.messages.php');
16
-
17
- $current_tab = isset($_REQUEST['tab']) ? sanitize_text_field($_REQUEST['tab']) : 'general';
18
- ?>
19
-
20
- <div class="wrap">
21
- <?php duplicator_header(__("Settings", 'duplicator')) ?>
22
-
23
- <h2 class="nav-tab-wrapper">
24
- <a href="?page=duplicator-settings&tab=general" class="nav-tab <?php echo ($current_tab == 'general') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('General', 'duplicator'); ?></a>
25
- <a href="?page=duplicator-settings&tab=package" class="nav-tab <?php echo ($current_tab == 'package') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Packages', 'duplicator'); ?></a>
26
- <a href="?page=duplicator-settings&tab=schedule" class="nav-tab <?php echo ($current_tab == 'schedule') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Schedules', 'duplicator'); ?></a>
27
- <a href="?page=duplicator-settings&tab=storage" class="nav-tab <?php echo ($current_tab == 'storage') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Storage', 'duplicator'); ?></a>
28
- <a href="?page=duplicator-settings&tab=license" class="nav-tab <?php echo ($current_tab == 'license') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('License', 'duplicator'); ?></a>
29
- <a href="?page=duplicator-settings&tab=about" class="nav-tab <?php echo ($current_tab == 'about') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('About', 'duplicator'); ?></a>
30
- </h2>
31
-
32
- <?php
33
- switch ($current_tab) {
34
- case 'general': include("{$dup_local_settings_path}/general.php");
35
- break;
36
- case 'package': include("{$dup_local_settings_path}/packages.php");
37
- break;
38
- case 'schedule': include("{$dup_local_settings_path}/schedule.php");
39
- break;
40
- case 'storage': include("{$dup_local_settings_path}/storage.php");
41
- break;
42
- case 'license': include("{$dup_local_settings_path}/license.php");
43
- break;
44
- case 'about': include("{$dup_local_settings_path}/about-info.php");
45
- break;
46
- }
47
- ?>
48
  </div>
1
+ <?php
2
+ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
3
+
4
+ DUP_Handler::init_error_handler();
5
+ DUP_Util::hasCapability('manage_options');
6
+
7
+ global $wpdb;
8
+
9
+ $dup_local_settings_path = dirname(__FILE__);
10
+
11
+ //COMMON HEADER DISPLAY
12
+ require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
13
+ require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
14
+ require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.ui.dialog.php');
15
+ require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.ui.messages.php');
16
+
17
+ $current_tab = isset($_REQUEST['tab']) ? sanitize_text_field($_REQUEST['tab']) : 'general';
18
+ ?>
19
+
20
+ <div class="wrap">
21
+ <?php duplicator_header(__("Settings", 'duplicator')) ?>
22
+
23
+ <h2 class="nav-tab-wrapper">
24
+ <a href="?page=duplicator-settings&tab=general" class="nav-tab <?php echo ($current_tab == 'general') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('General', 'duplicator'); ?></a>
25
+ <a href="?page=duplicator-settings&tab=package" class="nav-tab <?php echo ($current_tab == 'package') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Packages', 'duplicator'); ?></a>
26
+ <a href="?page=duplicator-settings&tab=schedule" class="nav-tab <?php echo ($current_tab == 'schedule') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Schedules', 'duplicator'); ?></a>
27
+ <a href="?page=duplicator-settings&tab=storage" class="nav-tab <?php echo ($current_tab == 'storage') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Storage', 'duplicator'); ?></a>
28
+ <a href="?page=duplicator-settings&tab=license" class="nav-tab <?php echo ($current_tab == 'license') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('License', 'duplicator'); ?></a>
29
+ <a href="?page=duplicator-settings&tab=about" class="nav-tab <?php echo ($current_tab == 'about') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('About', 'duplicator'); ?></a>
30
+ </h2>
31
+
32
+ <?php
33
+ switch ($current_tab) {
34
+ case 'general': include("{$dup_local_settings_path}/general.php");
35
+ break;
36
+ case 'package': include("{$dup_local_settings_path}/packages.php");
37
+ break;
38
+ case 'schedule': include("{$dup_local_settings_path}/schedule.php");
39
+ break;
40
+ case 'storage': include("{$dup_local_settings_path}/storage.php");
41
+ break;
42
+ case 'license': include("{$dup_local_settings_path}/license.php");
43
+ break;
44
+ case 'about': include("{$dup_local_settings_path}/about-info.php");
45
+ break;
46
+ }
47
+ ?>
48
  </div>
views/tools/controller.php CHANGED
@@ -1,42 +1,42 @@
1
- <?php
2
- defined('ABSPATH') || defined('DUPXABSPATH') || exit;
3
- require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.ui.dialog.php');
4
- require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
5
- require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
6
-
7
- global $wpdb;
8
- global $wp_version;
9
-
10
- $dup_local_tools_path = dirname(__FILE__);
11
-
12
- DUP_Handler::init_error_handler();
13
- DUP_Util::hasCapability('manage_options');
14
- $current_tab = isset($_REQUEST['tab']) ? esc_html($_REQUEST['tab']) : 'diagnostics';
15
- if ('d' == $current_tab) {
16
- $current_tab = 'diagnostics';
17
- }
18
- ?>
19
-
20
- <div class="wrap">
21
- <?php duplicator_header(__("Tools", 'duplicator')) ?>
22
-
23
- <h2 class="nav-tab-wrapper">
24
- <a href="?page=duplicator-tools&tab=diagnostics" class="nav-tab <?php echo ($current_tab == 'diagnostics') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Diagnostics', 'duplicator'); ?></a>
25
- <a href="?page=duplicator-tools&tab=templates" class="nav-tab <?php echo ($current_tab == 'templates') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Templates', 'duplicator'); ?></a>
26
- <a href="?page=duplicator-tools&tab=recovery" class="nav-tab <?php echo ($current_tab == 'recovery') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Recovery', 'duplicator'); ?></a>
27
- <a href="?page=duplicator-tools&tab=import" class="nav-tab <?php echo ($current_tab == 'import') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Import', 'duplicator'); ?></a>
28
- </h2>
29
-
30
- <?php
31
- switch ($current_tab) {
32
- case 'diagnostics': include('diagnostics/main.php');
33
- break;
34
- case 'templates': include("{$dup_local_tools_path}/templates.php");
35
- break;
36
- case 'recovery': include("{$dup_local_tools_path}/recovery.php");
37
- break;
38
- case 'import': include("{$dup_local_tools_path}/import.php");
39
- break;
40
- }
41
- ?>
42
- </div>
1
+ <?php
2
+ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
3
+ require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.ui.dialog.php');
4
+ require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
5
+ require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
6
+
7
+ global $wpdb;
8
+ global $wp_version;
9
+
10
+ $dup_local_tools_path = dirname(__FILE__);
11
+
12
+ DUP_Handler::init_error_handler();
13
+ DUP_Util::hasCapability('manage_options');
14
+ $current_tab = isset($_REQUEST['tab']) ? esc_html($_REQUEST['tab']) : 'diagnostics';
15
+ if ('d' == $current_tab) {
16
+ $current_tab = 'diagnostics';
17
+ }
18
+ ?>
19
+
20
+ <div class="wrap">
21
+ <?php duplicator_header(__("Tools", 'duplicator')) ?>
22
+
23
+ <h2 class="nav-tab-wrapper">
24
+ <a href="?page=duplicator-tools&tab=diagnostics" class="nav-tab <?php echo ($current_tab == 'diagnostics') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Diagnostics', 'duplicator'); ?></a>
25
+ <a href="?page=duplicator-tools&tab=templates" class="nav-tab <?php echo ($current_tab == 'templates') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Templates', 'duplicator'); ?></a>
26
+ <a href="?page=duplicator-tools&tab=recovery" class="nav-tab <?php echo ($current_tab == 'recovery') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Recovery', 'duplicator'); ?></a>
27
+ <a href="?page=duplicator-tools&tab=import" class="nav-tab <?php echo ($current_tab == 'import') ? 'nav-tab-active' : '' ?>"> <?php esc_html_e('Import', 'duplicator'); ?></a>
28
+ </h2>
29
+
30
+ <?php
31
+ switch ($current_tab) {
32
+ case 'diagnostics': include('diagnostics/main.php');
33
+ break;
34
+ case 'templates': include("{$dup_local_tools_path}/templates.php");
35
+ break;
36
+ case 'recovery': include("{$dup_local_tools_path}/recovery.php");
37
+ break;
38
+ case 'import': include("{$dup_local_tools_path}/import.php");
39
+ break;
40
+ }
41
+ ?>
42
+ </div>