Completed
Pull Request — master (#139)
by Mathias
10:02
created

Pickle::getType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/**
4
 * Pickle
5
 *
6
 *
7
 * @license
8
 *
9
 * New BSD License
10
 *
11
 * Copyright © 2015-2015, Pickle community. All rights reserved.
12
 *
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15
 *     * Redistributions of source code must retain the above copyright
16
 *       notice, this list of conditions and the following disclaimer.
17
 *     * Redistributions in binary form must reproduce the above copyright
18
 *       notice, this list of conditions and the following disclaimer in the
19
 *       documentation and/or other materials provided with the distribution.
20
 *     * Neither the name of the Hoa nor the names of its contributors may be
21
 *       used to endorse or promote products derived from this software without
22
 *       specific prior written permission.
23
 *
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
 * POSSIBILITY OF SUCH DAMAGE.
35
 */
36
37
namespace Pickle\Package\Convey\Command;
38
39
use Pickle\Config;
40
use Pickle\Base\Abstracts;
41
use Pickle\Base\Interfaces;
42
use Pickle\Package;
43
use Composer\Downloader\GitDownloader;
44
use Composer\Package\Version\VersionParser;
45
use Composer\Package\LinkConstraint\VersionConstraint;
46
47
class Pickle extends Abstracts\Package\Convey\Command implements Interfaces\Package\Convey\Command
48
{
49
    /**
50
     * @var string
51
     */
52
    protected $type;
53
54
    protected function fetchPackageJson()
55
    {
56
        $extensionJson = @file_get_contents('http://localhost:8080/json/'.$this->name.'.json');
57
        if (!$extensionJson) {
58
            $status = isset($http_response_header[0]) ? $http_response_header[0] : "";
59
            if (strpos($status, '404') !== false) {
60
                throw new \Exception("cannot find $this->name");
61
            } else {
62
                if ($status) {
63
                    throw new \Exception("http error while loading informatio for $this->name: ".$status);
64
                } else {
65
                    throw new \Exception("http error while loading informatio for $this->name: unknown error");
66
                }
67
            }
68
        }
69
70
        return json_decode($extensionJson, true);
71
    }
72
73
    protected function prepare()
74
    {
75
        if (Type::determinePickle($this->path, $matches) < 1) {
76
            throw new \Exception('Not a pickle git URI');
77
        }
78
79
        $this->name = $matches['package'];
80
81
        $extension = $this->fetchPackageJson();
82
83
        $versionParser = new VersionParser();
84
        if ($matches['version'] == '') {
85
            $versions = array_keys($extension['packages'][$this->name]);
86
            if (count($versions) > 1) {
87
                $versionToUse = $versions[1];
88
            } else {
89
                $versionToUse = $versions[0];
90
            }
91
        } else {
92
            $versionConstraints = $versionParser->parseConstraints($matches['version']);
93
94
            /* versions are sorted decreasing */
95
            foreach ($extension['packages'][$this->name] as $version => $release) {
96
                $constraint = new VersionConstraint('=', $versionParser->normalize($version));
0 ignored issues
show
Deprecated Code introduced by
The class Composer\Package\LinkConstraint\VersionConstraint has been deprecated with message: use Composer\Semver\Constraint\Constraint instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
97
                if ($versionConstraints->matches($constraint)) {
98
                    $versionToUse = $version;
99
                    break;
100
                }
101
            }
102
        }
103
104
        $package = $extension['packages'][$this->name][$versionToUse];
0 ignored issues
show
Bug introduced by
The variable $versionToUse does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
105
        $this->version = $versionToUse;
106
        $this->normalizedVersion = $versionParser->normalize($versionToUse);
0 ignored issues
show
Bug introduced by
The property normalizedVersion does not seem to exist. Did you mean version?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
107
108
        $this->name = $matches['package'];
109
        $this->prettyVersion = $this->version;
110
        $this->url = $package['source']['url'];
111
        $this->reference = $package['source']['reference'];
0 ignored issues
show
Bug introduced by
The property reference does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
112
        $this->type = $package['source']['type'];
113
    }
114
115
    protected function fetch($target)
116
    {
117
        $package = Package::factory($this->name, $this->version, $this->prettyVersion);
118
119
        $package->setSourceType($this->type);
120
        $package->setSourceUrl($this->url);
121
        $package->setSourceReference($this->version);
122
        $package->setRootDir($target);
123
124
        $downloader = new GitDownloader($this->io, new Config());
125
        if (null !== $downloader) {
126
            $downloader->download($package, $target);
0 ignored issues
show
Bug introduced by
It seems like $package defined by \Pickle\Package::factory..., $this->prettyVersion) on line 117 can also be of type null; however, Composer\Downloader\VcsDownloader::download() does only seem to accept object<Composer\Package\PackageInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
127
        }
128
    }
129
130
    public function execute($target, $no_convert)
131
    {
132
        $this->fetch($target);
133
134
        $exe = DefaultExecutor::factory($this);
135
136
        return $exe->execute($target, $no_convert);
137
    }
138
139
    public function getType()
140
    {
141
        return Type::GIT;
142
    }
143
}
144
145
/* vim: set tabstop=4 shiftwidth=4 expandtab: fdm=marker */
146