diff --git a/VERSIONS b/VERSIONS index e9546ac42f9843473b58d6c19660bd4e84720cce..4569dce092f24292673b6d953a4d434f94e25a18 100644 --- a/VERSIONS +++ b/VERSIONS @@ -1,5 +1,7 @@ 02/10/2017 - v7.11.3 + - ticket #59187 : Assistance: attacher des fichiers dans les tickets back office + - ticket #65353 : Correction du lien réserver. - ticket #63046 : Mise à jour du client Redmine (forge / demandes d'assistance ) qui n'était pas compatible PHP 7 diff --git a/application/modules/admin/controllers/RedmineController.php b/application/modules/admin/controllers/RedmineController.php index d6a04c54a70d5db032d799b365dbc6fa1d01c127..a6dc51e07e5406fc71a4795bb55a0717e2a38597 100644 --- a/application/modules/admin/controllers/RedmineController.php +++ b/application/modules/admin/controllers/RedmineController.php @@ -107,18 +107,32 @@ class Admin_RedmineController extends ZendAfi_Controller_Action { ->setService($service); $this->view->form = $form = ZendAfi_Form_Redmine_Issue::newWithIssue($issue, $service); - if ($this->_request->isPost() - && $form->isValid($this->_request->getPost())) { - $issue->updateAttributes($form->getValues()); - if ($service->createIssue($issue)) { - $this->_helper->notify($this->_('Demande enregistrée')); - $this->_redirectToIndex(); - return; - } + if (!$this->_request->isPost()) + return; + + if (!$form->isValid($this->_request->getPost())) + return $this->_helper->notify($this->_('Erreur lors de l\'enregistrement')); + + $issue->updateAttributes($form->getValues()); + + if (!$response = $service->createIssue($issue)) + return $this->_helper->notify($this->_('Erreur lors de la création du ticket')); - $this->_helper->notify($this->_('Erreur lors de l\'enregistrement')); + if(!$response instanceof SimpleXMLElement) + return $this->_helper->notify($this->_('Erreur lors de la création du ticket')); + + if($issue_id = $response->id->__toString()) { + $service->attachToIssue($issue->setid($issue_id)); + $this->_helper->notify($this->_('Demande %s créée', $issue_id)); + return $this->_redirect(Class_Url::absolute(['module' => 'admin', + 'controller' => 'redmine', + 'action' => 'edit-issue', + 'id' => $issue_id, + 'id_lib' => $this->_getParam('id_lib')])); } + + $this->_helper->notify($this->_('Erreur lors de la création du ticket')); } @@ -153,13 +167,55 @@ class Admin_RedmineController extends ZendAfi_Controller_Action { && $form->isValid($this->_request->getPost())) { $issue->updateAttributes($form->getValues()); $service->updateIssue($issue); + $service->attachToIssue($issue); $this->_helper->notify($this->_('Demande #%s enregistrée', $issue->getid())); - $this->_redirectToIndex(); + $this->_redirectToReferer(); } } + public function uploadFileAction() { + if (!$this->_request->isPost()) + return $this->_jsonError($this->_('La requête doit être de type POST')); + + $library = Class_Bib::find($this->_getParam('id_lib', 0)); + $service = new Class_WebService_Redmine($library); + + if (null !== $message = $service->validate()) + return $this->_jsonError($this->_('Le service Redmine est invalide.')); + + if(!$data = $this->_getParam('data')) + return $this->_jsonError($this->_('La pièce jointe est invalide.')); + + if(false !== ($pos = strpos($data, ","))) + $data = substr($data, $pos + 1); + + if(!$data = base64_decode($data)) + return $this->_jsonError($this->_('La pièce jointe est invalide.')); + + if (!$response = $service->uploadFile($data)) + return $this->_jsonError($this->_('L\'ajout de pièce jointe a échoué.')); + + $decoded_response = json_decode($response, true); + if(!isset($decoded_response['upload']['token'])) + return $this->_jsonError($this->_('La pièce jointe est invalide.')); + + if(!preg_match('/[^.]$/', $decoded_response['upload']['token'])) + return $this->_jsonError($this->_('L\'ajout de la pièce jointe a échoué car la clé reçue "%s" est invalide.', + $decoded_response['upload']['token'])); + + return $this->_helper->json($decoded_response); + } + + + protected function _jsonError($message) { + return $this->_helper->json(['status' => 'error', + 'message' => $message, + 'params' => $this->_request->getParams()]); + } + + protected function withResponseDo($data, $call_back) { $error_message = $this->view->getHelper('Redmine_AccountStatus')->connectionFail(); diff --git a/application/modules/admin/views/scripts/redmine/edit-issue.phtml b/application/modules/admin/views/scripts/redmine/edit-issue.phtml index 970664867c8a6c99a93ae75aa30030548fdd6baa..275987e2a3aafe9528940ec209bf65f73c78ac2e 100644 --- a/application/modules/admin/views/scripts/redmine/edit-issue.phtml +++ b/application/modules/admin/views/scripts/redmine/edit-issue.phtml @@ -1,5 +1,6 @@ <div class="form"> <fieldset> + <legend><?php echo $this->_('Titre');?></legend> <table> <tr> <td></td> @@ -18,6 +19,15 @@ </tr> </table> </fieldset> + <fieldset> + <legend><?php echo $this->_('Pièces jointes');?></legend> + <table> + <tr> + <td></td> + <td class="gauche"><?php echo $this->redmine_IssueAttachments($this->issue); ?></td> + </tr> + </table> + </fieldset> <fieldset> <legend><?php echo $this->_('Historique');?></legend> <table> diff --git a/application/modules/admin/views/scripts/redmine/index.phtml b/application/modules/admin/views/scripts/redmine/index.phtml index 1f5d91622606c386b3c642aad0c8226a7f31b743..ebe8cf6ae2d692798b08116aec44825bb865bfaa 100644 --- a/application/modules/admin/views/scripts/redmine/index.phtml +++ b/application/modules/admin/views/scripts/redmine/index.phtml @@ -1,5 +1,4 @@ <?php - if (!$this->libraries) { echo $this->getHelper('Redmine_Header')->shouldSelectLib($this->user); return; diff --git a/application/modules/opac/controllers/RechercheController.php b/application/modules/opac/controllers/RechercheController.php index a3b267889d5eebdb4ce93f06cd242682a9eb9b89..58f8c2cb2a08ca2406bb1d8720ede0ef2a9963fd 100644 --- a/application/modules/opac/controllers/RechercheController.php +++ b/application/modules/opac/controllers/RechercheController.php @@ -150,7 +150,8 @@ class RechercheController extends ZendAfi_Controller_Action { if (($ig = Zend_Controller_Front::getInstance() ->getPlugin('ZendAfi_Controller_Plugin_InspectorGadget')) && $ig->isEnabled()) - $ig->logRecord($this->view->searchInspector($this->moteur)); + $ig->logRecord($this->_('Configuration de la recherche'), + $this->view->searchInspector($this->moteur)); } @@ -302,7 +303,8 @@ class RechercheController extends ZendAfi_Controller_Action { if (($ig = Zend_Controller_Front::getInstance() ->getPlugin('ZendAfi_Controller_Plugin_InspectorGadget')) && $ig->isEnabled()) - $ig->logRecord($this->view->notice_Unimarc($notice)); + $ig->logRecord($this->_('Notice Bokeh'), + $this->view->notice_Unimarc($notice)); $notice_navigation = new Class_Notice_NavigationRecherche( $this->newCriteresRecherches($this->_request->getParams()), diff --git a/library/Class/Entity.php b/library/Class/Entity.php index d6ad0498a27ac1601434968b69988e9e81ddc62e..7b3e2df6eaff7306c30f84670d04372569cb9a44 100644 --- a/library/Class/Entity.php +++ b/library/Class/Entity.php @@ -46,6 +46,11 @@ class Class_Entity { } + public function __construct($attributes = []) { + $this->updateAttributes($attributes); + } + + public function get($name, $default=null) { return array_key_exists($name, $this->_attribs) ? $this->_attribs[$name] : $default; diff --git a/library/Class/WebService/Redmine.php b/library/Class/WebService/Redmine.php index daa11a004ac154787da22d2b59b08fa2076791c7..89c41bab2b3117bea6b1facaf465967e778b1087 100644 --- a/library/Class/WebService/Redmine.php +++ b/library/Class/WebService/Redmine.php @@ -84,6 +84,11 @@ class Class_WebService_Redmine extends Class_WebService_Abstract { } + protected function _getAttachmentApi() { + return $this->getClient()->api('attachment'); + } + + protected function getIssueStatusApi() { return $this->getClient()->api('issue_status'); } @@ -198,7 +203,22 @@ class Class_WebService_Redmine extends Class_WebService_Abstract { public function updateIssue($issue) { return $this->getIssueApi() - ->update($issue->getid(), $issue->getUpdateParams()); + ->update($issue->getid(), $issue->getUpdateParams()); + } + + + public function attachToIssue($issue) { + if(!$issue) + return null; + + if(!$token = $issue->gettoken()) + return null; + + return $this->getIssueApi() + ->attach($issue->getid(), + ['token' => $token, + 'filename' => $issue->getfilename(), + 'content_type' => $issue->getfiletype()]); } @@ -206,7 +226,7 @@ class Class_WebService_Redmine extends Class_WebService_Abstract { if (!$this->isValid() || !$ticket) return new Class_WebService_Redmine_Issue(); - $data = $this->getIssueApi()->show($ticket, ['include' => 'journals']); + $data = $this->getIssueApi()->show($ticket, ['include' => 'attachments,journals']); $issue = Class_WebService_Redmine_Issue::newWith(isset($data['issue']) ? $data['issue'] : []); $issue->setService($this); @@ -360,6 +380,12 @@ class Class_WebService_Redmine extends Class_WebService_Abstract { } + public function uploadFile($json) { + return $this->_getAttachmentApi() + ->upload($json); + } + + protected function getCustomOptions($id) { $options = []; foreach ($this->getCustomFields() as $field) { diff --git a/library/Class/WebService/Redmine/Issue.php b/library/Class/WebService/Redmine/Issue.php index a415ab2e3a76a3553cf54662caebe9f2ac0af73a..a3a1c911f760ed6bb9805282c1d5b95e6a53d982 100644 --- a/library/Class/WebService/Redmine/Issue.php +++ b/library/Class/WebService/Redmine/Issue.php @@ -25,9 +25,7 @@ class Class_WebService_Redmine_Issue extends Class_Entity { public static function newWith($data) { $instance = new static(); - $instance->updateAttributes($data); - - return $instance; + return $instance->updateAttributes($data); } @@ -55,8 +53,6 @@ class Class_WebService_Redmine_Issue extends Class_Entity { } - - public function getTechnicalInformations() { $datas = [$this->_('Url : ') . Class_Url::rootUrl() . Class_Url::baseUrl(), $this->_('Version : ') . BOKEH_RELEASE_NUMBER . ' (' . BOKEH_VERSION . ')', @@ -138,6 +134,21 @@ class Class_WebService_Redmine_Issue extends Class_Entity { } + public function renderAttachment($view, $attachment) { + if(!$attachment->getnew_value()) + return $view->tag('del', + $this->_('Pièce jointe : "%s"', $attachment->getold_value())); + + $show_url = sprintf('%s/attachments/download/%s/%s', + Class_AdminVar::get('REDMINE_SERVER_URL'), + $attachment->getname(), + $attachment->getnew_value()); + + return $view->tagAnchor($show_url, + $this->_('Pièce jointe : "%s"', $attachment->getnew_value()), ['target' => '_blank']); + } + + protected function withServiceDo($closure) { return ($service = $this->getService()) ? $closure($service) : null; } diff --git a/library/Class/WebService/Redmine/Issues.php b/library/Class/WebService/Redmine/Issues.php index afb87dfb44a12d5b6250f11012464198e86694f6..872a56d619b77fd451dff0a7cfabdce654ef150e 100644 --- a/library/Class/WebService/Redmine/Issues.php +++ b/library/Class/WebService/Redmine/Issues.php @@ -60,6 +60,11 @@ class Class_WebService_Redmine_Issues extends Storm_Collection { } + public function selectActionNeeded() { + return $this->select(function($issue) { return $issue->getStatusId() == Class_WebService_Redmine_Workflow_Afibre::QUESTION_CLIENT;}); + } + + public function selectLibraryId($id_bib) { return new Class_WebService_Redmine_Issues( $this->select( diff --git a/library/Class/WebService/Redmine/Workflow/Afibre.php b/library/Class/WebService/Redmine/Workflow/Afibre.php index 963aee819d990a67e20b6fdc64009bd521859870..b298a4442ee2e14e01dfdc7a2d3b774a85029e76 100644 --- a/library/Class/WebService/Redmine/Workflow/Afibre.php +++ b/library/Class/WebService/Redmine/Workflow/Afibre.php @@ -66,6 +66,10 @@ class Class_WebService_Redmine_Workflow_Afibre extends Class_WebService_Redmine public function getNumberOfIssuesNotification() { $issues = Class_WebService_Redmine_Issues::forUserFromCache(Class_Users::getIdentity()); - return count($issues->select(function($issue) { return $issue->getStatusId() == self::QUESTION_CLIENT; })); + return count($issues + ->select(function($issue) + { + return $issue->getStatusId() == self::QUESTION_CLIENT; + })); } } \ No newline at end of file diff --git a/library/ZendAfi/Controller/Plugin/InspectorGadget.php b/library/ZendAfi/Controller/Plugin/InspectorGadget.php index 03078e3990a05a2128c85199d01bf3d66728f33b..5a460a7895227917e1b38b29b59b8baf7508bfe3 100644 --- a/library/ZendAfi/Controller/Plugin/InspectorGadget.php +++ b/library/ZendAfi/Controller/Plugin/InspectorGadget.php @@ -20,11 +20,16 @@ */ class ZendAfi_Controller_Plugin_InspectorGadget extends Zend_Controller_Plugin_Abstract { + use Trait_Translator; + const PARAM_NAME = 'inspector_gadget'; + protected $_enabled = false, $_calls = [], $_record, - $_session; + $_record_label, + $_session, + $_view; public function preDispatch(Zend_Controller_Request_Abstract $request) { $this->_session = Zend_Registry::get('session'); @@ -38,6 +43,13 @@ class ZendAfi_Controller_Plugin_InspectorGadget extends Zend_Controller_Plugin_A Class_WebService_SIGB_AbstractService::setLogger($this); if (class_exists('SoapClient')) Class_WebService_MappedSoapClient::setLogger($this); + + $sl = Class_ScriptLoader::getInstance(); + $sl->addOPACPluginScript('form_to_tabs/form_to_tabs.js'); + Class_Admin_Skin::current() + ->renderButtonCssOn($sl) + ->renderJQueryCssOn($sl) + ->renderFormCssOn($sl); } @@ -61,6 +73,9 @@ class ZendAfi_Controller_Plugin_InspectorGadget extends Zend_Controller_Plugin_A public function postDispatch(Zend_Controller_Request_Abstract $request) { + if (!$this->isEnabled()) + return; + if (!$this->shouldRender()) return; @@ -87,15 +102,19 @@ class ZendAfi_Controller_Plugin_InspectorGadget extends Zend_Controller_Plugin_A return; } - $this->_session->inspectorCalls = []; - $this->_response->setBody(str_replace('</body>', $html . '</body>', $this->_response->getBody())); } protected function shouldRender() { - return $this->isEnabled() + $renderer = Zend_Controller_Action_HelperBroker::hasHelper('ViewRenderer') + ? Zend_Controller_Action_HelperBroker::getExistingHelper('ViewRenderer') + : null; + if ($renderer) + $this->_view = $renderer->view; + + return $this->_view && (!empty($this->_calls) || null !== $this->_record); } @@ -109,10 +128,9 @@ class ZendAfi_Controller_Plugin_InspectorGadget extends Zend_Controller_Plugin_A if (null == $this->_record) return ''; - return $this->renderButton('u') - . '<div data-type="' . self::PARAM_NAME . '-u" style="display:none;">' - . $this->_record - . '</div>'; + return $this->renderDialog($this->_record_label, + ['title' => $this->_record_label, + 'content' => $this->_record]); } @@ -120,25 +138,34 @@ class ZendAfi_Controller_Plugin_InspectorGadget extends Zend_Controller_Plugin_A if (empty($this->_calls)) return ''; - $html = $this->renderButton('i') - . '<div data-type="' . self::PARAM_NAME . '-i" style="display:none;"><ol>'; - $this->_calls = array_map( function($call) { return unserialize($call); }, $this->_calls); + $items = []; foreach(array_filter($this->_calls, 'is_object') as $call) - $html .= '<li>' . $call->render() . '</li>'; + $items[] = $this->_view->tag('li', $call->renderOn($this->_view)); - return $html . '</ol></div>'; + $this->_session->inspectorCalls = []; + $content = $this->_view->tag('ol', implode('', $items)); + + return $this + ->renderDialog($this->_('Appels webservices (%s)', count($items)), + ['title' => $this->_('Liste des appels webservices'), + 'content' => $content]) + ; } - protected function renderButton($content) { - return '<button style="width:20px;height:20px;text-align:center;" -onclick="$(\'[data-type=' . self::PARAM_NAME . '-' . $content . ']\').dialog({title:\'Inspector\', width:625});">' . $content . '</button>'; + protected function renderDialog($label, $datas) { + $button = (new Class_Entity) + ->setText($label) + ->setImage(Class_Admin_Skin::current()->renderActionIconOn('loupe', $this->_view)) + ->setAttribs(['onclick' => 'opacDialogFromData('. $this->_view->escape(json_encode($datas)) .');$(\'.ig-tabs\').tabs({activate: function(event, ui) {if (ui.newPanel.attr(\'id\') == \'ig-tab-items\') ui.newPanel.accordion();}});']); + + return $this->_view->admin_Button($button); } @@ -150,34 +177,51 @@ onclick="$(\'[data-type=' . self::PARAM_NAME . '-' . $content . ']\').dialog({ti $response_body = $response->getBody(); } - $this->_calls[] = serialize(new ZendAfi_Controller_Plugin_InspectorGadget_HttpCall($httpClient->getLastRequest(), $response_code, $response_body)); - $this->_session->inspectorCalls = $this->_calls; + $call = new ZendAfi_Controller_Plugin_InspectorGadget_ServiceCall + ($httpClient->getLastRequest(), + '', + '', + $response_body, + $response_code); + + $this->addCall($call); } public function logError($url, $message) { - $this->_calls[] = serialize(new ZendAfi_Controller_Plugin_InspectorGadget_HttpCall($url, - 'n/a', - $message)); - $this->_session->inspectorCalls = $this->_calls; + $call = new ZendAfi_Controller_Plugin_InspectorGadget_ServiceCall($url, + '', + '', + $message, + ''); + $this->addCall($call); } public function logSoap($client) { - $this->_calls[] = serialize(new ZendAfi_Controller_Plugin_InspectorGadget_SoapCall - ($client->__getLastRequestHeaders(), $client->__getLastRequest(), - $client->__getLastResponseHeaders(), $client->__getLastResponse())); + $call = new ZendAfi_Controller_Plugin_InspectorGadget_SoapCall + ($client->__getLastRequestHeaders(), + $client->__getLastRequest(), + $client->__getLastResponseHeaders(), + $client->__getLastResponse(), + ''); + + $this->addCall($call); + } + + + protected function addCall($call) { + $this->_calls[] = serialize($call); $this->_session->inspectorCalls = $this->_calls; } - public function logRecord($html) { + public function logRecord($label, $html) { if (!$this->isEnabled()) return $this; $this->_record = $html; + $this->_record_label = $label; return $this; } } - -?> \ No newline at end of file diff --git a/library/ZendAfi/Controller/Plugin/InspectorGadget/HttpCall.php b/library/ZendAfi/Controller/Plugin/InspectorGadget/HttpCall.php deleted file mode 100644 index 599e32a72bbe337a88474ae8a4e19398751cc50c..0000000000000000000000000000000000000000 --- a/library/ZendAfi/Controller/Plugin/InspectorGadget/HttpCall.php +++ /dev/null @@ -1,37 +0,0 @@ -<?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 ZendAfi_Controller_Plugin_InspectorGadget_HttpCall { - protected $_request, $_response_code, $_response_body; - - public function __construct($request, $response_code, $response_body) { - $this->_request = $request; - $this->_response_code = $response_code; - $this->_response_body = $response_body; - } - - - public function render() { - return - '<h3>Requête</h3>' . $this->_request . ' (' . $this->_response_code . ')' - . '<h3>Réponse</h3><textarea style="width:600px">' . $this->_response_body . '</textarea>'; - } -} \ No newline at end of file diff --git a/library/ZendAfi/Controller/Plugin/InspectorGadget/ServiceCall.php b/library/ZendAfi/Controller/Plugin/InspectorGadget/ServiceCall.php new file mode 100644 index 0000000000000000000000000000000000000000..5d441e5bf2b94ed7f89100f48ebe331c924e9e61 --- /dev/null +++ b/library/ZendAfi/Controller/Plugin/InspectorGadget/ServiceCall.php @@ -0,0 +1,73 @@ +<?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 ZendAfi_Controller_Plugin_InspectorGadget_ServiceCall { + use Trait_Translator; + + protected + $_request_headers, + $_request_body, + $_response_headers, + $_response_body, + $_response_code; + + public function __construct($request_headers, $request_body, + $response_headers, $response_body, $response_code) { + $this->_request_headers = $request_headers; + $this->_request_body = $request_body; + $this->_response_headers = $response_headers; + $this->_response_body = $response_body; + $this->_response_code = $response_code; + } + + + public function renderOn($view) { + return + $this->renderRequestOn($view) . $this->renderResponseOn($view); + } + + + protected function renderRequestOn($view) { + return $view->tag('h3', $this->_('Requête')) + . $view->tag('pre', $this->_request_headers) + . $this->renderBodyOn($this->_request_body, $view) + ; + } + + + protected function renderResponseOn($view) { + return $view->tag('h3', + $this->_response_code + ? $this->_('Réponse (%s)', $this->_response_code) + : $this->_('Réponse')) + . ($this->_response_headers ? $view->tag('pre', $this->_response_headers) : '') + . $this->renderBodyOn($this->_response_body, $view) + ; + } + + + protected function renderBodyOn($body, $view) { + return $body + ? $view->tag('textarea', $body, ['style' => 'width:600px;', 'rows' => 5]) + : ''; + } +} diff --git a/library/ZendAfi/Controller/Plugin/InspectorGadget/SoapCall.php b/library/ZendAfi/Controller/Plugin/InspectorGadget/SoapCall.php deleted file mode 100644 index a3baab2d30e1334e69a32ae5045eb9e40d42553f..0000000000000000000000000000000000000000 --- a/library/ZendAfi/Controller/Plugin/InspectorGadget/SoapCall.php +++ /dev/null @@ -1,42 +0,0 @@ -<?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 ZendAfi_Controller_Plugin_InspectorGadget_SoapCall { - protected $_request_headers, $_request_body, - $_response_headers, $_response_body; - - public function __construct($request_headers, $request_body, - $response_headers, $response_body) { - $this->_request_headers = $request_headers; - $this->_request_body = $request_body; - $this->_response_headers = $response_headers; - $this->_response_body = $response_body; - } - - - public function render() { - return - '<h3>Requête</h3>' . $this->_request_headers - . '<hr><textarea style="width:600px">' . $this->_request_body . '</textarea>' - . '<h3>Réponse</h3>' . $this->_response_headers - . '<hr><textarea style="width:600px">' . $this->_response_body . '</textarea>'; - } -} diff --git a/library/ZendAfi/Form/Redmine/Issue.php b/library/ZendAfi/Form/Redmine/Issue.php index 4c902d8afdce9eb379a4cdeccc07d63976f6d1bb..396ceb1dd78d9100691717acdf5dfaee915abf5b 100644 --- a/library/ZendAfi/Form/Redmine/Issue.php +++ b/library/ZendAfi/Form/Redmine/Issue.php @@ -23,8 +23,13 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form { protected $_issue, - $_status = [], $_priorities = [], $_modules = [], - $_default_priority, $_default_module, $_default_contact, $_default_customer; + $_status = [], + $_priorities = [], + $_modules = [], + $_default_priority, + $_default_module, + $_default_contact, + $_default_customer; public static function newWithIssue($issue, $service) { @@ -65,6 +70,37 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form { protected function initInputs() { + + Class_ScriptLoader::getInstance() + ->addOPACScript('file_uploader.js') + ->addJqueryReady(sprintf('$("#attachment").file_uploader("%s");', + Class_Url::relative(['module' => 'admin', + 'controller' => 'redmine', + 'action' => 'upload-file', + 'id_lib' => Class_Url::getParam('id_lib')]))); + + $this + ->addElement('file', + 'attachment', + ['label' => $this->_('Pièce jointe'), + 'destination' => PATH_TEMP]) + + ->addElement('hidden', + 'token') + + ->addElement('hidden', + 'filename') + + ->addElement('hidden', + 'filetype') + + ->addElement('info', + 'attachment_error', + ['value' => '', + 'id' => 'attachment_error', + 'class' => 'error', + 'style' => 'display: none;']); + if (!$this->_issue->getid()) { $this ->addElement('text', @@ -77,7 +113,7 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form { ->addElement('textarea', 'technical_informations', ['label' => $this->_('Informations techniques'), - 'rows' => 4, + 'rows' => 6, 'cols' => 70, 'required' => false, 'readonly' => 'readonly', @@ -94,7 +130,11 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form { 'value' => '', 'placeholder' => $this->_('Merci de préciser les différentes étapes pour reproduire le problème rencontré, l\'adresse de la page, si il faut être connecté avec un compte particulier')]) - ->addDisplayGroup(['subject', 'description', 'technical_informations'], + ->addDisplayGroup(['subject', + 'description', + 'technical_informations', + 'attachment', + 'attachment_error'], 'common', ['legend' => '']) ; @@ -103,8 +143,12 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form { if ($this->_issue->getid()) { $this - ->addElement('textarea', 'notes', ['rows' => 5, 'cols' => 75]) - ->addDisplayGroup(['notes'], 'default', ['legend' => $this->_('Nouvelle note')]); + ->addElement('textarea', 'notes', [ + 'label' => $this->_('Note'), + 'rows' => 5, 'cols' => 75]) + ->addDisplayGroup(['notes', + 'attachment', + 'attachment_error'], 'default', ['legend' => $this->_('Nouvelle note')]); } @@ -136,8 +180,11 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form { 'rows' => 2, 'cols' => 50, 'value' => $this->_issue->getContact() ? $this->_issue->getContact() : $this->getDefaultContact()]) - - ->addDisplayGroup(['customer', 'status_id', 'priority', 'module', 'contact'], + ->addDisplayGroup(['customer', + 'status_id', + 'priority', + 'module', + 'contact'], 'properties', ['legend' => $this->_('Propriétés')]); @@ -177,9 +224,9 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form { return; if ($library->hasMail() || $library->hasTelephone()) - return implode(' / ', array_filter([$library->getLibelle(), - $library->getMail(), - $library->getTelephone()])); + return implode(' / ', array_filter([$library->getLibelle(), + $library->getMail(), + $library->getTelephone()])); } diff --git a/library/ZendAfi/View/Helper/Admin/FrontNav.php b/library/ZendAfi/View/Helper/Admin/FrontNav.php index 04ef2e194d737375990e69e6965bc556e67dca11..50ac3b126cc8b0f1c342568ac3ed4090dc7e687f 100644 --- a/library/ZendAfi/View/Helper/Admin/FrontNav.php +++ b/library/ZendAfi/View/Helper/Admin/FrontNav.php @@ -67,15 +67,30 @@ class ZendAfi_View_Helper_Admin_FrontNav extends ZendAfi_View_Helper_BaseHelper protected function _myAccount() { $id = Class_Users::getIdentity()->getId(); + $name = Class_Users::getNomAff($id); + $anchors = [$this->_tag('li', + $this->view->tagAnchor(['module' => 'admin', + 'controller' => 'users', + 'action' => 'edit', + 'id' => $id], + $name, + ['title' => $this->_('Accéder à la page de modification de mon compte administrateur'), + 'data-popup' => 'true'])), + $this->_tag('li', $this->view->tagAnchor($this->view->url(['module' => 'admin', + 'controller' => 'auth', + 'action' => 'logout'], null, true), + $this->_('Se déconnecter') + . Class_Admin_Skin::current()->renderMenuIconOn('logout', + $this->view, + ['alt' => 'logout', + 'style' => 'filter: invert(1);']), + ['title' => $this->_('Se déconnecter du compte : %s', $name)]))]; + return $this->_tag('div', - $this->view->tagAnchor(['module' => 'admin', - 'controller' => 'users', - 'action' => 'edit', - 'id' => $id], - $this->_('Utilisateur courant : %s', Class_Users::getNomAff($id)), - ['title' => $this->_('Accéder à la page de modification de mon compte administrateur'), - 'data-popup' => 'true']), - ['class' => 'admin_menu_title']); + $this->_('Utilisateur courant'), + ['class' => 'admin_menu_title']) + + . $this->_tag('ul', implode($anchors)); } @@ -227,6 +242,16 @@ class ZendAfi_View_Helper_Admin_FrontNav extends ZendAfi_View_Helper_BaseHelper 'home')), ['title' => $this->_('Accéder à l\'interface d\'administration')])]; + if(Class_AdminVar::isRedmineEnabled()) + $links [] = $this->view->tagAnchor($this->view->url(['module' => 'admin', + 'controller' => 'redmine', + 'action' => 'index'], null, true), + Class_Admin_Skin::current()->renderMenuIconOn('redmine', + $this->view, + ['alt' => 'redmine']) + . $this->_('Assistance (%d)', Class_WebService_Redmine_Workflow::current()->getNumberOfIssuesNotification()), + ['title' => $this->_('Accéder à l\'assistance')]); + if($this->_isAllowed('cms', 'index')) $links[] = $this->view->tagAnchor(Class_Url::absolute('/admin/cms/'), $this->_('Articles') . diff --git a/library/ZendAfi/View/Helper/Button.php b/library/ZendAfi/View/Helper/Button.php index fb43bb5933316da333dda0e6ef12ab1ad7232212..f4c518a3e736df311c11891fa3b295796ceb525b 100644 --- a/library/ZendAfi/View/Helper/Button.php +++ b/library/ZendAfi/View/Helper/Button.php @@ -50,7 +50,7 @@ class ZendAfi_View_Helper_Button extends ZendAfi_View_Helper_BaseHelper { return $this; $button->setAttribs(array_merge($button->getAttribs(), - ['onclick' => sprintf('window.location.href = \'%s\';return false;', + ['onclick' => sprintf('window.location.href = \'%s\';', $button->getUrl())])); return $this; } diff --git a/library/ZendAfi/View/Helper/Notice/Unimarc.php b/library/ZendAfi/View/Helper/Notice/Unimarc.php index 16f604cadacf9a2a5a4e1f6b960d673247bc39d6..9bcacc4ee1ddb6034df9facc5fba44797488941d 100644 --- a/library/ZendAfi/View/Helper/Notice/Unimarc.php +++ b/library/ZendAfi/View/Helper/Notice/Unimarc.php @@ -32,33 +32,45 @@ class ZendAfi_View_Helper_Notice_Unimarc extends Zend_View_Helper_HtmlElement { $reader->setNotice($notice->getUnimarc(), 0); $reader->acceptVisitor($this); - Class_ScriptLoader::getInstance() - ->addJQueryReady('$(".ig-tabs").tabs({activate: function(event, ui) { -if (ui.newPanel.attr("id") == "ig-tab-items") - ui.newPanel.accordion(); -}});'); - - return $this->renderHeader($notice) . $this->_tag('hr') + return + $this->_tag('h2', $this->_('Indexation')) . $this->renderNotice($notice) . $this->_tag('hr') + . $this->_tag('h2', $this->_('Unimarc pivot')) . $this->_tag('div', $this->renderTabs() - . $this->renderZones() + . $this->renderZones($notice) . $this->renderItems($notice), ['class' => 'ig-tabs']); } protected function renderNotice($notice) { - $fields = ['facettes' => $this->_('Facettes'), - 'date_creation' => $this->_('Création / nouveauté'), - 'date_maj' => $this->_('Mis à jour le'), - 'clef_alpha' => $this->_('Clé alpha'), - 'clef_oeuvre' => $this->_('Clé oeuvre')]; - $html = ''; + $fields = + [ + 'date_maj' => $this->_('Mis à jour le'), + 'date_creation' => $this->_('Nouveauté jusqu\'au'), + 'alpha_titre' => $this->_('Alpha titres'), + 'alpha_auteur' => $this->_('Alpha auteur'), + 'titres' => $this->_('Titres'), + 'auteurs' => $this->_('Auteurs'), + 'editeur' => $this->_('Éditeur'), + 'facettes' => $this->_('Facettes'), + 'clef_alpha' => $this->_('Clé alpha'), + 'clef_oeuvre' => $this->_('Clé oeuvre'), + 'clef_chapeau' => $this->_('Clé chapeau'), + 'url_vignette' => $this->_('Url vignette'), + 'url_image' => $this->_('Url image'), + ]; + $lines = []; foreach ($fields as $field => $label) - $html .= $label . ': ' . $notice->callGetterByAttributeName($field) . '<br>'; + $lines[] = $this->_tag('tr', + $this->_tag('th', $label, + ['scope' => 'row', + 'style' => 'text-align:right;min-width:12em']) + . $this->_tag('td', + $notice->callGetterByAttributeName($field))); - return $html; + return $this->_tag('table', implode('', $lines)); } @@ -71,29 +83,29 @@ if (ui.newPanel.attr("id") == "ig-tab-items") } - protected function renderHeader($notice) { - $html = ''; - foreach($this->_headers as $k => $v) - $html .= $k . ' : ' . $v . '<br>'; + protected function renderDownload($notice) { + $download_url = $this->view->url(['controller' => 'recherche', + 'action' => 'download-record', + 'id' => $notice->getId()], + null, true); - $button = $this->_tag('button', $this->_('Télécharger'), - ['style' => 'float:right;font-size:80%', - 'onclick' => 'document.location.href=\'' - .$this->view->url(['controller' => 'recherche', - 'action' => 'download-record', - 'id' => $notice->getId()], - null, true).'\'']); + $button = (new Class_Entity) + ->setText($this->_('Télécharger')) + ->setImage(Class_Admin_Skin::current()->renderActionIconOn('down', $this->view)) + ->setAttribs(['style' => 'float:right;', + 'onclick' => 'document.location.href=\'' . $download_url .'\'']); - return $this->_tag('h2', $this->_('Notice unimarc') . $button) . $html; + return $this->view->admin_Button($button); } - protected function renderZones() { + protected function renderZones($notice) { $html = ''; foreach ($this->_zones as $zone) $html .= $zone->render(); - return $this->_tag('div', $this->_tag('table', $html), + return $this->_tag('div', + $this->renderDownload($notice) . $this->_tag('table', $html), ['id' => 'ig-tab-zones']); } diff --git a/library/ZendAfi/View/Helper/Redmine/Header.php b/library/ZendAfi/View/Helper/Redmine/Header.php index df6834e6b25eb2ff89045d2ce26813cb1bd236dd..d833b574a68c1e3205de8bd8f152c81c98576468 100644 --- a/library/ZendAfi/View/Helper/Redmine/Header.php +++ b/library/ZendAfi/View/Helper/Redmine/Header.php @@ -104,8 +104,9 @@ class ZendAfi_View_Helper_Redmine_Header extends ZendAfi_View_Helper_BaseHelper ->setUrl($this->view->url(['module' => 'admin', 'controller' => 'bib', 'action' => 'edit', - 'id' => $library->getId(), - 'backUrl' => $this->view->url()], null ,true) . '#fieldset-redmine') + 'id' => $library->getId()], null ,true) + . '?backUrl=' . $this->view->url() + . '#fieldset-redmine') ->setAttribs(['class' => 'library_redmine_account', 'title' => $title])); } diff --git a/library/ZendAfi/View/Helper/Redmine/IssueAttachments.php b/library/ZendAfi/View/Helper/Redmine/IssueAttachments.php new file mode 100644 index 0000000000000000000000000000000000000000..7602fe5bd84f66bd735d3a826e3912cc487f02c6 --- /dev/null +++ b/library/ZendAfi/View/Helper/Redmine/IssueAttachments.php @@ -0,0 +1,39 @@ +<?php +/** + * Copyright (c) 2012-2014, 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 ZendAfi_View_Helper_Redmine_IssueAttachments extends ZendAfi_View_Helper_BaseHelper { + protected $_issue; + + public function Redmine_IssueAttachments($issue) { + if (!$issue || (!$attachements = $issue->getattachments())) + return $this->_('Aucune pièce jointe'); + + $html = []; + foreach($attachements as $attachment) + $html [] = $this->_tag('li', + $issue->renderAttachment($this->view, (new Class_Entity($attachment)) + ->setnew_value($attachment['filename']) + ->setname($attachment['id']))); + + return $this->_tag('ul', implode($html)); + } +} \ No newline at end of file diff --git a/library/ZendAfi/View/Helper/Redmine/IssueJournal.php b/library/ZendAfi/View/Helper/Redmine/IssueJournal.php index 2b1a65b6fcf9c67033a3f1ca646f8b3a8dc50c44..518e56cebcbbbdba725118db44e49786346176af 100644 --- a/library/ZendAfi/View/Helper/Redmine/IssueJournal.php +++ b/library/ZendAfi/View/Helper/Redmine/IssueJournal.php @@ -95,6 +95,9 @@ class ZendAfi_View_Helper_Redmine_IssueJournal extends ZendAfi_View_Helper_BaseH protected function renderDetail($detail) { + if('attachment' == $detail['property']) + return $this->_tag('li', $this->_issue->renderAttachment($this->view, + new Class_Entity($detail))); if ('relation' == $detail['property']) return $this->_tag('li', $this->labelFromCode($detail['name'], isset($detail['old_value']) ? $detail['old_value'] : null, @@ -107,7 +110,7 @@ class ZendAfi_View_Helper_Redmine_IssueJournal extends ZendAfi_View_Helper_BaseH return $this->_tag('li', $this->getChangeLabel($this->customFrom($detail['name']), $detail['old_value'], $detail['new_value'])); - return ''; + return $this->_tag('li', implode(' ', $detail)); } diff --git a/library/ZendAfi/View/Helper/Redmine/Issues.php b/library/ZendAfi/View/Helper/Redmine/Issues.php index 85d8bc4f5c64fc8e35a62a8263c1317b6ff29bdf..97a3097d407c3e51bf9256b15a6242fdba5db39f 100644 --- a/library/ZendAfi/View/Helper/Redmine/Issues.php +++ b/library/ZendAfi/View/Helper/Redmine/Issues.php @@ -29,9 +29,16 @@ class ZendAfi_View_Helper_Redmine_Issues extends ZendAfi_View_Helper_BaseHelper if (!Class_AdminVar::isRedmineEnabled() || !$issues) return ''; - return - $this->renderIssues($library, $issues->selectNotClosed(), $this->_('Demandes en cours')) - . $this->renderIssues($library, $issues->selectClosed(), $this->_('Demandes fermées')); + $script_loader = Class_ScriptLoader::getInstance() + ->addSearchInputToContent($this->_('Chercher')) + ->addJQueryReady('$(\'#issues_list\').accordion({heightStyle: \'content\'});'); + +(new Class_Admin_Skin)->renderJQueryCssOn($script_loader); +return $this->_tag('div', + $this->renderIssues($library, $issues->selectActionNeeded(), $this->_('Demandes auxquelles je dois répondre')) + . $this->renderIssues($library, $issues->selectNotClosed(), $this->_('Demandes en cours')) + . $this->renderIssues($library, $issues->selectClosed(), $this->_('Demandes fermées')), + ['id' => 'issues_list']); } @@ -56,19 +63,20 @@ class ZendAfi_View_Helper_Redmine_Issues extends ZendAfi_View_Helper_BaseHelper return strftime('%x', strtotime($model->getcreated_on())); }; - return $this->_tag('h3', $label) - . $this->view->tagModelTable($issues, - [$this->_('Numéro'), $this->_('Sujet'), - $this->_('Statut'), $this->_('Créée le')], + return $this->_tag('h2', $label . $this->_tag('small', count($issues), ['style' => 'margin-left: 1em;'])) + . $this->_tag('div', + $this->view->tagModelTable($issues, + [$this->_('Numéro'), $this->_('Sujet'), + $this->_('Statut'), $this->_('Créée le')], - ['id', 'subject', 'status', 'created_on'], + ['id', 'subject', 'status', 'created_on'], - [$editAction], + [$editAction], - 'issues-' . $library->getId(), + 'issues-' . $library->getId(), null, - ['status' => $status_renderer, - 'created_on' => $date_renderer]); + ['status' => $status_renderer, + 'created_on' => $date_renderer])); } } \ No newline at end of file diff --git a/public/admin/skins/bokeh74/form.css b/public/admin/skins/bokeh74/form.css index 46148525ef829da91d7a27b842611e9839cc0fae..09f121a05d1697b96cc2fc177ae3f3151ec96ebd 100644 --- a/public/admin/skins/bokeh74/form.css +++ b/public/admin/skins/bokeh74/form.css @@ -158,3 +158,8 @@ body .ui-tabs .ui-tabs-nav > .ui-tabs-active > a.modified, body .ui-tabs .ui-tabs-nav > .ui-state-default > a.modified { color: var(--error-text); } + +.admin-form [readonly="readonly"] { + cursor: default; + background-color: var(--main-background); +} diff --git a/public/opac/java/form_to_tabs/form_to_tabs.js b/public/opac/java/form_to_tabs/form_to_tabs.js index 0ad150cce3c8888aa68c19ddef51229090f3280a..fb3b271709bbbaa27f59131021323e0f471103a5 100644 --- a/public/opac/java/form_to_tabs/form_to_tabs.js +++ b/public/opac/java/form_to_tabs/form_to_tabs.js @@ -21,29 +21,28 @@ (function ( $ ) { $.fn.form_to_tabs = function() { var form = $(this); - var tabs = $('<ul></ul>'); - var no_legend = $('<div></div>'); var form_fieldsets = form.find('fieldset'); - if(1 >= form_fieldsets.length) + if(0 == form_fieldsets.length) return false; + var tabs = $('<ul></ul>'); + var no_legend = $('<div></div>'); + form_fieldsets.each(function(index, element) { var fieldset = $(element); - //fieldset.attr('id', 'tab'+index) var legend = fieldset.find('legend'); - if(1 > legend.length) { - no_legend.append(fieldset.clone()); - fieldset.remove(); - return; + if(0 == legend.length) { + fieldset.appendTo(no_legend); + return true; } var tab_link = $('<a>' + legend.text() +'</a>'); tab_link.attr('href', '#' + fieldset.attr('id')); if (fieldset.find('.errors').length > 0) - tab_link.addClass('errors'); + tab_link.addClass('errors'); tabs.append($('<li></li>').append(tab_link)); diff --git a/public/opac/js/file_uploader.js b/public/opac/js/file_uploader.js new file mode 100644 index 0000000000000000000000000000000000000000..bfd89a389d12b5f61f0946bdeafc963de7139d21 --- /dev/null +++ b/public/opac/js/file_uploader.js @@ -0,0 +1,49 @@ +(function ( $ ) { + $.fn.file_uploader = function(url) { + var input_file = $(this); + $(input_file).change(function(event) { + postAjax(event); + }); + + var postAjax = function(event) { + var image_preview = input_file.closest('tr').find('img'); + input_file.closest('form').find('#attachment_error').hide(); + if(0 == image_preview.length) { + input_file.closest('td').append('<img style="display: block; width: 500px; margin: 1ex 0;"></img>') + image_preview = input_file.closest('tr').find('img'); + } + + var file = null, + is_image = null; + + if((!(file = event.target.files[0])) || + (!(is_image = file.type.match(/image.*/)))) { + image_preview.hide(); + } + + var reader = new FileReader(); + + reader.onload = function(e) { + var file_content = e.target.result; + if(is_image) { + var image = new Image(); + image.src = file_content; + image_preview.attr('src', file_content); + image_preview.show(); + } + $.post(url, + {data: file_content, + processData: false}, + function(data) { + if('message' in data) + return input_file.closest('form').find('#attachment_error').show().text(data.message); + + input_file.closest('form').find('#token').attr('value', data.upload.token); + input_file.closest('form').find('#filename').attr('value', file.name); + input_file.closest('form').find('#filetype').attr('value', file.type); + }); + }; + reader.readAsDataURL(file); + }; + } +} (jQuery)); diff --git a/tests/application/modules/admin/controllers/RedmineControllerTest.php b/tests/application/modules/admin/controllers/RedmineControllerTest.php index 2be95ef46d10ddc69e2b74f6a0cb30089121240a..8fc8aab752b9f33ce46d06d934da9cbcde9c5f9c 100644 --- a/tests/application/modules/admin/controllers/RedmineControllerTest.php +++ b/tests/application/modules/admin/controllers/RedmineControllerTest.php @@ -294,7 +294,7 @@ class Admin_RedmineControllerIndexTest extends Admin_RedmineControllerWithApiTes /** @test */ public function anchorToEditBibsShouldBePresent() { - $this->assertXPath('//div[@class="modules"]//button[contains(@onclick, "admin/bib/edit/id/1/backUrl/")]'); + $this->assertXPath('//div[@class="modules"]//button[contains(@onclick, "admin/bib/edit/id/1?backUrl=")]'); } @@ -433,10 +433,10 @@ abstract class Admin_RedmineControllerFixtureAbstractTest extends Admin_RedmineC parent::setUp(); $redmine_api = $this->mock() - ->whenCalled('show')->with('34247', ['include' => 'journals']) + ->whenCalled('show')->with('34247', ['include' => 'attachments,journals']) ->answers(RedmineFixtures::issue34247WithJournals()) - ->whenCalled('show')->with('34248', ['include' => 'journals']) + ->whenCalled('show')->with('34248', ['include' => 'attachments,journals']) ->answers(RedmineFixtures::issue34248WithJournals()) ->whenCalled('update')->answers('hfg') @@ -449,9 +449,26 @@ abstract class Admin_RedmineControllerFixtureAbstractTest extends Admin_RedmineC $redmine_api_priority = $this->mock() ->whenCalled('all')->answers(RedmineFixtures::supportPriority()); + $redmine_api_attachment = $this->mock() + + ->whenCalled('upload') + ->with('image content') + ->answers('{"upload":{"token":"7167.ed1ccdb093229ca1bd0b043618d88743"}}') + + ->whenCalled('upload') + ->with('image invalide') + ->answers('<html>ERROR 500</html>') + + ->whenCalled('upload') + ->with('token invalide') + ->answers('{"upload":{"token":"7167."}}') + + ->beStrict(); + $redmine_client = $this->mock() ->whenCalled('api')->with('issue')->answers($redmine_api) ->whenCalled('api')->with('issue_status')->answers($redmine_api_status) + ->whenCalled('api')->with('attachment')->answers($redmine_api_attachment) ->beStrict(); Class_WebService_Redmine::setClient($redmine_client); @@ -483,7 +500,7 @@ class Admin_RedmineControllerEditIssue34247Test extends Admin_RedmineControllerF ['//ul//li', 'Priorité client changé de Normale à Urgente'], ['//td','test-support'], ['//td', '07/01/2016 à 09:30:26'], - + ['//td//a', 'Pièce jointe : "proof.jpg"'] ]; } @@ -636,7 +653,7 @@ class Admin_RedmineControllerPostEditIssue34247Test extends Admin_RedmineControl parent::setUp(); $redmine_api = $this->mock() - ->whenCalled('show')->with('34247', ['include' => 'journals']) + ->whenCalled('show')->with('34247', ['include' => 'attachments,journals']) ->answers(RedmineFixtures::issue34247WithJournals()) ->whenCalled('update')->answers('hfg') @@ -726,13 +743,14 @@ class Admin_RedmineControllerAddIssueTest extends Admin_RedmineControllerFixture public function data_form() { - return [ ['//form'], + return [['//form'], ['//input[@id="subject"]'], ['//select[@id="priority"]//option[@value="Normale"][@selected]'], ['//select[@id="module"]'], ['//textarea[@id="description"]'], ['//textarea[@id="technical_informations"][@readonly][contains(text(), "Url :")]'], - ['//textarea[@id="contact"]']]; + ['//textarea[@id="contact"]'], + ['//input[@type="file"]']]; } @@ -743,4 +761,105 @@ class Admin_RedmineControllerAddIssueTest extends Admin_RedmineControllerFixture public function formShouldContains($tag) { $this->assertXPath($tag, $this->_response->getBody()); } -} \ No newline at end of file +} + + + + + +class Admin_RedmineControllerUploadFileTest extends Admin_RedmineControllerFixtureAbstractTest{ + + /** @test */ + public function shouldReturnJsonResponse() { + $this->postDispatch('admin/redmine/upload-file/id_lib/1', ['data' => base64_encode('image content')]); + $this->assertEquals('{"upload":{"token":"7167.ed1ccdb093229ca1bd0b043618d88743"}}', $this->_response->getBody()); + } + + + /** @test */ + public function shouldReturnErrorMessageInJsonBecauseContainsHTML() { + $this->postDispatch('admin/redmine/upload-file/id_lib/1', ['data' => base64_encode('image invalide')]); + $this->assertContains('{"status":"error","message":"La pi\u00e8ce jointe est invalide.",', $this->_response->getBody()); + } + + + /** @test */ + public function shouldReturnErrorMessageInJsonBecauseTokenDoesntMatch() { + $this->postDispatch('admin/redmine/upload-file/id_lib/1', ['data' => base64_encode('token invalide')]); + $this->assertContains('{"status":"error","message":"L\'ajout de la pi\u00e8ce jointe a \u00e9chou\u00e9 car la cl\u00e9 re\u00e7ue \"7167.\" est invalide."', $this->_response->getBody()); + } +} + + + + +class Admin_RedmineControllerPostEditIssue34247WithAttachmentTest extends Admin_RedmineControllerWithApiTestCase { + protected $_update_params; + + public function setUp() { + parent::setUp(); + + $redmine_api = $this->mock() + + ->whenCalled('show') + ->with('34247', ['include' => 'attachments,journals']) + ->answers(RedmineFixtures::issue34247WithJournals()) + + ->whenCalled('update') + ->with(34247, + ['status_id' => 5, + 'custom_fields' => [['id' => 5, + 'value' => 'Normale'], + ['id' => 37, + 'value' => ''], + ['id' => 43, + 'value' => ''], + ['id' => 38, + 'value' => 'Bug logiciel']], + 'notes' => 'add proof']) + ->answers(true) + + ->whenCalled('all') + ->with(['project_id' => 123]) + ->answers(RedmineFixtures::supportStatus()) + + ->whenCalled('attach') + ->with(34247, + ['token' => '7167.ed1ccdb093229ca1bd0b043618d88743', + 'filename' => 'proof.png', + 'content_type' => 'image/png']) + ->answers(true) + + ->beStrict(); + + $redmine_client = $this->mock() + ->whenCalled('api') + ->answers($redmine_api); + + Class_WebService_Redmine::setClient($redmine_client); + + $this->postDispatch('admin/redmine/edit-issue/id_lib/1/id/34247', + ['status_id' => '5', + 'priority' => 'Normale', + 'notes' => 'add proof', + 'module' => '', + 'contact' => '', + 'token' => '7167.ed1ccdb093229ca1bd0b043618d88743', + 'filename' => 'proof.png', + 'filetype' => 'image/png']); + + $this->_update_params = $redmine_api->getAttributesForLastCallOn('update')[1]; + } + + + /** @test */ + public function issue34247ShouldHaveBeenUpdated() { + $this->assertFlashMessengerContentContains('Demande #34247 enregistrée'); + } + + + /** @test */ + public function shouldRedirectToReferer() { + $this->assertRedirect(); + } +} diff --git a/tests/fixtures/RedmineFixtures.php b/tests/fixtures/RedmineFixtures.php index 475493334017a00665de29e7338bc9bf005a55b2..5bab9f300c192019c13ba59da5569c81b8682bd0 100644 --- a/tests/fixtures/RedmineFixtures.php +++ b/tests/fixtures/RedmineFixtures.php @@ -58,33 +58,33 @@ class RedmineFixtures { public static function sandreIssues() { return ['issues' => [ ['id' => 34246, - 'project' => ['id' => 56, - 'name' => 'Développement Bokeh AFI-OPAC 2.0'], - 'tracker' => ['id' => 2, - 'name' => 'Développement'], - 'status' => ['id' => 7 , - 'name' => 'En développement'], - 'priority' => ['id' => 4, - 'name' => 'Normal'], - 'author' => ['id' => 207, - 'name' => 'gloas'], - 'assigned_to' => ['id' => 207, - 'name' => 'gloas'], - 'subject' => 'Charte graphique back-office', - 'description' => 'un ticket redmine', - 'done_ratio' => 30, - 'custom_fields' => [ ['id' => 37, - 'name' => 'Module Portail', - 'value' => ''], - ['id' => 5 , - 'name' => 'Priorité client', - 'value' => 'Normale'], - ['id' => 11, - 'name' => 'Phase', - 'value' => '']], - 'created_on' => '2015-12-04T09:19:11Z', - 'updated_on' => '2015-12-04T09:25:42Z', - 'story_points' => ''], + 'project' => ['id' => 56, + 'name' => 'Développement Bokeh AFI-OPAC 2.0'], + 'tracker' => ['id' => 2, + 'name' => 'Développement'], + 'status' => ['id' => 7 , + 'name' => 'En développement'], + 'priority' => ['id' => 4, + 'name' => 'Normal'], + 'author' => ['id' => 207, + 'name' => 'gloas'], + 'assigned_to' => ['id' => 207, + 'name' => 'gloas'], + 'subject' => 'Charte graphique back-office', + 'description' => 'un ticket redmine', + 'done_ratio' => 30, + 'custom_fields' => [ ['id' => 37, + 'name' => 'Module Portail', + 'value' => ''], + ['id' => 5 , + 'name' => 'Priorité client', + 'value' => 'Normale'], + ['id' => 11, + 'name' => 'Phase', + 'value' => '']], + 'created_on' => '2015-12-04T09:19:11Z', + 'updated_on' => '2015-12-04T09:25:42Z', + 'story_points' => ''], static::issue34247(), static::issue34248()], @@ -166,131 +166,115 @@ class RedmineFixtures { public static function issue34247WithJournals() { return [ 'issue' => - [ 'id' => 34247, - 'project' => [ 'id' => 214, - 'name' => 'Support Bokeh AFI-OPAC 2.0', - ], - 'tracker' => [ 'id' => 12, - 'name' => 'Demande d\'assistance', - ], - 'status' => [ 'id' => 2, - 'name' => 'Affecté au dév.', - ], - 'priority' => [ 'id' => 5, - 'name' => 'Haut', - ], - 'author' => [ 'id' => 207, - 'name' => 'gloas', - ], - 'assigned_to' => [ 'id' => 207, - 'name' => 'gloas', - ], - 'subject' => 'reindexation des champs personnalisés ', - 'description' => 'Url de l\'anomalie : http://web.afi-sa.net/miop-test.net/admin/custom-fields/edit/id/1 + [ 'id' => 34247, + 'project' => [ 'id' => 214, + 'name' => 'Support Bokeh AFI-OPAC 2.0', + ], + 'tracker' => [ 'id' => 12, + 'name' => 'Demande d\'assistance', + ], + 'status' => [ 'id' => 2, + 'name' => 'Affecté au dév.', + ], + 'priority' => [ 'id' => 5, + 'name' => 'Haut', + ], + 'author' => [ 'id' => 207, + 'name' => 'gloas', + ], + 'assigned_to' => [ 'id' => 207, + 'name' => 'gloas', + ], + 'subject' => 'reindexation des champs personnalisés ', + 'description' => 'Url de l\'anomalie : http://web.afi-sa.net/miop-test.net/admin/custom-fields/edit/id/1 Étapes pour parvenir au bug : * indexer un champs personnalisé * les facettes des notices des articles qui ont une valeur de paramétrée pour ce champ personnalisé ne sont pas mises à jour. ', - 'done_ratio' => 20, - 'spent_hours' => 0, - 'custom_fields' => [ [ 'id' => 43, - 'name' => 'Personne à contacter', - 'value' => 'Nom / prénom / email / téléphone', - ], - [ 'id' => 42, - 'name' => 'Pris en charge par', - 'value' => '', - ], - [ 'id' => 37, - 'name' => 'Module Portail', - 'value' => 'Recherche', - ], - [ 'id' => 5, - 'name' => 'Priorité client', - 'value' => 'Normale', - ], - [ 'id' => 1, - 'name' => 'Client', - 'value' => '', - ], - [ 'id' => 46, - 'name' => 'Relancé le', - 'value' => '', - ], - ], - 'created_on' => '2015-09-29T10:01:49Z', - 'updated_on' => '2015-12-02T13:37:49Z', - 'journals' => [ [ 'id' => 149465, - 'user' => [ 'id' => 1198, - 'name' => 'test-support', - ], - 'notes' => '', - 'created_on' => '2016-01-07T08:30:26Z', - 'details' => [ [ 'property' => 'relation', - 'name' => 'copied_from', - 'new_value' => '35800', - ], - ], - ], - [ 'id' => 149517, - 'user' => [ 'id' => 92, - 'name' => 'other', - ], - 'notes' => 'Pris en charge par le developpement', - 'created_on' => '2016-01-07T09:38:13Z', - 'details' => [ [ 'property' => 'attr', - 'name' => 'status_id', - 'old_value' => '1', - 'new_value' => '2', - ], - [ 'property' => 'attr', - 'name' => 'done_ratio', - 'old_value' => '0', - 'new_value' => '20', - ], - ], - ], - [ 'id' => 149608, - 'user' => [ 'id' => 92, - 'name' => 'dev', - ], - 'notes' => '', - 'created_on' => '2016-01-07T11:10:00Z', - 'details' => [ [ 'property' => 'relation', - 'name' => 'copied_to', - 'old_value' => '35831', - ], - ], - ], - [ 'id' => 149610, - 'user' => [ 'id' => 92, - 'name' => 'dev', - ], - 'notes' => '', - 'created_on' => '2016-01-07T11:10:04Z', - 'details' => [ [ 'property' => 'relation', - 'name' => 'blocks', - 'new_value' => '35831', - ], - ], - ], - [ 'id' => 149612, - 'user' => [ 'id' => 1198, - 'name' => 'test-support', - ], - 'notes' => '', - 'created_on' => '2016-01-07T11:12:45Z', - 'details' => [ [ 'property' => 'cf', - 'name' => '5', - 'old_value' => 'Normale', - 'new_value' => 'Urgente', - ], - ], - ], - ], - ], -]; + 'done_ratio' => 20, + 'spent_hours' => 0, + 'custom_fields' => [ [ 'id' => 43, + 'name' => 'Personne à contacter', + 'value' => 'Nom / prénom / email / téléphone', + ], + [ 'id' => 42, + 'name' => 'Pris en charge par', + 'value' => '', + ], + [ 'id' => 37, + 'name' => 'Module Portail', + 'value' => 'Recherche', + ], + [ 'id' => 5, + 'name' => 'Priorité client', + 'value' => 'Normale', + ], + [ 'id' => 1, + 'name' => 'Client', + 'value' => '', + ], + [ 'id' => 46, + 'name' => 'Relancé le', + 'value' => '', + ], + ], + 'created_on' => '2015-09-29T10:01:49Z', + 'updated_on' => '2015-12-02T13:37:49Z', + 'journals' => [['id' => 149465, + 'user' => [ 'id' => 1198, + 'name' => 'test-support'], + 'notes' => '', + 'created_on' => '2016-01-07T08:30:26Z', + 'details' => [['property' => 'relation', + 'name' => 'copied_from', + 'new_value' => '35800']]], + ['id' => 149517, + 'user' => ['id' => 92, + 'name' => 'other'], + 'notes' => 'Pris en charge par le developpement', + 'created_on' => '2016-01-07T09:38:13Z', + 'details' => [['property' => 'attr', + 'name' => 'status_id', + 'old_value' => '1', + 'new_value' => '2'], + ['property' => 'attr', + 'name' => 'done_ratio', + 'old_value' => '0', + 'new_value' => '20']]], + ['id' => 149608, + 'user' => ['id' => 92, + 'name' => 'dev'], + 'notes' => '', + 'created_on' => '2016-01-07T11:10:00Z', + 'details' => [['property' => 'relation', + 'name' => 'copied_to', + 'old_value' => '35831']]], + ['id' => 149610, + 'user' => ['id' => 92, + 'name' => 'dev'], + 'notes' => '', + 'created_on' => '2016-01-07T11:10:04Z', + 'details' => [['property' => 'relation', + 'name' => 'blocks', + 'new_value' => '35831']]], + ['id' => 149612, + 'user' => ['id' => 1198, + 'name' => 'test-support'], + 'notes' => '', + 'created_on' => '2016-01-07T11:12:45Z', + 'details' => [['property' => 'cf', + 'name' => '5', + 'old_value' => 'Normale', + 'new_value' => 'Urgente']]], + ['id' => 249465, + 'user' => ['id' => 1198, + 'name' => 'test-support'], + 'notes' => '', + 'created_on' => '2016-01-07T08:30:26Z', + 'details' => [['property' => 'attachment', + 'name' => '456789', + 'new_value' => 'proof.jpg']]]]]]; } diff --git a/tests/library/ZendAfi/View/Helper/Notice/UnimarcTest.php b/tests/library/ZendAfi/View/Helper/Notice/UnimarcTest.php index f9cb30df65f89db83d8ab87b2df16da72221c05b..97ac9d39ab57dbed35f39c1f39bab343ebd1ec29 100644 --- a/tests/library/ZendAfi/View/Helper/Notice/UnimarcTest.php +++ b/tests/library/ZendAfi/View/Helper/Notice/UnimarcTest.php @@ -25,30 +25,47 @@ parent::setUp(); $this->_helper = new ZendAfi_View_Helper_Notice_Unimarc(); $this->_helper->setView(new ZendAfi_Controller_Action_Helper_View()); - $this->_html = $this->_helper->notice_Unimarc($this->fixture('Class_Notice', - ['id' => 1, - 'titre' => 'Pomme et Ananas', - 'clef_alpha' => 'POMMEETANANAS', - 'facettes' => 'A1 Q9', - 'date_maj' => '01/01/2015', - 'unimarc' => ''])); + $this->_html = $this->_helper + ->notice_Unimarc($this->fixture('Class_Notice', + ['id' => 1, + 'titre' => 'Pomme et Ananas', + 'clef_alpha' => 'POMMEETANANAS', + 'alpha_titre' => 'POM POMS ANANA ANANAS', + 'alpha_auteur' => 'AUTEUR AUTEURS', + 'facettes' => 'A1 Q9', + 'date_maj' => '01/01/2015', + 'date_creation' => '09/10/2017', + 'unimarc' => '', + 'url_vignette' => 'https://thumbs.net/xXv9873ct'])); } /** @test */ public function alphaKeyShouldBePresent() { - $this->assertContains('Clé alpha: POMMEETANANAS', $this->_html); + $this->assertXPathContentContains($this->_html, '//td', 'POMMEETANANAS'); } /** @test */ public function dateMajShouldBePresent() { - $this->assertContains('Mis à jour le: 01/01/2015', $this->_html); + $this->assertXPathContentContains($this->_html, '//td', '01/01/2015'); + } + + + /** @test */ + public function noverltyDateShouldBePresent() { + $this->assertXPathContentContains($this->_html, '//td', '09/10/2017'); } /** @test */ public function facetsShouldBePresent() { - $this->assertContains('Facettes: A1 Q9', $this->_html); + $this->assertXPathContentContains($this->_html, '//td', 'A1 Q9'); + } + + + /** @test */ + public function thumbnailUrlShouldBePresent() { + $this->assertXPathContentContains($this->_html, '//td', 'https://thumbs.net/xXv9873ct'); } }