PluginProbe
PublishPress Statuses – Custom Post Status and Workflow / trunk
PublishPress Statuses – Custom Post Status and Workflow vtrunk
1.3.6 1.3.4 1.3.3 1.3.2 trunk 1.0.4.1 1.0.5 1.0.6 1.0.6.2 1.0.6.3 1.0.6.4 1.0.6.5 1.0.6.6 1.0.6.7 1.0.6.8 1.0.6.9 1.0.7 1.0.8 1.0.9 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.14-rc All 38 releases
publishpress-statuses / publishpress-statuses.php

publishpress-statuses.php in PublishPress Statuses – Custom Post Status and Workflow trunk, at publishpress-statuses.php

413 lines 15.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: PublishPress Statuses Free
4 * Plugin URI: https://publishpress.com/statuses
5 * Description: Manage and create post statuses to customize your editorial workflow
6 * Version: 1.3.6
7 * Author: PublishPress
8 * Author URI: https://publishpress.com/
9 * Text Domain: publishpress-statuses
10 * Domain Path: /languages/
11 * Requires at least: 5.5
12 * Requires PHP: 7.2.5
13 * License: GPLv3
14 *
15 * Copyright (c) 2026 PublishPress
16 *
17 * GNU General Public License, Free Software Foundation <https://www.gnu.org/licenses/gpl-3.0.html>
18 *
19 * This program is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation, either version 3 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 *
32 * @package PublishPress Statuses
33 * @author PublishPress
34 * @copyright Copyright (C) 2026 PublishPress. All rights reserved.
35 * @license GNU General Public License version 3
36 * @link https://publishpress.com/
37 *
38 **/
39
40 if (!defined('ABSPATH')) exit; // Exit if accessed directly
41
42 global $wp_version;
43
44 $min_php_version = '7.2.5';
45 $min_wp_version = '5.5';
46
47 $invalid_php_version = version_compare(phpversion(), $min_php_version, '<');
48 $invalid_wp_version = version_compare($wp_version, $min_wp_version, '<');
49
50 // If the PHP version is not compatible, terminate the plugin execution and show an admin notice.
51 if (is_admin() && $invalid_php_version) {
52 add_action(
53 'admin_notices',
54 function () use ($min_php_version) {
55 if (current_user_can('activate_plugins')) {
56 echo '<div class="notice notice-error"><p>';
57 printf(
58 'PublishPress Statuses requires PHP version %s or higher.',
59 esc_html($min_php_version)
60 );
61 echo '</p></div>';
62 }
63 }
64 );
65 }
66
67 // If the WP version is not compatible, terminate the plugin execution and show an admin notice.
68 if (is_admin() && $invalid_wp_version) {
69 add_action(
70 'admin_notices',
71 function () use ($min_wp_version) {
72 if (current_user_can('activate_plugins')) {
73 echo '<div class="notice notice-error"><p>';
74 printf(
75 'PublishPress Statuses requires WordPress version %s or higher.',
76 esc_html($min_wp_version)
77 );
78 echo '</p></div>';
79 }
80 }
81 );
82 }
83
84 if ($invalid_php_version || $invalid_wp_version) {
85 return;
86 }
87
88 $pro_active = false;
89
90 global $publishpress_statuses_loaded_by_pro;
91
92 $publishpress_statuses_loaded_by_pro = strpos(str_replace('\\', '/', __FILE__), 'vendor/publishpress/');
93
94 // Detect separate Pro plugin activation, but not self-activation (this file loaded in vendor library by Pro)
95 if (false === $publishpress_statuses_loaded_by_pro) {
96 foreach ((array)get_option('active_plugins') as $plugin_file) {
97 if (false !== strpos($plugin_file, 'publishpress-statuses-pro.php')) {
98 $pro_active = true;
99 break;
100 }
101 }
102
103 if (!$pro_active && is_multisite()) {
104 foreach (array_keys((array)get_site_option('active_sitewide_plugins')) as $plugin_file) {
105 if (false !== strpos($plugin_file, 'publishpress-statuses-pro.php')) {
106 $pro_active = true;
107 break;
108 }
109 }
110 }
111
112 if ($pro_active) {
113 add_filter(
114 'plugin_row_meta',
115 function($links, $file)
116 {
117 if ($file == plugin_basename(__FILE__)) {
118 $links[]= __('<strong>This plugin can be deleted.</strong>', 'publishpress-statuses');
119 }
120
121 return $links;
122 },
123 10, 2
124 );
125 return;
126 }
127 }
128
129 if (! defined('PUBLISHPRESS_STATUSES_INTERNAL_VENDORPATH')) {
130 define('PUBLISHPRESS_STATUSES_INTERNAL_VENDORPATH', __DIR__ . '/lib/vendor');
131 }
132
133 if (!defined('PUBLISHPRESS_STATUSES_FILE') && !$publishpress_statuses_loaded_by_pro) {
134 $includeFileRelativePath = '/publishpress/instance-protection/include.php';
135 if (file_exists(PUBLISHPRESS_STATUSES_INTERNAL_VENDORPATH . $includeFileRelativePath)) {
136 require_once PUBLISHPRESS_STATUSES_INTERNAL_VENDORPATH . $includeFileRelativePath;
137 }
138
139 if (class_exists('PublishPressInstanceProtection\\Config')) {
140 $pluginCheckerConfig = new PublishPressInstanceProtection\Config();
141 $pluginCheckerConfig->pluginSlug = 'publishpress-statuses';
142 $pluginCheckerConfig->pluginFolder = 'publishpress-statuses';
143 $pluginCheckerConfig->pluginName = 'PublishPress Statuses';
144
145 $pluginChecker = new PublishPressInstanceProtection\InstanceChecker($pluginCheckerConfig);
146 }
147
148 if (! class_exists('ComposerAutoloaderInitPublishPressStatuses')
149 && file_exists(PUBLISHPRESS_STATUSES_INTERNAL_VENDORPATH . '/autoload.php')
150 ) {
151 require_once PUBLISHPRESS_STATUSES_INTERNAL_VENDORPATH . '/autoload.php';
152 }
153
154 // Load bundled-translations library
155 $bundledTranslationsPath = '/publishpress/bundled-translations/core/include.php';
156 if (file_exists(PUBLISHPRESS_STATUSES_INTERNAL_VENDORPATH . $bundledTranslationsPath)) {
157 require_once PUBLISHPRESS_STATUSES_INTERNAL_VENDORPATH . $bundledTranslationsPath;
158 }
159
160 // Initialize bundled translations
161 add_action('plugins_loaded', function() {
162 if (class_exists('PublishPress\BundledTranslations\BundledTranslations')) {
163 $bundledTranslations = new PublishPress\BundledTranslations\BundledTranslations(
164 'publishpress-statuses',
165 __DIR__ . '/languages',
166 __FILE__
167 );
168 $bundledTranslations->init();
169 }
170 }, 10);
171 }
172
173 if ((!defined('PUBLISHPRESS_STATUSES_FILE') && !$pro_active) || $publishpress_statuses_loaded_by_pro) {
174 define('PUBLISHPRESS_STATUSES_FILE', __FILE__);
175 define('PUBLISHPRESS_STATUSES_ABSPATH', __DIR__);
176
177 if (!defined('PUBLISHPRESS_STATUSES_CLASSPATH_COMMON')) {
178 define('PUBLISHPRESS_STATUSES_CLASSPATH_COMMON', __DIR__ . '/classes/PressShack');
179 }
180
181 function publishpress_statuses_load() {
182 global $publishpress_statuses_loaded_by_pro;
183
184 $publishpress_statuses_loaded_by_pro = strpos(str_replace('\\', '/', __FILE__), 'vendor/publishpress/');
185
186 if (defined('PUBLISHPRESS_STATUSES_VERSION')) {
187 return;
188 }
189
190 if (defined('PUBLISHPRESS_VERSION') && version_compare(PUBLISHPRESS_VERSION, '4.0-beta4', '<')) {
191 add_action('admin_notices', function() {
192 ?>
193 <div class="notice error">
194 <p><?php printf(
195 // translators: %s is a version number
196 esc_html__('To use PublishPress Statuses, please upgrade PublishPress Planner to version %s or higher.', 'publishpress-statuses'),
197 '4.0-beta4'
198 );
199 ?></p>
200 </div>
201 <?php
202 });
203
204 $interrupt_load = true;
205 }
206
207 if (defined('PRESSPERMIT_PRO_VERSION') && version_compare(PRESSPERMIT_PRO_VERSION, '4.6.4', '<')) {
208 add_action('admin_notices', function() {
209 ?>
210 <div class="notice error">
211 <p><?php printf(
212 // translators: %s is a version number
213 esc_html__('To use PublishPress Statuses, please upgrade PublishPress Permissions Pro to version %s or higher.', 'publishpress-statuses'),
214 '4.6.4'
215 );
216 ?></p>
217 </div>
218 <?php
219 });
220
221 $interrupt_load = true;
222 }
223
224 if (defined('PUBLISHPRESS_CAPS_PRO_VERSION') && version_compare(PUBLISHPRESS_CAPS_PRO_VERSION, '2.11-beta2', '<')) {
225 add_action('admin_notices', function() {
226 ?>
227 <div class="notice error">
228 <p><?php printf(
229 // translators: %s is a version number
230 esc_html__('To use PublishPress Statuses, please upgrade PublishPress Capabilities Pro to version %s or higher.', 'publishpress-statuses'),
231 '2.11-beta2'
232 );
233 ?></p>
234 </div>
235 <?php
236 });
237
238 $interrupt_load = true;
239 }
240
241 global $pagenow;
242
243 if (is_admin() && isset($pagenow) && ('customize.php' == $pagenow)) {
244 $interrupt_load = true;
245 }
246
247 if (empty($interrupt_load)) {
248 define('PUBLISHPRESS_STATUSES_VERSION', '1.3.6');
249
250 define('PUBLISHPRESS_STATUSES_URL', trailingslashit(plugins_url('', __FILE__))); // @todo: vendor lib
251
252 define('PUBLISHPRESS_STATUSES_DIR', __DIR__);
253
254 require_once(__DIR__ . '/lib/PP_Statuses_Functions.php');
255
256 if (!$publishpress_statuses_loaded_by_pro) {
257 require_once(__DIR__ . '/includes-core/Core.php');
258 new \PublishPress\Statuses\Core();
259
260 if (is_admin()) {
261 require_once(__DIR__ . '/includes-core/CoreAdmin.php');
262 new \PublishPress\Statuses\CoreAdmin();
263 }
264
265 // Include a back compat class if an older version of status-capabilities library will be used
266 add_filter('publishpress_status_capabilities_library',
267 function($status_caps_package_to_use) {
268 if (!empty($status_caps_package_to_use) && !empty($status_caps_package_to_use->version)) {
269 if (version_compare($status_caps_package_to_use->version, '1.3.0', '<')) {
270 require_once(__DIR__ . '/includes-core/PublishPress_Functions.php');
271 }
272 }
273
274 return $status_caps_package_to_use;
275 }, 99
276 );
277 }
278
279 require_once(__DIR__ . '/publishpress-module/Module_Base.php');
280 new \PublishPress\PPP_Module_Base();
281
282 require_once(__DIR__ . '/PublishPress_Statuses.php');
283 PublishPress_Statuses::instance();
284
285 do_action('publishpress_statuses_init');
286
287 add_action(
288 'init',
289 function() {
290 @load_plugin_textdomain('publishpress-statuses', false, dirname(plugin_basename(__FILE__)) . '/languages'); // phpcs:ignore PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound
291 },
292 5
293 );
294
295 if (!class_exists('PP_Custom_Status')
296 && (defined('PRESSPERMIT_VERSION') || (!defined('PUBLISHPRESS_VERSION') || version_compare(PUBLISHPRESS_VERSION, '4.0', '<')))
297 ) {
298 class_alias('\PublishPress_Statuses', '\PP_Custom_Status');
299 }
300 }
301 }
302
303 // negative priority to precede any default WP action handlers
304 if ($publishpress_statuses_loaded_by_pro) {
305 publishpress_statuses_load(); // Pro support
306 } else {
307 add_action('plugins_loaded', 'publishpress_statuses_load', -5);
308
309 // Disable early loading of capabilities-pro textdomain with Capabilities Pro 2.44.0
310 add_action(
311 'plugins_loaded',
312 function() {
313 if (defined('PUBLISHPRESS_CAPS_PRO_VERSION') && version_compare(PUBLISHPRESS_CAPS_PRO_VERSION, '2.45.0', '<')) {
314 global $l10n;
315
316 if ( !isset( $l10n[ 'capabilities-pro' ] ) ) {
317 $l10n[ 'capabilities-pro' ] = new NOOP_Translations(); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
318 }
319 }
320 }, 9
321 );
322
323 add_action(
324 'plugins_loaded',
325 function() {
326 if (defined('PUBLISHPRESS_CAPS_PRO_VERSION') && version_compare(PUBLISHPRESS_CAPS_PRO_VERSION, '2.45.0', '<')) {
327 global $l10n;
328 unset( $l10n[ 'capabilities-pro' ] ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
329 }
330 }, 11
331 );
332 }
333
334 register_activation_hook(
335 __FILE__,
336 function() {
337 if (!get_option('publishpress_statuses_activation_done')) {
338 update_option('publishpress_statuses_activation_done', true);
339 update_option('publishpress_statuses_activate', true);
340 }
341 }
342 );
343
344 register_deactivation_hook(
345 __FILE__,
346 function()
347 {
348 delete_transient('publishpress_statuses_maintenance');
349 delete_option('publishpress_statuses_planner_import_gmt');
350
351 if (!get_option('publishpress_version') || defined('PUBLISHPRESS_STATUSES_NO_PLANNER_BACK_COMPAT')) {
352 return;
353 }
354
355 // Restore archived PublishPress Planner 3.x term descriptions (with encoded status properties), in case it will be re-activated
356 if ($archived_term_descriptions = get_option('pp_statuses_archived_term_properties')) {
357
358 // Use hardcoded taxonomy string here because class PublishPress_Statuses is not loaded
359 $terms = get_terms(['taxonomy' => 'post_status', 'hide_empty' => false]);
360
361 if (is_array($terms)) {
362 foreach ($terms as $term) {
363 if (!empty($archived_term_descriptions[$term->term_id])) {
364 $description = $archived_term_descriptions[$term->term_id];
365
366 if (preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $description)
367 && (strlen($description) > 80) && (false === strpos($description, ' '))
368 ) {
369 // Use hardcoded taxonomy string here because class PublishPress_Statuses is not loaded
370 wp_update_term($term->term_id, 'post_status', ['description' => $description]);
371 }
372 }
373 }
374 }
375 }
376
377 // Set post_types option storage value back to "on" / "off"
378 $options = get_option('publishpress_custom_status_options');
379
380 if (is_object($options) && isset($options->enabled)) {
381 if ($options->enabled) {
382 $options->enabled = 'on';
383 $do_option_update = true;
384 } else {
385 $options->enabled = 'off';
386 $do_option_update = true;
387 }
388 }
389
390 if (is_object($options) && !empty($options->post_types)) {
391 foreach ($options->post_types as $post_type => $val) {
392 if ($val) {
393 $options->post_types[$post_type] = 'on';
394 $do_option_update = true;
395 } else {
396 $options->post_types[$post_type] = 'off';
397 $do_option_update = true;
398 }
399 }
400 }
401
402 if (!empty($options->loaded_once)) {
403 unset($options->loaded_once);
404 $do_option_update = true;
405 }
406
407 if (!empty($do_option_update)) {
408 update_option('publishpress_custom_status_options', $options);
409 }
410 }
411 );
412 }
413