Skip to content
Snippets Groups Projects
BibNumeriqueController.php 16.8 KiB
Newer Older
llaffont's avatar
llaffont committed
<?php
/**
 * Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved.
 *
Laurent's avatar
Laurent committed
 * BOKEH is free software; you can redistribute it and/or modify
llaffont's avatar
llaffont committed
 * 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
 * BOKEH is distributed in the hope that it will be useful,
llaffont's avatar
llaffont committed
 * 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
 * along with BOKEH; if not, write to the Free Software
Laurent's avatar
Laurent committed
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
Laurent's avatar
Laurent committed
class BibNumeriqueController extends ZendAfi_Controller_Action {
  protected $_user;

  public function init()  {
    parent::init();
    $this->_user = $this->view->user = Class_Users::getIdentity();
  }


Patrick Barroca's avatar
Patrick Barroca committed
  public function viewAlbumAction() {
    if (null === ($album = Class_Album::getLoader()->find((int)$this->_getParam('id')))) {
      $this->_redirect('opac/');
      return;
    }
Patrick Barroca's avatar
Patrick Barroca committed
    $this->view->album = $album;
  }
Patrick Barroca's avatar
Patrick Barroca committed
  public function albumAction() {
    $album = Class_Album::getLoader()->find((int)$this->_getParam('id'));
Patrick Barroca's avatar
Patrick Barroca committed
    $this->getHelper('ViewRenderer')->setNoRender();
    $this->_response->setBody($this->view->album_JsonVisitor($album));
  }
Patrick Barroca's avatar
Patrick Barroca committed
  public function albumXspfPlaylistAction() {
    $album = Class_Album::getLoader()->find((int)$this->_getParam('id'));
    $playlist = $this->view->album_XspfPlaylistVisitor($album);
Patrick Barroca's avatar
Patrick Barroca committed
    $this->getHelper('ViewRenderer')->setNoRender();
    $response = $this->_response;
    $response->clearAllHeaders();
    $response->setHeader('Content-Type', 'application/xspf+xml; name="' . $album->getId(). '.xspf"', true);
    $response->setHeader('Content-Disposition', 'attachment; filename="' . $album->getId(). '.xspf"', true);
    $response->setHeader('Content-Transfer-Encoding', 'base64', true);
    $response->setHeader('Expires', '0');
    $response->setHeader('Cache-Control', 'no-cache, must-revalidate');
    $response->setHeader('Pragma', 'no-cache');
    $response->setHeader('Access-Control-Allow-Origin', '*');
    $response->setBody($playlist);
  }
Patrick Barroca's avatar
Patrick Barroca committed
  public function albumRssFeedAction() {
    $this->getHelper('ViewRenderer')->setNoRender();
    $album = Class_Album::getLoader()->find((int)$this->_getParam('id'));
    $rss = $this->view->album_RssFeedVisitor($album);
    $this->_response->setBody($rss);
    $this->_response->setHeader('Content-Type', 'application/rss+xml', true);
  }
Patrick Barroca's avatar
Patrick Barroca committed
  public function downloadalbumAction() {
    $album = Class_Album::getLoader()->find((int)$this->_getParam('id'));
    echo $this->_renderFile($album->getBasePath().$album->getPdf(), true);
  }
Patrick Barroca's avatar
Patrick Barroca committed
  public function bookletAction() {
    $id = $this->_getParam('id');
    $container_id = sprintf('booklet_%d', $id);
    Class_ScriptLoader::getInstance()
      ->addAmberPackage('AFI')
      ->addAmberReady(sprintf("smalltalk.BibNumAlbum._load_in_scriptsRoot_('%s.json', '%s', '%s')",
                              $this->view->url(array('action' => 'album', 'id' => $id)),
                              '#'.$container_id,
                              AMBERURL."afi/souvigny/"))
      ->loadAmber();
    $this->view->container_id = $container_id;
  }
Patrick Barroca's avatar
Patrick Barroca committed
  public function viewCategorieAction() {
    if (null === ($categorie = Class_AlbumCategorie::getLoader()->find((int)$this->_getParam('id')))) {
      $this->_redirect('opac/');
      return;
    }
Patrick Barroca's avatar
Patrick Barroca committed
    $this->view->categorie = $categorie;
    $this->view->albums = $categorie->getAlbums();
    $this->view->subCategories = $categorie->getSousCategories();
  }
Patrick Barroca's avatar
Patrick Barroca committed
  public function getResourceAction() {
    echo $this->_getResource();
  }
Patrick Barroca's avatar
Patrick Barroca committed
  public function downloadResourceAction() {
    echo $this->_getResource(true);
  }
Patrick Barroca's avatar
Patrick Barroca committed
  public function playRessourceAction() {
    if (null === ($ressource = Class_AlbumRessource::find((int)$this->_getParam('id'))))
      exit;
Patrick Barroca's avatar
Patrick Barroca committed
    $event_data = ['titre' => $ressource->getTitre(),
                   'album' => $ressource->getTitreAlbum(),
                   'auteur' => $ressource->getAuteur(),
                   'editeur' => $ressource->getEditeur(),
                   'publication' => $ressource->getAnnee(),
                   'piste' => $ressource->getOrdre(),
                   'droits' => $ressource->getDroits(),
                   'source' => $this->view->absoluteUrl($ressource->getPermalink())];
Laurent's avatar
Laurent committed

Patrick Barroca's avatar
Patrick Barroca committed
    $this->_helper->trackEvent('bib-numerique', 'lecture', $event_data, $ressource->getId());
    $this->_redirect($this->view->absoluteUrl($ressource->getOriginalUrl()));
  }
Patrick Barroca's avatar
Patrick Barroca committed
  public function thumbnailAction() {
    if (null === ($ressource = Class_AlbumRessource::find((int)$this->_getParam('id'))))
      exit;
    // renvoi direct du contenu du fichier
    $this->_helper->getHelper('ViewRenderer')->setNoRender(true);

    $keys = array('width', 'crop_top', 'crop_right', 'crop_bottom', 'crop_left', 'id');
    $params = $this->_request->getParams();
    $thumbnail_params = array();
    foreach ($keys as $key) {
      if (array_key_exists($key, $params))
        $thumbnail_params[$key] = (int)$params[$key];
    }

    echo $this->_renderFile($ressource->getThumbnailFilePath($thumbnail_params),
                            $this->_getParam('attachment', false));
Patrick Barroca's avatar
Patrick Barroca committed
  /**
   * Interpretation des permaliens type http://localhost/afi-opac3/bib-numerique/notice/ido/D09030001/folio/1R4
   * sur les Albums + folios
   */
  public function noticeAction() {
    if (!$album = $this->findAlbumByIdOrIdOrigine()) {
      $this->_redirect('opac/index');
      return;
    }
Patrick Barroca's avatar
Patrick Barroca committed
    if (!$notice = $album->getNotice()) {
      $this->_redirect('opac/index');
      return;
    }
Laurent's avatar
Laurent committed

Patrick Barroca's avatar
Patrick Barroca committed
    $url_notice = 'opac/recherche/viewnotice/id/' . $notice->getId();
    if ($folio = $this->_getParam('folio'))
      $url_notice .= '#/page/'.$album->indexOfRessourceByFolio($folio);

    $this->_redirect($url_notice);
  }
