123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965 |
- <?php
- /*
- * This file is part of Packagist.
- *
- * (c) Jordi Boggiano <j.boggiano@seld.be>
- * Nils Adermann <naderman@naderman.de>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Packagist\WebBundle\Entity;
- use Composer\Factory;
- use Composer\IO\NullIO;
- use Composer\Repository\VcsRepository;
- use Doctrine\Common\Collections\ArrayCollection;
- use Doctrine\ORM\Mapping as ORM;
- use Symfony\Component\Validator\Constraints as Assert;
- use Symfony\Component\Validator\Context\ExecutionContextInterface;
- use Composer\Repository\Vcs\GitHubDriver;
- /**
- * @ORM\Entity(repositoryClass="Packagist\WebBundle\Entity\PackageRepository")
- * @ORM\Table(
- * name="package",
- * uniqueConstraints={@ORM\UniqueConstraint(name="package_name_idx", columns={"name"})},
- * indexes={
- * @ORM\Index(name="indexed_idx",columns={"indexedAt"}),
- * @ORM\Index(name="crawled_idx",columns={"crawledAt"}),
- * @ORM\Index(name="dumped_idx",columns={"dumpedAt"}),
- * @ORM\Index(name="repository_idx",columns={"repository"}),
- * @ORM\Index(name="remoteid_idx",columns={"remoteId"})
- * }
- * )
- * @Assert\Callback(callback="isPackageUnique")
- * @Assert\Callback(callback="isVendorWritable")
- * @Assert\Callback(callback="isRepositoryValid", groups={"Update", "Default"})
- * @author Jordi Boggiano <j.boggiano@seld.be>
- */
- class Package
- {
- const AUTO_MANUAL_HOOK = 1;
- const AUTO_GITHUB_HOOK = 2;
- /**
- * @ORM\Id
- * @ORM\Column(type="integer")
- * @ORM\GeneratedValue(strategy="AUTO")
- */
- private $id;
- /**
- * Unique package name
- *
- * @ORM\Column(length=191)
- */
- private $name;
- /**
- * @ORM\Column(nullable=true)
- */
- private $type;
- /**
- * @ORM\Column(type="text", nullable=true)
- */
- private $description;
- /**
- * @ORM\Column(type="string", nullable=true)
- */
- private $language;
- /**
- * @ORM\Column(type="text", nullable=true)
- */
- private $readme;
- /**
- * @ORM\Column(type="integer", nullable=true, name="github_stars")
- */
- private $gitHubStars;
- /**
- * @ORM\Column(type="integer", nullable=true, name="github_watches")
- */
- private $gitHubWatches;
- /**
- * @ORM\Column(type="integer", nullable=true, name="github_forks")
- */
- private $gitHubForks;
- /**
- * @ORM\Column(type="integer", nullable=true, name="github_open_issues")
- */
- private $gitHubOpenIssues;
- /**
- * @ORM\OneToMany(targetEntity="Packagist\WebBundle\Entity\Version", mappedBy="package")
- */
- private $versions;
- /**
- * @ORM\ManyToMany(targetEntity="User", inversedBy="packages")
- * @ORM\JoinTable(name="maintainers_packages")
- */
- private $maintainers;
- /**
- * @ORM\Column()
- * @Assert\NotBlank(groups={"Update", "Default"})
- */
- private $repository;
- // dist-tags / rel or runtime?
- /**
- * @ORM\Column(type="datetime")
- */
- private $createdAt;
- /**
- * @ORM\Column(type="datetime", nullable=true)
- */
- private $updatedAt;
- /**
- * @ORM\Column(type="datetime", nullable=true)
- */
- private $crawledAt;
- /**
- * @ORM\Column(type="datetime", nullable=true)
- */
- private $indexedAt;
- /**
- * @ORM\Column(type="datetime", nullable=true)
- */
- private $dumpedAt;
- /**
- * @ORM\OneToMany(targetEntity="Packagist\WebBundle\Entity\Download", mappedBy="package")
- */
- private $downloads;
- /**
- * @ORM\Column(type="string", nullable=true)
- */
- private $remoteId;
- /**
- * @ORM\Column(type="smallint")
- */
- private $autoUpdated = 0;
- /**
- * @var bool
- * @ORM\Column(type="boolean")
- */
- private $abandoned = false;
- /**
- * @var string
- * @ORM\Column(type="string", length=255, nullable=true)
- */
- private $replacementPackage;
- /**
- * @ORM\Column(type="boolean", options={"default"=false})
- */
- private $updateFailureNotified = false;
- /**
- * @ORM\Column(type="string", length=255, nullable=true)
- */
- private $suspect;
- private $entityRepository;
- private $router;
- /**
- * @var \Composer\Repository\Vcs\VcsDriverInterface
- */
- private $vcsDriver = true;
- private $vcsDriverError;
- /**
- * @var array lookup table for versions
- */
- private $cachedVersions;
- public function __construct()
- {
- $this->versions = new ArrayCollection();
- $this->createdAt = new \DateTime;
- }
- public function toArray(VersionRepository $versionRepo, bool $serializeForApi = false)
- {
- $versions = array();
- $partialVersions = $this->getVersions()->toArray();
- while ($partialVersions) {
- $slice = array_splice($partialVersions, 0, 100);
- $fullVersions = $versionRepo->refreshVersions($slice);
- $versionData = $versionRepo->getVersionData(array_map(function ($v) { return $v->getId(); }, $fullVersions));
- $versions = array_merge($versions, $versionRepo->detachToArray($fullVersions, $versionData, $serializeForApi));
- }
- $maintainers = array();
- foreach ($this->getMaintainers() as $maintainer) {
- /** @var $maintainer User */
- $maintainers[] = $maintainer->toArray();
- }
- $data = array(
- 'name' => $this->getName(),
- 'description' => $this->getDescription(),
- 'time' => $this->getCreatedAt()->format('c'),
- 'maintainers' => $maintainers,
- 'versions' => $versions,
- 'type' => $this->getType(),
- 'repository' => $this->getRepository(),
- 'github_stars' => $this->getGitHubStars(),
- 'github_watchers' => $this->getGitHubWatches(),
- 'github_forks' => $this->getGitHubForks(),
- 'github_open_issues' => $this->getGitHubOpenIssues(),
- 'language' => $this->getLanguage(),
- );
- if ($this->isAbandoned()) {
- $data['abandoned'] = $this->getReplacementPackage() ?: true;
- }
- return $data;
- }
- public function isRepositoryValid(ExecutionContextInterface $context)
- {
- // vcs driver was not nulled which means the repository was not set/modified and is still valid
- if (true === $this->vcsDriver && null !== $this->getName()) {
- return;
- }
- $property = 'repository';
- $driver = $this->vcsDriver;
- if (!is_object($driver)) {
- if (preg_match('{^http://}', $this->repository)) {
- $context->buildViolation('Non-secure HTTP URLs are not supported, make sure you use an HTTPS or SSH URL')
- ->atPath($property)
- ->addViolation()
- ;
- } elseif (preg_match('{https?://.+@}', $this->repository)) {
- $context->buildViolation('URLs with user@host are not supported, use a read-only public URL')
- ->atPath($property)
- ->addViolation()
- ;
- } elseif (is_string($this->vcsDriverError)) {
- $context->buildViolation('Uncaught Exception: '.htmlentities($this->vcsDriverError, ENT_COMPAT, 'utf-8'))
- ->atPath($property)
- ->addViolation()
- ;
- } else {
- $context->buildViolation('No valid/supported repository was found at the given URL')
- ->atPath($property)
- ->addViolation()
- ;
- }
- return;
- }
- try {
- $information = $driver->getComposerInformation($driver->getRootIdentifier());
- if (false === $information) {
- $context->buildViolation('No composer.json was found in the '.$driver->getRootIdentifier().' branch.')
- ->atPath($property)
- ->addViolation()
- ;
- return;
- }
- if (empty($information['name'])) {
- $context->buildViolation('The package name was not found in the composer.json, make sure there is a name present.')
- ->atPath($property)
- ->addViolation()
- ;
- return;
- }
- if (!preg_match('{^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9]([_.-]?[a-z0-9]+)*$}iD', $information['name'])) {
- $context->buildViolation('The package name '.htmlentities($information['name'], ENT_COMPAT, 'utf-8').' is invalid, it should have a vendor name, a forward slash, and a package name. The vendor and package name can be words separated by -, . or _. The complete name should match "[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9]([_.-]?[a-z0-9]+)*".')
- ->atPath($property)
- ->addViolation()
- ;
- return;
- }
- if (
- preg_match('{(free.*watch|watch.*free|(stream|online).*anschauver.*pelicula|ver.*completa|pelicula.*complet|season.*episode.*online|film.*(complet|entier)|(voir|regarder|guarda|assistir).*(film|complet)|full.*movie|online.*(free|tv|full.*hd)|(free|full|gratuit).*stream|movie.*free|free.*(movie|hack)|watch.*movie|watch.*full|generate.*resource|generate.*unlimited|hack.*coin|coin.*(hack|generat)|vbucks|hack.*cheat|hack.*generat|generat.*hack|hack.*unlimited|cheat.*(unlimited|generat)|(mod|cheat|apk).*(hack|cheat|mod)|hack.*(apk|mod|free|gold|gems|diamonds|coin)|putlocker|generat.*free|coins.*generat|(download|telecharg).*album|album.*(download|telecharg)|album.*(free|gratuit)|generat.*coins|unlimited.*coins|(fortnite|pubg|apex.*legend|t[1i]k.*t[o0]k).*(free|gratuit|generat|unlimited|coins|mobile|hack|follow))}i', str_replace(array('.', '-'), '', $information['name']))
- && !preg_match('{^(hexmode|calgamo|liberty_code|dvi)/}', $information['name'])
- ) {
- $context->buildViolation('The package name '.htmlentities($information['name'], ENT_COMPAT, 'utf-8').' is blocked, if you think this is a mistake please get in touch with us.')
- ->atPath($property)
- ->addViolation()
- ;
- return;
- }
- $reservedNames = ['nul', 'con', 'prn', 'aux', 'com1', 'com2', 'com3', 'com4', 'com5', 'com6', 'com7', 'com8', 'com9', 'lpt1', 'lpt2', 'lpt3', 'lpt4', 'lpt5', 'lpt6', 'lpt7', 'lpt8', 'lpt9'];
- $bits = explode('/', strtolower($information['name']));
- if (in_array($bits[0], $reservedNames, true) || in_array($bits[1], $reservedNames, true)) {
- $context->buildViolation('The package name '.htmlentities($information['name'], ENT_COMPAT, 'utf-8').' is reserved, package and vendor names can not match any of: '.implode(', ', $reservedNames).'.')
- ->atPath($property)
- ->addViolation()
- ;
- return;
- }
- if (preg_match('{\.json$}', $information['name'])) {
- $context->buildViolation('The package name '.htmlentities($information['name'], ENT_COMPAT, 'utf-8').' is invalid, package names can not end in .json, consider renaming it or perhaps using a -json suffix instead.')
- ->atPath($property)
- ->addViolation()
- ;
- return;
- }
- if (preg_match('{[A-Z]}', $information['name'])) {
- $suggestName = preg_replace('{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}', '\\1\\3-\\2\\4', $information['name']);
- $suggestName = strtolower($suggestName);
- $context->buildViolation('The package name '.htmlentities($information['name'], ENT_COMPAT, 'utf-8').' is invalid, it should not contain uppercase characters. We suggest using '.$suggestName.' instead.')
- ->atPath($property)
- ->addViolation()
- ;
- return;
- }
- } catch (\Exception $e) {
- $context->buildViolation('We had problems parsing your composer.json file, the parser reports: '.htmlentities($e->getMessage(), ENT_COMPAT, 'utf-8'))
- ->atPath($property)
- ->addViolation()
- ;
- }
- if (null === $this->getName()) {
- $context->buildViolation('An unexpected error has made our parser fail to find a package name in your repository, if you think this is incorrect please try again')
- ->atPath($property)
- ->addViolation()
- ;
- }
- }
- public function setEntityRepository($repository)
- {
- $this->entityRepository = $repository;
- }
- public function setRouter($router)
- {
- $this->router = $router;
- }
- public function isPackageUnique(ExecutionContextInterface $context)
- {
- try {
- if ($this->entityRepository->findOneByName($this->name)) {
- $context->buildViolation('A package with the name <a href="'.$this->router->generate('view_package', array('name' => $this->name)).'">'.$this->name.'</a> already exists.')
- ->atPath('repository')
- ->addViolation()
- ;
- }
- } catch (\Doctrine\ORM\NoResultException $e) {}
- }
- public function isVendorWritable(ExecutionContextInterface $context)
- {
- try {
- $vendor = $this->getVendor();
- if ($vendor && $this->entityRepository->isVendorTaken($vendor, reset($this->maintainers))) {
- $context->buildViolation('The vendor is already taken by someone else. '
- . 'You may ask them to add your package and give you maintainership access. '
- . 'If they add you as a maintainer on any package in that vendor namespace, '
- . 'you will then be able to add new packages in that namespace. '
- . 'The packages already in that vendor namespace can be found at '
- . '<a href="'.$this->router->generate('view_vendor', array('vendor' => $vendor)).'">'.$vendor.'</a>')
- ->atPath('repository')
- ->addViolation()
- ;
- }
- } catch (\Doctrine\ORM\NoResultException $e) {}
- }
- /**
- * Get id
- *
- * @return string
- */
- public function getId()
- {
- return $this->id;
- }
- /**
- * Set name
- *
- * @param string $name
- */
- public function setName($name)
- {
- $this->name = $name;
- }
- /**
- * Get name
- *
- * @return string
- */
- public function getName()
- {
- return $this->name;
- }
- /**
- * Get vendor prefix
- *
- * @return string
- */
- public function getVendor()
- {
- return preg_replace('{/.*$}', '', $this->name);
- }
- /**
- * Get package name without vendor
- *
- * @return string
- */
- public function getPackageName()
- {
- return preg_replace('{^[^/]*/}', '', $this->name);
- }
- /**
- * Set description
- *
- * @param string $description
- */
- public function setDescription($description)
- {
- $this->description = $description;
- }
- /**
- * Get description
- *
- * @return string
- */
- public function getDescription()
- {
- return $this->description;
- }
- /**
- * Set language
- *
- * @param string $language
- */
- public function setLanguage($language)
- {
- $this->language = $language;
- }
- /**
- * Get language
- *
- * @return string
- */
- public function getLanguage()
- {
- return $this->language;
- }
- /**
- * Set readme
- *
- * @param string $readme
- */
- public function setReadme($readme)
- {
- $this->readme = $readme;
- }
- /**
- * Get readme
- *
- * @return string
- */
- public function getReadme()
- {
- return $this->readme;
- }
- /**
- * Get readme with transformations that should not be done in the stored readme as they might not be valid in the long run
- *
- * @return string
- */
- public function getOptimizedReadme()
- {
- return str_replace(['<img src="https://raw.github.com/', '<img src="https://raw.githubusercontent.com/'], '<img src="https://rawcdn.githack.com/', $this->readme);
- }
- /**
- * @param int $val
- */
- public function setGitHubStars($val)
- {
- $this->gitHubStars = $val;
- }
- /**
- * @return int
- */
- public function getGitHubStars()
- {
- return $this->gitHubStars;
- }
- /**
- * @param int $val
- */
- public function setGitHubWatches($val)
- {
- $this->gitHubWatches = $val;
- }
- /**
- * @return int
- */
- public function getGitHubWatches()
- {
- return $this->gitHubWatches;
- }
- /**
- * @param int $val
- */
- public function setGitHubForks($val)
- {
- $this->gitHubForks = $val;
- }
- /**
- * @return int
- */
- public function getGitHubForks()
- {
- return $this->gitHubForks;
- }
- /**
- * @param int $val
- */
- public function setGitHubOpenIssues($val)
- {
- $this->gitHubOpenIssues = $val;
- }
- /**
- * @return int
- */
- public function getGitHubOpenIssues()
- {
- return $this->gitHubOpenIssues;
- }
- /**
- * Set createdAt
- *
- * @param \DateTime $createdAt
- */
- public function setCreatedAt($createdAt)
- {
- $this->createdAt = $createdAt;
- }
- /**
- * Get createdAt
- *
- * @return \DateTime
- */
- public function getCreatedAt()
- {
- return $this->createdAt;
- }
- /**
- * Set repository
- *
- * @param string $repository
- */
- public function setRepository($repoUrl)
- {
- $this->vcsDriver = null;
- // prevent local filesystem URLs
- if (preg_match('{^(\.|[a-z]:|/)}i', $repoUrl)) {
- return;
- }
- $repoUrl = preg_replace('{^git@github.com:}i', 'https://github.com/', $repoUrl);
- $repoUrl = preg_replace('{^git://github.com/}i', 'https://github.com/', $repoUrl);
- $repoUrl = preg_replace('{^(https://github.com/.*?)\.git$}i', '$1', $repoUrl);
- // normalize protocol case
- $repoUrl = preg_replace_callback('{^(https?|git|svn)://}i', function ($match) { return strtolower($match[1]) . '://'; }, $repoUrl);
- $this->repository = $repoUrl;
- $this->remoteId = null;
- // avoid user@host URLs
- if (preg_match('{https?://.+@}', $repoUrl)) {
- return;
- }
- try {
- $io = new NullIO();
- $config = Factory::createConfig();
- $io->loadConfiguration($config);
- $repository = new VcsRepository(array('url' => $this->repository), $io, $config);
- $driver = $this->vcsDriver = $repository->getDriver();
- if (!$driver) {
- return;
- }
- $information = $driver->getComposerInformation($driver->getRootIdentifier());
- if (!isset($information['name'])) {
- return;
- }
- if (null === $this->getName()) {
- $this->setName(trim($information['name']));
- }
- if ($driver instanceof GitHubDriver) {
- $this->repository = $driver->getRepositoryUrl();
- if ($repoData = $driver->getRepoData()) {
- $this->remoteId = parse_url($this->repository, PHP_URL_HOST).'/'.$repoData['id'];
- }
- }
- } catch (\Exception $e) {
- $this->vcsDriverError = '['.get_class($e).'] '.$e->getMessage();
- }
- }
- /**
- * Get repository
- *
- * @return string $repository
- */
- public function getRepository()
- {
- return $this->repository;
- }
- /**
- * Get a user-browsable version of the repository URL
- *
- * @return string $repository
- */
- public function getBrowsableRepository()
- {
- if (preg_match('{(://|@)bitbucket.org[:/]}i', $this->repository)) {
- return preg_replace('{^(?:git@|https://|git://)bitbucket.org[:/](.+?)(?:\.git)?$}i', 'https://bitbucket.org/$1', $this->repository);
- }
- return preg_replace('{^(git://github.com/|git@github.com:)}', 'https://github.com/', $this->repository);
- }
- /**
- * Add versions
- *
- * @param Version $versions
- */
- public function addVersions(Version $versions)
- {
- $this->versions[] = $versions;
- }
- /**
- * Get versions
- *
- * @return \Doctrine\Common\Collections\Collection
- */
- public function getVersions()
- {
- return $this->versions;
- }
- public function getVersion($normalizedVersion)
- {
- if (null === $this->cachedVersions) {
- $this->cachedVersions = array();
- foreach ($this->getVersions() as $version) {
- $this->cachedVersions[strtolower($version->getNormalizedVersion())] = $version;
- }
- }
- if (isset($this->cachedVersions[strtolower($normalizedVersion)])) {
- return $this->cachedVersions[strtolower($normalizedVersion)];
- }
- }
- /**
- * Set updatedAt
- *
- * @param \DateTime $updatedAt
- */
- public function setUpdatedAt($updatedAt)
- {
- $this->updatedAt = $updatedAt;
- $this->setUpdateFailureNotified(false);
- }
- /**
- * Get updatedAt
- *
- * @return \DateTime
- */
- public function getUpdatedAt()
- {
- return $this->updatedAt;
- }
- public function wasUpdatedInTheLast24Hours(): bool
- {
- return $this->updatedAt > new \DateTime('-24 hours');
- }
- /**
- * Set crawledAt
- *
- * @param \DateTime|null $crawledAt
- */
- public function setCrawledAt($crawledAt)
- {
- $this->crawledAt = $crawledAt;
- }
- /**
- * Get crawledAt
- *
- * @return \DateTime
- */
- public function getCrawledAt()
- {
- return $this->crawledAt;
- }
- /**
- * Set indexedAt
- *
- * @param \DateTime $indexedAt
- */
- public function setIndexedAt($indexedAt)
- {
- $this->indexedAt = $indexedAt;
- }
- /**
- * Get indexedAt
- *
- * @return \DateTime
- */
- public function getIndexedAt()
- {
- return $this->indexedAt;
- }
- /**
- * Set dumpedAt
- *
- * @param \DateTime $dumpedAt
- */
- public function setDumpedAt($dumpedAt)
- {
- $this->dumpedAt = $dumpedAt;
- }
- /**
- * Get dumpedAt
- *
- * @return \DateTime
- */
- public function getDumpedAt()
- {
- return $this->dumpedAt;
- }
- /**
- * Add maintainers
- *
- * @param User $maintainer
- */
- public function addMaintainer(User $maintainer)
- {
- $this->maintainers[] = $maintainer;
- }
- /**
- * Get maintainers
- *
- * @return \Doctrine\Common\Collections\Collection
- */
- public function getMaintainers()
- {
- return $this->maintainers;
- }
- /**
- * Set type
- *
- * @param string $type
- */
- public function setType($type)
- {
- $this->type = $type;
- }
- /**
- * Get type
- *
- * @return string
- */
- public function getType()
- {
- return $this->type;
- }
- public function setRemoteId(?string $remoteId)
- {
- $this->remoteId = $remoteId;
- }
- public function getRemoteId(): ?string
- {
- return $this->remoteId;
- }
- /**
- * Set autoUpdated
- *
- * @param int $autoUpdated
- */
- public function setAutoUpdated($autoUpdated)
- {
- $this->autoUpdated = $autoUpdated;
- }
- /**
- * Get autoUpdated
- *
- * @return int
- */
- public function getAutoUpdated()
- {
- return $this->autoUpdated;
- }
- /**
- * Get autoUpdated
- *
- * @return Boolean
- */
- public function isAutoUpdated()
- {
- return $this->autoUpdated > 0;
- }
- /**
- * Set updateFailureNotified
- *
- * @param Boolean $updateFailureNotified
- */
- public function setUpdateFailureNotified($updateFailureNotified)
- {
- $this->updateFailureNotified = $updateFailureNotified;
- }
- /**
- * Get updateFailureNotified
- *
- * @return Boolean
- */
- public function isUpdateFailureNotified()
- {
- return $this->updateFailureNotified;
- }
- public function setSuspect(?string $reason)
- {
- $this->suspect = $reason;
- }
- public function isSuspect(): bool
- {
- return !is_null($this->suspect);
- }
- public function getSuspect(): ?string
- {
- return $this->suspect;
- }
- /**
- * @return boolean
- */
- public function isAbandoned()
- {
- return $this->abandoned;
- }
- /**
- * @param boolean $abandoned
- */
- public function setAbandoned($abandoned)
- {
- $this->abandoned = $abandoned;
- }
- /**
- * @return string
- */
- public function getReplacementPackage()
- {
- return $this->replacementPackage;
- }
- /**
- * @param string $replacementPackage
- */
- public function setReplacementPackage($replacementPackage)
- {
- $this->replacementPackage = $replacementPackage;
- }
- public static function sortVersions($a, $b)
- {
- $aVersion = $a->getNormalizedVersion();
- $bVersion = $b->getNormalizedVersion();
- $aVersion = preg_replace('{^dev-.*}', '0.0.0-alpha', $aVersion);
- $bVersion = preg_replace('{^dev-.*}', '0.0.0-alpha', $bVersion);
- // equal versions are sorted by date
- if ($aVersion === $bVersion) {
- // make sure sort is stable
- if ($a->getReleasedAt() == $b->getReleasedAt()) {
- return $a->getNormalizedVersion() <=> $b->getNormalizedVersion();
- }
- return $b->getReleasedAt() > $a->getReleasedAt() ? 1 : -1;
- }
- // the rest is sorted by version
- return version_compare($bVersion, $aVersion);
- }
- }
|