From ffb9ac73d0dd5e3bd3bcd27b8d066e313066d15d Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Fri, 25 Oct 2013 15:05:03 +0200 Subject: [PATCH] Fix #1550 : Remove feed entry items that are not related to a record --- lib/classes/Feed/Entry/Item.php | 22 ++++++++++- .../Feed/Entry/Feed_Entry_ItemTest.php | 38 ++++++++++++++++++- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/lib/classes/Feed/Entry/Item.php b/lib/classes/Feed/Entry/Item.php index 3c20ae0514..0834ceb16f 100644 --- a/lib/classes/Feed/Entry/Item.php +++ b/lib/classes/Feed/Entry/Item.php @@ -10,6 +10,7 @@ */ use Alchemy\Phrasea\Application; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * @@ -273,9 +274,26 @@ class Feed_Entry_Item implements Feed_Entry_ItemInterface, cache_cacheableInterf } if (!isset($items[$row['item']])) { - $item = new self($app['phraseanet.appbox'], $entries[$row['entry']], $row['item']); + try { + $item = new self($app['phraseanet.appbox'], $entries[$row['entry']], $row['item']); + $record = $item->get_record(); + } catch (NotFoundHttpException $e) { + $sql = 'DELETE FROM feed_entry_elements WHERE id = :id'; + $stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql); + $stmt->execute(array(':id' => $row['item'])); + $stmt->closeCursor(); - if (null !== $preview = $item->get_record()->get_subdef('preview')) { + continue; + } catch (\Exception_Record_AdapterNotFound $e) { + $sql = 'DELETE FROM feed_entry_elements WHERE id = :id'; + $stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql); + $stmt->execute(array(':id' => $row['item'])); + $stmt->closeCursor(); + + continue; + } + + if (null !== $preview = $record->get_subdef('preview')) { if (null !== $permalink = $preview->get_permalink()) { $items[$row['item']] = $item; diff --git a/tests/classes/Feed/Entry/Feed_Entry_ItemTest.php b/tests/classes/Feed/Entry/Feed_Entry_ItemTest.php index e199120f98..d10bcaf537 100644 --- a/tests/classes/Feed/Entry/Feed_Entry_ItemTest.php +++ b/tests/classes/Feed/Entry/Feed_Entry_ItemTest.php @@ -1,5 +1,7 @@ assertCount(0, Feed_Entry_Item::loadLatest(self::$DI['app'], 20)); } + public function testLoadLatestWithDeletedDatabox() + { + $this->deleteEntries(); + self::$feed->set_public(true); + + $sql = 'INSERT INTO feed_entry_elements + (id, entry_id, sbas_id, record_id) + VALUES (null, :entry_id, :sbas_id, :record_id)'; + + $stmt = self::$DI['app']['phraseanet.appbox']->get_connection()->prepare($sql); + $stmt->execute(array(':entry_id' => self::$entry->get_id(), ':sbas_id' => self::$DI['record_1']->get_databox()->get_sbas_id(), ':record_id' => 0)); + $stmt->closeCursor(); + + $this->assertCount(0, Feed_Entry_Item::loadLatest(self::$DI['app'], 20)); + } + + public function testLoadLatestWithDeletedRecord() + { + $this->deleteEntries(); + self::$feed->set_public(true); + + $sql = 'INSERT INTO feed_entry_elements + (id, entry_id, sbas_id, record_id) + VALUES (null, :entry_id, :sbas_id, :record_id)'; + + $stmt = self::$DI['app']['phraseanet.appbox']->get_connection()->prepare($sql); + $stmt->execute(array(':entry_id' => self::$entry->get_id(), ':sbas_id' => -24, ':record_id' => 0)); + $stmt->closeCursor(); + + $this->assertCount(0, Feed_Entry_Item::loadLatest(self::$DI['app'], 20)); + } + public function testIs_record_in_public_feed() { $this->deleteEntries(); @@ -123,7 +157,7 @@ class Feed_Entry_ItemTest extends PhraseanetPHPUnitAuthenticatedAbstract private function deleteEntries() { - $sql = "TRUNCATE feed_entry_elements"; + $sql = "DELETE FROM feed_entry_elements"; $stmt = self::$DI['app']['phraseanet.appbox']->get_connection()->prepare($sql); $stmt->execute(); $stmt->closeCursor();