• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

daycry / jobs / 25524991494

07 May 2026 10:13PM UTC coverage: 75.044% (+0.04%) from 75.009%
25524991494

push

github

daycry
ci: pin Coveralls upload to PHP 8.5

Aligns the coverage source with the rest of the toolchain so the
reported numbers come from the same runtime PHPStan, Psalm and Rector
already exercise.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

2138 of 2849 relevant lines covered (75.04%)

11.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.18
/src/Traits/EnqueuableTrait.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of Daycry Queues.
7
 *
8
 * (c) Daycry <daycry9@proton.me>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace Daycry\Jobs\Traits;
15

16
use CodeIgniter\I18n\Time;
17
use DateInterval;
18
use DateTime;
19
use Daycry\Jobs\Exceptions\JobException;
20
use Daycry\Jobs\Exceptions\QueueException;
21
use Daycry\Jobs\Interfaces\QueueInterface;
22
use Daycry\Jobs\Libraries\QueueManager;
23
use Daycry\Jobs\Libraries\Utils;
24
use Daycry\Jobs\Queues\SyncQueue;
25

26
/**
27
 * Queue-centric capabilities: queue selection, scheduling, attempts tracking and priority validation.
28
 * push(): validates job data and delegates to configured worker enqueue.
29
 */
30
trait EnqueuableTrait
31
{
32
    /**
33
     * Number of completed execution cycles for this job.
34
     * Starts at 0 (never executed). Incremented exactly once per run (success or failure)
35
     * by RequeueHelper::finalize(). A requeued job therefore keeps its historical attempts
36
     * count so retry policies can make consistent decisions.
37
     */
38
    protected int $attempts = 0;
39

40
    protected ?string $queue = null;
41
    private QueueInterface $worker;
42
    protected ?DateTime $schedule = null;
43
    protected int $priority       = 0;
44

45
    /**
46
     * Marks the job to be placed on a queue (assigns/validates queue name).
47
     * Fluent: returns $this instead of bool so you can chain ->enqueue()->named('...')->priority(...)
48
     * NOTE: This does NOT actually push the job to the backend. Call push() for that.
49
     */
50
    public function enqueue(?string $queue = null): self
51
    {
52
        $queues = Utils::parseConfigFile(config('Jobs')->queues);
9✔
53
        // If a queue name is explicitly provided, assign it
54
        if ($queue !== null) {
9✔
55
            $this->queue = $queue;
8✔
56
        }
57

58
        // If still null, take the first available queue (if any)
59
        if ($this->queue === null && $queues !== []) {
9✔
60
            $this->queue = $queues[0];
1✔
61
        }
62

63
        if (! in_array($this->queue, $queues, true)) {
9✔
64
            throw QueueException::forInvalidQueue($this->queue);
×
65
        }
66

67
        return $this;
9✔
68
    }
69

70
    public function priority(int $priority): self
71
    {
72
        if ($priority < 0 || $priority > 10) {
345✔
73
            throw JobException::forInvalidPriority($priority);
×
74
        }
75

76
        $this->priority = $priority;
345✔
77

78
        return $this;
345✔
79
    }
80

81
    public function push()
82
    {
83
        // Assign default source if not already defined (direct queue usage)
84
        if (method_exists($this, 'getSource') && method_exists($this, 'source') && $this->getSource() === null) {
21✔
85
            $this->source('queue');
20✔
86
        }
87
        $this->checkWorker();
21✔
88
        // Fast path for SyncQueue: pass original Job instance so callback descriptor & closures are preserved.
89
        if ($this->worker instanceof SyncQueue) {
21✔
90
            // Perform validation using an export snapshot; inject placeholder for closure payload.
91
            $export = $this->toObject();
3✔
92
            if ($this->getJob() === 'closure') {
3✔
93
                $export->payload = '__closure__';
×
94
            }
95
            Utils::checkDataQueue($export, 'queueData');
3✔
96
            if ($this->getJob() !== 'closure') {
3✔
97
                Utils::checkDataQueue($export, $this->getJob());
3✔
98
            }
99

100
            return $this->worker->enqueue($this);
3✔
101
        }
102

103
        $object = $this->toObject();
18✔
104
        if ($this->getJob() === 'closure') {
18✔
105
            // Validation snapshot with placeholder
106
            $snapshot          = clone $object;
3✔
107
            $snapshot->payload = '__closure__';
3✔
108
            Utils::checkDataQueue($snapshot, 'queueData');
3✔
109
        } else {
110
            Utils::checkDataQueue($object, 'queueData');
15✔
111
            Utils::checkDataQueue($object, $this->getJob());
15✔
112
        }
113

114
        return $this->worker->enqueue($object);
17✔
115
    }
116

117
    public function setQueue(string $queue): self
118
    {
119
        $this->queue = $queue;
30✔
120

121
        return $this;
30✔
122
    }
123

124
    public function getQueue(): ?string
125
    {
126
        return $this->queue;
60✔
127
    }
128

129
    public function scheduled(DateTime|Time $schedule)
130
    {
131
        if ($schedule instanceof Time) {
13✔
132
            $schedule = $schedule->toDateTime();
1✔
133
        }
134

135
        $this->schedule = $schedule;
13✔
136

137
        return $this;
13✔
138
    }
139

140
    public function addAttempt(): self
141
    {
142
        $this->attempts++;
15✔
143

144
        if ($this->schedule !== null) {
15✔
145
            $this->scheduled((new DateTime())->add(new DateInterval('PT1H')));
1✔
146
        }
147

148
        return $this;
15✔
149
    }
150

151
    public function getAttempt(): int
152
    {
153
        return $this->attempts;
88✔
154
    }
155

156
    // No idempotency helpers (reverted)
157

158
    protected function checkWorker(): void
159
    {
160
        $this->worker = QueueManager::instance()->getDefault();
21✔
161
    }
162
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc