merged all category stuff, but r29061 - the group spezific global cats, to EPL-9.2 so it is now working well with an up to date EventMgr, still using the old db-format with cat_owner=-1 for global cats, it already uses the new global category UI in admin

This commit is contained in:
Ralf Becker 2010-02-04 02:20:55 +00:00
commit cc3c15d623
17 changed files with 902 additions and 1064 deletions

View File

@ -0,0 +1,327 @@
<?php
/**
* EGgroupware admin - Edit global categories
*
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @package admin
* @copyright (c) 2010 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
/**
* Edit global categories
*/
class admin_categories
{
/**
* Which methods of this class can be called as menuaction
*
* @var array
*/
public $public_functions = array(
'index' => true,
'edit' => true,
);
/**
* Path where the icons are stored (relative to webserver_url)
*/
const ICON_PATH = '/phpgwapi/images';
/**
* Stupid old admin ACL - dont think anybody uses or understands it ;-)
*
* @var boolean
*/
private static $acl_search;
private static $acl_add;
private static $acl_view;
private static $acl_edit;
private static $acl_delete;
private static $acl_add_sub;
/**
* Constructor
*/
function __construct()
{
if (!isset($GLOBALS['egw_info']['user']['apps']['admin']))
{
throw new egw_exception_no_permission_admin();
}
if ($GLOBALS['egw']->acl->check('global_categories_access',1,'admin'))
{
$GLOBALS['egw']->redirect_link('/index.php');
}
self::init_static();
}
/**
* Init static vars (static constructor)
*/
public static function init_static()
{
if (is_null(self::$acl_search))
{
self::$acl_search = !$GLOBALS['egw']->acl->check('global_categories_access',2,'admin');
self::$acl_add = !$GLOBALS['egw']->acl->check('global_categories_access',4,'admin');
self::$acl_view = !$GLOBALS['egw']->acl->check('global_categories_access',8,'admin');
self::$acl_edit = !$GLOBALS['egw']->acl->check('global_categories_access',16,'admin');
self::$acl_delete = !$GLOBALS['egw']->acl->check('global_categories_access',32,'admin');
self::$acl_add_sub= !$GLOBALS['egw']->acl->check('global_categories_access',64,'admin');
}
}
/**
* Edit / add a category
*
* @param array $content=null
* @param string $msg=''
*/
public function edit(array $content=null,$msg='')
{
if (!isset($content))
{
if (!(isset($_GET['cat_id']) && $_GET['cat_id'] > 0 &&
($content = categories::read($_GET['cat_id']))))
{
$content = array('data' => array());
if(isset($_GET['parent']) && $_GET['parent'] > 0)
{
$content['parent'] = (int)$_GET['parent'];
}
if (isset($_GET['appname']) && isset($GLOBALS['egw_info']['apps'][$_GET['appname']]))
{
$content['appname'] = $_GET['appname'];
}
else
{
$content['appname'] = categories::GLOBAL_APPNAME;
}
}
elseif (!self::$acl_edit)
{
// only allow to view category
$readonlys['__ALL__'] = true;
$readonlys['button[cancel]'] = false;
}
$content['base_url'] = self::icon_url();
$content['icon_url'] = $content['base_url'] . $content['data']['icon'];
}
elseif ($content['button'] || $content['delete'])
{
$cats = new categories(categories::GLOBAL_ACCOUNT,$content['appname']);
if ($content['delete']['delete'])
{
$button = 'delete';
$delete_subs = $content['delete']['subs'];
}
else
{
list($button) = each($content['button']);
unset($content['button']);
}
unset($content['delete']);
switch($button)
{
case 'save':
case 'apply':
if ($content['id'] && self::$acl_edit)
{
$cats->edit($content);
$msg = lang('Category saved.');
}
elseif (!$content['id'] && (
$content['parent'] && self::$acl_add_sub ||
!$content['parent'] && self::$acl_add))
{
$content['id'] = $cats->add($content);
$msg = lang('Category saved.');
}
else
{
$msg = lang('Permission denied!');
unset($button);
}
break;
case 'delete':
if (self::$acl_delete)
{
$cats->delete($content['id'],$delete_subs,!$delete_subs);
$msg = lang('Category deleted.');
}
else
{
$msg = lang('Permission denied!');
unset($button);
}
break;
}
$link = egw::link('/index.php',array(
'menuaction' => 'admin.admin_categories.index',
'msg' => $msg,
));
$js = "window.opener.location='$link';";
if ($button == 'save' || $button == 'delete')
{
echo "<html><head><script>\n$js;\nwindow.close();\n</script></head></html>\n";
common::egw_exit();
}
if (!empty($js)) $GLOBALS['egw']->js->set_onload($js);
}
$content['msg'] = $msg;
$sel_options['icon'] = self::get_icons();
$readonlys['button[delete]'] = !$content['id'] || !self::$acl_delete; // cant delete not yet saved category
$tmpl = new etemplate('admin.categories.edit');
$tmpl->exec('admin.admin_categories.edit',$content,$sel_options,$readonlys,$content+array(
'old_parent' => $content['old_parent'] ? $content['old_parent'] : $content['parent'],
),2);
}
/**
* Return URL of an icon, or base url with trailing slash
*
* @param string $icon='' filename
* @return string url
*/
static function icon_url($icon='')
{
return $GLOBALS['egw_info']['server']['webserver_url'].self::ICON_PATH.'/'.$icon;
}
/**
* Return icons from /phpgwapi/images
*
* @return array filename => label
*/
static function get_icons()
{
$dir = dir(EGW_SERVER_ROOT.self::ICON_PATH);
$icons = array();
while(($file = $dir->read()))
{
if (preg_match('/^(.*)\\.(png|gif|jpe?g)$/i',$file,$matches))
{
$icons[$file] = ucfirst($matches[1]);
}
}
$dir->close();
asort($icons);
return $icons;
}
/**
* query rows for the nextmatch widget
*
* @param array $query with keys 'start', 'search', 'order', 'sort', 'col_filter'
* @param array &$rows returned rows/competitions
* @param array &$readonlys eg. to disable buttons based on acl, not use here, maybe in a derived class
* @return int total number of rows
*/
static function get_rows($query,&$rows,&$readonlys)
{
self::init_static();
if (!isset($query['appname']))
{
throw new egw_exception_assertion_failed(__METHOD__.'($query,...) $query[appname] NOT set!');
}
egw_cache::setSession(__CLASS__,'nm',$query);
$cats = new categories(categories::GLOBAL_ACCOUNT,$query['appname']);
$rows = $cats->return_sorted_array($query['start'],$query['num_rows'],$query['search'],$query['sort'],$query['order'],true,0,true);
foreach($rows as &$row)
{
$row['level_spacer'] = str_repeat('&nbsp; &nbsp; ',$row['level']);
if ($row['data']['icon']) $row['icon_url'] = self::icon_url($row['data']['icon']);
$row['subs'] = count($row['children']);
$row['class'] = 'level'.$row['level'];
$readonlys["edit[$row[id]]"] = !self::$acl_edit;
$readonlys["add[$row[id]]"] = !self::$acl_add_sub;
$readonlys["delete[$row[id]]"] = !self::$acl_delete;
}
// make appname available for actions
$rows['appname'] = $query['appname'];
$GLOBALS['egw_info']['flags']['app_header'] = lang('Admin').' - '.lang('Global categories').
($query['appname'] != categories::GLOBAL_APPNAME ? ': '.lang($query['appname']) : '');
return $cats->total_records;
}
/**
* Display the accesslog
*
* @param array $content=null
* @param string $msg=''
*/
public function index(array $content=null,$msg='')
{
//_debug_array($content);
if(!isset($content))
{
if (isset($_GET['msg'])) $msg = $_GET['msg'];
$content['nm'] = egw_cache::getSession(__CLASS__,'nm');
if (!is_array($content['nm']))
{
$content['nm'] = array(
'get_rows' => 'admin_categories::get_rows', // I method/callback to request the data for the rows eg. 'notes.bo.get_rows'
'no_filter' => True, // I disable the 1. filter
'no_filter2' => True, // I disable the 2. filter (params are the same as for filter)
'no_cat' => True, // I disable the cat-selectbox
'header_left' => false, // I template to show left of the range-value, left-aligned (optional)
'header_right' => false, // I template to show right of the range-value, right-aligned (optional)
'never_hide' => True, // I never hide the nextmatch-line if less then maxmatch entries
'lettersearch' => false, // I show a lettersearch
'start' => 0, // IO position in list
'order' => 'name', // IO name of the column to sort after (optional for the sortheaders)
'sort' => 'ASC', // IO direction of the sort: 'ASC' or 'DESC'
'default_cols' => '!color,last_mod,subs', // I columns to use if there's no user or default pref (! as first char uses all but the named columns), default all columns
'csv_fields' => false, // I false=disable csv export, true or unset=enable it with auto-detected fieldnames,
//or array with name=>label or name=>array('label'=>label,'type'=>type) pairs (type is a eT widget-type)
'appname' => categories::GLOBAL_APPNAME,
'no_search' => !self::$acl_search,
);
}
if (isset($_GET['appname']) && ($_GET['appname'] == categories::GLOBAL_APPNAME ||
isset($GLOBALS['egw_info']['apps'][$_GET['appname']])))
{
$content['nm']['appname'] = $_GET['appname'];
}
}
else
{
if($content['delete']['delete'])
{
$cats = new categories(categories::GLOBAL_ACCOUNT,$content['nm']['appname']);
$cats->delete($content['delete']['cat_id'],$content['delete']['subs'],!$content['delete']['subs']);
$msg = lang('Category deleted.');
}
unset($content['delete']);
}
$content['msg'] = $msg;
$readonlys['add'] = !self::$acl_add;
$tmpl = new etemplate('admin.categories.index');
$tmpl->exec('admin.admin_categories.index',$content,$sel_options,$readonlys,array(
'nm' => $content['nm'],
));
}
}
admin_categories::init_static();

