Commit ccd057eb authored by Laurent's avatar Laurent
Browse files

Merge branch 'dev#103980_pairing_yann_domaines' into 'master'

dev #103980 Domain / test now displays record thumbnails with paginator and…

See merge request !3387
parents 64edba37 8079984d
Pipeline #9306 passed with stage
in 55 minutes and 47 seconds
- ticket #103980 : Administration / Domaines : l'écran de test/indexation affiche maintenant la liste des notices complète avec pagination et vignettes. Permet de générer les vignettes des notices.
\ No newline at end of file
...@@ -40,12 +40,16 @@ class Admin_CatalogueController extends ZendAfi_Controller_Action { ...@@ -40,12 +40,16 @@ class Admin_CatalogueController extends ZendAfi_Controller_Action {
if (!$catalogue = Class_Catalogue::find((int)$this->_getParam("id_catalogue", 0))) if (!$catalogue = Class_Catalogue::find((int)$this->_getParam("id_catalogue", 0)))
$this->_redirect("admin/catalogue/index"); $this->_redirect("admin/catalogue/index");
$this->view->page = $this->_getParam('page', 1);
$this->view->nb_per_page = 20;
$ret = ['requete' => '', $ret = ['requete' => '',
'nb_notices' => 0, 'nb_notices' => 0,
'avec_vignettes' => 0, 'avec_vignettes' => 0,
'notices' => '']; 'notices' => ''];
$this->getRequest()->setParam('render', null); $this->getRequest()->setParam('render', null);
$ret = array_merge($ret, $catalogue->getTestCatalogue()); $ret = array_merge($ret,
$catalogue->getTestCatalogue($this->view->nb_per_page,
$this->view->page));
if ($catalogue->hasIndexer()) if ($catalogue->hasIndexer())
$catalogue->indexWithBaskets(); $catalogue->indexWithBaskets();
......
...@@ -41,8 +41,7 @@ class Admin_SystemeController extends Zend_Controller_Action { ...@@ -41,8 +41,7 @@ class Admin_SystemeController extends Zend_Controller_Action {
if ($this->_getParam('mode') != 'reset_no') if ($this->_getParam('mode') != 'reset_no')
return $this; return $this;
Zend_Registry::get('sql') Class_WebService_Vignette::resetNoDataThumbnails();
->execute("update notices set url_vignette='',url_image='' where url_vignette='" . Class_WebService_Vignette::NO_DATA . "'");
} }
...@@ -89,16 +88,15 @@ class Admin_SystemeController extends Zend_Controller_Action { ...@@ -89,16 +88,15 @@ class Admin_SystemeController extends Zend_Controller_Action {
public function makecacheimagesAction() { public function makecacheimagesAction() {
if ($records_count = Class_Notice::countBy(['url_vignette' => ''])) {
$record = Class_Notice::findFirstBy(['url_vignette' => '']);
$record->fetchUrlLocalVignette();
}
$this->getHelper('ViewRenderer')->setNoRender(); $this->getHelper('ViewRenderer')->setNoRender();
$html = $records_count - 1; $cache = new Class_Notice_Thumbnail_Cache();
$cache->build($this->getRequest());
if ($next_record = Class_Notice::findFirstBy(['url_vignette' => ''])) { $html = $cache->getRecordCount();
if ($next_record = $cache->getNextRecord()) {
$html .= $this->view->tag('div', $html .= $this->view->tag('div',
$this->view->tag('a', $this->view->tag('a',
$next_record->getTitrePrincipal() . ' (' . $next_record->getAuteurPrincipal() . ')', $next_record->getTitrePrincipal() . ' (' . $next_record->getAuteurPrincipal() . ')',
...@@ -107,7 +105,12 @@ class Admin_SystemeController extends Zend_Controller_Action { ...@@ -107,7 +105,12 @@ class Admin_SystemeController extends Zend_Controller_Action {
null, null,
true), true),
'target' => '_blank'])); 'target' => '_blank']));
$html .= '<script>makeCacheImages("/admin/systeme/makecacheimages")</script>';
$html .= sprintf('<script>makeCacheImages(\'%s\')</script>',
$this->view->url($cache->getCallbackUrl($this->getRequest()),
null,
true));
} }
$this->getResponse()->setBody($html); $this->getResponse()->setBody($html);
......
...@@ -18,7 +18,14 @@ ...@@ -18,7 +18,14 @@
['alt' => $this->_('Paniers'), ['alt' => $this->_('Paniers'),
'class' => 'ico', 'class' => 'ico',
'title' => $this->_('Paniers rattachés au domaine "%s"', 'title' => $this->_('Paniers rattachés au domaine "%s"',
$this->catalogue->getLibelle())])), $this->catalogue->getLibelle())]))
.
$this->tagPreview($this->url(['module' => 'opac',
'controller' => 'recherche',
'action' => 'simple',
'id_catalogue' => $this->catalogue->getId()],
null, true),
$this->_('Visualiser le domaine "%s" dans un nouvel onglet', $this->catalogue->getLibelle())),
['class' => 'header_actions']); ['class' => 'header_actions']);
...@@ -30,23 +37,44 @@ if (!$this->notices) ...@@ -30,23 +37,44 @@ if (!$this->notices)
else { else {
echo $this->ligneInfos($this->_('Notices trouvées'), $this->nb_notices); echo $this->ligneInfos($this->_('Notices trouvées'), $this->nb_notices);
echo $this->ligneInfos($this->_('Avec vignettes en cache'), $this->avec_vignettes); echo $this->ligneInfos($this->_('Avec vignettes en cache'), $this->avec_vignettes);
echo $this->Admin_GenerateImageCache(
$this->url(['module' => 'admin',
'controller' => 'systeme',
'action' => 'makecacheimages',
'id_catalogue' => $this->catalogue->getId(),
'reset_no' => 1],
null,
true));
if (!$this->isPopup())
echo $this->button((new Class_Entity())
->setText($this->_('Modifier le domaine '))
->setAttribs(['title' => $this->_('Modifier le domaine : %s',
$this->catalogue->getLibelle())])
->setUrl($this->url(['action' => 'edit',
'id_catalogue' => $this->catalogue->getId()]))
->setImage($this->tagImg(Class_Admin_Skin::current()
->getIconUrl('buttons', 'configuration'))));
} }
echo $this->pager($this->nb_notices,
$this->nb_per_page,
$this->page,
$this->url(['module' => 'admin',
'controller' => 'catalogue',
'action' => 'tester',
'id_catalogue' => $this->catalogue->getId()],
null,
true));
if ($this->notices) { if ($this->notices) {
echo $this->listeNotices_Tableau($this->notices, echo $this->listeNotices_Tableau($this->notices,
['liste_codes' => 'T;J;A;N']); ['liste_codes' => implode(';',
[Class_Codification::CODE_THUMBNAIL,
Class_TypeDoc::CODE_FACETTE,
Class_Codification::CODE_TITRE,
Class_CodifAuteur::CODE_FACETTE,
Class_Codification::CODE_ANNEE ]),
'open_links_in_new_tab' => '1']);
} }
echo $this->tagNotice('Affichage des 20 premières notices uniquement.');
if (!$this->isPopup())
echo $this->button((new Class_Entity())
->setText($this->_('Modifier le domaine '))
->setAttribs(['title' => $this->_('Modifier le domaine : %s',
$this->catalogue->getLibelle())])
->setUrl($this->url(['action' => 'edit',
'id_catalogue' => $this->catalogue->getId()]))
->setImage($this->tagImg(Class_Admin_Skin::current()
->getIconUrl('buttons', 'configuration'))));
<script src="<?php echo URL_ADMIN_JS?>jquery-1.6.4.min"> </script>
<script src="<?php echo URL_ADMIN_JS?>cacheimages.js"> </script>
<?php <?php
echo $this->tag('h2', $this->_('Base de données')); echo $this->tag('h2', $this->_('Base de données'));
...@@ -20,14 +17,4 @@ echo $this->button( ...@@ -20,14 +17,4 @@ echo $this->button(
->setUrl($this->url(['mode' => 'reset_no'])) ->setUrl($this->url(['mode' => 'reset_no']))
->setImage($this->tagImg(Class_Admin_Skin::current()->getIconUrl('buttons', 'generate')))); ->setImage($this->tagImg(Class_Admin_Skin::current()->getIconUrl('buttons', 'generate'))));
echo $this->button( echo $this->Admin_GenerateImageCache();
(new Class_Entity())->setText($this->_('Constitution du cache'))
->setAttribs(['onclick' => 'makeCacheImages(); return false;'])
->setImage($this->tagImg(Class_Admin_Skin::current()->getIconUrl('actions', 'down'),
['style' => 'filter: invert();'])));
// Constitution du cache des images
echo BR.BR.'<div id="bloc_restantes" align="center" style="display:none">';
echo $this->tag('h2', $this->_('Constitution du cache en cours...'));
echo $this->tag('h3', $this->_('Notices à traiter: %s', '<span id="restantes"></span>'));
echo '</div>';
...@@ -345,10 +345,14 @@ class CatalogueLoader extends Storm_Model_Loader { ...@@ -345,10 +345,14 @@ class CatalogueLoader extends Storm_Model_Loader {
if ($catalogue && $catalogue->isEmpty()) if ($catalogue && $catalogue->isEmpty())
return []; return [];
if(isset($preferences['only_img']) && ($preferences['only_img'] == 1) if(isset($preferences['only_img']) && ($preferences['only_img'] == Class_Catalogue::ONLY_IMG)
&& (($catalogue && Class_Catalogue::getLoader()->hasFilters($preferences['id_catalogue'])) || !$catalogue)) && (($catalogue && Class_Catalogue::getLoader()->hasFilters($preferences['id_catalogue'])) || !$catalogue))
$conditions[] = "url_vignette > '' and url_vignette != '" . Class_WebService_Vignette::NO_DATA . "' "; $conditions[] = "url_vignette > '' and url_vignette != '" . Class_WebService_Vignette::NO_DATA . "' ";
if (isset($preferences['only_img']) && ($preferences['only_img'] == Class_Catalogue::WITHOUT_IMG))
$conditions[] = "url_vignette=''";
$join = (isset($preferences['avec_avis']) && ($preferences['avec_avis'] == 1)) $join = (isset($preferences['avec_avis']) && ($preferences['avec_avis'] == 1))
? ' INNER JOIN notices_avis ON notices.clef_oeuvre=notices_avis.clef_oeuvre ' ? ' INNER JOIN notices_avis ON notices.clef_oeuvre=notices_avis.clef_oeuvre '
: ''; : '';
...@@ -645,7 +649,10 @@ class CatalogueLoader extends Storm_Model_Loader { ...@@ -645,7 +649,10 @@ class CatalogueLoader extends Storm_Model_Loader {
class Class_Catalogue extends Storm_Model_Abstract { class Class_Catalogue extends Storm_Model_Abstract {
use Trait_TreeNode, Trait_Translator, Trait_CustomFields, Trait_Facetable; use Trait_TreeNode, Trait_Translator, Trait_CustomFields, Trait_Facetable;
const CODE_FACETTE = 'Q'; const
CODE_FACETTE = 'Q',
ONLY_IMG = 1,
WITHOUT_IMG = 2;
protected protected
$_table_name = 'catalogue', $_table_name = 'catalogue',
...@@ -827,9 +834,8 @@ class Class_Catalogue extends Storm_Model_Abstract { ...@@ -827,9 +834,8 @@ class Class_Catalogue extends Storm_Model_Abstract {
} }
public function getTestCatalogue() { public function getTestCatalogue($nb_per_page = 20, $page = 1) {
$preferences = $this->toArray(); $preferences = $this->toArray();
$preferences['nb_notices'] = 20;
$requetes = Class_Catalogue::getLoader()->getRequetes($preferences); $requetes = Class_Catalogue::getLoader()->getRequetes($preferences);
if(empty($requetes['req_liste'])) if(empty($requetes['req_liste']))
...@@ -839,9 +845,10 @@ class Class_Catalogue extends Storm_Model_Abstract { ...@@ -839,9 +845,10 @@ class Class_Catalogue extends Storm_Model_Abstract {
$temps = time(); $temps = time();
$ret["notices"] = Class_Notice::findAllByRequeteRecherche($requetes['req_ids'], $ret["notices"] = Class_Notice::findAllByRequeteRecherche($requetes['req_ids'],
$preferences['nb_notices'], $nb_per_page,
1); $page);
$ret["temps_execution"] = time() - $temps; $ret["temps_execution"] = time() - $temps;
$ret["nb_notices"] = fetchOne($requetes["req_comptage"]); $ret["nb_notices"] = fetchOne($requetes["req_comptage"]);
$req = $requetes["req_comptage"]; $req = $requetes["req_comptage"];
......
...@@ -42,10 +42,10 @@ ...@@ -42,10 +42,10 @@
* R: résumé * R: résumé
* S: section * S: section
* T: type de doc * T: type de doc
* U: * U: vignette/image
* V: disponibilité * V: disponibilité
* W: éditeur * W: éditeur
* X: * X: index dewey pcdm4
* Y: annexe * Y: annexe
* Z: tag * Z: tag
* 5: données autorités * 5: données autorités
...@@ -68,7 +68,9 @@ class Class_Codification { ...@@ -68,7 +68,9 @@ class Class_Codification {
CODE_AVAILABILITY='V', CODE_AVAILABILITY='V',
CODE_AUTHORITY_DATAS='5', CODE_AUTHORITY_DATAS='5',
CODE_URL = '8', CODE_URL = '8',
CODE_NOUVEAUTE = '9'; CODE_NOUVEAUTE = '9',
CODE_INDEX_DEWEY_PCDM4 = 'X',
CODE_THUMBNAIL = 'U';
protected protected
...@@ -92,7 +94,7 @@ class Class_Codification { ...@@ -92,7 +94,7 @@ class Class_Codification {
return ''; return '';
switch($type) { switch($type) {
case "X": case Class_Codification::CODE_INDEX_DEWEY_PCDM4:
$lib=[" ", $this->_('Livres et Vidéos'), $this->_('Musique')]; $lib=[" ", $this->_('Livres et Vidéos'), $this->_('Musique')];
$l=Class_AdminVar::get("FACETTE_PCDM4_LIBELLE"); if(trim($l)) $lib[2]=$l; $l=Class_AdminVar::get("FACETTE_PCDM4_LIBELLE"); if(trim($l)) $lib[2]=$l;
$l=Class_AdminVar::get("FACETTE_DEWEY_LIBELLE"); if(trim($l)) $lib[1]=$l; $l=Class_AdminVar::get("FACETTE_DEWEY_LIBELLE"); if(trim($l)) $lib[1]=$l;
...@@ -147,6 +149,7 @@ class Class_Codification { ...@@ -147,6 +149,7 @@ class Class_Codification {
Class_Codification::CODE_NOUVEAUTE => [ $this->_("Nouveauté"), $this->_("Nouveauté")], Class_Codification::CODE_NOUVEAUTE => [ $this->_("Nouveauté"), $this->_("Nouveauté")],
Class_Codification::CODE_PRIX => [ $this->_("Prix"), $this->_("Prix")], Class_Codification::CODE_PRIX => [ $this->_("Prix"), $this->_("Prix")],
Class_CodifEmplacement::CODE_FACETTE => [ $this->_('Emplacement'), $this->_('Emplacement')], Class_CodifEmplacement::CODE_FACETTE => [ $this->_('Emplacement'), $this->_('Emplacement')],
Class_Codification::CODE_THUMBNAIL => [ $this->_('Vignette'), $this->_('Vignette')],
Class_Codification::CODE_AUTHORITY_DATAS => [ $this->_('Autorité'), $this->_('Autorité')],]; Class_Codification::CODE_AUTHORITY_DATAS => [ $this->_('Autorité'), $this->_('Autorité')],];
$this->addThesauriToNomChamps(); $this->addThesauriToNomChamps();
......
...@@ -51,18 +51,21 @@ class NoticeLoader extends Storm_Model_Loader { ...@@ -51,18 +51,21 @@ class NoticeLoader extends Storm_Model_Loader {
} }
public function getNoticeIdsByRequeteRecherche($req) { public function getNoticeIdsByRequeteRecherche($req, $clear_cache = false) {
if (!$req) if (!$req)
return []; return [];
$closure = function() use ($req) { $cache = (new Storm_Cache())->useImplodeExplodeSerialization();
return Zend_Registry::get('sql')->fetchAllByColumn($req); $cache_key = [$req, __CLASS__, __FUNCTION__];
};
return (new Storm_Cache()) if ($clear_cache)
->useImplodeExplodeSerialization() $cache->remove($cache_key);
->memoize([$req, __CLASS__, __FUNCTION__],
$closure); return $cache->memoize($cache_key,
function() use ($req)
{
return Zend_Registry::get('sql')->fetchAllByColumn($req);
});
} }
......
<?php
/**
* Copyright (c) 2012-2020, 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_Notice_Thumbnail_Cache {
protected
$_remaining_records_count,
$_next_record;
public function build($request) {
$this->_next_record = null;
$this->_remaining_records_count = 0;
if ($request->getParam('reset_no'))
Class_WebService_Vignette::resetNoDataThumbnails();
return ($id_catalogue = $request->getParam('id_catalogue'))
? $this->_updateNextRecordForCatalogue($request)
: $this->_updateNextRecordForAll();
}
public function getCallbackUrl($request) {
return array_filter( ['module' => 'admin',
'controller' => 'systeme',
'action' => 'makecacheimages',
'id_catalogue' => $request->getParam('id_catalogue')] );
}
protected function _updateNextRecordForCatalogue($request) {
if (!$catalog = Class_Catalogue::find($request->getParam('id_catalogue')))
return $this;
$requetes = Class_Catalogue::getRequetes(['id_catalogue' => $catalog->getId(),
'only_img' => Class_Catalogue::WITHOUT_IMG]);
if (!$ids = Class_Notice::getNoticeIdsByRequeteRecherche($requetes['req_ids'], true))
return $this;
$this->_remaining_records_count = count($ids);
$this->_updateThumbnailForRecord(Class_Notice::find($ids[0]));
if ($this->_remaining_records_count > 0)
$this->_next_record = Class_Notice::find($ids[1]);
return $this;
}
protected function _updateNextRecordForAll() {
if (!$this->_remaining_records_count = Class_Notice::countBy(['url_vignette' => '']))
return $this;
$this->_updateThumbnailForRecord($this->_firstRecordWithoutThumbnail());
$this->_next_record = $this->_firstRecordWithoutThumbnail();
return $this;
}
protected function _updateThumbnailForRecord($record) {
$record->fetchUrlLocalVignette();
$this->_remaining_records_count --;
return $this;
}
public function getNextRecord() {
return $this->_next_record;
}
public function getRecordCount() {
return $this->_remaining_records_count;
}
public function isBuiltDone() {
return empty($this->_next_record);
}
protected function _firstRecordWithoutThumbnail() {
return Class_Notice::findFirstBy(['url_vignette' => '']);
}
}
<?php
/**
* Copyright (c) 2012, 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_Thumbs
{
var $config = array(
'album' => array(
"max_width" => 9999,
"max_height" => 9999,
"thumb_max_width" => 160,
"thumb_max_height" => 120
)
);
private $name;
private $path_to_save;
private $type;
private $working_img;
function __construct($path_to_img="",$type_img='avatar')
{
$this->type = $type_img;
$this->name = str_replace(dirname($path_to_img).'/','',$path_to_img);
$this->path_to_save = dirname($path_to_img).'/';
$this->working_img = $path_to_img;
}
//---------------------------------------------------------------------
// traite une image fabrique le thumb et retaille la grande image
//---------------------------------------------------------------------
public function traiteImage($adresse_fichier,$creer_thumb,$type)
{
// parametres du fichier
if(file_exists($adresse_fichier)==false) return array("erreur_image"=>"fichier image non trouvé");
// test si assez de memoire
$ret=$this->testConsoMemoire($adresse_fichier);
// Si pas assez de memoire : on degage
if($ret["statut"]==false)
{
return false;
}
// Grande image
$thumb = Thumbs_ThumbLib::create($adresse_fichier);
if($this->config[$type]["max_width"] != 9999)
{
$thumb->resize($this->config[$type]["max_width"], $this->config[$type]["max_height"]);
$thumb->save($adresse_fichier);
}
// thumb
if($creer_thumb==true)
{
$fic=pathinfo($adresse_fichier);
$path_thumbs=str_replace("/big","/thumbs",$fic["dirname"]);
if(file_exists($path_thumbs)==false) mkdir($path_thumbs);
$thumb->resize($this->config[$type]["thumb_max_width"], $this->config[$type]["thumb_max_height"]);
$thumb->save($path_thumbs.'/'.$fic["basename"]);
}
// retour
return $ret;
}
//---------------------------------------------------------------------
// teste la capacité de la memoire pour traiter l'image
//---------------------------------------------------------------------
function testConsoMemoire($fic)
{
// parametres
$facteur_pixels=204;
$marge_securite=100;
// limite memoire
$mem_limit=ini_get("memory_limit");
$mem_max=intval(str_replace("M","",$mem_limit))*1024;
$mem_used=intval(memory_get_usage()/1024);
$mem_dispo=($mem_max-$mem_used)-$marge_securite;
// estimation memoire pour l'image
$info=getimagesize ($fic);
$pixels=$info[0]*$info[1];
$mem_image=intval($pixels/$facteur_pixels);