HEX
Server: Apache/2.4.63 (Unix)
System: Linux TOMS-220NAS 4.4.302+ #86009 SMP Wed Nov 26 18:19:17 CST 2025 x86_64
User: flavio87 (1026)
PHP: 8.3.27
Disabled: NONE
Upload Files
File: /volume1/web/tom-marchisa/wp-content/plugins/real-physical-media/inc/rest/Queue.php
<?php

namespace DevOwl\RealPhysicalMedia\rest;

use DevOwl\RealPhysicalMedia\base\UtilsProvider;
use DevOwl\RealPhysicalMedia\configuration\Options;
use DevOwl\RealPhysicalMedia\listener\Lockfile;
use DevOwl\RealPhysicalMedia\queue\Queue as QueueQueue;
use DevOwl\RealPhysicalMedia\rest\Service as RestService;
use DevOwl\RealPhysicalMedia\Util;
use DevOwl\RealPhysicalMedia\view\AdminBar;
use MatthiasWeb\RealMediaLibrary\rest\Service;
use DevOwl\RealPhysicalMedia\Vendor\MatthiasWeb\Utils\Service as UtilsService;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
// @codeCoverageIgnoreStart
\defined('ABSPATH') or die('No script kiddies please!');
// Avoid direct file request
// @codeCoverageIgnoreEnd
/**
 * Main service.
 * @internal
 */
