FeedController.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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\Controller;
  12. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  13. use Zend\Feed\Writer\Entry;
  14. use Zend\Feed\Writer\Feed;
  15. use Packagist\WebBundle\Entity\Package;
  16. use Packagist\WebBundle\Entity\Version;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  19. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  20. /**
  21. * @author Rafael Dohms <rafael@doh.ms>
  22. *
  23. * @Route("/feeds")
  24. */
  25. class FeedController extends Controller
  26. {
  27. /**
  28. * @Route(
  29. * "/packages.{_format}",
  30. * name="feed_packages",
  31. * requirements={"_format"="(rss|atom)"}
  32. * )
  33. * @Method({"GET"})
  34. */
  35. public function packagesAction()
  36. {
  37. /** @var $repo \Packagist\WebBundle\Entity\VersionRepository */
  38. $repo = $this->getDoctrine()->getRepository('PackagistWebBundle:Version');
  39. $packages = $repo->getLatestVersionWithPackage(
  40. $this->container->getParameter('packagist_web.rss_max_items')
  41. );
  42. $feed = $this->buildFeed(
  43. 'Latest Packages',
  44. 'Latest packages updated on Packagist.',
  45. $packages
  46. );
  47. return $this->buildResponse($feed);
  48. }
  49. /**
  50. * @Route(
  51. * "/releases.{_format}",
  52. * name="feed_releases",
  53. * requirements={"_format"="(rss|atom)"}
  54. * )
  55. * @Method({"GET"})
  56. */
  57. public function releasesAction()
  58. {
  59. /** @var $repo \Packagist\WebBundle\Entity\PackageRepository */
  60. $repo = $this->getDoctrine()->getRepository('PackagistWebBundle:Package');
  61. $packages = $repo->getNewestPackages(
  62. $this->container->getParameter('packagist_web.rss_max_items')
  63. );
  64. $feed = $this->buildFeed(
  65. 'Latest Released Packages',
  66. 'Latest packages added to Packagist.',
  67. $packages
  68. );
  69. return $this->buildResponse($feed);
  70. }
  71. /**
  72. * @Route(
  73. * "/vendor.{filter}.{_format}",
  74. * name="feed_vendor",
  75. * requirements={"_format"="(rss|atom)"}
  76. * )
  77. * @Method({"GET"})
  78. */
  79. public function vendorAction($filter)
  80. {
  81. /** @var $repo \Packagist\WebBundle\Entity\PackageRepository */
  82. $repo = $this->getDoctrine()->getRepository('PackagistWebBundle:Package');
  83. $packages = $repo->getLatestPackagesByVendor(
  84. $filter,
  85. $this->container->getParameter('packagist_web.rss_max_items')
  86. );
  87. $feed = $this->buildFeed(
  88. "$filter Packages",
  89. "Latest packages updated on Packagist for $filter.",
  90. $packages
  91. );
  92. return $this->buildResponse($feed);
  93. }
  94. /**
  95. * Builds the desired feed
  96. *
  97. * @param string $title
  98. * @param string $description
  99. * @param array $items
  100. *
  101. * @return \Zend\Feed\Writer\Feed
  102. */
  103. protected function buildFeed($title, $description, $items)
  104. {
  105. $feed = new Feed();
  106. $feed->setTitle($title);
  107. $feed->setDescription($description);
  108. $feed->setLink($this->getRequest()->getSchemeAndHttpHost());
  109. $feed->setDateModified(time());
  110. foreach ($items as $item) {
  111. $entry = $feed->createEntry();
  112. $this->populateEntry($entry, $item);
  113. $feed->addEntry($entry);
  114. }
  115. if ($this->getRequest()->getRequestFormat() == 'atom') {
  116. $feed->setFeedLink($this->getRequest()->getUri(), $this->getRequest()->getRequestFormat());
  117. }
  118. return $feed;
  119. }
  120. /**
  121. * Receives either a Package or a Version and populates a feed entry.
  122. *
  123. * @param \Zend\Feed\Writer\Entry $entry
  124. * @param Package|Version $item
  125. */
  126. protected function populateEntry(Entry $entry, $item)
  127. {
  128. if ($item instanceof Package) {
  129. $version = $item->getVersions()->first() ?: new Version();
  130. $this->populatePackageData($entry, $item);
  131. $this->populateVersionData($entry, $version);
  132. }
  133. if ($item instanceof Version) {
  134. $this->populatePackageData($entry, $item->getPackage());
  135. $this->populateVersionData($entry, $item);
  136. }
  137. }
  138. /**
  139. * Populates a feed entry with data coming from Package objects.
  140. *
  141. * @param \Zend\Feed\Writer\Entry $entry
  142. * @param Package $package
  143. */
  144. protected function populatePackageData(Entry $entry, Package $package)
  145. {
  146. $entry->setTitle($package->getPackageName());
  147. $entry->setLink(
  148. $this->generateUrl(
  149. 'view_package',
  150. array('name' => $package->getName()),
  151. true
  152. )
  153. );
  154. $entry->setDateModified($package->getUpdatedAt());
  155. $entry->setDateCreated($package->getCreatedAt());
  156. $entry->setDescription($package->getDescription());
  157. }
  158. /**
  159. * Populates a feed entry with data coming from Version objects.
  160. *
  161. * @param \Zend\Feed\Writer\Entry $entry
  162. * @param Version $version
  163. */
  164. protected function populateVersionData(Entry $entry, Version $version)
  165. {
  166. $entry->setTitle($entry->getTitle()." ({$version->getVersion()})");
  167. foreach ($version->getAuthors() as $author) {
  168. /** @var $author \Packagist\WebBundle\Entity\Author */
  169. $entry->addAuthor(array(
  170. 'name' => $author->getName()
  171. ));
  172. }
  173. }
  174. /**
  175. * Creates a HTTP Response and exports feed
  176. *
  177. * @param \Zend\Feed\Writer\Feed $feed
  178. *
  179. * @return \Symfony\Component\HttpFoundation\Response
  180. */
  181. protected function buildResponse(Feed $feed)
  182. {
  183. $content = $feed->export($this->getRequest()->getRequestFormat());
  184. $response = new Response($content, 200);
  185. $response->setSharedMaxAge(3600);
  186. return $response;
  187. }
  188. }