Version.php 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  1. <?php
  2. /*
  3. * This file is part of Packagist.
  4. *
  5. * (c) Jordi Boggiano <j.boggiano@seld.be>
  6. * Nils Adermann <naderman@naderman.de>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Packagist\WebBundle\Entity;
  12. use Composer\Package\Version\VersionParser;
  13. use Doctrine\Common\Collections\ArrayCollection;
  14. use Doctrine\ORM\Mapping as ORM;
  15. use Symfony\Component\Validator\Constraints as Assert;
  16. /**
  17. * @ORM\Entity(repositoryClass="Packagist\WebBundle\Entity\VersionRepository")
  18. * @ORM\Table(
  19. * name="package_version",
  20. * uniqueConstraints={@ORM\UniqueConstraint(name="pkg_ver_idx",columns={"package_id","normalizedVersion"})},
  21. * indexes={
  22. * @ORM\Index(name="release_idx",columns={"releasedAt"}),
  23. * @ORM\Index(name="is_devel_idx",columns={"development"})
  24. * }
  25. * )
  26. * @author Jordi Boggiano <j.boggiano@seld.be>
  27. */
  28. class Version
  29. {
  30. /**
  31. * @ORM\Id
  32. * @ORM\Column(type="integer")
  33. * @ORM\GeneratedValue(strategy="AUTO")
  34. */
  35. private $id;
  36. /**
  37. * @ORM\Column
  38. * @Assert\NotBlank()
  39. */
  40. private $name;
  41. /**
  42. * @ORM\Column(type="text", nullable=true)
  43. */
  44. private $description;
  45. /**
  46. * @ORM\Column(nullable=true)
  47. */
  48. private $type;
  49. /**
  50. * @ORM\Column(nullable=true)
  51. */
  52. private $targetDir;
  53. /**
  54. * @ORM\Column(type="array", nullable=true)
  55. */
  56. private $extra = array();
  57. /**
  58. * @ORM\ManyToMany(targetEntity="Packagist\WebBundle\Entity\Tag", inversedBy="versions")
  59. * @ORM\JoinTable(name="version_tag",
  60. * joinColumns={@ORM\JoinColumn(name="version_id", referencedColumnName="id")},
  61. * inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")}
  62. * )
  63. */
  64. private $tags;
  65. /**
  66. * @ORM\ManyToOne(targetEntity="Packagist\WebBundle\Entity\Package", fetch="EAGER", inversedBy="versions")
  67. * @Assert\Type(type="Packagist\WebBundle\Entity\Package")
  68. */
  69. private $package;
  70. /**
  71. * @ORM\Column(nullable=true)
  72. * @Assert\Url()
  73. */
  74. private $homepage;
  75. /**
  76. * @ORM\Column
  77. * @Assert\NotBlank()
  78. */
  79. private $version;
  80. /**
  81. * @ORM\Column(length=191)
  82. * @Assert\NotBlank()
  83. */
  84. private $normalizedVersion;
  85. /**
  86. * @ORM\Column(type="boolean")
  87. * @Assert\NotBlank()
  88. */
  89. private $development;
  90. /**
  91. * @ORM\Column(type="text", nullable=true)
  92. */
  93. private $license;
  94. /**
  95. * Deprecated relation table, use the authorJson property instead
  96. *
  97. * @ORM\ManyToMany(targetEntity="Packagist\WebBundle\Entity\Author", inversedBy="versions")
  98. * @ORM\JoinTable(name="version_author",
  99. * joinColumns={@ORM\JoinColumn(name="version_id", referencedColumnName="id")},
  100. * inverseJoinColumns={@ORM\JoinColumn(name="author_id", referencedColumnName="id")}
  101. * )
  102. */
  103. private $authors;
  104. /**
  105. * @ORM\OneToMany(targetEntity="Packagist\WebBundle\Entity\RequireLink", mappedBy="version")
  106. */
  107. private $require;
  108. /**
  109. * @ORM\OneToMany(targetEntity="Packagist\WebBundle\Entity\ReplaceLink", mappedBy="version")
  110. */
  111. private $replace;
  112. /**
  113. * @ORM\OneToMany(targetEntity="Packagist\WebBundle\Entity\ConflictLink", mappedBy="version")
  114. */
  115. private $conflict;
  116. /**
  117. * @ORM\OneToMany(targetEntity="Packagist\WebBundle\Entity\ProvideLink", mappedBy="version")
  118. */
  119. private $provide;
  120. /**
  121. * @ORM\OneToMany(targetEntity="Packagist\WebBundle\Entity\DevRequireLink", mappedBy="version")
  122. */
  123. private $devRequire;
  124. /**
  125. * @ORM\OneToMany(targetEntity="Packagist\WebBundle\Entity\SuggestLink", mappedBy="version")
  126. */
  127. private $suggest;
  128. /**
  129. * @ORM\Column(type="text", nullable=true)
  130. */
  131. private $source;
  132. /**
  133. * @ORM\Column(type="text", nullable=true)
  134. */
  135. private $dist;
  136. /**
  137. * @ORM\Column(type="text", nullable=true)
  138. */
  139. private $autoload;
  140. /**
  141. * @ORM\Column(type="text", nullable=true)
  142. */
  143. private $binaries;
  144. /**
  145. * @ORM\Column(type="text", nullable=true)
  146. */
  147. private $includePaths;
  148. /**
  149. * @ORM\Column(type="text", nullable=true)
  150. */
  151. private $support;
  152. /**
  153. * @ORM\Column(name="authors", type="json", nullable=true)
  154. */
  155. private $authorJson;
  156. /**
  157. * @ORM\Column(type="datetime")
  158. */
  159. private $createdAt;
  160. /**
  161. * @ORM\Column(type="datetime", nullable=true)
  162. */
  163. private $softDeletedAt;
  164. /**
  165. * @ORM\Column(type="datetime")
  166. */
  167. private $updatedAt;
  168. /**
  169. * @ORM\Column(type="datetime", nullable=true)
  170. */
  171. private $releasedAt;
  172. public function __construct()
  173. {
  174. $this->tags = new ArrayCollection();
  175. $this->require = new ArrayCollection();
  176. $this->replace = new ArrayCollection();
  177. $this->conflict = new ArrayCollection();
  178. $this->provide = new ArrayCollection();
  179. $this->devRequire = new ArrayCollection();
  180. $this->suggest = new ArrayCollection();
  181. $this->authors = new ArrayCollection();
  182. $this->createdAt = new \DateTime;
  183. $this->updatedAt = new \DateTime;
  184. }
  185. public function toArray(array $versionData, bool $serializeForApi = false)
  186. {
  187. if (isset($versionData[$this->id]['tags'])) {
  188. $tags = $versionData[$this->id]['tags'];
  189. } else {
  190. $tags = array();
  191. foreach ($this->getTags() as $tag) {
  192. /** @var $tag Tag */
  193. $tags[] = $tag->getName();
  194. }
  195. }
  196. if (!is_null($this->getAuthorJson())) {
  197. $authors = $this->getAuthorJson();
  198. } else {
  199. if (isset($versionData[$this->id]['authors'])) {
  200. $authors = $versionData[$this->id]['authors'];
  201. } else {
  202. $authors = array();
  203. foreach ($this->getAuthors() as $author) {
  204. /** @var $author Author */
  205. $authors[] = $author->toArray();
  206. }
  207. }
  208. }
  209. foreach ($authors as &$author) {
  210. uksort($author, [$this, 'sortAuthorKeys']);
  211. }
  212. unset($author);
  213. $data = array(
  214. 'name' => $this->getName(),
  215. 'description' => (string) $this->getDescription(),
  216. 'keywords' => $tags,
  217. 'homepage' => (string) $this->getHomepage(),
  218. 'version' => $this->getVersion(),
  219. 'version_normalized' => $this->getNormalizedVersion(),
  220. 'license' => $this->getLicense(),
  221. 'authors' => $authors,
  222. 'source' => $this->getSource(),
  223. 'dist' => $this->getDist(),
  224. 'type' => $this->getType(),
  225. );
  226. if ($serializeForApi && $this->getSupport()) {
  227. $data['support'] = $this->getSupport();
  228. }
  229. if ($this->getReleasedAt()) {
  230. $data['time'] = $this->getReleasedAt()->format('Y-m-d\TH:i:sP');
  231. }
  232. if ($this->getAutoload()) {
  233. $data['autoload'] = $this->getAutoload();
  234. }
  235. if ($this->getExtra()) {
  236. $data['extra'] = $this->getExtra();
  237. }
  238. if ($this->getTargetDir()) {
  239. $data['target-dir'] = $this->getTargetDir();
  240. }
  241. if ($this->getIncludePaths()) {
  242. $data['include-path'] = $this->getIncludePaths();
  243. }
  244. if ($this->getBinaries()) {
  245. $data['bin'] = $this->getBinaries();
  246. }
  247. $supportedLinkTypes = array(
  248. 'require' => 'require',
  249. 'devRequire' => 'require-dev',
  250. 'suggest' => 'suggest',
  251. 'conflict' => 'conflict',
  252. 'provide' => 'provide',
  253. 'replace' => 'replace',
  254. );
  255. foreach ($supportedLinkTypes as $method => $linkType) {
  256. if (isset($versionData[$this->id][$method])) {
  257. foreach ($versionData[$this->id][$method] as $link) {
  258. $data[$linkType][$link['name']] = $link['version'];
  259. }
  260. continue;
  261. }
  262. foreach ($this->{'get'.$method}() as $link) {
  263. $link = $link->toArray();
  264. $data[$linkType][key($link)] = current($link);
  265. }
  266. }
  267. if ($this->getPackage()->isAbandoned()) {
  268. $data['abandoned'] = $this->getPackage()->getReplacementPackage() ?: true;
  269. }
  270. return $data;
  271. }
  272. public function toV2Array(array $versionData)
  273. {
  274. $array = $this->toArray($versionData);
  275. if ($this->getSupport()) {
  276. $array['support'] = $this->getSupport();
  277. ksort($array['support']);
  278. }
  279. return $array;
  280. }
  281. public function equals(Version $version)
  282. {
  283. return strtolower($version->getName()) === strtolower($this->getName())
  284. && strtolower($version->getNormalizedVersion()) === strtolower($this->getNormalizedVersion());
  285. }
  286. /**
  287. * Get id
  288. *
  289. * @return string $id
  290. */
  291. public function getId()
  292. {
  293. return $this->id;
  294. }
  295. /**
  296. * Set name
  297. *
  298. * @param string $name
  299. */
  300. public function setName($name)
  301. {
  302. $this->name = $name;
  303. }
  304. /**
  305. * Get name
  306. *
  307. * @return string $name
  308. */
  309. public function getName()
  310. {
  311. return $this->name;
  312. }
  313. public function getNames(array $versionData = null)
  314. {
  315. $names = array(
  316. strtolower($this->name) => true
  317. );
  318. if (isset($versionData[$this->id])) {
  319. foreach (($versionData[$this->id]['replace'] ?? []) as $link) {
  320. $names[strtolower($link['name'])] = true;
  321. }
  322. foreach (($versionData[$this->id]['provide'] ?? []) as $link) {
  323. $names[strtolower($link['name'])] = true;
  324. }
  325. } else {
  326. foreach ($this->getReplace() as $link) {
  327. $names[strtolower($link->getPackageName())] = true;
  328. }
  329. foreach ($this->getProvide() as $link) {
  330. $names[strtolower($link->getPackageName())] = true;
  331. }
  332. }
  333. return array_keys($names);
  334. }
  335. /**
  336. * Set description
  337. *
  338. * @param string $description
  339. */
  340. public function setDescription($description)
  341. {
  342. $this->description = $description;
  343. }
  344. /**
  345. * Get description
  346. *
  347. * @return string $description
  348. */
  349. public function getDescription()
  350. {
  351. return $this->description;
  352. }
  353. /**
  354. * Set homepage
  355. *
  356. * @param string $homepage
  357. */
  358. public function setHomepage($homepage)
  359. {
  360. $this->homepage = $homepage;
  361. }
  362. /**
  363. * Get homepage
  364. *
  365. * @return string $homepage
  366. */
  367. public function getHomepage()
  368. {
  369. return $this->homepage;
  370. }
  371. /**
  372. * Set version
  373. *
  374. * @param string $version
  375. */
  376. public function setVersion($version)
  377. {
  378. $this->version = $version;
  379. }
  380. /**
  381. * Get version
  382. *
  383. * @return string $version
  384. */
  385. public function getVersion()
  386. {
  387. return $this->version;
  388. }
  389. /**
  390. * @return string
  391. */
  392. public function getRequireVersion()
  393. {
  394. return preg_replace('{^v(\d)}', '$1', str_replace('.x-dev', '.*@dev', $this->getVersion()));
  395. }
  396. /**
  397. * Set normalizedVersion
  398. *
  399. * @param string $normalizedVersion
  400. */
  401. public function setNormalizedVersion($normalizedVersion)
  402. {
  403. $this->normalizedVersion = $normalizedVersion;
  404. }
  405. /**
  406. * Get normalizedVersion
  407. *
  408. * @return string $normalizedVersion
  409. */
  410. public function getNormalizedVersion()
  411. {
  412. return $this->normalizedVersion;
  413. }
  414. /**
  415. * Set license
  416. *
  417. * @param array $license
  418. */
  419. public function setLicense(array $license)
  420. {
  421. $this->license = json_encode($license);
  422. }
  423. /**
  424. * Get license
  425. *
  426. * @return array $license
  427. */
  428. public function getLicense()
  429. {
  430. return json_decode($this->license, true);
  431. }
  432. /**
  433. * Set source
  434. *
  435. * @param array $source
  436. */
  437. public function setSource($source)
  438. {
  439. $this->source = null === $source ? $source : json_encode($source);
  440. }
  441. /**
  442. * Get source
  443. *
  444. * @return array|null
  445. */
  446. public function getSource()
  447. {
  448. return json_decode($this->source, true);
  449. }
  450. /**
  451. * Set dist
  452. *
  453. * @param array $dist
  454. */
  455. public function setDist($dist)
  456. {
  457. $this->dist = null === $dist ? $dist : json_encode($dist);
  458. }
  459. /**
  460. * Get dist
  461. *
  462. * @return array|null
  463. */
  464. public function getDist()
  465. {
  466. return json_decode($this->dist, true);
  467. }
  468. /**
  469. * Set autoload
  470. *
  471. * @param array $autoload
  472. */
  473. public function setAutoload($autoload)
  474. {
  475. $this->autoload = json_encode($autoload);
  476. }
  477. /**
  478. * Get autoload
  479. *
  480. * @return array|null
  481. */
  482. public function getAutoload()
  483. {
  484. return json_decode($this->autoload, true);
  485. }
  486. /**
  487. * Set binaries
  488. *
  489. * @param array $binaries
  490. */
  491. public function setBinaries($binaries)
  492. {
  493. $this->binaries = null === $binaries ? $binaries : json_encode($binaries);
  494. }
  495. /**
  496. * Get binaries
  497. *
  498. * @return array|null
  499. */
  500. public function getBinaries()
  501. {
  502. return json_decode($this->binaries, true);
  503. }
  504. /**
  505. * Set include paths.
  506. *
  507. * @param array $paths
  508. */
  509. public function setIncludePaths($paths)
  510. {
  511. $this->includePaths = $paths ? json_encode($paths) : null;
  512. }
  513. /**
  514. * Get include paths.
  515. *
  516. * @return array|null
  517. */
  518. public function getIncludePaths()
  519. {
  520. return json_decode($this->includePaths, true);
  521. }
  522. /**
  523. * Set support
  524. *
  525. * @param array $support
  526. */
  527. public function setSupport($support)
  528. {
  529. $this->support = $support ? json_encode($support) : null;
  530. }
  531. /**
  532. * Get support
  533. *
  534. * @return array|null
  535. */
  536. public function getSupport()
  537. {
  538. return json_decode($this->support, true);
  539. }
  540. /**
  541. * Set createdAt
  542. *
  543. * @param \DateTime $createdAt
  544. */
  545. public function setCreatedAt($createdAt)
  546. {
  547. $this->createdAt = $createdAt;
  548. }
  549. /**
  550. * Get createdAt
  551. *
  552. * @return \DateTime
  553. */
  554. public function getCreatedAt()
  555. {
  556. return $this->createdAt;
  557. }
  558. /**
  559. * Set releasedAt
  560. *
  561. * @param \DateTime $releasedAt
  562. */
  563. public function setReleasedAt($releasedAt)
  564. {
  565. $this->releasedAt = $releasedAt;
  566. }
  567. /**
  568. * Get releasedAt
  569. *
  570. * @return \DateTime
  571. */
  572. public function getReleasedAt()
  573. {
  574. return $this->releasedAt;
  575. }
  576. /**
  577. * Set package
  578. *
  579. * @param Package $package
  580. */
  581. public function setPackage(Package $package)
  582. {
  583. $this->package = $package;
  584. }
  585. /**
  586. * Get package
  587. *
  588. * @return Package
  589. */
  590. public function getPackage()
  591. {
  592. return $this->package;
  593. }
  594. /**
  595. * Get tags
  596. *
  597. * @return Tag[]
  598. */
  599. public function getTags()
  600. {
  601. return $this->tags;
  602. }
  603. /**
  604. * Set updatedAt
  605. *
  606. * @param \DateTime $updatedAt
  607. */
  608. public function setUpdatedAt($updatedAt)
  609. {
  610. $this->updatedAt = $updatedAt;
  611. }
  612. /**
  613. * Get updatedAt
  614. *
  615. * @return \DateTime $updatedAt
  616. */
  617. public function getUpdatedAt()
  618. {
  619. return $this->updatedAt;
  620. }
  621. /**
  622. * Set softDeletedAt
  623. *
  624. * @param \DateTime|null $softDeletedAt
  625. */
  626. public function setSoftDeletedAt($softDeletedAt)
  627. {
  628. $this->softDeletedAt = $softDeletedAt;
  629. }
  630. /**
  631. * Get softDeletedAt
  632. *
  633. * @return \DateTime|null $softDeletedAt
  634. */
  635. public function getSoftDeletedAt()
  636. {
  637. return $this->softDeletedAt;
  638. }
  639. /**
  640. * Get authors
  641. *
  642. * @return Author[]
  643. */
  644. public function getAuthors()
  645. {
  646. return $this->authors;
  647. }
  648. public function getAuthorJson(): ?array
  649. {
  650. return $this->authorJson;
  651. }
  652. public function setAuthorJson(?array $authors): void
  653. {
  654. $this->authorJson = $authors ?: [];
  655. }
  656. /**
  657. * Get authors
  658. *
  659. * @return array[]
  660. */
  661. public function getAuthorData(): array
  662. {
  663. if (!is_null($this->getAuthorJson())) {
  664. return $this->getAuthorJson();
  665. }
  666. $authors = [];
  667. foreach ($this->getAuthors() as $author) {
  668. $authors[] = array_filter([
  669. 'name' => $author->getName(),
  670. 'homepage' => $author->getHomepage(),
  671. 'email' => $author->getEmail(),
  672. 'role' => $author->getRole(),
  673. ]);
  674. }
  675. return $authors;
  676. }
  677. /**
  678. * Set type
  679. *
  680. * @param string $type
  681. */
  682. public function setType($type)
  683. {
  684. $this->type = $type;
  685. }
  686. /**
  687. * Get type
  688. *
  689. * @return string
  690. */
  691. public function getType()
  692. {
  693. return $this->type;
  694. }
  695. /**
  696. * Set targetDir
  697. *
  698. * @param string $targetDir
  699. */
  700. public function setTargetDir($targetDir)
  701. {
  702. $this->targetDir = $targetDir;
  703. }
  704. /**
  705. * Get targetDir
  706. *
  707. * @return string
  708. */
  709. public function getTargetDir()
  710. {
  711. return $this->targetDir;
  712. }
  713. /**
  714. * Set extra
  715. *
  716. * @param array $extra
  717. */
  718. public function setExtra($extra)
  719. {
  720. $this->extra = $extra;
  721. }
  722. /**
  723. * Get extra
  724. *
  725. * @return array
  726. */
  727. public function getExtra()
  728. {
  729. return $this->extra;
  730. }
  731. /**
  732. * Set development
  733. *
  734. * @param Boolean $development
  735. */
  736. public function setDevelopment($development)
  737. {
  738. $this->development = $development;
  739. }
  740. /**
  741. * Get development
  742. *
  743. * @return Boolean
  744. */
  745. public function getDevelopment()
  746. {
  747. return $this->development;
  748. }
  749. /**
  750. * @return Boolean
  751. */
  752. public function isDevelopment()
  753. {
  754. return $this->getDevelopment();
  755. }
  756. /**
  757. * Add tag
  758. *
  759. * @param Tag $tag
  760. */
  761. public function addTag(Tag $tag)
  762. {
  763. $this->tags[] = $tag;
  764. }
  765. /**
  766. * Add authors
  767. *
  768. * @param Author $author
  769. */
  770. public function addAuthor(Author $author)
  771. {
  772. $this->authors[] = $author;
  773. }
  774. /**
  775. * Add require
  776. *
  777. * @param RequireLink $require
  778. */
  779. public function addRequireLink(RequireLink $require)
  780. {
  781. $this->require[] = $require;
  782. }
  783. /**
  784. * Get require
  785. *
  786. * @return RequireLink[]
  787. */
  788. public function getRequire()
  789. {
  790. return $this->require;
  791. }
  792. /**
  793. * Add replace
  794. *
  795. * @param ReplaceLink $replace
  796. */
  797. public function addReplaceLink(ReplaceLink $replace)
  798. {
  799. $this->replace[] = $replace;
  800. }
  801. /**
  802. * Get replace
  803. *
  804. * @return ReplaceLink[]
  805. */
  806. public function getReplace()
  807. {
  808. return $this->replace;
  809. }
  810. /**
  811. * Add conflict
  812. *
  813. * @param ConflictLink $conflict
  814. */
  815. public function addConflictLink(ConflictLink $conflict)
  816. {
  817. $this->conflict[] = $conflict;
  818. }
  819. /**
  820. * Get conflict
  821. *
  822. * @return ConflictLink[]
  823. */
  824. public function getConflict()
  825. {
  826. return $this->conflict;
  827. }
  828. /**
  829. * Add provide
  830. *
  831. * @param ProvideLink $provide
  832. */
  833. public function addProvideLink(ProvideLink $provide)
  834. {
  835. $this->provide[] = $provide;
  836. }
  837. /**
  838. * Get provide
  839. *
  840. * @return ProvideLink[]
  841. */
  842. public function getProvide()
  843. {
  844. return $this->provide;
  845. }
  846. /**
  847. * Add devRequire
  848. *
  849. * @param DevRequireLink $devRequire
  850. */
  851. public function addDevRequireLink(DevRequireLink $devRequire)
  852. {
  853. $this->devRequire[] = $devRequire;
  854. }
  855. /**
  856. * Get devRequire
  857. *
  858. * @return DevRequireLink[]
  859. */
  860. public function getDevRequire()
  861. {
  862. return $this->devRequire;
  863. }
  864. /**
  865. * Add suggest
  866. *
  867. * @param SuggestLink $suggest
  868. */
  869. public function addSuggestLink(SuggestLink $suggest)
  870. {
  871. $this->suggest[] = $suggest;
  872. }
  873. /**
  874. * Get suggest
  875. *
  876. * @return SuggestLink[]
  877. */
  878. public function getSuggest()
  879. {
  880. return $this->suggest;
  881. }
  882. /**
  883. * @return Boolean
  884. */
  885. public function hasVersionAlias()
  886. {
  887. return $this->getDevelopment() && $this->getVersionAlias();
  888. }
  889. /**
  890. * @return string
  891. */
  892. public function getVersionAlias()
  893. {
  894. $extra = $this->getExtra();
  895. if (isset($extra['branch-alias'][$this->getVersion()])) {
  896. $parser = new VersionParser;
  897. $version = $parser->normalizeBranch(str_replace('-dev', '', $extra['branch-alias'][$this->getVersion()]));
  898. return preg_replace('{(\.9{7})+}', '.x', $version);
  899. }
  900. return '';
  901. }
  902. /**
  903. * @return string
  904. */
  905. public function getRequireVersionAlias()
  906. {
  907. return str_replace('.x-dev', '.*@dev', $this->getVersionAlias());
  908. }
  909. public function __toString()
  910. {
  911. return $this->name.' '.$this->version.' ('.$this->normalizedVersion.')';
  912. }
  913. private function sortAuthorKeys($a, $b)
  914. {
  915. static $order = ['name' => 1, 'email' => 2, 'homepage' => 3, 'role' => 4];
  916. $aIndex = $order[$a] ?? 5;
  917. $bIndex = $order[$b] ?? 5;
  918. if ($aIndex === $bIndex) {
  919. return $a <=> $b;
  920. }
  921. return $aIndex <=> $bIndex;
  922. }
  923. public function getMajorVersion(): int
  924. {
  925. return (int) explode('.', $this->normalizedVersion, 2)[0];
  926. }
  927. }