class Queue
{
    use UtilsProvider;
    /**
     * C'tor.
     */
    private function __construct()
    {
        // Silence is golden.
    }
    /**
     * Register endpoints.
     */
    public function rest_api_init()
    {
        $namespace = UtilsService::getNamespace($this);
        \register_rest_route($namespace, '/queue', ['methods' => 'GET', 'callback' => [$this, 'routeQueue'], 'permission_callback' => [$this, 'permission_callback']]);
        \register_rest_route($namespace, '/queue', ['methods' => 'POST', 'callback' => [$this, 'routeQueuePost'], 'permission_callback' => [$this, 'permission_callback']]);
        \register_rest_route($namespace, '/queue/automatic', ['methods' => 'POST', 'callback' => [$this, 'routeQueueAutomatic'], 'permission_callback' => [$this, 'permission_callback_manage_options'], 'args' => ['state' => ['type' => 'boolean']]]);
        \register_rest_route($namespace, '/queue/automatic-hint/dismiss', ['methods' => 'DELETE', 'callback' => [$this, 'routeQueueAutomaticHintDismiss'], 'permission_callback' => [$this, 'permission_callback_manage_options']]);
        \register_rest_route($namespace, '/queue/notice/dismiss', ['methods' => 'DELETE', 'callback' => [$this, 'routeQueueNoticeDismiss'], 'permission_callback' => [$this, 'permission_callback_manage_options']]);
        \register_rest_route($namespace, '/queue/item/(?P<id>\\d+)', ['methods' => 'POST', 'callback' => [$this, 'routeQueueItemAdd'], 'permission_callback' => [$this, 'permission_callback']]);
        \register_rest_route($namespace, '/queue/item/potential', ['methods' => 'POST', 'callback' => [$this, 'routeQueueItemAddPotential'], 'permission_callback' => [$this, 'permission_callback_manage_options']]);
        \register_rest_route($namespace, '/queue/cron/(?P<token>[A-za-z0-9]+)', ['methods' => 'GET', 'callback' => [$this, 'routeQueueCron'], 'permission_callback' => '__return_true']);
        \register_rest_route($namespace, '/lockfiles/reflect', ['methods' => 'POST', 'callback' => [$this, 'routeLockfilesReflect'], 'permission_callback' => [$this, 'permission_callback_manage_options']]);
        \register_rest_route($namespace, '/lockfiles', ['methods' => 'DELETE', 'callback' => [$this, 'routeLockfilesDelete'], 'permission_callback' => [$this, 'permission_callback_manage_options']]);
    }
    /**
     * Check if user is allowed to call this service requests.
     */
    public function permission_callback()
    {
        $permit = Service::permit();
        return $permit === null ? \true : $permit;
    }
    /**
     * Check if user is allowed to call this service requests with `manage_options` cap.
     */
    public function permission_callback_manage_options()
    {
        $permit = Service::permit();
        return $permit === null ? \true : $permit;
    }
    /**
     * See API docs.
     *
     * @param WP_REST_Request $request
     * @api {get} /real-physical-media/v1/queue Get queue information
     * @apiHeader {string} X-WP-Nonce
     * @apiParam {int} [skip=0] Offset
     * @apiParam {int} [top=5] Top, maximum 100
     * @apiName GetQueue
     * @apiGroup Queue
     * @apiVersion 1.0.0
     * @apiPermission upload_files
     */
    public function routeQueue($request)
    {
        $queue = QueueQueue::getInstance();
        return new WP_REST_Response($queue->prepareResponse($request->get_param('skip'), $request->get_param('top')));
    }
    /**
     * See API docs.
     *
     * @param WP_REST_Request $request
     * @api {post} /real-physical-media/v1/queue Process the queue and return back updating rows
     * @apiHeader {string} X-WP-Nonce
     * @apiParam {int} [skip=0] Offset
     * @apiParam {int} [top=5] Top, maximum 100
     * @apiParam {string} [skip] The skip mechanism: 'retry' or 'skip'
     * @apiName PostQueue
     * @apiGroup Queue
     * @apiVersion 1.0.0
     * @apiPermission upload_files
     */
    public function routeQueuePost($request)
    {
        $do = $this->doQueue($request);
        if (\is_wp_error($do)) {
            return $do;
        }
        return new WP_REST_Response($do);
    }
    /**
     * See API docs.
     *
     * @param WP_REST_Request $request
     * @api {get} /real-physical-media/v1/queue/cron/:token Process the queue for cron URL
     * @apiHeader {string} X-WP-Nonce
     * @apiParam {string} token The unique token for the given blog
     * @apiParam {string} [skip=0] Offset
     * @apiParam {int} [top=5] Top, maximum 100
     * @apiParam {string} [skip] The skip mechanism: 'retry' or 'skip'
     * @apiName CronQueue
     * @apiGroup Queue
     * @apiVersion 1.0.0
     */
    public function routeQueueCron($request)
    {
        if (Options::getInstance()->getCronJobToken() !== $request->get_param('token')) {
            return new WP_Error('rpm_cron_queue_process', \__('You are not allowed to do this. You can find your cronjob service URLs in the media settings.', 'real-physical-media'), ['status' => 403]);
        }
        $do = $this->doQueue($request);
        if (\is_wp_error($do)) {
            return $do;
        }
        return new WP_REST_Response($do);
    }
    /**
     * See API docs.
     *
     * @param WP_REST_Request $request
     * @api {post} /real-physical-media/v1/queue/item/:id Add an item to the queue
     * @apiHeader {string} X-WP-Nonce
     * @apiParam {int} id The attachment id
     * @apiName AddItem
     * @apiGroup Queue
     * @apiVersion 1.0.0
     * @apiPermission upload_files
     */
    public function routeQueueItemAdd($request)
    {
        if (($permit = Service::permit()) !== null) {
            return $permit;
        }
        $queue = QueueQueue::getInstance();
        // Add item to queue
        $result = $queue->add($request->get_param('id'));
        if (\is_wp_error($result)) {
            return $result;
        }
        return new WP_REST_Response(\true);
    }
    /**
     * See API docs.
     *
     * @param WP_REST_Request $request
     * @api {post} /real-physical-media/v1/queue/item/potential Reinitialize and add all potential files from this blog to the queue
     * @apiHeader {string} X-WP-Nonce
     * @apiName AddPotentialItems
     * @apiGroup Queue
     * @apiVersion 1.0.0
     * @apiPermission manage_options
     */
    public function routeQueueItemAddPotential($request)
    {
        if (($permit = Service::permit('manage_options')) !== null) {
            return $permit;
        }
        if (($demo = RestService::demoNotAllowed()) !== null) {
            return $demo;
        }
        QueueQueue::getInstance()->addPotentialFiles();
        return new WP_REST_Response(\true);
    }
    /**
     * See API docs.
     *
     * @param WP_REST_Request $request
     * @api {post} /real-physical-media/v1/queue/automatic Activate or deactivate the automatic queueing
     * @apiHeader {string} X-WP-Nonce
     * @apiParam {boolean} state The new state
     * @apiName SetAutomaticQueueing
     * @apiGroup Queue
     * @apiVersion 1.0.0
     * @apiPermission manage_options
     */
    public function routeQueueAutomatic($request)
    {
        if (($permit = Service::permit('manage_options')) !== null) {
            return $permit;
        }
        $queue = QueueQueue::getInstance();
        // Add item to queue
        $result = $queue->isAutomaticQueueing($request->get_param('state'));
        if (\is_wp_error($result)) {
            return $result;
        }
        return new WP_REST_Response($result);
    }
    /**
     * See API docs.
     *
     * @param WP_REST_Request $request
     * @api {delete} /real-physical-media/v1/queue/automatic-hint/dismiss Dismiss the hint to automatic queueing
     * @apiName DismissAutomaticHint
     * @apiGroup Queue
     * @apiVersion 1.1.0
     * @apiPermission manage_options
     */
    public function routeQueueAutomaticHintDismiss()
    {
        if (($permit = Service::permit('manage_options')) !== null) {
            return $permit;
        }
        AdminBar::getInstance()->isFirstTimeMoveHintDismissed(\true);
        return new WP_REST_Response(\true);
    }
    /**
     * See API docs.
     *
     * @param WP_REST_Request $request
     * @api {delete} /real-physical-media/v1/queue/notice/dismiss Dismiss the notice to queue admin bar
     * @apiName DismissQueueNotice
     * @apiGroup Queue
     * @apiVersion 1.1.0
     * @apiPermission manage_options
     */
    public function routeQueueNoticeDismiss()
    {
        if (($permit = Service::permit('manage_options')) !== null) {
            return $permit;
        }
        AdminBar::getInstance()->isFirstTimeQueueNoticeDismissed(\true);
        return new WP_REST_Response(\true);
    }
    /**
     * See API docs.
     *
     * @param WP_REST_Request $request
     * @api {post} /real-physical-media/v1/lockfiles/reflect Reflect the complete virtual structure to physical folders
     * @apiHeader {string} X-WP-Nonce
     * @apiParam {boolean} withlockfile Create lockfiles if true
     * @apiName ReflectLockfiles
     * @apiGroup Lockfiles
     * @apiVersion 1.0.0
     * @apiPermission manage_options
     */
    public function routeLockfilesReflect($request)
    {
        if (($permit = Service::permit('manage_options')) !== null) {
            return $permit;
        }
        Lockfile::getInstance()->createAll($request->get_param('withlockfile') === 'true');
        return new WP_REST_Response(\true);
    }
    /**
     * See API docs.
     *
     * @param WP_REST_Request $request
     * @api {delete} /real-physical-media/v1/lockfiles Remove all lockfiles
     * @apiHeader {string} X-WP-Nonce
     * @apiName DeleteLockfiles
     * @apiGroup Lockfiles
     * @apiVersion 1.0.0
     * @apiPermission manage_options
     */
    public function routeLockfilesDelete($request)
    {
        if (($permit = Service::permit('manage_options')) !== null) {
            return $permit;
        }
        Lockfile::getInstance()->removeAll();
        return new WP_REST_Response(\true);
    }
    /**
     * Process the queue.
     *
     * @param WP_REST_Request $request
     */
    private function doQueue($request)
    {
        $queue = QueueQueue::getInstance();
        // Delete error
        $skipError = $request->get_param('skip');
        if ($skipError === 'retry') {
            $queue->clearException();
        } elseif ($skipError === 'skip') {
            $queue->clearException(\true);
        }
        // Get first entry and process is available
        $result = $queue->process(Options::getInstance()->getMaxExecTime());
        if (\is_wp_error($result)) {
            return $result;
        }
        $response = $queue->prepareResponse($request->get_param('skip'), $request->get_param('top'));
        // Find common URL prefix to reduce payload
        $allDoneUrls = [];
        foreach ($result as $value) {
            $allDoneUrls = \array_merge($allDoneUrls, \array_values($value['u']));
        }
        $prefix = Util::commonPrefix($allDoneUrls);
        $prefln = \strlen($prefix);
        foreach ($result as &$value) {
            foreach ($value['u'] as $size => $url) {
                $value['u'][$size] = \substr($url, $prefln);
            }
        }
        $response['done'] = $result;
        $response['doneUrlPrefix'] = $prefix;
        return $response;
    }
    /**
     * New instance.
     */
    public static function instance()
    {
        return new \DevOwl\RealPhysicalMedia\rest\Queue();
    }
}