Implementation of global categories limited to a certain group:

- from user perspectiv they are global cat like the existing ones
  (also comming in two flavors: global or for a certain app)
- admins can select to limit a global cat when they create it
--> all members of a given group have the cat as a global one
==> This does a silent modification of the categories table: 
global cats get changed from cat_owner=-1 to cat_owner=0 !!!
This commit is contained in:
Ralf Becker 2010-01-31 03:36:01 +00:00
parent 41d1d4b5a6
commit 958452ff95
8 changed files with 84 additions and 23 deletions

View File

@ -112,7 +112,7 @@ class admin_categories
} }
elseif ($content['button'] || $content['delete']) elseif ($content['button'] || $content['delete'])
{ {
$cats = new categories(categories::GLOBAL_ACCOUNT,$content['appname']); $cats = new categories($content['owner'] ? $content['owner'] : categories::GLOBAL_ACCOUNT,$content['appname']);
if ($content['delete']['delete']) if ($content['delete']['delete'])
{ {
@ -178,6 +178,7 @@ class admin_categories
$sel_options['icon'] = self::get_icons(); $sel_options['icon'] = self::get_icons();
$readonlys['button[delete]'] = !$content['id'] || !self::$acl_delete; // cant delete not yet saved category $readonlys['button[delete]'] = !$content['id'] || !self::$acl_delete; // cant delete not yet saved category
$readonlys['owner'] = $content['id'] > 0;
$tmpl = new etemplate('admin.categories.edit'); $tmpl = new etemplate('admin.categories.edit');
$tmpl->exec('admin.admin_categories.edit',$content,$sel_options,$readonlys,$content+array( $tmpl->exec('admin.admin_categories.edit',$content,$sel_options,$readonlys,$content+array(

View File

@ -111,6 +111,7 @@ change password for %1 admin de Ändern des Passworts für %1
check acl for entries of not (longer) existing accounts admin de Prüfe ACL Einträge auf Bezüge zu nicht (mehr) existierenden Benutzerkonten check acl for entries of not (longer) existing accounts admin de Prüfe ACL Einträge auf Bezüge zu nicht (mehr) existierenden Benutzerkonten
check ip address of all sessions admin de IP-Adresse für alle Sessions überprüfen check ip address of all sessions admin de IP-Adresse für alle Sessions überprüfen
check items to <b>%1</b> to %2 for %3 admin de Durch Abhaken %3 in %2 <b>%1</b> check items to <b>%1</b> to %2 for %3 admin de Durch Abhaken %3 in %2 <b>%1</b>
children admin de Kinder
click to select a color admin de Anclicken um eine Farbe auszuwählen click to select a color admin de Anclicken um eine Farbe auszuwählen
color admin de Farbe color admin de Farbe
command scheduled to run at %1 admin de Ausführung des Befehls eingeplant am/um %1 command scheduled to run at %1 admin de Ausführung des Befehls eingeplant am/um %1
@ -323,6 +324,8 @@ leave the group untouched and return back to the list admin de Gruppe unverände
leave without saveing the entry admin de beendet ohne den Eintrag zu speichern leave without saveing the entry admin de beendet ohne den Eintrag zu speichern
leaves without saveing admin de beendet ohne zu speichern leaves without saveing admin de beendet ohne zu speichern
length<br>rows admin de Länge<br>Zeilen length<br>rows admin de Länge<br>Zeilen
limit global category to members of a certain group admin de Beschränkt die global Kategorie auf der Mitglieder einer bestimmten Gruppe
limit to members of admin de Beschränken auf Mitglieder von
list config settings admin de Konfigurationseinstellungen auflisten list config settings admin de Konfigurationseinstellungen auflisten
list current sessions admin de aktive Sitzungen anzeigen list current sessions admin de aktive Sitzungen anzeigen
list of current users admin de Liste der gegenwärtigen Benutzer list of current users admin de Liste der gegenwärtigen Benutzer

View File

@ -55,7 +55,7 @@ after how many unsuccessful attempts to login, an account should be blocked (def
after how many unsuccessful attempts to login, an ip should be blocked (default 3) ? admin en After how many unsuccessful attempts to login, an IP should be blocked (default 3) ? after how many unsuccessful attempts to login, an ip should be blocked (default 3) ? admin en After how many unsuccessful attempts to login, an IP should be blocked (default 3) ?
aliases admin en Aliases aliases admin en Aliases
all records and account information will be lost! admin en All records and account information will be lost! all records and account information will be lost! admin en All records and account information will be lost!
all users admin en All Users all users admin en All users
allow anonymous access to this app admin en Allow anonymous access to this app allow anonymous access to this app admin en Allow anonymous access to this app
allow remote administration from following install id's (comma separated) admin en Allow remote administration from following install ID's (comma separated) allow remote administration from following install id's (comma separated) admin en Allow remote administration from following install ID's (comma separated)
alternate email address admin en alternate email address alternate email address admin en alternate email address
@ -111,6 +111,7 @@ change password for %1 admin en change password for %1
check acl for entries of not (longer) existing accounts admin en Check ACL for entries of not (longer) existing accounts check acl for entries of not (longer) existing accounts admin en Check ACL for entries of not (longer) existing accounts
check ip address of all sessions admin en Check IP address of all sessions check ip address of all sessions admin en Check IP address of all sessions
check items to <b>%1</b> to %2 for %3 admin en Check items to <b>%1</b> to %2 for %3 check items to <b>%1</b> to %2 for %3 admin en Check items to <b>%1</b> to %2 for %3
children admin en Children
click to select a color admin en Click to select a color click to select a color admin en Click to select a color
color admin en Color color admin en Color
command scheduled to run at %1 admin en Command scheduled to run at %1 command scheduled to run at %1 admin en Command scheduled to run at %1
@ -321,6 +322,8 @@ leave the group untouched and return back to the list admin en Leave the group u
leave without saveing the entry admin en leave without saveing the entry leave without saveing the entry admin en leave without saveing the entry
leaves without saveing admin en leaves without saveing leaves without saveing admin en leaves without saveing
length<br>rows admin en Length<br>Rows length<br>rows admin en Length<br>Rows
limit global category to members of a certain group admin en Limit global category to members of a certain group
limit to members of admin en Limit to members of
list config settings admin en List config settings list config settings admin en List config settings
list current sessions admin en List current sessions list current sessions admin en List current sessions
list of current users admin en list of current users list of current users admin en list of current users

View File

@ -2,7 +2,7 @@
/** /**
* eGroupWare - eTemplates for Application admin * eGroupWare - eTemplates for Application admin
* http://www.egroupware.org * http://www.egroupware.org
* generated by soetemplate::dump4setup() 2010-01-31 00:50 * generated by soetemplate::dump4setup() 2010-01-31 04:31
* *
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package admin * @package admin
@ -33,11 +33,11 @@ $templ_data[] = array('name' => 'admin.categories.delete','template' => '','lang
{ {
}','modified' => '1264754384',); }','modified' => '1264754384',);
$templ_data[] = array('name' => 'admin.categories.edit','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:2:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:10:{i:0;a:10:{s:2:"c2";s:2:"th";s:2:"c3";s:3:"row";s:2:"c4";s:7:"row,top";s:2:"c5";s:3:"row";s:2:"c7";s:3:"row";s:2:"c6";s:3:"row";s:2:"c8";s:3:"row";s:2:"h7";s:15:",@appname=phpgw";s:2:"h2";s:2:"25";s:2:"h1";s:6:",!@msg";}i:1;a:2:{s:1:"A";a:4:{s:4:"type";s:5:"label";s:4:"span";s:13:"all,redItalic";s:5:"align";s:6:"center";s:4:"name";s:3:"msg";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:9:",,,parent";s:5:"label";s:15:"Parent category";}s:1:"B";a:3:{s:4:"type";s:10:"select-cat";s:4:"size";s:25:"None,,,$cont[appname],,-1";s:4:"name";s:6:"parent";}}i:3;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:7:",,,name";s:5:"label";s:4:"Name";}s:1:"B";a:3:{s:4:"type";s:4:"text";s:4:"size";s:6:"50,150";s:4:"name";s:4:"name";}}i:4;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:14:",,,description";s:5:"label";s:11:"Description";}s:1:"B";a:3:{s:4:"type";s:8:"textarea";s:4:"size";s:4:"5,50";s:4:"name";s:11:"description";}}i:5;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:18:",,,cat_data[color]";s:5:"label";s:5:"Color";}s:1:"B";a:2:{s:4:"type";s:11:"colorpicker";s:4:"name";s:11:"data[color]";}}i:6;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:17:",,,cat_data[icon]";s:5:"label";s:4:"Icon";}s:1:"B";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:4:{s:4:"type";s:6:"select";s:4:"name";s:10:"data[icon]";s:4:"size";s:4:"None";s:8:"onchange";s:73:"document.getElementById(\'icon_url\').src = \'$cont[base_url]\' + this.value;";}i:2;a:3:{s:4:"type";s:5:"image";s:4:"name";s:8:"icon_url";s:4:"span";s:9:",leftPad5";}}}i:7;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:11:"Application";}s:1:"B";a:3:{s:4:"type";s:10:"select-app";s:4:"name";s:7:"appname";s:8:"readonly";s:1:"1";}}i:8;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Modified";}s:1:"B";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:8:"last_mod";s:8:"readonly";s:1:"1";}}i:9;a:2:{s:1:"A";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:3:{s:4:"type";s:6:"button";s:5:"label";s:4:"Save";s:4:"name";s:12:"button[save]";}i:2;a:3:{s:4:"type";s:6:"button";s:5:"label";s:5:"Apply";s:4:"name";s:13:"button[apply]";}}s:1:"B";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:4:{s:4:"type";s:10:"buttononly";s:4:"name";s:14:"button[cancel]";s:5:"label";s:6:"Cancel";s:7:"onclick";s:15:"window.close();";}i:2;a:6:{s:4:"type";s:10:"buttononly";s:5:"label";s:6:"Delete";s:5:"align";s:5:"right";s:4:"name";s:14:"button[delete]";s:4:"help";s:20:"Delete this category";s:7:"onclick";s:157:"set_style_by_class(\'tr\',\'confirmSubs\',\'visibility\',\'$cont[children]\'?\'visible\':\'collapse\'); set_style_by_class(\'fieldset\',\'confirmDelete\',\'display\',\'block\');";}}}}s:4:"rows";i:9;s:4:"cols";i:2;}i:1;a:2:{s:4:"type";s:8:"template";s:4:"name";s:23:"admin.categories.delete";}}','size' => '','style' => '','modified' => '1264740967',); $templ_data[] = array('name' => 'admin.categories.edit','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:2:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:11:{i:0;a:12:{s:2:"c2";s:2:"th";s:2:"c3";s:3:"row";s:2:"c4";s:7:"row,top";s:2:"c5";s:3:"row";s:2:"c7";s:3:"row";s:2:"c6";s:3:"row";s:2:"h7";s:15:",@appname=phpgw";s:2:"h2";s:2:"25";s:2:"h1";s:6:",!@msg";s:2:"c9";s:3:"row";s:2:"c8";s:3:"row";s:2:"h9";s:11:",!@last_mod";}i:1;a:2:{s:1:"A";a:4:{s:4:"type";s:5:"label";s:4:"span";s:13:"all,redItalic";s:5:"align";s:6:"center";s:4:"name";s:3:"msg";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:9:",,,parent";s:5:"label";s:15:"Parent category";}s:1:"B";a:3:{s:4:"type";s:10:"select-cat";s:4:"size";s:25:"None,,,$cont[appname],,-1";s:4:"name";s:6:"parent";}}i:3;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:7:",,,name";s:5:"label";s:4:"Name";}s:1:"B";a:3:{s:4:"type";s:4:"text";s:4:"size";s:6:"50,150";s:4:"name";s:4:"name";}}i:4;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:14:",,,description";s:5:"label";s:11:"Description";}s:1:"B";a:3:{s:4:"type";s:8:"textarea";s:4:"size";s:4:"5,50";s:4:"name";s:11:"description";}}i:5;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:18:",,,cat_data[color]";s:5:"label";s:5:"Color";}s:1:"B";a:2:{s:4:"type";s:11:"colorpicker";s:4:"name";s:11:"data[color]";}}i:6;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:13:",,,data[icon]";s:5:"label";s:4:"Icon";}s:1:"B";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:4:{s:4:"type";s:6:"select";s:4:"name";s:10:"data[icon]";s:4:"size";s:4:"None";s:8:"onchange";s:73:"document.getElementById(\'icon_url\').src = \'$cont[base_url]\' + this.value;";}i:2;a:3:{s:4:"type";s:5:"image";s:4:"name";s:8:"icon_url";s:4:"span";s:9:",leftPad5";}}}i:7;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:11:"Application";}s:1:"B";a:4:{s:4:"type";s:10:"select-app";s:4:"name";s:7:"appname";s:8:"readonly";s:1:"1";s:4:"size";s:16:"All applications";}}i:8;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:8:",,,owner";s:5:"label";s:19:"Limit to members of";}s:1:"B";a:4:{s:4:"type";s:14:"select-account";s:4:"size";s:16:"All users,groups";s:4:"name";s:5:"owner";s:4:"help";s:51:"Limit global category to members of a certain group";}}i:9;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Modified";}s:1:"B";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:8:"last_mod";s:8:"readonly";s:1:"1";}}i:10;a:2:{s:1:"A";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:3:{s:4:"type";s:6:"button";s:5:"label";s:4:"Save";s:4:"name";s:12:"button[save]";}i:2;a:3:{s:4:"type";s:6:"button";s:5:"label";s:5:"Apply";s:4:"name";s:13:"button[apply]";}}s:1:"B";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:4:{s:4:"type";s:10:"buttononly";s:4:"name";s:14:"button[cancel]";s:5:"label";s:6:"Cancel";s:7:"onclick";s:15:"window.close();";}i:2;a:6:{s:4:"type";s:10:"buttononly";s:5:"label";s:6:"Delete";s:5:"align";s:5:"right";s:4:"name";s:14:"button[delete]";s:4:"help";s:20:"Delete this category";s:7:"onclick";s:157:"set_style_by_class(\'tr\',\'confirmSubs\',\'visibility\',\'$cont[children]\'?\'visible\':\'collapse\'); set_style_by_class(\'fieldset\',\'confirmDelete\',\'display\',\'block\');";}}}}s:4:"rows";i:10;s:4:"cols";i:2;}i:1;a:2:{s:4:"type";s:8:"template";s:4:"name";s:23:"admin.categories.delete";}}','size' => '','style' => '','modified' => '1264740967',);
$templ_data[] = array('name' => 'admin.categories.index','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:2:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:1:{s:2:"h1";s:6:",!@msg";}i:1;a:1:{s:1:"A";a:4:{s:4:"type";s:5:"label";s:4:"name";s:3:"msg";s:5:"align";s:6:"center";s:4:"span";s:13:"all,redItalic";}}i:2;a:1:{s:1:"A";a:3:{s:4:"type";s:9:"nextmatch";s:4:"size";s:4:"rows";s:4:"name";s:2:"nm";}}i:3;a:1:{s:1:"A";a:4:{s:4:"type";s:10:"buttononly";s:5:"label";s:3:"Add";s:4:"name";s:3:"add";s:7:"onclick";s:193:"window.open(egw::link(\'/index.php\',\'menuaction=admin.admin_categories.edit&appname={$cont[nm][appname]}\'),\'_blank\',\'dependent=yes,width=600,height=300,scrollbars=yes,status=yes\'); return false;";}}}s:4:"rows";i:3;s:4:"cols";i:1;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}i:1;a:2:{s:4:"type";s:8:"template";s:4:"name";s:23:"admin.categories.delete";}}','size' => '100%','style' => '.level0 { font-weight: bold; }','modified' => '1264657515',); $templ_data[] = array('name' => 'admin.categories.index','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:2:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:1:{s:2:"h1";s:6:",!@msg";}i:1;a:1:{s:1:"A";a:4:{s:4:"type";s:5:"label";s:4:"name";s:3:"msg";s:5:"align";s:6:"center";s:4:"span";s:13:"all,redItalic";}}i:2;a:1:{s:1:"A";a:3:{s:4:"type";s:9:"nextmatch";s:4:"size";s:4:"rows";s:4:"name";s:2:"nm";}}i:3;a:1:{s:1:"A";a:4:{s:4:"type";s:10:"buttononly";s:5:"label";s:3:"Add";s:4:"name";s:3:"add";s:7:"onclick";s:193:"window.open(egw::link(\'/index.php\',\'menuaction=admin.admin_categories.edit&appname={$cont[nm][appname]}\'),\'_blank\',\'dependent=yes,width=600,height=300,scrollbars=yes,status=yes\'); return false;";}}}s:4:"rows";i:3;s:4:"cols";i:1;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}i:1;a:2:{s:4:"type";s:8:"template";s:4:"name";s:23:"admin.categories.delete";}}','size' => '100%','style' => '.level0 { font-weight: bold; }','modified' => '1264657515',);
$templ_data[] = array('name' => 'admin.categories.index.rows','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:6:{s:2:"c1";s:2:"th";s:2:"c2";s:13:"$row_cont[id]";s:1:"E";s:2:"80";s:1:"D";s:2:"40";s:1:"H";s:2:"1%";s:1:"G";s:2:"30";}i:1;a:8:{s:1:"A";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"Name";s:4:"name";s:4:"name";}s:1:"B";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:11:"Description";s:4:"name";s:11:"description";}s:1:"C";a:3:{s:4:"type";s:16:"nextmatch-header";s:4:"name";s:7:"appname";s:5:"label";s:11:"Application";}s:1:"D";a:4:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:4:"Icon";s:4:"name";s:4:"icon";s:5:"align";s:6:"center";}s:1:"E";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:5:"Color";s:4:"name";s:5:"color";}s:1:"F";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"Modified";s:4:"name";s:8:"last_mod";}s:1:"G";a:4:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:8:"Children";s:4:"name";s:4:"subs";s:5:"align";s:6:"center";}s:1:"H";a:2:{s:4:"type";s:5:"label";s:5:"label";s:7:"Actions";}}i:2;a:8:{s:1:"A";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:2:{s:4:"type";s:4:"html";s:4:"name";s:20:"${row}[level_spacer]";}i:2;a:3:{s:4:"type";s:5:"label";s:4:"name";s:12:"${row}[name]";s:4:"span";s:17:",$row_cont[class]";}}s:1:"B";a:2:{s:4:"type";s:5:"label";s:4:"name";s:19:"${row}[description]";}s:1:"C";a:4:{s:4:"type";s:10:"select-app";s:4:"name";s:15:"${row}[appname]";s:4:"size";s:6:"Global";s:8:"readonly";s:1:"1";}s:1:"D";a:4:{s:4:"type";s:5:"image";s:4:"name";s:16:"${row}[icon_url]";s:5:"label";s:23:"{$row_cont[data][icon]}";s:5:"align";s:6:"center";}s:1:"E";a:2:{s:4:"type";s:5:"label";s:4:"name";s:19:"${row}[data][color]";}s:1:"F";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:16:"${row}[last_mod]";s:8:"readonly";s:1:"1";}s:1:"G";a:3:{s:4:"type";s:5:"label";s:4:"name";s:12:"${row}[subs]";s:5:"align";s:6:"center";}s:1:"H";a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"3,,0,0";i:1;a:5:{s:4:"type";s:10:"buttononly";s:4:"size";s:4:"edit";s:5:"label";s:4:"Edit";s:4:"name";s:19:"edit[$row_cont[id]]";s:7:"onclick";s:185:"window.open(egw::link(\'/index.php\',\'menuaction=admin.admin_categories.edit&cat_id=$row_cont[id]\'),\'_blank\',\'dependent=yes,width=600,height=300,scrollbars=yes,status=yes\'); return false;";}i:2;a:5:{s:4:"type";s:10:"buttononly";s:4:"size";s:3:"new";s:5:"label";s:7:"Add sub";s:4:"name";s:18:"add[$row_cont[id]]";s:7:"onclick";s:208:"window.open(egw::link(\'/index.php\',\'menuaction=admin.admin_categories.edit&parent=$row_cont[id]&appname=$cont[appname]\'),\'_blank\',\'dependent=yes,width=600,height=300,scrollbars=yes,status=yes\'); return false;";}i:3;a:7:{s:4:"type";s:10:"buttononly";s:4:"size";s:6:"delete";s:5:"label";s:6:"Delete";s:4:"name";s:21:"delete[$row_cont[id]]";s:4:"help";s:20:"Delete this category";s:7:"onclick";s:246:"document.getElementById(\'exec[delete][cat_id]\').value=\'$row_cont[id]\'; set_style_by_class(\'tr\',\'confirmSubs\',\'visibility\',\'$row_cont[children]\'?\'visible\':\'collapse\'); set_style_by_class(\'fieldset\',\'confirmDelete\',\'display\',\'block\'); return false;";s:4:"span";s:9:",leftPad5";}}}}s:4:"rows";i:2;s:4:"cols";i:8;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1264657599',); $templ_data[] = array('name' => 'admin.categories.index.rows','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:6:{s:2:"c1";s:2:"th";s:2:"c2";s:13:"$row_cont[id]";s:1:"E";s:2:"40";s:1:"H";s:2:"30";s:1:"I";s:2:"1%";s:1:"F";s:2:"80";}i:1;a:9:{s:1:"A";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"Name";s:4:"name";s:4:"name";}s:1:"B";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:11:"Description";s:4:"name";s:11:"description";}s:1:"C";a:3:{s:4:"type";s:16:"nextmatch-header";s:4:"name";s:3:"app";s:5:"label";s:11:"Application";}s:1:"D";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:19:"Limit to members of";s:4:"name";s:5:"owner";}s:1:"E";a:4:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:4:"Icon";s:4:"name";s:4:"icon";s:5:"align";s:6:"center";}s:1:"F";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:5:"Color";s:4:"name";s:5:"color";}s:1:"G";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"Modified";s:4:"name";s:8:"last_mod";}s:1:"H";a:4:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:8:"Children";s:4:"name";s:4:"subs";s:5:"align";s:6:"center";}s:1:"I";a:2:{s:4:"type";s:5:"label";s:5:"label";s:7:"Actions";}}i:2;a:9:{s:1:"A";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:2:{s:4:"type";s:4:"html";s:4:"name";s:20:"${row}[level_spacer]";}i:2;a:3:{s:4:"type";s:5:"label";s:4:"name";s:12:"${row}[name]";s:4:"span";s:17:",$row_cont[class]";}}s:1:"B";a:2:{s:4:"type";s:5:"label";s:4:"name";s:19:"${row}[description]";}s:1:"C";a:3:{s:4:"type";s:10:"select-app";s:4:"name";s:15:"${row}[appname]";s:8:"readonly";s:1:"1";}s:1:"D";a:4:{s:4:"type";s:14:"select-account";s:4:"name";s:13:"${row}[owner]";s:8:"readonly";s:1:"1";s:4:"size";s:16:"All users,groups";}s:1:"E";a:4:{s:4:"type";s:5:"image";s:4:"name";s:16:"${row}[icon_url]";s:5:"label";s:23:"{$row_cont[data][icon]}";s:5:"align";s:6:"center";}s:1:"F";a:2:{s:4:"type";s:5:"label";s:4:"name";s:19:"${row}[data][color]";}s:1:"G";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:16:"${row}[last_mod]";s:8:"readonly";s:1:"1";}s:1:"H";a:3:{s:4:"type";s:5:"label";s:4:"name";s:12:"${row}[subs]";s:5:"align";s:6:"center";}s:1:"I";a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"3,,0,0";i:1;a:5:{s:4:"type";s:10:"buttononly";s:4:"size";s:4:"edit";s:5:"label";s:4:"Edit";s:4:"name";s:19:"edit[$row_cont[id]]";s:7:"onclick";s:185:"window.open(egw::link(\'/index.php\',\'menuaction=admin.admin_categories.edit&cat_id=$row_cont[id]\'),\'_blank\',\'dependent=yes,width=600,height=380,scrollbars=yes,status=yes\'); return false;";}i:2;a:5:{s:4:"type";s:10:"buttononly";s:4:"size";s:3:"new";s:5:"label";s:7:"Add sub";s:4:"name";s:18:"add[$row_cont[id]]";s:7:"onclick";s:208:"window.open(egw::link(\'/index.php\',\'menuaction=admin.admin_categories.edit&parent=$row_cont[id]&appname=$cont[appname]\'),\'_blank\',\'dependent=yes,width=600,height=380,scrollbars=yes,status=yes\'); return false;";}i:3;a:7:{s:4:"type";s:10:"buttononly";s:4:"size";s:6:"delete";s:5:"label";s:6:"Delete";s:4:"name";s:21:"delete[$row_cont[id]]";s:4:"help";s:20:"Delete this category";s:7:"onclick";s:246:"document.getElementById(\'exec[delete][cat_id]\').value=\'$row_cont[id]\'; set_style_by_class(\'tr\',\'confirmSubs\',\'visibility\',\'$row_cont[children]\'?\'visible\':\'collapse\'); set_style_by_class(\'fieldset\',\'confirmDelete\',\'display\',\'block\'); return false;";s:4:"span";s:9:",leftPad5";}}}}s:4:"rows";i:2;s:4:"cols";i:9;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1264657599',);
$templ_data[] = array('name' => 'admin.cmds','template' => '','lang' => '','group' => '0','version' => '1.5.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:9:"nextmatch";s:4:"size";s:15:"admin.cmds.rows";s:4:"name";s:2:"nm";}}}s:4:"rows";i:1;s:4:"cols";i:1;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1195518120',); $templ_data[] = array('name' => 'admin.cmds','template' => '','lang' => '','group' => '0','version' => '1.5.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:9:"nextmatch";s:4:"size";s:15:"admin.cmds.rows";s:4:"name";s:2:"nm";}}}s:4:"rows";i:1;s:4:"cols";i:1;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1195518120',);

View File

@ -80,7 +80,7 @@
<colorpicker id="data[color]"/> <colorpicker id="data[color]"/>
</row> </row>
<row class="row"> <row class="row">
<description options=",,,cat_data[icon]" value="Icon"/> <description options=",,,data[icon]" value="Icon"/>
<hbox options="0,0"> <hbox options="0,0">
<menulist> <menulist>
<menupopup id="data[icon]" options="None" onchange="document.getElementById('icon_url').src = '$cont[base_url]' + this.value;"/> <menupopup id="data[icon]" options="None" onchange="document.getElementById('icon_url').src = '$cont[base_url]' + this.value;"/>
@ -91,10 +91,16 @@
<row class="row" disabled="@appname=phpgw"> <row class="row" disabled="@appname=phpgw">
<description value="Application"/> <description value="Application"/>
<menulist> <menulist>
<menupopup type="select-app" id="appname" readonly="true"/> <menupopup type="select-app" id="appname" readonly="true" options="All applications"/>
</menulist> </menulist>
</row> </row>
<row class="row"> <row class="row">
<description options=",,,owner" value="Limit to members of"/>
<menulist>
<menupopup type="select-account" options="All users,groups" id="owner" statustext="Limit global category to members of a certain group"/>
</menulist>
</row>
<row class="row" disabled="!@last_mod">
<description value="Modified"/> <description value="Modified"/>
<date-time id="last_mod" readonly="true"/> <date-time id="last_mod" readonly="true"/>
</row> </row>

View File

@ -7,6 +7,7 @@
<column/> <column/>
<column/> <column/>
<column/> <column/>
<column/>
<column width="40"/> <column width="40"/>
<column width="80"/> <column width="80"/>
<column/> <column/>
@ -17,7 +18,8 @@
<row class="th"> <row class="th">
<nextmatch-sortheader label="Name" id="name"/> <nextmatch-sortheader label="Name" id="name"/>
<nextmatch-sortheader label="Description" id="description"/> <nextmatch-sortheader label="Description" id="description"/>
<nextmatch-header id="appname" label="Application"/> <nextmatch-header id="app" label="Application"/>
<nextmatch-header label="Limit to members of" id="owner"/>
<nextmatch-header label="Icon" id="icon" align="center"/> <nextmatch-header label="Icon" id="icon" align="center"/>
<nextmatch-header label="Color" id="color"/> <nextmatch-header label="Color" id="color"/>
<nextmatch-sortheader label="Modified" id="last_mod"/> <nextmatch-sortheader label="Modified" id="last_mod"/>
@ -31,15 +33,18 @@
</hbox> </hbox>
<description id="${row}[description]"/> <description id="${row}[description]"/>
<menulist> <menulist>
<menupopup type="select-app" id="${row}[appname]" options="Global" readonly="true"/> <menupopup type="select-app" id="${row}[appname]" readonly="true"/>
</menulist>
<menulist>
<menupopup type="select-account" id="${row}[owner]" readonly="true" options="All users,groups"/>
</menulist> </menulist>
<image src="${row}[icon_url]" label="{$row_cont[data][icon]}" align="center"/> <image src="${row}[icon_url]" label="{$row_cont[data][icon]}" align="center"/>
<description id="${row}[data][color]"/> <description id="${row}[data][color]"/>
<date-time id="${row}[last_mod]" readonly="true"/> <date-time id="${row}[last_mod]" readonly="true"/>
<description id="${row}[subs]" align="center"/> <description id="${row}[subs]" align="center"/>
<hbox options="0,0"> <hbox options="0,0">
<buttononly options="edit" label="Edit" id="edit[$row_cont[id]]" onclick="window.open(egw::link('/index.php','menuaction=admin.admin_categories.edit&amp;cat_id=$row_cont[id]'),'_blank','dependent=yes,width=600,height=300,scrollbars=yes,status=yes'); return false;"/> <buttononly options="edit" label="Edit" id="edit[$row_cont[id]]" onclick="window.open(egw::link('/index.php','menuaction=admin.admin_categories.edit&amp;cat_id=$row_cont[id]'),'_blank','dependent=yes,width=600,height=380,scrollbars=yes,status=yes'); return false;"/>
<buttononly options="new" label="Add sub" id="add[$row_cont[id]]" onclick="window.open(egw::link('/index.php','menuaction=admin.admin_categories.edit&amp;parent=$row_cont[id]&amp;appname=$cont[appname]'),'_blank','dependent=yes,width=600,height=300,scrollbars=yes,status=yes'); return false;"/> <buttononly options="new" label="Add sub" id="add[$row_cont[id]]" onclick="window.open(egw::link('/index.php','menuaction=admin.admin_categories.edit&amp;parent=$row_cont[id]&amp;appname=$cont[appname]'),'_blank','dependent=yes,width=600,height=380,scrollbars=yes,status=yes'); return false;"/>
<buttononly options="delete" label="Delete" id="delete[$row_cont[id]]" statustext="Delete this category" onclick="document.getElementById('exec[delete][cat_id]').value='$row_cont[id]'; set_style_by_class('tr','confirmSubs','visibility','$row_cont[children]'?'visible':'collapse'); set_style_by_class('fieldset','confirmDelete','display','block'); return false;" class="leftPad5"/> <buttononly options="delete" label="Delete" id="delete[$row_cont[id]]" statustext="Delete this category" onclick="document.getElementById('exec[delete][cat_id]').value='$row_cont[id]'; set_style_by_class('tr','confirmSubs','visibility','$row_cont[children]'?'visible':'collapse'); set_style_by_class('fieldset','confirmDelete','display','block'); return false;" class="leftPad5"/>
</hbox> </hbox>
</row> </row>

View File

@ -193,7 +193,7 @@ class select_widget
{ {
$s = str_repeat('&nbsp;',$cat['level']) . stripslashes($cat['name']); $s = str_repeat('&nbsp;',$cat['level']) . stripslashes($cat['name']);
if ($cat['app_name'] == categories::GLOBAL_APPNAME || $cat['owner'] == categories::GLOBAL_ACCOUNT) if (categories::is_global($cat))
{ {
$s .= ' &#9830;'; $s .= ' &#9830;';
} }
@ -225,7 +225,8 @@ class select_widget
$cell['no_lang'] = True; $cell['no_lang'] = True;
foreach(is_array($value) ? $value : (strpos($value,',') !== false ? explode(',',$value) : array($value)) as $id) foreach(is_array($value) ? $value : (strpos($value,',') !== false ? explode(',',$value) : array($value)) as $id)
{ {
$cell['sel_options'][$id] = $this->accountInfo($id,$acc,$type2,$type=='both'); $cell['sel_options'][$id] = !$id && !is_numeric($rows) ? lang($rows) :
$this->accountInfo($id,$acc,$type2,$type=='both');
} }
break; break;
} }

View File

@ -92,7 +92,16 @@ class categories
/** /**
* account_id for global categories * account_id for global categories
*/ */
const GLOBAL_ACCOUNT = -1; const GLOBAL_ACCOUNT = 0;
/**
* Owners for global accounts
*
* Usually the users group memberships and self::GLOBAL_ACCOUNT
*
* @var array
*/
private $global_owners = array(self::GLOBAL_ACCOUNT);
/** /**
* constructor for categories class * constructor for categories class
@ -104,13 +113,16 @@ class categories
{ {
if (!$app_name) $app_name = $GLOBALS['egw_info']['flags']['currentapp']; if (!$app_name) $app_name = $GLOBALS['egw_info']['flags']['currentapp'];
if ($accountid == self::GLOBAL_ACCOUNT) if ($accountid === self::GLOBAL_ACCOUNT ||
$accountid < 0 && $GLOBALS['egw']->accounts->exists($accountid) == 2)
{ {
$this->account_id = self::GLOBAL_ACCOUNT; $this->account_id = (int) $accountid;
} }
else else
{ {
$this->account_id = (int) get_account_id($accountid); $this->account_id = (int) get_account_id($accountid);
$this->global_owners = $GLOBALS['egw']->accounts->memberships($this->account_id,true);
$this->global_owners[] = self::GLOBAL_ACCOUNT;
} }
$this->app_name = $app_name; $this->app_name = $app_name;
$this->db = $GLOBALS['egw']->db; $this->db = $GLOBALS['egw']->db;
@ -466,22 +478,24 @@ class categories
*/ */
public function check_perms($needed,$category) public function check_perms($needed,$category)
{ {
if (!is_array($category) && !($category = self::$cache[$category])) if (!is_array($category) && !($category = self::read($category)))
{ {
return null; return null;
} }
// The user for the global cats has id self::GLOBAL_ACCOUNT, this one has full access to all global cats // The user for the global cats has id self::GLOBAL_ACCOUNT, this one has full access to all global cats
if ($this->account_id == self::GLOBAL_ACCOUNT && ($category['appname'] == self::GLOBAL_APPNAME if ($this->account_id == self::GLOBAL_ACCOUNT && ($category['appname'] == self::GLOBAL_APPNAME ||
|| $category['appname'] == $this->app_name && $category['owner'] == self::GLOBAL_ACCOUNT)) $category['appname'] == $this->app_name && self::is_global($category)))
{ {
//echo "<p>".__METHOD__."($needed,$category[name]) access because class instanciated for GLOBAL ACCOUNT</p>\n";
return true; return true;
} }
// Read access to global categories // Read access to global categories
if ($needed == EGW_ACL_READ && ($category['appname'] == self::GLOBAL_APPNAME if ($needed == EGW_ACL_READ && in_array($category['owner'],$this->global_owners) &&
|| $category['appname'] == $this->app_name && $category['owner'] == self::GLOBAL_ACCOUNT)) ($category['appname'] == self::GLOBAL_APPNAME || $category['appname'] == $this->app_name))
{ {
//echo "<p>".__METHOD__."($needed,$category[name]) access because global via memberships</p>\n";
return true; return true;
} }
@ -659,7 +673,7 @@ class categories
foreach($cats as $k => $cat) foreach($cats as $k => $cat)
{ {
$cats[$k]['weight'] = 100 * ($cat['name'] == $cat_name) + $cats[$k]['weight'] = 100 * ($cat['name'] == $cat_name) +
10 * ($cat['owner'] == $this->account_id ? 3 : ($cat['owner'] == self::GLOBAL_ACCOUNT ? 2 : 1)) + 10 * ($cat['owner'] == $this->account_id ? 3 : ($cat['owner'] <= self::GLOBAL_ACCOUNT ? 2 : 1)) +
($cat['appname'] != self::GLOBAL_APPNAME); ($cat['appname'] != self::GLOBAL_APPNAME);
} }
// sort heighest weight to the top // sort heighest weight to the top
@ -667,6 +681,19 @@ class categories
} }
return $cache[$cat['cat_name']] = (int) $cats[0]['id']; return $cache[$cat['cat_name']] = (int) $cats[0]['id'];
} }
/**
* Check if catgory is global (owner <= 0 || appname == 'phpgw')
*
* @param int|array $cat
* @return boolean
*/
static function is_global($cat)
{
if (!is_array($cat) && !($cat = self::read($cat))) return null; // cat not found
return $cat['owner'] <= self::GLOBAL_ACCOUNT || $cat['appname'] == self::GLOBAL_APPNAME;
}
/** /**
* return category information for a given id * return category information for a given id
@ -781,12 +808,27 @@ class categories
//error_log(__METHOD__."() ".count($cache)." cats restored: ".function_backtrace()); //error_log(__METHOD__."() ".count($cache)." cats restored: ".function_backtrace());
return self::$cache =& $cache; return self::$cache =& $cache;
} }
// check if we are already updated to global owner == 0, if not do it now
if (!$GLOBALS['egw']->db->select(self::TABLE,'COUNT(*)','cat_owner=0',__LINE__,__FILE__)->fetchColumn())
{
$GLOBALS['egw']->db->update(self::TABLE,'cat_owner=0','cat_owner=-1',__LINE__,__FILE__);
$GLOBALS['egw']->db->insert(self::TABLE,array(
'cat_main' => 0,
'cat_parent' => 0,
'cat_level' => 0,
'cat_owner' => 0,
'cat_appname' => '*update*',
'cat_name' => 'global=0',
'cat_description' => 'global=0',
),false,__LINE__,__FILE__);
}
self::$cache = array(); self::$cache = array();
// read all cats (cant use $this->db!) // read all cats (cant use $this->db!)
foreach($GLOBALS['egw']->db->select(self::TABLE,'*',false,__LINE__,__FILE__, foreach($GLOBALS['egw']->db->select(self::TABLE,'*',false,__LINE__,__FILE__,
false,'ORDER BY cat_main, cat_level, cat_name ASC') as $cat) false,'ORDER BY cat_main, cat_level, cat_name ASC') as $cat)
{ {
$cat = egw_db::strip_array_keys($cat,'cat_'); $cat = egw_db::strip_array_keys($cat,'cat_');
if ($cat['appname'] == '*update*') continue; // --> ignore update marker
$cat['app_name'] = $cat['appname']; $cat['app_name'] = $cat['appname'];
// backlink children to their parent // backlink children to their parent
if ($cat['parent']) if ($cat['parent'])
@ -898,7 +940,7 @@ class categories
} }
$s .= '>'.str_repeat('&nbsp;',$cat['level']); $s .= '>'.str_repeat('&nbsp;',$cat['level']);
$s .= $GLOBALS['egw']->strip_html($cat['name']); $s .= $GLOBALS['egw']->strip_html($cat['name']);
if ($cat['app_name'] == self::GLOBAL_APPNAME || $cat['owner'] == 'self::GLOBAL_ACCOUNT') if (self::is_global($cat))
{ {
$s .= ' &#9830;'; $s .= ' &#9830;';
} }