newest version of fix_deprecated and changes made by it: fixes deprecated warnings of php5.3

This commit is contained in:
Ralf Becker 2010-09-15 19:19:53 +00:00
parent 2ce1178fd2
commit bf74c8bc0c
12 changed files with 6084 additions and 5 deletions

View File

@ -0,0 +1,71 @@
<?php
/**************************************************************************\
* eGroupWare - Administration *
* http://www.egroupware.org *
* This file written by Joseph Engo <jengo@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$ */
class bocurrentsessions
{
var $ui;
var $so;
var $public_functions = array(
'kill' => True
);
function total()
{
return $GLOBALS['egw']->session->session_count();
}
function list_sessions($start,$order,$sort)
{
$values = $GLOBALS['egw']->session->session_list($start,$sort,$order);
while (list(,$value) = @each($values))
{
if (strpos($value['session_lid'],'@') !== false)
{
$t = explode('@',$value['session_lid']);
$session_lid = $t[0];
}
else
{
$session_lid = $value['session_lid'];
}
$tmp = time() - $value['session_dla'];
$secs = $tmp % 60;
$mins = (($tmp - $secs) % 3600) / 60;
$hours = ($tmp - ($mins * 60) - $secs) / 3600;
$_values[] = array(
'session_id' => $value['session_id'],
'session_lid' => $session_lid,
'session_ip' => $value['session_ip'],
'session_logintime' => $GLOBALS['egw']->common->show_date($value['session_logintime']),
'session_action' => $value['session_action'],
'session_dla' => $value['session_dla'],
'session_idle' => str_pad($hours, 2, '0', STR_PAD_LEFT) . ':' . str_pad($mins, 2, '0', STR_PAD_LEFT) . ':' . str_pad($secs, 2, '0', STR_PAD_LEFT)
);
}
return $_values;
}
function kill()
{
if ($_GET['ksession'] &&
($GLOBALS['sessionid'] != $_GET['ksession']) &&
! $GLOBALS['egw']->acl->check('current_sessions_access',8,'admin'))
{
$GLOBALS['egw']->session->destroy($_GET['ksession'],0);
}
$this->ui =& CreateObject('admin.uicurrentsessions');
$this->ui->list_sessions();
}
}

1714
admin/inc/class.uiaccounts.inc.php Executable file

File diff suppressed because it is too large Load Diff

541
calendar/csv_import.php Normal file
View File

@ -0,0 +1,541 @@
<?php
/**
* Calendar - CSV import
*
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @package calendar
* @copyright (c) 2003-9 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
$GLOBALS['egw_info'] = array(
'flags' => array(
'currentapp' => 'calendar',
'noheader' => True
),
);
include('../header.inc.php');
$is_admin = isset($GLOBALS['egw_info']['user']['apps']['admin']) && $GLOBALS['egw_info']['user']['apps']['admin'];
if (isset($_FILES['csvfile']['tmp_name']))
{
$csvfile = tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
$GLOBALS['egw']->session->appsession('csvfile','',$csvfile);
$_POST['action'] = move_uploaded_file($_FILES['csvfile']['tmp_name'],$csvfile) ?
'download' : '';
}
else
{
$csvfile = $GLOBALS['egw']->session->appsession('csvfile');
}
if ($_POST['cancel'])
{
@unlink($csvfile);
$GLOBALS['egw']->redirect_link('/calendar/index.php');
}
if (isset($_POST['charset']))
{
// we have to set the local, to fix eg. utf-8 imports, as fgetcsv requires it!
common::setlocale(LC_CTYPE,$_POST['charset']);
}
$GLOBALS['egw_info']['flags']['app_header'] = $GLOBALS['egw_info']['apps']['calendar']['title'].' - '.lang('Import CSV-File');
$cal = new calendar_boupdate(true);
$GLOBALS['egw']->common->egw_header();
$GLOBALS['egw']->template->set_file(array('import_t' => 'csv_import.tpl'));
$GLOBALS['egw']->template->set_block('import_t','filename','filenamehandle');
$GLOBALS['egw']->template->set_block('import_t','fheader','fheaderhandle');
$GLOBALS['egw']->template->set_block('import_t','fields','fieldshandle');
$GLOBALS['egw']->template->set_block('import_t','ffooter','ffooterhandle');
$GLOBALS['egw']->template->set_block('import_t','imported','importedhandle');
$GLOBALS['egw']->template->set_block('import_t','import','importhandle');
if(($_POST['action'] == 'download' || $_POST['action'] == 'continue') && (!$_POST['fieldsep'] || !$csvfile || !($fp=fopen($csvfile,'rb'))))
{
$_POST['action'] = '';
}
$GLOBALS['egw']->template->set_var("action_url",$GLOBALS['egw']->link("/calendar/csv_import.php"));
$PSep = '||'; // Pattern-Separator, separats the pattern-replacement-pairs in trans
$ASep = '|>'; // Assignment-Separator, separats pattern and replacesment
$VPre = '|#'; // Value-Prefix, is expanded to \ for ereg_replace
$CPre = '|['; $CPreReg = '\|\['; // |{csv-fieldname} is expanded to the value of the csv-field
$CPos = ']'; $CPosReg = '\]'; // if used together with @ (replacement is eval-ed) value gets autom. quoted
function addr_id( $n_family,$n_given=null,$org_name=null )
{ // find in Addressbook, at least n_family AND (n_given OR org_name) have to match
static $contacts;
if (!is_object($contacts))
{
$contacts =& CreateObject('phpgwapi.contacts');
}
if (!is_null($org_name)) // org_name given?
{
$addrs = $contacts->read( 0,0,array('id'),'',"n_family=$n_family,n_given=$n_given,org_name=$org_name" );
if (!count($addrs))
{
$addrs = $contacts->read( 0,0,array('id'),'',"n_family=$n_family,org_name=$org_name",'','n_family,org_name');
}
}
if (!is_null($n_given) && (is_null($org_name) || !count($addrs))) // first name given and no result so far
{
$addrs = $contacts->read( 0,0,array('id'),'',"n_family=$n_family,n_given=$n_given",'','n_family,n_given' );
}
if (is_null($n_given) && is_null($org_name)) // just one name given, check against fn (= full name)
{
$addrs = $contacts->read( 0,0,array('id'),'',"n_fn=$n_family",'','n_fn' );
}
if (count($addrs))
{
return $addrs[0]['id'];
}
return False;
}
$cat2id = array( );
function cat_id($cats)
{
if (!$cats)
{
return '';
}
foreach(preg_split('/[,;]/',$cats) as $cat)
{
if (isset($cat2id[$cat]))
{
$ids[$cat] = $cat2id[$cat]; // cat is in cache
}
else
{
if (is_numeric($cat) && $GLOBALS['egw']->categories->id2name($cat) != '--')
{
$cat2id[$cat] = $ids[$cat] = $cat;
}
elseif ($id = $GLOBALS['egw']->categories->name2id( addslashes($cat) ))
{ // cat exists
$cat2id[$cat] = $ids[$cat] = $id;
}
else
{ // create new cat
$GLOBALS['egw']->categories->add( array('name' => $cat,'descr' => $cat ));
$cat2id[$cat] = $ids[$cat] = $GLOBALS['egw']->categories->name2id( addslashes($cat) );
}
}
}
return implode( ',',$ids );
}
if ($_POST['next']) $_POST['action'] = 'next';
switch ($_POST['action'])
{
case '': // Start, ask Filename
$GLOBALS['egw']->template->set_var('lang_csvfile',lang('CSV-Filename'));
$GLOBALS['egw']->template->set_var('lang_fieldsep',lang('Fieldseparator'));
$GLOBALS['egw']->template->set_var('lang_charset',lang('Charset of file'));
$GLOBALS['egw']->template->set_var('lang_help',lang('Please note: You can configure the field assignments AFTER you uploaded the file.'));
$GLOBALS['egw']->template->set_var('select_charset',
html::select('charset','',translation::get_installed_charsets(),True));
$GLOBALS['egw']->template->set_var('fieldsep',$_POST['fieldsep'] ? $_POST['fieldsep'] : ';');
$GLOBALS['egw']->template->set_var('submit',lang('Import'));
$GLOBALS['egw']->template->set_var('enctype','ENCTYPE="multipart/form-data"');
$GLOBALS['egw']->template->parse('rows','filename');
break;
case 'continue':
case 'download':
$GLOBALS['egw']->preferences->read_repository();
$defaults = $GLOBALS['egw_info']['user']['preferences']['calendar']['cvs_import'];
if (!is_array($defaults))
{
$defaults = array();
}
$GLOBALS['egw']->template->set_var('lang_csv_fieldname',lang('CSV-Fieldname'));
$GLOBALS['egw']->template->set_var('lang_info_fieldname',lang('calendar-Fieldname'));
$GLOBALS['egw']->template->set_var('lang_translation',lang("Translation").' <a href="#help">'.lang('help').'</a>');
$GLOBALS['egw']->template->set_var('submit',
html::submit_button('convert','Import') . '&nbsp;'.
html::submit_button('cancel','Cancel'));
$GLOBALS['egw']->template->set_var('lang_debug',lang('Test Import (show importable records <u>only</u> in browser)'));
$GLOBALS['egw']->template->parse('rows','fheader');
$cal_names = array(
'title' => 'Title varchar(80)',
'description' => 'Description text',
'location' => 'Location varchar(255)',
'start' => 'Start Date: Timestamp or eg. YYYY-MM-DD hh:mm',
'end' => 'End Date: Timestamp or eg. YYYY-MM-DD hh:mm',
'participants' => 'Participants: comma separated user-id\'s or -names',
'category' => 'Categories: id\'s or names, comma separated (new ones got created)',
'priority' => 'Priority: 1=Low, 2=Normal, 3=High',
'public' => 'Access: 1=public, 0=private',
'owner' => 'Owner: int(11) user-id/-name',
'modified' => 'Modification date',
'modifier' => 'Modification user',
'non_blocking' => '0=Event blocks time, 1=Event creates no conflicts',
'uid' => 'Unique Id, allows multiple import to update identical entries',
// 'recur_type'=> 'Type of recuring event',
'addr_id' => 'Link to Addressbook, use nlast,nfirst[,org] or contact_id from addressbook',
'link_1' => '1. link: appname:appid the entry should be linked to, eg.: addressbook:123',
'link_2' => '2. link: appname:appid the entry should be linked to, eg.: addressbook:123',
'link_3' => '3. link: appname:appid the entry should be linked to, eg.: addressbook:123',
);
$custom_fields = config::get_customfields('calendar');
//echo "custom-fields=<pre>".print_r($custom_fields,True)."</pre>";
foreach ($custom_fields as $name => $data)
{
$cal_names['#'.$name] = $data['label'].': Custom field ('.$data['type'].')';
}
// the next line is used in the help-text too
$mktime_lotus = "${PSep}0?([0-9]+)[ .:-]+0?([0-9]*)[ .:-]+0?([0-9]*)[ .:-]+0?([0-9]*)[ .:-]+0?([0-9]*)[ .:-]+0?([0-9]*).*$ASep@mktime(${VPre}4,${VPre}5,${VPre}6,${VPre}2,${VPre}3,${VPre}1)";
$cal_name_options = "<option value=\"\">none\n";
foreach($cal_names as $field => $name)
{
$cal_name_options .= "<option value=\"$field\">".$GLOBALS['egw']->strip_html($name)."\n";
}
$csv_fields = fgetcsv($fp,8000,$_POST['fieldsep']);
$csv_fields = translation::convert($csv_fields,$_POST['charset']);
$csv_fields[] = 'no CSV 1'; // eg. for static assignments
$csv_fields[] = 'no CSV 2';
$csv_fields[] = 'no CSV 3';
foreach($csv_fields as $csv_idx => $csv_field)
{
$GLOBALS['egw']->template->set_var('csv_field',$csv_field);
$GLOBALS['egw']->template->set_var('csv_idx',$csv_idx);
if ($def = $defaults[$csv_field])
{
list( $info,$trans ) = explode($PSep,$def,2);
$GLOBALS['egw']->template->set_var('trans',$trans);
$GLOBALS['egw']->template->set_var('cal_fields',str_replace('="'.$info.'">','="'.$info.'" selected>',$cal_name_options));
}
else
{
$GLOBALS['egw']->template->set_var('trans','');
$GLOBALS['egw']->template->set_var('cal_fields',$cal_name_options);
}
$GLOBALS['egw']->template->parse('rows','fields',True);
}
$GLOBALS['egw']->template->set_var('lang_start',lang('Startrecord'));
$GLOBALS['egw']->template->set_var('start',get_var('start',array('POST'),1));
$msg = ($safe_mode = ini_get('safe_mode') == 'On') ? lang('to many might exceed your execution-time-limit'):
lang('empty for all');
$GLOBALS['egw']->template->set_var('lang_max',lang('Number of records to read (%1)',$msg));
$GLOBALS['egw']->template->set_var('max',get_var('max',array('POST'),$safe_mode ? 200 : ''));
$GLOBALS['egw']->template->set_var('debug',get_var('debug',array('POST'),True)?' checked':'');
$GLOBALS['egw']->template->parse('rows','ffooter',True);
fclose($fp);
$hiddenvars = html::input_hidden(array(
'action' => 'import',
'fieldsep'=> $_POST['fieldsep'],
'charset' => $_POST['charset']
));
$help_on_trans = "<a name=\"help\"></a><b>How to use Translation's</b><p>".
"Translations enable you to change / adapt the content of each CSV field for your needs. <br>".
"General syntax is: <b>pattern1 ${ASep} replacement1 ${PSep} ... ${PSep} patternN ${ASep} replacementN</b><br>".
"If the pattern-part of a pair is ommited it will match everything ('^.*$'), which is only ".
"usefull for the last pair, as they are worked from left to right.<p>".
"First example: <b>1${ASep}private${PSep}public</b><br>".
"This will translate a '1' in the CVS field to 'privat' and everything else to 'public'.<p>".
"Patterns as well as the replacement can be regular expressions (the replacement is done via ereg_replace). ".
"If, after all replacements, the value starts with an '@' AND you have admin rights the whole value is eval()'ed, so you ".
"may use php, eGroupWare or your own functions. This is quiet powerfull, but <u>circumvents all ACL</u>.<p>".
"Example using regular expressions and '@'-eval(): <br><b>$mktime_lotus</b><br>".
"It will read a date of the form '2001-05-20 08:00:00.00000000000000000' (and many more, see the regular expr.). ".
"The&nbsp;[&nbsp;.:-]-separated fields are read and assigned in different order to @mktime(). Please note to use ".
"${VPre} insted of a backslash (I couldn't get backslash through all the involved templates and forms.) ".
"plus the field-number of the pattern.<p>".
"In addintion to the fields assign by the pattern of the reg.exp. you can use all other CSV-fields, with the ".
"syntax <b>${CPre}CVS-FIELDNAME$CPos</b>. Here is an example: <br>".
"<b>.+$ASep${CPre}Company$CPos: ${CPre}NFamily$CPos, ${CPre}NGiven$CPos$PSep${CPre}NFamily$CPos, ${CPre}NGiven$CPos</b><br>".
"It is used on the CVS-field 'Company' and constructs a something like <i>Company: FamilyName, GivenName</i> or ".
"<i>FamilyName, GivenName</i> if 'Company' is empty.<p>".
"You can use the 'No CVS #'-fields to assign cvs-values to more than on field, the following example uses the ".
"cvs-field 'Note' (which gots already assingned to the description) and construct a short subject: ".
"<b>@substr(${CPre}Note$CPos,0,60).' ...'</b><p>".
"Their is two important user-function for the calendar:<br>".
"<b>@addr_id(${CPre}NFamily$CPos,${CPre}NGiven$CPos,${CPre}Company$CPos)</b> ".
"searches the addressbook for an address and returns the id if it founds an exact match of at least ".
"<i>NFamily</i> AND (<i>NGiven</i> OR <i>Company</i>). This is necessary to link your imported calendar-entrys ".
"with the addressbook.<br>".
"<b>@cat_id(Cat1,...,CatN)</b> returns a (','-separated) list with the cat_id's. If a category isn't found, it ".
"will be automaticaly added. This function is automaticaly called if the category is not numerical!<p>".
"I hope that helped to understand the features, if not <a href='mailto:egroupware-users@lists.sf.net'>ask</a>.";
$GLOBALS['egw']->template->set_var('help_on_trans',lang($help_on_trans)); // I don't think anyone will translate this
break;
case 'next':
$_POST['cal_fields'] = unserialize(stripslashes($_POST['cal_fields']));
$_POST['trans'] = unserialize(stripslashes($_POST['trans']));
// fall-through
case 'import':
$hiddenvars = html::input_hidden(array(
'action' => 'continue',
'fieldsep'=> $_POST['fieldsep'],
'charset' => $_POST['charset'],
'start' => $_POST['start']+(!$_POST['debug'] ? $_POST['max'] : 0),
'max' => $_POST['max'],
'debug' => $_POST['debug'],
'cal_fields' => $_POST['cal_fields'],
'trans' => $_POST['trans']
));
@set_time_limit(0);
$fp=fopen($csvfile,'r');
$csv_fields = fgetcsv($fp,8000,$_POST['fieldsep']);
$csv_fields = translation::convert($csv_fields,$_POST['charset']);
$csv_fields[] = 'no CSV 1'; // eg. for static assignments
$csv_fields[] = 'no CSV 2';
$csv_fields[] = 'no CSV 3';
$cal_fields = array_diff($_POST['cal_fields'],array( '' )); // throw away empty / not assigned entrys
$defaults = array();
foreach($cal_fields as $csv_idx => $info)
{ // convert $trans[$csv_idx] into array of pattern => value
$defaults[$csv_fields[$csv_idx]] = $info;
if ($_POST['trans'][$csv_idx])
{
$defaults[$csv_fields[$csv_idx]] .= $PSep.addslashes($_POST['trans'][$csv_idx]);
}
}
$GLOBALS['egw']->preferences->read_repository();
$GLOBALS['egw']->preferences->add('calendar','cvs_import',$defaults);
$GLOBALS['egw']->preferences->save_repository(True);
$log = '<table border="1" style="border: 1px dotted black; border-collapse: collapse;">'."\n\t<tr><td>#</td>\n";
foreach($cal_fields as $csv_idx => $info)
{ // convert $trans[$csv_idx] into array of pattern => value
// if (!$debug) echo "<p>$csv_idx: ".$csv_fields[$csv_idx].": $info".($trans[$csv_idx] ? ': '.$trans[$csv_idx] : '')."</p>";
$pat_reps = explode($PSep,stripslashes($_POST['trans'][$csv_idx]));
$replaces = ''; $values = '';
if ($pat_reps[0] != '')
{
foreach($pat_reps as $k => $pat_rep)
{
list($pattern,$replace) = explode($ASep,$pat_rep,2);
if ($replace == '')
{
$replace = $pattern; $pattern = '^.*$';
}
$values[$pattern] = $replace; // replace two with only one, added by the form
$replaces .= ($replaces != '' ? $PSep : '') . $pattern . $ASep . $replace;
}
$trans[$csv_idx] = $values;
}
$log .= "\t\t<td><b>$info</b></td>\n";
}
if (!in_array('public',$cal_fields)) // autocreate public access if not set by user
{
$log .= "\t\t<td><b>isPublic</b></td>\n";
$cal_fields[] = 'public';
}
/* if (!in_array('recur_type',$cal_fields)) // autocreate single event if not set by user
{
$log .= "\t\t<td><b>recureing</b></td>\n";
}*/
$log .= "\t\t<td><b>Imported</b></td>\n\t</tr>\n";
$start = $_POST['start'] < 1 ? 1 : $_POST['start'];
// ignore empty lines, is_null($fields[0]) is returned on empty lines !!!
for($i = 1; $i < $start; ++$i) // overread lines before our start-record
{
while(($fields = fgetcsv($fp,8000,$_POST['fieldsep'])) && is_null($fields[0])) ;
}
for($anz = 0; !$_POST['max'] || $anz < $_POST['max']; ++$anz)
{
while(($fields = fgetcsv($fp,8000,$_POST['fieldsep'])) && is_null($fields[0])) ;
if (!$fields)
{
break; // EOF
}
$fields = translation::convert($fields,$_POST['charset']);
$log .= "\t<tr>\n\t\t<td>".($start+$anz)."</td>\n";
$values = $orig = array();
foreach($cal_fields as $csv_idx => $info)
{
//echo "<p>$csv: $info".($trans[$csv] ? ': '.$trans[$csv] : '')."</p>";
$val = $fields[$csv_idx];
if (isset($trans[$csv_idx]) && is_array($trans[$csv_idx]))
{
foreach($trans[$csv_idx] as $pattern => $replace)
{
if (ereg((string) $pattern,$val))
{
//echo "<p>csv_idx='$csv_idx',info='$info',trans_csv=".print_r($trans_csv).",preg_replace('/$pattern/','$replace','$val') = ";
$val = preg_replace('/'.(string) $pattern.'/',str_replace($VPre,'\\',$replace),(string) $val);
//echo "'$val'";
$reg = $CPreReg.'([a-zA-Z_0-9 ]+)'.$CPosReg;
while (ereg($reg,$val,$vars))
{ // expand all CSV fields
$val = str_replace($CPre.$vars[1].$CPos,$val[0] == '@' ? "'".addslashes($fields[array_search($vars[1],$csv_fields)])."'" : $fields[array_search($vars[1],$csv_fields)],$val);
}
//echo "='$val'</p>";
if ($val[0] == '@' && is_admin)
{
// removing the $ to close security hole of showing vars, which contain eg. passwords
$val = 'return '.substr(str_replace('$','',$val),1).';';
// echo "<p>eval('$val')=";
$val = eval($val);
// echo "'$val'</p>";
}
if ($pattern[0] != '@' || $val)
break;
}
}
}
$values[$info] = $orig[$info] = $val;
}
if (!isset($values['public']))
{
$values['public'] = 1; // public access if not set by user
}
if (!isset($values['recur_type']))
{
$values['recur_type'] = MCAL_RECUR_NONE; // single event if not set by user
}
if(count($values)) // dont import empty contacts
{
//echo "values=<pre>".print_r($values,True)."</pre>\n";
foreach(array('owner','modifier') as $name)
{
if (preg_match('/\[([^\]]+)\]/',$values[$name],$matches)) $values[$name] = $matches[1];
if (!is_numeric($values[$name])) $values[$name] = $GLOBALS['egw']->accounts->name2id($values[$name],'account_lid','u');
}
if (!$values['owner'] || !$GLOBALS['egw']->accounts->exists($values['owner']))
{
$values['owner'] = $GLOBALS['egw_info']['user']['account_id'];
}
if ($values['priority'] < 1 || $values['priority'] > 3)
{
$values['priority'] = 2;
}
// convert the category name to an id
if ($values['category'] && !is_numeric($values['category']))
{
$values['category'] = cat_id($values['category']);
}
if (empty($values['title']))
{
$values['title'] = '('.lang('none').')';
}
// convert dates to timestamps
foreach(array('start','end','modified') as $date)
{
if (isset($values[$date]) && !is_numeric($date))
{
// convert german DD.MM.YYYY format into ISO YYYY-MM-DD format
$values[$date] = preg_replace('/([0-9]{1,2}).([0-9]{1,2}).([0-9]{4})/','\3-\2-\1',$values[$date]);
// remove fractures of seconds if present at the end of the string
if (preg_match('/(.*)\.[0-9]+/',$values[$date],$parts)) $values[$date] = $parts[1];
$values[$date] = strtotime($values[$date]);
}
}
// convert participants-names to user-id's
$parts = $values['participants'] ? preg_split('/[,;]/',$values['participants']) : array();
$values['participants'] = array();
foreach($parts as $part_status)
{
list($part,$status) = explode('=',$part_status);
$valid_status = array('U'=>'U','u'=>'U','A'=>'A','a'=>'A','R'=>'R','r'=>'R','T'=>'T','t'=>'T');
$status = isset($valid_status[$status]) ? $valid_status[$status] : 'U';
if (!is_numeric($part))
{
if (preg_match('/\[([^\]]+)\]/',$part,$matches)) $part = $matches[1];
$part = $GLOBALS['egw']->accounts->name2id($part);
}
if ($part && is_numeric($part))
{
$values['participants'][$part] = $status;
}
}
if (!count($values['participants'])) // no valid participants so far --> add the importing user/owner
{
$values['participants'][$values['owner']] = 'A';
}
if ($values['addr_id'] && !is_numeric($values['addr_id']))
{
list($lastname,$firstname,$org_name) = explode(',',$values['addr_id']);
$values['addr_id'] = addr_id($lastname,$firstname,$org_name);
}
if ($values['uid'])
{
if (is_numeric($values['uid'])) // to not conflict with our own id's
{
$values['uid'] = 'cal-csv-import-'.$values['uid'].'-'.$GLOBALS['egw_info']['server']['install_id'];
}
if (($event = $cal->read($values['uid'],null,$is_admin))) // no ACL check for admins
{
//echo "updating existing event"; _debug_array($event);
$values['id'] = $event['id'];
}
}
$action = $values['id'] ? 'updating' : 'adding';
//echo $action.'<pre>'.print_r($values,True)."</pre>\n";
// Keep links, $cal->update will remove them
$links = array(
'addr_id' => 'addressbook:' . $values['addr_id'],
'link_1' => $values['link_1'],
'link_2' => $values['link_2'],
'link_3' => $values['link_3'],
);
if (!$_POST['debug'] &&
($cal_id = $cal->update($values,true,!$values['modified'],$is_admin))) // ignoring conflicts and ACL (for admins) on import
{
foreach($links as $value) {
list($app,$app_id) = explode(':',$value);
if ($app && $app_id)
{
//echo "<p>linking calendar:$cal_id with $app:$app_id</p>\n";
egw_link::link('calendar',$cal_id,$app,$app_id);
}
}
}
// display read and interpreted results, so the user can check it
foreach($cal_fields as $name)
{
$log .= "\t\t<td>".($orig[$name] != $values[$name] ? htmlspecialchars($orig[$name]).' --> ' : '').
htmlspecialchars($values[$name])."</td>\n";
}
if(!$_POST['debug'] && count($values)) // dont import empty contacts
{
$log .= "\t\t".'<td align="center">'.($cal_id ? $action." cal_id=$cal_id" : 'Error '.$action)."</td>\n\t</tr>\n";
}
else
{
$log .= "\t\t".'<td align="center">only test</td>'."\n\t</tr>\n";
}
}
}
$log .= "</table>\n";
$GLOBALS['egw']->template->set_var('anz_imported',($_POST['debug'] ?
lang('%1 records read (not yet imported, you may go back and uncheck Test Import)',
$anz,'','') :
lang('%1 records imported',$anz)). '&nbsp;'.
(!$_POST['debug'] && $fields ? html::submit_button('next','Import next set') . '&nbsp;':'').
html::submit_button('continue','Back') . '&nbsp;'.
html::submit_button('cancel','Cancel'));
$GLOBALS['egw']->template->set_var('log',$log);
$GLOBALS['egw']->template->parse('rows','imported');
break;
}
$GLOBALS['egw']->template->set_var('hiddenvars',str_replace('{','&#x7B;',$hiddenvars));
$GLOBALS['egw']->template->pfp('phpgw_body','import');
$GLOBALS['egw']->common->egw_footer();

