Completed
Push — master ( 8ee32e...efc44e )
by Pablo
02:33
created

ConfigurationProcessorHandler::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 15
rs 9.4285
ccs 8
cts 8
cp 1
cc 1
eloc 13
nc 1
nop 6
crap 1
1
<?php
2
3
namespace PhpGitHooks\Module\Configuration\Contract\Command;
4
5
use Bruli\EventBusBundle\CommandBus\CommandHandlerInterface;
6
use Bruli\EventBusBundle\CommandBus\CommandInterface;
7
use Composer\IO\IOInterface;
8
use PhpGitHooks\Module\Configuration\Domain\CommitMsg;
9
use PhpGitHooks\Module\Configuration\Domain\Config;
10
use PhpGitHooks\Module\Configuration\Domain\PreCommit;
11
use PhpGitHooks\Module\Configuration\Domain\PrePush;
12
use PhpGitHooks\Module\Configuration\Infrastructure\Hook\HookCopier;
13
use PhpGitHooks\Module\Configuration\Model\ConfigurationFileReaderInterface;
14
use PhpGitHooks\Module\Configuration\Model\ConfigurationFileWriterInterface;
15
use PhpGitHooks\Module\Configuration\Service\CommitMsgProcessor;
16
use PhpGitHooks\Module\Configuration\Service\ConfigurationArrayTransformer;
17
use PhpGitHooks\Module\Configuration\Service\PreCommitProcessor;
18
use PhpGitHooks\Module\Configuration\Service\PrePushProcessor;
19
20
class ConfigurationProcessorHandler implements CommandHandlerInterface
21
{
22
    /**
23
     * @var IOInterface
24
     */
25
    private $io;
26
    /**
27
     * @var PreCommitProcessor
28
     */
29
    private $preCommitProcessor;
30
    /**
31
     * @var CommitMsgProcessor
32
     */
33
    private $commitMsgProcessor;
34
    /**
35
     * @var ConfigurationFileWriterInterface
36
     */
37
    private $configurationFileWriter;
38
    /**
39
     * @var HookCopier
40
     */
41
    private $hookCopier;
42
    /**
43
     * @var ConfigurationFileReaderInterface
44
     */
45
    private $configurationFileReader;
46
    /**
47
     * @var PrePushProcessor
48
     */
49
    private $prePushProcessor;
50
51
    /**
52
     * ConfigurationProcessor constructor.
53
     *
54
     * @param ConfigurationFileReaderInterface $configurationFileReader
55
     * @param PreCommitProcessor               $preCommitProcessor
56
     * @param CommitMsgProcessor               $commitMsgProcessor
57
     * @param ConfigurationFileWriterInterface $configurationFileWriter
58
     * @param HookCopier                       $hookCopier
59
     * @param PrePushProcessor                 $prePushProcessor
60
     */
61 2
    public function __construct(
62
        ConfigurationFileReaderInterface $configurationFileReader,
63
        PreCommitProcessor $preCommitProcessor,
64
        CommitMsgProcessor $commitMsgProcessor,
65
        ConfigurationFileWriterInterface $configurationFileWriter,
66
        HookCopier $hookCopier,
67
        PrePushProcessor $prePushProcessor
68
    ) {
69 2
        $this->preCommitProcessor = $preCommitProcessor;
70 2
        $this->commitMsgProcessor = $commitMsgProcessor;
71 2
        $this->configurationFileWriter = $configurationFileWriter;
72 2
        $this->hookCopier = $hookCopier;
73 2
        $this->configurationFileReader = $configurationFileReader;
74 2
        $this->prePushProcessor = $prePushProcessor;
75 2
    }
76
77
    /**
78
     * @param IOInterface $input
79
     */
80 2
    private function process(IOInterface $input)
81
    {
82 2
        $this->io = $input;
83
84 2
        $configData = $this->configurationFileReader->getData();
85 2
        $preCommit = $this->preCommitProcess($configData);
86
87 2
        if (true === $preCommit->isEnabled()) {
88 2
            $this->hookCopier->copyPreCommitHook();
89
        }
90
91 2
        $commitMsg = $this->commitMsgProcess($configData);
92
93 2
        if (true === $commitMsg->isEnabled()) {
94 2
            $this->hookCopier->copyCommitMsgHook();
95
        }
96
97 2
        $prePush = $this->prePushProcess($configData);
98
99 2
        if (true === $prePush->isEnabled()) {
100 2
            $this->hookCopier->copyPrePushHook();
101
        }
102
103 2
        $configArray = ConfigurationArrayTransformer::transform($preCommit, $commitMsg, $prePush);
104
105 2
        $this->configurationFileWriter->write($configArray);
106 2
    }
107
108
    /**
109
     * @param Config $configData
110
     *
111
     * @return PreCommit
112
     */
113 2
    private function preCommitProcess(Config $configData)
114
    {
115
        /**  @var PreCommit $preCommitData */
116 2
        $preCommitData = $configData->getPreCommit();
117
118 2
        return $this->preCommitProcessor->process($preCommitData, $this->io);
119
    }
120
121
    /**
122
     * @param Config $configData
123
     *
124
     * @return CommitMsg
125
     */
126 2
    private function commitMsgProcess(Config $configData)
127
    {
128
        /** @var CommitMsg $commitMsgData */
129 2
        $commitMsgData = $configData->getCommitMsg();
130
131 2
        return $this->commitMsgProcessor->process($commitMsgData, $this->io);
132
    }
133
134
    /**
135
     * @param Config $configData
136
     *
137
     * @return PrePush
138
     */
139 2
    private function prePushProcess(Config $configData)
140
    {
141
        /** @var PrePush $prePush */
142 2
        $prePush = $configData->getPrePush();
143
144 2
        return $this->prePushProcessor->process($prePush, $this->io);
145
    }
146
147
    /**
148
     * @param CommandInterface|ConfigurationProcessor $command
149
     */
150 2
    public function handle(CommandInterface $command)
151
    {
152 2
        $this->process($command->getInput());
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Bruli\EventBusBundle\CommandBus\CommandInterface as the method getInput() does only exist in the following implementations of said interface: PhpGitHooks\Module\Confi...\ConfigurationProcessor, PhpGitHooks\Module\Git\C...ommand\CommitMsgCommand.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
153 2
    }
154
}
155