Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring web controller (and others) #560

Merged
merged 1 commit into from Aug 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/Packagist/WebBundle/Controller/AboutController.php
Expand Up @@ -14,6 +14,7 @@

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\RedirectResponse;

/**
* @author Jordi Boggiano <j.boggiano@seld.be>
Expand All @@ -28,4 +29,12 @@ public function aboutAction()
{
return array();
}

/**
* @Route("/about-composer")
*/
public function aboutComposerFallbackAction()
{
return new RedirectResponse('https://getcomposer.org/', 301);
}
}
151 changes: 151 additions & 0 deletions src/Packagist/WebBundle/Controller/ExploreController.php
@@ -0,0 +1,151 @@
<?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\Controller;

use Doctrine\DBAL\ConnectionException;
use Packagist\WebBundle\Entity\Package;
use Packagist\WebBundle\Entity\PackageRepository;
use Packagist\WebBundle\Entity\VersionRepository;
use Pagerfanta\Adapter\FixedAdapter;
use Pagerfanta\Pagerfanta;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

/**
* @Route("/explore")
*/
class ExploreController extends Controller
{
/**
* @Template()
* @Route("/", name="browse")
*/
public function exploreAction()
{
/** @var PackageRepository $pkgRepo */
$pkgRepo = $this->getDoctrine()->getRepository('PackagistWebBundle:Package');
/** @var VersionRepository $verRepo */
$verRepo = $this->getDoctrine()->getRepository('PackagistWebBundle:Version');
$newSubmitted = $pkgRepo->getQueryBuilderForNewestPackages()->setMaxResults(10)
->getQuery()->useResultCache(true, 900, 'new_submitted_packages')->getResult();
$newReleases = $verRepo->getLatestReleases(10);
$randomIds = $this->getDoctrine()->getConnection()->fetchAll('SELECT id FROM package ORDER BY RAND() LIMIT 10');
$random = $pkgRepo->createQueryBuilder('p')->where('p.id IN (:ids)')->setParameter('ids', $randomIds)->getQuery()->getResult();
try {
$popular = array();
$popularIds = $this->get('snc_redis.default')->zrevrange('downloads:trending', 0, 9);
if ($popularIds) {
$popular = $pkgRepo->createQueryBuilder('p')->where('p.id IN (:ids)')->setParameter('ids', $popularIds)
->getQuery()->useResultCache(true, 900, 'popular_packages')->getResult();
usort($popular, function ($a, $b) use ($popularIds) {
return array_search($a->getId(), $popularIds) > array_search($b->getId(), $popularIds) ? 1 : -1;
});
}
} catch (ConnectionException $e) {
$popular = array();
}

$data = array(
'newlySubmitted' => $newSubmitted,
'newlyReleased' => $newReleases,
'random' => $random,
'popular' => $popular,
);

return $data;
}

/**
* @Template()
* @Route("/popular.{_format}", name="browse_popular", defaults={"_format"="html"})
* @Cache(smaxage=900)
*/
public function popularAction(Request $req)
{
try {
$redis = $this->get('snc_redis.default');
$perPage = $req->query->getInt('per_page', 15);
if ($perPage <= 0 || $perPage > 100) {
if ($req->getRequestFormat() === 'json') {
return new JsonResponse(array(
'status' => 'error',
'message' => 'The optional packages per_page parameter must be an integer between 1 and 100 (default: 15)',
), 400);
}

$perPage = max(0, min(100, $perPage));
}

$popularIds = $redis->zrevrange(
'downloads:trending',
($req->get('page', 1) - 1) * $perPage,
$req->get('page', 1) * $perPage - 1
);
$popular = $this->getDoctrine()->getRepository('PackagistWebBundle:Package')
->createQueryBuilder('p')->where('p.id IN (:ids)')->setParameter('ids', $popularIds)
->getQuery()->useResultCache(true, 900, 'popular_packages')->getResult();
usort($popular, function ($a, $b) use ($popularIds) {
return array_search($a->getId(), $popularIds) > array_search($b->getId(), $popularIds) ? 1 : -1;
});

$packages = new Pagerfanta(new FixedAdapter($redis->zcard('downloads:trending'), $popular));
$packages->setMaxPerPage($perPage);
$packages->setCurrentPage($req->get('page', 1), false, true);
} catch (ConnectionException $e) {
$packages = new Pagerfanta(new FixedAdapter(0, array()));
}

$data = array(
'packages' => $packages,
);
$data['meta'] = $this->getPackagesMetadata($data['packages']);

if ($req->getRequestFormat() === 'json') {
$result = array(
'packages' => array(),
'total' => $packages->getNbResults(),
);

/** @var Package $package */
foreach ($packages as $package) {
$url = $this->generateUrl('view_package', array('name' => $package->getName()), true);

$result['packages'][] = array(
'name' => $package->getName(),
'description' => $package->getDescription() ?: '',
'url' => $url,
'downloads' => $data['meta']['downloads'][$package->getId()],
'favers' => $data['meta']['favers'][$package->getId()],
);
}

if ($packages->hasNextPage()) {
$params = array(
'_format' => 'json',
'page' => $packages->getNextPage(),
);
if ($perPage !== 15) {
$params['per_page'] = $perPage;
}
$result['next'] = $this->generateUrl('browse_popular', $params, true);
}

return new JsonResponse($result);
}

return $data;
}
}