/** * @Route( * "/packages/{name}/unabandon", * name="unabandon_package", * requirements={"name"="[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+?"} * ) */ public function unabandonAction(Package $package) { if (!$package->getMaintainers()->contains($this->getUser()) && !$this->isGranted('ROLE_EDIT_PACKAGES')) { throw new AccessDeniedException(); } $package->setAbandoned(false); $package->setReplacementPackage(null); $package->setIndexedAt(null); $em = $this->getDoctrine()->getManager(); $em->flush(); return $this->redirect($this->generateUrl('view_package', array('name' => $package->getName()))); }
public function notifyUpdateFailure(Package $package, \Exception $e, $details = null) { if (!$package->isUpdateFailureNotified()) { $recipients = array(); foreach ($package->getMaintainers() as $maintainer) { if ($maintainer->isNotifiableForFailures()) { $recipients[$maintainer->getEmail()] = $maintainer->getUsername(); } } if ($recipients) { $body = $this->twig->render('PackagistWebBundle:Email:update_failed.txt.twig', array('package' => $package, 'exception' => get_class($e), 'exceptionMessage' => $e->getMessage(), 'details' => $details)); $message = \Swift_Message::newInstance()->setSubject($package->getName() . ' failed to update, invalid composer.json data')->setFrom($this->options['from'], $this->options['fromName'])->setTo($recipients)->setBody($body); try { $this->mailer->send($message); } catch (\Swift_TransportException $e) { $this->logger->error('[' . get_class($e) . '] ' . $e->getMessage()); return false; } } $package->setUpdateFailureNotified(true); $this->em->flush(); } return true; }
private function createDeletePackageForm(Package $package) { if (!($user = $this->getUser())) { return; } // super admins bypass additional checks if (!$this->isGranted('ROLE_DELETE_PACKAGES')) { // non maintainers can not delete if (!$package->getMaintainers()->contains($user)) { return; } try { $downloads = $this->get('packagist.download_manager')->getTotalDownloads($package); } catch (ConnectionException $e) { return; } // more than 100 downloads = established package, do not allow deletion by maintainers if ($downloads > 100) { return; } } return $this->createFormBuilder(array())->getForm(); }
/** * Update a project * * @param \Packagist\WebBundle\Entity\Package $package * @param RepositoryInterface $repository the repository instance used to update from * @param int $flags a few of the constants of this class * @param \DateTime $start */ public function update(IOInterface $io, Config $config, Package $package, RepositoryInterface $repository, $flags = 0, \DateTime $start = null) { $rfs = new RemoteFilesystem($io, $config); $blacklist = '{^symfony/symfony (2.0.[456]|dev-charset|dev-console)}i'; if (null === $start) { $start = new \DateTime(); } $pruneDate = clone $start; $pruneDate->modify('-1min'); $em = $this->doctrine->getManager(); $apc = extension_loaded('apcu'); if ($repository instanceof VcsRepository) { $cfg = $repository->getRepoConfig(); if (isset($cfg['url']) && preg_match('{\\bgithub\\.com\\b}', $cfg['url'])) { foreach ($package->getMaintainers() as $maintainer) { if (!($newGithubToken = $maintainer->getGithubToken())) { continue; } $valid = null; if ($apc) { $valid = apcu_fetch('is_token_valid_' . $maintainer->getUsernameCanonical()); } if (true !== $valid) { $context = stream_context_create(['http' => ['header' => 'User-agent: packagist-token-check']]); $rate = json_decode(@file_get_contents('https://api.github.com/rate_limit?access_token=' . $newGithubToken, false, $context), true); // invalid/outdated token, wipe it so we don't try it again if (!$rate && (strpos($http_response_header[0], '403') || strpos($http_response_header[0], '401'))) { $maintainer->setGithubToken(null); $em->flush($maintainer); continue; } } if ($apc) { apcu_store('is_token_valid_' . $maintainer->getUsernameCanonical(), true, 86400); } $io->setAuthentication('github.com', $newGithubToken, 'x-oauth-basic'); break; } } } $versions = $repository->getPackages(); usort($versions, function ($a, $b) { $aVersion = $a->getVersion(); $bVersion = $b->getVersion(); if ($aVersion === '9999999-dev' || 'dev-' === substr($aVersion, 0, 4)) { $aVersion = 'dev'; } if ($bVersion === '9999999-dev' || 'dev-' === substr($bVersion, 0, 4)) { $bVersion = 'dev'; } $aIsDev = $aVersion === 'dev' || substr($aVersion, -4) === '-dev'; $bIsDev = $bVersion === 'dev' || substr($bVersion, -4) === '-dev'; // push dev versions to the end if ($aIsDev !== $bIsDev) { return $aIsDev ? 1 : -1; } // equal versions are sorted by date if ($aVersion === $bVersion) { return $a->getReleaseDate() > $b->getReleaseDate() ? 1 : -1; } // the rest is sorted by version return version_compare($aVersion, $bVersion); }); $versionRepository = $this->doctrine->getRepository('PackagistWebBundle:Version'); if ($flags & self::DELETE_BEFORE) { foreach ($package->getVersions() as $version) { $versionRepository->remove($version); } $em->flush(); $em->refresh($package); } $lastUpdated = true; $lastProcessed = null; foreach ($versions as $version) { if ($version instanceof AliasPackage) { continue; } if (preg_match($blacklist, $version->getName() . ' ' . $version->getPrettyVersion())) { continue; } if ($lastProcessed && $lastProcessed->getVersion() === $version->getVersion()) { $io->write('Skipping version ' . $version->getPrettyVersion() . ' (duplicate of ' . $lastProcessed->getPrettyVersion() . ')', true, IOInterface::VERBOSE); continue; } $lastProcessed = $version; $lastUpdated = $this->updateInformation($package, $version, $flags); if ($lastUpdated) { $em->flush(); } } if (!$lastUpdated) { $em->flush(); } // remove outdated versions foreach ($package->getVersions() as $version) { if ($version->getUpdatedAt() < $pruneDate) { $versionRepository->remove($version); } } if (preg_match('{^(?:git://|git@|https?://)github.com[:/]([^/]+)/(.+?)(?:\\.git|/)?$}i', $package->getRepository(), $match) && $repository instanceof VcsRepository) { $this->updateGitHubInfo($rfs, $package, $match[1], $match[2], $repository); } $package->setUpdatedAt(new \DateTime()); $package->setCrawledAt(new \DateTime()); $em->flush(); if ($repository->hadInvalidBranches()) { throw new InvalidRepositoryException('Some branches contained invalid data and were discarded, it is advised to review the log and fix any issues present in branches'); } }
private function createDeletePackageForm(Package $package) { if (!($user = $this->getUser())) { return; } // super admins bypass additional checks if (!$this->get('security.context')->isGranted('ROLE_DELETE_PACKAGES')) { // non maintainers can not delete if (!$package->getMaintainers()->contains($user)) { return; } try { /** @var $redis \Snc\RedisBundle\Client\Phpredis\Client */ $redis = $this->get('snc_redis.default'); $downloads = $redis->get('dl:' . $package->getId()); } catch (\Exception $e) { return; } // more than 50 downloads = established package, do not allow deletion by maintainers if ($downloads > 50) { return; } } return $this->createFormBuilder(array())->getForm(); }