From b796e11b4058d6d1cf8a2c8db2bceb7c501988c8 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Wed, 13 Feb 2013 19:03:16 +0100 Subject: [PATCH 01/18] Refactor reports into silex controllers Refactor reports into silex controllers --- config/nginx.rewrite.rules | 2 + lib/Alchemy/Phrasea/Application.php | 3 + .../Phrasea/Controller/Report/Root.php | 1575 +++++++++++++++++ lib/classes/module/report/nav.php | 19 +- lib/classes/module/report/sqlaction.php | 14 +- lib/classes/module/report/sqldownload.php | 19 +- lib/classes/module/report/sqlfilter.php | 26 +- .../web/report/ajax_data_content.html.twig | 8 +- .../web/report/ajax_report_content.html.twig | 18 +- .../Phrasea/Controller/Report/RootTest.php | 1309 ++++++++++++++ www/.htaccess | 2 + 11 files changed, 2965 insertions(+), 30 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Controller/Report/Root.php create mode 100644 tests/Alchemy/Tests/Phrasea/Controller/Report/RootTest.php diff --git a/config/nginx.rewrite.rules b/config/nginx.rewrite.rules index 69120b8c0c..85f72ad6f0 100644 --- a/config/nginx.rewrite.rules +++ b/config/nginx.rewrite.rules @@ -45,6 +45,8 @@ rewrite ^/user/notifications/.*$ /index.php last; rewrite ^/download/.*$ /index.php last; rewrite ^/session/.*$ /index.php last; +rewrite ^/report/.*$ /index.php last; + rewrite ^/client/.*$ /index.php last; rewrite ^/client/baskets.*$ /index.php last; diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 0ae7867460..5b24ece9c1 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -56,6 +56,7 @@ use Alchemy\Phrasea\Controller\Prod\TOU; use Alchemy\Phrasea\Controller\Prod\Upload; use Alchemy\Phrasea\Controller\Prod\UsrLists; use Alchemy\Phrasea\Controller\Prod\WorkZone; +use Alchemy\Phrasea\Controller\Report\Root as ReportRoot; use Alchemy\Phrasea\Controller\Root\Account; use Alchemy\Phrasea\Controller\Root\Developers; use Alchemy\Phrasea\Controller\Root\Login; @@ -649,6 +650,8 @@ class Application extends SilexApplication $this->mount('/download/', new DoDownload()); $this->mount('/session/', new Session()); + + $this->mount('/report/', new ReportRoot()); } private function reinitUser() diff --git a/lib/Alchemy/Phrasea/Controller/Report/Root.php b/lib/Alchemy/Phrasea/Controller/Report/Root.php new file mode 100644 index 0000000000..79b171e31b --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Report/Root.php @@ -0,0 +1,1575 @@ +before(function() use ($app) { + $app['firewall']->requireAccessToModule('report'); + }); + + $controllers->get('/dashboard', $this->call('getDashboard')); + + $controllers->post('/init', $this->call('initReport')); + + $controllers->post('/connexions', $this->call('doReportConnexions')); + + $controllers->post('/questions', $this->call('doReportQuestions')); + + $controllers->post('/downloads', $this->call('doReportDownloads')); + + $controllers->post('/documents', $this->call('doReportDocuments')); + + $controllers->post('/clients', $this->call('doReportClients')); + + $controllers->post('/activity/users/connexions', $this->call('doReportConnexionsByUsers')); + + $controllers->post('/activity/users/downloads', $this->call('doReportDownloadsByUsers')); + + $controllers->post('/activity/questions/best-of', $this->call('doReportBestOfQuestions')); + + $controllers->post('/activity/questions/no-best-of', $this->call('doReportNoBestOfQuestions')); + + $controllers->post('/activity/instance/hours', $this->call('doReportSiteActiviyPerHours')); + + $controllers->post('/activity/instance/days', $this->call('doReportSiteActiviyPerDays')); + + $controllers->post('/activity/documents/pushed', $this->call('doReportPushedDocuments')); + + $controllers->post('/activity/documents/added', $this->call('doReportAddedDocuments')); + + $controllers->post('/activity/documents/edited', $this->call('doReportEditedDocuments')); + + $controllers->post('/activity/documents/validated', $this->call('doReportValidatedDocuments')); + + $controllers->post('/informations/user', $this->call('doReportInformationsUser')); + + $controllers->post('/informations/browser', $this->call('doReportInformationsBrowser')); + + $controllers->post('/informations/document', $this->call('doReportInformationsDocument')); + + return $controllers; + } + + public function getDashboard(Application $app, Request $request) + { + \User_Adapter::updateClientInfos($app, 4); + + $dashboard = new \module_report_dashboard($app, $app['phraseanet.user']); + $dashboard->execute(); + + return $app['twig']->render('report/report_layout_child.html.twig', array( + 'ajax_dash' => true, + 'dashboard' => $dashboard, + 'home_title' => $app['phraseanet.registry']->get('GV_homeTitle'), + 'module' => "report", + "module_name" => "Report", + 'anonymous' => $app['phraseanet.registry']->get('GV_anonymousReport'), + 'g_anal' => $app['phraseanet.registry']->get('GV_googleAnalytics'), + 'ajax' => false, + 'ajax_chart' => false + )); + } + + public function initReport(Application $app, Request $request) + { + $dmin = $request->request->get('dmin', ''); + $dmax = $request->request->get('dmax', ''); + $popbases = $request->request->get('popbases', array()); + + if ($dmin == '') { + $dmin = '01-' . date('m') . '-' . date('Y'); + } + + if ($dmax == '') { + $dmax = date("d") . "-" . date("m") . "-" . date("Y"); + } + + $td = explode('-', $dmin); + $dmin = date('Y-m-d H:i:s', mktime(0, 0, 0, $td[1], $td[0], $td[2])); + + $td = explode('-', $dmax); + $dmax = date('Y-m-d H:i:s', mktime(23, 59, 59, $td[1], $td[0], $td[2])); + + //get user's sbas & collections selection from popbases + $selection = array(); + $liste = $id_sbas = ''; + $i = 0; + foreach (array_fill_keys($popbases, 0) as $key => $val) { + $exp = explode("_", $key); + if ($exp[0] != $id_sbas && $i != 0) { + $selection[$id_sbas]['liste'] = $liste; + $liste = ''; + } + $selection[$exp[0]][] = $exp[1]; + $liste .= (empty($liste) ? '' : ',') . $exp[1]; + $id_sbas = $exp[0]; + $i ++; + } + //fill the last entry + $selection[$id_sbas]['liste'] = $liste; + + return $app['twig']->render('report/ajax_report_content.html.twig', array( + 'selection' => $selection, + 'anonymous' => $app['phraseanet.registry']->get('GV_anonymousReport'), + 'ajax' => true + )); + } + + public function doReportConnexions(Application $app, Request $request) + { + $cnx = new \module_report_connexion( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $conf = array( + 'user' => array(_('phraseanet::utilisateurs'), 1, 1, 1, 1), + 'ddate' => array(_('report:: date'), 1, 0, 1, 1), + 'ip' => array(_('report:: IP'), 1, 0, 0, 0), + 'appli' => array(_('report:: modules'), 1, 0, 0, 0), + 'fonction' => array(_('report::fonction'), 1, 1, 1, 1), + 'activite' => array(_('report::activite'), 1, 1, 1, 1), + 'pays' => array(_('report::pays'), 1, 1, 1, 1), + 'societe' => array(_('report::societe'), 1, 1, 1, 1) + ); + + if ($request->request->get('printcsv') == 'on') { + $cnx->setHasLimit(false); + $cnx->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($cnx->getResult(), $cnx->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } + + $report = $this->doReport($app, $request, $cnx, $conf); + + if ($report instanceof Response) { + return $report; + } + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => $report['display_nav'], // do we display the prev and next button ? + 'next' => $report['next_page'], //Number of the next page + 'prev' => $report['previous_page'], //Number of the previoous page + 'page' => $report['page'], //The current page + 'filter' => ((sizeof($report['filter']) > 0) ? serialize($report['filter']) : ''), //the serialized filters + 'col' => $report['active_column'], //all the columns where a filter is applied + 'limit' => $report['nb_record'] + )); + } + + public function doReportQuestions(Application $app, Request $request) + { + $questions = new \module_report_question( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $conf = array( + 'user' => array(_('report:: utilisateur'), 1, 1, 1, 1), + 'search' => array(_('report:: question'), 1, 0, 1, 1), + 'ddate' => array(_('report:: date'), 1, 0, 1, 1), + 'fonction' => array(_('report:: fonction'), 1, 1, 1, 1), + 'activite' => array(_('report:: activite'), 1, 1, 1, 1), + 'pays' => array(_('report:: pays'), 1, 1, 1, 1), + 'societe' => array(_('report:: societe'), 1, 1, 1, 1) + ); + + if ($request->request->get('printcsv') == 'on') { + $questions->setHasLimit(false); + $questions->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($questions->getResult(), $questions->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } + + $report = $this->doReport($app, $request, $questions, $conf); + + if ($report instanceof Response) { + return $report; + } + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => $report['display_nav'], // do we display the prev and next button ? + 'next' => $report['next_page'], //Number of the next page + 'prev' => $report['previous_page'], //Number of the previoous page + 'page' => $report['page'], //The current page + 'filter' => ((sizeof($report['filter']) > 0) ? serialize($report['filter']) : ''), //the serialized filters + 'col' => $report['active_column'], //all the columns where a filter is applied + 'limit' => $report['nb_record'] + )); + } + + public function doReportDownloads(Application $app, Request $request) + { + $download = new \module_report_download( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $conf_pref = array(); + + foreach (\module_report::getPreff($app, $request->request->get('sbasid')) as $field) { + $conf_pref[strtolower($field)] = array($field, 0, 0, 0, 0); + } + + $conf = array_merge(array( + 'user' => array(_('report:: utilisateurs'), 1, 1, 1, 1), + 'ddate' => array(_('report:: date'), 1, 0, 1, 1), + 'record_id' => array(_('report:: record id'), 1, 1, 1, 1), + 'final' => array(_('phrseanet:: sous definition'), 1, 0, 1, 1), + 'coll_id' => array(_('report:: collections'), 1, 0, 1, 1), + 'comment' => array(_('report:: commentaire'), 1, 0, 0, 0), + 'fonction' => array(_('report:: fonction'), 1, 1, 1, 1), + 'activite' => array(_('report:: activite'), 1, 1, 1, 1), + 'pays' => array(_('report:: pays'), 1, 1, 1, 1), + 'societe' => array(_('report:: societe'), 1, 1, 1, 1) + ), $conf_pref); + + if ($request->request->get('printcsv') == 'on') { + $download->setHasLimit(false); + $download->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($download->getResult(), $download->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } + + $report = $this->doReport($app, $request, $download, $conf); + + if ($report instanceof Response) { + return $report; + } + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => $report['display_nav'], // do we display the prev and next button ? + 'next' => $report['next_page'], //Number of the next page + 'prev' => $report['previous_page'], //Number of the previoous page + 'page' => $report['page'], //The current page + 'filter' => ((sizeof($report['filter']) > 0) ? serialize($report['filter']) : ''), //the serialized filters + 'col' => $report['active_column'], //all the columns where a filter is applied + 'limit' => $report['nb_record'] + )); + } + + public function doReportDocuments(Application $app, Request $request) + { + $document = new \module_report_download( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $conf_pref = array(); + + foreach (\module_report::getPreff($app, $request->request->get('sbasid')) as $field) { + $conf_pref[strtolower($field)] = array($field, 0, 0, 0, 0); + } + + $conf = array_merge(array( + 'telechargement' => array(_('report:: telechargements'), 1, 0, 0, 0), + 'record_id' => array(_('report:: record id'), 1, 1, 1, 0), + 'final' => array(_('phraseanet:: sous definition'), 1, 0, 1, 1), + 'file' => array(_('report:: fichier'), 1, 0, 0, 1), + 'mime' => array(_('report:: type'), 1, 0, 1, 1), + 'size' => array(_('report:: taille'), 1, 0, 1, 1) + ), $conf_pref); + + if ($request->request->get('printcsv') == 'on') { + $document->setHasLimit(false); + $document->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($document->getResult(), $document->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } + + $report = $this->doReport($app, $request, $document, $conf, 'record_id'); + + if ($report instanceof Response) { + return $report; + } + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => true + )), + 'display_nav' => $report['display_nav'], // do we display the prev and next button ? + 'next' => $report['next_page'], //Number of the next page + 'prev' => $report['previous_page'], //Number of the previoous page + 'page' => $report['page'], //The current page + 'filter' => ((sizeof($report['filter']) > 0) ? serialize($report['filter']) : ''), //the serialized filters + 'col' => $report['active_column'], //all the columns where a filter is applied + 'limit' => $report['nb_record'] + )); + } + + public function doReportClients(Application $app, Request $request) + { + $nav = new \module_report_nav( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $conf_nav = array( + 'nav' => array(_('report:: navigateur'), 0, 1, 0, 0), + 'nb' => array(_('report:: nombre'), 0, 0, 0, 0), + 'pourcent' => array(_('report:: pourcentage'), 0, 0, 0, 0) + ); + + $conf_combo = array( + 'combo' => array(_('report:: navigateurs et plateforme'), 0, 0, 0, 0), + 'nb' => array(_('report:: nombre'), 0, 0, 0, 0), + 'pourcent' => array(_('report:: pourcentage'), 0, 0, 0, 0) + ); + $conf_os = array( + 'os' => array(_('report:: plateforme'), 0, 0, 0, 0), + 'nb' => array(_('report:: nombre'), 0, 0, 0, 0), + 'pourcent' => array(_('report:: pourcentage'), 0, 0, 0, 0) + ); + $conf_res = array( + 'res' => array(_('report:: resolution'), 0, 0, 0, 0), + 'nb' => array(_('report:: nombre'), 0, 0, 0, 0), + 'pourcent' => array(_('report:: pourcentage'), 0, 0, 0, 0) + ); + $conf_mod = array( + 'appli' => array(_('report:: module'), 0, 0, 0, 0), + 'nb' => array(_('report:: nombre'), 0, 0, 0, 0), + 'pourcent' => array(_('report:: pourcentage'), 0, 0, 0, 0) + ); + + $report = array( + 'nav' => $nav->buildTabNav($conf_nav), + 'os' => $nav->buildTabOs($conf_os), + 'res' => $nav->buildTabRes($conf_res), + 'mod' => $nav->buildTabModule($conf_mod), + 'combo' => $nav->buildTabCombo($conf_combo) + ); + + if ($request->request->get('printcsv') == 'on') { + return $app->json(array( + 'nav' => \format::arr_to_csv($report['nav']['result'], $conf_nav), + 'os' => \format::arr_to_csv($report['os']['result'], $conf_os), + 'res' => \format::arr_to_csv($report['res']['result'], $conf_res), + 'mod' => \format::arr_to_csv($report['mod']['result'], $conf_mod), + 'combo' => \format::arr_to_csv($report['combo']['result'], $conf_combo) + )); + } + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => true, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => false, + 'title' => false + )); + } + + public function doReportConnexionsByUsers(Application $app, Request $request) + { + $activity = new \module_report_activity( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $activity->setConfig(false); + $activity->setBound("user", true); + + //set Limit + if ($activity->getEnableLimit()) { + ('' !== $page = $request->request->get('page', '')) && ('' !== $limit = $request->request->get('limit', '')) ? + $activity->setLimit($page, $limit) : $activity->setLimit(false, false); + } + + if ($request->request->get('printcsv') == 'on') { + $activity->setHasLimit(false); + $activity->getConnexionBase(false, $request->request->get('on', 'user')); + + try { + $csv = \format::arr_to_csv($activity->getResult(), $activity->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } else { + $report = $activity->getConnexionBase(false, $request->request->get('on', 'user')); + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => false, + 'title' => false + )); + } + } + + public function doReportDownloadsByUsers(Application $app, Request $request) + { + $conf = array( + 'user' => array(_('report:: utilisateur'), 0, 1, 0, 0), + 'nbdoc' => array(_('report:: nombre de documents'), 0, 0, 0, 0), + 'poiddoc' => array(_('report:: poids des documents'), 0, 0, 0, 0), + 'nbprev' => array(_('report:: nombre de preview'), 0, 0, 0, 0), + 'poidprev' => array(_('report:: poids des previews'), 0, 0, 0, 0) + ); + + $activity = new \module_report_activity( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $activity->setConfig(false); + + //set Limit + if ($activity->getEnableLimit()) { + ('' !== $page = $request->request->get('page', '')) && ('' !== $limit = $request->request->get('limit', '')) ? + $activity->setLimit($page, $limit) : $activity->setLimit(false, false); + } + + $report = $activity->getDetailDownload($conf, $request->request->get('on')); + + if ($request->request->get('printcsv') == 'on') { + $activity->setHasLimit(false); + + try { + $csv = \format::arr_to_csv($activity->getResult(), $activity->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } else { + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => false, + 'title' => false + )); + } + } + + public function doReportBestOfQuestions(Application $app, Request $request) + { + $conf = array( + 'search' => array(_('report:: question'), 0, 0, 0, 0), + 'nb' => array(_('report:: nombre'), 0, 0, 0, 0), + 'nb_rep' => array(_('report:: nombre de reponses'), 0, 0, 0, 0) + ); + + $activity = new \module_report_activity( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $activity->setLimit(1, $request->request->get('limit', 20)); + $activity->setTop(20); + $activity->setConfig(false); + + if ($request->request->get('printcsv') == 'on') { + $activity->setHasLimit(false); + $activity->setPrettyString(false); + + $activity->getTopQuestion($conf); + + try { + $csv = \format::arr_to_csv($activity->getResult(), $activity->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } else { + $report = $activity->getTopQuestion($conf); + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => false, + 'title' => false + )); + } + } + + public function doReportNoBestOfQuestions(Application $app, Request $request) + { + $conf = array( + 'search' => array(_('report:: question'), 0, 0, 0, 0), + 'nb' => array(_('report:: nombre'), 0, 0, 0, 0), + 'nb_rep' => array(_('report:: nombre de reponses'), 0, 0, 0, 0) + ); + + $activity = new \module_report_activity( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + //set Limit + if ($activity->getEnableLimit()) { + ('' !== $page = $request->request->get('page', '')) && ('' !== $limit = $request->request->get('limit', '')) ? + $activity->setLimit($page, $limit) : $activity->setLimit(false, false); + } + + $activity->setConfig(false); + + if ($request->request->get('printcsv') == 'on') { + $activity->setHasLimit(false); + $activity->setPrettyString(false); + + $activity->getTopQuestion($conf, true); + + try { + $csv = \format::arr_to_csv($activity->getResult(), $activity->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } else { + $report = $activity->getTopQuestion($conf, true); + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => false, + 'title' => false + )); + } + } + + public function doReportSiteActiviyPerHours(Application $app, Request $request) + { + $activity = new \module_report_activity( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $activity->setConfig(false); + + $report = $activity->getActivityPerHours(); + + if ($request->request->get('printcsv') == 'on') { + $activity->setHasLimit(false); + $activity->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($activity->getResult(), $activity->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } else { + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => true, + 'is_doc' => false + )), + 'display_nav' => false, + 'title' => false + )); + } + } + + public function doReportSiteActiviyPerDays(Application $app, Request $request) + { + $conf = array( + 'ddate' => array(_('report:: jour'), 0, 0, 0, 0), + 'total' => array(_('report:: total des telechargements'), 0, 0, 0, 0), + 'preview' => array(_('report:: preview'), 0, 0, 0, 0), + 'document' => array(_('report:: document original'), 0, 0, 0, 0) + ); + + $activity = new \module_report_activity( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + //set Limit + if ($activity->getEnableLimit()) { + ('' !== $page = $request->request->get('page', '')) && ('' !== $limit = $request->request->get('limit', '')) ? + $activity->setLimit($page, $limit) : $activity->setLimit(false, false); + } + + $activity->setConfig(false); + + $report = $activity->getDownloadByBaseByDay($conf); + + if ($request->request->get('printcsv') == 'on') { + $activity->setHasLimit(false); + $activity->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($activity->getResult(), $activity->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } else { + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => false, + 'title' => false + )); + } + } + + public function doReportPushedDocuments(Application $app, Request $request) + { + $conf = array( + 'user' => array("", 1, 0, 1, 1), + 'getter' => array("Destinataire", 1, 0, 1, 1), + 'date' => array("", 1, 0, 1, 1), + 'record_id' => array("", 1, 1, 1, 1), + 'file' => array("", 1, 0, 1, 1), + 'mime' => array("", 1, 0, 1, 1), + ); + + $activity = new \module_report_push( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $activity->setConfig(false); + + if ($request->request->get('printcsv') == 'on') { + $activity->setHasLimit(false); + $activity->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($activity->getResult(), $activity->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } + + $report = $this->doReport($app, $request, $activity, $conf); + + if ($report instanceof Response) { + return $report; + } + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => $report['display_nav'], // do we display the prev and next button ? + 'next' => $report['next_page'], //Number of the next page + 'prev' => $report['previous_page'], //Number of the previoous page + 'page' => $report['page'], //The current page + 'filter' => ((sizeof($report['filter']) > 0) ? serialize($report['filter']) : ''), //the serialized filters + 'col' => $report['active_column'], //all the columns where a filter is applied + 'limit' => $report['nb_record'] + )); + } + + public function doReportAddedDocuments(Application $app, Request $request) + { + $conf = array( + 'user' => array("", 1, 0, 1, 1), + 'date' => array("", 1, 0, 1, 1), + 'record_id' => array("", 1, 1, 1, 1), + 'file' => array("", 1, 0, 1, 1), + 'mime' => array("", 1, 0, 1, 1), + ); + + $activity = new \module_report_add( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $activity->setConfig(false); + + if ($request->request->get('printcsv') == 'on') { + $activity->setHasLimit(false); + $activity->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($activity->getResult(), $activity->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } + + $report = $this->doReport($app, $request, $activity, $conf); + + if ($report instanceof Response) { + return $report; + } + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => $report['display_nav'], // do we display the prev and next button ? + 'next' => $report['next_page'], //Number of the next page + 'prev' => $report['previous_page'], //Number of the previoous page + 'page' => $report['page'], //The current page + 'filter' => ((sizeof($report['filter']) > 0) ? serialize($report['filter']) : ''), //the serialized filters + 'col' => $report['active_column'], //all the columns where a filter is applied + 'limit' => $report['nb_record'] + )); + } + + public function doReportEditedDocuments(Application $app, Request $request) + { + $conf = array( + 'user' => array("", 1, 0, 1, 1), + 'date' => array("", 1, 0, 1, 1), + 'record_id' => array("", 1, 1, 1, 1), + 'file' => array("", 1, 0, 1, 1), + 'mime' => array("", 1, 0, 1, 1), + ); + + $activity = new \module_report_edit( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $activity->setConfig(false); + + if ($request->request->get('printcsv') == 'on') { + $activity->setHasLimit(false); + $activity->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($activity->getResult(), $activity->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } + + $report = $this->doReport($app, $request, $activity, $conf); + + if ($report instanceof Response) { + return $report; + } + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => $report['display_nav'], // do we display the prev and next button ? + 'next' => $report['next_page'], //Number of the next page + 'prev' => $report['previous_page'], //Number of the previoous page + 'page' => $report['page'], //The current page + 'filter' => ((sizeof($report['filter']) > 0) ? serialize($report['filter']) : ''), //the serialized filters + 'col' => $report['active_column'], //all the columns where a filter is applied + 'limit' => $report['nb_record'] + )); + } + + public function doReportValidatedDocuments(Application $app, Request $request) + { + $conf = array( + 'user' => array("", 1, 0, 1, 1), + 'getter' => array("Destinataire", 1, 0, 1, 1), + 'date' => array("", 1, 0, 1, 1), + 'record_id' => array("", 1, 1, 1, 1), + 'file' => array("", 1, 0, 1, 1), + 'mime' => array("", 1, 0, 1, 1), + ); + + $activity = new \module_report_validate( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $activity->setConfig(false); + + if ($request->request->get('printcsv') == 'on') { + $activity->setHasLimit(false); + $activity->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($activity->getResult(), $activity->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } + + $report = $this->doReport($app, $request, $activity, $conf); + + if ($report instanceof Response) { + return $report; + } + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($report['report']) ? $report['report'] : $report, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => $report['display_nav'], // do we display the prev and next button ? + 'next' => $report['next_page'], //Number of the next page + 'prev' => $report['previous_page'], //Number of the previoous page + 'page' => $report['page'], //The current page + 'filter' => ((sizeof($report['filter']) > 0) ? serialize($report['filter']) : ''), //the serialized filters + 'col' => $report['active_column'], //all the columns where a filter is applied + 'limit' => $report['nb_record'] + )); + } + + public function doReportInformationsUser(Application $app, Request $request) + { + $conf = array( + 'config' => array( + 'photo' => array(_('report:: document'), 0, 0, 0, 0), + 'record_id' => array(_('report:: record id'), 0, 0, 0, 0), + 'date' => array(_('report:: date'), 0, 0, 0, 0), + 'type' => array(_('phrseanet:: sous definition'), 0, 0, 0, 0), + 'titre' => array(_('report:: titre'), 0, 0, 0, 0), + 'taille' => array(_('report:: poids'), 0, 0, 0, 0) + ), + 'conf' => array( + 'identifiant' => array(_('report:: identifiant'), 0, 0, 0, 0), + 'nom' => array(_('report:: nom'), 0, 0, 0, 0), + 'mail' => array(_('report:: email'), 0, 0, 0, 0), + 'adresse' => array(_('report:: adresse'), 0, 0, 0, 0), + 'tel' => array(_('report:: telephone'), 0, 0, 0, 0) + ), + 'config_cnx' => array( + 'ddate' => array(_('report:: date'), 0, 0, 0, 0), + 'appli' => array(_('report:: modules'), 0, 0, 0, 0), + ), + 'config_dl' => array( + 'ddate' => array(_('report:: date'), 0, 0, 0, 0), + 'record_id' => array(_('report:: record id'), 0, 1, 0, 0), + 'final' => array(_('phrseanet:: sous definition'), 0, 0, 0, 0), + 'coll_id' => array(_('report:: collections'), 0, 0, 0, 0), + 'comment' => array(_('report:: commentaire'), 0, 0, 0, 0), + ), + 'config_ask' => array( + 'search' => array(_('report:: question'), 0, 0, 0, 0), + 'ddate' => array(_('report:: date'), 0, 0, 0, 0) + ) + ); + + $report = null; + $html = $html_info = ''; + $from = $request->request->get('from', ''); + $on = $request->request->get('on', ''); + $selectValue = $request->request->get('user', ''); + + if ('' === $selectValue) { + $app->abort(400); + } + + if ('' !== $on && $app['phraseanet.registry']->get('GV_anonymousReport') == true) { + $conf['conf'] = array( + $on => array($on, 0, 0, 0, 0), + 'nb' => array(_('report:: nombre'), 0, 0, 0, 0) + ); + } + + if ($from == 'CNXU' || $from == 'CNX') { + $report = new \module_report_connexion( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection' + )); + $conf_array = $conf['config_cnx']; + $title = _("report:: historique des connexions"); + } elseif ($from == "USR" || $from == "GEN") { + $report = new \module_report_download( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + $conf_array = $conf['config_dl']; + $title = _("report:: historique des telechargements"); + } elseif ($from == "ASK") { + $report = new \module_report_question( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + $conf_array = $conf['config_ask']; + $title = _("report:: historique des questions"); + } + + if ($report) { + $mapColumnTitleToSqlField = $report->getTransQueryString(); + + $currentfilter = array(); + + if ('' !== $serializedFilter = $request->request->get('liste_filter', '')) { + $currentfilter = @unserialize(urldecode($serializedFilter)); + } + + $filter = new \module_report_filter($app, $currentfilter, $mapColumnTitleToSqlField); + + if ('' !== $filterColumn = $request->request->get('filter_column', '')) { + $field = current(explode(' ', $filterColumn)); + $value = $request->request->get('filter_value', ''); + + if ($request->request->get('liste') == 'on') { + return $app->json(array('diag' => $app['twig']->render('report/colFilter.html.twig', array( + 'result' => $report->colFilter($field), + 'field' => $field + )), "title" => sprintf(_('filtrer les resultats sur la colonne %s'), $field))); + } + + if ($field === $value) { + $filter->removeFilter($field); + } else { + $filter->addFilter($field, '=', $value); + } + } + + if ('' !== $selectValue && '' !== $from) { + $filter->addfilter('usrid', '=', $selectValue); + } elseif ('' !== $on && '' !== $selectValue) { + $filter->addfilter($on, '=', $selectValue); + } + + if ($report instanceof \module_report_download) { + $report->setIsInformative(true); + } + + $report->setFilter($filter->getTabFilter()); + $report->setOrder('ddate', 'DESC'); + $report->setConfig(false); + $report->setTitle($title); + $report->setHasLimit(false); + + $reportArray = $report->buildReport($conf_array); + + if ($request->request->get('printcsv') == 'on') { + $report->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($report->getResult(), $report->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } + + $html = $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($reportArray['report']) ? $reportArray['report'] : $reportArray, + 'is_infouser' => $report instanceof \module_report_download, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )); + } + + $info = new \module_report_nav( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $info->setPeriode(''); + $info->setCsv(false); + + $infoArray = $info->buildTabGrpInfo( + null !== $report ? $report->getReq() : '', + null !== $report ? $report->getParams() : array(), + $selectValue, + $conf['conf'], + $on + ); + + if (false == $app['phraseanet.registry']->get('GV_anonymousReport')) { + $html_info = $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($infoArray['report']) ? $infoArray['report'] : $infoArray, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )); + + $title = ('' === $on && isset($infoArray['result'])) ? $infoArray['result'][0]['identifiant'] : $selectValue; + } else { + $title = $selectValue; + } + + return $app->json(array( + 'rs' => sprintf('%s%s', $html_info, $html), + 'display_nav' => false, + 'title' => $title + )); + } + + public function doReportinformationsBrowser(Application $app, Request $request) + { + $conf = array( + 'version' => array(_('report::version '), 0, 0, 0, 0), + 'nb' => array(_('report:: nombre'), 0, 0, 0, 0) + ); + + $info = new \module_report_nav( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $info->setCsv(false); + $info->setConfig(false); + + if ('' === $browser = $request->request->get('user', '')) { + $app->abort(400); + } + + $reportArray = $info->buildTabInfoNav($conf, $browser); + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($reportArray['report']) ? $reportArray['report'] : $reportArray, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => false, + 'title' => $browser + )); + } + + public function doReportInformationsDocument(Application $app, Request $request) + { + $config = array( + 'photo' => array(_('report:: document'), 0, 0, 0, 0), + 'record_id' => array(_('report:: record id'), 0, 0, 0, 0), + 'date' => array(_('report:: date'), 0, 0, 0, 0), + 'type' => array(_('phrseanet:: sous definition'), 0, 0, 0, 0), + 'titre' => array(_('report:: titre'), 0, 0, 0, 0), + 'taille' => array(_('report:: poids'), 0, 0, 0, 0) + ); + + $config_dl = array( + 'ddate' => array(_('report:: date'), 0, 0, 0, 0), + 'user' => array(_('report:: utilisateurs'), 0, 0, 0, 0), + 'final' => array(_('phrseanet:: sous definition'), 0, 0, 0, 0), + 'coll_id' => array(_('report:: collections'), 0, 0, 0, 0), + 'comment' => array(_('report:: commentaire'), 0, 0, 0, 0), + 'fonction' => array(_('report:: fonction'), 0, 0, 0, 0), + 'activite' => array(_('report:: activite'), 0, 0, 0, 0), + 'pays' => array(_('report:: pays'), 0, 0, 0, 0), + 'societe' => array(_('report:: societe'), 0, 0, 0, 0) + ); + + //format conf according user preferences + if ('' !== $columnsList = $request->request->get('list_column', '')) { + $new_conf = $config_dl; + $columns = explode(",", $columnsList); + + foreach (array_keys($config_dl) as $col) { + if (!in_array($col, $columns)) { + unset($new_conf[$col]); + } + } + + $config_dl = $new_conf; + } + + try { + $record = new \record_adapter( + $app, + $request->request->get('sbasid'), + $request->request->get('rid') + ); + } catch (\Exception $e) { + $app->abort(404); + } + + $what = new \module_report_nav( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $what->setPeriode(''); + $what->setCsv(false); + $what->setPrint(false); + + $reportArray = $what->buildTabUserWhat( + $record->get_base_id(), + $record->get_record_id(), + $config + ); + + $title = $what->getTitle(); + + $html = $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($reportArray['report']) ? $reportArray['report'] : $reportArray, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )); + + $from = $request->request->get('from', ''); + + if ('TOOL' === $from) { + $what->setTitle(''); + + return $app->json(array( + 'rs' => $html, + 'display_nav' => false, + 'title' => $title + )); + } + + if ('DASH' === $from) { + $download = new \module_report_download( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $mapColumnTitleToSqlField = $download->getTransQueryString(); + + $currentfilter = array(); + + if ('' !== $serializedFilter = $request->request->get('liste_filter', '')) { + $currentfilter = @unserialize(urldecode($serializedFilter)); + } + + $filter = new \module_report_filter($app, $currentfilter, $mapColumnTitleToSqlField); + + if ('' !== $filterColumn = $request->request->get('filter_column', '')) { + $field = current(explode(' ', $filterColumn)); + $value = $request->request->get('filter_value', ''); + + if ($request->request->get('liste') == 'on') { + return $app->json(array('diag' => $app['twig']->render('report/colFilter.html.twig', array( + 'result' => $report->colFilter($field), + 'field' => $field + )), "title" => sprintf(_('filtrer les resultats sur la colonne %s'), $field))); + } + + if ($field === $value) { + $filter->removeFilter($field); + } else { + $filter->addFilter($field, '=', $value); + } + } + + $filter->addfilter('record_id', '=', $record->get_record_id()); + + $download->setFilter($filter->getTabFilter()); + $download->setOrder('ddate', 'DESC'); + $download->setTitle(_("report:: historique des telechargements")); + $download->setConfig(false); + + $reportArray = $download->buildReport($config_dl); + + if ($request->request->get('printcsv') == 'on') { + $download->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($download->getResult(), $download->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } + + $html = $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($reportArray['report']) ? $reportArray['report'] : $reportArray, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )); + + return $app->json(array( + 'rs' => $html, + 'display_nav' => false, + 'title' => $title + )); + } + + if ($app['phraseanet.registry']->get('GV_anonymousReport') == false && $from !== 'DOC' && $from !== 'DASH' && $from !== "GEN" && $from !== "PUSHDOC") { + $conf = array( + 'identifiant' => array(_('report:: identifiant'), 0, 0, 0, 0), + 'nom' => array(_('report:: nom'), 0, 0, 0, 0), + 'mail' => array(_('report:: email'), 0, 0, 0, 0), + 'adresse' => array(_('report:: adresse'), 0, 0, 0, 0), + 'tel' => array(_('report:: telephone'), 0, 0, 0, 0) + ); + + $info = new \module_report_nav( + $app, + $request->request->get('dmin'), + $request->request->get('dmax'), + $request->request->get('sbasid'), + $request->request->get('collection') + ); + + $info->setPeriode(""); + $info->setConfig(false); + $info->setTitle(_('report:: utilisateur')); + + $reportArray = $info->buildTabGrpInfo(false, array(), $request->request->get('user'), $conf, false); + + if ($request->request->get('printcsv') == 'on') { + $download->setPrettyString(false); + + try { + $csv = \format::arr_to_csv($download->getResult(), $download->getDisplay()); + } catch (\Exception $e) { + $csv = ''; + } + + return $app->json(array('rs' => $csv)); + } + + $html = $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($reportArray['report']) ? $reportArray['report'] : $reportArray, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => false, + 'is_plot' => false, + 'is_doc' => false + )); + + return $app->json(array( + 'rs' => $html, + 'display_nav' => false, + 'title' => $title + )); + } + + return $app->json(array( + 'rs' => $html, + 'display_nav' => false, + 'title' => $title + )); + } + + private function doReport(Application $app, Request $request, \module_report $report, $conf, $what = false) + { + if ($app['phraseanet.registry']->get('GV_anonymousReport') == true) { + if (isset($conf['user'])) { + unset($conf['user']); + } + + if (isset($conf['ip'])){ + unset($conf['ip']); + } + } + //save initial conf + $base_conf = $conf; + //format conf according user preferences + if ('' !== $columnsList = $request->request->get('list_column', '')) { + $new_conf = $conf; + $columns = explode(",", $columnsList); + + foreach (array_keys($conf) as $col) { + if (!in_array($col, $columns)) { + unset($new_conf[$col]); + } + } + + $conf = $new_conf; + } + + //display content of a table column when user click on it + if ($request->request->get('conf') == 'on') { + + return $app->json(array('liste' => $app['twig']->render('report/listColumn.html.twig', array( + 'conf' => $base_conf + )), "title" => _("configuration"))); + } + + //set order + if (('' !== $order = $request->request->get('order', '')) && ('' !== $field = $request->request->get('champ', ''))) { + $report->setOrder($field, $order); + } + + //work on filters + $mapColumnTitleToSqlField = $report->getTransQueryString(); + + $currentfilter = array(); + + if ('' !== $serializedFilter = $request->request->get('liste_filter', '')) { + $currentfilter = @unserialize(urldecode($serializedFilter)); + } + + $filter = new \module_report_filter($app, $currentfilter, $mapColumnTitleToSqlField); + + if ('' !== $filterColumn = $request->request->get('filter_column', '')) { + $field = current(explode(' ', $filterColumn)); + $value = $request->request->get('filter_value', ''); + + if ($request->request->get('liste') == 'on') { + return $app->json(array('diag' => $app['twig']->render('report/colFilter.html.twig', array( + 'result' => $report->colFilter($field), + 'field' => $field + )), "title" => sprintf(_('filtrer les resultats sur la colonne %s'), $field))); + } + + if ($field === $value) { + $filter->removeFilter($field); + } else { + $filter->addFilter($field, '=', $value); + } + } + + //set new request filter if user asking for them + if ($request->request->get('precise') == 1) { + $filter->addFilter('xml', 'LIKE', $request->request->get('word', '')); + } elseif ($request->request->get('precise') == 2) { + $filter->addFilter('record_id', '=', $request->request->get('word', '')); + } + + //set filters to current report + $report->setFilter($filter->getTabFilter()); + $report->setActiveColumn($filter->getActiveColumn()); + $report->setPostingFilter($filter->getPostingFilter()); + + // display a new arraywhere results are group + if ('' !== $groupby = $request->request->get('groupby', '')) { + $report->setConfig(false); + $groupby = current(explode(' ', $groupby)); + + $reportArray = $report->buildReport(false, $groupby); + + if (count($reportArray['allChamps']) > 0 && count($reportArray['display']) > 0) { + $groupField = isset($reportArray['display'][$reportArray['allChamps'][0]]['title']) ? $reportArray['display'][$reportArray['allChamps'][0]]['title'] : ''; + } else { + $groupField = isset($conf[strtolower($groupby)]['title']) ? $conf[strtolower($groupby)]['title'] : ''; + } + + return $app->json(array( + 'rs' => $app['twig']->render('report/ajax_data_content.html.twig', array( + 'result' => isset($reportArray['report']) ? $reportArray['report'] : $reportArray, + 'is_infouser' => false, + 'is_nav' => false, + 'is_groupby' => true, + 'is_plot' => false, + 'is_doc' => false + )), + 'display_nav' => false, + 'title' => _(sprintf('Groupement des resultats sur le champ %s', $groupField)) + )); + } + + //set Limit + if ($report->getEnableLimit()) { + ('' !== $page = $request->request->get('page', '')) && ('' !== $limit = $request->request->get('limit', '')) ? + $report->setLimit($page, $limit) : $report->setLimit(false, false); + } + + //time to build our report + if (false === $what) { + $reportArray = $report->buildReport($conf); + } else { + $reportArray = $report->buildReport($conf, $what, $request->request->get('tbl', false)); + } + return $reportArray; + } + + /** + * Prefix the method to call with the controller class name + * + * @param string $method The method to call + * @return string + */ + private function call($method) + { + return sprintf('%s::%s', __CLASS__, $method); + } +} diff --git a/lib/classes/module/report/nav.php b/lib/classes/module/report/nav.php index 9ec4f80300..58300d229f 100644 --- a/lib/classes/module/report/nav.php +++ b/lib/classes/module/report/nav.php @@ -415,13 +415,6 @@ class module_report_nav extends module_report $filter_id_apbox = $filter_id_datbox = array(); $conn = $this->app['phraseanet.appbox']->get_connection(); - $datefilter = array(); - - if ($this->dmin && $this->dmax) { - $params = array(':dmin' => $this->dmin, ':dmax' => $this->dmax); - $datefilter = "date > :dmin AND date < :dmax"; - } - $this->title = sprintf(_('report:: Information sur les utilisateurs correspondant a %s'), $val); if ($on) { @@ -446,7 +439,7 @@ class module_report_nav extends module_report usr_mail as mail, adresse, tel FROM usr - WHERE $on = :value AND (" . $filter_id_apbox . ")"; + WHERE $on = :value " . (('' !== $filter_id_apbox) ? "AND (" . $filter_id_apbox . ")" : ''); } else { $sql = ' SELECT @@ -548,19 +541,19 @@ class module_report_nav extends module_report _('report:: Information sur le navigateur %s'), $navigator); $sqlBuilder = new module_report_sql($this->app, $this); $filter = $sqlBuilder->getFilters(); - $params = array(':browser' => $navigator); $report_filter = $filter->getReportFilter(); + $params = array_merge($report_filter['params'], array(':browser' => $navigator)); $sql = " - SELECT DISTINCT(version), COUNT(version) as nb + SELECT DISTINCT(tt.version), COUNT(tt.version) as nb FROM ( - SELECT DISTINCT (log.id) + SELECT DISTINCT (log.id), version FROM log FORCE INDEX (date_site, nav, version) INNER JOIN log_colls FORCE INDEX (couple) ON (log.id = log_colls.log_id) - WHERE ". $report_filter['sql'] . " WHERE nav = :browser + AND ". $report_filter['sql'] . " ) AS tt - GROUP BY tt.version + GROUP BY version ORDER BY nb DESC"; $stmt = $conn->prepare($sql); diff --git a/lib/classes/module/report/sqlaction.php b/lib/classes/module/report/sqlaction.php index cf3aa7cea4..4fd6d18e5c 100644 --- a/lib/classes/module/report/sqlaction.php +++ b/lib/classes/module/report/sqlaction.php @@ -38,6 +38,8 @@ class module_report_sqlaction extends module_report_sql implements module_report public function buildSql() { + $customFieldMap = array(); + $filter = $this->filter->getReportFilter() ? : array('params' => array(), 'sql' => false); $this->params = array_merge(array(':action' => $this->action), $filter['params']); @@ -53,12 +55,22 @@ class module_report_sqlaction extends module_report_sql implements module_report WHERE (" . $filter['sql'] . ") AND (d.action = :action) ) AS tt"; + $customFieldMap = array( + 'log.usrid' => 'tt.usrid', + 'log.user' => 'tt.user', + 'd.final' => 'getter', + 'd.record_id' => 'tt.record_id', + 'd.date' => 'tt.date', + 'record.mime' => 'tt.mime', + 'file' => 'tt.file', + ); + $stmt = $this->getConnBas()->prepare($this->sql); $stmt->execute($this->params); $this->total = $stmt->rowCount(); $stmt->closeCursor(); - $this->sql .= $this->filter->getOrderFilter() ? : ''; + $this->sql .= $this->filter->getOrderFilter($customFieldMap) ? : ''; $this->sql .= $this->filter->getLimitFilter() ? : ''; } else { $this->sql = " diff --git a/lib/classes/module/report/sqldownload.php b/lib/classes/module/report/sqldownload.php index effd4a581b..ee66a2bf38 100644 --- a/lib/classes/module/report/sqldownload.php +++ b/lib/classes/module/report/sqldownload.php @@ -25,6 +25,8 @@ class module_report_sqldownload extends module_report_sql implements module_repo public function buildSql() { + $customFieldMap = array(); + $filter = $this->filter->getReportFilter() ? : array('params' => array(), 'sql' => false); $this->params = array_merge(array(), $filter['params']); @@ -54,6 +56,16 @@ class module_report_sqldownload extends module_report_sql implements module_repo INNER JOIN log_colls FORCE INDEX (couple) ON (log.id = log_colls.log_id) INNER JOIN record ON (log_docs.record_id = record.record_id) INNER JOIN subdef ON (log_docs.record_id = subdef.record_id)'; + + $customFieldMap = array( + $field => $name, + 'log_docs.comment' => 'tt.comment', + 'subdef.size' => 'tt.size', + 'subdef.file' => 'tt.file', + 'subdef.mime' => 'tt.mime', + 'log_docs.final' => 'tt.final', + ); + } elseif ($this->on == 'DOC') { $this->sql = ' SELECT ' . $name . ', SUM(1) AS telechargement @@ -88,7 +100,12 @@ class module_report_sqldownload extends module_report_sql implements module_repo $this->total = $stmt->rowCount(); $stmt->closeCursor(); - $this->sql .= $this->filter->getOrderFilter() ? : ''; + if (count($customFieldMap) > 0) { + $this->sql .= $this->filter->getOrderFilter($customFieldMap) ? : ''; + } else { + $this->sql .= $this->filter->getOrderFilter() ? : ''; + } + $this->sql .= $this->filter->getLimitFilter() ? : ''; return $this; diff --git a/lib/classes/module/report/sqlfilter.php b/lib/classes/module/report/sqlfilter.php index b8ab51b14e..eea8f4299f 100644 --- a/lib/classes/module/report/sqlfilter.php +++ b/lib/classes/module/report/sqlfilter.php @@ -17,6 +17,7 @@ class module_report_sqlfilter private $filter; private $cor_query = array(); private $app; + private $report; public function __construct(Application $app, module_report $report) { @@ -27,6 +28,8 @@ class module_report_sqlfilter $this->cor_query = $report->getTransQueryString(); $this->buildFilter($report); + + $this->report = $report; } public static function constructDateFilter($dmin, $dmax) @@ -123,9 +126,13 @@ class module_report_sqlfilter return $this->filter['limit']; } - public function getOrderFilter() + public function getOrderFilter($customFieldMap = null) { - return $this->filter['order']; + if (null === $customFieldMap) { + return $this->filter['order']; + } + + return $this->overrideOrderFilter($customFieldMap); } private function dateFilter(module_report $report) @@ -259,4 +266,19 @@ class module_report_sqlfilter return; } + + private function overrideOrderFilter($customFieldMap) + { + if (sizeof($this->report->getOrder()) > 0) { + if (!isset($customFieldMap[$this->cor_query[$this->report->getOrder('champ')]])) { + return false; + } + + return " ORDER BY " + . $customFieldMap[$this->cor_query[$this->report->getOrder('champ')]] + . ' ' . $this->report->getOrder('order'); + } + + return false; + } } diff --git a/templates/web/report/ajax_data_content.html.twig b/templates/web/report/ajax_data_content.html.twig index 74bbdff487..e9548f3ce2 100644 --- a/templates/web/report/ajax_data_content.html.twig +++ b/templates/web/report/ajax_data_content.html.twig @@ -39,10 +39,10 @@ data : ({ tbl : 'what', rid : riid, - sbasid : '{{ param.sbasid }}', - collection : '{{ param.collection }}', - dmin : '{{ param.dmin }}', - dmax : '{{ param.dmax }}', + sbasid : '{{ app['request'].get('sbasid') }}', + collection : '{{ app['request'].get('collection') }}', + dmin : '{{ app['request'].get('dmin') }}', + dmax : '{{ app['request'].get('dmax') }}', from : 'TOOL' }) }, diff --git a/templates/web/report/ajax_report_content.html.twig b/templates/web/report/ajax_report_content.html.twig index eafdead750..a69f925275 100644 --- a/templates/web/report/ajax_report_content.html.twig +++ b/templates/web/report/ajax_report_content.html.twig @@ -3,12 +3,12 @@
{% for key, value in selection %} -
+
{% block ajax_data_content %}{% endblock %}
@@ -28,14 +28,14 @@
- - - + + + - - + + @@ -51,11 +51,11 @@ {% if anonymous %} - + {% else %} {% endif %} - + diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Report/RootTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Report/RootTest.php new file mode 100644 index 0000000000..e65df547a5 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Controller/Report/RootTest.php @@ -0,0 +1,1309 @@ +dmax = new \DateTime('now'); + $this->dmin = new \DateTime('-1 month'); + } + + public function testRouteDashboard() + { + $auth = new \Session_Authentication_None(self::$DI['user']); + self::$DI['app']->openAccount($auth); + + self::$DI['client']->request('GET', '/report/dashboard'); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testRouteInitReport() + { + self::$DI['client']->request('POST', '/report/init', array('popbases' => array('1_1'))); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportConnexions() + { + self::$DI['client']->request('POST', '/report/connexions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'order' => 'ASC', + 'champ' => 'user', + 'page' => 1, + 'limit' => 10, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportConnexionsPrintCSV() + { + self::$DI['client']->request('POST', '/report/connexions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportConnexionsFilterColumns() + { + self::$DI['client']->request('POST', '/report/connexions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'list_column' => 'user ddate', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportConnexionsFilterResultOnOneColumn() + { + self::$DI['client']->request('POST', '/report/connexions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'filter_column' => 'user', + 'filter_value' => 'admin', + 'liste' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportConnexionsFilterConf() + { + self::$DI['client']->request('POST', '/report/connexions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'conf' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportConnexionsGroupBy() + { + self::$DI['client']->request('POST', '/report/connexions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'groupby' => 'user', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + + public function testDoReportQuestions() + { + self::$DI['client']->request('POST', '/report/questions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'order' => 'ASC', + 'champ' => 'user', + 'page' => 1, + 'limit' => 10, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportQuestionsPrintCSV() + { + self::$DI['client']->request('POST', '/report/questions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportQuestionsFilterColumns() + { + self::$DI['client']->request('POST', '/report/questions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'list_column' => 'user ddate', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportQuestionsFilterResultOnOneColumn() + { + self::$DI['client']->request('POST', '/report/questions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'filter_column' => 'user', + 'filter_value' => 'admin', + 'liste' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportQuestionsFilterConf() + { + self::$DI['client']->request('POST', '/report/questions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'conf' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportQuestionsGroupBy() + { + self::$DI['client']->request('POST', '/report/questions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'groupby' => 'user', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDownloads() + { + self::$DI['client']->request('POST', '/report/downloads', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'order' => 'ASC', + 'champ' => 'user', + 'page' => 1, + 'limit' => 10, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDownloadsPrintCSV() + { + self::$DI['client']->request('POST', '/report/downloads', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDownloadsFilterColumns() + { + self::$DI['client']->request('POST', '/report/downloads', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'list_column' => 'user ddate', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDownloadsFilterResultOnOneColumn() + { + self::$DI['client']->request('POST', '/report/downloads', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'filter_column' => 'user', + 'filter_value' => 'admin', + 'liste' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDownloadsFilterConf() + { + self::$DI['client']->request('POST', '/report/downloads', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'conf' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDownloadsGroupBy() + { + self::$DI['client']->request('POST', '/report/downloads', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'groupby' => 'user', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDocuments() + { + self::$DI['client']->request('POST', '/report/documents', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'order' => 'ASC', + 'champ' => 'final', + 'tbl' => 'DOC', + 'page' => 1, + 'limit' => 10, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDocumentsPrintCSV() + { + self::$DI['client']->request('POST', '/report/documents', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDocumentsFilterColumns() + { + self::$DI['client']->request('POST', '/report/documents', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'list_column' => 'file mime', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDocumentsFilterResultOnOneColumn() + { + self::$DI['client']->request('POST', '/report/documents', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'filter_column' => 'mime', + 'filter_value' => 'pdf', + 'liste' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDocumentsFilterConf() + { + self::$DI['client']->request('POST', '/report/documents', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'conf' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDocumentsGroupBy() + { + self::$DI['client']->request('POST', '/report/documents', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'groupby' => 'mime', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + + public function testDoReportClients() + { + self::$DI['client']->request('POST', '/report/clients', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportClientPrintCSV() + { + self::$DI['client']->request('POST', '/report/clients', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportConnexionsByUsers() + { + self::$DI['client']->request('POST', '/report/activity/users/connexions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'page' => 1, + 'limit' => 10, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportConnexionsByUsersCSV() + { + self::$DI['client']->request('POST', '/report/activity/users/connexions', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'page' => 1, + 'limit' => 10, + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDownloadsByUsers() + { + self::$DI['client']->request('POST', '/report/activity/users/downloads', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'page' => 1, + 'limit' => 10, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportDownloadsByUsersCSV() + { + self::$DI['client']->request('POST', '/report/activity/users/downloads', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'page' => 1, + 'limit' => 10, + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportBestOfQuestions() + { + self::$DI['client']->request('POST', '/report/activity/questions/best-of', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'limit' => 10, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportBestOfQuestionsCSV() + { + self::$DI['client']->request('POST', '/report/activity/questions/best-of', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'limit' => 10, + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportNoBestOfQuestions() + { + self::$DI['client']->request('POST', '/report/activity/questions/no-best-of', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'limit' => 10, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportNoBestOfQuestionsCSV() + { + self::$DI['client']->request('POST', '/report/activity/questions/no-best-of', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'limit' => 10, + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportSiteActiviyPerHours() + { + self::$DI['client']->request('POST', '/report/activity/instance/hours', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportSiteActiviyPerHoursCSV() + { + self::$DI['client']->request('POST', '/report/activity/instance/hours', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportSiteActiviyPerDays() + { + self::$DI['client']->request('POST', '/report/activity/instance/days', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportSiteActiviyPerDaysCSV() + { + self::$DI['client']->request('POST', '/report/activity/instance/days', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportPushedDocuments() + { + self::$DI['client']->request('POST', '/report/activity/documents/pushed', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'order' => 'ASC', + 'champ' => 'user', + 'page' => 1, + 'limit' => 10, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportPushedDocumentsPrintCSV() + { + self::$DI['client']->request('POST', '/report/activity/documents/pushed', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportPushedDocumentsFilterColumns() + { + self::$DI['client']->request('POST', '/report/activity/documents/pushed', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'list_column' => 'user ddate', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportPushedDocumentsFilterResultOnOneColumn() + { + self::$DI['client']->request('POST', '/report/activity/documents/pushed', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'filter_column' => 'user', + 'filter_value' => 'admin', + 'liste' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportPushedDocumentsFilterConf() + { + self::$DI['client']->request('POST', '/report/activity/documents/pushed', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'conf' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportPushedDocumentsGroupBy() + { + self::$DI['client']->request('POST', '/report/activity/documents/pushed', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'groupby' => 'user', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportAddedDocuments() + { + self::$DI['client']->request('POST', '/report/activity/documents/added', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'order' => 'ASC', + 'champ' => 'user', + 'page' => 1, + 'limit' => 10, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportAddedDocumentsPrintCSV() + { + self::$DI['client']->request('POST', '/report/activity/documents/added', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportAddedDocumentsFilterColumns() + { + self::$DI['client']->request('POST', '/report/activity/documents/added', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'list_column' => 'user ddate', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportAddedDocumentsFilterResultOnOneColumn() + { + self::$DI['client']->request('POST', '/report/activity/documents/added', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'filter_column' => 'user', + 'filter_value' => 'admin', + 'liste' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportAddedDocumentsFilterConf() + { + self::$DI['client']->request('POST', '/report/activity/documents/added', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'conf' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportAddedDocumentsGroupBy() + { + self::$DI['client']->request('POST', '/report/activity/documents/added', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'groupby' => 'user', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportEditedDocuments() + { + self::$DI['client']->request('POST', '/report/activity/documents/edited', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'order' => 'ASC', + 'champ' => 'user', + 'page' => 1, + 'limit' => 10, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportEditedDocumentsPrintCSV() + { + self::$DI['client']->request('POST', '/report/activity/documents/edited', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportEditedDocumentsFilterColumns() + { + self::$DI['client']->request('POST', '/report/activity/documents/edited', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'list_column' => 'user ddate', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportEditedDocumentsFilterResultOnOneColumn() + { + self::$DI['client']->request('POST', '/report/activity/documents/edited', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'filter_column' => 'user', + 'filter_value' => 'admin', + 'liste' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportEditedDocumentsFilterConf() + { + self::$DI['client']->request('POST', '/report/activity/documents/edited', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'conf' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportEditedDocumentsGroupBy() + { + self::$DI['client']->request('POST', '/report/activity/documents/edited', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'groupby' => 'user', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportValidatedDocuments() + { + self::$DI['client']->request('POST', '/report/activity/documents/validated', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'order' => 'ASC', + 'champ' => 'user', + 'page' => 1, + 'limit' => 10, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportValidatedDocumentsPrintCSV() + { + self::$DI['client']->request('POST', '/report/activity/documents/validated', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'printcsv' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportValidatedDocumentsFilterColumns() + { + self::$DI['client']->request('POST', '/report/activity/documents/validated', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'list_column' => 'user ddate', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportValidatedDocumentsFilterResultOnOneColumn() + { + self::$DI['client']->request('POST', '/report/activity/documents/validated', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'filter_column' => 'user', + 'filter_value' => 'admin', + 'liste' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportValidatedDocumentsFilterConf() + { + self::$DI['client']->request('POST', '/report/activity/documents/validated', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'conf' => 'on', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportValidatedDocumentsGroupBy() + { + self::$DI['client']->request('POST', '/report/activity/documents/validated', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'groupby' => 'user', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportUserBadRequest() + { + self::$DI['client']->request('POST', '/report/informations/user', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertFalse($response->isOk()); + $this->assertEquals(400, $response->getStatusCode()); + } + + public function testDoReportUser() + { + self::$DI['client']->request('POST', '/report/informations/user', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'user' => self::$DI['user']->get_id(), + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportUserFromConnexion() + { + self::$DI['client']->request('POST', '/report/informations/user', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'user' => self::$DI['user']->get_id(), + 'from' => 'CNX', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportUserFromQuestion() + { + self::$DI['client']->request('POST', '/report/informations/user', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'from' => 'ASK', + 'user' => self::$DI['user']->get_id(), + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportUserFromDownload() + { + self::$DI['client']->request('POST', '/report/informations/user', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'from' => 'GEN', + 'user' => self::$DI['user']->get_id(), + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportUserFromConnexionCSV() + { + self::$DI['client']->request('POST', '/report/informations/user', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'from' => 'CNX', + 'printcsv' => 'on', + 'user' => self::$DI['user']->get_id(), + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportUserFromQuestionCSV() + { + self::$DI['client']->request('POST', '/report/informations/user', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'from' => 'ASK', + 'printcsv' => 'on', + 'user' => self::$DI['user']->get_id(), + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportUserFromDownloadCSV() + { + self::$DI['client']->request('POST', '/report/informations/user', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'from' => 'GEN', + 'printcsv' => 'on', + 'user' => self::$DI['user']->get_id(), + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportUserFromDownloadOnCustomField() + { + self::$DI['client']->request('POST', '/report/informations/user', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'from' => 'GEN', + 'on' => 'usr_mail', + 'user' => self::$DI['user']->get_email() + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportUserFromConnexionOnCustomField() + { + self::$DI['client']->request('POST', '/report/informations/user', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'from' => 'CNX', + 'on' => 'usr_mail', + 'user' => self::$DI['user']->get_email() + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportUserFromQuestionOnCustomField() + { + self::$DI['client']->request('POST', '/report/informations/user', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'from' => 'ASK', + 'on' => 'usr_mail', + 'user' => self::$DI['user']->get_email() + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportInformationsBrowserBadRequest() + { + self::$DI['client']->request('POST', '/report/informations/browser', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertFalse($response->isOk()); + $this->assertEquals(400, $response->getStatusCode()); + } + + public function testDoReportInfomationsBrowser() + { + self::$DI['client']->request('POST', '/report/informations/browser', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'user' => 'chrome', + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportInfomationsDocumentsNotFound() + { + self::$DI['client']->request('POST', '/report/informations/document', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'sbasid' => 0, + 'rid' => 0, + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertFalse($response->isOk()); + $this->assertEquals(404, $response->getStatusCode()); + } + + public function testDoReportInfomationsDocuments() + { + self::$DI['client']->request('POST', '/report/informations/document', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'sbasid' => self::$DI['record_1']->get_sbas_id(), + 'rid' => self::$DI['record_1']->get_record_id(), + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportInfomationsDocumentsFromTool() + { + self::$DI['client']->request('POST', '/report/informations/document', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'sbasid' => self::$DI['record_1']->get_sbas_id(), + 'rid' => self::$DI['record_1']->get_record_id(), + 'from' => 'TOOL' + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportInfomationsDocumentsFromDashboard() + { + self::$DI['client']->request('POST', '/report/informations/document', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'sbasid' => self::$DI['record_1']->get_sbas_id(), + 'rid' => self::$DI['record_1']->get_record_id(), + 'from' => 'DASH' + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } + + public function testDoReportInfomationsDocumentsFromOther() + { + self::$DI['client']->request('POST', '/report/informations/document', array( + 'dmin' => $this->dmin->format('Y-m-d H:i:s'), + 'dmax' => $this->dmax->format('Y-m-d H:i:s'), + 'sbasid' => self::$DI['collection']->get_sbas_id(), + 'collection' => self::$DI['collection']->get_coll_id(), + 'sbasid' => self::$DI['record_1']->get_sbas_id(), + 'rid' => self::$DI['record_1']->get_record_id(), + 'user' => self::$DI['user']->get_id() + )); + + $response = self::$DI['client']->getResponse(); + + $this->assertTrue($response->isOk()); + } +} + diff --git a/www/.htaccess b/www/.htaccess index 0228de1fce..1b82266701 100644 --- a/www/.htaccess +++ b/www/.htaccess @@ -46,6 +46,8 @@ RewriteRule ^download/.*$ /index.php [L] RewriteRule ^session/.*$ /index.php [L] + RewriteRule ^report/.*$ /index.php [L] + RewriteRule ^client/.*$ /index.php [L] RewriteRule ^client/baskets.*$ /index.php [L] From 2a93a7739f8ab75bf8e4cd85c4175e37c2fc395e Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Thu, 14 Feb 2013 16:43:56 +0100 Subject: [PATCH 02/18] Add binding to report routes --- .../Phrasea/Controller/Report/Root.php | 60 ++++++++++++------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/Report/Root.php b/lib/Alchemy/Phrasea/Controller/Report/Root.php index 79b171e31b..9c4c805593 100644 --- a/lib/Alchemy/Phrasea/Controller/Report/Root.php +++ b/lib/Alchemy/Phrasea/Controller/Report/Root.php @@ -26,45 +26,65 @@ class Root implements ControllerProviderInterface $app['firewall']->requireAccessToModule('report'); }); - $controllers->get('/dashboard', $this->call('getDashboard')); + $controllers->get('/dashboard', $this->call('getDashboard')) + ->bind('report_dashboard'); - $controllers->post('/init', $this->call('initReport')); + $controllers->post('/init', $this->call('initReport')) + ->bind('report_init'); - $controllers->post('/connexions', $this->call('doReportConnexions')); + $controllers->post('/connexions', $this->call('doReportConnexions')) + ->bind('report_connexions'); - $controllers->post('/questions', $this->call('doReportQuestions')); + $controllers->post('/questions', $this->call('doReportQuestions')) + ->bind('report_questions'); - $controllers->post('/downloads', $this->call('doReportDownloads')); + $controllers->post('/downloads', $this->call('doReportDownloads')) + ->bind('report_downloads'); - $controllers->post('/documents', $this->call('doReportDocuments')); + $controllers->post('/documents', $this->call('doReportDocuments')) + ->bind('report_documents'); - $controllers->post('/clients', $this->call('doReportClients')); + $controllers->post('/clients', $this->call('doReportClients')) + ->bind('report_clients'); - $controllers->post('/activity/users/connexions', $this->call('doReportConnexionsByUsers')); + $controllers->post('/activity/users/connexions', $this->call('doReportConnexionsByUsers')) + ->bind('report_activity_users_connexions'); - $controllers->post('/activity/users/downloads', $this->call('doReportDownloadsByUsers')); + $controllers->post('/activity/users/downloads', $this->call('doReportDownloadsByUsers')) + ->bind('report_activity_users_downloads');; - $controllers->post('/activity/questions/best-of', $this->call('doReportBestOfQuestions')); + $controllers->post('/activity/questions/best-of', $this->call('doReportBestOfQuestions')) + ->bind('report_activity_questions_bestof'); - $controllers->post('/activity/questions/no-best-of', $this->call('doReportNoBestOfQuestions')); + $controllers->post('/activity/questions/no-best-of', $this->call('doReportNoBestOfQuestions')) + ->bind('report_activity_questions_nobestof'); - $controllers->post('/activity/instance/hours', $this->call('doReportSiteActiviyPerHours')); + $controllers->post('/activity/instance/hours', $this->call('doReportSiteActiviyPerHours')) + ->bind('report_activity_instance_hours'); - $controllers->post('/activity/instance/days', $this->call('doReportSiteActiviyPerDays')); + $controllers->post('/activity/instance/days', $this->call('doReportSiteActiviyPerDays')) + ->bind('report_activity_instance_days'); - $controllers->post('/activity/documents/pushed', $this->call('doReportPushedDocuments')); + $controllers->post('/activity/documents/pushed', $this->call('doReportPushedDocuments')) + ->bind('report_activity_documents_pushed'); - $controllers->post('/activity/documents/added', $this->call('doReportAddedDocuments')); + $controllers->post('/activity/documents/added', $this->call('doReportAddedDocuments')) + ->bind('report_activity_documents_added'); - $controllers->post('/activity/documents/edited', $this->call('doReportEditedDocuments')); + $controllers->post('/activity/documents/edited', $this->call('doReportEditedDocuments')) + ->bind('report_activity_documents_edited'); - $controllers->post('/activity/documents/validated', $this->call('doReportValidatedDocuments')); + $controllers->post('/activity/documents/validated', $this->call('doReportValidatedDocuments')) + ->bind('report_activity_documents_validated'); - $controllers->post('/informations/user', $this->call('doReportInformationsUser')); + $controllers->post('/informations/user', $this->call('doReportInformationsUser')) + ->bind('report_infomations_user'); - $controllers->post('/informations/browser', $this->call('doReportInformationsBrowser')); + $controllers->post('/informations/browser', $this->call('doReportInformationsBrowser')) + ->bind('report_infomations_browser'); - $controllers->post('/informations/document', $this->call('doReportInformationsDocument')); + $controllers->post('/informations/document', $this->call('doReportInformationsDocument')) + ->bind('report_infomations_document'); return $controllers; } From 6718d284c79f2eb39ad98b7047b652671d1f7a74 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Thu, 14 Feb 2013 17:03:16 +0100 Subject: [PATCH 03/18] Add Slash controller --- lib/Alchemy/Phrasea/Controller/Report/Root.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Alchemy/Phrasea/Controller/Report/Root.php b/lib/Alchemy/Phrasea/Controller/Report/Root.php index 9c4c805593..f4b8980765 100644 --- a/lib/Alchemy/Phrasea/Controller/Report/Root.php +++ b/lib/Alchemy/Phrasea/Controller/Report/Root.php @@ -26,6 +26,10 @@ class Root implements ControllerProviderInterface $app['firewall']->requireAccessToModule('report'); }); + $controllers->get('/', function(Application $app) { + return $app->redirect($app->path('report_dashboard')); + })->bind('report'); + $controllers->get('/dashboard', $this->call('getDashboard')) ->bind('report_dashboard'); From 6b662710d7d90f1f8ba841319148331a44aece5f Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Thu, 14 Feb 2013 20:09:50 +0100 Subject: [PATCH 04/18] Change report link in main menu bar --- templates/web/common/menubar.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/web/common/menubar.html.twig b/templates/web/common/menubar.html.twig index 1aaea4f260..993959f275 100644 --- a/templates/web/common/menubar.html.twig +++ b/templates/web/common/menubar.html.twig @@ -58,7 +58,7 @@ {# MODULE #} {% if app['phraseanet.user'].ACL.has_access_to_module('report') %}
  • - + {% trans 'admin::monitor: module report' %} From c5d48e8df1a776795c04c826e804a588bec503cd Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Thu, 14 Feb 2013 20:10:13 +0100 Subject: [PATCH 05/18] Move report images to skins --- www/skins/report/img/arrow_down.png | Bin 0 -> 1042 bytes www/skins/report/img/arrow_up.png | Bin 0 -> 992 bytes www/skins/report/img/checkbox_checked.png | Bin 0 -> 3339 bytes www/skins/report/img/checkbox_unchecked.png | Bin 0 -> 3124 bytes www/skins/report/img/config.png | Bin 0 -> 1308 bytes www/skins/report/img/csv.gif | Bin 0 -> 2899 bytes www/skins/report/img/favicon.ico | Bin 0 -> 1406 bytes www/skins/report/img/filter.png | Bin 0 -> 1267 bytes www/skins/report/img/filter_on.png | Bin 0 -> 3078 bytes www/skins/report/img/group.png | Bin 0 -> 1204 bytes www/skins/report/img/loupe2.png | Bin 0 -> 1586 bytes www/skins/report/img/noresults.png | Bin 0 -> 5600 bytes www/skins/report/img/print.png | Bin 0 -> 1194 bytes www/skins/report/img/white-arrow.gif | Bin 0 -> 185 bytes 14 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 www/skins/report/img/arrow_down.png create mode 100644 www/skins/report/img/arrow_up.png create mode 100644 www/skins/report/img/checkbox_checked.png create mode 100644 www/skins/report/img/checkbox_unchecked.png create mode 100644 www/skins/report/img/config.png create mode 100644 www/skins/report/img/csv.gif create mode 100644 www/skins/report/img/favicon.ico create mode 100644 www/skins/report/img/filter.png create mode 100644 www/skins/report/img/filter_on.png create mode 100644 www/skins/report/img/group.png create mode 100644 www/skins/report/img/loupe2.png create mode 100644 www/skins/report/img/noresults.png create mode 100644 www/skins/report/img/print.png create mode 100644 www/skins/report/img/white-arrow.gif diff --git a/www/skins/report/img/arrow_down.png b/www/skins/report/img/arrow_down.png new file mode 100644 index 0000000000000000000000000000000000000000..e3e43ec2bd564dca850a252e5120ae246b851c60 GIT binary patch literal 1042 zcmV+t1nv8YP)4Tx0C)j~RL^S@K@|QrZmG~B2wH0nvUrdpNm;9CMbtL^5n^i$+aIn^?(HA4aZWV5ov6ELTdbo0FI&wK{O>*+w4vx20?>!`FrQsdJlnHR>OPy zcd~b_n$otK2Za4V;76L-DzNVtaSB-y0*E}{p()372;bw_^6ZZ}PI-92wGS&j#91PI zKs7DSe@(bk%_Y-7gGe}(^>I=@oY#w#*Bu9GZf3^F5WP>3rn}7Ut74&?PWBFvy`A)a zPP5)V!Xd&78LdA?xQ(9mjMYElVd13a#D+Z_7&Y|xU=_C-srWU*6kiZcC!$nw*)9$7 zn6CX+@=AhmkT}X@VSsa5NKe;HZuq)~1$`#h6R+ZTR#D-3j}vF!)ZOnz+5)dI4jl{{ z44Mr{P!L4~VVJN`K!!XTF*LGrKO?IK8z<8w`3e3jI8lUGNUta*C8 zn(P`s>{pjD=7Kek#B;Fw@hxAK%$F&Q6vg9J^Xf~4by_hu-=A!MJ3Znq&n~srbFGPs zH&&aMXZ>nO`|hf|ljc?VPhR!${AbO?W8x_>CU%PFA&Hm8F7cAsOREdwU~R_;ot1_u z(ruCYB-LPGn!NQdT|ZlRy+(fw^-+`=%+gee_kY4FWHg<*4sZI8+sFJD270UUORdLHO0nA4V) z%{fwsET5CQ>B?eK%uw4yQc~9?*JVo2}ze(;aRcp*ceL#HUJSllrgm5wQKR zQu+C;QrUh^8rFfA`ftFz{YAidi-`aL010qNS#tmY3ljhU3ljkVnw%H_007EKL_t(2 z6_t@u5`r)cM3cg$obf~PTHei{3YSvqzP3^1OEVJ^n%(SDyj-o=KLOg!(oY-#0oUj? zRXtupcUz-hH7AL#IMz)aaJ(HfcPqthP^TiGn`@pgb0c++t#o2OEtX2Lvu2&w2vTe z&fBfV0UKrGP3CB@0008+X+uL$Nkc;* zP;zf(X>4Tx0C)j~RL^S@K@|QrZmG~B2wH0nvUrdpNm;9CMbtL^5n^i$+aIn^?(HA4aZWV5ov6ELTdbo0FI&wK{O>*+w4vx20?>!`FrQsdJlnHR>OPy zcd~b_n$otK2Za4V;76L-DzNVtaSB-y0*E}{p()372;bw_^6ZZ}PI-92wGS&j#91PI zKs7DSe@(bk%_Y-7gGe}(^>I=@oY#w#*Bu9GZf3^F5WP>3rn}7Ut74&?PWBFvy`A)a zPP5)V!Xd&78LdA?xQ(9mjMYElVd13a#D+Z_7&Y|xU=_C-srWU*6kiZcC!$nw*)9$7 zn6CX+@=AhmkT}X@VSsa5NKe;HZuq)~1$`#h6R+ZTR#D-3j}vF!)ZOnz+5)dI4jl{{ z44Mr{P!L4~VVJN`K!!XTF*LGrKO?IK8z<8w`3e3jI8lUGNUta*C8 zn(P`s>{pjD=7Kek#B;Fw@hxAK%$F&Q6vg9J^Xf~4by_hu-=A!MJ3Znq&n~srbFGPs zH&&aMXZ>nO`|hf|ljc?VPhR!${AbO?W8x_>CU%PFA&Hm8F7cAsOREdwU~R_;ot1_u z(ruCYB-LPGn!NQdT|ZlRy+(fw^-+`=%+gee_kY4FWHg<*4sZI8+sFJD270UUORdLHO0nA4V) z%{fwsET5CQ>B?eK%uw4yQc~9?*JVo2}ze(;aRcp*ceL#HUJSllrgm5wQKR zQu+C;QrUh^8rFfA`ftFz{YAidi-`aL010qNS#tmY3ljhU3ljkVnw%H_005XtL_t(2 z6_rri4TCTYw5u#tlF_;vWv{A=dj~!V^+)&K^a>|k4VEJ;z^D#_&lunvQ8k!PbchTqS~sAS=~fO1ve^GBmV#sH!E|uF=%Q4 O0000($ literal 0 HcmV?d00001 diff --git a/www/skins/report/img/checkbox_checked.png b/www/skins/report/img/checkbox_checked.png new file mode 100644 index 0000000000000000000000000000000000000000..6a3a8d470f174f45f4c4347ecf785a601ae59656 GIT binary patch literal 3339 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 literal 0 HcmV?d00001 diff --git a/www/skins/report/img/checkbox_unchecked.png b/www/skins/report/img/checkbox_unchecked.png new file mode 100644 index 0000000000000000000000000000000000000000..e4ab2932a00bcc05b3be3b6f3fcadf00145370ff GIT binary patch literal 3124 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 xxho^Z5aRn002ovPDHLkV1o7#hll_G literal 0 HcmV?d00001 diff --git a/www/skins/report/img/favicon.ico b/www/skins/report/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..6490aa2c2f2764074ccb1bbb1bb4f15156f245d3 GIT binary patch literal 1406 zcmeH{OD_Xa7>3`OQf1J(-|v@JUD{VWnO@RnrXen2A+fQjbyq@TV}XdUaQ`iA@h`BD z_!ES%sqd79u(R%S^1a`4CYh6*Z*c%kmd}SGxpJUcEFh&m^-5{*NCLK2Y+v#1p->3n za2O;Ji9`^MMx{)crin?@f@N8VT1muWF(eWRB$G*uC8m)|rI1diVcRw=dj^i_ zf&WZE6G)X>KL<2T7f6+D4A$tnOCTjGM%XE>OdutCI8-jpEs*ZYj)_pKa*rTy3pv)V z)KeuC_Z)6gZV04dH1u*%d9^@F)NxdKtw2gNGpyVzkX~;~9|OvL!q<81R$ect{kXqN O=^q+@@t+y}{O1#XDoKn0 literal 0 HcmV?d00001 diff --git a/www/skins/report/img/filter.png b/www/skins/report/img/filter.png new file mode 100644 index 0000000000000000000000000000000000000000..3b65d5c1a73f9cbc4510d79b37b121f2f1b89904 GIT binary patch literal 1267 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 UMDELY?f?J)07*qoM6N<$g1ivfkN^Mx literal 0 HcmV?d00001 diff --git a/www/skins/report/img/group.png b/www/skins/report/img/group.png new file mode 100644 index 0000000000000000000000000000000000000000..002d00c83a930bb42a8ac86a87719a2ed521979e GIT binary patch literal 1204 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 literal 0 HcmV?d00001 diff --git a/www/skins/report/img/noresults.png b/www/skins/report/img/noresults.png new file mode 100644 index 0000000000000000000000000000000000000000..127eda87a9b80e94006e475262d4bcf95707cf7a GIT binary patch literal 5600 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 IM6N<$f}@W%+5i9m literal 0 HcmV?d00001 diff --git a/www/skins/report/img/white-arrow.gif b/www/skins/report/img/white-arrow.gif new file mode 100644 index 0000000000000000000000000000000000000000..19ecebb38e692dc2de356aeae36a302063880f3c GIT binary patch literal 185 zcmV;q07m~uNk%w1VHf~L0J9GO{M)7e^yK{As{77`{p-#6usQdpAo#RH`M_fN!DINX zGynbi{_@`a=D+{{|M#UHA^8LW000jFEC2ui02ly9000DL@X2?kz1SL8vd4`ReB`4z zXi|C%>MSdUxabgDw0lcJjuN||2S6+qg~+6G$!t2G(5Q4uty-_xtai)odcWYXcuX#v n&*=2i$nFw+4nYtu9OMwlg^Q6)xD-kO4h>5M4hBpWND%-#f%#ek literal 0 HcmV?d00001 From e8461b87737257e3fbc6a75ea70ee733cf145f1f Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Thu, 14 Feb 2013 20:10:55 +0100 Subject: [PATCH 06/18] Bind ajax request to new report Path && fix some minor issues --- .../web/report/ajax_data_content.html.twig | 5 ++- .../web/report/ajax_report_content.html.twig | 1 + templates/web/report/generate_tab.html.twig | 12 +++---- templates/web/report/listColumn.html.twig | 4 +-- .../web/report/report_layout_child.html.twig | 36 +++++++++---------- www/report/report.js | 29 ++++++++------- 6 files changed, 46 insertions(+), 41 deletions(-) diff --git a/templates/web/report/ajax_data_content.html.twig b/templates/web/report/ajax_data_content.html.twig index e9548f3ce2..e9dad19e6d 100644 --- a/templates/web/report/ajax_data_content.html.twig +++ b/templates/web/report/ajax_data_content.html.twig @@ -27,9 +27,9 @@