Completed
Push — master ( 820d65...c97c2d )
by Valentin
03:28
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
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