Commit b3fc3f13 authored by Ghislain Loas's avatar Ghislain Loas

Merge branch 'hotline-master' into 'master'

Hotline master

See merge request afi/opacce!2513
parents a3a86f11 da24ad05
22/02/2018 - v7.11.21
- ticket #65371 : Affichage : correction de l'affichage des articles en mode mur / fluide sous Chrome
- ticket #71540 : Ressources numériques : Correctif du problème de connection à CVS avec un login contenant un caractère '&'
- ticket #70872 : Catalogage : Mise à jour des annexes des exemplaires lors de l'appel au webservice
- ticket #70912 : Affichage notice : prise en charge de l'affichage des editeurs multiples dans le bloc d'entête et la notice détaillée.
- ticket #71124 : Administration : Groupes : Correction de références circulaires
12/02/2018 - v7.11.20
- ticket #70867 : Ressources numériques Dilicom : amélioration des boutons d'emprunt ou de consultation d'un document PNB.
......
......@@ -110,7 +110,7 @@ class NoticeAjaxController extends Zend_Controller_Action {
$exemplaires = $this->_loadExemplaire(["id_notice" => $notice_ids]);
foreach($exemplaires as $exemplaire)
$exemplaire->updateAvailabilityFromSIGB()
$exemplaire->updateAvailabilityAndLocationFromSIGB()
->save();
$notices = Class_Notice::findAllBy(['id_notice' => $notice_ids]);
......@@ -132,7 +132,6 @@ class NoticeAjaxController extends Zend_Controller_Action {
protected function _loadExemplaire($params) {
$cond = $params;
$session = Zend_Registry::get('session');
$cond['id_bib'] = $session->id_bibs;
......
- ticket #65371 : correction de l'affichage des articles en mode mur / fluide sous Chrome
\ No newline at end of file
<?php
(new Class_Migration_HashAdminPasswords)->run();
\ No newline at end of file
(new Class_Migration_HashAdminPasswords)->run();
<?php
(new Class_Migration_CircularUserGroupCategories())->run();
......@@ -163,7 +163,9 @@ class Class_CVSLink {
$xml_user_infos = '';
foreach($user_infos as $k => $v)
$xml_user_infos .= '<' . $k . '>' . $v . '</' . $k . '>';
$xml_user_infos .= '<' . $k . '>' .
preg_replace('#&(?![a-z]{1,6};)#i', '&amp;',$v).
'</' . $k . '>';
return $xml_user_infos;
}
......
......@@ -205,13 +205,15 @@ class Class_Exemplaire extends Storm_Model_Abstract {
}
public function updateAvailabilityFromSIGB() {
public function updateAvailabilityAndLocationFromSIGB() {
if (!$sigb_exemplaire = $this->getSigbExemplaire())
return $this;
if (!$sigb_exemplaire->isValid())
return $this;
$this->setAnnexe($this->getCodeAnnexe());
return $this->setIsAvailable($sigb_exemplaire->isDisponible());
}
......@@ -373,7 +375,6 @@ class Class_Exemplaire extends Storm_Model_Abstract {
public function getCodeAnnexe() {
if ($code_annexe=$this->getSigbExemplaire()->getCodeAnnexe())
return $code_annexe;
return $this->annexe;
......
<?php
/**
* Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
* the Free Software Foundation.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
* along with BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Class_Migration_CircularUserGroupCategories {
public function run() {
foreach(Class_UserGroupCategorie::findAll() as $category)
$this->_runOne($category);
}
protected function _runOne($category) {
if ($category->isParentCategoryNotCircular())
return;
$category->setParentId(0)->save();
}
}
......@@ -728,7 +728,7 @@ class Class_Notice extends Storm_Model_Abstract {
switch ($champ) {
case Class_CodifAuteur::CODE_FACETTE: return $this->getAuteursUnimarc(false, true);
case Class_Codification::CODE_TITRE: return $this->getZonesTitre();
case Class_Codification::CODE_EDITEUR: return $this->getEditeur();
case Class_Codification::CODE_EDITEUR: return $this->getEditeurs();
case Class_Codification::CODE_COLLECTION: return $this->getCollections(true);
case Class_Codification::CODE_NOTES: return $this->getNotes();
case Class_Codification::CODE_COLLATION: return $this->getCollation();
......@@ -1307,9 +1307,16 @@ class Class_Notice extends Storm_Model_Abstract {
public function getEditeur() {
if ($this->_editeur)
return $this->_editeur;
if (!$data = $this->get_subfield('210', 'c'))
return '';
return trim($data[0]);
$editors = $this->getEditeurs();
return trim(reset($editors));
}
public function getEditeurs() {
return ($data = $this->get_subfield('210', 'c'))
? array_filter($data)
: [];
}
......
......@@ -105,12 +105,12 @@ class Class_UserGroupCategorie extends Storm_Model_Abstract {
public function validate() {
$this->checkAttribute('parent_id',
$this->_isParentCategoryNotCircular(),
$this->isParentCategoryNotCircular(),
$this->_('Référence circulaire'));
}
protected function _isParentCategoryNotCircular() {
public function isParentCategoryNotCircular() {
$parent = Class_UserGroupCategorie::getLoader()->find($this->getParentId());
while($parent) {
if ($parent->getId() == $this->getId()) {
......
......@@ -53,7 +53,7 @@ class ZendAfi_View_Helper_Notice_Unimarc extends Zend_View_Helper_HtmlElement {
'alpha_auteur' => $this->_('Alpha auteur'),
'titres' => $this->_('Titres'),
'auteurs' => $this->_('Auteurs'),
'editeur' => $this->_('Éditeur'),
'editeurs' => $this->_('Éditeurs'),
'facettes' => $this->_('Facettes'),
'clef_alpha' => $this->_('Clé alpha'),
'clef_oeuvre' => $this->_('Clé oeuvre'),
......@@ -68,7 +68,7 @@ class ZendAfi_View_Helper_Notice_Unimarc extends Zend_View_Helper_HtmlElement {
['scope' => 'row',
'style' => 'text-align:right;min-width:12em'])
. $this->_tag('td',
$notice->callGetterByAttributeName($field)));
str_replace(['"', '\\'], '', json_encode($notice->callGetterByAttributeName($field), JSON_PRETTY_PRINT))));
return $this->_tag('table', implode('', $lines));
}
......
......@@ -82,7 +82,7 @@ class Bokeh_Engine {
function setupConstants() {
defineConstant('BOKEH_MAJOR_VERSION','7.11');
defineConstant('BOKEH_RELEASE_NUMBER', BOKEH_MAJOR_VERSION . '.20');
defineConstant('BOKEH_RELEASE_NUMBER', BOKEH_MAJOR_VERSION . '.21');
defineConstant('BOKEH_REMOTE_FILES', 'http://git.afi-sa.fr/afi/opacce/');
......
......@@ -66,6 +66,10 @@ body .ui-tabs .ui-tabs-nav > .ui-tabs-active > a {
text-align:center;
}
.ui-dialog .ui-dialog-content td {
text-align: left;
}
.ui-dialog form label {
margin-right: 10px;
}
......
......@@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
include_once 'tests/fixtures/NanookFixtures.php';
class NoticeAjaxControllerNonRegressionTest extends AbstractControllerTestCase {
public function setUp() {
......@@ -764,6 +764,92 @@ abstract class NoticeAjaxControllerExemplairesTestCase extends AbstractControlle
class NoticeAjaxControllerExemplairesWithOtherAnnexTestCase extends AbstractControllerTestCase {
protected
$_storm_default_to_volatile=true,
$_notice,
$_service,
$_web_client,
$_sigb_exemplaire;
public function setUp() {
parent::setUp();
Class_WebService_SIGB_Nanook::reset();
$this->fixture('Class_Bib',
['id' => 6,
'libelle' => 'Seynod']);
$params = ['url_serveur' => 'http://nanook/',
'id_bib' => 6,
'type' => Class_intBib::COM_NANOOK];
$this->fixture('Class_IntBib',
['id' => 6,
'comm_sigb' => Class_IntBib::COM_NANOOK,
'comm_params' => serialize($params)
]);
$this->fixture('Class_bib',
['id' => 99]);
$this->fixture('Class_Bib',
['id' => 21,
'libelle' => 'Library']);
$this->_web_client = $this
->mock()
->whenCalled('open_url')
->with('http://nanook/service/GetRecords/id/369667')
->answers(NanookFixtures::xmlGetRecordsEx());
$this->_service = Class_WebService_SIGB_Nanook_Service::newInstance()
->setServerRoot('http://nanook/')
->setWebClient($this->_web_client);
Class_WebService_SIGB_Nanook::setService($params, $this->_service);
$this->_notice = $this->fixture('Class_Notice',
['id' => 123,
'clef_oeuvre' => 'AAA',
'facettes' => 'D78092 A3029 A9751 A117014 A117015 M37414 G464 HNNNN0002 HNANA0002 T4 B6 S1 Y6 V6 2018-04',
])
->setExemplaires([$this->fixture('Class_Exemplaire',
['id' => 999,
'id_bib' => 6,
'id_int_bib' => 6,
'id_notice' => 123,
'id_origine' => '369667',
'annexe' => 'MOUL',
'section' => 'A9',
'emplacement' => 'emplacement de test',
'cote' => 'VOD-T-DLJ',
'dispo' => 'Disponible',
'date_retour' => 'En mai',
'reservable' => true,
'code_barres' => '028111272'])]);
$this->_notice->save();
$this->fixture('Class_Notice', ['id' => 125,
'clef_oeuvre' => 'AAA',
'exemplaires' => [$this->fixture('Class_Exemplaire',
['id' => 799,
'id_bib' => 99,
'id_int_bib' => 4,
'id_notice' => 125,
'cote' => 'VOD',
'dispo' => 'Disponible'])]]);
}
/** @test */
public function facetsShouldBeUpdatedWithAnnex21() {
$this->dispatch('noticeajax/exemplaires/id/123', true);
$this->assertEquals('D78092 A3029 A9751 A117014 A117015 M37414 G464 HNNNN0002 HNANA0002 T0 B6 SA9 Eemplacement de test Y21 V6', Class_notice::find(123)->getFacettes());
}
}
class NoticeAjaxControllerExemplairesSameWorkTest extends NoticeAjaxControllerExemplairesTestCase {
......@@ -2526,4 +2612,32 @@ class NoticeAjaxControllerNanookSIGBWithHoldSiteEnabledTest extends AbstractCont
public function holdLinkShouldContainsPaulBranchCode() {
$this->assertXPath('//table//a[@href="/recherche/reservation-pickup-ajax/id_notice/10/id_int_bib/12/id_bib/12/copy_id/654/code_annexe/CAV"]', $this->_response->getBody());
}
}
class NoticeAjaxControllerDetailWithMultipleEditorsTest extends AbstractControllerTestCase {
protected $_storm_default_to_volatile = true;
public function setUp() {
parent::setUp();
$record = $this->fixture('Class_Notice',
['id' => 1,
'unimarc' => file_get_contents(__DIR__ . '/hl_70912.unimarc')]);
$this->dispatch('/opac/noticeajax/detail/id_notice/1', true);
}
/** @test */
public function shouldContainsEditorsActesSud() {
$this->assertXPathContentContains('//dd//div', 'Actes Sud');
}
/** @test */
public function shouldContainsEditorsKaizen() {
$this->assertXPathContentContains('//dd//div', 'Kaizen');
}
}
\ No newline at end of file
......@@ -392,8 +392,8 @@ class RechercheControllerViewNoticeWithPreferencesTest extends RechercheControll
/** @test */
public function enteteShouldDisplayEditeurGallimard() {
$this->assertXPathContentContains('//dl//dd', 'Gallimard');
public function enteteShouldDisplayEditeurCahiersDuCinema() {
$this->assertXPathContentContains('//dl//dd//div', 'Cahiers du cinéma');
}
......
02770nam0 2200457 450 001000700000010003400007100004500041101001300086102001100099105004500110106004500155181001600200181002400216182001000240182002200250200010400272210002800376210002400404211001300428215006800441225002300509304006700532330029100599333001600890345001800906410002300924606006900947606053501016610009601551676010801647700003601755701005001791702005101841801003301892856008201925902003102007903008802038903003402126947000902160992014302169178141 a978-2-330-07240-7bbr.d8 EUR a20170321d2017 m |0frey0103||||ba 0 afrecFRE aFRaFR a 0||y|  ar  0601aibxxxe 0602ctxt2rdacontent 0601an 0602cn2rdacontent1 aS'engager dans une AmapfFrançoise Vernet, Marie-Noëlle Himbertgillustrations de Cécilia Pepper aArles cActes Sudd2017 aPariscKaizend2017 a20170308 a1 vol. (62 p.)cillustrations en noir et en couleurd19 x 14 cm2 aJe passe à l'acte aAmap = Association pour le maintien d'une agriculture paysanne aCe guide pratique revient sur les origines historiques du concept d'Amap et détaille les étapes de création de cette structure. Chaque chapitre propose des outils différents : bases éthiques, équipement, aide au démarrage ou encore pistes vers d'autres activités. ©Electre 2017 aTout public b9782330072407 0tJe passe à l'acte aAssociations pour le maintien d'une agriculture paysanne2rameau 311970982aProduits agricolesxVente coopérative311931476yFrance311975688xGuides, manuels, etc.2rameau8Agriculture participative8Coopératives agricoles de vente8Vente coopérative de produits agricoles8Vente directe de produits agricoles8Vente directe de produits régionaux8Francie occidentale8Aide-mémoire8Caractéristiques techniqueswAwRépertoires8Données techniqueswAwRépertoires8Fiches techniques8Formulaires (technique)8Formulaires techniques8Guides pratiques8Guides techniques8Mémentos8Vade-mecum0 aagriculteur : agriculture biologique : politique agricole : produit agricole : coopérative a334tCoopératives, mutuelles et associations de consommateurs. Guide et protection du consommateurv23 1aVernetbFrançoise40706Auteur 1aHimbertbMarie-Noëlle31410630240706Auteur 1aPepperbCéciliaf1987-....44406Illustrateur 3aFRbElectrec20170321gAFNOR4 uhttp://www.electre.com/GetBlob.ashx?Ean=9782330072407,0-4045886&Size=Original aGrand public - Tout public aAgriculture, Forêts, Pêche - Politique et économie agricoles - Commercialisation aDocuments, essais - Documents c8.00 uhttps://images-eu.ssl-images-amazon.com/images/I/51ERhIJIeWL._SL160_.jpgvhttps://images-eu.ssl-images-amazon.com/images/I/51ERhIJIeWL.jpg
\ No newline at end of file
......@@ -1995,3 +1995,14 @@ class UpgradeDB_341_Test extends UpgradeDBTestCase {
$this->assertEquals(0, $datas['numberOf']);
}
}
class UpgradeDB_342_Test extends UpgradeDBTestCase {
public function prepare() {}
/** @test */
public function placeholderForCircularUserGroupCategories() {}
}
\ No newline at end of file
......@@ -630,7 +630,7 @@ class NanookFixtures {
public static function xmlGetLoanHistoryPageTwo() {
return '
return '
<GetLoanHistory>
<loans count="3" pageNumber="2" pageSize="2">
<loan>
......@@ -651,7 +651,10 @@ class NanookFixtures {
</loan>
</loans>
</GetLoanHistory>';
}
public static function xmlGetRecordsEx() {
return '<GetRecords><record><bibId>369667</bibId><title>Barbara</title><items><item><barcode>028111272</barcode><itemId>235195</itemId><available>1</available><holdable>1</holdable><holds>0</holds><visible>1</visible><locationLabel>Saint Pargoire</locationLabel><locationId>21</locationId><activityMessage>En rayon</activityMessage></item></items></record></GetRecords>';
}
}
\ No newline at end of file
......@@ -36,7 +36,7 @@ abstract class CVSLinkTestCase extends ModelTestCase {
->newInstanceWithId(4)
->setIdabon(34)
->setLogin(34)
->setPseudo('JKhan')
->setPseudo('J&Khan')
->setPrenom('Jerry')
->setNom('Khan')
->setMail('feu@essence.fr')
......@@ -144,7 +144,7 @@ class CVSLinkSearchTest extends CVSLinkTestCase {
<login>34</login>
<nom>Khan</nom>
<prenom>Jerry</prenom>
<pseudo>JKhan</pseudo>
<pseudo>J&amp;Khan</pseudo>
<password>secret</password>
<email>feu@essence.fr</email>
<dnaiss>1977-06-27</dnaiss>
......@@ -225,7 +225,7 @@ class CVSLinkWithAbonTest extends CVSLinkTestCase {
<login>34</login>
<nom>Khan</nom>
<prenom>Jerry</prenom>
<pseudo>JKhan</pseudo>
<pseudo>J&amp;Khan</pseudo>
<password>secret</password>
<email>feu@essence.fr</email>
<dnaiss>1977-06-27</dnaiss>
......@@ -300,7 +300,7 @@ class CVSLinkWithAbonAndLibraryLabelTest extends CVSLinkTestCase {
<login>34</login>
<nom>Khan</nom>
<prenom>Jerry</prenom>
<pseudo>JKhan</pseudo>
<pseudo>J&amp;Khan</pseudo>
<password>secret</password>
<email>feu@essence.fr</email>
<dnaiss>1977-06-27</dnaiss>
......
<?php
/**
* Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
* the Free Software Foundation.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
* along with BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Class_Migration_CircularUserGroupCategoriesTest extends ModelTestCase {
protected $_storm_default_to_volatile=true;
public function setUp() {
parent::setUp();
$this->fixture('Class_UserGroupCategorie',
['id' => 2,
'parent_id' =>1 ]);
// skip model validation to reproduce production data corruption
// one level
Class_UserGroupCategorie::getLoader()
->save(Class_UserGroupCategorie::newInstance(['id' => 3,
'parent_id' => 3 ]));
// two levels
Class_UserGroupCategorie::getLoader()
->save(Class_UserGroupCategorie::newInstance(['id' => 4,
'parent_id' => 5 ]));
Class_UserGroupCategorie::getLoader()
->save(Class_UserGroupCategorie::newInstance(['id' => 5,
'parent_id' => 4 ]));
// three levels
Class_UserGroupCategorie::getLoader()
->save(Class_UserGroupCategorie::newInstance(['id' => 10,
'parent_id' => 11 ]));
Class_UserGroupCategorie::getLoader()
->save(Class_UserGroupCategorie::newInstance(['id' => 11,
'parent_id' => 12 ]));
Class_UserGroupCategorie::getLoader()
->save(Class_UserGroupCategorie::newInstance(['id' => 12,
'parent_id' => 10 ]));
(new Class_Migration_CircularUserGroupCategories())->run();
}
/** @test */
public function notCircularShouldNotBeUpdated() {
$this->assertEquals(1, Class_UserGroupCategorie::find(2)->getParentId());
}
/** @test */
public function circularOneLevelShouldMoveToRoot() {
$this->assertEquals(0, Class_UserGroupCategorie::find(3)->getParentId());
}
/** @test */
public function circularTwoLevelsShouldMoveToRoot() {
$this->assertEquals(0, Class_UserGroupCategorie::find(4)->getParentId());
$this->assertEquals(4, Class_UserGroupCategorie::find(5)->getParentId());
}
/** @test */
public function circularTreeLevelsShouldMoveToRoot() {
$this->assertEquals(0, Class_UserGroupCategorie::find(10)->getParentId());
$this->assertEquals(12, Class_UserGroupCategorie::find(11)->getParentId());
$this->assertEquals(10, Class_UserGroupCategorie::find(12)->getParentId());
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment