Completed
Push — master ( 820d65...c97c2d )
by Valentin
03:28
created

Pheanstalk::workflowExists()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 7
ccs 4
cts 5
cp 0.8
rs 10
cc 2
nc 2
nop 1
crap 2.032
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;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Pheanstalk\Job. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
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
    private $_connection;
41
42
    /** @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...
43
    private $currentClass;
44
45
    /**
46
     * @param string $host
47
     * @param string $user
48
     * @param string $password
49
     * @param int    $port
50
     * @param int    $connectTimeout
51
     * @param bool   $connectPersistent
52
     */
53 5
    public function __construct($host, $user = null, $password = null, $port = PheanstalkInterface::DEFAULT_PORT, $connectTimeout = null, $connectPersistent = false)
54
    {
55 5
        $this->setConnection(new Connection($host, $user, $password, $port, $connectTimeout, $connectPersistent));
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61 5
    public function setConnection(Connection $connection)
62
    {
63 5
        $this->_connection = $connection;
64
65 5
        return $this;
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71 2
    public function getConnection()
72
    {
73 2
        return $this->_connection;
74
    }
75
76
    /**
77
     * @return PheanstalkInterface
78
     */
79 3
    public function getCurrentClass(): PheanstalkInterface
80
    {
81 3
        return $this->currentClass ?? $this;
82
    }
83
84
    /**
85
     * @param PheanstalkInterface $currentClass
86
     *
87
     * @return Pheanstalk
88
     */
89
    public function setCurrentClass(PheanstalkInterface $currentClass): PheanstalkInterface
90
    {
91
        $this->currentClass = $currentClass;
92
        return $this;
93
    }
94
95
    // ----------------------------------------
96
97
    /**
98
     * {@inheritdoc}
99
     */
100 2
    public function delete(Workflow $workflow)
101
    {
102 2
        return $this->_dispatch(new Command\DeleteCommand($workflow));
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_dispatch(...leteCommand($workflow)) returns the type Pheanstalk\Response which is incompatible with the return type mandated by Pheanstalk\PheanstalkInterface::delete() of boolean.

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...
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108 2
    public function workflowExists($name)
109
    {
110 2
        $workflow = $this->_dispatch(new Command\WorkflowExistsCommand($name));
111 1
        if ($workflow instanceof Workflow) {
112 1
            return $this->getCurrentClass()->getWorkflow($workflow);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getCurrent...>getWorkflow($workflow) returns the type Pheanstalk\Response which is incompatible with the return type mandated by Pheanstalk\PheanstalkInterface::workflowExists() of Pheanstalk\Structure\Workflow|boolean.

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...
113
        }
114
        return false;
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120 1
    public function getWorkflow(Workflow $workflow)
121
    {
122 1
        return $this->_dispatch(new Command\GetWorkflowCommand($workflow));
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_dispatch(...flowCommand($workflow)) returns the type Pheanstalk\Response which is incompatible with the return type mandated by Pheanstalk\PheanstalkInterface::getWorkflow() of Pheanstalk\Structure\Workflow|boolean.

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...
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     */
128
    public function getWorkflowInstances(?Workflow $workflow, string $status = null)
129
    {
130
        $status = empty($status) ? GetWorkflowInstancesDetailCommand::FILTERS : [$status];
131
        $instances = new ArrayCollection([]);
132
        foreach ($status as $stat) {
133
            $instances[strtolower($stat)] = $this->_dispatch(new Command\GetWorkflowInstancesCommand($workflow, $stat));
134
//            if ($stat === GetWorkflowInstancesCommand::FILTER_EXECUTING) {
135
                /** @var ArrayCollection $workflowCollection */
136
                $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

136
                /** @scrutinizer ignore-call */ 
137
                $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...
137
            if (!empty($workflowCollection)) {
138
                foreach ($workflowCollection as $instance) {
139
                    $this->getCurrentClass()->getWorkflowInstancesDetails($instance);
140
                }
141
            }
142
//            }
143
        }
144
145
        return $instances;
146
    }
147
148
    /**
149
     * {@inheritdoc}
150
     */
151
    public function getWorkflowInstancesDetails(WorkflowInstance $workflowInstance)
152
    {
153
        return $this->_dispatch(new Command\GetWorkflowInstancesDetailCommand($workflowInstance));
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_dispatch(...and($workflowInstance)) returns the type Pheanstalk\Response which is incompatible with the return type mandated by Pheanstalk\PheanstalkInt...kflowInstancesDetails() of Pheanstalk\Structure\WorkflowInstance|false.

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...
154
    }
155
156
    /**
157
     * {@inheritdoc}
158
     */
159 2
    public function tubeExists($name)
160
    {
161 2
        return $this->_dispatch(new Command\TubeExistsCommand($name));
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_dispatch(...beExistsCommand($name)) returns the type Pheanstalk\Response which is incompatible with the return type mandated by Pheanstalk\PheanstalkInterface::tubeExists() of Pheanstalk\Structure\Tube|boolean.

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...
162
    }
163
164
    /**
165
     * {@inheritdoc}
166
     */
167
    public function listTubes()
168
    {
169
        return $this->_dispatch(new Command\ListTubesCommand());
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     */
175
    public function peek()
176
    {
177
        $response = $this->_dispatch(new Command\PeekCommand());
178
179
        return $response;
180
    }
181
182
    /**
183
     * {@inheritdoc}
184
     */
185
    public function put(Workflow $workflow)
186
    {
187
        $response = $this->_dispatch(new Command\PutCommand($workflow));
188
189
        return $response['workflow-instance-id'];
190
    }
191
192
    /**
193
     * {@inheritdoc}
194
     */
195
    public function statsJob($job)
196
    {
197
        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...
198
    }
199
200
    /**
201
     * {@inheritdoc}
202
     */
203
    public function statsTube($tube)
204
    {
205
        return $this->_dispatch(new Command\StatsTubeCommand($tube));
206
    }
207
208
    /**
209
     * {@inheritdoc}
210
     */
211
    public function stats()
212
    {
213
        return $this->_dispatch(new Command\StatsCommand());
214
    }
215
216
    // ----------------------------------------
217
218
    /**
219
     * Dispatches the specified command to the connection object.
220
     *
221
     * If a SocketException occurs, the connection is reset, and the command is
222
     * re-attempted once.
223
     *
224
     * @param Command $command
225
     *
226
     * @return Response
227
     */
228 3
    private function _dispatch($command)
229
    {
230 3
        return $this->_connection->dispatchCommand($command);
231
    }
232
233
    /**
234
     * {@inheritdoc}
235
     */
236 2
    public function create(Workflow $workflow, $force = false): Workflow
237
    {
238
        try {
239 2
            $tubes = [];
240
            /** @var Job $job */
241 2
            foreach ($workflow->getJobs() as $job) {
242
                /** @var Task $task */
243 2
                foreach ($job->getTasks() as $task) {
244 2
                    $tubes = array_merge($tubes, [$task->getQueue()]);
245
                }
246
            }
247 2
            foreach ($tubes as $tube) {
248 2
                if (!$this->getCurrentClass()->tubeExists($tube)) {
249
                    $this->getCurrentClass()->createTube(new Tube($tube, 1));
250
                };
251
            }
252 2
            $workflow = $this->_dispatch(new Command\CreateCommand($workflow));
253
        } catch (ServerDuplicateEntryException $e) {
254
            if ($force) {
255
                $workflows = $this->_dispatch(new Command\ListWorkflowsCommand());
256
                $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...
Bug introduced by
The method filter() does not exist on Pheanstalk\Response. ( Ignorable by Annotation )

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

256
                $workflowToDelete = $workflows->/** @scrutinizer ignore-call */ filter(function(Workflow $listedWorkflow) use ($workflow) {

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...
257
                    return $listedWorkflow->getName() === $workflow->getName()
0 ignored issues
show
Bug introduced by
The method getName() does not exist on Pheanstalk\Response. ( Ignorable by Annotation )

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

257
                    return $listedWorkflow->getName() === $workflow->/** @scrutinizer ignore-call */ getName()

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...
258
                        && $listedWorkflow->getGroup() === $workflow->getGroup();
0 ignored issues
show
Bug introduced by
The method getGroup() does not exist on Pheanstalk\Response. ( Ignorable by Annotation )

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

258
                        && $listedWorkflow->getGroup() === $workflow->/** @scrutinizer ignore-call */ getGroup();

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...
259
                })->first();
260
                $this->getCurrentClass()->delete($workflowToDelete);
261
262
                return $this->getCurrentClass()->create($workflow);
263
            }
264
            throw $e;
265
        }
266
267 2
        return $workflow;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $workflow returns the type Pheanstalk\Response which is incompatible with the type-hinted return Pheanstalk\Structure\Workflow.
Loading history...
268
    }
269
270
    /**
271
     * {@inheritdoc}
272
     */
273
    public function update(Workflow $workflow): Workflow
274
    {
275
        $workflow = $this->_dispatch(new Command\UpdateCommand($workflow));
276
        return $workflow;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $workflow returns the type Pheanstalk\Response which is incompatible with the type-hinted return Pheanstalk\Structure\Workflow.
Loading history...
277
    }
278
279
    /**
280
     * {@inheritdoc}
281
     */
282
    public function createSchedule(Workflow $workflow, TimeSchedule $schedule, $onFailure = CreateScheduleCommand::FAILURE_TYPE_CONTINUE, $active = true, $comment = null)
283
    {
284
        $workflowSchedule = $this->_dispatch(
285
            new Command\CreateScheduleCommand($workflow, $schedule, $onFailure, $active, $comment)
286
        );
287
        return $workflowSchedule;
288
    }
289
290
    /**
291
     * {@inheritdoc}
292
     */
293 1
    public function createTask(string $name, string $group, string $path, $queue = 'default', $useAgent = false, $user = null, $host = null, $comment = null): Workflow
294
    {
295 1
        $task = new Task($path, $queue, $useAgent, $user, $host);
296 1
        $job = new Job(new ArrayCollection([$task]));
297 1
        $workflow = new Workflow($name, $group, new ArrayCollection([$job]), $comment);
298
299 1
        return $this->getCurrentClass()->create($workflow, true);
300
    }
301
302
    /**
303
     * {@inheritDoc}
304
     */
305
    public function createTube(Tube $tube): Tube
306
    {
307
        return $this->_dispatch(new Command\CreateTubeCommand($tube));
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_dispatch(...eateTubeCommand($tube)) returns the type Pheanstalk\Response which is incompatible with the type-hinted return Pheanstalk\Structure\Tube.
Loading history...
308
    }
309
310
    /**
311
     * {@inheritdoc}
312
     */
313
    public function updateTube(Tube $tube): Tube
314
    {
315
        return $this->_dispatch(new Command\UpdateTubeCommand($tube));
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_dispatch(...dateTubeCommand($tube)) returns the type Pheanstalk\Response which is incompatible with the type-hinted return Pheanstalk\Structure\Tube.
Loading history...
316
    }
317
318
    /**
319
     * {@inheritdoc}
320
     */
321
    public function cancel(WorkflowInstance $workflowInstance)
322
    {
323
        return $this->_dispatch(new Command\CancelCommand($workflowInstance));
324
    }
325
326
    /**
327
     * {@inheritdoc}
328
     */
329
    public function kill(WorkflowInstance $workflowInstance, TaskInstance $taskInstance)
330
    {
331
        return $this->_dispatch(new Command\KillCommand($workflowInstance, $taskInstance));
332
    }
333
}
334