RechercheController.php 28.9 KB
Newer Older
1 2 3 4
<?php
/**
 * Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved.
 *
Laurent's avatar
Laurent committed
5
 * BOKEH is free software; you can redistribute it and/or modify
6 7 8 9 10 11
 * 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).
 *
Laurent's avatar
Laurent committed
12
 * BOKEH is distributed in the hope that it will be useful,
13 14 15 16 17
 * 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
Laurent's avatar
Laurent committed
18
 * along with BOKEH; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
20 21
 */

22
class RechercheController extends ZendAfi_Controller_Action {
Patrick Barroca's avatar
Patrick Barroca committed
23 24 25
  protected
    $moteur,
    $preferences;
Patrick Barroca's avatar
Patrick Barroca committed
26 27


28 29 30 31
  public function __call($method_name, $args) {
    try {
      parent::__call($method_name, $args);
    } catch(Exception $e) {
32 33 34 35
      $this->_forward('simple',
                      'recherche',
                      'opac',
                      array_merge($this->_request->getParams(),
36 37
                                  ['q' => urldecode($this->_request->getActionName())]));
    }
38 39 40
  }


41
  public function getPlugins() {
42
    return ['ZendAfi_Controller_Plugin_Printer_SearchResult',
43
            'ZendAfi_Controller_Plugin_Mailer_SearchResult'];
44 45 46
  }


Patrick Barroca's avatar
Patrick Barroca committed
47 48 49
  public function init() {
    $this->moteur = Class_MoteurRecherche::getInstance();
    $this->view->resultat = [];
50

Patrick Barroca's avatar
Patrick Barroca committed
51
    $this->view->statut = $this->_getParam('statut');
52

Patrick Barroca's avatar
Patrick Barroca committed
53 54
    if ($this->view->statut == 'reset')
      $this->view->statut = 'saisie';
55

Patrick Barroca's avatar
Patrick Barroca committed
56 57
    $this->view->url_retour = BASE_URL . '/opac/recherche/simple/';
    $this->view->url_facette = $this->view->url_retour;
Patrick Barroca's avatar
Patrick Barroca committed
58

Patrick Barroca's avatar
Patrick Barroca committed
59 60
    $this->preferences = $this->_getParam('current_module')['preferences'];
  }
61 62


63
  public function preDispatch() {
64
    parent::preDispatch();
65 66 67 68 69 70
    if ('json' === $this->_getParam('format')
        && 'viewnotice' === $this->_request->getActionName())
      $this->_forward('json-record');
  }


Patrick Barroca's avatar
Patrick Barroca committed
71 72 73 74 75
  public function guideeAction() {
    $this->view->statut = 'guidee';
    $this->simpleAction();
    return;
  }
76

Patrick Barroca's avatar
Patrick Barroca committed
77

Patrick Barroca's avatar
Patrick Barroca committed
78 79 80
  public function indexAction() {
    $this->_forward('simple');
  }
81

82

Patrick Barroca's avatar
Patrick Barroca committed
83 84 85
  public function saisieAction() {
    $this->view->expressionRecherche = $this->_request->getParam('expressionRecherche');
  }
86 87


Patrick Barroca's avatar
Patrick Barroca committed
88
  public function simpleAction() {
89 90
    if ($this->view->statut == "saisie")
      return $this->_redirect('opac/recherche/saisie');
91

Patrick Barroca's avatar
Patrick Barroca committed
92 93 94 95 96
    $params = $this->_request->getParams();
    if (isset($params['q'])) {
      $params['expressionRecherche'] = $params['q'];
      unset($params['q']);
    }
97

98 99
    if ($multifacets = array_merge($this->_extractDynamicFacets($params),
                                   $this->_extractMultifacetsPost())) {
100 101 102 103 104
      $url = $this->newCriteresRecherches($params)
                  ->getUrlWithMultifacetsUpdate($multifacets);
      $this->_redirect($this->view->url($url, null, true),
                       ['prependBase' => false]);
      return;
Patrick Barroca's avatar
Patrick Barroca committed
105 106
    }

Patrick Barroca's avatar
Patrick Barroca committed
107
    $criteres_recherche = $this->newCriteresRecherches($params);
108

109 110
    if ($this->view->statut == 'guidee')
      $criteres_recherche->updateRubrique('guidee');
Laurent's avatar
Laurent committed
111

112 113 114 115 116
    if ($this->_request->isPost()) {
      $params = $criteres_recherche->getUrlCriteresWithFacettes();
      // preserve module as we may come from Telephone_RechercheController
      $params['module'] = $this->_request->getModuleName();
      return $this->_redirect($this->view->url($params, null, true),
117
                              ['prependBase' => false]);
118
    }
119

120 121
    if ($criteres_recherche->isBookmarked()
        && !$criteres_recherche->ownedBy(Class_Users::getIdentity()))
122
      return $this->_redirect('opac/auth/login?redirect=' . urlencode(Class_Url::absolute($this->view->url())));
123

124
    $this->_helper->addQuery($this->view, $criteres_recherche->getCriteres());
125 126 127 128 129 130 131 132

    $this->_runSearchAndRender($criteres_recherche);
  }


