From 4d8f00c1104e70f2e3b5419e3b598e84e1cd4069 Mon Sep 17 00:00:00 2001
From: pbarroca <pbarroca@git-test.afi-sa.fr>
Date: Thu, 3 May 2012 08:03:06 +0000
Subject: [PATCH] OAI: Ajout d'un getNotices et getNoticesCount sur
 Class_Catalogue + renommage de l'ancien getNotices en getNoticesByPreferences
 + utilisation du resumptionToken dans ListIdentifiers

---
 .../opac/controllers/JavaController.php       |  2 +-
 .../opac/controllers/RssController.php        |  2 +-
 library/Class/AvisNotice.php                  |  2 +-
 library/Class/Catalogue.php                   | 23 +++++-
 .../OAI/Response/ListIdentifiers.php          | 26 +++++--
 .../Class/WebService/OAI/ResumptionToken.php  | 16 +++--
 library/ZendAfi/View/Helper/Accueil/Tags.php  |  2 +-
 .../OAI/Response/ListIdentifiersTest.php      | 72 +++++++++++++++----
 .../WebService/OAI/ResumptionTokenTest.php    | 13 ++++
 9 files changed, 132 insertions(+), 26 deletions(-)

diff --git a/application/modules/opac/controllers/JavaController.php b/application/modules/opac/controllers/JavaController.php
index 360498c3d91..aabb352d5c1 100644
--- a/application/modules/opac/controllers/JavaController.php
+++ b/application/modules/opac/controllers/JavaController.php
@@ -52,7 +52,7 @@ class JavaController extends ZendAfi_Controller_IFrameAction {
 		
 		// Lire les notices
 		$catalogue=new Class_Catalogue();
-		$this->view->notices=$catalogue->getNotices($preferences,"url");
+		$this->view->notices=$catalogue->getNoticesByPreferences($preferences,"url");
 
 		// Redirection vers la bonne vue
 		$vue="/java/".$this->_getParam("vue").".phtml";
diff --git a/application/modules/opac/controllers/RssController.php b/application/modules/opac/controllers/RssController.php
index ee663d2655c..8917e146439 100644
--- a/application/modules/opac/controllers/RssController.php
+++ b/application/modules/opac/controllers/RssController.php
@@ -351,7 +351,7 @@ class RssController extends Zend_Controller_Action
 
 		$catalogue=new Class_Catalogue();
 		$preferences["aleatoire"] = 0; // les dernières seulement
-		$notices=$catalogue->getNotices($preferences,"url");
+		$notices=$catalogue->getNoticesByPreferences($preferences,"url");
 
 		$entries = array();
 
diff --git a/library/Class/AvisNotice.php b/library/Class/AvisNotice.php
index a7b0050dacd..7432f8b3b1c 100644
--- a/library/Class/AvisNotice.php
+++ b/library/Class/AvisNotice.php
@@ -30,7 +30,7 @@ class AvisNoticeLoader extends Storm_Model_Loader {
 		$preferences["avec_avis"] = 1; //seulement les notices avec avis
 
 		$catalogue = new Class_Catalogue();
-		$notices = $catalogue->getNotices($preferences);
+		$notices = $catalogue->getNoticesByPreferences($preferences);
 
     if (count($notices) == 0) {
 			//on ne doit retourner aucun avis
diff --git a/library/Class/Catalogue.php b/library/Class/Catalogue.php
index 0ac6161e7df..aa638c7c86c 100644
--- a/library/Class/Catalogue.php
+++ b/library/Class/Catalogue.php
@@ -37,6 +37,17 @@ class CatalogueLoader extends Storm_Model_Loader {
 	}
 
 
+	public function countNoticesFor($catalogue) {
+		if (!$catalogue)
+			return 0;
+		
+		if ('' == ($where = $this->clausesFor($catalogue)))
+			return 0;
+
+		return Class_Notice::getLoader()->countBy(array('where' => $where));
+	}
+
+
 	public function clausesFor($catalogue) {
 		if (1 == $catalogue->getAll())
 			return '1=1';
@@ -199,6 +210,16 @@ class Class_Catalogue extends Storm_Model_Abstract
 	}
 
 
+	public function getNotices($page = 1, $itemsByPage = CatalogueLoader::DEFAULT_ITEMS_BY_PAGE) {
+		return self::getLoader()->loadNoticesFor($this, $itemsByPage, $page);
+	}
+
+
+	public function getNoticesCount() {
+		return self::getLoader()->countNoticesFor($this);
+	}
+
+
 //------------------------------------------------------------------------------
 // Rend les notices et les stats (test d'un catalogue)
 //------------------------------------------------------------------------------
@@ -224,7 +245,7 @@ class Class_Catalogue extends Storm_Model_Abstract
 //------------------------------------------------------------------------------
 // Rend les notices selon les preferences (kiosques)
 //------------------------------------------------------------------------------
-	public function getNotices($preferences,$cache_vignette=false)
+	public function getNoticesByPreferences($preferences,$cache_vignette=false)
 	{
 		//Instanciations
 		$class_notice = new Class_Notice();
diff --git a/library/Class/WebService/OAI/Response/ListIdentifiers.php b/library/Class/WebService/OAI/Response/ListIdentifiers.php
index b27b5caee2b..8f34fcb2959 100644
--- a/library/Class/WebService/OAI/Response/ListIdentifiers.php
+++ b/library/Class/WebService/OAI/Response/ListIdentifiers.php
@@ -19,6 +19,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
  */
 class Class_WebService_OAI_Response_ListIdentifiers extends Class_WebService_OAI_Response_Null {
+	const IDENTIFIERS_BY_PAGE = 100;
+
 	protected $_metadataPrefix;
 	protected $_catalogue;
 	protected $_set;
@@ -26,6 +28,7 @@ class Class_WebService_OAI_Response_ListIdentifiers extends Class_WebService_OAI
 	protected $_until;
 	protected $_resumptionToken;
 	protected $_notices;
+	protected $_token;
 
 
 	public function xml($params = array()) {
@@ -66,7 +69,7 @@ class Class_WebService_OAI_Response_ListIdentifiers extends Class_WebService_OAI
 		if ($errors = $this->buildErrorsOn($builder))
 			return $response . $errors;
 
-		return $response . $this->listIdentifiers($builder);
+		return $response . $this->listIdentifiers($builder) . $this->resumptionToken($builder);
 	}
 
 
@@ -80,13 +83,23 @@ class Class_WebService_OAI_Response_ListIdentifiers extends Class_WebService_OAI
 		if ($this->_set && !$this->_catalogue)
 			return $builder->error(array('code' => 'badArgument'), 'Set not found');
 
+		if (0 == ($count = $this->_catalogue->getNoticesCount()))
+			return $builder->error(array('code' => 'noRecordsMatch'));
+
+		$token = null;
 		if ($this->_resumptionToken 
 				&& !($token = Class_WebService_OAI_ResumptionToken::find($this->_resumptionToken)))
 			return $builder->error(array('code' => 'badResumptionToken'));
 
-		$this->_notices = Class_Notice::getLoader()->findAllByCatalogue($this->_catalogue);
-		if (0 == count($this->_notices))
-			return $builder->error(array('code' => 'noRecordsMatch'));
+		$page_number = 1;
+		if (null != $token) {
+			$this->_token = $token->next(self::IDENTIFIERS_BY_PAGE); 
+			$page_number = $this->_token->getPageNumber();
+		} elseif (self::IDENTIFIERS_BY_PAGE < $count) {
+			$this->_token = Class_WebService_OAI_ResumptionToken::newWithParamsAndListSize($this->_params, $count);
+		}
+		
+		$this->_notices = $this->_catalogue->getNotices($page_number);
 	}
 
 
@@ -108,6 +121,11 @@ class Class_WebService_OAI_Response_ListIdentifiers extends Class_WebService_OAI
 	}
 
 
+	public function resumptionToken($builder) {
+		return (null != $this->_token) ? $this->_token->renderOn($builder) : '';
+	}
+
+
 	public function getCatalogueFromSetSpec($setSpec) {
 		if (null == $setSpec) 
 			return Class_Catalogue::newCatalogueForAll();
diff --git a/library/Class/WebService/OAI/ResumptionToken.php b/library/Class/WebService/OAI/ResumptionToken.php
index b700a1176b0..2f4ea4d1ebf 100644
--- a/library/Class/WebService/OAI/ResumptionToken.php
+++ b/library/Class/WebService/OAI/ResumptionToken.php
@@ -25,6 +25,7 @@ class Class_WebService_OAI_ResumptionToken {
 	protected $_params;
 	protected $_list_size;
 	protected $_cursor = 0;
+	protected $_page_number = 1;
 
 	public static function defaultCache($cache) {
 		self::$_cache = $cache;
@@ -38,8 +39,8 @@ class Class_WebService_OAI_ResumptionToken {
 	}
 
 
-	public static function newWithParamsAndListSize($params, $list_size, $cursor = 0) {
-		return new self($params, $list_size, $cursor);
+	public static function newWithParamsAndListSize($params, $list_size, $cursor = 0, $page_number = 1) {
+		return new self($params, $list_size, $cursor, $page_number);
 	}
 
 
@@ -48,10 +49,11 @@ class Class_WebService_OAI_ResumptionToken {
 	}
 
 
-	public function __construct($params, $list_size, $cursor) {
+	public function __construct($params, $list_size, $cursor, $page_number) {
 		$this->_params = $params;
 		$this->_list_size = $list_size;
 		$this->_cursor = $cursor;
+		$this->_page_number = $page_number;
 	}
 
 	public function save() {
@@ -63,7 +65,8 @@ class Class_WebService_OAI_ResumptionToken {
 	public function next($size) {
 		return self::newWithParamsAndListSize($this->_params, 
 																					$this->_list_size, 
-																					$this->_cursor + $size);
+																					$this->_cursor + $size,
+																					$this->_page_number + 1);
 	}
 
 
@@ -72,5 +75,10 @@ class Class_WebService_OAI_ResumptionToken {
 																					 'cursor' => $this->_cursor),
 																		 md5(serialize($this)));
 	}
+
+
+	public function getPageNumber() {
+		return $this->_page_number;
+	}
 }
 ?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Accueil/Tags.php b/library/ZendAfi/View/Helper/Accueil/Tags.php
index c040012782e..94c668a392f 100644
--- a/library/ZendAfi/View/Helper/Accueil/Tags.php
+++ b/library/ZendAfi/View/Helper/Accueil/Tags.php
@@ -55,7 +55,7 @@ class ZendAfi_View_Helper_Accueil_Tags extends ZendAfi_View_Helper_Accueil_Base
 		else
 			$this->preferences["tri"] = -1; // Permet de ne pas faire d'order by.
 
-		$notices = $catalogue->getNotices($this->preferences);
+		$notices = $catalogue->getNoticesByPreferences($this->preferences);
 
 		foreach ($notices as $notice)	{
 			$type="T".$notice["type_doc"];
diff --git a/tests/library/Class/WebService/OAI/Response/ListIdentifiersTest.php b/tests/library/Class/WebService/OAI/Response/ListIdentifiersTest.php
index 89416e5ea71..6f639a52c5c 100644
--- a/tests/library/Class/WebService/OAI/Response/ListIdentifiersTest.php
+++ b/tests/library/Class/WebService/OAI/Response/ListIdentifiersTest.php
@@ -27,19 +27,22 @@ class ListIdentifiersValidTest extends Storm_Test_ModelTestCase {
 		$this->_xpath = TestXPathFactory::newOai();
 		$this->_response = new Class_WebService_OAI_Response_ListIdentifiers('http://moulins.fr/oai2/do');
 		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Catalogue')
+			->whenCalled('countNoticesFor')
+			->answers(3)
+
 			->whenCalled('loadNoticesFor')
 			->answers(array(Class_Notice::getLoader()
-											  ->newInstanceWithId(2)
-											  ->setClefAlpha('harrypotter-sorciers')
-											  ->setDateMaj('2001-12-14 11:42:42'),
+											->newInstanceWithId(2)
+											->setClefAlpha('harrypotter-sorciers')
+											->setDateMaj('2001-12-14 11:42:42'),
 											Class_Notice::getLoader()
-											  ->newInstanceWithId(3)
-											  ->setClefAlpha('harrypotter-chambresecrets')
-											  ->setDateMaj('2005-10-24 11:42:42'),
+											->newInstanceWithId(3)
+											->setClefAlpha('harrypotter-chambresecrets')
+											->setDateMaj('2005-10-24 11:42:42'),
 											Class_Notice::getLoader()
-											  ->newInstanceWithId(4)
-											  ->setClefAlpha('harrypotter-azkaban')
-											  ->setDateMaj('2012-04-03 11:42:42')));
+											->newInstanceWithId(4)
+											->setClefAlpha('harrypotter-azkaban')
+											->setDateMaj('2012-04-03 11:42:42')));
 		$this->_xml = $this->_response->xml(array('metadataPrefix' => 'oai_dc'));
 	}
 
@@ -66,6 +69,14 @@ class ListIdentifiersValidTest extends Storm_Test_ModelTestCase {
 																	'//oai:ListIdentifiers/oai:metadata');
 	}
 
+
+	/** @test */
+	public function shouldNotHaveResumptionToken() {
+		$this->_xpath->assertNotXpath($this->_xml,
+																	'//oai:resumptionToken');
+	}
+
+
 	
 	/** @test */
 	public function firstIdentifierShouldContainSorciers() {
@@ -124,6 +135,40 @@ class ListIdentifiersValidTest extends Storm_Test_ModelTestCase {
 }
 
 
+class ListIdentifiersWithPaginatorTest extends Storm_Test_ModelTestCase {
+	public function setUp() {
+		parent::setUp();
+		$this->_xpath = TestXPathFactory::newOai();
+		$this->_response = new Class_WebService_OAI_Response_ListIdentifiers('http://moulins.fr/oai2/do');
+		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Catalogue')
+			->whenCalled('countNoticesFor')
+			->answers(10000)
+
+			->whenCalled('loadNoticesFor')
+			->answers(array(Class_Notice::getLoader()
+											->newInstanceWithId(2)
+											->setClefAlpha('harrypotter-sorciers')
+											->setDateMaj('2001-12-14 11:42:42'),
+											Class_Notice::getLoader()
+											->newInstanceWithId(3)
+											->setClefAlpha('harrypotter-chambresecrets')
+											->setDateMaj('2005-10-24 11:42:42'),
+											Class_Notice::getLoader()
+											->newInstanceWithId(4)
+											->setClefAlpha('harrypotter-azkaban')
+											->setDateMaj('2012-04-03 11:42:42')));
+		$this->_xml = $this->_response->xml(array('metadataPrefix' => 'oai_dc'));
+	}
+
+	
+	/** @test */
+	public function shouldHaveResumptionToken() {
+		$this->_xpath->assertXPath($this->_xml, '//oai:resumptionToken');
+	}
+
+}
+
+
 class ListIdentifiersInvalidParamsTest extends Storm_Test_ModelTestCase {
 	protected $_xpath;
 	protected $_response;
@@ -137,6 +182,7 @@ class ListIdentifiersInvalidParamsTest extends Storm_Test_ModelTestCase {
 
 	public function tearDown() {
 		Class_WebService_OAI_ResumptionToken::defaultCache(null);
+		parent::tearDown();
 	}
 
 
@@ -148,8 +194,8 @@ class ListIdentifiersInvalidParamsTest extends Storm_Test_ModelTestCase {
 
 	/** @test */
 	public function withUnknownFormatErrorCodeShouldBeCannotDisseminateFormat() {
-			$this->_xpath->assertXpath($this->_response->xml(array('metadataPrefix' => 'zork')),
-																 '//oai:error[@code="cannotDisseminateFormat"]');
+		$this->_xpath->assertXpath($this->_response->xml(array('metadataPrefix' => 'zork')),
+															 '//oai:error[@code="cannotDisseminateFormat"]');
 	}
 
 
@@ -167,8 +213,8 @@ class ListIdentifiersInvalidParamsTest extends Storm_Test_ModelTestCase {
 	/** @test */
 	public function withoutNoticesErrorCodeShouldBeNoRecordsMatch() {
 		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Notice')
-			->whenCalled('findAllBy')
-			->answers(array());
+			->whenCalled('countBy')
+			->answers(0);
 		$this->_xpath->assertXPath($this->_response->xml(array('metadataPrefix' => 'oai_dc')),
 															 '//oai:error[@code="noRecordsMatch"]');
 	}
diff --git a/tests/library/Class/WebService/OAI/ResumptionTokenTest.php b/tests/library/Class/WebService/OAI/ResumptionTokenTest.php
index 8dd01cb0062..7f1888a5ecf 100644
--- a/tests/library/Class/WebService/OAI/ResumptionTokenTest.php
+++ b/tests/library/Class/WebService/OAI/ResumptionTokenTest.php
@@ -67,6 +67,12 @@ class ResumptionTokenTest extends PHPUnit_Framework_TestCase {
 	}
 
 
+	/** @test */
+	public function pageNumberShouldBeOne() {
+		$this->assertEquals(1, $this->_token->getPageNumber());
+	}
+
+
 	/** @test */
 	public function findByMd5ShouldAnswerToken() {
 		$this->assertEquals($this->_token, Class_WebService_OAI_ResumptionToken::find(md5(serialize($this->_token))));
@@ -101,5 +107,12 @@ class ResumptionTokenTest extends PHPUnit_Framework_TestCase {
 																							'//resumptionToken[@completeListSize="10000"][@cursor="10"]',
 																							md5(serialize($next)));
 	}	
+
+
+	/** @test */
+	public function nextPageNumberShouldBeTwo() {
+			$this->assertEquals(2, $this->_token->next(10)->getPageNumber());
+	}
+
 }
 ?>
\ No newline at end of file
-- 
GitLab