View File

@ -60,7 +60,7 @@ class admin_prefs_sidebox_hooks
if (! $GLOBALS['egw']->acl->check('global_categories_access',1,'admin'))
{
$file['Global Categories'] = egw::link('/index.php','menuaction=admin.uicategories.index');
$file['Global Categories'] = egw::link('/index.php','menuaction=admin.admin_categories.index&appname=phpgw');
}
if (!$GLOBALS['egw']->acl->check('mainscreen_message_access',1,'admin') || !$GLOBALS['egw']->acl->check('mainscreen_message_access',2,'admin'))

View File

@ -1,150 +0,0 @@
<?php
/**************************************************************************\
* eGroupWare - Admin - Global categories *
* http://www.egroupware.org *
* Written by Bettina Gille [ceb@phpgroupware.org] *
* ----------------------------------------------- *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License, or (at your *
* option) any later version. *
\**************************************************************************/
/* $Id$ */
/* $Source$ */
class bocategories
{
var $cats;
var $start;
var $query;
var $sort;
var $order;
var $filter;
var $cat_id;
var $total;
var $debug = False;
function bocategories()
{
if ($_REQUEST['appname'])
{
$this->cats =& CreateObject('phpgwapi.categories',-1,$_REQUEST['appname']);
}
else
{
$this->cats =& CreateObject('phpgwapi.categories',$GLOBALS['egw_info']['user']['account_id'],'phpgw');
}
$this->read_sessiondata();
foreach(array('start','query','sort','order','cat_id') as $name)
{
if (isset($_REQUEST[$name])) $this->$name = $_REQUEST[$name];
}
}
function save_sessiondata($data)
{
if($this->debug) { echo '<br>Save:'; _debug_array($data); }
//echo '<p>'.__METHOD__."() start=$this->start, sort=$this->sort, order=$this->order, query=$this->query</p>\n";
$GLOBALS['egw']->session->appsession('session_data','admin_cats',$data);
}
function read_sessiondata()
{
$data = $GLOBALS['egw']->session->appsession('session_data','admin_cats');
if($this->debug) { echo '<br>Read:'; _debug_array($data); }
$this->start = $data['start'];
$this->query = $data['query'];
$this->sort = $data['sort'];
$this->order = $data['order'];
if(isset($data['cat_id']))
{
$this->cat_id = $data['cat_id'];
}
//echo '<p>'.__METHOD__."() start=$this->start, sort=$this->sort, order=$this->order, query=$this->query</p>\n";
}
function get_list()
{
if($this->debug) { echo '<br>querying: "' . $this->query . '"'; }
//echo '<p>'.__METHOD__."() start=$this->start, sort=$this->sort, order=$this->order, query=$this->query</p>\n";
return $this->cats->return_sorted_array($this->start,True,$this->query,$this->sort,$this->order,True);
}
function save_cat($values)
{
if ($values['id'] && $values['id'] != 0)
{
return $this->cats->edit($values);
}
else
{
return $this->cats->add($values);
}
}
function exists($data)
{
$data['type'] = $data['type'] ? $data['type'] : '';
$data['cat_id'] = $data['cat_id'] ? $data['cat_id'] : '';
return $this->cats->exists($data['type'],$data['cat_name'],$data['type'] == 'subs' ? 0 : $data['cat_id'],$data['type'] != 'subs' ? 0 : $data['cat_id']);
}
function formatted_list($data)
{
return $this->cats->formatted_list($data['select'],$data['all'],$data['cat_parent'],True);
}
function delete($cat_id,$subs=False)
{
return $this->cats->delete($cat_id,$subs,!$subs); // either delete the subs or modify them
}
function check_values($values)
{
if (strlen($values['descr']) >= 255)
{
$error[] = lang('Description can not exceed 255 characters in length !');
}
if (!$values['name'])
{
$error[] = lang('Please enter a name');
}
else
{
if (!$values['parent'])
{
$exists = $this->exists(array
(
'type' => 'appandmains',
'cat_name' => $values['name'],
'cat_id' => $values['id']
));
}
else
{
$exists = $this->exists(array
(
'type' => 'appandsubs',
'cat_name' => $values['name'],
'cat_id' => $values['id']
));
}
if ($exists == True)
{
$error[] = lang('That name has been used already');
}
}
if (is_array($error))
{
return $error;
}
}
}

View File

