LiteSpeed Cache - Version 3.4

Version Description

  • Aug 26 2020 =
  • LQIP New setting LQIP Excludes.
  • LQIP Added a Clear LQIP Queue button.
  • CCSS Added a Clear CCSS Queue button.
  • CCSS Fixed an issue which wrongly included preloaded images in CCSS. (@pixtweaks)
  • Network Primary site and subsite settings now display correctly.
  • Page Optimize Noscript tags generated by LSCWP will only be dropped when the corresponding option is enabled. (@ankit)
  • DB Optimize Fixed database optimizer conflicts w/ object cache transient setting. (#752931)
  • 3rd Fixed an issue with WooCommerce product purge when order is placed.
  • 3rd Improved WooCommerce product comment compatibility with WooCommerce Photo Reviews Premium plugin when using ESI.
  • CDN Fixed Remote jQuery compatibility with WordPress v5.5. (@pixtweaks)
  • API New API litespeed_purge_all_object and litespeed_purged_all_object action hooks.
Download this release

Release Info

Developer LiteSpeedTech
Plugin Icon 128x128 LiteSpeed Cache
Version 3.4
Comparing to
See all releases

Code changes from version 3.3.1 to 3.4

data/const.default.ini CHANGED
@@ -477,6 +477,9 @@ media-iframe_lazy_parent_cls_exc = ''
477
  ; O_MEDIA_LAZY_URI_EXC
478
  media-lazy_uri_exc = ''
479
 
 
 
 
480
 
481
 
482
 
477
  ; O_MEDIA_LAZY_URI_EXC
478
  media-lazy_uri_exc = ''
479
 
480
+ ; O_MEDIA_LQIP_EXC
481
+ media-lqip_exc = ''
482
+
483
 
484
 
485
 
lang/litespeed-cache.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the LiteSpeed Cache package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: LiteSpeed Cache 3.3.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/litespeed-cache\n"
7
- "POT-Creation-Date: 2020-08-12 20:09:53+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -28,11 +28,11 @@ msgstr ""
28
  msgid "Purged the tags!"
29
  msgstr ""
30
 
31
- #: src/activation.cls.php:432 src/activation.cls.php:437
32
  msgid "Failed to upgrade."
33
  msgstr ""
34
 
35
- #: src/activation.cls.php:441
36
  msgid "Upgraded successfully."
37
  msgstr ""
38
 
@@ -53,7 +53,7 @@ msgstr ""
53
  msgid "CDN"
54
  msgstr ""
55
 
56
- #: src/admin-display.cls.php:157 src/gui.cls.php:604
57
  #: tpl/dash/dashboard.tpl.php:52 tpl/dash/network_dash.tpl.php:27
58
  msgid "Image Optimization"
59
  msgstr ""
@@ -66,7 +66,7 @@ msgstr ""
66
  msgid "Database"
67
  msgstr ""
68
 
69
- #: src/admin-display.cls.php:163 src/lang.cls.php:217
70
  msgid "Crawler"
71
  msgstr ""
72
 
@@ -74,7 +74,7 @@ msgstr ""
74
  msgid "Toolbox"
75
  msgstr ""
76
 
77
- #: src/admin-display.cls.php:251 src/gui.cls.php:595
78
  msgid "Settings"
79
  msgstr ""
80
 
@@ -117,62 +117,66 @@ msgstr ""
117
  msgid "This setting is overwritten by the PHP constant %s"
118
  msgstr ""
119
 
120
- #: src/admin-display.cls.php:864
121
  msgid "This setting is overwritten by the primary site setting"
122
  msgstr ""
123
 
124
- #: src/admin-display.cls.php:867
 
 
 
 
125
  msgid "currently set to %s"
126
  msgstr ""
127
 
128
- #: src/admin-display.cls.php:877 tpl/cache/settings_inc.object.tpl.php:103
129
  #: tpl/crawler/settings-general.tpl.php:60
130
  #: tpl/crawler/settings-general.tpl.php:74
131
  #: tpl/crawler/settings-general.tpl.php:89 tpl/esi_widget_edit.php:70
132
  msgid "seconds"
133
  msgstr ""
134
 
135
- #: src/admin-display.cls.php:908 src/admin-display.cls.php:913
136
  msgid "Recommended value"
137
  msgstr ""
138
 
139
- #: src/admin-display.cls.php:937
140
  msgid "Invalid rewrite rule"
141
  msgstr ""
142
 
143
- #: src/admin-display.cls.php:954
144
  msgid "Path must end with %s"
145
  msgstr ""
146
 
147
- #: src/admin-display.cls.php:972
148
  msgid "Minimum value"
149
  msgstr ""
150
 
151
- #: src/admin-display.cls.php:975
152
  msgid "Maximum value"
153
  msgstr ""
154
 
155
- #: src/admin-display.cls.php:987
156
  msgid "Zero, or"
157
  msgstr ""
158
 
159
- #: src/admin-display.cls.php:994
160
  msgid "Larger than"
161
  msgstr ""
162
 
163
- #: src/admin-display.cls.php:997
164
  msgid "Smaller than"
165
  msgstr ""
166
 
167
- #: src/admin-display.cls.php:1000
168
  msgid "Value range"
169
  msgstr ""
170
 
171
- #: src/admin-display.cls.php:1025
172
  msgid "Invalid IP"
173
  msgstr ""
174
 
175
- #: src/admin-display.cls.php:1045 tpl/page_optm/settings_css.tpl.php:153
176
  #: tpl/page_optm/settings_html.tpl.php:126
177
  #: tpl/page_optm/settings_media_exc.tpl.php:25
178
  #: tpl/page_optm/settings_tuning.tpl.php:39
@@ -183,43 +187,43 @@ msgstr ""
183
  msgid "API"
184
  msgstr ""
185
 
186
- #: src/admin-display.cls.php:1046
187
  msgid "Server variable(s) %s available to override this setting."
188
  msgstr ""
189
 
190
- #: src/admin-display.cls.php:1058
191
  msgid "The URLs will be compared to the REQUEST_URI server variable."
192
  msgstr ""
193
 
194
- #: src/admin-display.cls.php:1059
195
  msgid "For example, for %s, %s can be used here."
196
  msgstr ""
197
 
198
- #: src/admin-display.cls.php:1061
199
  msgid "To match the beginning, add %s to the beginning of the item."
200
  msgstr ""
201
 
202
- #: src/admin-display.cls.php:1062
203
  msgid "To do an exact match, add %s to the end of the URL."
204
  msgstr ""
205
 
206
- #: src/admin-display.cls.php:1063 src/doc.cls.php:61
207
  msgid "One per line."
208
  msgstr ""
209
 
210
- #: src/admin-display.cls.php:1077
211
  msgid "%s groups"
212
  msgstr ""
213
 
214
- #: src/admin-display.cls.php:1080
215
  msgid "%s images"
216
  msgstr ""
217
 
218
- #: src/admin-display.cls.php:1090
219
  msgid "%s group"
220
  msgstr ""
221
 
222
- #: src/admin-display.cls.php:1093
223
  msgid "%s image"
224
  msgstr ""
225
 
@@ -320,7 +324,7 @@ msgstr ""
320
  msgid "Sync credit allowance with Cloud Server successfully."
321
  msgstr ""
322
 
323
- #: src/conf.cls.php:741
324
  msgid "Changed setting successfully."
325
  msgstr ""
326
 
@@ -352,6 +356,10 @@ msgstr ""
352
  msgid "Previously existed in blacklist"
353
  msgstr ""
354
 
 
 
 
 
355
  #: src/data.cls.php:205
356
  msgid ""
357
  "The database has been upgrading in the background since %s. This message "
@@ -417,28 +425,36 @@ msgid ""
417
  "admin before their natural expiration, if necessary."
418
  msgstr ""
419
 
420
- #: src/doc.cls.php:40 src/doc.cls.php:73 tpl/cdn/manage.tpl.php:66
421
  #: tpl/dash/dashboard.tpl.php:46 tpl/img_optm/summary.tpl.php:56
422
  #: tpl/img_optm/summary.tpl.php:96 tpl/inc/check_cache_disabled.php:42
423
  msgid "Learn More"
424
  msgstr ""
425
 
426
  #: src/doc.cls.php:72
 
 
 
 
 
 
 
 
427
  msgid "This setting will edit the .htaccess file."
428
  msgstr ""
429
 
430
- #: src/doc.cls.php:85
431
  msgid ""
432
  "For online services to work correctly, you must whitelist all online server "
433
  "IPs."
434
  msgstr ""
435
 
436
- #: src/doc.cls.php:86
437
  msgid ""
438
  "Before generating key, please verify all IPs on this list are whitelisted"
439
  msgstr ""
440
 
441
- #: src/doc.cls.php:87 tpl/general/settings.tpl.php:87
442
  msgid "Current Online Server IPs"
443
  msgstr ""
444
 
@@ -586,57 +602,57 @@ msgstr ""
586
  msgid "Failed to write to %s."
587
  msgstr ""
588
 
589
- #: src/gui.cls.php:85
590
  msgid "Public Caches"
591
  msgstr ""
592
 
593
- #: src/gui.cls.php:86
594
  msgid "Public Cache Hits"
595
  msgstr ""
596
 
597
- #: src/gui.cls.php:87
598
  msgid "Private Caches"
599
  msgstr ""
600
 
601
- #: src/gui.cls.php:88
602
  msgid "Private Cache Hits"
603
  msgstr ""
604
 
605
- #: src/gui.cls.php:404
606
  msgid "Purge this page"
607
  msgstr ""
608
 
609
- #: src/gui.cls.php:412
610
  msgid "Mark this page as "
611
  msgstr ""
612
 
613
- #: src/gui.cls.php:424
614
  msgid "Forced cacheable"
615
  msgstr ""
616
 
617
- #: src/gui.cls.php:435
618
  msgid "Non cacheable"
619
  msgstr ""
620
 
621
- #: src/gui.cls.php:446
622
  msgid "Private cache"
623
  msgstr ""
624
 
625
- #: src/gui.cls.php:457
626
  msgid "No optimization"
627
  msgstr ""
628
 
629
- #: src/gui.cls.php:465
630
  msgid "More settings"
631
  msgstr ""
632
 
633
- #: src/gui.cls.php:472 src/gui.cls.php:480 src/gui.cls.php:488
634
- #: src/gui.cls.php:497 src/gui.cls.php:507 src/gui.cls.php:517
635
- #: src/gui.cls.php:527 src/gui.cls.php:537 src/gui.cls.php:547
636
- #: src/gui.cls.php:613 src/gui.cls.php:621 src/gui.cls.php:629
637
- #: src/gui.cls.php:638 src/gui.cls.php:648 src/gui.cls.php:658
638
- #: src/gui.cls.php:668 src/gui.cls.php:678 src/gui.cls.php:688
639
- #: src/gui.cls.php:698 tpl/toolbox/purge.tpl.php:39
640
  #: tpl/toolbox/purge.tpl.php:45 tpl/toolbox/purge.tpl.php:54
641
  #: tpl/toolbox/purge.tpl.php:63 tpl/toolbox/purge.tpl.php:72
642
  #: tpl/toolbox/purge.tpl.php:81 tpl/toolbox/purge.tpl.php:90
@@ -644,81 +660,81 @@ msgstr ""
644
  msgid "Purge All"
645
  msgstr ""
646
 
647
- #: src/gui.cls.php:480 src/gui.cls.php:571 src/gui.cls.php:621
648
  msgid "LSCache"
649
  msgstr ""
650
 
651
- #: src/gui.cls.php:488 src/gui.cls.php:629 tpl/toolbox/purge.tpl.php:45
652
  msgid "CSS/JS Cache"
653
  msgstr ""
654
 
655
- #: src/gui.cls.php:497 src/gui.cls.php:648 src/lang.cls.php:79
656
  #: tpl/dash/dashboard.tpl.php:361 tpl/toolbox/purge.tpl.php:54
657
  msgid "Object Cache"
658
  msgstr ""
659
 
660
- #: src/gui.cls.php:507 src/gui.cls.php:658 tpl/toolbox/purge.tpl.php:63
661
  msgid "Opcode Cache"
662
  msgstr ""
663
 
664
- #: src/gui.cls.php:517 src/gui.cls.php:668 tpl/dash/dashboard.tpl.php:53
665
  #: tpl/dash/dashboard.tpl.php:402 tpl/toolbox/purge.tpl.php:72
666
  msgid "Critical CSS"
667
  msgstr ""
668
 
669
- #: src/gui.cls.php:527 src/gui.cls.php:678 tpl/toolbox/purge.tpl.php:81
670
  msgid "Localized Resources"
671
  msgstr ""
672
 
673
- #: src/gui.cls.php:537 src/gui.cls.php:688 tpl/toolbox/purge.tpl.php:90
674
  msgid "LQIP Cache"
675
  msgstr ""
676
 
677
- #: src/gui.cls.php:547 src/gui.cls.php:698 src/lang.cls.php:149
678
  #: tpl/toolbox/purge.tpl.php:99
679
  msgid "Gravatar Cache"
680
  msgstr ""
681
 
682
- #: src/gui.cls.php:571
683
  msgid "LiteSpeed Cache Purge All"
684
  msgstr ""
685
 
686
- #: src/gui.cls.php:587 tpl/cdn/entry.tpl.php:7 tpl/cdn/settings.tpl.php:253
687
  #: tpl/db_optm/entry.tpl.php:6
688
  msgid "Manage"
689
  msgstr ""
690
 
691
- #: src/gui.cls.php:638 tpl/cdn/manage.tpl.php:17
692
  msgid "Cloudflare"
693
  msgstr ""
694
 
695
- #: src/gui.cls.php:718 tpl/img_optm/summary.tpl.php:169
696
  msgid "Remove all previous unfinished image optimization requests."
697
  msgstr ""
698
 
699
- #: src/gui.cls.php:719 tpl/img_optm/summary.tpl.php:171
700
  msgid "Clean Up Unfinished Data"
701
  msgstr ""
702
 
703
- #: src/gui.cls.php:738
704
  msgid "Install %s"
705
  msgstr ""
706
 
707
- #: src/gui.cls.php:739
708
  msgid "Install Now"
709
  msgstr ""
710
 
711
- #: src/gui.cls.php:759
712
  msgid ""
713
  "<a href=\"%1$s\" %2$s>View version %3$s details</a> or <a href=\"%4$s\" %5$s "
714
  "target=\"_blank\">update now</a>."
715
  msgstr ""
716
 
717
- #: src/gui.cls.php:762
718
  msgid "View %1$s version %2$s details"
719
  msgstr ""
720
 
721
- #: src/gui.cls.php:767
722
  msgid "Update %s now"
723
  msgstr ""
724
 
@@ -1290,306 +1306,310 @@ msgid "Lazy Load URI Excludes"
1290
  msgstr ""
1291
 
1292
  #: src/lang.cls.php:160
1293
- msgid "Basic Image Placeholder"
1294
  msgstr ""
1295
 
1296
  #: src/lang.cls.php:161
1297
- msgid "Responsive Placeholder"
1298
  msgstr ""
1299
 
1300
  #: src/lang.cls.php:162
1301
- msgid "Responsive Placeholder Color"
1302
  msgstr ""
1303
 
1304
  #: src/lang.cls.php:163
1305
- msgid "Responsive Placeholder SVG"
1306
  msgstr ""
1307
 
1308
  #: src/lang.cls.php:164
1309
- msgid "LQIP Cloud Generator"
1310
  msgstr ""
1311
 
1312
  #: src/lang.cls.php:165
1313
- msgid "LQIP Quality"
1314
  msgstr ""
1315
 
1316
  #: src/lang.cls.php:166
 
 
 
 
1317
  msgid "LQIP Minimum Dimensions"
1318
  msgstr ""
1319
 
1320
- #: src/lang.cls.php:168
1321
  msgid "Generate LQIP In Background"
1322
  msgstr ""
1323
 
1324
- #: src/lang.cls.php:169
1325
  msgid "Lazy Load Iframes"
1326
  msgstr ""
1327
 
1328
- #: src/lang.cls.php:170
1329
  msgid "Inline Lazy Load Images Library"
1330
  msgstr ""
1331
 
1332
- #: src/lang.cls.php:171
1333
  msgid "Auto Request Cron"
1334
  msgstr ""
1335
 
1336
- #: src/lang.cls.php:172
1337
  msgid "Auto Pull Cron"
1338
  msgstr ""
1339
 
1340
- #: src/lang.cls.php:173
1341
  msgid "Optimize Original Images"
1342
  msgstr ""
1343
 
1344
- #: src/lang.cls.php:174
1345
  msgid "Remove Original Backups"
1346
  msgstr ""
1347
 
1348
- #: src/lang.cls.php:175
1349
  msgid "Create WebP Versions"
1350
  msgstr ""
1351
 
1352
- #: src/lang.cls.php:176
1353
  msgid "Optimize Losslessly"
1354
  msgstr ""
1355
 
1356
- #: src/lang.cls.php:177
1357
  msgid "Preserve EXIF/XMP data"
1358
  msgstr ""
1359
 
1360
- #: src/lang.cls.php:178
1361
  msgid "WebP Attribute To Replace"
1362
  msgstr ""
1363
 
1364
- #: src/lang.cls.php:179
1365
  msgid "WebP For Extra srcset"
1366
  msgstr ""
1367
 
1368
- #: src/lang.cls.php:180
1369
  msgid "WordPress Image Quality Control"
1370
  msgstr ""
1371
 
1372
- #: src/lang.cls.php:181 tpl/esi_widget_edit.php:36
1373
  msgid "Enable ESI"
1374
  msgstr ""
1375
 
1376
- #: src/lang.cls.php:182
1377
  msgid "Cache Admin Bar"
1378
  msgstr ""
1379
 
1380
- #: src/lang.cls.php:183
1381
  msgid "Cache Comment Form"
1382
  msgstr ""
1383
 
1384
- #: src/lang.cls.php:184
1385
  msgid "ESI Nonces"
1386
  msgstr ""
1387
 
1388
- #: src/lang.cls.php:185
1389
  msgid "Vary Group"
1390
  msgstr ""
1391
 
1392
- #: src/lang.cls.php:186
1393
  msgid "Purge All Hooks"
1394
  msgstr ""
1395
 
1396
- #: src/lang.cls.php:187
1397
  msgid "Improve HTTP/HTTPS Compatibility"
1398
  msgstr ""
1399
 
1400
- #: src/lang.cls.php:188
1401
  msgid "Instant Click"
1402
  msgstr ""
1403
 
1404
- #: src/lang.cls.php:189
1405
  msgid "Do Not Cache Cookies"
1406
  msgstr ""
1407
 
1408
- #: src/lang.cls.php:190
1409
  msgid "Do Not Cache User Agents"
1410
  msgstr ""
1411
 
1412
- #: src/lang.cls.php:191
1413
  msgid "Login Cookie"
1414
  msgstr ""
1415
 
1416
- #: src/lang.cls.php:192
1417
  msgid "Image WebP Replacement"
1418
  msgstr ""
1419
 
1420
- #: src/lang.cls.php:194
1421
  msgid "Frontend .htaccess Path"
1422
  msgstr ""
1423
 
1424
- #: src/lang.cls.php:195
1425
  msgid "Backend .htaccess Path"
1426
  msgstr ""
1427
 
1428
- #: src/lang.cls.php:196
1429
  msgid "Frontend Heartbeat Control"
1430
  msgstr ""
1431
 
1432
- #: src/lang.cls.php:197
1433
  msgid "Frontend Heartbeat TTL"
1434
  msgstr ""
1435
 
1436
- #: src/lang.cls.php:198
1437
  msgid "Backend Heartbeat Control"
1438
  msgstr ""
1439
 
1440
- #: src/lang.cls.php:199
1441
  msgid "Backend Heartbeat TTL"
1442
  msgstr ""
1443
 
1444
- #: src/lang.cls.php:200
1445
  msgid "Editor Heartbeat"
1446
  msgstr ""
1447
 
1448
- #: src/lang.cls.php:201
1449
  msgid "Editor Heartbeat TTL"
1450
  msgstr ""
1451
 
1452
- #: src/lang.cls.php:203
1453
  msgid "QUIC.cloud CDN"
1454
  msgstr ""
1455
 
1456
- #: src/lang.cls.php:204
1457
  msgid "Use CDN Mapping"
1458
  msgstr ""
1459
 
1460
- #: src/lang.cls.php:205
1461
  msgid "CDN URL"
1462
  msgstr ""
1463
 
1464
- #: src/lang.cls.php:206
1465
  msgid "Include Images"
1466
  msgstr ""
1467
 
1468
- #: src/lang.cls.php:207
1469
  msgid "Include CSS"
1470
  msgstr ""
1471
 
1472
- #: src/lang.cls.php:208
1473
  msgid "Include JS"
1474
  msgstr ""
1475
 
1476
- #: src/lang.cls.php:209 tpl/cdn/settings.tpl.php:148
1477
  msgid "Include File Types"
1478
  msgstr ""
1479
 
1480
- #: src/lang.cls.php:210
1481
  msgid "HTML Attribute To Replace"
1482
  msgstr ""
1483
 
1484
- #: src/lang.cls.php:211
1485
  msgid "Original URLs"
1486
  msgstr ""
1487
 
1488
- #: src/lang.cls.php:212
1489
  msgid "Included Directories"
1490
  msgstr ""
1491
 
1492
- #: src/lang.cls.php:213
1493
  msgid "Exclude Path"
1494
  msgstr ""
1495
 
1496
- #: src/lang.cls.php:214
1497
  msgid "Load JQuery Remotely"
1498
  msgstr ""
1499
 
1500
- #: src/lang.cls.php:215
1501
  msgid "Cloudflare API"
1502
  msgstr ""
1503
 
1504
- #: src/lang.cls.php:218
1505
  msgid "Delay"
1506
  msgstr ""
1507
 
1508
- #: src/lang.cls.php:219
1509
  msgid "Run Duration"
1510
  msgstr ""
1511
 
1512
- #: src/lang.cls.php:220
1513
  msgid "Interval Between Runs"
1514
  msgstr ""
1515
 
1516
- #: src/lang.cls.php:221
1517
  msgid "Crawl Interval"
1518
  msgstr ""
1519
 
1520
- #: src/lang.cls.php:222
1521
  msgid "Threads"
1522
  msgstr ""
1523
 
1524
- #: src/lang.cls.php:223
1525
  msgid "Timeout"
1526
  msgstr ""
1527
 
1528
- #: src/lang.cls.php:224
1529
  msgid "Server Load Limit"
1530
  msgstr ""
1531
 
1532
- #: src/lang.cls.php:225
1533
  msgid "Role Simulation"
1534
  msgstr ""
1535
 
1536
- #: src/lang.cls.php:226
1537
  msgid "Cookie Simulation"
1538
  msgstr ""
1539
 
1540
- #: src/lang.cls.php:227 tpl/crawler/settings-sitemap.tpl.php:115
1541
  msgid "Custom Sitemap"
1542
  msgstr ""
1543
 
1544
- #: src/lang.cls.php:228
1545
  msgid "Drop Domain from Sitemap"
1546
  msgstr ""
1547
 
1548
- #: src/lang.cls.php:229
1549
  msgid "Sitemap Timeout"
1550
  msgstr ""
1551
 
1552
- #: src/lang.cls.php:231 tpl/inc/disabled_all.php:5
1553
  msgid "Disable All Features"
1554
  msgstr ""
1555
 
1556
- #: src/lang.cls.php:232 tpl/toolbox/log_viewer.tpl.php:7
1557
  msgid "Debug Log"
1558
  msgstr ""
1559
 
1560
- #: src/lang.cls.php:233
1561
  msgid "Admin IPs"
1562
  msgstr ""
1563
 
1564
- #: src/lang.cls.php:234
1565
  msgid "Debug Level"
1566
  msgstr ""
1567
 
1568
- #: src/lang.cls.php:235
1569
  msgid "Log File Size Limit"
1570
  msgstr ""
1571
 
1572
- #: src/lang.cls.php:236
1573
  msgid "Log Cookies"
1574
  msgstr ""
1575
 
1576
- #: src/lang.cls.php:237
1577
  msgid "Collapse Query Strings"
1578
  msgstr ""
1579
 
1580
- #: src/lang.cls.php:238
1581
  msgid "Debug URI Includes"
1582
  msgstr ""
1583
 
1584
- #: src/lang.cls.php:239
1585
  msgid "Debug URI Excludes"
1586
  msgstr ""
1587
 
1588
- #: src/lang.cls.php:241
1589
  msgid "Revisions Max Number"
1590
  msgstr ""
1591
 
1592
- #: src/lang.cls.php:242
1593
  msgid "Revisions Max Age"
1594
  msgstr ""
1595
 
@@ -1682,11 +1702,11 @@ msgstr ""
1682
  msgid "Restore from backup"
1683
  msgstr ""
1684
 
1685
- #: src/placeholder.cls.php:82 tpl/dash/network_dash.tpl.php:30
1686
  msgid "LQIP"
1687
  msgstr ""
1688
 
1689
- #: src/placeholder.cls.php:140
1690
  msgid "LQIP image preview for size %s"
1691
  msgstr ""
1692
 
@@ -1726,11 +1746,11 @@ msgstr ""
1726
  msgid "Reset the entire opcode cache successfully."
1727
  msgstr ""
1728
 
1729
- #: src/purge.cls.php:348
1730
  msgid "Object cache is not enabled."
1731
  msgstr ""
1732
 
1733
- #: src/purge.cls.php:361
1734
  msgid "Purge all object caches successfully."
1735
  msgstr ""
1736
 
@@ -1738,23 +1758,23 @@ msgstr ""
1738
  msgid "Notified LiteSpeed Web Server to purge the front page."
1739
  msgstr ""
1740
 
1741
- #: src/purge.cls.php:538
1742
  msgid "Notified LiteSpeed Web Server to purge all pages."
1743
  msgstr ""
1744
 
1745
- #: src/purge.cls.php:558
1746
  msgid "Notified LiteSpeed Web Server to purge error pages."
1747
  msgstr ""
1748
 
1749
- #: src/purge.cls.php:586
1750
  msgid "Purge category %s"
1751
  msgstr ""
1752
 
1753
- #: src/purge.cls.php:614
1754
  msgid "Purge tag %s"
1755
  msgstr ""
1756
 
1757
- #: src/purge.cls.php:646
1758
  msgid "Purge url %s"
1759
  msgstr ""
1760
 
@@ -1766,23 +1786,23 @@ msgstr ""
1766
  msgid "LiteSpeed Crawler Cron"
1767
  msgstr ""
1768
 
1769
- #: src/utility.cls.php:254
1770
  msgid "right now"
1771
  msgstr ""
1772
 
1773
- #: src/utility.cls.php:254
1774
  msgid "just now"
1775
  msgstr ""
1776
 
1777
- #: src/utility.cls.php:257
1778
  msgid " %s ago"
1779
  msgstr ""
1780
 
1781
- #: src/utility.cls.php:877
1782
  msgid "&laquo;"
1783
  msgstr ""
1784
 
1785
- #: src/utility.cls.php:878
1786
  msgid "&raquo;"
1787
  msgstr ""
1788
 
@@ -1897,7 +1917,7 @@ msgstr ""
1897
  msgid "Dismiss this notice"
1898
  msgstr ""
1899
 
1900
- #. #-#-#-#-# litespeed-cache.pot (LiteSpeed Cache 3.3.1) #-#-#-#-#
1901
  #. Plugin Name of the plugin/theme
1902
  #: tpl/banner/new_version.php:59 tpl/banner/new_version_dev.tpl.php:12
1903
  #: tpl/cache/more_settings_tip.tpl.php:15 tpl/inc/admin_footer.php:8
@@ -4409,7 +4429,7 @@ msgstr ""
4409
  #: tpl/page_optm/settings_css.tpl.php:150
4410
  #: tpl/page_optm/settings_html.tpl.php:107
4411
  #: tpl/page_optm/settings_html.tpl.php:170 tpl/page_optm/settings_js.tpl.php:62
4412
- #: tpl/page_optm/settings_media.tpl.php:214
4413
  msgid ""
4414
  "This can improve your speed score in services like Pingdom, GTmetrix and "
4415
  "PageSpeed."
@@ -4443,54 +4463,54 @@ msgid ""
4443
  "Automatically generate critical CSS in the background via a cron-based queue."
4444
  msgstr ""
4445
 
4446
- #: tpl/page_optm/settings_css.tpl.php:204
4447
  msgid "URL list in queue waiting for cron"
4448
  msgstr ""
4449
 
4450
- #: tpl/page_optm/settings_css.tpl.php:215
4451
  #: tpl/page_optm/settings_localization.tpl.php:62
4452
- #: tpl/page_optm/settings_media.tpl.php:183
4453
  msgid "Run Queue Manually"
4454
  msgstr ""
4455
 
4456
- #: tpl/page_optm/settings_css.tpl.php:231
4457
  msgid ""
4458
  "List post types where each item of that type should have its own CCSS "
4459
  "generated."
4460
  msgstr ""
4461
 
4462
- #: tpl/page_optm/settings_css.tpl.php:232
4463
  msgid ""
4464
  "For example, if every Page on the site has different formatting, enter %s in "
4465
  "the box. Separate critical CSS files will be stored for every Page on the "
4466
  "site."
4467
  msgstr ""
4468
 
4469
- #: tpl/page_optm/settings_css.tpl.php:246
4470
  msgid ""
4471
  "Separate critical CSS files will be generated for paths containing these "
4472
  "strings."
4473
  msgstr ""
4474
 
4475
- #: tpl/page_optm/settings_css.tpl.php:260
4476
  msgid "This will inline the asynchronous CSS library to avoid render blocking."
4477
  msgstr ""
4478
 
4479
- #: tpl/page_optm/settings_css.tpl.php:271 tpl/page_optm/settings_js.tpl.php:73
4480
  msgid "Default"
4481
  msgstr ""
4482
 
4483
- #: tpl/page_optm/settings_css.tpl.php:273
4484
  msgid ""
4485
  "Set this to append %1$s to all %2$s rules before caching CSS to specify how "
4486
  "fonts should be displayed while being downloaded."
4487
  msgstr ""
4488
 
4489
- #: tpl/page_optm/settings_css.tpl.php:274
4490
  msgid "%s is recommended."
4491
  msgstr ""
4492
 
4493
- #: tpl/page_optm/settings_css.tpl.php:274
4494
  msgid "Swap"
4495
  msgstr ""
4496
 
@@ -4701,7 +4721,7 @@ msgid "Load images only when they enter the viewport."
4701
  msgstr ""
4702
 
4703
  #: tpl/page_optm/settings_media.tpl.php:26
4704
- #: tpl/page_optm/settings_media.tpl.php:200
4705
  msgid "This can improve page loading time by reducing initial HTTP requests."
4706
  msgstr ""
4707
 
@@ -4801,15 +4821,15 @@ msgid ""
4801
  "will be used."
4802
  msgstr ""
4803
 
4804
- #: tpl/page_optm/settings_media.tpl.php:177
4805
  msgid "Size list in queue waiting for cron"
4806
  msgstr ""
4807
 
4808
- #: tpl/page_optm/settings_media.tpl.php:199
4809
  msgid "Load iframes only when they enter the viewport."
4810
  msgstr ""
4811
 
4812
- #: tpl/page_optm/settings_media.tpl.php:213
4813
  msgid "Include the lazy load image JavaScript library inline."
4814
  msgstr ""
4815
 
@@ -4817,13 +4837,6 @@ msgstr ""
4817
  msgid "Listed images will not be lazy loaded."
4818
  msgstr ""
4819
 
4820
- #: tpl/page_optm/settings_media_exc.tpl.php:22
4821
- #: tpl/page_optm/settings_tuning.tpl.php:55
4822
- #: tpl/page_optm/settings_tuning.tpl.php:97
4823
- #: tpl/page_optm/settings_tuning.tpl.php:145
4824
- msgid "Both full URLs and partial strings can be used."
4825
- msgstr ""
4826
-
4827
  #: tpl/page_optm/settings_media_exc.tpl.php:26
4828
  #: tpl/page_optm/settings_tuning.tpl.php:59
4829
  #: tpl/page_optm/settings_tuning.tpl.php:101
@@ -4835,11 +4848,6 @@ msgstr ""
4835
  msgid "Images containing these class names will not be lazy loaded."
4836
  msgstr ""
4837
 
4838
- #: tpl/page_optm/settings_media_exc.tpl.php:50
4839
- #: tpl/page_optm/settings_media_exc.tpl.php:79
4840
- msgid "Both full and partial strings can be used."
4841
- msgstr ""
4842
-
4843
  #: tpl/page_optm/settings_media_exc.tpl.php:64
4844
  msgid "Images having these parent class names will not be lazy loaded."
4845
  msgstr ""
@@ -4856,6 +4864,10 @@ msgstr ""
4856
  msgid "Prevent any lazy load of listed pages."
4857
  msgstr ""
4858
 
 
 
 
 
4859
  #: tpl/page_optm/settings_tuning.tpl.php:32
4860
  msgid "Load combined CSS files before other CSS files."
4861
  msgstr ""
2
  # This file is distributed under the same license as the LiteSpeed Cache package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: LiteSpeed Cache 3.4\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/litespeed-cache\n"
7
+ "POT-Creation-Date: 2020-08-26 18:28:10+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
28
  msgid "Purged the tags!"
29
  msgstr ""
30
 
31
+ #: src/activation.cls.php:420 src/activation.cls.php:425
32
  msgid "Failed to upgrade."
33
  msgstr ""
34
 
35
+ #: src/activation.cls.php:429
36
  msgid "Upgraded successfully."
37
  msgstr ""
38
 
53
  msgid "CDN"
54
  msgstr ""
55
 
56
+ #: src/admin-display.cls.php:157 src/gui.cls.php:590
57
  #: tpl/dash/dashboard.tpl.php:52 tpl/dash/network_dash.tpl.php:27
58
  msgid "Image Optimization"
59
  msgstr ""
66
  msgid "Database"
67
  msgstr ""
68
 
69
+ #: src/admin-display.cls.php:163 src/lang.cls.php:218
70
  msgid "Crawler"
71
  msgstr ""
72
 
74
  msgid "Toolbox"
75
  msgstr ""
76
 
77
+ #: src/admin-display.cls.php:251 src/gui.cls.php:581
78
  msgid "Settings"
79
  msgstr ""
80
 
117
  msgid "This setting is overwritten by the PHP constant %s"
118
  msgstr ""
119
 
120
+ #: src/admin-display.cls.php:865
121
  msgid "This setting is overwritten by the primary site setting"
122
  msgstr ""
123
 
124
+ #: src/admin-display.cls.php:868
125
+ msgid "This setting is overwritten by the Network setting"
126
+ msgstr ""
127
+
128
+ #: src/admin-display.cls.php:872
129
  msgid "currently set to %s"
130
  msgstr ""
131
 
132
+ #: src/admin-display.cls.php:882 tpl/cache/settings_inc.object.tpl.php:103
133
  #: tpl/crawler/settings-general.tpl.php:60
134
  #: tpl/crawler/settings-general.tpl.php:74
135
  #: tpl/crawler/settings-general.tpl.php:89 tpl/esi_widget_edit.php:70
136
  msgid "seconds"
137
  msgstr ""
138
 
139
+ #: src/admin-display.cls.php:913 src/admin-display.cls.php:918
140
  msgid "Recommended value"
141
  msgstr ""
142
 
143
+ #: src/admin-display.cls.php:942
144
  msgid "Invalid rewrite rule"
145
  msgstr ""
146
 
147
+ #: src/admin-display.cls.php:959
148
  msgid "Path must end with %s"
149
  msgstr ""
150
 
151
+ #: src/admin-display.cls.php:977
152
  msgid "Minimum value"
153
  msgstr ""
154
 
155
+ #: src/admin-display.cls.php:980
156
  msgid "Maximum value"
157
  msgstr ""
158
 
159
+ #: src/admin-display.cls.php:992
160
  msgid "Zero, or"
161
  msgstr ""
162
 
163
+ #: src/admin-display.cls.php:999
164
  msgid "Larger than"
165
  msgstr ""
166
 
167
+ #: src/admin-display.cls.php:1002
168
  msgid "Smaller than"
169
  msgstr ""
170
 
171
+ #: src/admin-display.cls.php:1005
172
  msgid "Value range"
173
  msgstr ""
174
 
175
+ #: src/admin-display.cls.php:1030
176
  msgid "Invalid IP"
177
  msgstr ""
178
 
179
+ #: src/admin-display.cls.php:1050 tpl/page_optm/settings_css.tpl.php:153
180
  #: tpl/page_optm/settings_html.tpl.php:126
181
  #: tpl/page_optm/settings_media_exc.tpl.php:25
182
  #: tpl/page_optm/settings_tuning.tpl.php:39
187
  msgid "API"
188
  msgstr ""
189
 
190
+ #: src/admin-display.cls.php:1051
191
  msgid "Server variable(s) %s available to override this setting."
192
  msgstr ""
193
 
194
+ #: src/admin-display.cls.php:1063
195
  msgid "The URLs will be compared to the REQUEST_URI server variable."
196
  msgstr ""
197
 
198
+ #: src/admin-display.cls.php:1064
199
  msgid "For example, for %s, %s can be used here."
200
  msgstr ""
201
 
202
+ #: src/admin-display.cls.php:1066
203
  msgid "To match the beginning, add %s to the beginning of the item."
204
  msgstr ""
205
 
206
+ #: src/admin-display.cls.php:1067
207
  msgid "To do an exact match, add %s to the end of the URL."
208
  msgstr ""
209
 
210
+ #: src/admin-display.cls.php:1068 src/doc.cls.php:61
211
  msgid "One per line."
212
  msgstr ""
213
 
214
+ #: src/admin-display.cls.php:1082
215
  msgid "%s groups"
216
  msgstr ""
217
 
218
+ #: src/admin-display.cls.php:1085
219
  msgid "%s images"
220
  msgstr ""
221
 
222
+ #: src/admin-display.cls.php:1095
223
  msgid "%s group"
224
  msgstr ""
225
 
226
+ #: src/admin-display.cls.php:1098
227
  msgid "%s image"
228
  msgstr ""
229
 
324
  msgid "Sync credit allowance with Cloud Server successfully."
325
  msgstr ""
326
 
327
+ #: src/conf.cls.php:766
328
  msgid "Changed setting successfully."
329
  msgstr ""
330
 
356
  msgid "Previously existed in blacklist"
357
  msgstr ""
358
 
359
+ #: src/css.cls.php:448 src/placeholder.cls.php:542
360
+ msgid "Queue cleared successfully."
361
+ msgstr ""
362
+
363
  #: src/data.cls.php:205
364
  msgid ""
365
  "The database has been upgrading in the background since %s. This message "
425
  "admin before their natural expiration, if necessary."
426
  msgstr ""
427
 
428
+ #: src/doc.cls.php:40 src/doc.cls.php:88 tpl/cdn/manage.tpl.php:66
429
  #: tpl/dash/dashboard.tpl.php:46 tpl/img_optm/summary.tpl.php:56
430
  #: tpl/img_optm/summary.tpl.php:96 tpl/inc/check_cache_disabled.php:42
431
  msgid "Learn More"
432
  msgstr ""
433
 
434
  #: src/doc.cls.php:72
435
+ msgid "Both full and partial strings can be used."
436
+ msgstr ""
437
+
438
+ #: src/doc.cls.php:75
439
+ msgid "Both full URLs and partial strings can be used."
440
+ msgstr ""
441
+
442
+ #: src/doc.cls.php:87
443
  msgid "This setting will edit the .htaccess file."
444
  msgstr ""
445
 
446
+ #: src/doc.cls.php:100
447
  msgid ""
448
  "For online services to work correctly, you must whitelist all online server "
449
  "IPs."
450
  msgstr ""
451
 
452
+ #: src/doc.cls.php:101
453
  msgid ""
454
  "Before generating key, please verify all IPs on this list are whitelisted"
455
  msgstr ""
456
 
457
+ #: src/doc.cls.php:102 tpl/general/settings.tpl.php:87
458
  msgid "Current Online Server IPs"
459
  msgstr ""
460
 
602
  msgid "Failed to write to %s."
603
  msgstr ""
604
 
605
+ #: src/gui.cls.php:81
606
  msgid "Public Caches"
607
  msgstr ""
608
 
609
+ #: src/gui.cls.php:82
610
  msgid "Public Cache Hits"
611
  msgstr ""
612
 
613
+ #: src/gui.cls.php:83
614
  msgid "Private Caches"
615
  msgstr ""
616
 
617
+ #: src/gui.cls.php:84
618
  msgid "Private Cache Hits"
619
  msgstr ""
620
 
621
+ #: src/gui.cls.php:390
622
  msgid "Purge this page"
623
  msgstr ""
624
 
625
+ #: src/gui.cls.php:398
626
  msgid "Mark this page as "
627
  msgstr ""
628
 
629
+ #: src/gui.cls.php:410
630
  msgid "Forced cacheable"
631
  msgstr ""
632
 
633
+ #: src/gui.cls.php:421
634
  msgid "Non cacheable"
635
  msgstr ""
636
 
637
+ #: src/gui.cls.php:432
638
  msgid "Private cache"
639
  msgstr ""
640
 
641
+ #: src/gui.cls.php:443
642
  msgid "No optimization"
643
  msgstr ""
644
 
645
+ #: src/gui.cls.php:451
646
  msgid "More settings"
647
  msgstr ""
648
 
649
+ #: src/gui.cls.php:458 src/gui.cls.php:466 src/gui.cls.php:474
650
+ #: src/gui.cls.php:483 src/gui.cls.php:493 src/gui.cls.php:503
651
+ #: src/gui.cls.php:513 src/gui.cls.php:523 src/gui.cls.php:533
652
+ #: src/gui.cls.php:599 src/gui.cls.php:607 src/gui.cls.php:615
653
+ #: src/gui.cls.php:624 src/gui.cls.php:634 src/gui.cls.php:644
654
+ #: src/gui.cls.php:654 src/gui.cls.php:664 src/gui.cls.php:674
655
+ #: src/gui.cls.php:684 tpl/toolbox/purge.tpl.php:39
656
  #: tpl/toolbox/purge.tpl.php:45 tpl/toolbox/purge.tpl.php:54
657
  #: tpl/toolbox/purge.tpl.php:63 tpl/toolbox/purge.tpl.php:72
658
  #: tpl/toolbox/purge.tpl.php:81 tpl/toolbox/purge.tpl.php:90
660
  msgid "Purge All"
661
  msgstr ""
662
 
663
+ #: src/gui.cls.php:466 src/gui.cls.php:557 src/gui.cls.php:607
664
  msgid "LSCache"
665
  msgstr ""
666
 
667
+ #: src/gui.cls.php:474 src/gui.cls.php:615 tpl/toolbox/purge.tpl.php:45
668
  msgid "CSS/JS Cache"
669
  msgstr ""
670
 
671
+ #: src/gui.cls.php:483 src/gui.cls.php:634 src/lang.cls.php:79
672
  #: tpl/dash/dashboard.tpl.php:361 tpl/toolbox/purge.tpl.php:54
673
  msgid "Object Cache"
674
  msgstr ""
675
 
676
+ #: src/gui.cls.php:493 src/gui.cls.php:644 tpl/toolbox/purge.tpl.php:63
677
  msgid "Opcode Cache"
678
  msgstr ""
679
 
680
+ #: src/gui.cls.php:503 src/gui.cls.php:654 tpl/dash/dashboard.tpl.php:53
681
  #: tpl/dash/dashboard.tpl.php:402 tpl/toolbox/purge.tpl.php:72
682
  msgid "Critical CSS"
683
  msgstr ""
684
 
685
+ #: src/gui.cls.php:513 src/gui.cls.php:664 tpl/toolbox/purge.tpl.php:81
686
  msgid "Localized Resources"
687
  msgstr ""
688
 
689
+ #: src/gui.cls.php:523 src/gui.cls.php:674 tpl/toolbox/purge.tpl.php:90
690
  msgid "LQIP Cache"
691
  msgstr ""
692
 
693
+ #: src/gui.cls.php:533 src/gui.cls.php:684 src/lang.cls.php:149
694
  #: tpl/toolbox/purge.tpl.php:99
695
  msgid "Gravatar Cache"
696
  msgstr ""
697
 
698
+ #: src/gui.cls.php:557
699
  msgid "LiteSpeed Cache Purge All"
700
  msgstr ""
701
 
702
+ #: src/gui.cls.php:573 tpl/cdn/entry.tpl.php:7 tpl/cdn/settings.tpl.php:253
703
  #: tpl/db_optm/entry.tpl.php:6
704
  msgid "Manage"
705
  msgstr ""
706
 
707
+ #: src/gui.cls.php:624 tpl/cdn/manage.tpl.php:17
708
  msgid "Cloudflare"
709
  msgstr ""
710
 
711
+ #: src/gui.cls.php:703 tpl/img_optm/summary.tpl.php:169
712
  msgid "Remove all previous unfinished image optimization requests."
713
  msgstr ""
714
 
715
+ #: src/gui.cls.php:704 tpl/img_optm/summary.tpl.php:171
716
  msgid "Clean Up Unfinished Data"
717
  msgstr ""
718
 
719
+ #: src/gui.cls.php:722
720
  msgid "Install %s"
721
  msgstr ""
722
 
723
+ #: src/gui.cls.php:723
724
  msgid "Install Now"
725
  msgstr ""
726
 
727
+ #: src/gui.cls.php:742
728
  msgid ""
729
  "<a href=\"%1$s\" %2$s>View version %3$s details</a> or <a href=\"%4$s\" %5$s "
730
  "target=\"_blank\">update now</a>."
731
  msgstr ""
732
 
733
+ #: src/gui.cls.php:745
734
  msgid "View %1$s version %2$s details"
735
  msgstr ""
736
 
737
+ #: src/gui.cls.php:750
738
  msgid "Update %s now"
739
  msgstr ""
740
 
1306
  msgstr ""
1307
 
1308
  #: src/lang.cls.php:160
1309
+ msgid "LQIP Excludes"
1310
  msgstr ""
1311
 
1312
  #: src/lang.cls.php:161
1313
+ msgid "Basic Image Placeholder"
1314
  msgstr ""
1315
 
1316
  #: src/lang.cls.php:162
1317
+ msgid "Responsive Placeholder"
1318
  msgstr ""
1319
 
1320
  #: src/lang.cls.php:163
1321
+ msgid "Responsive Placeholder Color"
1322
  msgstr ""
1323
 
1324
  #: src/lang.cls.php:164
1325
+ msgid "Responsive Placeholder SVG"
1326
  msgstr ""
1327
 
1328
  #: src/lang.cls.php:165
1329
+ msgid "LQIP Cloud Generator"
1330
  msgstr ""
1331
 
1332
  #: src/lang.cls.php:166
1333
+ msgid "LQIP Quality"
1334
+ msgstr ""
1335
+
1336
+ #: src/lang.cls.php:167
1337
  msgid "LQIP Minimum Dimensions"
1338
  msgstr ""
1339
 
1340
+ #: src/lang.cls.php:169
1341
  msgid "Generate LQIP In Background"
1342
  msgstr ""
1343
 
1344
+ #: src/lang.cls.php:170
1345
  msgid "Lazy Load Iframes"
1346
  msgstr ""
1347
 
1348
+ #: src/lang.cls.php:171
1349
  msgid "Inline Lazy Load Images Library"
1350
  msgstr ""
1351
 
1352
+ #: src/lang.cls.php:172
1353
  msgid "Auto Request Cron"
1354
  msgstr ""
1355
 
1356
+ #: src/lang.cls.php:173
1357
  msgid "Auto Pull Cron"
1358
  msgstr ""
1359
 
1360
+ #: src/lang.cls.php:174
1361
  msgid "Optimize Original Images"
1362
  msgstr ""
1363
 
1364
+ #: src/lang.cls.php:175
1365
  msgid "Remove Original Backups"
1366
  msgstr ""
1367
 
1368
+ #: src/lang.cls.php:176
1369
  msgid "Create WebP Versions"
1370
  msgstr ""
1371
 
1372
+ #: src/lang.cls.php:177
1373
  msgid "Optimize Losslessly"
1374
  msgstr ""
1375
 
1376
+ #: src/lang.cls.php:178
1377
  msgid "Preserve EXIF/XMP data"
1378
  msgstr ""
1379
 
1380
+ #: src/lang.cls.php:179
1381
  msgid "WebP Attribute To Replace"
1382
  msgstr ""
1383
 
1384
+ #: src/lang.cls.php:180
1385
  msgid "WebP For Extra srcset"
1386
  msgstr ""
1387
 
1388
+ #: src/lang.cls.php:181
1389
  msgid "WordPress Image Quality Control"
1390
  msgstr ""
1391
 
1392
+ #: src/lang.cls.php:182 tpl/esi_widget_edit.php:36
1393
  msgid "Enable ESI"
1394
  msgstr ""
1395
 
1396
+ #: src/lang.cls.php:183
1397
  msgid "Cache Admin Bar"
1398
  msgstr ""
1399
 
1400
+ #: src/lang.cls.php:184
1401
  msgid "Cache Comment Form"
1402
  msgstr ""
1403
 
1404
+ #: src/lang.cls.php:185
1405
  msgid "ESI Nonces"
1406
  msgstr ""
1407
 
1408
+ #: src/lang.cls.php:186
1409
  msgid "Vary Group"
1410
  msgstr ""
1411
 
1412
+ #: src/lang.cls.php:187
1413
  msgid "Purge All Hooks"
1414
  msgstr ""
1415
 
1416
+ #: src/lang.cls.php:188
1417
  msgid "Improve HTTP/HTTPS Compatibility"
1418
  msgstr ""
1419
 
1420
+ #: src/lang.cls.php:189
1421
  msgid "Instant Click"
1422
  msgstr ""
1423
 
1424
+ #: src/lang.cls.php:190
1425
  msgid "Do Not Cache Cookies"
1426
  msgstr ""
1427
 
1428
+ #: src/lang.cls.php:191
1429
  msgid "Do Not Cache User Agents"
1430
  msgstr ""
1431
 
1432
+ #: src/lang.cls.php:192
1433
  msgid "Login Cookie"
1434
  msgstr ""
1435
 
1436
+ #: src/lang.cls.php:193
1437
  msgid "Image WebP Replacement"
1438
  msgstr ""
1439
 
1440
+ #: src/lang.cls.php:195
1441
  msgid "Frontend .htaccess Path"
1442
  msgstr ""
1443
 
1444
+ #: src/lang.cls.php:196
1445
  msgid "Backend .htaccess Path"
1446
  msgstr ""
1447
 
1448
+ #: src/lang.cls.php:197
1449
  msgid "Frontend Heartbeat Control"
1450
  msgstr ""
1451
 
1452
+ #: src/lang.cls.php:198
1453
  msgid "Frontend Heartbeat TTL"
1454
  msgstr ""
1455
 
1456
+ #: src/lang.cls.php:199
1457
  msgid "Backend Heartbeat Control"
1458
  msgstr ""
1459
 
1460
+ #: src/lang.cls.php:200
1461
  msgid "Backend Heartbeat TTL"
1462
  msgstr ""
1463
 
1464
+ #: src/lang.cls.php:201
1465
  msgid "Editor Heartbeat"
1466
  msgstr ""
1467
 
1468
+ #: src/lang.cls.php:202
1469
  msgid "Editor Heartbeat TTL"
1470
  msgstr ""
1471
 
1472
+ #: src/lang.cls.php:204
1473
  msgid "QUIC.cloud CDN"
1474
  msgstr ""
1475
 
1476
+ #: src/lang.cls.php:205
1477
  msgid "Use CDN Mapping"
1478
  msgstr ""
1479
 
1480
+ #: src/lang.cls.php:206
1481
  msgid "CDN URL"
1482
  msgstr ""
1483
 
1484
+ #: src/lang.cls.php:207
1485
  msgid "Include Images"
1486
  msgstr ""
1487
 
1488
+ #: src/lang.cls.php:208
1489
  msgid "Include CSS"
1490
  msgstr ""
1491
 
1492
+ #: src/lang.cls.php:209
1493
  msgid "Include JS"
1494
  msgstr ""
1495
 
1496
+ #: src/lang.cls.php:210 tpl/cdn/settings.tpl.php:148
1497
  msgid "Include File Types"
1498
  msgstr ""
1499
 
1500
+ #: src/lang.cls.php:211
1501
  msgid "HTML Attribute To Replace"
1502
  msgstr ""
1503
 
1504
+ #: src/lang.cls.php:212
1505
  msgid "Original URLs"
1506
  msgstr ""
1507
 
1508
+ #: src/lang.cls.php:213
1509
  msgid "Included Directories"
1510
  msgstr ""
1511
 
1512
+ #: src/lang.cls.php:214
1513
  msgid "Exclude Path"
1514
  msgstr ""
1515
 
1516
+ #: src/lang.cls.php:215
1517
  msgid "Load JQuery Remotely"
1518
  msgstr ""
1519
 
1520
+ #: src/lang.cls.php:216
1521
  msgid "Cloudflare API"
1522
  msgstr ""
1523
 
1524
+ #: src/lang.cls.php:219
1525
  msgid "Delay"
1526
  msgstr ""
1527
 
1528
+ #: src/lang.cls.php:220
1529
  msgid "Run Duration"
1530
  msgstr ""
1531
 
1532
+ #: src/lang.cls.php:221
1533
  msgid "Interval Between Runs"
1534
  msgstr ""
1535
 
1536
+ #: src/lang.cls.php:222
1537
  msgid "Crawl Interval"
1538
  msgstr ""
1539
 
1540
+ #: src/lang.cls.php:223
1541
  msgid "Threads"
1542
  msgstr ""
1543
 
1544
+ #: src/lang.cls.php:224
1545
  msgid "Timeout"
1546
  msgstr ""
1547
 
1548
+ #: src/lang.cls.php:225
1549
  msgid "Server Load Limit"
1550
  msgstr ""
1551
 
1552
+ #: src/lang.cls.php:226
1553
  msgid "Role Simulation"
1554
  msgstr ""
1555
 
1556
+ #: src/lang.cls.php:227
1557
  msgid "Cookie Simulation"
1558
  msgstr ""
1559
 
1560
+ #: src/lang.cls.php:228 tpl/crawler/settings-sitemap.tpl.php:115
1561
  msgid "Custom Sitemap"
1562
  msgstr ""
1563
 
1564
+ #: src/lang.cls.php:229
1565
  msgid "Drop Domain from Sitemap"
1566
  msgstr ""
1567
 
1568
+ #: src/lang.cls.php:230
1569
  msgid "Sitemap Timeout"
1570
  msgstr ""
1571
 
1572
+ #: src/lang.cls.php:232 tpl/inc/disabled_all.php:5
1573
  msgid "Disable All Features"
1574
  msgstr ""
1575
 
1576
+ #: src/lang.cls.php:233 tpl/toolbox/log_viewer.tpl.php:7
1577
  msgid "Debug Log"
1578
  msgstr ""
1579
 
1580
+ #: src/lang.cls.php:234
1581
  msgid "Admin IPs"
1582
  msgstr ""
1583
 
1584
+ #: src/lang.cls.php:235
1585
  msgid "Debug Level"
1586
  msgstr ""
1587
 
1588
+ #: src/lang.cls.php:236
1589
  msgid "Log File Size Limit"
1590
  msgstr ""
1591
 
1592
+ #: src/lang.cls.php:237
1593
  msgid "Log Cookies"
1594
  msgstr ""
1595
 
1596
+ #: src/lang.cls.php:238
1597
  msgid "Collapse Query Strings"
1598
  msgstr ""
1599
 
1600
+ #: src/lang.cls.php:239
1601
  msgid "Debug URI Includes"
1602
  msgstr ""
1603
 
1604
+ #: src/lang.cls.php:240
1605
  msgid "Debug URI Excludes"
1606
  msgstr ""
1607
 
1608
+ #: src/lang.cls.php:242
1609
  msgid "Revisions Max Number"
1610
  msgstr ""
1611
 
1612
+ #: src/lang.cls.php:243
1613
  msgid "Revisions Max Age"
1614
  msgstr ""
1615
 
1702
  msgid "Restore from backup"
1703
  msgstr ""
1704
 
1705
+ #: src/placeholder.cls.php:83 tpl/dash/network_dash.tpl.php:30
1706
  msgid "LQIP"
1707
  msgstr ""
1708
 
1709
+ #: src/placeholder.cls.php:141
1710
  msgid "LQIP image preview for size %s"
1711
  msgstr ""
1712
 
1746
  msgid "Reset the entire opcode cache successfully."
1747
  msgstr ""
1748
 
1749
+ #: src/purge.cls.php:358
1750
  msgid "Object cache is not enabled."
1751
  msgstr ""
1752
 
1753
+ #: src/purge.cls.php:371
1754
  msgid "Purge all object caches successfully."
1755
  msgstr ""
1756
 
1758
  msgid "Notified LiteSpeed Web Server to purge the front page."
1759
  msgstr ""
1760
 
1761
+ #: src/purge.cls.php:537
1762
  msgid "Notified LiteSpeed Web Server to purge all pages."
1763
  msgstr ""
1764
 
1765
+ #: src/purge.cls.php:556
1766
  msgid "Notified LiteSpeed Web Server to purge error pages."
1767
  msgstr ""
1768
 
1769
+ #: src/purge.cls.php:583
1770
  msgid "Purge category %s"
1771
  msgstr ""
1772
 
1773
+ #: src/purge.cls.php:610
1774
  msgid "Purge tag %s"
1775
  msgstr ""
1776
 
1777
+ #: src/purge.cls.php:641
1778
  msgid "Purge url %s"
1779
  msgstr ""
1780
 
1786
  msgid "LiteSpeed Crawler Cron"
1787
  msgstr ""
1788
 
1789
+ #: src/utility.cls.php:250
1790
  msgid "right now"
1791
  msgstr ""
1792
 
1793
+ #: src/utility.cls.php:250
1794
  msgid "just now"
1795
  msgstr ""
1796
 
1797
+ #: src/utility.cls.php:253
1798
  msgid " %s ago"
1799
  msgstr ""
1800
 
1801
+ #: src/utility.cls.php:857
1802
  msgid "&laquo;"
1803
  msgstr ""
1804
 
1805
+ #: src/utility.cls.php:858
1806
  msgid "&raquo;"
1807
  msgstr ""
1808
 
1917
  msgid "Dismiss this notice"
1918
  msgstr ""
1919
 
1920
+ #. #-#-#-#-# litespeed-cache.pot (LiteSpeed Cache 3.4) #-#-#-#-#
1921
  #. Plugin Name of the plugin/theme
1922
  #: tpl/banner/new_version.php:59 tpl/banner/new_version_dev.tpl.php:12
1923
  #: tpl/cache/more_settings_tip.tpl.php:15 tpl/inc/admin_footer.php:8
4429
  #: tpl/page_optm/settings_css.tpl.php:150
4430
  #: tpl/page_optm/settings_html.tpl.php:107
4431
  #: tpl/page_optm/settings_html.tpl.php:170 tpl/page_optm/settings_js.tpl.php:62
4432
+ #: tpl/page_optm/settings_media.tpl.php:217
4433
  msgid ""
4434
  "This can improve your speed score in services like Pingdom, GTmetrix and "
4435
  "PageSpeed."
4463
  "Automatically generate critical CSS in the background via a cron-based queue."
4464
  msgstr ""
4465
 
4466
+ #: tpl/page_optm/settings_css.tpl.php:205
4467
  msgid "URL list in queue waiting for cron"
4468
  msgstr ""
4469
 
4470
+ #: tpl/page_optm/settings_css.tpl.php:218
4471
  #: tpl/page_optm/settings_localization.tpl.php:62
4472
+ #: tpl/page_optm/settings_media.tpl.php:186
4473
  msgid "Run Queue Manually"
4474
  msgstr ""
4475
 
4476
+ #: tpl/page_optm/settings_css.tpl.php:234
4477
  msgid ""
4478
  "List post types where each item of that type should have its own CCSS "
4479
  "generated."
4480
  msgstr ""
4481
 
4482
+ #: tpl/page_optm/settings_css.tpl.php:235
4483
  msgid ""
4484
  "For example, if every Page on the site has different formatting, enter %s in "
4485
  "the box. Separate critical CSS files will be stored for every Page on the "
4486
  "site."
4487
  msgstr ""
4488
 
4489
+ #: tpl/page_optm/settings_css.tpl.php:249
4490
  msgid ""
4491
  "Separate critical CSS files will be generated for paths containing these "
4492
  "strings."
4493
  msgstr ""
4494
 
4495
+ #: tpl/page_optm/settings_css.tpl.php:263
4496
  msgid "This will inline the asynchronous CSS library to avoid render blocking."
4497
  msgstr ""
4498
 
4499
+ #: tpl/page_optm/settings_css.tpl.php:274 tpl/page_optm/settings_js.tpl.php:73
4500
  msgid "Default"
4501
  msgstr ""
4502
 
4503
+ #: tpl/page_optm/settings_css.tpl.php:276
4504
  msgid ""
4505
  "Set this to append %1$s to all %2$s rules before caching CSS to specify how "
4506
  "fonts should be displayed while being downloaded."
4507
  msgstr ""
4508
 
4509
+ #: tpl/page_optm/settings_css.tpl.php:277
4510
  msgid "%s is recommended."
4511
  msgstr ""
4512
 
4513
+ #: tpl/page_optm/settings_css.tpl.php:277
4514
  msgid "Swap"
4515
  msgstr ""
4516
 
4721
  msgstr ""
4722
 
4723
  #: tpl/page_optm/settings_media.tpl.php:26
4724
+ #: tpl/page_optm/settings_media.tpl.php:203
4725
  msgid "This can improve page loading time by reducing initial HTTP requests."
4726
  msgstr ""
4727
 
4821
  "will be used."
4822
  msgstr ""
4823
 
4824
+ #: tpl/page_optm/settings_media.tpl.php:178
4825
  msgid "Size list in queue waiting for cron"
4826
  msgstr ""
4827
 
4828
+ #: tpl/page_optm/settings_media.tpl.php:202
4829
  msgid "Load iframes only when they enter the viewport."
4830
  msgstr ""
4831
 
4832
+ #: tpl/page_optm/settings_media.tpl.php:216
4833
  msgid "Include the lazy load image JavaScript library inline."
4834
  msgstr ""
4835
 
4837
  msgid "Listed images will not be lazy loaded."
4838
  msgstr ""
4839
 
 
 
 
 
 
 
 
4840
  #: tpl/page_optm/settings_media_exc.tpl.php:26
4841
  #: tpl/page_optm/settings_tuning.tpl.php:59
4842
  #: tpl/page_optm/settings_tuning.tpl.php:101
4848
  msgid "Images containing these class names will not be lazy loaded."
4849
  msgstr ""
4850
 
 
 
 
 
 
4851
  #: tpl/page_optm/settings_media_exc.tpl.php:64
4852
  msgid "Images having these parent class names will not be lazy loaded."
4853
  msgstr ""
4864
  msgid "Prevent any lazy load of listed pages."
4865
  msgstr ""
4866
 
4867
+ #: tpl/page_optm/settings_media_exc.tpl.php:121
4868
+ msgid "These images will not generate LQIP."
4869
+ msgstr ""
4870
+
4871
  #: tpl/page_optm/settings_tuning.tpl.php:32
4872
  msgid "Load combined CSS files before other CSS files."
4873
  msgstr ""
litespeed-cache.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: LiteSpeed Cache
4
  * Plugin URI: https://www.litespeedtech.com/products/cache-plugins/wordpress-acceleration
5
  * Description: High-performance page caching and site optimization from LiteSpeed
6
- * Version: 3.3.1
7
  * Author: LiteSpeed Technologies
8
  * Author URI: https://www.litespeedtech.com
9
  * License: GPLv3
@@ -33,7 +33,7 @@ if ( class_exists( 'LiteSpeed\Core' ) || defined( 'LSCWP_DIR' ) ) {
33
  return;
34
  }
35
 
36
- ! defined( 'LSCWP_V' ) && define( 'LSCWP_V', '3.3.1' );
37
 
38
  ! defined( 'LSCWP_CONTENT_DIR' ) && define( 'LSCWP_CONTENT_DIR', WP_CONTENT_DIR ) ;
39
  ! defined( 'LSCWP_DIR' ) && define( 'LSCWP_DIR', __DIR__ . '/' ) ;// Full absolute path '/var/www/html/***/wp-content/plugins/litespeed-cache/' or MU
3
  * Plugin Name: LiteSpeed Cache
4
  * Plugin URI: https://www.litespeedtech.com/products/cache-plugins/wordpress-acceleration
5
  * Description: High-performance page caching and site optimization from LiteSpeed
6
+ * Version: 3.4
7
  * Author: LiteSpeed Technologies
8
  * Author URI: https://www.litespeedtech.com
9
  * License: GPLv3
33
  return;
34
  }
35
 
36
+ ! defined( 'LSCWP_V' ) && define( 'LSCWP_V', '3.4' );
37
 
38
  ! defined( 'LSCWP_CONTENT_DIR' ) && define( 'LSCWP_CONTENT_DIR', WP_CONTENT_DIR ) ;
39
  ! defined( 'LSCWP_DIR' ) && define( 'LSCWP_DIR', __DIR__ . '/' ) ;// Full absolute path '/var/www/html/***/wp-content/plugins/litespeed-cache/' or MU
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: LiteSpeedTech
3
  Tags: caching, optimize, performance, pagespeed, seo, speed, image optimize, compress, object cache, redis, memcached, database cleaner
4
  Requires at least: 4.0
5
- Tested up to: 5.4.2
6
- Stable tag: 3.3.1
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl.html
9
 
@@ -245,6 +245,19 @@ The vast majority of plugins and themes are compatible with LiteSpeed Cache. The
245
 
246
  == Changelog ==
247
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  = 3.3.1 - Aug 12 2020 =
249
  * 🌱**Page Optimize** New option to Remove Noscript Tags. (@phuc88bmt)
250
  * 🐞**LQIP** Fixed a critical bug that bypassed all requests in v3.3.
2
  Contributors: LiteSpeedTech
3
  Tags: caching, optimize, performance, pagespeed, seo, speed, image optimize, compress, object cache, redis, memcached, database cleaner
4
  Requires at least: 4.0
5
+ Tested up to: 5.5
6
+ Stable tag: 3.4
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl.html
9
 
245
 
246
  == Changelog ==
247
 
248
+ = 3.4 - Aug 26 2020 =
249
+ * 🌱**LQIP** New setting **LQIP Excludes**.
250
+ * 🌱**LQIP** Added a Clear LQIP Queue button.
251
+ * 🌱**CCSS** Added a Clear CCSS Queue button.
252
+ * **CCSS** Fixed an issue which wrongly included preloaded images in CCSS. (@pixtweaks)
253
+ * **Network** Primary site and subsite settings now display correctly.
254
+ * **Page Optimize** Noscript tags generated by LSCWP will only be dropped when the corresponding option is enabled. (@ankit)
255
+ * **DB Optimize** Fixed database optimizer conflicts w/ object cache transient setting. (#752931)
256
+ * **3rd** Fixed an issue with WooCommerce product purge when order is placed.
257
+ * **3rd** Improved WooCommerce product comment compatibility with **WooCommerce Photo Reviews Premium** plugin when using ESI.
258
+ * **CDN** Fixed Remote jQuery compatibility with WordPress v5.5. (@pixtweaks)
259
+ * **API** New API `litespeed_purge_all_object` and `litespeed_purged_all_object` action hooks.
260
+
261
  = 3.3.1 - Aug 12 2020 =
262
  * 🌱**Page Optimize** New option to Remove Noscript Tags. (@phuc88bmt)
263
  * 🐞**LQIP** Fixed a critical bug that bypassed all requests in v3.3.
src/activation.cls.php CHANGED
@@ -8,20 +8,19 @@
8
  * @subpackage LiteSpeed/inc
9
  * @author LiteSpeed Technologies <info@litespeedtech.com>
10
  */
11
- namespace LiteSpeed ;
12
 
13
- defined( 'WPINC' ) || exit ;
14
 
15
- class Activation extends Instance
16
- {
17
- protected static $_instance ;
18
 
19
- const TYPE_UPGRADE = 'upgrade' ;
20
- const TYPE_INSTALL_3RD = 'install_3rd' ;
21
- const TYPE_INSTALL_ZIP = 'install_zip' ;
22
- const TYPE_DISMISS_RECOMMENDED = 'dismiss_recommended' ;
23
 
24
- const NETWORK_TRANSIENT_COUNT = 'lscwp_network_count' ;
25
 
26
  /**
27
  * The activation hook callback.
@@ -29,23 +28,22 @@ class Activation extends Instance
29
  * @since 1.0.0
30
  * @access public
31
  */
32
- public static function register_activation()
33
- {
34
- $count = 0 ;
35
- ! defined( 'LSCWP_LOG_TAG' ) && define( 'LSCWP_LOG_TAG', 'Activate_' . get_current_blog_id() ) ;
36
 
37
  if ( is_multisite() ) {
38
- $count = self::get_network_count() ;
39
  if ( $count !== false ) {
40
- $count = intval( $count ) + 1 ;
41
- set_site_transient( self::NETWORK_TRANSIENT_COUNT, $count, DAY_IN_SECONDS ) ;
42
  }
43
  }
44
 
45
- do_action( 'litespeed_load_thirdparty' ) ;
46
 
47
  // Check new version @since 2.9.3
48
- Cloud::version_check( 'activate' . ( defined( 'LSCWP_REF' ) ? '_' . LSCWP_REF : '' ) ) ;
49
 
50
  /* Network file handler */
51
 
@@ -55,24 +53,24 @@ class Activation extends Instance
55
  if ( $count === 1 ) {
56
  // Only itself is activated, set .htaccess with only CacheLookUp
57
  try {
58
- Htaccess::get_instance()->insert_ls_wrapper() ;
59
  } catch ( \Exception $ex ) {
60
- Admin_Display::error( $ex->getMessage() ) ;
61
  }
62
  }
63
- return ;
64
  }
65
 
66
- Conf::get_instance()->update_confs() ;
67
 
68
- return ;
69
  }
70
 
71
  /* Single site file handler */
72
- Conf::get_instance()->update_confs() ;
73
 
74
  if ( defined( 'LSCWP_REF' ) && LSCWP_REF == 'whm' ) {
75
- GUI::update_option( GUI::WHM_MSG, GUI::WHM_MSG_VAL ) ;
76
  }
77
  }
78
 
@@ -80,30 +78,29 @@ class Activation extends Instance
80
  * Uninstall plugin
81
  * @since 1.1.0
82
  */
83
- public static function uninstall_litespeed_cache()
84
- {
85
  Task::destroy();
86
 
87
  // Delete options
88
  foreach ( Conf::get_instance()->load_default_vals() as $k => $v ) {
89
- Base::delete_option( $k ) ;
90
  }
91
 
92
  // Delete site options
93
  if ( is_multisite() ) {
94
  foreach ( Conf::get_instance()->load_default_site_vals() as $k => $v ) {
95
- Base::delete_site_option( $k ) ;
96
  }
97
  }
98
 
99
  // Delete avatar table
100
- Data::get_instance()->tables_del() ;
101
 
102
  if ( file_exists( LITESPEED_STATIC_DIR ) ) {
103
- File::rrmdir( LITESPEED_STATIC_DIR ) ;
104
  }
105
 
106
- Cloud::version_check( 'uninstall' ) ;
107
 
108
  // Files has been deleted when deactivated
109
  }
@@ -117,22 +114,21 @@ class Activation extends Instance
117
  * @access public
118
  * @return array The array of blog ids.
119
  */
120
- public static function get_network_ids( $args = array() )
121
- {
122
- global $wp_version ;
123
  if ( version_compare( $wp_version, '4.6', '<' ) ) {
124
- $blogs = wp_get_sites( $args ) ;
125
  if ( ! empty( $blogs ) ) {
126
  foreach ( $blogs as $key => $blog ) {
127
- $blogs[ $key ] = $blog[ 'blog_id' ] ;
128
  }
129
  }
130
  }
131
  else {
132
- $args[ 'fields' ] = 'ids' ;
133
- $blogs = get_sites( $args ) ;
134
  }
135
- return $blogs ;
136
  }
137
 
138
  /**
@@ -141,26 +137,25 @@ class Activation extends Instance
141
  * @since 1.0.12
142
  * @access private
143
  */
144
- private static function get_network_count()
145
- {
146
- $count = get_site_transient( self::NETWORK_TRANSIENT_COUNT ) ;
147
  if ( $count !== false ) {
148
- return intval( $count ) ;
149
  }
150
  // need to update
151
- $default = array() ;
152
- $count = 0 ;
153
 
154
- $sites = self::get_network_ids( array( 'deleted' => 0 ) ) ;
155
  if ( empty( $sites ) ) {
156
- return false ;
157
  }
158
 
159
  foreach ( $sites as $site ) {
160
- $bid = is_object( $site ) && property_exists( $site, 'blog_id' ) ? $site->blog_id : $site ;
161
- $plugins = get_blog_option( $bid , 'active_plugins', $default ) ;
162
  if ( in_array( LSCWP_BASENAME, $plugins, true ) ) {
163
- $count++ ;
164
  }
165
  }
166
 
@@ -170,13 +165,13 @@ class Activation extends Instance
170
  * @since 2.0
171
  */
172
  if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
173
- require_once( ABSPATH . '/wp-admin/includes/plugin.php' ) ;
174
  }
175
 
176
  if ( is_plugin_active_for_network( LSCWP_BASENAME ) ) {
177
- $count++ ;
178
  }
179
- return $count ;
180
  }
181
 
182
  /**
@@ -185,21 +180,20 @@ class Activation extends Instance
185
  * @since 1.0.12
186
  * @access private
187
  */
188
- private static function is_deactivate_last()
189
- {
190
- $count = self::get_network_count() ;
191
  if ( $count === false ) {
192
- return false ;
193
  }
194
  if ( $count !== 1 ) {
195
  // Not deactivating the last one.
196
- $count-- ;
197
- set_site_transient( self::NETWORK_TRANSIENT_COUNT, $count, DAY_IN_SECONDS ) ;
198
- return false ;
199
  }
200
 
201
- delete_site_transient( self::NETWORK_TRANSIENT_COUNT ) ;
202
- return true ;
203
  }
204
 
205
  /**
@@ -210,13 +204,12 @@ class Activation extends Instance
210
  * @since 1.0.0
211
  * @access public
212
  */
213
- public static function register_deactivation()
214
- {
215
  Task::destroy();
216
 
217
- ! defined( 'LSCWP_LOG_TAG' ) && define( 'LSCWP_LOG_TAG', 'Deactivate_' . get_current_blog_id() ) ;
218
 
219
- Purge::purge_all() ;
220
 
221
  if ( is_multisite() ) {
222
 
@@ -224,41 +217,41 @@ class Activation extends Instance
224
  if ( is_network_admin() ) {
225
  // Still other activated subsite left, set .htaccess with only CacheLookUp
226
  try {
227
- Htaccess::get_instance()->insert_ls_wrapper() ;
228
  } catch ( \Exception $ex ) {
229
- Admin_Display::error( $ex->getMessage() ) ;
230
  }
231
  }
232
- return ;
233
  }
234
  }
235
 
236
  /* 1) wp-config.php; */
237
 
238
  try {
239
- self::get_instance()->_manage_wp_cache_const( false ) ;
240
  } catch ( \Exception $ex ) {
241
- error_log('In wp-config.php: WP_CACHE could not be set to false during deactivation!') ;
242
 
243
- Admin_Display::error( $ex->getMessage() ) ;
244
  }
245
 
246
  /* 2) adv-cache.php; Dropped in v3.0.4 */
247
 
248
  /* 3) object-cache.php; */
249
 
250
- Object_Cache::get_instance()->del_file() ;
251
 
252
  /* 4) .htaccess; */
253
 
254
  try {
255
- Htaccess::get_instance()->clear_rules() ;
256
  } catch ( \Exception $ex ) {
257
- Admin_Display::error( $ex->getMessage() ) ;
258
  }
259
 
260
  // delete in case it's not deleted prior to deactivation.
261
- GUI::dismiss_whm() ;
262
  }
263
 
264
  /**
@@ -275,8 +268,7 @@ class Activation extends Instance
275
  * @since 3.0
276
  * @access public
277
  */
278
- public function update_files()
279
- {
280
  // Update cache setting `_CACHE`
281
  Conf::get_instance()->define_cache();
282
 
@@ -322,49 +314,48 @@ class Activation extends Instance
322
  * @since 3.0 Refactored
323
  * @access private
324
  */
325
- private function _manage_wp_cache_const( $enable )
326
- {
327
  if ( $enable ) {
328
  if ( defined( 'WP_CACHE' ) && WP_CACHE ) {
329
- return false ;
330
  }
331
  }
332
  elseif ( ! defined( 'WP_CACHE' ) || ( defined( 'WP_CACHE' ) && ! WP_CACHE ) ) {
333
- return false ;
334
  }
335
 
336
  /**
337
  * Follow WP's logic to locate wp-config file
338
  * @see wp-load.php
339
  */
340
- $conf_file = ABSPATH . 'wp-config.php' ;
341
  if ( ! file_exists( $conf_file ) ) {
342
- $conf_file = dirname( ABSPATH ) . '/wp-config.php' ;
343
  }
344
 
345
- $content = File::read( $conf_file ) ;
346
  if ( ! $content ) {
347
- throw new \Exception( 'wp-config file content is empty: ' . $conf_file ) ;
348
 
349
  }
350
 
351
  // Remove the line `define('WP_CACHE', true/false);` first
352
  if ( defined( 'WP_CACHE' ) ) {
353
- $content = preg_replace( '|define\(\s*(["\'])WP_CACHE\1\s*,\s*\w+\)\s*;|sU', '', $content ) ;
354
  }
355
 
356
  // Insert const
357
  if ( $enable ) {
358
- $content = preg_replace( '|^<\?php|', "<?php\ndefine( 'WP_CACHE', true ) ;", $content ) ;
359
  }
360
 
361
- $res = File::save( $conf_file, $content, false, false, false ) ;
362
 
363
  if ( $res !== true ) {
364
- throw new \Exception( 'wp-config.php operation failed when changing `WP_CACHE` const: ' . $res ) ;
365
  }
366
 
367
- return true ;
368
  }
369
 
370
  /**
@@ -374,13 +365,12 @@ class Activation extends Instance
374
  * @since 2.9.8 Moved here from ls.cls
375
  * @access public
376
  */
377
- public static function auto_update()
378
- {
379
  if ( ! Conf::val( Base::O_AUTO_UPGRADE ) ) {
380
- return ;
381
  }
382
 
383
- add_filter( 'auto_update_plugin', array( self::get_instance(), 'auto_update_hook' ), 10, 2 ) ;
384
  }
385
 
386
  /**
@@ -389,13 +379,12 @@ class Activation extends Instance
389
  * @since 3.0
390
  * @access public
391
  */
392
- public function auto_update_hook( $update, $item )
393
- {
394
  if ( $item->slug == 'litespeed-cache' ) {
395
- $auto_v = Cloud::version_check( 'auto_update_plugin' ) ;
396
 
397
  if ( ! empty( $auto_v[ 'latest' ] ) && ! empty( $item->new_version ) && $auto_v[ 'latest' ] === $item->new_version ) {
398
- return true ;
399
  }
400
  }
401
 
@@ -408,37 +397,36 @@ class Activation extends Instance
408
  * @since 2.9
409
  * @access public
410
  */
411
- public function upgrade()
412
- {
413
- $plugin = Core::PLUGIN_FILE ;
414
 
415
  /**
416
  * @see wp-admin/update.php
417
  */
418
- include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ;
419
- include_once ABSPATH . 'wp-admin/includes/file.php' ;
420
- include_once ABSPATH . 'wp-admin/includes/misc.php' ;
421
 
422
  try {
423
- ob_start() ;
424
- $skin = new \WP_Ajax_Upgrader_Skin() ;
425
- $upgrader = new \Plugin_Upgrader( $skin ) ;
426
- $result = $upgrader->upgrade( $plugin ) ;
427
  if ( ! is_plugin_active( $plugin ) ) {// todo: upgrade should reactivate the plugin again by WP. Need to check why disabled after upgraded.
428
- activate_plugin( $plugin ) ;
429
  }
430
- ob_end_clean() ;
431
  } catch ( \Exception $e ) {
432
- Admin_Display::error( __( 'Failed to upgrade.', 'litespeed-cache' ) ) ;
433
- return ;
434
  }
435
 
436
  if ( is_wp_error( $result ) ) {
437
- Admin_Display::error( __( 'Failed to upgrade.', 'litespeed-cache' ) ) ;
438
- return ;
439
  }
440
 
441
- Admin_Display::succeed( __( 'Upgraded successfully.', 'litespeed-cache' ) ) ;
442
  }
443
 
444
  /**
@@ -446,13 +434,12 @@ class Activation extends Instance
446
  *
447
  * @since 1.0
448
  */
449
- public function dash_notifier_is_plugin_active( $plugin )
450
- {
451
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' ) ;
452
 
453
- $plugin_path = $plugin . '/' . $plugin . '.php' ;
454
 
455
- return is_plugin_active( $plugin_path ) ;
456
  }
457
 
458
  /**
@@ -460,15 +447,14 @@ class Activation extends Instance
460
  *
461
  * @since 1.0
462
  */
463
- public function dash_notifier_is_plugin_installed( $plugin )
464
- {
465
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' ) ;
466
 
467
- $plugin_path = $plugin . '/' . $plugin . '.php' ;
468
 
469
- $valid = validate_plugin( $plugin_path ) ;
470
 
471
- return ! is_wp_error( $valid ) ;
472
  }
473
 
474
  /**
@@ -476,16 +462,15 @@ class Activation extends Instance
476
  *
477
  * @since 1.0
478
  */
479
- public function dash_notifier_get_plugin_info( $slug )
480
- {
481
- include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ) ;
482
- $result = plugins_api( 'plugin_information', array( 'slug' => $slug ) ) ;
483
 
484
  if ( is_wp_error( $result ) ) {
485
- return false ;
486
  }
487
 
488
- return $result ;
489
  }
490
 
491
  /**
@@ -493,45 +478,44 @@ class Activation extends Instance
493
  *
494
  * @since 1.0
495
  */
496
- public function dash_notifier_install_3rd()
497
- {
498
  ! defined( 'SILENCE_INSTALL' ) && define( 'SILENCE_INSTALL', true );
499
 
500
  $slug = ! empty( $_GET[ 'plugin' ] ) ? $_GET[ 'plugin' ] : false;
501
 
502
  // Check if plugin is installed already
503
  if ( ! $slug || $this->dash_notifier_is_plugin_active( $slug ) ) {
504
- return ;
505
  }
506
 
507
  /**
508
  * @see wp-admin/update.php
509
  */
510
- include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ;
511
- include_once ABSPATH . 'wp-admin/includes/file.php' ;
512
- include_once ABSPATH . 'wp-admin/includes/misc.php' ;
513
 
514
- $plugin_path = $slug . '/' . $slug . '.php' ;
515
 
516
  if ( ! $this->dash_notifier_is_plugin_installed( $slug ) ) {
517
- $plugin_info = $this->dash_notifier_get_plugin_info( $slug ) ;
518
  if ( ! $plugin_info ) {
519
- return ;
520
  }
521
  // Try to install plugin
522
  try {
523
- ob_start() ;
524
- $skin = new \Automatic_Upgrader_Skin() ;
525
- $upgrader = new \Plugin_Upgrader( $skin ) ;
526
- $result = $upgrader->install( $plugin_info->download_link ) ;
527
- ob_end_clean() ;
528
  } catch ( \Exception $e ) {
529
- return ;
530
  }
531
  }
532
 
533
  if ( ! is_plugin_active( $plugin_path ) ) {
534
- activate_plugin( $plugin_path ) ;
535
  }
536
 
537
  }
@@ -542,26 +526,25 @@ class Activation extends Instance
542
  * @since 2.9
543
  * @access public
544
  */
545
- public static function handler()
546
- {
547
- $instance = self::get_instance() ;
548
 
549
- $type = Router::verify_type() ;
550
 
551
  switch ( $type ) {
552
  case self::TYPE_UPGRADE :
553
- $instance->upgrade() ;
554
- break ;
555
 
556
  case self::TYPE_INSTALL_3RD :
557
- $instance->dash_notifier_install_3rd() ;
558
- break ;
559
 
560
  case self::TYPE_DISMISS_RECOMMENDED :
561
  $news = get_option( 'litespeed-recommended', array() );
562
  $news[ 'new' ] = 0;
563
  update_option( 'litespeed-recommended', $news );
564
- break ;
565
 
566
  case self::TYPE_INSTALL_ZIP :
567
  $news = get_option( 'litespeed-recommended', array() );
@@ -570,13 +553,13 @@ class Activation extends Instance
570
  update_option( 'litespeed-recommended', $news );
571
  Debug2::get_instance()->beta_test( $news[ 'zip' ] );
572
  }
573
- break ;
574
 
575
  default:
576
- break ;
577
  }
578
 
579
- Admin::redirect() ;
580
  }
581
 
582
  }
8
  * @subpackage LiteSpeed/inc
9
  * @author LiteSpeed Technologies <info@litespeedtech.com>
10
  */
11
+ namespace LiteSpeed;
12
 
13
+ defined( 'WPINC' ) || exit;
14
 
15
+ class Activation extends Instance {
16
+ protected static $_instance;
 
17
 
18
+ const TYPE_UPGRADE = 'upgrade';
19
+ const TYPE_INSTALL_3RD = 'install_3rd';
20
+ const TYPE_INSTALL_ZIP = 'install_zip';
21
+ const TYPE_DISMISS_RECOMMENDED = 'dismiss_recommended';
22
 
23
+ const NETWORK_TRANSIENT_COUNT = 'lscwp_network_count';
24
 
25
  /**
26
  * The activation hook callback.
28
  * @since 1.0.0
29
  * @access public
30
  */
31
+ public static function register_activation() {
32
+ $count = 0;
33
+ ! defined( 'LSCWP_LOG_TAG' ) && define( 'LSCWP_LOG_TAG', 'Activate_' . get_current_blog_id() );
 
34
 
35
  if ( is_multisite() ) {
36
+ $count = self::get_network_count();
37
  if ( $count !== false ) {
38
+ $count = intval( $count ) + 1;
39
+ set_site_transient( self::NETWORK_TRANSIENT_COUNT, $count, DAY_IN_SECONDS );
40
  }
41
  }
42
 
43
+ do_action( 'litespeed_load_thirdparty' );
44
 
45
  // Check new version @since 2.9.3
46
+ Cloud::version_check( 'activate' . ( defined( 'LSCWP_REF' ) ? '_' . LSCWP_REF : '' ) );
47
 
48
  /* Network file handler */
49
 
53
  if ( $count === 1 ) {
54
  // Only itself is activated, set .htaccess with only CacheLookUp
55
  try {
56
+ Htaccess::get_instance()->insert_ls_wrapper();
57
  } catch ( \Exception $ex ) {
58
+ Admin_Display::error( $ex->getMessage() );
59
  }
60
  }
61
+ return;
62
  }
63
 
64
+ Conf::get_instance()->update_confs();
65
 
66
+ return;
67
  }
68
 
69
  /* Single site file handler */
70
+ Conf::get_instance()->update_confs();
71
 
72
  if ( defined( 'LSCWP_REF' ) && LSCWP_REF == 'whm' ) {
73
+ GUI::update_option( GUI::WHM_MSG, GUI::WHM_MSG_VAL );
74
  }
75
  }
76
 
78
  * Uninstall plugin
79
  * @since 1.1.0
80
  */
81
+ public static function uninstall_litespeed_cache() {
 
82
  Task::destroy();
83
 
84
  // Delete options
85
  foreach ( Conf::get_instance()->load_default_vals() as $k => $v ) {
86
+ Base::delete_option( $k );
87
  }
88
 
89
  // Delete site options
90
  if ( is_multisite() ) {
91
  foreach ( Conf::get_instance()->load_default_site_vals() as $k => $v ) {
92
+ Base::delete_site_option( $k );
93
  }
94
  }
95
 
96
  // Delete avatar table
97
+ Data::get_instance()->tables_del();
98
 
99
  if ( file_exists( LITESPEED_STATIC_DIR ) ) {
100
+ File::rrmdir( LITESPEED_STATIC_DIR );
101
  }
102
 
103
+ Cloud::version_check( 'uninstall' );
104
 
105
  // Files has been deleted when deactivated
106
  }
114
  * @access public
115
  * @return array The array of blog ids.
116
  */
117
+ public static function get_network_ids( $args = array() ) {
118
+ global $wp_version;
 
119
  if ( version_compare( $wp_version, '4.6', '<' ) ) {
120
+ $blogs = wp_get_sites( $args );
121
  if ( ! empty( $blogs ) ) {
122
  foreach ( $blogs as $key => $blog ) {
123
+ $blogs[ $key ] = $blog[ 'blog_id' ];
124
  }
125
  }
126
  }
127
  else {
128
+ $args[ 'fields' ] = 'ids';
129
+ $blogs = get_sites( $args );
130
  }
131
+ return $blogs;
132
  }
133
 
134
  /**
137
  * @since 1.0.12
138
  * @access private
139
  */
140
+ private static function get_network_count() {
141
+ $count = get_site_transient( self::NETWORK_TRANSIENT_COUNT );
 
142
  if ( $count !== false ) {
143
+ return intval( $count );
144
  }
145
  // need to update
146
+ $default = array();
147
+ $count = 0;
148
 
149
+ $sites = self::get_network_ids( array( 'deleted' => 0 ) );
150
  if ( empty( $sites ) ) {
151
+ return false;
152
  }
153
 
154
  foreach ( $sites as $site ) {
155
+ $bid = is_object( $site ) && property_exists( $site, 'blog_id' ) ? $site->blog_id : $site;
156
+ $plugins = get_blog_option( $bid , 'active_plugins', $default );
157
  if ( in_array( LSCWP_BASENAME, $plugins, true ) ) {
158
+ $count++;
159
  }
160
  }
161
 
165
  * @since 2.0
166
  */
167
  if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
168
+ require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
169
  }
170
 
171
  if ( is_plugin_active_for_network( LSCWP_BASENAME ) ) {
172
+ $count++;
173
  }
174
+ return $count;
175
  }
176
 
177
  /**
180
  * @since 1.0.12
181
  * @access private
182
  */
183
+ private static function is_deactivate_last() {
184
+ $count = self::get_network_count();
 
185
  if ( $count === false ) {
186
+ return false;
187
  }
188
  if ( $count !== 1 ) {
189
  // Not deactivating the last one.
190
+ $count--;
191
+ set_site_transient( self::NETWORK_TRANSIENT_COUNT, $count, DAY_IN_SECONDS );
192
+ return false;
193
  }
194
 
195
+ delete_site_transient( self::NETWORK_TRANSIENT_COUNT );
196
+ return true;
197
  }
198
 
199
  /**
204
  * @since 1.0.0
205
  * @access public
206
  */
207
+ public static function register_deactivation() {
 
208
  Task::destroy();
209
 
210
+ ! defined( 'LSCWP_LOG_TAG' ) && define( 'LSCWP_LOG_TAG', 'Deactivate_' . get_current_blog_id() );
211
 
212
+ Purge::purge_all();
213
 
214
  if ( is_multisite() ) {
215
 
217
  if ( is_network_admin() ) {
218
  // Still other activated subsite left, set .htaccess with only CacheLookUp
219
  try {
220
+ Htaccess::get_instance()->insert_ls_wrapper();
221
  } catch ( \Exception $ex ) {
222
+ Admin_Display::error( $ex->getMessage() );
223
  }
224
  }
225
+ return;
226
  }
227
  }
228
 
229
  /* 1) wp-config.php; */
230
 
231
  try {
232
+ self::get_instance()->_manage_wp_cache_const( false );
233
  } catch ( \Exception $ex ) {
234
+ error_log('In wp-config.php: WP_CACHE could not be set to false during deactivation!') ;
235
 
236
+ Admin_Display::error( $ex->getMessage() );
237
  }
238
 
239
  /* 2) adv-cache.php; Dropped in v3.0.4 */
240
 
241
  /* 3) object-cache.php; */
242
 
243
+ Object_Cache::get_instance()->del_file();
244
 
245
  /* 4) .htaccess; */
246
 
247
  try {
248
+ Htaccess::get_instance()->clear_rules();
249
  } catch ( \Exception $ex ) {
250
+ Admin_Display::error( $ex->getMessage() );
251
  }
252
 
253
  // delete in case it's not deleted prior to deactivation.
254
+ GUI::dismiss_whm();
255
  }
256
 
257
  /**
268
  * @since 3.0
269
  * @access public
270
  */
271
+ public function update_files() {
 
272
  // Update cache setting `_CACHE`
273
  Conf::get_instance()->define_cache();
274
 
314
  * @since 3.0 Refactored
315
  * @access private
316
  */
317
+ private function _manage_wp_cache_const( $enable ) {
 
318
  if ( $enable ) {
319
  if ( defined( 'WP_CACHE' ) && WP_CACHE ) {
320
+ return false;
321
  }
322
  }
323
  elseif ( ! defined( 'WP_CACHE' ) || ( defined( 'WP_CACHE' ) && ! WP_CACHE ) ) {
324
+ return false;
325
  }
326
 
327
  /**
328
  * Follow WP's logic to locate wp-config file
329
  * @see wp-load.php
330
  */
331
+ $conf_file = ABSPATH . 'wp-config.php';
332
  if ( ! file_exists( $conf_file ) ) {
333
+ $conf_file = dirname( ABSPATH ) . '/wp-config.php';
334
  }
335
 
336
+ $content = File::read( $conf_file );
337
  if ( ! $content ) {
338
+ throw new \Exception( 'wp-config file content is empty: ' . $conf_file );
339
 
340
  }
341
 
342
  // Remove the line `define('WP_CACHE', true/false);` first
343
  if ( defined( 'WP_CACHE' ) ) {
344
+ $content = preg_replace( '|define\(\s*(["\'])WP_CACHE\1\s*,\s*\w+\)\s*;|sU', '', $content );
345
  }
346
 
347
  // Insert const
348
  if ( $enable ) {
349
+ $content = preg_replace( '|^<\?php|', "<?php\ndefine( 'WP_CACHE', true );", $content );
350
  }
351
 
352
+ $res = File::save( $conf_file, $content, false, false, false );
353
 
354
  if ( $res !== true ) {
355
+ throw new \Exception( 'wp-config.php operation failed when changing `WP_CACHE` const: ' . $res );
356
  }
357
 
358
+ return true;
359
  }
360
 
361
  /**
365
  * @since 2.9.8 Moved here from ls.cls
366
  * @access public
367
  */
368
+ public static function auto_update() {
 
369
  if ( ! Conf::val( Base::O_AUTO_UPGRADE ) ) {
370
+ return;
371
  }
372
 
373
+ add_filter( 'auto_update_plugin', array( self::get_instance(), 'auto_update_hook' ), 10, 2 );
374
  }
375
 
376
  /**
379
  * @since 3.0
380
  * @access public
381
  */
382
+ public function auto_update_hook( $update, $item ) {
 
383
  if ( $item->slug == 'litespeed-cache' ) {
384
+ $auto_v = Cloud::version_check( 'auto_update_plugin' );
385
 
386
  if ( ! empty( $auto_v[ 'latest' ] ) && ! empty( $item->new_version ) && $auto_v[ 'latest' ] === $item->new_version ) {
387
+ return true;
388
  }
389
  }
390
 
397
  * @since 2.9
398
  * @access public
399
  */
400
+ public function upgrade() {
401
+ $plugin = Core::PLUGIN_FILE;
 
402
 
403
  /**
404
  * @see wp-admin/update.php
405
  */
406
+ include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
407
+ include_once ABSPATH . 'wp-admin/includes/file.php';
408
+ include_once ABSPATH . 'wp-admin/includes/misc.php';
409
 
410
  try {
411
+ ob_start();
412
+ $skin = new \WP_Ajax_Upgrader_Skin();
413
+ $upgrader = new \Plugin_Upgrader( $skin );
414
+ $result = $upgrader->upgrade( $plugin );
415
  if ( ! is_plugin_active( $plugin ) ) {// todo: upgrade should reactivate the plugin again by WP. Need to check why disabled after upgraded.
416
+ activate_plugin( $plugin );
417
  }
418
+ ob_end_clean();
419
  } catch ( \Exception $e ) {
420
+ Admin_Display::error( __( 'Failed to upgrade.', 'litespeed-cache' ) );
421
+ return;
422
  }
423
 
424
  if ( is_wp_error( $result ) ) {
425
+ Admin_Display::error( __( 'Failed to upgrade.', 'litespeed-cache' ) );
426
+ return;
427
  }
428
 
429
+ Admin_Display::succeed( __( 'Upgraded successfully.', 'litespeed-cache' ) );
430
  }
431
 
432
  /**
434
  *
435
  * @since 1.0
436
  */
437
+ public function dash_notifier_is_plugin_active( $plugin ) {
438
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
 
439
 
440
+ $plugin_path = $plugin . '/' . $plugin . '.php';
441
 
442
+ return is_plugin_active( $plugin_path );
443
  }
444
 
445
  /**
447
  *
448
  * @since 1.0
449
  */
450
+ public function dash_notifier_is_plugin_installed( $plugin ) {
451
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
 
452
 
453
+ $plugin_path = $plugin . '/' . $plugin . '.php';
454
 
455
+ $valid = validate_plugin( $plugin_path );
456
 
457
+ return ! is_wp_error( $valid );
458
  }
459
 
460
  /**
462
  *
463
  * @since 1.0
464
  */
465
+ public function dash_notifier_get_plugin_info( $slug ) {
466
+ include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
467
+ $result = plugins_api( 'plugin_information', array( 'slug' => $slug ) );
 
468
 
469
  if ( is_wp_error( $result ) ) {
470
+ return false;
471
  }
472
 
473
+ return $result;
474
  }
475
 
476
  /**
478
  *
479
  * @since 1.0
480
  */
481
+ public function dash_notifier_install_3rd() {
 
482
  ! defined( 'SILENCE_INSTALL' ) && define( 'SILENCE_INSTALL', true );
483
 
484
  $slug = ! empty( $_GET[ 'plugin' ] ) ? $_GET[ 'plugin' ] : false;
485
 
486
  // Check if plugin is installed already
487
  if ( ! $slug || $this->dash_notifier_is_plugin_active( $slug ) ) {
488
+ return;
489
  }
490
 
491
  /**
492
  * @see wp-admin/update.php
493
  */
494
+ include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
495
+ include_once ABSPATH . 'wp-admin/includes/file.php';
496
+ include_once ABSPATH . 'wp-admin/includes/misc.php';
497
 
498
+ $plugin_path = $slug . '/' . $slug . '.php';
499
 
500
  if ( ! $this->dash_notifier_is_plugin_installed( $slug ) ) {
501
+ $plugin_info = $this->dash_notifier_get_plugin_info( $slug );
502
  if ( ! $plugin_info ) {
503
+ return;
504
  }
505
  // Try to install plugin
506
  try {
507
+ ob_start();
508
+ $skin = new \Automatic_Upgrader_Skin();
509
+ $upgrader = new \Plugin_Upgrader( $skin );
510
+ $result = $upgrader->install( $plugin_info->download_link );
511
+ ob_end_clean();
512
  } catch ( \Exception $e ) {
513
+ return;
514
  }
515
  }
516
 
517
  if ( ! is_plugin_active( $plugin_path ) ) {
518
+ activate_plugin( $plugin_path );
519
  }
520
 
521
  }
526
  * @since 2.9
527
  * @access public
528
  */
529
+ public static function handler() {
530
+ $instance = self::get_instance();
 
531
 
532
+ $type = Router::verify_type();
533
 
534
  switch ( $type ) {
535
  case self::TYPE_UPGRADE :
536
+ $instance->upgrade();
537
+ break;
538
 
539
  case self::TYPE_INSTALL_3RD :
540
+ $instance->dash_notifier_install_3rd();
541
+ break;
542
 
543
  case self::TYPE_DISMISS_RECOMMENDED :
544
  $news = get_option( 'litespeed-recommended', array() );
545
  $news[ 'new' ] = 0;
546
  update_option( 'litespeed-recommended', $news );
547
+ break;
548
 
549
  case self::TYPE_INSTALL_ZIP :
550
  $news = get_option( 'litespeed-recommended', array() );
553
  update_option( 'litespeed-recommended', $news );
554
  Debug2::get_instance()->beta_test( $news[ 'zip' ] );
555
  }
556
+ break;
557
 
558
  default:
559
+ break;
560
  }
561
 
562
+ Admin::redirect();
563
  }
564
 
565
  }
src/admin-display.cls.php CHANGED
@@ -861,7 +861,12 @@ class Admin_Display extends Base {
861
  if ( $const_val !== null ) {
862
  echo sprintf( __( 'This setting is overwritten by the PHP constant %s', 'litespeed-cache' ), '<code>' . Base::conf_const( $id ) . '</code>' );
863
  } else {
864
- echo __( 'This setting is overwritten by the primary site setting', 'litespeed-cache' );
 
 
 
 
 
865
  }
866
 
867
  echo ', ' . sprintf( __( 'currently set to %s', 'litespeed-cache' ), "<code>$val</code>" ) . '</div>';
861
  if ( $const_val !== null ) {
862
  echo sprintf( __( 'This setting is overwritten by the PHP constant %s', 'litespeed-cache' ), '<code>' . Base::conf_const( $id ) . '</code>' );
863
  } else {
864
+ if ( get_current_blog_id() != BLOG_ID_CURRENT_SITE && Conf::val( Base::NETWORK_O_USE_PRIMARY ) ) {
865
+ echo __( 'This setting is overwritten by the primary site setting', 'litespeed-cache' );
866
+ }
867
+ else {
868
+ echo __( 'This setting is overwritten by the Network setting', 'litespeed-cache' );
869
+ }
870
  }
871
 
872
  echo ', ' . sprintf( __( 'currently set to %s', 'litespeed-cache' ), "<code>$val</code>" ) . '</div>';
src/api.cls.php CHANGED
@@ -106,6 +106,7 @@ class API extends Base {
106
  add_action( 'litespeed_purge_private_all', __NAMESPACE__ . '\Purge::add_private_all' ); // @previous API::purge_private_all()
107
  // Action `litespeed_api_purge_post` // Triggered when purge a post // @previous API::hook_purge_post($hook)
108
  // Action `litespeed_purged_all` // Triggered after purged all.
 
109
 
110
  /**
111
  * ESI
106
  add_action( 'litespeed_purge_private_all', __NAMESPACE__ . '\Purge::add_private_all' ); // @previous API::purge_private_all()
107
  // Action `litespeed_api_purge_post` // Triggered when purge a post // @previous API::hook_purge_post($hook)
108
  // Action `litespeed_purged_all` // Triggered after purged all.
109
+ add_action( 'litespeed_purge_all_object', __NAMESPACE__ . '\Purge::purge_all_object' );
110
 
111
  /**
112
  * ESI
src/base.cls.php CHANGED
@@ -210,6 +210,7 @@ class Base extends Instance {
210
  const O_MEDIA_IFRAME_LAZY_CLS_EXC = 'media-iframe_lazy_cls_exc';
211
  const O_MEDIA_IFRAME_LAZY_PARENT_CLS_EXC = 'media-iframe_lazy_parent_cls_exc';
212
  const O_MEDIA_LAZY_URI_EXC = 'media-lazy_uri_exc';
 
213
 
214
  ## -------------------------------------------------- ##
215
  ## -------------- Image Optm ----------------- ##
@@ -505,6 +506,7 @@ class Base extends Instance {
505
  self::O_MEDIA_IFRAME_LAZY_CLS_EXC => array(),
506
  self::O_MEDIA_IFRAME_LAZY_PARENT_CLS_EXC => array(),
507
  self::O_MEDIA_LAZY_URI_EXC => array(),
 
508
 
509
  // Image Optm
510
  self::O_IMG_OPTM_AUTO => false,
210
  const O_MEDIA_IFRAME_LAZY_CLS_EXC = 'media-iframe_lazy_cls_exc';
211
  const O_MEDIA_IFRAME_LAZY_PARENT_CLS_EXC = 'media-iframe_lazy_parent_cls_exc';
212
  const O_MEDIA_LAZY_URI_EXC = 'media-lazy_uri_exc';
213
+ const O_MEDIA_LQIP_EXC = 'media-lqip_exc';
214
 
215
  ## -------------------------------------------------- ##
216
  ## -------------- Image Optm ----------------- ##
506
  self::O_MEDIA_IFRAME_LAZY_CLS_EXC => array(),
507
  self::O_MEDIA_IFRAME_LAZY_PARENT_CLS_EXC => array(),
508
  self::O_MEDIA_LAZY_URI_EXC => array(),
509
+ self::O_MEDIA_LQIP_EXC => array(),
510
 
511
  // Image Optm
512
  self::O_IMG_OPTM_AUTO => false,
src/cdn.cls.php CHANGED
@@ -60,7 +60,7 @@ class CDN extends Instance {
60
  */
61
  $this->_cfg_cdn_remote_jquery = Conf::val( Base::O_CDN_REMOTE_JQ );
62
  if ( $this->_cfg_cdn_remote_jquery ) {
63
- $this->_load_jquery_remotely();
64
  }
65
 
66
  $this->_cfg_cdn = Conf::val( Base::O_CDN );
@@ -582,10 +582,9 @@ class CDN extends Instance {
582
  * Remote load jQuery remotely
583
  *
584
  * @since 1.5
585
- * @since 2.9.8 Changed to private
586
- * @access private
587
  */
588
- private function _load_jquery_remotely() {
589
  // default jq version
590
  $v = '1.12.4';
591
 
@@ -599,10 +598,12 @@ class CDN extends Instance {
599
 
600
  $src = $this->_cfg_cdn_remote_jquery == Base::VAL_ON2 ? "//cdnjs.cloudflare.com/ajax/libs/jquery/$v/jquery.min.js" : "//ajax.googleapis.com/ajax/libs/jquery/$v/jquery.min.js";
601
 
602
- Debug2::debug2( '[CDN] load_jquery_remotely: ' . $src );
603
-
604
  wp_deregister_script( 'jquery-core' );
 
 
 
 
605
 
606
- wp_register_script( 'jquery-core', $src, false, $v );
607
  }
608
  }
60
  */
61
  $this->_cfg_cdn_remote_jquery = Conf::val( Base::O_CDN_REMOTE_JQ );
62
  if ( $this->_cfg_cdn_remote_jquery ) {
63
+ add_action( 'wp', array( $this, 'load_jquery_remotely' ) );
64
  }
65
 
66
  $this->_cfg_cdn = Conf::val( Base::O_CDN );
582
  * Remote load jQuery remotely
583
  *
584
  * @since 1.5
585
+ * @access public
 
586
  */
587
+ public function load_jquery_remotely() {
588
  // default jq version
589
  $v = '1.12.4';
590
 
598
 
599
  $src = $this->_cfg_cdn_remote_jquery == Base::VAL_ON2 ? "//cdnjs.cloudflare.com/ajax/libs/jquery/$v/jquery.min.js" : "//ajax.googleapis.com/ajax/libs/jquery/$v/jquery.min.js";
600
 
 
 
601
  wp_deregister_script( 'jquery-core' );
602
+ wp_deregister_script( 'jquery' );
603
+
604
+ $res = wp_register_script( 'jquery-core', $src, false, $v );
605
+ $res = wp_register_script( 'jquery', $src, false, $v );
606
 
607
+ Debug2::debug2( '[CDN] load_jquery_remotely: ' . $src, $res );
608
  }
609
  }
src/conf.cls.php CHANGED
@@ -15,8 +15,7 @@ namespace LiteSpeed;
15
  defined( 'WPINC' ) || exit;
16
 
17
 
18
- class Conf extends Base
19
- {
20
  protected static $_instance;
21
 
22
  const TYPE_SET = 'set';
@@ -26,6 +25,7 @@ class Conf extends Base
26
  private $_primary_options = array();
27
  private $_site_options = array();
28
  private $_updated_ids = array();
 
29
 
30
 
31
  /**
@@ -34,8 +34,7 @@ class Conf extends Base
34
  * @since 1.0.0
35
  * @access protected
36
  */
37
- protected function __construct()
38
- {
39
  }
40
 
41
  /**
@@ -44,8 +43,7 @@ class Conf extends Base
44
  * @since 3.0
45
  * @access public
46
  */
47
- public function init()
48
- {
49
  // Check if conf exists or not. If not, create them in DB (won't change version if is converting v2.9- data)
50
  // Conf may be stale, upgrade later
51
  $this->_conf_db_init();
@@ -55,13 +53,13 @@ class Conf extends Base
55
  * @since 2.9.7
56
  */
57
  if ( $this->_options[ self::O_CDN_QUIC ] ) {
58
- ! defined( 'LITESPEED_ALLOWED' ) && define( 'LITESPEED_ALLOWED', true ) ;
59
  }
60
 
61
  add_action( 'litespeed_conf_append', array( $this, 'option_append' ), 10, 2 );
62
  add_action( 'litespeed_conf_force', array( $this, 'force_option' ), 10, 2 );
63
 
64
- $this->define_cache() ;
65
  }
66
 
67
  /**
@@ -70,8 +68,7 @@ class Conf extends Base
70
  * @since 3.0
71
  * @access private
72
  */
73
- private function _conf_db_init()
74
- {
75
  /**
76
  * Try to load options first, network sites can override this later
77
  *
@@ -123,13 +120,13 @@ class Conf extends Base
123
  */
124
  if ( ! $ver || $ver != Core::VER ) {
125
  // Load default values
126
- $this->load_default_vals() ;
127
 
128
  // Init new default/missing options
129
  foreach ( self::$_default_options as $k => $v ) {
130
  // If the option existed, bypass updating
131
  // Bcos we may ask clients to deactivate for debug temporarily, we need to keep the current cfg in deactivation, hence we need to only try adding default cfg when activating.
132
- self::add_option( $k, $v ) ;
133
  }
134
  }
135
 
@@ -138,7 +135,7 @@ class Conf extends Base
138
  *
139
  * Override conf if is network subsites and chose `Use Primary Config`
140
  */
141
- $this->_try_load_site_options() ;
142
 
143
  }
144
 
@@ -167,8 +164,10 @@ class Conf extends Base
167
  }
168
 
169
  // Bypass site special settings
170
- if ( $blog_id !== null ) {
171
- $options = array_diff_key( $options, array_flip( self::$SINGLE_SITE_OPTIONS ) ); // These options are network only
 
 
172
  $this->_primary_options = array_merge( $this->_primary_options, $options );
173
  }
174
  else {
@@ -200,8 +199,10 @@ class Conf extends Base
200
 
201
  $this->_conf_site_db_init();
202
 
 
 
203
  // If network set to use primary setting
204
- if ( ! empty ( $this->_site_options[ self::NETWORK_O_USE_PRIMARY ] ) ) {
205
  // Get the primary site settings
206
  // If it's just upgraded, 2nd blog is being visited before primary blog, can just load default config (won't hurt as this could only happen shortly)
207
  $this->load_options( BLOG_ID_CURRENT_SITE );
@@ -211,9 +212,35 @@ class Conf extends Base
211
  foreach ( self::$_default_options as $k => $v ) {
212
  if ( isset( $this->_site_options[ $k ] ) ) {
213
  // $this->_options[ $k ] = $this->_site_options[ $k ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  $this->_primary_options[ $k ] = $this->_site_options[ $k ];
215
  }
216
  }
 
217
  }
218
 
219
  /**
@@ -222,10 +249,9 @@ class Conf extends Base
222
  * @since 3.0
223
  * @access private
224
  */
225
- private function _if_need_site_options()
226
- {
227
  if ( ! is_multisite() ) {
228
- return false ;
229
  }
230
 
231
  // Check if needs to use site_options or not
@@ -237,17 +263,17 @@ class Conf extends Base
237
  * @since 2.0
238
  */
239
  if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
240
- require_once( ABSPATH . '/wp-admin/includes/plugin.php' ) ;
241
  }
242
  // If is not activated on network, it will not have site options
243
  if ( ! is_plugin_active_for_network( Core::PLUGIN_FILE ) ) {
244
  if ( (int) $this->_options[ self::O_CACHE ] == self::VAL_ON2 ) { // Default to cache on
245
- $this->_options[ self::_CACHE ] = true ;
246
  }
247
- return false ;
248
  }
249
 
250
- return true ;
251
  }
252
 
253
  /**
@@ -256,11 +282,10 @@ class Conf extends Base
256
  * @since 3.0
257
  * @access private
258
  */
259
- private function _conf_site_db_init()
260
- {
261
- $this->load_site_options() ;
262
 
263
- $ver = $this->_site_options[ Base::_VER ] ;
264
 
265
  /**
266
  * Don't upgrade or run new installations other than from backend visit
@@ -268,8 +293,8 @@ class Conf extends Base
268
  */
269
  if ( ! $ver || $ver != Core::VER ) {
270
  if ( ! is_admin() && ! defined( 'LITESPEED_CLI' ) ) {
271
- $this->_site_options = $this->load_default_site_vals() ;
272
- return ;
273
  }
274
  }
275
 
@@ -278,7 +303,7 @@ class Conf extends Base
278
  */
279
  if ( $ver && $ver != Core::VER ) {
280
  // Site plugin versin will change inside
281
- Data::get_instance()->conf_site_upgrade( $ver ) ;
282
  }
283
 
284
  /**
@@ -286,12 +311,12 @@ class Conf extends Base
286
  */
287
  if ( ! $ver || $ver != Core::VER ) {
288
  // Load default values
289
- $this->load_default_site_vals() ;
290
 
291
  // Init new default/missing options
292
  foreach ( self::$_default_site_options as $k => $v ) {
293
  // If the option existed, bypass updating
294
- self::add_site_option( $k, $v ) ;
295
  }
296
  }
297
  }
@@ -304,10 +329,9 @@ class Conf extends Base
304
  * @since 1.0.2
305
  * @access public
306
  */
307
- public function load_site_options()
308
- {
309
  if ( ! is_multisite() || $this->_site_options ) {
310
- return $this->_site_options ;
311
  }
312
 
313
  // Load all site options
@@ -325,13 +349,15 @@ class Conf extends Base
325
  *
326
  * This will not be affected by network use primary site setting.
327
  *
 
 
328
  * @since 3.0
329
  * @access public
330
  */
331
- public function option_append( $name, $default )
332
- {
333
- self::$_default_options[ $name ] = $default ;
334
- $this->_options[ $name ] = self::get_option( $name, $default ) ;
335
  }
336
 
337
  /**
@@ -340,21 +366,20 @@ class Conf extends Base
340
  * @since 2.6
341
  * @access public
342
  */
343
- public function force_option( $k, $v )
344
- {
345
  if ( ! array_key_exists( $k, $this->_options ) ) {
346
- return ;
347
  }
348
 
349
  $v = $this->type_casting( $v, $k );
350
 
351
  if ( $this->_options[ $k ] === $v ) {
352
- return ;
353
  }
354
 
355
- Debug2::debug( "[Conf] ** $k forced from " . var_export( $this->_options[ $k ], true ) . ' to ' . var_export( $v, true ) ) ;
356
 
357
- $this->_options[ $k ] = $v ;
358
  }
359
 
360
  /**
@@ -363,27 +388,26 @@ class Conf extends Base
363
  * @since 3.0
364
  * @access public
365
  */
366
- public function define_cache()
367
- {
368
  // Init global const cache on setting
369
- $this->_options[ self::_CACHE ] = false ;
370
  if ( (int) $this->_options[ self::O_CACHE ] == self::VAL_ON || $this->_options[ self::O_CDN_QUIC ] ) {
371
- $this->_options[ self::_CACHE ] = true ;
372
  }
373
 
374
  // Check network
375
  if ( ! $this->_if_need_site_options() ) {
376
  // Set cache on
377
- $this->_define_cache_on() ;
378
- return ;
379
  }
380
 
381
  // If use network setting
382
  if ( (int) $this->_options[ self::O_CACHE ] == self::VAL_ON2 && $this->_site_options[ self::O_CACHE ] ) {
383
- $this->_options[ self::_CACHE ] = true ;
384
  }
385
 
386
- $this->_define_cache_on() ;
387
  }
388
 
389
  /**
@@ -392,8 +416,7 @@ class Conf extends Base
392
  * @since 2.1
393
  * @access private
394
  */
395
- private function _define_cache_on()
396
- {
397
  if ( ! $this->_options[ self::_CACHE ] ) {
398
  return;
399
  }
@@ -408,13 +431,12 @@ class Conf extends Base
408
  * @access public
409
  * @return array The list of configured options.
410
  */
411
- public function get_options( $ori = false )
412
- {
413
  if ( ! $ori ) {
414
  return array_merge( $this->_options, $this->_primary_options, $this->_const_options );
415
  }
416
 
417
- return $this->_options ;
418
  }
419
 
420
  /**
@@ -423,15 +445,14 @@ class Conf extends Base
423
  * @since 3.0
424
  * @access public
425
  */
426
- public static function val( $id, $ori = false )
427
- {
428
  $instance = self::get_instance();
429
 
430
  if ( isset( $instance->_options[ $id ] ) ) {
431
  if ( ! $ori ) {
432
  $val = $instance->const_overwritten( $id );
433
  if ( $val !== null ) {
434
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Conf] 🏛️ const option ' . $id . '=' . var_export( $val, true ) ) ;
435
  return $val;
436
  }
437
 
@@ -441,14 +462,18 @@ class Conf extends Base
441
  }
442
  }
443
 
444
- return $instance->_options[ $id ];
 
 
 
 
445
  }
446
 
447
  if ( isset( $instance->_site_options[ $id ] ) ) {
448
  if ( ! $ori ) {
449
  $val = $instance->const_overwritten( $id );
450
  if ( $val !== null ) {
451
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Conf] 🏛️ const option ' . $id . '=' . var_export( $val, true ) ) ;
452
  return $val;
453
  }
454
  }
@@ -466,8 +491,7 @@ class Conf extends Base
466
  *
467
  * @since 3.0
468
  */
469
- public function const_overwritten( $id )
470
- {
471
  if ( ! isset( $this->_const_options[ $id ] ) || $this->_const_options[ $id ] == $this->_options[ $id ] ) {
472
  return null;
473
  }
@@ -479,11 +503,16 @@ class Conf extends Base
479
  *
480
  * @since 3.2.2
481
  */
482
- public function primary_overwritten( $id )
483
- {
484
  if ( ! isset( $this->_primary_options[ $id ] ) || $this->_primary_options[ $id ] == $this->_options[ $id ] ) {
485
  return null;
486
  }
 
 
 
 
 
 
487
  return $this->_primary_options[ $id ];
488
  }
489
 
@@ -493,8 +522,7 @@ class Conf extends Base
493
  * @since 3.0
494
  * @access public
495
  */
496
- public function update_confs( $the_matrix = false )
497
- {
498
  if ( $the_matrix ) {
499
  foreach ( $the_matrix as $id => $val ) {
500
  $this->update( $id, $val );
@@ -559,8 +587,7 @@ class Conf extends Base
559
  * @since 3.0
560
  * @access public
561
  */
562
- public function update( $id, $val )
563
- {
564
  // Bypassed this bcos $this->_options could be changed by force_option()
565
  // if ( $this->_options[ $id ] === $val ) {
566
  // return;
@@ -625,51 +652,51 @@ class Conf extends Base
625
  public function network_update( $id, $val ) {
626
  if ( ! array_key_exists( $id, self::$_default_site_options ) ) {
627
  defined( 'LSCWP_LOG' ) && Debug2::debug( '[Conf] Invalid network option ID ' . $id );
628
- return ;
629
  }
630
 
631
  // Validate type
632
  if ( is_bool( self::$_default_site_options[ $id ] ) ) {
633
- $max = $this->_conf_multi_switch( $id ) ;
634
  if ( $max && $val > 1 ) {
635
- $val %= $max + 1 ;
636
  }
637
  else {
638
- $val = (bool) $val ;
639
  }
640
  }
641
  elseif ( is_array( self::$_default_site_options[ $id ] ) ) {
642
  // from textarea input
643
  if ( ! is_array( $val ) ) {
644
- $val = Utility::sanitize_lines( $val, $this->_conf_filter( $id ) ) ;
645
  }
646
  }
647
  elseif ( ! is_string( self::$_default_site_options[ $id ] ) ) {
648
- $val = (int) $val ;
649
  }
650
  else {
651
  // Check if the string has a limit set
652
- $val = $this->_conf_string_val( $id, $val ) ;
653
  }
654
 
655
  // Save data
656
- self::update_site_option( $id, $val ) ;
657
 
658
  // Handle purge if setting changed
659
  if ( $this->_site_options[ $id ] != $val ) {
660
  // Check if need to do a purge all or not
661
  if ( $this->_conf_purge_all( $id ) ) {
662
- Purge::purge_all( '[Conf] Network conf changed [id] ' . $id ) ;
663
  }
664
  }
665
 
666
  // No need to update cron here, Cron will register in each init
667
 
668
  // Update in-memory data
669
- $this->_site_options[ $id ] = $val ;
670
 
671
  if ( isset( $this->_options[ $id ] ) ) {
672
- $this->_options[ $id ] = $val ;
673
  }
674
  }
675
 
@@ -681,18 +708,17 @@ class Conf extends Base
681
  * @param string $role The user role
682
  * @return int The set value if already set
683
  */
684
- public function in_optm_exc_roles( $role = null )
685
- {
686
  // Get user role
687
  if ( $role === null ) {
688
- $role = Router::get_role() ;
689
  }
690
 
691
  if ( ! $role ) {
692
- return false ;
693
  }
694
 
695
- return in_array( $role, self::val( self::O_OPTM_EXC_ROLES ) ) ? $role : false ;
696
  }
697
 
698
  /**
@@ -701,8 +727,7 @@ class Conf extends Base
701
  * @since 2.9
702
  * @access private
703
  */
704
- private function _set_conf()
705
- {
706
  /**
707
  * NOTE: For URL Query String setting,
708
  * 1. If append lines to an array setting e.g. `cache-force_uri`, use `set[cache-force_uri][]=the_url`.
@@ -721,7 +746,7 @@ class Conf extends Base
721
 
722
  // Append new item to array type settings
723
  if ( is_array( $v ) && is_array( $this->_options[ $id ] ) ) {
724
- $v = array_merge( $this->_options[ $id ], $v ) ;
725
 
726
  Debug2::debug( '[Conf] Appended to settings [' . $id . ']: ' . var_export( $v, true ) );
727
  }
@@ -733,7 +758,7 @@ class Conf extends Base
733
  }
734
 
735
  if ( ! $the_matrix ) {
736
- return ;
737
  }
738
 
739
  $this->update_confs( $the_matrix );
@@ -754,8 +779,7 @@ class Conf extends Base
754
  * @since 2.9
755
  * @access public
756
  */
757
- public static function handler()
758
- {
759
  $instance = self::get_instance();
760
 
761
  $type = Router::verify_type();
15
  defined( 'WPINC' ) || exit;
16
 
17
 
18
+ class Conf extends Base {
 
19
  protected static $_instance;
20
 
21
  const TYPE_SET = 'set';
25
  private $_primary_options = array();
26
  private $_site_options = array();
27
  private $_updated_ids = array();
28
+ private $_is_primary = false;
29
 
30
 
31
  /**
34
  * @since 1.0.0
35
  * @access protected
36
  */
37
+ protected function __construct() {
 
38
  }
39
 
40
  /**
43
  * @since 3.0
44
  * @access public
45
  */
46
+ public function init() {
 
47
  // Check if conf exists or not. If not, create them in DB (won't change version if is converting v2.9- data)
48
  // Conf may be stale, upgrade later
49
  $this->_conf_db_init();
53
  * @since 2.9.7
54
  */
55
  if ( $this->_options[ self::O_CDN_QUIC ] ) {
56
+ ! defined( 'LITESPEED_ALLOWED' ) && define( 'LITESPEED_ALLOWED', true );
57
  }
58
 
59
  add_action( 'litespeed_conf_append', array( $this, 'option_append' ), 10, 2 );
60
  add_action( 'litespeed_conf_force', array( $this, 'force_option' ), 10, 2 );
61
 
62
+ $this->define_cache();
63
  }
64
 
65
  /**
68
  * @since 3.0
69
  * @access private
70
  */
71
+ private function _conf_db_init() {
 
72
  /**
73
  * Try to load options first, network sites can override this later
74
  *
120
  */
121
  if ( ! $ver || $ver != Core::VER ) {
122
  // Load default values
123
+ $this->load_default_vals();
124
 
125
  // Init new default/missing options
126
  foreach ( self::$_default_options as $k => $v ) {
127
  // If the option existed, bypass updating
128
  // Bcos we may ask clients to deactivate for debug temporarily, we need to keep the current cfg in deactivation, hence we need to only try adding default cfg when activating.
129
+ self::add_option( $k, $v );
130
  }
131
  }
132
 
135
  *
136
  * Override conf if is network subsites and chose `Use Primary Config`
137
  */
138
+ $this->_try_load_site_options();
139
 
140
  }
141
 
164
  }
165
 
166
  // Bypass site special settings
167
+ if ( $blog_id !== null ) { // This is to load the primary settings ONLY
168
+ // These options are the ones that can be overwritten by primary
169
+ $options = array_diff_key( $options, array_flip( self::$SINGLE_SITE_OPTIONS ) );
170
+
171
  $this->_primary_options = array_merge( $this->_primary_options, $options );
172
  }
173
  else {
199
 
200
  $this->_conf_site_db_init();
201
 
202
+ $this->_is_primary = get_current_blog_id() == BLOG_ID_CURRENT_SITE;
203
+
204
  // If network set to use primary setting
205
+ if ( ! empty ( $this->_site_options[ self::NETWORK_O_USE_PRIMARY ] ) && ! $this->_is_primary ) { // subsites or network admin
206
  // Get the primary site settings
207
  // If it's just upgraded, 2nd blog is being visited before primary blog, can just load default config (won't hurt as this could only happen shortly)
208
  $this->load_options( BLOG_ID_CURRENT_SITE );
212
  foreach ( self::$_default_options as $k => $v ) {
213
  if ( isset( $this->_site_options[ $k ] ) ) {
214
  // $this->_options[ $k ] = $this->_site_options[ $k ];
215
+
216
+ // Special handler to `Enable Cache` option if the value is set to OFF
217
+ if ( $k == self::O_CACHE ) {
218
+ if ( $this->_is_primary ) {
219
+ if ( $this->_options[ $k ] != $this->_site_options[ $k ] ) {
220
+ if ( $this->_options[ $k ] != self::VAL_ON2 ) {
221
+ continue;
222
+ }
223
+ }
224
+ }
225
+ else {
226
+ if ( $this->_site_options[ self::NETWORK_O_USE_PRIMARY ] ) {
227
+ if ( isset( $this->_primary_options[ $k ] ) && $this->_primary_options[ $k ] != self::VAL_ON2 ) { // This case will use _primary_options override always
228
+ continue;
229
+ }
230
+ }
231
+ else {
232
+ if ( $this->_options[ $k ] != self::VAL_ON2 ) {
233
+ continue;
234
+ }
235
+ }
236
+ }
237
+ }
238
+
239
+ // _primary_options will store primary settings + network settings, OR, store the network settings for subsites
240
  $this->_primary_options[ $k ] = $this->_site_options[ $k ];
241
  }
242
  }
243
+ // var_dump($this->_options);
244
  }
245
 
246
  /**
249
  * @since 3.0
250
  * @access private
251
  */
252
+ private function _if_need_site_options() {
 
253
  if ( ! is_multisite() ) {
254
+ return false;
255
  }
256
 
257
  // Check if needs to use site_options or not
263
  * @since 2.0
264
  */
265
  if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
266
+ require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
267
  }
268
  // If is not activated on network, it will not have site options
269
  if ( ! is_plugin_active_for_network( Core::PLUGIN_FILE ) ) {
270
  if ( (int) $this->_options[ self::O_CACHE ] == self::VAL_ON2 ) { // Default to cache on
271
+ $this->_options[ self::_CACHE ] = true;
272
  }
273
+ return false;
274
  }
275
 
276
+ return true;
277
  }
278
 
279
  /**
282
  * @since 3.0
283
  * @access private
284
  */
285
+ private function _conf_site_db_init() {
286
+ $this->load_site_options();
 
287
 
288
+ $ver = $this->_site_options[ Base::_VER ];
289
 
290
  /**
291
  * Don't upgrade or run new installations other than from backend visit
293
  */
294
  if ( ! $ver || $ver != Core::VER ) {
295
  if ( ! is_admin() && ! defined( 'LITESPEED_CLI' ) ) {
296
+ $this->_site_options = $this->load_default_site_vals();
297
+ return;
298
  }
299
  }
300
 
303
  */
304
  if ( $ver && $ver != Core::VER ) {
305
  // Site plugin versin will change inside
306
+ Data::get_instance()->conf_site_upgrade( $ver );
307
  }
308
 
309
  /**
311
  */
312
  if ( ! $ver || $ver != Core::VER ) {
313
  // Load default values
314
+ $this->load_default_site_vals();
315
 
316
  // Init new default/missing options
317
  foreach ( self::$_default_site_options as $k => $v ) {
318
  // If the option existed, bypass updating
319
+ self::add_site_option( $k, $v );
320
  }
321
  }
322
  }
329
  * @since 1.0.2
330
  * @access public
331
  */
332
+ public function load_site_options() {
 
333
  if ( ! is_multisite() || $this->_site_options ) {
334
+ return $this->_site_options;
335
  }
336
 
337
  // Load all site options
349
  *
350
  * This will not be affected by network use primary site setting.
351
  *
352
+ * NOTE: If it is a multi switch option, need to call `_conf_multi_switch()` first
353
+ *
354
  * @since 3.0
355
  * @access public
356
  */
357
+ public function option_append( $name, $default ) {
358
+ self::$_default_options[ $name ] = $default;
359
+ $this->_options[ $name ] = self::get_option( $name, $default );
360
+ $this->_options[ $name ] = $this->type_casting( $this->_options[ $name ], $name );
361
  }
362
 
363
  /**
366
  * @since 2.6
367
  * @access public
368
  */
369
+ public function force_option( $k, $v ) {
 
370
  if ( ! array_key_exists( $k, $this->_options ) ) {
371
+ return;
372
  }
373
 
374
  $v = $this->type_casting( $v, $k );
375
 
376
  if ( $this->_options[ $k ] === $v ) {
377
+ return;
378
  }
379
 
380
+ Debug2::debug( "[Conf] ** $k forced from " . var_export( $this->_options[ $k ], true ) . ' to ' . var_export( $v, true ) );
381
 
382
+ $this->_options[ $k ] = $v;
383
  }
384
 
385
  /**
388
  * @since 3.0
389
  * @access public
390
  */
391
+ public function define_cache() {
 
392
  // Init global const cache on setting
393
+ $this->_options[ self::_CACHE ] = false;
394
  if ( (int) $this->_options[ self::O_CACHE ] == self::VAL_ON || $this->_options[ self::O_CDN_QUIC ] ) {
395
+ $this->_options[ self::_CACHE ] = true;
396
  }
397
 
398
  // Check network
399
  if ( ! $this->_if_need_site_options() ) {
400
  // Set cache on
401
+ $this->_define_cache_on();
402
+ return;
403
  }
404
 
405
  // If use network setting
406
  if ( (int) $this->_options[ self::O_CACHE ] == self::VAL_ON2 && $this->_site_options[ self::O_CACHE ] ) {
407
+ $this->_options[ self::_CACHE ] = true;
408
  }
409
 
410
+ $this->_define_cache_on();
411
  }
412
 
413
  /**
416
  * @since 2.1
417
  * @access private
418
  */
419
+ private function _define_cache_on() {
 
420
  if ( ! $this->_options[ self::_CACHE ] ) {
421
  return;
422
  }
431
  * @access public
432
  * @return array The list of configured options.
433
  */
434
+ public function get_options( $ori = false ) {
 
435
  if ( ! $ori ) {
436
  return array_merge( $this->_options, $this->_primary_options, $this->_const_options );
437
  }
438
 
439
+ return $this->_options;
440
  }
441
 
442
  /**
445
  * @since 3.0
446
  * @access public
447
  */
448
+ public static function val( $id, $ori = false ) {
 
449
  $instance = self::get_instance();
450
 
451
  if ( isset( $instance->_options[ $id ] ) ) {
452
  if ( ! $ori ) {
453
  $val = $instance->const_overwritten( $id );
454
  if ( $val !== null ) {
455
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Conf] 🏛️ const option ' . $id . '=' . var_export( $val, true ) );
456
  return $val;
457
  }
458
 
462
  }
463
  }
464
 
465
+ // Network orignal value will be in _site_options
466
+ if ( ! is_network_admin() || ! isset( $instance->_site_options[ $id ] ) ) {
467
+ return $instance->_options[ $id ];
468
+ }
469
+
470
  }
471
 
472
  if ( isset( $instance->_site_options[ $id ] ) ) {
473
  if ( ! $ori ) {
474
  $val = $instance->const_overwritten( $id );
475
  if ( $val !== null ) {
476
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Conf] 🏛️ const option ' . $id . '=' . var_export( $val, true ) );
477
  return $val;
478
  }
479
  }
491
  *
492
  * @since 3.0
493
  */
494
+ public function const_overwritten( $id ) {
 
495
  if ( ! isset( $this->_const_options[ $id ] ) || $this->_const_options[ $id ] == $this->_options[ $id ] ) {
496
  return null;
497
  }
503
  *
504
  * @since 3.2.2
505
  */
506
+ public function primary_overwritten( $id ) {
 
507
  if ( ! isset( $this->_primary_options[ $id ] ) || $this->_primary_options[ $id ] == $this->_options[ $id ] ) {
508
  return null;
509
  }
510
+
511
+ // Network admin settings is impossible to be overwritten by primary
512
+ if ( is_network_admin() ) {
513
+ return null;
514
+ }
515
+
516
  return $this->_primary_options[ $id ];
517
  }
518
 
522
  * @since 3.0
523
  * @access public
524
  */
525
+ public function update_confs( $the_matrix = false ) {
 
526
  if ( $the_matrix ) {
527
  foreach ( $the_matrix as $id => $val ) {
528
  $this->update( $id, $val );
587
  * @since 3.0
588
  * @access public
589
  */
590
+ public function update( $id, $val ) {
 
591
  // Bypassed this bcos $this->_options could be changed by force_option()
592
  // if ( $this->_options[ $id ] === $val ) {
593
  // return;
652
  public function network_update( $id, $val ) {
653
  if ( ! array_key_exists( $id, self::$_default_site_options ) ) {
654
  defined( 'LSCWP_LOG' ) && Debug2::debug( '[Conf] Invalid network option ID ' . $id );
655
+ return;
656
  }
657
 
658
  // Validate type
659
  if ( is_bool( self::$_default_site_options[ $id ] ) ) {
660
+ $max = $this->_conf_multi_switch( $id );
661
  if ( $max && $val > 1 ) {
662
+ $val %= $max + 1;
663
  }
664
  else {
665
+ $val = (bool) $val;
666
  }
667
  }
668
  elseif ( is_array( self::$_default_site_options[ $id ] ) ) {
669
  // from textarea input
670
  if ( ! is_array( $val ) ) {
671
+ $val = Utility::sanitize_lines( $val, $this->_conf_filter( $id ) );
672
  }
673
  }
674
  elseif ( ! is_string( self::$_default_site_options[ $id ] ) ) {
675
+ $val = (int) $val;
676
  }
677
  else {
678
  // Check if the string has a limit set
679
+ $val = $this->_conf_string_val( $id, $val );
680
  }
681
 
682
  // Save data
683
+ self::update_site_option( $id, $val );
684
 
685
  // Handle purge if setting changed
686
  if ( $this->_site_options[ $id ] != $val ) {
687
  // Check if need to do a purge all or not
688
  if ( $this->_conf_purge_all( $id ) ) {
689
+ Purge::purge_all( '[Conf] Network conf changed [id] ' . $id );
690
  }
691
  }
692
 
693
  // No need to update cron here, Cron will register in each init
694
 
695
  // Update in-memory data
696
+ $this->_site_options[ $id ] = $val;
697
 
698
  if ( isset( $this->_options[ $id ] ) ) {
699
+ $this->_options[ $id ] = $val;
700
  }
701
  }
702
 
708
  * @param string $role The user role
709
  * @return int The set value if already set
710
  */
711
+ public function in_optm_exc_roles( $role = null ) {
 
712
  // Get user role
713
  if ( $role === null ) {
714
+ $role = Router::get_role();
715
  }
716
 
717
  if ( ! $role ) {
718
+ return false;
719
  }
720
 
721
+ return in_array( $role, self::val( self::O_OPTM_EXC_ROLES ) ) ? $role : false;
722
  }
723
 
724
  /**
727
  * @since 2.9
728
  * @access private
729
  */
730
+ private function _set_conf() {
 
731
  /**
732
  * NOTE: For URL Query String setting,
733
  * 1. If append lines to an array setting e.g. `cache-force_uri`, use `set[cache-force_uri][]=the_url`.
746
 
747
  // Append new item to array type settings
748
  if ( is_array( $v ) && is_array( $this->_options[ $id ] ) ) {
749
+ $v = array_merge( $this->_options[ $id ], $v );
750
 
751
  Debug2::debug( '[Conf] Appended to settings [' . $id . ']: ' . var_export( $v, true ) );
752
  }
758
  }
759
 
760
  if ( ! $the_matrix ) {
761
+ return;
762
  }
763
 
764
  $this->update_confs( $the_matrix );
779
  * @since 2.9
780
  * @access public
781
  */
782
+ public static function handler() {
 
783
  $instance = self::get_instance();
784
 
785
  $type = Router::verify_type();
src/css.cls.php CHANGED
@@ -11,6 +11,7 @@ class CSS extends Base {
11
  protected static $_instance;
12
 
13
  const TYPE_GENERATE_CRITICAL = 'generate_critical';
 
14
 
15
  protected $_summary;
16
 
@@ -217,8 +218,10 @@ class CSS extends Base {
217
  $attrs = Utility::parse_attr( $match[ 1 ] );
218
 
219
  if ( ! empty( $attrs[ 'rel' ] ) ) {
220
- if ( $attrs[ 'rel' ] !== 'stylesheet' && $attrs[ 'rel' ] !== 'preload' ) {
221
- continue;
 
 
222
  }
223
  }
224
 
@@ -429,6 +432,23 @@ class CSS extends Base {
429
  self::save_summary();
430
  }
431
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432
  /**
433
  * The critical css file for current page
434
  *
@@ -485,6 +505,10 @@ class CSS extends Base {
485
  self::cron_ccss( true );
486
  break;
487
 
 
 
 
 
488
  default:
489
  break;
490
  }
11
  protected static $_instance;
12
 
13
  const TYPE_GENERATE_CRITICAL = 'generate_critical';
14
+ const TYPE_CLEAR_Q = 'clear_q';
15
 
16
  protected $_summary;
17
 
218
  $attrs = Utility::parse_attr( $match[ 1 ] );
219
 
220
  if ( ! empty( $attrs[ 'rel' ] ) ) {
221
+ if ( $attrs[ 'rel' ] != 'stylesheet' ) {
222
+ if ( $attrs[ 'rel' ] != 'preload' || empty( $attrs[ 'as' ] ) || $attrs[ 'as' ] != 'style' ) {
223
+ continue;
224
+ }
225
  }
226
  }
227
 
432
  self::save_summary();
433
  }
434
 
435
+ /**
436
+ * Clear all waiting queues
437
+ *
438
+ * @since 3.4
439
+ */
440
+ public function clear_q() {
441
+ if ( empty( $this->_summary[ 'queue' ] ) ) {
442
+ return;
443
+ }
444
+
445
+ $this->_summary[ 'queue' ] = array();
446
+ self::save_summary();
447
+
448
+ $msg = __( 'Queue cleared successfully.', 'litespeed-cache' );
449
+ Admin_Display::succeed( $msg );
450
+ }
451
+
452
  /**
453
  * The critical css file for current page
454
  *
505
  self::cron_ccss( true );
506
  break;
507
 
508
+ case self::TYPE_CLEAR_Q :
509
+ $instance->clear_q();
510
+ break;
511
+
512
  default:
513
  break;
514
  }
src/db-optm.cls.php CHANGED
@@ -183,7 +183,7 @@ class DB_Optm extends Instance {
183
  return __( 'Clean expired transients successfully.', 'litespeed-cache' );
184
 
185
  case 'all_transients':
186
- $wpdb->query( "DELETE FROM `$wpdb->options` WHERE option_name LIKE '%_transient_%'" );
187
  return __( 'Clean all transients successfully.', 'litespeed-cache' );
188
 
189
  case 'optimize_tables':
183
  return __( 'Clean expired transients successfully.', 'litespeed-cache' );
184
 
185
  case 'all_transients':
186
+ $wpdb->query( "DELETE FROM `$wpdb->options` WHERE option_name LIKE '%\\_transient\\_%'" );
187
  return __( 'Clean all transients successfully.', 'litespeed-cache' );
188
 
189
  case 'optimize_tables':
src/doc.cls.php CHANGED
@@ -61,6 +61,21 @@ class Doc {
61
  echo __( 'One per line.', 'litespeed-cache' );
62
  }
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  /**
65
  * Notice to edit .htaccess
66
  *
61
  echo __( 'One per line.', 'litespeed-cache' );
62
  }
63
 
64
+ /**
65
+ * One per line
66
+ *
67
+ * @since 3.4
68
+ * @access public
69
+ */
70
+ public static function full_or_partial_url( $string_only = false ) {
71
+ if ( $string_only ) {
72
+ echo __( 'Both full and partial strings can be used.', 'litespeed-cache' );
73
+ }
74
+ else {
75
+ echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' );
76
+ }
77
+ }
78
+
79
  /**
80
  * Notice to edit .htaccess
81
  *
src/esi.cls.php CHANGED
@@ -396,6 +396,7 @@ class ESI extends Instance {
396
  }
397
  if ( $params ) {
398
  $appended_params[ self::QS_PARAMS ] = base64_encode( json_encode( $params ) ) ;
 
399
  }
400
 
401
  // Append hash
@@ -812,31 +813,22 @@ class ESI extends Instance {
812
  *
813
  * @since 1.1.3
814
  * @access public
815
- * @param array $defaults The default comment form settings.
816
- * @return array The default comment form settings.
817
  */
818
- public function register_comment_form_actions( $defaults )
819
- {
820
  $this->esi_args = $defaults ;
821
  echo GUI::clean_wrapper_begin() ;
822
- add_filter( 'comment_form_submit_button', array( $this, 'sub_comment_form_block' ), 1000, 2 ) ;// Needs to get param from this hook and generate esi block
 
823
  return $defaults ;
824
  }
825
 
826
  /**
827
- * Hooked to the comment_form_submit_button filter.
828
- *
829
- * This method will compare the used comment form args against the default args. The difference will be passed to the esi request.
830
  *
 
831
  * @access public
832
- * @since 1.1.3
833
- * @global type $post
834
- * @param $unused
835
- * @param array $args The used comment form args.
836
- * @return unused.
837
  */
838
- public function sub_comment_form_block( $unused, $args )
839
- {
840
  if ( empty( $args ) || empty( $this->esi_args ) ) {
841
  Debug2::debug( 'comment form args empty?' ) ;
842
  return $unused ;
@@ -859,17 +851,29 @@ class ESI extends Instance {
859
  }
860
  }
861
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
862
  echo GUI::clean_wrapper_end() ;
863
- global $post ;
864
  $params = array(
865
- self::PARAM_ID => $post->ID,
866
- self::PARAM_ARGS => $esi_args,
867
  ) ;
868
 
869
  echo self::sub_esi_block( 'comment-form', 'comment form', $params ) ;
870
  echo GUI::clean_wrapper_begin() ;
871
  add_action( 'comment_form_after', array( $this, 'comment_form_sub_clean' ) ) ;
872
- return $unused ;
873
  }
874
 
875
  /**
396
  }
397
  if ( $params ) {
398
  $appended_params[ self::QS_PARAMS ] = base64_encode( json_encode( $params ) ) ;
399
+ Debug2::debug2( '[ESI] param ', $params );
400
  }
401
 
402
  // Append hash
813
  *
814
  * @since 1.1.3
815
  * @access public
 
 
816
  */
817
+ public function register_comment_form_actions( $defaults ) {
 
818
  $this->esi_args = $defaults ;
819
  echo GUI::clean_wrapper_begin() ;
820
+ add_filter( 'comment_form_submit_button', array( $this, 'sub_comment_form_btn' ), 1000, 2 ); // To save the params passed in
821
+ add_action( 'comment_form', array( $this, 'sub_comment_form_block' ), 1000 ) ;
822
  return $defaults ;
823
  }
824
 
825
  /**
826
+ * Store the args passed in comment_form for the ESI comment param usage in `$this->sub_comment_form_block()`
 
 
827
  *
828
+ * @since 3.4
829
  * @access public
 
 
 
 
 
830
  */
831
+ public function sub_comment_form_btn( $unused, $args ) {
 
832
  if ( empty( $args ) || empty( $this->esi_args ) ) {
833
  Debug2::debug( 'comment form args empty?' ) ;
834
  return $unused ;
851
  }
852
  }
853
 
854
+ $this->esi_args = $esi_args;
855
+
856
+ return $unused ;
857
+ }
858
+
859
+ /**
860
+ * Hooked to the comment_form_submit_button filter.
861
+ *
862
+ * This method will compare the used comment form args against the default args. The difference will be passed to the esi request.
863
+ *
864
+ * @access public
865
+ * @since 1.1.3
866
+ */
867
+ public function sub_comment_form_block( $post_id ) {
868
  echo GUI::clean_wrapper_end() ;
 
869
  $params = array(
870
+ self::PARAM_ID => $post_id,
871
+ self::PARAM_ARGS => $this->esi_args,
872
  ) ;
873
 
874
  echo self::sub_esi_block( 'comment-form', 'comment form', $params ) ;
875
  echo GUI::clean_wrapper_begin() ;
876
  add_action( 'comment_form_after', array( $this, 'comment_form_sub_clean' ) ) ;
 
877
  }
878
 
879
  /**
src/gui.cls.php CHANGED
@@ -9,28 +9,27 @@
9
  namespace LiteSpeed;
10
  defined( 'WPINC' ) || exit;
11
 
12
- class GUI extends Base
13
- {
14
- protected static $_instance ;
15
 
16
- private static $_clean_counter = 0 ;
17
 
18
- private $_promo_true ;
19
 
20
  // [ file_tag => [ days, litespeed_only ], ... ]
21
  private $_promo_list = array(
22
  'new_version' => array( 1, false ),
23
  'score' => array( 5, false ),
24
  // 'slack' => array( 3, false ),
25
- ) ;
26
 
27
 
28
- const TYPE_DISMISS_WHM = 'whm' ;
29
- const TYPE_DISMISS_EXPIRESDEFAULT = 'ExpiresDefault' ;
30
- const TYPE_DISMISS_PROMO = 'promo' ;
31
 
32
- const WHM_MSG = 'lscwp_whm_install' ;
33
- const WHM_MSG_VAL = 'whm_install' ;
34
 
35
  protected $_summary;
36
 
@@ -40,8 +39,7 @@ class GUI extends Base
40
  * @since 1.3
41
  * @access protected
42
  */
43
- protected function __construct()
44
- {
45
  $this->_summary = self::get_summary();
46
 
47
  }
@@ -51,16 +49,15 @@ class GUI extends Base
51
  *
52
  * @since 3.0
53
  */
54
- public function frontend_init()
55
- {
56
  if ( is_admin() ) {
57
  return;
58
  }
59
 
60
- Debug2::debug2( '[GUI] init' ) ;
61
  if ( is_admin_bar_showing() && current_user_can( 'manage_options' ) ) {
62
- add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_style' ) ) ;
63
- add_action( 'admin_bar_menu', array( $this, 'frontend_shortcut' ), 95 ) ;
64
  }
65
 
66
  /**
@@ -68,7 +65,7 @@ class GUI extends Base
68
  * @since 1.8.2
69
  */
70
  if ( Conf::val( Base::O_UTIL_INSTANT_CLICK ) ) {
71
- add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_style_public' ) ) ;
72
  }
73
  }
74
 
@@ -77,8 +74,7 @@ class GUI extends Base
77
  *
78
  * @since 3.0
79
  */
80
- public function lscache_stats()
81
- {
82
  return false;
83
 
84
  $stat_titles = array(
@@ -104,12 +100,11 @@ class GUI extends Base
104
  *
105
  * @since 1.6.6
106
  */
107
- public static function pie( $percent, $width = 50, $finished_tick = false, $without_percentage = false, $append_cls = false )
108
- {
109
- $percentage = '<text x="50%" y="50%">' . $percent . ( $without_percentage ? '' : '%' ) . '</text>' ;
110
 
111
  if ( $percent == 100 && $finished_tick ) {
112
- $percentage = '<text x="50%" y="50%" class="litespeed-pie-done">&#x2713</text>' ;
113
  }
114
 
115
  return "
@@ -126,8 +121,7 @@ class GUI extends Base
126
  *
127
  * @since 3.0
128
  */
129
- public static function pie_tiny( $percent, $width = 50, $tooltip = '', $tooltip_pos = 'up', $append_cls = false )
130
- {
131
 
132
  // formula C = 2πR
133
  $dasharray = 2 * 3.1416 * 9 * ( $percent / 100 );
@@ -154,17 +148,16 @@ class GUI extends Base
154
  * @since 2.9
155
  * @access public
156
  */
157
- public function get_cls_of_pagescore( $score )
158
- {
159
  if ( $score >= 90 ) {
160
- return 'success' ;
161
  }
162
 
163
  if ( $score >= 50 ) {
164
- return 'warning' ;
165
  }
166
 
167
- return 'danger' ;
168
  }
169
 
170
  /**
@@ -173,59 +166,58 @@ class GUI extends Base
173
  * @since 1.0
174
  * @access public
175
  */
176
- public static function dismiss()
177
- {
178
- $_instance = self::get_instance() ;
179
  switch ( Router::verify_type() ) {
180
  case self::TYPE_DISMISS_WHM :
181
- self::dismiss_whm() ;
182
- break ;
183
 
184
  case self::TYPE_DISMISS_EXPIRESDEFAULT :
185
- self::update_option( Admin_Display::DB_DISMISS_MSG, Admin_Display::RULECONFLICT_DISMISSED ) ;
186
- break ;
187
 
188
  case self::TYPE_DISMISS_PROMO :
189
  if ( empty( $_GET[ 'promo_tag' ] ) ) {
190
- break ;
191
  }
192
 
193
- $promo_tag = $_GET[ 'promo_tag' ] ;
194
 
195
  if ( empty( $_instance->_promo_list[ $promo_tag ] ) ) {
196
- break ;
197
  }
198
 
199
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[GUI] Dismiss promo ' . $promo_tag ) ;
200
 
201
  // Forever dismiss
202
  if ( ! empty( $_GET[ 'done' ] ) ) {
203
- $_instance->_summary[ $promo_tag ] = 'done' ;
204
  }
205
  elseif ( ! empty( $_GET[ 'later' ] ) ) {
206
  // Delay the banner to half year later
207
- $_instance->_summary[ $promo_tag ] = time() + 86400 * 180 ;
208
  }
209
  else {
210
  // Update welcome banner to 30 days after
211
- $_instance->_summary[ $promo_tag ] = time() + 86400 * 30 ;
212
  }
213
 
214
- self::save_summary() ;
215
 
216
- break ;
217
 
218
  default:
219
- break ;
220
  }
221
 
222
  if ( Router::is_ajax() ) {
223
  // All dismiss actions are considered as ajax call, so just exit
224
- exit( json_encode( array( 'success' => 1 ) ) ) ;
225
  }
226
 
227
  // Plain click link, redirect to referral url
228
- Admin::redirect() ;
229
  }
230
 
231
  /**
@@ -235,9 +227,8 @@ class GUI extends Base
235
  * @access public
236
  * @return boolean
237
  */
238
- public static function has_msg_ruleconflict()
239
- {
240
- return self::get_option( Admin_Display::DB_DISMISS_MSG ) == Admin_Display::RULECONFLICT_ON ;
241
  }
242
 
243
  /**
@@ -247,9 +238,8 @@ class GUI extends Base
247
  * @access public
248
  * @return boolean
249
  */
250
- public static function has_whm_msg()
251
- {
252
- return self::get_option( self::WHM_MSG ) == self::WHM_MSG_VAL ;
253
  }
254
 
255
  /**
@@ -258,9 +248,8 @@ class GUI extends Base
258
  * @since 1.1.1
259
  * @access public
260
  */
261
- public static function dismiss_whm()
262
- {
263
- self::delete_option( self::WHM_MSG ) ;
264
  }
265
 
266
  /**
@@ -268,8 +257,7 @@ class GUI extends Base
268
  *
269
  * @since 2.9
270
  */
271
- private function _is_litespeed_page()
272
- {
273
  if ( ! empty( $_GET[ 'page' ] ) && in_array( $_GET[ 'page' ],
274
  array(
275
  'litespeed-settings',
@@ -281,10 +269,10 @@ class GUI extends Base
281
  'litespeed-report',
282
  ) )
283
  ) {
284
- return true ;
285
  }
286
 
287
- return false ;
288
  }
289
 
290
  /**
@@ -366,9 +354,8 @@ class GUI extends Base
366
  * @since 1.8.2
367
  * @access public
368
  */
369
- public function frontend_enqueue_style_public()
370
- {
371
- wp_enqueue_script( Core::PLUGIN_NAME, LSWCP_PLUGIN_URL . 'assets/js/instant_click.min.js', array(), Core::VER, true ) ;
372
  }
373
 
374
  /**
@@ -377,9 +364,8 @@ class GUI extends Base
377
  * @since 1.3
378
  * @access public
379
  */
380
- public function frontend_enqueue_style()
381
- {
382
- wp_enqueue_style( Core::PLUGIN_NAME, LSWCP_PLUGIN_URL . 'assets/css/litespeed.css', array(), Core::VER, 'all' ) ;
383
  }
384
 
385
  /**
@@ -389,14 +375,14 @@ class GUI extends Base
389
  * @access public
390
  */
391
  public function frontend_shortcut() {
392
- global $wp_admin_bar ;
393
 
394
  $wp_admin_bar->add_menu( array(
395
  'id' => 'litespeed-menu',
396
  'title' => '<span class="ab-icon"></span>',
397
  'href' => get_admin_url( null, 'admin.php?page=litespeed' ),
398
  'meta' => array( 'tabindex' => 0, 'class' => 'litespeed-top-toolbar' ),
399
- ) ) ;
400
 
401
  $wp_admin_bar->add_menu( array(
402
  'parent' => 'litespeed-menu',
@@ -417,7 +403,7 @@ class GUI extends Base
417
  $append_arr = array(
418
  Conf::TYPE_SET . '[' . Base::O_CACHE_FORCE_URI . '][]' => $_SERVER[ 'REQUEST_URI' ] . '$',
419
  'redirect' => $_SERVER[ 'REQUEST_URI' ],
420
- ) ;
421
  $wp_admin_bar->add_menu( array(
422
  'parent' => 'litespeed-single-action',
423
  'id' => 'litespeed-single-forced_cache',
@@ -428,7 +414,7 @@ class GUI extends Base
428
  $append_arr = array(
429
  Conf::TYPE_SET . '[' . Base::O_CACHE_EXC . '][]' => $_SERVER[ 'REQUEST_URI' ] . '$',
430
  'redirect' => $_SERVER[ 'REQUEST_URI' ],
431
- ) ;
432
  $wp_admin_bar->add_menu( array(
433
  'parent' => 'litespeed-single-action',
434
  'id' => 'litespeed-single-noncache',
@@ -439,7 +425,7 @@ class GUI extends Base
439
  $append_arr = array(
440
  Conf::TYPE_SET . '[' . Base::O_CACHE_PRIV_URI . '][]' => $_SERVER[ 'REQUEST_URI' ] . '$',
441
  'redirect' => $_SERVER[ 'REQUEST_URI' ],
442
- ) ;
443
  $wp_admin_bar->add_menu( array(
444
  'parent' => 'litespeed-single-action',
445
  'id' => 'litespeed-single-private',
@@ -450,7 +436,7 @@ class GUI extends Base
450
  $append_arr = array(
451
  Conf::TYPE_SET . '[' . Base::O_OPTM_EXC . '][]' => $_SERVER[ 'REQUEST_URI' ] . '$',
452
  'redirect' => $_SERVER[ 'REQUEST_URI' ],
453
- ) ;
454
  $wp_admin_bar->add_menu( array(
455
  'parent' => 'litespeed-single-action',
456
  'id' => 'litespeed-single-nonoptimize',
@@ -563,7 +549,7 @@ class GUI extends Base
563
  * @since 1.7.2 Moved from admin_display.cls to gui.cls; Renamed from `add_quick_purge` to `backend_shortcut`
564
  */
565
  public function backend_shortcut() {
566
- global $wp_admin_bar ;
567
 
568
  // if ( defined( 'LITESPEED_ON' ) ) {
569
  $wp_admin_bar->add_menu( array(
@@ -571,14 +557,14 @@ class GUI extends Base
571
  'title' => '<span class="ab-icon" title="' . __( 'LiteSpeed Cache Purge All', 'litespeed-cache' ) . ' - ' . __( 'LSCache', 'litespeed-cache' ) . '"></span>',
572
  'href' => Utility::build_url( Router::ACTION_PURGE, Purge::TYPE_PURGE_ALL_LSCACHE ),
573
  'meta' => array( 'tabindex' => 0, 'class' => 'litespeed-top-toolbar' ),
574
- ) ) ;
575
  // }
576
  // else {
577
  // $wp_admin_bar->add_menu( array(
578
  // 'id' => 'litespeed-menu',
579
  // 'title' => '<span class="ab-icon" title="' . __( 'LiteSpeed Cache', 'litespeed-cache' ) . '"></span>',
580
  // 'meta' => array( 'tabindex' => 0, 'class' => 'litespeed-top-toolbar' ),
581
- // ) ) ;
582
  // }
583
 
584
  $wp_admin_bar->add_menu( array(
@@ -710,14 +696,13 @@ class GUI extends Base
710
  * @since 2.4.2
711
  * @access public
712
  */
713
- public static function img_optm_clean_up( $unfinished_num )
714
- {
715
  return sprintf(
716
  '<a href="%1$s" class="button litespeed-btn-warning" data-balloon-pos="up" aria-label="%2$s"><span class="dashicons dashicons-editor-removeformatting"></span>&nbsp;%3$s</a>',
717
  Utility::build_url( Router::ACTION_IMG_OPTM, Img_Optm::TYPE_CLEAN ),
718
  __( 'Remove all previous unfinished image optimization requests.', 'litespeed-cache' ),
719
  __( 'Clean Up Unfinished Data', 'litespeed-cache' ) . ( $unfinished_num ? ': ' . Admin_Display::print_plural( $unfinished_num, 'image' ) : '')
720
- ) ;
721
  }
722
 
723
  /**
@@ -726,9 +711,8 @@ class GUI extends Base
726
  * @since 2.4.2
727
  * @access public
728
  */
729
- public static function plugin_install_link( $title, $name, $v )
730
- {
731
- $url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $name ), 'install-plugin_' . $name ) ;
732
 
733
  $action = sprintf(
734
  '<a href="%1$s" class="install-now" data-slug="%2$s" data-name="%3$s" aria-label="%4$s">%5$s</a>',
@@ -739,9 +723,9 @@ class GUI extends Base
739
  __( 'Install Now' )
740
  );
741
 
742
- return $action ;
743
 
744
- // $msg .= " <a href='$upgrade_link' class='litespeed-btn-success' target='_blank'>" . __( 'Click here to upgrade', 'litespeed-cache' ) . '</a>' ;
745
 
746
  }
747
 
@@ -751,10 +735,9 @@ class GUI extends Base
751
  * @since 2.4.2
752
  * @access public
753
  */
754
- public static function plugin_upgrade_link( $title, $name, $v )
755
- {
756
  $details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $name . '&section=changelog&TB_iframe=true&width=600&height=800' );
757
- $file = $name . '/' . $name . '.php' ;
758
 
759
  $msg = sprintf( __( '<a href="%1$s" %2$s>View version %3$s details</a> or <a href="%4$s" %5$s target="_blank">update now</a>.' ),
760
  esc_url( $details_url ),
@@ -768,7 +751,7 @@ class GUI extends Base
768
  )
769
  );
770
 
771
- return $msg ;
772
  }
773
 
774
  /**
@@ -777,10 +760,9 @@ class GUI extends Base
777
  * @since 1.6
778
  * @access public
779
  */
780
- public static function finalize( $buffer )
781
- {
782
- $instance = self::get_instance() ;
783
- return $instance->_clean_wrapper( $buffer ) ;
784
  }
785
 
786
  /**
@@ -790,39 +772,38 @@ class GUI extends Base
790
  * @since 1.6 converted to private with adding prefix _
791
  * @access private
792
  */
793
- private function _clean_wrapper( $buffer )
794
- {
795
  if ( self::$_clean_counter < 1 ) {
796
- Debug2::debug2( "GUI bypassed by no counter" ) ;
797
- return $buffer ;
798
  }
799
 
800
- Debug2::debug2( "GUI start cleaning counter " . self::$_clean_counter ) ;
801
 
802
- for ( $i = 1 ; $i <= self::$_clean_counter ; $i ++ ) {
803
  // If miss beginning
804
- $start = strpos( $buffer, self::clean_wrapper_begin( $i ) ) ;
805
  if ( $start === false ) {
806
- $buffer = str_replace( self::clean_wrapper_end( $i ), '', $buffer ) ;
807
- Debug2::debug2( "GUI lost beginning wrapper $i" ) ;
808
  continue;
809
  }
810
 
811
  // If miss end
812
- $end_wrapper = self::clean_wrapper_end( $i ) ;
813
- $end = strpos( $buffer, $end_wrapper ) ;
814
  if ( $end === false ) {
815
- $buffer = str_replace( self::clean_wrapper_begin( $i ), '', $buffer ) ;
816
- Debug2::debug2( "GUI lost ending wrapper $i" ) ;
817
  continue;
818
  }
819
 
820
  // Now replace wrapped content
821
- $buffer = substr_replace( $buffer, '', $start, $end - $start + strlen( $end_wrapper ) ) ;
822
- Debug2::debug2( "GUI cleaned wrapper $i" ) ;
823
  }
824
 
825
- return $buffer ;
826
  }
827
 
828
  /**
@@ -831,14 +812,13 @@ class GUI extends Base
831
  * @since 1.4
832
  * @access public
833
  */
834
- public static function clean_wrapper_begin( $counter = false )
835
- {
836
  if ( $counter === false ) {
837
- self::$_clean_counter ++ ;
838
- $counter = self::$_clean_counter ;
839
- Debug2::debug( "GUI clean wrapper $counter begin" ) ;
840
  }
841
- return '<!-- LiteSpeed To Be Removed begin ' . $counter . ' -->' ;
842
  }
843
 
844
  /**
@@ -847,13 +827,12 @@ class GUI extends Base
847
  * @since 1.4
848
  * @access public
849
  */
850
- public static function clean_wrapper_end( $counter = false )
851
- {
852
  if ( $counter === false ) {
853
- $counter = self::$_clean_counter ;
854
- Debug2::debug( "GUI clean wrapper $counter end" ) ;
855
  }
856
- return '<!-- LiteSpeed To Be Removed end ' . $counter . ' -->' ;
857
  }
858
 
859
  }
9
  namespace LiteSpeed;
10
  defined( 'WPINC' ) || exit;
11
 
12
+ class GUI extends Base {
13
+ protected static $_instance;
 
14
 
15
+ private static $_clean_counter = 0;
16
 
17
+ private $_promo_true;
18
 
19
  // [ file_tag => [ days, litespeed_only ], ... ]
20
  private $_promo_list = array(
21
  'new_version' => array( 1, false ),
22
  'score' => array( 5, false ),
23
  // 'slack' => array( 3, false ),
24
+ );
25
 
26
 
27
+ const TYPE_DISMISS_WHM = 'whm';
28
+ const TYPE_DISMISS_EXPIRESDEFAULT = 'ExpiresDefault';
29
+ const TYPE_DISMISS_PROMO = 'promo';
30
 
31
+ const WHM_MSG = 'lscwp_whm_install';
32
+ const WHM_MSG_VAL = 'whm_install';
33
 
34
  protected $_summary;
35
 
39
  * @since 1.3
40
  * @access protected
41
  */
42
+ protected function __construct() {
 
43
  $this->_summary = self::get_summary();
44
 
45
  }
49
  *
50
  * @since 3.0
51
  */
52
+ public function frontend_init() {
 
53
  if ( is_admin() ) {
54
  return;
55
  }
56
 
57
+ Debug2::debug2( '[GUI] init' );
58
  if ( is_admin_bar_showing() && current_user_can( 'manage_options' ) ) {
59
+ add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_style' ) );
60
+ add_action( 'admin_bar_menu', array( $this, 'frontend_shortcut' ), 95 );
61
  }
62
 
63
  /**
65
  * @since 1.8.2
66
  */
67
  if ( Conf::val( Base::O_UTIL_INSTANT_CLICK ) ) {
68
+ add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_style_public' ) );
69
  }
70
  }
71
 
74
  *
75
  * @since 3.0
76
  */
77
+ public function lscache_stats() {
 
78
  return false;
79
 
80
  $stat_titles = array(
100
  *
101
  * @since 1.6.6
102
  */
103
+ public static function pie( $percent, $width = 50, $finished_tick = false, $without_percentage = false, $append_cls = false ) {
104
+ $percentage = '<text x="50%" y="50%">' . $percent . ( $without_percentage ? '' : '%' ) . '</text>';
 
105
 
106
  if ( $percent == 100 && $finished_tick ) {
107
+ $percentage = '<text x="50%" y="50%" class="litespeed-pie-done">&#x2713</text>';
108
  }
109
 
110
  return "
121
  *
122
  * @since 3.0
123
  */
124
+ public static function pie_tiny( $percent, $width = 50, $tooltip = '', $tooltip_pos = 'up', $append_cls = false ) {
 
125
 
126
  // formula C = 2πR
127
  $dasharray = 2 * 3.1416 * 9 * ( $percent / 100 );
148
  * @since 2.9
149
  * @access public
150
  */
151
+ public function get_cls_of_pagescore( $score ) {
 
152
  if ( $score >= 90 ) {
153
+ return 'success';
154
  }
155
 
156
  if ( $score >= 50 ) {
157
+ return 'warning';
158
  }
159
 
160
+ return 'danger';
161
  }
162
 
163
  /**
166
  * @since 1.0
167
  * @access public
168
  */
169
+ public static function dismiss() {
170
+ $_instance = self::get_instance();
 
171
  switch ( Router::verify_type() ) {
172
  case self::TYPE_DISMISS_WHM :
173
+ self::dismiss_whm();
174
+ break;
175
 
176
  case self::TYPE_DISMISS_EXPIRESDEFAULT :
177
+ self::update_option( Admin_Display::DB_DISMISS_MSG, Admin_Display::RULECONFLICT_DISMISSED );
178
+ break;
179
 
180
  case self::TYPE_DISMISS_PROMO :
181
  if ( empty( $_GET[ 'promo_tag' ] ) ) {
182
+ break;
183
  }
184
 
185
+ $promo_tag = $_GET[ 'promo_tag' ];
186
 
187
  if ( empty( $_instance->_promo_list[ $promo_tag ] ) ) {
188
+ break;
189
  }
190
 
191
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[GUI] Dismiss promo ' . $promo_tag );
192
 
193
  // Forever dismiss
194
  if ( ! empty( $_GET[ 'done' ] ) ) {
195
+ $_instance->_summary[ $promo_tag ] = 'done';
196
  }
197
  elseif ( ! empty( $_GET[ 'later' ] ) ) {
198
  // Delay the banner to half year later
199
+ $_instance->_summary[ $promo_tag ] = time() + 86400 * 180;
200
  }
201
  else {
202
  // Update welcome banner to 30 days after
203
+ $_instance->_summary[ $promo_tag ] = time() + 86400 * 30;
204
  }
205
 
206
+ self::save_summary();
207
 
208
+ break;
209
 
210
  default:
211
+ break;
212
  }
213
 
214
  if ( Router::is_ajax() ) {
215
  // All dismiss actions are considered as ajax call, so just exit
216
+ exit( json_encode( array( 'success' => 1 ) ) );
217
  }
218
 
219
  // Plain click link, redirect to referral url
220
+ Admin::redirect();
221
  }
222
 
223
  /**
227
  * @access public
228
  * @return boolean
229
  */
230
+ public static function has_msg_ruleconflict() {
231
+ return self::get_option( Admin_Display::DB_DISMISS_MSG ) == Admin_Display::RULECONFLICT_ON;
 
232
  }
233
 
234
  /**
238
  * @access public
239
  * @return boolean
240
  */
241
+ public static function has_whm_msg() {
242
+ return self::get_option( self::WHM_MSG ) == self::WHM_MSG_VAL;
 
243
  }
244
 
245
  /**
248
  * @since 1.1.1
249
  * @access public
250
  */
251
+ public static function dismiss_whm() {
252
+ self::delete_option( self::WHM_MSG );
 
253
  }
254
 
255
  /**
257
  *
258
  * @since 2.9
259
  */
260
+ private function _is_litespeed_page() {
 
261
  if ( ! empty( $_GET[ 'page' ] ) && in_array( $_GET[ 'page' ],
262
  array(
263
  'litespeed-settings',
269
  'litespeed-report',
270
  ) )
271
  ) {
272
+ return true;
273
  }
274
 
275
+ return false;
276
  }
277
 
278
  /**
354
  * @since 1.8.2
355
  * @access public
356
  */
357
+ public function frontend_enqueue_style_public() {
358
+ wp_enqueue_script( Core::PLUGIN_NAME, LSWCP_PLUGIN_URL . 'assets/js/instant_click.min.js', array(), Core::VER, true );
 
359
  }
360
 
361
  /**
364
  * @since 1.3
365
  * @access public
366
  */
367
+ public function frontend_enqueue_style() {
368
+ wp_enqueue_style( Core::PLUGIN_NAME, LSWCP_PLUGIN_URL . 'assets/css/litespeed.css', array(), Core::VER, 'all' );
 
369
  }
370
 
371
  /**
375
  * @access public
376
  */
377
  public function frontend_shortcut() {
378
+ global $wp_admin_bar;
379
 
380
  $wp_admin_bar->add_menu( array(
381
  'id' => 'litespeed-menu',
382
  'title' => '<span class="ab-icon"></span>',
383
  'href' => get_admin_url( null, 'admin.php?page=litespeed' ),
384
  'meta' => array( 'tabindex' => 0, 'class' => 'litespeed-top-toolbar' ),
385
+ ) );
386
 
387
  $wp_admin_bar->add_menu( array(
388
  'parent' => 'litespeed-menu',
403
  $append_arr = array(
404
  Conf::TYPE_SET . '[' . Base::O_CACHE_FORCE_URI . '][]' => $_SERVER[ 'REQUEST_URI' ] . '$',
405
  'redirect' => $_SERVER[ 'REQUEST_URI' ],
406
+ );
407
  $wp_admin_bar->add_menu( array(
408
  'parent' => 'litespeed-single-action',
409
  'id' => 'litespeed-single-forced_cache',
414
  $append_arr = array(
415
  Conf::TYPE_SET . '[' . Base::O_CACHE_EXC . '][]' => $_SERVER[ 'REQUEST_URI' ] . '$',
416
  'redirect' => $_SERVER[ 'REQUEST_URI' ],
417
+ );
418
  $wp_admin_bar->add_menu( array(
419
  'parent' => 'litespeed-single-action',
420
  'id' => 'litespeed-single-noncache',
425
  $append_arr = array(
426
  Conf::TYPE_SET . '[' . Base::O_CACHE_PRIV_URI . '][]' => $_SERVER[ 'REQUEST_URI' ] . '$',
427
  'redirect' => $_SERVER[ 'REQUEST_URI' ],
428
+ );
429
  $wp_admin_bar->add_menu( array(
430
  'parent' => 'litespeed-single-action',
431
  'id' => 'litespeed-single-private',
436
  $append_arr = array(
437
  Conf::TYPE_SET . '[' . Base::O_OPTM_EXC . '][]' => $_SERVER[ 'REQUEST_URI' ] . '$',
438
  'redirect' => $_SERVER[ 'REQUEST_URI' ],
439
+ );
440
  $wp_admin_bar->add_menu( array(
441
  'parent' => 'litespeed-single-action',
442
  'id' => 'litespeed-single-nonoptimize',
549
  * @since 1.7.2 Moved from admin_display.cls to gui.cls; Renamed from `add_quick_purge` to `backend_shortcut`
550
  */
551
  public function backend_shortcut() {
552
+ global $wp_admin_bar;
553
 
554
  // if ( defined( 'LITESPEED_ON' ) ) {
555
  $wp_admin_bar->add_menu( array(
557
  'title' => '<span class="ab-icon" title="' . __( 'LiteSpeed Cache Purge All', 'litespeed-cache' ) . ' - ' . __( 'LSCache', 'litespeed-cache' ) . '"></span>',
558
  'href' => Utility::build_url( Router::ACTION_PURGE, Purge::TYPE_PURGE_ALL_LSCACHE ),
559
  'meta' => array( 'tabindex' => 0, 'class' => 'litespeed-top-toolbar' ),
560
+ ) );
561
  // }
562
  // else {
563
  // $wp_admin_bar->add_menu( array(
564
  // 'id' => 'litespeed-menu',
565
  // 'title' => '<span class="ab-icon" title="' . __( 'LiteSpeed Cache', 'litespeed-cache' ) . '"></span>',
566
  // 'meta' => array( 'tabindex' => 0, 'class' => 'litespeed-top-toolbar' ),
567
+ // ) );
568
  // }
569
 
570
  $wp_admin_bar->add_menu( array(
696
  * @since 2.4.2
697
  * @access public
698
  */
699
+ public static function img_optm_clean_up( $unfinished_num ) {
 
700
  return sprintf(
701
  '<a href="%1$s" class="button litespeed-btn-warning" data-balloon-pos="up" aria-label="%2$s"><span class="dashicons dashicons-editor-removeformatting"></span>&nbsp;%3$s</a>',
702
  Utility::build_url( Router::ACTION_IMG_OPTM, Img_Optm::TYPE_CLEAN ),
703
  __( 'Remove all previous unfinished image optimization requests.', 'litespeed-cache' ),
704
  __( 'Clean Up Unfinished Data', 'litespeed-cache' ) . ( $unfinished_num ? ': ' . Admin_Display::print_plural( $unfinished_num, 'image' ) : '')
705
+ );
706
  }
707
 
708
  /**
711
  * @since 2.4.2
712
  * @access public
713
  */
714
+ public static function plugin_install_link( $title, $name, $v ) {
715
+ $url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $name ), 'install-plugin_' . $name );
 
716
 
717
  $action = sprintf(
718
  '<a href="%1$s" class="install-now" data-slug="%2$s" data-name="%3$s" aria-label="%4$s">%5$s</a>',
723
  __( 'Install Now' )
724
  );
725
 
726
+ return $action;
727
 
728
+ // $msg .= " <a href='$upgrade_link' class='litespeed-btn-success' target='_blank'>" . __( 'Click here to upgrade', 'litespeed-cache' ) . '</a>';
729
 
730
  }
731
 
735
  * @since 2.4.2
736
  * @access public
737
  */
738
+ public static function plugin_upgrade_link( $title, $name, $v ) {
 
739
  $details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $name . '&section=changelog&TB_iframe=true&width=600&height=800' );
740
+ $file = $name . '/' . $name . '.php';
741
 
742
  $msg = sprintf( __( '<a href="%1$s" %2$s>View version %3$s details</a> or <a href="%4$s" %5$s target="_blank">update now</a>.' ),
743
  esc_url( $details_url ),
751
  )
752
  );
753
 
754
+ return $msg;
755
  }
756
 
757
  /**
760
  * @since 1.6
761
  * @access public
762
  */
763
+ public static function finalize( $buffer ) {
764
+ $instance = self::get_instance();
765
+ return $instance->_clean_wrapper( $buffer );
 
766
  }
767
 
768
  /**
772
  * @since 1.6 converted to private with adding prefix _
773
  * @access private
774
  */
775
+ private function _clean_wrapper( $buffer ) {
 
776
  if ( self::$_clean_counter < 1 ) {
777
+ Debug2::debug2( "GUI bypassed by no counter" );
778
+ return $buffer;
779
  }
780
 
781
+ Debug2::debug2( "GUI start cleaning counter " . self::$_clean_counter );
782
 
783
+ for ( $i = 1; $i <= self::$_clean_counter; $i ++ ) {
784
  // If miss beginning
785
+ $start = strpos( $buffer, self::clean_wrapper_begin( $i ) );
786
  if ( $start === false ) {
787
+ $buffer = str_replace( self::clean_wrapper_end( $i ), '', $buffer );
788
+ Debug2::debug2( "GUI lost beginning wrapper $i" );
789
  continue;
790
  }
791
 
792
  // If miss end
793
+ $end_wrapper = self::clean_wrapper_end( $i );
794
+ $end = strpos( $buffer, $end_wrapper );
795
  if ( $end === false ) {
796
+ $buffer = str_replace( self::clean_wrapper_begin( $i ), '', $buffer );
797
+ Debug2::debug2( "GUI lost ending wrapper $i" );
798
  continue;
799
  }
800
 
801
  // Now replace wrapped content
802
+ $buffer = substr_replace( $buffer, '', $start, $end - $start + strlen( $end_wrapper ) );
803
+ Debug2::debug2( "GUI cleaned wrapper $i" );
804
  }
805
 
806
+ return $buffer;
807
  }
808
 
809
  /**
812
  * @since 1.4
813
  * @access public
814
  */
815
+ public static function clean_wrapper_begin( $counter = false ) {
 
816
  if ( $counter === false ) {
817
+ self::$_clean_counter ++;
818
+ $counter = self::$_clean_counter;
819
+ Debug2::debug( "GUI clean wrapper $counter begin" );
820
  }
821
+ return '<!-- LiteSpeed To Be Removed begin ' . $counter . ' -->';
822
  }
823
 
824
  /**
827
  * @since 1.4
828
  * @access public
829
  */
830
+ public static function clean_wrapper_end( $counter = false ) {
 
831
  if ( $counter === false ) {
832
+ $counter = self::$_clean_counter;
833
+ Debug2::debug( "GUI clean wrapper $counter end" );
834
  }
835
+ return '<!-- LiteSpeed To Be Removed end ' . $counter . ' -->';
836
  }
837
 
838
  }
src/lang.cls.php CHANGED
@@ -157,6 +157,7 @@ class Lang extends Base
157
  self::O_MEDIA_IFRAME_LAZY_CLS_EXC => __( 'Lazy Load Iframe Class Name Excludes', 'litespeed-cache' ),
158
  self::O_MEDIA_IFRAME_LAZY_PARENT_CLS_EXC => __( 'Lazy Load Iframe Parent Class Name Excludes', 'litespeed-cache' ),
159
  self::O_MEDIA_LAZY_URI_EXC => __( 'Lazy Load URI Excludes', 'litespeed-cache' ),
 
160
  self::O_MEDIA_LAZY_PLACEHOLDER => __( 'Basic Image Placeholder', 'litespeed-cache' ),
161
  self::O_MEDIA_PLACEHOLDER_RESP => __( 'Responsive Placeholder', 'litespeed-cache' ),
162
  self::O_MEDIA_PLACEHOLDER_RESP_COLOR => __( 'Responsive Placeholder Color', 'litespeed-cache' ),
157
  self::O_MEDIA_IFRAME_LAZY_CLS_EXC => __( 'Lazy Load Iframe Class Name Excludes', 'litespeed-cache' ),
158
  self::O_MEDIA_IFRAME_LAZY_PARENT_CLS_EXC => __( 'Lazy Load Iframe Parent Class Name Excludes', 'litespeed-cache' ),
159
  self::O_MEDIA_LAZY_URI_EXC => __( 'Lazy Load URI Excludes', 'litespeed-cache' ),
160
+ self::O_MEDIA_LQIP_EXC => __( 'LQIP Excludes', 'litespeed-cache' ),
161
  self::O_MEDIA_LAZY_PLACEHOLDER => __( 'Basic Image Placeholder', 'litespeed-cache' ),
162
  self::O_MEDIA_PLACEHOLDER_RESP => __( 'Responsive Placeholder', 'litespeed-cache' ),
163
  self::O_MEDIA_PLACEHOLDER_RESP_COLOR => __( 'Responsive Placeholder Color', 'litespeed-cache' ),
src/object-cache.cls.php CHANGED
@@ -7,32 +7,31 @@
7
  * @subpackage LiteSpeed/inc
8
  * @author LiteSpeed Technologies <info@litespeedtech.com>
9
  */
10
- namespace LiteSpeed ;
11
 
12
- defined( 'WPINC' ) || exit ;
13
 
14
- class Object_Cache
15
- {
16
- protected static $_instance ;
17
 
18
- private $_oc_data_file ;
19
- private $_conn ;
20
- private $_cfg_enabled ;
21
- private $_cfg_method ;
22
- private $_cfg_host ;
23
- private $_cfg_port ;
24
- private $_cfg_persistent ;
25
- private $_cfg_admin ;
26
- private $_cfg_transients ;
27
- private $_cfg_db ;
28
- private $_cfg_user ;
29
- private $_cfg_pswd ;
30
- private $_default_life = 360 ;
31
 
32
- private $_oc_driver = 'Memcached' ; // Redis or Memcached
33
 
34
- private $_global_groups ;
35
- private $_non_persistent_groups ;
36
 
37
  /**
38
  * Init
@@ -42,80 +41,79 @@ class Object_Cache
42
  * @since 1.8
43
  * @access protected
44
  */
45
- protected function __construct( $cfg = false )
46
- {
47
- defined( 'LSCWP_LOG' ) && Debug2::debug2( '[Object] init' ) ;
48
 
49
- $this->_oc_data_file = WP_CONTENT_DIR . '/.object-cache.ini' ;
50
 
51
  if ( $cfg ) {
52
  if ( ! is_array( $cfg[ Base::O_OBJECT_GLOBAL_GROUPS ] ) ) {
53
- $cfg[ Base::O_OBJECT_GLOBAL_GROUPS ] = explode( "\n", $cfg[ Base::O_OBJECT_GLOBAL_GROUPS ] ) ;
54
  }
55
  if ( ! is_array( $cfg[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ] ) ) {
56
- $cfg[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ] = explode( "\n", $cfg[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ] ) ;
57
  }
58
- $this->_cfg_method = $cfg[ Base::O_OBJECT_KIND ] ? true : false ;
59
- $this->_cfg_host = $cfg[ Base::O_OBJECT_HOST ] ;
60
- $this->_cfg_port = $cfg[ Base::O_OBJECT_PORT ] ;
61
- $this->_cfg_life = $cfg[ Base::O_OBJECT_LIFE ] ;
62
- $this->_cfg_persistent = $cfg[ Base::O_OBJECT_PERSISTENT ] ;
63
- $this->_cfg_admin = $cfg[ Base::O_OBJECT_ADMIN ] ;
64
- $this->_cfg_transients = $cfg[ Base::O_OBJECT_TRANSIENTS ] ;
65
- $this->_cfg_db = $cfg[ Base::O_OBJECT_DB_ID ] ;
66
- $this->_cfg_user = $cfg[ Base::O_OBJECT_USER ] ;
67
- $this->_cfg_pswd = $cfg[ Base::O_OBJECT_PSWD ] ;
68
- $this->_global_groups = $cfg[ Base::O_OBJECT_GLOBAL_GROUPS ] ;
69
- $this->_non_persistent_groups = $cfg[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ] ;
70
 
71
  if ( $this->_cfg_method ) {
72
- $this->_oc_driver = 'Redis' ;
73
  }
74
- $this->_cfg_enabled = $cfg[ Base::O_OBJECT ] && class_exists( $this->_oc_driver ) && $this->_cfg_host ;
75
 
76
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] init with cfg result : ', $this->_cfg_enabled ) ;
77
  }
78
  elseif ( class_exists( __NAMESPACE__ . '\Core' ) ) {
79
- $this->_cfg_method = Conf::val( Base::O_OBJECT_KIND ) ? true : false ;
80
- $this->_cfg_host = Conf::val( Base::O_OBJECT_HOST ) ;
81
- $this->_cfg_port = Conf::val( Base::O_OBJECT_PORT ) ;
82
- $this->_cfg_life = Conf::val( Base::O_OBJECT_LIFE ) ;
83
- $this->_cfg_persistent = Conf::val( Base::O_OBJECT_PERSISTENT ) ;
84
- $this->_cfg_admin = Conf::val( Base::O_OBJECT_ADMIN ) ;
85
- $this->_cfg_transients = Conf::val( Base::O_OBJECT_TRANSIENTS ) ;
86
- $this->_cfg_db = Conf::val( Base::O_OBJECT_DB_ID ) ;
87
- $this->_cfg_user = Conf::val( Base::O_OBJECT_USER ) ;
88
- $this->_cfg_pswd = Conf::val( Base::O_OBJECT_PSWD ) ;
89
- $this->_global_groups = Conf::val( Base::O_OBJECT_GLOBAL_GROUPS ) ;
90
- $this->_non_persistent_groups = Conf::val( Base::O_OBJECT_NON_PERSISTENT_GROUPS ) ;
91
 
92
  if ( $this->_cfg_method ) {
93
- $this->_oc_driver = 'Redis' ;
94
  }
95
- $this->_cfg_enabled = Conf::val( Base::O_OBJECT ) && class_exists( $this->_oc_driver ) && $this->_cfg_host ;
96
  }
97
  elseif ( file_exists( $this->_oc_data_file ) ) { // Get cfg from oc_data_file
98
- $cfg = parse_ini_file( $this->_oc_data_file, true ) ;
99
- $this->_cfg_method = ! empty( $cfg[ 'object_cache' ][ 'method' ] ) ? $cfg[ 'object_cache' ][ 'method' ] : false ;
100
- $this->_cfg_host = $cfg[ 'object_cache' ][ 'host' ] ;
101
- $this->_cfg_port = $cfg[ 'object_cache' ][ 'port' ] ;
102
- $this->_cfg_life = ! empty( $cfg[ 'object_cache' ][ 'life' ] ) ? $cfg[ 'object_cache' ][ 'life' ] : $this->_default_life ;
103
- $this->_cfg_persistent = ! empty( $cfg[ 'object_cache' ][ 'persistent' ] ) ? $cfg[ 'object_cache' ][ 'persistent' ] : false ;
104
- $this->_cfg_admin = ! empty( $cfg[ 'object_cache' ][ 'cache_admin' ] ) ? $cfg[ 'object_cache' ][ 'cache_admin' ] : false ;
105
- $this->_cfg_transients = ! empty( $cfg[ 'object_cache' ][ 'cache_transients' ] ) ? $cfg[ 'object_cache' ][ 'cache_transients' ] : false ;
106
- $this->_cfg_db = ! empty( $cfg[ 'object_cache' ][ 'db' ] ) ? $cfg[ 'object_cache' ][ 'db' ] : 0 ;
107
- $this->_cfg_user = ! empty( $cfg[ 'object_cache' ][ 'user' ] ) ? $cfg[ 'object_cache' ][ 'user' ] : '' ;
108
- $this->_cfg_pswd = ! empty( $cfg[ 'object_cache' ][ 'pswd' ] ) ? $cfg[ 'object_cache' ][ 'pswd' ] : '' ;
109
- $this->_global_groups = ! empty( $cfg[ 'object_cache' ][ 'global_groups' ] ) ? explode( ',', $cfg[ 'object_cache' ][ 'global_groups' ] ) : array() ;
110
- $this->_non_persistent_groups = ! empty( $cfg[ 'object_cache' ][ 'non_persistent_groups' ] ) ? explode( ',', $cfg[ 'object_cache' ][ 'non_persistent_groups' ] ) : array() ;
111
 
112
  if ( $this->_cfg_method ) {
113
- $this->_oc_driver = 'Redis' ;
114
  }
115
- $this->_cfg_enabled = class_exists( $this->_oc_driver ) && $this->_cfg_host ;
116
  }
117
  else {
118
- $this->_cfg_enabled = false ;
119
  }
120
  }
121
 
@@ -125,9 +123,8 @@ class Object_Cache
125
  * @since 1.8.3
126
  * @access public
127
  */
128
- public function store_transients( $group )
129
- {
130
- return $this->_cfg_transients && $this->_is_transients_group( $group ) ;
131
  }
132
 
133
  /**
@@ -136,9 +133,8 @@ class Object_Cache
136
  * @since 1.8.3
137
  * @access private
138
  */
139
- private function _is_transients_group( $group )
140
- {
141
- return in_array( $group, array( 'transient', 'site-transient' ) ) ;
142
  }
143
 
144
  /**
@@ -147,9 +143,8 @@ class Object_Cache
147
  * @since 1.8
148
  * @access public
149
  */
150
- public function update_file( $options )
151
- {
152
- $changed = false ;
153
 
154
  // Update data file
155
  $data = "[object_cache]"
@@ -167,31 +162,31 @@ class Object_Cache
167
  . "\nnon_persistent_groups = " . implode( ',', $options[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ] )
168
  ;
169
 
170
- $old_data = File::read( $this->_oc_data_file ) ;
171
  if ( $old_data != $data ) {
172
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Settings] Update .object_cache.ini and flush object cache' ) ;
173
- File::save( $this->_oc_data_file, $data ) ;
174
 
175
- $changed = true ;
176
  }
177
 
178
  // NOTE: When included in oc.php, `LSCWP_DIR` will show undefined, so this must be assigned/generated when used
179
- $_oc_ori_file = LSCWP_DIR . 'lib/object-cache.php' ;
180
- $_oc_wp_file = WP_CONTENT_DIR . '/object-cache.php' ;
181
 
182
  // Update cls file
183
  if ( ! file_exists( $_oc_wp_file ) || md5_file( $_oc_wp_file ) !== md5_file( $_oc_ori_file ) ) {
184
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] copying object-cache.php file to ' . $_oc_wp_file ) ;
185
- copy( $_oc_ori_file, $_oc_wp_file ) ;
186
 
187
- $changed = true ;
188
  }
189
 
190
  /**
191
  * Clear object cache
192
  */
193
  if ( $changed ) {
194
- $this->_reconnect( $options ) ;
195
  }
196
  }
197
 
@@ -201,20 +196,19 @@ class Object_Cache
201
  * @since 1.8.2
202
  * @access public
203
  */
204
- public function del_file()
205
- {
206
  // NOTE: When included in oc.php, `LSCWP_DIR` will show undefined, so this must be assigned/generated when used
207
- $_oc_ori_file = LSCWP_DIR . 'lib/object-cache.php' ;
208
- $_oc_wp_file = WP_CONTENT_DIR . '/object-cache.php' ;
209
 
210
  if ( file_exists( $_oc_wp_file ) && md5_file( $_oc_wp_file ) === md5_file( $_oc_ori_file ) ) {
211
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] removing ' . $_oc_wp_file ) ;
212
- unlink( $_oc_wp_file ) ;
213
  }
214
 
215
  if ( file_exists( $this->_oc_data_file ) ) {
216
- Debug2::debug( '[Object] Removing ' . $this->_oc_data_file ) ;
217
- unlink( $this->_oc_data_file ) ;
218
  }
219
  }
220
 
@@ -224,9 +218,8 @@ class Object_Cache
224
  * @since 1.8
225
  * @access public
226
  */
227
- public function test_connection()
228
- {
229
- return $this->_connect() ;
230
  }
231
 
232
  /**
@@ -235,22 +228,21 @@ class Object_Cache
235
  * @since 1.8
236
  * @access private
237
  */
238
- private function _reconnect( $cfg )
239
- {
240
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] Reconnecting' ) ;
241
- // error_log( 'Object: reconnect !' ) ;
242
  if ( isset( $this->_conn ) ) {
243
- // error_log( 'Object: Quiting existing connection!' ) ;
244
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] Quiting existing connection' ) ;
245
- $this->flush() ;
246
- $this->_conn = null ;
247
- self::$_instance = null ;
248
  }
249
 
250
- self::$_instance = new self( $cfg ) ;
251
- self::$_instance->_connect() ;
252
  if ( isset( self::$_instance->_conn ) ) {
253
- self::$_instance->flush() ;
254
  }
255
 
256
  }
@@ -261,20 +253,19 @@ class Object_Cache
261
  * @since 1.8
262
  * @access private
263
  */
264
- private function _connect()
265
- {
266
  if ( isset( $this->_conn ) ) {
267
- // error_log( 'Object: _connected' ) ;
268
- return true ;
269
  }
270
 
271
  if ( ! class_exists( $this->_oc_driver ) || ! $this->_cfg_host ) {
272
- return null ;
273
  }
274
 
275
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] connecting to ' . $this->_cfg_host . ':' . $this->_cfg_port ) ;
276
 
277
- $failed = false ;
278
  /**
279
  * Connect to Redis
280
  *
@@ -282,78 +273,78 @@ class Object_Cache
282
  * @see https://github.com/phpredis/phpredis/#example-1
283
  */
284
  if ( $this->_oc_driver == 'Redis' ) {
285
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] Init ' . $this->_oc_driver . ' connection' ) ;
286
 
287
- set_error_handler( 'litespeed_exception_handler' ) ;
288
  try {
289
- $this->_conn = new \Redis() ;
290
- // error_log( 'Object: _connect Redis' ) ;
291
 
292
  if ( $this->_cfg_persistent ) {
293
  if ( $this->_cfg_port ) {
294
- $this->_conn->pconnect( $this->_cfg_host, $this->_cfg_port ) ;
295
  }
296
  else {
297
- $this->_conn->pconnect( $this->_cfg_host ) ;
298
  }
299
  }
300
  else {
301
  if ( $this->_cfg_port ) {
302
- $this->_conn->connect( $this->_cfg_host, $this->_cfg_port ) ;
303
  }
304
  else {
305
- $this->_conn->connect( $this->_cfg_host ) ;
306
  }
307
  }
308
 
309
  if ( $this->_cfg_pswd ) {
310
- $this->_conn->auth( $this->_cfg_pswd ) ;
311
  }
312
 
313
  if ( $this->_cfg_db ) {
314
- $this->_conn->select( $this->_cfg_db ) ;
315
  }
316
 
317
- $res = $this->_conn->ping() ;
318
 
319
  if ( $res != '+PONG' ) {
320
- $failed = true ;
321
  }
322
  }
323
  catch ( \Exception $e ) {
324
- error_log( $e->getMessage() ) ;
325
- $failed = true ;
326
  }
327
  catch ( \ErrorException $e ) {
328
- error_log( $e->getMessage() ) ;
329
- $failed = true ;
330
  }
331
- restore_error_handler() ;
332
 
333
  }
334
  /**
335
  * Connect to Memcached
336
  */
337
  else {
338
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] Init ' . $this->_oc_driver . ' connection' ) ;
339
  if ( $this->_cfg_persistent ) {
340
- $this->_conn = new \Memcached( $this->_get_mem_id() ) ;
341
 
342
  // Check memcached persistent connection
343
  if ( $this->_validate_mem_server() ) {
344
- // error_log( 'Object: _validate_mem_server' ) ;
345
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] Got persistent ' . $this->_oc_driver . ' connection' ) ;
346
- return true ;
347
  }
348
 
349
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] No persistent ' . $this->_oc_driver . ' server list!' ) ;
350
  }
351
  else {
352
- // error_log( 'Object: new memcached!' ) ;
353
- $this->_conn = new \Memcached ;
354
  }
355
 
356
- $this->_conn->addServer( $this->_cfg_host, (int) $this->_cfg_port ) ;
357
 
358
  /**
359
  * Add SASL auth
@@ -361,29 +352,29 @@ class Object_Cache
361
  * @since 2.9.6 Fixed SASL connection @see https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:lsmcd:new_sasl
362
  */
363
  if ( $this->_cfg_user && $this->_cfg_pswd && method_exists( $this->_conn, 'setSaslAuthData' ) ) {
364
- $this->_conn->setOption( \Memcached::OPT_BINARY_PROTOCOL, true ) ;
365
- $this->_conn->setOption( \Memcached::OPT_COMPRESSION, false ) ;
366
- $this->_conn->setSaslAuthData( $this->_cfg_user, $this->_cfg_pswd ) ;
367
  }
368
 
369
  // Check connection
370
  if ( ! $this->_validate_mem_server() ) {
371
- $failed = true ;
372
  }
373
  }
374
 
375
  // If failed to connect
376
  if ( $failed ) {
377
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] Failed to connect ' . $this->_oc_driver . ' server!' ) ;
378
- $this->_conn = null ;
379
- $this->_cfg_enabled = false ;
380
- // error_log( 'Object: false!' ) ;
381
- return false ;
382
  }
383
 
384
- defined( 'LSCWP_LOG' ) && Debug2::debug2( '[Object] Connected' ) ;
385
 
386
- return true ;
387
  }
388
 
389
  /**
@@ -392,23 +383,22 @@ class Object_Cache
392
  * @since 1.8
393
  * @access private
394
  */
395
- private function _validate_mem_server()
396
- {
397
- $mem_list = $this->_conn->getStats() ;
398
  if ( empty( $mem_list ) ) {
399
- return false ;
400
  }
401
 
402
  foreach ( $mem_list as $k => $v ) {
403
  if ( substr( $k, 0, strlen( $this->_cfg_host ) ) != $this->_cfg_host ) {
404
- continue ;
405
  }
406
  if ( $v[ 'pid' ] > 0 ) {
407
- return true ;
408
  }
409
  }
410
 
411
- return false ;
412
  }
413
 
414
  /**
@@ -417,14 +407,13 @@ class Object_Cache
417
  * @since 1.8
418
  * @access private
419
  */
420
- private function _get_mem_id()
421
- {
422
- $mem_id = 'litespeed' ;
423
  if ( is_multisite() ) {
424
- $mem_id .= '_' . get_current_blog_id() ;
425
  }
426
 
427
- return $mem_id ;
428
  }
429
 
430
  /**
@@ -433,25 +422,24 @@ class Object_Cache
433
  * @since 1.8
434
  * @access public
435
  */
436
- public function get( $key )
437
- {
438
  if ( ! $this->_cfg_enabled ) {
439
- return null ;
440
  }
441
 
442
  if ( ! $this->_can_cache() ) {
443
- return null ;
444
  }
445
 
446
  if( ! $this->_connect() ) {
447
- return null ;
448
  }
449
 
450
- // defined( 'LSCWP_LOG' ) && Debug2::debug2( '[Object] get ' . $key ) ;
451
 
452
- $res = $this->_conn->get( $key ) ;
453
 
454
- return $res ;
455
  }
456
 
457
  /**
@@ -460,10 +448,9 @@ class Object_Cache
460
  * @since 1.8
461
  * @access public
462
  */
463
- public function set( $key, $data, $expire )
464
- {
465
  if ( ! $this->_cfg_enabled ) {
466
- return null ;
467
  }
468
 
469
  /**
@@ -471,31 +458,31 @@ class Object_Cache
471
  * Bug found by Stan at Jan/10/2020
472
  */
473
  // if ( ! $this->_can_cache() ) {
474
- // return null ;
475
  // }
476
 
477
  if( ! $this->_connect() ) {
478
- return null ;
479
  }
480
 
481
- // defined( 'LSCWP_LOG' ) && Debug2::debug2( '[Object] set ' . $key ) ;
482
 
483
- // error_log( 'Object: set ' . $key ) ;
484
 
485
- $ttl = $expire ?: $this->_cfg_life ;
486
 
487
  if ( $this->_oc_driver == 'Redis' ) {
488
  try {
489
- $res = $this->_conn->setEx( $key, $ttl, $data ) ;
490
  } catch ( \RedisException $ex ) {
491
  throw new \Exception( $ex->getMessage(), $ex->getCode(), $ex );
492
  }
493
  }
494
  else {
495
- $res = $this->_conn->set( $key, $data, $ttl ) ;
496
  }
497
 
498
- return $res ;
499
  }
500
 
501
  /**
@@ -504,12 +491,11 @@ class Object_Cache
504
  * @since 1.8
505
  * @access private
506
  */
507
- private function _can_cache()
508
- {
509
  if ( ! $this->_cfg_admin && defined( 'WP_ADMIN' ) ) {
510
- return false ;
511
  }
512
- return true ;
513
  }
514
 
515
  /**
@@ -518,26 +504,25 @@ class Object_Cache
518
  * @since 1.8
519
  * @access public
520
  */
521
- public function delete( $key )
522
- {
523
  if ( ! $this->_cfg_enabled ) {
524
- return null ;
525
  }
526
 
527
  if( ! $this->_connect() ) {
528
- return null ;
529
  }
530
 
531
- // defined( 'LSCWP_LOG' ) && Debug2::debug2( '[Object] delete ' . $key ) ;
532
 
533
  if ( $this->_oc_driver == 'Redis' ) {
534
- $res = $this->_conn->del( $key ) ;
535
  }
536
  else {
537
- $res = $this->_conn->delete( $key ) ;
538
  }
539
 
540
- return $res ;
541
  }
542
 
543
  /**
@@ -546,28 +531,27 @@ class Object_Cache
546
  * @since 1.8
547
  * @access public
548
  */
549
- public function flush()
550
- {
551
  if ( ! $this->_cfg_enabled ) {
552
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] bypass flushing' ) ;
553
- return null ;
554
  }
555
 
556
  if( ! $this->_connect() ) {
557
- return null ;
558
  }
559
 
560
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] flush!' ) ;
561
 
562
  if ( $this->_oc_driver == 'Redis' ) {
563
- $res = $this->_conn->flushDb() ;
564
  }
565
  else {
566
- $res = $this->_conn->flush() ;
567
- $this->_conn->resetServerList() ;
568
  }
569
 
570
- return $res ;
571
  }
572
 
573
  /**
@@ -576,14 +560,13 @@ class Object_Cache
576
  * @since 1.8
577
  * @access public
578
  */
579
- public function add_global_groups( $groups )
580
- {
581
  if ( ! is_array( $groups ) ) {
582
- $groups = array( $groups ) ;
583
  }
584
 
585
- $this->_global_groups = array_merge( $this->_global_groups, $groups ) ;
586
- $this->_global_groups = array_unique( $this->_global_groups ) ;
587
  }
588
 
589
  /**
@@ -592,9 +575,8 @@ class Object_Cache
592
  * @since 1.8
593
  * @access public
594
  */
595
- public function is_global( $group )
596
- {
597
- return in_array( $group, $this->_global_groups ) ;
598
  }
599
 
600
  /**
@@ -603,14 +585,13 @@ class Object_Cache
603
  * @since 1.8
604
  * @access public
605
  */
606
- public function add_non_persistent_groups( $groups )
607
- {
608
  if ( ! is_array( $groups ) ) {
609
- $groups = array( $groups ) ;
610
  }
611
 
612
- $this->_non_persistent_groups = array_merge( $this->_non_persistent_groups, $groups ) ;
613
- $this->_non_persistent_groups = array_unique( $this->_non_persistent_groups ) ;
614
  }
615
 
616
  /**
@@ -619,9 +600,8 @@ class Object_Cache
619
  * @since 1.8
620
  * @access public
621
  */
622
- public function is_non_persistent( $group )
623
- {
624
- return in_array( $group, $this->_non_persistent_groups ) ;
625
  }
626
 
627
  /**
@@ -630,12 +610,11 @@ class Object_Cache
630
  * @since 1.8
631
  * @access public
632
  */
633
- public static function get_instance()
634
- {
635
  if ( ! isset( self::$_instance ) ) {
636
- self::$_instance = new self() ;
637
  }
638
 
639
- return self::$_instance ;
640
  }
641
  }
7
  * @subpackage LiteSpeed/inc
8
  * @author LiteSpeed Technologies <info@litespeedtech.com>
9
  */
10
+ namespace LiteSpeed;
11
 
12
+ defined( 'WPINC' ) || exit;
13
 
14
+ class Object_Cache {
15
+ protected static $_instance;
 
16
 
17
+ private $_oc_data_file;
18
+ private $_conn;
19
+ private $_cfg_enabled;
20
+ private $_cfg_method;
21
+ private $_cfg_host;
22
+ private $_cfg_port;
23
+ private $_cfg_persistent;
24
+ private $_cfg_admin;
25
+ private $_cfg_transients;
26
+ private $_cfg_db;
27
+ private $_cfg_user;
28
+ private $_cfg_pswd;
29
+ private $_default_life = 360;
30
 
31
+ private $_oc_driver = 'Memcached'; // Redis or Memcached
32
 
33
+ private $_global_groups;
34
+ private $_non_persistent_groups;
35
 
36
  /**
37
  * Init
41
  * @since 1.8
42
  * @access protected
43
  */
44
+ protected function __construct( $cfg = false ) {
45
+ defined( 'LSCWP_LOG' ) && Debug2::debug2( '[Object] init' );
 
46
 
47
+ $this->_oc_data_file = WP_CONTENT_DIR . '/.object-cache.ini';
48
 
49
  if ( $cfg ) {
50
  if ( ! is_array( $cfg[ Base::O_OBJECT_GLOBAL_GROUPS ] ) ) {
51
+ $cfg[ Base::O_OBJECT_GLOBAL_GROUPS ] = explode( "\n", $cfg[ Base::O_OBJECT_GLOBAL_GROUPS ] );
52
  }
53
  if ( ! is_array( $cfg[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ] ) ) {
54
+ $cfg[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ] = explode( "\n", $cfg[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ] );
55
  }
56
+ $this->_cfg_method = $cfg[ Base::O_OBJECT_KIND ] ? true : false;
57
+ $this->_cfg_host = $cfg[ Base::O_OBJECT_HOST ];
58
+ $this->_cfg_port = $cfg[ Base::O_OBJECT_PORT ];
59
+ $this->_cfg_life = $cfg[ Base::O_OBJECT_LIFE ];
60
+ $this->_cfg_persistent = $cfg[ Base::O_OBJECT_PERSISTENT ];
61
+ $this->_cfg_admin = $cfg[ Base::O_OBJECT_ADMIN ];
62
+ $this->_cfg_transients = $cfg[ Base::O_OBJECT_TRANSIENTS ];
63
+ $this->_cfg_db = $cfg[ Base::O_OBJECT_DB_ID ];
64
+ $this->_cfg_user = $cfg[ Base::O_OBJECT_USER ];
65
+ $this->_cfg_pswd = $cfg[ Base::O_OBJECT_PSWD ];
66
+ $this->_global_groups = $cfg[ Base::O_OBJECT_GLOBAL_GROUPS ];
67
+ $this->_non_persistent_groups = $cfg[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ];
68
 
69
  if ( $this->_cfg_method ) {
70
+ $this->_oc_driver = 'Redis';
71
  }
72
+ $this->_cfg_enabled = $cfg[ Base::O_OBJECT ] && class_exists( $this->_oc_driver ) && $this->_cfg_host;
73
 
74
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] init with cfg result : ', $this->_cfg_enabled );
75
  }
76
  elseif ( class_exists( __NAMESPACE__ . '\Core' ) ) {
77
+ $this->_cfg_method = Conf::val( Base::O_OBJECT_KIND ) ? true : false;
78
+ $this->_cfg_host = Conf::val( Base::O_OBJECT_HOST );
79
+ $this->_cfg_port = Conf::val( Base::O_OBJECT_PORT );
80
+ $this->_cfg_life = Conf::val( Base::O_OBJECT_LIFE );
81
+ $this->_cfg_persistent = Conf::val( Base::O_OBJECT_PERSISTENT );
82
+ $this->_cfg_admin = Conf::val( Base::O_OBJECT_ADMIN );
83
+ $this->_cfg_transients = Conf::val( Base::O_OBJECT_TRANSIENTS );
84
+ $this->_cfg_db = Conf::val( Base::O_OBJECT_DB_ID );
85
+ $this->_cfg_user = Conf::val( Base::O_OBJECT_USER );
86
+ $this->_cfg_pswd = Conf::val( Base::O_OBJECT_PSWD );
87
+ $this->_global_groups = Conf::val( Base::O_OBJECT_GLOBAL_GROUPS );
88
+ $this->_non_persistent_groups = Conf::val( Base::O_OBJECT_NON_PERSISTENT_GROUPS );
89
 
90
  if ( $this->_cfg_method ) {
91
+ $this->_oc_driver = 'Redis';
92
  }
93
+ $this->_cfg_enabled = Conf::val( Base::O_OBJECT ) && class_exists( $this->_oc_driver ) && $this->_cfg_host;
94
  }
95
  elseif ( file_exists( $this->_oc_data_file ) ) { // Get cfg from oc_data_file
96
+ $cfg = parse_ini_file( $this->_oc_data_file, true );
97
+ $this->_cfg_method = ! empty( $cfg[ 'object_cache' ][ 'method' ] ) ? $cfg[ 'object_cache' ][ 'method' ] : false;
98
+ $this->_cfg_host = $cfg[ 'object_cache' ][ 'host' ];
99
+ $this->_cfg_port = $cfg[ 'object_cache' ][ 'port' ];
100
+ $this->_cfg_life = ! empty( $cfg[ 'object_cache' ][ 'life' ] ) ? $cfg[ 'object_cache' ][ 'life' ] : $this->_default_life;
101
+ $this->_cfg_persistent = ! empty( $cfg[ 'object_cache' ][ 'persistent' ] ) ? $cfg[ 'object_cache' ][ 'persistent' ] : false;
102
+ $this->_cfg_admin = ! empty( $cfg[ 'object_cache' ][ 'cache_admin' ] ) ? $cfg[ 'object_cache' ][ 'cache_admin' ] : false;
103
+ $this->_cfg_transients = ! empty( $cfg[ 'object_cache' ][ 'cache_transients' ] ) ? $cfg[ 'object_cache' ][ 'cache_transients' ] : false;
104
+ $this->_cfg_db = ! empty( $cfg[ 'object_cache' ][ 'db' ] ) ? $cfg[ 'object_cache' ][ 'db' ] : 0;
105
+ $this->_cfg_user = ! empty( $cfg[ 'object_cache' ][ 'user' ] ) ? $cfg[ 'object_cache' ][ 'user' ] : '';
106
+ $this->_cfg_pswd = ! empty( $cfg[ 'object_cache' ][ 'pswd' ] ) ? $cfg[ 'object_cache' ][ 'pswd' ] : '';
107
+ $this->_global_groups = ! empty( $cfg[ 'object_cache' ][ 'global_groups' ] ) ? explode( ',', $cfg[ 'object_cache' ][ 'global_groups' ] ) : array();
108
+ $this->_non_persistent_groups = ! empty( $cfg[ 'object_cache' ][ 'non_persistent_groups' ] ) ? explode( ',', $cfg[ 'object_cache' ][ 'non_persistent_groups' ] ) : array();
109
 
110
  if ( $this->_cfg_method ) {
111
+ $this->_oc_driver = 'Redis';
112
  }
113
+ $this->_cfg_enabled = class_exists( $this->_oc_driver ) && $this->_cfg_host;
114
  }
115
  else {
116
+ $this->_cfg_enabled = false;
117
  }
118
  }
119
 
123
  * @since 1.8.3
124
  * @access public
125
  */
126
+ public function store_transients( $group ) {
127
+ return $this->_cfg_transients && $this->_is_transients_group( $group );
 
128
  }
129
 
130
  /**
133
  * @since 1.8.3
134
  * @access private
135
  */
136
+ private function _is_transients_group( $group ) {
137
+ return in_array( $group, array( 'transient', 'site-transient' ) );
 
138
  }
139
 
140
  /**
143
  * @since 1.8
144
  * @access public
145
  */
146
+ public function update_file( $options ) {
147
+ $changed = false;
 
148
 
149
  // Update data file
150
  $data = "[object_cache]"
162
  . "\nnon_persistent_groups = " . implode( ',', $options[ Base::O_OBJECT_NON_PERSISTENT_GROUPS ] )
163
  ;
164
 
165
+ $old_data = File::read( $this->_oc_data_file );
166
  if ( $old_data != $data ) {
167
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Settings] Update .object_cache.ini and flush object cache' );
168
+ File::save( $this->_oc_data_file, $data );
169
 
170
+ $changed = true;
171
  }
172
 
173
  // NOTE: When included in oc.php, `LSCWP_DIR` will show undefined, so this must be assigned/generated when used
174
+ $_oc_ori_file = LSCWP_DIR . 'lib/object-cache.php';
175
+ $_oc_wp_file = WP_CONTENT_DIR . '/object-cache.php';
176
 
177
  // Update cls file
178
  if ( ! file_exists( $_oc_wp_file ) || md5_file( $_oc_wp_file ) !== md5_file( $_oc_ori_file ) ) {
179
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] copying object-cache.php file to ' . $_oc_wp_file );
180
+ copy( $_oc_ori_file, $_oc_wp_file );
181
 
182
+ $changed = true;
183
  }
184
 
185
  /**
186
  * Clear object cache
187
  */
188
  if ( $changed ) {
189
+ $this->_reconnect( $options );
190
  }
191
  }
192
 
196
  * @since 1.8.2
197
  * @access public
198
  */
199
+ public function del_file() {
 
200
  // NOTE: When included in oc.php, `LSCWP_DIR` will show undefined, so this must be assigned/generated when used
201
+ $_oc_ori_file = LSCWP_DIR . 'lib/object-cache.php';
202
+ $_oc_wp_file = WP_CONTENT_DIR . '/object-cache.php';
203
 
204
  if ( file_exists( $_oc_wp_file ) && md5_file( $_oc_wp_file ) === md5_file( $_oc_ori_file ) ) {
205
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] removing ' . $_oc_wp_file );
206
+ unlink( $_oc_wp_file );
207
  }
208
 
209
  if ( file_exists( $this->_oc_data_file ) ) {
210
+ Debug2::debug( '[Object] Removing ' . $this->_oc_data_file );
211
+ unlink( $this->_oc_data_file );
212
  }
213
  }
214
 
218
  * @since 1.8
219
  * @access public
220
  */
221
+ public function test_connection() {
222
+ return $this->_connect();
 
223
  }
224
 
225
  /**
228
  * @since 1.8
229
  * @access private
230
  */
231
+ private function _reconnect( $cfg ) {
232
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] Reconnecting' );
233
+ // error_log( 'Object: reconnect !' );
 
234
  if ( isset( $this->_conn ) ) {
235
+ // error_log( 'Object: Quiting existing connection!' );
236
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] Quiting existing connection' );
237
+ $this->flush();
238
+ $this->_conn = null;
239
+ self::$_instance = null;
240
  }
241
 
242
+ self::$_instance = new self( $cfg );
243
+ self::$_instance->_connect();
244
  if ( isset( self::$_instance->_conn ) ) {
245
+ self::$_instance->flush();
246
  }
247
 
248
  }
253
  * @since 1.8
254
  * @access private
255
  */
256
+ private function _connect() {
 
257
  if ( isset( $this->_conn ) ) {
258
+ // error_log( 'Object: _connected' );
259
+ return true;
260
  }
261
 
262
  if ( ! class_exists( $this->_oc_driver ) || ! $this->_cfg_host ) {
263
+ return null;
264
  }
265
 
266
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] connecting to ' . $this->_cfg_host . ':' . $this->_cfg_port );
267
 
268
+ $failed = false;
269
  /**
270
  * Connect to Redis
271
  *
273
  * @see https://github.com/phpredis/phpredis/#example-1
274
  */
275
  if ( $this->_oc_driver == 'Redis' ) {
276
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] Init ' . $this->_oc_driver . ' connection' );
277
 
278
+ set_error_handler( 'litespeed_exception_handler' );
279
  try {
280
+ $this->_conn = new \Redis();
281
+ // error_log( 'Object: _connect Redis' );
282
 
283
  if ( $this->_cfg_persistent ) {
284
  if ( $this->_cfg_port ) {
285
+ $this->_conn->pconnect( $this->_cfg_host, $this->_cfg_port );
286
  }
287
  else {
288
+ $this->_conn->pconnect( $this->_cfg_host );
289
  }
290
  }
291
  else {
292
  if ( $this->_cfg_port ) {
293
+ $this->_conn->connect( $this->_cfg_host, $this->_cfg_port );
294
  }
295
  else {
296
+ $this->_conn->connect( $this->_cfg_host );
297
  }
298
  }
299
 
300
  if ( $this->_cfg_pswd ) {
301
+ $this->_conn->auth( $this->_cfg_pswd );
302
  }
303
 
304
  if ( $this->_cfg_db ) {
305
+ $this->_conn->select( $this->_cfg_db );
306
  }
307
 
308
+ $res = $this->_conn->ping();
309
 
310
  if ( $res != '+PONG' ) {
311
+ $failed = true;
312
  }
313
  }
314
  catch ( \Exception $e ) {
315
+ error_log( $e->getMessage() );
316
+ $failed = true;
317
  }
318
  catch ( \ErrorException $e ) {
319
+ error_log( $e->getMessage() );
320
+ $failed = true;
321
  }
322
+ restore_error_handler();
323
 
324
  }
325
  /**
326
  * Connect to Memcached
327
  */
328
  else {
329
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] Init ' . $this->_oc_driver . ' connection' );
330
  if ( $this->_cfg_persistent ) {
331
+ $this->_conn = new \Memcached( $this->_get_mem_id() );
332
 
333
  // Check memcached persistent connection
334
  if ( $this->_validate_mem_server() ) {
335
+ // error_log( 'Object: _validate_mem_server' );
336
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] Got persistent ' . $this->_oc_driver . ' connection' );
337
+ return true;
338
  }
339
 
340
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] No persistent ' . $this->_oc_driver . ' server list!' );
341
  }
342
  else {
343
+ // error_log( 'Object: new memcached!' );
344
+ $this->_conn = new \Memcached;
345
  }
346
 
347
+ $this->_conn->addServer( $this->_cfg_host, (int) $this->_cfg_port );
348
 
349
  /**
350
  * Add SASL auth
352
  * @since 2.9.6 Fixed SASL connection @see https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:lsmcd:new_sasl
353
  */
354
  if ( $this->_cfg_user && $this->_cfg_pswd && method_exists( $this->_conn, 'setSaslAuthData' ) ) {
355
+ $this->_conn->setOption( \Memcached::OPT_BINARY_PROTOCOL, true );
356
+ $this->_conn->setOption( \Memcached::OPT_COMPRESSION, false );
357
+ $this->_conn->setSaslAuthData( $this->_cfg_user, $this->_cfg_pswd );
358
  }
359
 
360
  // Check connection
361
  if ( ! $this->_validate_mem_server() ) {
362
+ $failed = true;
363
  }
364
  }
365
 
366
  // If failed to connect
367
  if ( $failed ) {
368
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] Failed to connect ' . $this->_oc_driver . ' server!' );
369
+ $this->_conn = null;
370
+ $this->_cfg_enabled = false;
371
+ // error_log( 'Object: false!' );
372
+ return false;
373
  }
374
 
375
+ defined( 'LSCWP_LOG' ) && Debug2::debug2( '[Object] Connected' );
376
 
377
+ return true;
378
  }
379
 
380
  /**
383
  * @since 1.8
384
  * @access private
385
  */
386
+ private function _validate_mem_server() {
387
+ $mem_list = $this->_conn->getStats();
 
388
  if ( empty( $mem_list ) ) {
389
+ return false;
390
  }
391
 
392
  foreach ( $mem_list as $k => $v ) {
393
  if ( substr( $k, 0, strlen( $this->_cfg_host ) ) != $this->_cfg_host ) {
394
+ continue;
395
  }
396
  if ( $v[ 'pid' ] > 0 ) {
397
+ return true;
398
  }
399
  }
400
 
401
+ return false;
402
  }
403
 
404
  /**
407
  * @since 1.8
408
  * @access private
409
  */
410
+ private function _get_mem_id() {
411
+ $mem_id = 'litespeed';
 
412
  if ( is_multisite() ) {
413
+ $mem_id .= '_' . get_current_blog_id();
414
  }
415
 
416
+ return $mem_id;
417
  }
418
 
419
  /**
422
  * @since 1.8
423
  * @access public
424
  */
425
+ public function get( $key ) {
 
426
  if ( ! $this->_cfg_enabled ) {
427
+ return null;
428
  }
429
 
430
  if ( ! $this->_can_cache() ) {
431
+ return null;
432
  }
433
 
434
  if( ! $this->_connect() ) {
435
+ return null;
436
  }
437
 
438
+ // defined( 'LSCWP_LOG' ) && Debug2::debug2( '[Object] get ' . $key );
439
 
440
+ $res = $this->_conn->get( $key );
441
 
442
+ return $res;
443
  }
444
 
445
  /**
448
  * @since 1.8
449
  * @access public
450
  */
451
+ public function set( $key, $data, $expire ) {
 
452
  if ( ! $this->_cfg_enabled ) {
453
+ return null;
454
  }
455
 
456
  /**
458
  * Bug found by Stan at Jan/10/2020
459
  */
460
  // if ( ! $this->_can_cache() ) {
461
+ // return null;
462
  // }
463
 
464
  if( ! $this->_connect() ) {
465
+ return null;
466
  }
467
 
468
+ // defined( 'LSCWP_LOG' ) && Debug2::debug2( '[Object] set ' . $key );
469
 
470
+ // error_log( 'Object: set ' . $key );
471
 
472
+ $ttl = $expire ?: $this->_cfg_life;
473
 
474
  if ( $this->_oc_driver == 'Redis' ) {
475
  try {
476
+ $res = $this->_conn->setEx( $key, $ttl, $data );
477
  } catch ( \RedisException $ex ) {
478
  throw new \Exception( $ex->getMessage(), $ex->getCode(), $ex );
479
  }
480
  }
481
  else {
482
+ $res = $this->_conn->set( $key, $data, $ttl );
483
  }
484
 
485
+ return $res;
486
  }
487
 
488
  /**
491
  * @since 1.8
492
  * @access private
493
  */
494
+ private function _can_cache() {
 
495
  if ( ! $this->_cfg_admin && defined( 'WP_ADMIN' ) ) {
496
+ return false;
497
  }
498
+ return true;
499
  }
500
 
501
  /**
504
  * @since 1.8
505
  * @access public
506
  */
507
+ public function delete( $key ) {
 
508
  if ( ! $this->_cfg_enabled ) {
509
+ return null;
510
  }
511
 
512
  if( ! $this->_connect() ) {
513
+ return null;
514
  }
515
 
516
+ // defined( 'LSCWP_LOG' ) && Debug2::debug2( '[Object] delete ' . $key );
517
 
518
  if ( $this->_oc_driver == 'Redis' ) {
519
+ $res = $this->_conn->del( $key );
520
  }
521
  else {
522
+ $res = $this->_conn->delete( $key );
523
  }
524
 
525
+ return $res;
526
  }
527
 
528
  /**
531
  * @since 1.8
532
  * @access public
533
  */
534
+ public function flush() {
 
535
  if ( ! $this->_cfg_enabled ) {
536
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] bypass flushing' );
537
+ return null;
538
  }
539
 
540
  if( ! $this->_connect() ) {
541
+ return null;
542
  }
543
 
544
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[Object] flush!' );
545
 
546
  if ( $this->_oc_driver == 'Redis' ) {
547
+ $res = $this->_conn->flushDb();
548
  }
549
  else {
550
+ $res = $this->_conn->flush();
551
+ $this->_conn->resetServerList();
552
  }
553
 
554
+ return $res;
555
  }
556
 
557
  /**
560
  * @since 1.8
561
  * @access public
562
  */
563
+ public function add_global_groups( $groups ) {
 
564
  if ( ! is_array( $groups ) ) {
565
+ $groups = array( $groups );
566
  }
567
 
568
+ $this->_global_groups = array_merge( $this->_global_groups, $groups );
569
+ $this->_global_groups = array_unique( $this->_global_groups );
570
  }
571
 
572
  /**
575
  * @since 1.8
576
  * @access public
577
  */
578
+ public function is_global( $group ) {
579
+ return in_array( $group, $this->_global_groups );
 
580
  }
581
 
582
  /**
585
  * @since 1.8
586
  * @access public
587
  */
588
+ public function add_non_persistent_groups( $groups ) {
 
589
  if ( ! is_array( $groups ) ) {
590
+ $groups = array( $groups );
591
  }
592
 
593
+ $this->_non_persistent_groups = array_merge( $this->_non_persistent_groups, $groups );
594
+ $this->_non_persistent_groups = array_unique( $this->_non_persistent_groups );
595
  }
596
 
597
  /**
600
  * @since 1.8
601
  * @access public
602
  */
603
+ public function is_non_persistent( $group ) {
604
+ return in_array( $group, $this->_non_persistent_groups );
 
605
  }
606
 
607
  /**
610
  * @since 1.8
611
  * @access public
612
  */
613
+ public static function get_instance() {
 
614
  if ( ! isset( self::$_instance ) ) {
615
+ self::$_instance = new self();
616
  }
617
 
618
+ return self::$_instance;
619
  }
620
  }
src/optimize.cls.php CHANGED
@@ -605,7 +605,7 @@ class Optimize extends Base {
605
 
606
  // Drop noscript if enabled
607
  if ( Conf::val( Base::O_OPTM_NOSCRIPT_RM ) ) {
608
- $this->content = preg_replace( '#<noscript>.*</noscript>#isU', '', $this->content );
609
  }
610
 
611
  // HTML minify
605
 
606
  // Drop noscript if enabled
607
  if ( Conf::val( Base::O_OPTM_NOSCRIPT_RM ) ) {
608
+ // $this->content = preg_replace( '#<noscript>.*</noscript>#isU', '', $this->content );
609
  }
610
 
611
  // HTML minify
src/placeholder.cls.php CHANGED
@@ -15,6 +15,7 @@ class Placeholder extends Base {
15
  protected static $_instance;
16
 
17
  const TYPE_GENERATE = 'generate';
 
18
 
19
  private $_conf_placeholder_resp;
20
  private $_conf_placeholder_resp_svg;
@@ -228,6 +229,11 @@ class Placeholder extends Base {
228
  return $this->_generate_placeholder_locally( $size );
229
  }
230
 
 
 
 
 
 
231
  $this->_ph_queue[] = $arr_key;
232
 
233
  // Send request to generate placeholder
@@ -385,11 +391,15 @@ class Placeholder extends Base {
385
  // Parse containing size and src info
386
  $size_and_src = explode( ' ', $raw_size_and_src, 2 );
387
  $size = $size_and_src[ 0 ];
388
- $src = false;
389
- if ( ! empty( $size_and_src[ 1 ] ) ) {
390
- $src = $size_and_src[ 1 ];
 
 
391
  }
392
 
 
 
393
  $file = $this->_placeholder_realpath( $src, $size );
394
 
395
  // Local generate SVG to serve ( Repeatly doing this here to remove stored cron queue in case the setting _conf_lqip is changed )
@@ -416,6 +426,7 @@ class Placeholder extends Base {
416
  // CHeck if the image is 404 first
417
  if ( File::is_404( $req_data[ 'url' ] ) ) {
418
  $this->_popup_and_save( $raw_size_and_src );
 
419
  Debug2::debug( '[LQIP] 404 before request [src] ' . $req_data[ 'url' ] );
420
  return $this->_generate_placeholder_locally( $size );
421
  }
@@ -424,7 +435,7 @@ class Placeholder extends Base {
424
  $this->_summary[ 'curr_request' ] = time();
425
  self::save_summary();
426
 
427
- $json = Cloud::post( Cloud::SVC_LQIP, $req_data, 30 );
428
  if ( ! is_array( $json ) ) {
429
  return $this->_generate_placeholder_locally( $size );
430
  }
@@ -432,6 +443,7 @@ class Placeholder extends Base {
432
  if ( empty( $json[ 'lqip' ] ) || strpos( $json[ 'lqip' ], 'data:image/svg+xml' ) !== 0 ) {
433
  // image error, pop up the current queue
434
  $this->_popup_and_save( $raw_size_and_src );
 
435
  Debug2::debug( '[LQIP] wrong response format', $json );
436
 
437
  return $this->_generate_placeholder_locally( $size );
@@ -470,6 +482,37 @@ class Placeholder extends Base {
470
  return false;
471
  }
472
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
473
  /**
474
  * Pop up the current request and save
475
  *
@@ -483,6 +526,23 @@ class Placeholder extends Base {
483
  self::save_summary();
484
  }
485
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
486
  /**
487
  * Handle all request actions from main cls
488
  *
@@ -499,6 +559,10 @@ class Placeholder extends Base {
499
  self::cron( true );
500
  break;
501
 
 
 
 
 
502
  default:
503
  break;
504
  }
15
  protected static $_instance;
16
 
17
  const TYPE_GENERATE = 'generate';
18
+ const TYPE_CLEAR_Q = 'clear_q';
19
 
20
  private $_conf_placeholder_resp;
21
  private $_conf_placeholder_resp_svg;
229
  return $this->_generate_placeholder_locally( $size );
230
  }
231
 
232
+ if ( $hit = Utility::str_hit_array( $src, Conf::val( Base::O_MEDIA_LQIP_EXC ) ) ) {
233
+ Debug2::debug2( '[LQIP] file bypass generating due to exclude setting [hit] ' . $hit );
234
+ return $this->_generate_placeholder_locally( $size );
235
+ }
236
+
237
  $this->_ph_queue[] = $arr_key;
238
 
239
  // Send request to generate placeholder
391
  // Parse containing size and src info
392
  $size_and_src = explode( ' ', $raw_size_and_src, 2 );
393
  $size = $size_and_src[ 0 ];
394
+
395
+ if ( empty( $size_and_src[ 1 ] ) ) {
396
+ $this->_popup_and_save( $raw_size_and_src );
397
+ Debug2::debug( '[LQIP] ❌ No src [raw] ' . $raw_size_and_src );
398
+ return $this->_generate_placeholder_locally( $size );
399
  }
400
 
401
+ $src = $size_and_src[ 1 ];
402
+
403
  $file = $this->_placeholder_realpath( $src, $size );
404
 
405
  // Local generate SVG to serve ( Repeatly doing this here to remove stored cron queue in case the setting _conf_lqip is changed )
426
  // CHeck if the image is 404 first
427
  if ( File::is_404( $req_data[ 'url' ] ) ) {
428
  $this->_popup_and_save( $raw_size_and_src );
429
+ $this->_append_exc( $src );
430
  Debug2::debug( '[LQIP] 404 before request [src] ' . $req_data[ 'url' ] );
431
  return $this->_generate_placeholder_locally( $size );
432
  }
435
  $this->_summary[ 'curr_request' ] = time();
436
  self::save_summary();
437
 
438
+ $json = Cloud::post( Cloud::SVC_LQIP, $req_data, 120 );
439
  if ( ! is_array( $json ) ) {
440
  return $this->_generate_placeholder_locally( $size );
441
  }
443
  if ( empty( $json[ 'lqip' ] ) || strpos( $json[ 'lqip' ], 'data:image/svg+xml' ) !== 0 ) {
444
  // image error, pop up the current queue
445
  $this->_popup_and_save( $raw_size_and_src );
446
+ $this->_append_exc( $src );
447
  Debug2::debug( '[LQIP] wrong response format', $json );
448
 
449
  return $this->_generate_placeholder_locally( $size );
482
  return false;
483
  }
484
 
485
+ /**
486
+ * Add to LQIP exclude list
487
+ *
488
+ * @since 3.4
489
+ */
490
+ private function _append_exc( $src ) {
491
+ $val = Conf::val( Base::O_MEDIA_LQIP_EXC );
492
+ $val[] = $src;
493
+ Conf::get_instance()->update( Base::O_MEDIA_LQIP_EXC, $val );
494
+ Debug2::debug( '[LQIP] Appended to LQIP Excludes [URL] ' . $src );
495
+
496
+ if ( ! empty( $this->_summary[ 'queue' ] ) ) {
497
+ $changed = false;
498
+ foreach ( $this->_summary[ 'queue' ] as $k => $raw_size_and_src ) {
499
+ $size_and_src = explode( ' ', $raw_size_and_src, 2 );
500
+ if ( empty( $size_and_src[ 1 ] ) ) {
501
+ continue;
502
+ }
503
+
504
+ if ( $size_and_src[ 1 ] == $src ) {
505
+ unset( $this->_summary[ 'queue' ][ $k ] );
506
+ $changed = true;
507
+ }
508
+ }
509
+
510
+ if ( $changed ) {
511
+ self::save_summary();
512
+ }
513
+ }
514
+ }
515
+
516
  /**
517
  * Pop up the current request and save
518
  *
526
  self::save_summary();
527
  }
528
 
529
+ /**
530
+ * Clear all waiting queues
531
+ *
532
+ * @since 3.4
533
+ */
534
+ public function clear_q() {
535
+ if ( empty( $this->_summary[ 'queue' ] ) ) {
536
+ return;
537
+ }
538
+
539
+ $this->_summary[ 'queue' ] = array();
540
+ self::save_summary();
541
+
542
+ $msg = __( 'Queue cleared successfully.', 'litespeed-cache' );
543
+ Admin_Display::succeed( $msg );
544
+ }
545
+
546
  /**
547
  * Handle all request actions from main cls
548
  *
559
  self::cron( true );
560
  break;
561
 
562
+ case self::TYPE_CLEAR_Q :
563
+ $instance->clear_q();
564
+ break;
565
+
566
  default:
567
  break;
568
  }
src/purge.cls.php CHANGED
@@ -66,7 +66,7 @@ class Purge extends Base {
66
  // Purge post only when status is/was publish
67
  add_action( 'transition_post_status', __CLASS__ . '::purge_publish', 10, 3 );
68
 
69
- add_action( 'wp_update_comment_count', __CLASS__ . '::purge_feeds' ) ;
70
 
71
  }
72
 
@@ -209,8 +209,8 @@ class Purge extends Base {
209
  $this->_add( '*' );
210
 
211
  if ( ! $silence ) {
212
- $msg = __( 'Notified LiteSpeed Web Server to purge all LSCache entries.', 'litespeed-cache' ) ;
213
- ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg ) ;
214
  }
215
  }
216
 
@@ -223,11 +223,11 @@ class Purge extends Base {
223
  private function _purge_all_ccss( $silence = false ) {
224
  do_action( 'litespeed_purged_all_ccss' );
225
 
226
- CSS::get_instance()->rm_cache_folder() ;
227
 
228
  if ( ! $silence ) {
229
- $msg = __( 'Cleaned all Critical CSS files.', 'litespeed-cache' ) ;
230
- ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg ) ;
231
  }
232
  }
233
 
@@ -240,11 +240,11 @@ class Purge extends Base {
240
  private function _purge_all_lqip( $silence = false ) {
241
  do_action( 'litespeed_purged_all_lqip' );
242
 
243
- Placeholder::get_instance()->rm_lqip_cache_folder() ;
244
 
245
  if ( ! $silence ) {
246
- $msg = __( 'Cleaned all LQIP files.', 'litespeed-cache' ) ;
247
- ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg ) ;
248
  }
249
  }
250
 
@@ -257,11 +257,11 @@ class Purge extends Base {
257
  private function _purge_all_avatar( $silence = false ) {
258
  do_action( 'litespeed_purged_all_avatar' );
259
 
260
- Avatar::get_instance()->rm_cache_folder() ;
261
 
262
  if ( ! $silence ) {
263
- $msg = __( 'Cleaned all Gravatar files.', 'litespeed-cache' ) ;
264
- ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg ) ;
265
  }
266
  }
267
 
@@ -334,6 +334,16 @@ class Purge extends Base {
334
  return true;
335
  }
336
 
 
 
 
 
 
 
 
 
 
 
337
  /**
338
  * Purge object cache
339
  *
@@ -342,27 +352,27 @@ class Purge extends Base {
342
  */
343
  private function _purge_all_object( $silence = false ) {
344
  if ( ! defined( 'LSCWP_OBJECT_CACHE' ) ) {
345
- Debug2::debug( '[Purge] Failed to flush object cache due to object cache not enabled' ) ;
346
 
347
  if ( ! $silence ) {
348
- $msg = __( 'Object cache is not enabled.', 'litespeed-cache' ) ;
349
- Admin_Display::error( $msg ) ;
350
  }
351
 
352
- return false ;
353
  }
354
 
355
  do_action( 'litespeed_purged_all_object' );
356
 
357
- Object_Cache::get_instance()->flush() ;
358
- Debug2::debug( '[Purge] Flushed object cache' ) ;
359
 
360
  if ( ! $silence ) {
361
- $msg = __( 'Purge all object caches successfully.', 'litespeed-cache' ) ;
362
- ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg ) ;
363
  }
364
 
365
- return true ;
366
  }
367
 
368
  /**
@@ -372,9 +382,8 @@ class Purge extends Base {
372
  * @access public
373
  * @param mixed $tags Tags to add to the list.
374
  */
375
- public static function add( $tags )
376
- {
377
- self::get_instance()->_add( $tags ) ;
378
  }
379
 
380
  /**
@@ -383,28 +392,27 @@ class Purge extends Base {
383
  * @since 2.2
384
  * @access private
385
  */
386
- private function _add( $tags )
387
- {
388
  if ( ! is_array( $tags ) ) {
389
- $tags = array( $tags ) ;
390
  }
391
  if ( ! array_diff( $tags, $this->_pub_purge ) ) {
392
- return ;
393
  }
394
 
395
- $this->_pub_purge = array_merge( $this->_pub_purge, $tags ) ;
396
- Debug2::debug( '[Purge] added ' . implode( ',', $tags ), 8 ) ;
397
 
398
  // Send purge header immediately
399
- $curr_built = $this->_build() ;
400
  if ( defined( 'LITESPEED_DID_send_headers' ) ) {
401
  // Can't send, already has output, need to save and wait for next run
402
- self::update_option( self::DB_QUEUE, $curr_built ) ;
403
- Debug2::debug( '[Purge] Output existed, queue stored: ' . $curr_built ) ;
404
  }
405
  else {
406
- @header( $curr_built ) ;
407
- Debug2::debug( $curr_built ) ;
408
  }
409
 
410
  }
@@ -416,9 +424,8 @@ class Purge extends Base {
416
  * @access public
417
  * @param mixed $tags Tags to add to the list.
418
  */
419
- public static function add_private( $tags )
420
- {
421
- self::get_instance()->_add_private( $tags ) ;
422
  }
423
 
424
  /**
@@ -427,8 +434,7 @@ class Purge extends Base {
427
  * @since 3.0
428
  * @access public
429
  */
430
- public static function add_private_esi( $tag )
431
- {
432
  self::add_private( Tag::TYPE_ESI . $tag );
433
  }
434
 
@@ -438,8 +444,7 @@ class Purge extends Base {
438
  * @since 3.0
439
  * @access public
440
  */
441
- public static function add_private_all()
442
- {
443
  self::add_private( '*' );
444
  }
445
 
@@ -449,21 +454,20 @@ class Purge extends Base {
449
  * @since 2.2
450
  * @access private
451
  */
452
- private function _add_private( $tags )
453
- {
454
  if ( ! is_array( $tags ) ) {
455
- $tags = array( $tags ) ;
456
  }
457
  if ( ! array_diff( $tags, $this->_priv_purge ) ) {
458
- return ;
459
  }
460
 
461
- Debug2::debug( '[Purge] added [private] ' . implode( ',', $tags ), 3 ) ;
462
 
463
- $this->_priv_purge = array_merge( $this->_priv_purge, $tags ) ;
464
 
465
  // Send purge header immediately
466
- @header( $this->_build() ) ;
467
  }
468
 
469
  /**
@@ -472,9 +476,8 @@ class Purge extends Base {
472
  * @since 1.1.3
473
  * @access public
474
  */
475
- public static function set_purge_related()
476
- {
477
- self::get_instance()->_purge_related = true ;
478
  }
479
 
480
  /**
@@ -483,9 +486,8 @@ class Purge extends Base {
483
  * @since 1.1.3
484
  * @access public
485
  */
486
- public static function set_purge_single()
487
- {
488
- self::get_instance()->_purge_single = true ;
489
  }
490
 
491
  /**
@@ -495,16 +497,15 @@ class Purge extends Base {
495
  * @since 2.2 Renamed from `frontend_purge`; Access changed from public
496
  * @access private
497
  */
498
- private function _purge_front()
499
- {
500
  if ( empty( $_SERVER[ 'HTTP_REFERER' ] ) ) {
501
- exit( 'no referer' ) ;
502
  }
503
 
504
- self::purge_url( $_SERVER[ 'HTTP_REFERER' ] ) ;
505
 
506
- wp_redirect( $_SERVER[ 'HTTP_REFERER' ] ) ;
507
- exit() ;
508
  }
509
 
510
  /**
@@ -514,15 +515,14 @@ class Purge extends Base {
514
  * @since 2.2 Access changed from public to private, renamed from `_purge_front`
515
  * @access private
516
  */
517
- private function _purge_frontpage()
518
- {
519
- $this->_add( Tag::TYPE_FRONTPAGE ) ;
520
  if ( LITESPEED_SERVER_TYPE !== 'LITESPEED_SERVER_OLS' ) {
521
- $this->_add_private( Tag::TYPE_FRONTPAGE ) ;
522
  }
523
 
524
- $msg = __( 'Notified LiteSpeed Web Server to purge the front page.', 'litespeed-cache' ) ;
525
- ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg ) ;
526
  }
527
 
528
  /**
@@ -531,12 +531,11 @@ class Purge extends Base {
531
  * @since 1.0.15
532
  * @access private
533
  */
534
- private function _purge_pages()
535
- {
536
- $this->_add( Tag::TYPE_PAGES ) ;
537
 
538
- $msg = __( 'Notified LiteSpeed Web Server to purge all pages.', 'litespeed-cache' ) ;
539
- ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg ) ;
540
  }
541
 
542
  /**
@@ -545,18 +544,17 @@ class Purge extends Base {
545
  * @since 1.0.14
546
  * @access private
547
  */
548
- private function _purge_error( $type = false )
549
- {
550
- $this->_add( Tag::TYPE_HTTP ) ;
551
 
552
  if ( ! $type || ! in_array( $type, array( '403', '404', '500' ) ) ) {
553
- return ;
554
  }
555
 
556
- $this->_add( Tag::TYPE_HTTP . $type ) ;
557
 
558
- $msg = __( 'Notified LiteSpeed Web Server to purge error pages.', 'litespeed-cache' ) ;
559
- ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg ) ;
560
  }
561
 
562
  /**
@@ -565,25 +563,24 @@ class Purge extends Base {
565
  * @since 1.0.7
566
  * @access public
567
  */
568
- public function purge_cat( $value )
569
- {
570
- $val = trim( $value ) ;
571
  if ( empty( $val ) ) {
572
- return ;
573
  }
574
  if ( preg_match( '/^[a-zA-Z0-9-]+$/', $val ) == 0 ) {
575
- Debug2::debug( "[Purge] $val cat invalid" ) ;
576
- return ;
577
  }
578
- $cat = get_category_by_slug( $val ) ;
579
  if ( $cat == false ) {
580
- Debug2::debug( "[Purge] $val cat not existed/published" ) ;
581
- return ;
582
  }
583
 
584
- self::add( Tag::TYPE_ARCHIVE_TERM . $cat->term_id ) ;
585
 
586
- ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( sprintf( __( 'Purge category %s', 'litespeed-cache' ), $val ) ) ;
587
  }
588
 
589
 
@@ -593,25 +590,24 @@ class Purge extends Base {
593
  * @since 1.0.7
594
  * @access public
595
  */
596
- public static function purge_tag( $val )
597
- {
598
- $val = trim( $val ) ;
599
  if ( empty( $val ) ) {
600
- return ;
601
  }
602
  if ( preg_match( '/^[a-zA-Z0-9-]+$/', $val ) == 0 ) {
603
- Debug2::debug( "[Purge] $val tag invalid" ) ;
604
- return ;
605
  }
606
- $term = get_term_by( 'slug', $val, 'post_tag' ) ;
607
  if ( $term == 0 ) {
608
- Debug2::debug( "[Purge] $val tag not exist" ) ;
609
- return ;
610
  }
611
 
612
- self::add( Tag::TYPE_ARCHIVE_TERM . $term->term_id ) ;
613
 
614
- ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( sprintf( __( 'Purge tag %s', 'litespeed-cache' ), $val ) ) ;
615
  }
616
 
617
  /**
@@ -620,30 +616,29 @@ class Purge extends Base {
620
  * @since 1.0.7
621
  * @access public
622
  */
623
- public static function purge_url( $url )
624
- {
625
- $val = trim( $url ) ;
626
  if ( empty( $val ) ) {
627
- return ;
628
  }
629
 
630
  if ( strpos( $val, '<' ) !== false ) {
631
- Debug2::debug( "[Purge] $val url contains <" ) ;
632
- return ;
633
  }
634
 
635
- $val = Utility::make_relative( $val ) ;
636
 
637
- $hash = Tag::get_uri_tag( $val ) ;
638
 
639
  if ( $hash === false ) {
640
- Debug2::debug( "[Purge] $val url invalid" ) ;
641
- return ;
642
  }
643
 
644
- self::add( $hash ) ;
645
 
646
- ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( sprintf( __( 'Purge url %s', 'litespeed-cache' ), $val ) ) ;
647
  }
648
 
649
  /**
@@ -652,39 +647,38 @@ class Purge extends Base {
652
  * @since 1.0.7
653
  * @access public
654
  */
655
- public function purge_list()
656
- {
657
  if ( ! isset($_REQUEST[Admin_Display::PURGEBYOPT_SELECT]) || ! isset($_REQUEST[Admin_Display::PURGEBYOPT_LIST]) ) {
658
- return ;
659
  }
660
- $sel = $_REQUEST[Admin_Display::PURGEBYOPT_SELECT] ;
661
- $list_buf = $_REQUEST[Admin_Display::PURGEBYOPT_LIST] ;
662
  if ( empty($list_buf) ) {
663
- return ;
664
  }
665
- $list_buf = str_replace(",", "\n", $list_buf) ;// for cli
666
- $list = explode("\n", $list_buf) ;
667
  switch($sel) {
668
  case Admin_Display::PURGEBY_CAT:
669
- $cb = 'purge_cat' ;
670
- break ;
671
  case Admin_Display::PURGEBY_PID:
672
- $cb = 'purge_post' ;
673
- break ;
674
  case Admin_Display::PURGEBY_TAG:
675
- $cb = 'purge_tag' ;
676
- break ;
677
  case Admin_Display::PURGEBY_URL:
678
- $cb = 'purge_url' ;
679
- break ;
680
 
681
  default:
682
- return ;
683
  }
684
  array_map( __CLASS__ . "::$cb", $list );
685
 
686
  // for redirection
687
- $_GET[ Admin_Display::PURGEBYOPT_SELECT ] = $sel ;
688
  }
689
 
690
  /**
@@ -693,8 +687,7 @@ class Purge extends Base {
693
  * @since 3.0
694
  * @access public
695
  */
696
- public static function purge_esi( $tag )
697
- {
698
  self::add( Tag::TYPE_ESI . $tag );
699
  }
700
 
@@ -704,8 +697,7 @@ class Purge extends Base {
704
  * @since 3.0
705
  * @access public
706
  */
707
- public static function purge_posttype( $post_type )
708
- {
709
  self::add( Tag::TYPE_ARCHIVE_POSTTYPE . $post_type );
710
  }
711
 
@@ -715,8 +707,7 @@ class Purge extends Base {
715
  * @since 1.0.0
716
  * @access public
717
  */
718
- public static function purge_post( $pid )
719
- {
720
  $pid = intval( $pid );
721
  // ignore the status we don't care
722
  if ( ! $pid || ! in_array( get_post_status( $pid ), array( 'publish', 'trash', 'private', 'draft' ) ) ) {
@@ -744,16 +735,15 @@ class Purge extends Base {
744
  * @since 1.1.3
745
  * @access public
746
  */
747
- public static function purge_widget( $widget_id = null )
748
- {
749
  if ( is_null($widget_id) ) {
750
- $widget_id = $_POST['widget-id'] ;
751
  if ( is_null($widget_id) ) {
752
- return ;
753
  }
754
  }
755
- self::add(Tag::TYPE_WIDGET . $widget_id) ;
756
- self::add_private(Tag::TYPE_WIDGET . $widget_id) ;
757
  }
758
 
759
  /**
@@ -764,13 +754,12 @@ class Purge extends Base {
764
  * @since 1.1.3
765
  * @global type $wp_widget_factory
766
  */
767
- public static function purge_comment_widget()
768
- {
769
- global $wp_widget_factory ;
770
- $recent_comments = $wp_widget_factory->widgets['WP_Widget_Recent_Comments'] ;
771
  if ( !is_null($recent_comments) ) {
772
- self::add(Tag::TYPE_WIDGET . $recent_comments->id) ;
773
- self::add_private(Tag::TYPE_WIDGET . $recent_comments->id) ;
774
  }
775
  }
776
 
@@ -780,10 +769,9 @@ class Purge extends Base {
780
  * @since 1.0.9
781
  * @access public
782
  */
783
- public static function purge_feeds()
784
- {
785
  if ( Conf::val(Base::O_CACHE_TTL_FEED) > 0 ) {
786
- self::add(Tag::TYPE_FEED) ;
787
  }
788
  }
789
 
@@ -793,9 +781,8 @@ class Purge extends Base {
793
  * @access public
794
  * @since 1.1.3
795
  */
796
- public static function purge_on_logout()
797
- {
798
- self::add_private('*') ;
799
  }
800
 
801
  /**
@@ -804,39 +791,38 @@ class Purge extends Base {
804
  * @access private
805
  * @since 1.1.3
806
  */
807
- private function _finalize()
808
- {
809
  // Make sure header output only run once
810
  if ( ! defined( 'LITESPEED_DID_' . __FUNCTION__ ) ) {
811
- define( 'LITESPEED_DID_' . __FUNCTION__, true ) ;
812
  }
813
  else {
814
- return ;
815
  }
816
 
817
- do_action('litespeed_purge_finalize') ;
818
 
819
  // Append unique uri purge tags if Admin QS is `PURGESINGLE`
820
  if ( $this->_purge_single ) {
821
- $this->_pub_purge[] = Tag::build_uri_tag() ; // TODO: add private tag too
822
  }
823
  // Append related purge tags if Admin QS is `PURGE`
824
  if ( $this->_purge_related ) {
825
  // Before this, tags need to be finalized
826
- $tags_related = Tag::output_tags() ;
827
  // NOTE: need to remove the empty item `B1_` to avoid purging all
828
- $tags_related = array_filter($tags_related) ;
829
  if ( $tags_related ) {
830
- $this->_pub_purge = array_merge($this->_pub_purge, $tags_related) ;
831
  }
832
  }
833
 
834
  if ( ! empty($this->_pub_purge) ) {
835
- $this->_pub_purge = array_unique($this->_pub_purge) ;
836
  }
837
 
838
  if ( ! empty($this->_priv_purge) ) {
839
- $this->_priv_purge = array_unique($this->_priv_purge) ;
840
  }
841
  }
842
 
@@ -849,13 +835,12 @@ class Purge extends Base {
849
  * @access public
850
  * @return string the built purge header
851
  */
852
- public static function output()
853
- {
854
- $instance = self::get_instance() ;
855
 
856
- $instance->_finalize() ;
857
 
858
- return $instance->_build() ;
859
  }
860
 
861
  /**
@@ -865,36 +850,35 @@ class Purge extends Base {
865
  * @access private
866
  * @return string the built purge header
867
  */
868
- private function _build()
869
- {
870
  if ( empty( $this->_pub_purge ) && empty( $this->_priv_purge ) ) {
871
- return ;
872
  }
873
 
874
- $purge_header = '' ;
875
- $private_prefix = self::X_HEADER . ': private,' ;
876
 
877
  if ( ! empty( $this->_pub_purge ) ) {
878
- $public_tags = $this->_append_prefix( $this->_pub_purge ) ;
879
  if ( empty( $public_tags ) ) {
880
  // If this ends up empty, private will also end up empty
881
- return ;
882
  }
883
- $purge_header = self::X_HEADER . ': public,' ;
884
  if ( Control::is_stale() ) {
885
- $purge_header .= 'stale,' ;
886
  }
887
- $purge_header .= implode( ',', $public_tags ) ;
888
- $private_prefix = ';private,' ;
889
  }
890
 
891
  // Handle priv purge tags
892
  if ( ! empty( $this->_priv_purge ) ) {
893
- $private_tags = $this->_append_prefix( $this->_priv_purge, true ) ;
894
- $purge_header .= $private_prefix . implode( ',', $private_tags ) ;
895
  }
896
 
897
- return $purge_header ;
898
  }
899
 
900
  /**
@@ -903,8 +887,7 @@ class Purge extends Base {
903
  * @since 1.1.0
904
  * @access private
905
  */
906
- private function _append_prefix( $purge_tags, $is_private = false )
907
- {
908
  $curr_bid = is_multisite() ? get_current_blog_id() : '';
909
 
910
  if ( ! in_array( '*', $purge_tags ) ) {
@@ -928,19 +911,19 @@ class Purge extends Base {
928
  if ( is_multisite() && (is_network_admin() || (
929
  Router::is_ajax() && (check_ajax_referer('updates', false, false) || check_ajax_referer('litespeed-purgeall-network', false, false))
930
  )) ) {
931
- $blogs = Activation::get_network_ids() ;
932
  if ( empty($blogs) ) {
933
- Debug2::debug('[Purge] build_purge_headers: blog list is empty') ;
934
- return '' ;
935
  }
936
- $tags = array() ;
937
  foreach ($blogs as $blog_id) {
938
- $tags[] = LSWCP_TAG_PREFIX . $blog_id . '_' ;
939
  }
940
- return $tags ;
941
  }
942
  else {
943
- return array(LSWCP_TAG_PREFIX . $curr_bid . '_') ;
944
  }
945
  }
946
 
@@ -954,118 +937,117 @@ class Purge extends Base {
954
  * @since 1.0.0
955
  * @access private
956
  */
957
- private function _get_purge_tags_by_post( $post_id )
958
- {
959
  // If this is a valid post we want to purge the post, the home page and any associated tags & cats
960
  // If not, purge everything on the site.
961
 
962
- $purge_tags = array() ;
963
- $config = Conf::get_instance() ;
964
 
965
  if ( Conf::val( Base::O_PURGE_POST_ALL ) ) {
966
  // ignore the rest if purge all
967
- return array( '*' ) ;
968
  }
969
 
970
  // now do API hook action for post purge
971
- do_action('litespeed_api_purge_post', $post_id) ;
972
 
973
  // post
974
- $purge_tags[] = Tag::TYPE_POST . $post_id ;
975
- $purge_tags[] = Tag::get_uri_tag(wp_make_link_relative(get_permalink($post_id))) ;
976
 
977
  // for archive of categories|tags|custom tax
978
- global $post ;
979
- $original_post = $post ;
980
- $post = get_post($post_id) ;
981
- $post_type = $post->post_type ;
982
 
983
- global $wp_widget_factory ;
984
- $recent_posts = $wp_widget_factory->widgets['WP_Widget_Recent_Posts'] ;
985
  if ( ! is_null($recent_posts) ) {
986
- $purge_tags[] = Tag::TYPE_WIDGET . $recent_posts->id ;
987
  }
988
 
989
  // get adjacent posts id as related post tag
990
  if( $post_type == 'post' ){
991
- $prev_post = get_previous_post() ;
992
- $next_post = get_next_post() ;
993
  if( ! empty($prev_post->ID) ) {
994
- $purge_tags[] = Tag::TYPE_POST . $prev_post->ID ;
995
- Debug2::debug('--------purge_tags prev is: '.$prev_post->ID) ;
996
  }
997
  if( ! empty($next_post->ID) ) {
998
- $purge_tags[] = Tag::TYPE_POST . $next_post->ID ;
999
- Debug2::debug('--------purge_tags next is: '.$next_post->ID) ;
1000
  }
1001
  }
1002
 
1003
  if ( Conf::val( Base::O_PURGE_POST_TERM ) ) {
1004
- $taxonomies = get_object_taxonomies($post_type) ;
1005
- //Debug2::debug('purge by post, check tax = ' . var_export($taxonomies, true)) ;
1006
  foreach ( $taxonomies as $tax ) {
1007
- $terms = get_the_terms($post_id, $tax) ;
1008
  if ( ! empty($terms) ) {
1009
  foreach ( $terms as $term ) {
1010
- $purge_tags[] = Tag::TYPE_ARCHIVE_TERM . $term->term_id ;
1011
  }
1012
  }
1013
  }
1014
  }
1015
 
1016
  if ( Conf::val( Base::O_CACHE_TTL_FEED ) ) {
1017
- $purge_tags[] = Tag::TYPE_FEED ;
1018
  }
1019
 
1020
  // author, for author posts and feed list
1021
  if ( Conf::val( Base::O_PURGE_POST_AUTHOR) ) {
1022
- $purge_tags[] = Tag::TYPE_AUTHOR . get_post_field('post_author', $post_id) ;
1023
  }
1024
 
1025
  // archive and feed of post type
1026
  // todo: check if type contains space
1027
  if ( Conf::val( Base::O_PURGE_POST_POSTTYPE) ) {
1028
  if ( get_post_type_archive_link($post_type) ) {
1029
- $purge_tags[] = Tag::TYPE_ARCHIVE_POSTTYPE . $post_type ;
1030
  }
1031
  }
1032
 
1033
  if ( Conf::val( Base::O_PURGE_POST_FRONTPAGE) ) {
1034
- $purge_tags[] = Tag::TYPE_FRONTPAGE ;
1035
  }
1036
 
1037
  if ( Conf::val( Base::O_PURGE_POST_HOMEPAGE) ) {
1038
- $purge_tags[] = Tag::TYPE_HOME ;
1039
  }
1040
 
1041
  if ( Conf::val( Base::O_PURGE_POST_PAGES) ) {
1042
- $purge_tags[] = Tag::TYPE_PAGES ;
1043
  }
1044
 
1045
  if ( Conf::val( Base::O_PURGE_POST_PAGES_WITH_RECENT_POSTS) ) {
1046
- $purge_tags[] = Tag::TYPE_PAGES_WITH_RECENT_POSTS ;
1047
  }
1048
 
1049
  // if configured to have archived by date
1050
- $date = $post->post_date ;
1051
- $date = strtotime($date) ;
1052
 
1053
  if ( Conf::val( Base::O_PURGE_POST_DATE) ) {
1054
- $purge_tags[] = Tag::TYPE_ARCHIVE_DATE . date('Ymd', $date) ;
1055
  }
1056
 
1057
  if ( Conf::val( Base::O_PURGE_POST_MONTH) ) {
1058
- $purge_tags[] = Tag::TYPE_ARCHIVE_DATE . date('Ym', $date) ;
1059
  }
1060
 
1061
  if ( Conf::val( Base::O_PURGE_POST_YEAR) ) {
1062
- $purge_tags[] = Tag::TYPE_ARCHIVE_DATE . date('Y', $date) ;
1063
  }
1064
 
1065
  // Set back to original post as $post_id might affecting the global $post value
1066
- $post = $original_post ;
1067
 
1068
- return array_unique($purge_tags) ;
1069
  }
1070
 
1071
  /**
@@ -1076,9 +1058,8 @@ class Purge extends Base {
1076
  * @param string $val The filter value
1077
  * @return string The filter value
1078
  */
1079
- public static function filter_with_purge_all( $val )
1080
- {
1081
- self::purge_all() ;
1082
- return $val ;
1083
  }
1084
  }
66
  // Purge post only when status is/was publish
67
  add_action( 'transition_post_status', __CLASS__ . '::purge_publish', 10, 3 );
68
 
69
+ add_action( 'wp_update_comment_count', __CLASS__ . '::purge_feeds' );
70
 
71
  }
72
 
209
  $this->_add( '*' );
210
 
211
  if ( ! $silence ) {
212
+ $msg = __( 'Notified LiteSpeed Web Server to purge all LSCache entries.', 'litespeed-cache' );
213
+ ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg );
214
  }
215
  }
216
 
223
  private function _purge_all_ccss( $silence = false ) {
224
  do_action( 'litespeed_purged_all_ccss' );
225
 
226
+ CSS::get_instance()->rm_cache_folder();
227
 
228
  if ( ! $silence ) {
229
+ $msg = __( 'Cleaned all Critical CSS files.', 'litespeed-cache' );
230
+ ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg );
231
  }
232
  }
233
 
240
  private function _purge_all_lqip( $silence = false ) {
241
  do_action( 'litespeed_purged_all_lqip' );
242
 
243
+ Placeholder::get_instance()->rm_lqip_cache_folder();
244
 
245
  if ( ! $silence ) {
246
+ $msg = __( 'Cleaned all LQIP files.', 'litespeed-cache' );
247
+ ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg );
248
  }
249
  }
250
 
257
  private function _purge_all_avatar( $silence = false ) {
258
  do_action( 'litespeed_purged_all_avatar' );
259
 
260
+ Avatar::get_instance()->rm_cache_folder();
261
 
262
  if ( ! $silence ) {
263
+ $msg = __( 'Cleaned all Gravatar files.', 'litespeed-cache' );
264
+ ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg );
265
  }
266
  }
267
 
334
  return true;
335
  }
336
 
337
+ /**
338
+ * Purge object cache
339
+ *
340
+ * @since 3.4
341
+ * @access public
342
+ */
343
+ public static function purge_all_object( $silence = true ) {
344
+ self::get_instance()->_purge_all_object( $silence );
345
+ }
346
+
347
  /**
348
  * Purge object cache
349
  *
352
  */
353
  private function _purge_all_object( $silence = false ) {
354
  if ( ! defined( 'LSCWP_OBJECT_CACHE' ) ) {
355
+ Debug2::debug( '[Purge] Failed to flush object cache due to object cache not enabled' );
356
 
357
  if ( ! $silence ) {
358
+ $msg = __( 'Object cache is not enabled.', 'litespeed-cache' );
359
+ Admin_Display::error( $msg );
360
  }
361
 
362
+ return false;
363
  }
364
 
365
  do_action( 'litespeed_purged_all_object' );
366
 
367
+ Object_Cache::get_instance()->flush();
368
+ Debug2::debug( '[Purge] Flushed object cache' );
369
 
370
  if ( ! $silence ) {
371
+ $msg = __( 'Purge all object caches successfully.', 'litespeed-cache' );
372
+ ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg );
373
  }
374
 
375
+ return true;
376
  }
377
 
378
  /**
382
  * @access public
383
  * @param mixed $tags Tags to add to the list.
384
  */
385
+ public static function add( $tags ) {
386
+ self::get_instance()->_add( $tags );
 
387
  }
388
 
389
  /**
392
  * @since 2.2
393
  * @access private
394
  */
395
+ private function _add( $tags ) {
 
396
  if ( ! is_array( $tags ) ) {
397
+ $tags = array( $tags );
398
  }
399
  if ( ! array_diff( $tags, $this->_pub_purge ) ) {
400
+ return;
401
  }
402
 
403
+ $this->_pub_purge = array_merge( $this->_pub_purge, $tags );
404
+ Debug2::debug( '[Purge] added ' . implode( ',', $tags ), 8 );
405
 
406
  // Send purge header immediately
407
+ $curr_built = $this->_build();
408
  if ( defined( 'LITESPEED_DID_send_headers' ) ) {
409
  // Can't send, already has output, need to save and wait for next run
410
+ self::update_option( self::DB_QUEUE, $curr_built );
411
+ Debug2::debug( '[Purge] Output existed, queue stored: ' . $curr_built );
412
  }
413
  else {
414
+ @header( $curr_built );
415
+ Debug2::debug( $curr_built );
416
  }
417
 
418
  }
424
  * @access public
425
  * @param mixed $tags Tags to add to the list.
426
  */
427
+ public static function add_private( $tags ) {
428
+ self::get_instance()->_add_private( $tags );
 
429
  }
430
 
431
  /**
434
  * @since 3.0
435
  * @access public
436
  */
437
+ public static function add_private_esi( $tag ) {
 
438
  self::add_private( Tag::TYPE_ESI . $tag );
439
  }
440
 
444
  * @since 3.0
445
  * @access public
446
  */
447
+ public static function add_private_all() {
 
448
  self::add_private( '*' );
449
  }
450
 
454
  * @since 2.2
455
  * @access private
456
  */
457
+ private function _add_private( $tags ) {
 
458
  if ( ! is_array( $tags ) ) {
459
+ $tags = array( $tags );
460
  }
461
  if ( ! array_diff( $tags, $this->_priv_purge ) ) {
462
+ return;
463
  }
464
 
465
+ Debug2::debug( '[Purge] added [private] ' . implode( ',', $tags ), 3 );
466
 
467
+ $this->_priv_purge = array_merge( $this->_priv_purge, $tags );
468
 
469
  // Send purge header immediately
470
+ @header( $this->_build() );
471
  }
472
 
473
  /**
476
  * @since 1.1.3
477
  * @access public
478
  */
479
+ public static function set_purge_related() {
480
+ self::get_instance()->_purge_related = true;
 
481
  }
482
 
483
  /**
486
  * @since 1.1.3
487
  * @access public
488
  */
489
+ public static function set_purge_single() {
490
+ self::get_instance()->_purge_single = true;
 
491
  }
492
 
493
  /**
497
  * @since 2.2 Renamed from `frontend_purge`; Access changed from public
498
  * @access private
499
  */
500
+ private function _purge_front() {
 
501
  if ( empty( $_SERVER[ 'HTTP_REFERER' ] ) ) {
502
+ exit( 'no referer' );
503
  }
504
 
505
+ self::purge_url( $_SERVER[ 'HTTP_REFERER' ] );
506
 
507
+ wp_redirect( $_SERVER[ 'HTTP_REFERER' ] );
508
+ exit();
509
  }
510
 
511
  /**
515
  * @since 2.2 Access changed from public to private, renamed from `_purge_front`
516
  * @access private
517
  */
518
+ private function _purge_frontpage() {
519
+ $this->_add( Tag::TYPE_FRONTPAGE );
 
520
  if ( LITESPEED_SERVER_TYPE !== 'LITESPEED_SERVER_OLS' ) {
521
+ $this->_add_private( Tag::TYPE_FRONTPAGE );
522
  }
523
 
524
+ $msg = __( 'Notified LiteSpeed Web Server to purge the front page.', 'litespeed-cache' );
525
+ ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg );
526
  }
527
 
528
  /**
531
  * @since 1.0.15
532
  * @access private
533
  */
534
+ private function _purge_pages() {
535
+ $this->_add( Tag::TYPE_PAGES );
 
536
 
537
+ $msg = __( 'Notified LiteSpeed Web Server to purge all pages.', 'litespeed-cache' );
538
+ ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg );
539
  }
540
 
541
  /**
544
  * @since 1.0.14
545
  * @access private
546
  */
547
+ private function _purge_error( $type = false ) {
548
+ $this->_add( Tag::TYPE_HTTP );
 
549
 
550
  if ( ! $type || ! in_array( $type, array( '403', '404', '500' ) ) ) {
551
+ return;
552
  }
553
 
554
+ $this->_add( Tag::TYPE_HTTP . $type );
555
 
556
+ $msg = __( 'Notified LiteSpeed Web Server to purge error pages.', 'litespeed-cache' );
557
+ ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( $msg );
558
  }
559
 
560
  /**
563
  * @since 1.0.7
564
  * @access public
565
  */
566
+ public function purge_cat( $value ) {
567
+ $val = trim( $value );
 
568
  if ( empty( $val ) ) {
569
+ return;
570
  }
571
  if ( preg_match( '/^[a-zA-Z0-9-]+$/', $val ) == 0 ) {
572
+ Debug2::debug( "[Purge] $val cat invalid" );
573
+ return;
574
  }
575
+ $cat = get_category_by_slug( $val );
576
  if ( $cat == false ) {
577
+ Debug2::debug( "[Purge] $val cat not existed/published" );
578
+ return;
579
  }
580
 
581
+ self::add( Tag::TYPE_ARCHIVE_TERM . $cat->term_id );
582
 
583
+ ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( sprintf( __( 'Purge category %s', 'litespeed-cache' ), $val ) );
584
  }
585
 
586
 
590
  * @since 1.0.7
591
  * @access public
592
  */
593
+ public static function purge_tag( $val ) {
594
+ $val = trim( $val );
 
595
  if ( empty( $val ) ) {
596
+ return;
597
  }
598
  if ( preg_match( '/^[a-zA-Z0-9-]+$/', $val ) == 0 ) {
599
+ Debug2::debug( "[Purge] $val tag invalid" );
600
+ return;
601
  }
602
+ $term = get_term_by( 'slug', $val, 'post_tag' );
603
  if ( $term == 0 ) {
604
+ Debug2::debug( "[Purge] $val tag not exist" );
605
+ return;
606
  }
607
 
608
+ self::add( Tag::TYPE_ARCHIVE_TERM . $term->term_id );
609
 
610
+ ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( sprintf( __( 'Purge tag %s', 'litespeed-cache' ), $val ) );
611
  }
612
 
613
  /**
616
  * @since 1.0.7
617
  * @access public
618
  */
619
+ public static function purge_url( $url ) {
620
+ $val = trim( $url );
 
621
  if ( empty( $val ) ) {
622
+ return;
623
  }
624
 
625
  if ( strpos( $val, '<' ) !== false ) {
626
+ Debug2::debug( "[Purge] $val url contains <" );
627
+ return;
628
  }
629
 
630
+ $val = Utility::make_relative( $val );
631
 
632
+ $hash = Tag::get_uri_tag( $val );
633
 
634
  if ( $hash === false ) {
635
+ Debug2::debug( "[Purge] $val url invalid" );
636
+ return;
637
  }
638
 
639
+ self::add( $hash );
640
 
641
+ ! defined( 'LITESPEED_PURGE_SILENT' ) && Admin_Display::succeed( sprintf( __( 'Purge url %s', 'litespeed-cache' ), $val ) );
642
  }
643
 
644
  /**
647
  * @since 1.0.7
648
  * @access public
649
  */
650
+ public function purge_list() {
 
651
  if ( ! isset($_REQUEST[Admin_Display::PURGEBYOPT_SELECT]) || ! isset($_REQUEST[Admin_Display::PURGEBYOPT_LIST]) ) {
652
+ return;
653
  }
654
+ $sel = $_REQUEST[Admin_Display::PURGEBYOPT_SELECT];
655
+ $list_buf = $_REQUEST[Admin_Display::PURGEBYOPT_LIST];
656
  if ( empty($list_buf) ) {
657
+ return;
658
  }
659
+ $list_buf = str_replace(",", "\n", $list_buf);// for cli
660
+ $list = explode("\n", $list_buf);
661
  switch($sel) {
662
  case Admin_Display::PURGEBY_CAT:
663
+ $cb = 'purge_cat';
664
+ break;
665
  case Admin_Display::PURGEBY_PID:
666
+ $cb = 'purge_post';
667
+ break;
668
  case Admin_Display::PURGEBY_TAG:
669
+ $cb = 'purge_tag';
670
+ break;
671
  case Admin_Display::PURGEBY_URL:
672
+ $cb = 'purge_url';
673
+ break;
674
 
675
  default:
676
+ return;
677
  }
678
  array_map( __CLASS__ . "::$cb", $list );
679
 
680
  // for redirection
681
+ $_GET[ Admin_Display::PURGEBYOPT_SELECT ] = $sel;
682
  }
683
 
684
  /**
687
  * @since 3.0
688
  * @access public
689
  */
690
+ public static function purge_esi( $tag ) {
 
691
  self::add( Tag::TYPE_ESI . $tag );
692
  }
693
 
697
  * @since 3.0
698
  * @access public
699
  */
700
+ public static function purge_posttype( $post_type ) {
 
701
  self::add( Tag::TYPE_ARCHIVE_POSTTYPE . $post_type );
702
  }
703
 
707
  * @since 1.0.0
708
  * @access public
709
  */
710
+ public static function purge_post( $pid ) {
 
711
  $pid = intval( $pid );
712
  // ignore the status we don't care
713
  if ( ! $pid || ! in_array( get_post_status( $pid ), array( 'publish', 'trash', 'private', 'draft' ) ) ) {
735
  * @since 1.1.3
736
  * @access public
737
  */
738
+ public static function purge_widget( $widget_id = null ) {
 
739
  if ( is_null($widget_id) ) {
740
+ $widget_id = $_POST['widget-id'];
741
  if ( is_null($widget_id) ) {
742
+ return;
743
  }
744
  }
745
+ self::add(Tag::TYPE_WIDGET . $widget_id);
746
+ self::add_private(Tag::TYPE_WIDGET . $widget_id);
747
  }
748
 
749
  /**
754
  * @since 1.1.3
755
  * @global type $wp_widget_factory
756
  */
757
+ public static function purge_comment_widget() {
758
+ global $wp_widget_factory;
759
+ $recent_comments = $wp_widget_factory->widgets['WP_Widget_Recent_Comments'];
 
760
  if ( !is_null($recent_comments) ) {
761
+ self::add(Tag::TYPE_WIDGET . $recent_comments->id);
762
+ self::add_private(Tag::TYPE_WIDGET . $recent_comments->id);
763
  }
764
  }
765
 
769
  * @since 1.0.9
770
  * @access public
771
  */
772
+ public static function purge_feeds() {
 
773
  if ( Conf::val(Base::O_CACHE_TTL_FEED) > 0 ) {
774
+ self::add(Tag::TYPE_FEED);
775
  }
776
  }
777
 
781
  * @access public
782
  * @since 1.1.3
783
  */
784
+ public static function purge_on_logout() {
785
+ self::add_private('*');
 
786
  }
787
 
788
  /**
791
  * @access private
792
  * @since 1.1.3
793
  */
794
+ private function _finalize() {
 
795
  // Make sure header output only run once
796
  if ( ! defined( 'LITESPEED_DID_' . __FUNCTION__ ) ) {
797
+ define( 'LITESPEED_DID_' . __FUNCTION__, true );
798
  }
799
  else {
800
+ return;
801
  }
802
 
803
+ do_action('litespeed_purge_finalize');
804
 
805
  // Append unique uri purge tags if Admin QS is `PURGESINGLE`
806
  if ( $this->_purge_single ) {
807
+ $this->_pub_purge[] = Tag::build_uri_tag(); // TODO: add private tag too
808
  }
809
  // Append related purge tags if Admin QS is `PURGE`
810
  if ( $this->_purge_related ) {
811
  // Before this, tags need to be finalized
812
+ $tags_related = Tag::output_tags();
813
  // NOTE: need to remove the empty item `B1_` to avoid purging all
814
+ $tags_related = array_filter($tags_related);
815
  if ( $tags_related ) {
816
+ $this->_pub_purge = array_merge($this->_pub_purge, $tags_related);
817
  }
818
  }
819
 
820
  if ( ! empty($this->_pub_purge) ) {
821
+ $this->_pub_purge = array_unique($this->_pub_purge);
822
  }
823
 
824
  if ( ! empty($this->_priv_purge) ) {
825
+ $this->_priv_purge = array_unique($this->_priv_purge);
826
  }
827
  }
828
 
835
  * @access public
836
  * @return string the built purge header
837
  */
838
+ public static function output() {
839
+ $instance = self::get_instance();
 
840
 
841
+ $instance->_finalize();
842
 
843
+ return $instance->_build();
844
  }
845
 
846
  /**
850
  * @access private
851
  * @return string the built purge header
852
  */
853
+ private function _build() {
 
854
  if ( empty( $this->_pub_purge ) && empty( $this->_priv_purge ) ) {
855
+ return;
856
  }
857
 
858
+ $purge_header = '';
859
+ $private_prefix = self::X_HEADER . ': private,';
860
 
861
  if ( ! empty( $this->_pub_purge ) ) {
862
+ $public_tags = $this->_append_prefix( $this->_pub_purge );
863
  if ( empty( $public_tags ) ) {
864
  // If this ends up empty, private will also end up empty
865
+ return;
866
  }
867
+ $purge_header = self::X_HEADER . ': public,';
868
  if ( Control::is_stale() ) {
869
+ $purge_header .= 'stale,';
870
  }
871
+ $purge_header .= implode( ',', $public_tags );
872
+ $private_prefix = ';private,';
873
  }
874
 
875
  // Handle priv purge tags
876
  if ( ! empty( $this->_priv_purge ) ) {
877
+ $private_tags = $this->_append_prefix( $this->_priv_purge, true );
878
+ $purge_header .= $private_prefix . implode( ',', $private_tags );
879
  }
880
 
881
+ return $purge_header;
882
  }
883
 
884
  /**
887
  * @since 1.1.0
888
  * @access private
889
  */
890
+ private function _append_prefix( $purge_tags, $is_private = false ) {
 
891
  $curr_bid = is_multisite() ? get_current_blog_id() : '';
892
 
893
  if ( ! in_array( '*', $purge_tags ) ) {
911
  if ( is_multisite() && (is_network_admin() || (
912
  Router::is_ajax() && (check_ajax_referer('updates', false, false) || check_ajax_referer('litespeed-purgeall-network', false, false))
913
  )) ) {
914
+ $blogs = Activation::get_network_ids();
915
  if ( empty($blogs) ) {
916
+ Debug2::debug('[Purge] build_purge_headers: blog list is empty');
917
+ return '';
918
  }
919
+ $tags = array();
920
  foreach ($blogs as $blog_id) {
921
+ $tags[] = LSWCP_TAG_PREFIX . $blog_id . '_';
922
  }
923
+ return $tags;
924
  }
925
  else {
926
+ return array(LSWCP_TAG_PREFIX . $curr_bid . '_');
927
  }
928
  }
929
 
937
  * @since 1.0.0
938
  * @access private
939
  */
940
+ private function _get_purge_tags_by_post( $post_id ) {
 
941
  // If this is a valid post we want to purge the post, the home page and any associated tags & cats
942
  // If not, purge everything on the site.
943
 
944
+ $purge_tags = array();
945
+ $config = Conf::get_instance();
946
 
947
  if ( Conf::val( Base::O_PURGE_POST_ALL ) ) {
948
  // ignore the rest if purge all
949
+ return array( '*' );
950
  }
951
 
952
  // now do API hook action for post purge
953
+ do_action('litespeed_api_purge_post', $post_id);
954
 
955
  // post
956
+ $purge_tags[] = Tag::TYPE_POST . $post_id;
957
+ $purge_tags[] = Tag::get_uri_tag(wp_make_link_relative(get_permalink($post_id)));
958
 
959
  // for archive of categories|tags|custom tax
960
+ global $post;
961
+ $original_post = $post;
962
+ $post = get_post($post_id);
963
+ $post_type = $post->post_type;
964
 
965
+ global $wp_widget_factory;
966
+ $recent_posts = $wp_widget_factory->widgets['WP_Widget_Recent_Posts'];
967
  if ( ! is_null($recent_posts) ) {
968
+ $purge_tags[] = Tag::TYPE_WIDGET . $recent_posts->id;
969
  }
970
 
971
  // get adjacent posts id as related post tag
972
  if( $post_type == 'post' ){
973
+ $prev_post = get_previous_post();
974
+ $next_post = get_next_post();
975
  if( ! empty($prev_post->ID) ) {
976
+ $purge_tags[] = Tag::TYPE_POST . $prev_post->ID;
977
+ Debug2::debug('--------purge_tags prev is: '.$prev_post->ID);
978
  }
979
  if( ! empty($next_post->ID) ) {
980
+ $purge_tags[] = Tag::TYPE_POST . $next_post->ID;
981
+ Debug2::debug('--------purge_tags next is: '.$next_post->ID);
982
  }
983
  }
984
 
985
  if ( Conf::val( Base::O_PURGE_POST_TERM ) ) {
986
+ $taxonomies = get_object_taxonomies($post_type);
987
+ //Debug2::debug('purge by post, check tax = ' . var_export($taxonomies, true));
988
  foreach ( $taxonomies as $tax ) {
989
+ $terms = get_the_terms($post_id, $tax);
990
  if ( ! empty($terms) ) {
991
  foreach ( $terms as $term ) {
992
+ $purge_tags[] = Tag::TYPE_ARCHIVE_TERM . $term->term_id;
993
  }
994
  }
995
  }
996
  }
997
 
998
  if ( Conf::val( Base::O_CACHE_TTL_FEED ) ) {
999
+ $purge_tags[] = Tag::TYPE_FEED;
1000
  }
1001
 
1002
  // author, for author posts and feed list
1003
  if ( Conf::val( Base::O_PURGE_POST_AUTHOR) ) {
1004
+ $purge_tags[] = Tag::TYPE_AUTHOR . get_post_field('post_author', $post_id);
1005
  }
1006
 
1007
  // archive and feed of post type
1008
  // todo: check if type contains space
1009
  if ( Conf::val( Base::O_PURGE_POST_POSTTYPE) ) {
1010
  if ( get_post_type_archive_link($post_type) ) {
1011
+ $purge_tags[] = Tag::TYPE_ARCHIVE_POSTTYPE . $post_type;
1012
  }
1013
  }
1014
 
1015
  if ( Conf::val( Base::O_PURGE_POST_FRONTPAGE) ) {
1016
+ $purge_tags[] = Tag::TYPE_FRONTPAGE;
1017
  }
1018
 
1019
  if ( Conf::val( Base::O_PURGE_POST_HOMEPAGE) ) {
1020
+ $purge_tags[] = Tag::TYPE_HOME;
1021
  }
1022
 
1023
  if ( Conf::val( Base::O_PURGE_POST_PAGES) ) {
1024
+ $purge_tags[] = Tag::TYPE_PAGES;
1025
  }
1026
 
1027
  if ( Conf::val( Base::O_PURGE_POST_PAGES_WITH_RECENT_POSTS) ) {
1028
+ $purge_tags[] = Tag::TYPE_PAGES_WITH_RECENT_POSTS;
1029
  }
1030
 
1031
  // if configured to have archived by date
1032
+ $date = $post->post_date;
1033
+ $date = strtotime($date);
1034
 
1035
  if ( Conf::val( Base::O_PURGE_POST_DATE) ) {
1036
+ $purge_tags[] = Tag::TYPE_ARCHIVE_DATE . date('Ymd', $date);
1037
  }
1038
 
1039
  if ( Conf::val( Base::O_PURGE_POST_MONTH) ) {
1040
+ $purge_tags[] = Tag::TYPE_ARCHIVE_DATE . date('Ym', $date);
1041
  }
1042
 
1043
  if ( Conf::val( Base::O_PURGE_POST_YEAR) ) {
1044
+ $purge_tags[] = Tag::TYPE_ARCHIVE_DATE . date('Y', $date);
1045
  }
1046
 
1047
  // Set back to original post as $post_id might affecting the global $post value
1048
+ $post = $original_post;
1049
 
1050
+ return array_unique($purge_tags);
1051
  }
1052
 
1053
  /**
1058
  * @param string $val The filter value
1059
  * @return string The filter value
1060
  */
1061
+ public static function filter_with_purge_all( $val ) {
1062
+ self::purge_all();
1063
+ return $val;
 
1064
  }
1065
  }
src/utility.cls.php CHANGED
@@ -5,9 +5,9 @@
5
  * @since 1.1.5
6
  * @since 1.5 Moved into /inc
7
  */
8
- namespace LiteSpeed ;
9
 
10
- defined( 'WPINC' ) || exit ;
11
 
12
  class Utility extends Instance {
13
  protected static $_instance;
@@ -22,20 +22,20 @@ class Utility extends Instance {
22
  * @return bool True for valid rules, false otherwise.
23
  */
24
  public static function syntax_checker( $rules ) {
25
- $success = true ;
26
 
27
- set_error_handler( 'litespeed_exception_handler' ) ;
28
 
29
  try {
30
- preg_match( self::arr2regex( $rules ), null ) ;
31
  }
32
  catch ( \ErrorException $e ) {
33
- $success = false ;
34
  }
35
 
36
- restore_error_handler() ;
37
 
38
- return $success ;
39
  }
40
 
41
  /**
@@ -86,9 +86,8 @@ class Utility extends Instance {
86
  * @deprecated 2.9.4 Moved to REST class
87
  * @access public
88
  */
89
- public static function is_rest( $url = false )
90
- {
91
- return false ;
92
  }
93
 
94
  /**
@@ -96,80 +95,79 @@ class Utility extends Instance {
96
  *
97
  * @since 2.9
98
  */
99
- public static function page_type()
100
- {
101
- global $wp_query ;
102
- $page_type = 'default' ;
103
 
104
  if ( $wp_query->is_page ) {
105
- $page_type = is_front_page() ? 'front' : 'page' ;
106
  }
107
  elseif ( $wp_query->is_home ) {
108
- $page_type = 'home' ;
109
  }
110
  elseif ( $wp_query->is_single ) {
111
- // $page_type = $wp_query->is_attachment ? 'attachment' : 'single' ;
112
- $page_type = get_post_type() ;
113
  }
114
  elseif ( $wp_query->is_category ) {
115
- $page_type = 'category' ;
116
  }
117
  elseif ( $wp_query->is_tag ) {
118
- $page_type = 'tag' ;
119
  }
120
  elseif ( $wp_query->is_tax ) {
121
- $page_type = 'tax' ;
122
- // $page_type = get_queried_object()->taxonomy ;
123
  }
124
  elseif ( $wp_query->is_archive ) {
125
  if ( $wp_query->is_day ) {
126
- $page_type = 'day' ;
127
  }
128
  elseif ( $wp_query->is_month ) {
129
- $page_type = 'month' ;
130
  }
131
  elseif ( $wp_query->is_year ) {
132
- $page_type = 'year' ;
133
  }
134
  elseif ( $wp_query->is_author ) {
135
- $page_type = 'author' ;
136
  }
137
  else {
138
- $page_type = 'archive' ;
139
  }
140
  }
141
  elseif ( $wp_query->is_search ) {
142
- $page_type = 'search' ;
143
  }
144
  elseif ( $wp_query->is_404 ) {
145
- $page_type = '404' ;
146
  }
147
 
148
  return $page_type;
149
 
150
  // if ( is_404() ) {
151
- // $page_type = '404' ;
152
  // }
153
  // elseif ( is_singular() ) {
154
- // $page_type = get_post_type() ;
155
  // }
156
  // elseif ( is_home() && get_option( 'show_on_front' ) == 'page' ) {
157
- // $page_type = 'home' ;
158
  // }
159
  // elseif ( is_front_page() ) {
160
- // $page_type = 'front' ;
161
  // }
162
  // elseif ( is_tax() ) {
163
- // $page_type = get_queried_object()->taxonomy ;
164
  // }
165
  // elseif ( is_category() ) {
166
- // $page_type = 'category' ;
167
  // }
168
  // elseif ( is_tag() ) {
169
- // $page_type = 'tag' ;
170
  // }
171
 
172
- // return $page_type ;
173
  }
174
 
175
  /**
@@ -177,26 +175,25 @@ class Utility extends Instance {
177
  *
178
  * @since 2.9
179
  */
180
- public static function ping( $domain )
181
- {
182
  if ( strpos( $domain, ':' ) ) {
183
- $domain = parse_url( $domain, PHP_URL_HOST ) ;
184
  }
185
- $starttime = microtime( true ) ;
186
- $file = fsockopen( $domain, 443, $errno, $errstr, 10 ) ;
187
- $stoptime = microtime( true ) ;
188
- $status = 0 ;
189
 
190
- if ( ! $file ) $status = 99999 ;// Site is down
191
  else {
192
- fclose( $file ) ;
193
- $status = ( $stoptime - $starttime ) * 1000 ;
194
- $status = floor( $status ) ;
195
  }
196
 
197
- Debug2::debug( "[Util] ping [Domain] $domain \t[Speed] $status" ) ;
198
 
199
- return $status ;
200
  }
201
 
202
  /**
@@ -205,49 +202,48 @@ class Utility extends Instance {
205
  * @since 1.6.5
206
  * @access public
207
  */
208
- public static function readable_time( $seconds_or_timestamp, $timeout = 3600, $forword = false )
209
- {
210
 
211
  if ( strlen( $seconds_or_timestamp ) == 10 ) {
212
- $seconds = time() - $seconds_or_timestamp ;
213
  if ( $seconds > $timeout ) {
214
- return date( 'm/d/Y H:i:s', $seconds_or_timestamp + LITESPEED_TIME_OFFSET ) ;
215
  }
216
  }
217
  else {
218
- $seconds = $seconds_or_timestamp ;
219
  }
220
 
221
  $res = '';
222
  if ( $seconds > 86400 ) {
223
- $num = floor( $seconds / 86400 ) ;
224
- $res .= $num . 'd' ;
225
- $seconds %= 86400 ;
226
  }
227
 
228
  if ( $seconds > 3600 ) {
229
  if ( $res ) {
230
- $res .= ', ' ;
231
  }
232
- $num = floor( $seconds / 3600 ) ;
233
- $res .= $num . 'h' ;
234
- $seconds %= 3600 ;
235
  }
236
 
237
  if ( $seconds > 60 ) {
238
  if ( $res ) {
239
- $res .= ', ' ;
240
  }
241
- $num = floor( $seconds / 60 ) ;
242
- $res .= $num . 'm' ;
243
- $seconds %= 60 ;
244
  }
245
 
246
  if ( $seconds > 0 ) {
247
  if ( $res ) {
248
- $res .= ' ' ;
249
  }
250
- $res .= $seconds . 's' ;
251
  }
252
 
253
  if ( ! $res ) {
@@ -256,7 +252,7 @@ class Utility extends Instance {
256
 
257
  $res = $forword ? $res : sprintf( __( ' %s ago', 'litespeed-cache' ), $res );
258
 
259
- return $res ;
260
  }
261
 
262
 
@@ -266,13 +262,12 @@ class Utility extends Instance {
266
  * @since 1.6
267
  * @access public
268
  */
269
- public static function arr2str( $arr )
270
- {
271
  if ( ! is_array( $arr ) ) {
272
- return $arr ;
273
  }
274
 
275
- return base64_encode( json_encode( $arr ) ) ;
276
  }
277
 
278
  /**
@@ -281,8 +276,7 @@ class Utility extends Instance {
281
  * @since 1.6
282
  * @access public
283
  */
284
- public static function real_size( $filesize, $is_1000 = false )
285
- {
286
  $unit = $is_1000 ? 1000 : 1024;
287
 
288
  if ( $filesize >= pow( $unit, 3 ) ) {
@@ -309,14 +303,13 @@ class Utility extends Instance {
309
  * @param string $str
310
  * @return array All the attributes
311
  */
312
- public static function parse_attr( $str )
313
- {
314
- $attrs = array() ;
315
- preg_match_all( '#([\w-]+)=["\']([^"\']*)["\']#isU', $str, $matches, PREG_SET_ORDER ) ;
316
  foreach ( $matches as $match ) {
317
- $attrs[ $match[ 1 ] ] = trim( $match[ 2 ] ) ;
318
  }
319
- return $attrs ;
320
  }
321
 
322
  /**
@@ -330,65 +323,64 @@ class Utility extends Instance {
330
  * @param array $haystack
331
  * @return bool|string False if not found, otherwise return the matched string in haystack.
332
  */
333
- public static function str_hit_array( $needle, $haystack, $has_ttl = false )
334
- {
335
  /**
336
  * Safety check to avoid PHP warning
337
  * @see https://github.com/litespeedtech/lscache_wp/pull/131/commits/45fc03af308c7d6b5583d1664fad68f75fb6d017
338
  */
339
  if ( ! is_array( $haystack ) ) {
340
- Debug2::debug( "[Util] ❌ bad param in str_hit_array()!" ) ;
341
 
342
- return false ;
343
  }
344
 
345
- $hit = false ;
346
- $this_ttl = 0 ;
347
  foreach( $haystack as $item ) {
348
  if ( ! $item ) {
349
- continue ;
350
  }
351
 
352
  if ( $has_ttl ) {
353
- $this_ttl = 0 ;
354
- $item = explode( ' ', $item ) ;
355
  if ( ! empty( $item[ 1 ] ) ) {
356
- $this_ttl = $item[ 1 ] ;
357
  }
358
- $item = $item[ 0 ] ;
359
  }
360
 
361
  if ( substr( $item, -1 ) === '$' ) {
362
  // do exact match
363
  if ( substr( $item, 0, -1 ) === $needle ) {
364
- $hit = $item ;
365
- break ;
366
  }
367
  }
368
  elseif ( substr( $item, 0, 1 ) === '^' ) {
369
  // match beginning
370
  if ( substr( $item, 1 ) === substr( $needle, 0, strlen( $item ) - 1 ) ) {
371
- $hit = $item ;
372
- break ;
373
  }
374
  }
375
  else {
376
  if ( strpos( $needle, $item ) !== false ) {
377
- $hit = $item ;
378
- break ;
379
  }
380
  }
381
  }
382
 
383
  if ( $hit ) {
384
  if ( $has_ttl ) {
385
- return array( $hit, $this_ttl ) ;
386
  }
387
 
388
- return $hit ;
389
  }
390
 
391
- return false ;
392
  }
393
 
394
  /**
@@ -397,9 +389,8 @@ class Utility extends Instance {
397
  * @since 1.2.2
398
  *
399
  */
400
- public static function compatibility()
401
- {
402
- require_once LSCWP_DIR . 'lib/php-compatibility.func.php' ;
403
  }
404
 
405
  /**
@@ -410,17 +401,16 @@ class Utility extends Instance {
410
  * @param string $uri `xx/xx.html` or `/subfolder/xx/xx.html`
411
  * @return string http://www.example.com/subfolder/xx/xx.html
412
  */
413
- public static function uri2url( $uri )
414
- {
415
  if ( substr( $uri, 0, 1 ) === '/' ) {
416
- self::domain_const() ;
417
- $url = LSCWP_DOMAIN . $uri ;
418
  }
419
  else {
420
- $url = home_url( '/' ) . $uri ;
421
  }
422
 
423
- return $url ;
424
  }
425
 
426
  /**
@@ -430,17 +420,16 @@ class Utility extends Instance {
430
  * @since 1.6.2.1 Added 2nd param keep_qs
431
  * @access public
432
  */
433
- public static function url2uri( $url, $keep_qs = false )
434
- {
435
- $url = trim( $url ) ;
436
- $uri = @parse_url( $url, PHP_URL_PATH ) ;
437
- $qs = @parse_url( $url, PHP_URL_QUERY ) ;
438
 
439
  if ( ! $keep_qs || ! $qs ) {
440
- return $uri ;
441
  }
442
 
443
- return $uri . '?' . $qs ;
444
  }
445
 
446
  /**
@@ -451,21 +440,20 @@ class Utility extends Instance {
451
  * @param string `https://aa.com/bbb/wp-content/upload/2018/08/test.jpg` or `/bbb/wp-content/upload/2018/08/test.jpg`
452
  * @return string `2018/08/test.jpg`
453
  */
454
- public static function att_short_path( $url )
455
- {
456
  if ( ! defined( 'LITESPEED_UPLOAD_PATH' ) ) {
457
- $_wp_upload_dir = wp_upload_dir() ;
458
 
459
- $upload_path = self::url2uri( $_wp_upload_dir[ 'baseurl' ] ) ;
460
 
461
- define( 'LITESPEED_UPLOAD_PATH', $upload_path ) ;
462
  }
463
 
464
- $local_file = self::url2uri( $url ) ;
465
 
466
- $short_path = substr( $local_file, strlen( LITESPEED_UPLOAD_PATH ) + 1 ) ;
467
 
468
- return $short_path ;
469
  }
470
 
471
  /**
@@ -476,14 +464,13 @@ class Utility extends Instance {
476
  * @param string $url
477
  * @return string Relative URL, start with /
478
  */
479
- public static function make_relative( $url )
480
- {
481
  // replace home_url if the url is full url
482
- self::domain_const() ;
483
  if ( strpos( $url, LSCWP_DOMAIN ) === 0 ) {
484
- $url = substr( $url, strlen( LSCWP_DOMAIN ) ) ;
485
  }
486
- return trim( $url ) ;
487
  }
488
 
489
  /**
@@ -491,18 +478,17 @@ class Utility extends Instance {
491
  *
492
  * @since 1.7.1
493
  */
494
- public static function parse_domain( $url )
495
- {
496
- $url = @parse_url( $url ) ;
497
  if ( empty( $url[ 'host' ] ) ) {
498
- return '' ;
499
  }
500
 
501
  if ( ! empty( $url[ 'scheme' ] ) ) {
502
- return $url[ 'scheme' ] . '://' . $url[ 'host' ] ;
503
  }
504
 
505
- return '//' . $url[ 'host' ] ;
506
  }
507
 
508
  /**
@@ -529,16 +515,15 @@ class Utility extends Instance {
529
  * @since 1.3
530
  * @access public
531
  */
532
- public static function domain_const()
533
- {
534
  if ( defined( 'LSCWP_DOMAIN' ) ) {
535
- return ;
536
  }
537
 
538
- self::compatibility() ;
539
- $domain = http_build_url( get_home_url(), array(), HTTP_URL_STRIP_ALL ) ;
540
 
541
- define( 'LSCWP_DOMAIN', $domain ) ;
542
  }
543
 
544
  /**
@@ -553,28 +538,28 @@ class Utility extends Instance {
553
  public static function sanitize_lines( $arr, $type = null ) {
554
  if ( ! $arr ) {
555
  if ( $type === 'string' ) {
556
- return '' ;
557
  }
558
- return array() ;
559
  }
560
 
561
  if ( ! is_array( $arr ) ) {
562
- $arr = explode( "\n", $arr ) ;
563
  }
564
 
565
- $arr = array_map( 'trim', $arr ) ;
566
- $changed = false ;
567
  if ( $type === 'uri' ) {
568
- $arr = array_map( __CLASS__ . '::url2uri', $arr ) ;
569
- $changed = true ;
570
  }
571
  if ( $type === 'relative' ) {
572
- $arr = array_map( __CLASS__ . '::make_relative', $arr ) ;// Remove domain
573
- $changed = true ;
574
  }
575
  if ( $type === 'domain' ) {
576
- $arr = array_map( __CLASS__ . '::parse_domain', $arr ) ;// Only keep domain
577
- $changed = true ;
578
  }
579
 
580
  if ( $type === 'noprotocol' ) {
@@ -583,16 +568,16 @@ class Utility extends Instance {
583
  }
584
 
585
  if ( $changed ) {
586
- $arr = array_map( 'trim', $arr ) ;
587
  }
588
- $arr = array_unique( $arr ) ;
589
- $arr = array_filter( $arr ) ;
590
 
591
  if ( $type === 'string' ) {
592
- return implode( "\n", $arr ) ;
593
  }
594
 
595
- return $arr ;
596
  }
597
 
598
  /**
@@ -604,8 +589,7 @@ class Utility extends Instance {
604
  * @access public
605
  * @return string The built url.
606
  */
607
- public static function build_url( $action, $type = false, $is_ajax = false, $page = null, $append_arr = array() )
608
- {
609
  $prefix = '?';
610
 
611
  if ( $page === '_ori' ) {
@@ -617,62 +601,62 @@ class Utility extends Instance {
617
  if ( $page ) {
618
  // If use admin url
619
  if ( $page === true ) {
620
- $page = 'admin.php' ;
621
  }
622
  else {
623
  if ( strpos( $page, '?' ) !== false ) {
624
- $prefix = '&' ;
625
  }
626
  }
627
- $combined = $page . $prefix . Router::ACTION . '=' . $action ;
628
  }
629
  else {
630
  // Current page rebuild URL
631
- $params = $_GET ;
632
 
633
  if ( ! empty( $params ) ) {
634
  if ( isset( $params[ Router::ACTION ] ) ) {
635
- unset( $params[ Router::ACTION ] ) ;
636
  }
637
  if ( isset( $params[ '_wpnonce' ] ) ) {
638
- unset( $params[ '_wpnonce' ] ) ;
639
  }
640
  if ( ! empty( $params ) ) {
641
- $prefix .= http_build_query( $params ) . '&' ;
642
  }
643
  }
644
- global $pagenow ;
645
- $combined = $pagenow . $prefix . Router::ACTION . '=' . $action ;
646
  }
647
  }
648
  else {
649
- $combined = 'admin-ajax.php?action=litespeed_ajax&' . Router::ACTION . '=' . $action ;
650
  }
651
 
652
  if ( is_network_admin() ) {
653
- $prenonce = network_admin_url( $combined ) ;
654
  }
655
  else {
656
- $prenonce = admin_url( $combined ) ;
657
  }
658
- $url = wp_nonce_url( $prenonce, $action, Router::NONCE ) ;
659
 
660
  if ( $type ) {
661
  // Remove potential param `type` from url
662
- $url = parse_url( htmlspecialchars_decode( $url ) ) ;
663
- parse_str( $url[ 'query' ], $query ) ;
664
 
665
- $built_arr = array_merge( $query, array( Router::TYPE => $type ) ) ;
666
  if ( $append_arr ) {
667
- $built_arr = array_merge( $built_arr, $append_arr ) ;
668
  }
669
- $url[ 'query' ] = http_build_query( $built_arr ) ;
670
- self::compatibility() ;
671
- $url = http_build_url( $url ) ;
672
- $url = htmlspecialchars( $url, ENT_QUOTES, 'UTF-8' ) ;
673
  }
674
 
675
- return $url ;
676
  }
677
 
678
  /**
@@ -681,20 +665,19 @@ class Utility extends Instance {
681
  * @since 1.2.3
682
  *
683
  */
684
- public static function internal( $host )
685
- {
686
  if ( ! defined( 'LITESPEED_FRONTEND_HOST' ) ) {
687
  if ( defined( 'WP_HOME' ) ) {
688
- $home_host = WP_HOME ;// Also think of `WP_SITEURL`
689
  }
690
  else {
691
- $home_host = get_option( 'home' ) ;
692
  }
693
- define( 'LITESPEED_FRONTEND_HOST', parse_url( $home_host, PHP_URL_HOST ) ) ;
694
  }
695
 
696
  if ( $host === LITESPEED_FRONTEND_HOST ) {
697
- return true ;
698
  }
699
 
700
  /**
@@ -702,14 +685,14 @@ class Utility extends Instance {
702
  * @since 2.9.4
703
  */
704
  if ( ! isset( self::$_internal_domains ) ) {
705
- self::$_internal_domains = apply_filters( 'litespeed_internal_domains', array() ) ;
706
  }
707
 
708
  if ( self::$_internal_domains ) {
709
- return in_array( $host, self::$_internal_domains ) ;
710
  }
711
 
712
- return false ;
713
  }
714
 
715
  /**
@@ -720,34 +703,33 @@ class Utility extends Instance {
720
  * @access public
721
  * @return string|bool The real path of file OR false
722
  */
723
- public static function is_internal_file( $url, $addition_postfix = false )
724
- {
725
- $url_parsed = parse_url( $url ) ;
726
  if ( isset( $url_parsed[ 'host' ] ) && ! self::internal( $url_parsed[ 'host' ] ) ) {
727
  // Check if is cdn path
728
  // Do this to avoid user hardcoded src in tpl
729
  if ( ! CDN::internal( $url_parsed[ 'host' ] ) ) {
730
- Debug2::debug2( '[Util] external' ) ;
731
- return false ;
732
  }
733
  }
734
 
735
  if ( empty( $url_parsed[ 'path' ] ) ) {
736
- return false ;
737
  }
738
 
739
  // Need to replace child blog path for assets, ref: .htaccess
740
  if ( is_multisite() && defined( 'PATH_CURRENT_SITE' ) ) {
741
- $pattern = '#^' . PATH_CURRENT_SITE . '([_0-9a-zA-Z-]+/)(wp-(content|admin|includes))#U' ;
742
- $replacement = PATH_CURRENT_SITE . '$2' ;
743
- $url_parsed[ 'path' ] = preg_replace( $pattern, $replacement, $url_parsed[ 'path' ] ) ;
744
- // $current_blog = (int) get_current_blog_id() ;
745
- // $main_blog_id = (int) get_network()->site_id ;
746
  // if ( $current_blog === $main_blog_id ) {
747
- // define( 'LITESPEED_IS_MAIN_BLOG', true ) ;
748
  // }
749
  // else {
750
- // define( 'LITESPEED_IS_MAIN_BLOG', false ) ;
751
  // }
752
  }
753
 
@@ -755,21 +737,21 @@ class Utility extends Instance {
755
  /**
756
  * Trying to fix pure /.htaccess rewrite to /wordpress case
757
  *
758
- * Add `define( 'LITESPEED_WP_REALPATH', '/wordpress' ) ;` in wp-config.php in this case
759
  *
760
  * @internal #611001 - Combine & Minify not working?
761
  * @since 1.6.3
762
  */
763
  if ( substr( $url_parsed[ 'path' ], 0, 1 ) === '/' ) {
764
  if ( defined( 'LITESPEED_WP_REALPATH' ) ) {
765
- $file_path_ori = $_SERVER[ 'DOCUMENT_ROOT' ] . LITESPEED_WP_REALPATH . $url_parsed[ 'path' ] ;
766
  }
767
  else {
768
- $file_path_ori = $_SERVER[ 'DOCUMENT_ROOT' ] . $url_parsed[ 'path' ] ;
769
  }
770
  }
771
  else {
772
- $file_path_ori = Router::frontend_path() . '/' . $url_parsed[ 'path' ] ;
773
  }
774
 
775
  /**
@@ -777,7 +759,7 @@ class Utility extends Instance {
777
  * @since 2.2.4
778
  */
779
  if ( $addition_postfix ) {
780
- $file_path_ori .= '.' . $addition_postfix ;
781
  }
782
 
783
  /**
@@ -785,15 +767,15 @@ class Utility extends Instance {
785
  * @see #101091 plugin `Hide My WordPress`
786
  * @since 2.2.3
787
  */
788
- $file_path_ori = apply_filters( 'litespeed_realpath', $file_path_ori ) ;
789
 
790
- $file_path = realpath( $file_path_ori ) ;
791
  if ( ! is_file( $file_path ) ) {
792
- Debug2::debug2( '[Util] file not exist: ' . $file_path_ori ) ;
793
- return false ;
794
  }
795
 
796
- return array( $file_path, filesize( $file_path ) ) ;
797
  }
798
 
799
  /**
@@ -801,48 +783,47 @@ class Utility extends Instance {
801
  *
802
  * @since 2.2.3
803
  */
804
- public static function srcset_replace( $content, $callback )
805
- {
806
- preg_match_all( '# srcset=([\'"])(.+)\g{1}#iU', $content, $matches ) ;
807
- $srcset_ori = array() ;
808
- $srcset_final = array() ;
809
  foreach ( $matches[ 2 ] as $k => $urls_ori ) {
810
 
811
- $urls_final = explode( ',', $urls_ori ) ;
812
 
813
- $changed = false ;
814
 
815
  foreach ( $urls_final as $k2 => $url_info ) {
816
  $url_info_arr = explode( ' ', trim( $url_info ) );
817
 
818
  if ( ! $url2 = call_user_func( $callback, $url_info_arr[ 0 ] ) ) {
819
- continue ;
820
  }
821
 
822
- $changed = true ;
823
 
824
- $urls_final[ $k2 ] = str_replace( $url_info_arr[ 0 ], $url2, $url_info ) ;
825
 
826
- Debug2::debug2( '[Util] - srcset replaced to ' . $url2 . ( ! empty( $url_info_arr[ 1 ] ) ? ' ' . $url_info_arr[ 1 ] : '' ) ) ;
827
  }
828
 
829
  if ( ! $changed ) {
830
- continue ;
831
  }
832
 
833
- $urls_final = implode( ',', $urls_final ) ;
834
 
835
- $srcset_ori[] = $matches[ 0 ][ $k ] ;
836
 
837
- $srcset_final[] = str_replace( $urls_ori, $urls_final, $matches[ 0 ][ $k ] ) ;
838
  }
839
 
840
  if ( $srcset_ori ) {
841
- $content = str_replace( $srcset_ori, $srcset_final, $content ) ;
842
- Debug2::debug2( '[Util] - srcset replaced' ) ;
843
  }
844
 
845
- return $content ;
846
 
847
  }
848
 
@@ -852,8 +833,7 @@ class Utility extends Instance {
852
  * @since 3.0
853
  * @access public
854
  */
855
- public static function pagination( $total, $limit, $return_offset = false )
856
- {
857
  $pagenum = isset( $_GET[ 'pagenum' ] ) ? absint( $_GET[ 'pagenum' ] ) : 1;
858
 
859
  $offset = ( $pagenum - 1 ) * $limit;
@@ -889,8 +869,7 @@ class Utility extends Instance {
889
  * @since 2.0
890
  * @access public
891
  */
892
- public static function chunk_placeholder( $data, $fields )
893
- {
894
  $division = substr_count( $fields, ',' ) + 1;
895
 
896
  $q = implode( ',', array_map(
5
  * @since 1.1.5
6
  * @since 1.5 Moved into /inc
7
  */
8
+ namespace LiteSpeed;
9
 
10
+ defined( 'WPINC' ) || exit;
11
 
12
  class Utility extends Instance {
13
  protected static $_instance;
22
  * @return bool True for valid rules, false otherwise.
23
  */
24
  public static function syntax_checker( $rules ) {
25
+ $success = true;
26
 
27
+ set_error_handler( 'litespeed_exception_handler' );
28
 
29
  try {
30
+ preg_match( self::arr2regex( $rules ), null );
31
  }
32
  catch ( \ErrorException $e ) {
33
+ $success = false;
34
  }
35
 
36
+ restore_error_handler();
37
 
38
+ return $success;
39
  }
40
 
41
  /**
86
  * @deprecated 2.9.4 Moved to REST class
87
  * @access public
88
  */
89
+ public static function is_rest( $url = false ) {
90
+ return false;
 
91
  }
92
 
93
  /**
95
  *
96
  * @since 2.9
97
  */
98
+ public static function page_type() {
99
+ global $wp_query;
100
+ $page_type = 'default';
 
101
 
102
  if ( $wp_query->is_page ) {
103
+ $page_type = is_front_page() ? 'front' : 'page';
104
  }
105
  elseif ( $wp_query->is_home ) {
106
+ $page_type = 'home';
107
  }
108
  elseif ( $wp_query->is_single ) {
109
+ // $page_type = $wp_query->is_attachment ? 'attachment' : 'single';
110
+ $page_type = get_post_type();
111
  }
112
  elseif ( $wp_query->is_category ) {
113
+ $page_type = 'category';
114
  }
115
  elseif ( $wp_query->is_tag ) {
116
+ $page_type = 'tag';
117
  }
118
  elseif ( $wp_query->is_tax ) {
119
+ $page_type = 'tax';
120
+ // $page_type = get_queried_object()->taxonomy;
121
  }
122
  elseif ( $wp_query->is_archive ) {
123
  if ( $wp_query->is_day ) {
124
+ $page_type = 'day';
125
  }
126
  elseif ( $wp_query->is_month ) {
127
+ $page_type = 'month';
128
  }
129
  elseif ( $wp_query->is_year ) {
130
+ $page_type = 'year';
131
  }
132
  elseif ( $wp_query->is_author ) {
133
+ $page_type = 'author';
134
  }
135
  else {
136
+ $page_type = 'archive';
137
  }
138
  }
139
  elseif ( $wp_query->is_search ) {
140
+ $page_type = 'search';
141
  }
142
  elseif ( $wp_query->is_404 ) {
143
+ $page_type = '404';
144
  }
145
 
146
  return $page_type;
147
 
148
  // if ( is_404() ) {
149
+ // $page_type = '404';
150
  // }
151
  // elseif ( is_singular() ) {
152
+ // $page_type = get_post_type();
153
  // }
154
  // elseif ( is_home() && get_option( 'show_on_front' ) == 'page' ) {
155
+ // $page_type = 'home';
156
  // }
157
  // elseif ( is_front_page() ) {
158
+ // $page_type = 'front';
159
  // }
160
  // elseif ( is_tax() ) {
161
+ // $page_type = get_queried_object()->taxonomy;
162
  // }
163
  // elseif ( is_category() ) {
164
+ // $page_type = 'category';
165
  // }
166
  // elseif ( is_tag() ) {
167
+ // $page_type = 'tag';
168
  // }
169
 
170
+ // return $page_type;
171
  }
172
 
173
  /**
175
  *
176
  * @since 2.9
177
  */
178
+ public static function ping( $domain ) {
 
179
  if ( strpos( $domain, ':' ) ) {
180
+ $domain = parse_url( $domain, PHP_URL_HOST );
181
  }
182
+ $starttime = microtime( true );
183
+ $file = fsockopen( $domain, 443, $errno, $errstr, 10 );
184
+ $stoptime = microtime( true );
185
+ $status = 0;
186
 
187
+ if ( ! $file ) $status = 99999;// Site is down
188
  else {
189
+ fclose( $file );
190
+ $status = ( $stoptime - $starttime ) * 1000;
191
+ $status = floor( $status );
192
  }
193
 
194
+ Debug2::debug( "[Util] ping [Domain] $domain \t[Speed] $status" );
195
 
196
+ return $status;
197
  }
198
 
199
  /**
202
  * @since 1.6.5
203
  * @access public
204
  */
205
+ public static function readable_time( $seconds_or_timestamp, $timeout = 3600, $forword = false ) {
 
206
 
207
  if ( strlen( $seconds_or_timestamp ) == 10 ) {
208
+ $seconds = time() - $seconds_or_timestamp;
209
  if ( $seconds > $timeout ) {
210
+ return date( 'm/d/Y H:i:s', $seconds_or_timestamp + LITESPEED_TIME_OFFSET );
211
  }
212
  }
213
  else {
214
+ $seconds = $seconds_or_timestamp;
215
  }
216
 
217
  $res = '';
218
  if ( $seconds > 86400 ) {
219
+ $num = floor( $seconds / 86400 );
220
+ $res .= $num . 'd';
221
+ $seconds %= 86400;
222
  }
223
 
224
  if ( $seconds > 3600 ) {
225
  if ( $res ) {
226
+ $res .= ', ';
227
  }
228
+ $num = floor( $seconds / 3600 );
229
+ $res .= $num . 'h';
230
+ $seconds %= 3600;
231
  }
232
 
233
  if ( $seconds > 60 ) {
234
  if ( $res ) {
235
+ $res .= ', ';
236
  }
237
+ $num = floor( $seconds / 60 );
238
+ $res .= $num . 'm';
239
+ $seconds %= 60;
240
  }
241
 
242
  if ( $seconds > 0 ) {
243
  if ( $res ) {
244
+ $res .= ' ';
245
  }
246
+ $res .= $seconds . 's';
247
  }
248
 
249
  if ( ! $res ) {
252
 
253
  $res = $forword ? $res : sprintf( __( ' %s ago', 'litespeed-cache' ), $res );
254
 
255
+ return $res;
256
  }
257
 
258
 
262
  * @since 1.6
263
  * @access public
264
  */
265
+ public static function arr2str( $arr ) {
 
266
  if ( ! is_array( $arr ) ) {
267
+ return $arr;
268
  }
269
 
270
+ return base64_encode( json_encode( $arr ) );
271
  }
272
 
273
  /**
276
  * @since 1.6
277
  * @access public
278
  */
279
+ public static function real_size( $filesize, $is_1000 = false ) {
 
280
  $unit = $is_1000 ? 1000 : 1024;
281
 
282
  if ( $filesize >= pow( $unit, 3 ) ) {
303
  * @param string $str
304
  * @return array All the attributes
305
  */
306
+ public static function parse_attr( $str ) {
307
+ $attrs = array();
308
+ preg_match_all( '#([\w-]+)=["\']([^"\']*)["\']#isU', $str, $matches, PREG_SET_ORDER );
 
309
  foreach ( $matches as $match ) {
310
+ $attrs[ $match[ 1 ] ] = trim( $match[ 2 ] );
311
  }
312
+ return $attrs;
313
  }
314
 
315
  /**
323
  * @param array $haystack
324
  * @return bool|string False if not found, otherwise return the matched string in haystack.
325
  */
326
+ public static function str_hit_array( $needle, $haystack, $has_ttl = false ) {
 
327
  /**
328
  * Safety check to avoid PHP warning
329
  * @see https://github.com/litespeedtech/lscache_wp/pull/131/commits/45fc03af308c7d6b5583d1664fad68f75fb6d017
330
  */
331
  if ( ! is_array( $haystack ) ) {
332
+ Debug2::debug( "[Util] ❌ bad param in str_hit_array()!" );
333
 
334
+ return false;
335
  }
336
 
337
+ $hit = false;
338
+ $this_ttl = 0;
339
  foreach( $haystack as $item ) {
340
  if ( ! $item ) {
341
+ continue;
342
  }
343
 
344
  if ( $has_ttl ) {
345
+ $this_ttl = 0;
346
+ $item = explode( ' ', $item );
347
  if ( ! empty( $item[ 1 ] ) ) {
348
+ $this_ttl = $item[ 1 ];
349
  }
350
+ $item = $item[ 0 ];
351
  }
352
 
353
  if ( substr( $item, -1 ) === '$' ) {
354
  // do exact match
355
  if ( substr( $item, 0, -1 ) === $needle ) {
356
+ $hit = $item;
357
+ break;
358
  }
359
  }
360
  elseif ( substr( $item, 0, 1 ) === '^' ) {
361
  // match beginning
362
  if ( substr( $item, 1 ) === substr( $needle, 0, strlen( $item ) - 1 ) ) {
363
+ $hit = $item;
364
+ break;
365
  }
366
  }
367
  else {
368
  if ( strpos( $needle, $item ) !== false ) {
369
+ $hit = $item;
370
+ break;
371
  }
372
  }
373
  }
374
 
375
  if ( $hit ) {
376
  if ( $has_ttl ) {
377
+ return array( $hit, $this_ttl );
378
  }
379
 
380
+ return $hit;
381
  }
382
 
383
+ return false;
384
  }
385
 
386
  /**
389
  * @since 1.2.2
390
  *
391
  */
392
+ public static function compatibility() {
393
+ require_once LSCWP_DIR . 'lib/php-compatibility.func.php';
 
394
  }
395
 
396
  /**
401
  * @param string $uri `xx/xx.html` or `/subfolder/xx/xx.html`
402
  * @return string http://www.example.com/subfolder/xx/xx.html
403
  */
404
+ public static function uri2url( $uri ) {
 
405
  if ( substr( $uri, 0, 1 ) === '/' ) {
406
+ self::domain_const();
407
+ $url = LSCWP_DOMAIN . $uri;
408
  }
409
  else {
410
+ $url = home_url( '/' ) . $uri;
411
  }
412
 
413
+ return $url;
414
  }
415
 
416
  /**
420
  * @since 1.6.2.1 Added 2nd param keep_qs
421
  * @access public
422
  */
423
+ public static function url2uri( $url, $keep_qs = false ) {
424
+ $url = trim( $url );
425
+ $uri = @parse_url( $url, PHP_URL_PATH );
426
+ $qs = @parse_url( $url, PHP_URL_QUERY );
 
427
 
428
  if ( ! $keep_qs || ! $qs ) {
429
+ return $uri;
430
  }
431
 
432
+ return $uri . '?' . $qs;
433
  }
434
 
435
  /**
440
  * @param string `https://aa.com/bbb/wp-content/upload/2018/08/test.jpg` or `/bbb/wp-content/upload/2018/08/test.jpg`
441
  * @return string `2018/08/test.jpg`
442
  */
443
+ public static function att_short_path( $url ) {
 
444
  if ( ! defined( 'LITESPEED_UPLOAD_PATH' ) ) {
445
+ $_wp_upload_dir = wp_upload_dir();
446
 
447
+ $upload_path = self::url2uri( $_wp_upload_dir[ 'baseurl' ] );
448
 
449
+ define( 'LITESPEED_UPLOAD_PATH', $upload_path );
450
  }
451
 
452
+ $local_file = self::url2uri( $url );
453
 
454
+ $short_path = substr( $local_file, strlen( LITESPEED_UPLOAD_PATH ) + 1 );
455
 
456
+ return $short_path;
457
  }
458
 
459
  /**
464
  * @param string $url
465
  * @return string Relative URL, start with /
466
  */
467
+ public static function make_relative( $url ) {
 
468
  // replace home_url if the url is full url
469
+ self::domain_const();
470
  if ( strpos( $url, LSCWP_DOMAIN ) === 0 ) {
471
+ $url = substr( $url, strlen( LSCWP_DOMAIN ) );
472
  }
473
+ return trim( $url );
474
  }
475
 
476
  /**
478
  *
479
  * @since 1.7.1
480
  */
481
+ public static function parse_domain( $url ) {
482
+ $url = @parse_url( $url );
 
483
  if ( empty( $url[ 'host' ] ) ) {
484
+ return '';
485
  }
486
 
487
  if ( ! empty( $url[ 'scheme' ] ) ) {
488
+ return $url[ 'scheme' ] . '://' . $url[ 'host' ];
489
  }
490
 
491
+ return '//' . $url[ 'host' ];
492
  }
493
 
494
  /**
515
  * @since 1.3
516
  * @access public
517
  */
518
+ public static function domain_const() {
 
519
  if ( defined( 'LSCWP_DOMAIN' ) ) {
520
+ return;
521
  }
522
 
523
+ self::compatibility();
524
+ $domain = http_build_url( get_home_url(), array(), HTTP_URL_STRIP_ALL );
525
 
526
+ define( 'LSCWP_DOMAIN', $domain );
527
  }
528
 
529
  /**
538
  public static function sanitize_lines( $arr, $type = null ) {
539
  if ( ! $arr ) {
540
  if ( $type === 'string' ) {
541
+ return '';
542
  }
543
+ return array();
544
  }
545
 
546
  if ( ! is_array( $arr ) ) {
547
+ $arr = explode( "\n", $arr );
548
  }
549
 
550
+ $arr = array_map( 'trim', $arr );
551
+ $changed = false;
552
  if ( $type === 'uri' ) {
553
+ $arr = array_map( __CLASS__ . '::url2uri', $arr );
554
+ $changed = true;
555
  }
556
  if ( $type === 'relative' ) {
557
+ $arr = array_map( __CLASS__ . '::make_relative', $arr );// Remove domain
558
+ $changed = true;
559
  }
560
  if ( $type === 'domain' ) {
561
+ $arr = array_map( __CLASS__ . '::parse_domain', $arr );// Only keep domain
562
+ $changed = true;
563
  }
564
 
565
  if ( $type === 'noprotocol' ) {
568
  }
569
 
570
  if ( $changed ) {
571
+ $arr = array_map( 'trim', $arr );
572
  }
573
+ $arr = array_unique( $arr );
574
+ $arr = array_filter( $arr );
575
 
576
  if ( $type === 'string' ) {
577
+ return implode( "\n", $arr );
578
  }
579
 
580
+ return $arr;
581
  }
582
 
583
  /**
589
  * @access public
590
  * @return string The built url.
591
  */
592
+ public static function build_url( $action, $type = false, $is_ajax = false, $page = null, $append_arr = array() ) {
 
593
  $prefix = '?';
594
 
595
  if ( $page === '_ori' ) {
601
  if ( $page ) {
602
  // If use admin url
603
  if ( $page === true ) {
604
+ $page = 'admin.php';
605
  }
606
  else {
607
  if ( strpos( $page, '?' ) !== false ) {
608
+ $prefix = '&';
609
  }
610
  }
611
+ $combined = $page . $prefix . Router::ACTION . '=' . $action;
612
  }
613
  else {
614
  // Current page rebuild URL
615
+ $params = $_GET;
616
 
617
  if ( ! empty( $params ) ) {
618
  if ( isset( $params[ Router::ACTION ] ) ) {
619
+ unset( $params[ Router::ACTION ] );
620
  }
621
  if ( isset( $params[ '_wpnonce' ] ) ) {
622
+ unset( $params[ '_wpnonce' ] );
623
  }
624
  if ( ! empty( $params ) ) {
625
+ $prefix .= http_build_query( $params ) . '&';
626
  }
627
  }
628
+ global $pagenow;
629
+ $combined = $pagenow . $prefix . Router::ACTION . '=' . $action;
630
  }
631
  }
632
  else {
633
+ $combined = 'admin-ajax.php?action=litespeed_ajax&' . Router::ACTION . '=' . $action;
634
  }
635
 
636
  if ( is_network_admin() ) {
637
+ $prenonce = network_admin_url( $combined );
638
  }
639
  else {
640
+ $prenonce = admin_url( $combined );
641
  }
642
+ $url = wp_nonce_url( $prenonce, $action, Router::NONCE );
643
 
644
  if ( $type ) {
645
  // Remove potential param `type` from url
646
+ $url = parse_url( htmlspecialchars_decode( $url ) );
647
+ parse_str( $url[ 'query' ], $query );
648
 
649
+ $built_arr = array_merge( $query, array( Router::TYPE => $type ) );
650
  if ( $append_arr ) {
651
+ $built_arr = array_merge( $built_arr, $append_arr );
652
  }
653
+ $url[ 'query' ] = http_build_query( $built_arr );
654
+ self::compatibility();
655
+ $url = http_build_url( $url );
656
+ $url = htmlspecialchars( $url, ENT_QUOTES, 'UTF-8' );
657
  }
658
 
659
+ return $url;
660
  }
661
 
662
  /**
665
  * @since 1.2.3
666
  *
667
  */
668
+ public static function internal( $host ) {
 
669
  if ( ! defined( 'LITESPEED_FRONTEND_HOST' ) ) {
670
  if ( defined( 'WP_HOME' ) ) {
671
+ $home_host = WP_HOME;// Also think of `WP_SITEURL`
672
  }
673
  else {
674
+ $home_host = get_option( 'home' );
675
  }
676
+ define( 'LITESPEED_FRONTEND_HOST', parse_url( $home_host, PHP_URL_HOST ) );
677
  }
678
 
679
  if ( $host === LITESPEED_FRONTEND_HOST ) {
680
+ return true;
681
  }
682
 
683
  /**
685
  * @since 2.9.4
686
  */
687
  if ( ! isset( self::$_internal_domains ) ) {
688
+ self::$_internal_domains = apply_filters( 'litespeed_internal_domains', array() );
689
  }
690
 
691
  if ( self::$_internal_domains ) {
692
+ return in_array( $host, self::$_internal_domains );
693
  }
694
 
695
+ return false;
696
  }
697
 
698
  /**
703
  * @access public
704
  * @return string|bool The real path of file OR false
705
  */
706
+ public static function is_internal_file( $url, $addition_postfix = false ) {
707
+ $url_parsed = parse_url( $url );
 
708
  if ( isset( $url_parsed[ 'host' ] ) && ! self::internal( $url_parsed[ 'host' ] ) ) {
709
  // Check if is cdn path
710
  // Do this to avoid user hardcoded src in tpl
711
  if ( ! CDN::internal( $url_parsed[ 'host' ] ) ) {
712
+ Debug2::debug2( '[Util] external' );
713
+ return false;
714
  }
715
  }
716
 
717
  if ( empty( $url_parsed[ 'path' ] ) ) {
718
+ return false;
719
  }
720
 
721
  // Need to replace child blog path for assets, ref: .htaccess
722
  if ( is_multisite() && defined( 'PATH_CURRENT_SITE' ) ) {
723
+ $pattern = '#^' . PATH_CURRENT_SITE . '([_0-9a-zA-Z-]+/)(wp-(content|admin|includes))#U';
724
+ $replacement = PATH_CURRENT_SITE . '$2';
725
+ $url_parsed[ 'path' ] = preg_replace( $pattern, $replacement, $url_parsed[ 'path' ] );
726
+ // $current_blog = (int) get_current_blog_id();
727
+ // $main_blog_id = (int) get_network()->site_id;
728
  // if ( $current_blog === $main_blog_id ) {
729
+ // define( 'LITESPEED_IS_MAIN_BLOG', true );
730
  // }
731
  // else {
732
+ // define( 'LITESPEED_IS_MAIN_BLOG', false );
733
  // }
734
  }
735
 
737
  /**
738
  * Trying to fix pure /.htaccess rewrite to /wordpress case
739
  *
740
+ * Add `define( 'LITESPEED_WP_REALPATH', '/wordpress' );` in wp-config.php in this case
741
  *
742
  * @internal #611001 - Combine & Minify not working?
743
  * @since 1.6.3
744
  */
745
  if ( substr( $url_parsed[ 'path' ], 0, 1 ) === '/' ) {
746
  if ( defined( 'LITESPEED_WP_REALPATH' ) ) {
747
+ $file_path_ori = $_SERVER[ 'DOCUMENT_ROOT' ] . LITESPEED_WP_REALPATH . $url_parsed[ 'path' ];
748
  }
749
  else {
750
+ $file_path_ori = $_SERVER[ 'DOCUMENT_ROOT' ] . $url_parsed[ 'path' ];
751
  }
752
  }
753
  else {
754
+ $file_path_ori = Router::frontend_path() . '/' . $url_parsed[ 'path' ];
755
  }
756
 
757
  /**
759
  * @since 2.2.4
760
  */
761
  if ( $addition_postfix ) {
762
+ $file_path_ori .= '.' . $addition_postfix;
763
  }
764
 
765
  /**
767
  * @see #101091 plugin `Hide My WordPress`
768
  * @since 2.2.3
769
  */
770
+ $file_path_ori = apply_filters( 'litespeed_realpath', $file_path_ori );
771
 
772
+ $file_path = realpath( $file_path_ori );
773
  if ( ! is_file( $file_path ) ) {
774
+ Debug2::debug2( '[Util] file not exist: ' . $file_path_ori );
775
+ return false;
776
  }
777
 
778
+ return array( $file_path, filesize( $file_path ) );
779
  }
780
 
781
  /**
783
  *
784
  * @since 2.2.3
785
  */
786
+ public static function srcset_replace( $content, $callback ) {
787
+ preg_match_all( '# srcset=([\'"])(.+)\g{1}#iU', $content, $matches );
788
+ $srcset_ori = array();
789
+ $srcset_final = array();
 
790
  foreach ( $matches[ 2 ] as $k => $urls_ori ) {
791
 
792
+ $urls_final = explode( ',', $urls_ori );
793
 
794
+ $changed = false;
795
 
796
  foreach ( $urls_final as $k2 => $url_info ) {
797
  $url_info_arr = explode( ' ', trim( $url_info ) );
798
 
799
  if ( ! $url2 = call_user_func( $callback, $url_info_arr[ 0 ] ) ) {
800
+ continue;
801
  }
802
 
803
+ $changed = true;
804
 
805
+ $urls_final[ $k2 ] = str_replace( $url_info_arr[ 0 ], $url2, $url_info );
806
 
807
+ Debug2::debug2( '[Util] - srcset replaced to ' . $url2 . ( ! empty( $url_info_arr[ 1 ] ) ? ' ' . $url_info_arr[ 1 ] : '' ) );
808
  }
809
 
810
  if ( ! $changed ) {
811
+ continue;
812
  }
813
 
814
+ $urls_final = implode( ',', $urls_final );
815
 
816
+ $srcset_ori[] = $matches[ 0 ][ $k ];
817
 
818
+ $srcset_final[] = str_replace( $urls_ori, $urls_final, $matches[ 0 ][ $k ] );
819
  }
820
 
821
  if ( $srcset_ori ) {
822
+ $content = str_replace( $srcset_ori, $srcset_final, $content );
823
+ Debug2::debug2( '[Util] - srcset replaced' );
824
  }
825
 
826
+ return $content;
827
 
828
  }
829
 
833
  * @since 3.0
834
  * @access public
835
  */
836
+ public static function pagination( $total, $limit, $return_offset = false ) {
 
837
  $pagenum = isset( $_GET[ 'pagenum' ] ) ? absint( $_GET[ 'pagenum' ] ) : 1;
838
 
839
  $offset = ( $pagenum - 1 ) * $limit;
869
  * @since 2.0
870
  * @access public
871
  */
872
+ public static function chunk_placeholder( $data, $fields ) {
 
873
  $division = substr_count( $fields, ',' ) + 1;
874
 
875
  $q = implode( ',', array_map(
thirdparty/woocommerce.cls.php CHANGED
@@ -646,8 +646,9 @@ class WooCommerce extends Instance
646
  * @access public
647
  * @param WC_Product $product
648
  */
649
- public function purge_product($product)
650
- {
 
651
  $config = apply_filters( 'litespeed_conf', self::O_UPDATE_INTERVAL ) ;
652
  if ( is_null($config) ) {
653
  $config = self::O_PQS_CS ;
@@ -657,6 +658,7 @@ class WooCommerce extends Instance
657
  $this->backend_purge($product->get_id()) ;
658
  }
659
  elseif ( $config !== self::O_PQS_CS && $product->is_in_stock() ) {
 
660
  return ;
661
  }
662
  elseif ( $config !== self::O_PS_CN && ! $product->is_in_stock() ) {
@@ -766,14 +768,13 @@ class WooCommerce extends Instance
766
  * @since 1.6.3 Removed static
767
  * @since 3.0 new API
768
  */
769
- private function _option_append()
770
- {
 
 
771
  do_action( 'litespeed_conf_append', self::O_UPDATE_INTERVAL, false );
772
  do_action( 'litespeed_conf_append', self::O_SHOP_FRONT_TTL, true );
773
  do_action( 'litespeed_conf_append', self::O_WOO_CACHE_CART, true );
774
-
775
- // Append option save value filter
776
- do_action( 'litespeed_conf_multi_switch', self::O_UPDATE_INTERVAL, 3 );
777
  }
778
 
779
  /**
646
  * @access public
647
  * @param WC_Product $product
648
  */
649
+ public function purge_product($product) {
650
+ do_action( 'litespeed_debug', '[3rd] Woo Purge [pid]' . $product->get_id() );
651
+
652
  $config = apply_filters( 'litespeed_conf', self::O_UPDATE_INTERVAL ) ;
653
  if ( is_null($config) ) {
654
  $config = self::O_PQS_CS ;
658
  $this->backend_purge($product->get_id()) ;
659
  }
660
  elseif ( $config !== self::O_PQS_CS && $product->is_in_stock() ) {
661
+ do_action( 'litespeed_debug', '[3rd] Woo No purge needed [option] ' . $config );
662
  return ;
663
  }
664
  elseif ( $config !== self::O_PS_CN && ! $product->is_in_stock() ) {
768
  * @since 1.6.3 Removed static
769
  * @since 3.0 new API
770
  */
771
+ private function _option_append() {
772
+ // Append option save value filter
773
+ do_action( 'litespeed_conf_multi_switch', self::O_UPDATE_INTERVAL, 3 ); // This need to be before conf_append
774
+
775
  do_action( 'litespeed_conf_append', self::O_UPDATE_INTERVAL, false );
776
  do_action( 'litespeed_conf_append', self::O_SHOP_FRONT_TTL, true );
777
  do_action( 'litespeed_conf_append', self::O_WOO_CACHE_CART, true );
 
 
 
778
  }
779
 
780
  /**
tpl/page_optm/settings_css.tpl.php CHANGED
@@ -201,7 +201,10 @@ $closest_server = Cloud::get_summary( 'server.' . Cloud::SVC_CCSS );
201
 
202
  <?php if ( ! empty( $css_summary[ 'queue' ] ) ) : ?>
203
  <div class="litespeed-callout notice notice-warning inline">
204
- <h4><?php echo __( 'URL list in queue waiting for cron','litespeed-cache' ); ?></h4>
 
 
 
205
  <p>
206
  <?php foreach ( $css_summary[ 'queue' ] as $k => $v ) : ?>
207
  <?php if ( ! is_array( $v ) ) continue; ?>
201
 
202
  <?php if ( ! empty( $css_summary[ 'queue' ] ) ) : ?>
203
  <div class="litespeed-callout notice notice-warning inline">
204
+ <h4>
205
+ <?php echo __( 'URL list in queue waiting for cron','litespeed-cache' ); ?>
206
+ <a href="<?php echo Utility::build_url( Router::ACTION_CSS, CSS::TYPE_CLEAR_Q ); ?>" class="button litespeed-btn-warning litespeed-right">Clear</a>
207
+ </h4>
208
  <p>
209
  <?php foreach ( $css_summary[ 'queue' ] as $k => $v ) : ?>
210
  <?php if ( ! is_array( $v ) ) continue; ?>
tpl/page_optm/settings_media.tpl.php CHANGED
@@ -174,7 +174,10 @@ $closest_server = Cloud::get_summary( 'server.' . Cloud::SVC_LQIP );
174
 
175
  <?php if ( ! empty( $placeholder_summary[ 'queue' ] ) ) : ?>
176
  <div class="litespeed-callout notice notice-warning inline">
177
- <h4><?php echo __( 'Size list in queue waiting for cron','litespeed-cache' ); ?></h4>
 
 
 
178
  <p>
179
  <?php echo implode( '<br>', $placeholder_summary[ 'queue' ] ); ?>
180
  </p>
174
 
175
  <?php if ( ! empty( $placeholder_summary[ 'queue' ] ) ) : ?>
176
  <div class="litespeed-callout notice notice-warning inline">
177
+ <h4>
178
+ <?php echo __( 'Size list in queue waiting for cron','litespeed-cache' ); ?>
179
+ <a href="<?php echo Utility::build_url( Router::ACTION_PLACEHOLDER, Placeholder::TYPE_CLEAR_Q ); ?>" class="button litespeed-btn-warning litespeed-right">Clear</a>
180
+ </h4>
181
  <p>
182
  <?php echo implode( '<br>', $placeholder_summary[ 'queue' ] ); ?>
183
  </p>
tpl/page_optm/settings_media_exc.tpl.php CHANGED
@@ -19,7 +19,7 @@ defined( 'WPINC' ) || exit;
19
  <?php $this->build_textarea( $id ); ?>
20
  <div class="litespeed-desc">
21
  <?php echo __( 'Listed images will not be lazy loaded.', 'litespeed-cache' ); ?>
22
- <?php echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' ); ?>
23
  <?php Doc::one_per_line(); ?>
24
  <br /><font class="litespeed-success">
25
  <?php echo __( 'API', 'litespeed-cache' ); ?>:
@@ -47,7 +47,7 @@ defined( 'WPINC' ) || exit;
47
 
48
  <div class="litespeed-desc">
49
  <?php echo __( 'Images containing these class names will not be lazy loaded.', 'litespeed-cache' ); ?>
50
- <?php echo __( 'Both full and partial strings can be used.', 'litespeed-cache' ); ?>
51
  <?php Doc::one_per_line(); ?>
52
  </div>
53
  </td>
@@ -76,7 +76,7 @@ defined( 'WPINC' ) || exit;
76
  <?php $this->build_textarea( $id ); ?>
77
  <div class="litespeed-desc">
78
  <?php echo __( 'Iframes containing these class names will not be lazy loaded.', 'litespeed-cache' ); ?>
79
- <?php echo __( 'Both full and partial strings can be used.', 'litespeed-cache' ); ?>
80
  <?php Doc::one_per_line(); ?>
81
  </div>
82
  </td>
@@ -110,4 +110,18 @@ defined( 'WPINC' ) || exit;
110
  </td>
111
  </tr>
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  </tbody></table>
19
  <?php $this->build_textarea( $id ); ?>
20
  <div class="litespeed-desc">
21
  <?php echo __( 'Listed images will not be lazy loaded.', 'litespeed-cache' ); ?>
22
+ <?php Doc::full_or_partial_url(); ?>
23
  <?php Doc::one_per_line(); ?>
24
  <br /><font class="litespeed-success">
25
  <?php echo __( 'API', 'litespeed-cache' ); ?>:
47
 
48
  <div class="litespeed-desc">
49
  <?php echo __( 'Images containing these class names will not be lazy loaded.', 'litespeed-cache' ); ?>
50
+ <?php Doc::full_or_partial_url( true ); ?>
51
  <?php Doc::one_per_line(); ?>
52
  </div>
53
  </td>
76
  <?php $this->build_textarea( $id ); ?>
77
  <div class="litespeed-desc">
78
  <?php echo __( 'Iframes containing these class names will not be lazy loaded.', 'litespeed-cache' ); ?>
79
+ <?php Doc::full_or_partial_url( true ); ?>
80
  <?php Doc::one_per_line(); ?>
81
  </div>
82
  </td>
110
  </td>
111
  </tr>
112
 
113
+ <tr>
114
+ <th>
115
+ <?php $id = Base::O_MEDIA_LQIP_EXC; ?>
116
+ <?php $this->title( $id ); ?>
117
+ </th>
118
+ <td>
119
+ <?php $this->build_textarea( $id ); ?>
120
+ <div class="litespeed-desc">
121
+ <?php echo __( 'These images will not generate LQIP.', 'litespeed-cache' ); ?>
122
+ <?php Doc::full_or_partial_url(); ?>
123
+ </div>
124
+ </td>
125
+ </tr>
126
+
127
  </tbody></table>
tpl/page_optm/settings_tuning.tpl.php CHANGED
@@ -52,7 +52,7 @@ ksort( $roles );
52
  <?php $this->build_textarea( $id ); ?>
53
  <div class="litespeed-desc">
54
  <?php echo __( 'Listed CSS files will not be minified/combined.', 'litespeed-cache' ); ?>
55
- <?php echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' ); ?>
56
  <?php Doc::one_per_line(); ?>
57
  <br /><font class="litespeed-success">
58
  <?php echo __( 'API', 'litespeed-cache' ); ?>:
@@ -94,7 +94,7 @@ ksort( $roles );
94
  <?php $this->build_textarea( $id ); ?>
95
  <div class="litespeed-desc">
96
  <?php echo __( 'Listed JS files will not be minified/combined.', 'litespeed-cache' ); ?>
97
- <?php echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' ); ?>
98
  <?php Doc::one_per_line(); ?>
99
  <br /><font class="litespeed-success">
100
  <?php echo __( 'API', 'litespeed-cache' ); ?>:
@@ -142,7 +142,7 @@ ksort( $roles );
142
  <?php $this->build_textarea( $id ); ?>
143
  <div class="litespeed-desc">
144
  <?php echo __( 'Listed JS files will not be deferred.', 'litespeed-cache' ); ?>
145
- <?php echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' ); ?>
146
  <?php Doc::one_per_line(); ?>
147
  <br /><span class="litespeed-success">
148
  <?php echo __( 'API', 'litespeed-cache' ); ?>:
52
  <?php $this->build_textarea( $id ); ?>
53
  <div class="litespeed-desc">
54
  <?php echo __( 'Listed CSS files will not be minified/combined.', 'litespeed-cache' ); ?>
55
+ <?php Doc::full_or_partial_url(); ?>
56
  <?php Doc::one_per_line(); ?>
57
  <br /><font class="litespeed-success">
58
  <?php echo __( 'API', 'litespeed-cache' ); ?>:
94
  <?php $this->build_textarea( $id ); ?>
95
  <div class="litespeed-desc">
96
  <?php echo __( 'Listed JS files will not be minified/combined.', 'litespeed-cache' ); ?>
97
+ <?php Doc::full_or_partial_url(); ?>
98
  <?php Doc::one_per_line(); ?>
99
  <br /><font class="litespeed-success">
100
  <?php echo __( 'API', 'litespeed-cache' ); ?>:
142
  <?php $this->build_textarea( $id ); ?>
143
  <div class="litespeed-desc">
144
  <?php echo __( 'Listed JS files will not be deferred.', 'litespeed-cache' ); ?>
145
+ <?php Doc::full_or_partial_url(); ?>
146
  <?php Doc::one_per_line(); ?>
147
  <br /><span class="litespeed-success">
148
  <?php echo __( 'API', 'litespeed-cache' ); ?>: