Эх сурвалжийг харах

Add json api to dependents and suggesters, and add sort by downloads for dependents

Jordi Boggiano 5 жил өмнө
parent
commit
6c1127b2e3

+ 58 - 8
src/Packagist/WebBundle/Controller/PackageController.php

@@ -1001,53 +1001,103 @@ class PackageController extends Controller
 
     /**
      * @Route(
-     *      "/packages/{name}/dependents",
+     *      "/packages/{name}/dependents.{_format}",
      *      name="view_package_dependents",
-     *      requirements={"name"="([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+?|ext-[A-Za-z0-9_.-]+?)"}
+     *      requirements={"name"="([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+?|ext-[A-Za-z0-9_.-]+?)"},
+     *      defaults={"_format"="html"}
      * )
      */
     public function dependentsAction(Request $req, $name)
     {
         $page = max(1, (int) $req->query->get('page', 1));
+        $perPage = 15;
+        $orderBy = $req->query->get('order_by', 'name');
+
+        if ($req->getRequestFormat() === 'json') {
+            $perPage = 100;
+        }
 
         /** @var PackageRepository $repo */
         $repo = $this->getDoctrine()->getRepository(Package::class);
         $depCount = $repo->getDependantCount($name);
-        $packages = $repo->getDependents($name, ($page - 1) * 15, 15);
+        $packages = $repo->getDependents($name, ($page - 1) * $perPage, $perPage, $orderBy);
 
         $paginator = new Pagerfanta(new FixedAdapter($depCount, $packages));
-        $paginator->setMaxPerPage(15);
+        $paginator->setMaxPerPage($perPage);
         $paginator->setCurrentPage($page, false, true);
 
+        if ($req->getRequestFormat() === 'json') {
+            $data = [
+                'packages' => $paginator->getCurrentPageResults(),
+            ];
+            $meta = $this->getPackagesMetadata($data['packages']);
+            foreach ($data['packages'] as $index => $package) {
+                $data['packages'][$index]['downloads'] = $meta['downloads'][$package['id']];
+                $data['packages'][$index]['favers'] = $meta['favers'][$package['id']];
+            }
+
+            if ($paginator->hasNextPage()) {
+                $data['next'] = $this->generateUrl('view_package_dependents', ['name' => $name, 'page' => $page + 1, '_format' => 'json', 'order_by' => $orderBy], UrlGeneratorInterface::ABSOLUTE_URL);
+            }
+            $data['ordered_by_name'] = $this->generateUrl('view_package_dependents', ['name' => $name, '_format' => 'json', 'order_by' => 'name'], UrlGeneratorInterface::ABSOLUTE_URL);
+            $data['ordered_by_downloads'] = $this->generateUrl('view_package_dependents', ['name' => $name, '_format' => 'json', 'order_by' => 'downloads'], UrlGeneratorInterface::ABSOLUTE_URL);
+
+            return new JsonResponse($data);
+        }
+
         $data['packages'] = $paginator;
         $data['count'] = $depCount;
 
         $data['meta'] = $this->getPackagesMetadata($data['packages']);
         $data['name'] = $name;
+        $data['order_by'] = $orderBy;
 
         return $this->render('PackagistWebBundle:package:dependents.html.twig', $data);
     }
 
     /**
      * @Route(
-     *      "/packages/{name}/suggesters",
+     *      "/packages/{name}/suggesters.{_format}",
      *      name="view_package_suggesters",
-     *      requirements={"name"="([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+?|ext-[A-Za-z0-9_.-]+?)"}
+     *      requirements={"name"="([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+?|ext-[A-Za-z0-9_.-]+?)"},
+     *      defaults={"_format"="html"}
      * )
      */
     public function suggestersAction(Request $req, $name)
     {
         $page = max(1, (int) $req->query->get('page', 1));
+        $perPage = 15;
+
+        if ($req->getRequestFormat() === 'json') {
+            $perPage = 100;
+        }
 
         /** @var PackageRepository $repo */
         $repo = $this->getDoctrine()->getRepository(Package::class);
         $suggestCount = $repo->getSuggestCount($name);
-        $packages = $repo->getSuggests($name, ($page - 1) * 15, 15);
+        $packages = $repo->getSuggests($name, ($page - 1) * $perPage, $perPage);
 
         $paginator = new Pagerfanta(new FixedAdapter($suggestCount, $packages));
-        $paginator->setMaxPerPage(15);
+        $paginator->setMaxPerPage($perPage);
         $paginator->setCurrentPage($page, false, true);
 
+        if ($req->getRequestFormat() === 'json') {
+            $data = [
+                'packages' => $paginator->getCurrentPageResults(),
+            ];
+            $meta = $this->getPackagesMetadata($data['packages']);
+            foreach ($data['packages'] as $index => $package) {
+                $data['packages'][$index]['downloads'] = $meta['downloads'][$package['id']];
+                $data['packages'][$index]['favers'] = $meta['favers'][$package['id']];
+            }
+
+            if ($paginator->hasNextPage()) {
+                $data['next'] = $this->generateUrl('view_package_suggesters', ['name' => $name, 'page' => $page + 1, '_format' => 'json'], UrlGeneratorInterface::ABSOLUTE_URL);
+            }
+
+            return new JsonResponse($data);
+        }
+
         $data['packages'] = $paginator;
         $data['count'] = $suggestCount;
 

+ 12 - 3
src/Packagist/WebBundle/Entity/PackageRepository.php

@@ -384,21 +384,30 @@ class PackageRepository extends ServiceEntityRepository
         return (int) $result[0]['count'];
     }
 