@ -1,568 +0,0 @@
<?php
/**************************************************************************\
* eGroupWare - Admin - Global categories *
* http://www.egroupware.org *
* Written by Bettina Gille [ceb@phpgroupware.org] *
* Simplified ;-) and icon & color added by RalfBecker@outdoor-training.de *
* ----------------------------------------------- *
* Copyright 2000 - 2003 Free Software Foundation, Inc *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License, or (at your *
* option) any later version. *
\**************************************************************************/
/* $Id$ */
class uicategories
{
var $bo;
var $template;
var $start;
var $query;
var $sort;
var $order;
var $cat_id;
var $debug = False;
var $public_functions = array
(
'index' => True,
'edit' => True,
'delete' => True
);
function uicategories()
{
if ($GLOBALS['egw']->acl->check('global_categories_access',1,'admin'))
{
$GLOBALS['egw']->redirect_link('/index.php');
}
$this->bo =& CreateObject('admin.bocategories');
$this->template = $GLOBALS['egw']->template;
$this->nextmatchs =& CreateObject('phpgwapi.nextmatchs');
$this->acl_search = !$GLOBALS['egw']->acl->check('global_categories_access',2,'admin');
$this->acl_add = !$GLOBALS['egw']->acl->check('global_categories_access',4,'admin');
$this->acl_view = !$GLOBALS['egw']->acl->check('global_categories_access',8,'admin');
$this->acl_edit = !$GLOBALS['egw']->acl->check('global_categories_access',16,'admin');
$this->acl_delete = !$GLOBALS['egw']->acl->check('global_categories_access',32,'admin');
$this->acl_add_sub= !$GLOBALS['egw']->acl->check('global_categories_access',64,'admin');
$GLOBALS['egw']->js->validate_file('jscode','openwindow','admin');
$this->appname = get_var('appname',array('GET','POST'));
$GLOBALS['egw_info']['flags']['app_header'] = $GLOBALS['egw_info']['apps'][$this->appname ? $this->appname : 'admin']['title'];
$this->start = $this->bo->start;
$this->query = $this->bo->query;
$this->sort = $this->bo->sort;
$this->order = $this->bo->order;
$this->cat_id = $this->bo->cat_id;
if($this->debug) { $this->_debug_sqsof(); }
$dir = dir(EGW_SERVER_ROOT.'/phpgwapi/images');
while($file = $dir->read())
{
if (preg_match('/\\.(png|gif|jpe?g)$/i',$file))
{
$this->icons[] = $file;
}
}
$dir->close();
sort($this->icons);
$this->img_url = $GLOBALS['egw_info']['server']['webserver_url'].'/phpgwapi/images/';
}
function _debug_sqsof()
{
$data = array(
'start' => $this->start,
'query' => $this->query,
'sort' => $this->sort,
'order' => $this->order,
'cat_id' => $this->cat_id
);
echo '<br>UI:<br>';
_debug_array($data);
}
function save_sessiondata()
{
$data = array
(
'start' => $this->start,
'query' => $this->query,
'sort' => $this->sort,
'order' => $this->order
);
if(isset($this->cat_id))
{
$data['cat_id'] = $this->cat_id;
}
$this->bo->save_sessiondata($data);
}
function set_langs()
{
$this->template->set_var('lang_save',lang('Save'));
$this->template->set_var('lang_search',lang('Search'));
$this->template->set_var('lang_sub',lang('Add sub'));
$this->template->set_var('lang_icon',lang('icon'));
$this->template->set_var('lang_edit',lang('Edit'));
$this->template->set_var('lang_delete',lang('Delete'));
$this->template->set_var('lang_parent',lang('Parent category'));
$this->template->set_var('lang_none',lang('None'));
$this->template->set_var('lang_name',lang('Name'));
$this->template->set_var('lang_descr',lang('Description'));
$this->template->set_var('lang_add',lang('Add'));
$this->template->set_var('lang_reset',lang('Clear Form'));
$this->template->set_var('lang_cancel',lang('Cancel'));
$this->template->set_var('lang_done',lang('Done'));
$this->template->set_var('lang_color',lang('Color'));
$this->template->set_var('lang_icon',lang('Icon'));
}
function index()
{
$link_data = array
(
'menuaction' => 'admin.uicategories.edit',
'appname' => $this->appname
);
if ($_POST['add'])
{
$GLOBALS['egw']->redirect_link('/index.php',$link_data);
}
if ($_POST['done'])
{
$GLOBALS['egw']->redirect_link('/admin/index.php');
}
$this->template->set_file(array('cat_list_t' => 'listcats.tpl'));
$this->template->set_block('cat_list_t','cat_list','list');
if (!$this->acl_add)
{
$this->template->set_block('cat_list_t','add','addhandle');
}
if (!$this->acl_search)
{
$this->template->set_block('cat_list_t','search','searchhandle');
}
$GLOBALS['egw_info']['flags']['app_header'] .= ' - '.lang('Global categories');
$GLOBALS['egw']->common->egw_header();
echo parse_navbar();
$this->set_langs();
$this->template->set_var('query',$this->query);
$link_data['menuaction'] = 'admin.uicategories.index';
$this->template->set_var('action_url',$GLOBALS['egw']->link('/index.php',$link_data));
if(!$start)
{
$start = 0;
}
$cats = $this->bo->get_list();
if (!is_array($cats)) $cats = array();
$left = $this->nextmatchs->left('/index.php',$this->start,$this->bo->cats->total_records,$link_data);
$right = $this->nextmatchs->right('/index.php',$this->start,$this->bo->cats->total_records,$link_data);
$this->template->set_var('left',$left);
$this->template->set_var('right',$right);
$this->template->set_var('lang_showing',$this->nextmatchs->show_hits($this->bo->cats->total_records,$this->start));
$this->template->set_var('sort_name',$this->nextmatchs->show_sort_order($this->sort,'cat_name',$this->order,'/index.php',lang('Name'),$link_data));
$this->template->set_var('sort_description',$this->nextmatchs->show_sort_order($this->sort,'cat_description',$this->order,'/index.php',lang('Description'),$link_data));
foreach($cats as $cat)
{
$data = unserialize($cat['data']);
if ($data['color'])
{
$this->template->set_var('td_color',$data['color']);
$gray = (hexdec(substr($data['color'],1,2))+hexdec(substr($data['color'],3,2))+hexdec(substr($data['color'],5,2)))/3;
}
else
{
$this->template->set_var('td_color','');
//$this->nextmatchs->template_alternate_row_color($this->template);
$gray = 255;
}
//else
//{
$this->nextmatchs->template_alternate_row_color($this->template);
$gray = 255;
// }
$this->template->set_var('color',$gray < 128 ? 'style="color: white;"' : '');
$id = $cat['id'];
$level = $cat['level'];
$cat_name = $GLOBALS['egw']->strip_html($cat['name']);
if ($level > 0)
{
$space = '&nbsp;&nbsp;';
$spaceset = str_repeat($space,$level);
$cat_name = $spaceset . $cat_name;
}
$descr = $GLOBALS['egw']->strip_html($cat['description']);
if (!$descr) { $descr = '&nbsp;'; }
if ($level == 0)
{
$cat_name = '<font color="FF0000"><b>' . $cat_name . '</b></font>';
$descr = '<font color="FF0000"><b>' . $descr . '</b></font>';
}
if ($this->appname && $cat['app_name'] == 'phpgw')
{
$appendix = '&lt;' . lang('Global') . '&gt;';
}
else
{
$appendix = '';
}
$this->template->set_var(array
(
'name' => $cat_name . $appendix,
'descr' => $descr
));
if ($this->acl_add_sub)
{
$link_data['menuaction'] = 'admin.uicategories.edit';
$link_data['cat_parent'] = $id;
unset($link_data['cat_id']);
$this->template->set_var('add_sub','<a href="'.$GLOBALS['egw']->link('/index.php',$link_data).'">'.
lang('Add sub').'</a>');
}
if ($this->appname && $cat['app_name'] == $this->appname)
{
$show_edit_del = True;
}
elseif(!$this->appname && $cat['app_name'] == 'phpgw')
{
$show_edit_del = True;
}
else
{
$show_edit_del = False;
}
$link_data['cat_id'] = $id;
unset($link_data['cat_parent']);
if ($show_edit_del && $this->acl_edit)
{
$link_data['menuaction'] = 'admin.uicategories.edit';
$this->template->set_var('edit','<a href="'.$GLOBALS['egw']->link('/index.php',$link_data).'">'.
lang('Edit').'</a>');
}
else
{
$this->template->set_var('edit','');
}
if ($show_edit_del && $this->acl_delete)
{
$link_data['menuaction'] = 'admin.uicategories.delete';
$this->template->set_var('delete','<a href="'.$GLOBALS['egw']->link('/index.php',$link_data).'">'.
lang('Delete').'</a>');
}
else
{
$this->template->set_var('delete','');
}
$data = unserialize($cat['data']);
$icon = $data['icon'];
$dir_img = $GLOBALS['egw_info']['server']['webserver_url'] . SEP . 'phpgwapi' . SEP . 'images' . SEP;
if (strlen($icon) > 0)
$this->template->set_var('icon', "<img src='". $dir_img . $icon ."'>");
else
$this->template->set_var('icon', "&nbsp;");
$this->template->fp('list','cat_list',True);
}
$link_data['menuaction'] = 'admin.uicategories.edit';
unset($link_data['cat_id']);
unset($link_data['cat_parent']);
$this->template->set_var('add_action',$GLOBALS['egw']->link('/index.php',$link_data));
$this->save_sessiondata();
$this->template->pfp('out','cat_list_t',True);
}
function edit()
{
if (!preg_match('/^(#[0-9a-f]+|[a-z]+)?$/i',$_POST['cat_data']['color'])) unset($_POST['cat_data']['color']);
if (!preg_match('/^[-_\.a-z0-9]+\.(png|gif|jpe?g)$/i',$_POST['cat_data']['icon'])) unset($_POST['cat_data']['icon']);
$new_parent = (int)$_POST['new_parent'];
$cat_parent = (int)$_POST['cat_parent'];
$cat_name = $_POST['cat_name'];
$cat_description = $_POST['cat_description'];
$cat_data = $_POST['cat_data'];
$old_parent = (int)$_POST['old_parent'];
if ($new_parent)
{
$cat_parent = $new_parent;
}
$link_data = array
(
'menuaction' => 'admin.uicategories.index',
'appname' => $this->appname
);
if (!$this->acl_add && $cat_parent == 0 || !$this->acl_add_sub && $cat_parent != 0)
{
$GLOBALS['egw']->redirect_link('/index.php');
}
if ($_POST['cancel'] || $this->cat_id && !$this->acl_edit || $this->cat_id &&
(!$this->acl_add && $cat_parent == 0 || !$this->acl_add_sub && $cat_parent != 0))
{
$GLOBALS['egw']->redirect_link('/index.php',$link_data);
}
if ($_POST['save'])
{
$data = serialize($cat_data);
$values = array
(
'parent' => $cat_parent,
'descr' => $cat_description,
'name' => $cat_name,
'access' => 'public',
'data' => $data
);
if ($this->cat_id)
{
$values['id'] = $this->cat_id;
$values['old_parent'] = $old_parent;
}
$error = $this->bo->check_values($values);
if (is_array($error))
{
$this->template->set_var('message',$GLOBALS['egw']->common->error_list($error));
}
else
{
$this->cat_id = $this->bo->save_cat($values);
$GLOBALS['egw']->redirect_link('/index.php',$link_data);
}
}
$GLOBALS['egw_info']['flags']['app_header'] .= ' - '.($this->cat_id ? lang('Edit global category'):lang('Add global category'));
$this->set_langs();
$this->template->set_file(array('form' => 'category_form.tpl'));
if ($this->cat_id)
{
list($cat) = $this->bo->cats->return_single($this->cat_id);
$cat['data'] = unserialize($cat['data']);
}
else
{
$cat = array();
$cat['parent'] = $_GET['cat_parent'];
}
// update the old calendar color format, color was added to the description
if (preg_match('/(#[0-9a-fA-F]{6})\n?$/',$cat['description'],$matches))
{
$cat['data']['color'] = $matches[1];
$cat['description'] = str_replace($matches[1],'',$cat['description']);
}
$hidden_vars = '<input type="hidden" name="cat_id" value="' . $this->cat_id . '">' . "\n" .
'<input type="hidden" name="old_parent" value="' . $cat['parent'] . '">' . "\n";
$link_data['menuaction'] = 'admin.uicategories.edit';
$link_data['cat_id'] = $this->cat_id;
$this->template->set_var('action_url',$GLOBALS['egw']->link('/index.php',$link_data));
if ($this->acl_delete)
{
$link_data['menuaction'] = 'admin.uicategories.delete';
$this->template->set_var('delete','<form method="POST" action="' . $GLOBALS['egw']->link('/index.php',$link_data)
. '"><input type="submit" value="' . lang('Delete') .'"></form>');
}
else
{
$this->template->set_var('delete','&nbsp;');
}
$this->template->set_var('cat_name',$GLOBALS['egw']->strip_html($cat['name']));
$this->template->set_var('cat_description',$GLOBALS['egw']->strip_html($cat['description']));
$this->template->set_var('category_list',$this->bo->cats->formatted_list(array('selected' => $cat['parent'],'self' => $this->cat_id)));
$this->template->set_var('color',html::inputColor('cat_data[color]',$cat['data']['color'],lang('Click to select a color')));
//$options = '<option value=""'.(!$cat['data']['icon'] ? ' selected="1"':'').'>'.lang('none')."</options>\n";
$options = '';
$options = '<option value="">'.lang('none')."</options>\n";
foreach ($this->icons as $icon)
{
$options .= '<option value="'.$icon.'"'.($icon == $cat['data']['icon'] ? ' selected="1"':'').'>'.
ucfirst(preg_replace('/\\.(png|gif|jpe?g)$/i','',$icon))."</option>\n";
}
$this->template->set_var('select_icon', '<select name="cat_data[icon]" onchange="document.images[\'icon\'].src=\''.$this->img_url.'\' + this.value;">'.$options."</select>\n");
$this->template->set_var('icon','<img id="icon" src="'. $this->img_url.$cat['data']['icon'] .'">');
$already_done = array('icon','color');
if ($extra)
{
foreach(explode(',',$extra) as $i => $name)
{
$this->template->set_var('class',($i & 1) ? 'row_on' : 'row_off');
$this->template->set_var('td_data','<input name="cat_data[' . htmlspecialchars($name) . ']" size="50" value="' . htmlspecialchars($cat['data'][$name]) . '">');
$this->template->set_var('lang_data',lang($name));
$this->template->fp('row','data_row',True);
$already_done[] = $name;
}
}
// preserv everything in the data array, not already shown via extra
if (is_array($cat['data']))
{
foreach($cat['data'] as $name => $value)
{
if (!in_array($name,$already_done))
{
$hidden_vars .= '<input type="hidden" name="cat_data['.htmlspecialchars($name).']" value="' . htmlspecialchars($value) . '">';
}
}
}
$this->template->set_var('hidden_vars',$hidden_vars);
$GLOBALS['egw']->common->egw_header();
echo parse_navbar();
$this->template->pfp('out','form');
}
function delete()
{
if (!$this->acl_delete)
{
$GLOBALS['egw']->redirect_link('/index.php');
}
$link_data = array
(
'menuaction' => 'admin.uicategories.index',
'appname' => $this->appname
);
if (!$this->cat_id || $_POST['cancel'])
{
$GLOBALS['egw']->redirect_link('/index.php',$link_data);
}
if ($_POST['confirm'])
{
if ($_POST['subs'])
{
$this->bo->delete($this->cat_id,True);
}
else
{
$this->bo->delete($this->cat_id,False);
}
$GLOBALS['egw']->redirect_link('/index.php',$link_data);
}
$this->template->set_file(array('category_delete' => 'delete_cat.tpl'));
if ($this->appname)
{
$type = 'noglobalapp';
}
else
{
$type = 'noglobal';
}
$apps_cats = $this->bo->exists(array
(
'type' => $type,
'cat_name' => '',
'cat_id' => $this->cat_id
));
$GLOBALS['egw_info']['flags']['app_header'] .= ' - '.lang('Delete category');
$GLOBALS['egw']->js->validate_file('jscode','openwindow','admin');
$GLOBALS['egw']->common->egw_header();
echo parse_navbar();
$hidden_vars = '<input type="hidden" name="cat_id" value="' . $this->cat_id . '">' . "\n";
$this->template->set_var('hidden_vars',$hidden_vars);
$cats = $this->bo->cats->return_single($this->cat_id);
$this->template->set_var('cat_name',$cat['name']);
if ($apps_cats)
{
$this->template->set_block('category_delete','delete','deletehandle');
$this->template->set_var('messages',lang('This category is currently being used by applications as a parent category') . '<br>'
. lang('You will need to remove the subcategories before you can delete this category'));
$this->template->set_var('lang_subs','');
$this->template->set_var('subs','');
$this->template->set_var('nolink',$nolink);
$this->template->set_var('deletehandle','');
$this->template->set_var('donehandle','');
$this->template->set_var('lang_ok',lang('Ok'));
$this->template->pfp('out','category_delete');
}
else
{
$this->template->set_block('category_delete','done','donehandle');
$this->template->set_var('messages',lang('Are you sure you want to delete this category ?'));
$exists = $this->bo->exists(array
(
'type' => 'subs',
'cat_name' => '',
'cat_id' => $this->cat_id
));
if ($exists)
{
$this->template->set_var('lang_subs',lang('Do you also want to delete all global subcategories ?'));
$this->template->set_var('subs','<input type="checkbox" name="subs" value="True">');
}
else
{
$this->template->set_var('lang_subs','');
$this->template->set_var('subs', '');
}
$link_data['menuaction'] = 'admin.uicategories.delete';
$link_data['cat_id'] = $this->cat_id;
$this->template->set_var('action_url',$GLOBALS['egw']->link('/index.php',$link_data));
$this->template->set_var('lang_yes',lang('Yes'));
$this->template->set_var('lang_no',lang('No'));
$this->template->pfp('out','category_delete');
}
}
}
?>