Patrick Barroca's avatar
Patrick Barroca committed
  public function noticeThumbnailAction() {
    $this->_helper->getHelper('ViewRenderer')->setNoRender(true);
    if (!$album = $this->findAlbumByIdOrIdOrigine())
      return;

    echo $this->_renderFile($album->getThumbnailPath() ,false);
  }
Patrick Barroca's avatar
Patrick Barroca committed
  protected function findAlbumByIdOrIdOrigine() {
    if ($id_origine = $this->_getParam('ido'))
      return Class_Album::getLoader()->findFirstBy(array('id_origine' => $this->_getParam('ido')));
Laurent's avatar
Laurent committed

Patrick Barroca's avatar
Patrick Barroca committed
    return Class_Album::getLoader()->find((int)$this->_getParam('id'));
  }
Patrick Barroca's avatar
Patrick Barroca committed
  protected function _getResource($as_attachment = false) {
    if (null === ($resource = Class_AlbumRessource::getLoader()->find((int)$this->_getParam('id')))) {
      // ressource inexistante, on ne fait rien
      exit;
    }
Patrick Barroca's avatar
Patrick Barroca committed
    if ('' == $resource->getFichier()) {
      exit;
    }
    if ($datas=$this->_renderFile($resource->getOriginalPath(), $as_attachment))
      echo $datas;
    else
      die('404 File not found');
  }
