Completed
Push — master ( e54759...0c780c )
by Valentin
03:37
created

Pheanstalk::createTask()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 10
cc 1
nc 1
nop 8
crap 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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
    const VERSION = '3.2.1';
40
41
    private $_connection;
42
    private $_using = PheanstalkInterface::DEFAULT_TUBE;
0 ignored issues
show
introduced by
The private property $_using is not used, and could be removed.
Loading history...
43
    private $_watching = array(PheanstalkInterface::DEFAULT_TUBE => true);
0 ignored issues
show
introduced by
The private property $_watching is not used, and could be removed.
Loading history...
Coding Style introduced by
Short array syntax must be used to define arrays
Loading history...
44
45
    /** @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...
46
    private $currentClass;
47
48
    /**
49
     * @param string $host
50
     * @param string $user
51
     * @param string $password
52
     * @param int    $port
53
     * @param int    $connectTimeout
54
     * @param bool   $connectPersistent
55
     */
56 3
    public function __construct($host, $user = null, $password = null, $port = PheanstalkInterface::DEFAULT_PORT, $connectTimeout = null, $connectPersistent = false)
57
    {
58 3
        $this->setConnection(new Connection($host, $user, $password, $port, $connectTimeout, $connectPersistent));
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64 3
    public function setConnection(Connection $connection)
65
    {
66 3
        $this->_connection = $connection;
67
68 3
        return $this;
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74 2
    public function getConnection()
75
    {
76 2
        return $this->_connection;
77
    }
78
79
    /**
80
     * @return PheanstalkInterface
81
     */
82 1
    public function getCurrentClass(): PheanstalkInterface
83
    {
84 1
        return $this->currentClass ?? $this;
85
    }
86
87
    /**
88
     * @param PheanstalkInterface $currentClass
89
     *
90
     * @return Pheanstalk
91
     */
92
    public function setCurrentClass(PheanstalkInterface $currentClass): PheanstalkInterface
93
    {
94
        $this->currentClass = $currentClass;
95
        return $this;
96
    }
97
98
    // ----------------------------------------
99
100
    /**
101
     * {@inheritdoc}
102
     */
103 1
    public function delete(Workflow $workflow)
104
    {
105 1
        $this->_dispatch(new Command\DeleteCommand($workflow));
106
107 1
        return $this;
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113 1
    public function workflowExists($name)
114
    {
115 1
        $workflow = $this->_dispatch(new Command\WorkflowExistsCommand($name));
116
        if ($workflow instanceof Workflow)
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
117
            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...
118
        return false;
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124
    public function getWorkflow(Workflow $workflow)
125
    {
126
        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...
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132
    public function getWorkflowInstances(?Workflow $workflow, string $status = null)
133
    {
134
        $status = empty($status) ? GetWorkflowInstancesDetailCommand::FILTERS : [$status];
135
        $instances = new ArrayCollection([]);
136
        foreach($status as $stat) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after FOREACH keyword; 0 found
Loading history...
137
            $instances[strtolower($stat)] = $this->_dispatch(new Command\GetWorkflowInstancesCommand($workflow, $stat));
138
//            if ($stat === GetWorkflowInstancesCommand::FILTER_EXECUTING) {
139
                /** @var ArrayCollection $workflowCollection */
140
                $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

140
                /** @scrutinizer ignore-call */ 
141
                $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...
141
                if (!empty($workflowCollection)) {
142
                    foreach($workflowCollection as $instance) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after FOREACH keyword; 0 found
Loading history...
143
                        $this->getCurrentClass()->getWorkflowInstancesDetails($instance);
144
                    }
145
                }
146
//            }
147
        }
148
149
        return $instances;
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155
    public function getWorkflowInstancesDetails(WorkflowInstance $workflowInstance)
156
    {
157
        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...
158
    }
159
160
    /**
161
     * {@inheritdoc}
162
     */
163 1
    public function tubeExists($name)
164
    {
165 1
        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...
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171
    public function listTubes()
172
    {
173
        return $this->_dispatch(new Command\ListTubesCommand());
174
    }
175
176
    /**
177
     * {@inheritdoc}
178
     */
179
    public function peek()
180
    {
181
        $response = $this->_dispatch(new Command\PeekCommand());
182
183
        return $response;
184
    }
185
186
    /**
187
     * {@inheritdoc}
188
     */
189
    public function put(Workflow $workflow) {
190
        $response = $this->_dispatch(new Command\PutCommand($workflow));
191
192
        return $response['workflow-instance-id'];
193
    }
194
195
    /**
196
     * {@inheritdoc}
197
     */
198
    public function statsJob($job)
199
    {
200
        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...
201
    }
202
203
    /**
204
     * {@inheritdoc}
205
     */
206
    public function statsTube($tube)
207
    {
208
        return $this->_dispatch(new Command\StatsTubeCommand($tube));
209
    }
210
211
    /**
212
     * {@inheritdoc}
213
     */
214
    public function stats()
215
    {
216
        return $this->_dispatch(new Command\StatsCommand());
217
    }
218
219
    // ----------------------------------------
220
221
    /**
222
     * Dispatches the specified command to the connection object.
223
     *
224
     * If a SocketException occurs, the connection is reset, and the command is
225
     * re-attempted once.
226
     *
227
     * @param Command $command
228
     *
229
     * @return Response
230
     */
231 1
    private function _dispatch($command)
232
    {
233 1
        return $this->_connection->dispatchCommand($command);
234
    }
235
236
    /**
237
     * {@inheritdoc}
238
     */
239 1
    public function create(Workflow $workflow, $force = false): Workflow
240
    {
241
        try{
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after TRY keyword; 0 found
Loading history...
242 1
            $tubes = [];
243
            /** @var Job $job */
244 1
            foreach($workflow->getJobs() as $job) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after FOREACH keyword; 0 found
Loading history...
245
                /** @var Task $task */
246 1
                foreach ($job->getTasks() as $task) {
247 1
                    $tubes = array_merge($tubes, [$task->getQueue()]);
248
                }
249
            }
250 1
            foreach($tubes as $tube) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after FOREACH keyword; 0 found
Loading history...
251 1
                if (!$this->getCurrentClass()->tubeExists($tube)) {
252
                    $this->getCurrentClass()->createTube(new Tube($tube, 1));
253
                };
254
            }
255 1
            $workflow = $this->_dispatch(new Command\CreateCommand($workflow));
256
        } catch(ServerDuplicateEntryException $e) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after CATCH keyword; 0 found
Loading history...
257
            if ($force) {
258
                $workflows = $this->_dispatch(new Command\ListWorkflowsCommand());
259
                $workflowToDelete = $workflows->filter(function(Workflow $listedWorkflow) use ($workflow) {
1 ignored issue
show
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

259
                $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...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
260
                    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

260
                    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...
261
                        && $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

261
                        && $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...
262
                })->first();
263
                $this->getCurrentClass()->delete($workflowToDelete);
264
265
                return $this->getCurrentClass()->create($workflow);
0 ignored issues
show
Bug introduced by
It seems like $workflow can also be of type Pheanstalk\Response; however, parameter $workflow of Pheanstalk\Pheanstalk::create() does only seem to accept Pheanstalk\Structure\Workflow, maybe add an additional type check? ( Ignorable by Annotation )

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

265
                return $this->getCurrentClass()->create(/** @scrutinizer ignore-type */ $workflow);
Loading history...
266
            }
267
            throw $e;
268
        }
269
270 1
        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...
271
    }
272
273
    /**
274
     * {@inheritdoc}
275
     */
276
    public function update(Workflow $workflow): Workflow
277
    {
278
        $workflow = $this->_dispatch(new Command\UpdateCommand($workflow));
279
        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...
280
    }
281
282
    /**
283
     * {@inheritdoc}
284
     */
285
    public function createSchedule(Workflow $workflow, TimeSchedule $schedule, $onFailure = CreateScheduleCommand::FAILURE_TYPE_CONTINUE, $active = true, $comment = null)
286
    {
287
        $workflowSchedule = $this->_dispatch(
288
            new Command\CreateScheduleCommand($workflow, $schedule, $onFailure, $active, $comment)
289
        );
290
        return $workflowSchedule;
291
    }
292
293
    /**
294
     * {@inheritdoc}
295
     */
296 1
    public function createTask(string $name, string $group, string $path, $queue = 'default', $useAgent = false, $user = null, $host = null, $comment = null): Workflow
297
    {
298 1
        $task = new Task($path, $queue, $useAgent, $user, $host);
299 1
        $job = new Job(new ArrayCollection([$task]));
300 1
        $workflow = new Workflow($name, $group, new ArrayCollection([$job]), $comment);
301
302 1
        return $this->getCurrentClass()->create($workflow, true);
303
    }
304
305
    /**
306
     * {@inheritDoc}
307
     */
308
    public function createTube(Tube $tube): Tube
309
    {
310
        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...
311
    }
312
313
    /**
314
     * {@inheritdoc}
315
     */
316
    public function updateTube(Tube $tube): Tube
317
    {
318
        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...
319
    }
320
321
    /**
322
     * {@inheritdoc}
323
     */
324
    public function cancel(WorkflowInstance $workflowInstance)
325
    {
326
        return $this->_dispatch(new Command\CancelCommand($workflowInstance));
327
    }
328
329
    /**
330
     * {@inheritdoc}
331
     */
332
    public function kill(WorkflowInstance $workflowInstance, TaskInstance $taskInstance)
333
    {
334
        return $this->_dispatch(new Command\KillCommand($workflowInstance, $taskInstance));
335
    }
336
}
337