  protected function _runSearchAndRender($criteres_recherche) {
    $search_start_time = microtime(true);

Ghislain Loas's avatar
Ghislain Loas committed
133
    $this->view->search_result = $search_result = $this->moteur->lancerRecherche($criteres_recherche);
134

135
    $this->_logSearch();
136

137 138
    if ('json' == $this->_getParam('format', ''))
      return $this->_renderJsonResult($search_result);
139

140 141
    if ('atom' == $this->_getParam('format', ''))
      return $this->_renderAtomResult($search_result);
Laurent's avatar
Laurent committed
142

143 144 145 146 147 148 149
    $this->preferences['liste_format'] = $this->_getParam('liste_format',
                                                          $this->preferences['liste_format']);

    if (Class_AdminVar::isModuleEnabled('ENABLE_SEARCH_MULTIPLE_RECORD_SELECTION')) {
      $this->preferences['display_add_to_cart'] = false;
      $this->preferences['display_select_record'] = true;
    }
150

151 152 153 154
    $this->view->titre = $this->getTitreRechercheSimple($criteres_recherche);

    if($criteres_recherche->getPertinence())
      $this->view->titre .= $this->_(' (recherche élargie triée par pertinence)');
Laurent's avatar
Laurent committed
155

Ghislain Loas's avatar
Ghislain Loas committed
156
    $search_result
157 158
      ->setDuration(microtime(true) - $search_start_time)
      ->setSettings($this->preferences);
159

Ghislain Loas's avatar
Ghislain Loas committed
160 161
    if (!$search_result->isError())
      $this->addHistoRecherche($criteres_recherche);
Laurent's avatar
Laurent committed
162 163 164
  }


165 166 167 168
  protected function _logSearch() {
    if (($ig = Zend_Controller_Front::getInstance()
         ->getPlugin('ZendAfi_Controller_Plugin_InspectorGadget'))
        && $ig->isEnabled())
169 170
      $ig->addButton(new Class_Entity(['Label' => $this->_('Configuration de la recherche'),
                                       'Content' => $this->view->searchInspector($this->moteur)]));
171 172 173
  }


174 175 176 177 178 179 180 181 182 183 184 185
  protected function _extractDynamicFacets(&$params) {
    $facets = [];

    foreach(Class_CodifThesaurus::getDynamicCodes() as $code) {
      $param = 'rech_' . Class_CodifThesaurus::CODE_FACETTE . $code;
      if (!$value = $this->_getParam($param))
        continue;

      unset($params[$param]);
      $instance = Class_CodifThesaurus::findFirstBy(['code' => $code,
                                                     'libelle' => $value]);
      if($instance)
186
        $facets[$instance->getFacetteIndex()] = 1;
187 188 189 190 191 192
    }

    return array_filter($facets);
  }


193
  protected function _extractMultifacetsPost() {
194 195
    return $this->_request->isPost()
      ? ZendAfi_View_Helper_Facettes::extractMultiFacets($this->_request->getPost())
196
      : [];
197 198 199
  }


Laurent's avatar
Laurent committed
200
  protected function _renderAtomResult($search_result) {
Laurent's avatar
Laurent committed
201 202
    $this->getHelper('ViewRenderer')->setNoRender();

Laurent's avatar
Laurent committed
203
    $builder = new ZendAfi_Feed_SearchResult($search_result, $this->view);
Laurent's avatar
Laurent committed
204 205 206 207 208 209 210
    $feed = Zend_Feed::importBuilder($builder, 'atom');

    $this->_response->setHeader('Content-Type', 'application/atom+xml;charset=utf-8');
    $this->_response->setBody($feed->saveXML());
  }


Laurent's avatar
Laurent committed
211 212 213 214 215 216 217
  protected function _renderJsonResult($search_result) {
    $records = $search_result
      ->recordsCollect(
                       function($record) {
                         return $record
                           ->acceptVisitor(new Class_Notice_JsonVisitor())
                           ->data();
Laurent's avatar
Laurent committed
218
                       });
219

Laurent's avatar
Laurent committed
220 221 222 223 224
    $this->_helper->json(['url' => Class_Url::absolute(),
                          'total' => $search_result->getRecordsCount(),
                          'page_size' => $search_result->getPageSize(),
                          'page' => $this->_getParam('page', 1),
                          'records' => $records]);
Patrick Barroca's avatar
Patrick Barroca committed
225
  }
226 227


Patrick Barroca's avatar
Patrick Barroca committed
228 229 230
  protected function getTitreRechercheSimple($criteres_recherche)  {
    if($title = $this->getTitleForPage($criteres_recherche))
      return $title;
231

Patrick Barroca's avatar
Patrick Barroca committed
232 233
    return $this->view->_('Résultat de la recherche');
  }
234 235


Patrick Barroca's avatar
Patrick Barroca committed
236 237 238 239
  protected function getTitreRechercheViewNotice($criteres_recherche) {
    if($title = $this->getTitleForPage($criteres_recherche))
      return $this->view->titreAdd($title);
  }
240 241


Patrick Barroca's avatar
Patrick Barroca committed
242 243 244
  protected function getTitleForPage($criteres_recherche) {
    if ($titre = $this->_request->getParam('titre'))
      return $titre;
245

Patrick Barroca's avatar
Patrick Barroca committed
246 247
    if ($this->_request->getParam('rubrique'))
      return $this->view->_('Recherche guidée');
248

249 250 251 252 253 254
    if ($titre_from_profil = $this->_getTitreFromProfil())
      return $titre_from_profil;

    if ($titre_from_module = $this->getTitreFromModule())
      return $titre_from_module;

255 256
    if ($criteres_recherche->isBookmarked())
      return $criteres_recherche->getBookmarkedLabel();
257

Patrick Barroca's avatar
Patrick Barroca committed
258 259
    if ($panier = $criteres_recherche->getPanier())
      return $panier->getLibelle();
260

261 262 263
    if ($catalogue = $criteres_recherche->getCatalogue())
      return $catalogue->getLibelle();

Patrick Barroca's avatar
Patrick Barroca committed
264 265
    return null;
  }
266 267


Patrick Barroca's avatar
Patrick Barroca committed
268 269 270
  protected function getTitreFromModule() {
    if(!$id_module = $this->extractIdModuleFromUrl())
      return null;
271

Patrick Barroca's avatar
Patrick Barroca committed
272 273
    if(!$profil = $this->extractProfilFromUrl())
      return null;
274

Patrick Barroca's avatar
Patrick Barroca committed
275 276
    return $profil->getModuleTitle($id_module);
  }
277

278

279 280 281 282 283 284 285
  protected function _getTitreFromProfil() {
    $params = Class_Profil::getCurrentProfil()->getSearchResultSettings();
    return isset($params['titre'])
      ? $params['titre']
      : '';
  }

286

Patrick Barroca's avatar
Patrick Barroca committed
287 288 289
  public function appelmenuAction() {
    $this->_forward('simple');
  }
290

291

Patrick Barroca's avatar
Patrick Barroca committed
292
  public function avanceeAction() {
293
    $this->view->annexes = Class_CodifAnnexe::getMultiOptions();
Patrick Barroca's avatar
Patrick Barroca committed
294
    $this->view->criteres_recherche = $this->newCriteresRecherches($this->_request->getParams());
295
    $this->view->active_tab = $this->_getParam('form_id', 0);
296 297 298 299
    $this->view->search_forms =
      Class_SearchForm::findAllByPrefs(isset($this->preferences['forms'])
                                       ? $this->preferences['forms']
                                       : '');
Patrick Barroca's avatar
Patrick Barroca committed
300
  }
301

Patrick Barroca's avatar
Patrick Barroca committed
302

Patrick Barroca's avatar
Patrick Barroca committed
303 304
  public function viewnoticeAction() {
    $id_notice = (int)$this->_getParam('id');
Patrick Barroca's avatar
Patrick Barroca committed
305
    $clef_alpha = (string)$this->_getParam('clef');
306

Patrick Barroca's avatar
Patrick Barroca committed
307
    $result = $this->_findRecordByKeyOrId($clef_alpha, $id_notice);
308

Patrick Barroca's avatar
Patrick Barroca committed
309 310 311 312
    if ($result->isTooManyResults()) {
      $query = implode(' ', array_filter(array_slice(explode('-', $clef_alpha), 0, 3)));
      $this->_helper->notify($this->_('Plusieurs documents trouvés'));
      return $this->_redirect('/opac/recherche?'.http_build_query(['q' => $query]));
Patrick Barroca's avatar
Patrick Barroca committed
313
    }
314

Patrick Barroca's avatar
Patrick Barroca committed
315 316
    if (!$notice = $result->getRecord()) {
      $this->_helper->notify($this->_('Document introuvable'));
317
      return $this->_redirect('opac/recherche/simple');
Patrick Barroca's avatar
Patrick Barroca committed
318
    }
319

Patrick Barroca's avatar
Patrick Barroca committed
320
    Class_ScriptLoader::getInstance()->addRecordMeta($notice);
321

322
    $this->_addInspectorGadget($notice);
323

Patrick Barroca's avatar
Patrick Barroca committed
324 325 326 327
    $notice_navigation = new Class_Notice_NavigationRecherche(
                                                              $this->newCriteresRecherches($this->_request->getParams()),
                                                              $this->moteur,
                                                              $notice);
gloas's avatar
gloas committed
328

Patrick Barroca's avatar
Patrick Barroca committed
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
    if ($navigation=$this->_getParam('navigation')) {
      $notice_to_show = ($navigation ==='suivant'
                         ? $notice_navigation->getNoticeSuivante()
                         : $notice_navigation->getNoticePrecedente());
      return $this->_redirect($this->view->absoluteUrl(['id'=>$notice_to_show->getId(),
                                                        'clef'=>$notice_to_show->getClefAlpha(),
                                                        'navigation'=> null]));
    }

    if ($this->_getParam('code_rebond', false)
        || !($this->_getParam('retour_abonne', false)
             || $this->_getParam('retour_avis', false)))
      $this->view->notice_navigation = $notice_navigation;

    $current_module = $this->_getParam('current_module');

    $current_module['preferences'] = $this->preferences = $this->extractProfilFromUrl()
                                                               ->getCfgModulesPreferences('recherche', 'viewnotice', $notice->getTypeDoc());

    $current_module['action2'] = $notice->getTypeDoc();
    $this->view->_current_module = $current_module;
    $this->_request->setParam('current_module', $current_module);

    $this->view->notice = $notice;
    $this->view->preferences = $this->preferences;
354

Patrick Barroca's avatar
Patrick Barroca committed
355 356 357 358
    $criteres_recherche = $this->newCriteresRecherches($this->_request->getParams());
    $this->view->criteres_recherche = $criteres_recherche;

    $this->view->display_modifier_vignette_link = Class_Users::isCurrentUserCanAccesBackend() && $notice->isVignetteUpdatableToCacheServer();
359

360 361
    $this->view->show_reset_thumbnail_link = Class_Users::isCurrentUserCanAccesBackend();

Patrick Barroca's avatar
Patrick Barroca committed
362 363 364 365 366 367
    $this->getTitreRechercheViewNotice($criteres_recherche);
    $this->view->title = strip_tags($this->view->notice->getTitrePrincipal());

    if ($auteur = $this->view->notice->getAuteurPrincipal())
      $this->view->nomSite .= ' / ' . $auteur;

Meusburger's avatar
Meusburger committed
368 369
    if (($genres = $notice->getChampNotice('G', $notice->getFacettes()))
        && ($genre = Class_CodifGenre::find($genres[0]->getId()))
Patrick Barroca's avatar
Patrick Barroca committed
370 371 372 373 374
        && ('_vide.gif' != $genre->getPicto())) {
      $this->view->picto_genre = $genre->getPicto();
    }

    $this->view->url_panier = $this->view->url(['controller' => 'panier',
Ghislain Loas's avatar
Ghislain Loas committed
375
                                                'action' => 'add-record-ajax',
Patrick Barroca's avatar
Patrick Barroca committed
376 377 378 379 380 381 382 383 384 385 386 387
                                                'id_notice' => $id_notice]);

    $this->_helper->trackEvent('recherche',
                               'notice',
                               ['titre' => $notice->getTitrePrincipal(),
                                'auteur' => $notice->getAuteurPrincipal(),
                                'editeur' => $notice->getEditeur(),
                                'tome' => $notice->getTomeAlpha(),
                                'support' => $notice->getTypeDocLabel(),
                                'ressource' => $this->view->absoluteUrl($this->view->urlNotice($notice))
                               ],
                               $notice->getId());
388 389 390 391 392 393 394 395 396

    if ($model = Class_PremierChapitre::findFirstBy(['ean' => $notice->getIsbnOrEan()])) {
      $event_data = ['titre' => $model->getTitre(),
                     'auteur' => $model->getAuteur(),
                     'url' => $model->getUrl(),
                     'ean' => $model->getId()];
      $this->_helper->trackEvent('premier-chapitre', 'vue-notice', $event_data, $model->getId());
    }

Patrick Barroca's avatar
Patrick Barroca committed
397 398 399 400 401 402 403
    $stat= new Class_StatsNotices();
    $stat->addStatVisu($id_notice);

    Class_ScriptLoader::getInstance()->loadBabeltheque();
  }


404 405 406
  public function jsonRecordAction() {
    $this->_helper->getHelper('viewRenderer')->setNoRender();

Patrick Barroca's avatar
Patrick Barroca committed
407 408 409
    $result = $this->_findRecordByKeyOrId((string)$this->_getParam('clef'),
                                          (int)$this->_getParam('id'));
    ($record = $result->getRecord())
410 411 412 413 414 415 416 417
      ? $this->_helper->json($record
                             ->acceptVisitor(new Class_Notice_JsonVisitor())
                             ->data())
      : $this->_response->setHttpResponseCode(404);
  }


