diff --git a/lib/Alchemy/Phrasea/Application/Root.php b/lib/Alchemy/Phrasea/Application/Root.php
index 88e3e5bad4..41a5daad95 100644
--- a/lib/Alchemy/Phrasea/Application/Root.php
+++ b/lib/Alchemy/Phrasea/Application/Root.php
@@ -35,6 +35,7 @@ use Alchemy\Phrasea\Controller\Admin\Users;
use Alchemy\Phrasea\Controller\Prod\Basket;
use Alchemy\Phrasea\Controller\Prod\Bridge;
use Alchemy\Phrasea\Controller\Prod\Edit;
+use Alchemy\Phrasea\Controller\Prod\Export;
use Alchemy\Phrasea\Controller\Prod\Feed;
use Alchemy\Phrasea\Controller\Prod\Language;
use Alchemy\Phrasea\Controller\Prod\Lazaret;
@@ -51,11 +52,12 @@ use Alchemy\Phrasea\Controller\Prod\Tools;
use Alchemy\Phrasea\Controller\Prod\Tooltip;
use Alchemy\Phrasea\Controller\Prod\TOU;
use Alchemy\Phrasea\Controller\Prod\Upload;
-use Alchemy\Phrasea\Controller\Prod\UserPreferences;
use Alchemy\Phrasea\Controller\Prod\UsrLists;
use Alchemy\Phrasea\Controller\Prod\WorkZone;
use Alchemy\Phrasea\Controller\Utils\ConnectionTest;
use Alchemy\Phrasea\Controller\Utils\PathFileTest;
+use Alchemy\Phrasea\Controller\User\Notifications;
+use Alchemy\Phrasea\Controller\User\Preferences;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -127,7 +129,6 @@ return call_user_func(function($environment = null) {
$app->mount('/admin/tests/connection', new ConnectionTest());
$app->mount('/admin/tests/pathurl', new PathFileTest());
- $app->mount('/prod/UserPreferences/', new UserPreferences());
$app->mount('/prod/query/', new Query());
$app->mount('/prod/order/', new Order());
$app->mount('/prod/baskets', new Basket());
@@ -141,6 +142,8 @@ return call_user_func(function($environment = null) {
$app->mount('/prod/bridge/', new Bridge());
$app->mount('/prod/push/', new Push());
$app->mount('/prod/printer/', new Printer());
+ $app->mount('/prod/share/', new Share());
+ $app->mount('/prod/export/', new Export());
$app->mount('/prod/TOU/', new TOU());
$app->mount('/prod/feeds', new Feed());
$app->mount('/prod/tooltip', new Tooltip());
@@ -150,6 +153,9 @@ return call_user_func(function($environment = null) {
$app->mount('/prod/upload/', new Upload());
$app->mount('/prod/', new Prod());
+ $app->mount('/user/preferences/', new Preferences());
+ $app->mount('/user/notifications/', new Notifications());
+
$app->error(function(\Exception $e) use ($app) {
$request = $app['request'];
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Export.php b/lib/Alchemy/Phrasea/Controller/Prod/Export.php
new file mode 100644
index 0000000000..730e9a3ee3
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Export.php
@@ -0,0 +1,296 @@
+before(function(Request $request) use ($app) {
+ $app['firewall']->requireNotGuest();
+ });
+
+ /**
+ * Display multi export
+ *
+ * name : export_multi_export
+ *
+ * description : Display multi export
+ *
+ * method : POST
+ *
+ * parameters : none
+ *
+ * return : HTML Response
+ */
+ $controllers->post('/multi-export/', $this->call('displayMultiExport'))
+ ->bind('export_multi_export');
+
+ /**
+ * Export by mail
+ *
+ * name : export_mail
+ *
+ * description : Export by mail
+ *
+ * method : POST
+ *
+ * parameters : none
+ *
+ * return : JSON Response
+ */
+ $controllers->post('/mail/', $this->call('exportMail'))
+ ->bind('export_mail');
+
+ /**
+ * Export by FTP
+ *
+ * name : export_ftp
+ *
+ * description : Export by FTP
+ *
+ * method : POST
+ *
+ * parameters : none
+ *
+ * return : JSON Response
+ */
+ $controllers->post('/ftp/', $this->call('exportFtp'))
+ ->bind('export_ftp');
+
+ /**
+ * Test FTP connexion
+ *
+ * name : export_ftp_test
+ *
+ * description : Test a FTP connexion
+ *
+ * method : POST
+ *
+ * parameters : none
+ *
+ * return : JSON Response
+ */
+ $controllers->post('/ftp/test/', $this->call('testFtpConnexion'))
+ ->bind('export_ftp_test');
+
+ return $controllers;
+ }
+
+ /**
+ * Display form to export documents
+ *
+ * @param Application $app
+ * @param Request $request
+ * @return Response
+ */
+ public function displayMultiExport(Application $app, Request $request)
+ {
+ $download = new \set_export($app, $request->request->get('lst', ''), (int) $request->request->get('ssel'), $request->request->get('story'));
+
+ return new Response($app['twig']->render('common/dialog_export.html.twig', array(
+ 'download' => $download,
+ 'ssttid' => $request->request->get('ssel'),
+ 'lst' => $download->serialize_list(),
+ 'default_export_title' => $app['phraseanet.registry']->get('GV_default_export_title'),
+ 'choose_export_title' => $app['phraseanet.registry']->get('GV_choose_export_title')
+ )));
+ }
+
+ /**
+ * Test a FTP connexion
+ *
+ * @param Application $app
+ * @param Request $request
+ * @return JsonResponse
+ */
+ public function testFtpConnexion(Application $app, Request $request)
+ {
+ if (!$request->isXmlHttpRequest()) {
+ $app->abort(400);
+ }
+
+ $success = false;
+ try {
+ $ftpClient = $app['phraseanet.ftp.client']($request->request->get('addr', ''), 21, 90, !!$request->request->get('ssl'));
+ $ftpClient->login($request->request->get('login', ''), $request->request->get('pwd', ''));
+ $ftpClient->close();
+ $msg = _('Connection to FTP succeed');
+ $success = true;
+ } catch (Exception $e) {
+ $msg = sprintf(_('Error while connecting to FTP'));
+ }
+
+ return $app->json(array(
+ 'success' => $success,
+ 'message' => $msg
+ ));
+ }
+
+ /**
+ *
+ * @param Application $app
+ * @param Request $request
+ * @return JsonResponse
+ */
+ public function exportFtp(Application $app, Request $request)
+ {
+ $download = new \set_exportftp($app, $request->request->get('lst'), $request->request->get('ssttid'));
+
+ if (null === $address = $request->request->get('addr')) {
+ $app->abort(400, _('Missing ftp adress'));
+ }
+
+ if (null === $login = $request->request->get('login')) {
+ $app->abort(400, _('Missing ftp lofin'));
+ }
+
+ if (null === $destFolder = $request->request->get('destfolder')) {
+ $app->abort(400, _('Missing destination folder'));
+ }
+
+ if (null === $folderTocreate = $request->request->get('NAMMKDFOLD')) {
+ $app->abort(400, _('Missing folder to create'));
+ }
+
+ if (null === $subdefs = $request->request->get('obj')) {
+ $app->abort(400, _('Missing subdefs to export'));
+ }
+
+ if (count($download->get_display_ftp()) == 0) {
+
+ return $app->json(array('success' => false, 'message' => _('Documents can be sent by FTP')));
+ } else {
+ try {
+ $download->prepare_export($app['phraseanet.user'], $app['filesystem'], $request->request->get('obj'), false, $request->request->get('businessfields'));
+ $download->export_ftp($request->request->get('user_dest'), $address, $login, $request->request->get('pwd', ''), $request->request->get('ssl'), $request->request->get('nbretry'), $request->request->get('passif'), $destFolder, $folderTocreate, $request->request->get('logfile'));
+
+ return $app->json(array(
+ 'success' => true,
+ 'message' => _('Export saved in the waiting queue')
+ ));
+ } catch (Exception $e) {
+
+ return $app->json(array(
+ 'success' => false,
+ 'message' => _('Something gone wrong')
+ ));
+ }
+ }
+ }
+
+ public function exportMail(Application $app, Request $request)
+ {
+ set_time_limit(0);
+ session_write_close();
+ ignore_user_abort(true);
+
+ //prepare export
+ $download = new \set_export($app, $request->get('lst', ''), $request->get('ssttid', ''));
+ $list = $download->prepare_export($app['phraseanet.user'], $app['filesystem'], $request->get('obj'), $request->get("type") == "title" ? : false, $request->get('businessfields'));
+ $list['export_name'] = sprintf("%s.zip", $download->getExportName());
+ $list['email'] = $request->get("destmail", "");
+
+ $destMails = array();
+ //get destination mails
+ foreach (explode(";", $list['email']) as $mail) {
+ if (filter_var($mail, FILTER_VALIDATE_EMAIL)) {
+ $destMails[] = $mail;
+ } else {
+ $app['events-manager']->trigger('__EXPORT_MAIL_FAIL__', array(
+ 'usr_id' => $app['phraseanet.user']->get_id(),
+ 'lst' => $request->get('lst', ''),
+ 'ssttid' => $request->get('ssttid', ''),
+ 'dest' => $mail,
+ 'reason' => \eventsmanager_notify_downloadmailfail::MAIL_NO_VALID
+ ));
+ }
+ }
+
+ //generate validation token
+ $endDateObject = new \DateTime('+1 day');
+ $token = \random::getUrlToken($app, \random::TYPE_EMAIL, false, $endDateObject, serialize($list));
+
+ if (count($destMails) > 0 && $token) {
+ //zip documents
+ \set_export::build_zip(new Filesystem(), $token, $list, $app['phraseanet.registry']->get('GV_RootPath') . 'tmp/download/' . $token . '.zip');
+
+ $remaingEmails = $destMails;
+
+ $url = $app['phraseanet.registry']->get('GV_ServerName') . 'mail-export/' . $token . '/';
+
+ $from = array(
+ 'name' => $app['phraseanet.user']->get_display_name(),
+ 'email' => $app['phraseanet.user']->get_email()
+ );
+
+ //send mails
+ foreach ($destMails as $key => $mail) {
+ if (\mail::send_documents($app, trim($mail), $url, $from, $endDateObject, $request->get('textmail'), $request->get('reading_confirm') == '1' ? : false)) {
+ unset($remaingEmails[$key]);
+ }
+ }
+
+ //some mails failed
+ if (count($remaingEmails) > 0) {
+ foreach ($remaingEmails as $mail) {
+ $app['events-manager']->trigger('__EXPORT_MAIL_FAIL__', array(
+ 'usr_id' => $app['phraseanet.user']->get_id(),
+ 'lst' => $request->get('lst', ''),
+ 'ssttid' => $request->get('ssttid', ''),
+ 'dest' => $mail,
+ 'reason' => \eventsmanager_notify_downloadmailfail::MAIL_FAIL
+ ));
+ }
+ }
+ } elseif (!$token && count($destMails) > 0) { //couldn't generate token
+ foreach ($destMails as $mail) {
+ $app['events-manager']->trigger('__EXPORT_MAIL_FAIL__', array(
+ 'usr_id' => $app['phraseanet.user']->get_id(),
+ 'lst' => $request->get('lst', ''),
+ 'ssttid' => $request->get('ssttid', ''),
+ 'dest' => $mail,
+ 'reason' => 0
+ ));
+ }
+ }
+ }
+
+ /**
+ * 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/Alchemy/Phrasea/Controller/Prod/Language.php b/lib/Alchemy/Phrasea/Controller/Prod/Language.php
index 0266f05e61..941f952ba6 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Language.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Language.php
@@ -101,6 +101,7 @@ class Language implements ControllerProviderInterface
$out['feedbackCanContribute'] = _('User contribute to the feedback');
$out['feedbackCanSeeOthers'] = _('User can see others choices');
$out['forceSendDocument'] = _('Force sending of the document ?');
+ $out['export'] = _('Export');
return $app->json($out);
});
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Query.php b/lib/Alchemy/Phrasea/Controller/Prod/Query.php
index 9975c4b7c3..65e17a9a73 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Query.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Query.php
@@ -13,7 +13,9 @@ namespace Alchemy\Phrasea\Controller\Prod;
use Silex\Application;
use Silex\ControllerProviderInterface;
+use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
/**
*
@@ -28,180 +30,252 @@ class Query implements ControllerProviderInterface
$controllers = $app['controllers_factory'];
$controllers->before(function(Request $request) use ($app) {
- $app['firewall']->requireAuthentication();
- });
+ $app['firewall']->requireAuthentication();
+ });
- $controllers->post('/', function(Application $app, Request $request) {
- $query = (string) $request->request->get('qry');
+ $controllers->post('/', $this->call('query'))
+ ->bind('prod_query');
+
+ $controllers->post('/answer-train/', $this->call('queryAnswerTrain'))
+ ->bind('preview_answer_train');
- $mod = $app['phraseanet.user']->getPrefs('view');
+ $controllers->post('/reg-train/', $this->call('queryRegTrain'))
+ ->bind('preview_reg_train');
- $json = array();
+ return $controllers;
+ }
- $options = new \searchEngine_options();
+ /**
+ * Query Phraseanet to fetch records
+ *
+ * @param Application $app
+ * @param Request $request
+ * @return JsonResponse
+ */
+ public function query(Application $app, Request $request)
+ {
+ $query = (string) $request->request->get('qry');
- $bas = is_array($request->request->get('bas')) ? $request->request->get('bas') : array_keys($user->ACL()->get_granted_base());
+ $mod = $app['phraseanet.user']->getPrefs('view');
- if ($app['phraseanet.user']->ACL()->has_right('modifyrecord')) {
- $options->set_business_fields(array());
+ $json = array();
- $BF = array();
+ $options = new \searchEngine_options();
- foreach ($app['phraseanet.user']->ACL()->get_granted_base(array('canmodifrecord')) as $collection) {
- if (count($bas) === 0 || in_array($collection->get_base_id(), $bas)) {
- $BF[] = $collection->get_base_id();
- }
+ $bas = is_array($request->request->get('bas')) ? $request->request->get('bas') : array_keys($user->ACL()->get_granted_base());
+
+ if ($app['phraseanet.user']->ACL()->has_right('modifyrecord')) {
+ $options->set_business_fields(array());
+
+ $BF = array();
+
+ foreach ($app['phraseanet.user']->ACL()->get_granted_base(array('canmodifrecord')) as $collection) {
+ if (count($bas) === 0 || in_array($collection->get_base_id(), $bas)) {
+ $BF[] = $collection->get_base_id();
}
- $options->set_business_fields($BF);
- } else {
- $options->set_business_fields(array());
}
+ $options->set_business_fields($BF);
+ } else {
+ $options->set_business_fields(array());
+ }
- $status = is_array($request->request->get('status')) ? $request->request->get('status') : array();
- $fields = is_array($request->request->get('fields')) ? $request->request->get('fields') : array();
+ $status = is_array($request->request->get('status')) ? $request->request->get('status') : array();
+ $fields = is_array($request->request->get('fields')) ? $request->request->get('fields') : array();
- $options->set_fields($fields);
- $options->set_status($status);
- $options->set_bases($bas, $app['phraseanet.user']->ACL());
+ $options->set_fields($fields);
+ $options->set_status($status);
+ $options->set_bases($bas, $app['phraseanet.user']->ACL());
- $options->set_search_type($request->request->get('search_type'));
- $options->set_record_type($request->request->get('recordtype'));
- $options->set_min_date($request->request->get('datemin'));
- $options->set_max_date($request->request->get('datemax'));
- $options->set_date_fields(explode('|', $request->request->get('datefield')));
- $options->set_sort($request->request->get('sort'), $request->request->get('ord', PHRASEA_ORDER_DESC));
- $options->set_use_stemming($request->request->get('stemme'));
+ $options->set_search_type($request->request->get('search_type'));
+ $options->set_record_type($request->request->get('recordtype'));
+ $options->set_min_date($request->request->get('datemin'));
+ $options->set_max_date($request->request->get('datemax'));
+ $options->set_date_fields(explode('|', $request->request->get('datefield')));
+ $options->set_sort($request->request->get('sort'), $request->request->get('ord', PHRASEA_ORDER_DESC));
+ $options->set_use_stemming($request->request->get('stemme'));
- $form = serialize($options);
+ $form = serialize($options);
- $perPage = (int) $app['phraseanet.user']->getPrefs('images_per_page');
+ $perPage = (int) $app['phraseanet.user']->getPrefs('images_per_page');
- $search_engine = new \searchEngine_adapter($app);
- $search_engine->set_options($options);
+ $search_engine = new \searchEngine_adapter($app);
+ $search_engine->set_options($options);
- $page = (int) $request->request->get('pag');
+ $page = (int) $request->request->get('pag');
- if ($page < 1) {
- $search_engine->set_is_first_page(true);
- $search_engine->reset_cache();
- $page = 1;
- }
+ if ($page < 1) {
+ $search_engine->set_is_first_page(true);
+ $search_engine->reset_cache();
+ $page = 1;
+ }
- $result = $search_engine->query_per_page($query, $page, $perPage);
+ $result = $search_engine->query_per_page($query, $page, $perPage);
- $proposals = $search_engine->is_first_page() ? $result->get_propositions() : false;
+ $proposals = $search_engine->is_first_page() ? $result->get_propositions() : false;
- $npages = $result->get_total_pages();
+ $npages = $result->get_total_pages();
- $page = $result->get_current_page();
+ $page = $result->get_current_page();
- $string = '';
+ $string = '';
- if ($npages > 1) {
+ if ($npages > 1) {
- $d2top = ($npages - $page);
- $d2bottom = $page;
+ $d2top = ($npages - $page);
+ $d2bottom = $page;
- if (min($d2top, $d2bottom) < 4) {
- if ($d2bottom < 4) {
- for ($i = 1; ($i <= 4 && (($i <= $npages) === true)); $i++) {
- if ($i == $page)
- $string .= '';
- else
- $string .= "" . $i . "";
- }
- if ($npages > 4)
- $string .= ">>";
- } else {
- $start = $npages - 4;
- if (($start) > 0)
- $string .= "<<";
- else
- $start = 1;
- for ($i = ($start); $i <= $npages; $i++) {
- if ($i == $page)
- $string .= '';
- else
- $string .= "" . $i . "";
- }
- }
- } else {
- $string .= "<<";
-
- for ($i = ($page - 2); $i <= ($page + 2); $i++) {
+ if (min($d2top, $d2bottom) < 4) {
+ if ($d2bottom < 4) {
+ for ($i = 1; ($i <= 4 && (($i <= $npages) === true)); $i++) {
+ if ($i == $page)
+ $string .= '';
+ else
+ $string .= "" . $i . "";
+ }
+ if ($npages > 4)
+ $string .= ">>";
+ } else {
+ $start = $npages - 4;
+ if (($start) > 0)
+ $string .= "<<";
+ else
+ $start = 1;
+ for ($i = ($start); $i <= $npages; $i++) {
if ($i == $page)
$string .= '';
else
$string .= "" . $i . "";
}
-
- $string .= ">>";
}
- }
- $string .= '
';
-
- $explain = "";
-
- $explain .= "
";
-
- if ($result->get_count_total_results() != $result->get_count_available_results()) {
- $explain .= sprintf(_('reponses:: %d Resultats rappatries sur un total de %d trouves'), $result->get_count_available_results(), $result->get_count_total_results());
} else {
- $explain .= sprintf(_('reponses:: %d Resultats'), $result->get_count_total_results());
+ $string .= "<<";
+
+ for ($i = ($page - 2); $i <= ($page + 2); $i++) {
+ if ($i == $page)
+ $string .= '';
+ else
+ $string .= "" . $i . "";
+ }
+
+ $string .= ">>";
}
+ }
+ $string .= '';
- $explain .= " ";
- $explain .= '
' . $result->get_query_time() . ' s
dans index ' . $result->get_search_indexes();
- $explain .= "
";
+ $explain = "";
- $infoResult = '
' . sprintf(_('reponses:: %d reponses'), $result->get_count_total_results()) . ' | ' . sprintf(_('reponses:: %s documents selectionnes'), '
');
+ $explain .= "
";
- $json['infos'] = $infoResult;
- $json['navigation'] = $string;
+ if ($result->get_count_total_results() != $result->get_count_available_results()) {
+ $explain .= sprintf(_('reponses:: %d Resultats rappatries sur un total de %d trouves'), $result->get_count_available_results(), $result->get_count_total_results());
+ } else {
+ $explain .= sprintf(_('reponses:: %d Resultats'), $result->get_count_total_results());
+ }
- $prop = null;
+ $explain .= " ";
+ $explain .= '
' . $result->get_query_time() . ' s
dans index ' . $result->get_search_indexes();
+ $explain .= "
";
- if ($search_engine->is_first_page()) {
- $propals = $result->get_suggestions($app['locale.I18n']);
- if (count($propals) > 0) {
- foreach ($propals as $prop_array) {
- if ($prop_array['value'] !== $query && $prop_array['hits'] > $result->get_count_total_results()) {
- $prop = $prop_array['value'];
- break;
- }
+ $infoResult = '' . sprintf(_('reponses:: %d reponses'), $result->get_count_total_results()) . ' | ' . sprintf(_('reponses:: %s documents selectionnes'), '');
+
+ $json['infos'] = $infoResult;
+ $json['navigation'] = $string;
+
+ $prop = null;
+
+ if ($search_engine->is_first_page()) {
+ $propals = $result->get_suggestions($app['locale.I18n']);
+ if (count($propals) > 0) {
+ foreach ($propals as $prop_array) {
+ if ($prop_array['value'] !== $query && $prop_array['hits'] > $result->get_count_total_results()) {
+ $prop = $prop_array['value'];
+ break;
}
}
}
+ }
- if ($result->get_count_total_results() === 0) {
- $template = 'prod/results/help.html.twig';
+ if ($result->get_count_total_results() === 0) {
+ $template = 'prod/results/help.html.twig';
+ } else {
+ if ($mod == 'thumbs') {
+ $template = 'prod/results/answergrid.html.twig';
} else {
- if ($mod == 'thumbs') {
- $template = 'prod/results/answergrid.html.twig';
- } else {
- $template = 'prod/results/answerlist.html.twig';
- }
+ $template = 'prod/results/answerlist.html.twig';
}
+ }
- $json['results'] = $app['twig']->render($template, array(
- 'results' => $result,
- 'GV_social_tools' => $app['phraseanet.registry']->get('GV_social_tools'),
- 'highlight' => $search_engine->get_query(),
- 'searchEngine' => $search_engine,
- 'suggestions' => $prop
- )
- );
+ $json['results'] = $app['twig']->render($template, array(
+ 'results' => $result,
+ 'GV_social_tools' => $app['phraseanet.registry']->get('GV_social_tools'),
+ 'highlight' => $search_engine->get_query(),
+ 'searchEngine' => $search_engine,
+ 'suggestions' => $prop
+ )
+ );
- $json['query'] = $query;
- $json['phrasea_props'] = $proposals;
- $json['total_answers'] = (int) $result->get_count_available_results();
- $json['next_page'] = ($page < $npages && $result->get_count_available_results() > 0) ? ($page + 1) : false;
- $json['prev_page'] = ($page > 1 && $result->get_count_available_results() > 0) ? ($page - 1) : false;
- $json['form'] = $form;
+ $json['query'] = $query;
+ $json['phrasea_props'] = $proposals;
+ $json['total_answers'] = (int) $result->get_count_available_results();
+ $json['next_page'] = ($page < $npages && $result->get_count_available_results() > 0) ? ($page + 1) : false;
+ $json['prev_page'] = ($page > 1 && $result->get_count_available_results() > 0) ? ($page - 1) : false;
+ $json['form'] = $form;
- return $app->json($json);
- });
+ return $app->json($json);
+ }
- return $controllers;
+ /**
+ *
+ * @param Application $app
+ * @param Request $request
+ * @return JsonResponse
+ */
+ public function queryAnswerTrain(Application $app, Request $request)
+ {
+ $searchEngine = null;
+
+ if (($options = unserialize($request->request->get('options_serial'))) !== false) {
+ $searchEngine = new \searchEngine_adapter($app);
+ $searchEngine->set_options($options);
+ }
+
+ $pos = $request->request->get('pos');
+ $query = $request->request->get('query');
+
+ $record = new \record_preview($app, 'RESULT', $pos, '', '', $searchEngine, $query);
+
+ return $app->json(array(
+ 'current' => $app['twig']->render('prod/preview/result_train.html.twig', array(
+ 'records' => $record->get_train($pos, $query, $searchEngine),
+ 'selected' => $pos
+ ))
+ ));
+ }
+
+ /**
+ *
+ * @param Application $app
+ * @param Request $request
+ * @return Response
+ */
+ public function queryRegTrain(Application $app, Request $request)
+ {
+ $record = new \record_preview($app, 'REG', $request->request->get('pos'), $request->request->get('cont'));
+
+ return $app['twig']->render('prod/preview/reg_train.html.twig', array(
+ 'container_records' => $record->get_container()->get_children(),
+ 'record' => $record
+ ));
+ }
+
+ /**
+ * 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/Alchemy/Phrasea/Controller/Prod/Record/Property.php b/lib/Alchemy/Phrasea/Controller/Prod/Record/Property.php
index 0e82a42461..654cae990a 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Record/Property.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Record/Property.php
@@ -14,6 +14,7 @@ namespace Alchemy\Phrasea\Controller\Prod\Record;
use Alchemy\Phrasea\Controller\RecordsRequest;
use Silex\Application;
use Silex\ControllerProviderInterface;
+use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -39,12 +40,54 @@ class Property implements ControllerProviderInterface
}
});
+ /**
+ * Display records property
+ *
+ * name : display_property
+ *
+ * description : Display records property
+ *
+ * method : GET
+ *
+ * parameters : none
+ *
+ * return : HTML Response
+ */
$controllers->get('/', $this->call('displayProperty'))
->bind('display_property');
+ /**
+ * Change records status
+ *
+ * name : change_status
+ *
+ * description : Change records status
+ *
+ * method : POST
+ *
+ * parameters : none
+ *
+ * return : JSON Response
+ */
$controllers->post('/status/', $this->call('changeStatus'))
->bind('change_status');
+ /**
+ * Change records type
+ *
+ * name : change_type
+ *
+ * description : Change records type
+ *
+ * method : POST
+ *
+ * parameters : none
+ *
+ * return : JSON Response
+ */
+ $controllers->post('/type/', $this->call('changeType'))
+ ->bind('change_type');
+
return $controllers;
}
@@ -69,20 +112,54 @@ class Property implements ControllerProviderInterface
if (!$app['phraseanet.user']->ACL()->has_hd_grant($record) ||
!$app['phraseanet.user']->ACL()->has_preview_grant($record)) {
try {
- $conn = $record->get_databox()->get_connection();
-
- $sql = sprintf('SELECT record_id FROM record WHERE ((status ^ %s) & %s) = 0 AND record_id = :record_id', $app['phraseanet.user']->ACL()->get_mask_xor($record->get_base_id()), $app['phraseanet.user']->ACL()->get_mask_and($record->get_base_id()));
-
- $stmt = $conn->prepare($sql);
+ $stmt = $record->get_databox()->get_connection()->prepare(sprintf('SELECT record_id FROM record WHERE ((status ^ %s) & %s) = 0 AND record_id = :record_id', $app['phraseanet.user']->ACL()->get_mask_xor($record->get_base_id()), $app['phraseanet.user']->ACL()->get_mask_and($record->get_base_id())));
$stmt->execute(array(':record_id' => $record->get_record_id()));
if (0 === $stmt->rowCount()) {
$toRemove[] = $key;
+ } else {
+ //perform logic
+ $sbasId = $record->get_databox()->get_sbas_id();
+
+ if (!isset($nRec[$sbasId])) {
+ $nRec[$sbasId] = array('stories' => 0, 'records' => 0);
+ }
+
+ $nRec[$sbasId]['records']++;
+
+ if ($record->is_grouping()) {
+ $nRec[$sbasId]['stories']++;
+ }
+
+ if (!isset($recordsType[$sbasId])) {
+ $recordsType[$sbasId] = array();
+ }
+
+ if (!isset($recordsType[$sbasId][$record->get_type()])) {
+ $recordsType[$sbasId][$record->get_type()] = array();
+ }
+
+ $recordsType[$sbasId][$record->get_type()][] = $record;
+
+ if (!isset($statusBit[$sbasId])) {
+
+ $statusBit[$sbasId] = isset($databoxStatus[$sbasId]) ? $databoxStatus[$sbasId] : array();
+
+ foreach (array_keys($statusBit[$sbasId]) as $bit) {
+ $statusBit[$sbasId][$bit]['nset'] = 0;
+ }
+ }
+
+ $status = strrev($record->get_status());
+
+ foreach (array_keys($statusBit[$sbasId]) as $bit) {
+ $statusBit[$sbasId][$bit]["nset"] += substr($status, $bit, 1) !== "0" ? 1 : 0;
+ }
}
$stmt->closeCursor();
unset($stmt);
- } catch (Exception $e) {
+ } catch (\Exception $e) {
$toRemove[] = $key;
}
}
@@ -92,45 +169,6 @@ class Property implements ControllerProviderInterface
$records->remove($key);
}
- foreach ($records as $record) {
- $sbasId = $record->get_databox()->get_sbas_id();
-
- if (!isset($nRec[$sbasId])) {
- $nRec[$sbasId] = array('stories' => 0, 'records' => 0);
- }
-
- $nRec[$sbasId]['records']++;
-
- if ($record->is_grouping()) {
- $nRec[$sbasId]['stories']++;
- }
-
- if (!isset($recordsType[$sbasId])) {
- $recordsType[$sbasId] = array();
- }
-
- if (!isset($recordsType[$sbasId][$record->get_type()])) {
- $recordsType[$sbasId][$record->get_type()] = array();
- }
-
- $recordsType[$sbasId][$record->get_type()] = $record;
-
- if (!isset($statusBit[$sbasId])) {
-
- $statusBit[$sbasId] = isset($databoxStatus[$sbasId]) ? $databoxStatus[$sbasId] : array();
-
- foreach (array_keys($statusBit[$sbasId]) as $bit) {
- $statusBit[$sbasId][$bit]['nset'] = 0;
- }
- }
-
- $status = strrev($record->get_status());
-
- foreach (array_keys($statusBit[$sbasId]) as $bit) {
- $statusBit[$sbasId][$bit]["nset"] += substr($status, $bit, 1) !== "0" ? 1 : 0;
- }
- }
-
foreach ($records->databoxes() as $databox) {
$sbasId = $databox->get_sbas_id();
foreach ($statusBit[$sbasId] as $bit => $values) {
@@ -138,14 +176,21 @@ class Property implements ControllerProviderInterface
}
}
- return $app['twig']->render('prod/actions/Property/index.html.twig', array(
+ return new Response($app['twig']->render('prod/actions/Property/index.html.twig', array(
'records' => $records,
'statusBit' => $statusBit,
'recordsType' => $recordsType,
'nRec' => $nRec
- ));
+ )));
}
+ /**
+ * Change record status
+ *
+ * @param Application $app
+ * @param Request $request
+ * @return JsonResponse
+ */
public function changeStatus(Application $app, Request $request)
{
$applyStatusToChildren = $request->request->get('apply_to_children', array());
@@ -157,12 +202,16 @@ class Property implements ControllerProviderInterface
$sbasId = $record->get_databox()->get_sbas_id();
//update record
- $updated[$record->get_serialize_key()] = $this->updateRecordStatus($record, $postStatus);
+ if (null !== $updatedStatus = $this->updateRecordStatus($record, $postStatus)) {
+ $updated[$record->get_serialize_key()] = $updatedStatus;
+ }
//update children if current record is a story
if (isset($applyStatusToChildren[$sbasId]) && $record->is_grouping()) {
foreach ($record->get_children() as $child) {
- $updated[$record->get_serialize_key()] = $this->updateRecordStatus($child, $postStatus);
+ if (null !== $updatedStatus = $this->updateRecordStatus($child, $postStatus)) {
+ $updated[$record->get_serialize_key()] = $updatedStatus;
+ }
}
}
}
@@ -170,6 +219,43 @@ class Property implements ControllerProviderInterface
return $app->json(array('success' => true, 'updated' => $updated), 201);
}
+ /**
+ * Change record type
+ *
+ * @param Application $app
+ * @param Request $request
+ * @return type
+ */
+ public function changeType(Application $app, Request $request)
+ {
+ $typeLst = $request->request('types', array());
+ $records = RecordsRequest::fromRequest($app, $request, false, array('modifyrecord'));
+ $forceType = $request->request('force_types', '');
+ $updated = array();
+
+ foreach ($records as $record) {
+ try {
+ $recordType = !empty($forceType) ? $forceType : (isset($typeLst[$record->get_serialize_key()]) ? $typeLst[$record->get_serialize_key()] : null);
+
+ if ($recordType) {
+ $record->setType($recordType);
+ $updated[$record->get_serialize_key()] = $recordType;
+ }
+ } catch (\Exception $e) {
+
+ }
+ }
+
+ return $app->json(array('success' => true, 'updated' => $updated), 201);
+ }
+
+ /**
+ * Set new status to selected record
+ *
+ * @param \record_adapter $record
+ * @param array $postStatus
+ * @return array|null
+ */
private function updateRecordStatus(\record_adapter $record, Array $postStatus)
{
$sbasId = $record->get_databox()->get_sbas_id();
@@ -190,6 +276,8 @@ class Property implements ControllerProviderInterface
'new_status' => $newStatus
);
}
+
+ return null;
}
/**
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Root.php b/lib/Alchemy/Phrasea/Controller/Prod/Root.php
index fb4aa66293..4cea156ef5 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Root.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Root.php
@@ -126,19 +126,6 @@ class Root implements ControllerProviderInterface
));
});
- $controllers->post('/multi-export/', function(Application $app, Request $request) {
-
- $download = new \set_export($app, $request->request->get('lst', ''), (int) $request->request->get('ssel'), $request->request->get('story'));
-
- return $app['twig']->render('common/dialog_export.html.twig', array(
- 'download' => $download,
- 'ssttid' => (int) $request->request->get('ssel'),
- 'lst' => $download->serialize_list(),
- 'default_export_title' => $app['phraseanet.registry']->get('GV_default_export_title'),
- 'choose_export_title' => $app['phraseanet.registry']->get('GV_choose_export_title')
- ));
- });
-
return $controllers;
}
}
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Share.php b/lib/Alchemy/Phrasea/Controller/Prod/Share.php
new file mode 100644
index 0000000000..cd2dfa50c6
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Share.php
@@ -0,0 +1,95 @@
+before(function(Request $request) use ($app) {
+ $response = $app['firewall']->requireNotGuest();
+ if ($response instanceof Response) {
+ return $response;
+ }
+ });
+
+ /**
+ * Share a record
+ *
+ * name : share_record
+ *
+ * description : Share a record
+ *
+ * method : GET
+ *
+ * parameters : none
+ *
+ * return : HTML Response
+ */
+ $controllers->get('/record/{base_id}/{record_id}/', $this->call('shareRecord'))
+ ->before(function(Request $request) use ($app) {
+ $app['firewall']->requireRightOnBase(\phrasea::sbasFromBas($app, $request->attributes->get('base_id')), 'bas_chupub');
+ })
+ ->bind('share_record');
+
+ return $controllers;
+ }
+
+ /**
+ * Share a record
+ *
+ * @param Application $app
+ * @param Request $request
+ * @param integer $base_id
+ * @param integer $record_id
+ * @return Response
+ */
+ public function shareRecord(Application $app, Request $request, $base_id, $record_id)
+ {
+ $record = new \record_adapter($app, \phrasea::sbasFromBas($app, $base_id), $record_id);
+
+ if ( ! $app['phraseanet.user']->ACL()->has_access_to_subdef($record, 'preview')){
+ $app->abort(403);
+ }
+
+ return new Response($app['twig']->render('prod/Share/record.html.twig', array(
+ 'record' => $record,
+ )));
+ }
+
+ /**
+ * 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/Alchemy/Phrasea/Controller/Prod/UserPreferences.php b/lib/Alchemy/Phrasea/Controller/Prod/UserPreferences.php
deleted file mode 100644
index 196a304166..0000000000
--- a/lib/Alchemy/Phrasea/Controller/Prod/UserPreferences.php
+++ /dev/null
@@ -1,68 +0,0 @@
-before(function(Request $request) use ($app) {
- $app['firewall']->requireAuthentication();
- });
-
- $controllers->post('/save/', $this->call('savePreference'));
-
- return $controllers;
- }
-
- public function savePreference(Application $app, Request $request)
- {
- $ret = array('success' => false, 'message' => _('Error while saving preference'));
-
- try {
- $ret = $app['phraseanet.user']->setPrefs($request->request->get('prop'), $request->request->get('value'));
-
- if ($ret == $request->request->get('value'))
- $output = "1"; else
- $output = "0";
-
- $ret = array('success' => true, 'message' => _('Preference saved !'));
- } catch (\Exception $e) {
-
- }
-
- return $app->json($ret);
- }
-
- /**
- * 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/Alchemy/Phrasea/Controller/User/Notifications.php b/lib/Alchemy/Phrasea/Controller/User/Notifications.php
new file mode 100644
index 0000000000..2d9221d2ec
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Controller/User/Notifications.php
@@ -0,0 +1,123 @@
+before(function(Request $request) use ($app) {
+ $app['firewall']->requireNotGuest();
+ });
+
+
+ /**
+ * Read all notifications
+ *
+ * name : read_notifications_full
+ *
+ * description : Read full notification
+ *
+ * method : GET
+ *
+ * parameters : none
+ *
+ * return : JSON Response
+ */
+ $controllers->get('/', $this->call('listNotifications'))
+ ->bind('get_notifications');
+
+ /**
+ * Read notifications
+ *
+ * name : read_notifications
+ *
+ * description : Read notification
+ *
+ * method : GET
+ *
+ * parameters : none
+ *
+ * return : JSON Response
+ */
+ $controllers->post('/read/', $this->call('setNotificationsReaded'))
+ ->bind('');
+
+ return $controllers;
+ }
+
+ /**
+ * Get the new notifications
+ *
+ * @param Application $app
+ * @param Request $request
+ * @return JsonResponse
+ */
+ public function setNotificationsReaded(Application $app, Request $request)
+ {
+ if(!$request->isXmlHttpRequest()) {
+ $app->abort(400);
+ }
+
+ try {
+ $app['events-manager']->read(explode('_', (string) $request->query->get('notifications')), $app['phraseanet.user']->get_id());
+
+ return $app->json(array('success' => true, 'message' => ''));
+ } catch (Exception $e) {
+
+ return $app->json(array('success' => false, 'message' => $e->getMessage()));
+ }
+ }
+
+ /**
+ * Get all notifications
+ *
+ * @param Application $app
+ * @param Request $request
+ * @return JsonResponse
+ */
+ public function listNotifications(Application $app, Request $request)
+ {
+ if(!$request->isXmlHttpRequest()) {
+ $app->abort(400);
+ }
+
+ $page = (int) $request->query->get('page', 1);
+ return $app->json($app['events-manager']->get_json_notifications(($page < 1 ? 1 : $page)));
+ }
+
+ /**
+ * 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/Alchemy/Phrasea/Controller/User/Preferences.php b/lib/Alchemy/Phrasea/Controller/User/Preferences.php
new file mode 100644
index 0000000000..7d8d4e5c8e
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Controller/User/Preferences.php
@@ -0,0 +1,133 @@
+before(function(Request $request) use ($app) {
+ $app['firewall']->requireAuthentication();
+ });
+
+ /**
+ * Save preferences
+ *
+ * name : save_pref
+ *
+ * description : Save User preferences
+ *
+ * method : POST
+ *
+ * parameters : none
+ *
+ * return : JSON Response
+ */
+ $controllers->post('/', $this->call('saveUserPref'))
+ ->bind('save_pref');
+
+ /**
+ * Save CSS preferences
+ *
+ * name : save_css_pref
+ *
+ * description : Save CSS preferences
+ *
+ * method : POST
+ *
+ * parameters : none
+ *
+ * return : JSON Response
+ */
+ $controllers->post('/temporary/', $this->call('saveTemporaryPref'))
+ ->bind('save_css_pref');
+
+ return $controllers;
+ }
+
+ /**
+ * Save user production preferenes
+ *
+ * @param Application $app
+ * @param Request $request
+ * @return JsonResponse
+ */
+ public function saveTemporaryPref(Application $app, Request $request)
+ {
+ if(!$request->isXmlHttpRequest()) {
+ $app->abort(400);
+ }
+
+ $prop = $request->request->get('prop');
+ $value = $request->request->get('value');
+ $success = false;
+
+ if($prop && $value) {
+ $app['session']->set('pref.' . $prop, $value);
+ $success = true;
+ }
+
+ return new JsonResponse(array('success' => $success));
+ }
+
+ /**
+ * Save css production preferenes
+ *
+ * @param Application $app
+ * @param Request $request
+ * @return JsonResponse
+ */
+ public function saveUserPref(Application $app, Request $request)
+ {
+ if(!$request->isXmlHttpRequest()) {
+ $app->abort(400);
+ }
+
+ $msg = _('Error while saving preference');
+ $prop = $request->request->get('prop');
+ $value = $request->request->get('value');
+
+ $success = false;
+ if($prop && $value) {
+ $success = ! ! $app['phraseanet.user']->setPrefs($prop, $value);
+ $msg = _('Preference saved !');
+ }
+
+ return new JsonResponse(array('success' => $success, 'message' => $msg));
+ }
+
+ /**
+ * 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/eventsmanager/broker.class.php b/lib/classes/eventsmanager/broker.class.php
index 1a2ce98e5e..1adbe2dad0 100644
--- a/lib/classes/eventsmanager/broker.class.php
+++ b/lib/classes/eventsmanager/broker.class.php
@@ -203,7 +203,7 @@ class eventsmanager_broker
$data['next'] = '' . _('charger d\'avantages de notifications') . '';
}
- return p4string::jsonencode($datas);
+ return p4string::jsonencode($data);
}
public function get_unread_notifications_number()
diff --git a/templates/web/common/dialog_export.html.twig b/templates/web/common/dialog_export.html.twig
index 525cb71dec..a0e39659bb 100644
--- a/templates/web/common/dialog_export.html.twig
+++ b/templates/web/common/dialog_export.html.twig
@@ -76,24 +76,18 @@
{% endmacro %}
-{% if download.get_total_download() <= 0 and download.get_total_order() <= 0 and download.get_total_ftp() <= 0%}
-
-{% endif %}
+{% if app['phraseanet.registry'].get('GV_needAuth2DL') and app['phraseanet.user'].is_guest() %}
+
+{% else %}
-
-
{% if download.get_total_download() > 0 %}
@@ -233,14 +227,8 @@
{% endtrans %}
- {% endif %}
-
-
-
+
+
{% endif %}
@@ -270,108 +258,123 @@
{% endfor %}
{% endif %}
-
- {% endif %}
- {% endfor %}
-
-