forked from extern/egroupware
first version of xmlrpc support for infolog
This commit is contained in:
parent
0711abd82b
commit
c5dd013f18
@ -37,6 +37,30 @@
|
||||
var $valid_pathes = array();
|
||||
var $send_file_ips = array();
|
||||
|
||||
var $xmlrpc_methods = array();
|
||||
var $soap_functions = array(
|
||||
'read' => array(
|
||||
'in' => array('int'),
|
||||
'out' => array('array')
|
||||
),
|
||||
'search' => array(
|
||||
'in' => array('array'),
|
||||
'out' => array('array')
|
||||
),
|
||||
'write' => array(
|
||||
'in' => array('array'),
|
||||
'out' => array()
|
||||
),
|
||||
'delete' => array(
|
||||
'in' => array('int'),
|
||||
'out' => array()
|
||||
),
|
||||
'categories' => array(
|
||||
'in' => array('bool'),
|
||||
'out' => array('array')
|
||||
),
|
||||
);
|
||||
|
||||
function boinfolog( $info_id = 0)
|
||||
{
|
||||
$this->enums = $this->stock_enums = array(
|
||||
@ -108,6 +132,9 @@
|
||||
$this->tz_offset = $GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset'];
|
||||
$this->tz_offset_sec = 60*60*$this->tz_offset;
|
||||
|
||||
// are we called via xmlrpc?
|
||||
$this->xmlrpc = is_object($GLOBALS['server']) && $GLOBALS['server']->last_method;
|
||||
|
||||
$this->read( $info_id);
|
||||
}
|
||||
|
||||
@ -178,7 +205,27 @@
|
||||
|
||||
function read($info_id)
|
||||
{
|
||||
$err = $this->so->read($info_id) === False;
|
||||
if (is_array($info_id))
|
||||
{
|
||||
$info_id = (int)$info_id['info_id'];
|
||||
}
|
||||
|
||||
if ($this->so->read($info_id) === False)
|
||||
{
|
||||
if ($this->xmlrpc)
|
||||
{
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['not_exist'],$GLOBALS['xmlrpcstr']['not_exist']);
|
||||
}
|
||||
return False;
|
||||
}
|
||||
if (!$this->check_access($info_id,PHPGW_ACL_READ)) // check behind read, to prevent a double read
|
||||
{
|
||||
if ($this->xmlrpc)
|
||||
{
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
|
||||
}
|
||||
return False;
|
||||
}
|
||||
$data = &$this->so->data;
|
||||
|
||||
if ($data['info_subject'] == $this->subject_from_des($data['info_des']))
|
||||
@ -187,11 +234,30 @@
|
||||
}
|
||||
$this->link_id2from($data);
|
||||
|
||||
return $err ? False : $data;
|
||||
if ($this->xmlrpc)
|
||||
{
|
||||
$data = $this->data2xmlrpc($data);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
function delete($info_id,$delete_children,$new_parent)
|
||||
function delete($info_id,$delete_children=False,$new_parent=False)
|
||||
{
|
||||
if (is_array($info_id))
|
||||
{
|
||||
$delete_children = $info_id['delete_children'];
|
||||
$new_parent = $info_id['new_parent'];
|
||||
$info_id = $info_id['info_id'];
|
||||
}
|
||||
if (!$this->check_access($info_id,PHPGW_ACL_DELETE))
|
||||
{
|
||||
if ($this->xmlrpc)
|
||||
{
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
$this->link->unlink(0,'infolog',$info_id);
|
||||
|
||||
$this->so->delete($info_id,$delete_children,$new_parent);
|
||||
@ -199,7 +265,20 @@
|
||||
|
||||
function write($values,$check_defaults=True,$touch_modified=True)
|
||||
{
|
||||
while (list($key,$val) = each($values))
|
||||
if ($values['info_id'] && !$this->check_access($values['info_id'],PHPGW_ACL_EDIT) ||
|
||||
!$values['info_id'] && $values['info_id_parent'] && !$this->check_access($values['info_id_parent'],PHPGW_ACL_ADD))
|
||||
{
|
||||
if ($this->xmlrpc)
|
||||
{
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
|
||||
}
|
||||
return False;
|
||||
}
|
||||
if ($this->xmlrpc)
|
||||
{
|
||||
$values = $this->xmlrpc2data($values);
|
||||
}
|
||||
foreach($values as $key => $val)
|
||||
{
|
||||
if ($key[0] != '#' && substr($key,0,5) != 'info_')
|
||||
{
|
||||
@ -247,9 +326,32 @@
|
||||
return $this->so->anzSubs( $info_id );
|
||||
}
|
||||
|
||||
function search($order,$sort,$filter,$cat_id,$query,$action,$action_id,$ordermethod,&$start,&$total,$col_filter=False)
|
||||
/*!
|
||||
@function search
|
||||
@abstract searches InfoLog for a certain pattern in $query
|
||||
@syntax search( $query )
|
||||
@param $query[order] column-name to sort after
|
||||
@param $query[sort] sort-order DESC or ASC
|
||||
@param $query[filter] string with combination of acl-, date- and status-filters, eg. 'own-open-today' or ''
|
||||
@param $query[cat_id] category to use or 0 or unset
|
||||
@param $query[search] pattern to search, search is done in info_from, info_subject and info_des
|
||||
@param $query[action] / $query[action_id] if only entries linked to a specified app/entry show be used
|
||||
@param &$query[start], &$query[total] nextmatch-parameters will be used and set if query returns less entries
|
||||
@param $query[col_filter] array with column-name - data pairs, data == '' means no filter (!)
|
||||
@returns array with id's as key of the matching log-entries
|
||||
*/
|
||||
function search(&$query)
|
||||
{
|
||||
return $this->so->search($order,$sort,$filter,$cat_id,$query,$action,$action_id,$ordermethod,$start,$total,$col_filter);
|
||||
$ret = $this->so->search($query);
|
||||
if ($this->xmlrpc && is_array($ret))
|
||||
{
|
||||
foreach($ret as $id => $data)
|
||||
{
|
||||
$ret[$id] = $this->data2xmlrpc($data);
|
||||
}
|
||||
}
|
||||
//echo "<p>boinfolog::search(".print_r($query,True).")=<pre>".print_r($ret,True)."</pre>\n";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -280,13 +382,19 @@
|
||||
*/
|
||||
function link_query( $pattern )
|
||||
{
|
||||
$start = $total = 0;
|
||||
$ids = $this->search('','','','',$pattern,'','','',&$start,&$total);
|
||||
$query = array(
|
||||
'search' => $pattern,
|
||||
'start' => 0,
|
||||
);
|
||||
$ids = $this->search($query);
|
||||
$content = array();
|
||||
while (is_array($ids) && list( $id,$info ) = each( $ids ))
|
||||
if (is_array($ids))
|
||||
{
|
||||
foreach($ids as $id => $info )
|
||||
{
|
||||
$content[$id] = $this->link_title($id);
|
||||
}
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
@ -315,11 +423,15 @@
|
||||
$GLOBALS['phpgw']->translation->add_app('infolog');
|
||||
|
||||
$do_events = $args['location'] == 'calendar_include_events';
|
||||
$start = 0;
|
||||
$to_include = array();
|
||||
$date_wanted = sprintf('%04d/%02d/%02d',$args['year'],$args['month'],$args['day']);
|
||||
while ($infos = $this->search('info_startdate'.($do_events?'':' DESC'),'',
|
||||
"user$user".($do_events?'date':'opentoday').$date_wanted,'','','','','',$start,$total))
|
||||
$query = array(
|
||||
'order' => 'info_startdate',
|
||||
'sort' => $do_events ? 'ASC' : 'DESC',
|
||||
'filter'=> "user$user".($do_events ? 'date' : 'opentoday').$date_wanted,
|
||||
'start' => 0,
|
||||
);
|
||||
while ($infos = $this->search($query))
|
||||
{
|
||||
foreach($infos as $info)
|
||||
{
|
||||
@ -352,7 +464,7 @@
|
||||
'content' => $content
|
||||
);
|
||||
}
|
||||
if ($total <= ($start+=count($infos)))
|
||||
if ($query['total'] <= ($query['start']+=count($infos)))
|
||||
{
|
||||
break; // no more availible
|
||||
}
|
||||
@ -360,4 +472,106 @@
|
||||
//echo "boinfolog::cal_to_include("; print_r($args); echo ")<pre>"; print_r($to_include); echo "</pre>\n";
|
||||
return $to_include;
|
||||
}
|
||||
|
||||
function list_methods($_type='xmlrpc')
|
||||
{
|
||||
/*
|
||||
** This handles introspection or discovery by the logged in client,
|
||||
** in which case the input might be an array. The server always calls
|
||||
** this function to fill the server dispatch map using a string.
|
||||
*/
|
||||
|
||||
if (is_array($_type))
|
||||
{
|
||||
$_type = $_type['type'] ? $_type['type'] : $_type[0];
|
||||
}
|
||||
|
||||
switch($_type)
|
||||
{
|
||||
case 'xmlrpc':
|
||||
$xml_functions = array(
|
||||
'read' => array(
|
||||
'function' => 'read',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
|
||||
'docstring' => lang('Read one record by passing its id.')
|
||||
),
|
||||
'search' => array(
|
||||
'function' => 'search',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
|
||||
'docstring' => lang('Returns a list / search for records.')
|
||||
),
|
||||
'write' => array(
|
||||
'function' => 'write',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
|
||||
'docstring' => lang('Write (add or update) a record by passing its fields.')
|
||||
),
|
||||
'delete' => array(
|
||||
'function' => 'delete',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
|
||||
'docstring' => lang('Delete one record by passing its id.')
|
||||
),
|
||||
'categories' => array(
|
||||
'function' => 'categories',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
|
||||
'docstring' => lang('List all categories.')
|
||||
),
|
||||
'list_methods' => array(
|
||||
'function' => 'list_methods',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcString)),
|
||||
'docstring' => lang('Read this list of methods.')
|
||||
)
|
||||
);
|
||||
return $xml_functions;
|
||||
break;
|
||||
case 'soap':
|
||||
return $this->soap_functions;
|
||||
break;
|
||||
default:
|
||||
return array();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function data2xmlrpc($data)
|
||||
{
|
||||
// translate timestamps
|
||||
foreach(array('info_startdate','info_enddate','info_datemodified') as $name)
|
||||
{
|
||||
if (isset($data[$name]))
|
||||
{
|
||||
$data[$name] = $GLOBALS['server']->date2iso8601($data[$name]);
|
||||
}
|
||||
}
|
||||
// translate cat_id
|
||||
if (isset($data['cat_id']))
|
||||
{
|
||||
$data['cat_id'] = $GLOBALS['server']->cats2xmlrpc(array($data['cat_id']));
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
function xmlrpc2data($data)
|
||||
{
|
||||
// translate timestamps
|
||||
foreach(array('info_startdate','info_enddate','info_datemodified') as $name)
|
||||
{
|
||||
if (isset($data[$name]))
|
||||
{
|
||||
$data[$name] = $GLOBALS['server']->iso86012date($data[$name],True);
|
||||
}
|
||||
}
|
||||
// translate cat_id
|
||||
if (isset($data['cat_id']))
|
||||
{
|
||||
$cats = $GLOBALS['server']->xmlrpc2cats($data['cat_id']);
|
||||
$data['cat_id'] = (int)$cats[0];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
// return array with all infolog categories (for xmlrpc)
|
||||
function categories($complete = False)
|
||||
{
|
||||
return $GLOBALS['server']->categories($complete);
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
@abstract storage object / db-layer for InfoLog
|
||||
@author Ralf Becker
|
||||
@copyright GPL - GNU General Public License
|
||||
@note all values passed to this class are run either through intval or addslashes to prevent query-inserting
|
||||
@note all values passed to this class are run either through intval or addslashes to prevent query-insertion
|
||||
and for pgSql 7.3 compatibility
|
||||
*/
|
||||
class soinfolog // DB-Layer
|
||||
@ -104,7 +104,7 @@
|
||||
}
|
||||
if (is_array($this->grants))
|
||||
{
|
||||
while (list($user,$grant) = each($this->grants))
|
||||
foreach($this->grants as $user => $grant)
|
||||
{
|
||||
// echo "<p>grants: user=$user, grant=$grant</p>";
|
||||
if ($grant & (PHPGW_ACL_READ|PHPGW_ACL_EDIT))
|
||||
@ -180,7 +180,8 @@
|
||||
@syntax dateFilter($filter = '')
|
||||
@param $filter upcoming = startdate is in the future<br>
|
||||
today startdate < tomorrow<br>
|
||||
overdue enddate < tomorrow
|
||||
overdue enddate < tomorrow<br>
|
||||
limitYYYY/MM/DD not older or open
|
||||
@returns the necesary sql
|
||||
*/
|
||||
function dateFilter($filter = '')
|
||||
@ -212,6 +213,8 @@
|
||||
return '';
|
||||
}
|
||||
return " AND ($today <= info_startdate AND info_startdate < $tomorrow)";
|
||||
case 'limit':
|
||||
return " AND (info_modified >= '$today' OR NOT (info_status IN ('done','billed')))";
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@ -454,53 +457,51 @@
|
||||
/*!
|
||||
@function search
|
||||
@abstract searches InfoLog for a certain pattern in $query
|
||||
@syntax search( $order,$sort,$filter,$cat_id,$query,$action,$action_id,$ordermethod,&$start,&$total )
|
||||
@param $order comma-separated list of columns to order the result (no 'ORDER BY'), eg. 'info_subject DESC'
|
||||
@param $sort comma-separated list of columns to to sort by (incl. 'SORT BY') or ''
|
||||
@param $filter string with combination of acl-, date- and status-filters, eg. 'own-open-today' or ''
|
||||
@param $cat_id category to use or 0
|
||||
@param $query pattern to search, search is done in info_from, info_subject and info_des
|
||||
@param $action / $action_id if only entries linked to a specified app/entry show be used
|
||||
@param &$start, &$total nextmatch-parameters will be used and set if query returns less entries
|
||||
@param $col_filter array with column-name - data pairs, data == '' means no filter (!)
|
||||
@syntax search( $query )
|
||||
@param $query[order] column-name to sort after
|
||||
@param $query[sort] sort-order DESC or ASC
|
||||
@param $query[filter] string with combination of acl-, date- and status-filters, eg. 'own-open-today' or ''
|
||||
@param $query[cat_id] category to use or 0 or unset
|
||||
@param $query[search] pattern to search, search is done in info_from, info_subject and info_des
|
||||
@param $query[action] / $query[action_id] if only entries linked to a specified app/entry show be used
|
||||
@param &$query[start], &$query[total] nextmatch-parameters will be used and set if query returns less entries
|
||||
@param $query[col_filter] array with column-name - data pairs, data == '' means no filter (!)
|
||||
@returns array with id's as key of the matching log-entries
|
||||
*/
|
||||
function search($order,$sort,$filter,$cat_id,$query,$action,$action_id,$ordermethod,&$start,&$total,$col_filter=False)
|
||||
function search(&$query)
|
||||
{
|
||||
//echo "<p>soinfolog.search(order='$order',,filter='$filter',,query='$query',action='$action/$action_id')</p>\n";
|
||||
//echo "<p>soinfolog.search(".print_r($query,True).")</p>\n";
|
||||
$action2app = array(
|
||||
'addr' => 'addressbook',
|
||||
'proj' => 'projects',
|
||||
'event' => 'calendar'
|
||||
);
|
||||
if (isset($action2app[$action]))
|
||||
{
|
||||
$action = $action2app[$action];
|
||||
}
|
||||
$action = isset($action2app[$query['action']]) ? $action2app[$query['action']] : $query['action'];
|
||||
|
||||
if ($action != '')
|
||||
{
|
||||
$links = $this->links->get_links($action=='sp'?'infolog':$action,$action_id,'infolog');
|
||||
$links = $this->links->get_links($action=='sp'?'infolog':$action,$query['action_id'],'infolog');
|
||||
|
||||
if (count($links))
|
||||
{
|
||||
$link_extra = ($action == 'sp' ? 'OR' : 'AND').' phpgw_infolog.info_id IN ('.implode(',',$links).')';
|
||||
}
|
||||
}
|
||||
if ($order)
|
||||
if ($query['order'])
|
||||
{
|
||||
$ordermethod = 'ORDER BY ' . $this->db->db_addslashes($order) . ' ' . $this->db->db_addslashes($sort);
|
||||
$ordermethod = 'ORDER BY ' . $this->db->db_addslashes($query['order']) . ' ' . $this->db->db_addslashes($query['sort']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ordermethod = 'ORDER BY info_datemodified DESC'; // newest first
|
||||
}
|
||||
$filtermethod = $this->aclFilter($filter);
|
||||
$filtermethod .= $this->statusFilter($filter);
|
||||
$filtermethod .= $this->dateFilter($filter);
|
||||
$filtermethod = $this->aclFilter($query['filter']);
|
||||
$filtermethod .= $this->statusFilter($query['filter']);
|
||||
$filtermethod .= $this->dateFilter($query['filter']);
|
||||
|
||||
if (is_array($col_filter))
|
||||
if (is_array($query['col_filter']))
|
||||
{
|
||||
foreach($col_filter as $col => $data)
|
||||
foreach($query['col_filter'] as $col => $data)
|
||||
{
|
||||
$data = $this->db->db_addslashes($data);
|
||||
if (!empty($data))
|
||||
@ -511,19 +512,19 @@
|
||||
}
|
||||
//echo "<p>filtermethod='$filtermethod'</p>";
|
||||
|
||||
if (intval($cat_id))
|
||||
if (intval($query['cat_id']))
|
||||
{
|
||||
$filtermethod .= ' AND info_cat='.intval($cat_id).' ';
|
||||
$filtermethod .= ' AND info_cat='.intval($query['cat_id']).' ';
|
||||
}
|
||||
$join = '';
|
||||
if ($query) // we search in _from, _subject, _des and _extra_value for $query
|
||||
if ($query['search']) // we search in _from, _subject, _des and _extra_value for $query
|
||||
{
|
||||
$query = $this->db->db_addslashes($query);
|
||||
$query['search'] = $this->db->db_addslashes($query['query']);
|
||||
$sql_query = "AND (info_from like '%$query%' OR info_subject ".
|
||||
"LIKE '%$query%' OR info_des LIKE '%$query%' OR info_extra_value LIKE '%$query%') ";
|
||||
$join = 'LEFT JOIN phpgw_infolog_extra ON phpgw_infolog.info_id=phpgw_infolog_extra.info_id';
|
||||
}
|
||||
$pid = 'AND info_id_parent='.($action == 'sp' ? $action_id : 0);
|
||||
$pid = 'AND info_id_parent='.($action == 'sp' ? $query['action_id'] : 0);
|
||||
|
||||
if (!$GLOBALS['phpgw_info']['user']['preferences']['infolog']['listNoSubs'] &&
|
||||
$action != 'sp')
|
||||
@ -533,15 +534,15 @@
|
||||
$ids = array( );
|
||||
if ($action == '' || $action == 'sp' || count($links))
|
||||
{
|
||||
$query = "FROM phpgw_infolog $join WHERE ($filtermethod $pid $sql_query) $link_extra";
|
||||
$this->db->query($sql='SELECT DISTINCT phpgw_infolog.info_id '.$query,__LINE__,__FILE__);
|
||||
$total = $this->db->num_rows();
|
||||
$sql_query = "FROM phpgw_infolog $join WHERE ($filtermethod $pid $sql_query) $link_extra";
|
||||
$this->db->query($sql='SELECT DISTINCT phpgw_infolog.info_id '.$sql_query,__LINE__,__FILE__);
|
||||
$query['total'] = $this->db->num_rows();
|
||||
|
||||
if (!$start || $start > $total)
|
||||
if (!$query['start'] || $query['start'] > $query['total'])
|
||||
{
|
||||
$start = 0;
|
||||
$query['start'] = 0;
|
||||
}
|
||||
$this->db->limit_query($sql="SELECT DISTINCT phpgw_infolog.* $query $ordermethod",$start,__LINE__,__FILE__);
|
||||
$this->db->limit_query($sql="SELECT DISTINCT phpgw_infolog.* $sql_query $ordermethod",$query['start'],__LINE__,__FILE__);
|
||||
//echo "<p>sql='$sql'</p>\n";
|
||||
while ($this->db->next_record())
|
||||
{
|
||||
@ -551,7 +552,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
$start = $total = 0;
|
||||
$query['start'] = $query['total'] = 0;
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
@ -159,24 +159,23 @@
|
||||
//echo "<p>uiinfolog.get_rows(start=$query[start],search='$query[search]',filter='$query[filter]',cat_id=$query[cat_id],action='$query[action]/$query[action_id]',col_filter=".print_r($query['col_filter'],True).")</p>\n";
|
||||
$this->save_sessiondata($query);
|
||||
|
||||
$ids = $this->bo->search($query['order'],$query['sort'],$query['filter'],$query['cat_id'],
|
||||
$query['search'],$query['action'],$query['action_id'],$query['ordermethod'],
|
||||
$query['start'],$total,$query['col_filter']);
|
||||
$ids = $this->bo->search($query);
|
||||
|
||||
if (!is_array($ids))
|
||||
{
|
||||
$ids = array( );
|
||||
}
|
||||
$rows = array( $total );
|
||||
$rows = array( $query['total'] );
|
||||
$readonlys = array();
|
||||
foreach($ids as $id => $info)
|
||||
{
|
||||
$rows[] = $this->get_info($info,$readonlys,$query['action'],$query['action_id']);
|
||||
}
|
||||
//echo "<p>readonlys = "; _debug_array($readonlys);
|
||||
//echo "rows=<pre>".print_r($rows,True)."</pre>\n";
|
||||
reset($rows);
|
||||
|
||||
return $total;
|
||||
return $query['total'];
|
||||
}
|
||||
|
||||
function index($values = 0,$action='',$action_id='',$referer=0,$extra_app_header=False,$return_html=False)
|
||||
@ -253,7 +252,7 @@
|
||||
$action_id = 0;
|
||||
break;
|
||||
}
|
||||
$values['main'][1] = $this->get_info($action_id,&$readonlys['main']);
|
||||
$values['main'][1] = $this->get_info($action_id,$readonlys['main']);
|
||||
break;
|
||||
}
|
||||
$readonlys['cancel'] = $action != 'sp';
|
||||
@ -298,7 +297,7 @@
|
||||
return $referer ? $this->tmpl->location($referer) : $this->index();
|
||||
}
|
||||
$readonlys = $values = array();
|
||||
$values['main'][1] = $this->get_info($info_id,&$readonlys['main']);
|
||||
$values['main'][1] = $this->get_info($info_id,$readonlys['main']);
|
||||
|
||||
$this->tmpl->read('infolog.delete');
|
||||
|
||||
@ -659,8 +658,7 @@
|
||||
$extra = $this->messages + $this->filters;
|
||||
$enums = $this->bo->enums + $this->bo->status;
|
||||
unset($enums['defaults']);
|
||||
reset($enums);
|
||||
while (list($key,$msg_arr) = each($enums))
|
||||
foreach($enums as $key => $msg_arr)
|
||||
{
|
||||
$extra += $msg_arr;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user