Worker::doJob()   B
last analyzed

Complexity

Conditions 4
Paths 10

Size

Total Lines 38
Code Lines 22

Duplication

Lines 12
Ratio 31.58 %

Code Coverage

Tests 13
CRAP Score 4.8849

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 12
loc 38
ccs 13
cts 21
cp 0.619
rs 8.5806
cc 4
eloc 22
nc 10
nop 1
crap 4.8849
1
<?php
2
3
namespace Messenger\Sms\Alpha;
4
5
use Cronario\AbstractJob;
6
use Cronario\AbstractWorker;
7
use Messenger\Sms\Job;
8
use Messenger\Sms\ResultException;
9
use Messenger\Sms\Worker as SmsWorker;
10
11
/**
12
 * Class Worker
13
 *
14
 * @package Messenger\Sms\Alpha
15
 */
16
class Worker extends AbstractWorker
17
{
18
19
    protected static $config
20
        = [
21
            AbstractWorker::CONFIG_P_MANAGERS_LIMIT    => 3,
22
            AbstractWorker::CONFIG_P_MANAGER_POOL_SIZE => 5,
23
            SmsWorker::GATEWAY_DISPATCH_CLASS          => '\\Messenger\\Sms\\Worker',
24
            self::CONFIG_P_CLIENT                      => [
25
                'login'    => 'xxx',
26
                'password' => 'xxx',
27
                'server'   => 'xxx',
28
                'version'  => 'xxx',
29
            ],
30
        ];
31
32
    // region CLIENT ********************************************************
33
34
    const CONFIG_P_CLIENT = 'client';
35
36
    /**
37
     * @var \AlphaSMS\Client
38
     */
39
    protected $transport;
40
41
    /**
42
     * @return \AlphaSMS\Client
43
     */
44 2 View Code Duplication
    protected function getTransport()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
45
    {
46 2
        if (null === $this->transport) {
47 2
            $clientConfig = self::getConfig(self::CONFIG_P_CLIENT);
48 2
            $this->transport = new \AlphaSMS\Client($clientConfig['login'], $clientConfig['password']);
49 2
        }
50
51 2
        return $this->transport;
52
    }
53
54
    // endregion *************************************************************
55
56
    // region VALIDATE ********************************************************
57
58 4 View Code Duplication
    protected function validateJobParams(Job $job)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
59
    {
60 4
        if (empty($job->getSender())) {
61 1
            throw new ResultException(ResultException::ERROR_PARAM_SENDER);
62
        }
63
64 4
        if (empty($job->getRecipient())) {
65 1
            throw new ResultException(ResultException::ERROR_PARAM_RECIPIENT);
66
        }
67
68 4
        if (empty($job->getText())) {
69 1
            throw new ResultException(ResultException::ERROR_PARAM_TEXT);
70
        }
71 3
    }
72
73
    // endregion *************************************************************
74
75
    /**
76
     * @param AbstractJob|Job $job
77
     *
78
     * @throws ResultException
79
     */
80 4
    protected function doJob(AbstractJob $job)
81
    {
82 4
        $this->validateJobParams($job);
0 ignored issues
show
Compatibility introduced by
$job of type object<Cronario\AbstractJob> is not a sub-type of object<Messenger\Sms\Job>. It seems like you assume a child class of the class Cronario\AbstractJob to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
83
84 3
        $resultData = SmsWorker::buildResultDataDefault(__NAMESPACE__);
85
86
        try {
87 3
            $transport = $this->getTransport();
88 3
            $transport->sendSMS($job->getSender(), $job->getRecipient(), $job->getText());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Cronario\AbstractJob as the method getSender() does only exist in the following sub-classes of Cronario\AbstractJob: Messenger\Sms\Job. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Cronario\AbstractJob as the method getRecipient() does only exist in the following sub-classes of Cronario\AbstractJob: Messenger\Sms\Job. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Cronario\AbstractJob as the method getText() does only exist in the following sub-classes of Cronario\AbstractJob: Messenger\Sms\Job. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
89
90 3
            $response = $transport->getResponse();
91 3
            $resultData[SmsWorker::P_RESULT_DATA_SUCCESS] = (count($response['errors']) == 0);
92 3
            $resultData[SmsWorker::P_RESULT_DATA_VENDOR_ID] = $response['id'];
93 3
            $resultData[SmsWorker::P_RESULT_DATA_ERRORS] = $response['errors'];
94
95 3
            $job->addDebug(['vendor_response' => $response]);
96
97 3
        } catch (\Exception $ex) {
98
            $job->addDebug(['exception' => $ex->getMessage()]);
99
            throw new ResultException(ResultException::ERROR_TRANSPORT);
100
        }
101
102
103 3 View Code Duplication
        if (false === $resultData[SmsWorker::P_RESULT_DATA_SUCCESS]) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104
105
            if (!$job->isSync()) {
106
                // redirect result for new root gateway class
107
                $gatewayClass = static::getConfig(SmsWorker::GATEWAY_DISPATCH_CLASS);
108
                $job->addDebug(['set_gateway' => $gatewayClass]);
109
                $job->setWorkerClass($gatewayClass)->save();
110
                throw new ResultException(ResultException::RETRY_GATEWAY_DISPATCH_CLASS);
111
            }
112
113
            throw new ResultException(ResultException::R_FAILURE, $resultData);
114
        }
115
116 3
        throw new ResultException(ResultException::R_SUCCESS, $resultData);
117
    }
118
119
}
120
121
122
123
124
125
126