Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ Thumbs.db
# Logs
*.log

# Translation tool backups
*backup*
*.po~
*.pot~

# Local config
.env
.env.local
Expand Down
81 changes: 81 additions & 0 deletions build-plugin.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env bash
#
# Build a WordPress.org-ready zip archive for the WP Queue plugin.
#
# Usage:
# cd wp-content/plugins/wp-queue
# ./build-plugin.sh
#
# The archive is written to build/wp-queue.<version>.zip
# and contains only the files required for publishing/installing the plugin.
#

set -euo pipefail

# Ensure the script is run from the plugin root.
if [[ ! -f "wp-queue.php" ]]; then
echo "Error: wp-queue.php not found. Please run this script from the plugin root directory." >&2
exit 1
fi

PLUGIN_SLUG="wp-queue"
VERSION=$(grep -m1 "Version:" wp-queue.php | sed -E 's/^[^:]*Version:[[:space:]]*//')
BUILD_DIR="build"
ZIP_NAME="${PLUGIN_SLUG}.${VERSION}.zip"
ZIP_PATH="${BUILD_DIR}/${ZIP_NAME}"

if [[ -z "${VERSION}" ]]; then
echo "Error: could not detect plugin version from wp-queue.php" >&2
exit 1
fi

TMP_DIR=$(mktemp -d)
STAGING_DIR="${TMP_DIR}/${PLUGIN_SLUG}"
mkdir -p "${STAGING_DIR}"

echo "Building ${ZIP_NAME}..."

# Required plugin files.
cp wp-queue.php readme.txt LICENSE "${STAGING_DIR}/"

# Source code.
cp -r src "${STAGING_DIR}/"

# Runtime admin assets only (CSS/JS). Images are excluded because they are
# either WordPress.org promo assets or unused in the admin UI.
mkdir -p "${STAGING_DIR}/assets"
cp -r assets/css assets/js "${STAGING_DIR}/assets/"

# Translations: include compiled and source files, remove editor backups.
cp -r languages "${STAGING_DIR}/"
find "${STAGING_DIR}/languages" -type f \( \
-name '*backup*' \
-o -name '*.po~' \
-o -name '*.pot~' \
-o -name '*.mo~' \
\) -delete

# Verify the main plugin file exists in the staging directory.
if [[ ! -f "${STAGING_DIR}/wp-queue.php" ]]; then
echo "Error: staged plugin file is missing." >&2
rm -rf "${TMP_DIR}"
exit 1
fi

# Prepare build output directory.
mkdir -p "${BUILD_DIR}"
rm -f "${ZIP_PATH}"

# Create the zip with the plugin slug as the top-level directory.
(
cd "${TMP_DIR}"
zip -r "${OLDPWD}/${ZIP_PATH}" "${PLUGIN_SLUG}" -q
)

# Clean up staging directory.
rm -rf "${TMP_DIR}"

echo "Archive created: ${ZIP_PATH}"
echo ""
echo "Contents:"
unzip -l "${ZIP_PATH}"
19 changes: 15 additions & 4 deletions readme.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
=== WP Queue - Background Job Manager ===
=== Queue Manager ===
Contributors: rwsite
Donate link: https://rwsite.ru/donate
Tags: queue, cron, background-processing, jobs, scheduler
Requires at least: 6.0
Tested up to: 6.9
Requires at least: 6.2
Tested up to: 7.0
Requires PHP: 8.3
Stable tag: 1.2.0
Stable tag: 1.2.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Expand Down Expand Up @@ -147,6 +147,14 @@ Yes, WP Queue works with WordPress multisite installations.

== Changelog ==

= 1.2.1 =
* Added ABSPATH guards to all PHP files
* Fixed WordPress Plugin Check errors: escaping, i18n placeholders, input sanitization
* Refactored database queries to use identifier placeholders
* Fixed arbitrary class instantiation in REST API run job endpoint
* Renamed plugin display name to Queue Manager
* Updated "Tested up to" to 7.0 and "Requires at least" to 6.2

= 1.2.0 =
* Added runtime modes: cron_loopback, daemon, auto
* Added loopback dispatch for immediate queue processing after dispatch()
Expand All @@ -173,6 +181,9 @@ Yes, WP Queue works with WordPress multisite installations.

== Upgrade Notice ==

= 1.2.1 =
Maintenance release with WordPress Plugin Check fixes and plugin rename to Queue Manager.

= 1.2.0 =
New runtime modes. Use `define('WP_QUEUE_RUNTIME_MODE', 'daemon')` with a separate worker process, or keep the default `cron_loopback` mode for shared hosting.

Expand Down
49 changes: 33 additions & 16 deletions src/Admin/AdminPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
use WPQueue\Runtime\RuntimeMode;
use WPQueue\WPQueue;

if (! defined('ABSPATH')) {
exit;
}