  protected function _findRecordByKeyOrId($key, $id) {
Patrick Barroca's avatar
Patrick Barroca committed
418 419
    $result = new RechercheController_FindRecordByKeyOrIdResult();

420
    if (!$key || (!$records = Class_Notice::getAllNoticesByClefAlpha($key)))
Patrick Barroca's avatar
Patrick Barroca committed
421
      return $result->setRecord(Class_Notice::find($id));
422 423

    if (!$id && (count($records) > 1))
Patrick Barroca's avatar
Patrick Barroca committed
424
      return $result->beTooManyResults();
425 426 427

    foreach($records as $record)
      if ($id == $record->getId())
Patrick Barroca's avatar
Patrick Barroca committed
428
        return $result->setRecord($record);
429

Patrick Barroca's avatar
Patrick Barroca committed
430
    return $result->setRecord(array_pop($records));
431 432 433
  }


Patrick Barroca's avatar
Patrick Barroca committed
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
  public function readnoticeAction()  {
    $this
      ->getHelper('ViewRenderer')
      ->setLayoutScript('readspeaker.phtml');

    $id_notice = intVal($this->_request->id);
    $class_notice = new Class_Notice();
    $this->view->notice = Class_Notice::find($id_notice);
  }


  public function rebondAction()  {
    $this->_forward('simple');
  }


