diff --git a/CHANGELOG.md b/CHANGELOG.md index dbfbffd0c2..bcef5265e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ - Add localized labels for databox names. - Add plugin architecture for third party modules and customization. - Add records sent-by-mail report. + - User time limit restrictions can now be set per databox. * 3.7.12 (2013-05-13) diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Users.php b/lib/Alchemy/Phrasea/Controller/Admin/Users.php index 43b9319c46..3c3791ec5c 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Users.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Users.php @@ -107,6 +107,12 @@ class Users implements ControllerProviderInterface return $app['twig']->render('admin/editusers_timelimit.html.twig', $rights->get_time()); }); + $controllers->post('/rights/time/sbas/', function(Application $app) { + $rights = new UserHelper\Edit($app, $app['request']); + + return $app['twig']->render('admin/editusers_timelimit_sbas.html.twig', $rights->get_time_sbas()); + }); + $controllers->post('/rights/time/apply/', function(Application $app) { $rights = new UserHelper\Edit($app, $app['request']); $rights->apply_time(); diff --git a/lib/Alchemy/Phrasea/Helper/User/Edit.php b/lib/Alchemy/Phrasea/Helper/User/Edit.php index f6b3ac582b..673fbc1dc1 100644 --- a/lib/Alchemy/Phrasea/Helper/User/Edit.php +++ b/lib/Alchemy/Phrasea/Helper/User/Edit.php @@ -193,7 +193,7 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper $sql = "SELECT u.usr_id, restrict_dwnld, remain_dwnld, month_dwnld_max FROM (usr u INNER JOIN basusr bu ON u.usr_id = bu.usr_id) - WHERE u.usr_id = " . implode(' OR u.usr_id = ', $this->users) . " + WHERE (u.usr_id = " . implode(' OR u.usr_id = ', $this->users) . ") AND bu.base_id = :base_id"; $conn = \connection::getPDOConnection($this->app); @@ -315,7 +315,7 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper $sql = "SELECT u.usr_id, time_limited, limited_from, limited_to FROM (usr u INNER JOIN basusr bu ON u.usr_id = bu.usr_id) - WHERE u.usr_id = " . implode(' OR u.usr_id = ', $this->users) . " + WHERE (u.usr_id = " . implode(' OR u.usr_id = ', $this->users) . ") AND bu.base_id = :base_id"; $conn = \connection::getPDOConnection($this->app); @@ -363,6 +363,79 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper ); } + public function get_time_sbas() + { + $sbas_id = (int) $this->request->get('sbas_id'); + + $sql = "SELECT u.usr_id, time_limited, limited_from, limited_to + FROM (usr u + INNER JOIN basusr bu ON u.usr_id = bu.usr_id + INNER JOIN bas b ON b.base_id = bu.base_id) + WHERE (u.usr_id = " . implode(' OR u.usr_id = ', $this->users) . ") + AND b.sbas_id = :sbas_id"; + + $conn = \connection::getPDOConnection($this->app); + $stmt = $conn->prepare($sql); + $stmt->execute(array(':sbas_id' => $sbas_id)); + $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); + $stmt->closeCursor(); + + $time_limited = $limited_from = $limited_to = array(); + + foreach ($rs as $row) { + $time_limited[] = $row['time_limited']; + $limited_from[] = $row['limited_from']; + $limited_to[] = $row['limited_to']; + } + + $time_limited = array_unique($time_limited); + $limited_from = array_unique($limited_from); + $limited_to = array_unique($limited_to); + + if (1 === count($time_limited) + && 1 === count($limited_from) + && 1 === count($limited_to)) { + $limited_from = array_pop($limited_from); + $limited_to = array_pop($limited_to); + + if ($limited_from !== '' && trim($limited_from) != '0000-00-00 00:00:00') { + $date_obj_from = new \DateTime($limited_from); + $limited_from = $date_obj_from->format('Y-m-d'); + } else { + $limited_from = false; + } + + if ($limited_to !== '' && trim($limited_to) != '0000-00-00 00:00:00') { + $date_obj_to = new \DateTime($limited_to); + $limited_to = $date_obj_to->format('Y-m-d'); + } else { + $limited_to = false; + } + + $datas = array( + 'time_limited' => array_pop($time_limited), + 'limited_from' => $limited_from, + 'limited_to' => $limited_to + ); + } else { + $datas = array( + 'time_limited' => 2, + 'limited_from' => '', + 'limited_to' => '' + ); + } + + $this->users_datas = $datas; + + return array( + 'sbas_id' => $sbas_id, + 'datas' => $this->users_datas, + 'users' => $this->users, + 'users_serial' => implode(';', $this->users), + 'databox' => $this->app['phraseanet.appbox']->get_databox($sbas_id), + ); + } + public function apply_rights() { $request = \http_request::getInstance(); @@ -627,16 +700,27 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper public function apply_time() { $this->base_id = (int) $this->request->get('base_id'); + $sbas_id = (int) $this->request->get('sbas_id'); $dmin = $this->request->get('dmin') ? new \DateTime($this->request->get('dmin')) : null; $dmax = $this->request->get('dmax') ? new \DateTime($this->request->get('dmax')) : null; $activate = !!$this->request->get('limit'); + $base_ids = array_keys($this->app['authentication']->getUser()->ACL()->get_granted_base(array('canadmin'))); + foreach ($this->users as $usr_id) { $user = \User_Adapter::getInstance($usr_id, $this->app); - $user->ACL()->set_limits($this->base_id, $activate, $dmin, $dmax); + if ($this->base_id > 0) { + $user->ACL()->set_limits($this->base_id, $activate, $dmin, $dmax); + } elseif ($sbas_id > 0) { + foreach ($base_ids as $base_id) { + $user->ACL()->set_limits($base_id, $activate, $dmin, $dmax); + } + } else { + $this->app->abort(400, 'No collection or databox id available'); + } } } diff --git a/templates/web/admin/editusers.html.twig b/templates/web/admin/editusers.html.twig index 9869805110..bf133e0f5c 100644 --- a/templates/web/admin/editusers.html.twig +++ b/templates/web/admin/editusers.html.twig @@ -258,7 +258,10 @@ - +
+ + +
diff --git a/templates/web/admin/editusers_timelimit_sbas.html.twig b/templates/web/admin/editusers_timelimit_sbas.html.twig new file mode 100644 index 0000000000..8e266a3b20 --- /dev/null +++ b/templates/web/admin/editusers_timelimit_sbas.html.twig @@ -0,0 +1,75 @@ +

{% trans 'Limite temporelle' %}

+
+{% set base = databox.get_viewname() %} +{% trans %}Base {{base}}{% endtrans %} +
+
+ + + + + + + + + + + +
+
+ +
+
+ {% trans 'Activer' %} +
+ {% trans 'De' %} + +
+ {% trans 'A' %} + +
+ + +
+ + diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Admin/UsersTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Admin/UsersTest.php index e26a73ad89..5546abebc0 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Admin/UsersTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Admin/UsersTest.php @@ -133,6 +133,16 @@ class ControllerUsersTest extends \PhraseanetWebTestCaseAuthenticatedAbstract $this->assertTrue($response->isOK()); } + public function testRouteRightTimeSbas() + { + $sbas_id = self::$DI['record_1']->get_databox()->get_sbas_id(); + $params = array('sbas_id' => $sbas_id, 'users' => self::$DI['user']->get_id()); + + self::$DI['client']->request('POST', '/admin/users/rights/time/sbas/', $params); + $response = self::$DI['client']->getResponse(); + $this->assertTrue($response->isOK()); + } + public function testRouteRightTimeApply() { $username = uniqid('user_'); @@ -149,6 +159,37 @@ class ControllerUsersTest extends \PhraseanetWebTestCaseAuthenticatedAbstract $user->delete(); } + public function testRouteRightTimeApplySbas() + { + $username = uniqid('user_'); + $user = \User_Adapter::create(self::$DI['app'], $username, "test", $username . "@email.com", false); + $sbas_id = self::$DI['record_1']->get_databox()->get_sbas_id(); + $date = new \Datetime(); + $date->modify("-10 days"); + $dmin = $date->format(DATE_ATOM); + $date->modify("+30 days"); + $dmax = $date->format(DATE_ATOM); + self::$DI['client']->request('POST', '/admin/users/rights/time/apply/', array('sbas_id' => $sbas_id, 'dmin' => $dmin, 'dmax' => $dmax, 'limit' => 1, 'users' => $user->get_id())); + $response = self::$DI['client']->getResponse(); + $this->assertTrue($response->isOK()); + $user->delete(); + } + + public function testRouteRightTimeApplyWithtoutBasOrSbas() + { + $username = uniqid('user_'); + $user = \User_Adapter::create(self::$DI['app'], $username, "test", $username . "@email.com", false); + $date = new \Datetime(); + $date->modify("-10 days"); + $dmin = $date->format(DATE_ATOM); + $date->modify("+30 days"); + $dmax = $date->format(DATE_ATOM); + self::$DI['client']->request('POST', '/admin/users/rights/time/apply/', array('dmin' => $dmin, 'dmax' => $dmax, 'limit' => 1, 'users' => $user->get_id())); + $response = self::$DI['client']->getResponse(); + $this->assertEquals(400, $response->getStatusCode()); + $user->delete(); + } + public function testRouteRightMask() { $keys = array_keys(self::$DI['user']->ACL()->get_granted_base()); diff --git a/www/skins/admin/editusers.js b/www/skins/admin/editusers.js index 9234de7f1c..a023d4a65d 100644 --- a/www/skins/admin/editusers.js +++ b/www/skins/admin/editusers.js @@ -1,7 +1,7 @@ function ini_edit_usrs(){ initialize_geoname_field($('#user_infos_tab input.geoname_field')); - + $('.users_col.options').bind('click', function(event){ $('#users_check_uncheck').remove(); event.stopPropagation(); @@ -83,7 +83,7 @@ $('#right-ajax button.users_rights_valid').bind('click', function(){ }; $.ajax({ type: 'POST', - url: '/admin/users/rights/apply/', + url: '../admin/users/rights/apply/', dataType:'json', data: datas, success: function(data){ @@ -95,7 +95,7 @@ $('#right-ajax button.users_rights_valid').bind('click', function(){ }); return false; }); - + $('#right-ajax .users_rights_cancel').bind('click', function(){ var $this = $(this); $('#right-ajax').empty().addClass('loading').parent().show(); @@ -103,7 +103,7 @@ $('#right-ajax button.users_rights_valid').bind('click', function(){ $.get($this.attr('href'), function(data) { $('#right-ajax').removeClass('loading').html(data); }); - + return false; }); @@ -157,53 +157,91 @@ $('#right-ajax button.users_rights_valid').bind('click', function(){ }); $('#users_rights_form .time_trigger').bind('click', function(){ var base_id = $(this).find('input[name="time_base_id"]').val(); - $.ajax({ - type: 'POST', - url: '/admin/users/rights/time/', - data: { - users:$('#users_rights_form input[name="users"]').val(), - base_id:base_id - }, - success: function(data){ - var dialog = $('#time_dialog'); - - dialog.html(data).dialog('open'); - - $('div.switch_time', dialog).bind('click', function(event){ - var newclass, boxes; + if ('undefined' !== typeof base_id) { + $.ajax({ + type: 'POST', + url: '../admin/users/rights/time/', + data: { + users:$('#users_rights_form input[name="users"]').val(), + base_id:base_id + }, + success: function(data){ + var dialog = $('#time_dialog'); - boxes = $(this).closest('form').find('input.datepicker'); + dialog.html(data).dialog('open'); - if(($(this).hasClass('mixed') === true) || ($(this).hasClass('unchecked') === true)) - { - newclass = 'checked'; - boxes.removeAttr('readonly'); - } - else - { - newclass = 'unchecked'; - boxes.attr('readonly','readonly'); + $('div.switch_time', dialog).bind('click', function(event){ + var newclass, boxes; + + boxes = $(this).closest('form').find('input.datepicker'); + + if(($(this).hasClass('mixed') === true) || ($(this).hasClass('unchecked') === true)) + { + newclass = 'checked'; + boxes.removeAttr('readonly'); + } + else + { + newclass = 'unchecked'; + boxes.attr('readonly','readonly'); + } + + $(this).removeClass('mixed checked unchecked').addClass(newclass); + }); } + }); + } else { + var sbas_id = $(this).find('input[name="time_sbas_id"]').val(); - $(this).removeClass('mixed checked unchecked').addClass(newclass); - }); - } - }); + $.ajax({ + type: 'POST', + url: '../admin/users/rights/time/sbas/', + data: { + users:$('#users_rights_form input[name="users"]').val(), + sbas_id:sbas_id + }, + success: function(data){ + var dialog = $('#time_dialog'); + + dialog.html(data); + dialog.dialog('open'); + + $('div.switch_time', dialog).bind('click', function(event){ + var newclass, boxes; + + boxes = $(this).closest('form').find('input.datepicker'); + + if(($(this).hasClass('mixed') === true) || ($(this).hasClass('unchecked') === true)) + { + newclass = 'checked'; + boxes.removeAttr('readonly'); + } + else + { + newclass = 'unchecked'; + boxes.attr('readonly','readonly'); + } + + $(this).removeClass('mixed checked unchecked').addClass(newclass); + }); + } + }); + } }); $('#users_rights_form .quota_trigger').bind('click', function(){ var base_id = $(this).find('input[name="quota_base_id"]').val(); $.ajax({ type: 'POST', - url: '/admin/users/rights/quotas/', + url: '../admin/users/rights/quotas/', data: { users:$('#users_rights_form input[name="users"]').val(), base_id:base_id }, success: function(data){ - + var dialog = $('#quotas_dialog'); dialog.html(data).dialog('open'); - + $('div.switch_quota', dialog).bind('click', function(event){ var newclass, boxes; @@ -230,7 +268,7 @@ $('#right-ajax button.users_rights_valid').bind('click', function(){ var base_id = $(this).find('input[name="masks_base_id"]').val(); $.ajax({ type: 'POST', - url: '/admin/users/rights/masks/', + url: '../admin/users/rights/masks/', data: { users:$('#users_rights_form input[name="users"]').val(), base_id:base_id @@ -324,7 +362,7 @@ $('#right-ajax button.users_rights_valid').bind('click', function(){ $.ajax({ type: 'POST', - url: '/admin/users/rights/masks/apply/', + url: '../admin/users/rights/masks/apply/', data: { users:users, base_id:base_id, @@ -360,7 +398,7 @@ $('#right-ajax button.users_rights_valid').bind('click', function(){ $.ajax({ type: 'POST', - url: '/admin/users/rights/quotas/apply/', + url: '../admin/users/rights/quotas/apply/', data: { act:"APPLYQUOTAS", users:users, @@ -382,6 +420,7 @@ $('#right-ajax button.users_rights_valid').bind('click', function(){ var dmax = $('input[name="dmax"]', cont).val(); var users = $('input[name="users"]', cont).val(); var base_id = $('input[name="base_id"]', cont).val(); + var sbas_id = $('input[name="sbas_id"]', cont).val(); var switch_time = $('.switch_time', cont); @@ -392,13 +431,14 @@ $('#right-ajax button.users_rights_valid').bind('click', function(){ if(switch_time.hasClass('checked')) limit = 1; - + $.ajax({ type: 'POST', - url: '/admin/users/rights/time/apply/', + url: '../admin/users/rights/time/apply/', data: { users:users, base_id:base_id, + sbas_id:sbas_id, limit:limit, dmin:dmin, dmax:dmax diff --git a/www/skins/admin/users.js b/www/skins/admin/users.js index 6804778f58..2c40d7db31 100644 --- a/www/skins/admin/users.js +++ b/www/skins/admin/users.js @@ -83,7 +83,7 @@ $(document).ready(function(){ $('#new_user_loader').show(); $.ajax({ type: 'POST', - url: '/admin/users/create/', + url: '../../admin/users/create/', dataType : 'json', data: { act:'CREATENEWUSER', @@ -102,7 +102,7 @@ $(document).ready(function(){ p4.users.sel = []; $.ajax({ type: 'POST', - url: '/admin/users/rights/', + url: '../../admin/users/rights/', data: { users : data.data }, @@ -145,7 +145,7 @@ $(document).ready(function(){ $('#right-ajax').empty().addClass('loading'); $.ajax({ type: 'POST', - url: '/admin/users/search/', + url: '../../admin/users/search/', data: datas, success: function(data){ $('#right-ajax').removeClass('loading').empty().html(data); @@ -160,7 +160,7 @@ $(document).ready(function(){ $('#right-ajax').empty().addClass('loading'); $.ajax({ type: 'POST', - url: '/admin/users/search/', + url: '../../admin/users/search/', data: datas, success: function(data){ $('#right-ajax').removeClass('loading').empty().html(data); @@ -331,7 +331,7 @@ $(document).ready(function(){ p4.users.sel = []; $.ajax({ type: 'POST', - url: '/admin/users/rights/', + url: '../../admin/users/rights/', data: { users : users }, @@ -354,7 +354,7 @@ $(document).ready(function(){ p4.users.sel = []; $.ajax({ type: 'POST', - url: '/admin/users/delete/', + url: '../../admin/users/delete/', data: { users : users }, @@ -376,7 +376,7 @@ $(document).ready(function(){ p4.users.sel = []; $.ajax({ type: 'POST', - url: '/admin/users/rights/', + url: '../../admin/users/rights/', data: { users : users },