View File

@ -0,0 +1,397 @@
<?php
/**************************************************************************\
* eGroupWare SiteMgr - Web Content Management *
* http://www.egroupware.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: class.module_calendar_list.inc.php,v 1.9 2008-12-30 17:56:19 hjtappe Exp $ */
/*
// AN EXAMPLE STYLESHEET
.cal_list_event {
padding-bottom: 5px;
}
.cal_list_title {
clear: both;
font-weight: bold;
}
.cal_list_date {
clear: both;
padding-left:15px;
}
.cal_list_weekday {
}
.cal_list_descr {
clear: both;
padding-left: 15px;
font-style: italic;
}
.cal_list_end {
display: none;
}
.cal_event_even {
background: #F1F1F1;
}
.cal_event_uneven {
}
.cal_list_weeksplit {
width = 80%;
vertical-align: center;
border-top-width: 1px;
}
.cal_list_weektop {
}
.cal_list_weeksplit {
width: 100%;
border-top: 1px;
border-top-style: solid;
}
.cal_list_weekbottom {
}
*/
class module_calendar_list extends Module
{
/**
* Instance of the business object of calendar
*
* @var bo
*/
var $bo;
/**
* Instance of the user interface object of calendar
*
* @var ui
*/
var $ui;
function module_calendar_list()
{
$this->arguments = array(
'category' => array(
'type' => 'select',
'label' => lang('Choose a category'),
'options' => array(), // specification of options is postponed into the get_user_interface function
'multiple' => true,
),
'numWeeks' => array(
'type' => 'textfield',
'label' => lang('Number of weeks to show'),
'default' => '4',
'params' => array('size' => 1),
),
'showTitle' => array(
'type' => 'checkbox',
'label' => lang('Show a calendar title'),
'default' => false,
),
'offset' => array(
'type' => 'textfield',
'label' => lang('Weeks offset (for multi-column display)'),
'default' => '0',
'params' => array('size' => 1),
),
'search' => array(
'type' => 'textfield',
'label' => lang('Search string for the events'),
),
'numEntries' => array(
'type' => 'textfield',
'label' => lang('Max. Number of entries to show (leave empty for no restriction)'),
'default' => '',
'params' => array('size' => 1),
),
'entryOffset' => array(
'type' => 'textfield',
'label' => lang('How much entries to skip'),
'default' => '0',
'params' => array('size' => 1),
),
'users' => array(
'type' => 'select',
'options' => array(),
'label' => lang('Group(s) or user(s) whose calendars to show (if ACL exists)'),
// 'multiple' => true, is set in the get_user_interface function.
),
'showWeeks' => array(
'type' => 'checkbox',
'label' => lang('Should the number of weeks be shown on top of the calendar (only if offset = 0)'),
'default' => false,
),
'useWeekStart' => array(
'type' => 'checkbox',
'label' => lang('Use weekday start'),
'default' => false,
),
'acceptDateParam' => array(
'type' => 'checkbox',
'label' => lang('Shall the date parameter be accepted (e.g. from calendar module)?'),
'default' => false,
),
);
$this->title = lang('Calendar - List');
$this->description = lang("This module displays calendar events as a list.");
}
function get_user_interface()
{
// copied from bookmarks module.
$cat = createobject('phpgwapi.categories','','calendar');
$cats = $cat->return_array('all',0,False,'','cat_name','',True);
$cat_ids = array();
while (list(,$category) = @each($cats))
{
$cat_ids[$category['id']] = $GLOBALS['egw']->strip_html($category['name']);
}
$this->arguments['category']['options'] = $cat_ids;
if (count($cat_ids) > 5) {
$this->arguments['category']['multiple'] = 5;
}
if (! isset($GLOBALS['egw']->accounts))
{
$GLOBALS['egw']->accounts = new accounts();
}
$this->accounts =& $GLOBALS['egw']->accounts;
$search_params=array(
'type' => 'both',
'app' => 'calendar',
);
$accounts = $this->accounts->search($search_params);
$users = array();
$groups = array();
// sort users and groups separately.
if (isset($GLOBALS['sitemgr_info']['anonymous_user']))
{
$anon_user = $this->accounts->name2id($GLOBALS['sitemgr_info']['anonymous_user'],'account_lid','u');
}
else
{
// sitemgr is not in global variables. Get it.
/*
* Get possible sitemgr paths from the HTTP_REFERRER in order to unreveal the
* anonymous user for the correct site.
*/
$sitemgr_path = preg_replace('/^[^\/]+:\/\/[^\/]+\/([^\?]*)(\?.*)*$/',"/\${1}",$_SERVER['HTTP_REFERER']);
// Remove the trailing file- / pathname if any
$sitemgr_path = preg_replace('/[^\/]*$/', '', $sitemgr_path);
// Add leading slash if it has been lost.
if (strncmp('/', $sitemgr_path, 1) != 0)
{
$sitemgr_path = '/'.$sitemgr_path;
}
// Code adapted from sitemgr-site/index.php
$site_urls = array();
$site_urls[] = $sitemgr_path;
$site_urls[] = ($_SERVER['HTTPS'] ? 'https://' : 'http://') . $_SERVER['SERVER_ADDR'] . $sitemgr_path;
$site_urls[] = $site_url = ($_SERVER['HTTPS'] ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'] . $sitemgr_path;
$GLOBALS['egw']->db->select('egw_sitemgr_sites','anonymous_user,anonymous_passwd,site_id',
array('site_url' => $site_urls),__LINE__,__FILE__,false,'','sitemgr');
$GLOBALS['egw']->db->next_record();
$anon_user = $this->accounts->name2id($GLOBALS['egw']->db->f('anonymous_user'),'account_lid','u');
}
$anon_groups = $this->accounts->memberships($anon_user,true);
foreach ($accounts as $entry)
{
$is_group = false;
$has_read_permissions = false;
$acl = new acl($entry['account_id']);
$acl->read_repository();
// get the rights for each account to check whether the anon user has read permissions.
$rights = $acl->get_rights($anon_user,'calendar');
// also add the anon user if it's his own calendar.
if (($rights & EGW_ACL_READ) || ($entry['account_id'] == $anon_user))
{
$has_read_permissions = true;
}
else
{
// scan the groups which pass on permissions to the anon user group member
// or ass permissions if this is the anon group's calendar.
foreach ($anon_groups as $parent_group)
{
$rights = $acl->get_rights($parent_group,'calendar');
if (($rights & EGW_ACL_READ) || ($entry['account_id'] == $parent_group))
{
$has_read_permissions = true;
break;
}
}
}
if ($has_read_permissions)
{
// Separate groups from users for improved readability.
if ($is_group)
{
$groups[$entry['account_id']] = $entry['account_lid'];
}
else
{
$users[$entry['account_id']] = $GLOBALS['egw']->common->display_fullname($entry['account_lid'],$entry['account_firstname'],$entry['account_lastname']);
}
}
}
asort($groups);
asort($users);
// concat users and groups to the option array.
$this->arguments['users']['options'] = $groups + $users;
if (count($this->arguments['users']['options']) > 10)
{
$this->arguments['users']['multiple'] = 10;
}
else if (count($this->arguments['users']['options']) > 0)
{
$this->arguments['users']['multiple'] = true;
}
return parent::get_user_interface();
}
function get_content(&$arguments,$properties)
{
$html = "";
$GLOBALS['egw']->translation->add_app('calendar');
$this->bo = new calendar_bo();
$this->ui = new calendar_uiviews();
$this->ui->allowEdit = false;
$this->ui->use_time_grid = isset($arguments['grid']) ? $arguments['grid'] : false;
$weeks = $arguments['numWeeks'] ? (int) $arguments['numWeeks'] : 4;
$dateOffset = $arguments['offset'] ? (int) $arguments['offset'] : 0;
if (($arguments['acceptDateParam']) && (get_var('date',array('POST','GET'))))
{
$first = $start = (int) (strtotime(get_var('date',array('POST','GET'))) +
(60 * 60 * 24 * 7 * $dateOffset));
}
else
{
$first = $start = (int) ($this->bo->now_su +
(60 * 60 * 24 * 7 * $dateOffset));
}
if ($arguments['useWeekStart'])
{
$first = $this->ui->datetime->get_weekday_start(
adodb_date('Y',$start),
adodb_date('m',$start),
adodb_date('d',$start));
}
$last = (int) ($first +
(60 * 60 * 24 * 7 * $weeks));
if ($arguments['showTitle'])
{
$html .= '<div id="divAppboxHeader">'.$GLOBALS['egw_info']['apps']['calendar']['title'].' - ';
$html .= lang('After %1',$this->bo->long_date($first));
$html .= "</div>";
}
// set the search parameters
$search_params = Array
(
'offset' => $arguments['entryOffset'] ? (int) $arguments['entryOffset'] : false,
'order' => 'cal_start ASC',
'start' => $first,
'end' => $last,
);
$search_string = trim($arguments['search']);
if ($search_string != "")
{
$search_params['query'] = $search_string;
}
if (count($arguments['category']) > 0)
{
$search_params['cat_id'] = $arguments['category'];
}
if ((is_array($arguments['users'])) && (count($arguments['users']) > 0))
{
$search_params['users'] = $arguments['users'];
}
if ($arguments['numEntries'])
{
$search_params['num_rows'] = (int) $arguments['numEntries'];
$search_params['offset'] = $arguments['entryOffset'] ? (int) $arguments['entryOffset'] :0;
}
$rows = array();
foreach((array) $this->bo->search($search_params) as $event)
{
$event['date'] = $this->bo->date2string($event['start']);
if (empty($event['description'])) $event['description'] = ' '; // no description screws the titles horz. alignment
if (empty($event['location'])) $event['location'] = ' '; // no location screws the owner horz. alignment
$rows[] = $event;
}
if (($arguments['showWeeks']) && ((int)$arguments['offset'] == 0))
{
$html .= "<div>".lang('Next')." ".lang('%1 weeks', $weeks).":</div>\n";
}
if (($search_params['offset'] && $this->bo->total == 0) || count($rows)==0)
{
$html .= "<div>".lang("no events found")."</div>";
}
else
{
$event_count = 0;
$last_week = 0;
$html .= "\n<div>\n";
$html .= ' <div class="cal_list_weektop"></div>'."\n";
foreach ($rows as $event)
{
if (($last_week != 0) && (adodb_date('W-Y',$event['start']) != $last_week))
{
$html .= ' <div class="cal_list_weeksplit"></div>'."\n";
}
$last_week = adodb_date('W-Y',$event['start']);
$html .= " <!-- Event -->\n";
if ($event_count % 2 == 0) {
$html .= ' <div class="cal_list_event cal_event_even">'."\n";
}
else
{
$html .= ' <div class="cal_list_event cal_event_uneven">'."\n";
}
$html .= ' <div class="cal_list_title">'.$event['title']."</div>\n";
$html .= ' <div class="cal_list_date">';
$html .= '<span class="cal_list_start">';
$html .= '<span class="cal_list_weekday">'.lang(adodb_date('D',$event['start'])).".".($this->bo->common_prefs['dateformat'][0] != 'd' ? ' ' : ', ')."</span>";
$html .= $this->bo->format_date($event['start'])."</span>";
$html .= '<span class="cal_list_end"> - ';
$html .= '<span class="cal_list_weekday">'.lang(adodb_date('D',$event['end'])).".".($this->bo->common_prefs['dateformat'][0] != 'd' ? ' ' : ', ')."</span>";
$html .= $this->bo->format_date($event['end'])."</span></div>\n";
$descr = trim($event['description']);
if (! empty($descr)) {
$html .= " <div class=\"cal_list_descr\">\n".preg_replace('/\\n/',"<br>\n",$event['description'])."</div>\n";
}
$html .= " </div><!-- cal_list_event -->\n";
$event_count ++;
}
$html .= ' <div class="cal_list_weekbottom"></div>'."\n";
$html .= "<!-- End module -->\n";
$html .= "</div>\n";
}
return $html;
}
}

View File

@ -46,7 +46,7 @@ class module_calendar_month extends Module
function module_calendar_month()
{
$this->bo =& new calendar_bo();
$this->bo = new calendar_bo();
$this->arguments = array(
'category' => array(
'type' => 'select',
@ -166,7 +166,7 @@ class module_calendar_month extends Module
{
$is_group = false;
$has_read_permissions = false;
$acl =& new acl($entry['account_id']);
$acl = new acl($entry['account_id']);
$acl->read_repository();
// get the rights for each account to check whether the anon user has read permissions.
$rights = $acl->get_rights($anon_user,'calendar');
@ -222,7 +222,7 @@ class module_calendar_month extends Module
{
$html = "";
$GLOBALS['egw']->translation->add_app('calendar');
$this->ui =& new calendar_uiviews();
$this->ui = new calendar_uiviews();
$this->ui->allowEdit = false;
$this->ui->use_time_grid = isset($arguments['grid']) ? $arguments['grid'] : false;

File diff suppressed because it is too large Load Diff

View File

@ -106,7 +106,7 @@
$this->accountid = $GLOBALS['egw_info']['user']['account_id'];
$this->bopreferences = CreateObject('felamimail.bopreferences',$_restoreSession);
//$this->sofelamimail =& new sofelamimail;
//$this->sofelamimail = new sofelamimail;
$this->mailPreferences = $this->bopreferences->getPreferences();
if ($this->mailPreferences) {

View File

@ -1282,7 +1282,7 @@
$Protocol = '(http:\/\/|(ftp:\/\/|https:\/\/))'; // only http:// gets removed, other protocolls are shown
$newBody = preg_replace('~'.$Protocol.'[^>]*\?'.$Protocol.'~sim','$1',$newBody); // removes stuff between http:// and ?http://
// spamsaver emailaddress, needed to be able to apply email compose links later
$newBody = preg_replace('/'.'(?<!"|href=|href\s=\s|href=\s|href\s=)'.'mailto:([a-z0-9._-]+)@([a-z0-9_-]+)\.([a-z0-9._-]+)/i',
$newBody = preg_replace('/(?<!"|href=|href\s=\s|href=\s|href\s=)'.'mailto:([a-z0-9._-]+)@([a-z0-9_-]+)\.([a-z0-9._-]+)/i',
'<a href="#" onclick="document.location=\'mai\'+\'lto:\\1\'+unescape(\'%40\')+\'\\2.\\3\'; return false;">\\1 AT \\2 DOT \\3</a>',
$newBody);

566
infolog/csv_import.php Normal file
View File

@ -0,0 +1,566 @@
<?php
/**
* InfoLog - CSV import
*
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @package infolog
* @copyright (c) 2003-9 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
$GLOBALS['egw_info'] = array(
'flags' => array(
'currentapp' => 'infolog',
'noheader' => True,
'enable_contacts_class' => True,
),
);
include('../header.inc.php');
if (!isset($GLOBALS['egw_info']['user']['apps']['admin']) ||
!$GLOBALS['egw_info']['user']['apps']['admin']) // no admin
{
$GLOBALS['egw']->redirect_link('/home.php');
}
if (isset($_FILES['csvfile']['tmp_name']))
{
$csvfile = tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
$GLOBALS['egw']->session->appsession('csvfile','',$csvfile);
$_POST['action'] = move_uploaded_file($_FILES['csvfile']['tmp_name'],$csvfile) ?
'download' : '';
}
else
{
$csvfile = $GLOBALS['egw']->session->appsession('csvfile');
}
if ($_POST['cancel'])
{
@unlink($csvfile);
$GLOBALS['egw']->redirect_link('/infolog/index.php');
}
if (isset($_POST['charset']))
{
// we have to set the local, to fix eg. utf-8 imports, as fgetcsv requires it!
common::setlocale(LC_CTYPE,$_POST['charset']);
}
$GLOBALS['egw_info']['flags']['app_header'] = lang('InfoLog - Import CSV-File');
$GLOBALS['egw']->common->egw_header();
$infolog_bo = createobject('infolog.infolog_bo');
$GLOBALS['egw']->template->set_file(array('import_t' => 'csv_import.tpl'));
$GLOBALS['egw']->template->set_block('import_t','filename','filenamehandle');
$GLOBALS['egw']->template->set_block('import_t','fheader','fheaderhandle');
$GLOBALS['egw']->template->set_block('import_t','fields','fieldshandle');
$GLOBALS['egw']->template->set_block('import_t','ffooter','ffooterhandle');
$GLOBALS['egw']->template->set_block('import_t','imported','importedhandle');
$GLOBALS['egw']->template->set_block('import_t','import','importhandle');
if(($_POST['action'] == 'download' || $_POST['action'] == 'continue') && (!$_POST['fieldsep'] || !$csvfile || !($fp=fopen($csvfile,'rb'))))
{
$_POST['action'] = '';
}
$GLOBALS['egw']->template->set_var("action_url",$GLOBALS['egw']->link("/infolog/csv_import.php"));
$PSep = '||'; // Pattern-Separator, separats the pattern-replacement-pairs in trans
$ASep = '|>'; // Assignment-Separator, separats pattern and replacesment
$VPre = '|#'; // Value-Prefix, is expanded to \ for ereg_replace
$CPre = '|['; $CPreReg = '\|\['; // |{csv-fieldname} is expanded to the value of the csv-field
$CPos = ']'; $CPosReg = '\]'; // if used together with @ (replacement is eval-ed) value gets autom. quoted
function addr_id( $n_family,$n_given=null,$org_name=null )
{ // find in Addressbook, at least n_family AND (n_given OR org_name) have to match
static $contacts;
if (!is_object($contacts))
{
$contacts =& CreateObject('phpgwapi.contacts');
}
if (!is_null($org_name)) // org_name given?
{
$addrs = $contacts->read( 0,0,array('id'),'',"n_family=$n_family,n_given=$n_given,org_name=$org_name" );
if (!count($addrs))
{
$addrs = $contacts->read( 0,0,array('id'),'',"n_family=$n_family,org_name=$org_name",'','n_family,org_name');
}
}
if (!is_null($n_given) && (is_null($org_name) || !count($addrs))) // first name given and no result so far
{
$addrs = $contacts->read( 0,0,array('id'),'',"n_family=$n_family,n_given=$n_given",'','n_family,n_given' );
}
if (is_null($n_given) && is_null($org_name)) // just one name given, check against fn (= full name)
{
$addrs = $contacts->read( 0,0,array('id'),'',"n_fn=$n_family",'','n_fn' );
}
if (count($addrs))
{
return $addrs[0]['id'];
}
return False;
}
function project_id($num_or_title)
{
static $boprojects;
if (!$num_or_title) return false;
if (!is_object($boprojects))
{
$boprojects =& CreateObject('projectmanager.boprojectmanager');
}
if (($projects = $boprojects->search(array('pm_number' => $num_or_title))) ||
($projects = $boprojects->search(array('pm_title' => $num_or_title))))
{
return $projects[0]['pm_id'];
}
return false;
}
$cat2id = array( );
function cat_id($cats)
{
if (!$cats)
{
return '';
}
// no multiple cat's in InfoLog atm.
foreach(array($cats) /*split('[,;]',$cats)*/ as $cat)
{
if (isset($cat2id[$cat]))
{
$ids[$cat] = $cat2id[$cat]; // cat is in cache
}
else
{
if (!is_object($GLOBALS['egw']->categories))
{
$GLOBALS['egw']->categories = createobject('phpgwapi.categories');
}
if (is_numeric($cat) && $GLOBALS['egw']->categories->id2name($cat) != '--')
{
$cat2id[$cat] = $ids[$cat] = $cat;
}
elseif (($id = $GLOBALS['egw']->categories->name2id( addslashes($cat) )))
{ // cat exists
$cat2id[$cat] = $ids[$cat] = $id;
}
else
{ // create new cat
$GLOBALS['egw']->categories->add( array('name' => $cat,'descr' => $cat ));
$cat2id[$cat] = $ids[$cat] = $GLOBALS['egw']->categories->name2id( addslashes($cat) );
}
}
}
$id_str = implode( ',',$ids );
if (count($ids) > 1) // multiple cats need to be in ','
{
$id_str = ",$id_str,";
}
return $id_str;
}
if ($_POST['next']) $_POST['action'] = 'next';
switch ($_POST['action'])
{
case '': // Start, ask Filename
$GLOBALS['egw']->template->set_var('lang_csvfile',lang('CSV-Filename'));
$GLOBALS['egw']->template->set_var('lang_fieldsep',lang('Fieldseparator'));
$GLOBALS['egw']->template->set_var('lang_charset',lang('Charset of file'));
$GLOBALS['egw']->template->set_var('select_charset',
html::select('charset','',translation::get_installed_charsets(),True));
$GLOBALS['egw']->template->set_var('fieldsep',$_POST['fieldsep'] ? $_POST['fieldsep'] : ';');
$GLOBALS['egw']->template->set_var('submit',lang('Import'));
$GLOBALS['egw']->template->set_var('enctype','ENCTYPE="multipart/form-data"');
$GLOBALS['egw']->template->parse('rows','filename');
break;
case 'continue':
case 'download':
$GLOBALS['egw']->preferences->read_repository();
$defaults = $GLOBALS['egw_info']['user']['preferences']['infolog']['cvs_import'];
if (!is_array($defaults))
{
$defaults = array();
}
$GLOBALS['egw']->template->set_var('lang_csv_fieldname',lang('CSV-Fieldname'));
$GLOBALS['egw']->template->set_var('lang_info_fieldname',lang('InfoLog-Fieldname'));
$GLOBALS['egw']->template->set_var('lang_translation',lang("Translation").' <a href="#help">'.lang('help').'</a>');
$GLOBALS['egw']->template->set_var('submit',
html::submit_button('convert','Import') . '&nbsp;'.
html::submit_button('cancel','Cancel'));
$GLOBALS['egw']->template->set_var('lang_debug',lang('Test Import (show importable records <u>only</u> in browser)'));
$GLOBALS['egw']->template->parse('rows','fheader');
$info_names = array(
'type' => 'Type: char(10) task,phone,note',
'from' => 'From: text(255) free text if no Addressbook-entry assigned',
'addr' => 'Addr: text(255) phone-nr/email-address',
'subject' => 'Subject: text(255)',
'des' => 'Description: text long free text',
'location' => 'Location: text(255)',
'responsible' => 'Responsible: int(11) user-id or user-name',
'owner' => 'Owner: int(11) user-id/-name of owner, if empty current user',
'access' => 'Access: public,private',
'cat' => 'Category: int(11) category-id or -name (new ones got created)',
'startdate' => 'Start Date: DateTime: Timestamp or eg. YYYY-MM-DD hh:mm',
'enddate' => 'End Date: DateTime',
'datecompleted'=> 'Date completed: DateTime',
'datemodified'=> 'Date Last Modified: DateTime, if empty = Date Created',
'modifier' => 'Modifier: int(11) user-id, if empty current user',
'priority' => 'Priority: 3=urgent, 2=high, 1=normal, 0=low',
'planned_time'=> 'planned Time: int(11) time used in min',
'used_time' => 'used Time: int(11) time used in min',
'status' => 'Status: char(10) offer,not-started,ongoing,call,will-call,done,billed,cancelled',
'percent' => 'Percent completed: int',
// 'confirm' => 'Confirmation: char(10) not,accept,finish,both when to confirm',
'project_id' => 'Link to Projectmanager, use Project-ID, Title or @project_id(id_or_title)',
'addr_id' => 'Link to Addressbook, use nlast,nfirst[,org] or contact_id from addressbook',
'link_1' => '1. link: appname:appid the entry should be linked to, eg.: addressbook:123',
'link_2' => '2. link: appname:appid the entry should be linked to, eg.: addressbook:123',
'link_3' => '3. link: appname:appid the entry should be linked to, eg.: addressbook:123',
);
// add custom fields
if ($infolog_bo->customfields)
{
foreach($infolog_bo->customfields as $name => $field)
{
if ($field['type'] == 'label' || !count($field['values']) && $field['rows'] <= 1 && $field['len'] <= 0) continue;
$info_names['#'.$name] = lang('custom fields').': '.$field['label'];
}
}
// the next line is used in the help-text too
$mktime_lotus = "${PSep}0?([0-9]+)[ .:-]+0?([0-9]*)[ .:-]+0?([0-9]*)[ .:-]+0?([0-9]*)[ .:-]+0?([0-9]*)[ .:-]+0?([0-9]*).*$ASep@mktime(${VPre}4,${VPre}5,${VPre}6,${VPre}2,${VPre}3,${VPre}1)";
/* this are settings to import from Lotus Organizer
$defaults += array( 'Land' => "addr$PSep.*[(]+([0-9]+)[)]+$ASep+${VPre}1 (${CPre}Ortsvorwahl$CPos) ${CPre}Telefon$CPos$PSep${CPre}Telefon$CPos",
'Notiz' => 'des',
'Privat' => "access${PSep}1${ASep}private${PSep}public",
'Startdatum' => 'startdate'.$mktime_lotus,
'Enddatum' => 'enddate'.$mktime_lotus,
'Erledigt' => "status${PSep}1${ASep}done${PSep}call",
'Nachname' => "addr_id${PSep}@addr_id(${CPre}Nachname$CPos,${CPre}Vorname$CPos,${CPre}Firma$CPos)",
'Firma' => "from${PSep}.+$ASep${CPre}Firma$CPos: ${CPre}Nachname$CPos, ${CPre}Vorname$CPos".
"${PSep}${CPre}Nachname$CPos, ${CPre}Vorname$CPos",
'no CSV 1' => "type${PSep}phone",
'no CSV 2' => "subject${PSep}@substr(${CPre}Notiz$CPos,0,60).' ...'" );
*/
$info_name_options = "<option value=\"\">none\n";
foreach($info_names as $field => $name)
{
$info_name_options .= "<option value=\"$field\">".$GLOBALS['egw']->strip_html($name)."\n";
}
$csv_fields = fgetcsv($fp,8000,$_POST['fieldsep']);
$csv_fields = translation::convert($csv_fields,$_POST['charset']);
$csv_fields[] = 'no CSV 1'; // eg. for static assignments
$csv_fields[] = 'no CSV 2';
$csv_fields[] = 'no CSV 3';
foreach($csv_fields as $csv_idx => $csv_field)
{
$GLOBALS['egw']->template->set_var('csv_field',$csv_field);
$GLOBALS['egw']->template->set_var('csv_idx',$csv_idx);
if (($def = $defaults[$csv_field]))
{
list( $info,$trans ) = explode($PSep,$def,2);
$GLOBALS['egw']->template->set_var('trans',$trans);
$GLOBALS['egw']->template->set_var('info_fields',str_replace('="'.$info.'">','="'.$info.'" selected>',$info_name_options));
}
else
{
$GLOBALS['egw']->template->set_var('trans','');
$GLOBALS['egw']->template->set_var('info_fields',$info_name_options);
}
$GLOBALS['egw']->template->parse('rows','fields',True);
}
$GLOBALS['egw']->template->set_var('lang_start',lang('Startrecord'));
$GLOBALS['egw']->template->set_var('start',get_var('start',array('POST'),1));
$msg = ($safe_mode = ini_get('safe_mode') == 'On') ? lang('to many might exceed your execution-time-limit'):
lang('empty for all');
$GLOBALS['egw']->template->set_var('lang_max',lang('Number of records to read (%1)',$msg));
$GLOBALS['egw']->template->set_var('max',get_var('max',array('POST'),$safe_mode ? 200 : ''));
$GLOBALS['egw']->template->set_var('debug',get_var('debug',array('POST'),True)?' checked':'');
$GLOBALS['egw']->template->parse('rows','ffooter',True);
fclose($fp);
$hiddenvars = html::input_hidden(array(
'action' => 'import',
'fieldsep'=> $_POST['fieldsep'],
'charset' => $_POST['charset']
));
$help_on_trans = "<a name=\"help\"></a><b>How to use Translation's</b><p>".
"Translations enable you to change / adapt the content of each CSV field for your needs. <br>".
"General syntax is: <b>pattern1 ${ASep} replacement1 ${PSep} ... ${PSep} patternN ${ASep} replacementN</b><br>".
"If the pattern-part of a pair is ommited it will match everything ('^.*$'), which is only ".
"usefull for the last pair, as they are worked from left to right.<p>".
"First example: <b>1${ASep}private${PSep}public</b><br>".
"This will translate a '1' in the CVS field to 'privat' and everything else to 'public'.<p>".
"Patterns as well as the replacement can be regular expressions (the replacement is done via ereg_replace). ".
"If, after all replacements, the value starts with an '@' the whole value is eval()'ed, so you ".
"may use all php, phpgw plus your own functions. This is quiet powerfull, but <u>circumvents all ACL</u>.<p>".
"Example using regular expressions and '@'-eval(): <br><b>$mktime_lotus</b><br>".
"It will read a date of the form '2001-05-20 08:00:00.00000000000000000' (and many more, see the regular expr.). ".
"The&nbsp;[&nbsp;.:-]-separated fields are read and assigned in different order to @mktime(). Please note to use ".
"${VPre} insted of a backslash (I couldn't get backslash through all the involved templates and forms.) ".
"plus the field-number of the pattern.<p>".
"In addintion to the fields assign by the pattern of the reg.exp. you can use all other CSV-fields, with the ".
"syntax <b>${CPre}CVS-FIELDNAME$CPos</b>. Here is an example: <br>".
"<b>.+$ASep${CPre}Company$CPos: ${CPre}NFamily$CPos, ${CPre}NGiven$CPos$PSep${CPre}NFamily$CPos, ${CPre}NGiven$CPos</b><br>".
"It is used on the CVS-field 'Company' and constructs a something like <i>Company: FamilyName, GivenName</i> or ".
"<i>FamilyName, GivenName</i> if 'Company' is empty.<p>".
"You can use the 'No CVS #'-fields to assign cvs-values to more than on field, the following example uses the ".
"cvs-field 'Note' (which gots already assingned to the description) and construct a short subject: ".
"<b>@substr(${CPre}Note$CPos,0,60).' ...'</b><p>".
"Their is two important user-function for the InfoLog:<br>".
"<b>@addr_id(${CPre}NFamily$CPos,${CPre}NGiven$CPos,${CPre}Company$CPos)</b> ".
"searches the addressbook for an address and returns the id if it founds an exact match of at least ".
"<i>NFamily</i> AND (<i>NGiven</i> OR <i>Company</i>). This is necessary to link your imported InfoLog-entrys ".
"with the addressbook.<br>".
"<b>@cat_id(Cat-name)</b> returns a numerical cat_id. If a category isn't found, it ".
"will be automaticaly added.<p>".
"I hope that helped to understand the features, if not <a href='mailto:egroupware-users@lists.sf.net'>ask</a>.";
$GLOBALS['egw']->template->set_var('help_on_trans',lang($help_on_trans)); // I don't think anyone will translate this
break;
case 'next':
$_POST['info_fields'] = unserialize(stripslashes($_POST['info_fields']));
$_POST['trans'] = unserialize(stripslashes($_POST['trans']));
// fall-through
case 'import':
$hiddenvars = html::input_hidden(array(
'action' => 'continue',
'fieldsep'=> $_POST['fieldsep'],
'charset' => $_POST['charset'],
'start' => $_POST['start']+(!$_POST['debug'] ? $_POST['max'] : 0),
'max' => $_POST['max'],
'debug' => $_POST['debug'],
'info_fields' => $_POST['info_fields'],
'trans' => $_POST['trans']
));
@set_time_limit(0);
$fp=fopen($csvfile,'r');
$csv_fields = fgetcsv($fp,8000,$_POST['fieldsep']);
$csv_fields = translation::convert($csv_fields,$_POST['charset']);
$csv_fields[] = 'no CSV 1'; // eg. for static assignments
$csv_fields[] = 'no CSV 2';
$csv_fields[] = 'no CSV 3';
$info_fields = array_diff($_POST['info_fields'],array( '' )); // throw away empty / not assigned entrys
$defaults = array();
foreach($info_fields as $csv_idx => $info)
{ // convert $trans[$csv_idx] into array of pattern => value
$defaults[$csv_fields[$csv_idx]] = $info;
if ($_POST['trans'][$csv_idx])
{
$defaults[$csv_fields[$csv_idx]] .= $PSep.addslashes($_POST['trans'][$csv_idx]);
}
}
$GLOBALS['egw']->preferences->read_repository();
$GLOBALS['egw']->preferences->add('infolog','cvs_import',$defaults);
$GLOBALS['egw']->preferences->save_repository(True);
$log = '<table border="1" style="border: 1px dotted black; border-collapse: collapse;">'."\n\t<tr><td>#</td>\n";
foreach($info_fields as $csv_idx => $info)
{ // convert $trans[$csv_idx] into array of pattern => value
// if (!$debug) echo "<p>$csv_idx: ".$csv_fields[$csv_idx].": $info".($trans[$csv_idx] ? ': '.$trans[$csv_idx] : '')."</p>";
$pat_reps = explode($PSep,stripslashes($_POST['trans'][$csv_idx]));
$replaces = ''; $values = '';
if ($pat_reps[0] != '')
{
foreach($pat_reps as $k => $pat_rep)
{
list($pattern,$replace) = explode($ASep,$pat_rep,2);
if ($replace == '')
{
$replace = $pattern; $pattern = '^.*$';
}
$values[$pattern] = $replace; // replace two with only one, added by the form
$replaces .= ($replaces != '' ? $PSep : '') . $pattern . $ASep . $replace;
}
$trans[$csv_idx] = $values;
} /*else
unset( $trans[$csv_idx] );*/
$log .= "\t\t<td><b>$info</b></td>\n";
}
if (!in_array('access',$info_fields)) // autocreate public access if not set by user
{
$log .= "\t\t<td><b>access</b></td>\n";
}
$start = $_POST['start'] < 1 ? 1 : $_POST['start'];
// ignore empty lines, is_null($fields[0]) is returned on empty lines !!!
for($i = 1; $i < $start; ++$i) // overread lines before our start-record
{
while(($fields = fgetcsv($fp,8000,$_POST['fieldsep'])) && is_null($fields[0])) ;
}
for($anz = 0; !$_POST['max'] || $anz < $_POST['max']; ++$anz)
{
while(($fields = fgetcsv($fp,8000,$_POST['fieldsep'])) && is_null($fields[0])) ;
if (!$fields)
{
break; // EOF
}
$fields = translation::convert($fields,$_POST['charset']);
$log .= "\t</tr><tr><td>".($start+$anz)."</td>\n";
$values = $orig = array();
foreach($info_fields as $csv_idx => $info)
{
//echo "<p>$csv: $info".($trans[$csv] ? ': '.$trans[$csv] : '')."</p>";
$val = $fields[$csv_idx];
if (isset($trans[$csv_idx]))
{
$trans_csv = $trans[$csv_idx];
while (list($pattern,$replace) = each($trans_csv))
{
if (ereg((string) $pattern,$val))
{
// echo "<p>csv_idx='$csv_idx',info='$info',trans_csv=".print_r($trans_csv).",preg_replace('/$pattern/','$replace','$val') = ";
$val = preg_replace('/'.(string) $pattern.'/',str_replace($VPre,'\\',$replace),(string) $val);
// echo "'$val'</p>";
$reg = $CPreReg.'([a-zA-Z_0-9]+)'.$CPosReg;
while (ereg($reg,$val,$vars))
{ // expand all CSV fields
$val = str_replace($CPre.$vars[1].$CPos,$val[0] == '@' ? "'".addslashes($fields[array_search($vars[1],$csv_fields)])."'" : $fields[array_search($vars[1],$csv_fields)],$val);
}
if ($val[0] == '@')
{
// removing the $ to close security hole of showing vars, which contain eg. passwords
$val = 'return '.substr(str_replace('$','',$val),1).';';
// echo "<p>eval('$val')=";
$val = eval($val);
// echo "'$val'</p>";
}
if ($pattern[0] != '@' || $val)
break;
}
}
}
$values[$info] = $orig[$info] = $val;
}
$empty = !count($values);
// convert the category name to an id
if ($values['cat'] && !is_numeric($values['cat']))
{
$values['cat'] = cat_id($values['cat']);
}
// convert dates to timestamps
foreach(array('startdate','enddate','datemodified','datecompleted') as $date)
{
if (isset($values[$date]) && !is_numeric($date))
{
if (preg_match('/(.*)\.[0-9]+/',$values[$date],$parts)) $values[$date] = $parts[1];
$values[$date] = strtotime($values[$date]);
}
}
if (!isset($values['datemodified'])) $values['datemodified'] = $values['startdate'];
// convert user-names to user-id's
foreach(array('owner','modifier') as $user)
{
if (isset($values[$user]) && !is_numeric($values[$user]))
{
if (preg_match('/\[([^\]]+)\]/',$values[$user],$matches)) $values[$user] = $matches[1];
$values[$user] = $GLOBALS['egw']->accounts->name2id($values[$user],'account_lid',$user=='owner'?null:'u');
}
}
if (isset($values['responsible']))
{
$responsible = $values['responsible'];
$values['responsible'] = array();
foreach(preg_split('/[,;]/',$responsible) as $user)
{
if (preg_match('/\[([^\]]+)\]/',$user,$matches)) $user = $matches[1];
if ($user && !is_numeric($user)) $user = $GLOBALS['egw']->accounts->name2id($user);
if ($user) $values['responsible'][] = $user;
}
}
if (!in_array('access',$info_fields))
{
$values['access'] = 'public'; // public access if not set by user
$log .= "\t\t<td>".$values['access']."</td>\n";
}
if(!$_POST['debug'] && !$empty) // dont import empty contacts
{
// create new names with info_ prefix
$to_write = array();
foreach($values as $name => $value)
{
$to_write[substr($name,0,5) != 'info_' && $name{0} != '#' ? 'info_'.$name : $name] = $value;
}
if ($values['addr_id'] && !is_numeric($values['addr_id']))
{
list($lastname,$firstname,$org_name) = explode(',',$values['addr_id']);
$values['addr_id'] = addr_id($lastname,$firstname,$org_name);
}
if ($values['project_id'] && !is_numeric($values['project_id']))
{
$values['project_id'] = project_id($values['project_id']);
}
if (($id = $infolog_bo->write($to_write,True,False)))
{
$info_link_id = false;
foreach(array(
'projectmanager:'.$values['project_id'],
'addressbook:'.$values['addr_id'],
$values['link_1'],$values['link_2'],$values['link_3'],
) as $value)
{
list($app,$app_id) = explode(':',$value);
if ($app && $app_id)
{
//echo "<p>linking infolog:$id with $app:$app_id</p>\n";
$link_id = egw_link::link('infolog',$id,$app,$app_id);
if ($link_id && !$info_link_id)
{
$to_write = array(
'info_id' => $id,
'info_link_id' => $link_id,
);
$infolog_bo->write($to_write);
$info_link_id = true;
}
}
}
}
}
// display read and interpreted results, so the user can check it
foreach($info_fields as $name)
{
$log .= "\t\t<td>".($orig[$name] != $values[$name] ? htmlspecialchars($orig[$name]).' --> ' : '').
htmlspecialchars($values[$name])."</td>\n";
}
}
$log .= "\t</tr>\n</table>\n";
$GLOBALS['egw']->template->set_var('anz_imported',($_POST['debug'] ?
lang('%1 records read (not yet imported, you may go %2back%3 and uncheck Test Import)',
$anz,'','') :
lang('%1 records imported',$anz)). '&nbsp;'.
(!$_POST['debug'] && $fields ? html::submit_button('next','Import next set') . '&nbsp;':'').
html::submit_button('continue','Back') . '&nbsp;'.
html::submit_button('cancel','Cancel'));
$GLOBALS['egw']->template->set_var('log',$log);
$GLOBALS['egw']->template->parse('rows','imported');
break;
}
$GLOBALS['egw']->template->set_var('hiddenvars',str_replace('{','&#x7B;',$hiddenvars));
$GLOBALS['egw']->template->pfp('phpgw_body','import');
$GLOBALS['egw']->common->egw_footer();

View File

@ -0,0 +1,305 @@
<?php
/**************************************************************************\
* eGroupWare API - Validator *
* This file written by Dave Hall <skwashd@phpgroupware.org> *
* Copyright (C) 2003 Free Software Foundation *
* ------------------------------------------------------------------------ *
* This library is part of the eGroupWare API *
* http://www.egroupware.org/api *
* ------------------------------------------------------------------------ *
* 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$ */
//NOTE This class still needs to be documented and the stubbed methods fixed!
class validator
{
var $error;
function clear_error()
{
$this->nonfree_call();
}
/* check if string contains any whitespace */
function has_space($text)
{
return ereg("( |\n|\t|\r)+", $text);
}
function chconvert($fragment)
{
$this->nonfree_call();
}
function get_perms($fileName)
{
$this->nonfree_call();
}
function is_sane($filename)
{
$this->nonfree_call();
}
/* strips all whitespace from a string */
function strip_space($text)
{
return preg_replace('/'."( |\n|\t|\r)+".'/', '', $text);
}
function is_allnumbers($text)
{
$this->nonfree_call();
}
function strip_numbers($text)
{
$this->nonfree_call();
}
function is_allletters($text)
{
$this->nonfree_call();
}
function strip_letters($text)
{
$this->nonfree_call();
}
function has_html($text='')
{
return ($text != $this->strip_html($text));
}
function strip_html($text='')
{
return strip_tags($text);
}
function has_metas($text='')
{
return ($text != $this->strip_metas($text));
}
function strip_metas($text = "")
{
$metas = array('$','^','*','(',')','+','[',']','.','?');
return str_replace($metas, '', stripslashes($text));
}
function custom_strip($Chars, $text = "")
{
$this->nonfree_call();
}
function array_echo($array, $name='Array')
{
echo '<pre>';
print_r($array);
echo '<pre>';
}
function is_email($address='')
{
list($user, $domain) = explode('@', $address);
if(!($user && $domain))
{
return false;
}
if(!$this->has_space($user) && $this->is_host($domain))
{
return true;
}
}
function is_url($url='')
{
//echo "Checking $url<br>";
$uris = array(
'ftp' => True,
'https' => True,
'http' => True
);
$url_elements = parse_url($url);
//echo '<pre>';
//print_r($url_elements);
//echo '</pre>';
if(!is_array($url_elements))
{
return false;
}
//echo 'Scheme ' . $url_elements['scheme'];
if(@$uris[$url_elements['scheme']])
{
//echo ' is valid<br>host ' . $url_elements['host'];
if(preg_match('/'."[a-z]".'/i', $url_elements['host']))
{
//echo ' is name<br>';
return $this->is_hostname($url_elements['host']);
}
else
{
//echo ' is ip<br>';
return $this->is_ipaddress($url_elements['host']);
}
}
else
{
//echo ' is invalid<br>';
return $false;
}
}
//the url may be valid, but this method can't test all types
function url_responds($url='')
{
if(!$this->is_url($url))
{
return false;
}
$fp=@fopen($url);
if($fp)
{
fclose($fp);
return true;
}
else
{
return false;
}
}
function is_phone($Phone='')
{
$this->nonfree_call();
}
function is_hostname($hostname='')
{
//echo "Checking $hostname<br>";
$segs = explode('.', $hostname);
if(is_array($segs))
{
foreach($segs as $seg)
{
//echo "Checking $seg<br>";
if(preg_match('/'."[a-z0-9\-]{0,62}".'/i',$seg))
{
$return = True;
}
if(!$return)
{
return False;
}
}
return True;
}
return False;
}
function is_bigfour($tld)
{
$this->nonfree_call();
}
function is_host($hostname='', $type='ANY')
{
if($this->is_hostname($hostname))
{
return checkdnsrr($hostname, $type);
}
else
{
return false;
}
}
function is_ipaddress($ip='')
{
if(strlen($ip) <= 15)
{
$segs = explode('.', $ip);
if(count($segs) != 4)
{
return false;
}
foreach($segs as $seg)
{
if(($seg < 0) || ($seg >= 255))
{
return false;
}
}
return true;
}
else
{
return false;
}
}
function ip_resolves($ip='')
{
if($this->is_ipaddress($ip))
{
return !strcmp($hostname, gethostbyaddr($ip));
}
else
{
return false;
}
}
function browser_gen()
{
$this->nonfree_call();
}
function is_state($State = "")
{
$this->nonfree_call();
}
function is_zip($zipcode = "")
{
$this->nonfree_call();
}
function is_country($countrycode='')
{
$this->nonfree_call();
}
function nonfree_call()
{
echo 'class.validator.inc.php used to contain code that was not Free ';
echo 'Software (<a href="(http://www.gnu.org/philosophy/free-sw.html">see ';
echo 'definition</a> , therefore it has been removed. <br><br>';
echo 'If you are a application maintainer, please update your app. ';
echo 'If you are a user, please file a bug report on ';
echo '<a href="http://sourceforge.net/projects/egroupwaregroup">';
echo 'our project page at sourceforge.net</a>. Please copy and paste ';
echo 'the following information into the bug report:<br>';
echo '<b>Summary<b>: ' . $GLOBALS['egw_info']['flags']['currentapp'];
echo 'calls class.validator.inc.php';
echo 'Information:<br> The call was found when calling: ' . $_SERVER['QUERY_STRING'];
echo '<br><br>This application will now halt!<br><br>';
echo '<a href="'. $GLOBALS['egw']->link('/home.php') .'">Return to Home Screen</a>';
exit;
}
}
?>

View File

@ -0,0 +1,400 @@
<?php
/*******************************************************************************
* Utility to generate font definition files *
* Version: 1.12 *
* Date: 2003-12-30 *
*******************************************************************************/
function ReadMap($enc)
{
//Read a map file
$file=dirname(__FILE__).'/'.strtolower($enc).'.map';
$a=file($file);
if(empty($a))
die('<B>Error:</B> encoding not found: '.$enc);
$cc2gn=array();
foreach($a as $l)
{
if($l{0}=='!')
{
$e=preg_split('/[ \\t]+/',chop($l));
$cc=hexdec(substr($e[0],1));
$gn=$e[2];
$cc2gn[$cc]=$gn;
}
}
for($i=0;$i<=255;$i++)
if(!isset($cc2gn[$i]))
$cc2gn[$i]='.notdef';
return $cc2gn;
}
function ReadAFM($file,&$map)
{
//Read a font metric file
$a=file($file);
if(empty($a))
die('File not found');
$widths=array();
$fm=array();
$fix=array('Edot'=>'Edotaccent','edot'=>'edotaccent','Idot'=>'Idotaccent','Zdot'=>'Zdotaccent','zdot'=>'zdotaccent',
'Odblacute'=>'Ohungarumlaut','odblacute'=>'ohungarumlaut','Udblacute'=>'Uhungarumlaut','udblacute'=>'uhungarumlaut',
'Gcedilla'=>'Gcommaaccent','gcedilla'=>'gcommaaccent','Kcedilla'=>'Kcommaaccent','kcedilla'=>'kcommaaccent',
'Lcedilla'=>'Lcommaaccent','lcedilla'=>'lcommaaccent','Ncedilla'=>'Ncommaaccent','ncedilla'=>'ncommaaccent',
'Rcedilla'=>'Rcommaaccent','rcedilla'=>'rcommaaccent','Scedilla'=>'Scommaaccent','scedilla'=>'scommaaccent',
'Tcedilla'=>'Tcommaaccent','tcedilla'=>'tcommaaccent','Dslash'=>'Dcroat','dslash'=>'dcroat','Dmacron'=>'Dcroat','dmacron'=>'dcroat',
'combininggraveaccent'=>'gravecomb','combininghookabove'=>'hookabovecomb','combiningtildeaccent'=>'tildecomb',
'combiningacuteaccent'=>'acutecomb','combiningdotbelow'=>'dotbelowcomb','dongsign'=>'dong');
foreach($a as $l)
{
$e=explode(' ',chop($l));
if(count($e)<2)
continue;
$code=$e[0];
$param=$e[1];
if($code=='C')
{
//Character metrics
$cc=(int)$e[1];
$w=$e[4];
$gn=$e[7];
if(substr($gn,-4)=='20AC')
$gn='Euro';
if(isset($fix[$gn]))
{
//Fix incorrect glyph name
foreach($map as $c=>$n)
if($n==$fix[$gn])
$map[$c]=$gn;
}
if(empty($map))
{
//Symbolic font: use built-in encoding
$widths[$cc]=$w;
}
else
{
$widths[$gn]=$w;
if($gn=='X')
$fm['CapXHeight']=$e[13];
}
if($gn=='.notdef')
$fm['MissingWidth']=$w;
}
elseif($code=='FontName')
$fm['FontName']=$param;
elseif($code=='Weight')
$fm['Weight']=$param;
elseif($code=='ItalicAngle')
$fm['ItalicAngle']=(double)$param;
elseif($code=='Ascender')
$fm['Ascender']=(int)$param;
elseif($code=='Descender')
$fm['Descender']=(int)$param;
elseif($code=='UnderlineThickness')
$fm['UnderlineThickness']=(int)$param;
elseif($code=='UnderlinePosition')
$fm['UnderlinePosition']=(int)$param;
elseif($code=='IsFixedPitch')
$fm['IsFixedPitch']=($param=='true');
elseif($code=='FontBBox')
$fm['FontBBox']=array($e[1],$e[2],$e[3],$e[4]);
elseif($code=='CapHeight')
$fm['CapHeight']=(int)$param;
elseif($code=='StdVW')
$fm['StdVW']=(int)$param;
}
if(!isset($fm['FontName']))
die('FontName not found');
if(!empty($map))
{
if(!isset($widths['.notdef']))
$widths['.notdef']=600;
if(!isset($widths['Delta']) and isset($widths['increment']))
$widths['Delta']=$widths['increment'];
//Order widths according to map
for($i=0;$i<=255;$i++)
{
if(!isset($widths[$map[$i]]))
{
echo '<B>Warning:</B> character '.$map[$i].' is missing<BR>';
$widths[$i]=$widths['.notdef'];
}
else
$widths[$i]=$widths[$map[$i]];
}
}
$fm['Widths']=$widths;
return $fm;
}
function MakeFontDescriptor($fm,$symbolic)
{
//Ascent
$asc=(isset($fm['Ascender']) ? $fm['Ascender'] : 1000);
$fd="array('Ascent'=>".$asc;
//Descent
$desc=(isset($fm['Descender']) ? $fm['Descender'] : -200);
$fd.=",'Descent'=>".$desc;
//CapHeight
if(isset($fm['CapHeight']))
$ch=$fm['CapHeight'];
elseif(isset($fm['CapXHeight']))
$ch=$fm['CapXHeight'];
else
$ch=$asc;
$fd.=",'CapHeight'=>".$ch;
//Flags
$flags=0;
if(isset($fm['IsFixedPitch']) and $fm['IsFixedPitch'])
$flags+=1<<0;
if($symbolic)
$flags+=1<<2;
if(!$symbolic)
$flags+=1<<5;
if(isset($fm['ItalicAngle']) and $fm['ItalicAngle']!=0)
$flags+=1<<6;
$fd.=",'Flags'=>".$flags;
//FontBBox
if(isset($fm['FontBBox']))
$fbb=$fm['FontBBox'];
else
$fbb=array(0,$des-100,1000,$asc+100);
$fd.=",'FontBBox'=>'[".$fbb[0].' '.$fbb[1].' '.$fbb[2].' '.$fbb[3]."]'";
//ItalicAngle
$ia=(isset($fm['ItalicAngle']) ? $fm['ItalicAngle'] : 0);
$fd.=",'ItalicAngle'=>".$ia;
//StemV
if(isset($fm['StdVW']))
$stemv=$fm['StdVW'];
elseif(isset($fm['Weight']) and preg_match('/(bold|black)/i',$fm['Weight']))
$stemv=120;
else
$stemv=70;
$fd.=",'StemV'=>".$stemv;
//MissingWidth
if(isset($fm['MissingWidth']))
$fd.=",'MissingWidth'=>".$fm['MissingWidth'];
$fd.=')';
return $fd;
}
function MakeWidthArray($fm)
{
//Make character width array
$s="array(\n\t";
$cw=$fm['Widths'];
for($i=0;$i<=255;$i++)
{
if(chr($i)=="'")
$s.="'\\''";
elseif(chr($i)=="\\")
$s.="'\\\\'";
elseif($i>=32 and $i<=126)
$s.="'".chr($i)."'";
else
$s.="chr($i)";
$s.='=>'.$fm['Widths'][$i];
if($i<255)
$s.=',';
if(($i+1)%22==0)
$s.="\n\t";
}
$s.=')';
return $s;
}
function MakeFontEncoding($map)
{
//Build differences from reference encoding
$ref=ReadMap('cp1252');
$s='';
$last=0;
for($i=32;$i<=255;$i++)
{
if($map[$i]!=$ref[$i])
{
if($i!=$last+1)
$s.=$i.' ';
$last=$i;
$s.='/'.$map[$i].' ';
}
}
return chop($s);
}
function SaveToFile($file,$s,$mode='t')
{
$f=fopen($file,'w'.$mode);
if(!$f)
die('Can\'t write to file '.$file);
fwrite($f,$s,strlen($s));
fclose($f);
}
function ReadShort($f)
{
$a=unpack('n1n',fread($f,2));
return $a['n'];
}
function ReadLong($f)
{
$a=unpack('N1N',fread($f,4));
return $a['N'];
}
function CheckTTF($file)
{
//Check if font license allows embedding
$f=fopen($file,'rb');
if(!$f)
die('<B>Error:</B> Can\'t open '.$file);
//Extract number of tables
fseek($f,4,SEEK_CUR);
$nb=ReadShort($f);
fseek($f,6,SEEK_CUR);
//Seek OS/2 table
$found=false;
for($i=0;$i<$nb;$i++)
{
if(fread($f,4)=='OS/2')
{
$found=true;
break;
}
fseek($f,12,SEEK_CUR);
}
if(!$found)
{
fclose($f);
return;
}
fseek($f,4,SEEK_CUR);
$offset=ReadLong($f);
fseek($f,$offset,SEEK_SET);
//Extract fsType flags
fseek($f,8,SEEK_CUR);
$fsType=ReadShort($f);
$rl=($fsType & 0x02)!=0;
$pp=($fsType & 0x04)!=0;
$e=($fsType & 0x08)!=0;
fclose($f);
if($rl and !$pp and !$e)
echo '<B>Warning:</B> font license does not allow embedding';
}
/*******************************************************************************
* $fontfile: path to TTF file (or empty string if not to be embedded) *
* $afmfile: path to AFM file *
* $enc: font encoding (or empty string for symbolic fonts) *
* $patch: optional patch for encoding *
* $type : font type if $fontfile is empty *
*******************************************************************************/
function MakeFont($fontfile,$afmfile,$enc='cp1252',$patch=array(),$type='TrueType')
{
//Generate a font definition file
set_magic_quotes_runtime(0);
if($enc)
{
$map=ReadMap($enc);
foreach($patch as $cc=>$gn)
$map[$cc]=$gn;
}
else
$map=array();
if(!file_exists($afmfile))
die('<B>Error:</B> AFM file not found: '.$afmfile);
$fm=ReadAFM($afmfile,$map);
if($enc)
$diff=MakeFontEncoding($map);
else
$diff='';
$fd=MakeFontDescriptor($fm,empty($map));
//Find font type
if($fontfile)
{
$ext=strtolower(substr($fontfile,-3));
if($ext=='ttf')
$type='TrueType';
elseif($ext=='pfb')
$type='Type1';
else
die('<B>Error:</B> unrecognized font file extension: '.$ext);
}
else
{
if($type!='TrueType' and $type!='Type1')
die('<B>Error:</B> incorrect font type: '.$type);
}
//Start generation
$s='<?php'."\n";
$s.='$type=\''.$type."';\n";
$s.='$name=\''.$fm['FontName']."';\n";
$s.='$desc='.$fd.";\n";
if(!isset($fm['UnderlinePosition']))
$fm['UnderlinePosition']=-100;
if(!isset($fm['UnderlineThickness']))
$fm['UnderlineThickness']=50;
$s.='$up='.$fm['UnderlinePosition'].";\n";
$s.='$ut='.$fm['UnderlineThickness'].";\n";
$w=MakeWidthArray($fm);
$s.='$cw='.$w.";\n";
$s.='$enc=\''.$enc."';\n";
$s.='$diff=\''.$diff."';\n";
$basename=substr(basename($afmfile),0,-4);
if($fontfile)
{
//Embedded font
if(!file_exists($fontfile))
die('<B>Error:</B> font file not found: '.$fontfile);
if($type=='TrueType')
CheckTTF($fontfile);
$f=fopen($fontfile,'rb');
if(!$f)
die('<B>Error:</B> Can\'t open '.$fontfile);
$file=fread($f,filesize($fontfile));
fclose($f);
if($type=='Type1')
{
//Find first two sections and discard third one
$pos=strpos($file,'eexec');
if(!$pos)
die('<B>Error:</B> font file does not seem to be valid Type1');
$size1=$pos+6;
$pos=strpos($file,'00000000');
if(!$pos)
die('<B>Error:</B> font file does not seem to be valid Type1');
$size2=$pos-$size1;
$file=substr($file,0,$size1+$size2);
}
if(function_exists('gzcompress'))
{
$cmp=$basename.'.z';
SaveToFile($cmp,gzcompress($file),'b');
$s.='$file=\''.$cmp."';\n";
echo 'Font file compressed ('.$cmp.')<BR>';
}
else
{
$s.='$file=\''.basename($fontfile)."';\n";
echo '<B>Notice:</B> font file could not be compressed (gzcompress not available)<BR>';
}
if($type=='Type1')
{
$s.='$size1='.$size1.";\n";
$s.='$size2='.$size2.";\n";
}
else
$s.='$originalsize='.filesize($fontfile).";\n";
}
else
{
//Not embedded font
$s.='$file='."'';\n";
}
$s.="?>\n";
SaveToFile($basename.'.php',$s);
echo 'Font definition file generated ('.$basename.'.php'.')<BR>';
}
?>

View File

@ -0,0 +1,960 @@
<?php
// by Edd Dumbill (C) 1999-2001
// <edd@usefulinc.com>
// xmlrpc.inc,v 1.18 2001/07/06 18:23:57 edmundd
// License is granted to use or modify this software ("XML-RPC for PHP")
// for commercial or non-commercial use provided the copyright of the author
// is preserved in any distributed or derivative work.
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/* $Id$ */
if (!function_exists('xml_parser_create'))
{
// Win 32 fix. From: "Leo West" <lwest@imaginet.fr>
if($WINDIR)
{
dl('php3_xml.dll');
}
else
{
dl('xml.so');
}
}
$GLOBALS['xmlrpc_valid_parents'] = array(
'BOOLEAN' => array('VALUE'),
'I4' => array('VALUE'),
'INT' => array('VALUE'),
'STRING' => array('VALUE'),
'DOUBLE' => array('VALUE'),
'DATETIME.ISO8601' => array('VALUE'),
'BASE64' => array('VALUE'),
'ARRAY' => array('VALUE'),
'STRUCT' => array('VALUE'),
'PARAM' => array('PARAMS'),
'METHODNAME' => array('METHODCALL'),
'PARAMS' => array('METHODCALL', 'METHODRESPONSE'),
'MEMBER' => array('STRUCT'),
'NAME' => array('MEMBER'),
'DATA' => array('ARRAY'),
'FAULT' => array('METHODRESPONSE'),
'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT'),
);
define('xmlrpcI4','i4');
define('xmlrpcInt','int');
define('xmlrpcBoolean','boolean');
define('xmlrpcDouble','double');
define('xmlrpcString','string');
define('xmlrpcDateTime','dateTime.iso8601');
define('xmlrpcBase64','base64');
define('xmlrpcArray','array');
define('xmlrpcStruct','struct');
$GLOBALS['xmlrpcTypes'] = array(
xmlrpcI4 => 1,
xmlrpcInt => 1,
xmlrpcBoolean => 1,
xmlrpcString => 1,
xmlrpcDouble => 1,
xmlrpcDateTime => 1,
xmlrpcBase64 => 1,
xmlrpcArray => 2,
xmlrpcStruct => 3
);
$GLOBALS['xmlEntities']=array(
'amp' => '&',
'quot' => '"',
'lt' => '<',
'gt' => '>',
'apos' => "'"
);
$GLOBALS['xmlrpcerr']['unknown_method']=1;
$GLOBALS['xmlrpcstr']['unknown_method']='Unknown method';
$GLOBALS['xmlrpcerr']['invalid_return']=2;
$GLOBALS['xmlrpcstr']['invalid_return']='Invalid return payload: enable debugging to examine incoming payload';
$GLOBALS['xmlrpcerr']['incorrect_params']=3;
$GLOBALS['xmlrpcstr']['incorrect_params']='Incorrect parameters passed to method';
$GLOBALS['xmlrpcerr']['introspect_unknown']=4;
$GLOBALS['xmlrpcstr']['introspect_unknown']="Can't introspect: method unknown";
$GLOBALS['xmlrpcerr']['http_error']=5;
$GLOBALS['xmlrpcstr']['http_error']="Didn't receive 200 OK from remote server.";
$GLOBALS['xmlrpcerr']['no_data']=6;
$GLOBALS['xmlrpcstr']['no_data']='No data received from server.';
$GLOBALS['xmlrpcerr']['no_ssl']=7;
$GLOBALS['xmlrpcstr']['no_ssl']='No SSL support compiled in.';
$GLOBALS['xmlrpcerr']['curl_fail']=8;
$GLOBALS['xmlrpcstr']['curl_fail']='CURL error';
$GLOBALS['xmlrpcerr']['multicall_notstruct'] = 9;
$GLOBALS['xmlrpcstr']['multicall_notstruct'] = 'system.multicall expected struct';
$GLOBALS['xmlrpcerr']['multicall_nomethod'] = 10;
$GLOBALS['xmlrpcstr']['multicall_nomethod'] = 'missing methodName';
$GLOBALS['xmlrpcerr']['multicall_notstring'] = 11;
$GLOBALS['xmlrpcstr']['multicall_notstring'] = 'methodName is not a string';
$GLOBALS['xmlrpcerr']['multicall_recursion'] = 12;
$GLOBALS['xmlrpcstr']['multicall_recursion'] = 'recursive system.multicall forbidden';
$GLOBALS['xmlrpcerr']['multicall_noparams'] = 13;
$GLOBALS['xmlrpcstr']['multicall_noparams'] = 'missing params';
$GLOBALS['xmlrpcerr']['multicall_notarray'] = 14;
$GLOBALS['xmlrpcstr']['multicall_notarray'] = 'params is not an array';
$GLOBALS['xmlrpcerr']['invalid_request']=15;
$GLOBALS['xmlrpcstr']['invalid_request']='Invalid request payload';
$GLOBALS['xmlrpcerr']['no_curl']=16;
$GLOBALS['xmlrpcstr']['no_curl']='No CURL support compiled in.';
$GLOBALS['xmlrpcerr']['server_error']=17;
$GLOBALS['xmlrpcstr']['server_error']='Internal server error';
$GLOBALS['xmlrpcerr']['no_access'] = 18;
$GLOBALS['xmlrpcstr']['no_access'] = 'Access denied';
$GLOBALS['xmlrpcerr']['not_existent'] = 19;
$GLOBALS['xmlrpcstr']['not_existent'] = 'Entry does not (longer) exist!';
$GLOBALS['xmlrpcerr']['cannot_decompress']=103;
$GLOBALS['xmlrpcstr']['cannot_decompress']='Received from server compressed HTTP and cannot decompress';
$GLOBALS['xmlrpcerr']['decompress_fail']=104;
$GLOBALS['xmlrpcstr']['decompress_fail']='Received from server invalid compressed HTTP';
$GLOBALS['xmlrpcerr']['dechunk_fail']=105;
$GLOBALS['xmlrpcstr']['dechunk_fail']='Received from server invalid chunked HTTP';
$GLOBALS['xmlrpcerr']['server_cannot_decompress']=106;
$GLOBALS['xmlrpcstr']['server_cannot_decompress']='Received from client compressed HTTP request and cannot decompress';
$GLOBALS['xmlrpcerr']['server_decompress_fail']=107;
$GLOBALS['xmlrpcstr']['server_decompress_fail']='Received from client invalid compressed HTTP request';
$GLOBALS['xmlrpc_defencoding'] = 'UTF-8';
$GLOBALS['xmlrpc_internalencoding']='ISO-8859-1';
$GLOBALS['xmlrpcName'] = 'XML-RPC for PHP';
$GLOBALS['xmlrpcVersion'] = '2.0';
// let user errors start at 800
$GLOBALS['xmlrpcerruser'] = 800;
// let XML parse errors start at 100
$GLOBALS['xmlrpcerrxml'] = 100;
// formulate backslashes for escaping regexp
$GLOBALS['xmlrpc_backslash'] = chr(92) . chr(92);
/*!
@function xmlrpcfault
@abstract Error reporting for XML-RPC
@discussion Author: jengo <br>
Returns XML-RPC fault and stops this execution of the application. <br>
Syntax: void xmlrpcfault(string) <br>
Example1: xmlrpcfault('Session could not be verifed'); <br>
@param $string Error message to be returned.
*/
function xmlrpcfault($string)
{
$r = CreateObject('phpgwapi.xmlrpcresp',
CreateObject('phpgwapi.xmlrpcval'),
$GLOBALS['xmlrpcerr']['unknown_method'],
$string
);
$payload = '<?xml version="1.0"?>' . "\n" . $r->serialize();
Header('Content-type: text/xml');
Header('Content-length: ' . bytes($payload));
print $payload;
$GLOBALS['egw']->common->phpgw_exit(False);
}
// used to store state during parsing
// quick explanation of components:
// ac - used to accumulate values
// isf - used to indicate a fault
// lv - used to indicate "looking for a value": implements
// the logic to allow values with no types to be strings
// params - used to store parameters in method calls
// method - used to store method name
// stack - array with genealogy of xml elements names:
// used to validate nesting of xmlrpc elements
$GLOBALS['_xh'] = null;
/**
* To help correct communication of non-ascii chars inside strings, regardless
* of the charset used when sending requests, parsing them, sending responses
* and parsing responses, convert all non-ascii chars present in the message
* into their equivalent 'charset entity'. Charset entities enumerated this way
* are independent of the charset encoding used to transmit them, and all XML
* parsers are bound to understand them.
*
* @author Eugene Pivnev
*/
function xmlrpc_encode_entities($data)
{
return htmlspecialchars($data,ENT_QUOTES,$GLOBALS['egw']->translation->system_charset ?
$GLOBALS['egw']->translation->system_charset : 'UTF-8');
}
if (!function_exists('htmlspecialchars_decode')) // php < 5.1
{
function htmlspecialchars_decode($text,$quote_style=ENT_COMPAT)
{
return strtr($text, array_flip(get_html_translation_table(HTML_SPECIALCHARS,$quote_style)));
}
}
function xmlrpc_entity_decode($string)
{
return htmlspecialchars_decode($data,ENT_QUOTES);
}
function xmlrpc_lookup_entity($ent)
{
if (isset($GLOBALS['xmlEntities'][strtolower($ent)]))
{
return $GLOBALS['xmlEntities'][strtolower($ent)];
}
if (preg_match('/'."^#([0-9]+)$".'/', $ent, $regs))
{
return chr($regs[1]);
}
return '?';
}
function xmlrpc_se($parser, $name, $attrs)
{
// if invalid xmlrpc already detected, skip all processing
if ($GLOBALS['_xh'][$parser]['isf'] < 2)
{
// check for correct element nesting
// top level element can only be of 2 types
if (count($GLOBALS['_xh'][$parser]['stack']) == 0)
{
if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')
{
$GLOBALS['_xh'][$parser]['isf'] = 2;
$GLOBALS['_xh'][$parser]['isf_reason'] = 'missing top level xmlrpc element';
return;
}
}
else
{
// not top level element: see if parent is OK
if (!in_array($GLOBALS['_xh'][$parser]['stack'][0], $GLOBALS['xmlrpc_valid_parents'][$name]))
{
$GLOBALS['_xh'][$parser]['isf'] = 2;
$GLOBALS['_xh'][$parser]['isf_reason'] = "xmlrpc element $name cannot be child of {$GLOBALS['_xh'][$parser]['stack'][0]}";
return;
}
}
switch($name)
{
case 'STRUCT':
case 'ARRAY':
// create an empty array to hold child values, and push it onto appropriate stack
$cur_val = array();
$cur_val['values'] = array();
$cur_val['type'] = $name;
@array_unshift($GLOBALS['_xh'][$parser]['valuestack'], $cur_val);
break;
case 'DATA':
case 'METHODCALL':
case 'METHODRESPONSE':
case 'PARAMS':
// valid elements that add little to processing
break;
case 'METHODNAME':
case 'NAME':
$GLOBALS['_xh'][$parser]['ac']='';
break;
case 'FAULT':
$GLOBALS['_xh'][$parser]['isf']=1;
break;
case 'VALUE':
$GLOBALS['_xh'][$parser]['vt']='value'; // indicator: no value found yet
$GLOBALS['_xh'][$parser]['ac']='';
$GLOBALS['_xh'][$parser]['lv']=1;
break;
case 'I4':
case 'INT':
case 'STRING':
case 'BOOLEAN':
case 'DOUBLE':
case 'DATETIME.ISO8601':
case 'BASE64':
if ($GLOBALS['_xh'][$parser]['vt']!='value')
{
//two data elements inside a value: an error occurred!
$GLOBALS['_xh'][$parser]['isf'] = 2;
$GLOBALS['_xh'][$parser]['isf_reason'] = "$name element following a {$GLOBALS['_xh'][$parser]['vt']} element inside a single value";
return;
}
$GLOBALS['_xh'][$parser]['ac']=''; // reset the accumulator
break;
case 'MEMBER':
$GLOBALS['_xh'][$parser]['valuestack'][0]['name']=''; // set member name to null, in case we do not find in the xml later on
//$GLOBALS['_xh'][$parser]['ac']='';
// Drop trough intentionally
case 'PARAM':
// clear value, so we can check later if no value will passed for this param/member
$GLOBALS['_xh'][$parser]['value']=null;
break;
default:
/// INVALID ELEMENT: RAISE ISF so that it is later recognized!!!
$GLOBALS['_xh'][$parser]['isf'] = 2;
$GLOBALS['_xh'][$parser]['isf_reason'] = "found not-xmlrpc xml element $name";
break;
}
// Save current element name to stack, to validate nesting
@array_unshift($GLOBALS['_xh'][$parser]['stack'], $name);
if($name!='VALUE')
{
$GLOBALS['_xh'][$parser]['lv']=0;
}
}
}
function xmlrpc_ee($parser, $name)
{
if ($GLOBALS['_xh'][$parser]['isf'] < 2)
{
// push this element name from stack
// NB: if XML validates, correct opening/closing is guaranteed and
// we do not have to check for $name == $curr_elem.
// we also checked for proper nesting at start of elements...
$curr_elem = array_shift($GLOBALS['_xh'][$parser]['stack']);
switch($name)
{
case 'STRUCT':
case 'ARRAY':
// fetch out of stack array of values, and promote it to current value
$curr_val = array_shift($GLOBALS['_xh'][$parser]['valuestack']);
$GLOBALS['_xh'][$parser]['value'] = $curr_val['values'];
$GLOBALS['_xh'][$parser]['vt']=strtolower($name);
break;
case 'NAME':
$GLOBALS['_xh'][$parser]['valuestack'][0]['name'] = $GLOBALS['_xh'][$parser]['ac'];
break;
case 'BOOLEAN':
case 'I4':
case 'INT':
case 'STRING':
case 'DOUBLE':
case 'DATETIME.ISO8601':
case 'BASE64':
$GLOBALS['_xh'][$parser]['vt']=strtolower($name);
if ($name=='STRING')
{
$GLOBALS['_xh'][$parser]['value']=$GLOBALS['_xh'][$parser]['ac'];
}
elseif ($name=='DATETIME.ISO8601')
{
$GLOBALS['_xh'][$parser]['vt'] = xmlrpcDateTime;
$GLOBALS['_xh'][$parser]['value']=$GLOBALS['_xh'][$parser]['ac'];
}
elseif ($name=='BASE64')
{
///@todo check for failure of base64 decoding / catch warnings
$GLOBALS['_xh'][$parser]['value'] = base64_decode($GLOBALS['_xh'][$parser]['ac']);
}
elseif ($name=='BOOLEAN')
{
// special case here: we translate boolean 1 or 0 into PHP
// constants true or false
// NB: this simple checks helps a lot sanitizing input, ie no
// security problems around here
if ($GLOBALS['_xh'][$parser]['ac']=='1')
{
$GLOBALS['_xh'][$parser]['value']=true;
}
else
{
// log if receiveing something strange, even though we set the value to false anyway
if ($GLOBALS['_xh'][$parser]['ac']!='0')
error_log('XML-RPC: invalid value received in BOOLEAN: '.$GLOBALS['_xh'][$parser]['ac']);
$GLOBALS['_xh'][$parser]['value']=false;
}
}
elseif ($name=='DOUBLE')
{
// we have a DOUBLE
// we must check that only 0123456789-.<space> are characters here
if (!preg_match('/'."^[+-]?[eE0123456789 \\t\\.]+$".'/', $GLOBALS['_xh'][$parser]['ac']))
{
// TODO: find a better way of throwing an error
// than this!
error_log('XML-RPC: non numeric value received in DOUBLE: '.$GLOBALS['_xh'][$parser]['ac']);
$GLOBALS['_xh'][$parser]['value']='ERROR_NON_NUMERIC_FOUND';
}
else
{
// it's ok, add it on
$GLOBALS['_xh'][$parser]['value']=(double)$GLOBALS['_xh'][$parser]['ac'];
}
}
else
{
// we have an I4/INT
// we must check that only 0123456789-<space> are characters here
if (!preg_match('/'."^[+-]?[0123456789 \\t]+$".'/', $GLOBALS['_xh'][$parser]['ac']))
{
// TODO: find a better way of throwing an error
// than this!
error_log('XML-RPC: non numeric value received in INT: '.$GLOBALS['_xh'][$parser]['ac']);
$GLOBALS['_xh'][$parser]['value']='ERROR_NON_NUMERIC_FOUND';
}
else
{
// it's ok, add it on
$GLOBALS['_xh'][$parser]['value'] = (int)$GLOBALS['_xh'][$parser]['ac'];
}
}
$GLOBALS['_xh'][$parser]['ac']=''; // is this necessary?
$GLOBALS['_xh'][$parser]['lv']=3; // indicate we've found a value
break;
case 'VALUE':
// This if() detects if no scalar was inside <VALUE></VALUE>
if ($GLOBALS['_xh'][$parser]['vt'] == 'value')
{
$GLOBALS['_xh'][$parser]['value'] = $GLOBALS['_xh'][$parser]['ac'];
$GLOBALS['_xh'][$parser]['vt'] = xmlrpcString;
}
// build the xmlrpc val out of the data received, and substitute it
$temp =& CreateObject('phpgwapi.xmlrpcval',$GLOBALS['_xh'][$parser]['value'], $GLOBALS['_xh'][$parser]['vt']);
// check if we are inside an array or struct:
// if value just built is inside an array, let's move it into array on the stack
if (count($GLOBALS['_xh'][$parser]['valuestack']) && $GLOBALS['_xh'][$parser]['valuestack'][0]['type']=='ARRAY')
{
$GLOBALS['_xh'][$parser]['valuestack'][0]['values'][] = $temp;
}
else
{
$GLOBALS['_xh'][$parser]['value'] = $temp;
}
break;
case 'MEMBER':
$GLOBALS['_xh'][$parser]['ac']=''; // is this necessary?
// add to array in the stack the last element built,
// unless no VALUE was found
if ($GLOBALS['_xh'][$parser]['value'])
$GLOBALS['_xh'][$parser]['valuestack'][0]['values'][$GLOBALS['_xh'][$parser]['valuestack'][0]['name']] = $GLOBALS['_xh'][$parser]['value'];
else
error_log('XML-RPC: missing VALUE inside STRUCT in received xml');
break;
case 'DATA':
$GLOBALS['_xh'][$parser]['ac']=''; // is this necessary?
break;
case 'PARAM':
// add to array of params the current value,
// unless no VALUE was found
if ($GLOBALS['_xh'][$parser]['value'])
$GLOBALS['_xh'][$parser]['params'][]=$GLOBALS['_xh'][$parser]['value'];
else
error_log('XML-RPC: missing VALUE inside PARAM in received xml');
break;
case 'METHODNAME':
$GLOBALS['_xh'][$parser]['method']=preg_replace('/'."^[\n\r\t ]+".'/', '', $GLOBALS['_xh'][$parser]['ac']);
break;
case 'PARAMS':
case 'FAULT':
case 'METHODCALL':
case 'METHORESPONSE':
break;
default:
// End of INVALID ELEMENT!
// shall we add an assert here for unreachable code???
break;
}
}
}
function xmlrpc_cd($parser, $data)
{
//if(preg_match('/'."^[\n\r \t]+$".'/', $data)) return;
// print "adding [${data}]\n";
// skip processing if xml fault already detected
if ($GLOBALS['_xh'][$parser]['isf'] < 2)
{
if($GLOBALS['_xh'][$parser]['lv']!=3)
{
// "lookforvalue==3" means that we've found an entire value
// and should discard any further character data
if($GLOBALS['_xh'][$parser]['lv']==1)
{
// if we've found text and we're just in a <value> then
// say we've found a value
$GLOBALS['_xh'][$parser]['lv']=2;
}
if(!@isset($GLOBALS['_xh'][$parser]['ac']))
{
$GLOBALS['_xh'][$parser]['ac'] = '';
}
$GLOBALS['_xh'][$parser]['ac'].=$data;
}
}
}
function xmlrpc_dh($parser, $data)
{
// skip processing if xml fault already detected
if ($GLOBALS['_xh'][$parser]['isf'] < 2)
{
if(substr($data, 0, 1) == '&' && substr($data, -1, 1) == ';')
{
if($GLOBALS['_xh'][$parser]['lv']==1)
{
$GLOBALS['_xh'][$parser]['lv']=2;
}
$GLOBALS['_xh'][$parser]['ac'].=$data;
}
}
}
// date helpers
function iso8601_encode($timet, $utc=0)
{
// return an ISO8601 encoded string
// really, timezones ought to be supported
// but the XML-RPC spec says:
//
// "Don't assume a timezone. It should be specified by the server in its
// documentation what assumptions it makes about timezones."
//
// these routines always assume localtime unless
// $utc is set to 1, in which case UTC is assumed
// and an adjustment for locale is made when encoding
if (!$utc)
{
$t=strftime("%Y%m%dT%H:%M:%S", $timet);
}
else
{
if(function_exists('gmstrftime'))
{
// gmstrftime doesn't exist in some versions
// of PHP
$t = gmstrftime("%Y%m%dT%H:%M:%S", $timet);
}
else
{
$t = strftime('%Y%m%dT%H:%M:%S', $timet-date('Z'));
}
}
return $t;
}
function iso8601_decode($idate, $utc=0)
{
// return a time in the localtime, or UTC
$t = 0;
if (preg_match('/'."([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})".'/',$idate, $regs))
{
if ($utc)
{
$t=gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
}
else
{
$t=mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
}
}
return $t;
}
/****************************************************************
* xmlrpc_decode takes a message in PHP xmlrpc object format and *
* tranlates it into native PHP types. *
* *
* author: Dan Libby (dan@libby.com) *
****************************************************************/
function phpgw_xmlrpc_decode($xmlrpc_val)
{
$kind = @$xmlrpc_val->kindOf();
if($kind == 'scalar')
{
return $xmlrpc_val->scalarval();
}
elseif($kind == 'array')
{
$size = $xmlrpc_val->arraysize();
$arr = array();
for($i = 0; $i < $size; $i++)
{
$arr[] = phpgw_xmlrpc_decode($xmlrpc_val->arraymem($i));
}
return $arr;
}
elseif($kind == 'struct')
{
$xmlrpc_val->structreset();
$arr = array();
while(list($key,$value)=$xmlrpc_val->structeach())
{
$arr[$key] = phpgw_xmlrpc_decode($value);
}
return $arr;
}
}
/****************************************************************
* xmlrpc_encode takes native php types and encodes them into *
* xmlrpc PHP object format. *
* BUG: All sequential arrays are turned into structs. I don't *
* know of a good way to determine if an array is sequential *
* only. *
* *
* feature creep -- could support more types via optional type *
* argument. *
* *
* author: Dan Libby (dan@libby.com) *
****************************************************************/
function phpgw_xmlrpc_encode($php_val)
{
$type = gettype($php_val);
$xmlrpc_val = CreateObject('phpgwapi.xmlrpcval');
switch($type)
{
case 'array':
case 'object':
$arr = array();
while(list($k,$v) = each($php_val))
{
$arr[$k] = phpgw_xmlrpc_encode($v);
}
$xmlrpc_val->addStruct($arr);
break;
case 'integer':
$xmlrpc_val->addScalar($php_val, xmlrpcInt);
break;
case 'double':
$xmlrpc_val->addScalar($php_val, xmlrpcDouble);
break;
case 'string':
$xmlrpc_val->addScalar($php_val, xmlrpcString);
break;
// <G_Giunta_2001-02-29>
// Add support for encoding/decoding of booleans, since they are supported in PHP
case 'boolean':
$xmlrpc_val->addScalar($php_val, xmlrpcBoolean);
break;
// </G_Giunta_2001-02-29>
case 'unknown type':
default:
$xmlrpc_val = False;
break;
}
return $xmlrpc_val;
}
/* The following functions are the system functions for login, logout, etc.
* They are added to the server map at the end of this file.
*/
$GLOBALS['_xmlrpcs_listMethods_sig'] = array(array(xmlrpcArray, xmlrpcString), array(xmlrpcArray));
$GLOBALS['_xmlrpcs_listMethods_doc'] = 'This method lists all the methods that the XML-RPC server knows how to dispatch';
function _xmlrpcs_listMethods($server, $m)
{
$v = CreateObject('phpgwapi.xmlrpcval');
$dmap = $server->dmap;
$outAr = array();
for(reset($dmap); list($key, $val) = each($dmap); )
{
$outAr[] = CreateObject('phpgwapi.xmlrpcval',$key, 'string');
}
$dmap = $GLOBALS['_xmlrpcs_dmap'];
for(reset($dmap); list($key, $val) = each($dmap); )
{
$outAr[] = CreateObject('phpgwapi.xmlrpcval',$key, 'string');
}
$v->addArray($outAr);
return CreateObject('phpgwapi.xmlrpcresp',$v);
}
$GLOBALS['_xmlrpcs_methodSignature_sig']=array(array(xmlrpcArray, xmlrpcString));
$GLOBALS['_xmlrpcs_methodSignature_doc']='Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)';
function _xmlrpcs_methodSignature($server, $m)
{
$methName = $m->getParam(0);
$methName = $methName->scalarval();
if (preg_match('/'."^system\.".'/', $methName))
{
$dmap = $GLOBALS['_xmlrpcs_dmap'];
$sysCall = 1;
}
else
{
$dmap = $server->dmap;
$sysCall = 0;
}
// print "<!-- ${methName} -->\n";
if (isset($dmap[$methName]))
{
if ($dmap[$methName]['signature'])
{
$sigs = array();
$thesigs=$dmap[$methName]['signature'];
for($i=0; $i<sizeof($thesigs); $i++)
{
$cursig = array();
$inSig = $thesigs[$i];
for($j=0; $j<sizeof($inSig); $j++)
{
$cursig[] = CreateObject('phpgwapi.xmlrpcval',$inSig[$j], 'string');
}
$sigs[] = CreateObject('phpgwapi.xmlrpcval',$cursig, 'array');
}
$r = CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$sigs, 'array'));
}
else
{
$r = CreateObject('phpgwapi.xmlrpcresp', CreateObject('phpgwapi.xmlrpcval','undef', 'string'));
}
}
else
{
$r = CreateObject('phpgwapi.xmlrpcresp',0,$GLOBALS['xmlrpcerr']['introspect_unknown'],$GLOBALS['xmlrpcstr']['introspect_unknown']);
}
return $r;
}
$GLOBALS['_xmlrpcs_methodHelp_sig'] = array(array(xmlrpcString, xmlrpcString));
$GLOBALS['_xmlrpcs_methodHelp_doc'] = 'Returns help text if defined for the method passed, otherwise returns an empty string';
function _xmlrpcs_methodHelp($server, $m)
{
$methName = $m->getParam(0);
$methName = $methName->scalarval();
if (preg_match('/'."^system\.".'/', $methName))
{
$dmap = $GLOBALS['_xmlrpcs_dmap'];
$sysCall=1;
}
else
{
$dmap = $server->dmap;
$sysCall=0;
}
// print "<!-- ${methName} -->\n";
if (isset($dmap[$methName]))
{
if ($dmap[$methName]['docstring'])
{
$r = CreateObject('phpgwapi.xmlrpcresp', CreateObject('phpgwapi.xmlrpcval',$dmap[$methName]['docstring']),'string');
}
else
{
$r = CreateObject('phpgwapi.xmlrpcresp', CreateObject('phpgwapi.xmlrpcval'), 'string');
}
}
else
{
$r = CreateObject('phpgwapi.xmlrpcresp',0,$GLOBALS['xmlrpcerr']['introspect_unknown'],$GLOBALS['xmlrpcstr']['introspect_unknown']);
}
return $r;
}
$GLOBALS['_xmlrpcs_login_sig'] = array(array(xmlrpcStruct,xmlrpcStruct));
$GLOBALS['_xmlrpcs_login_doc'] = 'eGroupWare client or server login via XML-RPC';
function _xmlrpcs_login($server,$m)
{
$rdata = $m->getParam(0);
$data = $rdata->scalarval();
if($data['server_name'])
{
$server_name = $data['server_name']->scalarval();
}
if($data['domain'])
{
$domain = $data['domain']->scalarval();
}
$username = $data['username']->scalarval();
$password = $data['password']->scalarval();
if($server_name)
{
list($sessionid,$kp3) = $GLOBALS['egw']->session->create($username.'@'.$server_name,$password,"text");
}
else
{
if($domain)
{
$user = $username.'@'.$domain;
}
else
{
$user = $username;
}
$GLOBALS['login'] = $user;
$sessionid = $GLOBALS['egw']->session->create($user,$password,"text");
$kp3 = $GLOBALS['egw']->session->kp3;
$domain = $GLOBALS['egw']->session->account_domain;
}
if($sessionid && $kp3)
{
$rtrn['domain'] = CreateObject('phpgwapi.xmlrpcval',$domain,'string');
$rtrn['sessionid'] = CreateObject('phpgwapi.xmlrpcval',$sessionid,'string');
$rtrn['kp3'] = CreateObject('phpgwapi.xmlrpcval',$kp3,'string');
}
else
{
$rtrn['GOAWAY'] = CreateObject('phpgwapi.xmlrpcval','XOXO','string');
}
return CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$rtrn,'struct'));
}
$GLOBALS['_xmlrpcs_logout_sig'] = array(array(xmlrpcStruct,xmlrpcStruct));
$GLOBALS['_xmlrpcs_logout_doc'] = 'eGroupWare client or server logout via XML-RPC';
function _xmlrpcs_logout($server,$m)
{
$rdata = $m->getParam(0);
$data = $rdata->scalarval();
$sessionid = $data['sessionid']->scalarval();
$kp3 = $data['kp3']->scalarval();
$later = $GLOBALS['egw']->session->destroy($sessionid,$kp3);
if ($later)
{
$rtrn['GOODBYE'] = CreateObject('phpgwapi.xmlrpcval','XOXO','string');
}
else
{
/* This never happens, yet */
$rtrn['OOPS'] = CreateObject('phpgwapi.xmlrpcval','WHAT?','string');
}
return CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$rtrn,'struct'));
}
$GLOBALS['_xmlrpcs_phpgw_api_version_sig'] = array(array(xmlrpcString));
$GLOBALS['_xmlrpcs_phpgw_api_version_doc'] = 'Returns the eGroupWare API version';
function _xmlrpcs_phpgw_api_version($server,$m)
{
$version = $GLOBALS['egw_info']['server']['versions']['phpgwapi'];
return CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$version,'string'));
}
/*
$GLOBALS['_xmlrpcs_listApps_sig'] = array(array(xmlrpcStruct,xmlrpcString));
$GLOBALS['_xmlrpcs_listApps_doc'] = 'Returns a list of installed phpgw apps';
function _xmlrpcs_listApps($server,$m)
{
$m->getParam(0);
$GLOBALS['egw']->db->query("SELECT * FROM egw_applications WHERE app_enabled<3",__LINE__,__FILE__);
if($GLOBALS['egw']->db->num_rows())
{
while($GLOBALS['egw']->db->next_record())
{
$name = $GLOBALS['egw']->db->f('app_name');
$title = $GLOBALS['egw']->db->f('app_title');
$status = $GLOBALS['egw']->db->f('app_enabled');
$version= $GLOBALS['egw']->db->f('app_version');
$apps[$name] = CreateObject('phpgwapi.xmlrpcval',
array(
'title' => CreateObject('phpgwapi.xmlrpcval',$title,'string'),
'name' => CreateObject('phpgwapi.xmlrpcval',$name,'string'),
'status' => CreateObject('phpgwapi.xmlrpcval',$status,'string'),
'version'=> CreateObject('phpgwapi.xmlrpcval',$version,'string')
),
'struct'
);
}
}
return CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$apps, 'struct'));
}
*/
$GLOBALS['_xmlrpcs_egw_time_sig'] = array(array(xmlrpcStruct));
$GLOBALS['_xmlrpcs_egw_time_doc'] = 'returns system-time and -timezone and if loged in user-time and timezone';
function _xmlrpcs_time($server,$m)
{
$return = array(
'system' => $GLOBALS['server']->date2iso8601(time()),
'system_tz_offset' => (int) date('Z'),
);
if ($GLOBALS['server']->authed)
{
$tz_offset_s = 3600 * (int) $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'];
$return += array(
'user' => $GLOBALS['server']->date2iso8601(time()+$tz_offset_s),
'user_tz_offset' => (int) date('Z') + $tz_offset_s,
);
}
return CreateObject(
'phpgwapi.xmlrpcresp',
$GLOBALS['server']->build_resp($return,true)
);
}
/* Add the system functions to the server map */
$GLOBALS['_xmlrpcs_dmap'] = array(
'system.listMethods' => array(
'function' => '_xmlrpcs_listMethods',
'signature' => $GLOBALS['_xmlrpcs_listMethods_sig'],
'docstring' => $GLOBALS['_xmlrpcs_listMethods_doc']
),
'system.methodHelp' => array(
'function' => '_xmlrpcs_methodHelp',
'signature' => $GLOBALS['_xmlrpcs_methodHelp_sig'],
'docstring' => $GLOBALS['_xmlrpcs_methodHelp_doc']
),
'system.methodSignature' => array(
'function' => '_xmlrpcs_methodSignature',
'signature' => $GLOBALS['_xmlrpcs_methodSignature_sig'],
'docstring' => $GLOBALS['_xmlrpcs_methodSignature_doc']
),
'system.login' => array(
'function' => '_xmlrpcs_login',
'signature' => $GLOBALS['_xmlrpcs_login_sig'],
'docstring' => $GLOBALS['_xmlrpcs_login_doc']
),
'system.logout' => array(
'function' => '_xmlrpcs_logout',
'signature' => $GLOBALS['_xmlrpcs_logout_sig'],
'docstring' => $GLOBALS['_xmlrpcs_logout_doc']
),
'system.phpgw_api_version' => array(
'function' => '_xmlrpcs_phpgw_api_version',
'signature' => $GLOBALS['_xmlrpcs_phpgw_api_version_sig'],
'docstring' => $GLOBALS['_xmlrpcs_phpgw_api_version_doc']
),
/*
'system.listApps' => array(
'function' => '_xmlrpcs_listApps',
'signature' => $GLOBALS['_xmlrpcs_listApps_sig'],
'docstring' => $GLOBALS['_xmlrpcs_listApps_doc']
),
*/
'system.time' => array(
'function' => '_xmlrpcs_time',
'signature' => $GLOBALS['_xmlrpcs_egw_time_sig'],
'docstring' => $GLOBALS['_xmlrpcs_egw_time_doc']
)
);
$GLOBALS['_xmlrpc_debuginfo'] = '';
function xmlrpc_debugmsg($m)
{
$GLOBALS['_xmlrpc_debuginfo'] .= $m . "\n";
}
?>