123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- <?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 Doctrine\DBAL\Connection;
- use Predis\Client;
- use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
- use Symfony\Bridge\Doctrine\RegistryInterface;
- /**
- * @author Jordi Boggiano <j.boggiano@seld.be>
- */
- class VersionRepository extends ServiceEntityRepository
- {
- private $redis;
- protected $supportedLinkTypes = array(
- 'require',
- 'conflict',
- 'provide',
- 'replace',
- 'devRequire',
- 'suggest',
- );
- public function __construct(RegistryInterface $registry, Client $redisCache)
- {
- parent::__construct($registry, Version::class);
- $this->redis = $redisCache;
- }
- public function remove(Version $version)
- {
- $em = $this->getEntityManager();
- $version->getPackage()->getVersions()->removeElement($version);
- $version->getPackage()->setCrawledAt(new \DateTime);
- $version->getPackage()->setUpdatedAt(new \DateTime);
- $em->getConnection()->executeQuery('DELETE FROM version_author WHERE version_id=:id', array('id' => $version->getId()));
- $em->getConnection()->executeQuery('DELETE FROM version_tag WHERE version_id=:id', array('id' => $version->getId()));
- $em->getConnection()->executeQuery('DELETE FROM link_suggest WHERE version_id=:id', array('id' => $version->getId()));
- $em->getConnection()->executeQuery('DELETE FROM link_conflict WHERE version_id=:id', array('id' => $version->getId()));
- $em->getConnection()->executeQuery('DELETE FROM link_replace WHERE version_id=:id', array('id' => $version->getId()));
- $em->getConnection()->executeQuery('DELETE FROM link_provide WHERE version_id=:id', array('id' => $version->getId()));
- $em->getConnection()->executeQuery('DELETE FROM link_require_dev WHERE version_id=:id', array('id' => $version->getId()));
- $em->getConnection()->executeQuery('DELETE FROM link_require WHERE version_id=:id', array('id' => $version->getId()));
- $em->getConnection()->executeQuery('DELETE FROM download WHERE id=:id AND type = :type', ['id' => $version->getId(), 'type' => Download::TYPE_VERSION]);
- $em->remove($version);
- }
- public function refreshVersions($versions)
- {
- $versionIds = [];
- foreach ($versions as $version) {
- $versionIds[] = $version->getId();
- $this->getEntityManager()->detach($version);
- }
- $refreshedVersions = $this->findBy(['id' => $versionIds]);
- $versionsById = [];
- foreach ($refreshedVersions as $version) {
- $versionsById[$version->getId()] = $version;
- }
- $refreshedVersions = [];
- foreach ($versions as $version) {
- $refreshedVersions[] = $versionsById[$version->getId()];
- }
- return $refreshedVersions;
- }
- /**
- * @param Version[] $versions
- */
- public function detachToArray(array $versions, array $versionData, bool $serializeForApi = false): array
- {
- $res = [];
- $em = $this->getEntityManager();
- foreach ($versions as $version) {
- $res[$version->getVersion()] = $version->toArray($versionData, $serializeForApi);
- $em->detach($version);
- }
- return $res;
- }
- public function getVersionData(array $versionIds)
- {
- $links = [
- 'require' => 'link_require',
- 'devRequire' => 'link_require_dev',
- 'suggest' => 'link_suggest',
- 'conflict' => 'link_conflict',
- 'provide' => 'link_provide',
- 'replace' => 'link_replace',
- ];
- $result = [];
- foreach ($versionIds as $id) {
- $result[$id] = [
- 'require' => [],
- 'devRequire' => [],
- 'suggest' => [],
- 'conflict' => [],
- 'provide' => [],
- 'replace' => [],
- 'authors' => [],
- 'tags' => [],
- ];
- }
- foreach ($links as $link => $table) {
- $rows = $this->getEntityManager()->getConnection()->fetchAll(
- 'SELECT version_id, packageName name, packageVersion version FROM '.$table.' WHERE version_id IN (:ids)',
- ['ids' => $versionIds],
- ['ids' => Connection::PARAM_INT_ARRAY]
- );
- foreach ($rows as $row) {
- $result[$row['version_id']][$link][] = $row;
- }
- }
- $rows = $this->getEntityManager()->getConnection()->fetchAll(
- 'SELECT va.version_id, name, email, homepage, role FROM author a JOIN version_author va ON va.author_id = a.id WHERE va.version_id IN (:ids)',
- ['ids' => $versionIds],
- ['ids' => Connection::PARAM_INT_ARRAY]
- );
- foreach ($rows as $row) {
- $versionId = $row['version_id'];
- unset($row['version_id']);
- $result[$versionId]['authors'][] = array_filter($row);
- }
- $rows = $this->getEntityManager()->getConnection()->fetchAll(
- 'SELECT vt.version_id, name FROM tag t JOIN version_tag vt ON vt.tag_id = t.id WHERE vt.version_id IN (:ids)',
- ['ids' => $versionIds],
- ['ids' => Connection::PARAM_INT_ARRAY]
- );
- foreach ($rows as $row) {
- $versionId = $row['version_id'];
- $result[$versionId]['tags'][] = $row['name'];
- }
- return $result;
- }
- public function getVersionMetadataForUpdate(Package $package)
- {
- $rows = $this->getEntityManager()->getConnection()->fetchAll(
- 'SELECT id, version, normalizedVersion, source, softDeletedAt, `authors` IS NULL as needs_author_migration FROM package_version v WHERE v.package_id = :id',
- ['id' => $package->getId()]
- );
- $versions = [];
- foreach ($rows as $row) {
- if ($row['source']) {
- $row['source'] = json_decode($row['source'], true);
- }
- $row['needs_author_migration'] = (int) $row['needs_author_migration'];
- $versions[strtolower($row['normalizedVersion'])] = $row;
- }
- return $versions;
- }
- public function getFullVersion($versionId)
- {
- $qb = $this->getEntityManager()->createQueryBuilder();
- $qb->select('v', 't', 'a')
- ->from('Packagist\WebBundle\Entity\Version', 'v')
- ->leftJoin('v.tags', 't')
- ->leftJoin('v.authors', 'a')
- ->where('v.id = :id')
- ->setParameter('id', $versionId);
- return $qb->getQuery()->getSingleResult();
- }
- /**
- * Returns the latest versions released
- *
- * @param string $vendor optional vendor filter
- * @param string $package optional vendor/package filter
- * @return \Doctrine\ORM\QueryBuilder
- */
- public function getQueryBuilderForLatestVersionWithPackage($vendor = null, $package = null)
- {
- $qb = $this->getEntityManager()->createQueryBuilder();
- $qb->select('v')
- ->from('Packagist\WebBundle\Entity\Version', 'v')
- ->where('v.development = false')
- ->andWhere('v.releasedAt <= ?0')
- ->orderBy('v.releasedAt', 'DESC');
- $qb->setParameter(0, date('Y-m-d H:i:s'));
- if ($vendor || $package) {
- $qb->innerJoin('v.package', 'p')
- ->addSelect('p');
- }
- if ($vendor) {
- $qb->andWhere('p.name LIKE ?1');
- $qb->setParameter(1, $vendor.'/%');
- } elseif ($package) {
- $qb->andWhere('p.name = ?1')
- ->setParameter(1, $package);
- }
- return $qb;
- }
- public function getLatestReleases($count = 10)
- {
- if ($cached = $this->redis->get('new_releases')) {
- return json_decode($cached, true);
- }
- $qb = $this->getEntityManager()->createQueryBuilder();
- $qb->select('v.name, v.version, v.description')
- ->from('Packagist\WebBundle\Entity\Version', 'v')
- ->where('v.development = false')
- ->andWhere('v.releasedAt < :now')
- ->orderBy('v.releasedAt', 'DESC')
- ->setMaxResults($count)
- ->setParameter('now', date('Y-m-d H:i:s'));
- $res = $qb->getQuery()->getResult();
- $this->redis->setex('new_releases', 600, json_encode($res));
- return $res;
- }
- }
|