  public function histoAction() {
    $ligne = $_SESSION["histo_recherche"][$_REQUEST["id_histo"]];
    $_SESSION["recherche"]["selection"] = $ligne["selection"];
    switch($ligne["type"]) {
      case 1: {
        $_SESSION["recherche"]["mode"]="simple";
        $this->_redirect('opac/recherche/simple');
      }
      case 2: {
        $_SESSION["recherche"]["mode"]="avancee";
        $this->_redirect('opac/recherche/avancee');
      }
    }
  }


466
  protected function addHistoRecherche($criteres_recherche) {
467
    $criteres_recherche->setTime(microtime(true));
Patrick Barroca's avatar
Patrick Barroca committed
468 469 470
    $criteres_histo = clone $criteres_recherche;
    $histo_session = new Zend_Session_Namespace('historiqueRecherche');

471 472 473 474 475
    (null == ($criteres = $histo_session->criteres))
      ? ($criteres = [serialize($criteres_histo)])
      : ($criteres[] = serialize($criteres_histo));

    return $histo_session->criteres = array_unique($criteres);
Patrick Barroca's avatar
Patrick Barroca committed
476 477 478 479 480 481 482 483 484 485 486 487 488
  }


  public function vignetteAction()  {
    $viewRenderer = $this->getHelper('ViewRenderer');
    $viewRenderer->setNoRender();
    session_write_close();

    $notice = Class_Notice::find((int)$this->_getParam('id_notice'));
    $this->_redirect($this->view->absoluteUrl($notice->fetchUrlLocalVignette()));
  }


489 490 491 492 493
  public function rawThumbnailAction() {
    $viewRenderer = $this->getHelper('ViewRenderer');
    $viewRenderer->setNoRender();
    session_write_close();

494
    $this->_response->setHeader('Content-Type', 'image/png');
495 496 497 498 499 500 501 502
    $record = Class_Notice::find((int)$this->_getParam('id'));
    (new Class_WebService_Vignette())
      ->renderThumbnail($record->getId(),
                        $record->getTitrePrincipal(),
                        $record->getTypeDoc());
  }


Patrick Barroca's avatar
Patrick Barroca committed
503
  public function reservationAction() {
504 505 506 507
    if ((!$library = Class_Bib::find((int)$this->_getParam('id_bib')))
        || !$record = Class_Notice::find((int)$this->_getParam('id_notice'))) {
      $this->_redirectToIndex();
      return;
Patrick Barroca's avatar
Patrick Barroca committed
508
    }
509

510 511
    $form = new ZendAfi_Form_Hold(['action' => $this->view->url(),
                                   'data-backurl' => $this->view->url(['action' => 'viewnotice']),
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
                                   'library' => $library]);

    if ($this->_request->isPost()
        && $form->isValid($this->_request->getPost())) {

      $subject = $this->_('Demande de réservation de document');

      //pour la bibliothèque
      $messages = [];
      $messages []= $this->_("Nom et prénom : %s", $form->getValue('user_name'));
      $messages []= '';
      $messages []= utf8_decode($this->_("Notice réservée : "));
      $messages []= $this->_("Titre : %s", utf8_decode($record->getTitrePrincipal()));
      $messages []= $this->_("Auteur : %s", utf8_decode($record->getAuteurPrincipal()));
      $messages []= $this->_("Editeur : %s", utf8_decode($record->getEditeur()));
      $messages []= $this->_("Cote : %s", utf8_decode($this->_getParam('cote')));
      $messages []= '';
      $messages []= utf8_decode($this->_("Message du demandeur :"));
      $messages []= utf8_decode($form->getValue('demande'));
      $message = implode("\r\n", $messages);

      (new ZendAfi_Mail('utf8'))
        ->setSubject($subject)
        ->setBodyText($message)
        ->setFrom($form->getValue('user_mail'), $form->getValue('user_name'))
        ->addTo($library->getMail())
        ->send();


      //pour l'utilisateur
      $texte_mail_resa = str_replace('%0D%0A', chr(13).chr(10), getVar('TEXTE_MAIL_RESA'));
      $texte_mail_resa_ok = urldecode($texte_mail_resa);
      $message_user = sprintf("%s\r\n\r\n", utf8_decode($texte_mail_resa_ok));

      (new ZendAfi_Mail('utf8'))
        ->setSubject($subject)
        ->setBodyText($message_user . $message)
        ->setFrom('nobody@noreply.fr', $library->getLibelle())
        ->addTo($form->getValue('user_mail'))
        ->send();

      $this->_redirect('opac/recherche/viewnotice/id/'.$record->getId()."?type_doc=".$record->getTypeDoc());

      return;
Patrick Barroca's avatar
Patrick Barroca committed
556
    }
557 558 559 560 561

    $resa = getVar("RESA_CONDITION");
    $resa_condition = str_replace('%0D%0A','<br />',$resa);
    $this->view->condition_resa = urldecode($resa_condition);
    $this->view->form = $form;
Patrick Barroca's avatar
Patrick Barroca committed
562 563 564 565
  }


