1
<?php
2

3
namespace BringYourOwnIdeas\UpdateChecker;
4

5
use BringYourOwnIdeas\Maintenance\Util\ComposerLoader;
6
use Composer\Composer;
7
use Composer\DependencyResolver\Pool;
8
use Composer\Package\BasePackage;
9
use Composer\Package\PackageInterface;
10
use Composer\Package\Version\VersionSelector;
11
use Composer\Repository\CompositeRepository;
12
use SilverStripe\Core\Injector\Injector;
13

14
/**
15
 * The update checker class is provided a {@link Link} object representing a package and uses the Composer API to
16
 * determine the next available updates for the package.
17
 */
18
class UpdateChecker
19
{
20
    /**
21
     * @var VersionSelector
22
     */
23
    protected $versionSelector;
24

25
    /**
26
     * Update types (see {@link ComposerPackageVersion}
27
     *
28
     * @var string
29
     */
30
    const TYPE_AVAILABLE = 'Available';
31
    const TYPE_LATEST = 'Latest';
32

33
    /**
34
     * Checks the given package for available and latest updates, and writes them to data models if found
35
     *
36
     * @param PackageInterface $package
37
     * @param string $constraint
38
     * @return string[]
39
     */
40 2
    public function checkForUpdates(PackageInterface $package, $constraint)
41
    {
42 2
        $installedVersion = $package->getPrettyVersion();
43

44
        /** @var Composer $composer */
45 2
        $composer = Injector::inst()->get(ComposerLoader::class)->getComposer();
46

47
        $updateInformation = [
48 2
            'Version' => $installedVersion,
49 2
            'VersionHash' => $package->getSourceReference(),
50 2
            'VersionConstraint' => $constraint,
51
        ];
52

53 2
        if ($available = $this->findLatestPackage($package, $constraint, $installedVersion, $composer, true)) {
54 0
            $updateInformation[self::TYPE_AVAILABLE . 'Version'] = $available->getPrettyVersion();
55 0
            $updateInformation[self::TYPE_AVAILABLE . 'Hash'] = $available->getSourceReference();
56
        }
57

58 2
        if ($latest = $this->findLatestPackage($package, $constraint, $installedVersion, $composer, false)) {
59 2
            $updateInformation[self::TYPE_LATEST . 'Version'] = $latest->getPrettyVersion();
60 2
            $updateInformation[self::TYPE_LATEST . 'Hash'] = $latest->getSourceReference();
61
        }
62

63 2
        return $updateInformation;
64
    }
65

66
    /**
67
     * @param Composer $composer
68
     * @return VersionSelector
69
     */
70 0
    protected function getVersionSelector(Composer $composer)
71
    {
72 0
        if (!$this->versionSelector) {
73
            // Instantiate a new repository pool, providing the stability flags from the project
74 0
            $pool = new Pool(
75 0
                $composer->getPackage()->getMinimumStability(),
76 0
                $composer->getPackage()->getStabilityFlags()
77
            );
78 0
            $pool->addRepository(new CompositeRepository($composer->getRepositoryManager()->getRepositories()));
79

80 0
            $this->versionSelector = new VersionSelector($pool);
81
        }
82

83 0
        return $this->versionSelector;
84
    }
85

86
    /**
87
     * Given a package, this finds the latest package matching it
88
     *
89
     * Based on Composer's ShowCommand::findLatestPackage
90
     *
91
     * @param PackageInterface $package
92
     * @param string $constraint
93
     * @param string $installedVersion
94
     * @param Composer $composer
95
     * @param bool $minorOnly
96
     * @return bool|PackageInterface
97
     */
98 0
    protected function findLatestPackage(
99
        PackageInterface $package,
100
        $constraint,
101
        $installedVersion,
102
        Composer $composer,
103
        $minorOnly = false
104
    ) {
105
        // find the latest version allowed in this pool
106 0
        $name = $package->getName();
107 0
        $versionSelector = $this->getVersionSelector($composer);
108 0
        $stability = $composer->getPackage()->getMinimumStability();
109 0
        $flags = $composer->getPackage()->getStabilityFlags();
110 0
        if (isset($flags[$name])) {
111 0
            $stability = array_search($flags[$name], BasePackage::$stabilities, true);
112
        }
113

114 0
        $bestStability = $stability;
115 0
        if ($composer->getPackage()->getPreferStable()) {
116 0
            $bestStability = $composer->getPackage()->getStability();
117
        }
118

119 0
        $targetVersion = null;
120 0
        if (0 === strpos($installedVersion, 'dev-')) {
121 0
            $targetVersion = $installedVersion;
122
        }
123

124 0
        if ($targetVersion === null && $minorOnly) {
125
            // Use the semver constraint to determine the next available version
126 0
            $targetVersion = $constraint;
127
        }
128

129 0
        return $versionSelector->findBestCandidate($name, $targetVersion, null, $bestStability);
130
    }
131
}

Read our documentation on viewing source code .

Loading