Patrick Barroca's avatar
Patrick Barroca committed
  protected function _renderFile($filepath, $as_attachment = false) {
    // renvoi direct du contenu du fichier
    $this->_helper->getHelper('ViewRenderer')->setNoRender(true);
Laurent's avatar
Laurent committed

Patrick Barroca's avatar
Patrick Barroca committed
    $response = Zend_Controller_Front::getInstance()->getResponse();
    $response->canSendHeaders(true);
    $mimeType = Class_File_Mime::getTypeFromPath($filepath);
Patrick Barroca's avatar
Patrick Barroca committed
    $fileInfos = stat($filepath);
    $parts = pathinfo($filepath);
    if (!$fileInfos['size'])
      return false;
    $response->clearAllHeaders();
    $response->setHeader('Content-Type', $mimeType . '; name="' . $parts['basename'] . '"', true);
    $response->setHeader('Content-Transfer-Encoding', 'binary', true);
    $response->setHeader('Content-Length', $fileInfos['size'], true);
    $response->setHeader('Expires', '0');
    $response->setHeader('Cache-Control', 'no-cache, must-revalidate');
    $response->setHeader('Pragma', 'no-cache');
Patrick Barroca's avatar
Patrick Barroca committed
    if ($as_attachment)
      $response->setHeader('Content-Disposition', 'attachment; filename="' . $parts['basename'] . '"', true);
Patrick Barroca's avatar
Patrick Barroca committed
    $response->sendHeaders();
Patrick Barroca's avatar
Patrick Barroca committed
    $file = fopen($filepath, 'rb');
    $file_data = fread($file, $fileInfos['size']);
    fclose($file);
    return $file_data;
  }
Patrick Barroca's avatar
Patrick Barroca committed
  public function fullScreenAction() {
    $viewRenderer = $this->getHelper('ViewRenderer');
    $viewRenderer->setNoRender();
Patrick Barroca's avatar
Patrick Barroca committed
    $html = 'Aucun document';
    if ($id = $this->_getParam('id'))
      $html = $this->view->monocleReaderServerSideFullScreen($id);
    $this->getResponse()->setHeader('Content-Type', 'text/html;charset=utf-8');
    $this->getResponse()->setBody('<!DOCTYPE html><html><body>'.$html.Class_ScriptLoader::getInstance()->html().'</body></html>');
Patrick Barroca's avatar
Patrick Barroca committed
  }