  public function suggestajaxAction() {
566 567 568
    if (!$startsWith = trim($this->_getParam('startsWith')))
      return $this->_helper->json([]);

Patrick Barroca's avatar
Patrick Barroca committed
569 570 571 572 573 574 575 576 577 578 579 580 581
    $results = Class_Autocomplete_Index::searchAll($startsWith);
    $terms = Class_Autocomplete_IndexSearcher::extractTerms($startsWith);
    $term_regex =  '/('.implode('|', $terms).')/iu';
    $json = [];
    foreach($results as $index => $result) {
      $json[] = ['label' => preg_replace($term_regex, '<span>$1</span>', $result),
                 'value' => $result];
    }

    $data = Zend_Controller_Action_HelperBroker::getStaticHelper('Json')->encodeJson($json);
    $this->_response->setBody($data);
  }

582

583
  public function consultationajaxAction() {
584 585
    if (!$this->userConnected())
      return;
586

587 588 589
    $title = $this->view->_('Consultation sur place');
    if (!$exemplaire = Class_Exemplaire::find($this->_getParam('copy_id')))
      return $this->renderPopupResult($title,$this->view->_('L\'exemplaire n\'existe pas'));
590

591
    $service_point = $this->_getParam('location');
592

593 594
    $response = Class_CommSigb::getInstance()
      ->onPlaceConsultationBooking(Class_Users::getIdentity(), $exemplaire, $service_point);
595

596
    $this->renderPopupResult($title, $this->_getConsultationBookingMessage($response));
597 598 599 600
  }


