Version.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092
  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(type="json", nullable=true)
  154. */
  155. private $funding;
  156. /**
  157. * @ORM\Column(name="authors", type="json", nullable=true)
  158. */
  159. private $authorJson;
  160. /**
  161. * @ORM\Column(type="datetime")
  162. */
  163. private $createdAt;
  164. /**
  165. * @ORM\Column(type="datetime", nullable=true)
  166. */
  167. private $softDeletedAt;
  168. /**
  169. * @ORM\Column(type="datetime")
  170. */
  171. private $updatedAt;
  172. /**
  173. * @ORM\Column(type="datetime", nullable=true)
  174. */
  175. private $releasedAt;
  176. public function __construct()
  177. {
  178. $this->tags = new ArrayCollection();
  179. $this->require = new ArrayCollection();
  180. $this->replace = new ArrayCollection();
  181. $this->conflict = new ArrayCollection();
  182. $this->provide = new ArrayCollection();
  183. $this->devRequire = new ArrayCollection();
  184. $this->suggest = new ArrayCollection();
  185. $this->authors = new ArrayCollection();
  186. $this->createdAt = new \DateTime;
  187. $this->updatedAt = new \DateTime;
  188. }
  189. public function toArray(array $versionData, bool $serializeForApi = false)
  190. {
  191. if (isset($versionData[$this->id]['tags'])) {
  192. $tags = $versionData[$this->id]['tags'];
  193. } else {
  194. $tags = array();
  195. foreach ($this->getTags() as $tag) {
  196. /** @var $tag Tag */
  197. $tags[] = $tag->getName();
  198. }
  199. }
  200. if (!is_null($this->getAuthorJson())) {
  201. $authors = $this->getAuthorJson();
  202. } else {
  203. if (isset($versionData[$this->id]['authors'])) {
  204. $authors = $versionData[$this->id]['authors'];
  205. } else {
  206. $authors = array();
  207. foreach ($this->getAuthors() as $author) {
  208. /** @var $author Author */
  209. $authors[] = $author->toArray();
  210. }
  211. }
  212. }
  213. foreach ($authors as &$author) {
  214. uksort($author, [$this, 'sortAuthorKeys']);
  215. }
  216. unset($author);
  217. $data = array(
  218. 'name' => $this->getName(),
  219. 'description' => (string) $this->getDescription(),
  220. 'keywords' => $tags,
  221. 'homepage' => (string) $this->getHomepage(),
  222. 'version' => $this->getVersion(),
  223. 'version_normalized' => $this->getNormalizedVersion(),
  224. 'license' => $this->getLicense(),
  225. 'authors' => $authors,
  226. 'source' => $this->getSource(),
  227. 'dist' => $this->getDist(),
  228. 'type' => $this->getType(),
  229. );
  230. if ($serializeForApi && $this->getSupport()) {
  231. $data['support'] = $this->getSupport();
  232. }
  233. if ($this->getFunding()) {
  234. $data['funding'] = $this->getFunding();
  235. }
  236. if ($this->getReleasedAt()) {
  237. $data['time'] = $this->getReleasedAt()->format('Y-m-d\TH:i:sP');
  238. }
  239. if ($this->getAutoload()) {
  240. $data['autoload'] = $this->getAutoload();
  241. }
  242. if ($this->getExtra()) {
  243. $data['extra'] = $this->getExtra();
  244. }
  245. if ($this->getTargetDir()) {
  246. $data['target-dir'] = $this->getTargetDir();
  247. }
  248. if ($this->getIncludePaths()) {
  249. $data['include-path'] = $this->getIncludePaths();
  250. }
  251. if ($this->getBinaries()) {
  252. $data['bin'] = $this->getBinaries();
  253. }
  254. $supportedLinkTypes = array(
  255. 'require' => 'require',
  256. 'devRequire' => 'require-dev',
  257. 'suggest' => 'suggest',
  258. 'conflict' => 'conflict',
  259. 'provide' => 'provide',
  260. 'replace' => 'replace',
  261. );
  262. foreach ($supportedLinkTypes as $method => $linkType) {
  263. if (isset($versionData[$this->id][$method])) {
  264. foreach ($versionData[$this->id][$method] as $link) {
  265. $data[$linkType][$link['name']] = $link['version'];
  266. }
  267. continue;
  268. }
  269. foreach ($this->{'get'.$method}() as $link) {
  270. $link = $link->toArray();
  271. $data[$linkType][key($link)] = current($link);
  272. }
  273. }
  274. if ($this->getPackage()->isAbandoned()) {
  275. $data['abandoned'] = $this->getPackage()->getReplacementPackage() ?: true;
  276. }
  277. return $data;
  278. }
  279. public function toV2Array(array $versionData)
  280. {
  281. $array = $this->toArray($versionData);
  282. if ($this->getSupport()) {
  283. $array['support'] = $this->getSupport();
  284. ksort($array['support']);
  285. }
  286. return $array;
  287. }
  288. public function equals(Version $version)
  289. {
  290. return strtolower($version->getName()) === strtolower($this->getName())
  291. && strtolower($version->getNormalizedVersion()) === strtolower($this->getNormalizedVersion());
  292. }
  293. /**
  294. * Get id
  295. *
  296. * @return string $id
  297. */
  298. public function getId()
  299. {
  300. return $this->id;
  301. }
  302. /**
  303. * Set name
  304. *
  305. * @param string $name
  306. */
  307. public function setName($name)
  308. {
  309. $this->name = $name;
  310. }
  311. /**
  312. * Get name
  313. *
  314. * @return string $name
  315. */
  316. public function getName()
  317. {
  318. return $this->name;
  319. }
  320. public function getNames(array $versionData = null)
  321. {
  322. $names = array(
  323. strtolower($this->name) => true
  324. );
  325. if (isset($versionData[$this->id])) {
  326. foreach (($versionData[$this->id]['replace'] ?? []) as $link) {
  327. $names[strtolower($link['name'])] = true;
  328. }
  329. foreach (($versionData[$this->id]['provide'] ?? []) as $link) {
  330. $names[strtolower($link['name'])] = true;
  331. }
  332. } else {
  333. foreach ($this->getReplace() as $link) {
  334. $names[strtolower($link->getPackageName())] = true;
  335. }
  336. foreach ($this->getProvide() as $link) {
  337. $names[strtolower($link->getPackageName())] = true;
  338. }
  339. }
  340. return array_keys($names);
  341. }
  342. /**
  343. * Set description
  344. *
  345. * @param string $description
  346. */
  347. public function setDescription($description)
  348. {
  349. $this->description = $description;
  350. }
  351. /**
  352. * Get description
  353. *
  354. * @return string $description
  355. */
  356. public function getDescription()
  357. {
  358. return $this->description;
  359. }
  360. /**
  361. * Set homepage
  362. *
  363. * @param string $homepage
  364. */
  365. public function setHomepage($homepage)
  366. {
  367. $this->homepage = $homepage;
  368. }
  369. /**
  370. * Get homepage
  371. *
  372. * @return string $homepage
  373. */
  374. public function getHomepage()
  375. {
  376. return $this->homepage;
  377. }
  378. /**
  379. * Set version
  380. *
  381. * @param string $version
  382. */
  383. public function setVersion($version)
  384. {
  385. $this->version = $version;
  386. }
  387. /**
  388. * Get version
  389. *
  390. * @return string $version
  391. */
  392. public function getVersion()
  393. {
  394. return $this->version;
  395. }
  396. /**
  397. * @return string
  398. */
  399. public function getRequireVersion()
  400. {
  401. return preg_replace('{^v(\d)}', '$1', str_replace('.x-dev', '.*@dev', $this->getVersion()));
  402. }
  403. /**
  404. * Set normalizedVersion
  405. *
  406. * @param string $normalizedVersion
  407. */
  408. public function setNormalizedVersion($normalizedVersion)
  409. {
  410. $this->normalizedVersion = $normalizedVersion;
  411. }
  412. /**
  413. * Get normalizedVersion
  414. *
  415. * @return string $normalizedVersion
  416. */
  417. public function getNormalizedVersion()
  418. {
  419. return $this->normalizedVersion;
  420. }
  421. /**
  422. * Set license
  423. *
  424. * @param array $license
  425. */
  426. public function setLicense(array $license)
  427. {
  428. $this->license = json_encode($license);
  429. }
  430. /**
  431. * Get license
  432. *
  433. * @return array $license
  434. */
  435. public function getLicense()
  436. {
  437. return json_decode($this->license, true);
  438. }
  439. /**
  440. * Set source
  441. *
  442. * @param array $source
  443. */
  444. public function setSource($source)
  445. {
  446. $this->source = null === $source ? $source : json_encode($source);
  447. }
  448. /**
  449. * Get source
  450. *
  451. * @return array|null
  452. */
  453. public function getSource()
  454. {
  455. return json_decode($this->source, true);
  456. }
  457. /**
  458. * Set dist
  459. *
  460. * @param array $dist
  461. */
  462. public function setDist($dist)
  463. {
  464. $this->dist = null === $dist ? $dist : json_encode($dist);
  465. }
  466. /**
  467. * Get dist
  468. *
  469. * @return array|null
  470. */
  471. public function getDist()
  472. {
  473. return json_decode($this->dist, true);
  474. }
  475. /**
  476. * Set autoload
  477. *
  478. * @param array $autoload
  479. */
  480. public function setAutoload($autoload)
  481. {
  482. $this->autoload = json_encode($autoload);
  483. }
  484. /**
  485. * Get autoload
  486. *
  487. * @return array|null
  488. */
  489. public function getAutoload()
  490. {
  491. return json_decode($this->autoload, true);
  492. }
  493. /**
  494. * Set binaries
  495. *
  496. * @param array $binaries
  497. */
  498. public function setBinaries($binaries)
  499. {
  500. $this->binaries = null === $binaries ? $binaries : json_encode($binaries);
  501. }
  502. /**
  503. * Get binaries
  504. *
  505. * @return array|null
  506. */
  507. public function getBinaries()
  508. {
  509. return json_decode($this->binaries, true);
  510. }
  511. /**
  512. * Set include paths.
  513. *
  514. * @param array $paths
  515. */
  516. public function setIncludePaths($paths)
  517. {
  518. $this->includePaths = $paths ? json_encode($paths) : null;
  519. }
  520. /**
  521. * Get include paths.
  522. *
  523. * @return array|null
  524. */
  525. public function getIncludePaths()
  526. {
  527. return json_decode($this->includePaths, true);
  528. }
  529. /**
  530. * Set support
  531. *
  532. * @param array $support
  533. */
  534. public function setSupport($support)
  535. {
  536. $this->support = $support ? json_encode($support) : null;
  537. }
  538. /**
  539. * Get support
  540. *
  541. * @return array|null
  542. */
  543. public function getSupport()
  544. {
  545. return json_decode($this->support, true);
  546. }
  547. /**
  548. * Set Funding
  549. *
  550. * @param array $funding
  551. */
  552. public function setFunding($funding)
  553. {
  554. // sort records when storing so to help the V2 metadata compression algo
  555. if ($funding) {
  556. usort($funding, function ($a, $b) {
  557. $keyA = ($a['type'] ?? '') . ($a['url'] ?? '');
  558. $keyB = ($b['type'] ?? '') . ($b['url'] ?? '');
  559. return $keyA <=> $keyB;
  560. });
  561. }
  562. $this->funding = $funding;
  563. }
  564. /**
  565. * Get funding
  566. *
  567. * @return array|null
  568. */
  569. public function getFunding()
  570. {
  571. return $this->funding;
  572. }
  573. /**
  574. * Set createdAt
  575. *
  576. * @param \DateTime $createdAt
  577. */
  578. public function setCreatedAt($createdAt)
  579. {
  580. $this->createdAt = $createdAt;
  581. }
  582. /**
  583. * Get createdAt
  584. *
  585. * @return \DateTime
  586. */
  587. public function getCreatedAt()
  588. {
  589. return $this->createdAt;
  590. }
  591. /**
  592. * Set releasedAt
  593. *
  594. * @param \DateTime $releasedAt
  595. */
  596. public function setReleasedAt($releasedAt)
  597. {
  598. $this->releasedAt = $releasedAt;
  599. }
  600. /**
  601. * Get releasedAt
  602. *
  603. * @return \DateTime
  604. */
  605. public function getReleasedAt()
  606. {
  607. return $this->releasedAt;
  608. }
  609. /**
  610. * Set package
  611. *
  612. * @param Package $package
  613. */
  614. public function setPackage(Package $package)
  615. {
  616. $this->package = $package;
  617. }
  618. /**
  619. * Get package
  620. *
  621. * @return Package
  622. */
  623. public function getPackage()
  624. {
  625. return $this->package;
  626. }
  627. /**
  628. * Get tags
  629. *
  630. * @return Tag[]
  631. */
  632. public function getTags()
  633. {
  634. return $this->tags;
  635. }
  636. /**
  637. * Set updatedAt
  638. *
  639. * @param \DateTime $updatedAt
  640. */
  641. public function setUpdatedAt($updatedAt)
  642. {
  643. $this->updatedAt = $updatedAt;
  644. }
  645. /**
  646. * Get updatedAt
  647. *
  648. * @return \DateTime $updatedAt
  649. */
  650. public function getUpdatedAt()
  651. {
  652. return $this->updatedAt;
  653. }
  654. /**
  655. * Set softDeletedAt
  656. *
  657. * @param \DateTime|null $softDeletedAt
  658. */
  659. public function setSoftDeletedAt($softDeletedAt)
  660. {
  661. $this->softDeletedAt = $softDeletedAt;
  662. }
  663. /**
  664. * Get softDeletedAt
  665. *
  666. * @return \DateTime|null $softDeletedAt
  667. */
  668. public function getSoftDeletedAt()
  669. {
  670. return $this->softDeletedAt;
  671. }
  672. /**
  673. * Get authors
  674. *
  675. * @return Author[]
  676. */
  677. public function getAuthors()
  678. {
  679. return $this->authors;
  680. }
  681. public function getAuthorJson(): ?array
  682. {
  683. return $this->authorJson;
  684. }
  685. public function setAuthorJson(?array $authors): void
  686. {
  687. $this->authorJson = $authors ?: [];
  688. }
  689. /**
  690. * Get authors
  691. *
  692. * @return array[]
  693. */
  694. public function getAuthorData(): array
  695. {
  696. if (!is_null($this->getAuthorJson())) {
  697. return $this->getAuthorJson();
  698. }
  699. $authors = [];
  700. foreach ($this->getAuthors() as $author) {
  701. $authors[] = array_filter([
  702. 'name' => $author->getName(),
  703. 'homepage' => $author->getHomepage(),
  704. 'email' => $author->getEmail(),
  705. 'role' => $author->getRole(),
  706. ]);
  707. }
  708. return $authors;
  709. }
  710. /**
  711. * Set type
  712. *
  713. * @param string $type
  714. */
  715. public function setType($type)
  716. {
  717. $this->type = $type;
  718. }
  719. /**
  720. * Get type
  721. *
  722. * @return string
  723. */
  724. public function getType()
  725. {
  726. return $this->type;
  727. }
  728. /**
  729. * Set targetDir
  730. *
  731. * @param string $targetDir
  732. */
  733. public function setTargetDir($targetDir)
  734. {
  735. $this->targetDir = $targetDir;
  736. }
  737. /**
  738. * Get targetDir
  739. *
  740. * @return string
  741. */
  742. public function getTargetDir()
  743. {
  744. return $this->targetDir;
  745. }
  746. /**
  747. * Set extra
  748. *
  749. * @param array $extra
  750. */
  751. public function setExtra($extra)
  752. {
  753. $this->extra = $extra;
  754. }
  755. /**
  756. * Get extra
  757. *
  758. * @return array
  759. */
  760. public function getExtra()
  761. {
  762. return $this->extra;
  763. }
  764. /**
  765. * Set development
  766. *
  767. * @param Boolean $development
  768. */
  769. public function setDevelopment($development)
  770. {
  771. $this->development = $development;
  772. }
  773. /**
  774. * Get development
  775. *
  776. * @return Boolean
  777. */
  778. public function getDevelopment()
  779. {
  780. return $this->development;
  781. }
  782. /**
  783. * @return Boolean
  784. */
  785. public function isDevelopment()
  786. {
  787. return $this->getDevelopment();
  788. }
  789. /**
  790. * Add tag
  791. *
  792. * @param Tag $tag
  793. */
  794. public function addTag(Tag $tag)
  795. {
  796. $this->tags[] = $tag;
  797. }
  798. /**
  799. * Add authors
  800. *
  801. * @param Author $author
  802. */
  803. public function addAuthor(Author $author)
  804. {
  805. $this->authors[] = $author;
  806. }
  807. /**
  808. * Add require
  809. *
  810. * @param RequireLink $require
  811. */
  812. public function addRequireLink(RequireLink $require)
  813. {
  814. $this->require[] = $require;
  815. }
  816. /**
  817. * Get require
  818. *
  819. * @return RequireLink[]
  820. */
  821. public function getRequire()
  822. {
  823. return $this->require;
  824. }
  825. /**
  826. * Add replace
  827. *
  828. * @param ReplaceLink $replace
  829. */
  830. public function addReplaceLink(ReplaceLink $replace)
  831. {
  832. $this->replace[] = $replace;
  833. }
  834. /**
  835. * Get replace
  836. *
  837. * @return ReplaceLink[]
  838. */
  839. public function getReplace()
  840. {
  841. return $this->replace;
  842. }
  843. /**
  844. * Add conflict
  845. *
  846. * @param ConflictLink $conflict
  847. */
  848. public function addConflictLink(ConflictLink $conflict)
  849. {
  850. $this->conflict[] = $conflict;
  851. }
  852. /**
  853. * Get conflict
  854. *
  855. * @return ConflictLink[]
  856. */
  857. public function getConflict()
  858. {
  859. return $this->conflict;
  860. }
  861. /**
  862. * Add provide
  863. *
  864. * @param ProvideLink $provide
  865. */
  866. public function addProvideLink(ProvideLink $provide)
  867. {
  868. $this->provide[] = $provide;
  869. }
  870. /**
  871. * Get provide
  872. *
  873. * @return ProvideLink[]
  874. */
  875. public function getProvide()
  876. {
  877. return $this->provide;
  878. }
  879. /**
  880. * Add devRequire
  881. *
  882. * @param DevRequireLink $devRequire
  883. */
  884. public function addDevRequireLink(DevRequireLink $devRequire)
  885. {
  886. $this->devRequire[] = $devRequire;
  887. }
  888. /**
  889. * Get devRequire
  890. *
  891. * @return DevRequireLink[]
  892. */
  893. public function getDevRequire()
  894. {
  895. return $this->devRequire;
  896. }
  897. /**
  898. * Add suggest
  899. *
  900. * @param SuggestLink $suggest
  901. */
  902. public function addSuggestLink(SuggestLink $suggest)
  903. {
  904. $this->suggest[] = $suggest;
  905. }
  906. /**
  907. * Get suggest
  908. *
  909. * @return SuggestLink[]
  910. */
  911. public function getSuggest()
  912. {
  913. return $this->suggest;
  914. }
  915. /**
  916. * @return Boolean
  917. */
  918. public function hasVersionAlias()
  919. {
  920. return $this->getDevelopment() && $this->getVersionAlias();
  921. }
  922. /**
  923. * @return string
  924. */
  925. public function getVersionAlias()
  926. {
  927. $extra = $this->getExtra();
  928. if (isset($extra['branch-alias'][$this->getVersion()])) {
  929. $parser = new VersionParser;
  930. $version = $parser->normalizeBranch(str_replace('-dev', '', $extra['branch-alias'][$this->getVersion()]));
  931. return preg_replace('{(\.9{7})+}', '.x', $version);
  932. }
  933. return '';
  934. }
  935. /**
  936. * @return string
  937. */
  938. public function getRequireVersionAlias()
  939. {
  940. return str_replace('.x-dev', '.*@dev', $this->getVersionAlias());
  941. }
  942. public function __toString()
  943. {
  944. return $this->name.' '.$this->version.' ('.$this->normalizedVersion.')';
  945. }
  946. private function sortAuthorKeys($a, $b)
  947. {
  948. static $order = ['name' => 1, 'email' => 2, 'homepage' => 3, 'role' => 4];
  949. $aIndex = $order[$a] ?? 5;
  950. $bIndex = $order[$b] ?? 5;
  951. if ($aIndex === $bIndex) {
  952. return $a <=> $b;
  953. }
  954. return $aIndex <=> $bIndex;
  955. }
  956. public function getMajorVersion(): int
  957. {
  958. return (int) explode('.', $this->normalizedVersion, 2)[0];
  959. }
  960. }