Passed
Push — master ( 574a9e...aeb17a )
by Luke
09:02
created

ValidateProjectStep::isValidPackageRepository()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
crap 2
1
<?php
2
3
/**
4
 * Moodle component manager.
5
 *
6
 * @author Luke Carrier <[email protected]>
7
 * @copyright 2016 Luke Carrier
8
 * @license GPL-3.0+
9
 */
10
11
namespace ComponentManager\Step;
12
13
use ComponentManager\ComponentSpecification;
14
use ComponentManager\Exception\InvalidProjectException;
15
use ComponentManager\Project\Project;
16
use Psr\Log\LoggerInterface;
17
18
/**
19
 * Validate the project file.
20
 */
21
class ValidateProjectStep implements Step {
22
    /**
23
     * Project to validate.
24
     *
25
     * @var \ComponentManager\Project\Project
26
     */
27
    protected $project;
28
29
    /**
30
     * Initialiser.
31
     *
32
     * @param \ComponentManager\Project\Project $project
33
     */
34
    public function __construct(Project $project) {
35
        $this->project = $project;
36
    }
37
38
    /**
39
     * @override \ComponentManager\Step\Step
40
     */
41
    public function execute($task, LoggerInterface $logger) {
42
        $componentSpecifications = $this->project->getProjectFile()->getComponentSpecifications();
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 98 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
43
        $packageRepositories = $this->project->getPackageRepositories();
44
45
        $result = true;
46
47
        if (!$this->project->getProjectFile()->getMoodleVersion()) {
48
            $result = false;
49
            $logger->warn('No moodle.version key; package operations will fail');
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Psr\Log\LoggerInterface as the method warn() does only exist in the following implementations of said interface: Monolog\Logger, Symfony\Bridge\Monolog\Logger.

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...
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 81 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
50
        }
51
52
        foreach ($componentSpecifications as $componentSpecification) {
53
            if (!$this->isValidComponentName($componentSpecification)) {
54
                $result = false;
55
                $logger->error('An invalid component name was specified', [
56
                    'componentName' => $componentSpecification->getName(),
57
                ]);
58
            }
59
60
            if (!$this->isComponentSpecificationComplete($componentSpecification)) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 84 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
61
                $result = false;
62
                $logger->error('An incomplete component specification was specified', [
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 87 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
63
                    'componentSpecification' => $componentSpecification,
64
                ]);
65
            }
66
67
            if (!$this->isValidPackageRepository($componentSpecification, $packageRepositories)) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 98 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
68
                $result = false;
69
                $logger->error('Component uses undeclared package repository', [
70
                    'componentName'         => $componentSpecification->getName(),
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 82 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
71
                    'packageRepositoryName' => $componentSpecification->getPackageRepository(),
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 95 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
72
                ]);
73
            }
74
75
            if (!$result) {
76
                throw new InvalidProjectException(
77
                        'The supplied project file is invalid',
78
                        InvalidProjectException::CODE_VALIDATION_FAILED);
79
            }
80
        }
81
    }
82
83
    /**
84
     * Does the supplied component have a valid name?
85
     *
86
     * @param \ComponentManager\ComponentSpecification $componentSpecification
87
     *
88
     * @return boolean
89
     */
90
    protected function isValidComponentName(ComponentSpecification $componentSpecification) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 93 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
91
        $parts = explode('_', $componentSpecification->getName(), 2);
92
        return count($parts) === 2;
93
    }
94
95
    /**
96
     * Is the supplied component's package repository known to us?
97
     *
98
     * @param \ComponentManager\ComponentSpecification                $componentSpecification
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 93 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
99
     * @param \ComponentManager\PackageRepository\PackageRepository[] $packageRepositories
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 90 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
100
     *
101
     * @return boolean
102
     */
103
    protected function isValidPackageRepository(ComponentSpecification $componentSpecification, $packageRepositories) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 119 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
104
        return array_key_exists(
105
                $componentSpecification->getPackageRepository(), $packageRepositories);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 87 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
106
    }
107
108
    /**
109
     * Is the supplied component's specification complete?
110
     *
111
     * @param \ComponentManager\ComponentSpecification $componentSpecification
112
     *
113
     * @return boolean
114
     */
115
    protected function isComponentSpecificationComplete(ComponentSpecification $componentSpecification) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 80 characters; contains 105 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
116
        return !!$componentSpecification->getPackageRepository()
117
                && !!$componentSpecification->getPackageSource();
118
    }
119
}
120