  protected function _getConsultationBookingMessage($response) {
601 602 603
    if ($response['erreur'])
      return  $response['erreur'];

604
    return $this->view->_('Votre réservation est enregistrée.');
605 606
  }

607

Patrick Barroca's avatar
Patrick Barroca committed
608 609 610 611
  public function reservationajaxAction() {
    $viewRenderer = $this->getHelper('ViewRenderer');
    $viewRenderer->setNoRender();

612
    if (!$user=$this->userConnected())
Patrick Barroca's avatar
Patrick Barroca committed
613 614 615
      return;

    $id_bib = (int)$this->_getParam('id_bib');
616
    $id_exemplaire = $this->_getParam('copy_id');
Patrick Barroca's avatar
Patrick Barroca committed
617 618 619 620 621 622 623
    $code_annexe = $this->_getParam('code_annexe');

    if (Class_CosmoVar::isSiteRetraitResaPatronLibrary())
      $code_annexe = $user->getUserIdSite();

    $comm = new Class_CommSigb();

624
    $ret = $comm->reserverExemplaire($id_bib, $id_exemplaire, $code_annexe);
Patrick Barroca's avatar
Patrick Barroca committed
625 626

    $this->renderPopupResult($this->view->_('Réservation'),
627
                             $this->_getHoldMessage($user, $id_exemplaire, $ret));
Patrick Barroca's avatar
Patrick Barroca committed
628 629 630 631 632 633 634
  }


  protected function _getHoldMessage($user, $item_id, $response) {
    if ($response['erreur'])
      return $response['erreur'];

635
    if (isset($response['popup']) && $response['popup'])
Patrick Barroca's avatar
Patrick Barroca committed
636 637 638 639
      return '<iframe src="' . $response['popup'] . '"></iframe>';

    $current_hold = null;
    foreach($user->getReservations() as $hold) {
640
      if (!$opac_item = $hold->getExemplaireOPAC())
Patrick Barroca's avatar
Patrick Barroca committed
641 642 643 644 645 646 647 648
        continue;

      if ($item_id == $opac_item->getId()) {
        $current_hold = $hold;
        break;
      }
    }

649 650 651 652 653
    return ($current_hold && ($location_label = $current_hold->getPickupLocationLabel()))
      ? $this->view->_('Votre réservation est enregistrée.<br>Nous vous informerons quand le document%s sera disponible pour être retiré à : %s',
                       $this->_getMessageNoticeLabel($item_id), $location_label)
      : $this->view->_('Votre réservation est enregistrée.<br>Nous vous informerons quand le document%s sera disponible',
                       $this->_getMessageNoticeLabel($item_id));
Patrick Barroca's avatar
Patrick Barroca committed
654 655 656 657 658 659 660 661 662 663 664 665 666 667
  }


