Completed
Push — feature/ss4-upgrade ( f41a3f )
by
unknown
10:12
created

AddonUpdater::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 9
nc 1
nop 4
1
<?php
2
3
namespace SilverStripe\Addons\Services;
4
5
use Composer\Package\AliasPackage;
6
use Composer\Package\CompletePackage;
7
use Composer\Semver\Constraint\Constraint;
8
use Guzzle\Http\Exception\ClientErrorResponseException;
9
use SilverStripe\Elastica\ElasticaService;
10
use Packagist\Api\Result\Package;
11
use Composer\Package\Version\VersionParser;
12
use SilverStripe\Addons\Model\Addon;
13
use SilverStripe\Addons\Model\AddonAuthor;
14
use SilverStripe\Addons\Model\AddonKeyword;
15
use SilverStripe\Addons\Model\AddonLink;
16
use SilverStripe\Addons\Model\AddonVendor;
17
use SilverStripe\Addons\Model\AddonVersion;
18
use SilverStripe\Addons\Model\SilverStripeVersion;
19
use SilverStripe\Core\Cache;
20
use SilverStripe\Control\Director;
21
22
/**
23
 * Updates all add-ons from Packagist.
24
 */
25
class AddonUpdater 
26
{
27
28
	/**
29
	 * @var PackagistService
30
	 */
31
	private $packagist;
32
33
	/**
34
	 * @var SilverStripe\Elastica\ElasticaService
35
	 */
36
	private $elastica;
37
38
	/**
39
	 * @var ResqueService
40
	 */
41
	private $resque;
42
43
	/**
44
	 * @var Composer\Package\Version\VersionParser
45
	 */
46
	private $versionParser;
47
48
	/**
49
	 * @var SilverStripeVersion[]
50
	 */
51
	private $silverstripes = [];
52
53
	public function __construct(
54
		PackagistService $packagist,
55
		ElasticaService $elastica,
56
		ResqueService $resque,
57
		VersionParser $versionParser
58
	) {
59
		$this->packagist = $packagist;
60
		$this->elastica = $elastica;
0 ignored issues
show
Documentation Bug introduced by
It seems like $elastica of type object<SilverStripe\Elastica\ElasticaService> is incompatible with the declared type object<SilverStripe\Addo...astica\ElasticaService> of property $elastica.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
61
		$this->resque = $resque;
62
		$this->versionParser = $versionParser;
0 ignored issues
show
Documentation Bug introduced by
It seems like $versionParser of type object<Composer\Package\Version\VersionParser> is incompatible with the declared type object<SilverStripe\Addo...\Version\VersionParser> of property $versionParser.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
63
	}
64
65
	/**
66
	 * Updates all add-ons.
67
	 *
68
	 * @param Boolean Clear existing addons before updating them.
69
	 * Will also clear their search index, and cascade the delete for associated data.
70
	 * @param Array Limit to specific addons, using their name incl. vendor prefix.
71
	 */
72
	public function update($clear = false, $limitAddons = null) {
73
		if($clear && !$limitAddons) {
74
			Addon::get()->removeAll();
75
			AddonAuthor::get()->removeAll();
76
			AddonKeyword::get()->removeAll();
77
			AddonLink::get()->removeAll();
78
			AddonVendor::get()->removeAll();
79
			AddonVersion::get()->removeAll();
80
		}
81
82
		foreach (SilverStripeVersion::get() as $version) {
83
			$this->silverstripes[$version->ID] = $version->getConstraint();
84
		}
85
86
		// This call to packagist can be expensive. Requests are served from a cache if usePackagistCache() returns true
87
		$cache = Cache::factory('addons');
88
		if($this->usePackagistCache() && $packages = $cache->load('packagist')) {
89
			$packages = unserialize($packages);
90
		} else {
91
			$packages = $this->packagist->getPackages();
92
			$cache->save(serialize($packages), 'packagist');
93
		}
94
		$this->elastica->startBulkIndex();
95
96
		foreach ($packages as $package) {
97
			$name = $package->getName();
98
			$versions = $package->getVersions();
99
100
			if($limitAddons && !in_array($name, $limitAddons)) continue;
101
102
			$addon = Addon::get()->filter('Name', $name)->first();
103
104
			if (!$addon) {
105
				$addon = new Addon();
106
				$addon->Name = $name;
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
107
				$addon->write();
108
			}
109
110
			usort($versions, function ($a, $b) {
111
				return version_compare($a->getVersionNormalized(), $b->getVersionNormalized());
112
			});
113
114
			$this->updateAddon($addon, $package, $versions);
0 ignored issues
show
Compatibility introduced by
$addon of type object<SilverStripe\ORM\DataObject> is not a sub-type of object<SilverStripe\Addons\Model\Addon>. It seems like you assume a child class of the class SilverStripe\ORM\DataObject 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...
115
		}
116
117
		$this->elastica->endBulkIndex();
118
	}
119
120
121
122
	/**
123
	 * Check whether or not we should contact packagist or use a cached version. This allows to speed up the task
124
	 * during development.
125
	 *
126
	 * @return bool
127
	 */
128
	protected function usePackagistCache() {
129
		return Director::isDev();
130
	}
131
132
	private function updateAddon(Addon $addon, Package $package, array $versions) {
133
		if (!$addon->VendorID) {
0 ignored issues
show
Documentation introduced by
The property VendorID does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
134
			$vendor = AddonVendor::get()->filter('Name', $addon->VendorName())->first();
135
136
			if (!$vendor) {
137
				$vendor = new AddonVendor();
138
				$vendor->Name = $addon->VendorName();
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<SilverStripe\Addons\Model\AddonVendor>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
139
				$vendor->write();
140
			}
141
142
			$addon->VendorID = $vendor->ID;
0 ignored issues
show
Documentation introduced by
The property VendorID does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
143
		}
144
145
		$addon->Type = str_replace('silverstripe-', '', $package->getType());
0 ignored issues
show
Documentation introduced by
The property Type does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
146
		$addon->Description = $package->getDescription();
0 ignored issues
show
Documentation introduced by
The property Description does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
147
		$addon->Released = strtotime($package->getTime());
0 ignored issues
show
Documentation introduced by
The property Released does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
148
		$addon->Repository = $package->getRepository();
0 ignored issues
show
Documentation introduced by
The property Repository does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
149
		$addon->Downloads = $package->getDownloads()->getTotal();
0 ignored issues
show
Documentation introduced by
The property Downloads does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
150
		$addon->DownloadsMonthly = $package->getDownloads()->getMonthly();
0 ignored issues
show
Documentation introduced by
The property DownloadsMonthly does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
151
		$addon->Favers = $package->getFavers();
0 ignored issues
show
Documentation introduced by
The property Favers does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
152
153
		foreach ($versions as $version) {
154
			$this->updateVersion($addon, $version);
155
		}
156
157
		// If there is no build, then queue one up if the add-on requires
158
		// one.
159
		if (!$addon->BuildQueued) {
0 ignored issues
show
Documentation introduced by
The property BuildQueued does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
160
			if (!$addon->BuiltAt) {
0 ignored issues
show
Documentation introduced by
The property BuiltAt does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
161
				$this->resque->queue('first_build', 'BuildAddonJob', ['id' => $addon->ID]);
162
				$addon->BuildQueued = true;
0 ignored issues
show
Documentation introduced by
The property BuildQueued does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
163
			} else {
164
				$built = (int) $addon->obj('BuiltAt')->format('U');
165
166
				foreach ($versions as $version) {
167
					if (strtotime($version->getTime()) > $built) {
168
						$this->resque->queue('update', 'BuildAddonJob', ['id' => $addon->ID]);
169
						$addon->BuildQueued = true;
0 ignored issues
show
Documentation introduced by
The property BuildQueued does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
170
171
						break;
172
					}
173
				}
174
			}
175
		}
176
177
		$addon->LastUpdated = time();
0 ignored issues
show
Documentation introduced by
The property LastUpdated does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
178
		$addon->write();
179
	}
180
181
	private function updateVersion(Addon $addon, Version $package) {
182
		$version = null;
183
184
		if ($addon->isInDB()) {
185
			$version = $addon->Versions()->filter('Version', $package->getVersionNormalized())->first();
0 ignored issues
show
Bug introduced by
The method Versions() does not exist on SilverStripe\Addons\Model\Addon. Did you maybe mean SortedVersions()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
186
		}
187
188
		if (!$version) {
189
			$version = new AddonVersion();
190
		}
191
192
		$version->Name = $package->getName();
193
		$version->Type = str_replace('silverstripe-', '', $package->getType());
194
		$version->Description = $package->getDescription();
195
		$version->Released = strtotime($package->getTime());
196
		$keywords = $package->getKeywords();
197
198
		if ($keywords) {
199
			foreach ($keywords as $keyword) {
200
				$keyword = AddonKeyword::get_by_name($keyword);
201
202
				$addon->Keywords()->add($keyword);
0 ignored issues
show
Documentation Bug introduced by
The method Keywords does not exist on object<SilverStripe\Addons\Model\Addon>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
203
				$version->Keywords()->add($keyword);
204
			}
205
		}
206
207
		$version->Version = $package->getVersionNormalized();
208
		$version->PrettyVersion = $package->getVersion();
209
210
		$stability = VersionParser::parseStability($package->getVersion());
211
		$isDev = $stability === 'dev';
212
		$version->Development = $isDev;
213
214
		$version->SourceType = $package->getSource()->getType();
215
		$version->SourceUrl = $package->getSource()->getUrl();
216
		$version->SourceReference = $package->getSource()->getReference();
217
218
		if($package->getDist()) {
219
			$version->DistType = $package->getDist()->getType();
220
			$version->DistUrl = $package->getDist()->getUrl();
221
			$version->DistReference = $package->getDist()->getReference();
222
			$version->DistChecksum = $package->getDist()->getShasum();
223
		}
224
225
		$version->Extra = $package->getExtra();
226
		$version->Homepage = $package->getHomepage();
227
		$version->License = $package->getLicense();
228
		// $version->Support = $package->getSupport();
229
230
		$addon->Versions()->add($version);
0 ignored issues
show
Bug introduced by
The method Versions() does not exist on SilverStripe\Addons\Model\Addon. Did you maybe mean SortedVersions()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
231
232
		$this->updateLinks($version, $package);
233
		$this->updateCompatibility($addon, $version, $package);
234
		$this->updateAuthors($version, $package);
235
	}
236
237
	private function updateLinks(AddonVersion $version, CompletePackage $package) {
238
		$getLink = function ($name, $type) use ($version) {
239
			$link = null;
240
241
			if ($version->isInDB()) {
242
				$link = $version->Links()->filter('Name', $name)->filter('Type', $type)->first();
0 ignored issues
show
Documentation Bug introduced by
The method Links does not exist on object<SilverStripe\Addons\Model\AddonVersion>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
243
			}
244
245
			if (!$link) {
246
				$link = new AddonLink();
247
				$link->Name = $name;
248
				$link->Type = $type;
249
			}
250
251
			return $link;
252
		};
253
254
		$types = [
255
			'require' => 'getRequire',
256
			'require-dev' => 'getRequireDev',
257
			'provide' => 'getProvide',
258
			'conflict' => 'getConflict',
259
			'replace' => 'getReplace'
260
		];
261
262
		foreach ($types as $type => $method) {
263
			if ($linked = $package->$method()) foreach ($linked as $link => $constraint) {
264
				$name = $link;
265
				$addon = Addon::get()->filter('Name', $name)->first();
266
267
				$local = $getLink($name, $type);
268
				$local->Constraint = $constraint;
269
270
				if ($addon) {
271
					$local->TargetID = $addon->ID;
272
				}
273
274
				$version->Links()->add($local);
0 ignored issues
show
Documentation Bug introduced by
The method Links does not exist on object<SilverStripe\Addons\Model\AddonVersion>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
275
			}
276
		}
277
278
		//to-do api have no method to get this.
279
		/*$suggested = $package->getSuggests();
280
281
		if ($suggested) foreach ($suggested as $package => $description) {
282
			$link = $getLink($package, 'suggest');
283
			$link->Description = $description;
284
285
			$version->Links()->add($link);
286
		}*/
287
	}
288
289
	private function updateCompatibility(Addon $addon, AddonVersion $version, CompletePackage $package) {
290
		$require = null;
291
292
		if($package->getRequire()) foreach ($package->getRequire() as $name => $link) {
0 ignored issues
show
Bug introduced by
The method getRequire() does not exist on Composer\Package\CompletePackage. Did you maybe mean getRequires()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
293
			if((string)$link == 'self.version') continue;
294
295
			if ($name == 'silverstripe/framework') {
296
				$require = $link;
297
				break;
298
			}
299
300
			if ($name == 'silverstripe/cms') {
301
				$require = $link;
302
			}
303
		}
304
305
		if (!$require) {
306
			return;
307
		}
308
309
		$addon->CompatibleVersions()->removeAll();
0 ignored issues
show
Documentation Bug introduced by
The method CompatibleVersions does not exist on object<SilverStripe\Addons\Model\Addon>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
310
		$version->CompatibleVersions()->removeAll();
0 ignored issues
show
Documentation Bug introduced by
The method CompatibleVersions does not exist on object<SilverStripe\Addons\Model\AddonVersion>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
311
312
		foreach ($this->silverstripes as $id => $link) {
313
			try {
314
				$constraint = $this->versionParser->parseConstraints($require);
315
				if ($link->matches($constraint)) {
0 ignored issues
show
Documentation Bug introduced by
The method matches does not exist on object<SilverStripe\Addo...el\SilverStripeVersion>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
316
					$addon->CompatibleVersions()->add($id);
0 ignored issues
show
Documentation Bug introduced by
The method CompatibleVersions does not exist on object<SilverStripe\Addons\Model\Addon>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
317
					$version->CompatibleVersions()->add($id);
0 ignored issues
show
Documentation Bug introduced by
The method CompatibleVersions does not exist on object<SilverStripe\Addons\Model\AddonVersion>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
318
				}
319
			} catch(Exception $e) {
0 ignored issues
show
Bug introduced by
The class SilverStripe\Addons\Services\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
320
				// An exception here shouldn't prevent further updates.
321
				Debug::log($addon->Name . "\t" . $addon->ID . "\t" . $e->getMessage());
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<SilverStripe\Addons\Model\Addon>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
322
			}
323
		}
324
	}
325
326
	private function updateAuthors(AddonVersion $version, CompletePackage $package) {
327
		if ($package->getAuthors()) foreach ($package->getAuthors() as $details) {
328
			$author = null;
329
330
			if (!$details->getName() && !$details->getEmail()) {
331
				continue;
332
			}
333
334
			if ($details->getEmail()) {
335
				$author = AddonAuthor::get()->filter('Email', $details->getEmail())->first();
336
			}
337
338
			if (!$author && $details->getHomepage()) {
339
				$author = AddonAuthor::get()
340
					->filter('Name', $details->getName())
341
					->filter('Homepage', $details->getHomepage())
342
					->first();
343
			}
344
345
			if (!$author && $details->getName()) {
346
				$author = AddonAuthor::get()
347
					->filter('Name', $details->getName())
348
					->filter('Versions.Addon.Name', $package->getName())
349
					->first();
350
			}
351
352
			if (!$author) {
353
				$author = new AddonAuthor();
354
			}
355
356
			if($details->getName()) $author->Name = $details->getName();
357
			if($details->getEmail()) $author->Email = $details->getEmail();
358
			if($details->getHomepage()) $author->Homepage = $details->getHomepage();
359
360
			//to-do not supported by API
361
			//if(isset($details['role'])) $author->Role = $details['role'];
362
363
			$version->Authors()->add($author->write());
0 ignored issues
show
Documentation Bug introduced by
The method Authors does not exist on object<SilverStripe\Addons\Model\AddonVersion>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
364
		}
365
	}
366
367
}
368