/**
* Admin Page with Rank Math style UI
* 3 main tabs: Queues, Scheduler, System
Expand Down Expand Up @@ -206,8 +210,8 @@ public function enqueueAssets(string $hook): void

public function renderPage(): void
{
$tab = sanitize_key($_GET['tab'] ?? 'queues');
$section = sanitize_key($_GET['section'] ?? '');
$tab = sanitize_key(wp_unslash($_GET['tab'] ?? 'queues'));
$section = sanitize_key(wp_unslash($_GET['section'] ?? ''));

if (! isset($this->tabs[$tab])) {
$tab = 'queues';
Expand All @@ -219,8 +223,8 @@ public function renderPage(): void
}

// Проверка на детальный просмотр очереди
$queueView = sanitize_key($_GET['queue'] ?? '');
$jobView = sanitize_key($_GET['job'] ?? '');
$queueView = sanitize_key(wp_unslash($_GET['queue'] ?? ''));
$jobView = sanitize_key(wp_unslash($_GET['job'] ?? ''));

?>
<div class="wrap wp-queue-wrap">
Expand Down Expand Up @@ -337,7 +341,7 @@ protected function renderQueuesOverview(): void
$metrics = WPQueue::logs()->metrics();
$queues = $this->getQueuesStatus();
$driver = WPQueue::manager()->getDefaultDriver();
$filter = sanitize_key($_GET['status'] ?? '');
$filter = sanitize_key(wp_unslash($_GET['status'] ?? ''));
?>
<div class="wp-queue-content-wrapper">
<!-- Статистика - кликабельные карточки -->
Expand Down Expand Up @@ -407,7 +411,7 @@ protected function renderQueuesOverview(): void
protected function renderQueueDetail(string $queueName, string $jobId = ''): void
{
$jobs = $this->getQueueJobs($queueName);
$page = max(1, (int) ($_GET['paged'] ?? 1));
$page = max(1, (int) wp_unslash($_GET['paged'] ?? 1));
$totalJobs = count($jobs);
$totalPages = max(1, (int) ceil($totalJobs / self::JOBS_PER_PAGE));
$offset = ($page - 1) * self::JOBS_PER_PAGE;
Expand All @@ -420,7 +424,11 @@ protected function renderQueueDetail(string $queueName, string $jobId = ''): voi
<!-- Заголовок с действиями -->
<div class="queue-detail-header">
<div class="queue-detail-title">
<h1><?php echo esc_html(sprintf(__('Queue: %s', 'wp-queue'), $queueName)); ?></h1>
<h1><?php echo esc_html(sprintf(
// translators: %s: Queue name.
__('Queue: %s', 'wp-queue'),
$queueName,
)); ?></h1>
<span class="status-badge status-<?php echo $isPaused ? 'paused' : ($isProcessing ? 'running' : 'idle'); ?>">
<?php
if ($isPaused) {
Expand Down Expand Up @@ -542,7 +550,11 @@ protected function renderQueueDetail(string $queueName, string $jobId = ''): voi
<div class="tablenav bottom">
<div class="tablenav-pages">
<span class="displaying-num">
<?php echo esc_html(sprintf(__('%d tasks', 'wp-queue'), $totalJobs)); ?>
<?php echo esc_html(sprintf(
// translators: %d: Number of tasks.
__('%d tasks', 'wp-queue'),
$totalJobs,
)); ?>
</span>
<span class="pagination-links">
<?php
Expand Down Expand Up @@ -809,9 +821,9 @@ protected function renderDocsIntro(): void

protected function renderQueuesHistory(): void
{
$filter = sanitize_key($_GET['filter'] ?? 'all');
$queueFilter = sanitize_key($_GET['queue_filter'] ?? '');
$page = max(1, (int) ($_GET['paged'] ?? 1));
$filter = sanitize_key(wp_unslash($_GET['filter'] ?? 'all'));
$queueFilter = sanitize_key(wp_unslash($_GET['queue_filter'] ?? ''));
$page = max(1, (int) wp_unslash($_GET['paged'] ?? 1));

// Получаем все логи
$allLogs = match ($filter) {
Expand Down Expand Up @@ -910,7 +922,11 @@ protected function renderQueuesHistory(): void
<div class="tablenav bottom">
<div class="tablenav-pages">
<span class="displaying-num">
<?php echo esc_html(sprintf(__('%d entries', 'wp-queue'), $totalLogs)); ?>
<?php echo esc_html(sprintf(
// translators: %d: Number of log entries.
__('%d entries', 'wp-queue'),
$totalLogs,
)); ?>
</span>
<span class="pagination-links">
<?php
Expand Down Expand Up @@ -940,7 +956,7 @@ protected function renderQueuesHistory(): void
protected function renderQueuesFailed(): void
{
$failedLogs = WPQueue::logs()->failed();
$page = max(1, (int) ($_GET['paged'] ?? 1));
$page = max(1, (int) wp_unslash($_GET['paged'] ?? 1));
$totalLogs = count($failedLogs);
$totalPages = max(1, (int) ceil($totalLogs / self::LOGS_PER_PAGE));
$offset = ($page - 1) * self::LOGS_PER_PAGE;
Expand Down Expand Up @@ -1031,7 +1047,8 @@ protected function renderQueuesDrivers(): void
<p>
<strong><?php echo esc_html__('⚠️ Warning:', 'wp-queue'); ?></strong>
<?php echo esc_html(sprintf(
__('Storage backend "%s" is configured in wp-config.php, but not available. Falling back to "%s".', 'wp-queue'),
// translators: 1: Configured storage backend, 2: Fallback storage backend.
__('Storage backend "%1$s" is configured in wp-config.php, but not available. Falling back to "%2$s".', 'wp-queue'),
$configuredDriver,
$currentDriver,
)); ?>
Expand Down Expand Up @@ -1072,7 +1089,7 @@ protected function renderQueuesDrivers(): void
<?php } ?>
</td>
<td>
<?php echo $this->renderDriverStatusBadge($status, $info); ?>
<?php echo wp_kses_post($this->renderDriverStatusBadge($status, $info)); ?>
</td>
<td>
<?php echo esc_html($info['message'] ?? $info['info'] ?? ''); ?>
Expand Down Expand Up @@ -1425,7 +1442,7 @@ protected function renderSchedulerOverview(): void
protected function renderSchedulerEvents(): void
{
$monitor = new CronMonitor();
$filter = sanitize_key($_GET['filter'] ?? 'all');
$filter = sanitize_key(wp_unslash($_GET['filter'] ?? 'all'));

$events = match ($filter) {
'wordpress' => array_filter($monitor->getAllEvents(), fn ($e) => $e['source'] === 'wordpress'),
Expand Down
4 changes: 4 additions & 0 deletions src/Admin/CronMonitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

namespace WPQueue\Admin;

if (! defined('ABSPATH')) {
exit;
}

class CronMonitor
{
/**
Expand Down
6 changes: 5 additions & 1 deletion src/Admin/RestApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
use WP_REST_Response;
use WPQueue\WPQueue;

if (! defined('ABSPATH')) {
exit;
}

class RestApi
{
public function __construct()
Expand Down Expand Up @@ -329,7 +333,7 @@ public function runJob(WP_REST_Request $request): WP_REST_Response|WP_Error
{
$jobClass = urldecode($request->get_param('job'));

if (! class_exists($jobClass)) {
if (! class_exists($jobClass) || ! is_subclass_of($jobClass, \WPQueue\Jobs\Job::class)) {
return new WP_Error('invalid_job', 'Job class not found', ['status' => 404]);
}

Expand Down
4 changes: 4 additions & 0 deletions src/Admin/SystemStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

namespace WPQueue\Admin;

if (! defined('ABSPATH')) {
exit;
}

class SystemStatus
{
/**
Expand Down
4 changes: 4 additions & 0 deletions src/Attributes/Queue.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

use Attribute;

if (! defined('ABSPATH')) {
exit;
}

#[Attribute(Attribute::TARGET_CLASS)]
final readonly class Queue
{
Expand Down
4 changes: 4 additions & 0 deletions src/Attributes/Retries.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

use Attribute;

if (! defined('ABSPATH')) {
exit;
}

#[Attribute(Attribute::TARGET_CLASS)]
final readonly class Retries
{
Expand Down
4 changes: 4 additions & 0 deletions src/Attributes/Schedule.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

use Attribute;

if (! defined('ABSPATH')) {
exit;
}

#[Attribute(Attribute::TARGET_CLASS)]
final readonly class Schedule
{
Expand Down
4 changes: 4 additions & 0 deletions src/Attributes/Timeout.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

use Attribute;

if (! defined('ABSPATH')) {
exit;
}

#[Attribute(Attribute::TARGET_CLASS)]
final readonly class Timeout
{
Expand Down
4 changes: 4 additions & 0 deletions src/Attributes/UniqueJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

use Attribute;

if (! defined('ABSPATH')) {
exit;
}

#[Attribute(Attribute::TARGET_CLASS)]
final readonly class UniqueJob
{
Expand Down
4 changes: 4 additions & 0 deletions src/CLI/CronCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
use WP_CLI\Utils;
use WPQueue\Admin\CronMonitor;

if (! defined('ABSPATH')) {
exit;
}

/**
* Manage WP-Cron events.
*
Expand Down
4 changes: 4 additions & 0 deletions src/CLI/QueueCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
use WPQueue\Admin\SystemStatus;
use WPQueue\WPQueue;

if (! defined('ABSPATH')) {
exit;
}

/**
* Manage WP Queue jobs and cron events.
*
Expand Down
Loading
Loading