  protected function _getMessageNoticeLabel($item_id) {
    if (!$item_id
        || !($item = Class_Exemplaire::find($item_id))
        || !($notice = $item->getNotice()))
      return '';

    return sprintf(" '%s / %s'",
                   $notice->getTitrePrincipal(),
                   $notice->getAuteurPrincipal());
  }

lbrun's avatar
lbrun committed
668

669
  protected function userConnected() {
Patrick Barroca's avatar
Patrick Barroca committed
670 671
    if (!$user = Class_Users::getIdentity()) {
      $this->_forward('popup-login', 'auth', 'opac', ['redirect' => $this->view->url()]);
672
      return false;
Patrick Barroca's avatar
Patrick Barroca committed
673
    }
674
    return $user;
675
  }
676

677

lbrun's avatar
lbrun committed
678
  protected function getReservationForm($action='reservation-pickup-ajax') {
679
    return $this->view
Patrick Barroca's avatar
Patrick Barroca committed
680 681 682
      ->newForm(['id' => 'pickup',
                 'class' => 'zend_form reservation_pickup',
                 'action' => $this->view->url(['controller' => 'recherche',
683
                                               'action' => $action])])
Patrick Barroca's avatar
Patrick Barroca committed
684 685
      ->addElement('Radio', 'code_annexe', ['required' => true,
                                            'allowEmpty' => false])
686

Ghislain Loas's avatar
Ghislain Loas committed
687
      ->addDisplayGroup(['code_annexe'], 'group', ['legend' => 'Site de retrait']);
688 689 690 691
  }


  public function consultationPickupAjaxAction() {
692 693
    if (!$this->userConnected())
      return ;
694 695

    if ($this->_request->isPost()) {
696
      return $this->_forward('consultationajax');
697
    }
698

lbrun's avatar
lbrun committed
699
    $form = new ZendAfi_Form_ConsultationPickup();
lbrun's avatar
lbrun committed
700 701
    $radio = $form->getElement('location');

702 703
    if (!$exemplaire = Class_Exemplaire::find($this->_getParam('copy_id')))
      return $this->renderPopupResult($this->view->_('Lieu de mise à disposition demandé'),$this->view->_('L\'exemplaire n\'existe pas'));
lbrun's avatar
lbrun committed
704 705 706 707
    $locations = Class_CommSigb::getInstance()->pickupLocation(Class_Users::getIdentity(), $exemplaire);
    foreach ($locations as $location) {
      foreach($location->getServicePoints() as $service_point)
        $radio->addMultiOption($service_point->getCode(), $service_point->getLabel());
708 709
    }

lbrun's avatar
lbrun committed
710 711
    $this->renderPopupResult($this->view->_('Lieu de mise à disposition demandé'),
                             $this->view->renderForm($form));
712 713 714 715
  }