Laurent's avatar
Laurent committed

  protected function _userShouldBeRedirect() {
    if (!$this->_user){
      $this->_forwardToLogin('', $this->view->url());
      return true;

    if (!$this->_user->hasRightAccessDilicom())
      return $this->_ajaxRedirectToNotice();

    if (!$this->view->album = Class_Album::find($this->_getParam('id')))
      return $this->_ajaxRedirectToNotice();

    return false;
  public function loanBookAjaxAction() {
    if($this->_userShouldBeRedirect())
    $this->view->form = $this->view
      ->newForm(['id' => 'pnb_devices'])
      ->setMethod('get')
      ->setAction($this->view->url(['action' => 'download-loan-book-ajax']));

    if ($user_agents = (new Class_AdminVar_Dilicom())->getUserAgents())
      $this->view->form->addElement('select', 'devices', ['label' => $this->_('Type de liseuse'),
                                                          'multiOptions' => $user_agents,
                                                          'value'=> (new Class_AdminVar_Dilicom())->defaultDevice()])
                       ->addDisplayGroup(['devices'], 'devices-group',[]);

    $this->view->form
      ->addElement('Submit', 'yes-button', ['label' => $this->_('Oui')])
      ->addElement('Button', 'no-button',
                   ['label' => $this->_('Non'),
                    'onclick' => 'opacDialogClose();return false;'])
      ->addDisplayGroup(['yes-button', 'no-button'],
                        'question',
                        ['legend' => $this->_('Êtes vous sûr de vouloir emprunter ce document ?')]);


    $this->view->titre = $this->_('Emprunter le livre au format EPUB');
    $this->renderScript('bib-numerique/loan-book.phtml');
  public function loanBookAction() {
    if (!$this->_user)
      return $this->_forwardToLogin('', $this->view->absoluteUrl());
    if (!$this->_user->hasRightAccessDilicom())
      return $this->_redirectToReferer();
    if (!$album = Class_Album::find($this->_getParam('id')))
      return $this->_redirectToReferer();
efalcy's avatar
efalcy committed
    $content = (new Class_WebService_BibNumerique_Dilicom_Hub())->loanBook($album, $this->_user , $this->_getParam('devices'));
    if ($content->returnMessage) {
      $this->_helper->notify(implode(',', $content->returnMessage));
      return $this->_redirectToNotice($album->getNoticeId());
    $this->_redirect($content->link->url);
Laurent's avatar
Laurent committed
  public function holdBookAction(){
    $album = Class_Album::find($this->_getParam('id'));

    $status= (new Class_WebService_BibNumerique_Dilicom_Hub())
      ->isAlbumHoldableBy($album, $this->_user);

    if ($status->returnMessage) {
      $this->_helper->notify($status->returnMessage[0]);
      return $this->_redirectToReferer();
    }


    $hold = new Class_Hold_Pnb();
    $hold->setRecordOriginId($album->getIdOrigine())
         ->setUser($this->_user)
         ->save();


    $this->_helper->notify($this->_('Réservation enregistrée : %s', $hold->getTitle()));
    $this->_redirectToReferer();
  }


efalcy's avatar
efalcy committed
  public function getLoan() {
    if (!$ids = $this->_getParam('loan_id'))
      return;
    $user_loan_id = explode('_',$ids);
efalcy's avatar
efalcy committed
    if (count($user_loan_id) != 2)
      return;
    if ( !$loan = Class_Loan_Pnb::findFirstBy(['id' => $user_loan_id[1],
                                               'user_id' => $user_loan_id[0]])) {
      $this->_helper->notify([$this->_('Pas de pret')]);
efalcy's avatar
efalcy committed
      return;
efalcy's avatar
efalcy committed
    return $loan;
  }


  public function extendsPnbLoanAction() {
    if (!$loan = $this->getLoan())
      return $this->_redirectToIndex();

    $content = (new Class_WebService_BibNumerique_Dilicom_Hub())->extendLoan($loan);
    if (!empty($content->returnMessage)) {
      $this->_helper->notify(implode($content->returnMessage));
      return $this->_redirectToReferer();
    }
efalcy's avatar
efalcy committed
    $this->_helper->notify($this->_('Votre prêt a été prolongé jusqu\'au %s', $loan->getExpectedReturnDate()));
    return $this->_redirectToReferer();
  }


  public function returnPnbLoanAction() {
efalcy's avatar
efalcy committed
    if (!$loan = $this->getLoan())
      return $this->_redirectToIndex();

    $content = (new Class_WebService_BibNumerique_Dilicom_Hub())->returnLoan($loan);
    if (!empty($content->returnMessage)) {
      $this->_helper->notify(implode($content->returnMessage));
      return $this->_redirectToReferer();
    }
    $this->_helper->notify($this->_('Votre document a été retourné'));
    return $this->_redirectToReferer();
  }


  public function downloadLoanBookAjaxAction() {
    if ($this->_userShouldBeRedirect())
      return;
efalcy's avatar
efalcy committed
    $content = (new Class_WebService_BibNumerique_Dilicom_Hub())->loanBook(Class_Album::find($this->_getParam('id')), $this->_user, $this->_getParam('devices'));
    $this->_withContentDo($content,
                          function($url)
                          {
                            $this->view->download_url = $url;
                            $this->renderPopupResult($this->_('Téléchargement'),
                                                     $this->view->render('bib-numerique/download-book.phtml'));


  protected function _ajaxRedirectToNotice() {
    $this->view->redirect_url = $this->view->url(['controller' => 'recherche',
                                                  'action' => 'viewnotice',
                                                  'render' => 'false']);
    $this->renderPopupResult('', $this->view->render('bib-numerique/redirect.phtml'));

    return true;
  }


  public function consultBookAjaxAction() {
    if($this->_userShouldBeRedirect())
      return;

    $this->view->titre = $this->_('Consulter le livre en ligne');
    $this->renderScript('bib-numerique/consult-book.phtml');
  }


  public function consultBookOpenAjaxAction() {
    if ($this->_userShouldBeRedirect())
      return;

    $client_ip = (new Class_RemoteClient($this->_request))->getIpAddress();
    $response = (new Class_WebService_BibNumerique_Dilicom_Hub())
      ->consultBook($this->view->album, $client_ip, $this->_user);

    return $this->_withContentDo($response,
                                 function($url)
                                 {
                                   $this->view->open_url = $url;
                                   $this->renderPopupResult($this->_('Consultation'),
                                                            $this->view->render('bib-numerique/consult-book-open.phtml'));
                                 });
Laurent's avatar
Laurent committed

Patrick Barroca's avatar
Patrick Barroca committed
  public function consultBookAction() {
    if (!$this->_user)
      return $this->_forwardToLogin('', $this->view->url());
    if (!$this->_user->hasRightAccessDilicom())
      return $this->_redirectToReferer();

Patrick Barroca's avatar
Patrick Barroca committed
    $album = Class_Album::find($this->_getParam('id'));
Patrick Barroca's avatar
Patrick Barroca committed
    $client_ip = (new Class_RemoteClient($this->_request))->getIpAddress();
    $response = (new Class_WebService_BibNumerique_Dilicom_Hub())
      ->consultBook($album, $client_ip, $this->_user);

    $content = $response;
Patrick Barroca's avatar
Patrick Barroca committed
    if ($content->returnMessage) {
      $this->_helper->notify(implode(',', $content->returnMessage));
      return $this->_redirectToNotice($album->getNoticeId());
Patrick Barroca's avatar
Patrick Barroca committed
    }
Laurent's avatar
Laurent committed

Patrick Barroca's avatar
Patrick Barroca committed
    $this->_redirect($content->link->url);
  }
  protected function _redirectToNotice($id = null) {
    $this->_redirect($this->view->url(['controller' => 'recherche',
                                       'action' => 'viewnotice',
                                       'id' => $id]),
                     ['prependBase' => false]);
  protected function _withContentDo($content, $closure) {
    if (!$content)
      return $this->_ajaxRedirectToNotice();
Patrick Barroca's avatar
Patrick Barroca committed
    if ($content->returnMessage) {
      $this->_helper->notify(implode(',', $content->returnMessage));
      return $this->_ajaxRedirectToNotice();
Patrick Barroca's avatar
Patrick Barroca committed
    }
    $closure($content->link->url);
Patrick Barroca's avatar
Patrick Barroca committed
  }
lbrun's avatar
lbrun committed


  public function widgetPageAction() {
    $id_module = (int)$this->_getParam('id_module');
    $id_division = (int)$this->_getParam('id_division');
    $page = (int)$this->_getParam('page');

    $module_params = Class_Profil::getCurrentProfil()
      ->getBoitesDivision($id_division)[$id_module];

    $helper = new ZendAfi_View_Helper_Accueil_BibNumerique($id_module, $module_params);
    $helper->setPage($page);
    $helper->setView($this->view);

    $this->view->sito_helper = $helper;
    $viewRenderer = $this->getHelper('ViewRenderer');
    $viewRenderer->setLayoutScript('empty.phtml');
  }