Completed
Branch master (450f26)
by Valentin
01:46
created

Pheanstalk::deleteTube()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Pheanstalk;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Pheanstalk\Command\CreateCommand;
7
use Pheanstalk\Command\CreateScheduleCommand;
8
use Pheanstalk\Command\CreateTubeCommand;
9
use Pheanstalk\Command\GetWorkflowCommand;
10
use Pheanstalk\Command\GetWorkflowInstancesCommand;
11
use Pheanstalk\Command\GetWorkflowInstancesDetailCommand;
12
use Pheanstalk\Command\ListWorkflowsCommand;
13
use Pheanstalk\Command\ReleaseCommand;
0 ignored issues
show
Bug introduced by
The type Pheanstalk\Command\ReleaseCommand was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use Pheanstalk\Command\UpdateTubeCommand;
15
use Pheanstalk\Command\WorkflowExistsCommand;
16
use Pheanstalk\Exception\ServerDuplicateEntryException;
17
use Pheanstalk\Structure\Job;
18
use Pheanstalk\Structure\Task;
19
use Pheanstalk\Structure\TaskInstance;
20
use Pheanstalk\Structure\TimeSchedule;
21
use Pheanstalk\Structure\Tube;
22
use Pheanstalk\Structure\Workflow;
23
use Pheanstalk\Structure\WorkflowInstance;
24
25
/**
26
 * Pheanstalk is a PHP client for the beanstalkd workqueue.
27
 *
28
 * The Pheanstalk class is a simple facade for the various underlying components.
29
 *
30
 * @see http://github.com/kr/beanstalkd
31
 * @see http://xph.us/software/beanstalkd/
32
 *
33
 * @author  Paul Annesley
34
 * @package Pheanstalk
35
 * @license http://www.opensource.org/licenses/mit-license.php
36
 */