  public function reservationPickupAjaxAction() {
716 717
    if (!$this->userConnected())
      return ;
718 719 720 721 722 723 724 725 726

    if (!Class_CosmoVar::isSiteRetraitResaChoiceEnabled()
        && !$this->arePickupLocationsProvidedByComm()) {
      $this->_forward('reservationajax');
      return;
    }


    $form = $this->getReservationForm();
Patrick Barroca's avatar
Patrick Barroca committed
727 728 729 730
    $radio = $form->getElement('code_annexe');
    $this->arePickupLocationsProvidedByComm() ?
      $this->_addLocationsFromCommTo($radio) :
      $this->_addLocationsFromCodifTo($radio);
731

Patrick Barroca's avatar
Patrick Barroca committed
732 733
    if ($this->_request->isPost()
        && $form->isValid($this->_request->getPost())) {
Ghislain Loas's avatar
Ghislain Loas committed
734 735 736
      return $this->_redirect($this->view->absoluteUrl(['action' => 'reservationajax',
                                                        'render' => null,
                                                        'code_annexe' => $this->_request->getPost('code_annexe')]));
Patrick Barroca's avatar
Patrick Barroca committed
737
    }
738

Patrick Barroca's avatar
Patrick Barroca committed
739 740 741
    $this->renderPopupResult($this->view->_('Lieu de mise à disposition demandé'),
                             $this->view->renderForm($form));
  }
742

743

Patrick Barroca's avatar
Patrick Barroca committed
744 745 746 747 748
  protected function _addLocationsFromCodifTo($element) {
    foreach (Class_CodifAnnexe::findAllByPickup() as $annexe)
      $element->addMultiOption($annexe->getCode(), $annexe->getLibelle());
    $element->setValue($this->_getParam('code_annexe'));
  }
749 750


Patrick Barroca's avatar
Patrick Barroca committed
751 752 753
  protected function _addLocationsFromCommTo($element) {
    if ((!$user = Class_Users::getIdentity())
        || (!$comm = $user->getSIGBComm())
754
        || (!$item = Class_Exemplaire::find($this->_getParam('copy_id'))))
Patrick Barroca's avatar
Patrick Barroca committed
755
      return;
756

Patrick Barroca's avatar
Patrick Barroca committed
757
    $first = '';
758 759
    $locations = $comm->pickupLocationsFor($user, $item);
    foreach($locations as $k => $v) {
Patrick Barroca's avatar
Patrick Barroca committed
760 761 762
      $first = $first ? $first : $k;
      $element->addMultiOption($k, $v);
    }
763 764 765 766 767 768 769 770 771 772 773 774 775

    if (($user_location = $user->getUserIdSite())
        && array_key_exists($user_location, $locations)) {
      $element->setValue($user_location);
      return;
    }

    if (($requested_location = $this->_getParam('code_annexe'))
        && array_key_exists($requested_location, $locations)) {
      $element->setValue($requested_location);
      return;
    }

Patrick Barroca's avatar
Patrick Barroca committed
776 777 778
    if ($first)
      $element->setValue($first);
  }
779 780


Patrick Barroca's avatar
Patrick Barroca committed
781 782
  protected function arePickupLocationsProvidedByComm() {
    if ((!$user = Class_Users::getIdentity())
783
        || (!Class_Exemplaire::find($this->_getParam('copy_id'))))
Patrick Barroca's avatar
Patrick Barroca committed
784
      return false;
785

Patrick Barroca's avatar
Patrick Barroca committed
786 787 788
    return ($comm = $user->getSIGBComm()) ?
      $comm->providesPickupLocations() : false;
  }
789 790


Patrick Barroca's avatar
Patrick Barroca committed
791 792 793
  public function setMoteurRecherche($moteur) {
    $this->moteur = $moteur;
  }
794 795


Patrick Barroca's avatar
Patrick Barroca committed
796
  public function downloadRecordAction() {
797 798
    if (!$record = Class_Notice::find($this->_getParam('id', 0)))
      return $this->_redirect('/');
799

800 801
    $this->_helper->binaryDownload($record->getUnimarc(), $record->getId() . '.txt');
  }
802 803


804 805 806
  public function downloadItemAction() {
    if (!$item = Class_Exemplaire::find($this->_getParam('id', 0)))
      return $this->_redirect('/');
807

808 809
    if (!$raw_record = Class_Cosmogramme_Integration_RawRecord::findFor($item))
      return $this->_redirect('/');
810

811
    $this->_helper->binaryDownload($raw_record->getData(), $raw_record->getName());
Patrick Barroca's avatar
Patrick Barroca committed
812
  }
813 814


Patrick Barroca's avatar
Patrick Barroca committed
815
  protected function newCriteresRecherches($params) {
816 817
    $criteres = (new Class_CriteresRecherche())
      ->setParams($params);
818

Patrick Barroca's avatar
Patrick Barroca committed
819 820
    if (isset($this->preferences['liste_nb_par_page']))
      $criteres->setDefaultPageSize($this->preferences['liste_nb_par_page']);
821

Patrick Barroca's avatar
Patrick Barroca committed
822 823
    return $criteres;
  }
efalcy's avatar
efalcy committed
824

825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840

  protected function _addInspectorGadget($record) {
    if (!$ig = Zend_Controller_Front::getInstance()
         ->getPlugin('ZendAfi_Controller_Plugin_InspectorGadget'))
      return;

    if(!$ig->isEnabled())
      return;

    $ig->addButton(new Class_Entity(['Label' => $this->_('Notice Bokeh'),
                                     'Content' => $this->view->notice_Unimarc($record)]));

    if($record->isDilicom())
      $ig->addButton(new Class_Entity(['Label' => $this->_('Dilicom'),
                                       'Content' => $this->view->notice_Dilicom($record)]));
  }
Patrick Barroca's avatar
Patrick Barroca committed
841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861
}



class RechercheController_FindRecordByKeyOrIdResult {
  protected
    $_record,
    $_too_many_results = false;

  public function setRecord($record) {
    $this->_record = $record;
    return $this;
  }


  public function getRecord() {
    return $this->_record;
  }


  public function beTooManyResults() {
862
    $this->_too_many_results = true;
Patrick Barroca's avatar
Patrick Barroca committed
863 864 865 866 867
    return $this;
  }


  public function isTooManyResults() {
868
    return $this->_too_many_results;
Patrick Barroca's avatar
Patrick Barroca committed
869
  }
870
}