-    public function getDependents($name, $offset = 0, $limit = 15)
+    public function getDependents($name, $offset = 0, $limit = 15, $orderBy = 'name')
     {
+        $orderByField = 'p.name ASC';
+        $join = '';
+        if ($orderBy === 'downloads') {
+            $orderByField = 'd.total DESC';
+            $join = 'LEFT JOIN download d ON d.id = p.id AND d.type = '.Download::TYPE_PACKAGE;
+        } else {
+            $orderBy = 'name';
+        }
+
         $sql = 'SELECT p.id, p.name, p.description, p.language, p.abandoned, p.replacementPackage
             FROM package p INNER JOIN (
                 SELECT pv.package_id FROM link_require r INNER JOIN package_version pv ON (pv.id = r.version_id AND pv.development = 1) WHERE r.packageName = :name
                 UNION
                 SELECT pv.package_id FROM link_require_dev r INNER JOIN package_version pv ON (pv.id = r.version_id AND pv.development = 1) WHERE r.packageName = :name
-            ) x ON x.package_id = p.id ORDER BY p.name ASC LIMIT '.((int)$limit).' OFFSET '.((int)$offset);
+            ) x ON x.package_id = p.id '.$join.' ORDER BY '.$orderByField.' LIMIT '.((int)$limit).' OFFSET '.((int)$offset);
 
         $stmt = $this->getEntityManager()->getConnection()
             ->executeCacheQuery(
                 $sql,
                 ['name' => $name],
                 [],
-                new QueryCacheProfile(7*86400, 'dependents_'.$name.'_'.$offset.'_'.$limit, $this->getEntityManager()->getConfiguration()->getResultCacheImpl())
+                new QueryCacheProfile(7*86400, 'dependents_'.$name.'_'.$offset.'_'.$limit.'_'.$orderBy, $this->getEntityManager()->getConfiguration()->getResultCacheImpl())
             );
         $result = $stmt->fetchAll();
         $stmt->closeCursor();

+ 1 - 0
src/Packagist/WebBundle/Resources/views/mirrors/index.html.twig

@@ -20,6 +20,7 @@
   <li>Asia, China <a href="https://packagist.mirrors.sjtug.sjtu.edu.cn">packagist.mirrors.sjtug.sjtu.edu.cn</a></li>
   <li>Asia, China <a href="https://mirrors.cloud.tencent.com/help/composer.html">mirrors.cloud.tencent.com/help/composer.html</a></li>
   <li>Asia, India <a href="https://packagist.in">packagist.in</a></li>
+  <li>Asia, India <a href="https://packagist.vrkansagara.in">packagist.vrkansagara.in</a></li>
   <li>Asia, Indonesia <a href="https://packagist.phpindonesia.id">packagist.phpindonesia.id</a></li>
   <li>Asia, Japan <a href="https://packagist.jp">packagist.jp</a></li>
   <li>Asia, South Korea <a href="https://packagist.kr">packagist.kr</a></li>

+ 5 - 0
src/Packagist/WebBundle/Resources/views/package/dependents.html.twig

@@ -13,6 +13,11 @@
                 <h2 class="title">
                     <a href="{{ path("view_package", {name: name}) }}">{{ name }}</a> {{ 'packages.dependents'|trans }}
                     <small>({{ count }})</small>
+                    <small>
+                        Order by:
+                        {% if order_by == 'name' %}name{% else %}<a href="{{ path("view_package_dependents", {name: name, order_by: 'name'}) }}">name</a>{% endif %} |
+                        {% if order_by == 'downloads' %}downloads{% else %}<a href="{{ path("view_package_dependents", {name: name, order_by: 'downloads'}) }}">downloads</a>{% endif %}
+                    </small>
                 </h2>
             </div>
         </div>

+ 1 - 1
src/Packagist/WebBundle/Resources/views/package/view_package.html.twig

@@ -181,7 +181,7 @@
                             {% if dependents is defined %}
                                 <p>
                                     <span>
-                                        <a href="{{ path('view_package_dependents', {name: package.name}) }}" rel="nofollow">Dependents</a>:
+                                        <a href="{{ path('view_package_dependents', {name: package.name, order_by: 'downloads'}) }}" rel="nofollow">Dependents</a>:
                                     </span>
                                     {{ dependents|number_format(0, '.', '&#8201;')|raw }}
                                 </p>