37
class Pheanstalk implements PheanstalkInterface
38
{
39
40
    /** @var Connection $connection */
41
    private $connection;
42
43
    /** @var $currentClass PheanstalkInterface */
0 ignored issues
show
Documentation Bug introduced by
The doc comment $currentClass at position 0 could not be parsed: Unknown type name '$currentClass' at position 0 in $currentClass.
Loading history...
44
    private $currentClass;
45
46
    /**
47
     * @param string $host
48
     * @param string $user
49
     * @param string $password
50
     * @param int    $port
51
     * @param int    $connectTimeout
52
     * @param bool   $connectPersistent
53
     */
54 10
    public function __construct($host, $user = null, $password = null, $port = PheanstalkInterface::DEFAULT_PORT, $connectTimeout = null, $connectPersistent = false)
55
    {
56 10
        $this->setConnection(new Connection($host, $user, $password, $port, $connectTimeout, $connectPersistent));
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62 10
    public function setConnection(Connection $connection)
63
    {
64 10
        $this->connection = $connection;
65
66 10
        return $this;
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72 2
    public function getConnection()
73
    {
74 2
        return $this->connection;
75
    }
76
77
    /**
78
     * @return PheanstalkInterface
79
     */
80 7
    public function getCurrentClass(): PheanstalkInterface
81
    {
82 7
        return $this->currentClass ?? $this;
83
    }
84
85
    /**
86
     * @param PheanstalkInterface $currentClass
87
     *
88
     * @return Pheanstalk
89
     */
90 1
    public function setCurrentClass(PheanstalkInterface $currentClass): PheanstalkInterface
91
    {
92 1
        $this->currentClass = $currentClass;
93 1
        return $this;
94
    }
95
96
    // ----------------------------------------
97
98
    /**
99
     * {@inheritdoc}
100
     */
101 3
    public function delete(Workflow $workflow)
102
    {
103 3
        return $this->_dispatch(new Command\DeleteCommand($workflow));
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109 1
    public function deleteTube(Tube $tube)
110
    {
111 1
        return $this->_dispatch(new Command\DeleteTubeCommand($tube));
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117 5
    public function workflowExists($name)
118
    {
119 5
        $workflow = $this->_dispatch(new Command\WorkflowExistsCommand($name));
120 4
        if ($workflow instanceof Workflow) {
121 4
            return $this->getCurrentClass()->getWorkflow($workflow);
122
        }
123 1
        return false;
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129 4
    public function getWorkflow(Workflow $workflow)
130
    {
131 4
        return $this->_dispatch(new Command\GetWorkflowCommand($workflow));
132
    }
133
134
    /**
135
     * {@inheritdoc}
136
     */
137 1
    public function getWorkflowInstances(?Workflow $workflow, string $status = null)
138
    {
139 1
        $status = empty($status) ? GetWorkflowInstancesDetailCommand::FILTERS : [$status];
140 1
        $instances = new ArrayCollection([]);
141 1
        foreach ($status as $stat) {
142 1
            $instances[strtolower($stat)] = $this->_dispatch(new Command\GetWorkflowInstancesCommand($workflow, $stat));
143
//            if ($stat === GetWorkflowInstancesCommand::FILTER_EXECUTING) {
144
                /** @var ArrayCollection $workflowCollection */
145 1
                $workflowCollection = $instances[strtolower($stat)]->get('workflow_instances');
0 ignored issues
show
Bug introduced by
The method get() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

145
                /** @scrutinizer ignore-call */ 
146
                $workflowCollection = $instances[strtolower($stat)]->get('workflow_instances');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
146 1
            if (!empty($workflowCollection)) {
147 1
                foreach ($workflowCollection as $instance) {
148 1
                    $this->getCurrentClass()->getWorkflowInstancesDetails($instance);
149
                }
150
            }
151
//            }
152
        }
153
154 1
        return $instances;
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160 1
    public function getWorkflowInstancesDetails(WorkflowInstance $workflowInstance)
161
    {
162 1
        return $this->_dispatch(new Command\GetWorkflowInstancesDetailCommand($workflowInstance));
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168 3
    public function tubeExists($name)
169
    {
170 3
        return $this->_dispatch(new Command\TubeExistsCommand($name));
171
    }
172
173
    /**
174
     * {@inheritdoc}
175
     */
176
    public function listTubes()
177
    {
178
        return $this->_dispatch(new Command\ListTubesCommand());
179
    }
180
181
    /**
182
     * {@inheritdoc}
183
     */
184
    public function peek()
185
    {
186
        $response = $this->_dispatch(new Command\PeekCommand());
187
188
        return $response;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $response returns the type array<integer,array<string,integer|mixed>|string> which is incompatible with the return type mandated by Pheanstalk\PheanstalkInterface::peek() of object.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
189
    }
190
191
    /**
192
     * {@inheritdoc}
193
     */
194 2
    public function put(Workflow $workflow)
195
    {
196 2
        $response = $this->_dispatch(new Command\PutCommand($workflow));
197
198 2
        return $response['workflow-instance-id'];
199
    }
200
201
    /**
202
     * {@inheritdoc}
203
     */
204
    public function statsJob($job)
205
    {
206
        return $this->_dispatch(new Command\StatsJobCommand($job));
0 ignored issues
show
Bug introduced by
The type Pheanstalk\Command\StatsJobCommand was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
207
    }
208
209
    /**
210
     * {@inheritdoc}
211
     */
212
    public function statsTube($tube)
213
    {
214
        return $this->_dispatch(new Command\StatsTubeCommand($tube));
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_dispatch(...tatsTubeCommand($tube)) returns the type array which is incompatible with the return type mandated by Pheanstalk\PheanstalkInterface::statsTube() of object.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
215
    }
216
217
    /**
218
     * {@inheritdoc}
219
     */
220
    public function stats()
221
    {
222
        return $this->_dispatch(new Command\StatsCommand());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_dispatch(...Command\StatsCommand()) returns the type array which is incompatible with the return type mandated by Pheanstalk\PheanstalkInterface::stats() of object.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
223
    }
224
225
    // ----------------------------------------
226
227
    /**
228
     * Dispatches the specified command to the connection object.
229
     *
230
     * If a SocketException occurs, the connection is reset, and the command is
231
     * re-attempted once.
232
     *
233
     * @throws Exception\ClientException
234
     * @param Command $command
235
     *
236
     * @return mixed
237
     */
238 7
    private function _dispatch($command)
239
    {
240 7
        return $this->connection->dispatchCommand($command);
241
    }
242
243
    /**
244
     * {@inheritdoc}
245
     */
246 2
    public function create(Workflow $workflow, $force = false): Workflow
247
    {
248
        try {
249 2
            $tubes = [];
250
            /** @var Job $job */
251 2
            foreach ($workflow->getJobs() as $job) {
252
                /** @var Task $task */
253 2
                foreach ($job->getTasks() as $task) {
254 2
                    $tubes = array_merge($tubes, [$task->getQueue()]);
255
                }
256
            }
257 2
            foreach ($tubes as $tube) {
258 2
                if (!$this->getCurrentClass()->tubeExists($tube)) {
259 1
                    $this->getCurrentClass()->createTube(new Tube($tube, 1));
260
                };
261
            }
262 2
            $workflow = $this->_dispatch(new Command\CreateCommand($workflow));
263 1
        } catch (ServerDuplicateEntryException $e) {
264 1
            if ($force) {
265 1
                $workflows = $this->_dispatch(new Command\ListWorkflowsCommand());
266
                $workflowToDelete = $workflows->filter(function(Workflow $listedWorkflow) use ($workflow) {
1 ignored issue
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
267 1
                    return $listedWorkflow->getName() === $workflow->getName()
268 1
                        && $listedWorkflow->getGroup() === $workflow->getGroup();
269 1
                })->first();
270 1
                $this->getCurrentClass()->delete($workflowToDelete);
271
272 1
                return $this->getCurrentClass()->create($workflow);
273
            }
274 1
            throw $e;
275
        }
276
277 2
        return $workflow;
278
    }
279
280
    /**
281
     * {@inheritdoc}
282
     */
283
    public function update(Workflow $workflow): Workflow
284
    {
285
        $workflow = $this->_dispatch(new Command\UpdateCommand($workflow));
286
        return $workflow;
287
    }
288
289
    /**
290
     * {@inheritdoc}
291
     */
292
    public function createSchedule(Workflow $workflow, TimeSchedule $schedule, $onFailure = CreateScheduleCommand::FAILURE_TYPE_CONTINUE, $active = true, $comment = null)
293
    {
294
        $workflowSchedule = $this->_dispatch(
295
            new Command\CreateScheduleCommand($workflow, $schedule, $onFailure, $active, $comment)
296
        );
297
        return $workflowSchedule;
298
    }
299
300
    /**
301
     * {@inheritdoc}
302
     */
303 1
    public function createTask(string $name, string $group, string $path, $queue = 'default', $useAgent = false, $user = null, $host = null, $comment = null): Workflow
304
    {
305 1
        $task = new Task($path, $queue, $useAgent, $user, $host);
306 1
        $job = new Job(new ArrayCollection([$task]));
307 1
        $workflow = new Workflow($name, $group, new ArrayCollection([$job]), $comment);
308
309 1
        return $this->getCurrentClass()->create($workflow, true);
310
    }
311
312
    /**
313
     * {@inheritDoc}
314
     */
315 1
    public function createTube(Tube $tube): Tube
316
    {
317 1
        return $this->_dispatch(new Command\CreateTubeCommand($tube));
318
    }
319
320
    /**
321
     * {@inheritdoc}
322
     */
323
    public function updateTube(Tube $tube): Tube
324
    {
325
        return $this->_dispatch(new Command\UpdateTubeCommand($tube));
326
    }
327
328
    /**
329
     * {@inheritdoc}
330
     */
331
    public function cancel(WorkflowInstance $workflowInstance)
332
    {
333
        return $this->_dispatch(new Command\CancelCommand($workflowInstance));
334
    }
335
336
    /**
337
     * {@inheritdoc}
338
     */
339
    public function kill(WorkflowInstance $workflowInstance, TaskInstance $taskInstance)
340
    {
341
        return $this->_dispatch(new Command\KillCommand($workflowInstance, $taskInstance));
342
    }
343
}
344