Post Expirator - Version 2.8.0

Version Description

Download this release

Release Info

Developer andergmartins
Plugin Icon 128x128 Post Expirator
Version 2.8.0
Comparing to
See all releases

Code changes from version 2.7.8 to 2.8.0

Files changed (128) hide show
  1. assets/css/settings.css +4 -0
  2. assets/css/style.css +0 -9
  3. assets/css/woocommerce.css +7 -0
  4. assets/js/admin-edit.js +0 -1
  5. classes/DummyForAutoloadDetection.php +0 -36
  6. composer.json +16 -9
  7. composer.lock +198 -910
  8. functions.php +0 -6
  9. languages/post-expirator-es_ES.mo +0 -0
  10. languages/post-expirator-es_ES.po +634 -0
  11. languages/post-expirator-fr_FR.mo +0 -0
  12. languages/post-expirator-fr_FR.po +634 -0
  13. languages/post-expirator-it_IT.mo +0 -0
  14. languages/post-expirator-it_IT.po +634 -0
  15. languages/post-expirator-pt_BR.po +1 -1
  16. languages/post-expirator.pot +1 -1
  17. legacy-functions.php +0 -84
  18. legacy/autoload.php +27 -0
  19. {classes → legacy/classes}/Cli.class.php +0 -0
  20. {classes → legacy/classes}/CronFacade.class.php +4 -1
  21. {classes → legacy/classes}/Display.class.php +59 -15
  22. {classes → legacy/classes}/Facade.class.php +37 -88
  23. {classes → legacy/classes}/Reviews.class.php +2 -2
  24. {classes → legacy/classes}/Util.class.php +3 -0
  25. legacy/debug.php +64 -0
  26. legacy/defines.php +85 -0
  27. legacy/deprecated-functions.php +288 -0
  28. legacy/functions.php +1331 -0
  29. {views → legacy/views}/bulk-edit.php +18 -13
  30. {views → legacy/views}/classic-metabox.php +5 -5
  31. {views → legacy/views}/expire-column.php +20 -17
  32. legacy/views/how-to-expire.php +56 -0
  33. {views → legacy/views}/menu-advanced.php +0 -0
  34. {views → legacy/views}/menu-defaults.php +39 -35
  35. {views → legacy/views}/menu-diagnostics.php +4 -1
  36. {views → legacy/views}/menu-display.php +0 -0
  37. {views → legacy/views}/menu-editor.php +0 -0
  38. {views → legacy/views}/menu-general.php +9 -8
  39. {views → legacy/views}/quick-edit.php +5 -1
  40. {views → legacy/views}/tabs.php +11 -7
  41. legacy/views/taxonomy-field.php +13 -0
  42. post-expirator-debug.php +0 -102
  43. post-expirator.php +31 -2262
  44. readme.txt +22 -1
  45. services.php +376 -0
  46. src/Core/DI/Container.php +127 -0
  47. src/Core/DI/ContainerNotInitializedException.php +14 -0
  48. src/Core/DI/ServiceNotFoundException.php +19 -0
  49. src/Core/DI/ServiceProvider.php +30 -0
  50. src/Core/DI/ServiceProviderInterface.php +14 -0
  51. src/Core/DI/ServicesAbstract.php +57 -0
  52. src/Core/HookableInterface.php +59 -0
  53. src/Core/HooksAbstract.php +14 -0
  54. src/Core/Paths.php +29 -0
  55. src/Core/Plugin.php +82 -0
  56. src/Framework/BaseException.php +13 -0
  57. src/Framework/InitializableInterface.php +14 -0
  58. src/Framework/Logger/LogLevelAbstract.php +21 -0
  59. src/Framework/Logger/Logger.php +260 -0
  60. src/Framework/Logger/LoggerInterface.php +117 -0
  61. src/Framework/ModuleInterface.php +14 -0
  62. src/Framework/WordPress/Exceptions/NonexistentPostException.php +13 -0
  63. src/Framework/WordPress/Exceptions/NonexistentTermException.php +13 -0
  64. src/Framework/WordPress/Exceptions/WordPressErrorException.php +14 -0
  65. src/Framework/WordPress/Facade/CronFacade.php +46 -0
  66. src/Framework/WordPress/Facade/DatabaseFacade.php +107 -0
  67. src/Framework/WordPress/Facade/DateTimeFacade.php +44 -0
  68. src/Framework/WordPress/Facade/EmailFacade.php +15 -0
  69. src/Framework/WordPress/Facade/ErrorFacade.php +29 -0
  70. src/Framework/WordPress/Facade/HooksFacade.php +93 -0
  71. src/Framework/WordPress/Facade/OptionsFacade.php +47 -0
  72. src/Framework/WordPress/Facade/RequestFacade.php +19 -0
  73. src/Framework/WordPress/Facade/SanitizationFacade.php +19 -0
  74. src/Framework/WordPress/Facade/SiteFacade.php +31 -0
  75. src/Framework/WordPress/Facade/UsersFacade.php +14 -0
  76. src/Framework/WordPress/Models/CurrentUserModel.php +16 -0
  77. src/Framework/WordPress/Models/PostModel.php +250 -0
  78. src/Framework/WordPress/Models/TermModel.php +80 -0
  79. src/Framework/WordPress/Models/UserModel.php +54 -0
  80. src/Modules/Debug/Controllers/Controller.php +40 -0
  81. src/Modules/Debug/Debug.php +70 -0
  82. src/Modules/Debug/DebugInterface.php +36 -0
  83. src/Modules/Debug/HooksAbstract.php +8 -0
  84. src/Modules/Debug/Module.php +55 -0
  85. src/Modules/Expirator/CapabilitiesAbstract.php +11 -0
  86. src/Modules/Expirator/Controllers/BulkEditController.php +129 -0
  87. src/Modules/Expirator/Controllers/ExpirationController.php +123 -0
  88. src/Modules/Expirator/Exceptions/UndefinedActionException.php +10 -0
  89. src/Modules/Expirator/ExpirationActionMapper.php +54 -0
  90. src/Modules/Expirator/ExpirationActions/DeletePost.php +53 -0
  91. src/Modules/Expirator/ExpirationActions/PostCategoryAdd.php +81 -0
  92. src/Modules/Expirator/ExpirationActions/PostCategoryRemove.php +82 -0
  93. src/Modules/Expirator/ExpirationActions/PostCategorySet.php +77 -0
  94. src/Modules/Expirator/ExpirationActions/PostStatusToDraft.php +57 -0
  95. src/Modules/Expirator/ExpirationActions/PostStatusToPrivate.php +56 -0
  96. src/Modules/Expirator/ExpirationActions/PostStatusToTrash.php +56 -0
  97. src/Modules/Expirator/ExpirationActions/StickPost.php +53 -0
  98. src/Modules/Expirator/ExpirationActions/UnstickPost.php +53 -0
  99. src/Modules/Expirator/ExpirationActionsAbstract.php +16 -0
  100. src/Modules/Expirator/ExpirationScheduler.php +215 -0
  101. src/Modules/Expirator/HooksAbstract.php +26 -0
  102. src/Modules/Expirator/Interfaces/ActionMapperInterface.php +17 -0
  103. src/Modules/Expirator/Interfaces/ActionableInterface.php +12 -0
  104. src/Modules/Expirator/Interfaces/ExpirationActionInterface.php +25 -0
  105. src/Modules/Expirator/Interfaces/SchedulerInterface.php +29 -0
  106. src/Modules/Expirator/Models/CurrentUserModel.php +19 -0
  107. src/Modules/Expirator/Models/DefaultDataModel.php +117 -0
  108. src/Modules/Expirator/Models/ExpirablePostModel.php +513 -0
  109. src/Modules/Expirator/Module.php +112 -0
  110. src/Modules/InstanceProtection/Module.php +43 -0
  111. src/Modules/Settings/Controllers/Controller.php +77 -0
  112. src/Modules/Settings/HooksAbstract.php +12 -0
  113. src/Modules/Settings/Module.php +57 -0
  114. src/Modules/Settings/SettingsFacade.php +202 -0
  115. src/Modules/WooCommerce/Module.php +62 -0
  116. vendor/autoload.php +1 -1
  117. vendor/composer/autoload_files.php +0 -1
  118. vendor/composer/autoload_psr4.php +2 -0
  119. vendor/composer/autoload_real.php +7 -7
  120. vendor/composer/autoload_static.php +23 -3
  121. vendor/composer/installed.json +63 -7
  122. vendor/composer/installed.php +18 -9
  123. vendor/psr/container/LICENSE +21 -0
  124. vendor/psr/container/composer.json +27 -0
  125. vendor/psr/container/src/ContainerExceptionInterface.php +13 -0
  126. vendor/psr/container/src/ContainerInterface.php +37 -0
  127. vendor/psr/container/src/NotFoundExceptionInterface.php +13 -0
  128. vendor/publishpress/publishpress-instance-protection/core/InstanceChecker.php +5 -5
assets/css/settings.css CHANGED
@@ -153,3 +153,7 @@ span.post-expiration-attributes {
153
  .pe-event-post {
154
  cursor: help;
155
  }
 
 
 
 
153
  .pe-event-post {
154
  cursor: help;
155
  }
156
+
157
+ .post-expirator-timestamp {
158
+ width: 20% !important;
159
+ }
assets/css/style.css CHANGED
@@ -8,15 +8,6 @@
8
  font-weight: normal;
9
  }
10
 
11
- .post-expirator-debug th {
12
- font-weight: bold;
13
- border-bottom: 1px solid black;
14
- }
15
-
16
- .post-expirator-timestamp {
17
- width: 150px;
18
- }
19
-
20
  /* metabox */
21
  #post-expirator-cat-list {
22
  max-width: 250px;
8
  font-weight: normal;
9
  }
10
 
 
 
 
 
 
 
 
 
 
11
  /* metabox */
12
  #post-expirator-cat-list {
13
  max-width: 250px;
assets/css/woocommerce.css ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 2022. PublishPress, All rights reserved.
3
+ */
4
+
5
+ .fixed .column-expirationdate {
6
+ width: 10%;
7
+ }
assets/js/admin-edit.js CHANGED
@@ -164,7 +164,6 @@
164
  if ($('.post-expirator-quickedit').length > 0) {
165
  $('#bulk_edit').on('click', function(e) {
166
  const isValid = validateBulkFields();
167
- console.log(isValid);
168
  if (! isValid) {
169
  e.preventDefault();
170
 
164
  if ($('.post-expirator-quickedit').length > 0) {
165
  $('#bulk_edit').on('click', function(e) {
166
  const isValid = validateBulkFields();
 
167
  if (! isValid) {
168
  e.preventDefault();
169
 
classes/DummyForAutoloadDetection.php DELETED
@@ -1,36 +0,0 @@
1
- <?php
2
- /**
3
- * GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>
4
- *
5
- * This program is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation, either version 3 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
- *
18
- * @package PublishPress-Future
19
- * @subpackage Classes
20
- * @author PublishPress <help@publishpress.com>
21
- * @copyright Copyright (C) 2021 PublishPress. All rights reserved.
22
- * @link https://publishpress.com/future/
23
- * @license GPLv2 or later
24
- * @since 2.7.1
25
- */
26
-
27
- namespace PublishPressFuture;
28
-
29
- /**
30
- * Dummy class for detecting if the composer autoload was already loaded.
31
- * Fixes error with duplicated class for the Composer's autoload_real.php file.
32
- */
33
- class DummyForAutoloadDetection
34
- {
35
-
36
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
composer.json CHANGED
@@ -25,9 +25,9 @@
25
  },
26
  "minimum-stability": "stable",
27
  "autoload": {
28
- "files": [
29
- "classes/DummyForAutoloadDetection.php"
30
- ]
31
  },
32
  "repositories": [
33
  {
@@ -42,7 +42,9 @@
42
  "require": {
43
  "php": ">=5.6.20",
44
  "publishpress/wordpress-reviews": "^1.1",
45
- "publishpress/publishpress-instance-protection": "^1.0"
 
 
46
  },
47
  "require-dev": {
48
  "lucatume/wp-browser": "^3",
@@ -58,7 +60,6 @@
58
  "dealerdirect/phpcodesniffer-composer-installer": "*",
59
  "phpcompatibility/php-compatibility": "*",
60
  "wp-coding-standards/wpcs": "*",
61
- "publishpress/publishpress-plugin-builder": "^1.4",
62
  "phpmd/phpmd": "^2.8",
63
  "squizlabs/php_codesniffer": "^3.5",
64
  "sebastian/phpcpd": "^5.0",
@@ -72,10 +73,16 @@
72
  "publishpress/publishpress-phpcs-standards": "dev-main",
73
  "spatie/ray": "*",
74
  "spatie/wordpress-ray": "dev-patch-1",
75
- "permafrost-dev/ray-cli": "^1.12"
 
 
76
  },
77
  "scripts": {
78
- "tests": "tests/bin/tests $1 $2",
 
 
 
 
79
  "tests-php": "tests/bin/get-php-versions",
80
  "build-dir": "builder/docker/scripts/build build-dir",
81
  "build": "builder/docker/scripts/build build",
@@ -88,11 +95,11 @@
88
  ]
89
  },
90
  "scripts-descriptions": {
91
- "tests": "Manage tests on Docker a container. You need to pass the PHP version as the first argument. Check versions available running 'composer test-php'.",
92
  "tests-php": "Show the available PHP versions for running tests."
93
  },
94
  "extra": {
95
  "plugin-slug": "post-expirator",
96
- "plugin-name": "publishpress-future"
 
97
  }
98
  }
25
  },
26
  "minimum-stability": "stable",
27
  "autoload": {
28
+ "psr-4": {
29
+ "PublishPressFuture\\": "./src"
30
+ }
31
  },
32
  "repositories": [
33
  {
42
  "require": {
43
  "php": ">=5.6.20",
44
  "publishpress/wordpress-reviews": "^1.1",
45
+ "publishpress/publishpress-instance-protection": "^1.0",
46
+ "psr/container": "1.0.0",
47
+ "ext-json": "*"
48
  },
49
  "require-dev": {
50
  "lucatume/wp-browser": "^3",
60
  "dealerdirect/phpcodesniffer-composer-installer": "*",
61
  "phpcompatibility/php-compatibility": "*",
62
  "wp-coding-standards/wpcs": "*",
 
63
  "phpmd/phpmd": "^2.8",
64
  "squizlabs/php_codesniffer": "^3.5",
65
  "sebastian/phpcpd": "^5.0",
73
  "publishpress/publishpress-phpcs-standards": "dev-main",
74
  "spatie/ray": "*",
75
  "spatie/wordpress-ray": "dev-patch-1",
76
+ "permafrost-dev/ray-cli": "^1.12",
77
+ "ext-pdo": "*",
78
+ "ext-yaml": "*"
79
  },
80
  "scripts": {
81
+ "tests-unit": "vendor/bin/codecept run unit",
82
+ "tests-wordpress": "tests/bin/tests php7.4 brun wordpress",
83
+ "tests-acceptance-php7.4": "tests/bin/tests php7.4 brun acceptance",
84
+ "tests-acceptance-php5.6": "tests/bin/tests php5.6 brun acceptance",
85
+ "tests-acceptance-php8.1": "tests/bin/tests php8.1 brun acceptance",
86
  "tests-php": "tests/bin/get-php-versions",
87
  "build-dir": "builder/docker/scripts/build build-dir",
88
  "build": "builder/docker/scripts/build build",
95
  ]
96
  },
97
  "scripts-descriptions": {
 
98
  "tests-php": "Show the available PHP versions for running tests."
99
  },
100
  "extra": {
101
  "plugin-slug": "post-expirator",
102
+ "plugin-name": "publishpress-future",
103
+ "plugin-folder": "post-expirator"
104
  }
105
  }
composer.lock CHANGED
@@ -4,20 +4,73 @@
4
  "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
  "This file is @generated automatically"
6
  ],
7
- "content-hash": "4ecc92676343948390e1467d6233ad61",
8
  "packages": [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  {
10
  "name": "publishpress/publishpress-instance-protection",
11
- "version": "v1.0.2",
12
  "source": {
13
  "type": "git",
14
  "url": "https://github.com/publishpress/publishpress-instance-protection.git",
15
- "reference": "ef1a631a41b723ce2e856f534ff4befbe914e964"
16
  },
17
  "dist": {
18
  "type": "zip",
19
- "url": "https://api.github.com/repos/publishpress/publishpress-instance-protection/zipball/ef1a631a41b723ce2e856f534ff4befbe914e964",
20
- "reference": "ef1a631a41b723ce2e856f534ff4befbe914e964",
21
  "shasum": ""
22
  },
23
  "require": {
@@ -41,9 +94,9 @@
41
  ],
42
  "support": {
43
  "issues": "https://github.com/publishpress/publishpress-instance-protection/issues",
44
- "source": "https://github.com/publishpress/publishpress-instance-protection/tree/v1.0.2"
45
  },
46
- "time": "2022-06-03T17:41:36+00:00"
47
  },
48
  {
49
  "name": "publishpress/wordpress-reviews",
@@ -1528,16 +1581,16 @@
1528
  },
1529
  {
1530
  "name": "composer/pcre",
1531
- "version": "3.0.0",
1532
  "source": {
1533
  "type": "git",
1534
  "url": "https://github.com/composer/pcre.git",
1535
- "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd"
1536
  },
1537
  "dist": {
1538
  "type": "zip",
1539
- "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd",
1540
- "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd",
1541
  "shasum": ""
1542
  },
1543
  "require": {
@@ -1579,7 +1632,7 @@
1579
  ],
1580
  "support": {
1581
  "issues": "https://github.com/composer/pcre/issues",
1582
- "source": "https://github.com/composer/pcre/tree/3.0.0"
1583
  },
1584
  "funding": [
1585
  {
@@ -1595,7 +1648,7 @@
1595
  "type": "tidelift"
1596
  }
1597
  ],
1598
- "time": "2022-02-25T20:21:48+00:00"
1599
  },
1600
  {
1601
  "name": "composer/semver",
@@ -1744,387 +1797,6 @@
1744
  ],
1745
  "time": "2022-02-25T21:32:43+00:00"
1746
  },
1747
- {
1748
- "name": "consolidation/annotated-command",
1749
- "version": "4.5.6",
1750
- "source": {
1751
- "type": "git",
1752
- "url": "https://github.com/consolidation/annotated-command.git",
1753
- "reference": "3968070538761628546270935f0733a0cc408e1f"
1754
- },
1755
- "dist": {
1756
- "type": "zip",
1757
- "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/3968070538761628546270935f0733a0cc408e1f",
1758
- "reference": "3968070538761628546270935f0733a0cc408e1f",
1759
- "shasum": ""
1760
- },
1761
- "require": {
1762
- "consolidation/output-formatters": "^4.1.1",
1763
- "php": ">=7.1.3",
1764
- "psr/log": "^1|^2|^3",
1765
- "symfony/console": "^4.4.8|^5|^6",
1766
- "symfony/event-dispatcher": "^4.4.8|^5|^6",
1767
- "symfony/finder": "^4.4.8|^5|^6"
1768
- },
1769
- "require-dev": {
1770
- "composer-runtime-api": "^2.0",
1771
- "phpunit/phpunit": "^7.5.20 || ^8 || ^9",
1772
- "squizlabs/php_codesniffer": "^3",
1773
- "yoast/phpunit-polyfills": "^0.2.0"
1774
- },
1775
- "type": "library",
1776
- "extra": {
1777
- "branch-alias": {
1778
- "dev-main": "4.x-dev"
1779
- }
1780
- },
1781
- "autoload": {
1782
- "psr-4": {
1783
- "Consolidation\\AnnotatedCommand\\": "src"
1784
- }
1785
- },
1786
- "notification-url": "https://packagist.org/downloads/",
1787
- "license": [
1788
- "MIT"
1789
- ],
1790
- "authors": [
1791
- {
1792
- "name": "Greg Anderson",
1793
- "email": "greg.1.anderson@greenknowe.org"
1794
- }
1795
- ],
1796
- "description": "Initialize Symfony Console commands from annotated command class methods.",
1797
- "support": {
1798
- "issues": "https://github.com/consolidation/annotated-command/issues",
1799
- "source": "https://github.com/consolidation/annotated-command/tree/4.5.6"
1800
- },
1801
- "time": "2022-06-22T20:17:12+00:00"
1802
- },
1803
- {
1804
- "name": "consolidation/config",
1805
- "version": "2.1.2",
1806
- "source": {
1807
- "type": "git",
1808
- "url": "https://github.com/consolidation/config.git",
1809
- "reference": "597f8d7fbeef801736250ec10c3e190569b1b0ae"
1810
- },
1811
- "dist": {
1812
- "type": "zip",
1813
- "url": "https://api.github.com/repos/consolidation/config/zipball/597f8d7fbeef801736250ec10c3e190569b1b0ae",
1814
- "reference": "597f8d7fbeef801736250ec10c3e190569b1b0ae",
1815
- "shasum": ""
1816
- },
1817
- "require": {
1818
- "dflydev/dot-access-data": "^1.1.0 || ^2 || ^3",
1819
- "grasmash/expander": "^2.0.1 || ^3",
1820
- "php": ">=7.1.3",
1821
- "symfony/event-dispatcher": "^4 || ^5 || ^6"
1822
- },
1823
- "require-dev": {
1824
- "ext-json": "*",
1825
- "phpunit/phpunit": ">=7.5.20",
1826
- "squizlabs/php_codesniffer": "^3",
1827
- "symfony/console": "^4 || ^5 || ^6",
1828
- "symfony/yaml": "^4 || ^5 || ^6",
1829
- "yoast/phpunit-polyfills": "^1"
1830
- },
1831
- "suggest": {
1832
- "symfony/event-dispatcher": "Required to inject configuration into Command options",
1833
- "symfony/yaml": "Required to use Consolidation\\Config\\Loader\\YamlConfigLoader"
1834
- },
1835
- "type": "library",
1836
- "extra": {
1837
- "branch-alias": {
1838
- "dev-main": "2.x-dev"
1839
- }
1840
- },
1841
- "autoload": {
1842
- "psr-4": {
1843
- "Consolidation\\Config\\": "src"
1844
- }
1845
- },
1846
- "notification-url": "https://packagist.org/downloads/",
1847
- "license": [
1848
- "MIT"
1849
- ],
1850
- "authors": [
1851
- {
1852
- "name": "Greg Anderson",
1853
- "email": "greg.1.anderson@greenknowe.org"
1854
- }
1855
- ],
1856
- "description": "Provide configuration services for a commandline tool.",
1857
- "support": {
1858
- "issues": "https://github.com/consolidation/config/issues",
1859
- "source": "https://github.com/consolidation/config/tree/2.1.2"
1860
- },
1861
- "time": "2022-10-06T17:48:03+00:00"
1862
- },
1863
- {
1864
- "name": "consolidation/log",
1865
- "version": "2.1.1",
1866
- "source": {
1867
- "type": "git",
1868
- "url": "https://github.com/consolidation/log.git",
1869
- "reference": "3ad08dc57e8aff9400111bad36beb0ed387fe6a9"
1870
- },
1871
- "dist": {
1872
- "type": "zip",
1873
- "url": "https://api.github.com/repos/consolidation/log/zipball/3ad08dc57e8aff9400111bad36beb0ed387fe6a9",
1874
- "reference": "3ad08dc57e8aff9400111bad36beb0ed387fe6a9",
1875
- "shasum": ""
1876
- },
1877
- "require": {
1878
- "php": ">=7.1.3",
1879
- "psr/log": "^1 || ^2",
1880
- "symfony/console": "^4 || ^5 || ^6"
1881
- },
1882
- "require-dev": {
1883
- "phpunit/phpunit": ">=7.5.20",
1884
- "squizlabs/php_codesniffer": "^3",
1885
- "yoast/phpunit-polyfills": "^0.2.0"
1886
- },
1887
- "type": "library",
1888
- "extra": {
1889
- "branch-alias": {
1890
- "dev-main": "2.x-dev"
1891
- }
1892
- },
1893
- "autoload": {
1894
- "psr-4": {
1895
- "Consolidation\\Log\\": "src"
1896
- }
1897
- },
1898
- "notification-url": "https://packagist.org/downloads/",
1899
- "license": [
1900
- "MIT"
1901
- ],
1902
- "authors": [
1903
- {
1904
- "name": "Greg Anderson",
1905
- "email": "greg.1.anderson@greenknowe.org"
1906
- }
1907
- ],
1908
- "description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components.",
1909
- "support": {
1910
- "issues": "https://github.com/consolidation/log/issues",
1911
- "source": "https://github.com/consolidation/log/tree/2.1.1"
1912
- },
1913
- "time": "2022-02-24T04:27:32+00:00"
1914
- },
1915
- {
1916
- "name": "consolidation/output-formatters",
1917
- "version": "4.2.2",
1918
- "source": {
1919
- "type": "git",
1920
- "url": "https://github.com/consolidation/output-formatters.git",
1921
- "reference": "d57992bf81ead908ee21cd94b46ed65afa2e785b"
1922
- },
1923
- "dist": {
1924
- "type": "zip",
1925
- "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/d57992bf81ead908ee21cd94b46ed65afa2e785b",
1926
- "reference": "d57992bf81ead908ee21cd94b46ed65afa2e785b",
1927
- "shasum": ""
1928
- },
1929
- "require": {
1930
- "dflydev/dot-access-data": "^1.1.0 || ^2 || ^3",
1931
- "php": ">=7.1.3",
1932
- "symfony/console": "^4|^5|^6",
1933
- "symfony/finder": "^4|^5|^6"
1934
- },
1935
- "require-dev": {
1936
- "php-coveralls/php-coveralls": "^2.4.2",
1937
- "phpunit/phpunit": ">=7",
1938
- "squizlabs/php_codesniffer": "^3",
1939
- "symfony/var-dumper": "^4|^5|^6",
1940
- "symfony/yaml": "^4|^5|^6",
1941
- "yoast/phpunit-polyfills": "^0.2.0"
1942
- },
1943
- "suggest": {
1944
- "symfony/var-dumper": "For using the var_dump formatter"
1945
- },
1946
- "type": "library",
1947
- "extra": {
1948
- "branch-alias": {
1949
- "dev-main": "4.x-dev"
1950
- }
1951
- },
1952
- "autoload": {
1953
- "psr-4": {
1954
- "Consolidation\\OutputFormatters\\": "src"
1955
- }
1956
- },
1957
- "notification-url": "https://packagist.org/downloads/",
1958
- "license": [
1959
- "MIT"
1960
- ],
1961
- "authors": [
1962
- {
1963
- "name": "Greg Anderson",
1964
- "email": "greg.1.anderson@greenknowe.org"
1965
- }
1966
- ],
1967
- "description": "Format text by applying transformations provided by plug-in formatters.",
1968
- "support": {
1969
- "issues": "https://github.com/consolidation/output-formatters/issues",
1970
- "source": "https://github.com/consolidation/output-formatters/tree/4.2.2"
1971
- },
1972
- "time": "2022-02-13T15:28:30+00:00"
1973
- },
1974
- {
1975
- "name": "consolidation/robo",
1976
- "version": "3.0.10",
1977
- "source": {
1978
- "type": "git",
1979
- "url": "https://github.com/consolidation/robo.git",
1980
- "reference": "206bbe23b34081a36bfefc4de2abbc1abcd29ef4"
1981
- },
1982
- "dist": {
1983
- "type": "zip",
1984
- "url": "https://api.github.com/repos/consolidation/robo/zipball/206bbe23b34081a36bfefc4de2abbc1abcd29ef4",
1985
- "reference": "206bbe23b34081a36bfefc4de2abbc1abcd29ef4",
1986
- "shasum": ""
1987
- },
1988
- "require": {
1989
- "consolidation/annotated-command": "^4.3",
1990
- "consolidation/config": "^1.2.1 || ^2.0.1",
1991
- "consolidation/log": "^1.1.1 || ^2.0.2",
1992
- "consolidation/output-formatters": "^4.1.2",
1993
- "consolidation/self-update": "^2.0",
1994
- "league/container": "^3.3.1 || ^4.0",
1995
- "php": ">=7.1.3",
1996
- "symfony/console": "^4.4.19 || ^5 || ^6",
1997
- "symfony/event-dispatcher": "^4.4.19 || ^5 || ^6",
1998
- "symfony/filesystem": "^4.4.9 || ^5 || ^6",
1999
- "symfony/finder": "^4.4.9 || ^5 || ^6",
2000
- "symfony/process": "^4.4.9 || ^5 || ^6",
2001
- "symfony/yaml": "^4.4 || ^5 || ^6"
2002
- },
2003
- "conflict": {
2004
- "codegyre/robo": "*"
2005
- },
2006
- "require-dev": {
2007
- "natxet/cssmin": "3.0.4",
2008
- "patchwork/jsqueeze": "^2",
2009
- "pear/archive_tar": "^1.4.4",
2010
- "phpunit/phpunit": "^7.5.20 || ^8",
2011
- "squizlabs/php_codesniffer": "^3.6",
2012
- "yoast/phpunit-polyfills": "^0.2.0"
2013
- },
2014
- "suggest": {
2015
- "natxet/cssmin": "For minifying CSS files in taskMinify",
2016
- "patchwork/jsqueeze": "For minifying JS files in taskMinify",
2017
- "pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively.",
2018
- "totten/lurkerlite": "For monitoring filesystem changes in taskWatch"
2019
- },
2020
- "bin": [
2021
- "robo"
2022
- ],
2023
- "type": "library",
2024
- "extra": {
2025
- "scenarios": {
2026
- "symfony4": {
2027
- "require": {
2028
- "symfony/console": "^4.4.11",
2029
- "symfony/event-dispatcher": "^4.4.11",
2030
- "symfony/filesystem": "^4.4.11",
2031
- "symfony/finder": "^4.4.11",
2032
- "symfony/process": "^4.4.11",
2033
- "phpunit/phpunit": "^6",
2034
- "nikic/php-parser": "^2"
2035
- },
2036
- "remove": [
2037
- "codeception/phpunit-wrapper"
2038
- ],
2039
- "config": {
2040
- "platform": {
2041
- "php": "7.1.3"
2042
- }
2043
- }
2044
- }
2045
- },
2046
- "branch-alias": {
2047
- "dev-master": "2.x-dev",
2048
- "dev-main": "2.x-dev"
2049
- }
2050
- },
2051
- "autoload": {
2052
- "psr-4": {
2053
- "Robo\\": "src"
2054
- }
2055
- },
2056
- "notification-url": "https://packagist.org/downloads/",
2057
- "license": [
2058
- "MIT"
2059
- ],
2060
- "authors": [
2061
- {
2062
- "name": "Davert",
2063
- "email": "davert.php@resend.cc"
2064
- }
2065
- ],
2066
- "description": "Modern task runner",
2067
- "support": {
2068
- "issues": "https://github.com/consolidation/robo/issues",
2069
- "source": "https://github.com/consolidation/robo/tree/3.0.10"
2070
- },
2071
- "time": "2022-02-21T17:19:14+00:00"
2072
- },
2073
- {
2074
- "name": "consolidation/self-update",
2075
- "version": "2.0.5",
2076
- "source": {
2077
- "type": "git",
2078
- "url": "https://github.com/consolidation/self-update.git",
2079
- "reference": "8a64bdd8daf5faa8e85f56534dd99caf928164b3"
2080
- },
2081
- "dist": {
2082
- "type": "zip",
2083
- "url": "https://api.github.com/repos/consolidation/self-update/zipball/8a64bdd8daf5faa8e85f56534dd99caf928164b3",
2084
- "reference": "8a64bdd8daf5faa8e85f56534dd99caf928164b3",
2085
- "shasum": ""
2086
- },
2087
- "require": {
2088
- "composer/semver": "^3.2",
2089
- "php": ">=5.5.0",
2090
- "symfony/console": "^2.8 || ^3 || ^4 || ^5 || ^6",
2091
- "symfony/filesystem": "^2.5 || ^3 || ^4 || ^5 || ^6"
2092
- },
2093
- "bin": [
2094
- "scripts/release"
2095
- ],
2096
- "type": "library",
2097
- "extra": {
2098
- "branch-alias": {
2099
- "dev-main": "2.x-dev"
2100
- }
2101
- },
2102
- "autoload": {
2103
- "psr-4": {
2104
- "SelfUpdate\\": "src"
2105
- }
2106
- },
2107
- "notification-url": "https://packagist.org/downloads/",
2108
- "license": [
2109
- "MIT"
2110
- ],
2111
- "authors": [
2112
- {
2113
- "name": "Alexander Menk",
2114
- "email": "menk@mestrona.net"
2115
- },
2116
- {
2117
- "name": "Greg Anderson",
2118
- "email": "greg.1.anderson@greenknowe.org"
2119
- }
2120
- ],
2121
- "description": "Provides a self:update command for Symfony Console applications.",
2122
- "support": {
2123
- "issues": "https://github.com/consolidation/self-update/issues",
2124
- "source": "https://github.com/consolidation/self-update/tree/2.0.5"
2125
- },
2126
- "time": "2022-02-09T22:44:24+00:00"
2127
- },
2128
  {
2129
  "name": "dealerdirect/phpcodesniffer-composer-installer",
2130
  "version": "v0.7.2",
@@ -2146,93 +1818,16 @@
2146
  },
2147
  "require-dev": {
2148
  "composer/composer": "*",
2149
- "php-parallel-lint/php-parallel-lint": "^1.3.1",
2150
- "phpcompatibility/php-compatibility": "^9.0"
2151
- },
2152
- "type": "composer-plugin",
2153
- "extra": {
2154
- "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
2155
- },
2156
- "autoload": {
2157
- "psr-4": {
2158
- "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
2159
- }
2160
- },
2161
- "notification-url": "https://packagist.org/downloads/",
2162
- "license": [
2163
- "MIT"
2164
- ],
2165
- "authors": [
2166
- {
2167
- "name": "Franck Nijhof",
2168
- "email": "franck.nijhof@dealerdirect.com",
2169
- "homepage": "http://www.frenck.nl",
2170
- "role": "Developer / IT Manager"
2171
- },
2172
- {
2173
- "name": "Contributors",
2174
- "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors"
2175
- }
2176
- ],
2177
- "description": "PHP_CodeSniffer Standards Composer Installer Plugin",
2178
- "homepage": "http://www.dealerdirect.com",
2179
- "keywords": [
2180
- "PHPCodeSniffer",
2181
- "PHP_CodeSniffer",
2182
- "code quality",
2183
- "codesniffer",
2184
- "composer",
2185
- "installer",
2186
- "phpcbf",
2187
- "phpcs",
2188
- "plugin",
2189
- "qa",
2190
- "quality",
2191
- "standard",
2192
- "standards",
2193
- "style guide",
2194
- "stylecheck",
2195
- "tests"
2196
- ],
2197
- "support": {
2198
- "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues",
2199
- "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer"
2200
- },
2201
- "time": "2022-02-04T12:51:07+00:00"
2202
- },
2203
- {
2204
- "name": "dflydev/dot-access-data",
2205
- "version": "v3.0.1",
2206
- "source": {
2207
- "type": "git",
2208
- "url": "https://github.com/dflydev/dflydev-dot-access-data.git",
2209
- "reference": "0992cc19268b259a39e86f296da5f0677841f42c"
2210
- },
2211
- "dist": {
2212
- "type": "zip",
2213
- "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/0992cc19268b259a39e86f296da5f0677841f42c",
2214
- "reference": "0992cc19268b259a39e86f296da5f0677841f42c",
2215
- "shasum": ""
2216
- },
2217
- "require": {
2218
- "php": "^7.1 || ^8.0"
2219
- },
2220
- "require-dev": {
2221
- "phpstan/phpstan": "^0.12.42",
2222
- "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3",
2223
- "scrutinizer/ocular": "1.6.0",
2224
- "squizlabs/php_codesniffer": "^3.5",
2225
- "vimeo/psalm": "^3.14"
2226
  },
2227
- "type": "library",
2228
  "extra": {
2229
- "branch-alias": {
2230
- "dev-main": "3.x-dev"
2231
- }
2232
  },
2233
  "autoload": {
2234
  "psr-4": {
2235
- "Dflydev\\DotAccessData\\": "src/"
2236
  }
2237
  },
2238
  "notification-url": "https://packagist.org/downloads/",
@@ -2241,39 +1836,41 @@
2241
  ],
2242
  "authors": [
2243
  {
2244
- "name": "Dragonfly Development Inc.",
2245
- "email": "info@dflydev.com",
2246
- "homepage": "http://dflydev.com"
2247
- },
2248
- {
2249
- "name": "Beau Simensen",
2250
- "email": "beau@dflydev.com",
2251
- "homepage": "http://beausimensen.com"
2252
- },
2253
- {
2254
- "name": "Carlos Frutos",
2255
- "email": "carlos@kiwing.it",
2256
- "homepage": "https://github.com/cfrutos"
2257
  },
2258
  {
2259
- "name": "Colin O'Dell",
2260
- "email": "colinodell@gmail.com",
2261
- "homepage": "https://www.colinodell.com"
2262
  }
2263
  ],
2264
- "description": "Given a deep data structure, access data by dot notation.",
2265
- "homepage": "https://github.com/dflydev/dflydev-dot-access-data",
2266
  "keywords": [
2267
- "access",
2268
- "data",
2269
- "dot",
2270
- "notation"
 
 
 
 
 
 
 
 
 
 
 
 
2271
  ],
2272
  "support": {
2273
- "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues",
2274
- "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.1"
2275
  },
2276
- "time": "2021-08-13T13:06:58+00:00"
2277
  },
2278
  {
2279
  "name": "dg/mysql-dump",
@@ -2430,23 +2027,23 @@
2430
  },
2431
  {
2432
  "name": "doctrine/inflector",
2433
- "version": "2.0.5",
2434
  "source": {
2435
  "type": "git",
2436
  "url": "https://github.com/doctrine/inflector.git",
2437
- "reference": "ade2b3bbfb776f27f0558e26eed43b5d9fe1b392"
2438
  },
2439
  "dist": {
2440
  "type": "zip",
2441
- "url": "https://api.github.com/repos/doctrine/inflector/zipball/ade2b3bbfb776f27f0558e26eed43b5d9fe1b392",
2442
- "reference": "ade2b3bbfb776f27f0558e26eed43b5d9fe1b392",
2443
  "shasum": ""
2444
  },
2445
  "require": {
2446
  "php": "^7.2 || ^8.0"
2447
  },
2448
  "require-dev": {
2449
- "doctrine/coding-standard": "^9",
2450
  "phpstan/phpstan": "^1.8",
2451
  "phpstan/phpstan-phpunit": "^1.1",
2452
  "phpstan/phpstan-strict-rules": "^1.3",
@@ -2501,7 +2098,7 @@
2501
  ],
2502
  "support": {
2503
  "issues": "https://github.com/doctrine/inflector/issues",
2504
- "source": "https://github.com/doctrine/inflector/tree/2.0.5"
2505
  },
2506
  "funding": [
2507
  {
@@ -2517,7 +2114,7 @@
2517
  "type": "tidelift"
2518
  }
2519
  ],
2520
- "time": "2022-09-07T09:01:28+00:00"
2521
  },
2522
  {
2523
  "name": "doctrine/instantiator",
@@ -2826,16 +2423,16 @@
2826
  },
2827
  {
2828
  "name": "friendsofphp/php-cs-fixer",
2829
- "version": "v3.12.0",
2830
  "source": {
2831
  "type": "git",
2832
- "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
2833
- "reference": "eae11d945e2885d86e1c080eec1bb30a2aa27998"
2834
  },
2835
  "dist": {
2836
  "type": "zip",
2837
- "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/eae11d945e2885d86e1c080eec1bb30a2aa27998",
2838
- "reference": "eae11d945e2885d86e1c080eec1bb30a2aa27998",
2839
  "shasum": ""
2840
  },
2841
  "require": {
@@ -2859,7 +2456,7 @@
2859
  },
2860
  "require-dev": {
2861
  "justinrainbow/json-schema": "^5.2",
2862
- "keradus/cli-executor": "^1.5",
2863
  "mikey179/vfsstream": "^1.6.10",
2864
  "php-coveralls/php-coveralls": "^2.5.2",
2865
  "php-cs-fixer/accessible-object": "^1.1",
@@ -2902,8 +2499,8 @@
2902
  ],
2903
  "description": "A tool to automatically fix PHP code style",
2904
  "support": {
2905
- "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues",
2906
- "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.12.0"
2907
  },
2908
  "funding": [
2909
  {
@@ -2911,7 +2508,7 @@
2911
  "type": "github"
2912
  }
2913
  ],
2914
- "time": "2022-10-12T14:20:51+00:00"
2915
  },
2916
  {
2917
  "name": "gettext/gettext",
@@ -2996,16 +2593,16 @@
2996
  },
2997
  {
2998
  "name": "gettext/languages",
2999
- "version": "2.9.0",
3000
  "source": {
3001
  "type": "git",
3002
  "url": "https://github.com/php-gettext/Languages.git",
3003
- "reference": "ed56dd2c7f4024cc953ed180d25f02f2640e3ffa"
3004
  },
3005
  "dist": {
3006
  "type": "zip",
3007
- "url": "https://api.github.com/repos/php-gettext/Languages/zipball/ed56dd2c7f4024cc953ed180d25f02f2640e3ffa",
3008
- "reference": "ed56dd2c7f4024cc953ed180d25f02f2640e3ffa",
3009
  "shasum": ""
3010
  },
3011
  "require": {
@@ -3054,7 +2651,7 @@
3054
  ],
3055
  "support": {
3056
  "issues": "https://github.com/php-gettext/Languages/issues",
3057
- "source": "https://github.com/php-gettext/Languages/tree/2.9.0"
3058
  },
3059
  "funding": [
3060
  {
@@ -3066,58 +2663,7 @@
3066
  "type": "github"
3067
  }
3068
  ],
3069
- "time": "2021-11-11T17:30:39+00:00"
3070
- },
3071
- {
3072
- "name": "grasmash/expander",
3073
- "version": "2.0.3",
3074
- "source": {
3075
- "type": "git",
3076
- "url": "https://github.com/grasmash/expander.git",
3077
- "reference": "b7cbc1f2fdf9a9c0e253a424c2a4058316b7cb6e"
3078
- },
3079
- "dist": {
3080
- "type": "zip",
3081
- "url": "https://api.github.com/repos/grasmash/expander/zipball/b7cbc1f2fdf9a9c0e253a424c2a4058316b7cb6e",
3082
- "reference": "b7cbc1f2fdf9a9c0e253a424c2a4058316b7cb6e",
3083
- "shasum": ""
3084
- },
3085
- "require": {
3086
- "dflydev/dot-access-data": "^3.0.0",
3087
- "php": ">=7.1",
3088
- "psr/log": "^1 | ^2 | ^3"
3089
- },
3090
- "require-dev": {
3091
- "greg-1-anderson/composer-test-scenarios": "^1",
3092
- "phpunit/phpunit": "^6.0 || ^8.0 || ^9",
3093
- "squizlabs/php_codesniffer": "^2.7 || ^3.3"
3094
- },
3095
- "type": "library",
3096
- "extra": {
3097
- "branch-alias": {
3098
- "dev-master": "1.x-dev"
3099
- }
3100
- },
3101
- "autoload": {
3102
- "psr-4": {
3103
- "Grasmash\\Expander\\": "src/"
3104
- }
3105
- },
3106
- "notification-url": "https://packagist.org/downloads/",
3107
- "license": [
3108
- "MIT"
3109
- ],
3110
- "authors": [
3111
- {
3112
- "name": "Matthew Grasmick"
3113
- }
3114
- ],
3115
- "description": "Expands internal property references in PHP arrays file.",
3116
- "support": {
3117
- "issues": "https://github.com/grasmash/expander/issues",
3118
- "source": "https://github.com/grasmash/expander/tree/2.0.3"
3119
- },
3120
- "time": "2022-04-25T22:17:46+00:00"
3121
  },
3122
  {
3123
  "name": "guzzlehttp/guzzle",
@@ -3333,16 +2879,16 @@
3333
  },
3334
  {
3335
  "name": "guzzlehttp/psr7",
3336
- "version": "2.4.1",
3337
  "source": {
3338
  "type": "git",
3339
  "url": "https://github.com/guzzle/psr7.git",
3340
- "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379"
3341
  },
3342
  "dist": {
3343
  "type": "zip",
3344
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/69568e4293f4fa993f3b0e51c9723e1e17c41379",
3345
- "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379",
3346
  "shasum": ""
3347
  },
3348
  "require": {
@@ -3432,7 +2978,7 @@
3432
  ],
3433
  "support": {
3434
  "issues": "https://github.com/guzzle/psr7/issues",
3435
- "source": "https://github.com/guzzle/psr7/tree/2.4.1"
3436
  },
3437
  "funding": [
3438
  {
@@ -3448,11 +2994,11 @@
3448
  "type": "tidelift"
3449
  }
3450
  ],
3451
- "time": "2022-08-28T14:45:39+00:00"
3452
  },
3453
  {
3454
  "name": "illuminate/collections",
3455
- "version": "v8.83.25",
3456
  "source": {
3457
  "type": "git",
3458
  "url": "https://github.com/illuminate/collections.git",
@@ -3506,7 +3052,7 @@
3506
  },
3507
  {
3508
  "name": "illuminate/contracts",
3509
- "version": "v8.83.25",
3510
  "source": {
3511
  "type": "git",
3512
  "url": "https://github.com/illuminate/contracts.git",
@@ -3554,7 +3100,7 @@
3554
  },
3555
  {
3556
  "name": "illuminate/macroable",
3557
- "version": "v8.83.25",
3558
  "source": {
3559
  "type": "git",
3560
  "url": "https://github.com/illuminate/macroable.git",
@@ -3600,7 +3146,7 @@
3600
  },
3601
  {
3602
  "name": "illuminate/support",
3603
- "version": "v8.83.25",
3604
  "source": {
3605
  "type": "git",
3606
  "url": "https://github.com/illuminate/support.git",
@@ -3736,88 +3282,6 @@
3736
  },
3737
  "time": "2022-04-13T08:02:27+00:00"
3738
  },
3739
- {
3740
- "name": "league/container",
3741
- "version": "4.2.0",
3742
- "source": {
3743
- "type": "git",
3744
- "url": "https://github.com/thephpleague/container.git",
3745
- "reference": "375d13cb828649599ef5d48a339c4af7a26cd0ab"
3746
- },
3747
- "dist": {
3748
- "type": "zip",
3749
- "url": "https://api.github.com/repos/thephpleague/container/zipball/375d13cb828649599ef5d48a339c4af7a26cd0ab",
3750
- "reference": "375d13cb828649599ef5d48a339c4af7a26cd0ab",
3751
- "shasum": ""
3752
- },
3753
- "require": {
3754
- "php": "^7.2 || ^8.0",
3755
- "psr/container": "^1.1 || ^2.0"
3756
- },
3757
- "provide": {
3758
- "psr/container-implementation": "^1.0"
3759
- },
3760
- "replace": {
3761
- "orno/di": "~2.0"
3762
- },
3763
- "require-dev": {
3764
- "nette/php-generator": "^3.4",
3765
- "nikic/php-parser": "^4.10",
3766
- "phpstan/phpstan": "^0.12.47",
3767
- "phpunit/phpunit": "^8.5.17",
3768
- "roave/security-advisories": "dev-latest",
3769
- "scrutinizer/ocular": "^1.8",
3770
- "squizlabs/php_codesniffer": "^3.6"
3771
- },
3772
- "type": "library",
3773
- "extra": {
3774
- "branch-alias": {
3775
- "dev-master": "4.x-dev",
3776
- "dev-4.x": "4.x-dev",
3777
- "dev-3.x": "3.x-dev",
3778
- "dev-2.x": "2.x-dev",
3779
- "dev-1.x": "1.x-dev"
3780
- }
3781
- },
3782
- "autoload": {
3783
- "psr-4": {
3784
- "League\\Container\\": "src"
3785
- }
3786
- },
3787
- "notification-url": "https://packagist.org/downloads/",
3788
- "license": [
3789
- "MIT"
3790
- ],
3791
- "authors": [
3792
- {
3793
- "name": "Phil Bennett",
3794
- "email": "mail@philbennett.co.uk",
3795
- "role": "Developer"
3796
- }
3797
- ],
3798
- "description": "A fast and intuitive dependency injection container.",
3799
- "homepage": "https://github.com/thephpleague/container",
3800
- "keywords": [
3801
- "container",
3802
- "dependency",
3803
- "di",
3804
- "injection",
3805
- "league",
3806
- "provider",
3807
- "service"
3808
- ],
3809
- "support": {
3810
- "issues": "https://github.com/thephpleague/container/issues",
3811
- "source": "https://github.com/thephpleague/container/tree/4.2.0"
3812
- },
3813
- "funding": [
3814
- {
3815
- "url": "https://github.com/philipobenito",
3816
- "type": "github"
3817
- }
3818
- ],
3819
- "time": "2021-11-16T10:29:06+00:00"
3820
- },
3821
  {
3822
  "name": "lucatume/wp-browser",
3823
  "version": "3.1.6",
@@ -4233,79 +3697,6 @@
4233
  },
4234
  "time": "2020-12-25T09:08:58+00:00"
4235
  },
4236
- {
4237
- "name": "nelexa/zip",
4238
- "version": "4.0.2",
4239
- "source": {
4240
- "type": "git",
4241
- "url": "https://github.com/Ne-Lexa/php-zip.git",
4242
- "reference": "88a1b6549be813278ff2dd3b6b2ac188827634a7"
4243
- },
4244
- "dist": {
4245
- "type": "zip",
4246
- "url": "https://api.github.com/repos/Ne-Lexa/php-zip/zipball/88a1b6549be813278ff2dd3b6b2ac188827634a7",
4247
- "reference": "88a1b6549be813278ff2dd3b6b2ac188827634a7",
4248
- "shasum": ""
4249
- },
4250
- "require": {
4251
- "ext-zlib": "*",
4252
- "php": "^7.4 || ^8.0",
4253
- "psr/http-message": "*",
4254
- "symfony/finder": "*"
4255
- },
4256
- "require-dev": {
4257
- "ext-bz2": "*",
4258
- "ext-dom": "*",
4259
- "ext-fileinfo": "*",
4260
- "ext-iconv": "*",
4261
- "ext-openssl": "*",
4262
- "ext-xml": "*",
4263
- "friendsofphp/php-cs-fixer": "^3.4.0",
4264
- "guzzlehttp/psr7": "^1.6",
4265
- "phpunit/phpunit": "^9",
4266
- "symfony/http-foundation": "*",
4267
- "symfony/var-dumper": "*",
4268
- "vimeo/psalm": "^4.6"
4269
- },
4270
- "suggest": {
4271
- "ext-bz2": "Needed to support BZIP2 compression",
4272
- "ext-fileinfo": "Needed to get mime-type file",
4273
- "ext-iconv": "Needed to support convert zip entry name to requested character encoding",
4274
- "ext-openssl": "Needed to support encrypt zip entries or use ext-mcrypt"
4275
- },
4276
- "type": "library",
4277
- "autoload": {
4278
- "psr-4": {
4279
- "PhpZip\\": "src/"
4280
- }
4281
- },
4282
- "notification-url": "https://packagist.org/downloads/",
4283
- "license": [
4284
- "MIT"
4285
- ],
4286
- "authors": [
4287
- {
4288
- "name": "Ne-Lexa",
4289
- "email": "alexey@nelexa.ru",
4290
- "role": "Developer"
4291
- }
4292
- ],
4293
- "description": "PhpZip is a php-library for extended work with ZIP-archives. Open, create, update, delete, extract and get info tool. Supports appending to existing ZIP files, WinZip AES encryption, Traditional PKWARE Encryption, BZIP2 compression, external file attributes and ZIP64 extensions. Alternative ZipArchive. It does not require php-zip extension.",
4294
- "homepage": "https://github.com/Ne-Lexa/php-zip",
4295
- "keywords": [
4296
- "archive",
4297
- "extract",
4298
- "unzip",
4299
- "winzip",
4300
- "zip",
4301
- "ziparchive"
4302
- ],
4303
- "support": {
4304
- "issues": "https://github.com/Ne-Lexa/php-zip/issues",
4305
- "source": "https://github.com/Ne-Lexa/php-zip/tree/4.0.2"
4306
- },
4307
- "time": "2022-06-17T11:17:46+00:00"
4308
- },
4309
  {
4310
  "name": "nesbot/carbon",
4311
  "version": "2.62.1",
@@ -5300,16 +4691,16 @@
5300
  },
5301
  {
5302
  "name": "phpstan/phpstan",
5303
- "version": "1.8.9",
5304
  "source": {
5305
  "type": "git",
5306
  "url": "https://github.com/phpstan/phpstan.git",
5307
- "reference": "3a72d9d9f2528fbd50c2d8fcf155fd9f74ade3f2"
5308
  },
5309
  "dist": {
5310
  "type": "zip",
5311
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/3a72d9d9f2528fbd50c2d8fcf155fd9f74ade3f2",
5312
- "reference": "3a72d9d9f2528fbd50c2d8fcf155fd9f74ade3f2",
5313
  "shasum": ""
5314
  },
5315
  "require": {
@@ -5339,7 +4730,7 @@
5339
  ],
5340
  "support": {
5341
  "issues": "https://github.com/phpstan/phpstan/issues",
5342
- "source": "https://github.com/phpstan/phpstan/tree/1.8.9"
5343
  },
5344
  "funding": [
5345
  {
@@ -5355,7 +4746,7 @@
5355
  "type": "tidelift"
5356
  }
5357
  ],
5358
- "time": "2022-10-13T13:40:18+00:00"
5359
  },
5360
  {
5361
  "name": "phpunit/php-code-coverage",
@@ -5883,54 +5274,6 @@
5883
  },
5884
  "time": "2016-08-06T20:24:11+00:00"
5885
  },
5886
- {
5887
- "name": "psr/container",
5888
- "version": "1.1.2",
5889
- "source": {
5890
- "type": "git",
5891
- "url": "https://github.com/php-fig/container.git",
5892
- "reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
5893
- },
5894
- "dist": {
5895
- "type": "zip",
5896
- "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
5897
- "reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
5898
- "shasum": ""
5899
- },
5900
- "require": {
5901
- "php": ">=7.4.0"
5902
- },
5903
- "type": "library",
5904
- "autoload": {
5905
- "psr-4": {
5906
- "Psr\\Container\\": "src/"
5907
- }
5908
- },
5909
- "notification-url": "https://packagist.org/downloads/",
5910
- "license": [
5911
- "MIT"
5912
- ],
5913
- "authors": [
5914
- {
5915
- "name": "PHP-FIG",
5916
- "homepage": "https://www.php-fig.org/"
5917
- }
5918
- ],
5919
- "description": "Common Container Interface (PHP FIG PSR-11)",
5920
- "homepage": "https://github.com/php-fig/container",
5921
- "keywords": [
5922
- "PSR-11",
5923
- "container",
5924
- "container-interface",
5925
- "container-interop",
5926
- "psr"
5927
- ],
5928
- "support": {
5929
- "issues": "https://github.com/php-fig/container/issues",
5930
- "source": "https://github.com/php-fig/container/tree/1.1.2"
5931
- },
5932
- "time": "2021-11-05T16:50:12+00:00"
5933
- },
5934
  {
5935
  "name": "psr/event-dispatcher",
5936
  "version": "1.0.0",
@@ -6298,59 +5641,6 @@
6298
  },
6299
  "time": "2022-06-24T19:58:54+00:00"
6300
  },
6301
- {
6302
- "name": "publishpress/publishpress-plugin-builder",
6303
- "version": "v1.4.0",
6304
- "source": {
6305
- "type": "git",
6306
- "url": "https://github.com/publishpress/PublishPress-Plugin-Builder.git",
6307
- "reference": "75708e8b1b093988dfd160f50b95803bbff725f1"
6308
- },
6309
- "dist": {
6310
- "type": "zip",
6311
- "url": "https://api.github.com/repos/publishpress/PublishPress-Plugin-Builder/zipball/75708e8b1b093988dfd160f50b95803bbff725f1",
6312
- "reference": "75708e8b1b093988dfd160f50b95803bbff725f1",
6313
- "shasum": ""
6314
- },
6315
- "require": {
6316
- "consolidation/robo": "^3.0",
6317
- "nelexa/zip": "^3.3|^4.0",
6318
- "php": "^7.3|^8.0",
6319
- "symfony/yaml": "^5"
6320
- },
6321
- "require-dev": {
6322
- "codeception/codeception": "^4.1",
6323
- "codeception/module-asserts": "^1.0.0",
6324
- "codeception/module-cli": "^1.0",
6325
- "codeception/module-filesystem": "^1.0",
6326
- "codeception/util-universalframework": "^1.0",
6327
- "phpmd/phpmd": "^2.8",
6328
- "phpmetrics/phpmetrics": "^2.7",
6329
- "squizlabs/php_codesniffer": "^3.5"
6330
- },
6331
- "type": "library",
6332
- "autoload": {
6333
- "psr-4": {
6334
- "PublishPressBuilder\\": "src/"
6335
- }
6336
- },
6337
- "notification-url": "https://packagist.org/downloads/",
6338
- "license": [
6339
- "GPL-2.0-or-later"
6340
- ],
6341
- "authors": [
6342
- {
6343
- "name": "PublishPress",
6344
- "email": "help@publishpress.com"
6345
- }
6346
- ],
6347
- "description": "Robo tasks for building WordPress plugins",
6348
- "support": {
6349
- "issues": "https://github.com/publishpress/PublishPress-Plugin-Builder/issues",
6350
- "source": "https://github.com/publishpress/PublishPress-Plugin-Builder/tree/v1.4.0"
6351
- },
6352
- "time": "2022-04-14T15:14:49+00:00"
6353
- },
6354
  {
6355
  "name": "ralouphie/getallheaders",
6356
  "version": "3.0.3",
@@ -8127,16 +7417,16 @@
8127
  },
8128
  {
8129
  "name": "symfony/console",
8130
- "version": "v5.4.14",
8131
  "source": {
8132
  "type": "git",
8133
  "url": "https://github.com/symfony/console.git",
8134
- "reference": "984ea2c0f45f42dfed01d2f3987b187467c4b16d"
8135
  },
8136
  "dist": {
8137
  "type": "zip",
8138
- "url": "https://api.github.com/repos/symfony/console/zipball/984ea2c0f45f42dfed01d2f3987b187467c4b16d",
8139
- "reference": "984ea2c0f45f42dfed01d2f3987b187467c4b16d",
8140
  "shasum": ""
8141
  },
8142
  "require": {
@@ -8206,7 +7496,7 @@
8206
  "terminal"
8207
  ],
8208
  "support": {
8209
- "source": "https://github.com/symfony/console/tree/v5.4.14"
8210
  },
8211
  "funding": [
8212
  {
@@ -8222,7 +7512,7 @@
8222
  "type": "tidelift"
8223
  }
8224
  ],
8225
- "time": "2022-10-07T08:01:20+00:00"
8226
  },
8227
  {
8228
  "name": "symfony/css-selector",
@@ -8292,41 +7582,39 @@
8292
  },
8293
  {
8294
  "name": "symfony/dependency-injection",
8295
- "version": "v5.4.13",
8296
  "source": {
8297
  "type": "git",
8298
  "url": "https://github.com/symfony/dependency-injection.git",
8299
- "reference": "24cf522668845391c0542bc1de496366072a6d0e"
8300
  },
8301
  "dist": {
8302
  "type": "zip",
8303
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/24cf522668845391c0542bc1de496366072a6d0e",
8304
- "reference": "24cf522668845391c0542bc1de496366072a6d0e",
8305
  "shasum": ""
8306
  },
8307
  "require": {
8308
  "php": ">=7.2.5",
8309
- "psr/container": "^1.1.1",
8310
- "symfony/deprecation-contracts": "^2.1|^3",
8311
  "symfony/polyfill-php80": "^1.16",
8312
- "symfony/polyfill-php81": "^1.22",
8313
  "symfony/service-contracts": "^1.1.6|^2"
8314
  },
8315
  "conflict": {
8316
- "ext-psr": "<1.1|>=2",
8317
- "symfony/config": "<5.3",
8318
  "symfony/finder": "<4.4",
8319
  "symfony/proxy-manager-bridge": "<4.4",
8320
- "symfony/yaml": "<4.4.26"
8321
  },
8322
  "provide": {
8323
  "psr/container-implementation": "1.0",
8324
  "symfony/service-implementation": "1.0|2.0"
8325
  },
8326
  "require-dev": {
8327
- "symfony/config": "^5.3|^6.0",
8328
- "symfony/expression-language": "^4.4|^5.0|^6.0",
8329
- "symfony/yaml": "^4.4.26|^5.0|^6.0"
8330
  },
8331
  "suggest": {
8332
  "symfony/config": "",
@@ -8361,7 +7649,7 @@
8361
  "description": "Allows you to standardize and centralize the way objects are constructed in your application",
8362
  "homepage": "https://symfony.com",
8363
  "support": {
8364
- "source": "https://github.com/symfony/dependency-injection/tree/v5.4.13"
8365
  },
8366
  "funding": [
8367
  {
@@ -8377,7 +7665,7 @@
8377
  "type": "tidelift"
8378
  }
8379
  ],
8380
- "time": "2022-08-30T19:10:13+00:00"
8381
  },
8382
  {
8383
  "name": "symfony/deprecation-contracts",
@@ -8448,16 +7736,16 @@
8448
  },
8449
  {
8450
  "name": "symfony/dom-crawler",
8451
- "version": "v5.4.12",
8452
  "source": {
8453
  "type": "git",
8454
  "url": "https://github.com/symfony/dom-crawler.git",
8455
- "reference": "291c1e92281a09152dda089f782e23dedd34bd4f"
8456
  },
8457
  "dist": {
8458
  "type": "zip",
8459
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/291c1e92281a09152dda089f782e23dedd34bd4f",
8460
- "reference": "291c1e92281a09152dda089f782e23dedd34bd4f",
8461
  "shasum": ""
8462
  },
8463
  "require": {
@@ -8503,7 +7791,7 @@
8503
  "description": "Eases DOM navigation for HTML and XML documents",
8504
  "homepage": "https://symfony.com",
8505
  "support": {
8506
- "source": "https://github.com/symfony/dom-crawler/tree/v5.4.12"
8507
  },
8508
  "funding": [
8509
  {
@@ -8519,7 +7807,7 @@
8519
  "type": "tidelift"
8520
  }
8521
  ],
8522
- "time": "2022-08-03T13:09:21+00:00"
8523
  },
8524
  {
8525
  "name": "symfony/event-dispatcher",
@@ -9516,25 +8804,21 @@
9516
  },
9517
  {
9518
  "name": "symfony/service-contracts",
9519
- "version": "v2.5.2",
9520
  "source": {
9521
  "type": "git",
9522
  "url": "https://github.com/symfony/service-contracts.git",
9523
- "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c"
9524
  },
9525
  "dist": {
9526
  "type": "zip",
9527
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
9528
- "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
9529
  "shasum": ""
9530
  },
9531
  "require": {
9532
  "php": ">=7.2.5",
9533
- "psr/container": "^1.1",
9534
- "symfony/deprecation-contracts": "^2.1|^3"
9535
- },
9536
- "conflict": {
9537
- "ext-psr": "<1.1|>=2"
9538
  },
9539
  "suggest": {
9540
  "symfony/service-implementation": ""
@@ -9542,7 +8826,7 @@
9542
  "type": "library",
9543
  "extra": {
9544
  "branch-alias": {
9545
- "dev-main": "2.5-dev"
9546
  },
9547
  "thanks": {
9548
  "name": "symfony/contracts",
@@ -9579,7 +8863,7 @@
9579
  "standards"
9580
  ],
9581
  "support": {
9582
- "source": "https://github.com/symfony/service-contracts/tree/v2.5.2"
9583
  },
9584
  "funding": [
9585
  {
@@ -9595,7 +8879,7 @@
9595
  "type": "tidelift"
9596
  }
9597
  ],
9598
- "time": "2022-05-30T19:17:29+00:00"
9599
  },
9600
  {
9601
  "name": "symfony/stopwatch",
@@ -9661,16 +8945,16 @@
9661
  },
9662
  {
9663
  "name": "symfony/string",
9664
- "version": "v5.4.14",
9665
  "source": {
9666
  "type": "git",
9667
  "url": "https://github.com/symfony/string.git",
9668
- "reference": "089e7237497fae7a9c404d0c3aeb8db3254733e4"
9669
  },
9670
  "dist": {
9671
  "type": "zip",
9672
- "url": "https://api.github.com/repos/symfony/string/zipball/089e7237497fae7a9c404d0c3aeb8db3254733e4",
9673
- "reference": "089e7237497fae7a9c404d0c3aeb8db3254733e4",
9674
  "shasum": ""
9675
  },
9676
  "require": {
@@ -9727,7 +9011,7 @@
9727
  "utf8"
9728
  ],
9729
  "support": {
9730
- "source": "https://github.com/symfony/string/tree/v5.4.14"
9731
  },
9732
  "funding": [
9733
  {
@@ -10184,16 +9468,16 @@
10184
  },
10185
  {
10186
  "name": "vimeo/psalm",
10187
- "version": "4.29.0",
10188
  "source": {
10189
  "type": "git",
10190
  "url": "https://github.com/vimeo/psalm.git",
10191
- "reference": "7ec5ffbd5f68ae03782d7fd33fff0c45a69f95b3"
10192
  },
10193
  "dist": {
10194
  "type": "zip",
10195
- "url": "https://api.github.com/repos/vimeo/psalm/zipball/7ec5ffbd5f68ae03782d7fd33fff0c45a69f95b3",
10196
- "reference": "7ec5ffbd5f68ae03782d7fd33fff0c45a69f95b3",
10197
  "shasum": ""
10198
  },
10199
  "require": {
@@ -10286,9 +9570,9 @@
10286
  ],
10287
  "support": {
10288
  "issues": "https://github.com/vimeo/psalm/issues",
10289
- "source": "https://github.com/vimeo/psalm/tree/4.29.0"
10290
  },
10291
- "time": "2022-10-11T17:09:17+00:00"
10292
  },
10293
  {
10294
  "name": "voku/portable-ascii",
@@ -10647,16 +9931,16 @@
10647
  },
10648
  {
10649
  "name": "wp-cli/php-cli-tools",
10650
- "version": "v0.11.15",
10651
  "source": {
10652
  "type": "git",
10653
  "url": "https://github.com/wp-cli/php-cli-tools.git",
10654
- "reference": "b6edd35988892ea1451392eb7a26d9dbe98c836d"
10655
  },
10656
  "dist": {
10657
  "type": "zip",
10658
- "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/b6edd35988892ea1451392eb7a26d9dbe98c836d",
10659
- "reference": "b6edd35988892ea1451392eb7a26d9dbe98c836d",
10660
  "shasum": ""
10661
  },
10662
  "require": {
@@ -10695,22 +9979,22 @@
10695
  ],
10696
  "support": {
10697
  "issues": "https://github.com/wp-cli/php-cli-tools/issues",
10698
- "source": "https://github.com/wp-cli/php-cli-tools/tree/v0.11.15"
10699
  },
10700
- "time": "2022-08-15T10:15:55+00:00"
10701
  },
10702
  {
10703
  "name": "wp-cli/wp-cli",
10704
- "version": "v2.7.0",
10705
  "source": {
10706
  "type": "git",
10707
  "url": "https://github.com/wp-cli/wp-cli.git",
10708
- "reference": "832b7635a39b4e468c634572baaab2710a55d88b"
10709
  },
10710
  "dist": {
10711
  "type": "zip",
10712
- "url": "https://api.github.com/repos/wp-cli/wp-cli/zipball/832b7635a39b4e468c634572baaab2710a55d88b",
10713
- "reference": "832b7635a39b4e468c634572baaab2710a55d88b",
10714
  "shasum": ""
10715
  },
10716
  "require": {
@@ -10741,7 +10025,7 @@
10741
  "type": "library",
10742
  "extra": {
10743
  "branch-alias": {
10744
- "dev-master": "2.7.x-dev"
10745
  }
10746
  },
10747
  "autoload": {
@@ -10768,7 +10052,7 @@
10768
  "issues": "https://github.com/wp-cli/wp-cli/issues",
10769
  "source": "https://github.com/wp-cli/wp-cli"
10770
  },
10771
- "time": "2022-10-12T05:13:17+00:00"
10772
  },
10773
  {
10774
  "name": "wp-coding-standards/wpcs",
@@ -10887,8 +10171,12 @@
10887
  "prefer-stable": false,
10888
  "prefer-lowest": false,
10889
  "platform": {
10890
- "php": ">=5.6.20"
 
 
 
 
 
10891
  },
10892
- "platform-dev": [],
10893
  "plugin-api-version": "2.3.0"
10894
  }
4
  "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
  "This file is @generated automatically"
6
  ],
7
+ "content-hash": "ca6e051c526e41ef8e2a51b51c8805c5",
8
  "packages": [
9
+ {
10
+ "name": "psr/container",
11
+ "version": "1.0.0",
12
+ "source": {
13
+ "type": "git",
14
+ "url": "https://github.com/php-fig/container.git",
15
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
16
+ },
17
+ "dist": {
18
+ "type": "zip",
19
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
20
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
21
+ "shasum": ""
22
+ },
23
+ "require": {
24
+ "php": ">=5.3.0"
25
+ },
26
+ "type": "library",
27
+ "extra": {
28
+ "branch-alias": {
29
+ "dev-master": "1.0.x-dev"
30
+ }
31
+ },
32
+ "autoload": {
33
+ "psr-4": {
34
+ "Psr\\Container\\": "src/"
35
+ }
36
+ },
37
+ "notification-url": "https://packagist.org/downloads/",
38
+ "license": [
39
+ "MIT"
40
+ ],
41
+ "authors": [
42
+ {
43
+ "name": "PHP-FIG",
44
+ "homepage": "http://www.php-fig.org/"
45
+ }
46
+ ],
47
+ "description": "Common Container Interface (PHP FIG PSR-11)",
48
+ "homepage": "https://github.com/php-fig/container",
49
+ "keywords": [
50
+ "PSR-11",
51
+ "container",
52
+ "container-interface",
53
+ "container-interop",
54
+ "psr"
55
+ ],
56
+ "support": {
57
+ "issues": "https://github.com/php-fig/container/issues",
58
+ "source": "https://github.com/php-fig/container/tree/master"
59
+ },
60
+ "time": "2017-02-14T16:28:37+00:00"
61
+ },
62
  {
63
  "name": "publishpress/publishpress-instance-protection",
64
+ "version": "v1.0.3",
65
  "source": {
66
  "type": "git",
67
  "url": "https://github.com/publishpress/publishpress-instance-protection.git",
68
+ "reference": "6a4e7038c95fac43264b1d61a5cdae2b1e3cc4ee"
69
  },
70
  "dist": {
71
  "type": "zip",
72
+ "url": "https://api.github.com/repos/publishpress/publishpress-instance-protection/zipball/6a4e7038c95fac43264b1d61a5cdae2b1e3cc4ee",
73
+ "reference": "6a4e7038c95fac43264b1d61a5cdae2b1e3cc4ee",
74
  "shasum": ""
75
  },
76
  "require": {
94
  ],
95
  "support": {
96
  "issues": "https://github.com/publishpress/publishpress-instance-protection/issues",
97
+ "source": "https://github.com/publishpress/publishpress-instance-protection/tree/v1.0.3"
98
  },
99
+ "time": "2022-10-28T16:14:03+00:00"
100
  },
101
  {
102
  "name": "publishpress/wordpress-reviews",
1581
  },
1582
  {
1583
  "name": "composer/pcre",
1584
+ "version": "3.0.2",
1585
  "source": {
1586
  "type": "git",
1587
  "url": "https://github.com/composer/pcre.git",
1588
+ "reference": "4482b6409ca6bfc2af043a5711cd21ac3e7a8dfb"
1589
  },
1590
  "dist": {
1591
  "type": "zip",
1592
+ "url": "https://api.github.com/repos/composer/pcre/zipball/4482b6409ca6bfc2af043a5711cd21ac3e7a8dfb",
1593
+ "reference": "4482b6409ca6bfc2af043a5711cd21ac3e7a8dfb",
1594
  "shasum": ""
1595
  },
1596
  "require": {
1632
  ],
1633
  "support": {
1634
  "issues": "https://github.com/composer/pcre/issues",
1635
+ "source": "https://github.com/composer/pcre/tree/3.0.2"
1636
  },
1637
  "funding": [
1638
  {
1648
  "type": "tidelift"
1649
  }
1650
  ],
1651
+ "time": "2022-11-03T20:24:16+00:00"
1652
  },
1653
  {
1654
  "name": "composer/semver",
1797
  ],
1798
  "time": "2022-02-25T21:32:43+00:00"
1799
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1800
  {
1801
  "name": "dealerdirect/phpcodesniffer-composer-installer",
1802
  "version": "v0.7.2",
1818
  },
1819
  "require-dev": {
1820
  "composer/composer": "*",
1821
+ "php-parallel-lint/php-parallel-lint": "^1.3.1",
1822
+ "phpcompatibility/php-compatibility": "^9.0"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1823
  },
1824
+ "type": "composer-plugin",
1825
  "extra": {
1826
+ "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
 
 
1827
  },
1828
  "autoload": {
1829
  "psr-4": {
1830
+ "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
1831
  }
1832
  },
1833
  "notification-url": "https://packagist.org/downloads/",
1836
  ],
1837
  "authors": [
1838
  {
1839
+ "name": "Franck Nijhof",
1840
+ "email": "franck.nijhof@dealerdirect.com",
1841
+ "homepage": "http://www.frenck.nl",
1842
+ "role": "Developer / IT Manager"
 
 
 
 
 
 
 
 
 
1843
  },
1844
  {
1845
+ "name": "Contributors",
1846
+ "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors"
 
1847
  }
1848
  ],
1849
+ "description": "PHP_CodeSniffer Standards Composer Installer Plugin",
1850
+ "homepage": "http://www.dealerdirect.com",
1851
  "keywords": [
1852
+ "PHPCodeSniffer",
1853
+ "PHP_CodeSniffer",
1854
+ "code quality",
1855
+ "codesniffer",
1856
+ "composer",
1857
+ "installer",
1858
+ "phpcbf",
1859
+ "phpcs",
1860
+ "plugin",
1861
+ "qa",
1862
+ "quality",
1863
+ "standard",
1864
+ "standards",
1865
+ "style guide",
1866
+ "stylecheck",
1867
+ "tests"
1868
  ],
1869
  "support": {
1870
+ "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues",
1871
+ "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer"
1872
  },
1873
+ "time": "2022-02-04T12:51:07+00:00"
1874
  },
1875
  {
1876
  "name": "dg/mysql-dump",
2027
  },
2028
  {
2029
  "name": "doctrine/inflector",
2030
+ "version": "2.0.6",
2031
  "source": {
2032
  "type": "git",
2033
  "url": "https://github.com/doctrine/inflector.git",
2034
+ "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024"
2035
  },
2036
  "dist": {
2037
  "type": "zip",
2038
+ "url": "https://api.github.com/repos/doctrine/inflector/zipball/d9d313a36c872fd6ee06d9a6cbcf713eaa40f024",
2039
+ "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024",
2040
  "shasum": ""
2041
  },
2042
  "require": {
2043
  "php": "^7.2 || ^8.0"
2044
  },
2045
  "require-dev": {
2046
+ "doctrine/coding-standard": "^10",
2047
  "phpstan/phpstan": "^1.8",
2048
  "phpstan/phpstan-phpunit": "^1.1",
2049
  "phpstan/phpstan-strict-rules": "^1.3",
2098
  ],
2099
  "support": {
2100
  "issues": "https://github.com/doctrine/inflector/issues",
2101
+ "source": "https://github.com/doctrine/inflector/tree/2.0.6"
2102
  },
2103
  "funding": [
2104
  {
2114
  "type": "tidelift"
2115
  }
2116
  ],
2117
+ "time": "2022-10-20T09:10:12+00:00"
2118
  },
2119
  {
2120
  "name": "doctrine/instantiator",
2423
  },
2424
  {
2425
  "name": "friendsofphp/php-cs-fixer",
2426
+ "version": "v3.13.0",
2427
  "source": {
2428
  "type": "git",
2429
+ "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
2430
+ "reference": "a6232229a8309e8811dc751c28b91cb34b2943e1"
2431
  },
2432
  "dist": {
2433
  "type": "zip",
2434
+ "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a6232229a8309e8811dc751c28b91cb34b2943e1",
2435
+ "reference": "a6232229a8309e8811dc751c28b91cb34b2943e1",
2436
  "shasum": ""
2437
  },
2438
  "require": {
2456
  },
2457
  "require-dev": {
2458
  "justinrainbow/json-schema": "^5.2",
2459
+ "keradus/cli-executor": "^2.0",
2460
  "mikey179/vfsstream": "^1.6.10",
2461
  "php-coveralls/php-coveralls": "^2.5.2",
2462
  "php-cs-fixer/accessible-object": "^1.1",
2499
  ],
2500
  "description": "A tool to automatically fix PHP code style",
2501
  "support": {
2502
+ "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
2503
+ "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.13.0"
2504
  },
2505
  "funding": [
2506
  {
2508
  "type": "github"
2509
  }
2510
  ],
2511
+ "time": "2022-10-31T19:28:50+00:00"
2512
  },
2513
  {
2514
  "name": "gettext/gettext",
2593
  },
2594
  {
2595
  "name": "gettext/languages",
2596
+ "version": "2.10.0",
2597
  "source": {
2598
  "type": "git",
2599
  "url": "https://github.com/php-gettext/Languages.git",
2600
+ "reference": "4d61d67fe83a2ad85959fe6133d6d9ba7dddd1ab"
2601
  },
2602
  "dist": {
2603
  "type": "zip",
2604
+ "url": "https://api.github.com/repos/php-gettext/Languages/zipball/4d61d67fe83a2ad85959fe6133d6d9ba7dddd1ab",
2605
+ "reference": "4d61d67fe83a2ad85959fe6133d6d9ba7dddd1ab",
2606
  "shasum": ""
2607
  },
2608
  "require": {
2651
  ],
2652
  "support": {
2653
  "issues": "https://github.com/php-gettext/Languages/issues",
2654
+ "source": "https://github.com/php-gettext/Languages/tree/2.10.0"
2655
  },
2656
  "funding": [
2657
  {
2663
  "type": "github"
2664
  }
2665
  ],
2666
+ "time": "2022-10-18T15:00:10+00:00"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2667
  },
2668
  {
2669
  "name": "guzzlehttp/guzzle",
2879
  },
2880
  {
2881
  "name": "guzzlehttp/psr7",
2882
+ "version": "2.4.3",
2883
  "source": {
2884
  "type": "git",
2885
  "url": "https://github.com/guzzle/psr7.git",
2886
+ "reference": "67c26b443f348a51926030c83481b85718457d3d"
2887
  },
2888
  "dist": {
2889
  "type": "zip",
2890
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d",
2891
+ "reference": "67c26b443f348a51926030c83481b85718457d3d",
2892
  "shasum": ""
2893
  },
2894
  "require": {
2978
  ],
2979
  "support": {
2980
  "issues": "https://github.com/guzzle/psr7/issues",
2981
+ "source": "https://github.com/guzzle/psr7/tree/2.4.3"
2982
  },
2983
  "funding": [
2984
  {
2994
  "type": "tidelift"
2995
  }
2996
  ],
2997
+ "time": "2022-10-26T14:07:24+00:00"
2998
  },
2999
  {
3000
  "name": "illuminate/collections",
3001
+ "version": "v8.83.26",
3002
  "source": {
3003
  "type": "git",
3004
  "url": "https://github.com/illuminate/collections.git",
3052
  },
3053
  {
3054
  "name": "illuminate/contracts",
3055
+ "version": "v8.83.26",
3056
  "source": {
3057
  "type": "git",
3058
  "url": "https://github.com/illuminate/contracts.git",
3100
  },
3101
  {
3102
  "name": "illuminate/macroable",
3103
+ "version": "v8.83.26",
3104
  "source": {
3105
  "type": "git",
3106
  "url": "https://github.com/illuminate/macroable.git",
3146
  },
3147
  {
3148
  "name": "illuminate/support",
3149
+ "version": "v8.83.26",
3150
  "source": {
3151
  "type": "git",
3152
  "url": "https://github.com/illuminate/support.git",
3282
  },
3283
  "time": "2022-04-13T08:02:27+00:00"
3284
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3285
  {
3286
  "name": "lucatume/wp-browser",
3287
  "version": "3.1.6",
3697
  },
3698
  "time": "2020-12-25T09:08:58+00:00"
3699
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3700
  {
3701
  "name": "nesbot/carbon",
3702
  "version": "2.62.1",
4691
  },
4692
  {
4693
  "name": "phpstan/phpstan",
4694
+ "version": "1.9.1",
4695
  "source": {
4696
  "type": "git",
4697
  "url": "https://github.com/phpstan/phpstan.git",
4698
+ "reference": "a59c8b5bfd4a236f27efc8b5ce72c313c2b54b5f"
4699
  },
4700
  "dist": {
4701
  "type": "zip",
4702
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a59c8b5bfd4a236f27efc8b5ce72c313c2b54b5f",
4703
+ "reference": "a59c8b5bfd4a236f27efc8b5ce72c313c2b54b5f",
4704
  "shasum": ""
4705
  },
4706
  "require": {
4730
  ],
4731
  "support": {
4732
  "issues": "https://github.com/phpstan/phpstan/issues",
4733
+ "source": "https://github.com/phpstan/phpstan/tree/1.9.1"
4734
  },
4735
  "funding": [
4736
  {
4746
  "type": "tidelift"
4747
  }
4748
  ],
4749
+ "time": "2022-11-04T13:35:59+00:00"
4750
  },
4751
  {
4752
  "name": "phpunit/php-code-coverage",
5274
  },
5275
  "time": "2016-08-06T20:24:11+00:00"
5276
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5277
  {
5278
  "name": "psr/event-dispatcher",
5279
  "version": "1.0.0",
5641
  },
5642
  "time": "2022-06-24T19:58:54+00:00"
5643
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5644
  {
5645
  "name": "ralouphie/getallheaders",
5646
  "version": "3.0.3",
7417
  },
7418
  {
7419
  "name": "symfony/console",
7420
+ "version": "v5.4.15",
7421
  "source": {
7422
  "type": "git",
7423
  "url": "https://github.com/symfony/console.git",
7424
+ "reference": "ea59bb0edfaf9f28d18d8791410ee0355f317669"
7425
  },
7426
  "dist": {
7427
  "type": "zip",
7428
+ "url": "https://api.github.com/repos/symfony/console/zipball/ea59bb0edfaf9f28d18d8791410ee0355f317669",
7429
+ "reference": "ea59bb0edfaf9f28d18d8791410ee0355f317669",
7430
  "shasum": ""
7431
  },
7432
  "require": {
7496
  "terminal"
7497
  ],
7498
  "support": {
7499
+ "source": "https://github.com/symfony/console/tree/v5.4.15"
7500
  },
7501
  "funding": [
7502
  {
7512
  "type": "tidelift"
7513
  }
7514
  ],
7515
+ "time": "2022-10-26T21:41:52+00:00"
7516
  },
7517
  {
7518
  "name": "symfony/css-selector",
7582
  },
7583
  {
7584
  "name": "symfony/dependency-injection",
7585
+ "version": "v5.2.12",
7586
  "source": {
7587
  "type": "git",
7588
  "url": "https://github.com/symfony/dependency-injection.git",
7589
+ "reference": "2f0326ab0e142a3600b1b435cb3e852bc96264b6"
7590
  },
7591
  "dist": {
7592
  "type": "zip",
7593
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2f0326ab0e142a3600b1b435cb3e852bc96264b6",
7594
+ "reference": "2f0326ab0e142a3600b1b435cb3e852bc96264b6",
7595
  "shasum": ""
7596
  },
7597
  "require": {
7598
  "php": ">=7.2.5",
7599
+ "psr/container": "^1.0",
7600
+ "symfony/deprecation-contracts": "^2.1",
7601
  "symfony/polyfill-php80": "^1.16",
 
7602
  "symfony/service-contracts": "^1.1.6|^2"
7603
  },
7604
  "conflict": {
7605
+ "symfony/config": "<5.1",
 
7606
  "symfony/finder": "<4.4",
7607
  "symfony/proxy-manager-bridge": "<4.4",
7608
+ "symfony/yaml": "<4.4"
7609
  },
7610
  "provide": {
7611
  "psr/container-implementation": "1.0",
7612
  "symfony/service-implementation": "1.0|2.0"
7613
  },
7614
  "require-dev": {
7615
+ "symfony/config": "^5.1",
7616
+ "symfony/expression-language": "^4.4|^5.0",
7617
+ "symfony/yaml": "^4.4|^5.0"
7618
  },
7619
  "suggest": {
7620
  "symfony/config": "",
7649
  "description": "Allows you to standardize and centralize the way objects are constructed in your application",
7650
  "homepage": "https://symfony.com",
7651
  "support": {
7652
+ "source": "https://github.com/symfony/dependency-injection/tree/v5.2.12"
7653
  },
7654
  "funding": [
7655
  {
7665
  "type": "tidelift"
7666
  }
7667
  ],
7668
+ "time": "2021-07-23T15:54:19+00:00"
7669
  },
7670
  {
7671
  "name": "symfony/deprecation-contracts",
7736
  },
7737
  {
7738
  "name": "symfony/dom-crawler",
7739
+ "version": "v5.4.15",
7740
  "source": {
7741
  "type": "git",
7742
  "url": "https://github.com/symfony/dom-crawler.git",
7743
+ "reference": "b8fd0ff9a0f00d944f1534f6d21e84f92eda7258"
7744
  },
7745
  "dist": {
7746
  "type": "zip",
7747
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b8fd0ff9a0f00d944f1534f6d21e84f92eda7258",
7748
+ "reference": "b8fd0ff9a0f00d944f1534f6d21e84f92eda7258",
7749
  "shasum": ""
7750
  },
7751
  "require": {
7791
  "description": "Eases DOM navigation for HTML and XML documents",
7792
  "homepage": "https://symfony.com",
7793
  "support": {
7794
+ "source": "https://github.com/symfony/dom-crawler/tree/v5.4.15"
7795
  },
7796
  "funding": [
7797
  {
7807
  "type": "tidelift"
7808
  }
7809
  ],
7810
+ "time": "2022-10-27T08:04:35+00:00"
7811
  },
7812
  {
7813
  "name": "symfony/event-dispatcher",
8804
  },
8805
  {
8806
  "name": "symfony/service-contracts",
8807
+ "version": "v2.2.0",
8808
  "source": {
8809
  "type": "git",
8810
  "url": "https://github.com/symfony/service-contracts.git",
8811
+ "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1"
8812
  },
8813
  "dist": {
8814
  "type": "zip",
8815
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1",
8816
+ "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1",
8817
  "shasum": ""
8818
  },
8819
  "require": {
8820
  "php": ">=7.2.5",
8821
+ "psr/container": "^1.0"
 
 
 
 
8822
  },
8823
  "suggest": {
8824
  "symfony/service-implementation": ""
8826
  "type": "library",
8827
  "extra": {
8828
  "branch-alias": {
8829
+ "dev-master": "2.2-dev"
8830
  },
8831
  "thanks": {
8832
  "name": "symfony/contracts",
8863
  "standards"
8864
  ],
8865
  "support": {
8866
+ "source": "https://github.com/symfony/service-contracts/tree/master"
8867
  },
8868
  "funding": [
8869
  {
8879
  "type": "tidelift"
8880
  }
8881
  ],
8882
+ "time": "2020-09-07T11:33:47+00:00"
8883
  },
8884
  {
8885
  "name": "symfony/stopwatch",
8945
  },
8946
  {
8947
  "name": "symfony/string",
8948
+ "version": "v5.4.15",
8949
  "source": {
8950
  "type": "git",
8951
  "url": "https://github.com/symfony/string.git",
8952
+ "reference": "571334ce9f687e3e6af72db4d3b2a9431e4fd9ed"
8953
  },
8954
  "dist": {
8955
  "type": "zip",
8956
+ "url": "https://api.github.com/repos/symfony/string/zipball/571334ce9f687e3e6af72db4d3b2a9431e4fd9ed",
8957
+ "reference": "571334ce9f687e3e6af72db4d3b2a9431e4fd9ed",
8958
  "shasum": ""
8959
  },
8960
  "require": {
9011
  "utf8"
9012
  ],
9013
  "support": {
9014
+ "source": "https://github.com/symfony/string/tree/v5.4.15"
9015
  },
9016
  "funding": [
9017
  {
9468
  },
9469
  {
9470
  "name": "vimeo/psalm",
9471
+ "version": "4.30.0",
9472
  "source": {
9473
  "type": "git",
9474
  "url": "https://github.com/vimeo/psalm.git",
9475
+ "reference": "d0bc6e25d89f649e4f36a534f330f8bb4643dd69"
9476
  },
9477
  "dist": {
9478
  "type": "zip",
9479
+ "url": "https://api.github.com/repos/vimeo/psalm/zipball/d0bc6e25d89f649e4f36a534f330f8bb4643dd69",
9480
+ "reference": "d0bc6e25d89f649e4f36a534f330f8bb4643dd69",
9481
  "shasum": ""
9482
  },
9483
  "require": {
9570
  ],
9571
  "support": {
9572
  "issues": "https://github.com/vimeo/psalm/issues",
9573
+ "source": "https://github.com/vimeo/psalm/tree/4.30.0"
9574
  },
9575
+ "time": "2022-11-06T20:37:08+00:00"
9576
  },
9577
  {
9578
  "name": "voku/portable-ascii",
9931
  },
9932
  {
9933
  "name": "wp-cli/php-cli-tools",
9934
+ "version": "v0.11.16",
9935
  "source": {
9936
  "type": "git",
9937
  "url": "https://github.com/wp-cli/php-cli-tools.git",
9938
+ "reference": "c32e51a5c9993ad40591bc426b21f5422a5ed293"
9939
  },
9940
  "dist": {
9941
  "type": "zip",
9942
+ "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/c32e51a5c9993ad40591bc426b21f5422a5ed293",
9943
+ "reference": "c32e51a5c9993ad40591bc426b21f5422a5ed293",
9944
  "shasum": ""
9945
  },
9946
  "require": {
9979
  ],
9980
  "support": {
9981
  "issues": "https://github.com/wp-cli/php-cli-tools/issues",
9982
+ "source": "https://github.com/wp-cli/php-cli-tools/tree/v0.11.16"
9983
  },
9984
+ "time": "2022-11-03T15:19:26+00:00"
9985
  },
9986
  {
9987
  "name": "wp-cli/wp-cli",
9988
+ "version": "v2.7.1",
9989
  "source": {
9990
  "type": "git",
9991
  "url": "https://github.com/wp-cli/wp-cli.git",
9992
+ "reference": "1ddc754f1c15e56fb2cdd1a4e82bd0ec6ca32a76"
9993
  },
9994
  "dist": {
9995
  "type": "zip",
9996
+ "url": "https://api.github.com/repos/wp-cli/wp-cli/zipball/1ddc754f1c15e56fb2cdd1a4e82bd0ec6ca32a76",
9997
+ "reference": "1ddc754f1c15e56fb2cdd1a4e82bd0ec6ca32a76",
9998
  "shasum": ""
9999
  },
10000
  "require": {
10025
  "type": "library",
10026
  "extra": {
10027
  "branch-alias": {
10028
+ "dev-master": "2.8.x-dev"
10029
  }
10030
  },
10031
  "autoload": {
10052
  "issues": "https://github.com/wp-cli/wp-cli/issues",
10053
  "source": "https://github.com/wp-cli/wp-cli"
10054
  },
10055
+ "time": "2022-10-17T23:10:42+00:00"
10056
  },
10057
  {
10058
  "name": "wp-coding-standards/wpcs",
10171
  "prefer-stable": false,
10172
  "prefer-lowest": false,
10173
  "platform": {
10174
+ "php": ">=5.6.20",
10175
+ "ext-json": "*"
10176
+ },
10177
+ "platform-dev": {
10178
+ "ext-pdo": "*",
10179
+ "ext-yaml": "*"
10180
  },
 
10181
  "plugin-api-version": "2.3.0"
10182
  }
functions.php DELETED
@@ -1,6 +0,0 @@
1
- <?php
2
- /**
3
- * This file provides access to all publicly exposed functions.
4
- */
5
-
6
- require_once POSTEXPIRATOR_BASEDIR . '/legacy-functions.php';
 
 
 
 
 
 
languages/post-expirator-es_ES.mo ADDED
Binary file
languages/post-expirator-es_ES.po ADDED
@@ -0,0 +1,634 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Translation of Plugins - PublishPress Future: Automatically Unpublish WordPress Posts - Stable (latest release) in Spanish (Spain)
2
+ # This file is distributed under the same license as the Plugins - PublishPress Future: Automatically Unpublish WordPress Posts - Stable (latest release) package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Plugins - PublishPress Future: Automatically Unpublish WordPress Posts - Stable (latest release)\n"
6
+ "POT-Creation-Date: \n"
7
+ "PO-Revision-Date: 2022-10-18 20:08+0200\n"
8
+ "Last-Translator: \n"
9
+ "Language-Team: \n"
10
+ "Language: es\n"
11
+ "MIME-Version: 1.0\n"
12
+ "Content-Type: text/plain; charset=UTF-8\n"
13
+ "Content-Transfer-Encoding: 8bit\n"
14
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
15
+ "X-Generator: Poedit 3.0.1\n"
16
+
17
+ #: classes/Facade.class.php:382 views/bulk-edit.php:128
18
+ #: views/classic-metabox.php:135 views/quick-edit.php:92
19
+ msgid "Expiration Taxonomies"
20
+ msgstr "Taxonomías de caducidad"
21
+
22
+ #: classes/Facade.class.php:377 views/how-to-expire.php:54
23
+ msgid "Taxonomy: Remove"
24
+ msgstr "Taxonomía: Quitar"
25
+
26
+ #: classes/Facade.class.php:376 views/how-to-expire.php:50
27
+ msgid "Taxonomy: Add"
28
+ msgstr "Taxonomía: Añadir"
29
+
30
+ #: classes/Facade.class.php:375 views/how-to-expire.php:46
31
+ msgid "Taxonomy: Replace"
32
+ msgstr "Taxonomía: Reemplazar"
33
+
34
+ #: classes/Facade.class.php:368
35
+ msgid "Taxonomy"
36
+ msgstr "Taxonomía"
37
+
38
+ #: views/menu-diagnostics.php:100
39
+ msgid "Posts and expiration settings"
40
+ msgstr "Ajustes de entradas y caducidad"
41
+
42
+ #: views/expire-column.php:21
43
+ msgid "Cron event not found!"
44
+ msgstr "¡Evento cron no encontrado!"
45
+
46
+ #: views/expire-column.php:18
47
+ msgid "Cron event scheduled."
48
+ msgstr "Evento cron programado."
49
+
50
+ #: classes/Display.class.php:80
51
+ msgid "You do not have permission to configure PublishPress Future."
52
+ msgstr "No tienes permisos para configurar PublishPress Future."
53
+
54
+ #: views/tabs.php:37
55
+ msgid "Advanced"
56
+ msgstr "Avanzado"
57
+
58
+ #: views/tabs.php:22
59
+ msgid "Display"
60
+ msgstr "Visualización"
61
+
62
+ #: views/menu-editor.php:10
63
+ msgid "Editor"
64
+ msgstr "Editor"
65
+
66
+ #: views/menu-defaults.php:126
67
+ msgid "Select whether the PublishPress Future is enabled for all new posts."
68
+ msgstr "Selecciona si PublishPress Future está activado para todas las nuevas entradas."
69
+
70
+ #: views/menu-advanced.php:51
71
+ msgid "Choose which user roles can use PublishPress Future"
72
+ msgstr "Elige qué perfiles pueden usar PublishPress Fruture"
73
+
74
+ #: classes/Display.class.php:435
75
+ msgid "Contact"
76
+ msgstr "Contacto"
77
+
78
+ #: classes/Display.class.php:433
79
+ msgid "Contact the PublishPress team"
80
+ msgstr "Contacta con el equipo de PublishPress"
81
+
82
+ #: classes/Display.class.php:427
83
+ msgid "Documentation"
84
+ msgstr "Documentación"
85
+
86
+ #: classes/Display.class.php:425
87
+ msgid "Future Documentation"
88
+ msgstr "Documentación de Future"
89
+
90
+ #: classes/Display.class.php:419
91
+ msgid "About"
92
+ msgstr "Acerca de"
93
+
94
+ #: classes/Display.class.php:417
95
+ msgid "About PublishPress Future"
96
+ msgstr "Acerca de PublishPress Future"
97
+
98
+ #: classes/Display.class.php:402
99
+ msgid "If you like %s, please leave us a %s rating. Thank you!"
100
+ msgstr "Si te gusta %s, por favor déjanos una valoración de %s. ¡Gracias!"
101
+
102
+ #: classes/Display.class.php:54
103
+ msgid "Future"
104
+ msgstr "Future"
105
+
106
+ #: classes/Display.class.php:53
107
+ msgid "PublishPress Future Options"
108
+ msgstr "Opciones de PublishPress Future"
109
+
110
+ #. Plugin Name of the plugin
111
+ #: classes/Facade.class.php:378 post-expirator.php:377 views/bulk-edit.php:18
112
+ #: views/tabs.php:10
113
+ msgid "PublishPress Future"
114
+ msgstr "PublishPress Future"
115
+
116
+ #: views/menu-advanced.php:104
117
+ msgid "Toggle between preserving or deleting data after the plugin is deactivated."
118
+ msgstr "Alterna entre preservar o guardar los datos después de desactivar el plugin."
119
+
120
+ #: views/menu-advanced.php:100
121
+ msgid "Delete data"
122
+ msgstr "Borrar datos"
123
+
124
+ #: views/menu-advanced.php:91
125
+ msgid "Preserve data"
126
+ msgstr "Preservar datos"
127
+
128
+ #: views/menu-advanced.php:82
129
+ msgid "Preserve data after deactivating the plugin"
130
+ msgstr "Preservar datos después de desactivar el plugin"
131
+
132
+ #: views/menu-diagnostics.php:73
133
+ msgid "No cron events found for the plugin."
134
+ msgstr "No se han encontrado eventos cron para el plugin."
135
+
136
+ #: classes/Facade.class.php:381
137
+ msgid "Loading"
138
+ msgstr "Cargando"
139
+
140
+ #: views/tabs.php:27
141
+ msgid "Post Types"
142
+ msgstr "Tipos de contenido"
143
+
144
+ #: views/menu-advanced.php:42 views/menu-editor.php:27
145
+ msgid "Toggle between native support for the Block Editor or the backward compatible Classic Editor style metabox."
146
+ msgstr "Alternar el estilo de la caja meta entre la compatibilidad nativa para el editor de bloques o la compatibilidad anterior con el editor clásico."
147
+
148
+ #: views/menu-advanced.php:40 views/menu-editor.php:25
149
+ msgid "Show Classic Editor style box"
150
+ msgstr "Mostrar el estilo de caja del editor clásico"
151
+
152
+ #: views/menu-advanced.php:34 views/menu-editor.php:21
153
+ msgid "Show Gutenberg style box"
154
+ msgstr "Mostrar el estilo de caja de Gutenberg"
155
+
156
+ #: views/menu-advanced.php:28 views/menu-editor.php:17
157
+ msgid "Block Editor Support"
158
+ msgstr "Compatibilidad del editor de bloques"
159
+
160
+ #: views/menu-advanced.php:18
161
+ msgid "Please do not update anything here unless you know what it entails. For advanced users only."
162
+ msgstr "Por favor, no actualices aquí nada, salvo que sepas lo que implica. Solo para usuarios avanzados."
163
+
164
+ #: views/menu-advanced.php:16
165
+ msgid "Advanced Options"
166
+ msgstr "Opciones avanzadas"
167
+
168
+ #: views/menu-general.php:82
169
+ msgid "The default format to use when displaying the expiration time within a post using the shortcode or within the footer. For information on valid formatting options, see: %s."
170
+ msgstr "El formato por defecto a usar cuando se muestre la hora de caducidad dentro de una entrada usando el shortcode o dentro del pie de página. Para información sobre las opciones de formato válidas, consulta: %s."
171
+
172
+ #: views/menu-general.php:65
173
+ msgid "The default format to use when displaying the expiration date within a post using the shortcode or within the footer. For information on valid formatting options, see: %s."
174
+ msgstr "El formato por defecto a usar cuando se muestre la fecha de caducidad dentro de una entrada usando el shortcode o dentro del pie de página. Para información sobre las opciones de formato válidas, consulta: %s."
175
+
176
+ #: views/menu-display.php:37
177
+ msgid "%1$s - valid options are %2$sfull%3$s (default), %4$sdate%5$s, %6$stime%7$s"
178
+ msgstr "%1$s - Las opciones válidas son %2$sfull%3$s (por defecto), %4$sdate%5$s y %6$stime%7$s"
179
+
180
+ #: views/menu-display.php:33
181
+ msgid "Valid %s attributes:"
182
+ msgstr "Atributos válidos de %s:"
183
+
184
+ #: views/menu-display.php:31
185
+ msgid "Shortcode"
186
+ msgstr "Shortcode"
187
+
188
+ #: views/menu-diagnostics.php:13
189
+ msgid "Debug Logging"
190
+ msgstr "Registro de depuración"
191
+
192
+ #: views/menu-defaults.php:199
193
+ msgid "Set the default expiration date to be used when creating a new post of this type."
194
+ msgstr "Establece la fecha de caducidad por defecto a usar al crear una nueva entrada de este tipo."
195
+
196
+ #: views/menu-defaults.php:169
197
+ msgid "Publish Time"
198
+ msgstr "Hora de publicación"
199
+
200
+ #: views/menu-defaults.php:167
201
+ msgid "Inherit from General Settings"
202
+ msgstr "Heredar desde los ajustes generales"
203
+
204
+ #: views/bulk-edit.php:108 views/quick-edit.php:74
205
+ msgid "Type"
206
+ msgstr "Tipo"
207
+
208
+ #: post-expirator.php:2115
209
+ msgid "No taxonomies found"
210
+ msgstr "No se han encontrado taxonomías"
211
+
212
+ #. Author URI of the plugin
213
+ msgid "http://publishpress.com"
214
+ msgstr "https://publishpress.com"
215
+
216
+ #. Author of the plugin
217
+ msgid "PublishPress"
218
+ msgstr "PublishPress"
219
+
220
+ #: views/menu-defaults.php:216 views/menu-general.php:123
221
+ msgid "Set the custom value to use for the default expiration date. For information on formatting, see %1$s. For example, you could enter %2$s+1 month%3$s or %4$s+1 week 2 days 4 hours 2 seconds%5$s or %6$snext Thursday%7$s."
222
+ msgstr "Establece el valor personalizado que se usará para la fecha de caducidad por defecto. Para información sobre el formato, consulta %1$s. Por ejemplo, puedes introducir %2$s+1 mes%3$s o %4$s+1 semana 2 días 4 horas 2 segundos%5$s o %6$spróximo jueves%7$s."
223
+
224
+ #: views/bulk-edit.php:45
225
+ msgid "Remove from posts"
226
+ msgstr "Eliminar de las entradas"
227
+
228
+ #: views/bulk-edit.php:42
229
+ msgid "Change & Add"
230
+ msgstr "Cambiar y añadir"
231
+
232
+ #: views/bulk-edit.php:39
233
+ msgid "Add to posts"
234
+ msgstr "Añadir a las entradas"
235
+
236
+ #: views/bulk-edit.php:38
237
+ msgid "Add expiry date if not enabled on posts"
238
+ msgstr "Añadir la fecha de caducidad si no está activada en las entradas"
239
+
240
+ #: views/bulk-edit.php:35
241
+ msgid "Change on posts"
242
+ msgstr "Cambiar en las entradas"
243
+
244
+ #: views/bulk-edit.php:34
245
+ msgid "Change expiry date if enabled on posts"
246
+ msgstr "Cambiar la fecha de caducidad si está activado en las entradas"
247
+
248
+ #: views/bulk-edit.php:30
249
+ msgid "No Change"
250
+ msgstr "Sin cambios"
251
+
252
+ #: post-expirator.php:1449
253
+ msgid "[%1$s] %2$s"
254
+ msgstr "[%1$s] %2$s"
255
+
256
+ #: classes/Facade.class.php:374 views/how-to-expire.php:42
257
+ msgid "Unstick"
258
+ msgstr "No fijar"
259
+
260
+ #: classes/Facade.class.php:373 views/how-to-expire.php:38
261
+ msgid "Stick"
262
+ msgstr "Fijar"
263
+
264
+ #: classes/Facade.class.php:371 views/how-to-expire.php:30
265
+ msgid "Trash"
266
+ msgstr "Papelera"
267
+
268
+ #: views/menu-defaults.php:158
269
+ msgid "Enter a comma separate list of emails that you would like to be notified when the post expires."
270
+ msgstr "Introduce una lista de correos electrónicos separada por comas a los que te gustaría avisar cuando caduque la entrada."
271
+
272
+ #: views/menu-general.php:232
273
+ msgid "Enter a comma separate list of emails that you would like to be notified when the post expires. This will be applied to ALL post types. You can set post type specific emails on the Defaults tab."
274
+ msgstr "Introduce una lista de correos electrónicos separada por comas a los que te gustaría avisar cuando caduque la entrada. Esto se aplicará a TODOS los tipos de contenido. Puedes establecer correos electrónicos específicos de tipo de contenido en la pestaña de los valores por defecto."
275
+
276
+ #: views/menu-defaults.php:151 views/menu-general.php:225
277
+ msgid "Who to notify"
278
+ msgstr "A quién avisar"
279
+
280
+ #: views/menu-general.php:216
281
+ msgid "This will include all users with the role of \"Administrator\" in the post expiration email."
282
+ msgstr "Esto incluirá a todos los usuarios con el perfil de «Administrador» en el correo electrónico de caducidad de la entrada."
283
+
284
+ #: views/menu-general.php:198
285
+ msgid "Include Blog Administrators?"
286
+ msgstr "¿Incluir a administradores de blog?"
287
+
288
+ #: views/menu-general.php:190
289
+ msgid "This will enable or disable the send of email notification on post expiration."
290
+ msgstr "Esto activará o desactivará el envío de la notificación por correo electrónico después del vencimiento."
291
+
292
+ #: views/menu-general.php:174
293
+ msgid "Enable Email Notification?"
294
+ msgstr "¿Activar la notificación por correo electrónico?"
295
+
296
+ #: views/menu-general.php:167
297
+ msgid "Whenever a post expires, an email can be sent to alert users of the expiration."
298
+ msgstr "Cuando caduca un post, puede enviarse un correo electrónico alertando a los usuarios del vencimiento."
299
+
300
+ #: views/menu-general.php:165
301
+ msgid "Expiration Email Notification"
302
+ msgstr "Correo electrónico para notificación del vencimiento"
303
+
304
+ #: post-expirator.php:1398
305
+ msgid "Post Expiration Complete \"%s\""
306
+ msgstr "Caducidad de la entrada completada «%s»"
307
+
308
+ #: post-expirator.php:1285 post-expirator.php:1341
309
+ msgid "%1$s (%2$s) has expired at %3$s. The following post \"%4$s\" have now been removed: \"%5$s\". The full list of categories on the post are: \"%6$s\"."
310
+ msgstr "%1$s (%2$s) ha caducado el %3$s. Ahora, la siguiente entrada «%4$s» ha sido eliminada: «%5$s». La lista completa de categorías en la entrada es: «%6$s»."
311
+
312
+ #: post-expirator.php:1164 post-expirator.php:1215
313
+ msgid "%1$s (%2$s) has expired at %3$s. The following post \"%4$s\" have now been added: \"%5$s\". The full list of categories on the post are: \"%6$s\"."
314
+ msgstr "%1$s (%2$s) ha caducado el %3$s. Ahora, la siguiente entrada «%4$s» ha sido añadida: «%5$s». La lista completa de categorías en la entrada es: «%6$s»."
315
+
316
+ #: post-expirator.php:1052 post-expirator.php:1101
317
+ msgid "%1$s (%2$s) has expired at %3$s. Post \"%4$s\" have now been set to \"%5$s\"."
318
+ msgstr "%1$s (%2$s) ha caducado el %3$s. Ahora, la entrada «%4$s» ha sido establecida como «%5$s»."
319
+
320
+ #: post-expirator.php:1022
321
+ msgid "%1$s (%2$s) has expired at %3$s. Post \"%4$s\" status has been successfully removed."
322
+ msgstr "%1$s (%2$s) ha caducado el %3$s. El estado «%4$s» de la entrada ha sido eliminado correctamente."
323
+
324
+ #: post-expirator.php:1001
325
+ msgid "%1$s (%2$s) has expired at %3$s. Post \"%4$s\" status has been successfully set."
326
+ msgstr "%1$s (%2$s) ha caducado el %3$s. El estado «%4$s» de la entrada ha sido establecido correctamente."
327
+
328
+ #: post-expirator.php:901 post-expirator.php:927 post-expirator.php:953
329
+ #: post-expirator.php:977
330
+ msgid "%1$s (%2$s) has expired at %3$s. Post status has been successfully changed to \"%4$s\"."
331
+ msgstr "%1$s (%2$s) ha caducado el %3$s. El estado de la entrada ha sido cambiado correctamente a «%4$s»."
332
+
333
+ #. Description of the plugin
334
+ msgid "Allows you to add an expiration date (minute) to posts which you can configure to either delete the post, change it to a draft, or update the post categories at expiration time."
335
+ msgstr "Te permite añadir una fecha de caducidad (minutos) a las entradas que puedes configurar para eliminar la publicación, cambiarla a borrador o actualizar las categorías de la entrada en el momento de la caducidad."
336
+
337
+ #. Plugin URI of the plugin
338
+ msgid "http://wordpress.org/extend/plugins/post-expirator/"
339
+ msgstr "https://es.wordpress.org/plugins/post-expirator/"
340
+
341
+ #: classes/Facade.class.php:372 views/how-to-expire.php:34
342
+ msgid "Private"
343
+ msgstr "Privado"
344
+
345
+ #: classes/Facade.class.php:370 views/how-to-expire.php:26
346
+ msgid "Delete"
347
+ msgstr "Borrar"
348
+
349
+ #: classes/Facade.class.php:369 views/how-to-expire.php:22
350
+ msgid "Draft"
351
+ msgstr "Borrador"
352
+
353
+ #: classes/Display.class.php:197
354
+ msgid "Below is a dump of the debugging table, this should be useful for troubleshooting."
355
+ msgstr "A continuación tienes un volcado de la tabla de depuración, esto debería ser útil para solucionar problemas."
356
+
357
+ #: views/menu-diagnostics.php:97
358
+ msgid "Event"
359
+ msgstr "Evento"
360
+
361
+ #: views/bulk-edit.php:23 views/menu-diagnostics.php:94 views/quick-edit.php:18
362
+ msgid "Date"
363
+ msgstr "Fecha"
364
+
365
+ #: views/menu-diagnostics.php:82
366
+ msgid "The below table will show all currently scheduled cron events for the plugin with the next run time."
367
+ msgstr "La siguiente tabla mostrará todos los eventos cron actualmente programados para el plugin con la próxima hora de ejecución."
368
+
369
+ #: views/menu-diagnostics.php:65
370
+ msgid "Current Cron Schedule"
371
+ msgstr "Programación actual del cron"
372
+
373
+ #: views/menu-diagnostics.php:52
374
+ msgid "WP-Cron Status"
375
+ msgstr "Estado del cron de WP"
376
+
377
+ #: views/menu-diagnostics.php:44 views/menu-diagnostics.php:47
378
+ msgid "Purge Debug Log"
379
+ msgstr "Purgar el registro de depuración"
380
+
381
+ #: views/menu-diagnostics.php:35
382
+ msgid "Enable Debugging"
383
+ msgstr "Activar depuración"
384
+
385
+ #: views/menu-diagnostics.php:20
386
+ msgid "Disable Debugging"
387
+ msgstr "Desactivar depuración"
388
+
389
+ #: views/menu-diagnostics.php:9
390
+ msgid "Advanced Diagnostics"
391
+ msgstr "Diagnósticos avanzados"
392
+
393
+ #: classes/Display.class.php:181
394
+ msgid "Debugging Table Emptied"
395
+ msgstr "Tabla de depuración vaciada"
396
+
397
+ #: classes/Display.class.php:174
398
+ msgid "Debugging Enabled"
399
+ msgstr "Depuración activada"
400
+
401
+ #: classes/Display.class.php:169
402
+ msgid "Debugging Disabled"
403
+ msgstr "Depuración desactivada"
404
+
405
+ #: post-expirator.php:2127
406
+ msgid "Select the hierarchical taxonomy to be used for \"category\" based expiration."
407
+ msgstr "Seleccionar la taxonomía jerárquica que se utilizará para el vencimiento basado en la «categoría»."
408
+
409
+ #: views/menu-defaults.php:135
410
+ msgid "Taxonomy (hierarchical)"
411
+ msgstr "Taxonomía (jerárquico)"
412
+
413
+ #: views/menu-defaults.php:108
414
+ msgid "Auto-Enable?"
415
+ msgstr "¿Activar automaticamente?"
416
+
417
+ #: views/menu-defaults.php:102
418
+ msgid "Select the default expire action for the post type."
419
+ msgstr "Elige la acción de caducidad por defecto para el tipo de contenido."
420
+
421
+ #: views/menu-defaults.php:83
422
+ msgid "Select whether the PublishPress Future meta box is active for this post type."
423
+ msgstr "Selecciona si la caja meta de PublishPress Future está activa para este tipo de contenido."
424
+
425
+ #: views/menu-defaults.php:81
426
+ msgid "Inactive"
427
+ msgstr "Inactiva"
428
+
429
+ #: views/menu-defaults.php:65 views/menu-defaults.php:73
430
+ msgid "Active"
431
+ msgstr "Activa"
432
+
433
+ #: views/menu-defaults.php:13
434
+ msgid "Use the values below to set the default actions/values to be used for each for the corresponding post types. These values can all be overwritten when creating/editing the post/page."
435
+ msgstr "Utiliza los siguientes valores para establecer las acciones/valores por defecto que se utilizarán para cada uno de los tipos de contenido correspondientes. Estos valores se pueden sobrescribir al crear/editar la publicación/página."
436
+
437
+ #: views/menu-defaults.php:10
438
+ msgid "Default Expiration Values"
439
+ msgstr "Valores de caducidad por defecto"
440
+
441
+ #: views/menu-advanced.php:116 views/menu-defaults.php:239
442
+ #: views/menu-display.php:132 views/menu-editor.php:37
443
+ #: views/menu-general.php:243
444
+ msgid "Save Changes"
445
+ msgstr "Guardar los cambios"
446
+
447
+ #: views/menu-display.php:125
448
+ msgid "The inline css which will be used to style the footer text."
449
+ msgstr "El css incrustado que se utilizará para dar estilo al texto del pie de página."
450
+
451
+ #: views/menu-display.php:122
452
+ msgid "This post will expire on"
453
+ msgstr "Esta entrada caducará el"
454
+
455
+ #: views/menu-display.php:116
456
+ msgid "Footer Style"
457
+ msgstr "Estilo del pie de página"
458
+
459
+ #: views/menu-display.php:98
460
+ msgid "Enter the text you would like to appear at the bottom of every post that will expire. The following placeholders will be replaced with the post expiration date in the following format:"
461
+ msgstr "Introduce el texto que deseas que aparezca en la parte inferior de cada entrada con caducidad. Los siguientes marcadores de posición se reemplazarán por la fecha de vencimiento de la entrada en el siguiente formato:"
462
+
463
+ #: views/menu-display.php:93
464
+ msgid "Footer Contents"
465
+ msgstr "Contenidos del pie de página"
466
+
467
+ #: views/menu-display.php:85
468
+ msgid "This will enable or disable displaying the post expiration date in the post footer."
469
+ msgstr "Esto activa o desactiva la visualización de la fecha de caducidad en pie de página."
470
+
471
+ #: views/menu-defaults.php:124 views/menu-diagnostics.php:32
472
+ #: views/menu-diagnostics.php:59 views/menu-display.php:83
473
+ #: views/menu-general.php:188 views/menu-general.php:214
474
+ msgid "Disabled"
475
+ msgstr "Desactivado"
476
+
477
+ #: views/menu-defaults.php:116 views/menu-diagnostics.php:17
478
+ #: views/menu-diagnostics.php:56 views/menu-display.php:78
479
+ #: views/menu-general.php:181 views/menu-general.php:206
480
+ msgid "Enabled"
481
+ msgstr "Activado"
482
+
483
+ #: views/menu-display.php:73
484
+ msgid "Show in post footer?"
485
+ msgstr "¿Mostrar en el pie de página de la entrada?"
486
+
487
+ #: views/menu-display.php:66
488
+ msgid "Enabling this below will display the expiration date automatically at the end of any post which is set to expire."
489
+ msgstr "Se mostrará la fecha de caducidad de forma automática al final de cualquier entrada que esté a punto de caducar."
490
+
491
+ #: views/menu-display.php:64
492
+ msgid "Post Footer Display"
493
+ msgstr "Mostrar pie de pagina de la entrada"
494
+
495
+ #: views/menu-general.php:159
496
+ msgid "Sets the default expiration category for the post."
497
+ msgstr "Establece la categoría de caducidad por defecto para la entrada."
498
+
499
+ #: views/menu-general.php:140
500
+ msgid "Default Expiration Taxonomy"
501
+ msgstr "Categoría por defecto para vencimiento"
502
+
503
+ #: views/menu-general.php:107
504
+ msgid "Set the default expiration date to be used when creating new posts and pages. Defaults to none."
505
+ msgstr "Ajusta la fecha de caducidad por defecto que se utilizará al crear nuevas entradas y páginas. El valor por defecto es ninguno."
506
+
507
+ #: views/menu-general.php:104
508
+ msgid "Post/Page Publish Time"
509
+ msgstr "Hora de publicación de la entrada/página"
510
+
511
+ #: views/menu-defaults.php:168 views/menu-defaults.php:209
512
+ #: views/menu-general.php:101 views/menu-general.php:117
513
+ msgid "Custom"
514
+ msgstr "Personalizada"
515
+
516
+ #: views/menu-defaults.php:166 views/menu-general.php:98
517
+ msgid "None"
518
+ msgstr "Ninguno"
519
+
520
+ #: views/menu-defaults.php:184 views/menu-general.php:92
521
+ msgid "Default Date/Time Duration"
522
+ msgstr "Duración por defecto de fecha/hora"
523
+
524
+ #: views/menu-general.php:75
525
+ msgid "Time Format"
526
+ msgstr "Formato de hora"
527
+
528
+ #: views/menu-general.php:58
529
+ msgid "Date Format"
530
+ msgstr "Formato de fecha"
531
+
532
+ #: views/menu-display.php:51 views/menu-display.php:56
533
+ msgid "%s - format set here will override the value set on the settings page"
534
+ msgstr "%s - el formato establecido aquí anulará el valor establecido en la página de ajustes"
535
+
536
+ #: classes/Display.class.php:253 classes/Display.class.php:315
537
+ #: classes/Display.class.php:365
538
+ msgid "Saved Options!"
539
+ msgstr "¡Opciones guardadas!"
540
+
541
+ #: views/menu-diagnostics.php:29 views/tabs.php:44
542
+ msgid "View Debug Logs"
543
+ msgstr "Ver registro de depuración"
544
+
545
+ #: views/tabs.php:32
546
+ msgid "Diagnostics"
547
+ msgstr "Diagnósticos"
548
+
549
+ #: views/menu-general.php:54 views/tabs.php:17
550
+ msgid "Defaults"
551
+ msgstr "Valores por defecto"
552
+
553
+ #: views/classic-metabox.php:167
554
+ msgid "Taxonomy Name"
555
+ msgstr "Nombre de taxonomía"
556
+
557
+ #: views/classic-metabox.php:149
558
+ msgid "More than 1 heirachical taxonomy detected. You must assign a default taxonomy on the settings screen."
559
+ msgstr "Detectadas más de 1 taxonomía jerarquizada. Debes asignar una taxonomía por defecto en la pantalla de Ajustes."
560
+
561
+ #: views/classic-metabox.php:144
562
+ msgid "You must assign a hierarchical taxonomy to this post type to use this feature."
563
+ msgstr "Para utilizar esta función debes asignar una taxonomía jerarquizada a este tipo de contenido."
564
+
565
+ #: classes/Facade.class.php:380 views/bulk-edit.php:110
566
+ #: views/classic-metabox.php:117 views/menu-defaults.php:92
567
+ #: views/quick-edit.php:76
568
+ msgid "How to expire"
569
+ msgstr "Caduca como"
570
+
571
+ #: views/bulk-edit.php:96 views/classic-metabox.php:110 views/quick-edit.php:63
572
+ msgid "Minute"
573
+ msgstr "Minuto"
574
+
575
+ #: views/bulk-edit.php:89 views/classic-metabox.php:85 views/quick-edit.php:57
576
+ msgid "Hour"
577
+ msgstr "Hora"
578
+
579
+ #: views/bulk-edit.php:75 views/classic-metabox.php:78 views/quick-edit.php:43
580
+ msgid "Day"
581
+ msgstr "Día"
582
+
583
+ #: views/bulk-edit.php:51 views/classic-metabox.php:56 views/quick-edit.php:21
584
+ msgid "Month"
585
+ msgstr "Mes"
586
+
587
+ #: views/bulk-edit.php:82 views/classic-metabox.php:27 views/quick-edit.php:50
588
+ msgid "Year"
589
+ msgstr "Año"
590
+
591
+ #: views/classic-metabox.php:18
592
+ msgid "The published date/time will be used as the expiration value"
593
+ msgstr "La fecha/hora de publicación se usará como valor de caducidad"
594
+
595
+ #: classes/Facade.class.php:379 views/bulk-edit.php:26
596
+ #: views/classic-metabox.php:11 views/quick-edit.php:12
597
+ msgid "Enable Post Expiration"
598
+ msgstr "Activar caducidad de la entrada"
599
+
600
+ #: views/expire-column.php:24
601
+ msgid "Never"
602
+ msgstr "Nunca"
603
+
604
+ #: post-expirator.php:113 post-expirator.php:199
605
+ msgid "Expires"
606
+ msgstr "Caduca"
607
+
608
+ #: post-expirator.php:65
609
+ msgid "Settings"
610
+ msgstr "Ajustes"
611
+
612
+ #: post-expirator.php:32
613
+ msgid "Post expires at EXPIRATIONTIME on EXPIRATIONDATE"
614
+ msgstr "La entrada caduca en EXPIRATIONTIME el EXPIRATIONDATE"
615
+
616
+ #: post-expirator.php:31
617
+ msgid "g:ia"
618
+ msgstr "g:ia"
619
+
620
+ #: post-expirator.php:30
621
+ msgid "l F jS, Y"
622
+ msgstr "l, j F Y"
623
+
624
+ #: post-expirator-debug.php:87
625
+ msgid "Message"
626
+ msgstr "Mensaje"
627
+
628
+ #: post-expirator-debug.php:86
629
+ msgid "Timestamp"
630
+ msgstr "Marca temporal"
631
+
632
+ #: post-expirator-debug.php:81
633
+ msgid "Debugging table is currently empty."
634
+ msgstr "La tabla de depuración está vacía."
languages/post-expirator-fr_FR.mo ADDED
Binary file
languages/post-expirator-fr_FR.po ADDED
@@ -0,0 +1,634 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Translation of Plugins - PublishPress Future: Automatically Unpublish WordPress Posts - Stable (latest release) in French (France)
2
+ # This file is distributed under the same license as the Plugins - PublishPress Future: Automatically Unpublish WordPress Posts - Stable (latest release) package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Plugins - PublishPress Future: Automatically Unpublish WordPress Posts - Stable (latest release)\n"
6
+ "POT-Creation-Date: \n"
7
+ "PO-Revision-Date: 2022-10-18 20:35+0200\n"
8
+ "Last-Translator: \n"
9
+ "Language-Team: \n"
10
+ "Language: fr\n"
11
+ "MIME-Version: 1.0\n"
12
+ "Content-Type: text/plain; charset=UTF-8\n"
13
+ "Content-Transfer-Encoding: 8bit\n"
14
+ "Plural-Forms: nplurals=2; plural=n > 1;\n"
15
+ "X-Generator: Poedit 3.0.1\n"
16
+
17
+ #: classes/Facade.class.php:382 views/bulk-edit.php:128
18
+ #: views/classic-metabox.php:135 views/quick-edit.php:92
19
+ msgid "Expiration Taxonomies"
20
+ msgstr "Taxonomies d’expiration"
21
+
22
+ #: classes/Facade.class.php:377 views/how-to-expire.php:54
23
+ msgid "Taxonomy: Remove"
24
+ msgstr "Taxonomie : Retirer"
25
+
26
+ #: classes/Facade.class.php:376 views/how-to-expire.php:50
27
+ msgid "Taxonomy: Add"
28
+ msgstr "Taxonomie : Ajouter"
29
+
30
+ #: classes/Facade.class.php:375 views/how-to-expire.php:46
31
+ msgid "Taxonomy: Replace"
32
+ msgstr "Taxonomie : Remplacer"
33
+
34
+ #: classes/Facade.class.php:368
35
+ msgid "Taxonomy"
36
+ msgstr "Taxonomie"
37
+
38
+ #: views/menu-diagnostics.php:100
39
+ msgid "Posts and expiration settings"
40
+ msgstr "Réglages des publications et de l’expiration"
41
+
42
+ #: views/expire-column.php:21
43
+ msgid "Cron event not found!"
44
+ msgstr "L’évènement cron n’a pas été trouvé !"
45
+
46
+ #: views/expire-column.php:18
47
+ msgid "Cron event scheduled."
48
+ msgstr "L’évènement cron a été planifié."
49
+
50
+ #: classes/Display.class.php:80
51
+ msgid "You do not have permission to configure PublishPress Future."
52
+ msgstr "Vous n’avez pas les droits nécessaires pour configurer PublishPress Future."
53
+
54
+ #: views/tabs.php:37
55
+ msgid "Advanced"
56
+ msgstr "Avancé"
57
+
58
+ #: views/tabs.php:22
59
+ msgid "Display"
60
+ msgstr "Afficher"
61
+
62
+ #: views/menu-editor.php:10
63
+ msgid "Editor"
64
+ msgstr "Éditeur"
65
+
66
+ #: views/menu-defaults.php:126
67
+ msgid "Select whether the PublishPress Future is enabled for all new posts."
68
+ msgstr "Sélectionnez si la fonctionnalité PublishPress est activée ou non pour toutes les nouvelles publications."
69
+
70
+ #: views/menu-advanced.php:51
71
+ msgid "Choose which user roles can use PublishPress Future"
72
+ msgstr "Choisir les rôles pouvant utiliser PublishPress Future"
73
+
74
+ #: classes/Display.class.php:435
75
+ msgid "Contact"
76
+ msgstr "Contact"
77
+
78
+ #: classes/Display.class.php:433
79
+ msgid "Contact the PublishPress team"
80
+ msgstr "Contacter l’équipe PublishPress"
81
+
82
+ #: classes/Display.class.php:427
83
+ msgid "Documentation"
84
+ msgstr "Documentation"
85
+
86
+ #: classes/Display.class.php:425
87
+ msgid "Future Documentation"
88
+ msgstr "Documentation de Future"
89
+
90
+ #: classes/Display.class.php:419
91
+ msgid "About"
92
+ msgstr "À propos"
93
+
94
+ #: classes/Display.class.php:417
95
+ msgid "About PublishPress Future"
96
+ msgstr "À propos de PublishPress Future"
97
+
98
+ #: classes/Display.class.php:402
99
+ msgid "If you like %s, please leave us a %s rating. Thank you!"
100
+ msgstr "Si vous appréciez %s, veuillez nous laisser une note de %s. Merci !"
101
+
102
+ #: classes/Display.class.php:54
103
+ msgid "Future"
104
+ msgstr "Future"
105
+
106
+ #: classes/Display.class.php:53
107
+ msgid "PublishPress Future Options"
108
+ msgstr "Options de PublishPress Future"
109
+
110
+ #. Plugin Name of the plugin
111
+ #: classes/Facade.class.php:378 post-expirator.php:377 views/bulk-edit.php:18
112
+ #: views/tabs.php:10
113
+ msgid "PublishPress Future"
114
+ msgstr "PublishPress Future"
115
+
116
+ #: views/menu-advanced.php:104
117
+ msgid "Toggle between preserving or deleting data after the plugin is deactivated."
118
+ msgstr "Permutez entre la conservation ou la suppression des données après la désactivation de l’extension."
119
+
120
+ #: views/menu-advanced.php:100
121
+ msgid "Delete data"
122
+ msgstr "Supprimer les données"
123
+
124
+ #: views/menu-advanced.php:91
125
+ msgid "Preserve data"
126
+ msgstr "Conserver les données"
127
+
128
+ #: views/menu-advanced.php:82
129
+ msgid "Preserve data after deactivating the plugin"
130
+ msgstr "Conserver les données après la désactivation de l’extension"
131
+
132
+ #: views/menu-diagnostics.php:73
133
+ msgid "No cron events found for the plugin."
134
+ msgstr "Aucun évènement cron n’a été trouvé pour l’extension."
135
+
136
+ #: classes/Facade.class.php:381
137
+ msgid "Loading"
138
+ msgstr "Chargement"
139
+
140
+ #: views/tabs.php:27
141
+ msgid "Post Types"
142
+ msgstr "Type de publications"
143
+
144
+ #: views/menu-advanced.php:42 views/menu-editor.php:27
145
+ msgid "Toggle between native support for the Block Editor or the backward compatible Classic Editor style metabox."
146
+ msgstr "Permuter entre la prise en charge native de l’éditeur de blocs et la boite méta de l’éditeur classique, qui est rétrocompatible."
147
+
148
+ #: views/menu-advanced.php:40 views/menu-editor.php:25
149
+ msgid "Show Classic Editor style box"
150
+ msgstr "Afficher la boîte de style de l’éditeur classique"
151
+
152
+ #: views/menu-advanced.php:34 views/menu-editor.php:21
153
+ msgid "Show Gutenberg style box"
154
+ msgstr "Afficher la boîte de style Gutenberg"
155
+
156
+ #: views/menu-advanced.php:28 views/menu-editor.php:17
157
+ msgid "Block Editor Support"
158
+ msgstr "Support de l’éditeur de blocs"
159
+
160
+ #: views/menu-advanced.php:18
161
+ msgid "Please do not update anything here unless you know what it entails. For advanced users only."
162
+ msgstr "Veuillez ne rien mettre à jour ici si vous ne savez pas ce que cela implique. Pour les utilisateurs/utilisatrices avancés uniquement."
163
+
164
+ #: views/menu-advanced.php:16
165
+ msgid "Advanced Options"
166
+ msgstr "Options avancées"
167
+
168
+ #: views/menu-general.php:82
169
+ msgid "The default format to use when displaying the expiration time within a post using the shortcode or within the footer. For information on valid formatting options, see: %s."
170
+ msgstr "Le format par défaut à utiliser pour afficher le délai d’expiration dans une publication à l’aide du code court ou dans le pied de page. Pour plus d’informations sur les options de formatage valides, voir : %s."
171
+
172
+ #: views/menu-general.php:65
173
+ msgid "The default format to use when displaying the expiration date within a post using the shortcode or within the footer. For information on valid formatting options, see: %s."
174
+ msgstr "Le format par défaut à utiliser lors de l’affichage de la date d’expiration dans une publication à l’aide du code court ou dans le pied de page. Pour plus d’informations sur les options de formatage valides, voir : %s."
175
+
176
+ #: views/menu-display.php:37
177
+ msgid "%1$s - valid options are %2$sfull%3$s (default), %4$sdate%5$s, %6$stime%7$s"
178
+ msgstr "%1$s - les options valides sont %2$sfull%3$s (par défaut), %4$sdate%5$s, %6$stime%7$s"
179
+
180
+ #: views/menu-display.php:33
181
+ msgid "Valid %s attributes:"
182
+ msgstr "Attributs %s valides :"
183
+
184
+ #: views/menu-display.php:31
185
+ msgid "Shortcode"
186
+ msgstr "Code court"
187
+
188
+ #: views/menu-diagnostics.php:13
189
+ msgid "Debug Logging"
190
+ msgstr "Journalisation de débogage"
191
+
192
+ #: views/menu-defaults.php:199
193
+ msgid "Set the default expiration date to be used when creating a new post of this type."
194
+ msgstr "Définissez la date d’expiration par défaut à utiliser lors de la création d’une nouvelle publication de ce type."
195
+
196
+ #: views/menu-defaults.php:169
197
+ msgid "Publish Time"
198
+ msgstr "Heure de publication"
199
+
200
+ #: views/menu-defaults.php:167
201
+ msgid "Inherit from General Settings"
202
+ msgstr "Hériter des réglages généraux"
203
+
204
+ #: views/bulk-edit.php:108 views/quick-edit.php:74
205
+ msgid "Type"
206
+ msgstr "Type"
207
+
208
+ #: post-expirator.php:2115
209
+ msgid "No taxonomies found"
210
+ msgstr "Aucune taxonomie trouvée"
211
+
212
+ #. Author URI of the plugin
213
+ msgid "http://publishpress.com"
214
+ msgstr "http://publishpress.com"
215
+
216
+ #. Author of the plugin
217
+ msgid "PublishPress"
218
+ msgstr "PublishPress"
219
+
220
+ #: views/menu-defaults.php:216 views/menu-general.php:123
221
+ msgid "Set the custom value to use for the default expiration date. For information on formatting, see %1$s. For example, you could enter %2$s+1 month%3$s or %4$s+1 week 2 days 4 hours 2 seconds%5$s or %6$snext Thursday%7$s."
222
+ msgstr "Définissez la valeur personnalisée à utiliser pour la date d’expiration par défaut. Pour plus d’informations sur le formatage, voir %1$s. Par exemple, vous pouvez saisir %2$s+1 mois%3$s ou %4$s+1 semaine 2 jours 4 heures 2 secondes%5$s ou %6$sjeudi prochain%7$s."
223
+
224
+ #: views/bulk-edit.php:45
225
+ msgid "Remove from posts"
226
+ msgstr "Retirer des publications"
227
+
228
+ #: views/bulk-edit.php:42
229
+ msgid "Change & Add"
230
+ msgstr "Modifier et ajouter"
231
+
232
+ #: views/bulk-edit.php:39
233
+ msgid "Add to posts"
234
+ msgstr "Ajouter aux publications"
235
+
236
+ #: views/bulk-edit.php:38
237
+ msgid "Add expiry date if not enabled on posts"
238
+ msgstr "Ajouter la date d’expiration si elle n’est pas activée sur les publications"
239
+
240
+ #: views/bulk-edit.php:35
241
+ msgid "Change on posts"
242
+ msgstr "Modification des publications"
243
+
244
+ #: views/bulk-edit.php:34
245
+ msgid "Change expiry date if enabled on posts"
246
+ msgstr "Modifier la date d’expiration si elle est activée sur les publications"
247
+
248
+ #: views/bulk-edit.php:30
249
+ msgid "No Change"
250
+ msgstr "Aucune modification"
251
+
252
+ #: post-expirator.php:1449
253
+ msgid "[%1$s] %2$s"
254
+ msgstr "[%1$s] %2$s"
255
+
256
+ #: classes/Facade.class.php:374 views/how-to-expire.php:42
257
+ msgid "Unstick"
258
+ msgstr "Ne plus épingler"
259
+
260
+ #: classes/Facade.class.php:373 views/how-to-expire.php:38
261
+ msgid "Stick"
262
+ msgstr "Épingler"
263
+
264
+ #: classes/Facade.class.php:371 views/how-to-expire.php:30
265
+ msgid "Trash"
266
+ msgstr "Corbeille"
267
+
268
+ #: views/menu-defaults.php:158
269
+ msgid "Enter a comma separate list of emails that you would like to be notified when the post expires."
270
+ msgstr "Saisissez une liste d’e-mails (séparés par des virgules) que vous voulez notifier quand la publication arrive à expiration."
271
+
272
+ #: views/menu-general.php:232
273
+ msgid "Enter a comma separate list of emails that you would like to be notified when the post expires. This will be applied to ALL post types. You can set post type specific emails on the Defaults tab."
274
+ msgstr "Saisissez une liste d’e-mails (séparés par des virgules) que vous voulez notifier quand la publication arrive à expiration. Cela s’appliquera à TOUS les types de contenu. Vous pouvez définir des e-mails spécifiques en fonction du type de contenu dans l’onglet Par défaut."
275
+
276
+ #: views/menu-defaults.php:151 views/menu-general.php:225
277
+ msgid "Who to notify"
278
+ msgstr "Personne à notifier"
279
+
280
+ #: views/menu-general.php:216
281
+ msgid "This will include all users with the role of \"Administrator\" in the post expiration email."
282
+ msgstr "Inclus tous les utilisateurs avec le rôle « Administrateur » dans l’e-mail informant de l’expiration d’un contenu."
283
+
284
+ #: views/menu-general.php:198
285
+ msgid "Include Blog Administrators?"
286
+ msgstr "Inclure les Admins ?"
287
+
288
+ #: views/menu-general.php:190
289
+ msgid "This will enable or disable the send of email notification on post expiration."
290
+ msgstr "Cela activera ou désactivera l’envoi d’une notification par e-mail au moment de l’expiration d’un contenu."
291
+
292
+ #: views/menu-general.php:174
293
+ msgid "Enable Email Notification?"
294
+ msgstr "Activer la notification par e-mail ?"
295
+
296
+ #: views/menu-general.php:167
297
+ msgid "Whenever a post expires, an email can be sent to alert users of the expiration."
298
+ msgstr "Dès qu’un contenu arrive à expiration, un e-mail peut être envoyé pour informer les utilisateurs de l’expiration."
299
+
300
+ #: views/menu-general.php:165
301
+ msgid "Expiration Email Notification"
302
+ msgstr "Notification e-mail de l’expiration"
303
+
304
+ #: post-expirator.php:1398
305
+ msgid "Post Expiration Complete \"%s\""
306
+ msgstr "Expiration du contenu « %s »"
307
+
308
+ #: post-expirator.php:1285 post-expirator.php:1341
309
+ msgid "%1$s (%2$s) has expired at %3$s. The following post \"%4$s\" have now been removed: \"%5$s\". The full list of categories on the post are: \"%6$s\"."
310
+ msgstr "%1$s (%2$s) a expiré à %3$s. Les publications suivantes « %4$s » ont été retirées : « %5$s ». La liste complète des catégories de la publication est : « %6$s »."
311
+
312
+ #: post-expirator.php:1164 post-expirator.php:1215
313
+ msgid "%1$s (%2$s) has expired at %3$s. The following post \"%4$s\" have now been added: \"%5$s\". The full list of categories on the post are: \"%6$s\"."
314
+ msgstr "%1$s (%2$s) a expiré à %3$s. Les publications suivantes ont été ajoutées : « %4$s », « %5$s ». La liste complète des catégories de la publication est : « %6$s »."
315
+
316
+ #: post-expirator.php:1052 post-expirator.php:1101
317
+ msgid "%1$s (%2$s) has expired at %3$s. Post \"%4$s\" have now been set to \"%5$s\"."
318
+ msgstr "%1$s (%2$s) a expiré à %3$s. La publication « %4$s » est désormais réglée sur « %5$s »."
319
+
320
+ #: post-expirator.php:1022
321
+ msgid "%1$s (%2$s) has expired at %3$s. Post \"%4$s\" status has been successfully removed."
322
+ msgstr "%1$s (%2$s) a expiré à %3$s. L’état de la publication « %4$s » a bien été retiré."
323
+
324
+ #: post-expirator.php:1001
325
+ msgid "%1$s (%2$s) has expired at %3$s. Post \"%4$s\" status has been successfully set."
326
+ msgstr "%1$s (%2$s) a expiré à %3$s. L’état de la publication « %4$s » a bien été défini."
327
+
328
+ #: post-expirator.php:901 post-expirator.php:927 post-expirator.php:953
329
+ #: post-expirator.php:977
330
+ msgid "%1$s (%2$s) has expired at %3$s. Post status has been successfully changed to \"%4$s\"."
331
+ msgstr "%1$s (%2$s) a expiré à %3$s. L’état de la publication a bien été modifié en « %4$s »."
332
+
333
+ #. Description of the plugin
334
+ msgid "Allows you to add an expiration date (minute) to posts which you can configure to either delete the post, change it to a draft, or update the post categories at expiration time."
335
+ msgstr "Autorise l’ajout à vos publications d’une date d’expiration (à la minute près) que vous pouvez configurer pour supprimer la publication, la mettre en brouillon ou mettre à jour les catégories au moment de l’expiration."
336
+
337
+ #. Plugin URI of the plugin
338
+ msgid "http://wordpress.org/extend/plugins/post-expirator/"
339
+ msgstr "http://wordpress.org/extend/plugins/post-expirator/"
340
+
341
+ #: classes/Facade.class.php:372 views/how-to-expire.php:34
342
+ msgid "Private"
343
+ msgstr "Privé"
344
+
345
+ #: classes/Facade.class.php:370 views/how-to-expire.php:26
346
+ msgid "Delete"
347
+ msgstr "Supprimer"
348
+
349
+ #: classes/Facade.class.php:369 views/how-to-expire.php:22
350
+ msgid "Draft"
351
+ msgstr "Brouillon"
352
+
353
+ #: classes/Display.class.php:197
354
+ msgid "Below is a dump of the debugging table, this should be useful for troubleshooting."
355
+ msgstr "Ci-dessous une extraction de la table de débogage, cela devrait vous aider."
356
+
357
+ #: views/menu-diagnostics.php:97
358
+ msgid "Event"
359
+ msgstr "Évènement"
360
+
361
+ #: views/bulk-edit.php:23 views/menu-diagnostics.php:94 views/quick-edit.php:18
362
+ msgid "Date"
363
+ msgstr "Date"
364
+
365
+ #: views/menu-diagnostics.php:82
366
+ msgid "The below table will show all currently scheduled cron events for the plugin with the next run time."
367
+ msgstr "Le tableau ci-dessous affiche tous les évènements cron actuellement planifiés pour l’extension avec la prochaine date d’exécution."
368
+
369
+ #: views/menu-diagnostics.php:65
370
+ msgid "Current Cron Schedule"
371
+ msgstr "Planification cron actuelle"
372
+
373
+ #: views/menu-diagnostics.php:52
374
+ msgid "WP-Cron Status"
375
+ msgstr "État de WP-Cron"
376
+
377
+ #: views/menu-diagnostics.php:44 views/menu-diagnostics.php:47
378
+ msgid "Purge Debug Log"
379
+ msgstr "Purge le log de débogage"
380
+
381
+ #: views/menu-diagnostics.php:35
382
+ msgid "Enable Debugging"
383
+ msgstr "Activer le débogage"
384
+
385
+ #: views/menu-diagnostics.php:20
386
+ msgid "Disable Debugging"
387
+ msgstr "Désactiver le débogage"
388
+
389
+ #: views/menu-diagnostics.php:9
390
+ msgid "Advanced Diagnostics"
391
+ msgstr "Diagnostics avancés"
392
+
393
+ #: classes/Display.class.php:181
394
+ msgid "Debugging Table Emptied"
395
+ msgstr "Table de débogage vidée"
396
+
397
+ #: classes/Display.class.php:174
398
+ msgid "Debugging Enabled"
399
+ msgstr "Débogage activé"
400
+
401
+ #: classes/Display.class.php:169
402
+ msgid "Debugging Disabled"
403
+ msgstr "Débogage désactivé"
404
+
405
+ #: post-expirator.php:2127
406
+ msgid "Select the hierarchical taxonomy to be used for \"category\" based expiration."
407
+ msgstr "Sélectionnez la taxonomie hiérarchique à utiliser pour l’expiration basée sur la catégorie."
408
+
409
+ #: views/menu-defaults.php:135
410
+ msgid "Taxonomy (hierarchical)"
411
+ msgstr "Taxonomie (hiérarchique)"
412
+
413
+ #: views/menu-defaults.php:108
414
+ msgid "Auto-Enable?"
415
+ msgstr "Activer automatiquement"
416
+
417
+ #: views/menu-defaults.php:102
418
+ msgid "Select the default expire action for the post type."
419
+ msgstr "Sélectionnez le mode d’expiration par défaut pour ce type de publication."
420
+
421
+ #: views/menu-defaults.php:83
422
+ msgid "Select whether the PublishPress Future meta box is active for this post type."
423
+ msgstr "Sélectionnez si la boîte méta d’expiration de la publication est active pour ce type de publication."
424
+
425
+ #: views/menu-defaults.php:81
426
+ msgid "Inactive"
427
+ msgstr "Inactif"
428
+
429
+ #: views/menu-defaults.php:65 views/menu-defaults.php:73
430
+ msgid "Active"
431
+ msgstr "Actif"
432
+
433
+ #: views/menu-defaults.php:13
434
+ msgid "Use the values below to set the default actions/values to be used for each for the corresponding post types. These values can all be overwritten when creating/editing the post/page."
435
+ msgstr "Utilisez les valeurs ci-dessous pour définir les actions/valeurs par défaut à utiliser pour chaque type de publication correspondant. Ces valeurs peuvent toutes être remplacées lors de la création/modification de la publication/page."
436
+
437
+ #: views/menu-defaults.php:10
438
+ msgid "Default Expiration Values"
439
+ msgstr "Valeurs d’expiration par défaut"
440
+
441
+ #: views/menu-advanced.php:116 views/menu-defaults.php:239
442
+ #: views/menu-display.php:132 views/menu-editor.php:37
443
+ #: views/menu-general.php:243
444
+ msgid "Save Changes"
445
+ msgstr "Enregistrer les modifications"
446
+
447
+ #: views/menu-display.php:125
448
+ msgid "The inline css which will be used to style the footer text."
449
+ msgstr "Les CSS en ligne qui seront utilisées pour styler le texte de pied de page."
450
+
451
+ #: views/menu-display.php:122
452
+ msgid "This post will expire on"
453
+ msgstr "Cette publication expirera le"
454
+
455
+ #: views/menu-display.php:116
456
+ msgid "Footer Style"
457
+ msgstr "Style du pied de page"
458
+
459
+ #: views/menu-display.php:98
460
+ msgid "Enter the text you would like to appear at the bottom of every post that will expire. The following placeholders will be replaced with the post expiration date in the following format:"
461
+ msgstr "Entrez le texte que vous souhaitez afficher au bas de chaque publication qui expirera. Les textes indicatifs ci-après seront remplacées par la date d’expiration dans le format indiqué :"
462
+
463
+ #: views/menu-display.php:93
464
+ msgid "Footer Contents"
465
+ msgstr "Contenus du pied de page"
466
+
467
+ #: views/menu-display.php:85
468
+ msgid "This will enable or disable displaying the post expiration date in the post footer."
469
+ msgstr "Active ou désactive l’affichage de la date d’expiration de la publication dans le pied de page."
470
+
471
+ #: views/menu-defaults.php:124 views/menu-diagnostics.php:32
472
+ #: views/menu-diagnostics.php:59 views/menu-display.php:83
473
+ #: views/menu-general.php:188 views/menu-general.php:214
474
+ msgid "Disabled"
475
+ msgstr "Désactivé"
476
+
477
+ #: views/menu-defaults.php:116 views/menu-diagnostics.php:17
478
+ #: views/menu-diagnostics.php:56 views/menu-display.php:78
479
+ #: views/menu-general.php:181 views/menu-general.php:206
480
+ msgid "Enabled"
481
+ msgstr "Activé"
482
+
483
+ #: views/menu-display.php:73
484
+ msgid "Show in post footer?"
485
+ msgstr "Afficher dans le pied de page de la publication ?"
486
+
487
+ #: views/menu-display.php:66
488
+ msgid "Enabling this below will display the expiration date automatically at the end of any post which is set to expire."
489
+ msgstr "L’activation de cette option affichera la date d’expiration automatiquement à la fin de toute publication qui doit expirer."
490
+
491
+ #: views/menu-display.php:64
492
+ msgid "Post Footer Display"
493
+ msgstr "Affichage dans le pied de page"
494
+
495
+ #: views/menu-general.php:159
496
+ msgid "Sets the default expiration category for the post."
497
+ msgstr "Définit la catégorie d’expiration par défaut pour la publication."
498
+
499
+ #: views/menu-general.php:140
500
+ msgid "Default Expiration Taxonomy"
501
+ msgstr "Taxonomie d’expiration par défaut"
502
+
503
+ #: views/menu-general.php:107
504
+ msgid "Set the default expiration date to be used when creating new posts and pages. Defaults to none."
505
+ msgstr "Définissez la date d’expiration par défaut à utiliser lors de la création de nouveaux articles et de pages. La valeur par défaut est « aucune »."
506
+
507
+ #: views/menu-general.php:104
508
+ msgid "Post/Page Publish Time"
509
+ msgstr "Date de publication"
510
+
511
+ #: views/menu-defaults.php:168 views/menu-defaults.php:209
512
+ #: views/menu-general.php:101 views/menu-general.php:117
513
+ msgid "Custom"
514
+ msgstr "Personnalisé "
515
+
516
+ #: views/menu-defaults.php:166 views/menu-general.php:98
517
+ msgid "None"
518
+ msgstr "Aucune"
519
+
520
+ #: views/menu-defaults.php:184 views/menu-general.php:92
521
+ msgid "Default Date/Time Duration"
522
+ msgstr "Date/heure de durée par défaut"
523
+
524
+ #: views/menu-general.php:75
525
+ msgid "Time Format"
526
+ msgstr "Format d’heure"
527
+
528
+ #: views/menu-general.php:58
529
+ msgid "Date Format"
530
+ msgstr "Format de date"
531
+
532
+ #: views/menu-display.php:51 views/menu-display.php:56
533
+ msgid "%s - format set here will override the value set on the settings page"
534
+ msgstr "%s - le format défini ici remplacera la valeur définie sur la page des réglages."
535
+
536
+ #: classes/Display.class.php:253 classes/Display.class.php:315
537
+ #: classes/Display.class.php:365
538
+ msgid "Saved Options!"
539
+ msgstr "Options enregistrées !"
540
+
541
+ #: views/menu-diagnostics.php:29 views/tabs.php:44
542
+ msgid "View Debug Logs"
543
+ msgstr "Voir les logs de déboguage"
544
+
545
+ #: views/tabs.php:32
546
+ msgid "Diagnostics"
547
+ msgstr "Diagnostics"
548
+
549
+ #: views/menu-general.php:54 views/tabs.php:17
550
+ msgid "Defaults"
551
+ msgstr "Défaut"
552
+
553
+ #: views/classic-metabox.php:167
554
+ msgid "Taxonomy Name"
555
+ msgstr "Nom de la taxonomie"
556
+
557
+ #: views/classic-metabox.php:149
558
+ msgid "More than 1 heirachical taxonomy detected. You must assign a default taxonomy on the settings screen."
559
+ msgstr "Plus de 1 taxonomie de hiérarchie détectée. Vous devez attribuer une taxonomie par défaut sur l’écran des paramètres."
560
+
561
+ #: views/classic-metabox.php:144
562
+ msgid "You must assign a hierarchical taxonomy to this post type to use this feature."
563
+ msgstr "Vous devez attribuer une taxonomie hiérarchique à ce type de publication pour utiliser cette fonctionnalité."
564
+
565
+ #: classes/Facade.class.php:380 views/bulk-edit.php:110
566
+ #: views/classic-metabox.php:117 views/menu-defaults.php:92
567
+ #: views/quick-edit.php:76
568
+ msgid "How to expire"
569
+ msgstr "Mode d’expiration"
570
+
571
+ #: views/bulk-edit.php:96 views/classic-metabox.php:110 views/quick-edit.php:63
572
+ msgid "Minute"
573
+ msgstr "Minute"
574
+
575
+ #: views/bulk-edit.php:89 views/classic-metabox.php:85 views/quick-edit.php:57
576
+ msgid "Hour"
577
+ msgstr "Heure"
578
+
579
+ #: views/bulk-edit.php:75 views/classic-metabox.php:78 views/quick-edit.php:43
580
+ msgid "Day"
581
+ msgstr "Jour"
582
+
583
+ #: views/bulk-edit.php:51 views/classic-metabox.php:56 views/quick-edit.php:21
584
+ msgid "Month"
585
+ msgstr "Mois"
586
+
587
+ #: views/bulk-edit.php:82 views/classic-metabox.php:27 views/quick-edit.php:50
588
+ msgid "Year"
589
+ msgstr "Année"
590
+
591
+ #: views/classic-metabox.php:18
592
+ msgid "The published date/time will be used as the expiration value"
593
+ msgstr "La date/heure publiée sera utilisée comme valeur d’expiration"
594
+
595
+ #: classes/Facade.class.php:379 views/bulk-edit.php:26
596
+ #: views/classic-metabox.php:11 views/quick-edit.php:12
597
+ msgid "Enable Post Expiration"
598
+ msgstr "Autoriser l’expiration de vos contenus"
599
+
600
+ #: views/expire-column.php:24
601
+ msgid "Never"
602
+ msgstr "Jamais"
603
+
604
+ #: post-expirator.php:113 post-expirator.php:199
605
+ msgid "Expires"
606
+ msgstr "Expires"
607
+
608
+ #: post-expirator.php:65
609
+ msgid "Settings"
610
+ msgstr "Réglages"
611
+
612
+ #: post-expirator.php:32
613
+ msgid "Post expires at EXPIRATIONTIME on EXPIRATIONDATE"
614
+ msgstr "La publication expire à EXPIRATIONTIME le EXPIRATIONDATE"
615
+
616
+ #: post-expirator.php:31
617
+ msgid "g:ia"
618
+ msgstr "g\\hia"
619
+
620
+ #: post-expirator.php:30
621
+ msgid "l F jS, Y"
622
+ msgstr "I j F Y"
623
+
624
+ #: post-expirator-debug.php:87
625
+ msgid "Message"
626
+ msgstr "Message"
627
+
628
+ #: post-expirator-debug.php:86
629
+ msgid "Timestamp"
630
+ msgstr "Horodatage"
631
+
632
+ #: post-expirator-debug.php:81
633
+ msgid "Debugging table is currently empty."
634
+ msgstr "La table de débogage est actuellement vide."
languages/post-expirator-it_IT.mo ADDED
Binary file
languages/post-expirator-it_IT.po ADDED
@@ -0,0 +1,634 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Translation of Plugins - PublishPress Future: Automatically Unpublish WordPress Posts - Stable (latest release) in Italian
2
+ # This file is distributed under the same license as the Plugins - PublishPress Future: Automatically Unpublish WordPress Posts - Stable (latest release) package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Plugins - PublishPress Future: Automatically Unpublish WordPress Posts - Stable (latest release)\n"
6
+ "POT-Creation-Date: \n"
7
+ "PO-Revision-Date: 2022-10-18 20:36+0200\n"
8
+ "Last-Translator: \n"
9
+ "Language-Team: \n"
10
+ "Language: it\n"
11
+ "MIME-Version: 1.0\n"
12
+ "Content-Type: text/plain; charset=UTF-8\n"
13
+ "Content-Transfer-Encoding: 8bit\n"
14
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
15
+ "X-Generator: Poedit 3.0.1\n"
16
+
17
+ #: classes/Facade.class.php:382 views/bulk-edit.php:128
18
+ #: views/classic-metabox.php:135 views/quick-edit.php:92
19
+ msgid "Expiration Taxonomies"
20
+ msgstr "Tassonomie della scadenza"
21
+
22
+ #: classes/Facade.class.php:377 views/how-to-expire.php:54
23
+ msgid "Taxonomy: Remove"
24
+ msgstr "Tassonomia: Rimuovere"
25
+
26
+ #: classes/Facade.class.php:376 views/how-to-expire.php:50
27
+ msgid "Taxonomy: Add"
28
+ msgstr "Tassonomia: Aggiungere"
29
+
30
+ #: classes/Facade.class.php:375 views/how-to-expire.php:46
31
+ msgid "Taxonomy: Replace"
32
+ msgstr "Tassonomia: Sostituire"
33
+
34
+ #: classes/Facade.class.php:368
35
+ msgid "Taxonomy"
36
+ msgstr "Tassonomia"
37
+
38
+ #: views/menu-diagnostics.php:100
39
+ msgid "Posts and expiration settings"
40
+ msgstr "Impostazioni degli articoli e della scadenza"
41
+
42
+ #: views/expire-column.php:21
43
+ msgid "Cron event not found!"
44
+ msgstr "Il cron dell'evento non è stato trovato!"
45
+
46
+ #: views/expire-column.php:18
47
+ msgid "Cron event scheduled."
48
+ msgstr "Il cron dell'evento è stato programmato."
49
+
50
+ #: classes/Display.class.php:80
51
+ msgid "You do not have permission to configure PublishPress Future."
52
+ msgstr "Non hai i permessi per configurare PublishPress Future."
53
+
54
+ #: views/tabs.php:37
55
+ msgid "Advanced"
56
+ msgstr "Avanzate"
57
+
58
+ #: views/tabs.php:22
59
+ msgid "Display"
60
+ msgstr "Visualizza"
61
+
62
+ #: views/menu-editor.php:10
63
+ msgid "Editor"
64
+ msgstr "Editor"
65
+
66
+ #: views/menu-defaults.php:126
67
+ msgid "Select whether the PublishPress Future is enabled for all new posts."
68
+ msgstr "Selezionare se PublishPress Future è abilitato per tutti i nuovi articoli."
69
+
70
+ #: views/menu-advanced.php:51
71
+ msgid "Choose which user roles can use PublishPress Future"
72
+ msgstr "Scegli quali ruoli utente possono utilizzare PublishPress Future"
73
+
74
+ #: classes/Display.class.php:435
75
+ msgid "Contact"
76
+ msgstr "Contatto"
77
+
78
+ #: classes/Display.class.php:433
79
+ msgid "Contact the PublishPress team"
80
+ msgstr "Contatta il team di PublishPress"
81
+
82
+ #: classes/Display.class.php:427
83
+ msgid "Documentation"
84
+ msgstr "Documentazione"
85
+
86
+ #: classes/Display.class.php:425
87
+ msgid "Future Documentation"
88
+ msgstr "Documentazione di Future"
89
+
90
+ #: classes/Display.class.php:419
91
+ msgid "About"
92
+ msgstr "Chi siamo"
93
+
94
+ #: classes/Display.class.php:417
95
+ msgid "About PublishPress Future"
96
+ msgstr "Informazioni su PublishPress Future"
97
+
98
+ #: classes/Display.class.php:402
99
+ msgid "If you like %s, please leave us a %s rating. Thank you!"
100
+ msgstr "Se %s ti piace, lasciaci una valutazione di %s!"
101
+
102
+ #: classes/Display.class.php:54
103
+ msgid "Future"
104
+ msgstr "Future"
105
+
106
+ #: classes/Display.class.php:53
107
+ msgid "PublishPress Future Options"
108
+ msgstr "Opzioni di PublishPress Future"
109
+
110
+ #. Plugin Name of the plugin
111
+ #: classes/Facade.class.php:378 post-expirator.php:377 views/bulk-edit.php:18
112
+ #: views/tabs.php:10
113
+ msgid "PublishPress Future"
114
+ msgstr "PublishPress Future"
115
+
116
+ #: views/menu-advanced.php:104
117
+ msgid "Toggle between preserving or deleting data after the plugin is deactivated."
118
+ msgstr "Attiva/disattiva la conservazione o l'eliminazione dei dati dopo la disattivazione del plugin."
119
+
120
+ #: views/menu-advanced.php:100
121
+ msgid "Delete data"
122
+ msgstr "Elimina i dati"
123
+
124
+ #: views/menu-advanced.php:91
125
+ msgid "Preserve data"
126
+ msgstr "Conserva i dati"
127
+
128
+ #: views/menu-advanced.php:82
129
+ msgid "Preserve data after deactivating the plugin"
130
+ msgstr "Conserva i dati dopo la disattivazione del plugin"
131
+
132
+ #: views/menu-diagnostics.php:73
133
+ msgid "No cron events found for the plugin."
134
+ msgstr "Nessun cron trovato per il plugin."
135
+
136
+ #: classes/Facade.class.php:381
137
+ msgid "Loading"
138
+ msgstr "Caricamento in corso"
139
+
140
+ #: views/tabs.php:27
141
+ msgid "Post Types"
142
+ msgstr "Tipi di contenuto"
143
+
144
+ #: views/menu-advanced.php:42 views/menu-editor.php:27
145
+ msgid "Toggle between native support for the Block Editor or the backward compatible Classic Editor style metabox."
146
+ msgstr "Commuta tra il supporto nativo per l'editor a blocchi e il metabox in stile editor classico, compatibile con le versioni precedenti."
147
+
148
+ #: views/menu-advanced.php:40 views/menu-editor.php:25
149
+ msgid "Show Classic Editor style box"
150
+ msgstr "Mostra la casella in stile editor classico"
151
+
152
+ #: views/menu-advanced.php:34 views/menu-editor.php:21
153
+ msgid "Show Gutenberg style box"
154
+ msgstr "Mostra la casella in stile Gutenberg"
155
+
156
+ #: views/menu-advanced.php:28 views/menu-editor.php:17
157
+ msgid "Block Editor Support"
158
+ msgstr "Supporto editor a blocchi"
159
+
160
+ #: views/menu-advanced.php:18
161
+ msgid "Please do not update anything here unless you know what it entails. For advanced users only."
162
+ msgstr "Si raccomanda di non aggiornare nulla qui se non se ne conoscono le conseguenze. Solo per utenti avanzati."
163
+
164
+ #: views/menu-advanced.php:16
165
+ msgid "Advanced Options"
166
+ msgstr "Opzioni avanzate"
167
+
168
+ #: views/menu-general.php:82
169
+ msgid "The default format to use when displaying the expiration time within a post using the shortcode or within the footer. For information on valid formatting options, see: %s."
170
+ msgstr "Il formato predefinito da utilizzare quando si visualizza l'ora di scadenza all'interno di un articolo utilizzando lo shortcode o nel footer. Per informazioni sulle opzioni di formattazione valide, vedere: %s."
171
+
172
+ #: views/menu-general.php:65
173
+ msgid "The default format to use when displaying the expiration date within a post using the shortcode or within the footer. For information on valid formatting options, see: %s."
174
+ msgstr "Il formato predefinito da utilizzare quando si visualizza la data di scadenza all'interno di un articolo utilizzando lo shortcode o nel footer. Per informazioni sulle opzioni di formattazione valide, vedere: %s."
175
+
176
+ #: views/menu-display.php:37
177
+ msgid "%1$s - valid options are %2$sfull%3$s (default), %4$sdate%5$s, %6$stime%7$s"
178
+ msgstr "%1$s - le opzioni valide sono %2$sfull%3$s (predefinito), %4$sdata%5$s, %6$sora%7$s"
179
+
180
+ #: views/menu-display.php:33
181
+ msgid "Valid %s attributes:"
182
+ msgstr "Attributi %s validi:"
183
+
184
+ #: views/menu-display.php:31
185
+ msgid "Shortcode"
186
+ msgstr "Shortcode"
187
+
188
+ #: views/menu-diagnostics.php:13
189
+ msgid "Debug Logging"
190
+ msgstr "Registrazione di debug"
191
+
192
+ #: views/menu-defaults.php:199
193
+ msgid "Set the default expiration date to be used when creating a new post of this type."
194
+ msgstr "Impostare la data di scadenza predefinita da utilizzare quando si crea un nuovo articolo di questo tipo."
195
+
196
+ #: views/menu-defaults.php:169
197
+ msgid "Publish Time"
198
+ msgstr "Data di pubblicazione"
199
+
200
+ #: views/menu-defaults.php:167
201
+ msgid "Inherit from General Settings"
202
+ msgstr "Eredita dalle impostazioni generali"
203
+
204
+ #: views/bulk-edit.php:108 views/quick-edit.php:74
205
+ msgid "Type"
206
+ msgstr "Tipo"
207
+
208
+ #: post-expirator.php:2115
209
+ msgid "No taxonomies found"
210
+ msgstr "Nessuna tassonomia trovata"
211
+
212
+ #. Author URI of the plugin
213
+ msgid "http://publishpress.com"
214
+ msgstr "http://publishpress.com"
215
+
216
+ #. Author of the plugin
217
+ msgid "PublishPress"
218
+ msgstr "PublishPress"
219
+
220
+ #: views/menu-defaults.php:216 views/menu-general.php:123
221
+ msgid "Set the custom value to use for the default expiration date. For information on formatting, see %1$s. For example, you could enter %2$s+1 month%3$s or %4$s+1 week 2 days 4 hours 2 seconds%5$s or %6$snext Thursday%7$s."
222
+ msgstr "Impostare il valore personalizzato da utilizzare per la data di scadenza predefinita. Per informazioni sulla formattazione, vedere %1$s. Ad esempio, si può inserire %2$s+1 mese%3$s o %4$s+1 settimana 2 giorni 4 ore 2 secondi%5$s o %6$sil prossimo giovedì%7$s."
223
+
224
+ #: views/bulk-edit.php:45
225
+ msgid "Remove from posts"
226
+ msgstr "Rimuovi dagli articoli"
227
+
228
+ #: views/bulk-edit.php:42
229
+ msgid "Change & Add"
230
+ msgstr "Cambia e aggiungi"
231
+
232
+ #: views/bulk-edit.php:39
233
+ msgid "Add to posts"
234
+ msgstr "Aggiungi agli articoli"
235
+
236
+ #: views/bulk-edit.php:38
237
+ msgid "Add expiry date if not enabled on posts"
238
+ msgstr "Aggiungi la data di scadenza se non è abilitata negli articoli"
239
+
240
+ #: views/bulk-edit.php:35
241
+ msgid "Change on posts"
242
+ msgstr "Cambia negli articoli"
243
+
244
+ #: views/bulk-edit.php:34
245
+ msgid "Change expiry date if enabled on posts"
246
+ msgstr "Cambia la data di scadenza se è abilitata negli articoli"
247
+
248
+ #: views/bulk-edit.php:30
249
+ msgid "No Change"
250
+ msgstr "Non cambiare"
251
+
252
+ #: post-expirator.php:1449
253
+ msgid "[%1$s] %2$s"
254
+ msgstr "[%1$s] %2$s"
255
+
256
+ #: classes/Facade.class.php:374 views/how-to-expire.php:42
257
+ msgid "Unstick"
258
+ msgstr "Rimuovi in evidenza"
259
+
260
+ #: classes/Facade.class.php:373 views/how-to-expire.php:38
261
+ msgid "Stick"
262
+ msgstr "Metti in evidenza"
263
+
264
+ #: classes/Facade.class.php:371 views/how-to-expire.php:30
265
+ msgid "Trash"
266
+ msgstr "Cestino"
267
+
268
+ #: views/menu-defaults.php:158
269
+ msgid "Enter a comma separate list of emails that you would like to be notified when the post expires."
270
+ msgstr "Inserisci un elenco di email separate da virgola a cui vuoi inviare una notifica quando scade l'articolo."
271
+
272
+ #: views/menu-general.php:232
273
+ msgid "Enter a comma separate list of emails that you would like to be notified when the post expires. This will be applied to ALL post types. You can set post type specific emails on the Defaults tab."
274
+ msgstr "Inserisci un elenco di email separate da virgole a cui ti piacerebbe inviare una notifica quando scade l'articolo. Questo sarà applicato a tutti i tipi di contenuto. È possibile impostare email specifiche per un tipo di contenuto nella scheda \"Valori predefiniti\"."
275
+
276
+ #: views/menu-defaults.php:151 views/menu-general.php:225
277
+ msgid "Who to notify"
278
+ msgstr "Chi avvisare"
279
+
280
+ #: views/menu-general.php:216
281
+ msgid "This will include all users with the role of \"Administrator\" in the post expiration email."
282
+ msgstr "Ciò includerà tutti gli utenti con il ruolo di \"Amministratore\" nell'email di scadenza dell'articolo."
283
+
284
+ #: views/menu-general.php:198
285
+ msgid "Include Blog Administrators?"
286
+ msgstr "Includere gli amministratori del blog?"
287
+
288
+ #: views/menu-general.php:190
289
+ msgid "This will enable or disable the send of email notification on post expiration."
290
+ msgstr "Questo abiliterà o disabiliterà l'invio della notifica via email alla scadenza dell'articolo."
291
+
292
+ #: views/menu-general.php:174
293
+ msgid "Enable Email Notification?"
294
+ msgstr "Abilita notifica email?"
295
+
296
+ #: views/menu-general.php:167
297
+ msgid "Whenever a post expires, an email can be sent to alert users of the expiration."
298
+ msgstr "Ogni volta che un articolo scade, un'email può essere spedita per avvisare gli utenti della scadenza."
299
+
300
+ #: views/menu-general.php:165
301
+ msgid "Expiration Email Notification"
302
+ msgstr "Email di notifica scadenza"
303
+
304
+ #: post-expirator.php:1398
305
+ msgid "Post Expiration Complete \"%s\""
306
+ msgstr "Scadenza articolo completata \"%s\""
307
+
308
+ #: post-expirator.php:1285 post-expirator.php:1341
309
+ msgid "%1$s (%2$s) has expired at %3$s. The following post \"%4$s\" have now been removed: \"%5$s\". The full list of categories on the post are: \"%6$s\"."
310
+ msgstr "%1$s (%2$s) è scaduto il %3$s. Il seguente articolo \"%4$s\" è stato rimosso: \"%5$s\". L'elenco completo delle categorie dell'articolo è: \"%6$s\"."
311
+
312
+ #: post-expirator.php:1164 post-expirator.php:1215
313
+ msgid "%1$s (%2$s) has expired at %3$s. The following post \"%4$s\" have now been added: \"%5$s\". The full list of categories on the post are: \"%6$s\"."
314
+ msgstr "%1$s (%2$s) è scaduto il %3$s. Il seguente articolo \"%4$s\" è stato aggiunto: \"%5$s\". L'elenco completo delle categorie dell'articolo è: \"%6$s\"."
315
+
316
+ #: post-expirator.php:1052 post-expirator.php:1101
317
+ msgid "%1$s (%2$s) has expired at %3$s. Post \"%4$s\" have now been set to \"%5$s\"."
318
+ msgstr "%1$s (%2$s) è scaduto il %3$s. L'articolo \"%4$s\" è stato impostato su \"%5$s\"."
319
+
320
+ #: post-expirator.php:1022
321
+ msgid "%1$s (%2$s) has expired at %3$s. Post \"%4$s\" status has been successfully removed."
322
+ msgstr "%1$s (%2$s) è scaduto il %3$s. Lo stato \"%4$s\" dell'articolo è stato rimosso con successo."
323
+
324
+ #: post-expirator.php:1001
325
+ msgid "%1$s (%2$s) has expired at %3$s. Post \"%4$s\" status has been successfully set."
326
+ msgstr "%1$s (%2$s) è scaduto il %3$s. Lo stato \"%4$s\" dell'articolo è stato impostato con successo."
327
+
328
+ #: post-expirator.php:901 post-expirator.php:927 post-expirator.php:953
329
+ #: post-expirator.php:977
330
+ msgid "%1$s (%2$s) has expired at %3$s. Post status has been successfully changed to \"%4$s\"."
331
+ msgstr "%1$s (%2$s) è scaduto il %3$s. Lo stato dell'articolo è stato cambiato con successo in \"%4$s\"."
332
+
333
+ #. Description of the plugin
334
+ msgid "Allows you to add an expiration date (minute) to posts which you can configure to either delete the post, change it to a draft, or update the post categories at expiration time."
335
+ msgstr "Consente di aggiungere una data e un orario di scadenza agli articoli con la possibilità di configurare se eliminare il post, metterlo in bozza o aggiornare le categorie al momento della scadenza."
336
+
337
+ #. Plugin URI of the plugin
338
+ msgid "http://wordpress.org/extend/plugins/post-expirator/"
339
+ msgstr "http://wordpress.org/extend/plugins/post-expirator/"
340
+
341
+ #: classes/Facade.class.php:372 views/how-to-expire.php:34
342
+ msgid "Private"
343
+ msgstr "Privato"
344
+
345
+ #: classes/Facade.class.php:370 views/how-to-expire.php:26
346
+ msgid "Delete"
347
+ msgstr "Elimina"
348
+
349
+ #: classes/Facade.class.php:369 views/how-to-expire.php:22
350
+ msgid "Draft"
351
+ msgstr "Bozza"
352
+
353
+ #: classes/Display.class.php:197
354
+ msgid "Below is a dump of the debugging table, this should be useful for troubleshooting."
355
+ msgstr "Di seguito è riportato un dump della tabella di debug, questo dovrebbe essere utile per la risoluzione dei problemi."
356
+
357
+ #: views/menu-diagnostics.php:97
358
+ msgid "Event"
359
+ msgstr "Evento"
360
+
361
+ #: views/bulk-edit.php:23 views/menu-diagnostics.php:94 views/quick-edit.php:18
362
+ msgid "Date"
363
+ msgstr "Data"
364
+
365
+ #: views/menu-diagnostics.php:82
366
+ msgid "The below table will show all currently scheduled cron events for the plugin with the next run time."
367
+ msgstr "La tabella seguente mostra tutti gli eventi cron attualmente programmati per il plugin con il prossimo orario di esecuzione."
368
+
369
+ #: views/menu-diagnostics.php:65
370
+ msgid "Current Cron Schedule"
371
+ msgstr "Programma cron attuale"
372
+
373
+ #: views/menu-diagnostics.php:52
374
+ msgid "WP-Cron Status"
375
+ msgstr "Stato di WP-Cron"
376
+
377
+ #: views/menu-diagnostics.php:44 views/menu-diagnostics.php:47
378
+ msgid "Purge Debug Log"
379
+ msgstr "Svuota il registro di debug"
380
+
381
+ #: views/menu-diagnostics.php:35
382
+ msgid "Enable Debugging"
383
+ msgstr "Attiva il debugging"
384
+
385
+ #: views/menu-diagnostics.php:20
386
+ msgid "Disable Debugging"
387
+ msgstr "Disattiva il debugging"
388
+
389
+ #: views/menu-diagnostics.php:9
390
+ msgid "Advanced Diagnostics"
391
+ msgstr "Diagnostica avanzata"
392
+
393
+ #: classes/Display.class.php:181
394
+ msgid "Debugging Table Emptied"
395
+ msgstr "Tabella di debug svuotata"
396
+
397
+ #: classes/Display.class.php:174
398
+ msgid "Debugging Enabled"
399
+ msgstr "Debug abilitato"
400
+
401
+ #: classes/Display.class.php:169
402
+ msgid "Debugging Disabled"
403
+ msgstr "Debug disabilitato"
404
+
405
+ #: post-expirator.php:2127
406
+ msgid "Select the hierarchical taxonomy to be used for \"category\" based expiration."
407
+ msgstr "Seleziona la tassonomia gerarchica da utilizzare per la scadenza basata sulla \"categoria\"."
408
+
409
+ #: views/menu-defaults.php:135
410
+ msgid "Taxonomy (hierarchical)"
411
+ msgstr "Tassonomia (gerarchica)"
412
+
413
+ #: views/menu-defaults.php:108
414
+ msgid "Auto-Enable?"
415
+ msgstr "Abilitazione automatica?"
416
+
417
+ #: views/menu-defaults.php:102
418
+ msgid "Select the default expire action for the post type."
419
+ msgstr "Seleziona l'azione di scadenza predefinita per il tipo di contenuto."
420
+
421
+ #: views/menu-defaults.php:83
422
+ msgid "Select whether the PublishPress Future meta box is active for this post type."
423
+ msgstr "Selezionare se la casella di meta PublishPress Future è attiva per questo tipo di articolo."
424
+
425
+ #: views/menu-defaults.php:81
426
+ msgid "Inactive"
427
+ msgstr "Inattivo"
428
+
429
+ #: views/menu-defaults.php:65 views/menu-defaults.php:73
430
+ msgid "Active"
431
+ msgstr "Attivo"
432
+
433
+ #: views/menu-defaults.php:13
434
+ msgid "Use the values below to set the default actions/values to be used for each for the corresponding post types. These values can all be overwritten when creating/editing the post/page."
435
+ msgstr "Utilizza i seguenti valori per impostare azioni/valori predefiniti da utilizzare per ciascuno dei tipi di contenuto corrispondenti. Questi valori possono essere tutti sovrascritti in fase di creazione/modifica di ciascun articolo/pagina."
436
+
437
+ #: views/menu-defaults.php:10
438
+ msgid "Default Expiration Values"
439
+ msgstr "Valori di scadenza predefiniti"
440
+
441
+ #: views/menu-advanced.php:116 views/menu-defaults.php:239
442
+ #: views/menu-display.php:132 views/menu-editor.php:37
443
+ #: views/menu-general.php:243
444
+ msgid "Save Changes"
445
+ msgstr "Salva modifiche"
446
+
447
+ #: views/menu-display.php:125
448
+ msgid "The inline css which will be used to style the footer text."
449
+ msgstr "Il css inline che verrà utilizzato per definire lo stile del testo del footer."
450
+
451
+ #: views/menu-display.php:122
452
+ msgid "This post will expire on"
453
+ msgstr "Questo articolo scadrà il"
454
+
455
+ #: views/menu-display.php:116
456
+ msgid "Footer Style"
457
+ msgstr "Stile del footer"
458
+
459
+ #: views/menu-display.php:98
460
+ msgid "Enter the text you would like to appear at the bottom of every post that will expire. The following placeholders will be replaced with the post expiration date in the following format:"
461
+ msgstr "Inserisci il testo che vorresti far apparire in fondo a ogni articolo impostato con una scadenza. I seguenti segnaposto verranno sostituiti con la data di scadenza nel modo indicato:"
462
+
463
+ #: views/menu-display.php:93
464
+ msgid "Footer Contents"
465
+ msgstr "Contenuto del footer"
466
+
467
+ #: views/menu-display.php:85
468
+ msgid "This will enable or disable displaying the post expiration date in the post footer."
469
+ msgstr "Questo abiliterà o disabiliterà la visualizzazione della data di scadenza dell'articolo nel footer dello stesso."
470
+
471
+ #: views/menu-defaults.php:124 views/menu-diagnostics.php:32
472
+ #: views/menu-diagnostics.php:59 views/menu-display.php:83
473
+ #: views/menu-general.php:188 views/menu-general.php:214
474
+ msgid "Disabled"
475
+ msgstr "Disabilitato"
476
+
477
+ #: views/menu-defaults.php:116 views/menu-diagnostics.php:17
478
+ #: views/menu-diagnostics.php:56 views/menu-display.php:78
479
+ #: views/menu-general.php:181 views/menu-general.php:206
480
+ msgid "Enabled"
481
+ msgstr "Abilitato"
482
+
483
+ #: views/menu-display.php:73
484
+ msgid "Show in post footer?"
485
+ msgstr "Mostrare nel footer dell'articolo?"
486
+
487
+ #: views/menu-display.php:66
488
+ msgid "Enabling this below will display the expiration date automatically at the end of any post which is set to expire."
489
+ msgstr "Abilitando l'opzione seguente verrà mostrata automaticamente la data di scadenza alla fine di ogni articolo che è impostato per scadere."
490
+
491
+ #: views/menu-display.php:64
492
+ msgid "Post Footer Display"
493
+ msgstr "Visualizzazione nel footer"
494
+
495
+ #: views/menu-general.php:159
496
+ msgid "Sets the default expiration category for the post."
497
+ msgstr "Imposta la categoria di scadenza predefinita per l'articolo."
498
+
499
+ #: views/menu-general.php:140
500
+ msgid "Default Expiration Taxonomy"
501
+ msgstr "Tassonomia di scadenza predefinita"
502
+
503
+ #: views/menu-general.php:107
504
+ msgid "Set the default expiration date to be used when creating new posts and pages. Defaults to none."
505
+ msgstr "Imposta la data di scadenza predefinita da utilizzare quando si creano nuovi articoli e pagine. Il valore predefinito è nessuno."
506
+
507
+ #: views/menu-general.php:104
508
+ msgid "Post/Page Publish Time"
509
+ msgstr "Data/ora di pubblicazione dell'articolo o della pagina"
510
+
511
+ #: views/menu-defaults.php:168 views/menu-defaults.php:209
512
+ #: views/menu-general.php:101 views/menu-general.php:117
513
+ msgid "Custom"
514
+ msgstr "Personalizzato"
515
+
516
+ #: views/menu-defaults.php:166 views/menu-general.php:98
517
+ msgid "None"
518
+ msgstr "Nessuna"
519
+
520
+ #: views/menu-defaults.php:184 views/menu-general.php:92
521
+ msgid "Default Date/Time Duration"
522
+ msgstr "Durata Data/Ora predefinita"
523
+
524
+ #: views/menu-general.php:75
525
+ msgid "Time Format"
526
+ msgstr "Formato ora"
527
+
528
+ #: views/menu-general.php:58
529
+ msgid "Date Format"
530
+ msgstr "Formato data"
531
+
532
+ #: views/menu-display.php:51 views/menu-display.php:56
533
+ msgid "%s - format set here will override the value set on the settings page"
534
+ msgstr "%s - il formato impostato qui sovrascrive il valore configurato nella pagina delle impostazioni"
535
+
536
+ #: classes/Display.class.php:253 classes/Display.class.php:315
537
+ #: classes/Display.class.php:365
538
+ msgid "Saved Options!"
539
+ msgstr "Opzioni salvate!"
540
+
541
+ #: views/menu-diagnostics.php:29 views/tabs.php:44
542
+ msgid "View Debug Logs"
543
+ msgstr "Visualizza i log di debug"
544
+
545
+ #: views/tabs.php:32
546
+ msgid "Diagnostics"
547
+ msgstr "Diagnostica"
548
+
549
+ #: views/menu-general.php:54 views/tabs.php:17
550
+ msgid "Defaults"
551
+ msgstr "Valori predefiniti"
552
+
553
+ #: views/classic-metabox.php:167
554
+ msgid "Taxonomy Name"
555
+ msgstr "Nome tassonomia"
556
+
557
+ #: views/classic-metabox.php:149
558
+ msgid "More than 1 heirachical taxonomy detected. You must assign a default taxonomy on the settings screen."
559
+ msgstr "È stata rilevata più di 1 tassonomia gerarchica. È necessario assegnare una tassonomia predefinita nella schermata delle impostazioni."
560
+
561
+ #: views/classic-metabox.php:144
562
+ msgid "You must assign a hierarchical taxonomy to this post type to use this feature."
563
+ msgstr "Per usare questa caratteristica devi assegnare una tassonomia gerarchica a questo tipo di contenuto."
564
+
565
+ #: classes/Facade.class.php:380 views/bulk-edit.php:110
566
+ #: views/classic-metabox.php:117 views/menu-defaults.php:92
567
+ #: views/quick-edit.php:76
568
+ msgid "How to expire"
569
+ msgstr "Come applicare la scadenza"
570
+
571
+ #: views/bulk-edit.php:96 views/classic-metabox.php:110 views/quick-edit.php:63
572
+ msgid "Minute"
573
+ msgstr "Minuto"
574
+
575
+ #: views/bulk-edit.php:89 views/classic-metabox.php:85 views/quick-edit.php:57
576
+ msgid "Hour"
577
+ msgstr "Ora"
578
+
579
+ #: views/bulk-edit.php:75 views/classic-metabox.php:78 views/quick-edit.php:43
580
+ msgid "Day"
581
+ msgstr "Giorno"
582
+
583
+ #: views/bulk-edit.php:51 views/classic-metabox.php:56 views/quick-edit.php:21
584
+ msgid "Month"
585
+ msgstr "Mese"
586
+
587
+ #: views/bulk-edit.php:82 views/classic-metabox.php:27 views/quick-edit.php:50
588
+ msgid "Year"
589
+ msgstr "Anno"
590
+
591
+ #: views/classic-metabox.php:18
592
+ msgid "The published date/time will be used as the expiration value"
593
+ msgstr "La data e l'ora pubblicate verranno utilizzate come valore di scadenza"
594
+
595
+ #: classes/Facade.class.php:379 views/bulk-edit.php:26
596
+ #: views/classic-metabox.php:11 views/quick-edit.php:12
597
+ msgid "Enable Post Expiration"
598
+ msgstr "Abilita scadenza articolo"
599
+
600
+ #: views/expire-column.php:24
601
+ msgid "Never"
602
+ msgstr "Mai"
603
+
604
+ #: post-expirator.php:113 post-expirator.php:199
605
+ msgid "Expires"
606
+ msgstr "Scadenza"
607
+
608
+ #: post-expirator.php:65
609
+ msgid "Settings"
610
+ msgstr "Impostazioni"
611
+
612
+ #: post-expirator.php:32
613
+ msgid "Post expires at EXPIRATIONTIME on EXPIRATIONDATE"
614
+ msgstr "L'articolo scade alle EXPIRATIONTIME del EXPIRATIONDATE"
615
+
616
+ #: post-expirator.php:31
617
+ msgid "g:ia"
618
+ msgstr "G:i"
619
+
620
+ #: post-expirator.php:30
621
+ msgid "l F jS, Y"
622
+ msgstr "l j F Y"
623
+
624
+ #: post-expirator-debug.php:87
625
+ msgid "Message"
626
+ msgstr "Messaggio"
627
+
628
+ #: post-expirator-debug.php:86
629
+ msgid "Timestamp"
630
+ msgstr "Data e ora"
631
+
632
+ #: post-expirator-debug.php:81
633
+ msgid "Debugging table is currently empty."
634
+ msgstr "La tabella di debug è attualmente vuota."
languages/post-expirator-pt_BR.po CHANGED
@@ -532,7 +532,7 @@ msgid "Default Expiration Taxonomy"
532
  msgstr ""
533
 
534
  #: views/menu-general.php:205
535
- msgid "Sets the default expiration category for the post."
536
  msgstr ""
537
 
538
  #: views/menu-general.php:211
532
  msgstr ""
533
 
534
  #: views/menu-general.php:205
535
+ msgid "Sets the default expiration taxonomy for the post."
536
  msgstr ""
537
 
538
  #: views/menu-general.php:211
languages/post-expirator.pot CHANGED
@@ -629,7 +629,7 @@ msgid "Default Expiration Taxonomy"
629
  msgstr ""
630
 
631
  #: views/menu-general.php:170
632
- msgid "Sets the default expiration category for the post."
633
  msgstr ""
634
 
635
  #: views/menu-general.php:176
629
  msgstr ""
630
 
631
  #: views/menu-general.php:170
632
+ msgid "Sets the default expiration taxonomy for the post."
633
  msgstr ""
634
 
635
  #: views/menu-general.php:176
legacy-functions.php DELETED
@@ -1,84 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * This file provides access to all legacy functions that are now deprecated.
5
- */
6
-
7
- if (! function_exists('_scheduleExpiratorEvent')) {
8
- /**
9
- * Schedules the single event.
10
- *
11
- * @since 2.4.3
12
- * @deprecated 2.4.3
13
- */
14
- function _scheduleExpiratorEvent($id, $ts, $opts)
15
- {
16
- postexpirator_schedule_event($id, $ts, $opts);
17
- }
18
- }
19
-
20
-
21
- if (! function_exists('_unscheduleExpiratorEvent')) {
22
- /**
23
- * Unschedules the single event.
24
- *
25
- * @since 2.4.3
26
- * @deprecated 2.4.3
27
- */
28
- function _unscheduleExpiratorEvent($id)
29
- {
30
- postexpirator_unschedule_event($id);
31
- }
32
- }
33
-
34
-
35
- if (! function_exists('postExpiratorExpire')) {
36
- /**
37
- * Expires the post.
38
- *
39
- * @since 2.4.3
40
- * @deprecated 2.4.3
41
- */
42
- function postExpiratorExpire($id)
43
- {
44
- postexpirator_expire_post($id);
45
- }
46
- }
47
-
48
-
49
- if (! function_exists('_postExpiratorExpireType')) {
50
- /**
51
- * Get the HTML for expire type.
52
- *
53
- * @since 2.5.0
54
- * @deprecated 2.5.0
55
- */
56
- function _postExpiratorExpireType($opts)
57
- {
58
- ob_start();
59
- _postexpirator_expire_type($opts);
60
-
61
- return ob_get_clean();
62
- }
63
- }
64
-
65
- /**
66
- * Get correct URL (HTTP or HTTPS)
67
- *
68
- * @internal
69
- * @access private
70
- *
71
- * @deprecated 2.7.1
72
- */
73
- function expirationdate_get_blog_url()
74
- {
75
- _deprecated_function(__FUNCTION__, '2.7.1');
76
-
77
- if (is_multisite()) {
78
- $url = network_home_url('/');
79
- } else {
80
- $url = home_url('/');
81
- }
82
-
83
- echo esc_url($url);
84
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
legacy/autoload.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Autoloads the classes.
5
+ *
6
+ * @deprecated 2.8.0
7
+ */
8
+ function postexpirator_autoload($class)
9
+ {
10
+ $namespaces = array('PostExpirator');
11
+ foreach ($namespaces as $namespace) {
12
+ if (substr($class, 0, strlen($namespace)) === $namespace) {
13
+ $class = str_replace('_', '', strstr($class, '_'));
14
+
15
+ $filename = POSTEXPIRATOR_LEGACYDIR . '/classes/' . sprintf('%s.class.php', $class);
16
+ if (is_readable($filename)) {
17
+ require_once $filename;
18
+
19
+ return true;
20
+ }
21
+ }
22
+ }
23
+
24
+ return false;
25
+ }
26
+
27
+ spl_autoload_register('postexpirator_autoload');
{classes → legacy/classes}/Cli.class.php RENAMED
File without changes
{classes → legacy/classes}/CronFacade.class.php RENAMED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  /**
4
  * Utility functions.
5
  */
@@ -41,7 +43,8 @@ class PostExpirator_CronFacade
41
  private static function get_valid_events()
42
  {
43
  return [
44
- 'postExpiratorExpire',
 
45
  ];
46
  }
47
 
1
  <?php
2
 
3
+ use PublishPressFuture\Modules\Expirator\HooksAbstract as ExpiratorHooks;
4
+
5
  /**
6
  * Utility functions.
7
  */
43
  private static function get_valid_events()
44
  {
45
  return [
46
+ ExpiratorHooks::ACTION_EXPIRE_POST,
47
+ ExpiratorHooks::ACTION_LEGACY_EXPIRE_POST,
48
  ];
49
  }
50
 
{classes → legacy/classes}/Display.class.php RENAMED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  /**
4
  * The class that is responsible for all the displays.
5
  */
@@ -83,6 +85,7 @@ class PostExpirator_Display
83
  PostExpirator_Facade::load_assets('settings');
84
 
85
  $allowed_tabs = array('general', 'defaults', 'display', 'editor', 'diagnostics', 'viewdebug', 'advanced');
 
86
  $tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : '';
87
  if (empty($tab) || ! in_array($tab, $allowed_tabs, true)) {
88
  $tab = 'general';
@@ -92,9 +95,8 @@ class PostExpirator_Display
92
  $this->load_tab($tab);
93
  $html = ob_get_clean();
94
 
95
- $debug = postexpirator_debug(); // check for/load debug
96
-
97
- if (! POSTEXPIRATOR_DEBUG) {
98
  unset($allowed_tabs['viewdebug']);
99
  }
100
 
@@ -108,6 +110,7 @@ class PostExpirator_Display
108
  */
109
  private function menu_editor()
110
  {
 
111
  if (isset($_POST['expirationdateSaveEditor']) && sanitize_key($_POST['expirationdateSaveEditor'])) {
112
  if (! isset($_POST['_postExpiratorMenuEditor_nonce']) || ! wp_verify_nonce(
113
  sanitize_key($_POST['_postExpiratorMenuEditor_nonce']),
@@ -116,6 +119,7 @@ class PostExpirator_Display
116
  print 'Form Validation Failure: Sorry, your nonce did not verify.';
117
  exit;
118
  } else {
 
119
  update_option('expirationdateGutenbergSupport', sanitize_text_field($_POST['gutenberg-support']));
120
  }
121
  }
@@ -128,6 +132,7 @@ class PostExpirator_Display
128
  */
129
  private function menu_display()
130
  {
 
131
  if (isset($_POST['expirationdateSaveDisplay']) && sanitize_key($_POST['expirationdateSaveDisplay'])) {
132
  if (! isset($_POST['_postExpiratorMenuDisplay_nonce']) || ! wp_verify_nonce(
133
  sanitize_key($_POST['_postExpiratorMenuDisplay_nonce']),
@@ -139,7 +144,7 @@ class PostExpirator_Display
139
  // Filter Content
140
  $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
141
 
142
- // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
143
  update_option('expirationdateDisplayFooter', $_POST['expired-display-footer']);
144
  update_option('expirationdateFooterContents', $_POST['expired-footer-contents']);
145
  update_option('expirationdateFooterStyle', $_POST['expired-footer-style']);
@@ -155,6 +160,7 @@ class PostExpirator_Display
155
  */
156
  private function menu_diagnostics()
157
  {
 
158
  if ($_SERVER['REQUEST_METHOD'] === 'POST') {
159
  if (! isset($_POST['_postExpiratorMenuDiagnostics_nonce']) || ! wp_verify_nonce(
160
  sanitize_key($_POST['_postExpiratorMenuDiagnostics_nonce']),
@@ -174,7 +180,8 @@ class PostExpirator_Display
174
  _e('Debugging Enabled', 'post-expirator');
175
  echo '</p></div>';
176
  } elseif (isset($_POST['purge-debug'])) {
177
- require_once(POSTEXPIRATOR_BASEDIR . '/post-expirator-debug.php');
 
178
  $debug = new PostExpiratorDebug();
179
  $debug->purge();
180
  echo "<div id='message' class='updated fade'><p>";
@@ -183,8 +190,6 @@ class PostExpirator_Display
183
  }
184
  }
185
 
186
- $debug = postexpirator_debug();
187
-
188
  $this->render_template('menu-diagnostics');
189
  }
190
 
@@ -193,13 +198,33 @@ class PostExpirator_Display
193
  */
194
  private function menu_viewdebug()
195
  {
196
- require_once POSTEXPIRATOR_BASEDIR . '/post-expirator-debug.php';
197
  print '<p>' . esc_html__(
198
  'Below is a dump of the debugging table, this should be useful for troubleshooting.',
199
  'post-expirator'
200
  ) . '</p>';
201
  $debug = new PostExpiratorDebug();
202
- $debug->getTable();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  }
204
 
205
  /**
@@ -207,7 +232,6 @@ class PostExpirator_Display
207
  */
208
  private function menu_defaults()
209
  {
210
- $debug = postexpirator_debug();
211
  $types = postexpirator_get_post_types();
212
  $defaults = array();
213
 
@@ -236,6 +260,7 @@ class PostExpirator_Display
236
  if (isset($_POST['expirationdate_activemeta-' . $type])) {
237
  $defaults[$type]['activeMetaBox'] = sanitize_text_field($_POST['expirationdate_activemeta-' . $type]);
238
  }
 
239
  $defaults[$type]['emailnotification'] = trim(sanitize_text_field($_POST['expirationdate_emailnotification-' . $type]));
240
 
241
  if (isset($_POST['expired-default-date-' . $type])) {
@@ -276,6 +301,7 @@ class PostExpirator_Display
276
  // Filter Content
277
  $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
278
 
 
279
  update_option('expirationdateDefaultDateFormat', sanitize_text_field($_POST['expired-default-date-format']));
280
  update_option('expirationdateDefaultTimeFormat', sanitize_text_field($_POST['expired-default-time-format']));
281
  update_option('expirationdateEmailNotification', sanitize_text_field($_POST['expired-email-notification']));
@@ -283,12 +309,12 @@ class PostExpirator_Display
283
  update_option('expirationdateEmailNotificationList', trim(sanitize_text_field($_POST['expired-email-notification-list'])));
284
  update_option(
285
  'expirationdateCategoryDefaults',
 
286
  isset($_POST['expirationdate_category']) ? PostExpirator_Util::sanitize_array_of_integers($_POST['expirationdate_category']) : []
287
  );
288
  update_option('expirationdateDefaultDate', sanitize_text_field($_POST['expired-default-expiration-date']));
289
- if (!empty($_POST['expired-custom-expiration-date'])) {
290
- update_option('expirationdateDefaultDateCustom', sanitize_text_field($_POST['expired-custom-expiration-date']));
291
- }
292
 
293
  if (! isset($_POST['allow-user-roles']) || ! is_array($_POST['allow-user-roles'])) {
294
  $_POST['allow-user-roles'] = array();
@@ -338,7 +364,9 @@ class PostExpirator_Display
338
  // Filter Content
339
  $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
340
 
 
341
  update_option('expirationdateGutenbergSupport', sanitize_text_field($_POST['gutenberg-support']));
 
342
  update_option('expirationdatePreserveData', (int)$_POST['expired-preserve-data-deactivating']);
343
 
344
  if (! isset($_POST['allow-user-roles']) || ! is_array($_POST['allow-user-roles'])) {
@@ -375,7 +403,7 @@ class PostExpirator_Display
375
  */
376
  public function render_template($name, $params = null)
377
  {
378
- $template = POSTEXPIRATOR_BASEDIR . "/views/{$name}.php";
379
  if (file_exists($template)) {
380
  // expand all parameters so that they can be directly accessed with their name.
381
  if ($params) {
@@ -387,6 +415,22 @@ class PostExpirator_Display
387
  }
388
  }
389
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  /**
391
  * PublishPress footer
392
  */
@@ -451,7 +495,7 @@ class PostExpirator_Display
451
  <div class="pp-pressshack-logo">
452
  <a href="https://publishpress.com" target="_blank" rel="noopener noreferrer">
453
  <img src="<?php
454
- echo esc_url(plugins_url('assets/images/publishpress-logo.png', dirname(__FILE__))) ?>"/>
455
  </a>
456
  </div>
457
  </footer>
1
  <?php
2
 
3
+ use PublishPressFuture\Modules\Settings\HooksAbstract;
4
+
5
  /**
6
  * The class that is responsible for all the displays.
7
  */
85
  PostExpirator_Facade::load_assets('settings');
86
 
87
  $allowed_tabs = array('general', 'defaults', 'display', 'editor', 'diagnostics', 'viewdebug', 'advanced');
88
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
89
  $tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : '';
90
  if (empty($tab) || ! in_array($tab, $allowed_tabs, true)) {
91
  $tab = 'general';
95
  $this->load_tab($tab);
96
  $html = ob_get_clean();
97
 
98
+ $debugIsEnabled = (bool)apply_filters(HooksAbstract::FILTER_DEBUG_ENABLED, false);
99
+ if (! $debugIsEnabled) {
 
100
  unset($allowed_tabs['viewdebug']);
101
  }
102
 
110
  */
111
  private function menu_editor()
112
  {
113
+ // phpcs:ignore WordPress.Security.NonceVerification.Missing
114
  if (isset($_POST['expirationdateSaveEditor']) && sanitize_key($_POST['expirationdateSaveEditor'])) {
115
  if (! isset($_POST['_postExpiratorMenuEditor_nonce']) || ! wp_verify_nonce(
116
  sanitize_key($_POST['_postExpiratorMenuEditor_nonce']),
119
  print 'Form Validation Failure: Sorry, your nonce did not verify.';
120
  exit;
121
  } else {
122
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
123
  update_option('expirationdateGutenbergSupport', sanitize_text_field($_POST['gutenberg-support']));
124
  }
125
  }
132
  */
133
  private function menu_display()
134
  {
135
+ // phpcs:ignore WordPress.Security.NonceVerification.Missing
136
  if (isset($_POST['expirationdateSaveDisplay']) && sanitize_key($_POST['expirationdateSaveDisplay'])) {
137
  if (! isset($_POST['_postExpiratorMenuDisplay_nonce']) || ! wp_verify_nonce(
138
  sanitize_key($_POST['_postExpiratorMenuDisplay_nonce']),
144
  // Filter Content
145
  $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
146
 
147
+ // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
148
  update_option('expirationdateDisplayFooter', $_POST['expired-display-footer']);
149
  update_option('expirationdateFooterContents', $_POST['expired-footer-contents']);
150
  update_option('expirationdateFooterStyle', $_POST['expired-footer-style']);
160
  */
161
  private function menu_diagnostics()
162
  {
163
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
164
  if ($_SERVER['REQUEST_METHOD'] === 'POST') {
165
  if (! isset($_POST['_postExpiratorMenuDiagnostics_nonce']) || ! wp_verify_nonce(
166
  sanitize_key($_POST['_postExpiratorMenuDiagnostics_nonce']),
180
  _e('Debugging Enabled', 'post-expirator');
181
  echo '</p></div>';
182
  } elseif (isset($_POST['purge-debug'])) {
183
+ require_once POSTEXPIRATOR_LEGACYDIR . '/debug.php';
184
+
185
  $debug = new PostExpiratorDebug();
186
  $debug->purge();
187
  echo "<div id='message' class='updated fade'><p>";
190
  }
191
  }
192
 
 
 
193
  $this->render_template('menu-diagnostics');
194
  }
195
 
198
  */
199
  private function menu_viewdebug()
200
  {
201
+ require_once POSTEXPIRATOR_LEGACYDIR . '/debug.php';
202
  print '<p>' . esc_html__(
203
  'Below is a dump of the debugging table, this should be useful for troubleshooting.',
204
  'post-expirator'
205
  ) . '</p>';
206
  $debug = new PostExpiratorDebug();
207
+ $results = $debug->getTable();
208
+
209
+ if (empty($results)) {
210
+ print '<p>' . esc_html__('Debugging table is currently empty.', 'post-expirator') . '</p>';
211
+
212
+ return;
213
+ }
214
+ print '<table class="form-table"><tbody><tr><td>';
215
+ print '<table class="post-expirator-debug striped wp-list-table widefat fixed table-view-list">';
216
+ print '<thead>';
217
+ print '<tr><th class="post-expirator-timestamp">' . esc_html__('Timestamp', 'post-expirator') . '</th>';
218
+ print '<th>' . esc_html__('Message', 'post-expirator') . '</th></tr>';
219
+ print '</thead>';
220
+ print '<tbody>';
221
+ foreach ($results as $result) {
222
+ print '<tr><td>' . esc_html($result->timestamp) . '</td>';
223
+ print '<td>' . esc_html($result->message) . '</td></tr>';
224
+ }
225
+ print '</tbody>';
226
+ print '</table>';
227
+ print '</td></tr></tbody></table>';
228
  }
229
 
230
  /**
232
  */
233
  private function menu_defaults()
234
  {
 
235
  $types = postexpirator_get_post_types();
236
  $defaults = array();
237
 
260
  if (isset($_POST['expirationdate_activemeta-' . $type])) {
261
  $defaults[$type]['activeMetaBox'] = sanitize_text_field($_POST['expirationdate_activemeta-' . $type]);
262
  }
263
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
264
  $defaults[$type]['emailnotification'] = trim(sanitize_text_field($_POST['expirationdate_emailnotification-' . $type]));
265
 
266
  if (isset($_POST['expired-default-date-' . $type])) {
301
  // Filter Content
302
  $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
303
 
304
+ // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotValidated
305
  update_option('expirationdateDefaultDateFormat', sanitize_text_field($_POST['expired-default-date-format']));
306
  update_option('expirationdateDefaultTimeFormat', sanitize_text_field($_POST['expired-default-time-format']));
307
  update_option('expirationdateEmailNotification', sanitize_text_field($_POST['expired-email-notification']));
309
  update_option('expirationdateEmailNotificationList', trim(sanitize_text_field($_POST['expired-email-notification-list'])));
310
  update_option(
311
  'expirationdateCategoryDefaults',
312
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
313
  isset($_POST['expirationdate_category']) ? PostExpirator_Util::sanitize_array_of_integers($_POST['expirationdate_category']) : []
314
  );
315
  update_option('expirationdateDefaultDate', sanitize_text_field($_POST['expired-default-expiration-date']));
316
+ update_option('expirationdateDefaultDateCustom', sanitize_text_field($_POST['expired-custom-expiration-date']));
317
+ // phpcs:enable
 
318
 
319
  if (! isset($_POST['allow-user-roles']) || ! is_array($_POST['allow-user-roles'])) {
320
  $_POST['allow-user-roles'] = array();
364
  // Filter Content
365
  $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
366
 
367
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
368
  update_option('expirationdateGutenbergSupport', sanitize_text_field($_POST['gutenberg-support']));
369
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
370
  update_option('expirationdatePreserveData', (int)$_POST['expired-preserve-data-deactivating']);
371
 
372
  if (! isset($_POST['allow-user-roles']) || ! is_array($_POST['allow-user-roles'])) {
403
  */
404
  public function render_template($name, $params = null)
405
  {
406
+ $template = POSTEXPIRATOR_LEGACYDIR . "/views/{$name}.php";
407
  if (file_exists($template)) {
408
  // expand all parameters so that they can be directly accessed with their name.
409
  if ($params) {
415
  }
416
  }
417
 
418
+ /**
419
+ * Returns the rendered template
420
+ *
421
+ * @param string $name
422
+ * @param array $param
423
+ * @return string
424
+ */
425
+ public function get_rendered_template($name, $params = null)
426
+ {
427
+ ob_start();
428
+
429
+ $this->render_template($name, $params);
430
+
431
+ return ob_get_clean();
432
+ }
433
+
434
  /**
435
  * PublishPress footer
436
  */
495
  <div class="pp-pressshack-logo">
496
  <a href="https://publishpress.com" target="_blank" rel="noopener noreferrer">
497
  <img src="<?php
498
+ echo esc_url(plugins_url('../assets/images/publishpress-logo.png', dirname(__FILE__))) ?>"/>
499
  </a>
500
  </div>
501
  </footer>
{classes → legacy/classes}/Facade.class.php RENAMED
@@ -1,5 +1,10 @@
1
  <?php
2
 
 
 
 
 
 
3
  /**
4
  * The class that acts as a facade for the plugin's core functions.
5
  *
@@ -8,19 +13,24 @@
8
  class PostExpirator_Facade
9
  {
10
 
11
- const DEFAULT_CAPABILITY_EXPIRE_POST = 'publishpress_future_expire_post';
 
 
 
12
 
13
  /**
14
  * The singleton instance.
15
  */
16
  private static $instance = null;
 
17
  /**
18
  * List of capabilities used by the plugin.
19
  *
20
  * @var string[]
 
21
  */
22
  private $capabilities = array(
23
- 'expire_post' => self::DEFAULT_CAPABILITY_EXPIRE_POST,
24
  );
25
 
26
  /**
@@ -60,8 +70,8 @@ class PostExpirator_Facade
60
  return false;
61
  }
62
 
63
- return $user_role_instance->has_cap($this->capabilities['expire_post'])
64
- && $user_role_instance->capabilities[$this->capabilities['expire_post']] === true;
65
  }
66
 
67
  /**
@@ -75,7 +85,7 @@ class PostExpirator_Facade
75
  return;
76
  }
77
 
78
- $admin_role->add_cap(self::DEFAULT_CAPABILITY_EXPIRE_POST);
79
  }
80
 
81
  /**
@@ -115,6 +125,8 @@ class PostExpirator_Facade
115
 
116
  /**
117
  * Set the expire type, categories etc. corresponding to the new (gutenberg) structure.
 
 
118
  */
119
  public static function set_expire_principles($id, $opts)
120
  {
@@ -139,11 +151,13 @@ class PostExpirator_Facade
139
  }
140
 
141
  // not through bulk edit.
 
142
  if (isset($_POST['post_ids'])) {
143
  return;
144
  }
145
 
146
  // not through quick edit.
 
147
  if (isset($_POST['expirationdate_quickedit'])) {
148
  return;
149
  }
@@ -201,11 +215,6 @@ class PostExpirator_Facade
201
  $taxonomyName = $taxonomyNameNew;
202
  }
203
 
204
- $expireStatusNew = get_post_meta($id, '_expiration-date-status', true);
205
- if (! empty($expireStatusNew)) {
206
- $expireStatus = $expireStatusNew;
207
- }
208
-
209
  // _expiration-date-options is deprecated when using block editor
210
  $opts = get_post_meta($id, '_expiration-date-options', true);
211
  if (empty($expireType) && isset($opts['expireType'])) {
@@ -232,7 +241,7 @@ class PostExpirator_Facade
232
  */
233
  private function schedule_event($post_id, $ts, $opts)
234
  {
235
- postexpirator_schedule_event($post_id, $ts, $opts);
236
  }
237
 
238
  /**
@@ -334,7 +343,11 @@ class PostExpirator_Facade
334
  return;
335
  }
336
 
337
- $defaults = get_option('expirationdateDefaults' . ucfirst($post->post_type));
 
 
 
 
338
  // if settings are not configured, show the metabox by default only for posts and pages
339
  if (
340
  (! isset($defaults['activeMetaBox']) && in_array(
@@ -414,93 +427,29 @@ class PostExpirator_Facade
414
  * Returns true if the current user can expire posts.
415
  *
416
  * @return bool
 
417
  */
418
  public function current_user_can_expire_posts()
419
  {
420
- $current_user = wp_get_current_user();
 
421
 
422
- return is_a($current_user, WP_User::class)
423
- && $current_user->has_cap($this->capabilities['expire_post']);
 
424
  }
425
 
426
  /**
427
  * Calculates the default expiry date as set in the options.
 
 
428
  */
429
  public static function get_default_expiry($post_type)
430
  {
431
- $defaultmonth = date_i18n('m');
432
- $defaultday = date_i18n('d');
433
- $defaulthour = date_i18n('H');
434
- $defaultyear = date_i18n('Y');
435
- $defaultminute = date_i18n('i');
436
- $ts = time();
437
-
438
- $default_date_expiry = $custom_date = '';
439
- $general_date_expiry = $general_custom_date = '';
440
-
441
- // get the values from the general settings
442
- $general_date_expiry = get_option('expirationdateDefaultDate', POSTEXPIRATOR_EXPIREDEFAULT);
443
- if ('custom' === $general_date_expiry) {
444
- $custom = get_option('expirationdateDefaultDateCustom');
445
- if ($custom !== false) {
446
- $general_custom_date = $custom;
447
- }
448
- }
449
-
450
- // get the values from the post_type
451
- $defaults = get_option('expirationdateDefaults' . ucfirst($post_type));
452
-
453
- if (isset($defaults['default-expire-type'])) {
454
- $default_date_expiry = $defaults['default-expire-type'];
455
- switch ($default_date_expiry) {
456
- case 'custom':
457
- $custom_date = $defaults['default-custom-date'];
458
- break;
459
- case 'inherit':
460
- $custom_date = $general_custom_date;
461
- $default_date_expiry = $general_date_expiry;
462
- break;
463
- }
464
- } else {
465
- $default_date_expiry = $general_date_expiry;
466
- $custom_date = $general_custom_date;
467
- }
468
-
469
- if ('custom' === $default_date_expiry) {
470
- $custom = get_option('expirationdateDefaultDateCustom');
471
- if (! empty($custom_date)) {
472
- $tz = get_option('timezone_string');
473
- if ($tz) {
474
- // @TODO Using date_default_timezone_set() and similar isn't allowed, instead use WP internal timezone support.
475
- // phpcs:ignore WordPress.DateTime.RestrictedFunctions.timezone_change_date_default_timezone_set
476
- date_default_timezone_set($tz);
477
- }
478
-
479
- // strip the quotes in case the user provides them.
480
- $custom_date = str_replace('"', '', html_entity_decode($custom_date, ENT_QUOTES));
481
 
482
- $ts = time() + (strtotime($custom_date) - time());
483
- if ($tz) {
484
- // @TODO Using date_default_timezone_set() and similar isn't allowed, instead use WP internal timezone support.
485
- // phpcs:ignore WordPress.DateTime.RestrictedFunctions.timezone_change_date_default_timezone_set
486
- date_default_timezone_set('UTC');
487
- }
488
- }
489
- $defaultmonth = get_date_from_gmt(gmdate('Y-m-d H:i:s', $ts), 'm');
490
- $defaultday = get_date_from_gmt(gmdate('Y-m-d H:i:s', $ts), 'd');
491
- $defaultyear = get_date_from_gmt(gmdate('Y-m-d H:i:s', $ts), 'Y');
492
- $defaulthour = get_date_from_gmt(gmdate('Y-m-d H:i:s', $ts), 'H');
493
- $defaultminute = get_date_from_gmt(gmdate('Y-m-d H:i:s', $ts), 'i');
494
- }
495
-
496
- return array(
497
- 'month' => $defaultmonth,
498
- 'day' => $defaultday,
499
- 'year' => $defaultyear,
500
- 'hour' => $defaulthour,
501
- 'minute' => $defaultminute,
502
- 'ts' => $ts,
503
- );
504
  }
505
 
506
  /**
@@ -515,7 +464,7 @@ class PostExpirator_Facade
515
  return array_merge(
516
  $capabilities,
517
  array(
518
- 'PublishPress Future' => array(self::DEFAULT_CAPABILITY_EXPIRE_POST),
519
  )
520
  );
521
  }
1
  <?php
2
 
3
+ use PublishPressFuture\Core\DI\Container;
4
+ use PublishPressFuture\Core\DI\ServicesAbstract as Services;
5
+ use PublishPressFuture\Modules\Expirator\CapabilitiesAbstract as Capabilities;
6
+ use PublishPressFuture\Modules\Expirator\HooksAbstract;
7
+
8
  /**
9
  * The class that acts as a facade for the plugin's core functions.
10
  *
13
  class PostExpirator_Facade
14
  {
15
 
16
+ /**
17
+ * @deprecated 2.8.0 Use CapabilitiesAbstract::EXPIRE_POST;
18
+ */
19
+ const DEFAULT_CAPABILITY_EXPIRE_POST = Capabilities::EXPIRE_POST;
20
 
21
  /**
22
  * The singleton instance.
23
  */
24
  private static $instance = null;
25
+
26
  /**
27
  * List of capabilities used by the plugin.
28
  *
29
  * @var string[]
30
+ * @deprecated 2.8.0
31
  */
32
  private $capabilities = array(
33
+ 'expire_post' => Capabilities::EXPIRE_POST,
34
  );
35
 
36
  /**
70
  return false;
71
  }
72
 
73
+ return $user_role_instance->has_cap(Capabilities::EXPIRE_POST)
74
+ && $user_role_instance->capabilities[Capabilities::EXPIRE_POST] === true;
75
  }
76
 
77
  /**
85
  return;
86
  }
87
 
88
+ $admin_role->add_cap(Capabilities::EXPIRE_POST);
89
  }
90
 
91
  /**
125
 
126
  /**
127
  * Set the expire type, categories etc. corresponding to the new (gutenberg) structure.
128
+ *
129
+ * @deprecated 2.8.0
130
  */
131
  public static function set_expire_principles($id, $opts)
132
  {
151
  }
152
 
153
  // not through bulk edit.
154
+ // phpcs:ignore WordPress.Security.NonceVerification.Missing
155
  if (isset($_POST['post_ids'])) {
156
  return;
157
  }
158
 
159
  // not through quick edit.
160
+ // phpcs:ignore WordPress.Security.NonceVerification.Missing
161
  if (isset($_POST['expirationdate_quickedit'])) {
162
  return;
163
  }
215
  $taxonomyName = $taxonomyNameNew;
216
  }
217
 
 
 
 
 
 
218
  // _expiration-date-options is deprecated when using block editor
219
  $opts = get_post_meta($id, '_expiration-date-options', true);
220
  if (empty($expireType) && isset($opts['expireType'])) {
241
  */
242
  private function schedule_event($post_id, $ts, $opts)
243
  {
244
+ do_action(HooksAbstract::ACTION_SCHEDULE_POST_EXPIRATION, $post_id, $ts, $opts);
245
  }
246
 
247
  /**
343
  return;
344
  }
345
 
346
+ $container = \PublishPressFuture\Core\DI\Container::getInstance();
347
+ $settingsFacade = $container->get(\PublishPressFuture\Core\DI\ServicesAbstract::SETTINGS);
348
+
349
+ $defaults = $settingsFacade->getPostTypeDefaults($post->post_type);
350
+
351
  // if settings are not configured, show the metabox by default only for posts and pages
352
  if (
353
  (! isset($defaults['activeMetaBox']) && in_array(
427
  * Returns true if the current user can expire posts.
428
  *
429
  * @return bool
430
+ * @deprecated 2.8.0
431
  */
432
  public function current_user_can_expire_posts()
433
  {
434
+ $container = Container::getInstance();
435
+ $currentUserModelFactory = $container->get(Services::CURRENT_USER_MODEL_FACTORY);
436
 
437
+ $currentUserModel = $currentUserModelFactory();
438
+
439
+ return $currentUserModel->userCanExpirePosts();
440
  }
441
 
442
  /**
443
  * Calculates the default expiry date as set in the options.
444
+ *
445
+ * @deprecated 2.8.0
446
  */
447
  public static function get_default_expiry($post_type)
448
  {
449
+ $container = Container::getInstance();
450
+ $defaultDataModel = $container->get(Services::DEFAULT_DATA_MODEL);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
 
452
+ return $defaultDataModel->getDefaultExpirationDateForPostType($post_type);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
  }
454
 
455
  /**
464
  return array_merge(
465
  $capabilities,
466
  array(
467
+ 'PublishPress Future' => [Capabilities::EXPIRE_POST],
468
  )
469
  );
470
  }
{classes → legacy/classes}/Reviews.class.php RENAMED
@@ -35,8 +35,8 @@ abstract class PostExpirator_Reviews
35
  return false;
36
  }
37
 
38
- if ($pagenow === 'admin.php' && isset($_GET['page'])) {
39
- if ($_GET['page'] === 'publishpress-future') {
40
  return true;
41
  }
42
  }
35
  return false;
36
  }
37
 
38
+ if ($pagenow === 'admin.php' && isset($_GET['page'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
39
+ if ($_GET['page'] === 'publishpress-future') { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
40
  return true;
41
  }
42
  }
{classes → legacy/classes}/Util.class.php RENAMED
@@ -70,6 +70,9 @@ class PostExpirator_Util
70
  return $timezone->getOffset(new DateTime());
71
  }
72
 
 
 
 
73
  public static function get_wp_date($format, $timestamp)
74
  {
75
  $gmtTime = gmdate('Y-m-d H:i:s', $timestamp);
70
  return $timezone->getOffset(new DateTime());
71
  }
72
 
73
+ /**
74
+ * @deprecated 2.8.0 Use PublishPressFuture/Core/Helper/Date::getWpDate instead
75
+ */
76
  public static function get_wp_date($format, $timestamp)
77
  {
78
  $gmtTime = gmdate('Y-m-d H:i:s', $timestamp);
legacy/debug.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Psr\Container\ContainerExceptionInterface;
4
+ use Psr\Container\NotFoundExceptionInterface;
5
+ use PublishPressFuture\Core\DI\Container;
6
+ use PublishPressFuture\Core\DI\ContainerNotInitializedException;
7
+ use PublishPressFuture\Core\DI\ServicesAbstract as Services;
8
+ use PublishPressFuture\Modules\Debug\DebugInterface;
9
+
10
+ /**
11
+ * The class that adds debug entries to the database.
12
+ *
13
+ * @deprecated 2.8.0
14
+ */
15
+ class PostExpiratorDebug
16
+ {
17
+ /**
18
+ * @var DebugInterface
19
+ */
20
+ private $debug;
21
+
22
+ /**
23
+ * Constructor.
24
+ * @throws ContainerNotInitializedException
25
+ * @throws NotFoundExceptionInterface
26
+ * @throws ContainerExceptionInterface
27
+ */
28
+ public function __construct()
29
+ {
30
+ $this->debug = Container::getInstance()->get(Services::DEBUG);
31
+ }
32
+
33
+ /**
34
+ * Drop Database Table.
35
+ */
36
+ public function removeDBTable()
37
+ {
38
+ $this->debug->dropDatabaseTable();
39
+ }
40
+
41
+ /**
42
+ * Insert into Database Table.
43
+ */
44
+ public function save($data)
45
+ {
46
+ $this->debug->log($data['message']);
47
+ }
48
+
49
+ /**
50
+ * Get the HTML of the table's data.
51
+ */
52
+ public function getTable()
53
+ {
54
+ return $this->debug->fetchAll();
55
+ }
56
+
57
+ /**
58
+ * Truncate Database Table.
59
+ */
60
+ public function purge()
61
+ {
62
+ $this->debug->deleteLogs();
63
+ }
64
+ }
legacy/defines.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use PublishPressFuture\Core\DI\ServicesAbstract;
4
+
5
+ $defaultData = $container->get(ServicesAbstract::DEFAULT_DATA);
6
+
7
+ /**
8
+ * @deprecated 2.8.0
9
+ */
10
+ define('POSTEXPIRATOR_VERSION', $container->get(ServicesAbstract::PLUGIN_VERSION));
11
+
12
+ /**
13
+ * @deprecated 2.8.0
14
+ */
15
+ define('POSTEXPIRATOR_DATEFORMAT', $defaultData[ServicesAbstract::DEFAULT_DATE_FORMAT]);
16
+
17
+ /**
18
+ * @deprecated 2.8.0
19
+ */
20
+ define('POSTEXPIRATOR_TIMEFORMAT', $defaultData[ServicesAbstract::DEFAULT_TIME_FORMAT]);
21
+
22
+ /**
23
+ * @deprecated 2.8.0
24
+ */
25
+ define('POSTEXPIRATOR_FOOTERCONTENTS', $defaultData[ServicesAbstract::DEFAULT_FOOTER_CONTENT]);
26
+
27
+ /**
28
+ * @deprecated 2.8.0
29
+ */
30
+ define('POSTEXPIRATOR_FOOTERSTYLE', $defaultData[ServicesAbstract::DEFAULT_FOOTER_STYLE]);
31
+
32
+ /**
33
+ * @deprecated 2.8.0
34
+ */
35
+ define('POSTEXPIRATOR_FOOTERDISPLAY', $defaultData[ServicesAbstract::DEFAULT_FOOTER_DISPLAY]);
36
+
37
+ /**
38
+ * @deprecated 2.8.0
39
+ */
40
+ define('POSTEXPIRATOR_EMAILNOTIFICATION', $defaultData[ServicesAbstract::DEFAULT_EMAIL_NOTIFICATION]);
41
+
42
+ /**
43
+ * @deprecated 2.8.0
44
+ */
45
+ define('POSTEXPIRATOR_EMAILNOTIFICATIONADMINS', $defaultData[ServicesAbstract::DEFAULT_EMAIL_NOTIFICATION_ADMINS]);
46
+
47
+ /**
48
+ * @deprecated 2.8.0
49
+ */
50
+ define('POSTEXPIRATOR_DEBUGDEFAULT', $defaultData[ServicesAbstract::DEFAULT_DEBUG]);
51
+
52
+ /**
53
+ * @deprecated 2.8.0
54
+ */
55
+ define('POSTEXPIRATOR_EXPIREDEFAULT', $defaultData[ServicesAbstract::DEFAULT_EXPIRATION_DATE]);
56
+
57
+ /**
58
+ * @deprecated 2.8.0
59
+ */
60
+ define('POSTEXPIRATOR_SLUG', $container->get(ServicesAbstract::PLUGIN_SLUG));
61
+
62
+ /**
63
+ * @deprecated 2.8.0
64
+ */
65
+ define('POSTEXPIRATOR_BASEDIR', $container->get(ServicesAbstract::BASE_PATH));
66
+
67
+ /**
68
+ * @deprecated 2.8.0
69
+ */
70
+ define('POSTEXPIRATOR_BASENAME', basename($pluginFile));
71
+
72
+ /**
73
+ * @deprecated 2.8.0
74
+ */
75
+ define('POSTEXPIRATOR_BASEURL', $container->get(ServicesAbstract::BASE_URL));
76
+
77
+ /**
78
+ * @deprecated 2.8.0
79
+ */
80
+ define('POSTEXPIRATOR_LOADED', true);
81
+
82
+ /**
83
+ * @deprecated 2.8.0
84
+ */
85
+ define('POSTEXPIRATOR_LEGACYDIR', POSTEXPIRATOR_BASEDIR . '/legacy');
legacy/deprecated-functions.php ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use PublishPressFuture\Modules\Expirator\HooksAbstract as ExpiratorHooks;
4
+
5
+ if (! function_exists('_scheduleExpiratorEvent')) {
6
+ /**
7
+ * Schedules the single event.
8
+ *
9
+ * @deprecated 2.4.3
10
+ */
11
+ function _scheduleExpiratorEvent($id, $ts, $opts)
12
+ {
13
+ _deprecated_function(__FUNCTION__, '2.4.3', 'postexpirator_schedule_event');
14
+ postexpirator_schedule_event($id, $ts, $opts);
15
+ }
16
+ }
17
+
18
+
19
+ if (! function_exists('_unscheduleExpiratorEvent')) {
20
+ /**
21
+ * Unschedules the single event.
22
+ *
23
+ * @deprecated 2.4.3
24
+ */
25
+ function _unscheduleExpiratorEvent($id)
26
+ {
27
+ _deprecated_function(__FUNCTION__, '2.4.3', 'postexpirator_unschedule_event');
28
+ postexpirator_unschedule_event($id);
29
+ }
30
+ }
31
+
32
+
33
+ if (! function_exists('postExpiratorExpire')) {
34
+ /**
35
+ * Expires the post.
36
+ *
37
+ * @deprecated 2.4.3
38
+ */
39
+ function postExpiratorExpire($id)
40
+ {
41
+ _deprecated_function(__FUNCTION__, '2.4.3', 'postexpirator_expire_post');
42
+ postexpirator_expire_post($id);
43
+ }
44
+ }
45
+
46
+
47
+ if (! function_exists('_postExpiratorExpireType')) {
48
+ /**
49
+ * Get the HTML for expire type.
50
+ *
51
+ * @deprecated 2.5.0
52
+ */
53
+ function _postExpiratorExpireType($opts)
54
+ {
55
+ _deprecated_function(__FUNCTION__, '2.5.0', '_postexpirator_expire_type');
56
+
57
+ ob_start();
58
+ _postexpirator_expire_type($opts);
59
+
60
+ return ob_get_clean();
61
+ }
62
+ }
63
+
64
+ if (! function_exists('expirationdate_get_blog_url')) {
65
+ /**
66
+ * Get correct URL (HTTP or HTTPS)
67
+ *
68
+ * @internal
69
+ * @access private
70
+ *
71
+ * @deprecated 2.7.1
72
+ */
73
+ function expirationdate_get_blog_url()
74
+ {
75
+ _deprecated_function(__FUNCTION__, '2.7.1');
76
+
77
+ if (is_multisite()) {
78
+ $url = network_home_url('/');
79
+ } else {
80
+ $url = home_url('/');
81
+ }
82
+
83
+ echo esc_url($url);
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Schedules the single event.
89
+ *
90
+ * @deprecated 2.8.0
91
+ * @internal
92
+ *
93
+ * @access private
94
+ */
95
+ function postexpirator_schedule_event($postId, $timestamp, $opts)
96
+ {
97
+ _deprecated_function(__FUNCTION__, '2.8.0');
98
+
99
+ do_action(ExpiratorHooks::ACTION_SCHEDULE_POST_EXPIRATION, $postId, $timestamp, $opts);
100
+ }
101
+
102
+ /**
103
+ * Unschedules the single event.
104
+ *
105
+ * @internal
106
+ *
107
+ * @access private
108
+ * @deprecated 2.8.0
109
+ */
110
+ function postexpirator_unschedule_event($postId)
111
+ {
112
+ _deprecated_function(__FUNCTION__, '2.8.0');
113
+
114
+ do_action(ExpiratorHooks::ACTION_UNSCHEDULE_POST_EXPIRATION, $postId);
115
+ }
116
+
117
+
118
+ /**
119
+ * Show the menu.
120
+ *
121
+ * @internal
122
+ *
123
+ * @access private
124
+ * @deprecated 2.5.0
125
+ */
126
+ function postexpirator_menu()
127
+ {
128
+ _deprecated_function(__FUNCTION__, '2.5.0');
129
+ }
130
+
131
+ /**
132
+ * Hook's to add plugin page menu
133
+ *
134
+ * @internal
135
+ *
136
+ * @access private
137
+ * @deprecated 2.5.0
138
+ */
139
+ function postexpirator_add_menu()
140
+ {
141
+ _deprecated_function(__FUNCTION__, '2.5.0');
142
+ }
143
+
144
+ /**
145
+ * Show the Expiration Date options page
146
+ *
147
+ * @internal
148
+ *
149
+ * @access private
150
+ * @deprecated 2.5.0
151
+ */
152
+ function postexpirator_menu_general()
153
+ {
154
+ _deprecated_function(__FUNCTION__, '2.5.0');
155
+ PostExpirator_Display::getInstance()->load_tab('general');
156
+ }
157
+
158
+ /**
159
+ * The default menu.
160
+ *
161
+ * @internal
162
+ *
163
+ * @access private
164
+ * @deprecated 2.5.0
165
+ */
166
+ function postexpirator_menu_defaults()
167
+ {
168
+ _deprecated_function(__FUNCTION__, '2.5.0');
169
+ PostExpirator_Display::getInstance()->load_tab('defaults');
170
+ }
171
+
172
+ /**
173
+ * Diagnostics menu.
174
+ *
175
+ * @internal
176
+ *
177
+ * @access private
178
+ * @deprecated 2.5.0
179
+ */
180
+ function postexpirator_menu_diagnostics()
181
+ {
182
+ _deprecated_function(__FUNCTION__, '2.5.0');
183
+ PostExpirator_Display::getInstance()->load_tab('diagnostics');
184
+ }
185
+
186
+ /**
187
+ * Debug menu.
188
+ *
189
+ * @internal
190
+ *
191
+ * @access private
192
+ * @deprecated 2.5.0
193
+ */
194
+ function postexpirator_menu_debug()
195
+ {
196
+ _deprecated_function(__FUNCTION__, '2.5.0');
197
+ PostExpirator_Display::getInstance()->load_tab('viewdebug');
198
+ }
199
+
200
+ /**
201
+ * Check for Debug
202
+ *
203
+ * @internal
204
+ *
205
+ * @access private
206
+ * @deprecated 2.8.0
207
+ */
208
+ function postexpirator_debug()
209
+ {
210
+ _deprecated_function(__FUNCTION__, '2.8.0');
211
+
212
+ $debug = get_option('expirationdateDebug');
213
+
214
+ // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
215
+ if ($debug == 1) {
216
+ if (! defined('POSTEXPIRATOR_DEBUG')) {
217
+ define('POSTEXPIRATOR_DEBUG', 1);
218
+ }
219
+
220
+ require_once POSTEXPIRATOR_LEGACYDIR . '/debug.php';
221
+
222
+ return new PostExpiratorDebug();
223
+ } else {
224
+ if (! defined('POSTEXPIRATOR_DEBUG')) {
225
+ /**
226
+ * @deprecated
227
+ */
228
+ define('POSTEXPIRATOR_DEBUG', 0);
229
+ }
230
+
231
+ return false;
232
+ }
233
+ }
234
+
235
+ /**
236
+ * Internal method to get category names corresponding to the category IDs.
237
+ *
238
+ * @internal
239
+ *
240
+ * @access private
241
+ * @deprecated 2.8.0
242
+ */
243
+ function _postexpirator_get_cat_names($cats)
244
+ {
245
+ _deprecated_function(__FUNCTION__, '2.8.0');
246
+
247
+ $out = array();
248
+ foreach ($cats as $cat) {
249
+ $out[$cat] = get_the_category_by_id($cat);
250
+ }
251
+
252
+ return $out;
253
+ }
254
+
255
+ /**
256
+ * @param $id
257
+ * @param $log
258
+ * @return void
259
+ * @deprecated 2.8.0
260
+ */
261
+ function postexpirator_register_expiration_meta($id, $log)
262
+ {
263
+ _deprecated_function(__FUNCTION__, '2.8.0');
264
+
265
+ $log['expired_on'] = date('Y-m-d H:i:s');
266
+
267
+ add_post_meta($id, 'expiration_log', wp_json_encode($log));
268
+ }
269
+
270
+ /**
271
+ * The new expiration function, to work with single scheduled events.
272
+ *
273
+ * This was designed to hopefully be more flexible for future tweaks/modifications to the architecture.
274
+ *
275
+ * @internal
276
+ *
277
+ * @access private
278
+ * @deprecated 2.8.0
279
+ */
280
+ function postexpirator_expire_post($postId)
281
+ {
282
+ _deprecated_function(__FUNCTION__, '2.8.0');
283
+
284
+ do_action(
285
+ ExpiratorHooks::ACTION_EXPIRE_POST,
286
+ $postId
287
+ );
288
+ }
legacy/functions.php ADDED
@@ -0,0 +1,1331 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * This file provides access to all legacy functions that are now deprecated.
5
+ */
6
+
7
+ use PublishPressFuture\Core\DI\Container;
8
+ use PublishPressFuture\Core\DI\ServicesAbstract;
9
+ use PublishPressFuture\Core\HooksAbstract as CoreHooks;
10
+ use PublishPressFuture\Modules\Debug\HooksAbstract as DebugHooks;
11
+ use PublishPressFuture\Modules\Expirator\HooksAbstract as ExpiratorHooks;
12
+
13
+ /**
14
+ * Adds links to the plugin listing screen.
15
+ *
16
+ * @internal
17
+ *
18
+ * @access private
19
+ */
20
+ function postexpirator_plugin_action_links($links, $file)
21
+ {
22
+ $this_plugin = basename(plugin_dir_url(__FILE__)) . '/post-expirator.php';
23
+ if ($file === $this_plugin) {
24
+ $links[] = '<a href="admin.php?page=publishpress-future">' . __('Settings', 'post-expirator') . '</a>';
25
+ }
26
+
27
+ return $links;
28
+ }
29
+
30
+ add_filter('plugin_action_links', 'postexpirator_plugin_action_links', 10, 2);
31
+
32
+ /**
33
+ * Load translation, if it exists.
34
+ *
35
+ * @internal
36
+ *
37
+ * @access private
38
+ */
39
+ function postexpirator_init()
40
+ {
41
+ $plugin_dir = plugin_basename(__DIR__);
42
+ load_plugin_textdomain('post-expirator', null, $plugin_dir . '/languages/');
43
+
44
+ PostExpirator_Reviews::init();
45
+
46
+ if (class_exists('WP_CLI')) {
47
+ PostExpirator_Cli::getInstance();
48
+ }
49
+
50
+ add_action('wp_insert_post', 'postexpirator_set_default_meta_for_post', 10, 3);
51
+ }
52
+
53
+ add_action('plugins_loaded', 'postexpirator_init');
54
+
55
+ /**
56
+ * Adds an 'Expires' column to the post display table.
57
+ *
58
+ * @internal
59
+ *
60
+ * @access private
61
+ */
62
+ function postexpirator_add_column($columns, $type)
63
+ {
64
+ $container = Container::getInstance();
65
+ $settingsFacade = $container->get(ServicesAbstract::SETTINGS);
66
+
67
+ $defaults = $settingsFacade->getPostTypeDefaults($type);
68
+
69
+ // if settings are not configured, show the metabox by default only for posts and pages
70
+ if ((! isset($defaults['activeMetaBox']) && in_array($type, array(
71
+ 'post',
72
+ 'page'
73
+ ), true)) || (is_array(
74
+ $defaults
75
+ ) && $defaults['activeMetaBox'] === 'active')) {
76
+ $columns['expirationdate'] = __('Expires', 'post-expirator');
77
+ }
78
+
79
+ return $columns;
80
+ }
81
+
82
+ add_filter('manage_posts_columns', 'postexpirator_add_column', 10, 2);
83
+
84
+ /**
85
+ * Adds sortable columns.
86
+ *
87
+ * @internal
88
+ *
89
+ * @access private
90
+ */
91
+ function postexpirator_manage_sortable_columns()
92
+ {
93
+ $post_types = postexpirator_get_post_types();
94
+ foreach ($post_types as $post_type) {
95
+ add_filter('manage_edit-' . $post_type . '_sortable_columns', 'postexpirator_sortable_column');
96
+ }
97
+ }
98
+
99
+ add_action('admin_init', 'postexpirator_manage_sortable_columns', 100);
100
+
101
+ /**
102
+ * Adds an 'Expires' column to the post display table.
103
+ *
104
+ * @internal
105
+ *
106
+ * @access private
107
+ */
108
+ function postexpirator_sortable_column($columns)
109
+ {
110
+ $columns['expirationdate'] = 'expirationdate';
111
+
112
+ return $columns;
113
+ }
114
+
115
+ /**
116
+ * Modify the sorting of posts.
117
+ *
118
+ * @internal
119
+ *
120
+ * @access private
121
+ */
122
+ function postexpirator_orderby($query)
123
+ {
124
+ if (! is_admin()) {
125
+ return;
126
+ }
127
+
128
+ $orderBy = $query->get('orderby');
129
+
130
+ if ('expirationdate' === $orderBy && $query->is_main_query()) {
131
+ $query->set(
132
+ 'meta_query', array(
133
+ 'relation' => 'OR',
134
+ array(
135
+ 'key' => '_expiration-date',
136
+ 'compare' => 'EXISTS',
137
+ ),
138
+ array(
139
+ 'key' => '_expiration-date',
140
+ 'compare' => 'NOT EXISTS',
141
+ 'value' => '',
142
+ ),
143
+ )
144
+ );
145
+ $query->set('orderby', 'meta_value_num');
146
+ }
147
+ }
148
+
149
+ add_action('pre_get_posts', 'postexpirator_orderby');
150
+
151
+ /**
152
+ * Adds an 'Expires' column to the page display table.
153
+ *
154
+ * @internal
155
+ *
156
+ * @access private
157
+ */
158
+ function postexpirator_add_column_page($columns)
159
+ {
160
+ $container = Container::getInstance();
161
+ $settingsFacade = $container->get(ServicesAbstract::SETTINGS);
162
+
163
+ $defaults = $settingsFacade->getPostTypeDefaults('page');
164
+
165
+ if (! isset($defaults['activeMetaBox']) || $defaults['activeMetaBox'] === 'active') {
166
+ $columns['expirationdate'] = __('Expires', 'post-expirator');
167
+ }
168
+
169
+ return $columns;
170
+ }
171
+
172
+ add_filter('manage_pages_columns', 'postexpirator_add_column_page');
173
+
174
+ /**
175
+ * Fills the 'Expires' column of the post display table.
176
+ *
177
+ * @internal
178
+ *
179
+ * @access private
180
+ */
181
+ function postexpirator_show_value($column_name)
182
+ {
183
+ if ($column_name !== 'expirationdate') {
184
+ return;
185
+ }
186
+
187
+ global $post;
188
+
189
+ // get the attributes that quick edit functionality requires
190
+ // and save it as a JSON encoded HTML attribute
191
+ $attributes = PostExpirator_Facade::get_expire_principles($post->ID);
192
+ PostExpirator_Display::getInstance()->render_template('expire-column', array(
193
+ 'id' => $post->ID,
194
+ 'post_type' => $post->post_type,
195
+ 'attributes' => $attributes
196
+ ));
197
+ }
198
+
199
+ add_action('manage_posts_custom_column', 'postexpirator_show_value');
200
+ add_action('manage_pages_custom_column', 'postexpirator_show_value');
201
+
202
+
203
+ /**
204
+ * Quick Edit functionality.
205
+ *
206
+ * @internal
207
+ *
208
+ * @access private
209
+ */
210
+ function postexpirator_quickedit($column_name, $post_type)
211
+ {
212
+ if ($column_name !== 'expirationdate') {
213
+ return;
214
+ }
215
+
216
+ $facade = PostExpirator_Facade::getInstance();
217
+
218
+ if (! $facade->current_user_can_expire_posts()) {
219
+ return;
220
+ }
221
+
222
+ $container = Container::getInstance();
223
+ $settingsFacade = $container->get(ServicesAbstract::SETTINGS);
224
+
225
+ $defaults = $settingsFacade->getPostTypeDefaults($post_type);
226
+ $taxonomy = isset($defaults['taxonomy']) ? $defaults['taxonomy'] : '';
227
+ $label = '';
228
+
229
+ // if settings have not been configured and this is the default post type
230
+ if (empty($taxonomy) && 'post' === $post_type) {
231
+ $taxonomy = 'category';
232
+ }
233
+
234
+ if (! empty($taxonomy)) {
235
+ $tax_object = get_taxonomy($taxonomy);
236
+ $label = $tax_object ? $tax_object->label : '';
237
+ }
238
+
239
+ PostExpirator_Display::getInstance()->render_template('quick-edit', array(
240
+ 'post_type' => $post_type,
241
+ 'taxonomy' => $taxonomy,
242
+ 'tax_label' => $label
243
+ ));
244
+ }
245
+
246
+ add_action('quick_edit_custom_box', 'postexpirator_quickedit', 10, 2);
247
+
248
+ /**
249
+ * Bulk Edit functionality.
250
+ *
251
+ * @internal
252
+ *
253
+ * @access private
254
+ */
255
+ function postexpirator_bulkedit($column_name, $post_type)
256
+ {
257
+ if ($column_name !== 'expirationdate') {
258
+ return;
259
+ }
260
+
261
+ $facade = PostExpirator_Facade::getInstance();
262
+
263
+ if (! $facade->current_user_can_expire_posts()) {
264
+ return;
265
+ }
266
+
267
+ $container = Container::getInstance();
268
+ $settingsFacade = $container->get(ServicesAbstract::SETTINGS);
269
+
270
+ $defaults = $settingsFacade->getPostTypeDefaults($post_type);
271
+
272
+ $taxonomy = isset($defaults['taxonomy']) ? $defaults['taxonomy'] : '';
273
+ $label = '';
274
+
275
+ // if settings have not been configured and this is the default post type
276
+ if (empty($taxonomy) && 'post' === $post_type) {
277
+ $taxonomy = 'category';
278
+ }
279
+
280
+ if (! empty($taxonomy)) {
281
+ $tax_object = get_taxonomy($taxonomy);
282
+ $label = $tax_object ? $tax_object->label : '';
283
+ }
284
+
285
+ PostExpirator_Display::getInstance()->render_template('bulk-edit', array(
286
+ 'post_type' => $post_type,
287
+ 'taxonomy' => $taxonomy,
288
+ 'tax_label' => $label
289
+ ));
290
+ }
291
+
292
+ add_action('bulk_edit_custom_box', 'postexpirator_bulkedit', 10, 2);
293
+
294
+ /**
295
+ * Returns the post types that are supported.
296
+ *
297
+ * @internal
298
+ *
299
+ * @access private
300
+ */
301
+ function postexpirator_get_post_types()
302
+ {
303
+ $post_types = get_post_types(array('public' => true));
304
+ $post_types = array_merge(
305
+ $post_types,
306
+ get_post_types(array(
307
+ 'public' => false,
308
+ 'show_ui' => true,
309
+ '_builtin' => false
310
+ ))
311
+ );
312
+
313
+ // in case some post types should not be supported.
314
+ $unset_post_types = apply_filters('postexpirator_unset_post_types', array('attachment'));
315
+ if ($unset_post_types) {
316
+ foreach ($unset_post_types as $type) {
317
+ unset($post_types[$type]);
318
+ }
319
+ }
320
+
321
+ return $post_types;
322
+ }
323
+
324
+ /**
325
+ * Adds hooks to get the meta box added to pages and custom post types
326
+ *
327
+ * @internal
328
+ *
329
+ * @access private
330
+ */
331
+ function postexpirator_meta_custom()
332
+ {
333
+ $facade = PostExpirator_Facade::getInstance();
334
+
335
+ if (! $facade->current_user_can_expire_posts()) {
336
+ return;
337
+ }
338
+
339
+ $container = Container::getInstance();
340
+ $settingsFacade = $container->get(ServicesAbstract::SETTINGS);
341
+
342
+ $post_types = postexpirator_get_post_types();
343
+ foreach ($post_types as $type) {
344
+ $defaults = $settingsFacade->getPostTypeDefaults($type);
345
+
346
+ // if settings are not configured, show the metabox by default only for posts and pages
347
+ if ((! isset($defaults['activeMetaBox']) && in_array($type, array(
348
+ 'post',
349
+ 'page'
350
+ ), true)) || (is_array(
351
+ $defaults
352
+ ) && $defaults['activeMetaBox'] === 'active')) {
353
+ add_meta_box(
354
+ 'expirationdatediv',
355
+ __('PublishPress Future', 'post-expirator'),
356
+ 'postexpirator_meta_box',
357
+ $type,
358
+ 'side',
359
+ 'core',
360
+ array('__back_compat_meta_box' => PostExpirator_Facade::show_gutenberg_metabox())
361
+ );
362
+ }
363
+ }
364
+ }
365
+
366
+ add_action('add_meta_boxes', 'postexpirator_meta_custom');
367
+
368
+ /**
369
+ * Actually adds the meta box
370
+ *
371
+ * @internal
372
+ *
373
+ * @access private
374
+ */
375
+ function postexpirator_meta_box($post)
376
+ {
377
+ $postMetaDate = get_post_meta($post->ID, '_expiration-date', true);
378
+ $postMetaStatus = get_post_meta($post->ID, '_expiration-date-status', true);
379
+
380
+ $expireType = $default = $enabled = '';
381
+
382
+ $container = Container::getInstance();
383
+ $settingsFacade = $container->get(ServicesAbstract::SETTINGS);
384
+
385
+ $defaultsOption = $settingsFacade->getPostTypeDefaults($post->post_type);
386
+
387
+ if (empty($postMetaDate)) {
388
+ $defaultExpire = PostExpirator_Facade::get_default_expiry($post->post_type);
389
+
390
+ $defaultMonth = $defaultExpire['month'];
391
+ $defaultDay = $defaultExpire['day'];
392
+ $defaultHour = $defaultExpire['hour'];
393
+ $defaultYear = $defaultExpire['year'];
394
+ $defaultMinute = $defaultExpire['minute'];
395
+
396
+ $categories = get_option('expirationdateCategoryDefaults');
397
+
398
+ if (isset($defaultsOption['expireType'])) {
399
+ $expireType = $defaultsOption['expireType'];
400
+ }
401
+ } else {
402
+ $defaultMonth = get_date_from_gmt(gmdate('Y-m-d H:i:s', $postMetaDate), 'm');
403
+ $defaultDay = get_date_from_gmt(gmdate('Y-m-d H:i:s', $postMetaDate), 'd');
404
+ $defaultYear = get_date_from_gmt(gmdate('Y-m-d H:i:s', $postMetaDate), 'Y');
405
+ $defaultHour = get_date_from_gmt(gmdate('Y-m-d H:i:s', $postMetaDate), 'H');
406
+ $defaultMinute = get_date_from_gmt(gmdate('Y-m-d H:i:s', $postMetaDate), 'i');
407
+
408
+ $attributes = PostExpirator_Facade::get_expire_principles($post->ID);
409
+ $expireType = $attributes['expireType'];
410
+ $categories = $attributes['category'];
411
+ }
412
+
413
+ if (PostExpirator_Facade::is_expiration_enabled_for_post($post->ID)) {
414
+ $enabled = ' checked="checked"';
415
+ }
416
+
417
+ PostExpirator_Display::getInstance()->render_template(
418
+ 'classic-metabox', [
419
+ 'post' => $post,
420
+ 'enabled' => $enabled,
421
+ 'default' => $default,
422
+ 'defaultsOption' => $defaultsOption,
423
+ 'defaultmonth' => $defaultMonth,
424
+ 'defaultday' => $defaultDay,
425
+ 'defaulthour' => $defaultHour,
426
+ 'defaultyear' => $defaultYear,
427
+ 'defaultminute' => $defaultMinute,
428
+ 'categories' => $categories,
429
+ 'expireType' => $expireType,
430
+ ]
431
+ );
432
+ }
433
+
434
+ function postexpirator_set_default_meta_for_post($postId, $post, $update)
435
+ {
436
+ if ($update) {
437
+ return;
438
+ }
439
+
440
+ $container = Container::getInstance();
441
+ $settingsFacade = $container->get(ServicesAbstract::SETTINGS);
442
+
443
+ $postTypeDefaults = $settingsFacade->getPostTypeDefaults($post->post_type);
444
+
445
+ if (empty($postTypeDefaults) || (int)$postTypeDefaults['autoEnable'] !== 1) {
446
+ return;
447
+ }
448
+
449
+ $defaultExpire = PostExpirator_Facade::get_default_expiry($post->post_type);
450
+
451
+ $categories = get_option('expirationdateCategoryDefaults');
452
+
453
+ $status = ! empty($defaultExpire['ts']) ? 'saved' : '';
454
+
455
+ $opts = [
456
+ 'expireType' => $postTypeDefaults['expireType'],
457
+ 'category' => $categories,
458
+ 'categoryTaxonomy' => (string)$postTypeDefaults['taxonomy'],
459
+ 'enabled' => $status === 'saved',
460
+ ];
461
+
462
+ update_post_meta($post->ID, '_expiration-date', $defaultExpire['ts']);
463
+ update_post_meta($post->ID, '_expiration-date-status', $status);
464
+ update_post_meta($post->ID, '_expiration-date-options', $opts);
465
+ update_post_meta($post->ID, '_expiration-date-type', $postTypeDefaults['expireType']);
466
+ update_post_meta($post->ID, '_expiration-date-categories', (array)$categories);
467
+ update_post_meta($post->ID, '_expiration-date-taxonomy', $opts['categoryTaxonomy']);
468
+ }
469
+
470
+ /**
471
+ * Add's ajax javascript.
472
+ *
473
+ * @internal
474
+ *
475
+ * @access private
476
+ */
477
+ function postexpirator_js_admin_header()
478
+ {
479
+ $facade = PostExpirator_Facade::getInstance();
480
+
481
+ if (! $facade->current_user_can_expire_posts()) {
482
+ return;
483
+ }
484
+ ?>
485
+ <script type="text/javascript">
486
+ //<![CDATA[
487
+ (function ($) {
488
+ $(document).ready(function () {
489
+ init();
490
+ });
491
+
492
+ function init() {
493
+ $('#enable-expirationdate').on('click', function (e) {
494
+ if ($(this).is(':checked')) {
495
+ $('.pe-classic-fields').show();
496
+ } else {
497
+ $('.pe-classic-fields').hide();
498
+ }
499
+ });
500
+
501
+ $('.pe-howtoexpire').on('change', function (e) {
502
+ if ($(this).val().indexOf('category') !== -1) {
503
+ $('#expired-category-selection').show();
504
+ } else {
505
+ $('#expired-category-selection').hide();
506
+ }
507
+ });
508
+ }
509
+ })(jQuery);
510
+ //]]>
511
+ </script>
512
+ <?php
513
+ }
514
+
515
+ add_action('admin_head', 'postexpirator_js_admin_header');
516
+
517
+ /**
518
+ * Called when post is saved - stores expiration-date meta value
519
+ *
520
+ * @internal
521
+ *
522
+ * @access private
523
+ */
524
+ function postexpirator_update_post_meta($id)
525
+ {
526
+ // don't run the echo if this is an auto save
527
+ if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
528
+ return;
529
+ }
530
+
531
+ // don't run the echo if the function is called for saving revision.
532
+ $posttype = get_post_type((int)$id);
533
+ if ($posttype === 'revision') {
534
+ return;
535
+ }
536
+
537
+ // Do not process Bulk edit here. It is processed on the function "postexpirator_date_save_bulk_edit"
538
+ if (isset($_GET['postexpirator_view']) && $_GET['postexpirator_view'] === 'bulk-edit') {
539
+ return;
540
+ }
541
+
542
+ $facade = PostExpirator_Facade::getInstance();
543
+
544
+ if (! $facade->current_user_can_expire_posts()) {
545
+ return;
546
+ }
547
+
548
+ $container = Container::getInstance();
549
+ $settingsFacade = $container->get(ServicesAbstract::SETTINGS);
550
+
551
+ $postTypeDefaults = $settingsFacade->getPostTypeDefaults($posttype);
552
+
553
+ $shouldSchedule = false;
554
+ $ts = null;
555
+ $opts = [];
556
+
557
+ if (isset($_POST['postexpirator_view'])) {
558
+ if (defined('DOING_AJAX') && DOING_AJAX) {
559
+ check_ajax_referer('__postexpirator', '_postexpiratornonce');
560
+ } else {
561
+ check_admin_referer('__postexpirator', '_postexpiratornonce');
562
+ }
563
+
564
+ // Classic editor, quick edit
565
+ $shouldSchedule = isset($_POST['enable-expirationdate']);
566
+
567
+ $default = get_option('expirationdateDefaultDate', POSTEXPIRATOR_EXPIREDEFAULT);
568
+ if ($default === 'publish') {
569
+ if (! isset($_POST['mm'])
570
+ || ! isset($_POST['jj'])
571
+ || ! isset($_POST['aa'])
572
+ || ! isset($_POST['hh'])
573
+ || ! isset($_POST['mn'])
574
+ ) {
575
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
576
+ error_log('PUBLISHPRESS FUTURE: Missing expiration date on POST');
577
+ }
578
+
579
+ $month = intval($_POST['mm']);
580
+ $day = intval($_POST['jj']);
581
+ $year = intval($_POST['aa']);
582
+ $hour = intval($_POST['hh']);
583
+ $minute = intval($_POST['mn']);
584
+ } else {
585
+ if (! isset($_POST['expirationdate_month'])
586
+ || ! isset($_POST['expirationdate_day'])
587
+ || ! isset($_POST['expirationdate_year'])
588
+ || ! isset($_POST['expirationdate_hour'])
589
+ || ! isset($_POST['expirationdate_minute'])
590
+ ) {
591
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
592
+ error_log('PUBLISHPRESS FUTURE: Missing expiration date on POST');
593
+ }
594
+
595
+ $month = intval($_POST['expirationdate_month']);
596
+ $day = intval($_POST['expirationdate_day']);
597
+ $year = intval($_POST['expirationdate_year']);
598
+ $hour = intval($_POST['expirationdate_hour']);
599
+ $minute = intval($_POST['expirationdate_minute']);
600
+
601
+ if (empty($day)) {
602
+ $day = date('d');
603
+ }
604
+ if (empty($year)) {
605
+ $year = date('Y');
606
+ }
607
+ }
608
+ $category = isset($_POST['expirationdate_category'])
609
+ ? PostExpirator_Util::sanitize_array_of_integers(
610
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
611
+ $_POST['expirationdate_category']
612
+ ) : [];
613
+
614
+ $ts = get_gmt_from_date("$year-$month-$day $hour:$minute:0", 'U');
615
+
616
+ if (isset($_POST['expirationdate_quickedit'])) {
617
+ $opts = PostExpirator_Facade::get_expire_principles($id);
618
+ if (isset($_POST['expirationdate_expiretype'])) {
619
+ $opts['expireType'] = sanitize_key($_POST['expirationdate_expiretype']);
620
+ if (in_array($opts['expireType'], array(
621
+ 'category',
622
+ 'category-add',
623
+ 'category-remove'
624
+ ), true)) {
625
+ $opts['category'] = $category;
626
+ $opts['categoryTaxonomy'] = $postTypeDefaults['taxonomy'];
627
+ }
628
+ }
629
+ } else {
630
+ // Schedule/Update Expiration
631
+ $opts['expireType'] = sanitize_key($_POST['expirationdate_expiretype']);
632
+ $opts['id'] = $id;
633
+
634
+ if ($opts['expireType'] === 'category' || $opts['expireType'] === 'category-add' || $opts['expireType'] === 'category-remove') {
635
+ if (isset($category) && ! empty($category)) {
636
+ $opts['category'] = $category;
637
+ $opts['categoryTaxonomy'] = $postTypeDefaults['taxonomy'];
638
+ }
639
+ }
640
+ }
641
+ } else {
642
+ // Gutenberg or script request
643
+ if (function_exists('`wpcom_vip_file_get_contents')) {
644
+ $payload = wpcom_vip_file_get_contents('php://input');
645
+ } else {
646
+ // phpcs:ignore WordPressVIPMinimum.Performance.FetchingRemoteData.FileGetContentsRemoteFile
647
+ $payload = @file_get_contents('php://input');
648
+ }
649
+
650
+ if (empty($payload)) {
651
+ do_action(
652
+ DebugHooks::ACTION_DEBUG_LOG,
653
+ $id . ' -> NO PAYLOAD ON SAVE_POST'
654
+ );
655
+
656
+ return;
657
+ }
658
+
659
+ $payload = @json_decode($payload, true);
660
+
661
+ if (isset($payload['meta'])) {
662
+ if (isset($payload['meta']['_expiration-date-status'])) {
663
+ $shouldSchedule = $payload['meta']['_expiration-date-status'] === 'saved'
664
+ && isset($payload['meta']['_expiration-date'])
665
+ && false === empty($payload['meta']['_expiration-date']);
666
+ } else {
667
+ $shouldSchedule = PostExpirator_Facade::is_expiration_enabled_for_post($id);
668
+ }
669
+
670
+ if ($shouldSchedule) {
671
+ if (isset($payload['meta']['_expiration-date'])) {
672
+ $ts = sanitize_text_field($payload['meta']['_expiration-date']);
673
+ } else {
674
+ $ts = get_post_meta($id, '_expiration-date', true);
675
+ }
676
+
677
+ if (isset($payload['meta']['_expiration-date-type'])) {
678
+ $opts['expireType'] = sanitize_key($payload['meta']['_expiration-date-type']);
679
+ } else {
680
+ $opts['expireType'] = get_post_meta($id, '_expiration-date-type', true);
681
+ }
682
+
683
+ if (isset($payload['meta']['_expiration-date-categories'])) {
684
+ $opts['category'] = PostExpirator_Util::sanitize_array_of_integers(
685
+ $payload['meta']['_expiration-date-categories']
686
+ );
687
+ } else {
688
+ $opts['category'] = (array)get_post_meta($id, '_expiration-date-categories', true);
689
+ }
690
+
691
+ $opts['categoryTaxonomy'] = $postTypeDefaults['taxonomy'];
692
+ }
693
+ } else {
694
+ $shouldSchedule = PostExpirator_Facade::is_expiration_enabled_for_post($id);
695
+
696
+ if ($shouldSchedule) {
697
+ $ts = get_post_meta($id, '_expiration-date', true);
698
+
699
+ $opts['expireType'] = get_post_meta($id, '_expiration-date-type', true);
700
+ $opts['category'] = (array)get_post_meta($id, '_expiration-date-categories', true);
701
+ $opts['categoryTaxonomy'] = $postTypeDefaults['taxonomy'];
702
+ }
703
+ }
704
+ }
705
+
706
+ if ($shouldSchedule) {
707
+ $opts['id'] = $id;
708
+
709
+ do_action(ExpiratorHooks::ACTION_SCHEDULE_POST_EXPIRATION, $id, $ts, $opts);
710
+ } else {
711
+ do_action(ExpiratorHooks::ACTION_UNSCHEDULE_POST_EXPIRATION, $id);
712
+ }
713
+ }
714
+
715
+ add_action('save_post', 'postexpirator_update_post_meta');
716
+
717
+
718
+ /**
719
+ * Register the shortcode.
720
+ *
721
+ * @internal
722
+ *
723
+ * @access private
724
+ */
725
+ function postexpirator_shortcode($atts)
726
+ {
727
+ global $post;
728
+
729
+ $enabled = PostExpirator_Facade::is_expiration_enabled_for_post($post->ID);
730
+ $expirationdatets = get_post_meta($post->ID, '_expiration-date', true);
731
+ if (! $enabled || empty($expirationdatets)) {
732
+ return false;
733
+ }
734
+
735
+ // @TODO remove extract
736
+ // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
737
+ extract(
738
+ shortcode_atts(
739
+ array(
740
+ 'dateformat' => get_option('expirationdateDefaultDateFormat', POSTEXPIRATOR_DATEFORMAT),
741
+ 'timeformat' => get_option('expirationdateDefaultTimeFormat', POSTEXPIRATOR_TIMEFORMAT),
742
+ 'type' => 'full',
743
+ 'tz' => date('T'),
744
+ ),
745
+ $atts
746
+ )
747
+ );
748
+
749
+ if (empty($dateformat)) {
750
+ global $expirationdateDefaultDateFormat;
751
+ $dateformat = $expirationdateDefaultDateFormat;
752
+ }
753
+
754
+ if (empty($timeformat)) {
755
+ global $expirationdateDefaultTimeFormat;
756
+ $timeformat = $expirationdateDefaultTimeFormat;
757
+ }
758
+
759
+ if ($type === 'full') {
760
+ $format = $dateformat . ' ' . $timeformat;
761
+ } elseif ($type === 'date') {
762
+ $format = $dateformat;
763
+ } elseif ($type === 'time') {
764
+ $format = $timeformat;
765
+ }
766
+
767
+ return PostExpirator_Util::get_wp_date($format, $expirationdatets);
768
+ }
769
+
770
+ add_shortcode('postexpirator', 'postexpirator_shortcode');
771
+
772
+ /**
773
+ * Add the footer.
774
+ *
775
+ * @internal
776
+ *
777
+ * @access private
778
+ */
779
+ function postexpirator_add_footer($text)
780
+ {
781
+ global $post;
782
+
783
+ // Check to see if its enabled
784
+ $displayFooter = get_option('expirationdateDisplayFooter');
785
+
786
+ // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
787
+ if ($displayFooter === false || $displayFooter == 0) {
788
+ return $text;
789
+ }
790
+
791
+ $enabled = PostExpirator_Facade::is_expiration_enabled_for_post($post->ID);
792
+
793
+ if (empty($enabled)) {
794
+ return $text;
795
+ }
796
+
797
+ $expirationdatets = get_post_meta($post->ID, '_expiration-date', true);
798
+ if (! is_numeric($expirationdatets)) {
799
+ return $text;
800
+ }
801
+
802
+ $dateformat = get_option('expirationdateDefaultDateFormat', POSTEXPIRATOR_DATEFORMAT);
803
+ $timeformat = get_option('expirationdateDefaultTimeFormat', POSTEXPIRATOR_TIMEFORMAT);
804
+ $expirationdateFooterContents = get_option('expirationdateFooterContents', POSTEXPIRATOR_FOOTERCONTENTS);
805
+ $expirationdateFooterStyle = get_option('expirationdateFooterStyle', POSTEXPIRATOR_FOOTERSTYLE);
806
+
807
+ $search = array(
808
+ 'EXPIRATIONFULL',
809
+ 'EXPIRATIONDATE',
810
+ 'EXPIRATIONTIME',
811
+ );
812
+
813
+ $replace = array(
814
+ PostExpirator_Util::get_wp_date("$dateformat $timeformat", $expirationdatets),
815
+ PostExpirator_Util::get_wp_date($dateformat, $expirationdatets),
816
+ PostExpirator_Util::get_wp_date($timeformat, $expirationdatets)
817
+ );
818
+
819
+ $add_to_footer = '<p style="' . $expirationdateFooterStyle . '">' . str_replace(
820
+ $search,
821
+ $replace,
822
+ $expirationdateFooterContents
823
+ ) . '</p>';
824
+
825
+ return $text . $add_to_footer;
826
+ }
827
+
828
+ add_action('the_content', 'postexpirator_add_footer', 0);
829
+
830
+
831
+ /**
832
+ * Add Stylesheet
833
+ *
834
+ * @internal
835
+ *
836
+ * @access private
837
+ */
838
+ function postexpirator_css($screen_id)
839
+ {
840
+ switch ($screen_id) {
841
+ case 'post.php':
842
+ case 'post-new.php':
843
+ case 'settings_page_post-expirator':
844
+ wp_enqueue_style(
845
+ 'postexpirator-css',
846
+ POSTEXPIRATOR_BASEURL . '/assets/css/style.css',
847
+ array(),
848
+ POSTEXPIRATOR_VERSION
849
+ );
850
+ break;
851
+ case 'edit.php':
852
+ wp_enqueue_style(
853
+ 'postexpirator-edit',
854
+ POSTEXPIRATOR_BASEURL . '/assets/css/edit.css',
855
+ array(),
856
+ POSTEXPIRATOR_VERSION
857
+ );
858
+ break;
859
+ }
860
+ }
861
+
862
+ add_action('admin_enqueue_scripts', 'postexpirator_css', 10, 1);
863
+
864
+ /**
865
+ * PublishPress Future Activation/Upgrade
866
+ *
867
+ * @internal
868
+ *
869
+ * @access private
870
+ */
871
+ function postexpirator_upgrade()
872
+ {
873
+ // Check for current version, if not exists, run activation
874
+ $version = get_option('postexpiratorVersion');
875
+ if ($version === false) { // not installed, run default activation
876
+ do_action(CoreHooks::ACTION_ACTIVATE_PLUGIN);
877
+
878
+ update_option('postexpiratorVersion', POSTEXPIRATOR_VERSION);
879
+ } else {
880
+ if (version_compare($version, '1.6.1') === -1) {
881
+ update_option('postexpiratorVersion', POSTEXPIRATOR_VERSION);
882
+ update_option('expirationdateDefaultDate', POSTEXPIRATOR_EXPIREDEFAULT);
883
+ }
884
+
885
+ if (version_compare($version, '1.6.2') === -1) {
886
+ update_option('postexpiratorVersion', POSTEXPIRATOR_VERSION);
887
+ }
888
+
889
+ if (version_compare($version, '2.0.0-rc1') === -1) {
890
+ global $wpdb;
891
+
892
+ // Schedule Events/Migrate Config
893
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
894
+ $results = $wpdb->get_results(
895
+ $wpdb->prepare(
896
+ 'select post_id, meta_value from ' . $wpdb->postmeta . ' as postmeta, ' . $wpdb->posts . ' as posts where postmeta.post_id = posts.ID AND postmeta.meta_key = %s AND postmeta.meta_value >= %d',
897
+ 'expiration-date',
898
+ time()
899
+ )
900
+ );
901
+
902
+ foreach ($results as $result) {
903
+ wp_schedule_single_event(
904
+ $result->meta_value,
905
+ ExpiratorHooks::ACTION_EXPIRE_POST,
906
+ array($result->post_id)
907
+ );
908
+ $opts = array();
909
+ $opts['id'] = $result->post_id;
910
+ $posttype = get_post_type($result->post_id);
911
+ if ($posttype === 'page') {
912
+ $opts['expireType'] = strtolower(get_option('expirationdateExpiredPageStatus', 'Draft'));
913
+ } else {
914
+ $opts['expireType'] = strtolower(get_option('expirationdateExpiredPostStatus', 'Draft'));
915
+ }
916
+
917
+ $cat = get_post_meta($result->post_id, '_expiration-date-category', true);
918
+ if ((isset($cat) && ! empty($cat))) {
919
+ $opts['category'] = $cat;
920
+ $opts['expireType'] = 'category';
921
+ }
922
+
923
+ PostExpirator_Facade::set_expire_principles($result->post_id, $opts);
924
+ }
925
+
926
+ // update meta key to new format
927
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
928
+ $wpdb->query(
929
+ $wpdb->prepare(
930
+ "UPDATE $wpdb->postmeta SET meta_key = %s WHERE meta_key = %s",
931
+ '_expiration-date',
932
+ 'expiration-date'
933
+ )
934
+ );
935
+
936
+ // migrate defaults
937
+ $pagedefault = get_option('expirationdateExpiredPageStatus');
938
+ $postdefault = get_option('expirationdateExpiredPostStatus');
939
+ if ($pagedefault) {
940
+ update_option('expirationdateDefaultsPage', array('expireType' => $pagedefault));
941
+ }
942
+ if ($postdefault) {
943
+ update_option('expirationdateDefaultsPost', array('expireType' => $postdefault));
944
+ }
945
+
946
+ delete_option('expirationdateCronSchedule');
947
+ delete_option('expirationdateAutoEnabled');
948
+ delete_option('expirationdateExpiredPageStatus');
949
+ delete_option('expirationdateExpiredPostStatus');
950
+ update_option('postexpiratorVersion', POSTEXPIRATOR_VERSION);
951
+ }
952
+
953
+ if (version_compare($version, '2.0.1') === -1) {
954
+ // Forgot to do this in 2.0.0
955
+ if (is_multisite()) {
956
+ global $current_blog;
957
+ wp_clear_scheduled_hook('expirationdate_delete_' . $current_blog->blog_id);
958
+ } else {
959
+ wp_clear_scheduled_hook('expirationdate_delete');
960
+ }
961
+
962
+ update_option('postexpiratorVersion', POSTEXPIRATOR_VERSION);
963
+ }
964
+
965
+ update_option('postexpiratorVersion', POSTEXPIRATOR_VERSION);
966
+ }
967
+ }
968
+
969
+ add_action('admin_init', 'postexpirator_upgrade');
970
+
971
+ /**
972
+ * Called at plugin activation
973
+ *
974
+ * @internal
975
+ *
976
+ * @access private
977
+ * @deprecated 2.8.0
978
+ */
979
+ function postexpirator_activate()
980
+ {
981
+ _deprecated_function(__METHOD__, '2.8.0', 'Moved to the module Settings');
982
+ }
983
+
984
+ /**
985
+ * Called at plugin deactivation
986
+ *
987
+ * @internal
988
+ *
989
+ * @access private
990
+ *
991
+ * @deprecated 2.8.0
992
+ */
993
+ function expirationdate_deactivate()
994
+ {
995
+ _deprecated_function(__METHOD__, '2.8.0', 'Moved to the PublishPressFuture\Framework\PluginFacade class.');
996
+ }
997
+
998
+ /**
999
+ * The walker class for category checklist.
1000
+ *
1001
+ * @internal
1002
+ *
1003
+ * @access private
1004
+ */
1005
+ class Walker_PostExpirator_Category_Checklist extends Walker
1006
+ {
1007
+
1008
+ /**
1009
+ * What the class handles.
1010
+ *
1011
+ * @var string
1012
+ */
1013
+ public $tree_type = 'category';
1014
+
1015
+ /**
1016
+ * DB fields to use.
1017
+ *
1018
+ * @var array
1019
+ */
1020
+ public $db_fields = array('parent' => 'parent', 'id' => 'term_id'); // TODO: decouple this
1021
+
1022
+ /**
1023
+ * The disabled attribute.
1024
+ *
1025
+ * @var string
1026
+ */
1027
+ public $disabled = '';
1028
+
1029
+ /**
1030
+ * Set the disabled attribute.
1031
+ */
1032
+ public function setDisabled()
1033
+ {
1034
+ $this->disabled = 'disabled="disabled"';
1035
+ }
1036
+
1037
+ /**
1038
+ * Starts the list before the elements are added.
1039
+ *
1040
+ * The $args parameter holds additional values that may be used with the child
1041
+ * class methods. This method is called at the start of the output list.
1042
+ *
1043
+ * @param string $output Used to append additional content (passed by reference).
1044
+ * @param int $depth Depth of the item.
1045
+ * @param array $args An array of additional arguments.
1046
+ */
1047
+ public function start_lvl(&$output, $depth = 0, $args = array())
1048
+ {
1049
+ $indent = str_repeat("\t", $depth);
1050
+ $output .= "$indent<ul class='children'>\n";
1051
+ }
1052
+
1053
+ /**
1054
+ * Ends the list of after the elements are added.
1055
+ *
1056
+ * The $args parameter holds additional values that may be used with the child
1057
+ * class methods. This method finishes the list at the end of output of the elements.
1058
+ *
1059
+ * @param string $output Used to append additional content (passed by reference).
1060
+ * @param int $depth Depth of the item.
1061
+ * @param array $args An array of additional arguments.
1062
+ */
1063
+ public function end_lvl(&$output, $depth = 0, $args = array())
1064
+ {
1065
+ $indent = str_repeat("\t", $depth);
1066
+ $output .= "$indent</ul>\n";
1067
+ }
1068
+
1069
+ /**
1070
+ * Start the element output.
1071
+ *
1072
+ * The $args parameter holds additional values that may be used with the child
1073
+ * class methods. Includes the element output also.
1074
+ *
1075
+ * @param string $output Used to append additional content (passed by reference).
1076
+ * @param object $category The data object.
1077
+ * @param int $depth Depth of the item.
1078
+ * @param array $args An array of additional arguments.
1079
+ * @param int $current_object_id ID of the current item.
1080
+ */
1081
+ public function start_el(&$output, $category, $depth = 0, $args = array(), $current_object_id = 0)
1082
+ {
1083
+ // @TODO remove extract
1084
+ // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
1085
+ extract($args);
1086
+ if (empty($taxonomy)) {
1087
+ $taxonomy = 'category';
1088
+ }
1089
+
1090
+ $name = 'expirationdate_category';
1091
+
1092
+ $class = in_array($category->term_id, $popular_cats, true) ? ' class="expirator-category"' : '';
1093
+ $output .= "\n<li id='expirator-{$taxonomy}-{$category->term_id}'$class>" . '<label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="' . $name . '[]" id="expirator-in-' . $taxonomy . '-' . $category->term_id . '"' . checked(
1094
+ in_array($category->term_id, $selected_cats, true),
1095
+ true,
1096
+ false
1097
+ ) . disabled(empty($args['disabled']), false, false) . ' ' . $this->disabled . '/> ' . esc_html(
1098
+ apply_filters('the_category', $category->name)
1099
+ ) . '</label>';
1100
+ }
1101
+
1102
+ /**
1103
+ * Ends the element output, if needed.
1104
+ *
1105
+ * The $args parameter holds additional values that may be used with the child class methods.
1106
+ *
1107
+ * @param string $output Used to append additional content (passed by reference).
1108
+ * @param object $category The data object.
1109
+ * @param int $depth Depth of the item.
1110
+ * @param array $args An array of additional arguments.
1111
+ */
1112
+ public function end_el(&$output, $category, $depth = 0, $args = array())
1113
+ {
1114
+ $output .= "</li>\n";
1115
+ }
1116
+ }
1117
+
1118
+ /**
1119
+ * Get the HTML for expire type.
1120
+ *
1121
+ * @internal
1122
+ *
1123
+ * @access private
1124
+ */
1125
+ function _postexpirator_expire_type($opts)
1126
+ {
1127
+ if (empty($opts)) {
1128
+ return false;
1129
+ }
1130
+
1131
+ PostExpirator_Display::getInstance()->render_template('how-to-expire', array('opts' => $opts));
1132
+ }
1133
+
1134
+ /**
1135
+ * Get the HTML for taxonomy.
1136
+ *
1137
+ * @internal
1138
+ *
1139
+ * @access private
1140
+ */
1141
+ function _postexpirator_taxonomy($opts)
1142
+ {
1143
+ if (empty($opts)) {
1144
+ return false;
1145
+ }
1146
+
1147
+ if (! isset($opts['name'])) {
1148
+ return false;
1149
+ }
1150
+
1151
+ $name = sanitize_text_field($opts['name']);
1152
+
1153
+ if (! isset($id)) {
1154
+ $id = $name;
1155
+ }
1156
+
1157
+ $disabled = false;
1158
+ if (isset($opts['disabled'])) {
1159
+ $disabled = (bool)$opts['disabled'];
1160
+ }
1161
+
1162
+ $onchange = '';
1163
+ if (isset($opts['onchange'])) {
1164
+ $onchange = sanitize_text_field($opts['onchange']);
1165
+ }
1166
+
1167
+ $type = '';
1168
+ if (isset($opts['type'])) {
1169
+ $type = sanitize_text_field($opts['type']);
1170
+ }
1171
+
1172
+ $selected = false;
1173
+ if (isset($opts['selected'])) {
1174
+ $selected = $opts['selected'];
1175
+ }
1176
+
1177
+ $taxonomies = get_object_taxonomies($type, 'object');
1178
+ $taxonomies = wp_filter_object_list($taxonomies, array('hierarchical' => true));
1179
+
1180
+ if (empty($taxonomies)) {
1181
+ return esc_html__('No taxonomies found', 'post-expirator');
1182
+ }
1183
+
1184
+ $params = [
1185
+ 'name' => $name,
1186
+ 'id' => $id,
1187
+ 'disabled' => $disabled,
1188
+ 'taxonomies' => $taxonomies,
1189
+ 'selected' => $selected,
1190
+ 'onchange' => $onchange
1191
+ ];
1192
+
1193
+ return PostExpirator_Display::getInstance()->get_rendered_template('taxonomy-field', $params);
1194
+ }
1195
+
1196
+ /**
1197
+ * Include the JS.
1198
+ *
1199
+ * @internal
1200
+ *
1201
+ * @access private
1202
+ */
1203
+ function postexpirator_quickedit_javascript()
1204
+ {
1205
+ // if using code as plugin
1206
+ wp_enqueue_script('postexpirator-edit', POSTEXPIRATOR_BASEURL . '/assets/js/admin-edit.js', array(
1207
+ 'jquery',
1208
+ 'inline-edit-post'
1209
+ ), POSTEXPIRATOR_VERSION, true);
1210
+
1211
+ global $wp_version;
1212
+
1213
+ wp_localize_script(
1214
+ 'postexpirator-edit', 'postexpiratorConfig', array(
1215
+ 'wpAfter6' => version_compare($wp_version, '6', '>='),
1216
+ 'ajax' => array(
1217
+ 'nonce' => wp_create_nonce(POSTEXPIRATOR_SLUG),
1218
+ 'bulk_edit' => 'manage_wp_posts_using_bulk_quick_save_bulk_edit',
1219
+ ),
1220
+ )
1221
+ );
1222
+ }
1223
+
1224
+ add_action('admin_print_scripts-edit.php', 'postexpirator_quickedit_javascript');
1225
+
1226
+ function postexpirator_date_save_bulk_edit()
1227
+ {
1228
+ // Save Bulk edit data
1229
+ $doAction = isset($_GET['action']) ? sanitize_key($_GET['action']) : '';
1230
+ $facade = PostExpirator_Facade::getInstance();
1231
+
1232
+ if (
1233
+ 'edit' !== $doAction
1234
+ || ! isset($_REQUEST['postexpirator_view'])
1235
+ || $_REQUEST['postexpirator_view'] !== 'bulk-edit'
1236
+ || ! isset($_REQUEST['expirationdate_status'])
1237
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1238
+ || sanitize_key($_REQUEST['expirationdate_status']) === 'no-change'
1239
+ || ! $facade->current_user_can_expire_posts()
1240
+ || ! isset($_REQUEST['post'])
1241
+ || ! isset($_REQUEST['expirationdate_expiretype'])
1242
+ ) {
1243
+ return;
1244
+ }
1245
+
1246
+ check_admin_referer('bulk-posts');
1247
+
1248
+ $status = sanitize_key($_REQUEST['expirationdate_status']);
1249
+ $validStatuses = ['change-only', 'add-only', 'change-add', 'remove-only'];
1250
+
1251
+ if (! in_array($status, $validStatuses)) {
1252
+ return;
1253
+ }
1254
+
1255
+ $postIds = array_map('intval', (array)$_REQUEST['post']);
1256
+
1257
+ if (empty($postIds)) {
1258
+ return;
1259
+ }
1260
+
1261
+ $postType = get_post_type($postIds[0]);
1262
+
1263
+ $defaults = PostExpirator_Facade::get_default_expiry($postType);
1264
+
1265
+ $year = $defaults['year'];
1266
+ if (isset($_REQUEST['expirationdate_year'])) {
1267
+ $year = (int)$_REQUEST['expirationdate_year'];
1268
+ }
1269
+
1270
+ $month = $defaults['month'];
1271
+ if (isset($_REQUEST['expirationdate_month'])) {
1272
+ $month = (int)$_REQUEST['expirationdate_month'];
1273
+ }
1274
+
1275
+ $day = $defaults['day'];
1276
+ if (isset($_REQUEST['expirationdate_day'])) {
1277
+ $day = (int)$_REQUEST['expirationdate_day'];
1278
+ }
1279
+
1280
+ $hour = $defaults['hour'];
1281
+ if (isset($_REQUEST['expirationdate_hour'])) {
1282
+ $hour = (int)$_REQUEST['expirationdate_hour'];
1283
+ }
1284
+
1285
+ $minute = $defaults['minute'];
1286
+ if (isset($_REQUEST['expirationdate_minute'])) {
1287
+ $minute = (int)$_REQUEST['expirationdate_minute'];
1288
+ }
1289
+
1290
+ $newExpirationDate = get_gmt_from_date("$year-$month-$day $hour:$minute:0", 'U');
1291
+
1292
+ if (! $newExpirationDate) {
1293
+ return;
1294
+ }
1295
+
1296
+ $expireType = sanitize_key($_REQUEST['expirationdate_expiretype']);
1297
+ $expireTaxonomy = null;
1298
+ if (in_array($expireType, ['category', 'category-add', 'category-remove'], true)) {
1299
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
1300
+ $expireTaxonomy = PostExpirator_Util::sanitize_array_of_integers($_REQUEST['expirationdate_category']);
1301
+ }
1302
+
1303
+ foreach ($postIds as $postId) {
1304
+ $postExpirationDate = get_post_meta($postId, '_expiration-date', true);
1305
+
1306
+ if ($status === 'remove-only') {
1307
+ do_action(ExpiratorHooks::ACTION_UNSCHEDULE_POST_EXPIRATION, $postId);
1308
+
1309
+ continue;
1310
+ }
1311
+
1312
+ if ($status === 'change-only' && empty($postExpirationDate)) {
1313
+ continue;
1314
+ }
1315
+
1316
+ if ($status === 'add-only' && ! empty($postExpirationDate)) {
1317
+ continue;
1318
+ }
1319
+
1320
+ $opts = PostExpirator_Facade::get_expire_principles($postId);
1321
+ $opts['expireType'] = $expireType;
1322
+
1323
+ if (in_array($opts['expireType'], array('category', 'category-add', 'category-remove'), true)) {
1324
+ $opts['category'] = $expireTaxonomy;
1325
+ }
1326
+
1327
+ do_action(ExpiratorHooks::ACTION_SCHEDULE_POST_EXPIRATION, $postId, $newExpirationDate, $opts);
1328
+ }
1329
+ }
1330
+
1331
+ add_action('admin_init', 'postexpirator_date_save_bulk_edit');
{views → legacy/views}/bulk-edit.php RENAMED
@@ -4,11 +4,11 @@ defined('ABSPATH') or die('Direct access not allowed.');
4
 
5
  $defaults = PostExpirator_Facade::get_default_expiry($post_type);
6
 
7
- $year = $defaults['year'];
8
- $month = $defaults['month'];
9
- $day = $defaults['day'];
10
- $hour = $defaults['hour'];
11
- $minute = $defaults['minute'];
12
  ?>
13
  <div style="clear:both"></div>
14
  <div class="inline-edit-col post-expirator-quickedit">
@@ -31,13 +31,14 @@ $minute = $defaults['minute'];
31
  </option>
32
  <option value="change-only" data-show-fields="true"
33
  title="<?php
34
- esc_attr_e('Change expiry date if enabled on posts', 'post-expirator'); ?>"><?php
35
  esc_html_e('Change on posts', 'post-expirator'); ?></option>
36
  <option value="add-only" data-show-fields="true"
37
  title="<?php
38
  esc_attr_e('Add expiry date if not enabled on posts', 'post-expirator'); ?>"><?php
39
  esc_html_e('Add to posts', 'post-expirator'); ?></option>
40
  <option value="change-add"
 
41
  data-show-fields="true"><?php
42
  esc_html_e('Change & Add', 'post-expirator'); ?></option>
43
  <option value="remove-only"
@@ -56,7 +57,7 @@ $minute = $defaults['minute'];
56
  $monthNumeric = PostExpirator_Util::get_wp_date('m', $now);
57
  $monthStr = PostExpirator_Util::get_wp_date('M', $now);
58
  // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
59
- $selected = $monthNumeric == $defaults['month'] ? 'selected' : '';
60
  ?>
61
  <option value="<?php
62
  echo esc_attr($monthNumeric); ?>"
@@ -74,28 +75,28 @@ $minute = $defaults['minute'];
74
  <span class="screen-reader-text"><?php
75
  esc_html_e('Day', 'post-expirator'); ?></span>
76
  <input name="expirationdate_day" required value="<?php
77
- echo esc_attr($day); ?>" size="2"
78
  maxlength="2" autocomplete="off" type="text">
79
  </label>,
80
  <label>
81
  <span class="screen-reader-text"><?php
82
  esc_html_e('Year', 'post-expirator'); ?></span>
83
  <input name="expirationdate_year" required value="<?php
84
- echo esc_attr($year); ?>" size="4"
85
  maxlength="4" autocomplete="off" type="text">
86
  </label> @
87
  <label>
88
  <span class="screen-reader-text"><?php
89
  esc_html_e('Hour', 'post-expirator'); ?></span>
90
  <input name="expirationdate_hour" required value="<?php
91
- echo esc_attr($hour); ?>" size="2"
92
- maxlength="2" autocomplete="off" type="text">
93
  </label> :
94
  <label>
95
  <span class="screen-reader-text"><?php
96
  esc_html_e('Minute', 'post-expirator'); ?></span>
97
  <input name="expirationdate_minute" required value="<?php
98
- echo esc_attr($minute); ?>" size="2" maxlength="2" autocomplete="off" type="text">
99
  </label>
100
 
101
  <?php
@@ -111,7 +112,11 @@ $minute = $defaults['minute'];
111
  </legend>
112
  <label>
113
  <?php
114
- $defaults = get_option('expirationdateDefaults' . ucfirst($post_type));
 
 
 
 
115
  _postexpirator_expire_type(array(
116
  'name' => 'expirationdate_expiretype',
117
  'selected' => empty($defaults) ? 'draft' : $defaults['expireType'],
4
 
5
  $defaults = PostExpirator_Facade::get_default_expiry($post_type);
6
 
7
+ $defaultYear = $defaults['year'];
8
+ $defaultMonth = $defaults['month'];
9
+ $defaultDay = $defaults['day'];
10
+ $defaultHour = $defaults['hour'];
11
+ $defaultMinute = $defaults['minute'];
12
  ?>
13
  <div style="clear:both"></div>
14
  <div class="inline-edit-col post-expirator-quickedit">
31
  </option>
32
  <option value="change-only" data-show-fields="true"
33
  title="<?php
34
+ esc_attr_e('Change expiry date if enabled on p osts', 'post-expirator'); ?>"><?php
35
  esc_html_e('Change on posts', 'post-expirator'); ?></option>
36
  <option value="add-only" data-show-fields="true"
37
  title="<?php
38
  esc_attr_e('Add expiry date if not enabled on posts', 'post-expirator'); ?>"><?php
39
  esc_html_e('Add to posts', 'post-expirator'); ?></option>
40
  <option value="change-add"
41
+
42
  data-show-fields="true"><?php
43
  esc_html_e('Change & Add', 'post-expirator'); ?></option>
44
  <option value="remove-only"
57
  $monthNumeric = PostExpirator_Util::get_wp_date('m', $now);
58
  $monthStr = PostExpirator_Util::get_wp_date('M', $now);
59
  // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
60
+ $selected = $monthNumeric == $defaultMonth ? 'selected' : '';
61
  ?>
62
  <option value="<?php
63
  echo esc_attr($monthNumeric); ?>"
75
  <span class="screen-reader-text"><?php
76
  esc_html_e('Day', 'post-expirator'); ?></span>
77
  <input name="expirationdate_day" required value="<?php
78
+ echo esc_attr($defaultDay); ?>" size="2"
79
  maxlength="2" autocomplete="off" type="text">
80
  </label>,
81
  <label>
82
  <span class="screen-reader-text"><?php
83
  esc_html_e('Year', 'post-expirator'); ?></span>
84
  <input name="expirationdate_year" required value="<?php
85
+ echo esc_attr($defaultYear); ?>" size="4"
86
  maxlength="4" autocomplete="off" type="text">
87
  </label> @
88
  <label>
89
  <span class="screen-reader-text"><?php
90
  esc_html_e('Hour', 'post-expirator'); ?></span>
91
  <input name="expirationdate_hour" required value="<?php
92
+ echo esc_attr($defaultHour); ?>" size="2"
93
+ mdefaultMxlength="2" autocomplete="off" type="text">
94
  </label> :
95
  <label>
96
  <span class="screen-reader-text"><?php
97
  esc_html_e('Minute', 'post-expirator'); ?></span>
98
  <input name="expirationdate_minute" required value="<?php
99
+ echo esc_attr($defaultMinute); ?>" size="2" maxlength="2" autocomplete="off" type="text">
100
  </label>
101
 
102
  <?php
112
  </legend>
113
  <label>
114
  <?php
115
+ $container = \PublishPressFuture\Core\DI\Container::getInstance();
116
+ $settingsFacade = $container->get(\PublishPressFuture\Core\DI\ServicesAbstract::SETTINGS);
117
+
118
+ $defaults = $settingsFacade->getPostTypeDefaults($post_type);
119
+
120
  _postexpirator_expire_type(array(
121
  'name' => 'expirationdate_expiretype',
122
  'selected' => empty($defaults) ? 'draft' : $defaults['expireType'],
{views → legacy/views}/classic-metabox.php RENAMED
@@ -152,22 +152,22 @@ echo empty($enabled) ? 'none' : 'flex'; ?>">
152
  ) . '</p>';
153
  } else {
154
  $keys = array_keys($taxonomies);
155
- $taxonomy = isset($defaultsOption['taxonomy']) ? $defaultsOption['taxonomy'] : $keys[0];
156
  wp_terms_checklist(0, array(
157
- 'taxonomy' => $taxonomy,
158
  'walker' => $walker,
159
  'selected_cats' => $categories,
160
  'checked_ontop' => false
161
  ));
162
- echo '<input type="hidden" name="taxonomy-hierarchical" value="' . esc_attr($taxonomy) . '" />';
163
  }
164
  echo '</ul>';
165
  echo '</div>';
166
- if (isset($taxonomy)) {
167
  echo '<p class="post-expirator-taxonomy-name">' . esc_html__(
168
  'Taxonomy Name',
169
  'post-expirator'
170
- ) . ': ' . esc_html($taxonomy) . '</p>';
171
  }
172
  echo '</div>';
173
  }
152
  ) . '</p>';
153
  } else {
154
  $keys = array_keys($taxonomies);
155
+ $taxonomyId = isset($defaultsOption['taxonomy']) ? $defaultsOption['taxonomy'] : $keys[0];
156
  wp_terms_checklist(0, array(
157
+ 'taxonomy' => $taxonomyId,
158
  'walker' => $walker,
159
  'selected_cats' => $categories,
160
  'checked_ontop' => false
161
  ));
162
+ echo '<input type="hidden" name="taxonomy-hierarchical" value="' . esc_attr($taxonomyId) . '" />';
163
  }
164
  echo '</ul>';
165
  echo '</div>';
166
+ if (isset($taxonomyId)) {
167
  echo '<p class="post-expirator-taxonomy-name">' . esc_html__(
168
  'Taxonomy Name',
169
  'post-expirator'
170
+ ) . ': ' . esc_html($taxonomyId) . '</p>';
171
  }
172
  echo '</div>';
173
  }
{views → legacy/views}/expire-column.php RENAMED
@@ -2,7 +2,7 @@
2
  defined('ABSPATH') or die('Direct access not allowed.');
3
  ?>
4
  <div class="post-expire-col" data-id="<?php echo esc_attr($id); ?>"
5
- data-expire-attributes="<?php echo esc_attr(json_encode($attributes)); ?>">
6
  <?php
7
  $iconClass = '';
8
  $iconTitle = '';
@@ -25,7 +25,10 @@ defined('ABSPATH') or die('Direct access not allowed.');
25
  $iconClass = 'marker icon-never';
26
  }
27
 
28
- $defaults = get_option('expirationdateDefaults' . ucfirst($post_type));
 
 
 
29
  $expireType = 'draft';
30
  if (isset($defaults['expireType'])) {
31
  $expireType = $defaults['expireType'];
@@ -34,22 +37,22 @@ defined('ABSPATH') or die('Direct access not allowed.');
34
  // these defaults will be used by quick edit
35
  $defaults = PostExpirator_Facade::get_default_expiry($post_type);
36
 
37
- $year = $defaults['year'];
38
- $month = $defaults['month'];
39
- $day = $defaults['day'];
40
- $hour = $defaults['hour'];
41
- $minute = $defaults['minute'];
42
  $enabled = $expirationDate && $expirationEnabled ? 'true' : 'false';
43
  $categories = '';
44
 
45
  // Values for Quick Edit
46
  if ($expirationDate) {
47
  $date = gmdate('Y-m-d H:i:s', $expirationDate);
48
- $year = get_date_from_gmt($date, 'Y');
49
- $month = get_date_from_gmt($date, 'm');
50
- $day = get_date_from_gmt($date, 'd');
51
- $hour = get_date_from_gmt($date, 'H');
52
- $minute = get_date_from_gmt($date, 'i');
53
  if (isset($attributes['expireType'])) {
54
  $expireType = $attributes['expireType'];
55
  }
@@ -69,11 +72,11 @@ defined('ABSPATH') or die('Direct access not allowed.');
69
  <span class="dashicons dashicons-<?php echo esc_attr($iconClass); ?>" title="<?php echo esc_attr($iconTitle); ?>"></span>
70
 
71
  <?php echo esc_html($display); ?>
72
- <input type="hidden" id="expirationdate_year-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($year); ?>" />
73
- <input type="hidden" id="expirationdate_month-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($month); ?>" />
74
- <input type="hidden" id="expirationdate_day-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($day); ?>" />
75
- <input type="hidden" id="expirationdate_hour-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($hour); ?>" />
76
- <input type="hidden" id="expirationdate_minute-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($minute); ?>" />
77
  <input type="hidden" id="expirationdate_enabled-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($enabled); ?>" />
78
  <input type="hidden" id="expirationdate_expireType-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($expireType); ?>" />
79
  <input type="hidden" id="expirationdate_categories-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($categories); ?>" />
2
  defined('ABSPATH') or die('Direct access not allowed.');
3
  ?>
4
  <div class="post-expire-col" data-id="<?php echo esc_attr($id); ?>"
5
+ data-expire-attributes="<?php echo esc_attr(wp_json_encode($attributes)); ?>">
6
  <?php
7
  $iconClass = '';
8
  $iconTitle = '';
25
  $iconClass = 'marker icon-never';
26
  }
27
 
28
+ $container = \PublishPressFuture\Core\DI\Container::getInstance();
29
+ $settingsFacade = $container->get(\PublishPressFuture\Core\DI\ServicesAbstract::SETTINGS);
30
+
31
+ $defaults = $settingsFacade->getPostTypeDefaults($post_type);
32
  $expireType = 'draft';
33
  if (isset($defaults['expireType'])) {
34
  $expireType = $defaults['expireType'];
37
  // these defaults will be used by quick edit
38
  $defaults = PostExpirator_Facade::get_default_expiry($post_type);
39
 
40
+ $defaultYear = $defaults['year'];
41
+ $defaultMonth = $defaults['month'];
42
+ $defaultDay = $defaults['day'];
43
+ $defaultHour = $defaults['hour'];
44
+ $defaultMinute = $defaults['minute'];
45
  $enabled = $expirationDate && $expirationEnabled ? 'true' : 'false';
46
  $categories = '';
47
 
48
  // Values for Quick Edit
49
  if ($expirationDate) {
50
  $date = gmdate('Y-m-d H:i:s', $expirationDate);
51
+ $defaultYear = get_date_from_gmt($date, 'Y');
52
+ $defaultMonth = get_date_from_gmt($date, 'm');
53
+ $defaultDay = get_date_from_gmt($date, 'd');
54
+ $defaultHour = get_date_from_gmt($date, 'H');
55
+ $defaultMinute = get_date_from_gmt($date, 'i');
56
  if (isset($attributes['expireType'])) {
57
  $expireType = $attributes['expireType'];
58
  }
72
  <span class="dashicons dashicons-<?php echo esc_attr($iconClass); ?>" title="<?php echo esc_attr($iconTitle); ?>"></span>
73
 
74
  <?php echo esc_html($display); ?>
75
+ <input type="hidden" id="expirationdate_year-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($defaultYear); ?>" />
76
+ <input type="hidden" id="expirationdate_month-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($defaultMonth); ?>" />
77
+ <input type="hidden" id="expirationdate_day-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($defaultDay); ?>" />
78
+ <input type="hidden" id="expirationdate_hour-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($defaultHour); ?>" />
79
+ <input type="hidden" id="expirationdate_minute-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($defaultMinute); ?>" />
80
  <input type="hidden" id="expirationdate_enabled-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($enabled); ?>" />
81
  <input type="hidden" id="expirationdate_expireType-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($expireType); ?>" />
82
  <input type="hidden" id="expirationdate_categories-<?php echo esc_attr($id); ?>" value="<?php echo esc_attr($categories); ?>" />
legacy/views/how-to-expire.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined('ABSPATH') or die('Direct access not allowed.');
3
+
4
+ if (! isset($opts['name'])) {
5
+ return false;
6
+ }
7
+ if (! isset($opts['id'])) {
8
+ $opts['id'] = $opts['name'];
9
+ }
10
+ if (! isset($opts['type'])) {
11
+ $opts['type'] = '';
12
+ }
13
+
14
+ // Maybe settings have not been configured.
15
+ if (empty($opts['type']) && isset($opts['post_type'])) {
16
+ $opts['type'] = $opts['post_type'];
17
+ }
18
+
19
+ ?>
20
+ <select name="<?php echo esc_attr($opts['name']); ?>" id="<?php echo esc_attr($opts['id']); ?>" class="pe-howtoexpire">
21
+ <option value="draft" <?php selected($opts['selected'], 'draft', true); ?>>
22
+ <?php esc_html_e('Draft', 'post-expirator'); ?>
23
+ </option>
24
+
25
+ <option value="delete" <?php selected($opts['selected'], 'delete', true); ?>>
26
+ <?php esc_html_e('Delete', 'post-expirator'); ?>
27
+ </option>
28
+
29
+ <option value="trash" <?php selected($opts['selected'], 'trash', true); ?>>
30
+ <?php esc_html_e('Trash', 'post-expirator'); ?>
31
+ </option>
32
+
33
+ <option value="private" <?php selected($opts['selected'], 'private', true); ?>>
34
+ <?php esc_html_e('Private', 'post-expirator'); ?>
35
+ </option>
36
+
37
+ <option value="stick" <?php selected($opts['selected'], 'stick', true); ?>>
38
+ <?php esc_html_e('Stick', 'post-expirator'); ?>
39
+ </option>
40
+
41
+ <option value="unstick" <?php selected($opts['selected'], 'unstick', true); ?>>
42
+ <?php esc_html_e('Unstick', 'post-expirator'); ?>
43
+ </option>
44
+
45
+ <option value="category" <?php selected($opts['selected'], 'category', true); ?>>
46
+ <?php esc_html_e('Taxonomy: Replace', 'post-expirator'); ?>
47
+ </option>
48
+
49
+ <option value="category-add" <?php selected($opts['selected'], 'category-add', true); ?>>
50
+ <?php esc_html_e('Taxonomy: Add', 'post-expirator'); ?>
51
+ </option>
52
+
53
+ <option value="category-remove" <?php selected($opts['selected'], 'category-remove', true); ?>>
54
+ <?php esc_html_e('Taxonomy: Remove', 'post-expirator'); ?>
55
+ </option>
56
+ </select>
{views → legacy/views}/menu-advanced.php RENAMED
File without changes
{views → legacy/views}/menu-defaults.php RENAMED
@@ -1,6 +1,9 @@
1
  <?php
2
 
3
  defined('ABSPATH') or die('Direct access not allowed.');
 
 
 
4
  ?>
5
 
6
  <form method="post">
@@ -16,12 +19,13 @@ defined('ABSPATH') or die('Direct access not allowed.');
16
  ); ?></p>
17
 
18
  <?php
19
- foreach ($types as $type) {
20
- $post_type_object = get_post_type_object($type);
21
- $singularName = $post_type_object->labels->singular_name;
22
  echo '<fieldset>';
23
  echo '<legend>&nbsp;' . esc_html($singularName) . '&nbsp;</legend>';
24
- $defaults = get_option('expirationdateDefaults' . ucfirst($type));
 
25
 
26
  // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
27
  if (isset($defaults['autoEnable']) && $defaults['autoEnable'] == 1) {
@@ -36,7 +40,7 @@ defined('ABSPATH') or die('Direct access not allowed.');
36
  $expiredactivemetadisabled = 'checked = "checked"';
37
 
38
  // if settings are not configured, show the metabox by default only for posts and pages
39
- if (! isset($defaults['activeMetaBox']) && in_array($type, array('post', 'page'), true)) {
40
  $expiredactivemetaenabled = 'checked = "checked"';
41
  $expiredactivemetadisabled = '';
42
  } elseif (isset($defaults['activeMetaBox'])) {
@@ -61,23 +65,23 @@ defined('ABSPATH') or die('Direct access not allowed.');
61
  <table class="form-table">
62
  <tr valign="top">
63
  <th scope="row"><label for="expirationdate_activemeta-<?php
64
- echo esc_attr($type); ?>"><?php
65
  esc_html_e('Active', 'post-expirator'); ?></label></th>
66
  <td>
67
  <input type="radio" name="expirationdate_activemeta-<?php
68
- echo esc_attr($type); ?>" id="expirationdate_activemeta-true-<?php
69
- echo esc_attr($type); ?>" value="active" <?php
70
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
71
  echo $expiredactivemetaenabled; ?>/> <label for="expirationdate_activemeta-true-<?php
72
- echo esc_attr($type); ?>"><?php
73
  esc_html_e('Active', 'post-expirator'); ?></label>
74
  &nbsp;&nbsp;
75
  <input type="radio" name="expirationdate_activemeta-<?php
76
- echo esc_attr($type); ?>" id="expirationdate_activemeta-false-<?php
77
- echo esc_attr($type); ?>" value="inactive" <?php
78
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
79
  echo $expiredactivemetadisabled; ?>/> <label for="expirationdate_activemeta-false-<?php
80
- echo esc_attr($type); ?>"><?php
81
  esc_html_e('Inactive', 'post-expirator'); ?></label>
82
  <p class="description"><?php
83
  esc_html_e(
@@ -88,13 +92,13 @@ defined('ABSPATH') or die('Direct access not allowed.');
88
  </tr>
89
  <tr valign="top">
90
  <th scope="row"><label for="expirationdate_expiretype-<?php
91
- echo esc_attr($type); ?>"><?php
92
  esc_html_e('How to expire', 'post-expirator'); ?></label></th>
93
  <td>
94
  <?php
95
  _postexpirator_expire_type(
96
  array(
97
- 'name' => 'expirationdate_expiretype-' . esc_attr($type),
98
  'selected' => (isset($defaults['expireType']) ? $defaults['expireType'] : '')
99
  )
100
  ); ?>
@@ -104,23 +108,23 @@ defined('ABSPATH') or die('Direct access not allowed.');
104
  </tr>
105
  <tr valign="top">
106
  <th scope="row"><label for="expirationdate_autoenable-<?php
107
- echo esc_attr($type); ?>"><?php
108
  esc_html_e('Auto-Enable?', 'post-expirator'); ?></label></th>
109
  <td>
110
  <input type="radio" name="expirationdate_autoenable-<?php
111
- echo esc_attr($type); ?>" id="expirationdate_autoenable-true-<?php
112
- echo esc_attr($type); ?>" value="1" <?php
113
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
114
  echo $expiredautoenabled; ?>/> <label for="expirationdate_autoenable-true-<?php
115
- echo esc_attr($type); ?>"><?php
116
  esc_html_e('Enabled', 'post-expirator'); ?></label>
117
  &nbsp;&nbsp;
118
  <input type="radio" name="expirationdate_autoenable-<?php
119
- echo esc_attr($type); ?>" id="expirationdate_autoenable-false-<?php
120
- echo esc_attr($type); ?>" value="0" <?php
121
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
122
  echo $expiredautodisabled; ?>/> <label for="expirationdate_autoenable-false-<?php
123
- echo esc_attr($type); ?>"><?php
124
  esc_html_e('Disabled', 'post-expirator'); ?></label>
125
  <p class="description"><?php
126
  esc_html_e(
@@ -131,14 +135,15 @@ defined('ABSPATH') or die('Direct access not allowed.');
131
  </tr>
132
  <tr valign="top">
133
  <th scope="row"><label for="expirationdate_taxonomy-<?php
134
- echo esc_attr($type); ?>"><?php
135
  esc_html_e('Taxonomy (hierarchical)', 'post-expirator'); ?></label></th>
136
  <td>
137
  <?php
 
138
  echo _postexpirator_taxonomy(
139
  [
140
- 'type' => $type,
141
- 'name' => 'expirationdate_taxonomy-' . $type,
142
  'selected' => $defaults['taxonomy']
143
  ]
144
  );
@@ -147,12 +152,12 @@ defined('ABSPATH') or die('Direct access not allowed.');
147
  </tr>
148
  <tr valign="top">
149
  <th scope="row"><label for="expirationdate_emailnotification-<?php
150
- echo esc_attr($type); ?>"><?php
151
  esc_html_e('Who to notify', 'post-expirator'); ?></label></th>
152
  <td>
153
  <input class="large-text" type="text" name="expirationdate_emailnotification-<?php
154
- echo esc_attr($type); ?>" id="expirationdate_emailnotification-<?php
155
- echo esc_attr($type); ?>" value="<?php
156
  echo esc_attr($defaults['emailnotification']); ?>"/>
157
  <p class="description"><?php
158
  esc_html_e(
@@ -163,7 +168,6 @@ defined('ABSPATH') or die('Direct access not allowed.');
163
  </tr>
164
  <?php
165
  $values = array(
166
- '' => esc_html__('None', 'post-expirator'),
167
  'inherit' => esc_html__('Inherit from General Settings', 'post-expirator'),
168
  'custom' => esc_html__('Custom', 'post-expirator'),
169
  'publish' => esc_html__('Publish Time', 'post-expirator'),
@@ -180,12 +184,12 @@ defined('ABSPATH') or die('Direct access not allowed.');
180
 
181
  <tr valign="top">
182
  <th scope="row"><label for="expired-default-date-<?php
183
- echo esc_attr($type); ?>"><?php
184
  esc_html_e('Default Date/Time Duration', 'post-expirator'); ?></label></th>
185
  <td>
186
  <select name="expired-default-date-<?php
187
- echo esc_attr($type); ?>" id="expired-default-date-<?php
188
- echo esc_attr($type); ?>" class="pe-custom-date-toggle">
189
  <?php
190
  foreach ($values as $value => $label) { ?>
191
  <option value="<?php
@@ -201,16 +205,16 @@ defined('ABSPATH') or die('Direct access not allowed.');
201
  'post-expirator'
202
  ); ?></p>
203
  <div id="expired-custom-container-<?php
204
- echo esc_attr($type); ?>" class="pe-custom-date-container" style="display: <?php
205
  echo esc_attr($show); ?>;">
206
  <br/>
207
  <label for="expired-custom-date-<?php
208
- echo esc_attr($type); ?>"><?php
209
  esc_html_e('Custom', 'post-expirator'); ?>:</label>
210
  <input type="text" value="<?php
211
  echo esc_attr($customDate); ?>" name="expired-custom-date-<?php
212
- echo esc_attr($type); ?>" id="expired-custom-date-<?php
213
- echo esc_attr($type); ?>"/>
214
  <p class="description"><?php
215
  echo sprintf(
216
  esc_html__(
1
  <?php
2
 
3
  defined('ABSPATH') or die('Direct access not allowed.');
4
+
5
+ $container = \PublishPressFuture\Core\DI\Container::getInstance();
6
+ $settingsFacade = $container->get(\PublishPressFuture\Core\DI\ServicesAbstract::SETTINGS);
7
  ?>
8
 
9
  <form method="post">
19
  ); ?></p>
20
 
21
  <?php
22
+ foreach ($types as $postType) {
23
+ $postTypeObject = get_post_type_object($postType);
24
+ $singularName = $postTypeObject->labels->singular_name;
25
  echo '<fieldset>';
26
  echo '<legend>&nbsp;' . esc_html($singularName) . '&nbsp;</legend>';
27
+
28
+ $defaults = $settingsFacade->getPostTypeDefaults($postType);
29
 
30
  // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
31
  if (isset($defaults['autoEnable']) && $defaults['autoEnable'] == 1) {
40
  $expiredactivemetadisabled = 'checked = "checked"';
41
 
42
  // if settings are not configured, show the metabox by default only for posts and pages
43
+ if (! isset($defaults['activeMetaBox']) && in_array($postType, array('post', 'page'), true)) {
44
  $expiredactivemetaenabled = 'checked = "checked"';
45
  $expiredactivemetadisabled = '';
46
  } elseif (isset($defaults['activeMetaBox'])) {
65
  <table class="form-table">
66
  <tr valign="top">
67
  <th scope="row"><label for="expirationdate_activemeta-<?php
68
+ echo esc_attr($postType); ?>"><?php
69
  esc_html_e('Active', 'post-expirator'); ?></label></th>
70
  <td>
71
  <input type="radio" name="expirationdate_activemeta-<?php
72
+ echo esc_attr($postType); ?>" id="expirationdate_activemeta-true-<?php
73
+ echo esc_attr($postType); ?>" value="active" <?php
74
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
75
  echo $expiredactivemetaenabled; ?>/> <label for="expirationdate_activemeta-true-<?php
76
+ echo esc_attr($postType); ?>"><?php
77
  esc_html_e('Active', 'post-expirator'); ?></label>
78
  &nbsp;&nbsp;
79
  <input type="radio" name="expirationdate_activemeta-<?php
80
+ echo esc_attr($postType); ?>" id="expirationdate_activemeta-false-<?php
81
+ echo esc_attr($postType); ?>" value="inactive" <?php
82
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
83
  echo $expiredactivemetadisabled; ?>/> <label for="expirationdate_activemeta-false-<?php
84
+ echo esc_attr($postType); ?>"><?php
85
  esc_html_e('Inactive', 'post-expirator'); ?></label>
86
  <p class="description"><?php
87
  esc_html_e(
92
  </tr>
93
  <tr valign="top">
94
  <th scope="row"><label for="expirationdate_expiretype-<?php
95
+ echo esc_attr($postType); ?>"><?php
96
  esc_html_e('How to expire', 'post-expirator'); ?></label></th>
97
  <td>
98
  <?php
99
  _postexpirator_expire_type(
100
  array(
101
+ 'name' => 'expirationdate_expiretype-' . esc_attr($postType),
102
  'selected' => (isset($defaults['expireType']) ? $defaults['expireType'] : '')
103
  )
104
  ); ?>
108
  </tr>
109
  <tr valign="top">
110
  <th scope="row"><label for="expirationdate_autoenable-<?php
111
+ echo esc_attr($postType); ?>"><?php
112
  esc_html_e('Auto-Enable?', 'post-expirator'); ?></label></th>
113
  <td>
114
  <input type="radio" name="expirationdate_autoenable-<?php
115
+ echo esc_attr($postType); ?>" id="expirationdate_autoenable-true-<?php
116
+ echo esc_attr($postType); ?>" value="1" <?php
117
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
118
  echo $expiredautoenabled; ?>/> <label for="expirationdate_autoenable-true-<?php
119
+ echo esc_attr($postType); ?>"><?php
120
  esc_html_e('Enabled', 'post-expirator'); ?></label>
121
  &nbsp;&nbsp;
122
  <input type="radio" name="expirationdate_autoenable-<?php
123
+ echo esc_attr($postType); ?>" id="expirationdate_autoenable-false-<?php
124
+ echo esc_attr($postType); ?>" value="0" <?php
125
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
126
  echo $expiredautodisabled; ?>/> <label for="expirationdate_autoenable-false-<?php
127
+ echo esc_attr($postType); ?>"><?php
128
  esc_html_e('Disabled', 'post-expirator'); ?></label>
129
  <p class="description"><?php
130
  esc_html_e(
135
  </tr>
136
  <tr valign="top">
137
  <th scope="row"><label for="expirationdate_taxonomy-<?php
138
+ echo esc_attr($postType); ?>"><?php
139
  esc_html_e('Taxonomy (hierarchical)', 'post-expirator'); ?></label></th>
140
  <td>
141
  <?php
142
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
143
  echo _postexpirator_taxonomy(
144
  [
145
+ 'type' => $postType,
146
+ 'name' => 'expirationdate_taxonomy-' . $postType,
147
  'selected' => $defaults['taxonomy']
148
  ]
149
  );
152
  </tr>
153
  <tr valign="top">
154
  <th scope="row"><label for="expirationdate_emailnotification-<?php
155
+ echo esc_attr($postType); ?>"><?php
156
  esc_html_e('Who to notify', 'post-expirator'); ?></label></th>
157
  <td>
158
  <input class="large-text" type="text" name="expirationdate_emailnotification-<?php
159
+ echo esc_attr($postType); ?>" id="expirationdate_emailnotification-<?php
160
+ echo esc_attr($postType); ?>" value="<?php
161
  echo esc_attr($defaults['emailnotification']); ?>"/>
162
  <p class="description"><?php
163
  esc_html_e(
168
  </tr>
169
  <?php
170
  $values = array(
 
171
  'inherit' => esc_html__('Inherit from General Settings', 'post-expirator'),
172
  'custom' => esc_html__('Custom', 'post-expirator'),
173
  'publish' => esc_html__('Publish Time', 'post-expirator'),
184
 
185
  <tr valign="top">
186
  <th scope="row"><label for="expired-default-date-<?php
187
+ echo esc_attr($postType); ?>"><?php
188
  esc_html_e('Default Date/Time Duration', 'post-expirator'); ?></label></th>
189
  <td>
190
  <select name="expired-default-date-<?php
191
+ echo esc_attr($postType); ?>" id="expired-default-date-<?php
192
+ echo esc_attr($postType); ?>" class="pe-custom-date-toggle">
193
  <?php
194
  foreach ($values as $value => $label) { ?>
195
  <option value="<?php
205
  'post-expirator'
206
  ); ?></p>
207
  <div id="expired-custom-container-<?php
208
+ echo esc_attr($postType); ?>" class="pe-custom-date-container" style="display: <?php
209
  echo esc_attr($show); ?>;">
210
  <br/>
211
  <label for="expired-custom-date-<?php
212
+ echo esc_attr($postType); ?>"><?php
213
  esc_html_e('Custom', 'post-expirator'); ?>:</label>
214
  <input type="text" value="<?php
215
  echo esc_attr($customDate); ?>" name="expired-custom-date-<?php
216
+ echo esc_attr($postType); ?>" id="expired-custom-date-<?php
217
+ echo esc_attr($postType); ?>"/>
218
  <p class="description"><?php
219
  echo sprintf(
220
  esc_html__(
{views → legacy/views}/menu-diagnostics.php RENAMED
@@ -1,5 +1,8 @@
1
  <?php
2
  defined('ABSPATH') or die('Direct access not allowed.');
 
 
 
3
  ?>
4
 
5
  <form method="post" id="postExpiratorMenuUpgrade">
@@ -12,7 +15,7 @@ defined('ABSPATH') or die('Direct access not allowed.');
12
  <th scope="row"><label for="postexpirator-log"><?php
13
  esc_html_e('Debug Logging', 'post-expirator'); ?></label></th>
14
  <td>
15
- <?php if (defined('POSTEXPIRATOR_DEBUG') && POSTEXPIRATOR_DEBUG) : ?>
16
  <i class="dashicons dashicons-yes-alt pe-status pe-status-enabled"></i> <span><?php
17
  esc_html_e('Enabled', 'post-expirator'); ?></span>
18
  <?php
1
  <?php
2
  defined('ABSPATH') or die('Direct access not allowed.');
3
+
4
+ $container = PublishPressFuture\Core\DI\Container::getInstance();
5
+ $debug = $container->get(\PublishPressFuture\Core\DI\ServicesAbstract::DEBUG);
6
  ?>
7
 
8
  <form method="post" id="postExpiratorMenuUpgrade">
15
  <th scope="row"><label for="postexpirator-log"><?php
16
  esc_html_e('Debug Logging', 'post-expirator'); ?></label></th>
17
  <td>
18
+ <?php if ($debug->isEnabled()) : ?>
19
  <i class="dashicons dashicons-yes-alt pe-status pe-status-enabled"></i> <span><?php
20
  esc_html_e('Enabled', 'post-expirator'); ?></span>
21
  <?php
{views → legacy/views}/menu-display.php RENAMED
File without changes
{views → legacy/views}/menu-editor.php RENAMED
File without changes
{views → legacy/views}/menu-general.php RENAMED
@@ -10,8 +10,12 @@ $expiredemailnotificationadmins = get_option(
10
  POSTEXPIRATOR_EMAILNOTIFICATIONADMINS
11
  );
12
  $expiredemailnotificationlist = get_option('expirationdateEmailNotificationList', '');
13
- $expirationdateDefaultDate = get_option('expirationdateDefaultDate', POSTEXPIRATOR_EXPIREDEFAULT);
14
- $expirationdateDefaultDateCustom = get_option('expirationdateDefaultDateCustom');
 
 
 
 
15
 
16
  $categories = get_option('expirationdateCategoryDefaults');
17
 
@@ -93,14 +97,11 @@ $plugin_facade = PostExpirator_Facade::getInstance();
93
  <td>
94
  <select name="expired-default-expiration-date" id="expired-default-expiration-date"
95
  class="pe-custom-date-toggle">
96
- <option value="null" <?php
97
- echo ($expirationdateDefaultDate == 'null') ? ' selected="selected"' : ''; ?>><?php
98
- esc_html_e('None', 'post-expirator'); ?></option>
99
  <option value="custom" <?php
100
- echo ($expirationdateDefaultDate == 'custom') ? ' selected="selected"' : ''; ?>><?php
101
  esc_html_e('Custom', 'post-expirator'); ?></option>
102
  <option value="publish" <?php
103
- echo ($expirationdateDefaultDate == 'publish') ? ' selected="selected"' : ''; ?>><?php
104
  esc_html_e('Post/Page Publish Time', 'post-expirator'); ?></option>
105
  </select>
106
  <p class="description"><?php
@@ -156,7 +157,7 @@ $plugin_facade = PostExpirator_Facade::getInstance();
156
  echo '</div>';
157
  ?>
158
  <p class="description"><?php
159
- esc_html_e('Sets the default expiration category for the post.', 'post-expirator'); ?></p>
160
  </td>
161
  </tr>
162
  </table>
10
  POSTEXPIRATOR_EMAILNOTIFICATIONADMINS
11
  );
12
  $expiredemailnotificationlist = get_option('expirationdateEmailNotificationList', '');
13
+
14
+ $container = \PublishPressFuture\Core\DI\Container::getInstance();
15
+ $settingsFacade = $container->get(\PublishPressFuture\Core\DI\ServicesAbstract::SETTINGS);
16
+
17
+ $expirationdateDefaultDate = $settingsFacade->getDefaultDate();
18
+ $expirationdateDefaultDateCustom = $settingsFacade->getDefaultDateCustom();
19
 
20
  $categories = get_option('expirationdateCategoryDefaults');
21
 
97
  <td>
98
  <select name="expired-default-expiration-date" id="expired-default-expiration-date"
99
  class="pe-custom-date-toggle">
 
 
 
100
  <option value="custom" <?php
101
+ echo ($expirationdateDefaultDate == 'custom') ? ' selected="selected"' : ''; ?>><?php
102
  esc_html_e('Custom', 'post-expirator'); ?></option>
103
  <option value="publish" <?php
104
+ echo ($expirationdateDefaultDate == 'publish') ? ' selected="selected"' : ''; ?>><?php
105
  esc_html_e('Post/Page Publish Time', 'post-expirator'); ?></option>
106
  </select>
107
  <p class="description"><?php
157
  echo '</div>';
158
  ?>
159
  <p class="description"><?php
160
+ esc_html_e('Sets the default expiration taxonomy for the post.', 'post-expirator'); ?></p>
161
  </td>
162
  </tr>
163
  </table>
{views → legacy/views}/quick-edit.php RENAMED
@@ -76,7 +76,11 @@ defined('ABSPATH') or die('Direct access not allowed.');
76
  esc_html_e('How to expire', 'post-expirator'); ?></span>
77
  </legend>
78
  <?php
79
- $defaults = get_option('expirationdateDefaults' . ucfirst($post_type));
 
 
 
 
80
  _postexpirator_expire_type(array(
81
  'name' => 'expirationdate_expiretype',
82
  'selected' => empty($defaults) ? 'draft' : $defaults['expireType'],
76
  esc_html_e('How to expire', 'post-expirator'); ?></span>
77
  </legend>
78
  <?php
79
+ $container = \PublishPressFuture\Core\DI\Container::getInstance();
80
+ $settingsFacade = $container->get(\PublishPressFuture\Core\DI\ServicesAbstract::SETTINGS);
81
+
82
+ $defaults = $settingsFacade->getPostTypeDefaults($post_type);
83
+
84
  _postexpirator_expire_type(array(
85
  'name' => 'expirationdate_expiretype',
86
  'selected' => empty($defaults) ? 'draft' : $defaults['expireType'],
{views → legacy/views}/tabs.php RENAMED
@@ -1,8 +1,12 @@
1
  <?php
2
 
3
- defined('ABSPATH') or die('Direct access not allowed.');
4
 
 
 
5
  $current_tab = empty($_GET['tab']) ? 'general' : sanitize_title(wp_unslash($_GET['tab']));
 
 
6
  ?>
7
 
8
  <div class="wrap">
@@ -26,17 +30,17 @@ $current_tab = empty($_GET['tab']) ? 'general' : sanitize_title(wp_unslash($_GET
26
  echo ($current_tab === 'defaults' ? 'nav-tab-active' : ''); ?>"><?php
27
  esc_html_e('Post Types', 'post-expirator'); ?></a>
28
  <a href="<?php
29
- echo esc_url(admin_url('admin.php?page=publishpress-future&tab=diagnostics')); ?>"
30
- class="pe-tab nav-tab <?php
31
- echo ($current_tab === 'diagnostics' ? 'nav-tab-active' : ''); ?>"><?php
32
- esc_html_e('Diagnostics', 'post-expirator'); ?></a>
33
- <a href="<?php
34
  echo esc_url(admin_url('admin.php?page=publishpress-future&tab=advanced')); ?>"
35
  class="pe-tab nav-tab <?php
36
  echo ($current_tab === 'advanced' ? 'nav-tab-active' : ''); ?>"><?php
37
  esc_html_e('Advanced', 'post-expirator'); ?></a>
 
 
 
 
 
38
  <?php
39
- if (POSTEXPIRATOR_DEBUG) { ?>
40
  <a href="<?php
41
  echo esc_url(admin_url('admin.php?page=publishpress-future&tab=viewdebug')); ?>"
42
  class="pe-tab nav-tab <?php
1
  <?php
2
 
3
+ use \PublishPressFuture\Modules\Settings\HooksAbstract;
4
 
5
+ defined('ABSPATH') or die('Direct access not allowed.');
6
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
7
  $current_tab = empty($_GET['tab']) ? 'general' : sanitize_title(wp_unslash($_GET['tab']));
8
+
9
+ $debugIsEnabled = apply_filters(HooksAbstract::FILTER_DEBUG_ENABLED, false);
10
  ?>
11
 
12
  <div class="wrap">
30
  echo ($current_tab === 'defaults' ? 'nav-tab-active' : ''); ?>"><?php
31
  esc_html_e('Post Types', 'post-expirator'); ?></a>
32
  <a href="<?php
 
 
 
 
 
33
  echo esc_url(admin_url('admin.php?page=publishpress-future&tab=advanced')); ?>"
34
  class="pe-tab nav-tab <?php
35
  echo ($current_tab === 'advanced' ? 'nav-tab-active' : ''); ?>"><?php
36
  esc_html_e('Advanced', 'post-expirator'); ?></a>
37
+ <a href="<?php
38
+ echo esc_url(admin_url('admin.php?page=publishpress-future&tab=diagnostics')); ?>"
39
+ class="pe-tab nav-tab <?php
40
+ echo ($current_tab === 'diagnostics' ? 'nav-tab-active' : ''); ?>"><?php
41
+ esc_html_e('Diagnostics', 'post-expirator'); ?></a>
42
  <?php
43
+ if ($debugIsEnabled) { ?>
44
  <a href="<?php
45
  echo esc_url(admin_url('admin.php?page=publishpress-future&tab=viewdebug')); ?>"
46
  class="pe-tab nav-tab <?php
legacy/views/taxonomy-field.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ echo '<select name="' . esc_attr($name) . '" id="' . esc_attr($id) . '"' . ($disabled === true ? ' disabled="disabled"' : '') . ' onchange="' . esc_attr($onchange) . '">';
4
+
5
+ foreach ($taxonomies as $taxonomy) {
6
+ echo '<option value="' . esc_attr($taxonomy->name) . '" ' . ($selected === esc_attr($taxonomy->name) ? 'selected="selected"' : '') . '>' . esc_html($taxonomy->label) . '</option>';
7
+ }
8
+
9
+ echo '</select>';
10
+ echo '<p class="description">' . esc_html__(
11
+ 'Select the hierarchical taxonomy to be used for "category" based expiration.',
12
+ 'post-expirator'
13
+ ) . '</p>';
post-expirator-debug.php CHANGED
@@ -1,103 +1 @@
1
  <?php
2
-
3
- /**
4
- * The class that adds debug entries to the database.
5
- */
6
- class PostExpiratorDebug
7
- {
8
-
9
- /**
10
- * Constructor.
11
- */
12
- public function __construct()
13
- {
14
- global $wpdb;
15
- $this->debug_table = $wpdb->prefix . 'postexpirator_debug';
16
- $this->createDBTable();
17
- }
18
-
19
- /**
20
- * Create Database Table to store debugging information if it does not already exist.
21
- */
22
- private function createDBTable()
23
- {
24
- global $wpdb;
25
-
26
- // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
27
- if ($wpdb->get_var("SHOW TABLES LIKE '" . $this->debug_table . "'") !== $this->debug_table) {
28
- $sql = 'CREATE TABLE `' . $this->debug_table . '` (
29
- `id` INT(9) NOT NULL AUTO_INCREMENT PRIMARY KEY,
30
- `timestamp` TIMESTAMP NOT NULL,
31
- `blog` INT(9) NOT NULL,
32
- `message` text NOT NULL
33
- );';
34
- require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
35
- dbDelta($sql);
36
- }
37
- }
38
-
39
- /**
40
- * Drop Database Table.
41
- */
42
- public function removeDBTable()
43
- {
44
- global $wpdb;
45
- // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
46
- $wpdb->query('DROP TABLE IF EXISTS ' . $this->debug_table);
47
- }
48
-
49
- /**
50
- * Insert into Database Table.
51
- */
52
- public function save($data)
53
- {
54
- global $wpdb;
55
- if (is_multisite()) {
56
- global $current_blog;
57
- $blog = $current_blog->blog_id;
58
- } else {
59
- $blog = 0;
60
- }
61
- $wpdb->query(
62
- // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
63
- $wpdb->prepare(
64
- 'INSERT INTO ' . $this->debug_table . ' (`timestamp`,`message`,`blog`) VALUES (FROM_UNIXTIME(%d),%s,%s)',
65
- time(),
66
- $data['message'],
67
- $blog
68
- )
69
- // phpcs:enable
70
- );
71
- }
72
-
73
- /**
74
- * Get the HTML of the table's data.
75
- */
76
- public function getTable()
77
- {
78
- global $wpdb;
79
- $results = $wpdb->get_results("SELECT * FROM {$this->debug_table} ORDER BY `id` ASC");
80
- if (empty($results)) {
81
- print '<p>' . esc_html__('Debugging table is currently empty.', 'post-expirator') . '</p>';
82
-
83
- return;
84
- }
85
- print '<table class="post-expirator-debug">';
86
- print '<tr><th class="post-expirator-timestamp">' . esc_html__('Timestamp', 'post-expirator') . '</th>';
87
- print '<th>' . esc_html__('Message', 'post-expirator') . '</th></tr>';
88
- foreach ($results as $result) {
89
- print '<tr><td>' . esc_html($result->timestamp) . '</td>';
90
- print '<td>' . esc_html($result->message) . '</td></tr>';
91
- }
92
- print '</table>';
93
- }
94
-
95
- /**
96
- * Truncate Database Table.
97
- */
98
- public function purge()
99
- {
100
- global $wpdb;
101
- $wpdb->query("TRUNCATE TABLE {$this->debug_table}");
102
- }
103
- }
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
post-expirator.php CHANGED
@@ -4,2287 +4,56 @@
4
  * Plugin URI: http://wordpress.org/extend/plugins/post-expirator/
5
  * Description: Allows you to add an expiration date (minute) to posts which you can configure to either delete the post, change it to a draft, or update the post categories at expiration time.
6
  * Author: PublishPress
7
- * Version: 2.7.8
8
  * Author URI: http://publishpress.com
9
  * Text Domain: post-expirator
10
  * Domain Path: /languages
11
  */
12
- $includeFilebRelativePath = '/publishpress/publishpress-instance-protection/include.php';
13
- if (file_exists(__DIR__ . '/vendor' . $includeFilebRelativePath)) {
14
- require_once __DIR__ . '/vendor' . $includeFilebRelativePath;
15
- } else if (defined('POSTEXPIRATOR_VENDOR_PATH') && file_exists(POSTEXPIRATOR_VENDOR_PATH . $includeFilebRelativePath)) {
16
- require_once POSTEXPIRATOR_VENDOR_PATH . $includeFilebRelativePath;
17
- }
18
-
19
- if (class_exists('PublishPressInstanceProtection\\Config')) {
20
- $pluginCheckerConfig = new PublishPressInstanceProtection\Config();
21
- $pluginCheckerConfig->pluginSlug = 'post-expirator';
22
- $pluginCheckerConfig->pluginName = 'PublishPress Future';
23
-
24
- $pluginChecker = new PublishPressInstanceProtection\InstanceChecker($pluginCheckerConfig);
25
- }
26
-
27
- if (! defined('POSTEXPIRATOR_LOADED')) {
28
- // Default Values
29
- define('POSTEXPIRATOR_VERSION', '2.7.8');
30
- define('POSTEXPIRATOR_DATEFORMAT', __('l F jS, Y', 'post-expirator'));
31
- define('POSTEXPIRATOR_TIMEFORMAT', __('g:ia', 'post-expirator'));
32
- define('POSTEXPIRATOR_FOOTERCONTENTS', __('Post expires at EXPIRATIONTIME on EXPIRATIONDATE', 'post-expirator'));
33
- define('POSTEXPIRATOR_FOOTERSTYLE', 'font-style: italic;');
34
- define('POSTEXPIRATOR_FOOTERDISPLAY', '0');
35
- define('POSTEXPIRATOR_EMAILNOTIFICATION', '0');
36
- define('POSTEXPIRATOR_EMAILNOTIFICATIONADMINS', '0');
37
- define('POSTEXPIRATOR_DEBUGDEFAULT', '0');
38
- define('POSTEXPIRATOR_EXPIREDEFAULT', 'null');
39
- define('POSTEXPIRATOR_SLUG', 'post-expirator');
40
- define('POSTEXPIRATOR_BASEDIR', dirname(__FILE__));
41
- define('POSTEXPIRATOR_BASENAME', basename(__FILE__));
42
- define('POSTEXPIRATOR_BASEURL', plugins_url('/', __FILE__));
43
- define('POSTEXPIRATOR_LOADED', true);
44
-
45
- require_once POSTEXPIRATOR_BASEDIR . '/functions.php';
46
-
47
- $autoloadPath = POSTEXPIRATOR_BASEDIR . '/vendor/autoload.php';
48
- if (false === class_exists('PublishPressFuture\\DummyForAutoloadDetection')
49
- && true === file_exists($autoloadPath)
50
- ) {
51
- include_once $autoloadPath;
52
- }
53
-
54
- /**
55
- * Adds links to the plugin listing screen.
56
- *
57
- * @internal
58
- *
59
- * @access private
60
- */
61
- function postexpirator_plugin_action_links($links, $file)
62
- {
63
- $this_plugin = basename(plugin_dir_url(__FILE__)) . '/post-expirator.php';
64
- if ($file === $this_plugin) {
65
- $links[] = '<a href="admin.php?page=publishpress-future">' . __('Settings', 'post-expirator') . '</a>';
66
- }
67
-
68
- return $links;
69
- }
70
-
71
- add_filter('plugin_action_links', 'postexpirator_plugin_action_links', 10, 2);
72
-
73
- /**
74
- * Load translation, if it exists.
75
- *
76
- * @internal
77
- *
78
- * @access private
79
- */
80
- function postexpirator_init()
81
- {
82
- $plugin_dir = plugin_basename(__DIR__);
83
- load_plugin_textdomain('post-expirator', null, $plugin_dir . '/languages/');
84
-
85
- PostExpirator_Reviews::init();
86
-
87
- if (class_exists('WP_CLI')) {
88
- PostExpirator_Cli::getInstance();
89
- }
90
-
91
- add_action('wp_insert_post', 'postexpirator_set_default_meta_for_post', 10, 3);
92
- }
93
-
94
- add_action('plugins_loaded', 'postexpirator_init');
95
-
96
- /**
97
- * Adds an 'Expires' column to the post display table.
98
- *
99
- * @internal
100
- *
101
- * @access private
102
- */
103
- function postexpirator_add_column($columns, $type)
104
- {
105
- $defaults = get_option('expirationdateDefaults' . ucfirst($type));
106
- // if settings are not configured, show the metabox by default only for posts and pages
107
- if ((! isset($defaults['activeMetaBox']) && in_array($type, array(
108
- 'post',
109
- 'page'
110
- ), true)) || (is_array(
111
- $defaults
112
- ) && $defaults['activeMetaBox'] === 'active')) {
113
- $columns['expirationdate'] = __('Expires', 'post-expirator');
114
- }
115
-
116
- return $columns;
117
- }
118
-
119
- add_filter('manage_posts_columns', 'postexpirator_add_column', 10, 2);
120
-
121
- /**
122
- * Adds sortable columns.
123
- *
124
- * @internal
125
- *
126
- * @access private
127
- */
128
- function postexpirator_manage_sortable_columns()
129
- {
130
- $post_types = postexpirator_get_post_types();
131
- foreach ($post_types as $post_type) {
132
- add_filter('manage_edit-' . $post_type . '_sortable_columns', 'postexpirator_sortable_column');
133
- }
134
- }
135
-
136
- add_action('admin_init', 'postexpirator_manage_sortable_columns', 100);
137
-
138
- /**
139
- * Adds an 'Expires' column to the post display table.
140
- *
141
- * @internal
142
- *
143
- * @access private
144
- */
145
- function postexpirator_sortable_column($columns)
146
- {
147
- $columns['expirationdate'] = 'expirationdate';
148
-
149
- return $columns;
150
- }
151
-
152
- /**
153
- * Modify the sorting of posts.
154
- *
155
- * @internal
156
- *
157
- * @access private
158
- */
159
- function postexpirator_orderby($query)
160
- {
161
- if (! is_admin()) {
162
- return;
163
- }
164
-
165
- $orderby = $query->get('orderby');
166
-
167
- if ('expirationdate' === $orderby) {
168
- $query->set(
169
- 'meta_query', array(
170
- 'relation' => 'OR',
171
- array(
172
- 'key' => '_expiration-date',
173
- 'compare' => 'EXISTS',
174
- ),
175
- array(
176
- 'key' => '_expiration-date',
177
- 'compare' => 'NOT EXISTS',
178
- 'value' => '',
179
- ),
180
- )
181
- );
182
- $query->set('orderby', 'meta_value_num');
183
- }
184
- }
185
-
186
- add_action('pre_get_posts', 'postexpirator_orderby');
187
-
188
- /**
189
- * Adds an 'Expires' column to the page display table.
190
- *
191
- * @internal
192
- *
193
- * @access private
194
- */
195
- function postexpirator_add_column_page($columns)
196
- {
197
- $defaults = get_option('expirationdateDefaultsPage');
198
- if (! isset($defaults['activeMetaBox']) || $defaults['activeMetaBox'] === 'active') {
199
- $columns['expirationdate'] = __('Expires', 'post-expirator');
200
- }
201
-
202
- return $columns;
203
- }
204
-
205
- add_filter('manage_pages_columns', 'postexpirator_add_column_page');
206
-
207
- /**
208
- * Fills the 'Expires' column of the post display table.
209
- *
210
- * @internal
211
- *
212
- * @access private
213
- */
214
- function postexpirator_show_value($column_name)
215
- {
216
- if ($column_name !== 'expirationdate') {
217
- return;
218
- }
219
-
220
- global $post;
221
-
222
- // get the attributes that quick edit functionality requires
223
- // and save it as a JSON encoded HTML attribute
224
- $attributes = PostExpirator_Facade::get_expire_principles($post->ID);
225
- PostExpirator_Display::getInstance()->render_template('expire-column', array(
226
- 'id' => $post->ID,
227
- 'post_type' => $post->post_type,
228
- 'attributes' => $attributes
229
- ));
230
- }
231
-
232
- add_action('manage_posts_custom_column', 'postexpirator_show_value');
233
- add_action('manage_pages_custom_column', 'postexpirator_show_value');
234
-
235
-
236
- /**
237
- * Quick Edit functionality.
238
- *
239
- * @internal
240
- *
241
- * @access private
242
- */
243
- function postexpirator_quickedit($column_name, $post_type)
244
- {
245
- if ($column_name !== 'expirationdate') {
246
- return;
247
- }
248
-
249
- $facade = PostExpirator_Facade::getInstance();
250
-
251
- if (! $facade->current_user_can_expire_posts()) {
252
- return;
253
- }
254
-
255
- $defaults = get_option('expirationdateDefaults' . ucfirst($post_type));
256
- $taxonomy = isset($defaults['taxonomy']) ? $defaults['taxonomy'] : '';
257
- $label = '';
258
-
259
- // if settings have not been configured and this is the default post type
260
- if (empty($taxonomy) && 'post' === $post_type) {
261
- $taxonomy = 'category';
262
- }
263
-
264
- if (! empty($taxonomy)) {
265
- $tax_object = get_taxonomy($taxonomy);
266
- $label = $tax_object ? $tax_object->label : '';
267
- }
268
-
269
- PostExpirator_Display::getInstance()->render_template('quick-edit', array(
270
- 'post_type' => $post_type,
271
- 'taxonomy' => $taxonomy,
272
- 'tax_label' => $label
273
- ));
274
- }
275
-
276
- add_action('quick_edit_custom_box', 'postexpirator_quickedit', 10, 2);
277
-
278
- /**
279
- * Bulk Edit functionality.
280
- *
281
- * @internal
282
- *
283
- * @access private
284
- */
285
- function postexpirator_bulkedit($column_name, $post_type)
286
- {
287
- if ($column_name !== 'expirationdate') {
288
- return;
289
- }
290
-
291
- $facade = PostExpirator_Facade::getInstance();
292
-
293
- if (! $facade->current_user_can_expire_posts()) {
294
- return;
295
- }
296
-
297
- $defaults = get_option('expirationdateDefaults' . ucfirst($post_type));
298
- $taxonomy = isset($defaults['taxonomy']) ? $defaults['taxonomy'] : '';
299
- $label = '';
300
-
301
- // if settings have not been configured and this is the default post type
302
- if (empty($taxonomy) && 'post' === $post_type) {
303
- $taxonomy = 'category';
304
- }
305
-
306
- if (! empty($taxonomy)) {
307
- $tax_object = get_taxonomy($taxonomy);
308
- $label = $tax_object ? $tax_object->label : '';
309
- }
310
-
311
- PostExpirator_Display::getInstance()->render_template('bulk-edit', array(
312
- 'post_type' => $post_type,
313
- 'taxonomy' => $taxonomy,
314
- 'tax_label' => $label
315
- ));
316
- }
317
-
318
- add_action('bulk_edit_custom_box', 'postexpirator_bulkedit', 10, 2);
319
-
320
- /**
321
- * Returns the post types that are supported.
322
- *
323
- * @internal
324
- *
325
- * @access private
326
- */
327
- function postexpirator_get_post_types()
328
- {
329
- $post_types = get_post_types(array('public' => true));
330
- $post_types = array_merge(
331
- $post_types,
332
- get_post_types(array(
333
- 'public' => false,
334
- 'show_ui' => true,
335
- '_builtin' => false
336
- ))
337
- );
338
-
339
- // in case some post types should not be supported.
340
- $unset_post_types = apply_filters('postexpirator_unset_post_types', array('attachment'));
341
- if ($unset_post_types) {
342
- foreach ($unset_post_types as $type) {
343
- unset($post_types[$type]);
344
- }
345
- }
346
-
347
- return $post_types;
348
- }
349
-
350
- /**
351
- * Adds hooks to get the meta box added to pages and custom post types
352
- *
353
- * @internal
354
- *
355
- * @access private
356
- */
357
- function postexpirator_meta_custom()
358
- {
359
- $facade = PostExpirator_Facade::getInstance();
360
-
361
- if (! $facade->current_user_can_expire_posts()) {
362
- return;
363
- }
364
-
365
- $post_types = postexpirator_get_post_types();
366
- foreach ($post_types as $type) {
367
- $defaults = get_option('expirationdateDefaults' . ucfirst($type));
368
- // if settings are not configured, show the metabox by default only for posts and pages
369
- if ((! isset($defaults['activeMetaBox']) && in_array($type, array(
370
- 'post',
371
- 'page'
372
- ), true)) || (is_array(
373
- $defaults
374
- ) && $defaults['activeMetaBox'] === 'active')) {
375
- add_meta_box(
376
- 'expirationdatediv',
377
- __('PublishPress Future', 'post-expirator'),
378
- 'postexpirator_meta_box',
379
- $type,
380
- 'side',
381
- 'core',
382
- array('__back_compat_meta_box' => PostExpirator_Facade::show_gutenberg_metabox())
383
- );
384
- }
385
- }
386
- }
387
-
388
- add_action('add_meta_boxes', 'postexpirator_meta_custom');
389
-
390
- /**
391
- * Actually adds the meta box
392
- *
393
- * @internal
394
- *
395
- * @access private
396
- */
397
- function postexpirator_meta_box($post)
398
- {
399
- $postMetaDate = get_post_meta($post->ID, '_expiration-date', true);
400
- $postMetaStatus = get_post_meta($post->ID, '_expiration-date-status', true);
401
-
402
- $expireType = $default = $enabled = '';
403
- $defaultsOption = get_option('expirationdateDefaults' . ucfirst($post->post_type));
404
- if (empty($postMetaDate)) {
405
- $defaultExpire = PostExpirator_Facade::get_default_expiry($post->post_type);
406
-
407
- $defaultMonth = $defaultExpire['month'];
408
- $defaultDay = $defaultExpire['day'];
409
- $defaultHour = $defaultExpire['hour'];
410
- $defaultYear = $defaultExpire['year'];
411
- $defaultMinute = $defaultExpire['minute'];
412
-
413
- $categories = get_option('expirationdateCategoryDefaults');
414
-
415
- if (isset($defaultsOption['expireType'])) {
416
- $expireType = $defaultsOption['expireType'];
417
- }
418
- } else {
419
- $defaultMonth = get_date_from_gmt(gmdate('Y-m-d H:i:s', $postMetaDate), 'm');
420
- $defaultDay = get_date_from_gmt(gmdate('Y-m-d H:i:s', $postMetaDate), 'd');
421
- $defaultYear = get_date_from_gmt(gmdate('Y-m-d H:i:s', $postMetaDate), 'Y');
422
- $defaultHour = get_date_from_gmt(gmdate('Y-m-d H:i:s', $postMetaDate), 'H');
423
- $defaultMinute = get_date_from_gmt(gmdate('Y-m-d H:i:s', $postMetaDate), 'i');
424
-
425
- $attributes = PostExpirator_Facade::get_expire_principles($post->ID);
426
- $expireType = $attributes['expireType'];
427
- $categories = $attributes['category'];
428
- }
429
-
430
- if (PostExpirator_Facade::is_expiration_enabled_for_post($post->ID)) {
431
- $enabled = ' checked="checked"';
432
- }
433
-
434
- PostExpirator_Display::getInstance()->render_template(
435
- 'classic-metabox', [
436
- 'post' => $post,
437
- 'enabled' => $enabled,
438
- 'default' => $default,
439
- 'defaultsOption' => $defaultsOption,
440
- 'defaultmonth' => $defaultMonth,
441
- 'defaultday' => $defaultDay,
442
- 'defaulthour' => $defaultHour,
443
- 'defaultyear' => $defaultYear,
444
- 'defaultminute' => $defaultMinute,
445
- 'categories' => $categories,
446
- 'expireType' => $expireType,
447
- ]
448
- );
449
- }
450
-
451
- function postexpirator_set_default_meta_for_post($postId, $post, $update)
452
- {
453
- if ($update) {
454
- return;
455
- }
456
-
457
- $postTypeDefaults = get_option('expirationdateDefaults' . ucfirst($post->post_type));
458
-
459
- if (empty($postTypeDefaults) || (int)$postTypeDefaults['autoEnable'] !== 1) {
460
- return;
461
- }
462
-
463
- $defaultExpire = PostExpirator_Facade::get_default_expiry($post->post_type);
464
-
465
- $categories = get_option('expirationdateCategoryDefaults');
466
-
467
- $status = ! empty($defaultExpire['ts']) ? 'saved' : '';
468
-
469
- $opts = [
470
- 'expireType' => $postTypeDefaults['expireType'],
471
- 'category' => $categories,
472
- 'categoryTaxonomy' => (string)$postTypeDefaults['taxonomy'],
473
- 'enabled' => $status === 'saved',
474
- ];
475
-
476
- update_post_meta($post->ID, '_expiration-date', $defaultExpire['ts']);
477
- update_post_meta($post->ID, '_expiration-date-status', $status);
478
- update_post_meta($post->ID, '_expiration-date-options', $opts);
479
- update_post_meta($post->ID, '_expiration-date-type', $postTypeDefaults['expireType']);
480
- update_post_meta($post->ID, '_expiration-date-categories', (array)$categories);
481
- update_post_meta($post->ID, '_expiration-date-taxonomy', $opts['categoryTaxonomy']);
482
- }
483
-
484
- /**
485
- * Add's ajax javascript.
486
- *
487
- * @internal
488
- *
489
- * @access private
490
- */
491
- function postexpirator_js_admin_header()
492
- {
493
- $facade = PostExpirator_Facade::getInstance();
494
-
495
- if (! $facade->current_user_can_expire_posts()) {
496
- return;
497
- }
498
- ?>
499
- <script type="text/javascript">
500
- //<![CDATA[
501
- (function ($) {
502
- $(document).ready(function () {
503
- init();
504
- });
505
-
506
- function init() {
507
- $('#enable-expirationdate').on('click', function (e) {
508
- if ($(this).is(':checked')) {
509
- $('.pe-classic-fields').show();
510
- } else {
511
- $('.pe-classic-fields').hide();
512
- }
513
- });
514
-
515
- $('.pe-howtoexpire').on('change', function (e) {
516
- if ($(this).val().indexOf('category') !== -1) {
517
- $('#expired-category-selection').show();
518
- } else {
519
- $('#expired-category-selection').hide();
520
- }
521
- });
522
- }
523
- })(jQuery);
524
- //]]>
525
- </script>
526
- <?php
527
- }
528
-
529
- add_action('admin_head', 'postexpirator_js_admin_header');
530
-
531
- /**
532
- * Called when post is saved - stores expiration-date meta value
533
- *
534
- * @internal
535
- *
536
- * @access private
537
- */
538
- function postexpirator_update_post_meta($id)
539
- {
540
- // don't run the echo if this is an auto save
541
- if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
542
- return;
543
- }
544
-
545
- // don't run the echo if the function is called for saving revision.
546
- $posttype = get_post_type((int) $id);
547
- if ($posttype === 'revision') {
548
- return;
549
- }
550
-
551
- // Do not process Bulk edit here. It is processed on the function "postexpirator_date_save_bulk_edit"
552
- if (isset($_GET['postexpirator_view']) && $_GET['postexpirator_view'] === 'bulk-edit') {
553
- return;
554
- }
555
-
556
- $facade = PostExpirator_Facade::getInstance();
557
-
558
- if (! $facade->current_user_can_expire_posts()) {
559
- return;
560
- }
561
-
562
- $postTypeDefaults = get_option('expirationdateDefaults' . ucfirst($posttype));
563
-
564
- $shouldSchedule = false;
565
- $ts = null;
566
- $opts = [];
567
-
568
- if (isset($_POST['postexpirator_view'])) {
569
- if (defined('DOING_AJAX') && DOING_AJAX) {
570
- check_ajax_referer('__postexpirator', '_postexpiratornonce');
571
- } else {
572
- check_admin_referer('__postexpirator', '_postexpiratornonce');
573
- }
574
-
575
- // Classic editor, quick edit
576
- $shouldSchedule = isset($_POST['enable-expirationdate']);
577
-
578
- $default = get_option('expirationdateDefaultDate', POSTEXPIRATOR_EXPIREDEFAULT);
579
- if ($default === 'publish') {
580
- $month = intval($_POST['mm']);
581
- $day = intval($_POST['jj']);
582
- $year = intval($_POST['aa']);
583
- $hour = intval($_POST['hh']);
584
- $minute = intval($_POST['mn']);
585
- } else {
586
- $month = intval($_POST['expirationdate_month']);
587
- $day = intval($_POST['expirationdate_day']);
588
- $year = intval($_POST['expirationdate_year']);
589
- $hour = intval($_POST['expirationdate_hour']);
590
- $minute = intval($_POST['expirationdate_minute']);
591
-
592
- if (empty($day)) {
593
- $day = date('d');
594
- }
595
- if (empty($year)) {
596
- $year = date('Y');
597
- }
598
- }
599
- $category = isset($_POST['expirationdate_category'])
600
- ? PostExpirator_Util::sanitize_array_of_integers($_POST['expirationdate_category']) : []; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
601
-
602
- $ts = get_gmt_from_date("$year-$month-$day $hour:$minute:0", 'U');
603
-
604
- if (isset($_POST['expirationdate_quickedit'])) {
605
- $opts = PostExpirator_Facade::get_expire_principles($id);
606
- if (isset($_POST['expirationdate_expiretype'])) {
607
- $opts['expireType'] = sanitize_key($_POST['expirationdate_expiretype']);
608
- if (in_array($opts['expireType'], array(
609
- 'category',
610
- 'category-add',
611
- 'category-remove'
612
- ), true)) {
613
- $opts['category'] = $category;
614
- $opts['categoryTaxonomy'] = $postTypeDefaults['taxonomy'];
615
- }
616
- }
617
- } else {
618
- // Schedule/Update Expiration
619
- $opts['expireType'] = sanitize_key($_POST['expirationdate_expiretype']);
620
- $opts['id'] = $id;
621
-
622
- if ($opts['expireType'] === 'category' || $opts['expireType'] === 'category-add' || $opts['expireType'] === 'category-remove') {
623
- if (isset($category) && ! empty($category)) {
624
- $opts['category'] = $category;
625
- $opts['categoryTaxonomy'] = $postTypeDefaults['taxonomy'];
626
- }
627
- }
628
- }
629
- } else {
630
- // Gutenberg or script request
631
- $payload = @file_get_contents('php://input');
632
-
633
- if (empty($payload)) {
634
- $debug = postexpirator_debug();
635
-
636
- if (POSTEXPIRATOR_DEBUG) {
637
- $debug->save(
638
- array(
639
- 'message' => $id . ' -> NO PAYLOAD ON SAVE_POST'
640
- )
641
- );
642
- }
643
-
644
- return;
645
- }
646
-
647
- $payload = @json_decode($payload, true);
648
-
649
- if (isset($payload['meta'])) {
650
- if (isset($payload['meta']['_expiration-date-status'])) {
651
- $shouldSchedule = $payload['meta']['_expiration-date-status'] === 'saved'
652
- && isset($payload['meta']['_expiration-date'])
653
- && false === empty($payload['meta']['_expiration-date']);
654
- } else {
655
- $shouldSchedule = PostExpirator_Facade::is_expiration_enabled_for_post($id);
656
- }
657
-
658
- if ($shouldSchedule) {
659
- if (isset($payload['meta']['_expiration-date'])) {
660
- $ts = sanitize_text_field($payload['meta']['_expiration-date']);
661
- } else {
662
- $ts = get_post_meta($id, '_expiration-date', true);
663
- }
664
-
665
- if (isset($payload['meta']['_expiration-date-type'])) {
666
- $opts['expireType'] = sanitize_key($payload['meta']['_expiration-date-type']);
667
- } else {
668
- $opts['expireType'] = get_post_meta($id, '_expiration-date-type', true);
669
- }
670
-
671
- if (isset($payload['meta']['_expiration-date-categories'])) {
672
- $opts['category'] = PostExpirator_Util::sanitize_array_of_integers($payload['meta']['_expiration-date-categories']);
673
- } else {
674
- $opts['category'] = (array)get_post_meta($id, '_expiration-date-categories', true);
675
- }
676
-
677
- $opts['categoryTaxonomy'] = $postTypeDefaults['taxonomy'];
678
- }
679
- } else {
680
- $shouldSchedule = PostExpirator_Facade::is_expiration_enabled_for_post($id);
681
-
682
- if ($shouldSchedule) {
683
- $ts = get_post_meta($id, '_expiration-date', true);
684
-
685
- $opts['expireType'] = get_post_meta($id, '_expiration-date-type', true);
686
- $opts['category'] = (array)get_post_meta($id, '_expiration-date-categories', true);
687
- $opts['categoryTaxonomy'] = $postTypeDefaults['taxonomy'];
688
- }
689
- }
690
- }
691
-
692
- if ($shouldSchedule) {
693
- $opts['id'] = $id;
694
- postexpirator_schedule_event($id, $ts, $opts);
695
- } else {
696
- postexpirator_unschedule_event($id);
697
- }
698
- }
699
-
700
- add_action('save_post', 'postexpirator_update_post_meta');
701
-
702
- /**
703
- * Schedules the single event.
704
- *
705
- * @internal
706
- *
707
- * @access private
708
- */
709
- function postexpirator_schedule_event($id, $ts, $opts)
710
- {
711
- $debug = postexpirator_debug(); // check for/load debug
712
-
713
- $id = intval($id);
714
-
715
- do_action('postexpirator_schedule', $id, $ts, $opts); // allow custom actions
716
-
717
- if (wp_next_scheduled('postExpiratorExpire', array($id)) !== false) {
718
- $error = wp_clear_scheduled_hook('postExpiratorExpire', array($id), true); // Remove any existing hooks
719
- if (POSTEXPIRATOR_DEBUG) {
720
- $debug->save(
721
- array(
722
- 'message' => $id . ' -> EXISTING CRON EVENT FOUND - UNSCHEDULED - ' . (is_wp_error(
723
- $error
724
- ) ? $error->get_error_message() : 'no error')
725
- )
726
- );
727
- }
728
- }
729
-
730
- $scheduled = wp_schedule_single_event($ts, 'postExpiratorExpire', array($id), true);
731
- if (POSTEXPIRATOR_DEBUG) {
732
- if ($scheduled) {
733
- $debug->save(
734
- array(
735
- 'message' => $id . ' -> CRON EVENT SCHEDULED at ' .
736
- PostExpirator_Util::get_wp_date('r', $ts)
737
- . ' ' . '(' . $ts . ') with options ' . print_r($opts, true) . ' no error'
738
- )
739
- );
740
- } else {
741
- $debug->save(
742
- array(
743
- 'message' => $id . ' -> TRIED TO SCHEDULE CRON EVENT at ' .
744
- PostExpirator_Util::get_wp_date('r', $ts)
745
- . ' ' . '(' . $ts . ') with options ' . print_r($opts, true) . ' ' . (is_wp_error(
746
- $scheduled
747
- ) ? $scheduled->get_error_message() : 'no error')
748
- )
749
- );
750
- }
751
- }
752
-
753
- // Update Post Meta
754
- update_post_meta($id, '_expiration-date', $ts);
755
- if (! is_null($opts)) {
756
- PostExpirator_Facade::set_expire_principles($id, $opts);
757
- }
758
- update_post_meta($id, '_expiration-date-status', 'saved');
759
- }
760
-
761
- /**
762
- * Unschedules the single event.
763
- *
764
- * @internal
765
- *
766
- * @access private
767
- */
768
- function postexpirator_unschedule_event($id)
769
- {
770
- $debug = postexpirator_debug(); // check for/load debug
771
-
772
- do_action('postexpirator_unschedule', $id); // allow custom actions
773
-
774
- delete_post_meta($id, '_expiration-date');
775
- delete_post_meta($id, '_expiration-date-options');
776
- delete_post_meta($id, '_expiration-date-type');
777
- delete_post_meta($id, '_expiration-date-categories');
778
- delete_post_meta($id, '_expiration-date-taxonomy');
779
-
780
- // Delete Scheduled Expiration
781
- if (wp_next_scheduled('postExpiratorExpire', array($id)) !== false) {
782
- wp_clear_scheduled_hook('postExpiratorExpire', array($id)); // Remove any existing hooks
783
- if (POSTEXPIRATOR_DEBUG) {
784
- $debug->save(array('message' => $id . ' -> UNSCHEDULED'));
785
- }
786
- }
787
- delete_post_meta($id, '_expiration-date-status');
788
- }
789
-
790
- /**
791
- * The new expiration function, to work with single scheduled events.
792
- *
793
- * This was designed to hopefully be more flexible for future tweaks/modifications to the architecture.
794
- *
795
- * @internal
796
- *
797
- * @access private
798
- */
799
- function postexpirator_expire_post($id)
800
- {
801
- $debug = postexpirator_debug(); // check for/load debug
802
-
803
- $id = (int)$id;
804
-
805
- if (POSTEXPIRATOR_DEBUG) {
806
- $debug->save(array('message' => 'Called postexpirator_expire_post with id=' . $id));
807
- }
808
-
809
- if (empty($id)) {
810
- if (POSTEXPIRATOR_DEBUG) {
811
- $debug->save(array('message' => 'No Post ID found - exiting'));
812
- }
813
-
814
- return false;
815
- }
816
-
817
- $post = get_post($id);
818
-
819
- if (is_null($post)) {
820
- if (POSTEXPIRATOR_DEBUG) {
821
- $debug->save(array('message' => $id . ' -> Post does not exist - exiting'));
822
- }
823
-
824
- return false;
825
- }
826
-
827
- $postExpireOptions = PostExpirator_Facade::get_expire_principles($id);
828
-
829
- if ($postExpireOptions['enabled'] === false) {
830
- if (POSTEXPIRATOR_DEBUG) {
831
- $debug->save(array('message' => $id . ' -> Post expire data exist but is not activated'));
832
- }
833
-
834
- return false;
835
- }
836
-
837
- $postType = get_post_type($id);
838
- $postTitle = get_the_title($id);
839
- $postLink = get_post_permalink($id);
840
-
841
- $expireType = $expireCategory = $expireCategoryTaxonomy = null;
842
-
843
- if (isset($postExpireOptions['expireType'])) {
844
- $expireType = $postExpireOptions['expireType'];
845
- }
846
-
847
- if (isset($postExpireOptions['category'])) {
848
- $expireCategory = $postExpireOptions['category'];
849
- }
850
-
851
- if (isset($postExpireOptions['categoryTaxonomy'])) {
852
- $expireCategoryTaxonomy = $postExpireOptions['categoryTaxonomy'];
853
- }
854
-
855
- $expirationDate = (int)get_post_meta($id, '_expiration-date', true);
856
-
857
- if (empty($expirationDate)) {
858
- if (POSTEXPIRATOR_DEBUG) {
859
- $debug->save(array('message' => $id . ' -> Tried to expire the post but the expire date is empty'));
860
- }
861
-
862
- return false;
863
- }
864
-
865
- // Check for default expire only if not passed in
866
- if (empty($expireType)) {
867
- $postType = get_post_type($id);
868
- if ($postType === 'page') {
869
- $expireType = strtolower(get_option('expirationdateExpiredPageStatus', POSTEXPIRATOR_PAGESTATUS));
870
- } elseif ($postType === 'post') {
871
- $expireType = strtolower(get_option('expirationdateExpiredPostStatus', 'draft'));
872
- } else {
873
- $expireType = apply_filters(
874
- 'postexpirator_custom_posttype_expire',
875
- $expireType,
876
- $postType
877
- ); // hook to set defaults for custom post types
878
- }
879
- }
880
-
881
- // Remove KSES - wp_cron runs as an unauthenticated user, which will by default trigger kses filtering,
882
- // even if the post was published by a admin user. It is fairly safe here to remove the filter call since
883
- // we are only changing the post status/meta information and not touching the content.
884
- kses_remove_filters();
885
-
886
- $postWasExpired = false;
887
- $expirationLog = [
888
- 'type' => sanitize_text_field($expireType),
889
- 'scheduled_for' => date('Y-m-d H:i:s', $expirationDate)
890
- ];
891
-
892
- // Do Work
893
- if ($expireType === 'draft') {
894
- // TODO: fix this, because wp_update_post returns int or WP_ERROR, not 0. Check other places doing the same.
895
- if (wp_update_post(array('ID' => $id, 'post_status' => 'draft')) === 0) {
896
- if (POSTEXPIRATOR_DEBUG) {
897
- $debug->save(array('message' => $id . ' -> FAILED ' . $expireType . ' ' . print_r($postExpireOptions, true)));
898
- }
899
- } else {
900
- $emailBody = sprintf(
901
- __(
902
- '%1$s (%2$s) has expired at %3$s. Post status has been successfully changed to "%4$s".',
903
- 'post-expirator'
904
- ),
905
- '##POSTTITLE##',
906
- '##POSTLINK##',
907
- '##EXPIRATIONDATE##',
908
- strtoupper($expireType)
909
- );
910
- if (POSTEXPIRATOR_DEBUG) {
911
- $debug->save(
912
- array('message' => $id . ' -> PROCESSED ' . $expireType . ' ' . print_r($postExpireOptions, true))
913
- );
914
- }
915
-
916
- wp_transition_post_status('draft', $post->post_status, $post);
917
-
918
- $postWasExpired = true;
919
- }
920
- } elseif ($expireType === 'private') {
921
- if (wp_update_post(array('ID' => $id, 'post_status' => 'private')) === 0) {
922
- if (POSTEXPIRATOR_DEBUG) {
923
- $debug->save(array('message' => $id . ' -> FAILED ' . $expireType . ' ' . print_r($postExpireOptions, true)));
924
- }
925
- } else {
926
- $emailBody = sprintf(
927
- __(
928
- '%1$s (%2$s) has expired at %3$s. Post status has been successfully changed to "%4$s".',
929
- 'post-expirator'
930
- ),
931
- '##POSTTITLE##',
932
- '##POSTLINK##',
933
- '##EXPIRATIONDATE##',
934
- strtoupper($expireType)
935
- );
936
- if (POSTEXPIRATOR_DEBUG) {
937
- $debug->save(
938
- array('message' => $id . ' -> PROCESSED ' . $expireType . ' ' . print_r($postExpireOptions, true))
939
- );
940
- }
941
-
942
- wp_transition_post_status('private', $post->post_status, $post);
943
-
944
- $postWasExpired = true;
945
- }
946
- } elseif ($expireType === 'delete') {
947
- if (wp_delete_post($id) === false) {
948
- if (POSTEXPIRATOR_DEBUG) {
949
- $debug->save(array('message' => $id . ' -> FAILED ' . $expireType . ' ' . print_r($postExpireOptions, true)));
950
- }
951
- } else {
952
- $emailBody = sprintf(
953
- __(
954
- '%1$s (%2$s) has expired at %3$s. Post status has been successfully changed to "%4$s".',
955
- 'post-expirator'
956
- ),
957
- '##POSTTITLE##',
958
- '##POSTLINK##',
959
- '##EXPIRATIONDATE##',
960
- strtoupper($expireType)
961
- );
962
- if (POSTEXPIRATOR_DEBUG) {
963
- $debug->save(
964
- array('message' => $id . ' -> PROCESSED ' . $expireType . ' ' . print_r($postExpireOptions, true))
965
- );
966
- }
967
-
968
- $postWasExpired = true;
969
- }
970
- } elseif ($expireType === 'trash') {
971
- if (wp_trash_post($id) === false) {
972
- if (POSTEXPIRATOR_DEBUG) {
973
- $debug->save(array('message' => $id . ' -> FAILED ' . $expireType . ' ' . print_r($postExpireOptions, true)));
974
- }
975
- } else {
976
- $emailBody = sprintf(
977
- __(
978
- '%1$s (%2$s) has expired at %3$s. Post status has been successfully changed to "%4$s".',
979
- 'post-expirator'
980
- ),
981
- '##POSTTITLE##',
982
- '##POSTLINK##',
983
- '##EXPIRATIONDATE##',
984
- strtoupper($expireType)
985
- );
986
- if (POSTEXPIRATOR_DEBUG) {
987
- $debug->save(
988
- array('message' => $id . ' -> PROCESSED ' . $expireType . ' ' . print_r($postExpireOptions, true))
989
- );
990
- }
991
-
992
- $postWasExpired = true;
993
- }
994
- } elseif ($expireType === 'stick') {
995
- if (stick_post($id) === false) {
996
- if (POSTEXPIRATOR_DEBUG) {
997
- $debug->save(array('message' => $id . ' -> FAILED ' . $expireType . ' ' . print_r($postExpireOptions, true)));
998
- }
999
- } else {
1000
- $emailBody = sprintf(
1001
- __('%1$s (%2$s) has expired at %3$s. Post "%4$s" status has been successfully set.', 'post-expirator'),
1002
- '##POSTTITLE##',
1003
- '##POSTLINK##',
1004
- '##EXPIRATIONDATE##',
1005
- 'STICKY'
1006
- );
1007
- if (POSTEXPIRATOR_DEBUG) {
1008
- $debug->save(
1009
- array('message' => $id . ' -> PROCESSED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1010
- );
1011
- }
1012
-
1013
- $postWasExpired = true;
1014
- }
1015
- } elseif ($expireType === 'unstick') {
1016
- if (unstick_post($id) === false) {
1017
- if (POSTEXPIRATOR_DEBUG) {
1018
- $debug->save(array('message' => $id . ' -> FAILED ' . $expireType . ' ' . print_r($postExpireOptions, true)));
1019
- }
1020
- } else {
1021
- $emailBody = sprintf(
1022
- __(
1023
- '%1$s (%2$s) has expired at %3$s. Post "%4$s" status has been successfully removed.',
1024
- 'post-expirator'
1025
- ),
1026
- '##POSTTITLE##',
1027
- '##POSTLINK##',
1028
- '##EXPIRATIONDATE##',
1029
- 'STICKY'
1030
- );
1031
- if (POSTEXPIRATOR_DEBUG) {
1032
- $debug->save(
1033
- array('message' => $id . ' -> PROCESSED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1034
- );
1035
- }
1036
 
1037
- $postWasExpired = true;
1038
- }
1039
- } elseif ($expireType === 'category') {
1040
- if (! empty($expireCategory)) {
1041
- if (empty($expireCategoryTaxonomy) || $expireCategoryTaxonomy === 'category') {
1042
- $expirationLog['taxonomy'] = 'category';
1043
 
1044
- if (wp_update_post(array('ID' => $id, 'post_category' => $expireCategory)) === 0) {
1045
- if (POSTEXPIRATOR_DEBUG) {
1046
- $debug->save(
1047
- array('message' => $id . ' -> FAILED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1048
- );
1049
- }
1050
- } else {
1051
- $emailBody = sprintf(
1052
- __(
1053
- '%1$s (%2$s) has expired at %3$s. Post "%4$s" have now been set to "%5$s".',
1054
- 'post-expirator'
1055
- ),
1056
- '##POSTTITLE##',
1057
- '##POSTLINK##',
1058
- '##EXPIRATIONDATE##',
1059
- 'CATEGORIES',
1060
- implode(',', _postexpirator_get_cat_names($expireCategory))
1061
- );
1062
- if (POSTEXPIRATOR_DEBUG) {
1063
- $debug->save(
1064
- array('message' => $id . ' -> PROCESSED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1065
- );
1066
- $debug->save(
1067
- array(
1068
- 'message' => $id . ' -> CATEGORIES REPLACED ' . print_r(
1069
- _postexpirator_get_cat_names($expireCategory),
1070
- true
1071
- )
1072
- )
1073
- );
1074
- $debug->save(
1075
- array(
1076
- 'message' => $id . ' -> CATEGORIES COMPLETE ' . print_r(
1077
- _postexpirator_get_cat_names($expireCategory),
1078
- true
1079
- )
1080
- )
1081
- );
1082
- }
1083
 
1084
- $postWasExpired = true;
1085
- }
1086
- } else {
1087
- $terms = PostExpirator_Util::sanitize_array_of_integers($expireCategory);
1088
-
1089
- $expirationLog['taxonomy'] = $expireCategoryTaxonomy;
1090
- $expirationLog['terms'] = $terms;
1091
-
1092
- if (is_wp_error(wp_set_object_terms($id, $terms, $expireCategoryTaxonomy, false))) {
1093
- if (POSTEXPIRATOR_DEBUG) {
1094
- $debug->save(
1095
- array('message' => $id . ' -> FAILED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1096
- );
1097
- }
1098
- } else {
1099
- // TODO: Use the sanitized variable instead
1100
- $emailBody = sprintf(
1101
- __(
1102
- '%1$s (%2$s) has expired at %3$s. Post "%4$s" have now been set to "%5$s".',
1103
- 'post-expirator'
1104
- ),
1105
- '##POSTTITLE##',
1106
- '##POSTLINK##',
1107
- '##EXPIRATIONDATE##',
1108
- 'CATEGORIES',
1109
- implode(',', _postexpirator_get_cat_names($expireCategory))
1110
- );
1111
- if (POSTEXPIRATOR_DEBUG) {
1112
- $debug->save(
1113
- array('message' => $id . ' -> PROCESSED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1114
- );
1115
- $debug->save(
1116
- array(
1117
- 'message' => $id . ' -> CATEGORIES REPLACED ' . print_r(
1118
- _postexpirator_get_cat_names($expireCategory),
1119
- true
1120
- )
1121
- )
1122
- );
1123
- $debug->save(
1124
- array(
1125
- 'message' => $id . ' -> CATEGORIES COMPLETE ' . print_r(
1126
- _postexpirator_get_cat_names($expireCategory),
1127
- true
1128
- )
1129
- )
1130
- );
1131
- }
1132
-
1133
- $postWasExpired = true;
1134
- }
1135
- }
1136
- } else {
1137
- if (POSTEXPIRATOR_DEBUG) {
1138
- $debug->save(
1139
- array(
1140
- 'message' => $id . ' -> CATEGORIES MISSING ' . $expireType . ' ' . print_r(
1141
- $postExpireOptions,
1142
- true
1143
- )
1144
- )
1145
- );
1146
- }
1147
- }
1148
- } elseif ($expireType === 'category-add') {
1149
- if (! empty($expireCategory)) {
1150
- if (empty($expireCategoryTaxonomy) || $expireCategoryTaxonomy === 'category') {
1151
- $expirationLog['taxonomy'] = 'category';
1152
- $expirationLog['terms'] = $expireCategory;
1153
-
1154
- $postCategories = wp_get_post_categories($id);
1155
- $mergedCategories = array_merge($postCategories, $expireCategory);
1156
- if (wp_update_post(array('ID' => $id, 'post_category' => $mergedCategories)) === 0) {
1157
- if (POSTEXPIRATOR_DEBUG) {
1158
- $debug->save(
1159
- array('message' => $id . ' -> FAILED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1160
- );
1161
- }
1162
- } else {
1163
- $emailBody = sprintf(
1164
- __(
1165
- '%1$s (%2$s) has expired at %3$s. The following post "%4$s" have now been added: "%5$s". The full list of categories on the post are: "%6$s".',
1166
- 'post-expirator'
1167
- ),
1168
- '##POSTTITLE##',
1169
- '##POSTLINK##',
1170
- '##EXPIRATIONDATE##',
1171
- 'CATEGORIES',
1172
- implode(',', _postexpirator_get_cat_names($expireCategory)),
1173
- implode(',', _postexpirator_get_cat_names($mergedCategories))
1174
- );
1175
- if (POSTEXPIRATOR_DEBUG) {
1176
- $debug->save(
1177
- array('message' => $id . ' -> PROCESSED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1178
- );
1179
- $debug->save(
1180
- array(
1181
- 'message' => $id . ' -> CATEGORIES ADDED ' . print_r(
1182
- _postexpirator_get_cat_names($expireCategory),
1183
- true
1184
- )
1185
- )
1186
- );
1187
- $debug->save(
1188
- array(
1189
- 'message' => $id . ' -> CATEGORIES COMPLETE ' . print_r(
1190
- _postexpirator_get_cat_names($mergedCategories),
1191
- true
1192
- )
1193
- )
1194
- );
1195
- }
1196
-
1197
- $postWasExpired = true;
1198
- }
1199
- } else {
1200
- $terms = PostExpirator_Util::sanitize_array_of_integers($expireCategory);
1201
-
1202
- ray($terms, $expireCategory, $expireCategoryTaxonomy);
1203
-
1204
- $expirationLog['taxonomy'] = $expireCategoryTaxonomy;
1205
- $expirationLog['terms'] = $terms;
1206
-
1207
- if (is_wp_error(wp_set_object_terms($id, $terms, $expireCategoryTaxonomy, true))) {
1208
- if (POSTEXPIRATOR_DEBUG) {
1209
- $debug->save(
1210
- array('message' => $id . ' -> FAILED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1211
- );
1212
- }
1213
- } else {
1214
- $emailBody = sprintf(
1215
- __(
1216
- '%1$s (%2$s) has expired at %3$s. The following post "%4$s" have now been added: "%5$s". The full list of categories on the post are: "%6$s".',
1217
- 'post-expirator'
1218
- ),
1219
- '##POSTTITLE##',
1220
- '##POSTLINK##',
1221
- '##EXPIRATIONDATE##',
1222
- 'CATEGORIES',
1223
- implode(',', _postexpirator_get_cat_names($expireCategory)),
1224
- implode(',', _postexpirator_get_cat_names($terms))
1225
- );
1226
- if (POSTEXPIRATOR_DEBUG) {
1227
- $debug->save(
1228
- array('message' => $id . ' -> PROCESSED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1229
- );
1230
- $debug->save(
1231
- array(
1232
- 'message' => $id . ' -> CATEGORIES ADDED ' . print_r(
1233
- _postexpirator_get_cat_names($expireCategory),
1234
- true
1235
- )
1236
- )
1237
- );
1238
- $debug->save(
1239
- array(
1240
- 'message' => $id . ' -> CATEGORIES COMPLETE ' . print_r(
1241
- _postexpirator_get_cat_names($expireCategory),
1242
- true
1243
- )
1244
- )
1245
- );
1246
- }
1247
-
1248
- $postWasExpired = true;
1249
- }
1250
- }
1251
- } else {
1252
- if (POSTEXPIRATOR_DEBUG) {
1253
- $debug->save(
1254
- array(
1255
- 'message' => $id . ' -> CATEGORIES MISSING ' . $expireType . ' ' . print_r(
1256
- $postExpireOptions,
1257
- true
1258
- )
1259
- )
1260
- );
1261
- }
1262
- }
1263
- } elseif ($expireType === 'category-remove') {
1264
- if (! empty($expireCategory)) {
1265
- if (empty($expireCategoryTaxonomy) || $expireCategoryTaxonomy === 'category') {
1266
- $expirationLog['taxonomy'] = 'category';
1267
- $expirationLog['terms'] = $expireCategory;
1268
-
1269
- $postCategories = wp_get_post_categories($id);
1270
- $mergedCategories = array();
1271
- foreach ($postCategories as $category) {
1272
- if (! in_array($category, $expireCategory, false)) {
1273
- $mergedCategories[] = $category;
1274
- }
1275
- }
1276
-
1277
- if (wp_update_post(array('ID' => $id, 'post_category' => $mergedCategories)) === 0) {
1278
- if (POSTEXPIRATOR_DEBUG) {
1279
- $debug->save(
1280
- array('message' => $id . ' -> FAILED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1281
- );
1282
- }
1283
- } else {
1284
- $emailBody = sprintf(
1285
- __(
1286
- '%1$s (%2$s) has expired at %3$s. The following post "%4$s" have now been removed: "%5$s". The full list of categories on the post are: "%6$s".',
1287
- 'post-expirator'
1288
- ),
1289
- '##POSTTITLE##',
1290
- '##POSTLINK##',
1291
- '##EXPIRATIONDATE##',
1292
- 'CATEGORIES',
1293
- implode(',', _postexpirator_get_cat_names($expireCategory)),
1294
- implode(',', _postexpirator_get_cat_names($mergedCategories))
1295
- );
1296
- if (POSTEXPIRATOR_DEBUG) {
1297
- $debug->save(
1298
- array('message' => $id . ' -> PROCESSED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1299
- );
1300
- $debug->save(
1301
- array(
1302
- 'message' => $id . ' -> CATEGORIES REMOVED ' . print_r(
1303
- _postexpirator_get_cat_names($expireCategory),
1304
- true
1305
- )
1306
- )
1307
- );
1308
- $debug->save(
1309
- array(
1310
- 'message' => $id . ' -> CATEGORIES COMPLETE ' . print_r(
1311
- _postexpirator_get_cat_names($mergedCategories),
1312
- true
1313
- )
1314
- )
1315
- );
1316
- }
1317
-
1318
- $postWasExpired = true;
1319
- }
1320
- } else {
1321
- $terms = wp_get_object_terms($id, $expireCategoryTaxonomy, array('fields' => 'ids'));
1322
-
1323
- $expirationLog['taxonomy'] = $expireCategoryTaxonomy;
1324
- $expirationLog['terms'] = $terms;
1325
-
1326
- $mergedCategories = array();
1327
- foreach ($terms as $term) {
1328
- if (! in_array($term, $expireCategory, false)) {
1329
- $mergedCategories[] = $term;
1330
- }
1331
- }
1332
- $terms = PostExpirator_Util::sanitize_array_of_integers($mergedCategories);
1333
- if (is_wp_error(wp_set_object_terms($id, $terms, $expireCategoryTaxonomy, false))) {
1334
- if (POSTEXPIRATOR_DEBUG) {
1335
- $debug->save(
1336
- array('message' => $id . ' -> FAILED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1337
- );
1338
- }
1339
- } else {
1340
- $emailBody = sprintf(
1341
- __(
1342
- '%1$s (%2$s) has expired at %3$s. The following post "%4$s" have now been removed: "%5$s". The full list of categories on the post are: "%6$s".',
1343
- 'post-expirator'
1344
- ),
1345
- '##POSTTITLE##',
1346
- '##POSTLINK##',
1347
- '##EXPIRATIONDATE##',
1348
- 'CATEGORIES',
1349
- implode(',', _postexpirator_get_cat_names($expireCategory)),
1350
- implode(',', _postexpirator_get_cat_names($mergedCategories))
1351
- );
1352
- if (POSTEXPIRATOR_DEBUG) {
1353
- $debug->save(
1354
- array('message' => $id . ' -> PROCESSED ' . $expireType . ' ' . print_r($postExpireOptions, true))
1355
- );
1356
- $debug->save(
1357
- array(
1358
- 'message' => $id . ' -> CATEGORIES REMOVED ' . print_r(
1359
- _postexpirator_get_cat_names($expireCategory),
1360
- true
1361
- )
1362
- )
1363
- );
1364
- $debug->save(
1365
- array(
1366
- 'message' => $id . ' -> CATEGORIES COMPLETE ' . print_r(
1367
- _postexpirator_get_cat_names($expireCategory),
1368
- true
1369
- )
1370
- )
1371
- );
1372
- }
1373
-
1374
- $postWasExpired = true;
1375
- }
1376
- }
1377
- } else {
1378
- if (POSTEXPIRATOR_DEBUG) {
1379
- $debug->save(
1380
- array(
1381
- 'message' => $id . ' -> CATEGORIES MISSING ' . $expireType . ' ' . print_r(
1382
- $postExpireOptions,
1383
- true
1384
- )
1385
- )
1386
- );
1387
- }
1388
- }
1389
  }
1390
 
1391
- // Process Email
1392
- $emailEnabled = get_option('expirationdateEmailNotification', POSTEXPIRATOR_EMAILNOTIFICATION);
1393
-
1394
- $expirationLog['email_enabled'] = (bool) $emailEnabled;
1395
-
1396
- // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1397
- if ($emailEnabled == 1 && isset($emailBody)) {
1398
- $emailSubject = sprintf(__('Post Expiration Complete "%s"', 'post-expirator'), $postTitle);
1399
- $emailBody = str_replace('##POSTTITLE##', $postTitle, $emailBody);
1400
- $emailBody = str_replace('##POSTLINK##', $postLink, $emailBody);
1401
- $emailBody = str_replace(
1402
- '##EXPIRATIONDATE##',
1403
- get_date_from_gmt(
1404
- gmdate('Y-m-d H:i:s', $expirationDate),
1405
- get_option('date_format') . ' ' . get_option('time_format')
1406
- ),
1407
- $emailBody
1408
- );
1409
-
1410
- $emailsToSend = array();
1411
 
1412
- // Get Blog Admins
1413
- $blogAdmins = get_option('expirationdateEmailNotificationAdmins', POSTEXPIRATOR_EMAILNOTIFICATIONADMINS);
1414
- // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1415
- if ($blogAdmins == 1) {
1416
- $blogUsers = get_users('role=Administrator');
1417
- foreach ($blogUsers as $user) {
1418
- $emailsToSend[] = $user->user_email;
1419
- }
1420
- }
1421
 
1422
- // Get Global Notification Emails
1423
- $emailsList = get_option('expirationdateEmailNotificationList');
1424
- if (! empty($emailsList)) {
1425
- $values = explode(',', $emailsList);
1426
- foreach ($values as $value) {
1427
- $emailsToSend[] = trim($value);
1428
- }
1429
- }
1430
 
1431
- // Get Post Type Notification Emails
1432
- $defaults = get_option('expirationdateDefaults' . ucfirst($postType));
1433
- if (isset($defaults['emailnotification']) && ! empty($defaults['emailnotification'])) {
1434
- $values = explode(',', $defaults['emailnotification']);
1435
- foreach ($values as $value) {
1436
- $emailsToSend[] = trim($value);
1437
- }
1438
- }
1439
 
1440
- $emailsToSend = array_unique($emailsToSend);
 
 
1441
 
1442
- if (! empty($emailsToSend)) {
1443
- if (POSTEXPIRATOR_DEBUG) {
1444
- $debug->save(array('message' => $id . ' -> SENDING EMAIL TO (' . implode(', ', $emailsToSend) . ')'));
1445
- }
1446
 
1447
- // Send Emails
1448
- foreach ($emailsToSend as $email) {
1449
- if (wp_mail($email, sprintf(__('[%1$s] %2$s'), get_option('blogname'), $emailSubject), $emailBody)) {
1450
- if (POSTEXPIRATOR_DEBUG) {
1451
- $debug->save(array('message' => $id . ' -> EXPIRATION EMAIL SENT (' . $email . ')'));
1452
- }
1453
-
1454
- $expirationLog['email_sent'] = true;
1455
- } else {
1456
- if (POSTEXPIRATOR_DEBUG) {
1457
- $debug->save(array('message' => $id . ' -> EXPIRATION EMAIL FAILED (' . $email . ')'));
1458
- }
1459
-
1460
- $expirationLog['email_sent'] = false;
1461
- }
1462
- }
1463
- }
1464
  }
1465
 
1466
- if (true === $postWasExpired) {
1467
- postexpirator_register_expiration_meta($id, $expirationLog);
1468
- postexpirator_unschedule_event($id);
1469
- }
1470
- }
1471
-
1472
- add_action('postExpiratorExpire', 'postexpirator_expire_post');
1473
-
1474
- function postexpirator_register_expiration_meta($id, $log)
1475
- {
1476
- $log['expired_on'] = date('Y-m-d H:i:s');
1477
-
1478
- add_post_meta($id, 'expiration_log', wp_json_encode($log));
1479
- }
1480
-
1481
- /**
1482
- * Internal method to get category names corresponding to the category IDs.
1483
- *
1484
- * @internal
1485
- *
1486
- * @access private
1487
- */
1488
- function _postexpirator_get_cat_names($cats)
1489
- {
1490
- $out = array();
1491
- foreach ($cats as $cat) {
1492
- $out[$cat] = get_the_category_by_id($cat);
1493
- }
1494
-
1495
- return $out;
1496
- }
1497
-
1498
-
1499
- /**
1500
- * Show the menu.
1501
- *
1502
- * @internal
1503
- *
1504
- * @access private
1505
- */
1506
- function postexpirator_menu()
1507
- {
1508
- _deprecated_function(__FUNCTION__, '2.5');
1509
- }
1510
-
1511
- /**
1512
- * Hook's to add plugin page menu
1513
- *
1514
- * @internal
1515
- *
1516
- * @access private
1517
- */
1518
- function postexpirator_add_menu()
1519
- {
1520
- _deprecated_function(__FUNCTION__, '2.5');
1521
- }
1522
-
1523
- /**
1524
- * Show the Expiration Date options page
1525
- *
1526
- * @internal
1527
- *
1528
- * @access private
1529
- */
1530
- function postexpirator_menu_general()
1531
- {
1532
- _deprecated_function(__FUNCTION__, '2.5');
1533
- PostExpirator_Display::getInstance()->load_tab('general');
1534
- }
1535
-
1536
- /**
1537
- * The default menu.
1538
- *
1539
- * @internal
1540
- *
1541
- * @access private
1542
- */
1543
- function postexpirator_menu_defaults()
1544
- {
1545
- _deprecated_function(__FUNCTION__, '2.5');
1546
- PostExpirator_Display::getInstance()->load_tab('defaults');
1547
- }
1548
-
1549
- /**
1550
- * Diagnostics menu.
1551
- *
1552
- * @internal
1553
- *
1554
- * @access private
1555
- */
1556
- function postexpirator_menu_diagnostics()
1557
- {
1558
- _deprecated_function(__FUNCTION__, '2.5');
1559
- PostExpirator_Display::getInstance()->load_tab('diagnostics');
1560
- }
1561
-
1562
- /**
1563
- * Debug menu.
1564
- *
1565
- * @internal
1566
- *
1567
- * @access private
1568
- */
1569
- function postexpirator_menu_debug()
1570
- {
1571
- _deprecated_function(__FUNCTION__, '2.5');
1572
- PostExpirator_Display::getInstance()->load_tab('viewdebug');
1573
- }
1574
-
1575
- /**
1576
- * Register the shortcode.
1577
- *
1578
- * @internal
1579
- *
1580
- * @access private
1581
- */
1582
- function postexpirator_shortcode($atts)
1583
- {
1584
- global $post;
1585
-
1586
- $enabled = PostExpirator_Facade::is_expiration_enabled_for_post($post->ID);
1587
- $expirationdatets = get_post_meta($post->ID, '_expiration-date', true);
1588
- if (! $enabled || empty($expirationdatets)) {
1589
- return false;
1590
- }
1591
-
1592
- // @TODO remove extract
1593
- // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
1594
- extract(
1595
- shortcode_atts(
1596
- array(
1597
- 'dateformat' => get_option('expirationdateDefaultDateFormat', POSTEXPIRATOR_DATEFORMAT),
1598
- 'timeformat' => get_option('expirationdateDefaultTimeFormat', POSTEXPIRATOR_TIMEFORMAT),
1599
- 'type' => 'full',
1600
- 'tz' => date('T'),
1601
- ),
1602
- $atts
1603
- )
1604
  );
1605
 
1606
- if (empty($dateformat)) {
1607
- global $expirationdateDefaultDateFormat;
1608
- $dateformat = $expirationdateDefaultDateFormat;
1609
- }
1610
-
1611
- if (empty($timeformat)) {
1612
- global $expirationdateDefaultTimeFormat;
1613
- $timeformat = $expirationdateDefaultTimeFormat;
1614
- }
1615
 
1616
- if ($type === 'full') {
1617
- $format = $dateformat . ' ' . $timeformat;
1618
- } elseif ($type === 'date') {
1619
- $format = $dateformat;
1620
- } elseif ($type === 'time') {
1621
- $format = $timeformat;
1622
- }
1623
-
1624
- return PostExpirator_Util::get_wp_date($format, $expirationdatets);
1625
  }
1626
-
1627
- add_shortcode('postexpirator', 'postexpirator_shortcode');
1628
-
1629
- /**
1630
- * Add the footer.
1631
- *
1632
- * @internal
1633
- *
1634
- * @access private
1635
- */
1636
- function postexpirator_add_footer($text)
1637
- {
1638
- global $post;
1639
-
1640
- // Check to see if its enabled
1641
- $displayFooter = get_option('expirationdateDisplayFooter');
1642
-
1643
- // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1644
- if ($displayFooter === false || $displayFooter == 0) {
1645
- return $text;
1646
- }
1647
-
1648
- $enabled = PostExpirator_Facade::is_expiration_enabled_for_post($post->ID);
1649
-
1650
- if (empty($enabled)) {
1651
- return $text;
1652
- }
1653
-
1654
- $expirationdatets = get_post_meta($post->ID, '_expiration-date', true);
1655
- if (! is_numeric($expirationdatets)) {
1656
- return $text;
1657
- }
1658
-
1659
- $dateformat = get_option('expirationdateDefaultDateFormat', POSTEXPIRATOR_DATEFORMAT);
1660
- $timeformat = get_option('expirationdateDefaultTimeFormat', POSTEXPIRATOR_TIMEFORMAT);
1661
- $expirationdateFooterContents = get_option('expirationdateFooterContents', POSTEXPIRATOR_FOOTERCONTENTS);
1662
- $expirationdateFooterStyle = get_option('expirationdateFooterStyle', POSTEXPIRATOR_FOOTERSTYLE);
1663
-
1664
- $search = array(
1665
- 'EXPIRATIONFULL',
1666
- 'EXPIRATIONDATE',
1667
- 'EXPIRATIONTIME',
1668
- );
1669
-
1670
- $replace = array(
1671
- PostExpirator_Util::get_wp_date("$dateformat $timeformat", $expirationdatets),
1672
- PostExpirator_Util::get_wp_date($dateformat, $expirationdatets),
1673
- PostExpirator_Util::get_wp_date($timeformat, $expirationdatets)
1674
- );
1675
-
1676
- $add_to_footer = '<p style="' . $expirationdateFooterStyle . '">' . str_replace(
1677
- $search,
1678
- $replace,
1679
- $expirationdateFooterContents
1680
- ) . '</p>';
1681
-
1682
- return $text . $add_to_footer;
1683
- }
1684
-
1685
- add_action('the_content', 'postexpirator_add_footer', 0);
1686
-
1687
- /**
1688
- * Check for Debug
1689
- *
1690
- * @internal
1691
- *
1692
- * @access private
1693
- */
1694
- function postexpirator_debug()
1695
- {
1696
- $debug = get_option('expirationdateDebug');
1697
- // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1698
- if ($debug == 1) {
1699
- if (! defined('POSTEXPIRATOR_DEBUG')) {
1700
- define('POSTEXPIRATOR_DEBUG', 1);
1701
- }
1702
- require_once(POSTEXPIRATOR_BASEDIR . '/post-expirator-debug.php'); // Load Class
1703
-
1704
- return new PostExpiratorDebug();
1705
- } else {
1706
- if (! defined('POSTEXPIRATOR_DEBUG')) {
1707
- define('POSTEXPIRATOR_DEBUG', 0);
1708
- }
1709
-
1710
- return false;
1711
- }
1712
- }
1713
-
1714
-
1715
- /**
1716
- * Add Stylesheet
1717
- *
1718
- * @internal
1719
- *
1720
- * @access private
1721
- */
1722
- function postexpirator_css($screen_id)
1723
- {
1724
- switch ($screen_id) {
1725
- case 'post.php':
1726
- case 'post-new.php':
1727
- case 'settings_page_post-expirator':
1728
- wp_enqueue_style(
1729
- 'postexpirator-css',
1730
- POSTEXPIRATOR_BASEURL . '/assets/css/style.css',
1731
- array(),
1732
- POSTEXPIRATOR_VERSION
1733
- );
1734
- break;
1735
- case 'edit.php':
1736
- wp_enqueue_style(
1737
- 'postexpirator-edit',
1738
- POSTEXPIRATOR_BASEURL . '/assets/css/edit.css',
1739
- array(),
1740
- POSTEXPIRATOR_VERSION
1741
- );
1742
- break;
1743
- }
1744
- }
1745
-
1746
- add_action('admin_enqueue_scripts', 'postexpirator_css', 10, 1);
1747
-
1748
- /**
1749
- * PublishPress Future Activation/Upgrade
1750
- *
1751
- * @internal
1752
- *
1753
- * @access private
1754
- */
1755
- function postexpirator_upgrade()
1756
- {
1757
- // Check for current version, if not exists, run activation
1758
- $version = get_option('postexpiratorVersion');
1759
- if ($version === false) { // not installed, run default activation
1760
- postexpirator_activate();
1761
- update_option('postexpiratorVersion', POSTEXPIRATOR_VERSION);
1762
- } else {
1763
- if (version_compare($version, '1.6.1') === -1) {
1764
- update_option('postexpiratorVersion', POSTEXPIRATOR_VERSION);
1765
- update_option('expirationdateDefaultDate', POSTEXPIRATOR_EXPIREDEFAULT);
1766
- }
1767
-
1768
- if (version_compare($version, '1.6.2') === -1) {
1769
- update_option('postexpiratorVersion', POSTEXPIRATOR_VERSION);
1770
- }
1771
-
1772
- if (version_compare($version, '2.0.0-rc1') === -1) {
1773
- global $wpdb;
1774
-
1775
- // Schedule Events/Migrate Config
1776
- $results = $wpdb->get_results(
1777
- $wpdb->prepare(
1778
- 'select post_id, meta_value from ' . $wpdb->postmeta . ' as postmeta, ' . $wpdb->posts . ' as posts where postmeta.post_id = posts.ID AND postmeta.meta_key = %s AND postmeta.meta_value >= %d',
1779
- 'expiration-date',
1780
- time()
1781
- )
1782
- );
1783
- foreach ($results as $result) {
1784
- wp_schedule_single_event($result->meta_value, 'postExpiratorExpire', array($result->post_id));
1785
- $opts = array();
1786
- $opts['id'] = $result->post_id;
1787
- $posttype = get_post_type($result->post_id);
1788
- if ($posttype === 'page') {
1789
- $opts['expireType'] = strtolower(get_option('expirationdateExpiredPageStatus', 'Draft'));
1790
- } else {
1791
- $opts['expireType'] = strtolower(get_option('expirationdateExpiredPostStatus', 'Draft'));
1792
- }
1793
-
1794
- $cat = get_post_meta($result->post_id, '_expiration-date-category', true);
1795
- if ((isset($cat) && ! empty($cat))) {
1796
- $opts['category'] = $cat;
1797
- $opts['expireType'] = 'category';
1798
- }
1799
-
1800
- PostExpirator_Facade::set_expire_principles($result->post_id, $opts);
1801
- }
1802
-
1803
- // update meta key to new format
1804
- $wpdb->query(
1805
- $wpdb->prepare(
1806
- "UPDATE $wpdb->postmeta SET meta_key = %s WHERE meta_key = %s",
1807
- '_expiration-date',
1808
- 'expiration-date'
1809
- )
1810
- );
1811
-
1812
- // migrate defaults
1813
- $pagedefault = get_option('expirationdateExpiredPageStatus');
1814
- $postdefault = get_option('expirationdateExpiredPostStatus');
1815
- if ($pagedefault) {
1816
- update_option('expirationdateDefaultsPage', array('expireType' => $pagedefault));
1817
- }
1818
- if ($postdefault) {
1819
- update_option('expirationdateDefaultsPost', array('expireType' => $postdefault));
1820
- }
1821
-
1822
- delete_option('expirationdateCronSchedule');
1823
- delete_option('expirationdateAutoEnabled');
1824
- delete_option('expirationdateExpiredPageStatus');
1825
- delete_option('expirationdateExpiredPostStatus');
1826
- update_option('postexpiratorVersion', POSTEXPIRATOR_VERSION);
1827
- }
1828
-
1829
- if (version_compare($version, '2.0.1') === -1) {
1830
- // Forgot to do this in 2.0.0
1831
- if (is_multisite()) {
1832
- global $current_blog;
1833
- wp_clear_scheduled_hook('expirationdate_delete_' . $current_blog->blog_id);
1834
- } else {
1835
- wp_clear_scheduled_hook('expirationdate_delete');
1836
- }
1837
-
1838
- update_option('postexpiratorVersion', POSTEXPIRATOR_VERSION);
1839
- }
1840
-
1841
- update_option('postexpiratorVersion', POSTEXPIRATOR_VERSION);
1842
- }
1843
- }
1844
-
1845
- add_action('admin_init', 'postexpirator_upgrade');
1846
-
1847
- /**
1848
- * Called at plugin activation
1849
- *
1850
- * @internal
1851
- *
1852
- * @access private
1853
- */
1854
- function postexpirator_activate()
1855
- {
1856
- if (get_option('expirationdateDefaultDateFormat') === false) {
1857
- update_option('expirationdateDefaultDateFormat', POSTEXPIRATOR_DATEFORMAT);
1858
- }
1859
- if (get_option('expirationdateDefaultTimeFormat') === false) {
1860
- update_option('expirationdateDefaultTimeFormat', POSTEXPIRATOR_TIMEFORMAT);
1861
- }
1862
- if (get_option('expirationdateFooterContents') === false) {
1863
- update_option('expirationdateFooterContents', POSTEXPIRATOR_FOOTERCONTENTS);
1864
- }
1865
- if (get_option('expirationdateFooterStyle') === false) {
1866
- update_option('expirationdateFooterStyle', POSTEXPIRATOR_FOOTERSTYLE);
1867
- }
1868
- if (get_option('expirationdateDisplayFooter') === false) {
1869
- update_option('expirationdateDisplayFooter', POSTEXPIRATOR_FOOTERDISPLAY);
1870
- }
1871
- if (get_option('expirationdateDebug') === false) {
1872
- update_option('expirationdateDebug', POSTEXPIRATOR_DEBUGDEFAULT);
1873
- }
1874
- if (get_option('expirationdateDefaultDate') === false) {
1875
- update_option('expirationdateDefaultDate', POSTEXPIRATOR_EXPIREDEFAULT);
1876
- }
1877
- if (get_option('expirationdateGutenbergSupport') === false) {
1878
- update_option('expirationdateGutenbergSupport', 1);
1879
- }
1880
- }
1881
-
1882
- /**
1883
- * Called at plugin deactivation
1884
- *
1885
- * @internal
1886
- *
1887
- * @access private
1888
- */
1889
- function expirationdate_deactivate()
1890
- {
1891
- $preserveData = (bool)get_option('expirationdatePreserveData', true);
1892
-
1893
- if ($preserveData) {
1894
- return;
1895
- }
1896
-
1897
- delete_option('expirationdateExpiredPostStatus');
1898
- delete_option('expirationdateExpiredPageStatus');
1899
- delete_option('expirationdateDefaultDateFormat');
1900
- delete_option('expirationdateDefaultTimeFormat');
1901
- delete_option('expirationdateDisplayFooter');
1902
- delete_option('expirationdateFooterContents');
1903
- delete_option('expirationdateFooterStyle');
1904
- delete_option('expirationdateCategory');
1905
- delete_option('expirationdateCategoryDefaults');
1906
- delete_option('expirationdateDebug');
1907
- delete_option('postexpiratorVersion');
1908
- delete_option('expirationdateCronSchedule');
1909
- delete_option('expirationdateDefaultDate');
1910
- delete_option('expirationdateDefaultDateCustom');
1911
- delete_option('expirationdateAutoEnabled');
1912
- delete_option('expirationdateDefaultsPage');
1913
- delete_option('expirationdateDefaultsPost');
1914
- delete_option('expirationdateGutenbergSupport');
1915
- delete_option('expirationdatePreserveData');
1916
-
1917
- // what about custom post types? - how to clean up?
1918
- if (is_multisite()) {
1919
- global $current_blog;
1920
-
1921
- wp_clear_scheduled_hook('expirationdate_delete_' . $current_blog->blog_id);
1922
- } else {
1923
- wp_clear_scheduled_hook('expirationdate_delete');
1924
- }
1925
- require_once(POSTEXPIRATOR_BASEDIR . '/post-expirator-debug.php');
1926
- $debug = new PostExpiratorDebug();
1927
- $debug->removeDbTable();
1928
- }
1929
-
1930
- register_deactivation_hook(__FILE__, 'expirationdate_deactivate');
1931
-
1932
- /**
1933
- * The walker class for category checklist.
1934
- *
1935
- * @internal
1936
- *
1937
- * @access private
1938
- */
1939
- class Walker_PostExpirator_Category_Checklist extends Walker
1940
- {
1941
-
1942
- /**
1943
- * What the class handles.
1944
- *
1945
- * @var string
1946
- */
1947
- public $tree_type = 'category';
1948
-
1949
- /**
1950
- * DB fields to use.
1951
- *
1952
- * @var array
1953
- */
1954
- public $db_fields = array('parent' => 'parent', 'id' => 'term_id'); // TODO: decouple this
1955
-
1956
- /**
1957
- * The disabled attribute.
1958
- *
1959
- * @var string
1960
- */
1961
- public $disabled = '';
1962
-
1963
- /**
1964
- * Set the disabled attribute.
1965
- */
1966
- public function setDisabled()
1967
- {
1968
- $this->disabled = 'disabled="disabled"';
1969
- }
1970
-
1971
- /**
1972
- * Starts the list before the elements are added.
1973
- *
1974
- * The $args parameter holds additional values that may be used with the child
1975
- * class methods. This method is called at the start of the output list.
1976
- *
1977
- * @param string $output Used to append additional content (passed by reference).
1978
- * @param int $depth Depth of the item.
1979
- * @param array $args An array of additional arguments.
1980
- */
1981
- public function start_lvl(&$output, $depth = 0, $args = array())
1982
- {
1983
- $indent = str_repeat("\t", $depth);
1984
- $output .= "$indent<ul class='children'>\n";
1985
- }
1986
-
1987
- /**
1988
- * Ends the list of after the elements are added.
1989
- *
1990
- * The $args parameter holds additional values that may be used with the child
1991
- * class methods. This method finishes the list at the end of output of the elements.
1992
- *
1993
- * @param string $output Used to append additional content (passed by reference).
1994
- * @param int $depth Depth of the item.
1995
- * @param array $args An array of additional arguments.
1996
- */
1997
- public function end_lvl(&$output, $depth = 0, $args = array())
1998
- {
1999
- $indent = str_repeat("\t", $depth);
2000
- $output .= "$indent</ul>\n";
2001
- }
2002
-
2003
- /**
2004
- * Start the element output.
2005
- *
2006
- * The $args parameter holds additional values that may be used with the child
2007
- * class methods. Includes the element output also.
2008
- *
2009
- * @param string $output Used to append additional content (passed by reference).
2010
- * @param object $category The data object.
2011
- * @param int $depth Depth of the item.
2012
- * @param array $args An array of additional arguments.
2013
- * @param int $current_object_id ID of the current item.
2014
- */
2015
- public function start_el(&$output, $category, $depth = 0, $args = array(), $current_object_id = 0)
2016
- {
2017
- // @TODO remove extract
2018
- // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
2019
- extract($args);
2020
- if (empty($taxonomy)) {
2021
- $taxonomy = 'category';
2022
- }
2023
-
2024
- $name = 'expirationdate_category';
2025
-
2026
- $class = in_array($category->term_id, $popular_cats, true) ? ' class="expirator-category"' : '';
2027
- $output .= "\n<li id='expirator-{$taxonomy}-{$category->term_id}'$class>" . '<label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="' . $name . '[]" id="expirator-in-' . $taxonomy . '-' . $category->term_id . '"' . checked(
2028
- in_array($category->term_id, $selected_cats, true),
2029
- true,
2030
- false
2031
- ) . disabled(empty($args['disabled']), false, false) . ' ' . $this->disabled . '/> ' . esc_html(
2032
- apply_filters('the_category', $category->name)
2033
- ) . '</label>';
2034
- }
2035
-
2036
- /**
2037
- * Ends the element output, if needed.
2038
- *
2039
- * The $args parameter holds additional values that may be used with the child class methods.
2040
- *
2041
- * @param string $output Used to append additional content (passed by reference).
2042
- * @param object $category The data object.
2043
- * @param int $depth Depth of the item.
2044
- * @param array $args An array of additional arguments.
2045
- */
2046
- public function end_el(&$output, $category, $depth = 0, $args = array())
2047
- {
2048
- $output .= "</li>\n";
2049
- }
2050
- }
2051
-
2052
- /**
2053
- * Get the HTML for expire type.
2054
- *
2055
- * @internal
2056
- *
2057
- * @access private
2058
- */
2059
- function _postexpirator_expire_type($opts)
2060
- {
2061
- if (empty($opts)) {
2062
- return false;
2063
- }
2064
-
2065
- PostExpirator_Display::getInstance()->render_template('how-to-expire', array('opts' => $opts));
2066
- }
2067
-
2068
- /**
2069
- * Get the HTML for taxonomy.
2070
- *
2071
- * @internal
2072
- *
2073
- * @access private
2074
- */
2075
- function _postexpirator_taxonomy($opts)
2076
- {
2077
- if (empty($opts)) {
2078
- return false;
2079
- }
2080
-
2081
- if (! isset($opts['name'])) {
2082
- return false;
2083
- }
2084
-
2085
- $name = sanitize_text_field($opts['name']);
2086
-
2087
- if (! isset($id)) {
2088
- $id = $name;
2089
- }
2090
-
2091
- $disabled = false;
2092
- if (isset($opts['disabled'])) {
2093
- $disabled = (bool)$opts['disabled'];
2094
- }
2095
-
2096
- $onchange = '';
2097
- if (isset($opts['onchange'])) {
2098
- $onchange = sanitize_text_field($opts['onchange']);
2099
- }
2100
-
2101
- $type = '';
2102
- if (isset($opts['type'])) {
2103
- $type = sanitize_text_field($opts['type']);
2104
- }
2105
-
2106
- $selected = false;
2107
- if (isset($opts['selected'])) {
2108
- $selected = $opts['selected'];
2109
- }
2110
-
2111
- $taxonomies = get_object_taxonomies($type, 'object');
2112
- $taxonomies = wp_filter_object_list($taxonomies, array('hierarchical' => true));
2113
-
2114
- if (empty($taxonomies)) {
2115
- return esc_html__('No taxonomies found', 'post-expirator');
2116
- }
2117
-
2118
- $output = [];
2119
-
2120
- $output[] = '<select name="' . esc_attr($name) . '" id="' . esc_attr($id) . '"' . ($disabled === true ? ' disabled="disabled"' : '') . ' onchange="' . esc_attr($onchange) . '">';
2121
-
2122
- foreach ($taxonomies as $taxonomy) {
2123
- $output[] = '<option value="' . esc_attr($taxonomy->name) . '" ' . ($selected === esc_attr($taxonomy->name) ? 'selected="selected"' : '') . '>' . esc_html($taxonomy->label) . '</option>';
2124
- }
2125
-
2126
- $output[] = '</select>';
2127
- $output[] = '<p class="description">' . esc_html__(
2128
- 'Select the hierarchical taxonomy to be used for "category" based expiration.',
2129
- 'post-expirator'
2130
- ) . '</p>';
2131
-
2132
- return implode("<br/>\n", $output);
2133
- }
2134
-
2135
- /**
2136
- * Include the JS.
2137
- *
2138
- * @internal
2139
- *
2140
- * @access private
2141
- */
2142
- function postexpirator_quickedit_javascript()
2143
- {
2144
- // if using code as plugin
2145
- wp_enqueue_script('postexpirator-edit', POSTEXPIRATOR_BASEURL . '/assets/js/admin-edit.js', array(
2146
- 'jquery',
2147
- 'inline-edit-post'
2148
- ), POSTEXPIRATOR_VERSION, true);
2149
-
2150
- global $wp_version;
2151
-
2152
- wp_localize_script(
2153
- 'postexpirator-edit', 'postexpiratorConfig', array(
2154
- 'wpAfter6' => version_compare($wp_version, '6', '>='),
2155
- 'ajax' => array(
2156
- 'nonce' => wp_create_nonce(POSTEXPIRATOR_SLUG),
2157
- 'bulk_edit' => 'manage_wp_posts_using_bulk_quick_save_bulk_edit',
2158
- ),
2159
- )
2160
- );
2161
- }
2162
-
2163
- add_action('admin_print_scripts-edit.php', 'postexpirator_quickedit_javascript');
2164
-
2165
- function postexpirator_date_save_bulk_edit()
2166
- {
2167
- // Save Bulk edit data
2168
- $doAction = isset($_GET['action']) ? sanitize_key($_GET['action']) : '';
2169
- $facade = PostExpirator_Facade::getInstance();
2170
-
2171
- if (
2172
- 'edit' !== $doAction
2173
- || ! isset($_REQUEST['postexpirator_view'])
2174
- || $_REQUEST['postexpirator_view'] !== 'bulk-edit'
2175
- || ! isset($_REQUEST['expirationdate_status'])
2176
- || sanitize_key($_REQUEST['expirationdate_status']) === 'no-change'
2177
- || ! $facade->current_user_can_expire_posts()
2178
- ) {
2179
- return;
2180
- }
2181
-
2182
- check_admin_referer('bulk-posts');
2183
-
2184
- $status = sanitize_key($_REQUEST['expirationdate_status']);
2185
-
2186
- $postIds = array_map('intval', (array)$_REQUEST['post']);
2187
-
2188
- if (empty($postIds)) {
2189
- return;
2190
- }
2191
-
2192
- $postType = get_post_type($postIds[0]);
2193
-
2194
- $defaults = PostExpirator_Facade::get_default_expiry($postType);
2195
-
2196
- $year = $defaults['year'];
2197
- if (isset($_REQUEST['expirationdate_year'])) {
2198
- $year = (int)$_REQUEST['expirationdate_year'];
2199
- }
2200
-
2201
- $month = $defaults['month'];
2202
- if (isset($_REQUEST['expirationdate_month'])) {
2203
- $month = (int)$_REQUEST['expirationdate_month'];
2204
- }
2205
-
2206
- $day = $defaults['day'];
2207
- if (isset($_REQUEST['expirationdate_day'])) {
2208
- $day = (int)$_REQUEST['expirationdate_day'];
2209
- }
2210
-
2211
- $hour = $defaults['hour'];
2212
- if (isset($_REQUEST['expirationdate_hour'])) {
2213
- $hour = (int)$_REQUEST['expirationdate_hour'];
2214
- }
2215
-
2216
- $minute = $defaults['minute'];
2217
- if (isset($_REQUEST['expirationdate_minute'])) {
2218
- $minute = (int)$_REQUEST['expirationdate_minute'];
2219
- }
2220
-
2221
- $newExpirationDate = get_gmt_from_date("$year-$month-$day $hour:$minute:0", 'U');
2222
-
2223
- if (! $newExpirationDate) {
2224
- return;
2225
- }
2226
-
2227
- foreach ($postIds as $postId) {
2228
- $postExpirationDate = get_post_meta($postId, '_expiration-date', true);
2229
-
2230
- if ($status === 'remove-only') {
2231
- delete_post_meta($postId, '_expiration-date');
2232
- postexpirator_unschedule_event($postId);
2233
- continue;
2234
- }
2235
-
2236
- $updateExpiry = ($status === 'change-only' && ! empty($postExpirationDate))
2237
- || ($status === 'add-only' && empty($postExpirationDate))
2238
- || $status === 'change-add';
2239
-
2240
-
2241
- if ($updateExpiry) {
2242
- $opts = PostExpirator_Facade::get_expire_principles($postId);
2243
- $opts['expireType'] = sanitize_key($_REQUEST['expirationdate_expiretype']);
2244
-
2245
- if (in_array($opts['expireType'], array('category', 'category-add', 'category-remove'), true)) {
2246
- $opts['category'] = PostExpirator_Util::sanitize_array_of_integers($_REQUEST['expirationdate_category']); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2247
- }
2248
-
2249
- PostExpirator_Facade::set_expire_principles($postId, $opts);
2250
- update_post_meta($postId, '_expiration-date', $newExpirationDate);
2251
- postexpirator_schedule_event($postId, $newExpirationDate, $opts);
2252
- }
2253
- }
2254
- }
2255
-
2256
- add_filter('admin_init', 'postexpirator_date_save_bulk_edit');
2257
-
2258
- /**
2259
- * Autoloads the classes.
2260
- */
2261
- function postexpirator_autoload($class)
2262
- {
2263
- $namespaces = array('PostExpirator');
2264
- foreach ($namespaces as $namespace) {
2265
- if (substr($class, 0, strlen($namespace)) === $namespace) {
2266
- $class = str_replace('_', '', strstr($class, '_'));
2267
- $filename = POSTEXPIRATOR_BASEDIR . '/classes/' . sprintf('%s.class.php', $class);
2268
- if (is_readable($filename)) {
2269
- require_once $filename;
2270
-
2271
- return true;
2272
- }
2273
- }
2274
- }
2275
-
2276
- return false;
2277
- }
2278
-
2279
- spl_autoload_register('postexpirator_autoload');
2280
-
2281
- /**
2282
- * Launch the plugin by initializing its helpers.
2283
- */
2284
- function postexpirator_launch()
2285
- {
2286
- PostExpirator_Facade::getInstance();
2287
- }
2288
-
2289
- postexpirator_launch();
2290
  }
4
  * Plugin URI: http://wordpress.org/extend/plugins/post-expirator/
5
  * Description: Allows you to add an expiration date (minute) to posts which you can configure to either delete the post, change it to a draft, or update the post categories at expiration time.
6
  * Author: PublishPress
7
+ * Version: 2.8.0
8
  * Author URI: http://publishpress.com
9
  * Text Domain: post-expirator
10
  * Domain Path: /languages
11
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
+ use PublishPressFuture\Core\DI\ServicesAbstract;
14
+ use PublishPressFuture\Core\DI\Container;
 
 
 
 
15
 
16
+ if (! defined('PUBLISHPRESS_FUTURE_LOADED')) {
17
+ define('PUBLISHPRESS_FUTURE_LOADED', true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
+ try {
20
+ $autoloadPath = __DIR__ . '/vendor/autoload.php';
21
+ if (! class_exists('PublishPressFuture\\Core\\Plugin') && is_readable($autoloadPath)) {
22
+ require_once $autoloadPath;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  }
24
 
25
+ $pluginFile = __FILE__;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
+ $services = require __DIR__ . '/services.php';
 
 
 
 
 
 
 
 
28
 
29
+ $container = new Container($services);
 
 
 
 
 
 
 
30
 
31
+ require_once __DIR__ . '/legacy/defines.php';
32
+ require_once __DIR__ . '/legacy/functions.php';
33
+ require_once __DIR__ . '/legacy/deprecated-functions.php';
34
+ require_once __DIR__ . '/legacy/autoload.php';
 
 
 
 
35
 
36
+ $container->get(ServicesAbstract::PLUGIN)->initialize();
37
+ } catch (Exception $e) {
38
+ $trace = $e->getTrace();
39
 
40
+ $traceText = '';
 
 
 
41
 
42
+ foreach ($trace as $item) {
43
+ $traceText .= $item['file'] . ':' . $item['line'] . ' ' . $item['function'] . '(), ';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
45
 
46
+ $message = sprintf(
47
+ "PUBLISHPRESS FUTURE Exception: %s: %s. Backtrace: %s",
48
+ get_class($e),
49
+ $e->getMessage(),
50
+ $traceText
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  );
52
 
53
+ // Make the log message binary safe removing any non-printable chars.
54
+ $message = addcslashes($message, "\000..\037\177..\377\\");
 
 
 
 
 
 
 
55
 
56
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
57
+ error_log($message);
 
 
 
 
 
 
 
58
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  }
readme.txt CHANGED
@@ -5,7 +5,7 @@ Author URI: https://publishpress.com
5
  Tags: expire, posts, pages, schedule
6
  Requires at least: 5.3
7
  Tested up to: 6.1
8
- Stable tag: 2.7.8
9
 
10
  Add an expiration date to posts. When your post is automatically unpublished, you can delete the post, change the status, or update the post categories.
11
 
@@ -81,6 +81,27 @@ This section describes how to install the plugin and get it working.
81
 
82
  == Changelog ==
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  = [2.7.8] - 17 Oct, 2022 =
85
 
86
  * CHANGED: Rename "Category" in the expiration options to use a more generic term: "Taxonomy";
5
  Tags: expire, posts, pages, schedule
6
  Requires at least: 5.3
7
  Tested up to: 6.1
8
+ Stable tag: 2.8.0
9
 
10
  Add an expiration date to posts. When your post is automatically unpublished, you can delete the post, change the status, or update the post categories.
11
 
81
 
82
  == Changelog ==
83
 
84
+ = [2.8.0] - 08 Nov, 2022 =
85
+
86
+ * ADDED: Add translations for ES, FR, IT languages, #297;
87
+ * FIXED: Fix the expire date column in WooCommerce products list, #276;
88
+ * CHANGED: Removed the "None" option from default expiration dates. If a site is using it, the default value is now "Custom" and set for "+1 week", #274;
89
+ * FIXED: Improve output escaping on a few views, #235;
90
+ * FIXED: Improve input sanitization, #235;
91
+ * FIXED: Add argument swapping on strings with multiple arguments, #305;
92
+ * FIXED: Expiration settings not working on Classic Editor, #274;
93
+ * FIXED: Fixed remaining message "Cron event not found!" for expirations that run successfully, #288;
94
+ * CHANGED: The code was partially refactored improving the code quality, applying DRY and other good practices;
95
+ * CHANGED: Deprecated some internal functions: postexpirator_activate, postexpirator_autoload, postexpirator_schedule_event, postexpirator_unschedule_event, postexpirator_debug, _postexpirator_get_cat_names, postexpirator_register_expiration_meta, postexpirator_expire_post, expirationdate_deactivate;
96
+ * CHANGED: Deprecated the constant: PostExpirator_Facade::PostExpirator_Facade => PublishPressFuture\Modules\Expirator\CapabilitiesAbstract::EXPIRE_POST;
97
+ * CHANGED: Deprecated the constant POSTEXPIRATOR_DEBUG;
98
+ * CHANGED: Deprecated the method PostExpirator_Facade::set_expire_principles;
99
+ * CHANGED: Deprecated the method PostExpirator_Facade::current_user_can_expire_posts;
100
+ * CHANGED: Deprecated the method PostExpirator_Facade::get_default_expiry;
101
+ * CHANGED: Deprecated the method PostExpirator_Util::get_wp_date;
102
+ * CHANGED: Deprecated the class PostExpiratorDebug;
103
+ * CHANGED: Deprecated the constants: POSTEXPIRATOR_VERSION, POSTEXPIRATOR_DATEFORMAT, POSTEXPIRATOR_TIMEFORMAT, POSTEXPIRATOR_FOOTERCONTENTS, POSTEXPIRATOR_FOOTERSTYLE, POSTEXPIRATOR_FOOTERDISPLAY, POSTEXPIRATOR_EMAILNOTIFICATION, POSTEXPIRATOR_EMAILNOTIFICATIONADMINS, POSTEXPIRATOR_DEBUGDEFAULT, POSTEXPIRATOR_EXPIREDEFAULT, POSTEXPIRATOR_SLUG, POSTEXPIRATOR_BASEDIR, POSTEXPIRATOR_BASENAME, POSTEXPIRATOR_BASEURL, POSTEXPIRATOR_LOADED, POSTEXPIRATOR_LEGACYDIR;
104
+
105
  = [2.7.8] - 17 Oct, 2022 =
106
 
107
  * CHANGED: Rename "Category" in the expiration options to use a more generic term: "Taxonomy";
services.php ADDED
@@ -0,0 +1,376 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Psr\Container\ContainerInterface;
4
+ use PublishPressFuture\Core\DI\ServicesAbstract as Services;
5
+ use PublishPressFuture\Core\HooksAbstract;
6
+ use PublishPressFuture\Core\Paths;
7
+ use PublishPressFuture\Core\Plugin;
8
+ use PublishPressFuture\Framework\Logger\Logger;
9
+ use PublishPressFuture\Framework\Logger\LoggerInterface;
10
+ use PublishPressFuture\Framework\ModuleInterface;
11
+ use PublishPressFuture\Framework\WordPress\Facade\CronFacade;
12
+ use PublishPressFuture\Framework\WordPress\Facade\DatabaseFacade;
13
+ use PublishPressFuture\Framework\WordPress\Facade\DateTimeFacade;
14
+ use PublishPressFuture\Framework\WordPress\Facade\EmailFacade;
15
+ use PublishPressFuture\Framework\WordPress\Facade\ErrorFacade;
16
+ use PublishPressFuture\Framework\WordPress\Facade\HooksFacade;
17
+ use PublishPressFuture\Framework\WordPress\Facade\OptionsFacade;
18
+ use PublishPressFuture\Framework\WordPress\Facade\RequestFacade;
19
+ use PublishPressFuture\Framework\WordPress\Facade\SanitizationFacade;
20
+ use PublishPressFuture\Framework\WordPress\Facade\SiteFacade;
21
+ use PublishPressFuture\Framework\WordPress\Facade\UsersFacade;
22
+ use PublishPressFuture\Framework\WordPress\Models\PostModel;
23
+ use PublishPressFuture\Framework\WordPress\Models\TermModel;
24
+ use PublishPressFuture\Framework\WordPress\Models\UserModel;
25
+ use PublishPressFuture\Modules\Debug\Module as ModuleDebug;
26
+ use PublishPressFuture\Modules\Expirator\ExpirationActionMapper;
27
+ use PublishPressFuture\Modules\Expirator\ExpirationScheduler;
28
+ use PublishPressFuture\Modules\Expirator\Interfaces\SchedulerInterface;
29
+ use PublishPressFuture\Modules\Expirator\Models\CurrentUserModel;
30
+ use PublishPressFuture\Modules\Expirator\Models\DefaultDataModel;
31
+ use PublishPressFuture\Modules\Expirator\Models\ExpirablePostModel;
32
+ use PublishPressFuture\Modules\Expirator\Module as ModuleExpirator;
33
+ use PublishPressFuture\Modules\InstanceProtection\Module as ModuleInstanceProtection;
34
+ use PublishPressFuture\Modules\Settings\Module as ModuleSettings;
35
+ use PublishPressFuture\Modules\Settings\SettingsFacade;
36
+ use PublishPressFuture\Modules\WooCommerce\Module as ModuleWooCommerce;
37
+
38
+ return [
39
+ Services::PLUGIN_VERSION => '2.8.0',
40
+
41
+ Services::PLUGIN_SLUG => 'post-expirator',
42
+
43
+ Services::PLUGIN_NAME => 'PublishPress Future',
44
+
45
+ Services::DEFAULT_DATA => [
46
+ Services::DEFAULT_DATE_FORMAT => __('l F jS, Y', 'post-expirator'),
47
+ Services::DEFAULT_TIME_FORMAT => __('g:ia', 'post-expirator'),
48
+ Services::DEFAULT_FOOTER_CONTENT => __(
49
+ 'Post expires at EXPIRATIONTIME on EXPIRATIONDATE',
50
+ 'post-expirator'
51
+ ),
52
+ Services::DEFAULT_FOOTER_STYLE => 'font-style: italic;',
53
+ Services::DEFAULT_FOOTER_DISPLAY => '0',
54
+ Services::DEFAULT_EMAIL_NOTIFICATION => '0',
55
+ Services::DEFAULT_EMAIL_NOTIFICATION_ADMINS => '0',
56
+ Services::DEFAULT_DEBUG => '0',
57
+ Services::DEFAULT_EXPIRATION_DATE => 'null',
58
+ ],
59
+
60
+ Services::BASE_PATH => __DIR__,
61
+
62
+ /**
63
+ * @return string
64
+ */
65
+ Services::BASE_URL => static function (ContainerInterface $container) {
66
+ return plugins_url('/', __FILE__);
67
+ },
68
+
69
+ /**
70
+ * @return ModuleInterface[]
71
+ */
72
+ Services::MODULES => static function (ContainerInterface $container) {
73
+ $modulesServiceList = [
74
+ Services::MODULE_DEBUG,
75
+ Services::MODULE_INSTANCE_PROTECTION,
76
+ Services::MODULE_EXPIRATOR,
77
+ Services::MODULE_SETTINGS,
78
+ Services::MODULE_WOOCOMMERCE,
79
+ ];
80
+
81
+ $modules = [];
82
+ foreach ($modulesServiceList as $service) {
83
+ $modules[] = $container->get($service);
84
+ }
85
+
86
+ return $container->get(Services::HOOKS)->applyFilters(
87
+ HooksAbstract::FILTER_MODULES_LIST,
88
+ $modules
89
+ );
90
+ },
91
+
92
+ /**
93
+ * @return Plugin
94
+ */
95
+ Services::PLUGIN => static function (ContainerInterface $container) {
96
+ return new Plugin(
97
+ $container->get(Services::MODULES),
98
+ $container->get(Services::LEGACY_PLUGIN),
99
+ $container->get(Services::HOOKS),
100
+ $container->get(Services::PLUGIN_SLUG),
101
+ $container->get(Services::BASE_PATH)
102
+ );
103
+ },
104
+
105
+ /**
106
+ * @return PostExpirator_Facade
107
+ */
108
+ Services::LEGACY_PLUGIN => static function (ContainerInterface $container) {
109
+ return PostExpirator_Facade::getInstance();
110
+ },
111
+
112
+ /**
113
+ * @return Paths
114
+ */
115
+ Services::PATHS => static function (ContainerInterface $container) {
116
+ return new Paths(__DIR__);
117
+ },
118
+
119
+ /**
120
+ * @return LoggerInterface
121
+ */
122
+ Services::LOGGER => static function (ContainerInterface $container) {
123
+ return new Logger(
124
+ $container->get(Services::DB),
125
+ $container->get(Services::SITE),
126
+ $container->get(Services::SETTINGS)
127
+ );
128
+ },
129
+
130
+ /**
131
+ * @return CronFacade
132
+ */
133
+ Services::CRON => static function (ContainerInterface $container) {
134
+ return new CronFacade();
135
+ },
136
+
137
+ /**
138
+ * @return HooksFacade
139
+ */
140
+ Services::HOOKS => static function (ContainerInterface $container) {
141
+ return new HooksFacade();
142
+ },
143
+
144
+ /**
145
+ * @return DatabaseFacade
146
+ */
147
+ Services::DB => static function (ContainerInterface $container) {
148
+ return new DatabaseFacade();
149
+ },
150
+
151
+ /**
152
+ * @return DateTimeFacade
153
+ */
154
+ Services::DATETIME => static function (ContainerInterface $container) {
155
+ return new DateTimeFacade();
156
+ },
157
+
158
+ /**
159
+ * @return ErrorFacade
160
+ */
161
+ Services::ERROR => static function (ContainerInterface $container) {
162
+ return new ErrorFacade();
163
+ },
164
+
165
+ /**
166
+ * @return OptionsFacade
167
+ */
168
+ Services::OPTIONS => static function (ContainerInterface $container) {
169
+ return new OptionsFacade();
170
+ },
171
+
172
+ /**
173
+ * @return SiteFacade
174
+ */
175
+ Services::SITE => static function (ContainerInterface $container) {
176
+ return new SiteFacade();
177
+ },
178
+
179
+ /**
180
+ * @return UsersFacade
181
+ */
182
+ Services::USERS => static function (ContainerInterface $container) {
183
+ return new UsersFacade();
184
+ },
185
+
186
+ /**
187
+ * @return EmailFacade
188
+ */
189
+ Services::EMAIL => static function (ContainerInterface $container) {
190
+ return new EmailFacade();
191
+ },
192
+
193
+ /**
194
+ * @return \PublishPressFuture\Framework\WordPress\Facade\RequestFacade
195
+ */
196
+ Services::REQUEST => static function (ContainerInterface $container) {
197
+ return new RequestFacade();
198
+ },
199
+
200
+ /**
201
+ * @return \PublishPressFuture\Framework\WordPress\Facade\SanitizationFacade
202
+ */
203
+ Services::SANITIZATION => static function (ContainerInterface $container) {
204
+ return new SanitizationFacade();
205
+ },
206
+
207
+ /**
208
+ * @return PublishPressFuture\Modules\Debug\Debug|null
209
+ */
210
+ Services::DEBUG => static function (ContainerInterface $container) {
211
+ return new PublishPressFuture\Modules\Debug\Debug(
212
+ $container->get(Services::LOGGER),
213
+ $container->get(Services::SETTINGS)
214
+ );
215
+ },
216
+
217
+ /**
218
+ * @return SettingsFacade
219
+ */
220
+ Services::SETTINGS => static function (ContainerInterface $container) {
221
+ return new SettingsFacade(
222
+ $container->get(Services::HOOKS),
223
+ $container->get(Services::OPTIONS),
224
+ $container->get(Services::DEFAULT_DATA)
225
+ );
226
+ },
227
+
228
+ /**
229
+ * @return SchedulerInterface
230
+ */
231
+ Services::EXPIRATION_SCHEDULER => static function (ContainerInterface $container) {
232
+ return new ExpirationScheduler(
233
+ $container->get(Services::HOOKS),
234
+ $container->get(Services::CRON),
235
+ $container->get(Services::ERROR),
236
+ $container->get(Services::LOGGER),
237
+ $container->get(Services::DATETIME),
238
+ $container->get(Services::POST_MODEL_FACTORY)
239
+ );
240
+ },
241
+
242
+ /**
243
+ * @return ModuleInterface
244
+ */
245
+ Services::MODULE_DEBUG => static function (ContainerInterface $container) {
246
+ return new ModuleDebug(
247
+ $container->get(Services::HOOKS),
248
+ $container->get(Services::LOGGER)
249
+ );
250
+ },
251
+
252
+ /**
253
+ * @return ModuleInterface
254
+ */
255
+ Services::MODULE_WOOCOMMERCE => static function (ContainerInterface $container) {
256
+ return new ModuleWooCommerce(
257
+ $container->get(Services::BASE_URL),
258
+ $container->get(Services::PLUGIN_VERSION)
259
+ );
260
+ },
261
+
262
+ /**
263
+ * @return ModuleInterface
264
+ */
265
+ Services::MODULE_INSTANCE_PROTECTION => static function (ContainerInterface $container) {
266
+ return new ModuleInstanceProtection(
267
+ $container->get(Services::PATHS),
268
+ $container->get(Services::PLUGIN_SLUG),
269
+ $container->get(Services::PLUGIN_NAME)
270
+ );
271
+ },
272
+
273
+ /**
274
+ * @return ModuleInterface
275
+ */
276
+ Services::MODULE_EXPIRATOR => static function (ContainerInterface $container) {
277
+ return new ModuleExpirator(
278
+ $container->get(Services::HOOKS),
279
+ $container->get(Services::SITE),
280
+ $container->get(Services::CRON),
281
+ $container->get(Services::EXPIRATION_SCHEDULER),
282
+ $container->get(Services::EXPIRABLE_POST_MODEL_FACTORY),
283
+ $container->get(Services::SANITIZATION),
284
+ $container->get(Services::CURRENT_USER_MODEL_FACTORY),
285
+ $container->get(Services::REQUEST)
286
+ );
287
+ },
288
+
289
+ /**
290
+ * @return ModuleInterface
291
+ */
292
+ Services::MODULE_SETTINGS => static function (ContainerInterface $container) {
293
+ return new ModuleSettings(
294
+ $container->get(Services::HOOKS),
295
+ $container->get(Services::SETTINGS)
296
+ );
297
+ },
298
+
299
+ Services::POST_MODEL_FACTORY => static function (ContainerInterface $container) {
300
+ return static function ($postId) use ($container) {
301
+ return new PostModel(
302
+ $postId,
303
+ $container->get(Services::TERM_MODEL_FACTORY)
304
+ );
305
+ };
306
+ },
307
+
308
+ Services::TERM_MODEL_FACTORY => static function (ContainerInterface $container) {
309
+ return static function ($termId) use ($container) {
310
+ return new TermModel($termId);
311
+ };
312
+ },
313
+
314
+ Services::USER_MODEL_FACTORY => static function (ContainerInterface $container) {
315
+ return static function ($user) use ($container) {
316
+ return new UserModel($user);
317
+ };
318
+ },
319
+
320
+ Services::CURRENT_USER_MODEL_FACTORY => static function (ContainerInterface $container) {
321
+ return static function () use ($container) {
322
+ return new CurrentUserModel();
323
+ };
324
+ },
325
+
326
+ Services::DEFAULT_DATA_MODEL => static function (ContainerInterface $container) {
327
+ return new DefaultDataModel(
328
+ $container->get(Services::SETTINGS),
329
+ $container->get(Services::OPTIONS)
330
+ );
331
+ },
332
+
333
+ Services::EXPIRABLE_POST_MODEL_FACTORY => static function (ContainerInterface $container) {
334
+ /**
335
+ * @return ExpirablePostModel
336
+ * @throws
337
+ */
338
+ return static function ($postId) use ($container) {
339
+ return new ExpirablePostModel(
340
+ $postId,
341
+ $container->get(Services::DEBUG),
342
+ $container->get(Services::OPTIONS),
343
+ $container->get(Services::HOOKS),
344
+ $container->get(Services::USERS),
345
+ $container->get(Services::EXPIRATION_ACTION_MAPPER),
346
+ $container->get(Services::EXPIRATION_SCHEDULER),
347
+ $container->get(Services::SETTINGS),
348
+ $container->get(Services::EMAIL),
349
+ $container->get(Services::TERM_MODEL_FACTORY),
350
+ $container->get(Services::EXPIRATION_ACTION_FACTORY)
351
+ );
352
+ };
353
+ },
354
+
355
+ Services::EXPIRATION_ACTION_MAPPER => static function (ContainerInterface $container) {
356
+ return new ExpirationActionMapper();
357
+ },
358
+
359
+ Services::EXPIRATION_ACTION_FACTORY => static function (ContainerInterface $container) {
360
+ /**
361
+ * @return \PublishPressFuture\Modules\Expirator\Interfaces\ActionableInterface|false
362
+ * @throws
363
+ */
364
+ return static function ($actionClassName, $postModel) use ($container) {
365
+ if (! class_exists($actionClassName)) {
366
+ $debug = $container->get(Services::DEBUG);
367
+
368
+ $debug->log('Expiration action class ' . $actionClassName . ' is undefined');
369
+
370
+ return false;
371
+ }
372
+
373
+ return new $actionClassName($postModel, $container->get(Services::ERROR));
374
+ };
375
+ }
376
+ ];
src/Core/DI/Container.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Core\DI;
7
+
8
+ use Closure;
9
+ use Psr\Container\ContainerInterface;
10
+
11
+ /**
12
+ * PHP Dependency Injection Container PSR-11.
13
+ * Based on code from https://dev.to/fadymr/php-create-dependency-injection-container-psr-11-like-php-di-or-pimple-128i
14
+ *
15
+ * @copyright 2019 F.R Michel
16
+ * @copyright 2022 PublishPress
17
+ */
18
+ class Container implements ContainerInterface
19
+ {
20
+ /**
21
+ * Singleton instance. This should be kept until we are
22
+ * able to finish the code refactoring removing deprecated
23
+ * legacy code. Otherwise, the legacy code can't reuse the
24
+ * new code structure.
25
+ *
26
+ * @var ContainerInterface
27
+ */
28
+ private static $instance;
29
+ /**
30
+ * @var array
31
+ */
32
+ private $resolvedEntries = [];
33
+ /**
34
+ * @var array
35
+ */
36
+ private $definitions = [];
37
+
38
+ public function __construct($definitions = [])
39
+ {
40
+ if (! empty($definitions)) {
41
+ $this->setDefinitions($definitions);
42
+ }
43
+
44
+ self::$instance = $this;
45
+ }
46
+
47
+ private function setDefinitions($definitions)
48
+ {
49
+ $this->definitions = array_merge(
50
+ $definitions,
51
+ [ContainerInterface::class => $this]
52
+ );
53
+ }
54
+
55
+ /**
56
+ * @return ContainerInterface
57
+ *
58
+ * @throws ContainerNotInitializedException
59
+ */
60
+ public static function getInstance()
61
+ {
62
+ if (empty(self::$instance)) {
63
+ throw new ContainerNotInitializedException();
64
+ }
65
+
66
+ return self::$instance;
67
+ }
68
+
69
+ /**
70
+ * Finds an entry of the container by its identifier and returns it.
71
+ *
72
+ * @param string $id Identifier of the entry to look for.
73
+ *
74
+ * @return mixed Entry.
75
+ * @throws ServiceNotFoundException No entry was found for **this** identifier.
76
+ */
77
+ public function get($id)
78
+ {
79
+ if (! $this->has($id)) {
80
+ throw new ServiceNotFoundException($id);
81
+ }
82
+
83
+ if (array_key_exists($id, $this->resolvedEntries)) {
84
+ return $this->resolvedEntries[$id];
85
+ }
86
+
87
+ $value = $this->definitions[$id];
88
+ if ($value instanceof Closure) {
89
+ $value = $value($this);
90
+ }
91
+
92
+ $this->resolvedEntries[$id] = $value;
93
+
94
+ return $value;
95
+ }
96
+
97
+ /**
98
+ * Returns true if the container can return an entry for the given identifier.
99
+ * Returns false otherwise.
100
+ *
101
+ * `has($id)` returning true does not mean that `get($id)` will not throw an exception.
102
+ * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
103
+ *
104
+ * @param string $id Identifier of the entry to look for.
105
+ *
106
+ * @return bool
107
+ */
108
+ public function has($id)
109
+ {
110
+ return array_key_exists($id, $this->definitions)
111
+ || array_key_exists($id, $this->resolvedEntries);
112
+ }
113
+
114
+ /**
115
+ * @param ServiceProviderInterface $serviceProvider
116
+ *
117
+ * @return void
118
+ */
119
+ public function register(ServiceProviderInterface $serviceProvider)
120
+ {
121
+ $factories = $serviceProvider->getFactories();
122
+
123
+ foreach ($factories as $serviceName => $factory) {
124
+ $this->definitions[$serviceName] = $factory;
125
+ }
126
+ }
127
+ }
src/Core/DI/ContainerNotInitializedException.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Core\DI;
7
+
8
+
9
+ use PublishPressFuture\Framework\BaseException;
10
+
11
+ class ContainerNotInitializedException extends BaseException
12
+ {
13
+
14
+ }
src/Core/DI/ServiceNotFoundException.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Core\DI;
7
+
8
+ use InvalidArgumentException;
9
+ use Psr\Container\NotFoundExceptionInterface;
10
+
11
+ class ServiceNotFoundException extends InvalidArgumentException implements NotFoundExceptionInterface
12
+ {
13
+ public function __construct($message = "", $code = 0, $previous = null)
14
+ {
15
+ $message = "No entry or class found in the container for service '$message'";
16
+
17
+ parent::__construct($message, $code, $previous);
18
+ }
19
+ }
src/Core/DI/ServiceProvider.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Core\DI;
7
+
8
+ class ServiceProvider implements ServiceProviderInterface
9
+ {
10
+ /**
11
+ * @var callable[]
12
+ */
13
+ protected $factories;
14
+
15
+ /**
16
+ * @param callable[] $factories
17
+ */
18
+ public function __construct($factories)
19
+ {
20
+ $this->factories = $factories;
21
+ }
22
+
23
+ /**
24
+ * @inheritDoc
25
+ */
26
+ public function getFactories()
27
+ {
28
+ return $this->factories;
29
+ }
30
+ }
src/Core/DI/ServiceProviderInterface.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Core\DI;
7
+
8
+ interface ServiceProviderInterface
9
+ {
10
+ /**
11
+ * @return callable[] A map of service names and theirs factory method.
12
+ */
13
+ public function getFactories();
14
+ }
src/Core/DI/ServicesAbstract.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Core\DI;
7
+
8
+ abstract class ServicesAbstract
9
+ {
10
+ const PLUGIN = 'plugin';
11
+ const PLUGIN_VERSION = 'plugin.version';
12
+ const PLUGIN_SLUG = 'plugin.slug';
13
+ const PLUGIN_NAME = 'plugin.name';
14
+ const DEFAULT_DATA = 'default.data';
15
+ const DEFAULT_DATE_FORMAT = 'default.date.format';
16
+ const DEFAULT_TIME_FORMAT = 'default.time.format';
17
+ const DEFAULT_FOOTER_CONTENT = 'default.footer.content';
18
+ const DEFAULT_FOOTER_STYLE = 'default.footer.style';
19
+ const DEFAULT_FOOTER_DISPLAY = 'default.footer.display';
20
+ const DEFAULT_EMAIL_NOTIFICATION = 'default.email.notification';
21
+ const DEFAULT_EMAIL_NOTIFICATION_ADMINS = 'default.email.notification.admins';
22
+ const DEFAULT_DEBUG = 'default.debug';
23
+ const DEFAULT_EXPIRATION_DATE = 'default.expiration.date';
24
+ const BASE_PATH = 'base.path';
25
+ const BASE_URL = 'base.url';
26
+ const HOOKS = 'hooks';
27
+ const LEGACY_PLUGIN = 'legacy.plugin';
28
+ const PATHS = 'paths';
29
+ const DB = 'db';
30
+ const SITE = 'site';
31
+ const SETTINGS = 'settings';
32
+ const LOGGER = 'logger';
33
+ const CRON = 'cron';
34
+ const ERROR = 'error';
35
+ const DATETIME = 'datetime';
36
+ const OPTIONS = 'options';
37
+ const USERS = 'users.facade';
38
+ const EMAIL = 'email.facade';
39
+ const REQUEST = 'request.facade';
40
+ const DEBUG = 'debug';
41
+ const SANITIZATION = 'sanitization';
42
+ const MODULES = 'modules';
43
+ const EXPIRATION_SCHEDULER = 'expiration.scheduler';
44
+ const MODULE_DEBUG = 'module.debug';
45
+ const MODULE_WOOCOMMERCE = 'module.woocommerce';
46
+ const MODULE_INSTANCE_PROTECTION = 'module.instance_protection';
47
+ const MODULE_EXPIRATOR = 'module.expirator';
48
+ const MODULE_SETTINGS = 'module.settings';
49
+ const POST_MODEL_FACTORY = 'post.model.factory';
50
+ const TERM_MODEL_FACTORY = 'term.model.factory';
51
+ const USER_MODEL_FACTORY = 'user.model.factory';
52
+ const CURRENT_USER_MODEL_FACTORY = 'current.user.model.factory';
53
+ const EXPIRABLE_POST_MODEL_FACTORY = 'expirable.post.model.factory';
54
+ const EXPIRATION_ACTION_FACTORY = 'expiration.action.factory';
55
+ const DEFAULT_DATA_MODEL = 'default.data.model.factory';
56
+ const EXPIRATION_ACTION_MAPPER = 'expiration.action.mapper';
57
+ }
src/Core/HookableInterface.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Core;
7
+
8
+ interface HookableInterface
9
+ {
10
+ /**
11
+ * Add a filter hook.
12
+ *
13
+ * @param string $filterName
14
+ * @param callable $callback
15
+ * @param int $priority
16
+ * @param int $acceptedArgs
17
+ *
18
+ * @return bool
19
+ */
20
+ public function addFilter($filterName, $callback, $priority = 10, $acceptedArgs = 1);
21
+
22
+ /**
23
+ * Apply filters to the passed value.
24
+ *
25
+ * @param string $filterName
26
+ * @param mixed $valueToBeFiltered
27
+ * @param mixed ...$args
28
+ * @return mixed
29
+ */
30
+ public function applyFilters($filterName, $valueToBeFiltered, ...$args);
31
+
32
+ /**
33
+ * Add an action hook.
34
+ *
35
+ * @param string $actionName
36
+ * @param callable $callback
37
+ * @param int $priority
38
+ * @param int $acceptedArgs
39
+ *
40
+ * @return bool
41
+ */
42
+ public function addAction($actionName, $callback, $priority = 10, $acceptedArgs = 1);
43
+
44
+ /**
45
+ * Execute the action.
46
+ *
47
+ * @param string $actionName
48
+ * @param mixed ...$args
49
+ *
50
+ * @return mixed
51
+ */
52
+ public function doAction($actionName, ...$args);
53
+
54
+ /**
55
+ * @param string $pluginFile
56
+ * @param callable $callback
57
+ */
58
+ public function registerDeactivationHook($pluginFile, $callback);
59
+ }
src/Core/HooksAbstract.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Core;
7
+
8
+ abstract class HooksAbstract
9
+ {
10
+ const ACTION_INIT_PLUGIN = 'publishpressfuture_init_plugin';
11
+ const ACTION_ACTIVATE_PLUGIN = 'publishpressfuture_activate_plugin';
12
+ const ACTION_DEACTIVATE_PLUGIN = 'publishpressfuture_deactivate_plugin';
13
+ const FILTER_MODULES_LIST = 'publishpressfuture_list_modules';
14
+ }
src/Core/Paths.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Core;
7
+
8
+ class Paths
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ private $baseDir;
14
+
15
+ public function __construct($baseDir)
16
+ {
17
+ $this->baseDir = (string)$baseDir;
18
+ }
19
+
20
+ public function getVendorDirPath()
21
+ {
22
+ return $this->getBaseDirPath() . '/vendor';
23
+ }
24
+
25
+ public function getBaseDirPath()
26
+ {
27
+ return rtrim($this->baseDir, '/');
28
+ }
29
+ }
src/Core/Plugin.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Core;
7
+
8
+ use PublishPressFuture\Framework\InitializableInterface;
9
+ use PublishPressFuture\Framework\ModuleInterface as ModuleInterface;
10
+
11
+ class Plugin implements InitializableInterface
12
+ {
13
+ /**
14
+ * @var ModuleInterface[]
15
+ */
16
+ private $modules;
17
+
18
+ /**
19
+ * @var object
20
+ */
21
+ private $legacyPlugin;
22
+
23
+ /**
24
+ * @var HookableInterface
25
+ */
26
+ private $hooks;
27
+
28
+ /**
29
+ * @var string
30
+ */
31
+ private $basePath;
32
+
33
+ /**
34
+ * @var string
35
+ */
36
+ private $pluginSlug;
37
+
38
+ /**
39
+ * @param ModuleInterface[] $modules
40
+ * @param object $legacyPlugin
41
+ * @param HookableInterface $hooksFacade
42
+ * @param string $pluginSlug
43
+ * @param string $basePath
44
+ */
45
+ public function __construct(
46
+ $modules,
47
+ $legacyPlugin,
48
+ HookableInterface $hooksFacade,
49
+ $pluginSlug,
50
+ $basePath
51
+ ) {
52
+ $this->modules = $modules;
53
+ $this->legacyPlugin = $legacyPlugin;
54
+ $this->hooks = $hooksFacade;
55
+ $this->basePath = $basePath;
56
+ $this->pluginSlug = $pluginSlug;
57
+ }
58
+
59
+ public function initialize()
60
+ {
61
+ $this->hooks->doAction(HooksAbstract::ACTION_INIT_PLUGIN);
62
+
63
+ $pluginFile = $this->basePath . '/' . $this->pluginSlug . '.php';
64
+ $this->hooks->registerDeactivationHook($pluginFile, [$this, 'deactivatePlugin']);
65
+
66
+ $this->initializeModules();
67
+ }
68
+
69
+ private function initializeModules()
70
+ {
71
+ foreach ($this->modules as $module) {
72
+ if (method_exists($module, 'initialize')) {
73
+ $module->initialize();
74
+ }
75
+ }
76
+ }
77
+
78
+ public function deactivatePlugin()
79
+ {
80
+ $this->hooks->doAction(HooksAbstract::ACTION_DEACTIVATE_PLUGIN);
81
+ }
82
+ }
src/Framework/BaseException.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework;
7
+
8
+ use Exception;
9
+
10
+ class BaseException extends Exception
11
+ {
12
+
13
+ }
src/Framework/InitializableInterface.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework;
7
+
8
+ interface InitializableInterface
9
+ {
10
+ /**
11
+ * @return void
12
+ */
13
+ public function initialize();
14
+ }
src/Framework/Logger/LogLevelAbstract.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\Logger;
7
+
8
+ /**
9
+ * Describes log levels.
10
+ */
11
+ abstract class LogLevelAbstract
12
+ {
13
+ const EMERGENCY = 'emergency';
14
+ const ALERT = 'alert';
15
+ const CRITICAL = 'critical';
16
+ const ERROR = 'error';
17
+ const WARNING = 'warning';
18
+ const NOTICE = 'notice';
19
+ const INFO = 'info';
20
+ const DEBUG = 'debug';
21
+ }
src/Framework/Logger/Logger.php ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\Logger;
7
+
8
+ use PublishPressFuture\Framework\Logger\LogLevelAbstract as LogLevel;
9
+ use PublishPressFuture\Framework\WordPress\Facade\DatabaseFacade;
10
+ use PublishPressFuture\Framework\WordPress\Facade\SiteFacade;
11
+ use PublishPressFuture\Modules\Settings\SettingsFacade;
12
+
13
+ class Logger implements LoggerInterface
14
+ {
15
+ /**
16
+ * @var string
17
+ */
18
+ private $dbTableName;
19
+
20
+ /**
21
+ * @var DatabaseFacade
22
+ */
23
+ private $db;
24
+
25
+ /**
26
+ * @var SiteFacade
27
+ */
28
+ private $site;
29
+
30
+ /**
31
+ * @var SettingsFacade
32
+ */
33
+ private $settings;
34
+
35
+ public function __construct($databaseFacade, $siteFacade, $settingsFacade)
36
+ {
37
+ $this->db = $databaseFacade;
38
+ $this->site = $siteFacade;
39
+ $this->settings = $settingsFacade;
40
+
41
+ $this->dbTableName = $this->db->getTablePrefix() . 'postexpirator_debug';
42
+
43
+ $this->initialize();
44
+ }
45
+
46
+ private function initialize()
47
+ {
48
+ if ($this->databaseTableDoNotExists()) {
49
+ $this->createDatabaseTable();
50
+ }
51
+ }
52
+
53
+ private function databaseTableDoNotExists()
54
+ {
55
+ $databaseTableName = $this->getDatabaseTableName();
56
+
57
+ return $this->db->getVar("SHOW TABLES LIKE '$databaseTableName'") !== $this->dbTableName;
58
+ }
59
+
60
+ private function getDatabaseTableName()
61
+ {
62
+ return $this->db->escape($this->dbTableName);
63
+ }
64
+
65
+ private function createDatabaseTable()
66
+ {
67
+ $databaseTableName = $this->getDatabaseTableName();
68
+
69
+ $tableStructure = "CREATE TABLE `$databaseTableName` (
70
+ `id` INT(9) NOT NULL AUTO_INCREMENT PRIMARY KEY,
71
+ `timestamp` TIMESTAMP NOT NULL,
72
+ `blog` INT(9) NOT NULL,
73
+ `message` text NOT NULL
74
+ );";
75
+
76
+ $this->db->modifyStructure($tableStructure);
77
+ }
78
+
79
+ public function deleteLogs()
80
+ {
81
+ $databaseTableName = $this->getDatabaseTableName();
82
+
83
+ $this->db->query("TRUNCATE TABLE $databaseTableName");
84
+ }
85
+
86
+ /**
87
+ * System is unusable.
88
+ *
89
+ * @param string $message
90
+ * @param array $context
91
+ * @return void
92
+ */
93
+ public function emergency($message, $context = [])
94
+ {
95
+ $this->log(LogLevel::EMERGENCY, $message, $context);
96
+ }
97
+
98
+ /**
99
+ * Logs with an arbitrary level.
100
+ *
101
+ * @param mixed $level
102
+ * @param string $message
103
+ * @param array $context
104
+ * @return void
105
+ * @noinspection SqlResolve
106
+ */
107
+ public function log($level, $message, $context = [])
108
+ {
109
+ if (! $this->debugIsEnabled()) {
110
+ return;
111
+ }
112
+
113
+ $levelDescription = strtoupper($level);
114
+
115
+ $databaseTableName = $this->getDatabaseTableName();
116
+
117
+ $fullMessage = sprintf(
118
+ '%s: %s',
119
+ $levelDescription,
120
+ $message
121
+ );
122
+
123
+ if (! empty($context)) {
124
+ $fullMessage .= '[' . implode(', ', $context) . ']';
125
+ }
126
+
127
+ $this->db->query(
128
+ $this->db->prepare(
129
+ "INSERT INTO $databaseTableName (`timestamp`,`message`,`blog`) VALUES (FROM_UNIXTIME(%d),%s,%s)",
130
+ time(),
131
+ $fullMessage,
132
+ $this->site->getBlogId()
133
+ )
134
+ );
135
+ }
136
+
137
+ /**
138
+ * @return bool
139
+ */
140
+ private function debugIsEnabled()
141
+ {
142
+ return $this->settings->getDebugIsEnabled();
143
+ }
144
+
145
+ /**
146
+ * Action must be taken immediately.
147
+ *
148
+ * Example: Entire website down, database unavailable, etc. This should
149
+ * trigger the SMS alerts and wake you up.
150
+ *
151
+ * @param string $message
152
+ * @param array $context
153
+ * @return void
154
+ */
155
+ public function alert($message, $context = [])
156
+ {
157
+ $this->log(LogLevel::ALERT, $message, $context);
158
+ }
159
+
160
+ /**
161
+ * Critical conditions.
162
+ *
163
+ * Example: Application component unavailable, unexpected exception.
164
+ *
165
+ * @param string $message
166
+ * @param array $context
167
+ * @return void
168
+ */
169
+ public function critical($message, $context = [])
170
+ {
171
+ $this->log(LogLevel::CRITICAL, $message, $context);
172
+ }
173
+
174
+ /**
175
+ * Runtime errors that do not require immediate action but should typically
176
+ * be logged and monitored.
177
+ *
178
+ * @param string $message
179
+ * @param array $context
180
+ * @return void
181
+ */
182
+ public function error($message, $context = [])
183
+ {
184
+ $this->log(LogLevel::ERROR, $message, $context);
185
+ }
186
+
187
+ /**
188
+ * Exceptional occurrences that are not errors.
189
+ *
190
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
191
+ * that are not necessarily wrong.
192
+ *
193
+ * @param string $message
194
+ * @param array $context
195
+ * @return void
196
+ */
197
+ public function warning($message, $context = [])
198
+ {
199
+ $this->log(LogLevel::WARNING, $message, $context);
200
+ }
201
+
202
+ /**
203
+ * Normal but significant events.
204
+ *
205
+ * @param string $message
206
+ * @param array $context
207
+ * @return void
208
+ */
209
+ public function notice($message, $context = [])
210
+ {
211
+ $this->log(LogLevel::NOTICE, $message, $context);
212
+ }
213
+
214
+ /**
215
+ * Interesting events.
216
+ *
217
+ * Example: User logs in, SQL logs.
218
+ *
219
+ * @param string $message
220
+ * @param array $context
221
+ * @return void
222
+ */
223
+ public function info($message, $context = [])
224
+ {
225
+ $this->log(LogLevel::INFO, $message, $context);
226
+ }
227
+
228
+ /**
229
+ * Detailed debug information.
230
+ *
231
+ * @param string $message
232
+ * @param array $context
233
+ * @return void
234
+ */
235
+ public function debug($message, $context = [])
236
+ {
237
+ $this->log(LogLevel::DEBUG, $message, $context);
238
+ }
239
+
240
+ /**
241
+ * @return array
242
+ * @noinspection SqlResolve
243
+ */
244
+ public function fetchAll()
245
+ {
246
+ $databaseTableName = $this->getDatabaseTableName();
247
+
248
+ return (array)$this->db->getResults("SELECT * FROM $databaseTableName ORDER BY `id`");
249
+ }
250
+
251
+ /**
252
+ * @return void
253
+ */
254
+ public function dropDatabaseTable()
255
+ {
256
+ $databaseTableName = $this->getDatabaseTableName();
257
+
258
+ $this->db->dropTable($databaseTableName);
259
+ }
260
+ }
src/Framework/Logger/LoggerInterface.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\Logger;
7
+
8
+ interface LoggerInterface
9
+ {
10
+ /**
11
+ * System is unusable.
12
+ *
13
+ * @param string $message
14
+ * @param array $context
15
+ * @return void
16
+ */
17
+ public function emergency($message, $context = []);
18
+
19
+ /**
20
+ * Action must be taken immediately.
21
+ *
22
+ * Example: Entire website down, database unavailable, etc. This should
23
+ * trigger the SMS alerts and wake you up.
24
+ *
25
+ * @param string $message
26
+ * @param array $context
27
+ * @return void
28
+ */
29
+ public function alert($message, $context = []);
30
+
31
+ /**
32
+ * Critical conditions.
33
+ *
34
+ * Example: Application component unavailable, unexpected exception.
35
+ *
36
+ * @param string $message
37
+ * @param array $context
38
+ * @return void
39
+ */
40
+ public function critical($message, $context = []);
41
+
42
+ /**
43
+ * Runtime errors that do not require immediate action but should typically
44
+ * be logged and monitored.
45
+ *
46
+ * @param string $message
47
+ * @param array $context
48
+ * @return void
49
+ */
50
+ public function error($message, $context = []);
51
+
52
+ /**
53
+ * Exceptional occurrences that are not errors.
54
+ *
55
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
56
+ * that are not necessarily wrong.
57
+ *
58
+ * @param string $message
59
+ * @param array $context
60
+ * @return void
61
+ */
62
+ public function warning($message, $context = []);
63
+
64
+ /**
65
+ * Normal but significant events.
66
+ *
67
+ * @param string $message
68
+ * @param array $context
69
+ * @return void
70
+ */
71
+ public function notice($message, $context = []);
72
+
73
+ /**
74
+ * Interesting events.
75
+ *
76
+ * Example: User logs in, SQL logs.
77
+ *
78
+ * @param string $message
79
+ * @param array $context
80
+ * @return void
81
+ */
82
+ public function info($message, $context = []);
83
+
84
+ /**
85
+ * Detailed debug information.
86
+ *
87
+ * @param string $message
88
+ * @param array $context
89
+ * @return void
90
+ */
91
+ public function debug($message, $context = []);
92
+
93
+ /**
94
+ * Logs with an arbitrary level.
95
+ *
96
+ * @param mixed $level
97
+ * @param string $message
98
+ * @param array $context
99
+ * @return void
100
+ */
101
+ public function log($level, $message, $context = []);
102
+
103
+ /**
104
+ * @return void
105
+ */
106
+ public function deleteLogs();
107
+
108
+ /**
109
+ * @return array
110
+ */
111
+ public function fetchAll();
112
+
113
+ /**
114
+ * @return void
115
+ */
116
+ public function dropDatabaseTable();
117
+ }
src/Framework/ModuleInterface.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework;
7
+
8
+ interface ModuleInterface
9
+ {
10
+ /**
11
+ * @return void
12
+ */
13
+ public function initialize();
14
+ }
src/Framework/WordPress/Exceptions/NonexistentPostException.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Exceptions;
7
+
8
+ use PublishPressFuture\Framework\BaseException;
9
+
10
+ class NonexistentPostException extends BaseException
11
+ {
12
+
13
+ }
src/Framework/WordPress/Exceptions/NonexistentTermException.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Exceptions;
7
+
8
+ use PublishPressFuture\Framework\BaseException;
9
+
10
+ class NonexistentTermException extends BaseException
11
+ {
12
+
13
+ }
src/Framework/WordPress/Exceptions/WordPressErrorException.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Exceptions;
7
+
8
+
9
+ use PublishPressFuture\Framework\BaseException;
10
+
11
+ class WordPressErrorException extends BaseException
12
+ {
13
+
14
+ }
src/Framework/WordPress/Facade/CronFacade.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Facade;
7
+
8
+ use WP_Error;
9
+
10
+ class CronFacade
11
+ {
12
+ /**
13
+ * Undocumented function
14
+ *
15
+ * @param string $hook
16
+ * @param array $args
17
+ * @param bool $wpError
18
+ * @return int|WP_Error|false
19
+ */
20
+ public function clearScheduledHook($hook, $args = [], $wpError = false)
21
+ {
22
+ return \wp_clear_scheduled_hook($hook, $args, $wpError);
23
+ }
24
+
25
+ /**
26
+ * @param string $hook
27
+ * @param array $args
28
+ * @return false|int
29
+ */
30
+ public function getNextScheduleForEvent($hook, $args = [])
31
+ {
32
+ return \wp_next_scheduled($hook, $args);
33
+ }
34
+
35
+ /**
36
+ * @param int $timestamp
37
+ * @param string $hook
38
+ * @param array $args
39
+ * @param bool $returnWpError
40
+ * @return bool|WP_Error
41
+ */
42
+ public function scheduleSingleEvent($timestamp, $hook, $args = [], $returnWpError = false)
43
+ {
44
+ return \wp_schedule_single_event($timestamp, $hook, $args, $returnWpError);
45
+ }
46
+ }
src/Framework/WordPress/Facade/DatabaseFacade.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Facade;
7
+
8
+ class DatabaseFacade
9
+ {
10
+ /**
11
+ * @return string
12
+ */
13
+ public function getTablePrefix()
14
+ {
15
+ global $wpdb;
16
+
17
+ return $wpdb->prefix;
18
+ }
19
+
20
+ /**
21
+ * @param string $query
22
+ * @param int $x
23
+ * @param int $y
24
+ *
25
+ * @return string|null
26
+ */
27
+ public function getVar($query = null, $x = 0, $y = 0)
28
+ {
29
+ global $wpdb;
30
+
31
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
32
+ return $wpdb->get_var($query, $x, $y);
33
+ }
34
+
35
+ /**
36
+ * @param string $query
37
+ *
38
+ * @return string
39
+ */
40
+ public function prepare($query, ...$args)
41
+ {
42
+ global $wpdb;
43
+
44
+ $functionArgs = func_get_args();
45
+
46
+ return call_user_func_array([$wpdb, 'prepare'], $functionArgs);
47
+ }
48
+
49
+ public function escape($data)
50
+ {
51
+ return \esc_sql($data);
52
+ }
53
+
54
+ /**
55
+ * @param string[]|string
56
+ * @param bool
57
+ *
58
+ * @return array
59
+ */
60
+ public function modifyStructure($queries = '', $execute = true)
61
+ {
62
+ if (! function_exists('dbDelta')) {
63
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
64
+ }
65
+
66
+ return \dbDelta($queries, $execute);
67
+ }
68
+
69
+ /**
70
+ * @param string $query
71
+ * @param string $output
72
+ * @return array|object|null
73
+ */
74
+ public function getResults($query = null, $output = 'OBJECT')
75
+ {
76
+ global $wpdb;
77
+
78
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
79
+ return $wpdb->get_results($query, $output);
80
+ }
81
+
82
+ /**
83
+ * @param string $tableName
84
+ *
85
+ * @return void
86
+ */
87
+ public function dropTable($tableName)
88
+ {
89
+ global $wpdb;
90
+
91
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
92
+ $wpdb->query('DROP TABLE IF EXISTS `' . esc_sql($tableName) . '`');
93
+ }
94
+
95
+ /**
96
+ * @param string $query
97
+ *
98
+ * @return int|bool
99
+ */
100
+ public function query($query)
101
+ {
102
+ global $wpdb;
103
+
104
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
105
+ return $wpdb->query($query);
106
+ }
107
+ }
src/Framework/WordPress/Facade/DateTimeFacade.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Facade;
7
+
8
+ use DateTimeZone;
9
+
10
+ class DateTimeFacade
11
+ {
12
+ /**
13
+ * @return DateTimeZone
14
+ */
15
+ public function getTimezone()
16
+ {
17
+ return \wp_timezone();
18
+ }
19
+
20
+ /**
21
+ * @param string $format
22
+ * @param int $timestamp
23
+ * @param DateTimeZone $timezone
24
+ * @return string|false
25
+ */
26
+ public function getLocalizedDate($format, $timestamp = null, $timezone = null)
27
+ {
28
+ return \wp_date($format, $timestamp, $timezone);
29
+ }
30
+
31
+ /**
32
+ * @param string $format
33
+ * @param int $timestamp
34
+ * @return false|string
35
+ */
36
+ public function getWpDate($format, $timestamp)
37
+ {
38
+ $gmtTime = gmdate('Y-m-d H:i:s', $timestamp);
39
+ $timezone = $this->getTimezone();
40
+ $datetime = date_create($gmtTime, new DateTimeZone('+0:00'));
41
+
42
+ return $this->getLocalizedDate($format, $datetime->getTimestamp(), $timezone);
43
+ }
44
+ }
src/Framework/WordPress/Facade/EmailFacade.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Facade;
7
+
8
+ class EmailFacade
9
+ {
10
+ public function send($to, $subject, $message, $headers = '', $attachments = [])
11
+ {
12
+ // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_mail_wp_mail
13
+ return wp_mail($to, $subject, $message, $headers, $attachments);
14
+ }
15
+ }
src/Framework/WordPress/Facade/ErrorFacade.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Facade;
7
+
8
+ use WP_Error;
9
+
10
+ class ErrorFacade
11
+ {
12
+ /**
13
+ * @param mixed $value
14
+ * @return bool
15
+ */
16
+ public function isWpError($value)
17
+ {
18
+ return \is_wp_error($value);
19
+ }
20
+
21
+ /**
22
+ * @param WP_Error $error
23
+ * @return string
24
+ */
25
+ public function getWpErrorMessage($error)
26
+ {
27
+ return $error->get_error_message();
28
+ }
29
+ }
src/Framework/WordPress/Facade/HooksFacade.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Facade;
7
+
8
+ use PublishPressFuture\Core\HookableInterface;
9
+
10
+ use function PublishPressFuture\Framework\WordPress\add_action;
11
+ use function PublishPressFuture\Framework\WordPress\add_filter;
12
+
13
+ class HooksFacade implements HookableInterface
14
+ {
15
+ /**
16
+ * Add a filter hook.
17
+ *
18
+ * @param string $filterName
19
+ * @param callable $callback
20
+ * @param int $priority
21
+ * @param int $acceptedArgs
22
+ *
23
+ * @return bool
24
+ */
25
+ public function addFilter($filterName, $callback, $priority = 10, $acceptedArgs = 1)
26
+ {
27
+ return \add_filter($filterName, $callback, $priority, $acceptedArgs);
28
+ }
29
+
30
+ /**
31
+ * Apply filters to the passed value.
32
+ *
33
+ * @param string $filterName
34
+ * @param mixed $valueToBeFiltered
35
+ * @param mixed ...$args
36
+ * @return mixed
37
+ */
38
+ public function applyFilters($filterName, $valueToBeFiltered, ...$args)
39
+ {
40
+ $params = array_merge([
41
+ $filterName,
42
+ $valueToBeFiltered
43
+ ], $args);
44
+
45
+ return call_user_func_array('apply_filters', $params);
46
+ }
47
+
48
+ /**
49
+ * Add an action hook.
50
+ *
51
+ * @param string $actionName
52
+ * @param callable $callback
53
+ * @param int $priority
54
+ * @param int $acceptedArgs
55
+ *
56
+ * @return bool
57
+ */
58
+ public function addAction($actionName, $callback, $priority = 10, $acceptedArgs = 1)
59
+ {
60
+ return \add_action($actionName, $callback, $priority, $acceptedArgs);
61
+ }
62
+
63
+ /**
64
+ * Execute the action.
65
+ *
66
+ * @param string $actionName
67
+ * @param mixed ...$args
68
+ *
69
+ * @return mixed
70
+ */
71
+ public function doAction($actionName, ...$args)
72
+ {
73
+ $params = array_merge([
74
+ $actionName,
75
+ ], $args);
76
+
77
+ return call_user_func_array('do_action', $params);
78
+ }
79
+
80
+ /**
81
+ * @param string $pluginFile
82
+ * @param callable $callback
83
+ */
84
+ public function registerDeactivationHook($pluginFile, $callback)
85
+ {
86
+ \register_deactivation_hook($pluginFile, $callback);
87
+ }
88
+
89
+ public function ksesRemoveFilters()
90
+ {
91
+ kses_remove_filters();
92
+ }
93
+ }
src/Framework/WordPress/Facade/OptionsFacade.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Facade;
7
+
8
+ use function PublishPressFuture\Framework\WordPress\get_option;
9
+
10
+ class OptionsFacade
11
+ {
12
+ public function initialize()
13
+ {
14
+ }
15
+
16
+ /**
17
+ * @param string $optionName
18
+ *
19
+ * @return bool
20
+ */
21
+ public function deleteOption($optionName)
22
+ {
23
+ return \delete_option($optionName);
24
+ }
25
+
26
+ /**
27
+ * @param string $optionName
28
+ * @param mixed $defaultValue
29
+ *
30
+ * @return mixed
31
+ */
32
+ public function getOption($optionName, $defaultValue = false)
33
+ {
34
+ return \get_option($optionName, $defaultValue);
35
+ }
36
+
37
+ /**
38
+ * @param string $optionName
39
+ * @param mixed $newValue
40
+ * @param string|bool $autoLoad
41
+ * @return bool
42
+ */
43
+ public function updateOption($optionName, $newValue, $autoLoad = null)
44
+ {
45
+ return \update_option($optionName, $newValue, $autoLoad);
46
+ }
47
+ }
src/Framework/WordPress/Facade/RequestFacade.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Facade;
7
+
8
+ class RequestFacade
9
+ {
10
+ /**
11
+ * @param string $action
12
+ * @param string $query_arg
13
+ * @return false|int|void
14
+ */
15
+ public function checkAdminReferer($action = -1, $query_arg = '_wpnonce')
16
+ {
17
+ return check_admin_referer($action, $query_arg);
18
+ }
19
+ }
src/Framework/WordPress/Facade/SanitizationFacade.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Facade;
7
+
8
+
9
+ class SanitizationFacade
10
+ {
11
+ /**
12
+ * @param string $key
13
+ * @return string
14
+ */
15
+ public function sanitizeKey($key)
16
+ {
17
+ return sanitize_key($key);
18
+ }
19
+ }
src/Framework/WordPress/Facade/SiteFacade.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Facade;
7
+
8
+ class SiteFacade
9
+ {
10
+ /**
11
+ * @return int
12
+ */
13
+ public function getBlogId()
14
+ {
15
+ if ($this->isMultisite()) {
16
+ global $current_blog;
17
+
18
+ return (int)$current_blog->blog_id;
19
+ }
20
+
21
+ return 0;
22
+ }
23
+
24
+ /**
25
+ * @return bool
26
+ */
27
+ public function isMultisite()
28
+ {
29
+ return \is_multisite();
30
+ }
31
+ }
src/Framework/WordPress/Facade/UsersFacade.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Facade;
7
+
8
+ class UsersFacade
9
+ {
10
+ public function getUsers($args = [])
11
+ {
12
+ return get_users($args);
13
+ }
14
+ }
src/Framework/WordPress/Models/CurrentUserModel.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Models;
7
+
8
+ class CurrentUserModel extends UserModel
9
+ {
10
+ public function __construct()
11
+ {
12
+ $user = wp_get_current_user();
13
+
14
+ parent::__construct($user);
15
+ }
16
+ }
src/Framework/WordPress/Models/PostModel.php ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Models;
7
+
8
+ use PublishPressFuture\Framework\WordPress\Exceptions\NonexistentPostException;
9
+ use WP_Post;
10
+
11
+ class PostModel
12
+ {
13
+ /**
14
+ * @var int
15
+ */
16
+ private $postId;
17
+ /**
18
+ * @var WP_Post
19
+ */
20
+ private $postInstance;
21
+
22
+ /**
23
+ * @var callable
24
+ */
25
+ protected $termModelFactory;
26
+
27
+ /**
28
+ * @param int|\WP_Post $post
29
+ * @param callable $termModelFactory
30
+ */
31
+ public function __construct($post, $termModelFactory)
32
+ {
33
+ if (is_object($post)) {
34
+ $this->postInstance = $post;
35
+ $this->postId = $post->ID;
36
+ }
37
+
38
+ if (is_numeric($post)) {
39
+ $this->postId = (int)$post;
40
+ }
41
+
42
+ $this->termModelFactory = $termModelFactory;
43
+ }
44
+
45
+ /**
46
+ * @param string $newPostStatus
47
+ *
48
+ * @return bool
49
+ * @throws \PublishPressFuture\Framework\WordPress\Exceptions\NonexistentPostException
50
+ */
51
+ public function setPostStatus($newPostStatus)
52
+ {
53
+ $post = $this->getPostInstance();
54
+
55
+ $updated = $this->update(
56
+ [
57
+ 'post_status' => $newPostStatus,
58
+ ]
59
+ );
60
+
61
+ wp_transition_post_status($newPostStatus, $post->post_status, $post);
62
+
63
+ return $updated;
64
+ }
65
+
66
+ /**
67
+ * @param array $data
68
+ *
69
+ * @return bool
70
+ */
71
+ public function update($data)
72
+ {
73
+ $data = array_merge(
74
+ ['ID' => $this->postId],
75
+ $data
76
+ );
77
+
78
+ return \wp_update_post($data) > 0;
79
+ }
80
+
81
+ /**
82
+ * @param string $metaKey
83
+ * @param mixed $metaValue
84
+ * @return false|int
85
+ */
86
+ public function addMeta($metaKey, $metaValue = null)
87
+ {
88
+ return add_post_meta($this->postId, $metaKey, $metaValue);
89
+ }
90
+
91
+ /**
92
+ * @param string|array $metaKey
93
+ * @param mixed $metaValue
94
+ * @return void
95
+ */
96
+ public function updateMeta($metaKey, $metaValue = null)
97
+ {
98
+ if (! is_array($metaKey)) {
99
+ $metaKey = [$metaKey => $metaValue];
100
+ }
101
+
102
+ $callback = function ($value, $key) {
103
+ \update_post_meta(
104
+ $this->postId,
105
+ \sanitize_key($key),
106
+ $value
107
+ );
108
+ };
109
+
110
+ // TODO: Replace array_walk with foreach.
111
+ array_walk($metaKey, $callback);
112
+ }
113
+
114
+ /**
115
+ * @param string|array $metaKey
116
+ * @return void
117
+ */
118
+ public function deleteMeta($metaKey)
119
+ {
120
+ if (! is_array($metaKey)) {
121
+ $metaKey = [$metaKey];
122
+ }
123
+
124
+ $callback = function ($key) {
125
+ \delete_post_meta(
126
+ $this->postId,
127
+ \sanitize_key($key)
128
+ );
129
+ };
130
+
131
+ // TODO: Replace array_walk with foreach.
132
+ array_walk($metaKey, $callback);
133
+ }
134
+
135
+ public function getMeta($metaKey, $single = false)
136
+ {
137
+ return get_post_meta($this->postId, $metaKey, $single);
138
+ }
139
+
140
+ /**
141
+ * @return bool
142
+ * @throws \PublishPressFuture\Framework\WordPress\Exceptions\NonexistentPostException
143
+ */
144
+ public function postExists()
145
+ {
146
+ $instance = $this->getPostInstance();
147
+
148
+ return is_object($instance);
149
+ }
150
+
151
+ /**
152
+ * @return WP_Post
153
+ * @throws \PublishPressFuture\Framework\WordPress\Exceptions\NonexistentPostException
154
+ */
155
+ private function getPostInstance()
156
+ {
157
+ if (empty($this->postInstance)) {
158
+ $this->postInstance = \get_post($this->postId);
159
+
160
+ if (! is_object($this->postInstance) || is_wp_error($this->postInstance)) {
161
+ throw new NonexistentPostException();
162
+ }
163
+ }
164
+
165
+ return $this->postInstance;
166
+ }
167
+
168
+ public function getPostType()
169
+ {
170
+ return get_post_type($this->getPostId());
171
+ }
172
+
173
+ public function getTitle()
174
+ {
175
+ return get_the_title($this->getPostId());
176
+ }
177
+
178
+ public function getPermalink()
179
+ {
180
+ return get_post_permalink($this->getPostId());
181
+ }
182
+
183
+ public function getPostId()
184
+ {
185
+ return $this->postId;
186
+ }
187
+
188
+ public function getTerms($taxonomy = 'post_tag', $args = [])
189
+ {
190
+ $terms = wp_get_post_terms($this->getPostId(), $taxonomy, $args);
191
+ $termModelFactory = $this->termModelFactory;
192
+
193
+ foreach ($terms as &$term) {
194
+ $term = $termModelFactory($term);
195
+ }
196
+
197
+ return $terms;
198
+ }
199
+
200
+ public function getTermNames($taxonomy = 'post_tag', $args = [])
201
+ {
202
+ $terms = $this->getTerms($taxonomy, $args);
203
+
204
+ foreach ($terms as &$term) {
205
+ $term = $term->getName();
206
+ }
207
+
208
+ return $terms;
209
+ }
210
+
211
+ public function getTermIDs($taxonomy = 'post_tag', $args = [])
212
+ {
213
+ $terms = $this->getTerms($taxonomy, $args);
214
+
215
+ foreach ($terms as &$term) {
216
+ $term = $term->getTermID();
217
+ }
218
+
219
+ return $terms;
220
+ }
221
+
222
+ public function appendTerms($termIDs, $taxonomy)
223
+ {
224
+ return wp_set_object_terms($this->getPostId(), $termIDs, $taxonomy, true);
225
+ }
226
+
227
+ public function setTerms($termIDs, $taxonomy)
228
+ {
229
+ return wp_set_object_terms($this->getPostId(), $termIDs, $taxonomy, false);
230
+ }
231
+
232
+ public function delete()
233
+ {
234
+ return wp_delete_post($this->getPostId()) !== false;
235
+ }
236
+
237
+ public function stick()
238
+ {
239
+ stick_post($this->getPostId());
240
+
241
+ return true;
242
+ }
243
+
244
+ public function unstick()
245
+ {
246
+ unstick_post($this->getPostId());
247
+
248
+ return true;
249
+ }
250
+ }
src/Framework/WordPress/Models/TermModel.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Models;
7
+
8
+
9
+ use PublishPressFuture\Framework\WordPress\Exceptions\NonexistentTermException;
10
+
11
+ class TermModel
12
+ {
13
+ /**
14
+ * @var int
15
+ */
16
+ private $termId;
17
+
18
+ /**
19
+ * @var \WP_Term;
20
+ */
21
+ private $termInstance;
22
+
23
+ /**
24
+ * @param int|\WP_Term $term
25
+ */
26
+ public function __construct($term)
27
+ {
28
+ if (is_object($term)) {
29
+ $this->termInstance = $term;
30
+ $this->termId = $term->term_id;
31
+ }
32
+
33
+ if (is_numeric($term)) {
34
+ $this->termId = (int)$term;
35
+ }
36
+ }
37
+
38
+ /**
39
+ * @return \WP_Term
40
+ * @throws \PublishPressFuture\Framework\WordPress\Exceptions\NonexistentTermException
41
+ */
42
+ public function getTermInstance()
43
+ {
44
+ if (empty($this->termInstance)) {
45
+ $this->termInstance = get_term($this->termId);
46
+
47
+ if (! is_object($this->termInstance) || is_wp_error($this->termInstance)) {
48
+ throw new NonexistentTermException();
49
+ }
50
+ }
51
+
52
+ return $this->termInstance;
53
+ }
54
+
55
+ /**
56
+ * @return bool
57
+ * @throws \PublishPressFuture\Framework\WordPress\Exceptions\NonexistentTermException
58
+ */
59
+ public function termExists()
60
+ {
61
+ $instance = $this->getTermInstance();
62
+
63
+ return is_object($instance);
64
+ }
65
+
66
+ public function getTermID()
67
+ {
68
+ return (int)$this->termId;
69
+ }
70
+
71
+ /**
72
+ * @throws \PublishPressFuture\Framework\WordPress\Exceptions\NonexistentTermException
73
+ */
74
+ public function getName()
75
+ {
76
+ $term = $this->getTermInstance();
77
+
78
+ return $term->name;
79
+ }
80
+ }
src/Framework/WordPress/Models/UserModel.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Framework\WordPress\Models;
7
+
8
+ class UserModel
9
+ {
10
+ /**
11
+ * @var int
12
+ */
13
+ private $userId;
14
+
15
+ /**
16
+ * @var \WP_User
17
+ */
18
+ private $userInstance;
19
+
20
+ /**
21
+ * @param \WP_User|int $user
22
+ */
23
+ public function __construct($user)
24
+ {
25
+ if (is_object($user)) {
26
+ $this->userInstance = $user;
27
+ $this->userId = $user->ID;
28
+ }
29
+
30
+ if (is_numeric($user)) {
31
+ $this->userId = (int)$user;
32
+ }
33
+ }
34
+
35
+ public function getUserInstance()
36
+ {
37
+ if (empty($this->userInstance)) {
38
+ $this->userInstance = get_user_by('ID', $this->userId);
39
+ }
40
+
41
+ return $this->userInstance;
42
+ }
43
+
44
+ /**
45
+ * @param string $capability
46
+ * @return bool
47
+ */
48
+ public function hasCapability($capability)
49
+ {
50
+ $userInstance = $this->getUserInstance();
51
+
52
+ return $userInstance->has_cap($capability);
53
+ }
54
+ }
src/Modules/Debug/Controllers/Controller.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Debug\Controllers;
7
+
8
+ use PublishPressFuture\Framework\InitializableInterface;
9
+ use PublishPressFuture\Framework\Logger\LoggerInterface;
10
+ use PublishPressFuture\Framework\WordPress\Facade\HooksFacade;
11
+ use PublishPressFuture\Modules\Debug\HooksAbstract;
12
+
13
+ class Controller implements InitializableInterface
14
+ {
15
+ /**
16
+ * @var HooksFacade
17
+ */
18
+ private $hooks;
19
+
20
+ /**
21
+ * @var LoggerInterface
22
+ */
23
+ private $logger;
24
+
25
+ public function __construct(HooksFacade $hooks, LoggerInterface $logger)
26
+ {
27
+ $this->hooks = $hooks;
28
+ $this->logger = $logger;
29
+ }
30
+
31
+ public function initialize()
32
+ {
33
+ $this->hooks->addAction(HooksAbstract::ACTION_DEBUG_LOG, [$this, 'onActionDebugLog']);
34
+ }
35
+
36
+ public function onActionDebugLog($message)
37
+ {
38
+ $this->logger->debug($message);
39
+ }
40
+ }
src/Modules/Debug/Debug.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Debug;
7
+
8
+
9
+ use PublishPressFuture\Framework\Logger\LoggerInterface;
10
+
11
+ class Debug implements DebugInterface
12
+ {
13
+ /**
14
+ * @var LoggerInterface
15
+ */
16
+ private $logger;
17
+
18
+ /**
19
+ * @var \PublishPressFuture\Modules\Settings\SettingsFacade
20
+ */
21
+ private $settings;
22
+
23
+ public function __construct(LoggerInterface $logger, $settings)
24
+ {
25
+ $this->logger = $logger;
26
+ $this->settings = $settings;
27
+ }
28
+
29
+ /**
30
+ * @inheritDoc
31
+ */
32
+ public function log($message)
33
+ {
34
+ if ($this->isEnabled()) {
35
+ $this->logger->debug($message);
36
+ }
37
+ }
38
+
39
+ /**
40
+ * @inheritDoc
41
+ */
42
+ public function dropDatabaseTable()
43
+ {
44
+ $this->logger->dropDatabaseTable();
45
+ }
46
+
47
+ /**
48
+ * @inheritDoc
49
+ */
50
+ public function fetchAll()
51
+ {
52
+ return $this->logger->fetchAll();
53
+ }
54
+
55
+ /**
56
+ * @inheritDoc
57
+ */
58
+ public function deleteLogs()
59
+ {
60
+ $this->logger->deleteLogs();
61
+ }
62
+
63
+ /**
64
+ * @inheritDoc
65
+ */
66
+ public function isEnabled()
67
+ {
68
+ return $this->settings->getDebugIsEnabled();
69
+ }
70
+ }
src/Modules/Debug/DebugInterface.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Debug;
7
+
8
+
9
+ interface DebugInterface
10
+ {
11
+ /**
12
+ * @param string $message
13
+ * @return void
14
+ */
15
+ public function log($message);
16
+
17
+ /**
18
+ * @return void
19
+ */
20
+ public function dropDatabaseTable();
21
+
22
+ /**
23
+ * @return array
24
+ */
25
+ public function fetchAll();
26
+
27
+ /**
28
+ * @return void
29
+ */
30
+ public function deleteLogs();
31
+
32
+ /**
33
+ * @return bool
34
+ */
35
+ public function isEnabled();
36
+ }
src/Modules/Debug/HooksAbstract.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Debug;
4
+
5
+ abstract class HooksAbstract
6
+ {
7
+ const ACTION_DEBUG_LOG = 'publishpressfuture_debug_log';
8
+ }
src/Modules/Debug/Module.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Debug;
7
+
8
+
9
+ use PublishPressFuture\Framework\Logger\LoggerInterface;
10
+ use PublishPressFuture\Framework\ModuleInterface;
11
+ use PublishPressFuture\Framework\WordPress\Facade\HooksFacade;
12
+ use PublishPressFuture\Modules\Debug\Controllers\Controller;
13
+
14
+ class Module implements ModuleInterface
15
+ {
16
+ /**
17
+ * @var HooksFacade
18
+ */
19
+ private $hooks;
20
+
21
+ /**
22
+ * @var LoggerInterface
23
+ */
24
+ private $logger;
25
+
26
+ /**
27
+ * @var Controller
28
+ */
29
+ private $controller;
30
+
31
+ /**
32
+ * @param HooksFacade $hooks
33
+ * @param LoggerInterface $logger
34
+ */
35
+ public function __construct(HooksFacade $hooks, LoggerInterface $logger)
36
+ {
37
+ $this->hooks = $hooks;
38
+ $this->logger = $logger;
39
+
40
+ $this->controller = $this->getController();
41
+ }
42
+
43
+ /**
44
+ * @inheritDoc
45
+ */
46
+ public function initialize()
47
+ {
48
+ $this->controller->initialize();
49
+ }
50
+
51
+ private function getController()
52
+ {
53
+ return new Controller($this->hooks, $this->logger);
54
+ }
55
+ }
src/Modules/Expirator/CapabilitiesAbstract.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Expirator;
7
+
8
+ abstract class CapabilitiesAbstract
9
+ {
10
+ const EXPIRE_POST = 'publishpress_future_expire_post';
11
+ }
src/Modules/Expirator/Controllers/BulkEditController.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Expirator\Controllers;
7
+
8
+ use PublishPressFuture\Core\HookableInterface;
9
+ use PublishPressFuture\Framework\InitializableInterface;
10
+ use PublishPressFuture\Modules\Expirator\HooksAbstract;
11
+
12
+ class BulkEditController implements InitializableInterface
13
+ {
14
+ /**
15
+ * @var HookableInterface
16
+ */
17
+ private $hooks;
18
+
19
+ /**
20
+ * @var callable
21
+ */
22
+ private $expirablePostModelFactory;
23
+
24
+ /**
25
+ * @var \PublishPressFuture\Framework\WordPress\Facade\SanitizationFacade
26
+ */
27
+ private $sanitization;
28
+
29
+ /**
30
+ * @var callable
31
+ */
32
+ private $currentUserModelFactory;
33
+
34
+ /**
35
+ * @var \PublishPressFuture\Framework\WordPress\Facade\RequestFacade
36
+ */
37
+ private $request;
38
+
39
+ /**
40
+ * @param HookableInterface $hooksFacade
41
+ * @param callable $expirablePostModelFactory
42
+ * @param \PublishPressFuture\Framework\WordPress\Facade\SanitizationFacade $sanitization
43
+ * @param callable $currentUserModelFactory
44
+ * @param \PublishPressFuture\Framework\WordPress\Facade\RequestFacade $request
45
+ */
46
+ public function __construct(
47
+ HookableInterface $hooksFacade,
48
+ $expirablePostModelFactory,
49
+ $sanitization,
50
+ $currentUserModelFactory,
51
+ $request
52
+ ) {
53
+ $this->hooks = $hooksFacade;
54
+ $this->expirablePostModelFactory = $expirablePostModelFactory;
55
+ $this->sanitization = $sanitization;
56
+ $this->currentUserModelFactory = $currentUserModelFactory;
57
+ $this->request = $request;
58
+ }
59
+
60
+ public function initialize()
61
+ {
62
+ $this->hooks->addAction(
63
+ HooksAbstract::ACTION_ADMIN_INIT,
64
+ [$this, 'onAdminInit']
65
+ );
66
+ }
67
+
68
+ public function onAdminInit()
69
+ {
70
+ // phpcs:disable WordPress.Security.NonceVerification.Recommended
71
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
72
+ $doAction = isset($_GET['action']) ? $this->sanitization->sanitizeKey($_GET['action']) : '';
73
+ if ('edit' !== $doAction) {
74
+ return;
75
+ }
76
+
77
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
78
+ if (! isset($_REQUEST['postexpirator_view'])) {
79
+ return;
80
+ }
81
+
82
+ if ($_REQUEST['postexpirator_view'] !== 'bulk-edit') {
83
+ return;
84
+ }
85
+
86
+ if (! isset($_REQUEST['expirationdate_status'])) {
87
+ return;
88
+ }
89
+
90
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
91
+ if ($this->sanitization->sanitizeKey($_REQUEST['expirationdate_status']) === 'no-change') {
92
+ return;
93
+ }
94
+
95
+ $currentUserModelFactory = $this->currentUserModelFactory;
96
+ $currentUserModel = $currentUserModelFactory();
97
+
98
+ if (! $currentUserModel->userCanExpirePosts()) {
99
+ return;
100
+ }
101
+
102
+ $this->request->checkAdminReferer('bulk-posts');
103
+
104
+ $this->saveBulkEditData();
105
+ // phpcs:enable
106
+ }
107
+
108
+ private function saveBulkEditData()
109
+ {
110
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
111
+ $status = $this->sanitization->sanitizeKey($_REQUEST['expirationdate_status']);
112
+ $validStatuses = ['change-only', 'add-only', 'change-add', 'remove-only'];
113
+
114
+ if (! in_array($status, $validStatuses)) {
115
+ return;
116
+ }
117
+
118
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.NonceVerification.Recommended
119
+ $postIds = array_map('intval', (array)$_REQUEST['post']);
120
+
121
+ if (empty($postIds)) {
122
+ return;
123
+ }
124
+
125
+ // Post model for the first post
126
+ $postModelFactory = $this->expirablePostModelFactory;
127
+ $postModel = $postModelFactory($postIds[0]);
128
+ }
129
+ }
src/Modules/Expirator/Controllers/ExpirationController.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Expirator\Controllers;
7
+
8
+ use PublishPressFuture\Core\HookableInterface;
9
+ use PublishPressFuture\Framework\InitializableInterface;
10
+ use PublishPressFuture\Framework\WordPress\Facade\CronFacade;
11
+ use PublishPressFuture\Framework\WordPress\Facade\SiteFacade;
12
+ use PublishPressFuture\Modules\Expirator\ExpirationScheduler;
13
+ use PublishPressFuture\Modules\Expirator\HooksAbstract;
14
+ use PublishPressFuture\Modules\Expirator\Interfaces\SchedulerInterface;
15
+ use PublishPressFuture\Modules\Settings\HooksAbstract as SettingsHooksAbstract;
16
+
17
+ class ExpirationController implements InitializableInterface
18
+ {
19
+ /**
20
+ * @var HookableInterface
21
+ */
22
+ private $hooks;
23
+
24
+ /**
25
+ * @var SiteFacade
26
+ */
27
+ private $site;
28
+
29
+ /**
30
+ * @var CronFacade
31
+ */
32
+ private $cron;
33
+
34
+ /**
35
+ * @var ExpirationScheduler
36
+ */
37
+ private $scheduler;
38
+
39
+ /**
40
+ * @var callable
41
+ */
42
+ private $expirablePostModelFactory;
43
+
44
+ /**
45
+ * @param HookableInterface $hooksFacade
46
+ * @param SiteFacade $siteFacade
47
+ * @param CronFacade $cronFacade
48
+ * @param SchedulerInterface $scheduler
49
+ * @param callable $expirablePostModelFactory
50
+ */
51
+ public function __construct(
52
+ HookableInterface $hooksFacade,
53
+ SiteFacade $siteFacade,
54
+ CronFacade $cronFacade,
55
+ SchedulerInterface $scheduler,
56
+ $expirablePostModelFactory
57
+ ) {
58
+ $this->hooks = $hooksFacade;
59
+ $this->site = $siteFacade;
60
+ $this->cron = $cronFacade;
61
+ $this->scheduler = $scheduler;
62
+ $this->expirablePostModelFactory = $expirablePostModelFactory;
63
+ }
64
+
65
+ public function initialize()
66
+ {
67
+ $this->hooks->addAction(
68
+ SettingsHooksAbstract::ACTION_DELETE_ALL_SETTINGS,
69
+ [$this, 'onActionDeleteAllSettings']
70
+ );
71
+ $this->hooks->addAction(
72
+ HooksAbstract::ACTION_SCHEDULE_POST_EXPIRATION,
73
+ [$this, 'onActionSchedulePostExpiration'],
74
+ 10,
75
+ 3
76
+ );
77
+ $this->hooks->addAction(
78
+ HooksAbstract::ACTION_UNSCHEDULE_POST_EXPIRATION,
79
+ [$this, 'onActionUnschedulePostExpiration']
80
+ );
81
+ $this->hooks->addAction(
82
+ HooksAbstract::ACTION_EXPIRE_POST,
83
+ [$this, 'onActionRunPostExpiration']
84
+ );
85
+ $this->hooks->addAction(
86
+ HooksAbstract::ACTION_LEGACY_EXPIRE_POST,
87
+ [$this, 'onActionRunPostExpiration']
88
+ );
89
+ }
90
+
91
+ public function onActionDeleteAllSettings()
92
+ {
93
+ // TODO: What about custom post types? How to clean up?
94
+
95
+ if ($this->site->isMultisite()) {
96
+ $this->cron->clearScheduledHook(
97
+ HooksAbstract::getActionLegacyMultisiteDelete($this->site->getBlogId())
98
+ );
99
+
100
+ return;
101
+ }
102
+
103
+ $this->cron->clearScheduledHook(HooksAbstract::ACTION_LEGACY_DELETE);
104
+ }
105
+
106
+ public function onActionSchedulePostExpiration($postId, $timestamp, $opts)
107
+ {
108
+ $this->scheduler->schedule($postId, $timestamp, $opts);
109
+ }
110
+
111
+ public function onActionUnschedulePostExpiration($postId)
112
+ {
113
+ $this->scheduler->unschedule($postId);
114
+ }
115
+
116
+ public function onActionRunPostExpiration($postId, $force = false)
117
+ {
118
+ $postModelFactory = $this->expirablePostModelFactory;
119
+
120
+ $postModel = $postModelFactory($postId);
121
+ $postModel->expire($force);
122
+ }
123
+ }
src/Modules/Expirator/Exceptions/UndefinedActionException.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator\Exceptions;
4
+
5
+ use PublishPressFuture\Framework\BaseException;
6
+
7
+ class UndefinedActionException extends BaseException
8
+ {
9
+
10
+ }
src/Modules/Expirator/ExpirationActionMapper.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator;
4
+
5
+ use PublishPressFuture\Framework\WordPress\Exceptions\NonexistentPostException;
6
+ use PublishPressFuture\Modules\Expirator\ExpirationActions\DeletePost;
7
+ use PublishPressFuture\Modules\Expirator\ExpirationActions\PostCategoryAdd;
8
+ use PublishPressFuture\Modules\Expirator\ExpirationActions\PostCategoryRemove;
9
+ use PublishPressFuture\Modules\Expirator\ExpirationActions\PostCategorySet;
10
+ use PublishPressFuture\Modules\Expirator\ExpirationActions\PostStatusToDraft;
11
+ use PublishPressFuture\Modules\Expirator\ExpirationActions\PostStatusToPrivate;
12
+ use PublishPressFuture\Modules\Expirator\ExpirationActions\PostStatusToTrash;
13
+ use PublishPressFuture\Modules\Expirator\ExpirationActions\StickPost;
14
+ use PublishPressFuture\Modules\Expirator\ExpirationActions\UnstickPost;
15
+ use PublishPressFuture\Modules\Expirator\Interfaces\ActionMapperInterface;
16
+
17
+ class ExpirationActionMapper implements ActionMapperInterface
18
+ {
19
+ /**
20
+ * @param array
21
+ */
22
+ private $actionClassesMap;
23
+
24
+ public function __construct()
25
+ {
26
+ $this->actionClassesMap = [
27
+ ExpirationActionsAbstract::POST_STATUS_TO_DRAFT => PostStatusToDraft::class,
28
+ ExpirationActionsAbstract::POST_STATUS_TO_PRIVATE => PostStatusToPrivate::class,
29
+ ExpirationActionsAbstract::POST_STATUS_TO_TRASH => PostStatusToTrash::class,
30
+ ExpirationActionsAbstract::DELETE_POST => DeletePost::class,
31
+ ExpirationActionsAbstract::STICK_POST => StickPost::class,
32
+ ExpirationActionsAbstract::UNSTICK_POST => UnstickPost::class,
33
+ ExpirationActionsAbstract::POST_CATEGORY_SET => PostCategorySet::class,
34
+ ExpirationActionsAbstract::POST_CATEGORY_ADD => PostCategoryAdd::class,
35
+ ExpirationActionsAbstract::POST_CATEGORY_REMOVE => PostCategoryRemove::class,
36
+ ];
37
+ }
38
+
39
+ /**
40
+ * @param string $actionName
41
+ *
42
+ * @return string
43
+ *
44
+ * @throws NonexistentPostException
45
+ */
46
+ public function map($actionName)
47
+ {
48
+ if (! isset($this->actionClassesMap[$actionName])) {
49
+ throw new NonexistentPostException();
50
+ }
51
+
52
+ return $this->actionClassesMap[$actionName];
53
+ }
54
+ }
src/Modules/Expirator/ExpirationActions/DeletePost.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator\ExpirationActions;
4
+
5
+ use PublishPressFuture\Modules\Expirator\Models\ExpirablePostModel;
6
+ use PublishPressFuture\Modules\Expirator\ExpirationActionsAbstract;
7
+ use PublishPressFuture\Modules\Expirator\Interfaces\ExpirationActionInterface;
8
+
9
+ class DeletePost implements ExpirationActionInterface
10
+ {
11
+ /**
12
+ * @var ExpirablePostModel
13
+ */
14
+ private $postModel;
15
+
16
+ /**
17
+ * @param ExpirablePostModel $postModel
18
+ * @param \PublishPressFuture\Framework\WordPress\Facade\ErrorFacade $errorFacade
19
+ */
20
+ public function __construct($postModel, $errorFacade)
21
+ {
22
+ $this->postModel = $postModel;
23
+ }
24
+
25
+ public function __toString()
26
+ {
27
+ return ExpirationActionsAbstract::DELETE_POST;
28
+ }
29
+
30
+ /**
31
+ * @inheritDoc
32
+ */
33
+ public function getNotificationText()
34
+ {
35
+ return __('Post has been successfully deleted.', 'post-expirator');
36
+ }
37
+
38
+ /**
39
+ * @inheritDoc
40
+ */
41
+ public function getExpirationLog()
42
+ {
43
+ return [];
44
+ }
45
+
46
+ /**
47
+ * @inheritDoc
48
+ */
49
+ public function execute()
50
+ {
51
+ return $this->postModel->delete();
52
+ }
53
+ }
src/Modules/Expirator/ExpirationActions/PostCategoryAdd.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator\ExpirationActions;
4
+
5
+ use PublishPressFuture\Framework\WordPress\Facade\ErrorFacade;
6
+ use PublishPressFuture\Modules\Expirator\Models\ExpirablePostModel;
7
+ use PublishPressFuture\Modules\Expirator\ExpirationActionsAbstract;
8
+ use PublishPressFuture\Modules\Expirator\Interfaces\ExpirationActionInterface;
9
+
10
+ class PostCategoryAdd implements ExpirationActionInterface
11
+ {
12
+ /**
13
+ * @var ExpirablePostModel
14
+ */
15
+ private $postModel;
16
+
17
+ /**
18
+ * @var \PublishPressFuture\Framework\WordPress\Facade\ErrorFacade
19
+ */
20
+ private $errorFacade;
21
+
22
+ /**
23
+ * @param ExpirablePostModel $postModel
24
+ * @param \PublishPressFuture\Framework\WordPress\Facade\ErrorFacade $errorFacade
25
+ */
26
+ public function __construct($postModel, $errorFacade)
27
+ {
28
+ $this->postModel = $postModel;
29
+ $this->errorFacade = $errorFacade;
30
+ }
31
+
32
+ public function __toString()
33
+ {
34
+ return ExpirationActionsAbstract::POST_CATEGORY_ADD;
35
+ }
36
+
37
+ /**
38
+ * @inheritDoc
39
+ */
40
+ public function getNotificationText()
41
+ {
42
+ $expirationTaxonomy = $this->postModel->getExpirationTaxonomy();
43
+ $expirationTermsName = $this->postModel->getExpirationCategoryNames();
44
+
45
+ $postTermsName = array_merge(
46
+ $this->postModel->getTermNames($expirationTaxonomy),
47
+ $expirationTermsName
48
+ );
49
+
50
+ return sprintf(
51
+ __('The following terms (%s) were added to the post: "%s". The full list of terms on the post is: %s.', 'post-expirator'),
52
+ $expirationTaxonomy,
53
+ implode(', ', $expirationTermsName),
54
+ implode(', ', $postTermsName)
55
+ );
56
+ }
57
+
58
+ /**
59
+ * @inheritDoc
60
+ */
61
+ public function getExpirationLog()
62
+ {
63
+ return [];
64
+ }
65
+
66
+ /**
67
+ * @inheritDoc
68
+ */
69
+ public function execute()
70
+ {
71
+ $expirationTaxonomy = $this->postModel->getExpirationTaxonomy();
72
+ $newTerms = $this->postModel->getExpirationCategoryIDs();
73
+ $postTerms = $this->postModel->getTermIDs($expirationTaxonomy);
74
+
75
+ $mergedTerms = array_merge($postTerms, $newTerms);
76
+
77
+ $result = $this->postModel->setTerms($mergedTerms, $expirationTaxonomy);
78
+
79
+ return ! $this->errorFacade->isWpError($result);
80
+ }
81
+ }
src/Modules/Expirator/ExpirationActions/PostCategoryRemove.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator\ExpirationActions;
4
+
5
+ use PublishPressFuture\Modules\Expirator\ExpirationActionsAbstract;
6
+ use PublishPressFuture\Modules\Expirator\Interfaces\ExpirationActionInterface;
7
+ use PublishPressFuture\Modules\Expirator\Models\ExpirablePostModel;
8
+
9
+ class PostCategoryRemove implements ExpirationActionInterface
10
+ {
11
+ /**
12
+ * @var ExpirablePostModel
13
+ */
14
+ private $postModel;
15
+
16
+ /**
17
+ * @var \PublishPressFuture\Framework\WordPress\Facade\ErrorFacade
18
+ */
19
+ private $errorFacade;
20
+
21
+ /**
22
+ * @param ExpirablePostModel $postModel
23
+ * @param \PublishPressFuture\Framework\WordPress\Facade\ErrorFacade $errorFacade
24
+ */
25
+ public function __construct($postModel, $errorFacade)
26
+ {
27
+ $this->postModel = $postModel;
28
+ $this->errorFacade = $errorFacade;
29
+ }
30
+
31
+ public function __toString()
32
+ {
33
+ return ExpirationActionsAbstract::POST_CATEGORY_REMOVE;
34
+ }
35
+
36
+ /**
37
+ * @inheritDoc
38
+ */
39
+ public function getNotificationText()
40
+ {
41
+ $expirationTaxonomy = $this->postModel->getExpirationTaxonomy();
42
+ $expirationTermsName = $this->postModel->getExpirationCategoryNames();
43
+ $postTermsName = $this->postModel->getTermNames($expirationTaxonomy);
44
+
45
+ $removedTerms = array_intersect($postTermsName, $expirationTermsName);
46
+ $newListOfTerms = array_diff($postTermsName, $expirationTermsName);
47
+
48
+ return sprintf(
49
+ __(
50
+ 'The following terms (%s) were removed from the post: "%s". The new list of terms on the post is: %s.',
51
+ 'post-expirator'
52
+ ),
53
+ $expirationTaxonomy,
54
+ implode(', ', $removedTerms),
55
+ implode(', ', $newListOfTerms)
56
+ );
57
+ }
58
+
59
+ /**
60
+ * @inheritDoc
61
+ */
62
+ public function getExpirationLog()
63
+ {
64
+ return [];
65
+ }
66
+
67
+ /**
68
+ * @inheritDoc
69
+ */
70
+ public function execute()
71
+ {
72
+ $expirationTaxonomy = $this->postModel->getExpirationTaxonomy();
73
+ $termsToRemove = $this->postModel->getExpirationCategoryIDs();
74
+ $postTerms = $this->postModel->getTermIDs($expirationTaxonomy);
75
+
76
+ $newPostTerms = array_diff($postTerms, $termsToRemove);
77
+
78
+ $result = $this->postModel->setTerms($newPostTerms, $expirationTaxonomy);
79
+
80
+ return ! $this->errorFacade->isWpError($result);
81
+ }
82
+ }
src/Modules/Expirator/ExpirationActions/PostCategorySet.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator\ExpirationActions;
4
+
5
+ use PublishPressFuture\Modules\Expirator\ExpirationActionsAbstract;
6
+ use PublishPressFuture\Modules\Expirator\Interfaces\ExpirationActionInterface;
7
+ use PublishPressFuture\Modules\Expirator\Models\ExpirablePostModel;
8
+
9
+ class PostCategorySet implements ExpirationActionInterface
10
+ {
11
+ /**
12
+ * @var ExpirablePostModel
13
+ */
14
+ private $postModel;
15
+
16
+ /**
17
+ * @var \PublishPressFuture\Framework\WordPress\Facade\ErrorFacade
18
+ */
19
+ private $errorFacade;
20
+
21
+ /**
22
+ * @param ExpirablePostModel $postModel
23
+ * @param \PublishPressFuture\Framework\WordPress\Facade\ErrorFacade $errorFacade
24
+ */
25
+ public function __construct($postModel, $errorFacade)
26
+ {
27
+ $this->postModel = $postModel;
28
+ $this->errorFacade = $errorFacade;
29
+ }
30
+
31
+ public function __toString()
32
+ {
33
+ return ExpirationActionsAbstract::POST_CATEGORY_SET;
34
+ }
35
+
36
+ /**
37
+ * @inheritDoc
38
+ */
39
+ public function getNotificationText()
40
+ {
41
+ $expirationTaxonomy = $this->postModel->getExpirationTaxonomy();
42
+ $expirationTermsName = $this->postModel->getExpirationCategoryNames();
43
+ $postTermsName = $this->postModel->getTermNames($expirationTaxonomy);
44
+
45
+ return sprintf(
46
+ __(
47
+ 'The following terms (%s) were set to the post: "%s". The old list of terms on the post was: %s.',
48
+ 'post-expirator'
49
+ ),
50
+ $expirationTaxonomy,
51
+ implode(', ', $expirationTermsName),
52
+ implode(', ', $postTermsName)
53
+ );
54
+ }
55
+
56
+ /**
57
+ * @inheritDoc
58
+ */
59
+ public function getExpirationLog()
60
+ {
61
+ return [];
62
+ }
63
+
64
+ /**
65
+ * @inheritDoc
66
+ */
67
+ public function execute()
68
+ {
69
+ $expirationTaxonomy = $this->postModel->getExpirationTaxonomy();
70
+ $newTerms = $this->postModel->getExpirationCategoryIDs();
71
+
72
+
73
+ $result = $this->postModel->setTerms($newTerms, $expirationTaxonomy);
74
+
75
+ return ! $this->errorFacade->isWpError($result);
76
+ }
77
+ }
src/Modules/Expirator/ExpirationActions/PostStatusToDraft.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator\ExpirationActions;
4
+
5
+ use PublishPressFuture\Modules\Expirator\Models\ExpirablePostModel;
6
+ use PublishPressFuture\Modules\Expirator\ExpirationActionsAbstract;
7
+ use PublishPressFuture\Modules\Expirator\Interfaces\ExpirationActionInterface;
8
+
9
+ class PostStatusToDraft implements ExpirationActionInterface
10
+ {
11
+ /**
12
+ * @var ExpirablePostModel
13
+ */
14
+ private $postModel;
15
+
16
+ /**
17
+ * @param ExpirablePostModel $postModel
18
+ * @param \PublishPressFuture\Framework\WordPress\Facade\ErrorFacade $errorFacade
19
+ */
20
+ public function __construct($postModel, $errorFacade)
21
+ {
22
+ $this->postModel = $postModel;
23
+ }
24
+
25
+ public function __toString()
26
+ {
27
+ return ExpirationActionsAbstract::POST_STATUS_TO_DRAFT;
28
+ }
29
+
30
+ /**
31
+ * @inheritDoc
32
+ */
33
+ public function getNotificationText()
34
+ {
35
+ return sprintf(
36
+ __('Post status has been successfully changed to "%s".', 'post-expirator'),
37
+ 'draft'
38
+ );
39
+ }
40
+
41
+ /**
42
+ * @inheritDoc
43
+ */
44
+ public function getExpirationLog()
45
+ {
46
+ return [];
47
+ }
48
+
49
+ /**
50
+ * @inheritDoc
51
+ * @throws \PublishPressFuture\Framework\WordPress\Exceptions\NonexistentPostException
52
+ */
53
+ public function execute()
54
+ {
55
+ return $this->postModel->setPostStatus('draft');
56
+ }
57
+ }
src/Modules/Expirator/ExpirationActions/PostStatusToPrivate.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator\ExpirationActions;
4
+
5
+ use PublishPressFuture\Modules\Expirator\Models\ExpirablePostModel;
6
+ use PublishPressFuture\Modules\Expirator\ExpirationActionsAbstract;
7
+ use PublishPressFuture\Modules\Expirator\Interfaces\ExpirationActionInterface;
8
+
9
+ class PostStatusToPrivate implements ExpirationActionInterface
10
+ {
11
+ /**
12
+ * @var ExpirablePostModel
13
+ */
14
+ private $postModel;
15
+
16
+ /**
17
+ * @param ExpirablePostModel $postModel
18
+ * @param \PublishPressFuture\Framework\WordPress\Facade\ErrorFacade $errorFacade
19
+ */
20
+ public function __construct($postModel, $errorFacade)
21
+ {
22
+ $this->postModel = $postModel;
23
+ }
24
+
25
+ public function __toString()
26
+ {
27
+ return ExpirationActionsAbstract::POST_STATUS_TO_PRIVATE;
28
+ }
29
+
30
+ /**
31
+ * @inheritDoc
32
+ */
33
+ public function getNotificationText()
34
+ {
35
+ return sprintf(
36
+ __('Post status has been successfully changed to "%s".', 'post-expirator'),
37
+ 'private'
38
+ );
39
+ }
40
+
41
+ /**
42
+ * @inheritDoc
43
+ */
44
+ public function getExpirationLog()
45
+ {
46
+ return [];
47
+ }
48
+
49
+ /**
50
+ * @inheritDoc
51
+ */
52
+ public function execute()
53
+ {
54
+ return $this->postModel->setPostStatus('private');
55
+ }
56
+ }
src/Modules/Expirator/ExpirationActions/PostStatusToTrash.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator\ExpirationActions;
4
+
5
+ use PublishPressFuture\Modules\Expirator\Models\ExpirablePostModel;
6
+ use PublishPressFuture\Modules\Expirator\ExpirationActionsAbstract;
7
+ use PublishPressFuture\Modules\Expirator\Interfaces\ExpirationActionInterface;
8
+
9
+ class PostStatusToTrash implements ExpirationActionInterface
10
+ {
11
+ /**
12
+ * @var ExpirablePostModel
13
+ */
14
+ private $postModel;
15
+
16
+ /**
17
+ * @param ExpirablePostModel $postModel
18
+ * @param \PublishPressFuture\Framework\WordPress\Facade\ErrorFacade $errorFacade
19
+ */
20
+ public function __construct($postModel, $errorFacade)
21
+ {
22
+ $this->postModel = $postModel;
23
+ }
24
+
25
+ public function __toString()
26
+ {
27
+ return ExpirationActionsAbstract::POST_STATUS_TO_TRASH;
28
+ }
29
+
30
+ /**
31
+ * @inheritDoc
32
+ */
33
+ public function getNotificationText()
34
+ {
35
+ return sprintf(
36
+ __('Post status has been successfully changed to "%s".', 'post-expirator'),
37
+ 'trash'
38
+ );
39
+ }
40
+
41
+ /**
42
+ * @inheritDoc
43
+ */
44
+ public function getExpirationLog()
45
+ {
46
+ return [];
47
+ }
48
+
49
+ /**
50
+ * @inheritDoc
51
+ */
52
+ public function execute()
53
+ {
54
+ return $this->postModel->setPostStatus('trash');
55
+ }
56
+ }
src/Modules/Expirator/ExpirationActions/StickPost.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator\ExpirationActions;
4
+
5
+ use PublishPressFuture\Modules\Expirator\Models\ExpirablePostModel;
6
+ use PublishPressFuture\Modules\Expirator\ExpirationActionsAbstract;
7
+ use PublishPressFuture\Modules\Expirator\Interfaces\ExpirationActionInterface;
8
+
9
+ class StickPost implements ExpirationActionInterface
10
+ {
11
+ /**
12
+ * @var ExpirablePostModel
13
+ */
14
+ private $postModel;
15
+
16
+ /**
17
+ * @param ExpirablePostModel $postModel
18
+ * @param \PublishPressFuture\Framework\WordPress\Facade\ErrorFacade $errorFacade
19
+ */
20
+ public function __construct($postModel, $errorFacade)
21
+ {
22
+ $this->postModel = $postModel;
23
+ }
24
+
25
+ public function __toString()
26
+ {
27
+ return ExpirationActionsAbstract::STICK_POST;
28
+ }
29
+
30
+ /**
31
+ * @inheritDoc
32
+ */
33
+ public function getNotificationText()
34
+ {
35
+ return __('Post has been added to stickies list.', 'post-expirator');
36
+ }
37
+
38
+ /**
39
+ * @inheritDoc
40
+ */
41
+ public function getExpirationLog()
42
+ {
43
+ return [];
44
+ }
45
+
46
+ /**
47
+ * @inheritDoc
48
+ */
49
+ public function execute()
50
+ {
51
+ return $this->postModel->stick();
52
+ }
53
+ }
src/Modules/Expirator/ExpirationActions/UnstickPost.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator\ExpirationActions;
4
+
5
+ use PublishPressFuture\Modules\Expirator\Models\ExpirablePostModel;
6
+ use PublishPressFuture\Modules\Expirator\ExpirationActionsAbstract;
7
+ use PublishPressFuture\Modules\Expirator\Interfaces\ExpirationActionInterface;
8
+
9
+ class UnstickPost implements ExpirationActionInterface
10
+ {
11
+ /**
12
+ * @var ExpirablePostModel
13
+ */
14
+ private $postModel;
15
+
16
+ /**
17
+ * @param ExpirablePostModel $postModel
18
+ * @param \PublishPressFuture\Framework\WordPress\Facade\ErrorFacade $errorFacade
19
+ */
20
+ public function __construct($postModel, $errorFacade)
21
+ {
22
+ $this->postModel = $postModel;
23
+ }
24
+
25
+ public function __toString()
26
+ {
27
+ return ExpirationActionsAbstract::STICK_POST;
28
+ }
29
+
30
+ /**
31
+ * @inheritDoc
32
+ */
33
+ public function getNotificationText()
34
+ {
35
+ return __('Post has been removed from stickies list.', 'post-expirator');
36
+ }
37
+
38
+ /**
39
+ * @inheritDoc
40
+ */
41
+ public function getExpirationLog()
42
+ {
43
+ return [];
44
+ }
45
+
46
+ /**
47
+ * @inheritDoc
48
+ */
49
+ public function execute()
50
+ {
51
+ return $this->postModel->unstick();
52
+ }
53
+ }
src/Modules/Expirator/ExpirationActionsAbstract.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator;
4
+
5
+ abstract class ExpirationActionsAbstract
6
+ {
7
+ const POST_STATUS_TO_DRAFT = 'draft';
8
+ const POST_STATUS_TO_PRIVATE = 'private';
9
+ const POST_STATUS_TO_TRASH = 'trash';
10
+ const DELETE_POST = 'delete';
11
+ const STICK_POST = 'stick';
12
+ const UNSTICK_POST = 'unstick';
13
+ const POST_CATEGORY_SET = 'category';
14
+ const POST_CATEGORY_ADD = 'category-add';
15
+ const POST_CATEGORY_REMOVE = 'category-remove';
16
+ }
src/Modules/Expirator/ExpirationScheduler.php ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Expirator;
7
+
8
+ use PublishPressFuture\Core\HookableInterface;
9
+ use PublishPressFuture\Framework\Logger\LoggerInterface;
10
+ use PublishPressFuture\Framework\WordPress\Facade\CronFacade;
11
+ use PublishPressFuture\Framework\WordPress\Facade\DateTimeFacade;
12
+ use PublishPressFuture\Framework\WordPress\Facade\ErrorFacade;
13
+ use PublishPressFuture\Modules\Expirator\Interfaces\SchedulerInterface;
14
+ use WP_Error;
15
+
16
+ class ExpirationScheduler implements SchedulerInterface
17
+ {
18
+ /**
19
+ * @var HookableInterface
20
+ */
21
+ private $hooks;
22
+
23
+ /**
24
+ * @var CronFacade
25
+ */
26
+ private $cron;
27
+
28
+ /**
29
+ * @var ErrorFacade
30
+ */
31
+ private $error;
32
+
33
+ /**
34
+ * @var LoggerInterface
35
+ */
36
+ private $logger;
37
+
38
+ /**
39
+ * @var DateTimeFacade
40
+ */
41
+ private $datetime;
42
+
43
+ /**
44
+ * @var callable
45
+ */
46
+ private $postModelFactory;
47
+
48
+ /**
49
+ * @param HookableInterface $hooksFacade
50
+ * @param CronFacade $cronFacade
51
+ * @param ErrorFacade $errorFacade
52
+ * @param LoggerInterface $logger
53
+ * @param DateTimeFacade $datetime
54
+ * @param callable $postModelFactory
55
+ */
56
+ public function __construct($hooksFacade, $cronFacade, $errorFacade, $logger, $datetime, $postModelFactory)
57
+ {
58
+ $this->hooks = $hooksFacade;
59
+ $this->cron = $cronFacade;
60
+ $this->error = $errorFacade;
61
+ $this->logger = $logger;
62
+ $this->datetime = $datetime;
63
+ $this->postModelFactory = $postModelFactory;
64
+ }
65
+
66
+ /**
67
+ * @param int $postId
68
+ * @param int $timestamp
69
+ * @param array $opts
70
+ * @return void
71
+ */
72
+ public function schedule($postId, $timestamp, $opts)
73
+ {
74
+ $postId = (int)$postId;
75
+
76
+ $this->hooks->doAction(HooksAbstract::ACTION_LEGACY_SCHEDULE, $postId, $timestamp, $opts);
77
+
78
+ $this->unscheduleIfScheduled($postId, $timestamp);
79
+
80
+ $scheduled = $this->cron->scheduleSingleEvent($timestamp, HooksAbstract::ACTION_EXPIRE_POST, [$postId], true);
81
+
82
+ if (! $scheduled) {
83
+ $this->logger->debug(
84
+ sprintf(
85
+ '%d -> TRIED TO SCHEDULE CRON EVENT at %s (%s) with options %s %s',
86
+ $postId,
87
+ $this->datetime->getWpDate('r', $timestamp),
88
+ $timestamp,
89
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
90
+ print_r($opts, true),
91
+ $this->error->isWpError($scheduled) ? $this->error->getWpErrorMessage(
92
+ $scheduled
93
+ ) : 'no errors found'
94
+ )
95
+ );
96
+
97
+ return;
98
+ }
99
+
100
+ $this->storeExpirationDataInPostMeta($postId, $timestamp, $opts);
101
+
102
+ $this->logger->debug(
103
+ sprintf(
104
+ '%d -> CRON EVENT SCHEDULED at %s (%s) with options %s, no errors found',
105
+ $postId,
106
+ $this->datetime->getWpDate('r', $timestamp),
107
+ $timestamp,
108
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
109
+ print_r($opts, true)
110
+ )
111
+ );
112
+ }
113
+
114
+ private function unscheduleIfScheduled($postId, $timestamp)
115
+ {
116
+ if ($this->isScheduled($postId)) {
117
+ $result = $this->removeSchedule($postId);
118
+
119
+ $errorDetails = $this->error->isWpError($result) ? $this->error->getWpErrorMessage(
120
+ $result
121
+ ) : 'no errors found';
122
+ $message = $postId . ' -> EXISTING CRON EVENT FOUND - UNSCHEDULED - ' . $errorDetails;
123
+
124
+ $this->logger->debug($message);
125
+ }
126
+ }
127
+
128
+ public function isScheduled($postId)
129
+ {
130
+ $scheduledWithNewHook = $this->cron->getNextScheduleForEvent(HooksAbstract::ACTION_EXPIRE_POST, [$postId]);
131
+
132
+ if ($scheduledWithNewHook) {
133
+ return true;
134
+ }
135
+
136
+ return $this->cron->getNextScheduleForEvent(HooksAbstract::ACTION_LEGACY_EXPIRE_POST, [$postId]);
137
+ }
138
+
139
+ /**
140
+ * @param int $postId
141
+ * @return false|int|WP_Error
142
+ */
143
+ private function removeSchedule($postId)
144
+ {
145
+ $legacyResult = $this->cron->clearScheduledHook(HooksAbstract::ACTION_LEGACY_EXPIRE_POST, [$postId], true);
146
+ $result = $this->cron->clearScheduledHook(HooksAbstract::ACTION_EXPIRE_POST, [$postId], true);
147
+
148
+ if ($this->error->isWpError($legacyResult)) {
149
+ return $legacyResult;
150
+ }
151
+
152
+ if ($this->error->isWpError($result)) {
153
+ return $result;
154
+ }
155
+
156
+ return $legacyResult || $result;
157
+ }
158
+
159
+ /**
160
+ * @param $postId
161
+ * @param $timestamp
162
+ * @param $opts
163
+ * @return void
164
+ */
165
+ private function storeExpirationDataInPostMeta($postId, $timestamp, $opts)
166
+ {
167
+ $postModelFactory = $this->postModelFactory;
168
+ $postModel = $postModelFactory($postId);
169
+
170
+ $postModel->updateMeta(
171
+ [
172
+ '_expiration-date' => $timestamp,
173
+ '_expiration-date-status' => 'saved',
174
+ '_expiration-date-options' => $opts,
175
+ '_expiration-date-type' => $opts['expireType'],
176
+ '_expiration-date-categories' => isset($opts['category']) ? $opts['category'] : [],
177
+ '_expiration-date-taxonomy' => isset($opts['categoryTaxonomy']) ? $opts['categoryTaxonomy'] : '',
178
+ ]
179
+ );
180
+ }
181
+
182
+ /**
183
+ * @inheritDoc
184
+ */
185
+ public function unschedule($postId)
186
+ {
187
+ $this->hooks->doAction(HooksAbstract::ACTION_LEGACY_UNSCHEDULE, $postId);
188
+
189
+ if ($this->isScheduled($postId)) {
190
+ $this->cron->clearScheduledHook(HooksAbstract::ACTION_LEGACY_EXPIRE_POST, [$postId]);
191
+ $this->cron->clearScheduledHook(HooksAbstract::ACTION_EXPIRE_POST, [$postId]);
192
+
193
+ $this->logger->debug(sprintf('%d -> UNSCHEDULED, no errors found', $postId));
194
+ }
195
+
196
+ $this->removeExpirationDataFromPostMeta($postId);
197
+ }
198
+
199
+ private function removeExpirationDataFromPostMeta($postId)
200
+ {
201
+ $postModelFactory = $this->postModelFactory;
202
+ $postModel = $postModelFactory($postId);
203
+
204
+ $postModel->deleteMeta(
205
+ [
206
+ '_expiration-date',
207
+ '_expiration-date-status',
208
+ '_expiration-date-options',
209
+ '_expiration-date-type',
210
+ '_expiration-date-categories',
211
+ '_expiration-date-taxonomy',
212
+ ]
213
+ );
214
+ }
215
+ }
src/Modules/Expirator/HooksAbstract.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Expirator;
7
+
8
+ abstract class HooksAbstract
9
+ {
10
+ const ACTION_ADMIN_INIT = 'admin_init';
11
+ const ACTION_LEGACY_SCHEDULE = 'postexpirator_schedule';
12
+ const ACTION_LEGACY_UNSCHEDULE = 'postexpirator_unschedule';
13
+ const ACTION_LEGACY_EXPIRE_POST = 'postExpiratorExpire';
14
+ const ACTION_LEGACY_DELETE = 'expirationdate_delete';
15
+ const ACTION_LEGACY_MULTISITE_DELETE_PREFIX = 'expirationdate_delete_';
16
+ const FILTER_LEGACY_CUSTOM_EXPIRATION_TYPE = 'postexpirator_custom_posttype_expire';
17
+ const ACTION_SCHEDULE_POST_EXPIRATION = 'publishpressfuture_schedule_expiration';
18
+ const ACTION_UNSCHEDULE_POST_EXPIRATION = 'publishpressfuture_unschedule_expiration';
19
+ const ACTION_EXPIRE_POST = 'publishpressfuture_expire';
20
+ const FILTER_CUSTOM_EXPIRATION_TYPE = 'publishpressfuture_custom_expiration_type';
21
+
22
+ public static function getActionLegacyMultisiteDelete($blogId)
23
+ {
24
+ return self::ACTION_LEGACY_MULTISITE_DELETE_PREFIX . $blogId;
25
+ }
26
+ }
src/Modules/Expirator/Interfaces/ActionMapperInterface.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Expirator\Interfaces;
7
+
8
+
9
+ interface ActionMapperInterface
10
+ {
11
+ /**
12
+ * @param string $actionName
13
+ *
14
+ * @return ActionableInterface
15
+ */
16
+ public function map($actionName);
17
+ }
src/Modules/Expirator/Interfaces/ActionableInterface.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PublishPressFuture\Modules\Expirator\Interfaces;
4
+
5
+
6
+ interface ActionableInterface
7
+ {
8
+ /**
9
+ * @return void
10
+ */
11
+ public function setAction($action);
12
+ }
src/Modules/Expirator/Interfaces/ExpirationActionInterface.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Expirator\Interfaces;
7
+
8
+
9
+ interface ExpirationActionInterface
10
+ {
11
+ /**
12
+ * @return bool
13
+ */
14
+ public function execute();
15
+
16
+ /**
17
+ * @return string
18
+ */
19
+ public function getNotificationText();
20
+
21
+ /**
22
+ * @return array
23
+ */
24
+ public function getExpirationLog();
25
+ }
src/Modules/Expirator/Interfaces/SchedulerInterface.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Expirator\Interfaces;
7
+
8
+ interface SchedulerInterface
9
+ {
10
+ /**
11
+ * @param int $postId
12
+ * @param int $timestamp
13
+ * @param array $opts
14
+ * @return void
15
+ */
16
+ public function schedule($postId, $timestamp, $opts);
17
+
18
+ /**
19
+ * @param int $postId
20
+ * @return void
21
+ */
22
+ public function unschedule($postId);
23
+
24
+ /**
25
+ * @param int $postId
26
+ * @return bool
27
+ */
28
+ public function isScheduled($postId);
29
+ }
src/Modules/Expirator/Models/CurrentUserModel.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Expirator\Models;
7
+
8
+ use PublishPressFuture\Modules\Expirator\CapabilitiesAbstract as Capabilities;
9
+
10
+ class CurrentUserModel extends \PublishPressFuture\Framework\WordPress\Models\CurrentUserModel
11
+ {
12
+ public function userCanExpirePosts()
13
+ {
14
+ $user = $this->getUserInstance();
15
+
16
+ return is_object($user)
17
+ && $user->has_cap(Capabilities::EXPIRE_POST);
18
+ }
19
+ }
src/Modules/Expirator/Models/DefaultDataModel.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Expirator\Models;
7
+
8
+ class DefaultDataModel
9
+ {
10
+ /**
11
+ * @var \PublishPressFuture\Modules\Settings\SettingsFacade
12
+ */
13
+ private $settings;
14
+
15
+ /**
16
+ * @var \PublishPressFuture\Framework\WordPress\Facade\OptionsFacade
17
+ */
18
+ private $options;
19
+
20
+ /**
21
+ * @param \PublishPressFuture\Modules\Settings\SettingsFacade $settings
22
+ * @param \PublishPressFuture\Framework\WordPress\Facade\OptionsFacade $options
23
+ */
24
+ public function __construct($settings, $options)
25
+ {
26
+ $this->settings = $settings;
27
+ $this->options = $options;
28
+ }
29
+
30
+ /**
31
+ * @param string $postType
32
+ * @return array
33
+ */
34
+ public function getDefaultExpirationDateForPostType($postType)
35
+ {
36
+ $defaultMonth = date_i18n('m');
37
+ $defaultDay = date_i18n('d');
38
+ $defaultHour = date_i18n('H');
39
+ $defaultYear = date_i18n('Y');
40
+ $defaultMinute = date_i18n('i');
41
+ $timestamp = time();
42
+
43
+ $defaultDate = $customDate = $generalDate = $generalCustomDate = '';
44
+
45
+ // Get the values from the general settings.
46
+ $generalDate = $this->settings->getDefaultDate();
47
+
48
+ if ('custom' === $generalDate) {
49
+ $custom = $this->settings->getDefaultDateCustom();
50
+ if ($custom !== false) {
51
+ $generalCustomDate = $custom;
52
+ }
53
+ }
54
+
55
+ // Get the values for the post_type.
56
+ $defaults = $this->settings->getPostTypeDefaults($postType);
57
+
58
+ if (isset($defaults['default-expire-type'])) {
59
+ $defaultDate = $defaults['default-expire-type'];
60
+ switch ($defaultDate) {
61
+ case 'custom':
62
+ $customDate = $defaults['default-custom-date'];
63
+ break;
64
+ case 'inherit':
65
+ $customDate = $generalCustomDate;
66
+ $defaultDate = $generalDate;
67
+ break;
68
+ }
69
+ } else {
70
+ $defaultDate = $generalDate;
71
+ $customDate = $generalCustomDate;
72
+ }
73
+
74
+ if ('custom' === $defaultDate) {
75
+ $custom = $this->settings->getDefaultDateCustom();
76
+
77
+ if (! empty($customDate)) {
78
+ $timezoneString = $this->options->getOption('timezone_string');
79
+ if ($timezoneString) {
80
+ // @TODO Using date_default_timezone_set() and similar isn't allowed, instead use WP internal timezone support.
81
+ // phpcs:ignore WordPress.DateTime.RestrictedFunctions.timezone_change_date_default_timezone_set
82
+ date_default_timezone_set($timezoneString);
83
+ }
84
+
85
+ // strip the quotes in case the user provides them.
86
+ $customDate = str_replace(
87
+ '"',
88
+ '',
89
+ html_entity_decode($customDate, ENT_QUOTES)
90
+ );
91
+
92
+ $timestamp = time() + (strtotime($customDate) - time());
93
+ if ($timezoneString) {
94
+ // @TODO Using date_default_timezone_set() and similar isn't allowed, instead use WP internal timezone support.
95
+ // phpcs:ignore WordPress.DateTime.RestrictedFunctions.timezone_change_date_default_timezone_set
96
+ date_default_timezone_set('UTC');
97
+ }
98
+ }
99
+
100
+ $defaultMonth = get_date_from_gmt(gmdate('Y-m-d H:i:s', $timestamp), 'm');
101
+ $defaultDay = get_date_from_gmt(gmdate('Y-m-d H:i:s', $timestamp), 'd');
102
+ $defaultYear = get_date_from_gmt(gmdate('Y-m-d H:i:s', $timestamp), 'Y');
103
+ $defaultHour = get_date_from_gmt(gmdate('Y-m-d H:i:s', $timestamp), 'H');
104
+ $defaultMinute = get_date_from_gmt(gmdate('Y-m-d H:i:s', $timestamp), 'i');
105
+ }
106
+
107
+ return array(
108
+ 'month' => $defaultMonth,
109
+ 'day' => $defaultDay,
110
+ 'year' => $defaultYear,
111
+ 'hour' => $defaultHour,
112
+ 'minute' => $defaultMinute,
113
+ 'ts' => $timestamp,
114
+ );
115
+ }
116
+
117
+ }
src/Modules/Expirator/Models/ExpirablePostModel.php ADDED
@@ -0,0 +1,513 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Expirator\Models;
7
+
8
+ use PublishPressFuture\Framework\WordPress\Models\PostModel;
9
+ use PublishPressFuture\Modules\Expirator\ExpirationActionsAbstract;
10
+ use PublishPressFuture\Modules\Expirator\HooksAbstract;
11
+ use PublishPressFuture\Modules\Expirator\Interfaces\ExpirationActionInterface;
12
+
13
+ class ExpirablePostModel extends PostModel
14
+ {
15
+ /**
16
+ * @var \PublishPressFuture\Modules\Debug\Debug
17
+ */
18
+ private $debug;
19
+
20
+ /**
21
+ * @var \PublishPressFuture\Framework\WordPress\Facade\OptionsFacade
22
+ */
23
+ private $options;
24
+
25
+ /**
26
+ * @var \PublishPressFuture\Framework\WordPress\Facade\HooksFacade
27
+ */
28
+ private $hooks;
29
+
30
+ /**
31
+ * @var \PublishPressFuture\Framework\WordPress\Facade\UsersFacade
32
+ */
33
+ private $users;
34
+
35
+ /**
36
+ * @var \PublishPressFuture\Modules\Expirator\ExpirationActionMapper
37
+ */
38
+ private $expirationActionMapper;
39
+
40
+ /**
41
+ * @var \PublishPressFuture\Modules\Expirator\Interfaces\SchedulerInterface
42
+ */
43
+ private $scheduler;
44
+
45
+ /**
46
+ * @var \PublishPressFuture\Modules\Settings\SettingsFacade
47
+ */
48
+ private $settings;
49
+
50
+ /**
51
+ * @var \PublishPressFuture\Framework\WordPress\Facade\EmailFacade
52
+ */
53
+ private $email;
54
+
55
+ /**
56
+ * @var string
57
+ */
58
+ private $expirationType = '';
59
+
60
+ /**
61
+ * @var string[]
62
+ */
63
+ private $expirationCategories = [];
64
+
65
+ /**
66
+ * @var string
67
+ */
68
+ private $expirationTaxonomy = '';
69
+
70
+ /**
71
+ * @var bool
72
+ */
73
+ private $expirationIsEnabled = null;
74
+
75
+ /**
76
+ * @var int
77
+ */
78
+ private $expirationDate = null;
79
+
80
+ /**
81
+ * @var array
82
+ */
83
+ private $expirationOptions = [];
84
+
85
+ /**
86
+ * @var \PublishPressFuture\Modules\Expirator\Interfaces\ExpirationActionInterface
87
+ */
88
+ private $expirationActionInstance;
89
+
90
+ /**
91
+ * @var callable
92
+ */
93
+ protected $termModelFactory;
94
+
95
+ /**
96
+ * @var callable
97
+ */
98
+ protected $expirationActionFactory;
99
+
100
+ /**
101
+ * @param int $postId
102
+ * @param \PublishPressFuture\Modules\Debug\Debug $debug
103
+ * @param \PublishPressFuture\Framework\WordPress\Facade\OptionsFacade $options
104
+ * @param \PublishPressFuture\Framework\WordPress\Facade\HooksFacade $hooks
105
+ * @param \PublishPressFuture\Framework\WordPress\Facade\UsersFacade $users
106
+ * @param \PublishPressFuture\Modules\Expirator\ExpirationActionMapper $expirationActionMapper
107
+ * @param \PublishPressFuture\Modules\Expirator\Interfaces\SchedulerInterface $scheduler
108
+ * @param \PublishPressFuture\Modules\Settings\SettingsFacade $settings
109
+ * @param \PublishPressFuture\Framework\WordPress\Facade\EmailFacade $email
110
+ * @param callable $termModelFactory
111
+ * @param callable $expirationActionFactory
112
+ */
113
+ public function __construct(
114
+ $postId,
115
+ $debug,
116
+ $options,
117
+ $hooks,
118
+ $users,
119
+ $expirationActionMapper,
120
+ $scheduler,
121
+ $settings,
122
+ $email,
123
+ $termModelFactory,
124
+ $expirationActionFactory
125
+ ) {
126
+ parent::__construct($postId, $termModelFactory);
127
+
128
+ $this->debug = $debug;
129
+ $this->options = $options;
130
+ $this->hooks = $hooks;
131
+ $this->expirationActionMapper = $expirationActionMapper;
132
+ $this->scheduler = $scheduler;
133
+ $this->users = $users;
134
+ $this->settings = $settings;
135
+ $this->email = $email;
136
+ $this->termModelFactory = $termModelFactory;
137
+ $this->expirationActionFactory = $expirationActionFactory;
138
+ }
139
+
140
+ public function getExpirationDataAsArray()
141
+ {
142
+ return [
143
+ 'expireType' => $this->getExpirationType(),
144
+ 'category' => $this->getExpirationCategoryIDs(),
145
+ 'categoryTaxonomy' => $this->getExpirationTaxonomy(),
146
+ 'enabled' => $this->isExpirationEnabled(),
147
+ 'date' => $this->getExpirationDate(),
148
+ ];
149
+ }
150
+
151
+ /**
152
+ * @return string
153
+ */
154
+ public function getExpirationType()
155
+ {
156
+ if (empty($this->expirationType)) {
157
+ $this->expirationType = $this->getMeta('_expiration-date-type', true);
158
+
159
+ $options = $this->getExpirationOptions();
160
+
161
+ if (empty($this->expirationType)) {
162
+ $this->expirationType = isset($options['expireType'])
163
+ ? $options['expireType'] : '';
164
+ }
165
+
166
+ $postType = $this->getPostType();
167
+
168
+ if (empty($this->expirationType)) {
169
+ switch ($postType) {
170
+ case 'page':
171
+ $this->expirationType = $this->options->getOption(
172
+ 'expirationdateExpiredPageStatus',
173
+ ExpirationActionsAbstract::POST_STATUS_TO_DRAFT
174
+ );
175
+ break;
176
+ case 'post':
177
+ $this->expirationType = $this->options->getOption(
178
+ 'expirationdateExpiredPostStatus',
179
+ ExpirationActionsAbstract::POST_STATUS_TO_DRAFT
180
+ );
181
+ break;
182
+ }
183
+ }
184
+
185
+ /**
186
+ * @deprecated
187
+ */
188
+ $this->expirationType = $this->hooks->applyFilters(
189
+ HooksAbstract::FILTER_LEGACY_CUSTOM_EXPIRATION_TYPE,
190
+ $this->expirationType,
191
+ $postType
192
+ );
193
+
194
+ $this->expirationType = $this->hooks->applyFilters(
195
+ HooksAbstract::FILTER_CUSTOM_EXPIRATION_TYPE,
196
+ $this->expirationType,
197
+ $postType
198
+ );
199
+ }
200
+
201
+ return $this->expirationType;
202
+ }
203
+
204
+ /**
205
+ * @return int[]
206
+ */
207
+ public function getExpirationCategoryIDs()
208
+ {
209
+ if (empty($this->expirationCategories)) {
210
+ $this->expirationCategories = (array)$this->getMeta('_expiration-date-categories', true);
211
+
212
+ $options = $this->getExpirationOptions();
213
+
214
+ if (empty($this->expirationCategories)) {
215
+ $this->expirationCategories = isset($options['category']) ? $options['category'] : false;
216
+ }
217
+
218
+ foreach ($this->expirationCategories as &$categoryID) {
219
+ $categoryID = (int)$categoryID;
220
+ }
221
+
222
+ $this->expirationCategories = array_unique($this->expirationCategories);
223
+ }
224
+
225
+ return $this->expirationCategories;
226
+ }
227
+
228
+ /**
229
+ * @return string[]
230
+ */
231
+ public function getExpirationCategoryNames()
232
+ {
233
+ $categories = $this->getExpirationCategoryIDs();
234
+
235
+ $categoryNames = [];
236
+
237
+ foreach ($categories as $categoryId) {
238
+ $termModelFactory = $this->termModelFactory;
239
+
240
+ $termModel = $termModelFactory($categoryId);
241
+
242
+ $categoryNames[] = $termModel->getName();
243
+ }
244
+
245
+ return $categoryNames;
246
+ }
247
+
248
+ /**
249
+ * @return string|false
250
+ */
251
+ public function getExpirationTaxonomy()
252
+ {
253
+ if (empty($this->expirationTaxonomy)) {
254
+ $this->expirationTaxonomy = $this->getMeta('_expiration-date-taxonomy', true);
255
+
256
+ $options = $this->getExpirationOptions();
257
+
258
+ if (empty($this->expirationTaxonomy)) {
259
+ $this->expirationTaxonomy = isset($options['categoryTaxonomy']) ? $options['categoryTaxonomy'] : '';
260
+ }
261
+ }
262
+
263
+ return $this->expirationTaxonomy;
264
+ }
265
+
266
+ /**
267
+ * @return bool
268
+ */
269
+ public function isExpirationEnabled()
270
+ {
271
+ if (is_null($this->expirationIsEnabled)) {
272
+ $date = $this->getExpirationDate();
273
+
274
+ $this->expirationIsEnabled = $this->getMeta('_expiration-date-status', true) === 'saved'
275
+ && ! (empty($date));
276
+ }
277
+
278
+ return (bool)$this->expirationIsEnabled;
279
+ }
280
+
281
+ /**
282
+ * @return int|false
283
+ */
284
+ public function getExpirationDate()
285
+ {
286
+ if (is_null($this->expirationDate)) {
287
+ $this->expirationDate = $this->getMeta('_expiration-date', true);
288
+ }
289
+
290
+ return $this->expirationDate;
291
+ }
292
+
293
+ /**
294
+ * @return array|false
295
+ */
296
+ public function getExpirationOptions()
297
+ {
298
+ if (empty($this->expirationOptions)) {
299
+ // Option _expiration-date-options is deprecated when using block editor.
300
+ $this->expirationOptions = $this->getMeta('_expiration-date-options', true);
301
+ }
302
+
303
+ return $this->expirationOptions;
304
+ }
305
+
306
+ /**
307
+ * @param bool $force
308
+ * @return bool
309
+ * @throws \PublishPressFuture\Framework\WordPress\Exceptions\NonexistentPostException
310
+ */
311
+ public function expire($force = false)
312
+ {
313
+ $postId = $this->getPostId();
314
+
315
+ if (! $this->isExpirationEnabled() && ! $force) {
316
+ $this->debug->log($postId . ' -> Post expiration is not activated for the post');
317
+
318
+ return false;
319
+ }
320
+
321
+ if (! $this->isExpirationEnabled() && $force) {
322
+ $this->debug->log(
323
+ $postId . ' -> Post expiration is not activated for the post, but $force = true'
324
+ );
325
+ }
326
+
327
+ /*
328
+ * Remove KSES - wp_cron runs as an unauthenticated user, which will by default trigger kses filtering,
329
+ * even if the post was published by a admin user. It is fairly safe here to remove the filter call since
330
+ * we are only changing the post status/meta information and not touching the content.
331
+ */
332
+ $this->hooks->ksesRemoveFilters();
333
+
334
+ $expirationAction = $this->getExpirationAction();
335
+
336
+ if (! $expirationAction) {
337
+ $this->debug->log(
338
+ $postId . ' -> Post expiration cancelled, action is not found'
339
+ );
340
+
341
+ return false;
342
+ }
343
+
344
+ $result = $expirationAction->execute();
345
+
346
+ if (! is_bool($result)) {
347
+ $this->debug->log($postId . ' -> ACTION ' . $expirationAction . ' returned a non boolean value');
348
+
349
+ return false;
350
+ }
351
+
352
+ if (! $result) {
353
+ $this->debug->log(
354
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
355
+ $postId . ' -> FAILED ' . print_r($this->getExpirationDataAsArray(), true)
356
+ );
357
+
358
+ return false;
359
+ }
360
+
361
+ $this->debug->log(
362
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
363
+ $postId . ' -> PROCESSED ' . print_r($this->getExpirationDataAsArray(), true)
364
+ );
365
+
366
+ $expirationPostLogData = $expirationAction->getExpirationLog();
367
+ $expirationPostLogData['expiration_type'] = $this->getExpirationType();
368
+ $expirationPostLogData['scheduled_for'] = $this->getExpirationDate();
369
+ $expirationPostLogData['executed_on'] = date('Y-m-d H:i:s');
370
+ $expirationPostLogData['email_enabled'] = $this->expirationEmailIsEnabled();
371
+
372
+ if ($expirationPostLogData['email_enabled']) {
373
+ $expirationPostLogData['email_sent'] = $this->sendEmail($expirationAction);
374
+ }
375
+
376
+ $this->addMeta('expiration_log', wp_json_encode($expirationPostLogData));
377
+
378
+ do_action(HooksAbstract::ACTION_UNSCHEDULE_POST_EXPIRATION, $postId);
379
+
380
+ return true;
381
+ }
382
+
383
+ private function expirationEmailIsEnabled()
384
+ {
385
+ return (bool)$this->options->getOption('expirationdateEmailNotification', POSTEXPIRATOR_EMAILNOTIFICATION);
386
+ }
387
+
388
+ /**
389
+ * @throws \PublishPressFuture\Framework\WordPress\Exceptions\NonexistentPostException
390
+ */
391
+ private function getExpirationActionClassName()
392
+ {
393
+ return $this->expirationActionMapper->map($this->getExpirationType());
394
+ }
395
+
396
+ /**
397
+ * @throws \PublishPressFuture\Framework\WordPress\Exceptions\NonexistentPostException
398
+ */
399
+ private function getExpirationAction()
400
+ {
401
+ if (empty($this->expirationActionInstance)) {
402
+ $actionClassName = $this->getExpirationActionClassName();
403
+
404
+ $factory = $this->expirationActionFactory;
405
+
406
+ $this->expirationActionInstance = $factory($actionClassName, $this);
407
+ }
408
+
409
+
410
+ return $this->expirationActionInstance;
411
+ }
412
+
413
+
414
+ /**
415
+ * @param ExpirationActionInterface $expirationAction
416
+ * @return bool
417
+ */
418
+ private function sendEmail($expirationAction)
419
+ {
420
+ $actionNotificationText = $expirationAction->getNotificationText();
421
+
422
+ $emailBody = sprintf(
423
+ __(
424
+ '%1$s (%2$s) has expired at %3$s. %4$s',
425
+ 'post-expirator'
426
+ ),
427
+ '##POSTTITLE##',
428
+ '##POSTLINK##',
429
+ '##EXPIRATIONDATE##',
430
+ $actionNotificationText
431
+ );
432
+
433
+ if (empty($emailBody)) {
434
+ $this->debug->log($this->getPostId() . ' -> Tried to send email, but notification text is empty');
435
+
436
+ return false;
437
+ }
438
+
439
+ $emailSubject = sprintf(
440
+ __('Post Expiration Complete "%s"', 'post-expirator'),
441
+ $this->getTitle()
442
+ );
443
+
444
+ $dateTimeFormat = $this->options->getOption('date_format') . ' ' . $this->options->getOption('time_format');
445
+
446
+ $emailBody = str_replace('##POSTTITLE##', $this->getTitle(), $emailBody);
447
+ $emailBody = str_replace('##POSTLINK##', $this->getPermalink(), $emailBody);
448
+ $emailBody = str_replace(
449
+ '##EXPIRATIONDATE##',
450
+ get_date_from_gmt(
451
+ gmdate('Y-m-d H:i:s', $this->getExpirationDate()),
452
+ $dateTimeFormat
453
+ ),
454
+ $emailBody
455
+ );
456
+
457
+ $emailAddresses = array();
458
+
459
+ if ($this->settings->getSendEmailNotificationToAdmins()) {
460
+ $blogAdmins = $this->users->getUsers('role=Administrator');
461
+
462
+ foreach ($blogAdmins as $user) {
463
+ $emailAddresses[] = $user->user_email;
464
+ }
465
+ }
466
+
467
+ // Get Global Notification Emails
468
+ $emailsList = $this->settings->getEmailNotificationAddressesList();
469
+
470
+ $emailAddresses = array_merge(
471
+ $emailsList,
472
+ $emailAddresses
473
+ );
474
+
475
+ // Get Post Type Notification Emails
476
+ $defaults = $this->settings->getPostTypeDefaults($this->getPostType());
477
+
478
+ if (! empty($defaults['emailnotification'])) {
479
+ $values = explode(',', $defaults['emailnotification']);
480
+
481
+ foreach ($values as $value) {
482
+ $emailAddresses[] = filter_var(trim($value), FILTER_SANITIZE_EMAIL);
483
+ }
484
+ }
485
+
486
+ $emailAddresses = array_unique($emailAddresses);
487
+ $emailSent = false;
488
+
489
+ if (! empty($emailAddresses)) {
490
+ $this->debug->log($this->getPostId() . ' -> SENDING EMAIL TO (' . implode(', ', $emailAddresses) . ')');
491
+
492
+ // Send each email.
493
+ foreach ($emailAddresses as $email) {
494
+ $emailSent = $this->email->send(
495
+ $email,
496
+ sprintf(__('[%1$s] %2$s'), $this->options->getOption('blogname'), $emailSubject),
497
+ $emailBody
498
+ );
499
+
500
+ $this->debug->log(
501
+ sprintf(
502
+ '%d -> %s (%s)',
503
+ $this->getPostId(),
504
+ $emailSent ? 'EXPIRATION EMAIL SENT' : 'EXPIRATION EMAIL FAILED',
505
+ $email
506
+ )
507
+ );
508
+ }
509
+ }
510
+
511
+ return $emailSent;
512
+ }
513
+ }
src/Modules/Expirator/Module.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Expirator;
7
+
8
+
9
+ use PublishPressFuture\Framework\InitializableInterface;
10
+ use PublishPressFuture\Framework\ModuleInterface;
11
+ use PublishPressFuture\Framework\WordPress\Facade\CronFacade;
12
+ use PublishPressFuture\Framework\WordPress\Facade\HooksFacade;
13
+ use PublishPressFuture\Framework\WordPress\Facade\SiteFacade;
14
+ use PublishPressFuture\Modules\Expirator\Controllers\BulkEditController;
15
+ use PublishPressFuture\Modules\Expirator\Controllers\ExpirationController;
16
+ use PublishPressFuture\Modules\Expirator\Interfaces\SchedulerInterface;
17
+ use PublishPressFuture\Framework\WordPress\Facade\SanitizationFacade;
18
+
19
+ class Module implements ModuleInterface
20
+ {
21
+ /**
22
+ * @var HooksFacade;
23
+ */
24
+ private $hooks;
25
+
26
+ /**
27
+ * @var SiteFacade
28
+ */
29
+ private $site;
30
+
31
+ /**
32
+ * @var CronFacade
33
+ */
34
+ private $cron;
35
+
36
+ /**
37
+ * @var InitializableInterface[]
38
+ */
39
+ private $controllers = [];
40
+
41
+ /**
42
+ * @var SchedulerInterface
43
+ */
44
+ private $scheduler;
45
+
46
+ /**
47
+ * @var callable
48
+ */
49
+ private $expirablePostModelFactory;
50
+
51
+ /**
52
+ * @var SanitizationFacade
53
+ */
54
+ private $sanitization;
55
+
56
+ /**
57
+ * @var callable
58
+ */
59
+ private $currentUserModelFactory;
60
+
61
+ /**
62
+ * @var \PublishPressFuture\Framework\WordPress\Facade\RequestFacade
63
+ */
64
+ private $request;
65
+
66
+ public function __construct($hooks, $site, $cron, $scheduler, $expirablePostModelFactory, $sanitization, $currentUserModelFactory, $request)
67
+ {
68
+ $this->hooks = $hooks;
69
+ $this->site = $site;
70
+ $this->cron = $cron;
71
+ $this->scheduler = $scheduler;
72
+ $this->expirablePostModelFactory = $expirablePostModelFactory;
73
+ $this->sanitization = $sanitization;
74
+ $this->currentUserModelFactory = $currentUserModelFactory;
75
+ $this->request = $request;
76
+
77
+ $this->controllers['expiration'] = $this->factoryExpirationController();
78
+ $this->controllers['bulk_edit'] = $this->factoryBulkEditController();
79
+ }
80
+
81
+ /**
82
+ * @inheritDoc
83
+ */
84
+ public function initialize()
85
+ {
86
+ foreach ($this->controllers as $controller) {
87
+ $controller->initialize();
88
+ }
89
+ }
90
+
91
+ private function factoryExpirationController()
92
+ {
93
+ return new ExpirationController(
94
+ $this->hooks,
95
+ $this->site,
96
+ $this->cron,
97
+ $this->scheduler,
98
+ $this->expirablePostModelFactory
99
+ );
100
+ }
101
+
102
+ private function factoryBulkEditController()
103
+ {
104
+ return new BulkEditController(
105
+ $this->hooks,
106
+ $this->expirablePostModelFactory,
107
+ $this->sanitization,
108
+ $this->currentUserModelFactory,
109
+ $this->request
110
+ );
111
+ }
112
+ }
src/Modules/InstanceProtection/Module.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\InstanceProtection;
7
+
8
+
9
+ use PublishPressFuture\Core\Paths;
10
+ use PublishPressFuture\Framework\ModuleInterface;
11
+ use PublishPressInstanceProtection\Config;
12
+ use PublishPressInstanceProtection\InstanceChecker;
13
+
14
+ class Module implements ModuleInterface
15
+ {
16
+ public function __construct(Paths $paths, $pluginSlug, $pluginName)
17
+ {
18
+ $includeFile = $paths->getVendorDirPath()
19
+ . '/publishpress/publishpress-instance-protection/include.php';
20
+
21
+ if (is_readable($includeFile)) {
22
+ // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable
23
+ require_once $includeFile;
24
+ }
25
+
26
+ if (! class_exists('PublishPressInstanceProtection\\Config')) {
27
+ return null;
28
+ }
29
+
30
+ $pluginCheckerConfig = new Config();
31
+ $pluginCheckerConfig->pluginSlug = $pluginSlug;
32
+ $pluginCheckerConfig->pluginName = $pluginName;
33
+
34
+ new InstanceChecker($pluginCheckerConfig);
35
+ }
36
+
37
+ /**
38
+ * @inheritDoc
39
+ */
40
+ public function initialize()
41
+ {
42
+ }
43
+ }
src/Modules/Settings/Controllers/Controller.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Settings\Controllers;
7
+
8
+ use PublishPressFuture\Core\HookableInterface;
9
+ use PublishPressFuture\Core\HooksAbstract as CoreAbstractHooks;
10
+ use PublishPressFuture\Framework\InitializableInterface;
11
+ use PublishPressFuture\Modules\Settings\HooksAbstract;
12
+ use PublishPressFuture\Modules\Settings\SettingsFacade;
13
+
14
+ class Controller implements InitializableInterface
15
+ {
16
+ /**
17
+ * @var HookableInterface
18
+ */
19
+ private $hooks;
20
+
21
+ /**
22
+ * @var SettingsFacade
23
+ */
24
+ private $settings;
25
+
26
+ /**
27
+ * @var array $defaultData
28
+ */
29
+ private $defaultData;
30
+
31
+ /**
32
+ * @param HookableInterface $hooks
33
+ * @param SettingsFacade $settings
34
+ */
35
+ public function __construct(HookableInterface $hooks, $settings)
36
+ {
37
+ $this->hooks = $hooks;
38
+ $this->settings = $settings;
39
+ }
40
+
41
+ public function initialize()
42
+ {
43
+ $this->hooks->addAction(
44
+ CoreAbstractHooks::ACTION_ACTIVATE_PLUGIN,
45
+ [$this, 'onActionActivatePlugin']
46
+ );
47
+ $this->hooks->addAction(
48
+ CoreAbstractHooks::ACTION_DEACTIVATE_PLUGIN,
49
+ [$this, 'onActionDeactivatePlugin']
50
+ );
51
+ $this->hooks->addFilter(
52
+ HooksAbstract::FILTER_DEBUG_ENABLED,
53
+ [$this, 'onFilterDebugEnabled']
54
+ );
55
+ }
56
+
57
+ public function onActionActivatePlugin()
58
+ {
59
+ $this->settings->setDefaultSettings();
60
+ }
61
+
62
+ public function onActionDeactivatePlugin()
63
+ {
64
+ if ($this->settings->getSettingPreserveData()) {
65
+ return;
66
+ }
67
+
68
+ $this->hooks->doAction(HooksAbstract::ACTION_DELETE_ALL_SETTINGS);
69
+
70
+ $this->settings->deleteAllSettings();
71
+ }
72
+
73
+ public function onFilterDebugEnabled($enabled = false)
74
+ {
75
+ return $this->settings->getDebugIsEnabled($enabled);
76
+ }
77
+ }
src/Modules/Settings/HooksAbstract.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Settings;
7
+
8
+ abstract class HooksAbstract
9
+ {
10
+ const ACTION_DELETE_ALL_SETTINGS = 'publishpressfuture_delete_settings';
11
+ const FILTER_DEBUG_ENABLED = 'publishpressfuture_debug_enabled';
12
+ }
src/Modules/Settings/Module.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Settings;
7
+
8
+
9
+ use PublishPressFuture\Core\HookableInterface;
10
+ use PublishPressFuture\Framework\ModuleInterface;
11
+ use PublishPressFuture\Modules\Settings\Controllers\Controller;
12
+
13
+ class Module implements ModuleInterface
14
+ {
15
+ /**
16
+ * @var Controller
17
+ */
18
+ private $controller;
19
+
20
+ /**
21
+ * @var HookableInterface
22
+ */
23
+ private $hooks;
24
+
25
+ /**
26
+ * @var SettingsFacade
27
+ */
28
+ private $settings;
29
+
30
+ /**
31
+ * @param HookableInterface $hooks
32
+ * @param SettingsFacade $settings
33
+ */
34
+ public function __construct(HookableInterface $hooks, $settings)
35
+ {
36
+ $this->hooks = $hooks;
37
+ $this->settings = $settings;
38
+
39
+ $this->controller = $this->getController();
40
+ }
41
+
42
+ /**
43
+ * @inheritDoc
44
+ */
45
+ public function initialize()
46
+ {
47
+ $this->controller->initialize();
48
+ }
49
+
50
+ private function getController()
51
+ {
52
+ return new Controller(
53
+ $this->hooks,
54
+ $this->settings
55
+ );
56
+ }
57
+ }
src/Modules/Settings/SettingsFacade.php ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\Settings;
7
+
8
+ use PublishPressFuture\Core\DI\ServicesAbstract as Services;
9
+ use PublishPressFuture\Core\HookableInterface;
10
+ use PublishPressFuture\Framework\WordPress\Facade\OptionsFacade;
11
+
12
+ class SettingsFacade
13
+ {
14
+ /**
15
+ * @var HookableInterface
16
+ */
17
+ private $hooks;
18
+
19
+ /**
20
+ * @var OptionsFacade
21
+ */
22
+ private $options;
23
+
24
+ /**
25
+ * @var array $defaultData
26
+ */
27
+ private $defaultData;
28
+
29
+ /**
30
+ * @var array
31
+ */
32
+ private $cache = [];
33
+
34
+ const DEFAULT_CUSTOM_DATE = '+1 week';
35
+
36
+ /**
37
+ * @param HookableInterface $hooks
38
+ * @param OptionsFacade $options
39
+ * @param array $defaultData
40
+ */
41
+ public function __construct(HookableInterface $hooks, $options, $defaultData)
42
+ {
43
+ $this->hooks = $hooks;
44
+ $this->options = $options;
45
+ $this->defaultData = $defaultData;
46
+ }
47
+
48
+ public function deleteAllSettings()
49
+ {
50
+ $allOptions = [
51
+ 'expirationdateExpiredPostStatus',
52
+ 'expirationdateExpiredPageStatus',
53
+ 'expirationdateDefaultDateFormat',
54
+ 'expirationdateDefaultTimeFormat',
55
+ 'expirationdateDisplayFooter',
56
+ 'expirationdateFooterContents',
57
+ 'expirationdateFooterStyle',
58
+ 'expirationdateCategory',
59
+ 'expirationdateCategoryDefaults',
60
+ 'expirationdateDebug',
61
+ 'postexpiratorVersion',
62
+ 'expirationdateCronSchedule',
63
+ 'expirationdateDefaultDate',
64
+ 'expirationdateDefaultDateCustom',
65
+ 'expirationdateAutoEnabled',
66
+ 'expirationdateDefaultsPost',
67
+ 'expirationdateDefaultsPage',
68
+ 'expirationdateGutenbergSupport',
69
+ 'expirationdatePreserveData',
70
+ 'expirationdateEmailNotificationAdmins',
71
+ 'expirationdateEmailNotificationList',
72
+ ];
73
+
74
+ // TODO: Remove the custom post type default settings like expirationdateDefaults<post_type>, etc.
75
+
76
+ foreach ($allOptions as $optionName) {
77
+ $this->options->deleteOption($optionName);
78
+ }
79
+ }
80
+
81
+ public function setDefaultSettings()
82
+ {
83
+ $defaultValues = [
84
+ 'expirationdateDefaultDateFormat' => $this->defaultData[Services::DEFAULT_DATE_FORMAT],
85
+ 'expirationdateDefaultTimeFormat' => $this->defaultData[Services::DEFAULT_TIME_FORMAT],
86
+ 'expirationdateFooterContents' => $this->defaultData[Services::DEFAULT_FOOTER_CONTENT],
87
+ 'expirationdateFooterStyle' => $this->defaultData[Services::DEFAULT_FOOTER_STYLE],
88
+ 'expirationdateDisplayFooter' => $this->defaultData[Services::DEFAULT_FOOTER_DISPLAY],
89
+ 'expirationdateDebug' => $this->defaultData[Services::DEFAULT_DEBUG],
90
+ 'expirationdateDefaultDate' => $this->defaultData[Services::DEFAULT_EXPIRATION_DATE],
91
+ 'expirationdateGutenbergSupport' => 1,
92
+ ];
93
+
94
+ foreach ($defaultValues as $optionName => $defaultValue) {
95
+ if ($this->options->getOption($optionName) === false) {
96
+ $this->options->updateOption($optionName, $defaultValue);
97
+ }
98
+ }
99
+ }
100
+
101
+ /**
102
+ * @param bool $default
103
+ *
104
+ * @return bool
105
+ */
106
+ public function getSettingPreserveData($default = true)
107
+ {
108
+ return (bool)$this->options->getOption('expirationdatePreserveData', $default);
109
+ }
110
+
111
+ /**
112
+ * @param bool $default
113
+ * @return bool
114
+ */
115
+ public function getDebugIsEnabled($default = false)
116
+ {
117
+ if (! isset($this->cache['debugIsEnabled'])) {
118
+ $this->cache['debugIsEnabled'] = (bool)$this->options->getOption('expirationdateDebug', $default);
119
+ }
120
+
121
+ return (bool) $this->cache['debugIsEnabled'];
122
+ }
123
+
124
+ public function getSendEmailNotificationToAdmins()
125
+ {
126
+ return (bool)$this->options->getOption(
127
+ 'expirationdateEmailNotificationAdmins',
128
+ POSTEXPIRATOR_EMAILNOTIFICATIONADMINS
129
+ );
130
+ }
131
+
132
+ public function getEmailNotificationAddressesList()
133
+ {
134
+ $emailsList = $this->options->getOption(
135
+ 'expirationdateEmailNotificationList',
136
+ ''
137
+ );
138
+
139
+ $emailsList = explode(',', $emailsList);
140
+
141
+ foreach ($emailsList as &$emailAddress) {
142
+ $emailAddress = filter_var(trim($emailAddress), FILTER_SANITIZE_EMAIL);
143
+ }
144
+
145
+ return (array)$emailsList;
146
+ }
147
+
148
+ public function getPostTypeDefaults($postType)
149
+ {
150
+ $defaults = [
151
+ 'expireType' => null,
152
+ 'autoEnable' => null,
153
+ 'taxonomy' => null,
154
+ 'activeMetaBox' => null,
155
+ 'emailnotification' => null,
156
+ 'default-expire-type' => null,
157
+ 'default-custom-date' => null,
158
+ ];
159
+
160
+ $defaults = array_merge(
161
+ $defaults,
162
+ (array)$this->options->getOption('expirationdateDefaults' . ucfirst($postType))
163
+ );
164
+
165
+ if ($defaults['default-expire-type'] === 'null' || empty($defaults['default-expire-type'])) {
166
+ $defaults['default-expire-type'] = 'inherit';
167
+ }
168
+
169
+ return $defaults;
170
+ }
171
+
172
+ /**
173
+ * @return mixed
174
+ */
175
+ public function getDefaultDate()
176
+ {
177
+ $defaultDateOption = $this->options->getOption(
178
+ 'expirationdateDefaultDate',
179
+ $this->defaultData[Services::DEFAULT_EXPIRATION_DATE]
180
+ );
181
+
182
+ if ('null' === $defaultDateOption || empty($defaultDateOption)) {
183
+ $defaultDateOption = 'custom';
184
+ }
185
+
186
+ return $defaultDateOption;
187
+ }
188
+
189
+ /**
190
+ * @return mixed
191
+ */
192
+ public function getDefaultDateCustom()
193
+ {
194
+ $defaultDateOption = $this->options->getOption('expirationdateDefaultDateCustom');
195
+
196
+ if (empty($defaultDateOption)) {
197
+ $defaultDateOption = self::DEFAULT_CUSTOM_DATE;
198
+ }
199
+
200
+ return $defaultDateOption;
201
+ }
202
+ }
src/Modules/WooCommerce/Module.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2022. PublishPress, All rights reserved.
4
+ */
5
+
6
+ namespace PublishPressFuture\Modules\WooCommerce;
7
+
8
+
9
+ use PublishPressFuture\Framework\ModuleInterface;
10
+
11
+ class Module implements ModuleInterface
12
+ {
13
+ /**
14
+ * @var string
15
+ */
16
+ private $baseUrl;
17
+
18
+ /**
19
+ * @var string
20
+ */
21
+ private $pluginVersion;
22
+
23
+
24
+ public function __construct($baseUrl, $pluginVersion)
25
+ {
26
+ $this->baseUrl = $baseUrl;
27
+ $this->pluginVersion = $pluginVersion;
28
+ }
29
+
30
+ /**
31
+ * @inheritDoc
32
+ */
33
+ public function initialize()
34
+ {
35
+ add_action('admin_enqueue_scripts', [$this, 'enqueueStyle']);
36
+ }
37
+
38
+ public function enqueueStyle()
39
+ {
40
+ $currentScreen = get_current_screen();
41
+
42
+ if (! is_admin()) {
43
+ return;
44
+ }
45
+
46
+ if ($currentScreen->base !== 'edit') {
47
+ return;
48
+ }
49
+
50
+ if ($currentScreen->post_type !== 'product') {
51
+ return;
52
+ }
53
+
54
+ wp_enqueue_style(
55
+ 'publishpress-future-woocommerce',
56
+ $this->baseUrl . '/assets/css/woocommerce.css',
57
+ array(),
58
+ $this->pluginVersion,
59
+ false
60
+ );
61
+ }
62
+ }
vendor/autoload.php CHANGED
@@ -9,4 +9,4 @@ if (PHP_VERSION_ID < 50600) {
9
 
10
  require_once __DIR__ . '/composer/autoload_real.php';
11
 
12
- return ComposerAutoloaderInita29fda89681b0e16b29b1d03f8491329::getLoader();
9
 
10
  require_once __DIR__ . '/composer/autoload_real.php';
11
 
12
+ return ComposerAutoloaderInit008d5fbba23d4487431bb48cd9baaa3e::getLoader();
vendor/composer/autoload_files.php CHANGED
@@ -7,5 +7,4 @@ $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
  '41c664bd04a95c2d6a2f2a3e00f06593' => $vendorDir . '/publishpress/wordpress-reviews/ReviewsController.php',
10
- '44b552ca20ee394f431a64ca58af7ab1' => $baseDir . '/classes/DummyForAutoloadDetection.php',
11
  );
7
 
8
  return array(
9
  '41c664bd04a95c2d6a2f2a3e00f06593' => $vendorDir . '/publishpress/wordpress-reviews/ReviewsController.php',
 
10
  );
vendor/composer/autoload_psr4.php CHANGED
@@ -6,4 +6,6 @@ $vendorDir = dirname(__DIR__);
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
 
9
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'PublishPressFuture\\' => array($baseDir . '/src'),
10
+ 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
11
  );
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInita29fda89681b0e16b29b1d03f8491329
6
  {
7
  private static $loader;
8
 
@@ -24,18 +24,18 @@ class ComposerAutoloaderInita29fda89681b0e16b29b1d03f8491329
24
 
25
  require __DIR__ . '/platform_check.php';
26
 
27
- spl_autoload_register(array('ComposerAutoloaderInita29fda89681b0e16b29b1d03f8491329', 'loadClassLoader'), true, true);
28
  self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
29
- spl_autoload_unregister(array('ComposerAutoloaderInita29fda89681b0e16b29b1d03f8491329', 'loadClassLoader'));
30
 
31
  require __DIR__ . '/autoload_static.php';
32
- call_user_func(\Composer\Autoload\ComposerStaticInita29fda89681b0e16b29b1d03f8491329::getInitializer($loader));
33
 
34
  $loader->register(true);
35
 
36
- $includeFiles = \Composer\Autoload\ComposerStaticInita29fda89681b0e16b29b1d03f8491329::$files;
37
  foreach ($includeFiles as $fileIdentifier => $file) {
38
- composerRequirea29fda89681b0e16b29b1d03f8491329($fileIdentifier, $file);
39
  }
40
 
41
  return $loader;
@@ -47,7 +47,7 @@ class ComposerAutoloaderInita29fda89681b0e16b29b1d03f8491329
47
  * @param string $file
48
  * @return void
49
  */
50
- function composerRequirea29fda89681b0e16b29b1d03f8491329($fileIdentifier, $file)
51
  {
52
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
53
  $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit008d5fbba23d4487431bb48cd9baaa3e
6
  {
7
  private static $loader;
8
 
24
 
25
  require __DIR__ . '/platform_check.php';
26
 
27
+ spl_autoload_register(array('ComposerAutoloaderInit008d5fbba23d4487431bb48cd9baaa3e', 'loadClassLoader'), true, true);
28
  self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
29
+ spl_autoload_unregister(array('ComposerAutoloaderInit008d5fbba23d4487431bb48cd9baaa3e', 'loadClassLoader'));
30
 
31
  require __DIR__ . '/autoload_static.php';
32
+ call_user_func(\Composer\Autoload\ComposerStaticInit008d5fbba23d4487431bb48cd9baaa3e::getInitializer($loader));
33
 
34
  $loader->register(true);
35
 
36
+ $includeFiles = \Composer\Autoload\ComposerStaticInit008d5fbba23d4487431bb48cd9baaa3e::$files;
37
  foreach ($includeFiles as $fileIdentifier => $file) {
38
+ composerRequire008d5fbba23d4487431bb48cd9baaa3e($fileIdentifier, $file);
39
  }
40
 
41
  return $loader;
47
  * @param string $file
48
  * @return void
49
  */
50
+ function composerRequire008d5fbba23d4487431bb48cd9baaa3e($fileIdentifier, $file)
51
  {
52
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
53
  $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
vendor/composer/autoload_static.php CHANGED
@@ -4,11 +4,29 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInita29fda89681b0e16b29b1d03f8491329
8
  {
9
  public static $files = array (
10
  '41c664bd04a95c2d6a2f2a3e00f06593' => __DIR__ . '/..' . '/publishpress/wordpress-reviews/ReviewsController.php',
11
- '44b552ca20ee394f431a64ca58af7ab1' => __DIR__ . '/../..' . '/classes/DummyForAutoloadDetection.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  );
13
 
14
  public static $classMap = array (
@@ -18,7 +36,9 @@ class ComposerStaticInita29fda89681b0e16b29b1d03f8491329
18
  public static function getInitializer(ClassLoader $loader)
19
  {
20
  return \Closure::bind(function () use ($loader) {
21
- $loader->classMap = ComposerStaticInita29fda89681b0e16b29b1d03f8491329::$classMap;
 
 
22
 
23
  }, null, ClassLoader::class);
24
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit008d5fbba23d4487431bb48cd9baaa3e
8
  {
9
  public static $files = array (
10
  '41c664bd04a95c2d6a2f2a3e00f06593' => __DIR__ . '/..' . '/publishpress/wordpress-reviews/ReviewsController.php',
11
+ );
12
+
13
+ public static $prefixLengthsPsr4 = array (
14
+ 'P' =>
15
+ array (
16
+ 'PublishPressFuture\\' => 19,
17
+ 'Psr\\Container\\' => 14,
18
+ ),
19
+ );
20
+
21
+ public static $prefixDirsPsr4 = array (
22
+ 'PublishPressFuture\\' =>
23
+ array (
24
+ 0 => __DIR__ . '/../..' . '/src',
25
+ ),
26
+ 'Psr\\Container\\' =>
27
+ array (
28
+ 0 => __DIR__ . '/..' . '/psr/container/src',
29
+ ),
30
  );
31
 
32
  public static $classMap = array (
36
  public static function getInitializer(ClassLoader $loader)
37
  {
38
  return \Closure::bind(function () use ($loader) {
39
+ $loader->prefixLengthsPsr4 = ComposerStaticInit008d5fbba23d4487431bb48cd9baaa3e::$prefixLengthsPsr4;
40
+ $loader->prefixDirsPsr4 = ComposerStaticInit008d5fbba23d4487431bb48cd9baaa3e::$prefixDirsPsr4;
41
+ $loader->classMap = ComposerStaticInit008d5fbba23d4487431bb48cd9baaa3e::$classMap;
42
 
43
  }, null, ClassLoader::class);
44
  }
vendor/composer/installed.json CHANGED
@@ -1,24 +1,80 @@
1
  {
2
  "packages": [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  {
4
  "name": "publishpress/publishpress-instance-protection",
5
- "version": "v1.0.2",
6
- "version_normalized": "1.0.2.0",
7
  "source": {
8
  "type": "git",
9
  "url": "https://github.com/publishpress/publishpress-instance-protection.git",
10
- "reference": "ef1a631a41b723ce2e856f534ff4befbe914e964"
11
  },
12
  "dist": {
13
  "type": "zip",
14
- "url": "https://api.github.com/repos/publishpress/publishpress-instance-protection/zipball/ef1a631a41b723ce2e856f534ff4befbe914e964",
15
- "reference": "ef1a631a41b723ce2e856f534ff4befbe914e964",
16
  "shasum": ""
17
  },
18
  "require": {
19
  "php": ">=5.6.20"
20
  },
21
- "time": "2022-06-03T17:41:36+00:00",
22
  "type": "library",
23
  "installation-source": "dist",
24
  "notification-url": "https://packagist.org/downloads/",
@@ -38,7 +94,7 @@
38
  ],
39
  "support": {
40
  "issues": "https://github.com/publishpress/publishpress-instance-protection/issues",
41
- "source": "https://github.com/publishpress/publishpress-instance-protection/tree/v1.0.2"
42
  },
43
  "install-path": "../publishpress/publishpress-instance-protection"
44
  },
1
  {
2
  "packages": [
3
+ {
4
+ "name": "psr/container",
5
+ "version": "1.0.0",
6
+ "version_normalized": "1.0.0.0",
7
+ "source": {
8
+ "type": "git",
9
+ "url": "https://github.com/php-fig/container.git",
10
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
11
+ },
12
+ "dist": {
13
+ "type": "zip",
14
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
15
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
16
+ "shasum": ""
17
+ },
18
+ "require": {
19
+ "php": ">=5.3.0"
20
+ },
21
+ "time": "2017-02-14T16:28:37+00:00",
22
+ "type": "library",
23
+ "extra": {
24
+ "branch-alias": {
25
+ "dev-master": "1.0.x-dev"
26
+ }
27
+ },
28
+ "installation-source": "dist",
29
+ "autoload": {
30
+ "psr-4": {
31
+ "Psr\\Container\\": "src/"
32
+ }
33
+ },
34
+ "notification-url": "https://packagist.org/downloads/",
35
+ "license": [
36
+ "MIT"
37
+ ],
38
+ "authors": [
39
+ {
40
+ "name": "PHP-FIG",
41
+ "homepage": "http://www.php-fig.org/"
42
+ }
43
+ ],
44
+ "description": "Common Container Interface (PHP FIG PSR-11)",
45
+ "homepage": "https://github.com/php-fig/container",
46
+ "keywords": [
47
+ "PSR-11",
48
+ "container",
49
+ "container-interface",
50
+ "container-interop",
51
+ "psr"
52
+ ],
53
+ "support": {
54
+ "issues": "https://github.com/php-fig/container/issues",
55
+ "source": "https://github.com/php-fig/container/tree/master"
56
+ },
57
+ "install-path": "../psr/container"
58
+ },
59
  {
60
  "name": "publishpress/publishpress-instance-protection",
61
+ "version": "v1.0.3",
62
+ "version_normalized": "1.0.3.0",
63
  "source": {
64
  "type": "git",
65
  "url": "https://github.com/publishpress/publishpress-instance-protection.git",
66
+ "reference": "6a4e7038c95fac43264b1d61a5cdae2b1e3cc4ee"
67
  },
68
  "dist": {
69
  "type": "zip",
70
+ "url": "https://api.github.com/repos/publishpress/publishpress-instance-protection/zipball/6a4e7038c95fac43264b1d61a5cdae2b1e3cc4ee",
71
+ "reference": "6a4e7038c95fac43264b1d61a5cdae2b1e3cc4ee",
72
  "shasum": ""
73
  },
74
  "require": {
75
  "php": ">=5.6.20"
76
  },
77
+ "time": "2022-10-28T16:14:03+00:00",
78
  "type": "library",
79
  "installation-source": "dist",
80
  "notification-url": "https://packagist.org/downloads/",
94
  ],
95
  "support": {
96
  "issues": "https://github.com/publishpress/publishpress-instance-protection/issues",
97
+ "source": "https://github.com/publishpress/publishpress-instance-protection/tree/v1.0.3"
98
  },
99
  "install-path": "../publishpress/publishpress-instance-protection"
100
  },
vendor/composer/installed.php CHANGED
@@ -1,28 +1,37 @@
1
  <?php return array(
2
  'root' => array(
3
  'name' => 'publishpress/publishpress-future',
4
- 'pretty_version' => 'dev-main',
5
- 'version' => 'dev-main',
6
- 'reference' => '8a3604c2db38d2a1b8fc2db78910aaa93fbc3172',
7
  'type' => 'wordpress-plugin',
8
  'install_path' => __DIR__ . '/../../',
9
  'aliases' => array(),
10
  'dev' => false,
11
  ),
12
  'versions' => array(
 
 
 
 
 
 
 
 
 
13
  'publishpress/publishpress-future' => array(
14
- 'pretty_version' => 'dev-main',
15
- 'version' => 'dev-main',
16
- 'reference' => '8a3604c2db38d2a1b8fc2db78910aaa93fbc3172',
17
  'type' => 'wordpress-plugin',
18
  'install_path' => __DIR__ . '/../../',
19
  'aliases' => array(),
20
  'dev_requirement' => false,
21
  ),
22
  'publishpress/publishpress-instance-protection' => array(
23
- 'pretty_version' => 'v1.0.2',
24
- 'version' => '1.0.2.0',
25
- 'reference' => 'ef1a631a41b723ce2e856f534ff4befbe914e964',
26
  'type' => 'library',
27
  'install_path' => __DIR__ . '/../publishpress/publishpress-instance-protection',
28
  'aliases' => array(),
1
  <?php return array(
2
  'root' => array(
3
  'name' => 'publishpress/publishpress-future',
4
+ 'pretty_version' => 'dev-develop',
5
+ 'version' => 'dev-develop',
6
+ 'reference' => '037fdeee62c973b80c1adec3681bf5db266cbb96',
7
  'type' => 'wordpress-plugin',
8
  'install_path' => __DIR__ . '/../../',
9
  'aliases' => array(),
10
  'dev' => false,
11
  ),
12
  'versions' => array(
13
+ 'psr/container' => array(
14
+ 'pretty_version' => '1.0.0',
15
+ 'version' => '1.0.0.0',
16
+ 'reference' => 'b7ce3b176482dbbc1245ebf52b181af44c2cf55f',
17
+ 'type' => 'library',
18
+ 'install_path' => __DIR__ . '/../psr/container',
19
+ 'aliases' => array(),
20
+ 'dev_requirement' => false,
21
+ ),
22
  'publishpress/publishpress-future' => array(
23
+ 'pretty_version' => 'dev-develop',
24
+ 'version' => 'dev-develop',
25
+ 'reference' => '037fdeee62c973b80c1adec3681bf5db266cbb96',
26
  'type' => 'wordpress-plugin',
27
  'install_path' => __DIR__ . '/../../',
28
  'aliases' => array(),
29
  'dev_requirement' => false,
30
  ),
31
  'publishpress/publishpress-instance-protection' => array(
32
+ 'pretty_version' => 'v1.0.3',
33
+ 'version' => '1.0.3.0',
34
+ 'reference' => '6a4e7038c95fac43264b1d61a5cdae2b1e3cc4ee',
35
  'type' => 'library',
36
  'install_path' => __DIR__ . '/../publishpress/publishpress-instance-protection',
37
  'aliases' => array(),
vendor/psr/container/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013-2016 container-interop
4
+ Copyright (c) 2016 PHP Framework Interoperability Group
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
7
+ this software and associated documentation files (the "Software"), to deal in
8
+ the Software without restriction, including without limitation the rights to
9
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10
+ the Software, and to permit persons to whom the Software is furnished to do so,
11
+ subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
vendor/psr/container/composer.json ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "psr/container",
3
+ "type": "library",
4
+ "description": "Common Container Interface (PHP FIG PSR-11)",
5
+ "keywords": ["psr", "psr-11", "container", "container-interop", "container-interface"],
6
+ "homepage": "https://github.com/php-fig/container",
7
+ "license": "MIT",
8
+ "authors": [
9
+ {
10
+ "name": "PHP-FIG",
11
+ "homepage": "http://www.php-fig.org/"
12
+ }
13
+ ],
14
+ "require": {
15
+ "php": ">=5.3.0"
16
+ },
17
+ "autoload": {
18
+ "psr-4": {
19
+ "Psr\\Container\\": "src/"
20
+ }
21
+ },
22
+ "extra": {
23
+ "branch-alias": {
24
+ "dev-master": "1.0.x-dev"
25
+ }
26
+ }
27
+ }
vendor/psr/container/src/ContainerExceptionInterface.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
4
+ */
5
+
6
+ namespace Psr\Container;
7
+
8
+ /**
9
+ * Base interface representing a generic exception in a container.
10
+ */
11
+ interface ContainerExceptionInterface
12
+ {
13
+ }
vendor/psr/container/src/ContainerInterface.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
4
+ */
5
+
6
+ namespace Psr\Container;
7
+
8
+ /**
9
+ * Describes the interface of a container that exposes methods to read its entries.
10
+ */
11
+ interface ContainerInterface
12
+ {
13
+ /**
14
+ * Finds an entry of the container by its identifier and returns it.
15
+ *
16
+ * @param string $id Identifier of the entry to look for.
17
+ *
18
+ * @throws NotFoundExceptionInterface No entry was found for **this** identifier.
19
+ * @throws ContainerExceptionInterface Error while retrieving the entry.
20
+ *
21
+ * @return mixed Entry.
22
+ */
23
+ public function get($id);
24
+
25
+ /**
26
+ * Returns true if the container can return an entry for the given identifier.
27
+ * Returns false otherwise.
28
+ *
29
+ * `has($id)` returning true does not mean that `get($id)` will not throw an exception.
30
+ * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
31
+ *
32
+ * @param string $id Identifier of the entry to look for.
33
+ *
34
+ * @return bool
35
+ */
36
+ public function has($id);
37
+ }
vendor/psr/container/src/NotFoundExceptionInterface.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
4
+ */
5
+
6
+ namespace Psr\Container;
7
+
8
+ /**
9
+ * No entry was found in the container.
10
+ */
11
+ interface NotFoundExceptionInterface extends ContainerExceptionInterface
12
+ {
13
+ }
vendor/publishpress/publishpress-instance-protection/core/InstanceChecker.php CHANGED
@@ -57,7 +57,7 @@ class InstanceChecker
57
 
58
  public function getVersion()
59
  {
60
- return '1.0.2';
61
  }
62
 
63
  public function init()
@@ -209,7 +209,7 @@ class InstanceChecker
209
  <div class="multiple-instances-warning">
210
  <p>
211
  <span class="dashicons dashicons-warning"></span>
212
- <?php echo esc_html__('This plugin is outdated. You already have a more recent version installed. Please remove this version.', 'publishpress-intance-protection'); ?>
213
  </p>
214
  </div>
215
  </td>
@@ -240,7 +240,7 @@ class InstanceChecker
240
  <p>
241
  <span class="dashicons dashicons-warning"></span>
242
  <?php echo sprintf(
243
- esc_html__('This plugin is not installed in the standard folder. The current path is %s but it is expected to be %s.', 'publishpress-intance-protection'),
244
  '<code>' . esc_html($pluginFile) . '</code>',
245
  '<code>' . esc_html($expectedPath) . '</code>'
246
  );
@@ -266,7 +266,7 @@ class InstanceChecker
266
  add_action('admin_notices', function() use ($pluginName) {
267
  ?>
268
  <div class="notice notice-success is-dismissible">
269
- <p><?php echo sprintf(esc_html__('You have activated multiple instances of %s. Please keep only one activated and remove the others.', 'publishpress-intance-protection'), esc_html($pluginName)); ?></p>
270
  </div>
271
  <?php
272
  });
@@ -286,7 +286,7 @@ class InstanceChecker
286
  add_action('admin_notices', function() use ($pluginName, $freePluginName) {
287
  ?>
288
  <div class="notice notice-success is-dismissible">
289
- <p><?php echo sprintf(esc_html__('Please deactivate %s when %s is activated.', 'publishpress-intance-protection'), esc_html($freePluginName), esc_html($pluginName)); ?></p>
290
  </div>
291
  <?php
292
  });
57
 
58
  public function getVersion()
59
  {
60
+ return '1.0.3';
61
  }
62
 
63
  public function init()
209
  <div class="multiple-instances-warning">
210
  <p>
211
  <span class="dashicons dashicons-warning"></span>
212
+ <?php echo esc_html__('This plugin is outdated. You already have a more recent version installed. Please remove this version.', 'publishpress-instance-protection'); ?>
213
  </p>
214
  </div>
215
  </td>
240
  <p>
241
  <span class="dashicons dashicons-warning"></span>
242
  <?php echo sprintf(
243
+ esc_html__('This plugin is not installed in the standard folder. The current path is %1$s but it is expected to be %2$s.', 'publishpress-instance-protection'),
244
  '<code>' . esc_html($pluginFile) . '</code>',
245
  '<code>' . esc_html($expectedPath) . '</code>'
246
  );
266
  add_action('admin_notices', function() use ($pluginName) {
267
  ?>
268
  <div class="notice notice-success is-dismissible">
269
+ <p><?php echo sprintf(esc_html__('You have activated multiple instances of %s. Please keep only one activated and remove the others.', 'publishpress-instance-protection'), esc_html($pluginName)); ?></p>
270
  </div>
271
  <?php
272
  });
286
  add_action('admin_notices', function() use ($pluginName, $freePluginName) {
287
  ?>
288
  <div class="notice notice-success is-dismissible">
289
+ <p><?php echo sprintf(esc_html__('Please deactivate %1$s when %2$s is activated.', 'publishpress-instance-protection'), esc_html($freePluginName), esc_html($pluginName)); ?></p>
290
  </div>
291
  <?php
292
  });