/**
  * Index action
  *
  * Displays a list of items with endless scrolling. Allows to filter by language.
  *
  * @param integer $page The current page
  * @param string $language Filter by language, NULL for all languages
  */
 public function indexAction($page = 1, $language = NULL)
 {
     $offset = ($page - 1) * $this->perPage;
     $filter = new \Planetflow3\Domain\Dto\ItemFilter();
     $filter->setLanguage($language);
     $filter->setDisabled(FALSE);
     $result = $this->itemRepository->findByFilter($filter);
     $count = $result->count();
     $query = $result->getQuery();
     $query->setLimit(10);
     $query->setOffset($offset);
     $items = $query->execute();
     $this->view->assign('items', $items);
     $this->view->assign('language', $language);
     $this->view->assign('page', $page);
     $this->view->assign('count', $count);
     $this->view->assign('offset', $offset);
     $this->view->assign('perPage', $this->perPage);
     $this->view->assign('hasNext', $offset + $this->perPage <= $count);
     $this->view->assign('nextPage', $page + 1);
     $channels = $this->channelRepository->findAll();
     $this->view->assign('channels', $channels);
     $this->view->assign('languages', array('en', 'de'));
     // TODO Send correct cache control including last modified
 }
 /**
  * @FLOW3\SkipCsrfProtection
  */
 public function indexAction()
 {
     $items = $this->itemRepository->findByFilter(NULL);
     $recentItems = $items->getQuery()->setLimit(5)->execute();
     $this->view->assign('itemCount', $this->itemRepository->countAll());
     $this->view->assign('recentItems', $recentItems);
     $this->view->assign('channelCount', $this->channelRepository->countAll());
     $this->view->assign('topChannels', $this->channelRepository->findTopChannels());
 }
 /**
  * @test
  */
 public function fetchItemsGetsMatchingItemsFromFeed()
 {
     $channel = new \Planetflow3\Domain\Model\Channel();
     $channel->setFeedUrl('file://' . __DIR__ . '/../../Fixtures/Feeds/news.typo3.org-news-teams-flow3-rss.xml');
     $channel->setName('Test Feed');
     $channel->setUrl('http://www.example.com/test');
     $this->channelRepository->add($channel);
     $this->channelService->fetchItems($channel);
     $this->assertEquals(10, count($channel->getItems()), 'Should fetch all 10 items from feed');
 }
 /**
  * Index action
  *
  * @param \Planetflow3\Domain\Dto\ItemFilter $filter
  * @FLOW3\SkipCsrfProtection
  */
 public function indexAction($filter = NULL)
 {
     if ($filter === NULL) {
         $filter = new \Planetflow3\Domain\Dto\ItemFilter();
     }
     $items = $this->itemRepository->findByFilter($filter);
     $this->view->assign('items', $items);
     $this->view->assign('filter', $filter);
     $channels = $this->channelRepository->findAll();
     $categories = $this->categoryRepository->findAll();
     $this->view->assign('channels', $channels->toArray());
     $this->view->assign('categories', $categories->toArray());
 }
 /**
  * Create some test data
  *
  * @return void
  */
 protected function createTestData()
 {
     $channel = new \Planetflow3\Domain\Model\Channel();
     $channel->setName('Test channel');
     $channel->setUrl('http://www.example.com');
     $channel->setFeedUrl('http://www.example.com/rss.xml');
     $this->channelRepository->add($channel);
     $item = new \Planetflow3\Domain\Model\Item();
     $item->setChannel($channel);
     $item->setAuthor('Test author');
     // $item->setCategories(array('FLOW3'));
     $item->setTitle('A test post');
     $item->setContent('My random content');
     $item->setDescription('Some description');
     $item->setLanguage('en');
     $item->setLink('http://www.example.com/posts/2');
     $item->setPublicationDate(new \DateTime('2011-10-09 08:07:06'));
     $item->setUniversalIdentifier('http://www.example.com/posts/2');
     $this->itemRepository->add($item);
 }
 /**
  * Create sample data
  *
  * @return void
  */
 public function sampleDataCommand()
 {
     $this->itemRepository->removeAll();
     $this->channelRepository->removeAll();
     $this->categoryRepository->removeAll();
     $flow3Category = new \Planetflow3\Domain\Model\Category('FLOW3');
     $this->categoryRepository->add($flow3Category);
     $phpCategory = new \Planetflow3\Domain\Model\Category('PHP');
     $this->categoryRepository->add($phpCategory);
     $phoenixCategory = new \Planetflow3\Domain\Model\Category('Phoenix');
     $this->categoryRepository->add($phoenixCategory);
     $channels = array();
     $channel = new \Planetflow3\Domain\Model\Channel();
     $channel->setName('news.typo3.org: FLOW3');
     $channel->setUrl('http://news.typo3.org/news/teams/flow3/');
     $channel->setFeedUrl('http://news.typo3.org/news/teams/flow3/rss.xml');
     $channel->setDefaultCategory($flow3Category);
     $this->channelRepository->add($channel);
     $channels[] = $channel;
     $channel = new \Planetflow3\Domain\Model\Channel();
     $channel->setName('Karsten Dambekalns - Code & Content');
     $channel->setUrl('http://blog.k-fish.de');
     $channel->setFeedUrl('http://blog.k-fish.de/feeds/posts/default');
     $channel->setFetchedCategories(array('PHP', 'FLOW3'));
     $this->channelRepository->add($channel);
     $channels[] = $channel;
     $channel = new \Planetflow3\Domain\Model\Channel();
     $channel->setName('networkteam Blog - FLOW3');
     $channel->setUrl('http://www.networkteam.com/blog.html');
     $channel->setFeedUrl('http://www.networkteam.com/rss.xml');
     $channel->setFilter('FLOW3');
     $channel->setDefaultCategory($flow3Category);
     $this->channelRepository->add($channel);
     $channels[] = $channel;
     $channel = new \Planetflow3\Domain\Model\Channel();
     $channel->setName('Robert Lemke - Fluent Code Artisan');
     $channel->setUrl('http://robertlemke.de/blog/');
     $channel->setFeedUrl('http://robertlemke.de/blog/feeds/posts.rss.xml');
     $channel->setFilter('FLOW3,PHP');
     $channel->setDefaultCategory($flow3Category);
     $this->channelRepository->add($channel);
     $channels[] = $channel;
     $channel = new \Planetflow3\Domain\Model\Channel();
     $channel->setName('t3blog.de');
     $channel->setUrl('http://t3blog.de');
     $channel->setFeedUrl('http://t3blog.de/feed/');
     $channel->setFilter('FLOW3');
     $channel->setDefaultCategory($flow3Category);
     $this->channelRepository->add($channel);
     $channels[] = $channel;
     $channel = new \Planetflow3\Domain\Model\Channel();
     $channel->setName('layh.com');
     $channel->setUrl('http://www.layh.com');
     $channel->setFeedUrl('http://www.layh.com/wordpress/feed/');
     $channel->setFetchedCategories(array('FLOW3'));
     $this->channelRepository->add($channel);
     $channels[] = $channel;
     $this->outputLine('Created default categories and channels');
 }
 /**
  * Fetch new items from all channels
  *
  * This command should be run by a cronjob to do periodical
  * updates to the channel feeds.
  *
  * @param boolean $verbose TRUE if log messages should be shown on the console
  * @return void
  */
 public function fetchCommand($verbose = FALSE)
 {
     if ($verbose) {
         echo 'Fetching feeds';
     }
     $command = $this;
     $channels = $this->channelRepository->findAll();
     foreach ($channels as $channel) {
         if ($verbose) {
             echo 'Fetching items for ' . $channel->getFeedUrl() . '...' . PHP_EOL;
         }
         $this->channelService->fetchItems($channel, function (Item $item, $message, $severity = LOG_INFO) use($channel, $command, $verbose) {
             if ($verbose) {
                 echo $message . PHP_EOL;
             }
             $command->feedLogger->log($channel->getName() . ': ' . $item->getLink() . ' - ' . $message, $severity);
         });
         if ($verbose) {
             echo "Done fetching items." . PHP_EOL;
         }
     }
 }
 /**
  * Fetches (new) items from the configured feed of a channel
  *
  * Adds new items and updates channels with a new last fetch date.
  *
  * @param \Planetflow3\Domain\Model\Channel $channel
  * @param \Closure $logCallback
  * @return void
  */
 public function fetchItems(Channel $channel, $logCallback = NULL)
 {
     if ($logCallback === NULL) {
         $logCallback = function (Item $item, $message, $severity = LOG_INFO) {
         };
     }
     $simplePie = $this->createSimplePie($channel);
     $existingUniversalIdentifiers = $channel->getItemsUniversalIdentifier();
     $feedItems = $simplePie->get_items();
     foreach ($feedItems as $feedItem) {
         $item = new Item();
         $item->setUniversalIdentifier($feedItem->get_id());
         if (isset($existingUniversalIdentifiers[$item->getUniversalIdentifier()])) {
             $logCallback($item, 'Skipped item, already fetched', LOG_DEBUG);
             continue;
         }
         $this->populateItemProperties($item, $feedItem);
         $this->populateItemCategories($item, $feedItem, $logCallback);
         if ($item->getCategories()->count() === 0 && $channel->getDefaultCategory() !== NULL) {
             $item->addCategory($channel->getDefaultCategory());
         }
         if ($item->matchesChannel($channel)) {
             $language = $this->textcat->classify($item->getDescription() . ' ' . $item->getContent());
             if ($language !== FALSE) {
                 $item->setLanguage($language);
                 $logCallback($item, 'Detected language ' . $language . ' for item', LOG_DEBUG);
             }
             $channel->addItem($item);
             $this->itemRepository->add($item);
             $logCallback($item, 'Item fetched and saved', LOG_INFO);
             $existingUniversalIdentifiers[$item->getUniversalIdentifier()] = TRUE;
         } else {
             $logCallback($item, 'Skipped item, filter not matched', LOG_DEBUG);
         }
     }
     $channel->setLastFetchDate(new \DateTime());
     $this->channelRepository->update($channel);
 }
 /**
  * Delete action
  *
  * @param \Planetflow3\Domain\Model\Channel $channel
  * @FLOW3\IgnoreValidation("$channel")
  */
 public function deleteAction(\Planetflow3\Domain\Model\Channel $channel)
 {
     $this->channelRepository->remove($channel);
     $this->addFlashMessage('Channel removed.', 'Success', \TYPO3\FLOW3\Error\Message::SEVERITY_NOTICE);
     $this->redirect('index');
 }