View File

@ -1,18 +1,14 @@
<?php
/**************************************************************************\
* eGroupWare - administration *
* http://www.egroupware.org *
* Written by Joseph Engo <jengo@phpgroupware.org> *
* Modified by Stephen Brown <steve@dataclarity.net> *
* to distribute admin across the application directories *
* -------------------------------------------- *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License, or (at your *
* option) any later version. *
\**************************************************************************/
/* $Id$ */
/**
* EGgroupware administration
*
* @link http://www.egroupware.org
* @author Joseph Engo <jengo@phpgroupware.org>
* @author Stephen Brown <steve@dataclarity.net> distribute admin across the application directories
* @package admin
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
$GLOBALS['egw_info'] = array(
'flags' => array(
@ -78,7 +74,7 @@
if(is_array($file))
{
section_start($appname,
$GLOBALS['egw']->common->image(
common::image(
$appname,
Array(
'navbar',
@ -100,8 +96,7 @@
}
}
$GLOBALS['egw']->hooks->process('admin');
$GLOBALS['egw']->hooks->process('admin',array('admin'));
$GLOBALS['admin_tpl']->pparse('out','list');
$GLOBALS['egw']->common->egw_footer();
?>
common::egw_footer();

View File

@ -2,7 +2,7 @@
/**
* eGroupWare - eTemplates for Application admin
* http://www.egroupware.org
* generated by soetemplate::dump4setup() 2009-11-17 10:01
* generated by soetemplate::dump4setup() 2010-01-31 00:50
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package admin
@ -18,6 +18,27 @@ $templ_data[] = array('name' => 'admin.accesslog.get_rows','template' => '','lan
$templ_data[] = array('name' => 'admin.accesslog.rows','template' => '','lang' => '','group' => '0','version' => '1.7.002','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:3:{s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";s:1:"H";s:2:"1%";}i:1;a:8:{s:1:"A";a:3:{s:4:"type";s:23:"nextmatch-accountfilter";s:4:"size";s:7:"LoginID";s:4:"name";s:10:"account_id";}s:1:"B";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:12:"Login-Status";s:4:"name";s:13:"sessionstatus";}s:1:"C";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:7:"Loginid";s:4:"name";s:7:"loginid";}s:1:"D";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:2:"IP";s:4:"name";s:2:"ip";}s:1:"E";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:5:"Login";s:4:"name";s:2:"li";}s:1:"F";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:6:"Logout";s:4:"name";s:2:"lo";}s:1:"G";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:5:"Total";s:4:"name";s:5:"total";}s:1:"H";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:3:{s:4:"type";s:5:"label";s:5:"label";s:6:"Action";s:5:"align";s:6:"center";}i:2;a:4:{s:4:"type";s:10:"buttononly";s:4:"size";s:5:"check";s:5:"label";s:10:"Select all";s:7:"onclick";s:61:"toggle_all(this.form,form::name(\'selected[]\')); return false;";}}}i:2;a:8:{s:1:"A";a:3:{s:4:"type";s:14:"select-account";s:4:"name";s:18:"${row}[account_id]";s:8:"readonly";s:1:"1";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:4:"name";s:21:"${row}[sessionstatus]";}s:1:"C";a:2:{s:4:"type";s:5:"label";s:4:"name";s:15:"${row}[loginid]";}s:1:"D";a:2:{s:4:"type";s:5:"label";s:4:"name";s:10:"${row}[ip]";}s:1:"E";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:10:"${row}[li]";s:8:"readonly";s:1:"1";}s:1:"F";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:10:"${row}[lo]";s:8:"readonly";s:1:"1";}s:1:"G";a:4:{s:4:"type";s:13:"date-duration";s:4:"name";s:13:"${row}[total]";s:8:"readonly";s:1:"1";s:4:"size";s:6:",hm,24";}s:1:"H";a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:6:{s:4:"type";s:6:"button";s:4:"size";s:6:"delete";s:5:"label";s:6:"Delete";s:4:"name";s:28:"delete[$row_cont[sessionid]]";s:4:"help";s:21:"Delete this log entry";s:7:"onclick";s:40:"return confirm(\'Delete this log entry\');";}i:2;a:3:{s:4:"type";s:8:"checkbox";s:4:"size";s:20:"$row_cont[sessionid]";s:4:"name";s:10:"selected[]";}s:5:"align";s:6:"center";}}}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' => '1254816462',);
$templ_data[] = array('name' => 'admin.categories.delete','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:2:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:5:{s:4:"type";s:8:"groupbox";s:4:"size";s:1:"1";s:5:"label";s:20:"Delete this category";i:1;a:5:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:3:{s:2:"h3";s:2:"40";s:2:"h1";s:2:"30";s:2:"c2";s:11:"confirmSubs";}i:1;a:2:{s:1:"A";a:4:{s:4:"type";s:5:"label";s:4:"span";s:3:"all";s:5:"label";s:47:"Are you sure you want to delete this category ?";s:5:"align";s:6:"center";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:5:{s:4:"type";s:8:"checkbox";s:5:"label";s:53:"Do you also want to delete all global subcategories ?";s:4:"name";s:12:"delete[subs]";s:4:"span";s:3:"all";s:5:"align";s:6:"center";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:3;a:2:{s:1:"A";a:4:{s:4:"type";s:6:"button";s:5:"label";s:6:"Delete";s:4:"name";s:14:"delete[delete]";s:5:"align";s:6:"center";}s:1:"B";a:5:{s:4:"type";s:10:"buttononly";s:5:"label";s:6:"Cancel";s:4:"name";s:14:"delete[cancel]";s:5:"align";s:6:"center";s:7:"onclick";s:64:"set_style_by_class(\'fieldset\',\'confirmDelete\',\'display\',\'none\');";}}}s:4:"rows";i:3;s:4:"cols";i:2;s:7:"options";a:0:{}}s:4:"span";s:14:",confirmDelete";}}}s:4:"rows";i:1;s:4:"cols";i:1;}i:1;a:3:{s:4:"type";s:4:"text";s:4:"name";s:14:"delete[cat_id]";s:4:"span";s:12:",hiddenCatid";}}','size' => '','style' => '.confirmDelete {
position: absolute;
left: 120px;
top: 80px;
background-color: white;
display: none;
border: 2px solid black;
}
.hiddenCatid {
display: none;
}
.confirmSubs
{
}','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.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.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.rows','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:3:{i:0;a:3:{s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";s:2:"h2";s:4:",!@1";}i:1;a:10:{s:1:"A";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:5:"Title";s:4:"name";s:5:"title";}s:1:"B";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:9:"Requested";s:4:"name";s:9:"requested";}s:1:"C";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:9:"Scheduled";s:4:"name";s:13:"cmd_scheduled";}s:1:"D";a:3:{s:4:"type";s:22:"nextmatch-filterheader";s:4:"size";s:6:"Remote";s:4:"name";s:9:"remote_id";}s:1:"E";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:7:"Created";s:4:"name";s:11:"cmd_created";}s:1:"F";a:3:{s:4:"type";s:23:"nextmatch-accountfilter";s:4:"name";s:7:"creator";s:4:"size";s:7:"Creator";}s:1:"G";a:3:{s:4:"type";s:22:"nextmatch-filterheader";s:4:"name";s:6:"status";s:4:"size";s:6:"Status";}s:1:"H";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"Modified";s:4:"name";s:12:"cmd_modified";}s:1:"I";a:3:{s:4:"type";s:23:"nextmatch-accountfilter";s:4:"size";s:8:"Modifier";s:4:"name";s:8:"modifier";}s:1:"J";a:1:{s:4:"type";s:5:"label";}}i:2;a:10:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:4:"name";s:13:"${row}[title]";}s:1:"B";a:4:{s:4:"type";s:9:"url-email";s:4:"name";s:17:"${row}[requested]";s:4:"size";s:29:",,,$row_cont[requested_email]";s:8:"readonly";s:1:"1";}s:1:"C";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:17:"${row}[scheduled]";s:8:"readonly";s:1:"1";}s:1:"D";a:3:{s:4:"type";s:6:"select";s:4:"name";s:17:"${row}[remote_id]";s:8:"readonly";s:1:"1";}s:1:"E";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:15:"${row}[created]";s:8:"readonly";s:1:"1";}s:1:"F";a:4:{s:4:"type";s:9:"url-email";s:4:"name";s:15:"${row}[creator]";s:4:"size";s:27:",,,$row_cont[creator_email]";s:8:"readonly";s:1:"1";}s:1:"G";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:6:"2,,0,0";i:1;a:3:{s:4:"type";s:6:"select";s:4:"name";s:14:"${row}[status]";s:8:"readonly";s:1:"1";}i:2;a:3:{s:4:"type";s:5:"label";s:4:"name";s:13:"${row}[error]";s:4:"span";s:10:",redItalic";}}s:1:"H";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:16:"${row}[modified]";s:8:"readonly";s:1:"1";}s:1:"I";a:4:{s:4:"type";s:9:"url-email";s:4:"name";s:16:"${row}[modifier]";s:8:"readonly";s:1:"1";s:4:"size";s:28:",,,$row_cont[modifier_email]";}s:1:"J";a:6:{s:4:"type";s:6:"button";s:4:"size";s:6:"delete";s:5:"label";s:6:"Cancel";s:4:"name";s:21:"delete[$row_cont[id]]";s:4:"help";s:29:"Cancel this scheduled command";s:7:"onclick";s:48:"return confirm(\'Cancel this scheduled command\');";}}}s:4:"rows";i:2;s:4:"cols";i:10;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1195518170',);

View File

@ -0,0 +1,115 @@
<?xml version="1.0"?>
<!-- $Id$ -->
<overlay>
<template id="admin.categories.delete" template="" lang="" group="0" version="1.7.001">
<grid>
<columns>
<column/>
</columns>
<rows>
<row>
<groupbox class="confirmDelete">
<caption label="Delete this category"/>
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row height="30">
<description span="all" value="Are you sure you want to delete this category ?" align="center"/>
</row>
<row class="confirmSubs">
<checkbox label="Do you also want to delete all global subcategories ?" id="delete[subs]" span="all" align="center"/>
</row>
<row height="40">
<button label="Delete" id="delete[delete]" align="center"/>
<buttononly label="Cancel" id="delete[cancel]" align="center" onclick="set_style_by_class('fieldset','confirmDelete','display','none');"/>
</row>
</rows>
</grid>
</groupbox>
</row>
</rows>
</grid>
<textbox id="delete[cat_id]" class="hiddenCatid"/>
<styles>
.confirmDelete {
position: absolute;
left: 120px;
top: 80px;
background-color: white;
display: none;
border: 2px solid black;
}
.hiddenCatid {
display: none;
}
.confirmSubs
{
}
</styles>
</template>
<template id="admin.categories.edit" template="" lang="" group="0" version="1.7.001">
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row disabled="!@msg">
<description span="all" class="redItalic" align="center" id="msg"/>
<description/>
</row>
<row class="th" height="25">
<description options=",,,parent" value="Parent category"/>
<menulist>
<menupopup type="select-cat" options="None,,,$cont[appname],,-1" id="parent"/>
</menulist>
</row>
<row class="row">
<description options=",,,name" value="Name"/>
<textbox size="50" maxlength="150" id="name"/>
</row>
<row class="row" valign="top">
<description options=",,,description" value="Description"/>
<textbox multiline="true" rows="5" cols="50" id="description"/>
</row>
<row class="row">
<description options=",,,cat_data[color]" value="Color"/>
<colorpicker id="data[color]"/>
</row>
<row class="row">
<description options=",,,cat_data[icon]" value="Icon"/>
<hbox options="0,0">
<menulist>
<menupopup id="data[icon]" options="None" onchange="document.getElementById('icon_url').src = '$cont[base_url]' + this.value;"/>
</menulist>
<image src="icon_url" class="leftPad5"/>
</hbox>
</row>
<row class="row" disabled="@appname=phpgw">
<description value="Application"/>
<menulist>
<menupopup type="select-app" id="appname" readonly="true"/>
</menulist>
</row>
<row class="row">
<description value="Modified"/>
<date-time id="last_mod" readonly="true"/>
</row>
<row>
<hbox>
<button label="Save" id="button[save]"/>
<button label="Apply" id="button[apply]"/>
</hbox>
<hbox>
<buttononly id="button[cancel]" label="Cancel" onclick="window.close();"/>
<buttononly label="Delete" align="right" id="button[delete]" statustext="Delete this category" onclick="set_style_by_class('tr','confirmSubs','visibility','$cont[children]'?'visible':'collapse'); set_style_by_class('fieldset','confirmDelete','display','block');"/>
</hbox>
</row>
</rows>
</grid>
<template id="admin.categories.delete"/>
</template>
</overlay>

View File

@ -0,0 +1,118 @@
<?xml version="1.0"?>
<!-- $Id$ -->
<overlay>
<template id="admin.categories.index.rows" template="" lang="" group="0" version="1.7.001">
<grid width="100%">
<columns>
<column/>
<column/>
<column/>
<column width="40"/>
<column width="80"/>
<column/>
<column width="30"/>
<column width="1%"/>
</columns>
<rows>
<row class="th">
<nextmatch-sortheader label="Name" id="name"/>
<nextmatch-sortheader label="Description" id="description"/>
<nextmatch-header id="appname" label="Application"/>
<nextmatch-header label="Icon" id="icon" align="center"/>
<nextmatch-header label="Color" id="color"/>
<nextmatch-sortheader label="Modified" id="last_mod"/>
<nextmatch-header label="Children" id="subs" align="center"/>
<description value="Actions"/>
</row>
<row class="$row_cont[id]">
<hbox options="0,0">
<html id="${row}[level_spacer]"/>
<description id="${row}[name]" class="$row_cont[class]"/>
</hbox>
<description id="${row}[description]"/>
<menulist>
<menupopup type="select-app" id="${row}[appname]" options="Global" readonly="true"/>
</menulist>
<image src="${row}[icon_url]" label="{$row_cont[data][icon]}" align="center"/>
<description id="${row}[data][color]"/>
<date-time id="${row}[last_mod]" readonly="true"/>
<description id="${row}[subs]" align="center"/>
<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="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="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>
</row>
</rows>
</grid>
</template>
<template id="admin.categories.delete" template="" lang="" group="0" version="1.7.001">
<grid>
<columns>
<column/>
</columns>
<rows>
<row>
<groupbox class="confirmDelete">
<caption label="Delete this category"/>
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row height="30">
<description span="all" value="Are you sure you want to delete this category ?" align="center"/>
</row>
<row class="confirmSubs">
<checkbox label="Do you also want to delete all global subcategories ?" id="delete[subs]" span="all" align="center"/>
</row>
<row height="40">
<button label="Delete" id="delete[delete]" align="center"/>
<buttononly label="Cancel" id="delete[cancel]" align="center" onclick="set_style_by_class('fieldset','confirmDelete','display','none');"/>
</row>
</rows>
</grid>
</groupbox>
</row>
</rows>
</grid>
<textbox id="delete[cat_id]" class="hiddenCatid"/>
<styles>
.confirmDelete {
position: absolute;
left: 120px;
top: 80px;
background-color: white;
display: none;
border: 2px solid black;
}
.hiddenCatid {
display: none;
}
.confirmSubs
{
}
</styles>
</template>
<template id="admin.categories.index" template="" lang="" group="0" version="1.7.001">
<grid width="100%">
<columns>
<column/>
</columns>
<rows>
<row disabled="!@msg">
<description id="msg" align="center" span="all" class="redItalic"/>
</row>
<row>
<nextmatch options="admin.categories.index.rows" id="nm"/>
</row>
<row>
<buttononly label="Add" id="add" onclick="window.open(egw::link('/index.php','menuaction=admin.admin_categories.edit&amp;appname={$cont[nm][appname]}'),'_blank','dependent=yes,width=600,height=300,scrollbars=yes,status=yes'); return false;"/>
</row>
</rows>
</grid>
<template id="admin.categories.delete"/>
<styles>.level0 { font-weight: bold; }</styles>
</template>
</overlay>

View File

@ -1,48 +0,0 @@
<!-- $Id$ -->
<!-- BEGIN form -->
<br>
<center>
{message}<br>
<table border="0" width="80%" cellspacing="2" cellpadding="2">
<form name="edit_cat" action="{actionurl}" method="POST">
<tr class="th">
<td colspan="2">{lang_parent}</td>
<td><select name="new_parent"><option value="">{lang_none}</option>{category_list}</select></td>
</tr>
<tr class="row_on">
<td colspan="2">{lang_name}</font></td>
<td><input name="cat_name" size="50" value="{cat_name}"></td>
</tr>
<tr class="row_off">
<td colspan="2">{lang_descr}</td>
<td colspan="2"><textarea name="cat_description" rows="4" cols="50" wrap="virtual">{cat_description}</textarea></td>
</tr>
<tr class="row_on">
<td colspan="2">{lang_color}</td>
<td colspan="2">{color}</td>
</tr>
<tr class="row_off">
<td colspan="2">{lang_icon}</td>
<td colspan="2">{select_icon} {icon}</td>
</tr>
<!-- BEGIN data_row -->
<tr class="{class}">
<td colspan="2">{lang_data}</td>
<td>{td_data}</td>
</tr>
<!-- END data_row -->
<tr valign="bottom" height="50">
<td>
{hidden_vars}
<input type="submit" name="save" value="{lang_save}"></form></td>
<td>
<form method="POST" action="{cancel_url}">
<input type="submit" name="cancel" value="{lang_cancel}"></form></td>
<td align="right">{delete}</td>
</tr>
</table>
</center>
<!-- END form -->

View File

@ -1,57 +0,0 @@
<!-- $Id$ -->
<center>
<table border="0" cellspacing="2" cellpadding="2" width="100%">
<tr>
<td colspan="5" align="left">
<table border="0" width="100%">
<tr>
{left}
<td align="center">{lang_showing}</td>
{right}
</tr>
</table>
</td>
</tr>
<!-- BEGIN search -->
<tr>
<td colspan="5" align="right">
<form method="post" action="{action_nurl}">
<input type="text" name="query">&nbsp;<input type="submit" name="search" value="{lang_search}"></form></td>
</tr>
<!-- END search -->
<tr class="th">
<td width="20%">{sort_name}</td>
<td width="32%">{sort_description}</td>
<td width="8%">{lang_color}</td>
<td width="6%">{lang_icon}</td>
<td width="14%" align="center">{lang_sub}</td>
<td width="8%" align="center">{lang_edit}</td>
<td width="8%" align="center">{lang_delete}</td>
</tr>
<!-- BEGIN cat_list -->
<tr bgcolor="{tr_color}" {color}>
<td>{name}</td>
<td>{descr}</td>
<td bgcolor="{td_color}"></td>
<td>{icon}</td>
<td align="center">{add_sub}</a></td>
<td align="center">{edit}</a></td>
<td align="center">{delete}</a></td>
</tr>
<!-- END cat_list -->
<tr valign="bottom" height="50">
<form method="POST" action="{action_url}">
<!-- BEGIN add -->
<td><input type="submit" name="add" value="{lang_add}"> &nbsp;
<!-- END add -->
<input type="submit" name="done" value="{lang_cancel}"></td>
<td colspan="5">&nbsp;</td>
</form>
</tr>
</table>
</center>

View File

@ -1325,8 +1325,7 @@ class calendar_bo
if (!isset($id2cat[$cat_id]))
{
list($id2cat[$cat_id]) = $this->categories->return_single($cat_id);
$id2cat[$cat_id]['data'] = unserialize($id2cat[$cat_id]['data']);
$id2cat[$cat_id] = categories::read($cat_id);
}
$cat = $id2cat[$cat_id];

View File

@ -16,6 +16,11 @@
*/
class boetemplate extends soetemplate
{
/**
* Widget types implemented directly by etemplate (no extensions)
*
* @var array intern name => label
*/
static public $types = array(
'label' => 'Label', // Label $cell['label'] is (to be translated) textual content
'text' => 'Text', // Textfield 1 Line (size = [length][,maxlength])
@ -41,7 +46,8 @@ class boetemplate extends soetemplate
'box' => 'Box', // just a container for widgets (html: div)
'grid' => 'Grid', // tabular widget containing rows with columns of widgets
'deck' => 'Deck', // a container of elements where only one is visible, size = # of elem.
'passwd' => 'Password' // a text of type password
'passwd' => 'Password', // a text of type password
'colorpicker' => 'Colorpicker', // input for a color (eg. #123456)
);
/**

View File

@ -645,7 +645,7 @@ class etemplate extends boetemplate
{
return $cat2color[$cat];
}
$data = unserialize($GLOBALS['egw']->categories->id2name($cat,'data'));
$data = categories::id2name($cat,'data');
if (($color = $data['color']))
{
@ -1699,6 +1699,22 @@ class etemplate extends boetemplate
),'style,id'));
}
break;
case 'colorpicker':
if ($readonly)
{
$html = $value;
}
else
{
$html = html::inputColor($form_name,$value,$cell['help']);
self::$request->set_to_process($form_name,$cell['type'],array(
'maxlength' => 7,
'needed' => $cell['needed'],
'preg' => '/^(#[0-9a-f]{6}|)$/i',
));
}
break;
default:
if ($ext_type && $this->haveExtension($ext_type,'render'))
{
@ -1920,7 +1936,7 @@ class etemplate extends boetemplate
$on = str_replace($matches[0],"'<style>".str_replace(array("\n","\r"),'',$tpl->style)."</style>'",$on);
}
}
if (strpos($on,'confirm(') !== false && preg_match('/confirm\(["\']{1}(.*)["\']{1}\)/',$on,$matches)) {
if (strpos($on,'confirm(') !== false && preg_match('/confirm\(["\']{1}(.*)["\']{1}\)/U',$on,$matches)) {
$question = lang($matches[1]).(substr($matches[1],-1) != '?' ? '?' : ''); // add ? if not there, saves extra phrase
$on = str_replace($matches[0],'confirm(\''.str_replace("'","\\'",$question).'\')',$on);
}
@ -2042,6 +2058,7 @@ class etemplate extends boetemplate
case 'passwd':
case 'text':
case 'textarea':
case 'colorpicker':
if ($value === '' && $attr['needed'] && !$attr['blur'])
{
self::set_validation_error($form_name,lang('Field must not be empty !!!'),'');

View File

@ -102,7 +102,7 @@ class select_widget
*/
function pre_process($name,&$value,&$cell,&$readonlys,&$extension_data,&$tmpl)
{
list($rows,$type,$type2,$type3,$type4) = explode(',',$cell['size']);
list($rows,$type,$type2,$type3,$type4,$type5) = explode(',',$cell['size']);
$extension_data['type'] = $cell['type'];
@ -158,7 +158,7 @@ class select_widget
$cell['no_lang'] = True;
break;
case 'select-cat': // !$type == globals cats too, $type2: extraStyleMultiselect, $type3: application, if not current-app, $type4: parent-id
case 'select-cat': // !$type == globals cats too, $type2: extraStyleMultiselect, $type3: application, if not current-app, $type4: parent-id, $type5=owner (-1=global)
if ($readonly) // for readonly we dont need to fetch all cat's, nor do we need to indent them by level
{
$cell['no_lang'] = True;
@ -179,20 +179,21 @@ class select_widget
}
break;
}
if (!$type3 || $type3 === $GLOBALS['egw']->categories->app_name)
if ((!$type3 || $type3 === $GLOBALS['egw']->categories->app_name) &&
(!$type5 || $type5 == $GLOBALS['egw']->categories->account_id))
{
$categories = $GLOBALS['egw']->categories;
}
else // we need to instanciate a new cat object for the correct application
{
$categories = new categories('',$type3);
$categories = new categories($type5,$type3);
}
// we cast $type4 (parent) to int, to get default of 0 if omitted
foreach((array)$categories->return_sorted_array(0,False,'','','',!$type,(int)$type4) as $cat)
foreach((array)$categories->return_sorted_array(0,False,'','','',!$type,(int)$type4,true) as $cat)
{
$s = str_repeat('&nbsp;',$cat['level']) . stripslashes($cat['name']);
if ($cat['app_name'] == 'phpgw' || $cat['owner'] == '-1')
if ($cat['app_name'] == categories::GLOBAL_APPNAME || $cat['owner'] == categories::GLOBAL_ACCOUNT)
{
$s .= ' &#9830;';
}

View File

@ -24,6 +24,16 @@
* The egw object fills that cache ones per session, stores it in a private var, from which it restores it for each
* request of that session.
*
* $cat['data'] array:
* ------------------
* $cat['data'] array is stored serialized in the database to allow applications to simply add all
* sorts of values there (without the hassel of a DB schema change).
* Static methods categories::read($cat_id) and categories::id2name now returns data already unserialized
* and add() or edit() methods automatically serialize $cat['data'], if it's not yet serialized.
* return*() methods still return $cat['data'] serialized by default, but have a parameter to return
* it as array(). That default might change in future too, so better check if it's
* not already an array, before unserialize!
*
* @ToDo The cache now contains a backlink from the parent to it's children. Use that link to simplyfy return_all_children
* and other functions needing to know if a cat has children. Be aware a user might not see all children, as they can
* belong to other users.
@ -31,13 +41,13 @@
class categories
{
/**
* Account id this class is instanciated for (-1 for global cats)
* Account id this class is instanciated for (self::GLOBAL_ACCOUNT for global cats)
*
* @var int
*/
public $account_id;
/**
* Application this class is instancated for ('phpgw' for application global cats)
* Application this class is instancated for (self::GLOBAL_APPNAME for application global cats)
*
* @var string
*/
@ -74,17 +84,34 @@ class categories
*/
private static $cache;
/**
* Appname for global categories
*/
const GLOBAL_APPNAME = 'phpgw';
/**
* account_id for global categories
*/
const GLOBAL_ACCOUNT = -1;
/**
* constructor for categories class
*
* @param int/string $accountid='' account id or lid, default to current user
* @param int|string $accountid='' account id or lid, default to current user
* @param string $app_name='' app name defaults to current app
*/
function __construct($accountid='',$app_name = '')
{
if (!$app_name) $app_name = $GLOBALS['egw_info']['flags']['currentapp'];
if ($accountid == self::GLOBAL_ACCOUNT)
{
$this->account_id = self::GLOBAL_ACCOUNT;
}
else
{
$this->account_id = (int) get_account_id($accountid);
}
$this->app_name = $app_name;
$this->db = $GLOBALS['egw']->db;
@ -105,7 +132,6 @@ class categories
}
/**
* return_all_children
* returns array with id's of all children from $cat_id and $cat_id itself!
*
* @param int|array $cat_id (array of) integer cat-id to search for
@ -138,11 +164,12 @@ class categories
* @param int $lastmod = -1 if > 0 return only cats modified since then
* @param string $column='' if column-name given only that column is returned, not the full array with all cat-data
* @param array $filter=null array with column-name (without cat_-prefix) => value pairs (! negates the value)
* @param boolean $unserialize_data=false return $cat['data'] as array (not serialized array)
* @return array of cat-arrays or $column values
*/
function return_array($type='all', $start=0, $limit=true, $query='', $sort='ASC',$order='',$globals=false, $parent_id=null, $lastmod=-1, $column='', $filter=null)
function return_array($type='all', $start=0, $limit=true, $query='', $sort='ASC',$order='',$globals=false, $parent_id=null, $lastmod=-1, $column='', $filter=null,$unserialize_data=false)
{
//error_log(__METHOD__."($type,$start,$limit,$query,$sort,$order,globals=$globals,parent=".array2string($parent_id).",$lastmod,$column) account_id=$this->account_id, appname=$this->app_name: ".function_backtrace());
//error_log(__METHOD__."($type,$start,$limit,$query,$sort,$order,globals=$globals,parent=".array2string($parent_id).",$lastmod,$column,filter=".array2string($filter).",$unserialize_data) account_id=$this->account_id, appname=$this->app_name: ".function_backtrace());
$cats = array();
foreach(self::$cache as $cat_id => $cat)
{
@ -189,7 +216,7 @@ class categories
if ($parent_id && !in_array($cat['parent'],(array)$parent_id)) continue;
// return global categories just if $globals is set
if (!$globals && $cat['appname'] == 'phpgw')
if (!$globals && $cat['appname'] == self::GLOBAL_APPNAME)
{
continue;
}
@ -229,6 +256,8 @@ class categories
// check if last modified since
if ($lastmod > 0 && $cat['last_mod'] <= $lastmod) continue;
if ($unserialize_data) $cat['data'] = $cat['data'] ? unserialize($cat['data']) : array();
$cats[] = $cat;
}
if (!($this->total_records = count($cats)))
@ -261,7 +290,7 @@ class categories
$cats[$k] = $cat[$column];
}
}
//error_log(__METHOD__."($type,$start,$limit,$query,$sort,$order,$globals,parent=$parent_id,$lastmod,$column) account_id=$this->account_id, appname=$this->app_name = ".array2string($cats));
//error_log(__METHOD__."($type,$start,$limit,$query,$sort,$order,$globals,parent=".array2string($parent_id).",$lastmod,$column,filter=".array2string($filter).",$unserialize_data) account_id=$this->account_id, appname=$this->app_name = ".array2string($cats));
reset($cats); // some old code (eg. sitemgr) relies on the array-pointer!
return $cats;
@ -277,17 +306,18 @@ class categories
* @param string $order='cat_name' order by
* @param boolean $globals includes the global egroupware categories or not
* @param array|int $parent_id=0 return only subcats of $parent_id(s)
* @param boolean $unserialize_data=false return $cat['data'] as array (not serialized array)
* @return array with cats
*/
function return_sorted_array($start=0,$limit=True,$query='',$sort='ASC',$order='cat_name',$globals=False, $parent_id=0)
function return_sorted_array($start=0,$limit=True,$query='',$sort='ASC',$order='cat_name',$globals=False, $parent_id=0,$unserialize_data=false)
{
if (!$sort) $sort = 'ASC';
if (!$order) $order = 'cat_name';
//error_log(__METHOD__."($start,$limit,$query,$sort,$order,globals=$globals,parent=$parent_id) account_id=$this->account_id, appname=$this->app_name: ".function_backtrace());
//error_log(__METHOD__."($start,$limit,$query,$sort,$order,globals=$globals,parent=$parent_id,$unserialize_data) account_id=$this->account_id, appname=$this->app_name: ".function_backtrace());
$parents = $cats = array();
if (!($cats = $this->return_array('all',0,false,$query,$sort,$order,$globals,(array)$parent_id)))
if (!($cats = $this->return_array('all',0,false,$query,$sort,$order,$globals,(array)$parent_id,-1,'',null,$unserialize_data)))
{
$cats = array();
}
@ -297,7 +327,7 @@ class categories
}
while (count($parents))
{
if (!($subs = $this->return_array('all',0,false,$query,$sort,$order,$globals,$parents)))
if (!($subs = $this->return_array('all',0,false,$query,$sort,$order,$globals,$parents,-1,'',null,$unserialize_data)))
{
break;
}
@ -338,117 +368,23 @@ class categories
}
/**
* read a single category
* Read a category
*
* We use a shared cache together with id2name
*
* @param int $id id of category
* @return array|boolean array with one array of cat-data or false if cat not found
*/
static function return_single($id)
{
return isset(self::$cache[$id]) ? array(self::$cache[$id]) : false;
}
/**
* return into a select box, list or other formats
* Data array get automatically unserialized!
*
* @param string/array $format string 'select' or 'list', or array with all params
* @param string $type='' subs or mains
* @param int/array $selected - cat_id or array with cat_id values
* @param boolean $globals True or False, includes the global egroupware categories or not
* @deprecated use html class to create selectboxes
* @return string populated with categories
* @param int $id id of category
* @return array|boolean array with cat-data or false if cat not found
*/
function formatted_list($format,$type='',$selected = '',$globals = False,$site_link = 'site')
static function read($id)
{
if(is_array($format))
{
$type = ($format['type']?$format['type']:'all');
$selected = (isset($format['selected'])?$format['selected']:'');
$self = (isset($format['self'])?$format['self']:'');
$globals = (isset($format['globals'])?$format['globals']:True);
$site_link = (isset($format['site_link'])?$format['site_link']:'site');
$format = $format['format'] ? $format['format'] : 'select';
}
if (!isset(self::$cache[$id])) return false;
if (!is_array($selected))
{
$selected = explode(',',$selected);
}
$cat = self::$cache[$id];
$cat['data'] = $cat['data'] ? unserialize($cat['data']) : array();
if ($type != 'all')
{
$cats = $this->return_array($type,0,False,'','','',$globals);
}
else
{
$cats = $this->return_sorted_array(0,False,'','','',$globals);
}
if (!$cats) return '';
if($self)
{
foreach($cats as $key => $cat)
{
if ($cat['id'] == $self)
{
unset($cats[$key]);
}
}
}
switch ($format)
{
case 'select':
foreach($cats as $cat)
{
$s .= '<option value="' . $cat['id'] . '"';
if (in_array($cat['id'],$selected))
{
$s .= ' selected="selected"';
}
$s .= '>'.str_repeat('&nbsp;',$cat['level']);
$s .= $GLOBALS['egw']->strip_html($cat['name']);
if ($cat['app_name'] == 'phpgw' || $cat['owner'] == '-1')
{
$s .= ' &#9830;';
}
$s .= '</option>' . "\n";
}
break;
case 'list':
$space = '&nbsp;&nbsp;';
$s = '<table border="0" cellpadding="2" cellspacing="2">' . "\n";
foreach($cats as $cat)
{
$image_set = '&nbsp;';
if (in_array($cat['id'],$selected))
{
$image_set = '<img src="' . EGW_IMAGES_DIR . '/roter_pfeil.gif">';
}
if (($cat['level'] == 0) && !in_array($cat['id'],$selected))
{
$image_set = '<img src="' . EGW_IMAGES_DIR . '/grauer_pfeil.gif">';
}
$space_set = str_repeat($space,$cat['level']);
$s .= '<tr>' . "\n";
$s .= '<td width="8">' . $image_set . '</td>' . "\n";
$s .= '<td>' . $space_set . '<a href="' . $GLOBALS['egw']->link($site_link,'cat_id=' . $cat['id']) . '">'
. $GLOBALS['egw']->strip_html($cat['name'])
. '</a></td>' . "\n"
. '</tr>' . "\n";
}
$s .= '</table>' . "\n";
break;
}
return $s;
return $cat;
}
/**
@ -473,7 +409,7 @@ class categories
'cat_appname' => $this->app_name,
'cat_name' => $values['name'],
'cat_description' => isset($values['description']) ? $values['description'] : $values['descr'], // support old name different from returned one
'cat_data' => $values['data'],
'cat_data' => is_array($values['data']) ? serialize($values['data']) : $values['data'],
'cat_main' => $values['main'],
'cat_level' => $values['level'],
'last_mod' => time(),
@ -535,16 +471,16 @@ class categories
return null;
}
// The user for the global cats has id -1, this one has full access to all global cats
if ($this->account_id == -1 && ($category['appname'] == 'phpgw'
|| $category['appname'] == $this->app_name && $category['owner'] == -1))
// 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
|| $category['appname'] == $this->app_name && $category['owner'] == self::GLOBAL_ACCOUNT))
{
return true;
}
// Read access to global categories
if ($needed == EGW_ACL_READ && ($category['appname'] == 'phpgw'
|| $category['appname'] == $this->app_name && $category['owner'] == -1))
if ($needed == EGW_ACL_READ && ($category['appname'] == self::GLOBAL_APPNAME
|| $category['appname'] == $this->app_name && $category['owner'] == self::GLOBAL_ACCOUNT))
{
return true;
}
@ -561,8 +497,8 @@ class categories
$this->grants = $GLOBALS['egw']->acl->get_grants($this->app_name);
}
// Check for ACL granted access, the -1 user must not get access by ACL to keep old behaviour
return ($this->account_id != -1 && $category['appname'] == $this->app_name && ($this->grants[$category['owner']] & $needed) &&
// Check for ACL granted access, the self::GLOBAL_ACCOUNT user must not get access by ACL to keep old behaviour
return ($this->account_id != self::GLOBAL_ACCOUNT && $category['appname'] == $this->app_name && ($this->grants[$category['owner']] & $needed) &&
($category['access'] == 'public' || ($this->grants[$category['owner']] & EGW_ACL_PRIVATE)));
}
@ -657,7 +593,7 @@ class categories
$this->db->update(self::TABLE,array(
'cat_name' => $values['name'],
'cat_description' => isset($values['description']) ? $values['description'] : $values['descr'], // support old name different from the one read
'cat_data' => $values['data'],
'cat_data' => is_array($values['data']) ? serialize($values['data']) : $values['data'],
'cat_parent' => $values['parent'],
'cat_access' => $values['access'],
'cat_main' => $values['main'],
@ -712,7 +648,7 @@ class categories
if (!($cats = $this->return_array('all',0,false,'','','',true,null,-1,'',array(
'name' => $cats,
'appname' => array($this->app_name, 'phpgw'),
'appname' => array($this->app_name, self::GLOBAL_APPNAME),
))))
{
return 0; // cat not found, dont cache it, as it might be created in this request
@ -723,8 +659,8 @@ class categories
foreach($cats as $k => $cat)
{
$cats[$k]['weight'] = 100 * ($cat['name'] == $cat_name) +
10 * ($cat['owner'] == $this->account_id ? 3 : ($cat['owner'] == -1 ? 2 : 1)) +
($cat['appname'] != 'phpgw');
10 * ($cat['owner'] == $this->account_id ? 3 : ($cat['owner'] == self::GLOBAL_ACCOUNT ? 2 : 1)) +
($cat['appname'] != self::GLOBAL_APPNAME);
}
// sort heighest weight to the top
usort($cats,create_function('$a,$b',"return \$b['weight'] - \$a['weight'];"));
@ -735,7 +671,8 @@ class categories
/**
* return category information for a given id
*
* We use a shared cache together with return_single
* We use a shared cache together with read
* $item == 'data' is returned as array (not serialized array)!
*
* @param int $cat_id=0 cat-id
* @param string $item='name' requested information, 'path' = / delimited path of category names (incl. parents)
@ -757,7 +694,11 @@ class categories
}
$item = 'name';
}
if ($cat[$item])
if ($item == 'data')
{
return $cat['data'] ? unserialize($cat['data']) : array();
}
elseif ($cat[$item])
{
return $cat[$item];
}
@ -768,17 +709,6 @@ class categories
return null;
}
/**
* return category name for a given id
*
* @deprecated This is only a temp wrapper, use id2name() to keep things matching across the board. (jengo)
* @param int $cat_id
* @return string cat_name category name
*/
function return_name($cat_id)
{
return $this->id2name($cat_id);
}
/**
* check if a category id and/or name exists, if id AND name are given the check is for a category with same name and different id (!)
@ -888,4 +818,135 @@ class categories
// we need to invalidate the whole session cache, as it stores our cache
egw::invalidate_session_cache();
}
/**
******************************** old / deprecated functions ***********************************
*/
/**
* read a single category
*
* We use a shared cache together with id2name
*
* @deprecated use read($id) returning just the category array not an array with one element
* @param int $id id of category
* @return array|boolean array with one array of cat-data or false if cat not found
*/
static function return_single($id)
{
return isset(self::$cache[$id]) ? array(self::$cache[$id]) : false;
}
/**
* return into a select box, list or other formats
*
* @param string/array $format string 'select' or 'list', or array with all params
* @param string $type='' subs or mains
* @param int/array $selected - cat_id or array with cat_id values
* @param boolean $globals True or False, includes the global egroupware categories or not
* @deprecated use html class to create selectboxes
* @return string populated with categories
*/
function formatted_list($format,$type='',$selected = '',$globals = False,$site_link = 'site')
{
if(is_array($format))
{
$type = ($format['type']?$format['type']:'all');
$selected = (isset($format['selected'])?$format['selected']:'');
$self = (isset($format['self'])?$format['self']:'');
$globals = (isset($format['globals'])?$format['globals']:True);
$site_link = (isset($format['site_link'])?$format['site_link']:'site');
$format = $format['format'] ? $format['format'] : 'select';
}
if (!is_array($selected))
{
$selected = explode(',',$selected);
}
if ($type != 'all')
{
$cats = $this->return_array($type,0,False,'','','',$globals);
}
else
{
$cats = $this->return_sorted_array(0,False,'','','',$globals);
}
if (!$cats) return '';
if($self)
{
foreach($cats as $key => $cat)
{
if ($cat['id'] == $self)
{
unset($cats[$key]);
}
}
}
switch ($format)
{
case 'select':
foreach($cats as $cat)
{
$s .= '<option value="' . $cat['id'] . '"';
if (in_array($cat['id'],$selected))
{
$s .= ' selected="selected"';
}
$s .= '>'.str_repeat('&nbsp;',$cat['level']);
$s .= $GLOBALS['egw']->strip_html($cat['name']);
if ($cat['app_name'] == self::GLOBAL_APPNAME || $cat['owner'] == 'self::GLOBAL_ACCOUNT')
{
$s .= ' &#9830;';
}
$s .= '</option>' . "\n";
}
break;
case 'list':
$space = '&nbsp;&nbsp;';
$s = '<table border="0" cellpadding="2" cellspacing="2">' . "\n";
foreach($cats as $cat)
{
$image_set = '&nbsp;';
if (in_array($cat['id'],$selected))
{
$image_set = '<img src="' . EGW_IMAGES_DIR . '/roter_pfeil.gif">';
}
if (($cat['level'] == 0) && !in_array($cat['id'],$selected))
{
$image_set = '<img src="' . EGW_IMAGES_DIR . '/grauer_pfeil.gif">';
}
$space_set = str_repeat($space,$cat['level']);
$s .= '<tr>' . "\n";
$s .= '<td width="8">' . $image_set . '</td>' . "\n";
$s .= '<td>' . $space_set . '<a href="' . $GLOBALS['egw']->link($site_link,'cat_id=' . $cat['id']) . '">'
. $GLOBALS['egw']->strip_html($cat['name'])
. '</a></td>' . "\n"
. '</tr>' . "\n";
}
$s .= '</table>' . "\n";
break;
}
return $s;
}
/**
* return category name for a given id
*
* @deprecated This is only a temp wrapper, use id2name() to keep things matching across the board. (jengo)
* @param int $cat_id
* @return string cat_name category name
*/
function return_name($cat_id)
{
return $this->id2name($cat_id);
}
}

View File

@ -79,7 +79,7 @@ class html
/**
* Created an input-field with an attached color-picker
*
* Please note: it need to be called before the call to phpgw_header() !!!
* Please note: it need to be called before the call to egw_header() !!!
*
* @param string $name the name of the input-field
* @param string $value the actual value for the input-field, default ''
@ -89,8 +89,8 @@ class html
static function inputColor($name,$value='',$title='')
{
$id = str_replace(array('[',']'),array('_',''),$name).'_colorpicker';
$onclick = "javascript:window.open('".self::$api_js_url.'/colorpicker/select_color.html?id='.urlencode($id)."&color='+document.getElementById('$id').value,'colorPicker','width=240,height=187,scrollbars=no,resizable=no,toolbar=no');";
return '<input type="text" name="'.$name.'" id="'.$id.'" value="'.self::htmlspecialchars($value).'" /> '.
$onclick = "javascript:window.open('".self::$api_js_url.'/colorpicker/select_color.html?id='.urlencode($id)."&color='+encodeURIComponent(document.getElementById('$id').value),'colorPicker','width=240,height=187,scrollbars=no,resizable=no,toolbar=no');";
return '<input type="text" name="'.$name.'" id="'.$id.'" value="'.self::htmlspecialchars($value).'" size="7" maxsize="7" /> '.
'<a href="#" onclick="'.$onclick.'">'.
'<img src="'.self::$api_js_url.'/colorpicker/ed_color_bg.gif'.'"'.($title ? ' title="'.self::htmlspecialchars($title).'"' : '')." /></a>";
}

View File

@ -728,6 +728,7 @@ function &CreateObject($class)
'uimilestones' => 'projectmanager_milestones_ui',
'uipricelist' => 'projectmanager_pricelist_ui',
'bowiki' => 'wiki_bo',
'uicategories' => 'admin_categories',
);
if (isset($replace[$classname]))
{